| /* |
| * Copyright 2020 The WebRTC Project Authors. All rights reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #ifndef RTC_BASE_ROBO_CALLER_H_ |
| #define RTC_BASE_ROBO_CALLER_H_ |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "api/function_view.h" |
| #include "rtc_base/system/assume.h" |
| #include "rtc_base/system/inline.h" |
| #include "rtc_base/untyped_function.h" |
| |
| namespace webrtc { |
| namespace robo_caller_impl { |
| |
| class RoboCallerReceivers { |
| public: |
| RoboCallerReceivers(); |
| RoboCallerReceivers(const RoboCallerReceivers&) = delete; |
| RoboCallerReceivers& operator=(const RoboCallerReceivers&) = delete; |
| RoboCallerReceivers(RoboCallerReceivers&&) = delete; |
| RoboCallerReceivers& operator=(RoboCallerReceivers&&) = delete; |
| ~RoboCallerReceivers(); |
| |
| template <typename UntypedFunctionArgsT> |
| RTC_NO_INLINE void AddReceiver(UntypedFunctionArgsT args) { |
| receivers_.push_back(UntypedFunction::Create(args)); |
| } |
| |
| void Foreach(rtc::FunctionView<void(UntypedFunction&)> fv); |
| |
| private: |
| std::vector<UntypedFunction> receivers_; |
| }; |
| |
| extern template void RoboCallerReceivers::AddReceiver( |
| UntypedFunction::TrivialUntypedFunctionArgs<1>); |
| extern template void RoboCallerReceivers::AddReceiver( |
| UntypedFunction::TrivialUntypedFunctionArgs<2>); |
| extern template void RoboCallerReceivers::AddReceiver( |
| UntypedFunction::TrivialUntypedFunctionArgs<3>); |
| extern template void RoboCallerReceivers::AddReceiver( |
| UntypedFunction::TrivialUntypedFunctionArgs<4>); |
| extern template void RoboCallerReceivers::AddReceiver( |
| UntypedFunction::NontrivialUntypedFunctionArgs); |
| extern template void RoboCallerReceivers::AddReceiver( |
| UntypedFunction::FunctionPointerUntypedFunctionArgs); |
| |
| } // namespace robo_caller_impl |
| |
| // A collection of receivers (callable objects) that can be called all at once. |
| // Optimized for minimal binary size. |
| // |
| // Neither copyable nor movable. Could easily be made movable if necessary. |
| // |
| // TODO(kwiberg): Add support for removing receivers, if necessary. AddReceiver |
| // would have to return some sort of ID that the caller could save and then pass |
| // to RemoveReceiver. Alternatively, the callable objects could return one value |
| // if they wish to stay in the CSC and another value if they wish to be removed. |
| // It depends on what's convenient for the callers... |
| template <typename... ArgT> |
| class RoboCaller { |
| public: |
| RoboCaller() = default; |
| RoboCaller(const RoboCaller&) = delete; |
| RoboCaller& operator=(const RoboCaller&) = delete; |
| RoboCaller(RoboCaller&&) = delete; |
| RoboCaller& operator=(RoboCaller&&) = delete; |
| |
| // Adds a new receiver. The receiver (a callable object or a function pointer) |
| // must be movable, but need not be copyable. Its call signature should be |
| // `void(ArgT...)`. |
| template <typename F> |
| void AddReceiver(F&& f) { |
| receivers_.AddReceiver( |
| UntypedFunction::PrepareArgs<void(ArgT...)>(std::forward<F>(f))); |
| } |
| |
| // Calls all receivers with the given arguments. |
| template <typename... ArgU> |
| void Send(ArgU&&... args) { |
| receivers_.Foreach([&](UntypedFunction& f) { |
| f.Call<void(ArgT...)>(std::forward<ArgU>(args)...); |
| }); |
| } |
| |
| private: |
| robo_caller_impl::RoboCallerReceivers receivers_; |
| }; |
| |
| } // namespace webrtc |
| |
| #endif // RTC_BASE_ROBO_CALLER_H_ |