/* * 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 #include #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 RTC_NO_INLINE void AddReceiver(UntypedFunctionArgsT args) { receivers_.push_back(UntypedFunction::Create(args)); } void Foreach(rtc::FunctionView fv); private: std::vector 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 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 void AddReceiver(F&& f) { receivers_.AddReceiver( UntypedFunction::PrepareArgs(std::forward(f))); } // Calls all receivers with the given arguments. template void Send(ArgU&&... args) { receivers_.Foreach([&](UntypedFunction& f) { f.Call(std::forward(args)...); }); } private: robo_caller_impl::RoboCallerReceivers receivers_; }; } // namespace webrtc #endif // RTC_BASE_ROBO_CALLER_H_