blob: 218693aff4ab68d7bd69a7b8f79d4a767c8de415 [file] [log] [blame]
Karl Wiberg3d452cf2020-09-11 16:09:46 +02001/*
2 * Copyright 2020 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei3d259352020-10-23 12:04:40 +020011#ifndef RTC_BASE_CALLBACK_LIST_H_
12#define RTC_BASE_CALLBACK_LIST_H_
Karl Wiberg3d452cf2020-09-11 16:09:46 +020013
14#include <utility>
15#include <vector>
16
17#include "api/function_view.h"
Karl Wiberg3d452cf2020-09-11 16:09:46 +020018#include "rtc_base/system/assume.h"
Karl Wibergd2c69672020-09-29 13:55:13 +020019#include "rtc_base/system/inline.h"
Karl Wiberg70026f92020-09-18 10:03:16 +020020#include "rtc_base/untyped_function.h"
Karl Wiberg3d452cf2020-09-11 16:09:46 +020021
22namespace webrtc {
Mirko Bonadei3d259352020-10-23 12:04:40 +020023namespace callback_list_impl {
Karl Wiberg3d452cf2020-09-11 16:09:46 +020024
Mirko Bonadei3d259352020-10-23 12:04:40 +020025class CallbackListReceivers {
Karl Wiberg3d452cf2020-09-11 16:09:46 +020026 public:
Mirko Bonadei3d259352020-10-23 12:04:40 +020027 CallbackListReceivers();
28 CallbackListReceivers(const CallbackListReceivers&) = delete;
29 CallbackListReceivers& operator=(const CallbackListReceivers&) = delete;
30 CallbackListReceivers(CallbackListReceivers&&) = delete;
31 CallbackListReceivers& operator=(CallbackListReceivers&&) = delete;
32 ~CallbackListReceivers();
Karl Wiberg8d875582020-09-18 09:59:50 +020033
Karl Wibergd2c69672020-09-29 13:55:13 +020034 template <typename UntypedFunctionArgsT>
35 RTC_NO_INLINE void AddReceiver(UntypedFunctionArgsT args) {
36 receivers_.push_back(UntypedFunction::Create(args));
Karl Wiberg3d452cf2020-09-11 16:09:46 +020037 }
Karl Wiberg8d875582020-09-18 09:59:50 +020038
Karl Wiberg3d452cf2020-09-11 16:09:46 +020039 void Foreach(rtc::FunctionView<void(UntypedFunction&)> fv);
40
41 private:
Karl Wiberg3d452cf2020-09-11 16:09:46 +020042 std::vector<UntypedFunction> receivers_;
43};
44
Mirko Bonadei3d259352020-10-23 12:04:40 +020045extern template void CallbackListReceivers::AddReceiver(
Karl Wibergd2c69672020-09-29 13:55:13 +020046 UntypedFunction::TrivialUntypedFunctionArgs<1>);
Mirko Bonadei3d259352020-10-23 12:04:40 +020047extern template void CallbackListReceivers::AddReceiver(
Karl Wibergd2c69672020-09-29 13:55:13 +020048 UntypedFunction::TrivialUntypedFunctionArgs<2>);
Mirko Bonadei3d259352020-10-23 12:04:40 +020049extern template void CallbackListReceivers::AddReceiver(
Karl Wibergd2c69672020-09-29 13:55:13 +020050 UntypedFunction::TrivialUntypedFunctionArgs<3>);
Mirko Bonadei3d259352020-10-23 12:04:40 +020051extern template void CallbackListReceivers::AddReceiver(
Karl Wibergd2c69672020-09-29 13:55:13 +020052 UntypedFunction::TrivialUntypedFunctionArgs<4>);
Mirko Bonadei3d259352020-10-23 12:04:40 +020053extern template void CallbackListReceivers::AddReceiver(
Karl Wibergd2c69672020-09-29 13:55:13 +020054 UntypedFunction::NontrivialUntypedFunctionArgs);
Mirko Bonadei3d259352020-10-23 12:04:40 +020055extern template void CallbackListReceivers::AddReceiver(
Karl Wibergd2c69672020-09-29 13:55:13 +020056 UntypedFunction::FunctionPointerUntypedFunctionArgs);
57
Mirko Bonadei3d259352020-10-23 12:04:40 +020058} // namespace callback_list_impl
Karl Wiberg3d452cf2020-09-11 16:09:46 +020059
60// A collection of receivers (callable objects) that can be called all at once.
61// Optimized for minimal binary size.
62//
Karl Wiberg8d875582020-09-18 09:59:50 +020063// Neither copyable nor movable. Could easily be made movable if necessary.
64//
Karl Wiberg3d452cf2020-09-11 16:09:46 +020065// TODO(kwiberg): Add support for removing receivers, if necessary. AddReceiver
66// would have to return some sort of ID that the caller could save and then pass
67// to RemoveReceiver. Alternatively, the callable objects could return one value
68// if they wish to stay in the CSC and another value if they wish to be removed.
69// It depends on what's convenient for the callers...
70template <typename... ArgT>
Mirko Bonadei3d259352020-10-23 12:04:40 +020071class CallbackList {
Karl Wiberg3d452cf2020-09-11 16:09:46 +020072 public:
Mirko Bonadei3d259352020-10-23 12:04:40 +020073 CallbackList() = default;
74 CallbackList(const CallbackList&) = delete;
75 CallbackList& operator=(const CallbackList&) = delete;
76 CallbackList(CallbackList&&) = delete;
77 CallbackList& operator=(CallbackList&&) = delete;
Karl Wiberg8d875582020-09-18 09:59:50 +020078
79 // Adds a new receiver. The receiver (a callable object or a function pointer)
80 // must be movable, but need not be copyable. Its call signature should be
81 // `void(ArgT...)`.
Karl Wiberg3d452cf2020-09-11 16:09:46 +020082 template <typename F>
83 void AddReceiver(F&& f) {
84 receivers_.AddReceiver(
Karl Wibergd2c69672020-09-29 13:55:13 +020085 UntypedFunction::PrepareArgs<void(ArgT...)>(std::forward<F>(f)));
Karl Wiberg3d452cf2020-09-11 16:09:46 +020086 }
Karl Wiberg8d875582020-09-18 09:59:50 +020087
88 // Calls all receivers with the given arguments.
Karl Wibergd88b1692020-09-25 06:16:12 +020089 template <typename... ArgU>
90 void Send(ArgU&&... args) {
Karl Wiberg3d452cf2020-09-11 16:09:46 +020091 receivers_.Foreach([&](UntypedFunction& f) {
Karl Wibergd88b1692020-09-25 06:16:12 +020092 f.Call<void(ArgT...)>(std::forward<ArgU>(args)...);
Karl Wiberg3d452cf2020-09-11 16:09:46 +020093 });
94 }
95
96 private:
Mirko Bonadei3d259352020-10-23 12:04:40 +020097 callback_list_impl::CallbackListReceivers receivers_;
Karl Wiberg3d452cf2020-09-11 16:09:46 +020098};
99
100} // namespace webrtc
101
Mirko Bonadei3d259352020-10-23 12:04:40 +0200102#endif // RTC_BASE_CALLBACK_LIST_H_