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 "common/bind.h" 20 #include "common/callback.h" 21 22 namespace bluetooth { 23 namespace common { 24 25 class IPostableContext { 26 public: ~IPostableContext()27 virtual ~IPostableContext(){}; 28 virtual void Post(OnceClosure closure) = 0; 29 }; 30 31 template <typename R, typename... Args> 32 class ContextualOnceCallback; 33 34 // A callback bound to an execution context that can be invoked only once. 35 template <typename R, typename... Args> 36 class ContextualOnceCallback<R(Args...)> { 37 public: ContextualOnceCallback(common::OnceCallback<R (Args...)> && callback,IPostableContext * context)38 ContextualOnceCallback(common::OnceCallback<R(Args...)>&& callback, IPostableContext* context) 39 : callback_(std::move(callback)), context_(context) {} 40 41 constexpr ContextualOnceCallback() = default; 42 43 DISALLOW_COPY_AND_ASSIGN(ContextualOnceCallback); 44 45 ContextualOnceCallback(ContextualOnceCallback&&) noexcept = default; 46 ContextualOnceCallback& operator=(ContextualOnceCallback&&) noexcept = default; 47 Invoke(Args...args)48 void Invoke(Args... args) { 49 context_->Post(common::BindOnce(std::move(callback_), std::forward<Args>(args)...)); 50 } 51 InvokeIfNotEmpty(Args...args)52 void InvokeIfNotEmpty(Args... args) { 53 if (context_ != nullptr) { 54 context_->Post(common::BindOnce(std::move(callback_), std::forward<Args>(args)...)); 55 } 56 } 57 IsEmpty()58 bool IsEmpty() { 59 return context_ == nullptr; 60 } 61 62 private: 63 common::OnceCallback<R(Args...)> callback_; 64 IPostableContext* context_; 65 }; 66 67 template <typename R, typename... Args> 68 class ContextualCallback; 69 70 // A callback bound to an execution context that can be invoked multiple times. 71 template <typename R, typename... Args> 72 class ContextualCallback<R(Args...)> { 73 public: ContextualCallback(common::Callback<R (Args...)> && callback,IPostableContext * context)74 ContextualCallback(common::Callback<R(Args...)>&& callback, IPostableContext* context) 75 : callback_(std::move(callback)), context_(context) {} 76 77 constexpr ContextualCallback() = default; 78 79 ContextualCallback(const ContextualCallback&) = default; 80 ContextualCallback& operator=(const ContextualCallback&) = default; 81 ContextualCallback(ContextualCallback&&) noexcept = default; 82 ContextualCallback& operator=(ContextualCallback&&) noexcept = default; 83 Invoke(Args...args)84 void Invoke(Args... args) { 85 context_->Post(common::BindOnce(callback_, std::forward<Args>(args)...)); 86 } 87 InvokeIfNotEmpty(Args...args)88 void InvokeIfNotEmpty(Args... args) { 89 if (context_ != nullptr) { 90 context_->Post(common::BindOnce(callback_, std::forward<Args>(args)...)); 91 } 92 } 93 IsEmpty()94 bool IsEmpty() { 95 return context_ == nullptr; 96 } 97 98 private: 99 common::Callback<R(Args...)> callback_; 100 IPostableContext* context_; 101 }; 102 103 } // namespace common 104 } // namespace bluetooth 105