1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "bind.h"
20 #include "callback.h"
21 #include "i_postable_context.h"
22 
23 namespace bluetooth {
24 namespace common {
25 
26 template <typename R, typename... Args>
27 class ContextualOnceCallback;
28 
29 // A callback bound to an execution context that can be invoked only once.
30 template <typename R, typename... Args>
31 class ContextualOnceCallback<R(Args...)> {
32  public:
ContextualOnceCallback(common::OnceCallback<R (Args...)> && callback,IPostableContext * context)33   ContextualOnceCallback(common::OnceCallback<R(Args...)>&& callback, IPostableContext* context)
34       : callback_(std::move(callback)), context_(context) {}
35 
36   constexpr ContextualOnceCallback() = default;
37   ContextualOnceCallback(const ContextualOnceCallback&) = delete;
38   ContextualOnceCallback& operator=(const ContextualOnceCallback&) = delete;
39 
40   ContextualOnceCallback(ContextualOnceCallback&&) noexcept = default;
41   ContextualOnceCallback& operator=(ContextualOnceCallback&&) noexcept = default;
42 
operator()43   void operator()(Args... args) {
44     context_->Post(common::BindOnce(std::move(callback_), std::forward<Args>(args)...));
45   }
46 
47   operator bool() const {
48     return context_ && callback_;
49   }
50 
51  private:
52   common::OnceCallback<R(Args...)> callback_;
53   IPostableContext* context_;
54 };
55 
56 template <typename Callback>
57 ContextualOnceCallback(Callback&& callback, IPostableContext* context)
58     -> ContextualOnceCallback<typename Callback::RunType>;
59 
60 template <typename R, typename... Args>
61 class ContextualCallback;
62 
63 // A callback bound to an execution context that can be invoked multiple times.
64 template <typename R, typename... Args>
65 class ContextualCallback<R(Args...)> {
66  public:
ContextualCallback(common::Callback<R (Args...)> && callback,IPostableContext * context)67   ContextualCallback(common::Callback<R(Args...)>&& callback, IPostableContext* context)
68       : callback_(std::move(callback)), context_(context) {}
69 
70   constexpr ContextualCallback() = default;
71 
72   ContextualCallback(const ContextualCallback&) = default;
73   ContextualCallback& operator=(const ContextualCallback&) = default;
74   ContextualCallback(ContextualCallback&&) noexcept = default;
75   ContextualCallback& operator=(ContextualCallback&&) noexcept = default;
76 
operator()77   void operator()(Args... args) {
78     context_->Post(common::BindOnce(callback_, std::forward<Args>(args)...));
79   }
80 
81   operator bool() const {
82     return context_ && callback_;
83   }
84 
85  private:
86   common::Callback<R(Args...)> callback_;
87   IPostableContext* context_;
88 };
89 
90 template <typename Callback>
91 ContextualCallback(Callback&& callback, IPostableContext* context)
92     -> ContextualCallback<typename Callback::RunType>;
93 
94 }  // namespace common
95 }  // namespace bluetooth
96