Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / app / webrtc / proxy.h
1 /*
2  * libjingle
3  * Copyright 2013, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
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.
15  *
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.
26  */
27
28 // This file contains Macros for creating proxies for webrtc MediaStream and
29 // PeerConnection classes.
30
31 //
32 // Example usage:
33 //
34 // class TestInterface : public rtc::RefCountInterface {
35 //  public:
36 //   std::string FooA() = 0;
37 //   std::string FooB(bool arg1) const = 0;
38 //   std::string FooC(bool arg1)= 0;
39 //  };
40 //
41 // Note that return types can not be a const reference.
42 //
43 // class Test : public TestInterface {
44 // ... implementation of the interface.
45 // };
46 //
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)
51 // END_PROXY()
52 //
53 // The proxy can be created using TestProxy::Create(Thread*, TestInterface*).
54
55 #ifndef TALK_APP_WEBRTC_PROXY_H_
56 #define TALK_APP_WEBRTC_PROXY_H_
57
58 #include "webrtc/base/thread.h"
59
60 namespace webrtc {
61
62 template <typename R>
63 class ReturnType {
64  public:
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); }
73
74   R value() { return r_; }
75
76  private:
77   R r_;
78 };
79
80 template <>
81 class ReturnType<void> {
82  public:
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); }
91
92   void value() {}
93 };
94
95 template <typename C, typename R>
96 class MethodCall0 : public rtc::Message,
97                     public rtc::MessageHandler {
98  public:
99   typedef R (C::*Method)();
100   MethodCall0(C* c, Method m) : c_(c), m_(m) {}
101
102   R Marshal(rtc::Thread* t) {
103     t->Send(this, 0);
104     return r_.value();
105   }
106
107  private:
108   void OnMessage(rtc::Message*) {  r_.Invoke(c_, m_);}
109
110   C* c_;
111   Method m_;
112   ReturnType<R> r_;
113 };
114
115 template <typename C, typename R>
116 class ConstMethodCall0 : public rtc::Message,
117                          public rtc::MessageHandler {
118  public:
119   typedef R (C::*Method)() const;
120   ConstMethodCall0(C* c, Method m) : c_(c), m_(m) {}
121
122   R Marshal(rtc::Thread* t) {
123     t->Send(this, 0);
124     return r_.value();
125   }
126
127  private:
128   void OnMessage(rtc::Message*) { r_.Invoke(c_, m_); }
129
130   C* c_;
131   Method m_;
132   ReturnType<R> r_;
133 };
134
135 template <typename C, typename R,  typename T1>
136 class MethodCall1 : public rtc::Message,
137                     public rtc::MessageHandler {
138  public:
139   typedef R (C::*Method)(T1 a1);
140   MethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
141
142   R Marshal(rtc::Thread* t) {
143     t->Send(this, 0);
144     return r_.value();
145   }
146
147  private:
148   void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_); }
149
150   C* c_;
151   Method m_;
152   ReturnType<R> r_;
153   T1 a1_;
154 };
155
156 template <typename C, typename R,  typename T1>
157 class ConstMethodCall1 : public rtc::Message,
158                          public rtc::MessageHandler {
159  public:
160   typedef R (C::*Method)(T1 a1) const;
161   ConstMethodCall1(C* c, Method m, T1 a1) : c_(c), m_(m), a1_(a1) {}
162
163   R Marshal(rtc::Thread* t) {
164     t->Send(this, 0);
165     return r_.value();
166   }
167
168  private:
169   void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_); }
170
171   C* c_;
172   Method m_;
173   ReturnType<R> r_;
174   T1 a1_;
175 };
176
177 template <typename C, typename R, typename T1, typename T2>
178 class MethodCall2 : public rtc::Message,
179                     public rtc::MessageHandler {
180  public:
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) {}
183
184   R Marshal(rtc::Thread* t) {
185     t->Send(this, 0);
186     return r_.value();
187   }
188
189  private:
190   void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_); }
191
192   C* c_;
193   Method m_;
194   ReturnType<R> r_;
195   T1 a1_;
196   T2 a2_;
197 };
198
199 template <typename C, typename R, typename T1, typename T2, typename T3>
200 class MethodCall3 : public rtc::Message,
201                     public rtc::MessageHandler {
202  public:
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) {}
206
207   R Marshal(rtc::Thread* t) {
208     t->Send(this, 0);
209     return r_.value();
210   }
211
212  private:
213   void OnMessage(rtc::Message*) { r_.Invoke(c_, m_, a1_, a2_, a3_); }
214
215   C* c_;
216   Method m_;
217   ReturnType<R> r_;
218   T1 a1_;
219   T2 a2_;
220   T3 a3_;
221 };
222
223 #define BEGIN_PROXY_MAP(c) \
224   class c##Proxy : public c##Interface {\
225    protected:\
226     typedef c##Interface C;\
227     c##Proxy(rtc::Thread* thread, C* c)\
228       : owner_thread_(thread), \
229         c_(c)  {}\
230     ~c##Proxy() {\
231       MethodCall0<c##Proxy, void> call(this, &c##Proxy::Release_s);\
232       call.Marshal(owner_thread_);\
233     }\
234    public:\
235     static rtc::scoped_refptr<C> Create(rtc::Thread* thread, \
236                                               C* c) {\
237       return new rtc::RefCountedObject<c##Proxy>(thread, c);\
238     }\
239
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_);\
244     }\
245
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_);\
250      }\
251
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_);\
256     }\
257
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_);\
262     }\
263
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_);\
268     }\
269
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_);\
274     }\
275
276 #define END_PROXY() \
277    private:\
278     void Release_s() {\
279       c_ = NULL;\
280     }\
281     mutable rtc::Thread* owner_thread_;\
282     rtc::scoped_refptr<C> c_;\
283   };\
284
285 }  // namespace webrtc
286
287 #endif  //  TALK_APP_WEBRTC_PROXY_H_