blob: 9df6a48a5e54f9621108ec7400e5aabb7a6a480c [file] [log] [blame]
/*
* 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_