blob: 862de876557155da1d22da1824223b94a68e3600 [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()) {
deadbeef8d60a942017-02-27 14:47:33 -0800131 proxy_->OnMessage(nullptr);
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000132 } 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:
deadbeef8d60a942017-02-27 14:47:33 -0800140 void OnMessage(rtc::Message*) {
141 proxy_->OnMessage(nullptr);
142 e_->Set();
143 }
kwibergd1fe2812016-04-27 06:47:29 -0700144 std::unique_ptr<rtc::Event> e_;
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000145 rtc::MessageHandler* proxy_;
146};
147
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000148} // namespace internal
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000149
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000151class MethodCall0 : public rtc::Message,
152 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153 public:
154 typedef R (C::*Method)();
155 MethodCall0(C* c, Method m) : c_(c), m_(m) {}
156
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700157 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
158 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800159 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160 }
161
162 private:
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000163 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000164
165 C* c_;
166 Method m_;
167 ReturnType<R> r_;
168};
169
170template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000171class ConstMethodCall0 : public rtc::Message,
172 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
190template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000191class MethodCall1 : public rtc::Message,
192 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193 public:
194 typedef R (C::*Method)(T1 a1);
deadbeefd99a2002017-01-18 08:55:23 -0800195 MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(std::move(a1)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000196
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700197 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
198 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800199 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000200 }
201
202 private:
deadbeefd99a2002017-01-18 08:55:23 -0800203 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, std::move(a1_)); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204
205 C* c_;
206 Method m_;
207 ReturnType<R> r_;
208 T1 a1_;
209};
210
211template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000212class ConstMethodCall1 : public rtc::Message,
213 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214 public:
215 typedef R (C::*Method)(T1 a1) const;
deadbeefd99a2002017-01-18 08:55:23 -0800216 ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(std::move(a1)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000217
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700218 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
219 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800220 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000221 }
222
223 private:
deadbeefd99a2002017-01-18 08:55:23 -0800224 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, std::move(a1_)); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000225
226 C* c_;
227 Method m_;
228 ReturnType<R> r_;
229 T1 a1_;
230};
231
232template <typename C, typename R, typename T1, typename T2>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000233class MethodCall2 : public rtc::Message,
234 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 public:
236 typedef R (C::*Method)(T1 a1, T2 a2);
deadbeefd99a2002017-01-18 08:55:23 -0800237 MethodCall2(C* c, Method m, T1 a1, T2 a2)
238 : c_(c), m_(m), a1_(std::move(a1)), a2_(std::move(a2)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700240 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
241 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800242 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243 }
244
245 private:
deadbeefd99a2002017-01-18 08:55:23 -0800246 void OnMessage(rtc::Message*) {
247 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_));
248 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249
250 C* c_;
251 Method m_;
252 ReturnType<R> r_;
253 T1 a1_;
254 T2 a2_;
255};
256
257template <typename C, typename R, typename T1, typename T2, typename T3>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000258class MethodCall3 : public rtc::Message,
259 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260 public:
261 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3);
262 MethodCall3(C* c, Method m, T1 a1, T2 a2, T3 a3)
deadbeefd99a2002017-01-18 08:55:23 -0800263 : c_(c),
264 m_(m),
265 a1_(std::move(a1)),
266 a2_(std::move(a2)),
267 a3_(std::move(a3)) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700269 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
270 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800271 return r_.moved_result();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 }
273
274 private:
deadbeefd99a2002017-01-18 08:55:23 -0800275 void OnMessage(rtc::Message*) {
276 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_));
277 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278
279 C* c_;
280 Method m_;
281 ReturnType<R> r_;
282 T1 a1_;
283 T2 a2_;
284 T3 a3_;
285};
286
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000287template <typename C, typename R, typename T1, typename T2, typename T3,
288 typename T4>
289class MethodCall4 : public rtc::Message,
290 public rtc::MessageHandler {
291 public:
292 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4);
293 MethodCall4(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4)
deadbeefd99a2002017-01-18 08:55:23 -0800294 : c_(c),
295 m_(m),
296 a1_(std::move(a1)),
297 a2_(std::move(a2)),
298 a3_(std::move(a3)),
299 a4_(std::move(a4)) {}
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000300
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700301 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
302 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800303 return r_.moved_result();
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000304 }
305
306 private:
deadbeefd99a2002017-01-18 08:55:23 -0800307 void OnMessage(rtc::Message*) {
308 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_),
309 std::move(a4_));
310 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000311
312 C* c_;
313 Method m_;
314 ReturnType<R> r_;
315 T1 a1_;
316 T2 a2_;
317 T3 a3_;
318 T4 a4_;
319};
320
321template <typename C, typename R, typename T1, typename T2, typename T3,
322 typename T4, typename T5>
323class MethodCall5 : public rtc::Message,
324 public rtc::MessageHandler {
325 public:
326 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
327 MethodCall5(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
deadbeefd99a2002017-01-18 08:55:23 -0800328 : c_(c),
329 m_(m),
330 a1_(std::move(a1)),
331 a2_(std::move(a2)),
332 a3_(std::move(a3)),
333 a4_(std::move(a4)),
334 a5_(std::move(a5)) {}
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000335
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700336 R Marshal(const rtc::Location& posted_from, rtc::Thread* t) {
337 internal::SynchronousMethodCall(this).Invoke(posted_from, t);
deadbeefd99a2002017-01-18 08:55:23 -0800338 return r_.moved_result();
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000339 }
340
341 private:
deadbeefd99a2002017-01-18 08:55:23 -0800342 void OnMessage(rtc::Message*) {
343 r_.Invoke(c_, m_, std::move(a1_), std::move(a2_), std::move(a3_),
344 std::move(a4_), std::move(a5_));
345 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000346
347 C* c_;
348 Method m_;
349 ReturnType<R> r_;
350 T1 a1_;
351 T2 a2_;
352 T3 a3_;
353 T4 a4_;
354 T5 a5_;
355};
356
oprypin803dc292017-02-01 01:55:59 -0800357
deadbeefd99a2002017-01-18 08:55:23 -0800358// Helper macros to reduce code duplication.
deadbeefe814a0d2017-02-25 18:15:09 -0800359#define PROXY_MAP_BOILERPLATE(c) \
360 template <class INTERNAL_CLASS> \
361 class c##ProxyWithInternal; \
362 typedef c##ProxyWithInternal<c##Interface> c##Proxy; \
363 template <class INTERNAL_CLASS> \
364 class c##ProxyWithInternal : public c##Interface { \
365 protected: \
366 typedef c##Interface C; \
367 \
368 public: \
369 const INTERNAL_CLASS* internal() const { return c_; } \
370 INTERNAL_CLASS* internal() { return c_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000371
oprypin803dc292017-02-01 01:55:59 -0800372#define END_PROXY_MAP() \
373 };
374
deadbeefd99a2002017-01-18 08:55:23 -0800375#define SIGNALING_PROXY_MAP_BOILERPLATE(c) \
376 protected: \
377 c##ProxyWithInternal(rtc::Thread* signaling_thread, INTERNAL_CLASS* c) \
378 : signaling_thread_(signaling_thread), c_(c) {} \
379 \
380 private: \
381 mutable rtc::Thread* signaling_thread_;
382
383#define WORKER_PROXY_MAP_BOILERPLATE(c) \
384 protected: \
385 c##ProxyWithInternal(rtc::Thread* signaling_thread, \
386 rtc::Thread* worker_thread, INTERNAL_CLASS* c) \
387 : signaling_thread_(signaling_thread), \
388 worker_thread_(worker_thread), \
389 c_(c) {} \
390 \
391 private: \
392 mutable rtc::Thread* signaling_thread_; \
393 mutable rtc::Thread* worker_thread_;
394
395// Note that the destructor is protected so that the proxy can only be
396// destroyed via RefCountInterface.
397#define REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
398 protected: \
399 ~c##ProxyWithInternal() { \
400 MethodCall0<c##ProxyWithInternal, void> call( \
401 this, &c##ProxyWithInternal::DestroyInternal); \
402 call.Marshal(RTC_FROM_HERE, destructor_thread()); \
403 } \
404 \
405 private: \
406 void DestroyInternal() { c_ = nullptr; } \
407 rtc::scoped_refptr<INTERNAL_CLASS> c_;
408
deadbeefe814a0d2017-02-25 18:15:09 -0800409// Note: This doesn't use a unique_ptr, because it intends to handle a corner
410// case where an object's deletion triggers a callback that calls back into
411// this proxy object. If relying on a unique_ptr to delete the object, its
412// inner pointer would be set to null before this reentrant callback would have
413// a chance to run, resulting in a segfault.
deadbeefd99a2002017-01-18 08:55:23 -0800414#define OWNED_PROXY_MAP_BOILERPLATE(c) \
415 public: \
416 ~c##ProxyWithInternal() { \
417 MethodCall0<c##ProxyWithInternal, void> call( \
418 this, &c##ProxyWithInternal::DestroyInternal); \
419 call.Marshal(RTC_FROM_HERE, destructor_thread()); \
420 } \
421 \
422 private: \
deadbeefe814a0d2017-02-25 18:15:09 -0800423 void DestroyInternal() { delete c_; } \
424 INTERNAL_CLASS* c_;
deadbeefd99a2002017-01-18 08:55:23 -0800425
426#define BEGIN_SIGNALING_PROXY_MAP(c) \
427 PROXY_MAP_BOILERPLATE(c) \
428 SIGNALING_PROXY_MAP_BOILERPLATE(c) \
429 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
430 public: \
431 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \
432 rtc::Thread* signaling_thread, INTERNAL_CLASS* c) { \
433 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \
434 c); \
435 }
436
437#define BEGIN_PROXY_MAP(c) \
438 PROXY_MAP_BOILERPLATE(c) \
439 WORKER_PROXY_MAP_BOILERPLATE(c) \
440 REFCOUNTED_PROXY_MAP_BOILERPLATE(c) \
441 public: \
442 static rtc::scoped_refptr<c##ProxyWithInternal> Create( \
443 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \
444 INTERNAL_CLASS* c) { \
445 return new rtc::RefCountedObject<c##ProxyWithInternal>(signaling_thread, \
446 worker_thread, c); \
447 }
448
deadbeefe814a0d2017-02-25 18:15:09 -0800449#define BEGIN_OWNED_PROXY_MAP(c) \
450 PROXY_MAP_BOILERPLATE(c) \
451 WORKER_PROXY_MAP_BOILERPLATE(c) \
452 OWNED_PROXY_MAP_BOILERPLATE(c) \
453 public: \
454 static std::unique_ptr<c##Interface> Create( \
455 rtc::Thread* signaling_thread, rtc::Thread* worker_thread, \
456 std::unique_ptr<INTERNAL_CLASS> c) { \
457 return std::unique_ptr<c##Interface>(new c##ProxyWithInternal( \
458 signaling_thread, worker_thread, c.release())); \
deadbeefd99a2002017-01-18 08:55:23 -0800459 }
460
461#define PROXY_SIGNALING_THREAD_DESTRUCTOR() \
462 private: \
463 rtc::Thread* destructor_thread() const { return signaling_thread_; } \
464 \
oprypin803dc292017-02-01 01:55:59 -0800465 public: // NOLINTNEXTLINE
deadbeefd99a2002017-01-18 08:55:23 -0800466
467#define PROXY_WORKER_THREAD_DESTRUCTOR() \
468 private: \
469 rtc::Thread* destructor_thread() const { return worker_thread_; } \
470 \
oprypin803dc292017-02-01 01:55:59 -0800471 public: // NOLINTNEXTLINE
deadbeefd99a2002017-01-18 08:55:23 -0800472
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700473#define PROXY_METHOD0(r, method) \
474 r method() override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800475 MethodCall0<C, r> call(c_, &C::method); \
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700476 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000477 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000478
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700479#define PROXY_CONSTMETHOD0(r, method) \
480 r method() const override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800481 ConstMethodCall0<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
deadbeefe814a0d2017-02-25 18:15:09 -0800485#define PROXY_METHOD1(r, method, t1) \
486 r method(t1 a1) override { \
487 MethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
488 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_CONSTMETHOD1(r, method, t1) \
492 r method(t1 a1) const override { \
493 ConstMethodCall1<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_METHOD2(r, method, t1, t2) \
498 r method(t1 a1, t2 a2) override { \
499 MethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
500 std::move(a2)); \
501 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000502 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000503
deadbeefe814a0d2017-02-25 18:15:09 -0800504#define PROXY_METHOD3(r, method, t1, t2, t3) \
505 r method(t1 a1, t2 a2, t3 a3) override { \
506 MethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
507 std::move(a2), std::move(a3)); \
508 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800509 }
510
511#define PROXY_METHOD4(r, method, t1, t2, t3, t4) \
512 r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800513 MethodCall4<C, r, t1, t2, t3, t4> call(c_, &C::method, std::move(a1), \
514 std::move(a2), std::move(a3), \
515 std::move(a4)); \
deadbeefd99a2002017-01-18 08:55:23 -0800516 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
517 }
518
deadbeefe814a0d2017-02-25 18:15:09 -0800519#define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \
520 r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \
521 MethodCall5<C, r, t1, t2, t3, t4, t5> call(c_, &C::method, std::move(a1), \
522 std::move(a2), std::move(a3), \
523 std::move(a4), std::move(a5)); \
524 return call.Marshal(RTC_FROM_HERE, signaling_thread_); \
nisse5b68ab52016-04-07 07:45:54 -0700525 }
526
527// Define methods which should be invoked on the worker thread.
deadbeefd99a2002017-01-18 08:55:23 -0800528#define PROXY_WORKER_METHOD0(r, method) \
529 r method() override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800530 MethodCall0<C, r> call(c_, &C::method); \
deadbeefd99a2002017-01-18 08:55:23 -0800531 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
nisse5b68ab52016-04-07 07:45:54 -0700532 }
533
deadbeefd99a2002017-01-18 08:55:23 -0800534#define PROXY_WORKER_CONSTMETHOD0(r, method) \
535 r method() const override { \
deadbeefe814a0d2017-02-25 18:15:09 -0800536 ConstMethodCall0<C, r> call(c_, &C::method); \
deadbeefd99a2002017-01-18 08:55:23 -0800537 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000538 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000539
deadbeefe814a0d2017-02-25 18:15:09 -0800540#define PROXY_WORKER_METHOD1(r, method, t1) \
541 r method(t1 a1) override { \
542 MethodCall1<C, r, t1> call(c_, &C::method, std::move(a1)); \
543 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800544 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000545
deadbeefe814a0d2017-02-25 18:15:09 -0800546#define PROXY_WORKER_CONSTMETHOD1(r, method, t1) \
547 r method(t1 a1) const override { \
548 ConstMethodCall1<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 }
551
deadbeefe814a0d2017-02-25 18:15:09 -0800552#define PROXY_WORKER_METHOD2(r, method, t1, t2) \
553 r method(t1 a1, t2 a2) override { \
554 MethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
555 std::move(a2)); \
556 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800557 }
558
deadbeefe814a0d2017-02-25 18:15:09 -0800559#define PROXY_WORKER_CONSTMETHOD2(r, method, t1, t2) \
560 r method(t1 a1, t2 a2) const override { \
561 ConstMethodCall2<C, r, t1, t2> call(c_, &C::method, std::move(a1), \
562 std::move(a2)); \
563 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
564 }
565
566#define PROXY_WORKER_METHOD3(r, method, t1, t2, t3) \
567 r method(t1 a1, t2 a2, t3 a3) override { \
568 MethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
569 std::move(a2), std::move(a3)); \
570 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
571 }
572
573#define PROXY_WORKER_CONSTMETHOD3(r, method, t1, t2) \
574 r method(t1 a1, t2 a2, t3 a3) const override { \
575 ConstMethodCall3<C, r, t1, t2, t3> call(c_, &C::method, std::move(a1), \
576 std::move(a2), std::move(a3)); \
577 return call.Marshal(RTC_FROM_HERE, worker_thread_); \
deadbeefd99a2002017-01-18 08:55:23 -0800578 }
579
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000580} // namespace webrtc
581
Henrik Kjellander15583c12016-02-10 10:53:12 +0100582#endif // WEBRTC_API_PROXY_H_