blob: 99160517deebd79cd33d371febe21c4a7710caa1 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2013 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
11// This file contains Macros for creating proxies for webrtc MediaStream and
12// PeerConnection classes.
deadbeefb10f32f2017-02-08 01:38:21 -080013// TODO(deadbeef): Move this to pc/; this is part of the implementation.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000014
15//
16// Example usage:
17//
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000018// class TestInterface : public rtc::RefCountInterface {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000019// public:
20// std::string FooA() = 0;
21// std::string FooB(bool arg1) const = 0;
nisse72c8d2b2016-04-15 03:49:07 -070022// std::string FooC(bool arg1) = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000023// };
24//
25// Note that return types can not be a const reference.
26//
27// class Test : public TestInterface {
28// ... implementation of the interface.
29// };
30//
31// BEGIN_PROXY_MAP(Test)
deadbeefd99a2002017-01-18 08:55:23 -080032// PROXY_SIGNALING_THREAD_DESTRUCTOR()
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033// PROXY_METHOD0(std::string, FooA)
34// PROXY_CONSTMETHOD1(std::string, FooB, arg1)
nisse72c8d2b2016-04-15 03:49:07 -070035// PROXY_WORKER_METHOD1(std::string, FooC, arg1)
deadbeefd99a2002017-01-18 08:55:23 -080036// END_PROXY_MAP()
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037//
deadbeefd99a2002017-01-18 08:55:23 -080038// Where the destructor and first two methods are invoked on the signaling
39// thread, and the third is invoked on the worker thread.
nisse72c8d2b2016-04-15 03:49:07 -070040//
41// The proxy can be created using
42//
43// TestProxy::Create(Thread* signaling_thread, Thread* worker_thread,
44// TestInterface*).
45//
46// The variant defined with BEGIN_SIGNALING_PROXY_MAP is unaware of
47// the worker thread, and invokes all methods on the signaling thread.
deadbeefd99a2002017-01-18 08:55:23 -080048//
49// The variant defined with BEGIN_OWNED_PROXY_MAP does not use
50// refcounting, and instead just takes ownership of the object being proxied.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020052#ifndef API_PROXY_H_
53#define API_PROXY_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054
kwibergd1fe2812016-04-27 06:47:29 -070055#include <memory>
oprypin803dc292017-02-01 01:55:59 -080056#include <utility>
kwibergd1fe2812016-04-27 06:47:29 -070057
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "rtc_base/event.h"
Niels Möller84255bb2017-10-06 13:43:23 +020059#include "rtc_base/refcountedobject.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020060#include "rtc_base/thread.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061
62namespace webrtc {
63
64template <typename R>
65class ReturnType {
66 public:
Yves Gerey665174f2018-06-19 15:03:05 +020067 template <typename C, typename M>
68 void Invoke(C* c, M m) {
69 r_ = (c->*m)();
70 }
deadbeefd99a2002017-01-18 08:55:23 -080071 template <typename C, typename M, typename T1>
72 void Invoke(C* c, M m, T1 a1) {
73 r_ = (c->*m)(std::move(a1));
74 }
75 template <typename C, typename M, typename T1, typename T2>
76 void Invoke(C* c, M m, T1 a1, T2 a2) {
77 r_ = (c->*m)(std::move(a1), std::move(a2));
78 }
79 template <typename C, typename M, typename T1, typename T2, typename T3>
80 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) {
81 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3));
82 }
Yves Gerey665174f2018-06-19 15:03:05 +020083 template <typename C,
84 typename M,
85 typename T1,
86 typename T2,
87 typename T3,
88 typename T4>
perkj@webrtc.org81134d02015-01-12 08:30:16 +000089 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4) {
deadbeefd99a2002017-01-18 08:55:23 -080090 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3), std::move(a4));
perkj@webrtc.org81134d02015-01-12 08:30:16 +000091 }
Yves Gerey665174f2018-06-19 15:03:05 +020092 template <typename C,
93 typename M,
94 typename T1,
95 typename T2,
96 typename T3,
97 typename T4,
98 typename T5>
perkj@webrtc.org81134d02015-01-12 08:30:16 +000099 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
deadbeefd99a2002017-01-18 08:55:23 -0800100 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3), std::move(a4),
101 std::move(a5));
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000102 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000103
deadbeefd99a2002017-01-18 08:55:23 -0800104 R moved_result() { return std::move(r_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000105
106 private:
107 R r_;
108};
109
110template <>
111class ReturnType<void> {
112 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200113 template <typename C, typename M>
114 void Invoke(C* c, M m) {
115 (c->*m)();
116 }
deadbeefd99a2002017-01-18 08:55:23 -0800117 template <typename C, typename M, typename T1>
118 void Invoke(C* c, M m, T1 a1) {
119 (c->*m)(std::move(a1));
120 }
121 template <typename C, typename M, typename T1, typename T2>
122 void Invoke(C* c, M m, T1 a1, T2 a2) {
123 (c->*m)(std::move(a1), std::move(a2));
124 }
125 template <typename C, typename M, typename T1, typename T2, typename T3>
126 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) {
127 (c->*m)(std::move(a1), std::move(a2), std::move(a3));
128 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129
deadbeefd99a2002017-01-18 08:55:23 -0800130 void moved_result() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131};
132
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000133namespace internal {
134
Yves Gerey665174f2018-06-19 15:03:05 +0200135class SynchronousMethodCall : public rtc::MessageData,
136 public rtc::MessageHandler {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000137 public:
Steve Antonf2737d22017-10-31 16:27:34 -0700138 explicit SynchronousMethodCall(rtc::MessageHandler* proxy);
139 ~SynchronousMethodCall() override;
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000140
Steve Antonf2737d22017-10-31 16:27:34 -0700141 void Invoke(const rtc::Location& posted_from, rtc::Thread* t);
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000142
143 private:
Steve Antonf2737d22017-10-31 16:27:34 -0700144 void OnMessage(rtc::Message*) override;
145
Niels Möller58376f32018-11-15 09:31:38 +0100146 rtc::Event e_;
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000147 rtc::MessageHandler* proxy_;
148};
149
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000150} // namespace internal
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000151
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152template <typename C, typename R>
Yves Gerey665174f2018-06-19 15:03:05 +0200153class MethodCall0 : public rtc::Message, public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154 public:
155 typedef R (C::*Method)();
156 MethodCall0(C* c, Method m) : c_(c), m_(m) {}
157
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700158 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
159 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800160 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161 }
162
163 private:
Yves Gerey665174f2018-06-19 15:03:05 +0200164 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165
166 C* c_;
167 Method m_;
168 ReturnType<R> r_;
169};
170
171template <typename C, typename R>
Yves Gerey665174f2018-06-19 15:03:05 +0200172class ConstMethodCall0 : public rtc::Message, public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173 public:
174 typedef R (C::*Method)() const;
175 ConstMethodCall0(C* c, Method m) : c_(c), m_(m) {}
176
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700177 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
178 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800179 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180 }
181
182 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000183 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000184
185 C* c_;
186 Method m_;
187 ReturnType<R> r_;
188};
189
Yves Gerey665174f2018-06-19 15:03:05 +0200190template <typename C, typename R, typename T1>
191class MethodCall1 : public rtc::Message, public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000192 public:
193 typedef R (C::*Method)(T1 a1);
deadbeefd99a2002017-01-18 08:55:23 -0800194 MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(std::move(a1)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700196 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
197 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800198 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 }
200
201 private:
deadbeefd99a2002017-01-18 08:55:23 -0800202 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, std::move(a1_)); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000203
204 C* c_;
205 Method m_;
206 ReturnType<R> r_;
207 T1 a1_;
208};
209
Yves Gerey665174f2018-06-19 15:03:05 +0200210template <typename C, typename R, typename T1>
211class ConstMethodCall1 : public rtc::Message, public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 public:
213 typedef R (C::*Method)(T1 a1) const;
deadbeefd99a2002017-01-18 08:55:23 -0800214 ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(std::move(a1)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000215
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700216 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
217 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800218 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000219 }
220
221 private:
deadbeefd99a2002017-01-18 08:55:23 -0800222 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, std::move(a1_)); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223
224 C* c_;
225 Method m_;
226 ReturnType<R> r_;
227 T1 a1_;
228};
229
230template <typename C, typename R, typename T1, typename T2>
Yves Gerey665174f2018-06-19 15:03:05 +0200231class MethodCall2 : public rtc::Message, public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 public:
233 typedef R (C::*Method)(T1 a1, T2 a2);
deadbeefd99a2002017-01-18 08:55:23 -0800234 MethodCall2(C* c, Method m, T1 a1, T2 a2)
235 : c_(c), m_(m), a1_(std::move(a1)), a2_(std::move(a2)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700237 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
238 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800239 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240 }
241
242 private:
deadbeefd99a2002017-01-18 08:55:23 -0800243 void OnMessage(rtc::Message*) {
244 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_));
245 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246
247 C* c_;
248 Method m_;
249 ReturnType<R> r_;
250 T1 a1_;
251 T2 a2_;
252};
253
254template <typename C, typename R, typename T1, typename T2, typename T3>
Yves Gerey665174f2018-06-19 15:03:05 +0200255class MethodCall3 : public rtc::Message, public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 public:
257 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3);
258 MethodCall3(C* c, Method m, T1 a1, T2 a2, T3 a3)
deadbeefd99a2002017-01-18 08:55:23 -0800259 : c_(c),
260 m_(m),
261 a1_(std::move(a1)),
262 a2_(std::move(a2)),
263 a3_(std::move(a3)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000264
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700265 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
266 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800267 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 }
269
270 private:
deadbeefd99a2002017-01-18 08:55:23 -0800271 void OnMessage(rtc::Message*) {
272 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_));
273 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274
275 C* c_;
276 Method m_;
277 ReturnType<R> r_;
278 T1 a1_;
279 T2 a2_;
280 T3 a3_;
281};
282
Yves Gerey665174f2018-06-19 15:03:05 +0200283template <typename C,
284 typename R,
285 typename T1,
286 typename T2,
287 typename T3,
288 typename T4>
289class MethodCall4 : public rtc::Message, public rtc::MessageHandler {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000290 public:
291 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4);
292 MethodCall4(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4)
deadbeefd99a2002017-01-18 08:55:23 -0800293 : c_(c),
294 m_(m),
295 a1_(std::move(a1)),
296 a2_(std::move(a2)),
297 a3_(std::move(a3)),
298 a4_(std::move(a4)) {}
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000299
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700300 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
301 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800302 return r_.moved_result();
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000303 }
304
305 private:
deadbeefd99a2002017-01-18 08:55:23 -0800306 void OnMessage(rtc::Message*) {
307 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_),
308 std::move(a4_));
309 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000310
311 C* c_;
312 Method m_;
313 ReturnType<R> r_;
314 T1 a1_;
315 T2 a2_;
316 T3 a3_;
317 T4 a4_;
318};
319
Yves Gerey665174f2018-06-19 15:03:05 +0200320template <typename C,
321 typename R,
322 typename T1,
323 typename T2,
324 typename T3,
325 typename T4,
326 typename T5>
327class MethodCall5 : public rtc::Message, public rtc::MessageHandler {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000328 public:
329 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
330 MethodCall5(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
deadbeefd99a2002017-01-18 08:55:23 -0800331 : c_(c),
332 m_(m),
333 a1_(std::move(a1)),
334 a2_(std::move(a2)),
335 a3_(std::move(a3)),
336 a4_(std::move(a4)),
337 a5_(std::move(a5)) {}
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000338
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700339 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
340 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800341 return r_.moved_result();
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000342 }
343
344 private:
deadbeefd99a2002017-01-18 08:55:23 -0800345 void OnMessage(rtc::Message*) {
346 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_),
347 std::move(a4_), std::move(a5_));
348 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000349
350 C* c_;
351 Method m_;
352 ReturnType<R> r_;
353 T1 a1_;
354 T2 a2_;
355 T3 a3_;
356 T4 a4_;
357 T5 a5_;
358};
359
deadbeefd99a2002017-01-18 08:55:23 -0800360// Helper macros to reduce code duplication.
deadbeefe814a0d2017-02-25 18:15:09 -0800361#define PROXY_MAP_BOILERPLATE(c) \
362 template <class INTERNAL_CLASS> \
363 class c##ProxyWithInternal; \
364 typedef c##ProxyWithInternal<c##Interface> c##Proxy; \
365 template <class INTERNAL_CLASS> \
366 class c##ProxyWithInternal : public c##Interface { \
367 protected: \
368 typedef c##Interface C; \
369 \
370 public: \
371 const INTERNAL_CLASS* internal() const { return c_; } \
372 INTERNAL_CLASS* internal() { return c_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373
Yves Gerey665174f2018-06-19 15:03:05 +0200374// clang-format off
375// clang-format would put the semicolon alone,
376// leading to a presubmit error (cpplint.py)
oprypin803dc292017-02-01 01:55:59 -0800377#define END_PROXY_MAP() \
378 };
Yves Gerey665174f2018-06-19 15:03:05 +0200379// clang-format on
oprypin803dc292017-02-01 01:55:59 -0800380
deadbeefd99a2002017-01-18 08:55:23 -0800381#define SIGNALING_PROXY_MAP_BOILERPLATE(c) \
382 protected: \
383 c##ProxyWithInternal(rtc::Thread* signaling_thread, INTERNAL_CLASS* c) \
384 : signaling_thread_(signaling_thread), c_(c) {} \
385 \
386 private: \
387 mutable rtc::Thread* signaling_thread_;
388
389#define WORKER_PROXY_MAP_BOILERPLATE(c) \
390 protected: \
391 c##ProxyWithInternal(rtc::Thread* signaling_thread, \
392 rtc::Thread* worker_thread, INTERNAL_CLASS* c) \
393 : signaling_thread_(signaling_thread), \
394 worker_thread_(worker_thread), \
395 c_(c) {} \
396 \
397 private: \
398 mutable rtc::Thread* signaling_thread_; \
399 mutable rtc::Thread* worker_thread_;
400
401// Note that the destructor is protected so that the proxy can only be
402// destroyed via RefCountInterface.
403#define REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
404 protected: \
405 ~c##ProxyWithInternal() { \
406 MethodCall0<c##ProxyWithInternal, void> call( \
407 this, &c##ProxyWithInternal::DestroyInternal); \
408 call.Marshal(RTC_FROM_HERE, destructor_thread()); \
409 } \
410 \
411 private: \
412 void DestroyInternal() { c_ = nullptr; } \
413 rtc::scoped_refptr<INTERNAL_CLASS> c_;
414
deadbeefe814a0d2017-02-25 18:15:09 -0800415// Note: This doesn't use a unique_ptr, because it intends to handle a corner
416// case where an object's deletion triggers a callback that calls back into
417// this proxy object. If relying on a unique_ptr to delete the object, its
418// inner pointer would be set to null before this reentrant callback would have
419// a chance to run, resulting in a segfault.
deadbeefd99a2002017-01-18 08:55:23 -0800420#define OWNED_PROXY_MAP_BOILERPLATE(c) \
421 public: \
422 ~c##ProxyWithInternal() { \
423 MethodCall0<c##ProxyWithInternal, void> call( \
424 this, &c##ProxyWithInternal::DestroyInternal); \
425 call.Marshal(RTC_FROM_HERE, destructor_thread()); \
426 } \
427 \
428 private: \
deadbeefe814a0d2017-02-25 18:15:09 -0800429 void DestroyInternal() { delete c_; } \
430 INTERNAL_CLASS* c_;
deadbeefd99a2002017-01-18 08:55:23 -0800431
432#define BEGIN_SIGNALING_PROXY_MAP(c) \
433 PROXY_MAP_BOILERPLATE(c) \
434 SIGNALING_PROXY_MAP_BOILERPLATE(c) \
435 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
436 public: \
437 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \
438 rtc::Thread* signaling_thread, INTERNAL_CLASS* c) { \
439 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \
440 c); \
441 }
442
443#define BEGIN_PROXY_MAP(c) \
444 PROXY_MAP_BOILERPLATE(c) \
445 WORKER_PROXY_MAP_BOILERPLATE(c) \
446 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
447 public: \
448 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \
449 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \
450 INTERNAL_CLASS* c) { \
451 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \
452 worker_thread, c); \
453 }
454
deadbeefe814a0d2017-02-25 18:15:09 -0800455#define BEGIN_OWNED_PROXY_MAP(c) \
456 PROXY_MAP_BOILERPLATE(c) \
457 WORKER_PROXY_MAP_BOILERPLATE(c) \
458 OWNED_PROXY_MAP_BOILERPLATE(c) \
459 public: \
460 static std::unique_ptr<c##Interface> Create( \
461 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \
462 std::unique_ptr<INTERNAL_CLASS> c) { \
463 return std::unique_ptr<c##Interface>(new c##ProxyWithInternal( \
464 signaling_thread, worker_thread, c.release())); \
deadbeefd99a2002017-01-18 08:55:23 -0800465 }
466
467#define PROXY_SIGNALING_THREAD_DESTRUCTOR() \
468 private: \
469 rtc::Thread* destructor_thread() const { return signaling_thread_; } \
470 \
oprypin803dc292017-02-01 01:55:59 -0800471 public: // NOLINTNEXTLINE
deadbeefd99a2002017-01-18 08:55:23 -0800472
473#define PROXY_WORKER_THREAD_DESTRUCTOR() \
474 private: \
475 rtc::Thread* destructor_thread() const { return worker_thread_; } \
476 \
oprypin803dc292017-02-01 01:55:59 -0800477 public: // NOLINTNEXTLINE
deadbeefd99a2002017-01-18 08:55:23 -0800478
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700479#define PROXY_METHOD0(r, method) \
480 r method() override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800481 MethodCall0<C, r> call(c_, &C::method); \
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700482 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000483 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000484
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700485#define PROXY_CONSTMETHOD0(r, method) \
486 r method() const override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800487 ConstMethodCall0<C, r> call(c_, &C::method); \
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700488 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000489 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000490
deadbeefe814a0d2017-02-25 18:15:09 -0800491#define PROXY_METHOD1(r, method, t1) \
492 r method(t1 a1) override { \
493 MethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
494 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000495 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000496
deadbeefe814a0d2017-02-25 18:15:09 -0800497#define PROXY_CONSTMETHOD1(r, method, t1) \
498 r method(t1 a1) const override { \
499 ConstMethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
500 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000501 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000502
deadbeefe814a0d2017-02-25 18:15:09 -0800503#define PROXY_METHOD2(r, method, t1, t2) \
504 r method(t1 a1, t2 a2) override { \
505 MethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
506 std::move(a2)); \
507 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000508 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000509
deadbeefe814a0d2017-02-25 18:15:09 -0800510#define PROXY_METHOD3(r, method, t1, t2, t3) \
511 r method(t1 a1, t2 a2, t3 a3) override { \
512 MethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
513 std::move(a2), std::move(a3)); \
514 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800515 }
516
517#define PROXY_METHOD4(r, method, t1, t2, t3, t4) \
518 r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800519 MethodCall4<C, r, t1, t2, t3, t4> call(c_, &C::method, std::move(a1), \
520 std::move(a2), std::move(a3), \
521 std::move(a4)); \
deadbeefd99a2002017-01-18 08:55:23 -0800522 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
523 }
524
deadbeefe814a0d2017-02-25 18:15:09 -0800525#define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \
526 r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \
527 MethodCall5<C, r, t1, t2, t3, t4, t5> call(c_, &C::method, std::move(a1), \
528 std::move(a2), std::move(a3), \
529 std::move(a4), std::move(a5)); \
530 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
nisse5b68ab52016-04-07 07:45:54 -0700531 }
532
533// Define methods which should be invoked on the worker thread.
deadbeefd99a2002017-01-18 08:55:23 -0800534#define PROXY_WORKER_METHOD0(r, method) \
535 r method() override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800536 MethodCall0<C, r> call(c_, &C::method); \
deadbeefd99a2002017-01-18 08:55:23 -0800537 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
nisse5b68ab52016-04-07 07:45:54 -0700538 }
539
deadbeefd99a2002017-01-18 08:55:23 -0800540#define PROXY_WORKER_CONSTMETHOD0(r, method) \
541 r method() const override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800542 ConstMethodCall0<C, r> call(c_, &C::method); \
deadbeefd99a2002017-01-18 08:55:23 -0800543 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000544 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000545
deadbeefe814a0d2017-02-25 18:15:09 -0800546#define PROXY_WORKER_METHOD1(r, method, t1) \
547 r method(t1 a1) override { \
548 MethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
549 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800550 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000551
deadbeefe814a0d2017-02-25 18:15:09 -0800552#define PROXY_WORKER_CONSTMETHOD1(r, method, t1) \
553 r method(t1 a1) const override { \
554 ConstMethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
555 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800556 }
557
deadbeefe814a0d2017-02-25 18:15:09 -0800558#define PROXY_WORKER_METHOD2(r, method, t1, t2) \
559 r method(t1 a1, t2 a2) override { \
560 MethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
561 std::move(a2)); \
562 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800563 }
564
deadbeefe814a0d2017-02-25 18:15:09 -0800565#define PROXY_WORKER_CONSTMETHOD2(r, method, t1, t2) \
566 r method(t1 a1, t2 a2) const override { \
567 ConstMethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
568 std::move(a2)); \
569 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
570 }
571
572#define PROXY_WORKER_METHOD3(r, method, t1, t2, t3) \
573 r method(t1 a1, t2 a2, t3 a3) override { \
574 MethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
575 std::move(a2), std::move(a3)); \
576 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
577 }
578
579#define PROXY_WORKER_CONSTMETHOD3(r, method, t1, t2) \
580 r method(t1 a1, t2 a2, t3 a3) const override { \
581 ConstMethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
582 std::move(a2), std::move(a3)); \
583 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800584 }
585
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000586} // namespace webrtc
587
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200588#endif // API_PROXY_H_