OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef PPAPI_CPP_COMPLETION_CALLBACK_H_ | 5 #ifndef PPAPI_CPP_COMPLETION_CALLBACK_H_ |
6 #define PPAPI_CPP_COMPLETION_CALLBACK_H_ | 6 #define PPAPI_CPP_COMPLETION_CALLBACK_H_ |
7 | 7 |
8 #include "ppapi/c/pp_completion_callback.h" | 8 #include "ppapi/c/pp_completion_callback.h" |
9 #include "ppapi/c/pp_errors.h" | 9 #include "ppapi/c/pp_errors.h" |
10 #include "ppapi/cpp/logging.h" | 10 #include "ppapi/cpp/logging.h" |
11 #include "ppapi/cpp/non_thread_safe_ref_count.h" | 11 #include "ppapi/cpp/module.h" |
12 | 12 |
13 /// @file | 13 /// @file |
14 /// This file defines the API to create and run a callback. | 14 /// This file defines the API to create and run a callback. |
15 namespace pp { | 15 namespace pp { |
16 | 16 |
17 /// This API enables you to implement and receive callbacks when | 17 /// This API enables you to implement and receive callbacks when |
18 /// Pepper operations complete asynchronously. | 18 /// Pepper operations complete asynchronously. |
19 class CompletionCallback { | 19 class CompletionCallback { |
20 public: | 20 public: |
21 /// The default constructor will create a blocking | 21 /// The default constructor will create a blocking |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 }; | 149 }; |
150 | 150 |
151 /// BlockUntilComplete() is used in place of an actual completion callback | 151 /// BlockUntilComplete() is used in place of an actual completion callback |
152 /// to request blocking behavior. If specified, the calling thread will block | 152 /// to request blocking behavior. If specified, the calling thread will block |
153 /// until the function completes. Blocking completion callbacks are only | 153 /// until the function completes. Blocking completion callbacks are only |
154 /// allowed from background threads. | 154 /// allowed from background threads. |
155 /// | 155 /// |
156 /// @return A <code>CompletionCallback</code> corresponding to a NULL callback. | 156 /// @return A <code>CompletionCallback</code> corresponding to a NULL callback. |
157 CompletionCallback BlockUntilComplete(); | 157 CompletionCallback BlockUntilComplete(); |
158 | 158 |
159 /// CompletionCallbackFactory<T> may be used to create CompletionCallback | |
160 /// objects that are bound to member functions. | |
161 /// | |
162 /// If a factory is destroyed, then any pending callbacks will be cancelled | |
163 /// preventing any bound member functions from being called. The CancelAll() | |
164 /// method allows pending callbacks to be cancelled without destroying the | |
165 /// factory. | |
166 /// | |
167 /// <strong>Note: </strong><code>CompletionCallbackFactory<T></code> isn't | |
168 /// thread safe, but you can make it more thread-friendly by passing a | |
169 /// thread-safe refcounting class as the second template element. However, it | |
170 /// only guarantees safety for creating a callback from another thread, the | |
171 /// callback itself needs to execute on the same thread as the thread that | |
172 /// creates/destroys the factory. With this restriction, it is safe to create | |
173 /// the <code>CompletionCallbackFactory</code> on the main thread, create | |
174 /// callbacks from any thread and pass them to CallOnMainThread(). | |
175 /// | |
176 /// <strong>Example: </strong> | |
177 /// | |
178 /// @code | |
179 /// | |
180 /// class MyHandler { | |
181 /// public: | |
182 /// // If an compiler warns on following using |this| in the initializer | |
183 /// // list, use PP_ALLOW_THIS_IN_INITIALIZER_LIST macro. | |
184 /// MyHandler() : factory_(this), offset_(0) { | |
185 /// } | |
186 /// | |
187 /// void ProcessFile(const FileRef& file) { | |
188 /// CompletionCallback cc = factory_.NewRequiredCallback( | |
189 /// &MyHandler::DidOpen); | |
190 /// int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc); | |
191 /// CHECK(rv == PP_OK_COMPLETIONPENDING); | |
192 /// } | |
193 /// | |
194 /// private: | |
195 /// CompletionCallback NewCallback() { | |
196 /// return factory_.NewCallback(&MyHandler::DidCompleteIO); | |
197 /// } | |
198 /// | |
199 /// void DidOpen(int32_t result) { | |
200 /// if (result == PP_OK) { | |
201 /// // The file is open, and we can begin reading. | |
202 /// offset_ = 0; | |
203 /// ReadMore(); | |
204 /// } else { | |
205 /// // Failed to open the file with error given by 'result'. | |
206 /// } | |
207 /// } | |
208 /// | |
209 /// void DidRead(int32_t result) { | |
210 /// if (result > 0) { | |
211 /// // buf_ now contains 'result' number of bytes from the file. | |
212 /// ProcessBytes(buf_, result); | |
213 /// offset_ += result; | |
214 /// ReadMore(); | |
215 /// } else { | |
216 /// // Done reading (possibly with an error given by 'result'). | |
217 /// } | |
218 /// } | |
219 /// | |
220 /// void ReadMore() { | |
221 /// CompletionCallback cc = | |
222 /// factory_.NewOptionalCallback(&MyHandler::DidRead); | |
223 /// int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), | |
224 /// cc.pp_completion_callback()); | |
225 /// if (rv != PP_OK_COMPLETIONPENDING) | |
226 /// cc.Run(rv); | |
227 /// } | |
228 /// | |
229 /// void ProcessBytes(const char* bytes, int32_t length) { | |
230 /// // Do work ... | |
231 /// } | |
232 /// | |
233 /// pp::CompletionCallbackFactory<MyHandler> factory_; | |
234 /// pp::FileIO fio_; | |
235 /// char buf_[4096]; | |
236 /// int64_t offset_; | |
237 /// }; | |
238 /// | |
239 /// @endcode | |
240 /// | |
241 template <typename T, typename RefCount = NonThreadSafeRefCount> | |
242 class CompletionCallbackFactory { | |
243 public: | |
244 | |
245 /// This constructor creates a <code>CompletionCallbackFactory</code> | |
246 /// bound to an object. If the constructor is called without an argument, | |
247 /// the default value of <code>NULL</code> is used. The user then must call | |
248 /// Initialize() to initialize the object. | |
249 /// | |
250 /// param[in] object Optional parameter. An object whose member functions | |
251 /// are to be bound to CompletionCallbacks created by this | |
252 /// <code>CompletionCallbackFactory</code>. The default value of this | |
253 /// parameter is <code>NULL</code>. | |
254 explicit CompletionCallbackFactory(T* object = NULL) | |
255 : object_(object) { | |
256 InitBackPointer(); | |
257 } | |
258 | |
259 /// Destructor. | |
260 ~CompletionCallbackFactory() { | |
261 ResetBackPointer(); | |
262 } | |
263 | |
264 /// CancelAll() cancels all <code>CompletionCallbacks</code> allocated from | |
265 /// this factory. | |
266 void CancelAll() { | |
267 ResetBackPointer(); | |
268 InitBackPointer(); | |
269 } | |
270 /// Initialize() binds the <code>CallbackFactory</code> to a particular | |
271 /// object. Use this when the object is not available at | |
272 /// <code>CallbackFactory</code> creation, and the <code>NULL</code> default | |
273 /// is passed to the constructor. The object may only be initialized once, | |
274 /// either by the constructor, or by a call to Initialize(). | |
275 /// | |
276 /// @param[in] object The object whose member functions are to be bound to | |
277 /// the <code>CompletionCallback</code> created by this | |
278 /// <code>CompletionCallbackFactory</code>. | |
279 void Initialize(T* object) { | |
280 PP_DCHECK(object); | |
281 PP_DCHECK(!object_); // May only initialize once! | |
282 object_ = object; | |
283 } | |
284 | |
285 /// GetObject() returns the object that was passed at initialization to | |
286 /// Intialize(). | |
287 /// | |
288 /// @return the object passed to the constructor or Intialize(). | |
289 T* GetObject() { | |
290 return object_; | |
291 } | |
292 | |
293 /// NewCallback allocates a new, single-use <code>CompletionCallback</code>. | |
294 /// The <code>CompletionCallback</code> must be run in order for the memory | |
295 /// allocated by the methods to be freed. | |
296 /// NewCallback() is equivalent to NewRequiredCallback() below. | |
297 /// | |
298 /// @param[in] method The method to be invoked upon completion of the | |
299 /// operation. | |
300 /// | |
301 /// @return A <code>CompletionCallback</code>. | |
302 template <typename Method> | |
303 CompletionCallback NewCallback(Method method) { | |
304 PP_DCHECK(object_); | |
305 return NewCallbackHelper(Dispatcher0<Method>(method)); | |
306 } | |
307 | |
308 /// NewRequiredCallback() allocates a new, single-use | |
309 /// <code>CompletionCallback</code> that will always run. The | |
310 /// <code>CompletionCallback</code> must be run in order for the memory | |
311 /// allocated by the methods to be freed. | |
312 /// | |
313 /// @param[in] method The method to be invoked upon completion of the | |
314 /// operation. | |
315 /// | |
316 /// @return A <code>CompletionCallback</code>. | |
317 template <typename Method> | |
318 CompletionCallback NewRequiredCallback(Method method) { | |
319 CompletionCallback cc = NewCallback(method); | |
320 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
321 return cc; | |
322 } | |
323 | |
324 /// NewOptionalCallback() allocates a new, single-use | |
325 /// <code>CompletionCallback</code> that might not run if the method | |
326 /// taking it can complete synchronously. Thus, if after passing the | |
327 /// CompletionCallback to a Pepper method, the method does not return | |
328 /// PP_OK_COMPLETIONPENDING, then you should manually call the | |
329 /// CompletionCallback's Run method, or memory will be leaked. | |
330 /// | |
331 /// @param[in] method The method to be invoked upon completion of the | |
332 /// operation. | |
333 /// | |
334 /// @return A <code>CompletionCallback</code>. | |
335 template <typename Method> | |
336 CompletionCallback NewOptionalCallback(Method method) { | |
337 CompletionCallback cc = NewCallback(method); | |
338 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
339 return cc; | |
340 } | |
341 | |
342 /// NewCallback() allocates a new, single-use <code>CompletionCallback</code>. | |
343 /// The <code>CompletionCallback</code> must be run in order for the memory | |
344 /// allocated by the methods to be freed. | |
345 /// NewCallback() is equivalent to NewRequiredCallback() below. | |
346 /// | |
347 /// @param[in] method The method to be invoked upon completion of the | |
348 /// operation. Method should be of type: | |
349 /// <code>void (T::*)(int32_t result, const A& a)</code> | |
350 /// | |
351 /// @param[in] a Passed to <code>method</code> when the completion callback | |
352 /// runs. | |
353 /// | |
354 /// @return A <code>CompletionCallback</code>. | |
355 template <typename Method, typename A> | |
356 CompletionCallback NewCallback(Method method, const A& a) { | |
357 PP_DCHECK(object_); | |
358 return NewCallbackHelper(Dispatcher1<Method, A>(method, a)); | |
359 } | |
360 | |
361 /// NewRequiredCallback() allocates a new, single-use | |
362 /// <code>CompletionCallback</code> that will always run. The | |
363 /// <code>CompletionCallback</code> must be run in order for the memory | |
364 /// allocated by the methods to be freed. | |
365 /// | |
366 /// @param[in] method The method to be invoked upon completion of the | |
367 /// operation. Method should be of type: | |
368 /// <code>void (T::*)(int32_t result, const A& a)</code> | |
369 /// | |
370 /// @param[in] a Passed to <code>method</code> when the completion callback | |
371 /// runs. | |
372 /// | |
373 /// @return A <code>CompletionCallback</code>. | |
374 template <typename Method, typename A> | |
375 CompletionCallback NewRequiredCallback(Method method, const A& a) { | |
376 CompletionCallback cc = NewCallback(method, a); | |
377 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
378 return cc; | |
379 } | |
380 | |
381 /// NewOptionalCallback() allocates a new, single-use | |
382 /// <code>CompletionCallback</code> that might not run if the method | |
383 /// taking it can complete synchronously. Thus, if after passing the | |
384 /// CompletionCallback to a Pepper method, the method does not return | |
385 /// PP_OK_COMPLETIONPENDING, then you should manually call the | |
386 /// CompletionCallback's Run method, or memory will be leaked. | |
387 /// | |
388 /// @param[in] method The method to be invoked upon completion of the | |
389 /// operation. Method should be of type: | |
390 /// <code>void (T::*)(int32_t result, const A& a)</code> | |
391 /// | |
392 /// @param[in] a Passed to <code>method</code> when the completion callback | |
393 /// runs. | |
394 /// | |
395 /// @return A <code>CompletionCallback</code>. | |
396 template <typename Method, typename A> | |
397 CompletionCallback NewOptionalCallback(Method method, const A& a) { | |
398 CompletionCallback cc = NewCallback(method, a); | |
399 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
400 return cc; | |
401 } | |
402 | |
403 /// NewCallback() allocates a new, single-use | |
404 /// <code>CompletionCallback</code>. | |
405 /// The <code>CompletionCallback</code> must be run in order for the memory | |
406 /// allocated by the methods to be freed. | |
407 /// NewCallback() is equivalent to NewRequiredCallback() below. | |
408 /// | |
409 /// @param method The method taking the callback. Method should be of type: | |
410 /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code> | |
411 /// | |
412 /// @param[in] a Passed to <code>method</code> when the completion callback | |
413 /// runs. | |
414 /// | |
415 /// @param[in] b Passed to <code>method</code> when the completion callback | |
416 /// runs. | |
417 /// | |
418 /// @return A <code>CompletionCallback</code>. | |
419 template <typename Method, typename A, typename B> | |
420 CompletionCallback NewCallback(Method method, const A& a, const B& b) { | |
421 PP_DCHECK(object_); | |
422 return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b)); | |
423 } | |
424 | |
425 /// NewRequiredCallback() allocates a new, single-use | |
426 /// <code>CompletionCallback</code> that will always run. The | |
427 /// <code>CompletionCallback</code> must be run in order for the memory | |
428 /// allocated by the methods to be freed. | |
429 /// | |
430 /// @param method The method taking the callback. Method should be of type: | |
431 /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code> | |
432 /// | |
433 /// @param[in] a Passed to <code>method</code> when the completion callback | |
434 /// runs. | |
435 /// | |
436 /// @param[in] b Passed to <code>method</code> when the completion callback | |
437 /// runs. | |
438 /// | |
439 /// @return A <code>CompletionCallback</code>. | |
440 template <typename Method, typename A, typename B> | |
441 CompletionCallback NewRequiredCallback(Method method, const A& a, | |
442 const B& b) { | |
443 CompletionCallback cc = NewCallback(method, a, b); | |
444 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
445 return cc; | |
446 } | |
447 | |
448 /// NewOptionalCallback() allocates a new, single-use | |
449 /// <code>CompletionCallback</code> that might not run if the method | |
450 /// taking it can complete synchronously. Thus, if after passing the | |
451 /// CompletionCallback to a Pepper method, the method does not return | |
452 /// PP_OK_COMPLETIONPENDING, then you should manually call the | |
453 /// CompletionCallback's Run method, or memory will be leaked. | |
454 /// | |
455 /// @param[in] method The method taking the callback. Method should be of | |
456 /// type: | |
457 /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code> | |
458 /// | |
459 /// @param[in] a Passed to <code>method</code> when the completion callback | |
460 /// runs. | |
461 /// | |
462 /// @param[in] b Passed to <code>method</code> when the completion callback | |
463 /// runs. | |
464 /// | |
465 /// @return A <code>CompletionCallback</code>. | |
466 template <typename Method, typename A, typename B> | |
467 CompletionCallback NewOptionalCallback(Method method, const A& a, | |
468 const B& b) { | |
469 CompletionCallback cc = NewCallback(method, a, b); | |
470 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
471 return cc; | |
472 } | |
473 | |
474 /// NewCallback() allocates a new, single-use | |
475 /// <code>CompletionCallback</code>. | |
476 /// The <code>CompletionCallback</code> must be run in order for the memory | |
477 /// allocated by the methods to be freed. | |
478 /// NewCallback() is equivalent to NewRequiredCallback() below. | |
479 /// | |
480 /// @param method The method taking the callback. Method should be of type: | |
481 /// <code> | |
482 /// void (T::*)(int32_t result, const A& a, const B& b, const C& c) | |
483 /// </code> | |
484 /// | |
485 /// @param[in] a Passed to <code>method</code> when the completion callback | |
486 /// runs. | |
487 /// | |
488 /// @param[in] b Passed to <code>method</code> when the completion callback | |
489 /// runs. | |
490 /// | |
491 /// @param[in] c Passed to <code>method</code> when the completion callback | |
492 /// runs. | |
493 /// | |
494 /// @return A <code>CompletionCallback</code>. | |
495 template <typename Method, typename A, typename B, typename C> | |
496 CompletionCallback NewCallback(Method method, const A& a, const B& b, | |
497 const C& c) { | |
498 PP_DCHECK(object_); | |
499 return NewCallbackHelper(Dispatcher3<Method, A, B, C>(method, a, b, c)); | |
500 } | |
501 | |
502 /// NewRequiredCallback() allocates a new, single-use | |
503 /// <code>CompletionCallback</code> that will always run. The | |
504 /// <code>CompletionCallback</code> must be run in order for the memory | |
505 /// allocated by the methods to be freed. | |
506 /// | |
507 /// @param method The method taking the callback. Method should be of type: | |
508 /// <code> | |
509 /// void (T::*)(int32_t result, const A& a, const B& b, const C& c) | |
510 /// </code> | |
511 /// | |
512 /// @param[in] a Passed to <code>method</code> when the completion callback | |
513 /// runs. | |
514 /// | |
515 /// @param[in] b Passed to <code>method</code> when the completion callback | |
516 /// runs. | |
517 /// | |
518 /// @param[in] c Passed to <code>method</code> when the completion callback | |
519 /// runs. | |
520 /// | |
521 /// @return A <code>CompletionCallback</code>. | |
522 template <typename Method, typename A, typename B, typename C> | |
523 CompletionCallback NewRequiredCallback(Method method, const A& a, | |
524 const B& b, const C& c) { | |
525 CompletionCallback cc = NewCallback(method, a, b, c); | |
526 cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
527 return cc; | |
528 } | |
529 | |
530 /// NewOptionalCallback() allocates a new, single-use | |
531 /// <code>CompletionCallback</code> that might not run if the method | |
532 /// taking it can complete synchronously. Thus, if after passing the | |
533 /// CompletionCallback to a Pepper method, the method does not return | |
534 /// PP_OK_COMPLETIONPENDING, then you should manually call the | |
535 /// CompletionCallback's Run method, or memory will be leaked. | |
536 /// | |
537 /// @param[in] method The method taking the callback. Method should be of | |
538 /// type: | |
539 /// <code> | |
540 /// void (T::*)(int32_t result, const A& a, const B& b, const C& c) | |
541 /// </code> | |
542 /// | |
543 /// @param[in] a Passed to <code>method</code> when the completion callback | |
544 /// runs. | |
545 /// | |
546 /// @param[in] b Passed to <code>method</code> when the completion callback | |
547 /// runs. | |
548 /// | |
549 /// @param[in] c Passed to <code>method</code> when the completion callback | |
550 /// runs. | |
551 /// | |
552 /// @return A <code>CompletionCallback</code>. | |
553 template <typename Method, typename A, typename B, typename C> | |
554 CompletionCallback NewOptionalCallback(Method method, const A& a, | |
555 const B& b, const C& c) { | |
556 CompletionCallback cc = NewCallback(method, a, b, c); | |
557 cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); | |
558 return cc; | |
559 } | |
560 | |
561 private: | |
562 class BackPointer { | |
563 public: | |
564 typedef CompletionCallbackFactory<T, RefCount> FactoryType; | |
565 | |
566 BackPointer(FactoryType* factory) | |
567 : factory_(factory) { | |
568 } | |
569 | |
570 void AddRef() { | |
571 ref_.AddRef(); | |
572 } | |
573 | |
574 void Release() { | |
575 if (ref_.Release() == 0) | |
576 delete this; | |
577 } | |
578 | |
579 void DropFactory() { | |
580 factory_ = NULL; | |
581 } | |
582 | |
583 T* GetObject() { | |
584 return factory_ ? factory_->GetObject() : NULL; | |
585 } | |
586 | |
587 private: | |
588 RefCount ref_; | |
589 FactoryType* factory_; | |
590 }; | |
591 | |
592 template <typename Dispatcher> | |
593 class CallbackData { | |
594 public: | |
595 CallbackData(BackPointer* back_pointer, const Dispatcher& dispatcher) | |
596 : back_pointer_(back_pointer), | |
597 dispatcher_(dispatcher) { | |
598 back_pointer_->AddRef(); | |
599 } | |
600 | |
601 ~CallbackData() { | |
602 back_pointer_->Release(); | |
603 } | |
604 | |
605 static void Thunk(void* user_data, int32_t result) { | |
606 Self* self = static_cast<Self*>(user_data); | |
607 T* object = self->back_pointer_->GetObject(); | |
608 if (object) | |
609 self->dispatcher_(object, result); | |
610 delete self; | |
611 } | |
612 | |
613 private: | |
614 typedef CallbackData<Dispatcher> Self; | |
615 BackPointer* back_pointer_; | |
616 Dispatcher dispatcher_; | |
617 }; | |
618 | |
619 template <typename Method> | |
620 class Dispatcher0 { | |
621 public: | |
622 Dispatcher0(Method method) : method_(method) { | |
623 } | |
624 void operator()(T* object, int32_t result) { | |
625 (object->*method_)(result); | |
626 } | |
627 private: | |
628 Method method_; | |
629 }; | |
630 | |
631 template <typename Method, typename A> | |
632 class Dispatcher1 { | |
633 public: | |
634 Dispatcher1(Method method, const A& a) | |
635 : method_(method), | |
636 a_(a) { | |
637 } | |
638 void operator()(T* object, int32_t result) { | |
639 (object->*method_)(result, a_); | |
640 } | |
641 private: | |
642 Method method_; | |
643 A a_; | |
644 }; | |
645 | |
646 template <typename Method, typename A, typename B> | |
647 class Dispatcher2 { | |
648 public: | |
649 Dispatcher2(Method method, const A& a, const B& b) | |
650 : method_(method), | |
651 a_(a), | |
652 b_(b) { | |
653 } | |
654 void operator()(T* object, int32_t result) { | |
655 (object->*method_)(result, a_, b_); | |
656 } | |
657 private: | |
658 Method method_; | |
659 A a_; | |
660 B b_; | |
661 }; | |
662 | |
663 template <typename Method, typename A, typename B, typename C> | |
664 class Dispatcher3 { | |
665 public: | |
666 Dispatcher3(Method method, const A& a, const B& b, const C& c) | |
667 : method_(method), | |
668 a_(a), | |
669 b_(b), | |
670 c_(c) { | |
671 } | |
672 void operator()(T* object, int32_t result) { | |
673 (object->*method_)(result, a_, b_, c_); | |
674 } | |
675 private: | |
676 Method method_; | |
677 A a_; | |
678 B b_; | |
679 C c_; | |
680 }; | |
681 | |
682 void InitBackPointer() { | |
683 back_pointer_ = new BackPointer(this); | |
684 back_pointer_->AddRef(); | |
685 } | |
686 | |
687 void ResetBackPointer() { | |
688 back_pointer_->DropFactory(); | |
689 back_pointer_->Release(); | |
690 } | |
691 | |
692 template <typename Dispatcher> | |
693 CompletionCallback NewCallbackHelper(const Dispatcher& dispatcher) { | |
694 PP_DCHECK(object_); // Expects a non-null object! | |
695 return CompletionCallback( | |
696 &CallbackData<Dispatcher>::Thunk, | |
697 new CallbackData<Dispatcher>(back_pointer_, dispatcher)); | |
698 } | |
699 | |
700 // Disallowed: | |
701 CompletionCallbackFactory(const CompletionCallbackFactory&); | |
702 CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); | |
703 | |
704 T* object_; | |
705 BackPointer* back_pointer_; | |
706 }; | |
707 | |
708 } // namespace pp | 159 } // namespace pp |
709 | 160 |
710 #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_ | 161 #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_ |
OLD | NEW |