3 * Copyright 2013, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 // This file contains Macros for creating proxies for webrtc MediaStream and
29 // PeerConnection classes.
34 // class TestInterface : public rtc::RefCountInterface {
36 // std::string FooA() = 0;
37 // std::string FooB(bool arg1) const = 0;
38 // std::string FooC(bool arg1)= 0;
41 // Note that return types can not be a const reference.
43 // class Test : public TestInterface {
44 // ... implementation of the interface.
47 // BEGIN_PROXY_MAP(Test)
48 // PROXY_METHOD0(std::string, FooA)
49 // PROXY_CONSTMETHOD1(std::string, FooB, arg1)
50 // PROXY_METHOD1(std::string, FooC, arg1)
53 // The proxy can be created using TestProxy::Create(Thread*, TestInterface*).
55 #ifndef TALK_APP_WEBRTC_PROXY_H_
56 #define TALK_APP_WEBRTC_PROXY_H_
58 #include "webrtc/base/thread.h"
65 template<typename C, typename M>
66 void Invoke(C* c, M m) { r_ = (c->*m)(); }
67 template<typename C, typename M, typename T1>
68 void Invoke(C* c, M m, T1 a1) { r_ = (c->*m)(a1); }
69 template<typename C, typename M, typename T1, typename T2>
70 void Invoke(C* c, M m, T1 a1, T2 a2) { r_ = (c->*m)(a1, a2); }
71 template<typename C, typename M, typename T1, typename T2, typename T3>
72 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) { r_ = (c->*m)(a1, a2, a3); }
74 R value() { return r_; }
81 class ReturnType<void> {
83 template<typename C, typename M>
84 void Invoke(C* c, M m) { (c->*m)(); }
85 template<typename C, typename M, typename T1>
86 void Invoke(C* c, M m, T1 a1) { (c->*m)(a1); }
87 template<typename C, typename M, typename T1, typename T2>
88 void Invoke(C* c, M m, T1 a1, T2 a2) { (c->*m)(a1, a2); }
89 template<typename C, typename M, typename T1, typename T2, typename T3>
90 void Invoke(C* c, M m, T1 a1, T2 a2, T3 a3) { (c->*m)(a1, a2, a3); }
95 template <typename C, typename R>
96 class MethodCall0 : public rtc::Message,
97 public rtc::MessageHandler {
99 typedef R (C::*Method)();
100 MethodCall0(C* c, Method m) : c_(c), m_(m) {}
102 R Marshal(rtc::Thread* t) {
108 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_);}
115 template <typename C, typename R>
116 class ConstMethodCall0 : public rtc::Message,
117 public rtc::MessageHandler {
119 typedef R (C::*Method)() const;
120 ConstMethodCall0(C* c, Method m) : c_(c), m_(m) {}
122 R Marshal(rtc::Thread* t) {
128 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
135 template <typename C, typename R, typename T1>
136 class MethodCall1 : public rtc::Message,
137 public rtc::MessageHandler {
139 typedef R (C::*Method)(T1 a1);
140 MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
142 R Marshal(rtc::Thread* t) {
148 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_); }
156 template <typename C, typename R, typename T1>
157 class ConstMethodCall1 : public rtc::Message,
158 public rtc::MessageHandler {
160 typedef R (C::*Method)(T1 a1) const;
161 ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
163 R Marshal(rtc::Thread* t) {
169 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_); }
177 template <typename C, typename R, typename T1, typename T2>
178 class MethodCall2 : public rtc::Message,
179 public rtc::MessageHandler {
181 typedef R (C::*Method)(T1 a1, T2 a2);
182 MethodCall2(C* c, Method m, T1 a1, T2 a2) : c_(c), m_(m), a1_(a1), a2_(a2) {}
184 R Marshal(rtc::Thread* t) {
190 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_); }
199 template <typename C, typename R, typename T1, typename T2, typename T3>
200 class MethodCall3 : public rtc::Message,
201 public rtc::MessageHandler {
203 typedef R (C::*Method)(T1 a1, T2 a2, T3 a3);
204 MethodCall3(C* c, Method m, T1 a1, T2 a2, T3 a3)
205 : c_(c), m_(m), a1_(a1), a2_(a2), a3_(a3) {}
207 R Marshal(rtc::Thread* t) {
213 void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_, a3_); }
223 #define BEGIN_PROXY_MAP(c) \
224 class c##Proxy : public c##Interface {\
226 typedef c##Interface C;\
227 c##Proxy(rtc::Thread* thread, C* c)\
228 : owner_thread_(thread), \
231 MethodCall0<c##Proxy, void> call(this, &c##Proxy::Release_s);\
232 call.Marshal(owner_thread_);\
235 static rtc::scoped_refptr<C> Create(rtc::Thread* thread, \
237 return new rtc::RefCountedObject<c##Proxy>(thread, c);\
240 #define PROXY_METHOD0(r, method)\
241 r method() OVERRIDE {\
242 MethodCall0<C, r> call(c_.get(), &C::method);\
243 return call.Marshal(owner_thread_);\
246 #define PROXY_CONSTMETHOD0(r, method)\
247 r method() const OVERRIDE {\
248 ConstMethodCall0<C, r> call(c_.get(), &C::method);\
249 return call.Marshal(owner_thread_);\
252 #define PROXY_METHOD1(r, method, t1)\
253 r method(t1 a1) OVERRIDE {\
254 MethodCall1<C, r, t1> call(c_.get(), &C::method, a1);\
255 return call.Marshal(owner_thread_);\
258 #define PROXY_CONSTMETHOD1(r, method, t1)\
259 r method(t1 a1) const OVERRIDE {\
260 ConstMethodCall1<C, r, t1> call(c_.get(), &C::method, a1);\
261 return call.Marshal(owner_thread_);\
264 #define PROXY_METHOD2(r, method, t1, t2)\
265 r method(t1 a1, t2 a2) OVERRIDE {\
266 MethodCall2<C, r, t1, t2> call(c_.get(), &C::method, a1, a2);\
267 return call.Marshal(owner_thread_);\
270 #define PROXY_METHOD3(r, method, t1, t2, t3)\
271 r method(t1 a1, t2 a2, t3 a3) OVERRIDE {\
272 MethodCall3<C, r, t1, t2, t3> call(c_.get(), &C::method, a1, a2, a3);\
273 return call.Marshal(owner_thread_);\
276 #define END_PROXY() \
281 mutable rtc::Thread* owner_thread_;\
282 rtc::scoped_refptr<C> c_;\
285 } // namespace webrtc
287 #endif // TALK_APP_WEBRTC_PROXY_H_