blob: 1351a0427e6b4077f034bbc593b5626d9b16bb33 [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.
13
14//
15// Example usage:
16//
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000017// class TestInterface : public rtc::RefCountInterface {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000018// public:
19// std::string FooA() = 0;
20// std::string FooB(bool arg1) const = 0;
21// std::string FooC(bool arg1)= 0;
22// };
23//
24// Note that return types can not be a const reference.
25//
26// class Test : public TestInterface {
27// ... implementation of the interface.
28// };
29//
30// BEGIN_PROXY_MAP(Test)
31// PROXY_METHOD0(std::string, FooA)
32// PROXY_CONSTMETHOD1(std::string, FooB, arg1)
33// PROXY_METHOD1(std::string, FooC, arg1)
34// END_PROXY()
35//
36// The proxy can be created using TestProxy::Create(Thread*, TestInterface*).
37
Henrik Kjellander15583c12016-02-10 10:53:12 +010038#ifndef WEBRTC_API_PROXY_H_
39#define WEBRTC_API_PROXY_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040
tommi@webrtc.org18de6f92014-11-04 12:08:48 +000041#include "webrtc/base/event.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000042#include "webrtc/base/thread.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043
44namespace webrtc {
45
46template <typename R>
47class ReturnType {
48 public:
49 template<typename C, typename M>
50 void Invoke(C* c, M m) { r_ = (c->*m)(); }
51 template<typename C, typename M, typename T1>
52 void Invoke(C* c, M m, T1 a1) { r_ = (c->*m)(a1); }
53 template<typename C, typename M, typename T1, typename T2>
54 void Invoke(C* c, M m, T1 a1, T2 a2) { r_ = (c->*m)(a1, a2); }
55 template<typename C, typename M, typename T1, typename T2, typename T3>
56 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) { r_ = (c->*m)(a1, a2, a3); }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000057 template<typename C, typename M, typename T1, typename T2, typename T3,
58 typename T4>
59 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4) {
60 r_ = (c->*m)(a1, a2, a3, a4);
61 }
62 template<typename C, typename M, typename T1, typename T2, typename T3,
63 typename T4, typename T5>
64 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
65 r_ = (c->*m)(a1, a2, a3, a4, a5);
66 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067
68 R value() { return r_; }
69
70 private:
71 R r_;
72};
73
74template <>
75class ReturnType<void> {
76 public:
77 template<typename C, typename M>
78 void Invoke(C* c, M m) { (c->*m)(); }
79 template<typename C, typename M, typename T1>
80 void Invoke(C* c, M m, T1 a1) { (c->*m)(a1); }
81 template<typename C, typename M, typename T1, typename T2>
82 void Invoke(C* c, M m, T1 a1, T2 a2) { (c->*m)(a1, a2); }
83 template<typename C, typename M, typename T1, typename T2, typename T3>
84 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) { (c->*m)(a1, a2, a3); }
85
86 void value() {}
87};
88
tommi@webrtc.org18de6f92014-11-04 12:08:48 +000089namespace internal {
90
91class SynchronousMethodCall
92 : public rtc::MessageData,
93 public rtc::MessageHandler {
94 public:
perkj@webrtc.org81134d02015-01-12 08:30:16 +000095 explicit SynchronousMethodCall(rtc::MessageHandler* proxy)
tommi@webrtc.org18de6f92014-11-04 12:08:48 +000096 : e_(), proxy_(proxy) {}
97 ~SynchronousMethodCall() {}
98
99 void Invoke(rtc::Thread* t) {
100 if (t->IsCurrent()) {
101 proxy_->OnMessage(NULL);
102 } else {
103 e_.reset(new rtc::Event(false, false));
104 t->Post(this, 0);
andresp@webrtc.org53d90122015-02-09 14:19:09 +0000105 e_->Wait(rtc::Event::kForever);
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000106 }
107 }
108
109 private:
110 void OnMessage(rtc::Message*) { proxy_->OnMessage(NULL); e_->Set(); }
111 rtc::scoped_ptr<rtc::Event> e_;
112 rtc::MessageHandler* proxy_;
113};
114
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000115} // namespace internal
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000116
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000118class MethodCall0 : public rtc::Message,
119 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000120 public:
121 typedef R (C::*Method)();
122 MethodCall0(C* c, Method m) : c_(c), m_(m) {}
123
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000124 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000125 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000126 return r_.value();
127 }
128
129 private:
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000130 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131
132 C* c_;
133 Method m_;
134 ReturnType<R> r_;
135};
136
137template <typename C, typename R>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000138class ConstMethodCall0 : public rtc::Message,
139 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140 public:
141 typedef R (C::*Method)() const;
142 ConstMethodCall0(C* c, Method m) : c_(c), m_(m) {}
143
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000144 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000145 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000146 return r_.value();
147 }
148
149 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000150 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151
152 C* c_;
153 Method m_;
154 ReturnType<R> r_;
155};
156
157template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000158class MethodCall1 : public rtc::Message,
159 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160 public:
161 typedef R (C::*Method)(T1 a1);
162 MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
163
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000164 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000165 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 return r_.value();
167 }
168
169 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000170 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171
172 C* c_;
173 Method m_;
174 ReturnType<R> r_;
175 T1 a1_;
176};
177
178template <typename C, typename R, typename T1>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000179class ConstMethodCall1 : public rtc::Message,
180 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181 public:
182 typedef R (C::*Method)(T1 a1) const;
183 ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
184
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000185 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000186 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000187 return r_.value();
188 }
189
190 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000191 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000192
193 C* c_;
194 Method m_;
195 ReturnType<R> r_;
196 T1 a1_;
197};
198
199template <typename C, typename R, typename T1, typename T2>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000200class MethodCall2 : public rtc::Message,
201 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 public:
203 typedef R (C::*Method)(T1 a1, T2 a2);
204 MethodCall2(C* c, Method m, T1 a1, T2 a2) : c_(c), m_(m), a1_(a1), a2_(a2) {}
205
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000206 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000207 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 return r_.value();
209 }
210
211 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000212 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000213
214 C* c_;
215 Method m_;
216 ReturnType<R> r_;
217 T1 a1_;
218 T2 a2_;
219};
220
221template <typename C, typename R, typename T1, typename T2, typename T3>
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000222class MethodCall3 : public rtc::Message,
223 public rtc::MessageHandler {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000224 public:
225 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3);
226 MethodCall3(C* c, Method m, T1 a1, T2 a2, T3 a3)
227 : c_(c), m_(m), a1_(a1), a2_(a2), a3_(a3) {}
228
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000229 R Marshal(rtc::Thread* t) {
tommi@webrtc.org18de6f92014-11-04 12:08:48 +0000230 internal::SynchronousMethodCall(this).Invoke(t);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000231 return r_.value();
232 }
233
234 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000235 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_, a3_); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236
237 C* c_;
238 Method m_;
239 ReturnType<R> r_;
240 T1 a1_;
241 T2 a2_;
242 T3 a3_;
243};
244
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000245template <typename C, typename R, typename T1, typename T2, typename T3,
246 typename T4>
247class MethodCall4 : public rtc::Message,
248 public rtc::MessageHandler {
249 public:
250 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4);
251 MethodCall4(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4)
252 : c_(c), m_(m), a1_(a1), a2_(a2), a3_(a3), a4_(a4) {}
253
254 R Marshal(rtc::Thread* t) {
255 internal::SynchronousMethodCall(this).Invoke(t);
256 return r_.value();
257 }
258
259 private:
260 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_, a3_, a4_); }
261
262 C* c_;
263 Method m_;
264 ReturnType<R> r_;
265 T1 a1_;
266 T2 a2_;
267 T3 a3_;
268 T4 a4_;
269};
270
271template <typename C, typename R, typename T1, typename T2, typename T3,
272 typename T4, typename T5>
273class MethodCall5 : public rtc::Message,
274 public rtc::MessageHandler {
275 public:
276 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
277 MethodCall5(C* c, Method m, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
278 : c_(c), m_(m), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5) {}
279
280 R Marshal(rtc::Thread* t) {
281 internal::SynchronousMethodCall(this).Invoke(t);
282 return r_.value();
283 }
284
285 private:
286 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_, a3_, a4_, a5_); }
287
288 C* c_;
289 Method m_;
290 ReturnType<R> r_;
291 T1 a1_;
292 T2 a2_;
293 T3 a3_;
294 T4 a4_;
295 T5 a5_;
296};
297
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000298#define BEGIN_PROXY_MAP(c) \
299 class c##Proxy : public c##Interface { \
300 protected: \
301 typedef c##Interface C; \
302 c##Proxy(rtc::Thread* thread, C* c) : owner_thread_(thread), c_(c) {} \
303 ~c##Proxy() { \
304 MethodCall0<c##Proxy, void> call(this, &c##Proxy::Release_s); \
305 call.Marshal(owner_thread_); \
306 } \
307 \
308 public: \
309 static rtc::scoped_refptr<C> Create(rtc::Thread* thread, C* c) { \
310 return new rtc::RefCountedObject<c##Proxy>(thread, c); \
311 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000312
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000313#define PROXY_METHOD0(r, method) \
314 r method() override { \
315 MethodCall0<C, r> call(c_.get(), &C::method); \
316 return call.Marshal(owner_thread_); \
317 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000319#define PROXY_CONSTMETHOD0(r, method) \
320 r method() const override { \
321 ConstMethodCall0<C, r> call(c_.get(), &C::method); \
322 return call.Marshal(owner_thread_); \
323 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000325#define PROXY_METHOD1(r, method, t1) \
326 r method(t1 a1) override { \
327 MethodCall1<C, r, t1> call(c_.get(), &C::method, a1); \
328 return call.Marshal(owner_thread_); \
329 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000331#define PROXY_CONSTMETHOD1(r, method, t1) \
332 r method(t1 a1) const override { \
333 ConstMethodCall1<C, r, t1> call(c_.get(), &C::method, a1); \
334 return call.Marshal(owner_thread_); \
335 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000337#define PROXY_METHOD2(r, method, t1, t2) \
338 r method(t1 a1, t2 a2) override { \
339 MethodCall2<C, r, t1, t2> call(c_.get(), &C::method, a1, a2); \
340 return call.Marshal(owner_thread_); \
341 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000343#define PROXY_METHOD3(r, method, t1, t2, t3) \
344 r method(t1 a1, t2 a2, t3 a3) override { \
345 MethodCall3<C, r, t1, t2, t3> call(c_.get(), &C::method, a1, a2, a3); \
346 return call.Marshal(owner_thread_); \
347 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000348
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000349#define PROXY_METHOD4(r, method, t1, t2, t3, t4) \
350 r method(t1 a1, t2 a2, t3 a3, t4 a4) override { \
351 MethodCall4<C, r, t1, t2, t3, t4> call(c_.get(), &C::method, a1, a2, a3, \
352 a4); \
353 return call.Marshal(owner_thread_); \
354 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000355
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000356#define PROXY_METHOD5(r, method, t1, t2, t3, t4, t5) \
357 r method(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) override { \
358 MethodCall5<C, r, t1, t2, t3, t4, t5> call(c_.get(), &C::method, a1, a2, \
359 a3, a4, a5); \
360 return call.Marshal(owner_thread_); \
361 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000362
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363#define END_PROXY() \
364 private:\
365 void Release_s() {\
366 c_ = NULL;\
367 }\
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000368 mutable rtc::Thread* owner_thread_;\
369 rtc::scoped_refptr<C> c_;\
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000370 };\
371
372} // namespace webrtc
373
Henrik Kjellander15583c12016-02-10 10:53:12 +0100374#endif // WEBRTC_API_PROXY_H_