blob: 46c424d927ffb868d4a67f9c0b0a0eca40019127 [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
Henrik Kjellander15583c12016-02-10 10:53:12 +010052#ifndef WEBRTC_API_PROXY_H_
53#define WEBRTC_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
tommi@webrtc.org18de6f92014-11-04 12:08:48 +000058#include "webrtc/base/event.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000059#include "webrtc/base/thread.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060
61namespace webrtc {
62
63template <typename R>
64class ReturnType {
65 public:
66 template<typename C, typename M>
67 void Invoke(C* c, M m) { r_ = (c->*m)(); }
deadbeefd99a2002017-01-18 08:55:23 -080068 template <typename C, typename M, typename T1>
69 void Invoke(C* c, M m, T1 a1) {
70 r_ = (c->*m)(std::move(a1));
71 }
72 template <typename C, typename M, typename T1, typename T2>
73 void Invoke(C* c, M m, T1 a1, T2 a2) {
74 r_ = (c->*m)(std::move(a1), std::move(a2));
75 }
76 template <typename C, typename M, typename T1, typename T2, typename T3>
77 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) {
78 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3));
79 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000080 template<typename C, typename M, typename T1, typename T2, typename T3,
81 typename T4>
82 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4) {
deadbeefd99a2002017-01-18 08:55:23 -080083 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3), std::move(a4));
perkj@webrtc.org81134d02015-01-12 08:30:16 +000084 }
85 template<typename C, typename M, typename T1, typename T2, typename T3,
86 typename T4, typename T5>
87 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
deadbeefd99a2002017-01-18 08:55:23 -080088 r_ = (c->*m)(std::move(a1), std::move(a2), std::move(a3), std::move(a4),
89 std::move(a5));
perkj@webrtc.org81134d02015-01-12 08:30:16 +000090 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091
deadbeefd99a2002017-01-18 08:55:23 -080092 R moved_result() { return std::move(r_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000093
94 private:
95 R r_;
96};
97
98template <>
99class ReturnType<void> {
100 public:
101 template<typename C, typename M>
102 void Invoke(C* c, M m) { (c->*m)(); }
deadbeefd99a2002017-01-18 08:55:23 -0800103 template <typename C, typename M, typename T1>
104 void Invoke(C* c, M m, T1 a1) {
105 (c->*m)(std::move(a1));
106 }
107 template <typename C, typename M, typename T1, typename T2>
108 void Invoke(C* c, M m, T1 a1, T2 a2) {
109 (c->*m)(std::move(a1), std::move(a2));
110 }
111 template <typename C, typename M, typename T1, typename T2, typename T3>
112 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) {
113 (c->*m)(std::move(a1), std::move(a2), std::move(a3));
114 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000115
deadbeefd99a2002017-01-18 08:55:23 -0800116 void moved_result() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117};
118
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000119namespace internal {
120
121class SynchronousMethodCall
122 : public rtc::MessageData,
123 public rtc::MessageHandler {
124 public:
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000125 explicit SynchronousMethodCall(rtc::MessageHandler* proxy)
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000126 : e_(), proxy_(proxy) {}
127 ~SynchronousMethodCall() {}
128
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700129 void Invoke(const rtc::Location& posted_from, rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000130 if (t->IsCurrent()) {
131 proxy_->OnMessage(NULL);
132 } else {
133 e_.reset(new rtc::Event(false, false));
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700134 t->Post(posted_from, this, 0);
andresp@webrtc.org53d90122015-02-09 14:19:09 +0000135 e_->Wait(rtc::Event::kForever);
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000136 }
137 }
138
139 private:
140 void OnMessage(rtc::Message*) { proxy_->OnMessage(NULL); e_->Set(); }
kwibergd1fe2812016-04-27 06:47:29 -0700141 std::unique_ptr<rtc::Event> e_;
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000142 rtc::MessageHandler* proxy_;
143};
144
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000145} // namespace internal
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000146
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000147template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000148class MethodCall0 : public rtc::Message,
149 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150 public:
151 typedef R (C::*Method)();
152 MethodCall0(C* c, Method m) : c_(c), m_(m) {}
153
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700154 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
155 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800156 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157 }
158
159 private:
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000160 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161
162 C* c_;
163 Method m_;
164 ReturnType<R> r_;
165};
166
167template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000168class ConstMethodCall0 : public rtc::Message,
169 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000170 public:
171 typedef R (C::*Method)() const;
172 ConstMethodCall0(C* c, Method m) : c_(c), m_(m) {}
173
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700174 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
175 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800176 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000177 }
178
179 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000180 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181
182 C* c_;
183 Method m_;
184 ReturnType<R> r_;
185};
186
187template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000188class MethodCall1 : public rtc::Message,
189 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 public:
191 typedef R (C::*Method)(T1 a1);
deadbeefd99a2002017-01-18 08:55:23 -0800192 MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(std::move(a1)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700194 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
195 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800196 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000197 }
198
199 private:
deadbeefd99a2002017-01-18 08:55:23 -0800200 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, std::move(a1_)); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201
202 C* c_;
203 Method m_;
204 ReturnType<R> r_;
205 T1 a1_;
206};
207
208template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000209class ConstMethodCall1 : public rtc::Message,
210 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211 public:
212 typedef R (C::*Method)(T1 a1) const;
deadbeefd99a2002017-01-18 08:55:23 -0800213 ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(std::move(a1)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700215 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
216 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800217 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218 }
219
220 private:
deadbeefd99a2002017-01-18 08:55:23 -0800221 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, std::move(a1_)); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222
223 C* c_;
224 Method m_;
225 ReturnType<R> r_;
226 T1 a1_;
227};
228
229template <typename C, typename R, typename T1, typename T2>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000230class MethodCall2 : public rtc::Message,
231 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>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000255class MethodCall3 : public rtc::Message,
256 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 public:
258 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3);
259 MethodCall3(C* c, Method m, T1 a1, T2 a2, T3 a3)
deadbeefd99a2002017-01-18 08:55:23 -0800260 : c_(c),
261 m_(m),
262 a1_(std::move(a1)),
263 a2_(std::move(a2)),
264 a3_(std::move(a3)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000265
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700266 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
267 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800268 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269 }
270
271 private:
deadbeefd99a2002017-01-18 08:55:23 -0800272 void OnMessage(rtc::Message*) {
273 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_));
274 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000275
276 C* c_;
277 Method m_;
278 ReturnType<R> r_;
279 T1 a1_;
280 T2 a2_;
281 T3 a3_;
282};
283
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000284template <typename C, typename R, typename T1, typename T2, typename T3,
285 typename T4>
286class MethodCall4 : public rtc::Message,
287 public rtc::MessageHandler {
288 public:
289 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4);
290 MethodCall4(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4)
deadbeefd99a2002017-01-18 08:55:23 -0800291 : c_(c),
292 m_(m),
293 a1_(std::move(a1)),
294 a2_(std::move(a2)),
295 a3_(std::move(a3)),
296 a4_(std::move(a4)) {}
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000297
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700298 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
299 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800300 return r_.moved_result();
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000301 }
302
303 private:
deadbeefd99a2002017-01-18 08:55:23 -0800304 void OnMessage(rtc::Message*) {
305 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_),
306 std::move(a4_));
307 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000308
309 C* c_;
310 Method m_;
311 ReturnType<R> r_;
312 T1 a1_;
313 T2 a2_;
314 T3 a3_;
315 T4 a4_;
316};
317
318template <typename C, typename R, typename T1, typename T2, typename T3,
319 typename T4, typename T5>
320class MethodCall5 : public rtc::Message,
321 public rtc::MessageHandler {
322 public:
323 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
324 MethodCall5(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
deadbeefd99a2002017-01-18 08:55:23 -0800325 : c_(c),
326 m_(m),
327 a1_(std::move(a1)),
328 a2_(std::move(a2)),
329 a3_(std::move(a3)),
330 a4_(std::move(a4)),
331 a5_(std::move(a5)) {}
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000332
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700333 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
334 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800335 return r_.moved_result();
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000336 }
337
338 private:
deadbeefd99a2002017-01-18 08:55:23 -0800339 void OnMessage(rtc::Message*) {
340 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_),
341 std::move(a4_), std::move(a5_));
342 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000343
344 C* c_;
345 Method m_;
346 ReturnType<R> r_;
347 T1 a1_;
348 T2 a2_;
349 T3 a3_;
350 T4 a4_;
351 T5 a5_;
352};
353
oprypin803dc292017-02-01 01:55:59 -0800354
deadbeefd99a2002017-01-18 08:55:23 -0800355// Helper macros to reduce code duplication.
deadbeefe814a0d2017-02-25 18:15:09 -0800356#define PROXY_MAP_BOILERPLATE(c) \
357 template <class INTERNAL_CLASS> \
358 class c##ProxyWithInternal; \
359 typedef c##ProxyWithInternal<c##Interface> c##Proxy; \
360 template <class INTERNAL_CLASS> \
361 class c##ProxyWithInternal : public c##Interface { \
362 protected: \
363 typedef c##Interface C; \
364 \
365 public: \
366 const INTERNAL_CLASS* internal() const { return c_; } \
367 INTERNAL_CLASS* internal() { return c_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000368
oprypin803dc292017-02-01 01:55:59 -0800369#define END_PROXY_MAP() \
370 };
371
deadbeefd99a2002017-01-18 08:55:23 -0800372#define SIGNALING_PROXY_MAP_BOILERPLATE(c) \
373 protected: \
374 c##ProxyWithInternal(rtc::Thread* signaling_thread, INTERNAL_CLASS* c) \
375 : signaling_thread_(signaling_thread), c_(c) {} \
376 \
377 private: \
378 mutable rtc::Thread* signaling_thread_;
379
380#define WORKER_PROXY_MAP_BOILERPLATE(c) \
381 protected: \
382 c##ProxyWithInternal(rtc::Thread* signaling_thread, \
383 rtc::Thread* worker_thread, INTERNAL_CLASS* c) \
384 : signaling_thread_(signaling_thread), \
385 worker_thread_(worker_thread), \
386 c_(c) {} \
387 \
388 private: \
389 mutable rtc::Thread* signaling_thread_; \
390 mutable rtc::Thread* worker_thread_;
391
392// Note that the destructor is protected so that the proxy can only be
393// destroyed via RefCountInterface.
394#define REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
395 protected: \
396 ~c##ProxyWithInternal() { \
397 MethodCall0<c##ProxyWithInternal, void> call( \
398 this, &c##ProxyWithInternal::DestroyInternal); \
399 call.Marshal(RTC_FROM_HERE, destructor_thread()); \
400 } \
401 \
402 private: \
403 void DestroyInternal() { c_ = nullptr; } \
404 rtc::scoped_refptr<INTERNAL_CLASS> c_;
405
deadbeefe814a0d2017-02-25 18:15:09 -0800406// Note: This doesn't use a unique_ptr, because it intends to handle a corner
407// case where an object's deletion triggers a callback that calls back into
408// this proxy object. If relying on a unique_ptr to delete the object, its
409// inner pointer would be set to null before this reentrant callback would have
410// a chance to run, resulting in a segfault.
deadbeefd99a2002017-01-18 08:55:23 -0800411#define OWNED_PROXY_MAP_BOILERPLATE(c) \
412 public: \
413 ~c##ProxyWithInternal() { \
414 MethodCall0<c##ProxyWithInternal, void> call( \
415 this, &c##ProxyWithInternal::DestroyInternal); \
416 call.Marshal(RTC_FROM_HERE, destructor_thread()); \
417 } \
418 \
419 private: \
deadbeefe814a0d2017-02-25 18:15:09 -0800420 void DestroyInternal() { delete c_; } \
421 INTERNAL_CLASS* c_;
deadbeefd99a2002017-01-18 08:55:23 -0800422
423#define BEGIN_SIGNALING_PROXY_MAP(c) \
424 PROXY_MAP_BOILERPLATE(c) \
425 SIGNALING_PROXY_MAP_BOILERPLATE(c) \
426 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
427 public: \
428 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \
429 rtc::Thread* signaling_thread, INTERNAL_CLASS* c) { \
430 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \
431 c); \
432 }
433
434#define BEGIN_PROXY_MAP(c) \
435 PROXY_MAP_BOILERPLATE(c) \
436 WORKER_PROXY_MAP_BOILERPLATE(c) \
437 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
438 public: \
439 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \
440 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \
441 INTERNAL_CLASS* c) { \
442 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \
443 worker_thread, c); \
444 }
445
deadbeefe814a0d2017-02-25 18:15:09 -0800446#define BEGIN_OWNED_PROXY_MAP(c) \
447 PROXY_MAP_BOILERPLATE(c) \
448 WORKER_PROXY_MAP_BOILERPLATE(c) \
449 OWNED_PROXY_MAP_BOILERPLATE(c) \
450 public: \
451 static std::unique_ptr<c##Interface> Create( \
452 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \
453 std::unique_ptr<INTERNAL_CLASS> c) { \
454 return std::unique_ptr<c##Interface>(new c##ProxyWithInternal( \
455 signaling_thread, worker_thread, c.release())); \
deadbeefd99a2002017-01-18 08:55:23 -0800456 }
457
458#define PROXY_SIGNALING_THREAD_DESTRUCTOR() \
459 private: \
460 rtc::Thread* destructor_thread() const { return signaling_thread_; } \
461 \
oprypin803dc292017-02-01 01:55:59 -0800462 public: // NOLINTNEXTLINE
deadbeefd99a2002017-01-18 08:55:23 -0800463
464#define PROXY_WORKER_THREAD_DESTRUCTOR() \
465 private: \
466 rtc::Thread* destructor_thread() const { return worker_thread_; } \
467 \
oprypin803dc292017-02-01 01:55:59 -0800468 public: // NOLINTNEXTLINE
deadbeefd99a2002017-01-18 08:55:23 -0800469
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700470#define PROXY_METHOD0(r, method) \
471 r method() override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800472 MethodCall0<C, r> call(c_, &C::method); \
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700473 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000474 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000475
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700476#define PROXY_CONSTMETHOD0(r, method) \
477 r method() const override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800478 ConstMethodCall0<C, r> call(c_, &C::method); \
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700479 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000480 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000481
deadbeefe814a0d2017-02-25 18:15:09 -0800482#define PROXY_METHOD1(r, method, t1) \
483 r method(t1 a1) override { \
484 MethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
485 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000486 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000487
deadbeefe814a0d2017-02-25 18:15:09 -0800488#define PROXY_CONSTMETHOD1(r, method, t1) \
489 r method(t1 a1) const override { \
490 ConstMethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
491 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000492 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000493
deadbeefe814a0d2017-02-25 18:15:09 -0800494#define PROXY_METHOD2(r, method, t1, t2) \
495 r method(t1 a1, t2 a2) override { \
496 MethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
497 std::move(a2)); \
498 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000499 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000500
deadbeefe814a0d2017-02-25 18:15:09 -0800501#define PROXY_METHOD3(r, method, t1, t2, t3) \
502 r method(t1 a1, t2 a2, t3 a3) override { \
503 MethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
504 std::move(a2), std::move(a3)); \
505 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800506 }
507
508#define PROXY_METHOD4(r, method, t1, t2, t3, t4) \
509 r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800510 MethodCall4<C, r, t1, t2, t3, t4> call(c_, &C::method, std::move(a1), \
511 std::move(a2), std::move(a3), \
512 std::move(a4)); \
deadbeefd99a2002017-01-18 08:55:23 -0800513 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
514 }
515
deadbeefe814a0d2017-02-25 18:15:09 -0800516#define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \
517 r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \
518 MethodCall5<C, r, t1, t2, t3, t4, t5> call(c_, &C::method, std::move(a1), \
519 std::move(a2), std::move(a3), \
520 std::move(a4), std::move(a5)); \
521 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
nisse5b68ab52016-04-07 07:45:54 -0700522 }
523
524// Define methods which should be invoked on the worker thread.
deadbeefd99a2002017-01-18 08:55:23 -0800525#define PROXY_WORKER_METHOD0(r, method) \
526 r method() override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800527 MethodCall0<C, r> call(c_, &C::method); \
deadbeefd99a2002017-01-18 08:55:23 -0800528 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
nisse5b68ab52016-04-07 07:45:54 -0700529 }
530
deadbeefd99a2002017-01-18 08:55:23 -0800531#define PROXY_WORKER_CONSTMETHOD0(r, method) \
532 r method() const override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800533 ConstMethodCall0<C, r> call(c_, &C::method); \
deadbeefd99a2002017-01-18 08:55:23 -0800534 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000535 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000536
deadbeefe814a0d2017-02-25 18:15:09 -0800537#define PROXY_WORKER_METHOD1(r, method, t1) \
538 r method(t1 a1) override { \
539 MethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
540 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800541 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000542
deadbeefe814a0d2017-02-25 18:15:09 -0800543#define PROXY_WORKER_CONSTMETHOD1(r, method, t1) \
544 r method(t1 a1) const override { \
545 ConstMethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
546 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800547 }
548
deadbeefe814a0d2017-02-25 18:15:09 -0800549#define PROXY_WORKER_METHOD2(r, method, t1, t2) \
550 r method(t1 a1, t2 a2) override { \
551 MethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
552 std::move(a2)); \
553 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800554 }
555
deadbeefe814a0d2017-02-25 18:15:09 -0800556#define PROXY_WORKER_CONSTMETHOD2(r, method, t1, t2) \
557 r method(t1 a1, t2 a2) const override { \
558 ConstMethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
559 std::move(a2)); \
560 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
561 }
562
563#define PROXY_WORKER_METHOD3(r, method, t1, t2, t3) \
564 r method(t1 a1, t2 a2, t3 a3) override { \
565 MethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
566 std::move(a2), std::move(a3)); \
567 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
568 }
569
570#define PROXY_WORKER_CONSTMETHOD3(r, method, t1, t2) \
571 r method(t1 a1, t2 a2, t3 a3) const override { \
572 ConstMethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
573 std::move(a2), std::move(a3)); \
574 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800575 }
576
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577} // namespace webrtc
578
Henrik Kjellander15583c12016-02-10 10:53:12 +0100579#endif // WEBRTC_API_PROXY_H_