Line data Source code
1 : #ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
2 : #define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
3 :
4 : #include <google/protobuf/stubs/macros.h>
5 : #include <google/protobuf/stubs/type_traits.h>
6 :
7 : // ===================================================================
8 : // emulates google3/base/callback.h
9 :
10 : namespace google {
11 : namespace protobuf {
12 :
13 : // Abstract interface for a callback. When calling an RPC, you must provide
14 : // a Closure to call when the procedure completes. See the Service interface
15 : // in service.h.
16 : //
17 : // To automatically construct a Closure which calls a particular function or
18 : // method with a particular set of parameters, use the NewCallback() function.
19 : // Example:
20 : // void FooDone(const FooResponse* response) {
21 : // ...
22 : // }
23 : //
24 : // void CallFoo() {
25 : // ...
26 : // // When done, call FooDone() and pass it a pointer to the response.
27 : // Closure* callback = NewCallback(&FooDone, response);
28 : // // Make the call.
29 : // service->Foo(controller, request, response, callback);
30 : // }
31 : //
32 : // Example that calls a method:
33 : // class Handler {
34 : // public:
35 : // ...
36 : //
37 : // void FooDone(const FooResponse* response) {
38 : // ...
39 : // }
40 : //
41 : // void CallFoo() {
42 : // ...
43 : // // When done, call FooDone() and pass it a pointer to the response.
44 : // Closure* callback = NewCallback(this, &Handler::FooDone, response);
45 : // // Make the call.
46 : // service->Foo(controller, request, response, callback);
47 : // }
48 : // };
49 : //
50 : // Currently NewCallback() supports binding zero, one, or two arguments.
51 : //
52 : // Callbacks created with NewCallback() automatically delete themselves when
53 : // executed. They should be used when a callback is to be called exactly
54 : // once (usually the case with RPC callbacks). If a callback may be called
55 : // a different number of times (including zero), create it with
56 : // NewPermanentCallback() instead. You are then responsible for deleting the
57 : // callback (using the "delete" keyword as normal).
58 : //
59 : // Note that NewCallback() is a bit touchy regarding argument types. Generally,
60 : // the values you provide for the parameter bindings must exactly match the
61 : // types accepted by the callback function. For example:
62 : // void Foo(string s);
63 : // NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string
64 : // NewCallback(&Foo, string("foo")); // WORKS
65 : // Also note that the arguments cannot be references:
66 : // void Foo(const string& s);
67 : // string my_str;
68 : // NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes.
69 : // However, correctly-typed pointers will work just fine.
70 : class LIBPROTOBUF_EXPORT Closure {
71 : public:
72 190 : Closure() {}
73 : virtual ~Closure();
74 :
75 : virtual void Run() = 0;
76 :
77 : private:
78 : GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure);
79 : };
80 :
81 : template<typename R, typename A1>
82 : class LIBPROTOBUF_EXPORT ResultCallback1 {
83 : public:
84 : ResultCallback1() {}
85 : virtual ~ResultCallback1() {}
86 :
87 : virtual R Run(A1) = 0;
88 :
89 : private:
90 : GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback1);
91 : };
92 :
93 : template<typename R, typename A1, typename A2>
94 : class LIBPROTOBUF_EXPORT ResultCallback2 {
95 : public:
96 : ResultCallback2() {}
97 : virtual ~ResultCallback2() {}
98 :
99 : virtual R Run(A1,A2) = 0;
100 :
101 : private:
102 : GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback2);
103 : };
104 :
105 : namespace internal {
106 :
107 : class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure {
108 : public:
109 : typedef void (*FunctionType)();
110 :
111 0 : FunctionClosure0(FunctionType function, bool self_deleting)
112 380 : : function_(function), self_deleting_(self_deleting) {}
113 : ~FunctionClosure0();
114 :
115 190 : void Run() {
116 190 : bool needs_delete = self_deleting_; // read in case callback deletes
117 190 : function_();
118 190 : if (needs_delete) delete this;
119 190 : }
120 :
121 : private:
122 : FunctionType function_;
123 : bool self_deleting_;
124 : };
125 :
126 : template <typename Class>
127 : class MethodClosure0 : public Closure {
128 : public:
129 : typedef void (Class::*MethodType)();
130 :
131 : MethodClosure0(Class* object, MethodType method, bool self_deleting)
132 : : object_(object), method_(method), self_deleting_(self_deleting) {}
133 : ~MethodClosure0() {}
134 :
135 : void Run() {
136 : bool needs_delete = self_deleting_; // read in case callback deletes
137 : (object_->*method_)();
138 : if (needs_delete) delete this;
139 : }
140 :
141 : private:
142 : Class* object_;
143 : MethodType method_;
144 : bool self_deleting_;
145 : };
146 :
147 : template <typename Arg1>
148 : class FunctionClosure1 : public Closure {
149 : public:
150 : typedef void (*FunctionType)(Arg1 arg1);
151 :
152 : FunctionClosure1(FunctionType function, bool self_deleting,
153 : Arg1 arg1)
154 : : function_(function), self_deleting_(self_deleting),
155 0 : arg1_(arg1) {}
156 0 : ~FunctionClosure1() {}
157 :
158 0 : void Run() {
159 0 : bool needs_delete = self_deleting_; // read in case callback deletes
160 0 : function_(arg1_);
161 0 : if (needs_delete) delete this;
162 0 : }
163 :
164 : private:
165 : FunctionType function_;
166 : bool self_deleting_;
167 : Arg1 arg1_;
168 : };
169 :
170 : template <typename Class, typename Arg1>
171 : class MethodClosure1 : public Closure {
172 : public:
173 : typedef void (Class::*MethodType)(Arg1 arg1);
174 :
175 : MethodClosure1(Class* object, MethodType method, bool self_deleting,
176 : Arg1 arg1)
177 : : object_(object), method_(method), self_deleting_(self_deleting),
178 : arg1_(arg1) {}
179 : ~MethodClosure1() {}
180 :
181 : void Run() {
182 : bool needs_delete = self_deleting_; // read in case callback deletes
183 : (object_->*method_)(arg1_);
184 : if (needs_delete) delete this;
185 : }
186 :
187 : private:
188 : Class* object_;
189 : MethodType method_;
190 : bool self_deleting_;
191 : Arg1 arg1_;
192 : };
193 :
194 : template <typename Arg1, typename Arg2>
195 : class FunctionClosure2 : public Closure {
196 : public:
197 : typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2);
198 :
199 : FunctionClosure2(FunctionType function, bool self_deleting,
200 : Arg1 arg1, Arg2 arg2)
201 : : function_(function), self_deleting_(self_deleting),
202 : arg1_(arg1), arg2_(arg2) {}
203 : ~FunctionClosure2() {}
204 :
205 : void Run() {
206 : bool needs_delete = self_deleting_; // read in case callback deletes
207 : function_(arg1_, arg2_);
208 : if (needs_delete) delete this;
209 : }
210 :
211 : private:
212 : FunctionType function_;
213 : bool self_deleting_;
214 : Arg1 arg1_;
215 : Arg2 arg2_;
216 : };
217 :
218 : template <typename Class, typename Arg1, typename Arg2>
219 : class MethodClosure2 : public Closure {
220 : public:
221 : typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2);
222 :
223 : MethodClosure2(Class* object, MethodType method, bool self_deleting,
224 : Arg1 arg1, Arg2 arg2)
225 : : object_(object), method_(method), self_deleting_(self_deleting),
226 : arg1_(arg1), arg2_(arg2) {}
227 : ~MethodClosure2() {}
228 :
229 : void Run() {
230 : bool needs_delete = self_deleting_; // read in case callback deletes
231 : (object_->*method_)(arg1_, arg2_);
232 : if (needs_delete) delete this;
233 : }
234 :
235 : private:
236 : Class* object_;
237 : MethodType method_;
238 : bool self_deleting_;
239 : Arg1 arg1_;
240 : Arg2 arg2_;
241 : };
242 :
243 : template<typename R, typename Arg1>
244 : class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> {
245 : public:
246 : typedef R (*FunctionType)(Arg1 arg1);
247 :
248 : FunctionResultCallback_0_1(FunctionType function, bool self_deleting)
249 : : function_(function), self_deleting_(self_deleting) {}
250 : ~FunctionResultCallback_0_1() {}
251 :
252 : R Run(Arg1 a1) {
253 : bool needs_delete = self_deleting_; // read in case callback deletes
254 : R result = function_(a1);
255 : if (needs_delete) delete this;
256 : return result;
257 : }
258 :
259 : private:
260 : FunctionType function_;
261 : bool self_deleting_;
262 : };
263 :
264 : template<typename R, typename P1, typename A1>
265 : class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> {
266 : public:
267 : typedef R (*FunctionType)(P1, A1);
268 :
269 : FunctionResultCallback_1_1(FunctionType function, bool self_deleting,
270 : P1 p1)
271 : : function_(function), self_deleting_(self_deleting), p1_(p1) {}
272 : ~FunctionResultCallback_1_1() {}
273 :
274 : R Run(A1 a1) {
275 : bool needs_delete = self_deleting_; // read in case callback deletes
276 : R result = function_(p1_, a1);
277 : if (needs_delete) delete this;
278 : return result;
279 : }
280 :
281 : private:
282 : FunctionType function_;
283 : bool self_deleting_;
284 : P1 p1_;
285 : };
286 :
287 : template <typename T>
288 : struct InternalConstRef {
289 : typedef typename remove_reference<T>::type base_type;
290 : typedef const base_type& type;
291 : };
292 :
293 : template <typename R, typename T, typename P1, typename P2, typename P3,
294 : typename P4, typename P5, typename A1, typename A2>
295 : class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> {
296 : public:
297 : typedef R (T::*MethodType)(P1, P2, P3, P4, P5, A1, A2);
298 : MethodResultCallback_5_2(T* object, MethodType method, bool self_deleting,
299 : P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
300 : : object_(object),
301 : method_(method),
302 : self_deleting_(self_deleting),
303 : p1_(p1),
304 : p2_(p2),
305 : p3_(p3),
306 : p4_(p4),
307 : p5_(p5) {}
308 : ~MethodResultCallback_5_2() {}
309 :
310 : R Run(A1 a1, A2 a2) {
311 : bool needs_delete = self_deleting_;
312 : R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, a1, a2);
313 : if (needs_delete) delete this;
314 : return result;
315 : }
316 :
317 : private:
318 : T* object_;
319 : MethodType method_;
320 : bool self_deleting_;
321 : typename remove_reference<P1>::type p1_;
322 : typename remove_reference<P2>::type p2_;
323 : typename remove_reference<P3>::type p3_;
324 : typename remove_reference<P4>::type p4_;
325 : typename remove_reference<P5>::type p5_;
326 : };
327 :
328 : } // namespace internal
329 :
330 : // See Closure.
331 : inline Closure* NewCallback(void (*function)()) {
332 : return new internal::FunctionClosure0(function, true);
333 : }
334 :
335 : // See Closure.
336 : inline Closure* NewPermanentCallback(void (*function)()) {
337 : return new internal::FunctionClosure0(function, false);
338 : }
339 :
340 : // See Closure.
341 : template <typename Class>
342 : inline Closure* NewCallback(Class* object, void (Class::*method)()) {
343 : return new internal::MethodClosure0<Class>(object, method, true);
344 : }
345 :
346 : // See Closure.
347 : template <typename Class>
348 : inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) {
349 : return new internal::MethodClosure0<Class>(object, method, false);
350 : }
351 :
352 : // See Closure.
353 : template <typename Arg1>
354 : inline Closure* NewCallback(void (*function)(Arg1),
355 : Arg1 arg1) {
356 : return new internal::FunctionClosure1<Arg1>(function, true, arg1);
357 : }
358 :
359 : // See Closure.
360 : template <typename Arg1>
361 : inline Closure* NewPermanentCallback(void (*function)(Arg1),
362 : Arg1 arg1) {
363 : return new internal::FunctionClosure1<Arg1>(function, false, arg1);
364 : }
365 :
366 : // See Closure.
367 : template <typename Class, typename Arg1>
368 : inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1),
369 : Arg1 arg1) {
370 : return new internal::MethodClosure1<Class, Arg1>(object, method, true, arg1);
371 : }
372 :
373 : // See Closure.
374 : template <typename Class, typename Arg1>
375 : inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1),
376 : Arg1 arg1) {
377 : return new internal::MethodClosure1<Class, Arg1>(object, method, false, arg1);
378 : }
379 :
380 : // See Closure.
381 : template <typename Arg1, typename Arg2>
382 : inline Closure* NewCallback(void (*function)(Arg1, Arg2),
383 : Arg1 arg1, Arg2 arg2) {
384 : return new internal::FunctionClosure2<Arg1, Arg2>(
385 : function, true, arg1, arg2);
386 : }
387 :
388 : // See Closure.
389 : template <typename Arg1, typename Arg2>
390 : inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2),
391 : Arg1 arg1, Arg2 arg2) {
392 : return new internal::FunctionClosure2<Arg1, Arg2>(
393 : function, false, arg1, arg2);
394 : }
395 :
396 : // See Closure.
397 : template <typename Class, typename Arg1, typename Arg2>
398 : inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2),
399 : Arg1 arg1, Arg2 arg2) {
400 : return new internal::MethodClosure2<Class, Arg1, Arg2>(
401 : object, method, true, arg1, arg2);
402 : }
403 :
404 : // See Closure.
405 : template <typename Class, typename Arg1, typename Arg2>
406 : inline Closure* NewPermanentCallback(
407 : Class* object, void (Class::*method)(Arg1, Arg2),
408 : Arg1 arg1, Arg2 arg2) {
409 : return new internal::MethodClosure2<Class, Arg1, Arg2>(
410 : object, method, false, arg1, arg2);
411 : }
412 :
413 : // See ResultCallback1
414 : template<typename R, typename A1>
415 : inline ResultCallback1<R, A1>* NewCallback(R (*function)(A1)) {
416 : return new internal::FunctionResultCallback_0_1<R, A1>(function, true);
417 : }
418 :
419 : // See ResultCallback1
420 : template<typename R, typename A1>
421 : inline ResultCallback1<R, A1>* NewPermanentCallback(R (*function)(A1)) {
422 : return new internal::FunctionResultCallback_0_1<R, A1>(function, false);
423 : }
424 :
425 : // See ResultCallback1
426 : template<typename R, typename P1, typename A1>
427 : inline ResultCallback1<R, A1>* NewCallback(R (*function)(P1, A1), P1 p1) {
428 : return new internal::FunctionResultCallback_1_1<R, P1, A1>(
429 : function, true, p1);
430 : }
431 :
432 : // See ResultCallback1
433 : template<typename R, typename P1, typename A1>
434 : inline ResultCallback1<R, A1>* NewPermanentCallback(
435 : R (*function)(P1, A1), P1 p1) {
436 : return new internal::FunctionResultCallback_1_1<R, P1, A1>(
437 : function, false, p1);
438 : }
439 :
440 : // See MethodResultCallback_5_2
441 : template <typename R, typename T, typename P1, typename P2, typename P3,
442 : typename P4, typename P5, typename A1, typename A2>
443 : inline ResultCallback2<R, A1, A2>* NewPermanentCallback(
444 : T* object, R (T::*function)(P1, P2, P3, P4, P5, A1, A2),
445 : typename internal::InternalConstRef<P1>::type p1,
446 : typename internal::InternalConstRef<P2>::type p2,
447 : typename internal::InternalConstRef<P3>::type p3,
448 : typename internal::InternalConstRef<P4>::type p4,
449 : typename internal::InternalConstRef<P5>::type p5) {
450 : return new internal::MethodResultCallback_5_2<R, T, P1, P2, P3, P4, P5, A1,
451 : A2>(object, function, false, p1,
452 : p2, p3, p4, p5);
453 : }
454 :
455 : // A function which does nothing. Useful for creating no-op callbacks, e.g.:
456 : // Closure* nothing = NewCallback(&DoNothing);
457 : void LIBPROTOBUF_EXPORT DoNothing();
458 :
459 :
460 : } // namespace protobuf
461 : } // namespace google
462 :
463 : #endif // GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
|