diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 22:50:33 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 22:50:33 +0000 |
commit | ae5ff9ae378480a54511e007541b62b5d9ea94bf (patch) | |
tree | ed127f19d1125bb9f94b8b54e03fa32fbac634b1 /ppapi/cpp/completion_callback.h | |
parent | afc72b46447cc5a5fe181552318fc7bd76d1ffa6 (diff) | |
download | chromium_src-ae5ff9ae378480a54511e007541b62b5d9ea94bf.zip chromium_src-ae5ff9ae378480a54511e007541b62b5d9ea94bf.tar.gz chromium_src-ae5ff9ae378480a54511e007541b62b5d9ea94bf.tar.bz2 |
Move paint aggregator and the completion callback factory.
[Reland of 116281]
Move paint aggregator and the completion callback factory to the ppapi/helpers directory since they're not strictly wrappers.
Review URL: http://codereview.chromium.org/9030001
Review URL: http://codereview.chromium.org/9122012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@116759 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/cpp/completion_callback.h')
-rw-r--r-- | ppapi/cpp/completion_callback.h | 551 |
1 files changed, 1 insertions, 550 deletions
diff --git a/ppapi/cpp/completion_callback.h b/ppapi/cpp/completion_callback.h index 2e5f38b..b4564e1 100644 --- a/ppapi/cpp/completion_callback.h +++ b/ppapi/cpp/completion_callback.h @@ -8,7 +8,7 @@ #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/cpp/logging.h" -#include "ppapi/cpp/non_thread_safe_ref_count.h" +#include "ppapi/cpp/module.h" /// @file /// This file defines the API to create and run a callback. @@ -156,555 +156,6 @@ class CompletionCallback { /// @return A <code>CompletionCallback</code> corresponding to a NULL callback. CompletionCallback BlockUntilComplete(); -/// CompletionCallbackFactory<T> may be used to create CompletionCallback -/// objects that are bound to member functions. -/// -/// If a factory is destroyed, then any pending callbacks will be cancelled -/// preventing any bound member functions from being called. The CancelAll() -/// method allows pending callbacks to be cancelled without destroying the -/// factory. -/// -/// <strong>Note: </strong><code>CompletionCallbackFactory<T></code> isn't -/// thread safe, but you can make it more thread-friendly by passing a -/// thread-safe refcounting class as the second template element. However, it -/// only guarantees safety for creating a callback from another thread, the -/// callback itself needs to execute on the same thread as the thread that -/// creates/destroys the factory. With this restriction, it is safe to create -/// the <code>CompletionCallbackFactory</code> on the main thread, create -/// callbacks from any thread and pass them to CallOnMainThread(). -/// -/// <strong>Example: </strong> -/// -/// @code -/// -/// class MyHandler { -/// public: -/// // If an compiler warns on following using |this| in the initializer -/// // list, use PP_ALLOW_THIS_IN_INITIALIZER_LIST macro. -/// MyHandler() : factory_(this), offset_(0) { -/// } -/// -/// void ProcessFile(const FileRef& file) { -/// CompletionCallback cc = factory_.NewRequiredCallback( -/// &MyHandler::DidOpen); -/// int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc); -/// CHECK(rv == PP_OK_COMPLETIONPENDING); -/// } -/// -/// private: -/// CompletionCallback NewCallback() { -/// return factory_.NewCallback(&MyHandler::DidCompleteIO); -/// } -/// -/// void DidOpen(int32_t result) { -/// if (result == PP_OK) { -/// // The file is open, and we can begin reading. -/// offset_ = 0; -/// ReadMore(); -/// } else { -/// // Failed to open the file with error given by 'result'. -/// } -/// } -/// -/// void DidRead(int32_t result) { -/// if (result > 0) { -/// // buf_ now contains 'result' number of bytes from the file. -/// ProcessBytes(buf_, result); -/// offset_ += result; -/// ReadMore(); -/// } else { -/// // Done reading (possibly with an error given by 'result'). -/// } -/// } -/// -/// void ReadMore() { -/// CompletionCallback cc = -/// factory_.NewOptionalCallback(&MyHandler::DidRead); -/// int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), -/// cc.pp_completion_callback()); -/// if (rv != PP_OK_COMPLETIONPENDING) -/// cc.Run(rv); -/// } -/// -/// void ProcessBytes(const char* bytes, int32_t length) { -/// // Do work ... -/// } -/// -/// pp::CompletionCallbackFactory<MyHandler> factory_; -/// pp::FileIO fio_; -/// char buf_[4096]; -/// int64_t offset_; -/// }; -/// -/// @endcode -/// -template <typename T, typename RefCount = NonThreadSafeRefCount> -class CompletionCallbackFactory { - public: - - /// This constructor creates a <code>CompletionCallbackFactory</code> - /// bound to an object. If the constructor is called without an argument, - /// the default value of <code>NULL</code> is used. The user then must call - /// Initialize() to initialize the object. - /// - /// param[in] object Optional parameter. An object whose member functions - /// are to be bound to CompletionCallbacks created by this - /// <code>CompletionCallbackFactory</code>. The default value of this - /// parameter is <code>NULL</code>. - explicit CompletionCallbackFactory(T* object = NULL) - : object_(object) { - InitBackPointer(); - } - - /// Destructor. - ~CompletionCallbackFactory() { - ResetBackPointer(); - } - - /// CancelAll() cancels all <code>CompletionCallbacks</code> allocated from - /// this factory. - void CancelAll() { - ResetBackPointer(); - InitBackPointer(); - } - /// Initialize() binds the <code>CallbackFactory</code> to a particular - /// object. Use this when the object is not available at - /// <code>CallbackFactory</code> creation, and the <code>NULL</code> default - /// is passed to the constructor. The object may only be initialized once, - /// either by the constructor, or by a call to Initialize(). - /// - /// @param[in] object The object whose member functions are to be bound to - /// the <code>CompletionCallback</code> created by this - /// <code>CompletionCallbackFactory</code>. - void Initialize(T* object) { - PP_DCHECK(object); - PP_DCHECK(!object_); // May only initialize once! - object_ = object; - } - - /// GetObject() returns the object that was passed at initialization to - /// Intialize(). - /// - /// @return the object passed to the constructor or Intialize(). - T* GetObject() { - return object_; - } - - /// NewCallback allocates a new, single-use <code>CompletionCallback</code>. - /// The <code>CompletionCallback</code> must be run in order for the memory - /// allocated by the methods to be freed. - /// NewCallback() is equivalent to NewRequiredCallback() below. - /// - /// @param[in] method The method to be invoked upon completion of the - /// operation. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method> - CompletionCallback NewCallback(Method method) { - PP_DCHECK(object_); - return NewCallbackHelper(Dispatcher0<Method>(method)); - } - - /// NewRequiredCallback() allocates a new, single-use - /// <code>CompletionCallback</code> that will always run. The - /// <code>CompletionCallback</code> must be run in order for the memory - /// allocated by the methods to be freed. - /// - /// @param[in] method The method to be invoked upon completion of the - /// operation. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method> - CompletionCallback NewRequiredCallback(Method method) { - CompletionCallback cc = NewCallback(method); - cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); - return cc; - } - - /// NewOptionalCallback() allocates a new, single-use - /// <code>CompletionCallback</code> that might not run if the method - /// taking it can complete synchronously. Thus, if after passing the - /// CompletionCallback to a Pepper method, the method does not return - /// PP_OK_COMPLETIONPENDING, then you should manually call the - /// CompletionCallback's Run method, or memory will be leaked. - /// - /// @param[in] method The method to be invoked upon completion of the - /// operation. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method> - CompletionCallback NewOptionalCallback(Method method) { - CompletionCallback cc = NewCallback(method); - cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); - return cc; - } - - /// NewCallback() allocates a new, single-use <code>CompletionCallback</code>. - /// The <code>CompletionCallback</code> must be run in order for the memory - /// allocated by the methods to be freed. - /// NewCallback() is equivalent to NewRequiredCallback() below. - /// - /// @param[in] method The method to be invoked upon completion of the - /// operation. Method should be of type: - /// <code>void (T::*)(int32_t result, const A& a)</code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A> - CompletionCallback NewCallback(Method method, const A& a) { - PP_DCHECK(object_); - return NewCallbackHelper(Dispatcher1<Method, A>(method, a)); - } - - /// NewRequiredCallback() allocates a new, single-use - /// <code>CompletionCallback</code> that will always run. The - /// <code>CompletionCallback</code> must be run in order for the memory - /// allocated by the methods to be freed. - /// - /// @param[in] method The method to be invoked upon completion of the - /// operation. Method should be of type: - /// <code>void (T::*)(int32_t result, const A& a)</code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A> - CompletionCallback NewRequiredCallback(Method method, const A& a) { - CompletionCallback cc = NewCallback(method, a); - cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); - return cc; - } - - /// NewOptionalCallback() allocates a new, single-use - /// <code>CompletionCallback</code> that might not run if the method - /// taking it can complete synchronously. Thus, if after passing the - /// CompletionCallback to a Pepper method, the method does not return - /// PP_OK_COMPLETIONPENDING, then you should manually call the - /// CompletionCallback's Run method, or memory will be leaked. - /// - /// @param[in] method The method to be invoked upon completion of the - /// operation. Method should be of type: - /// <code>void (T::*)(int32_t result, const A& a)</code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A> - CompletionCallback NewOptionalCallback(Method method, const A& a) { - CompletionCallback cc = NewCallback(method, a); - cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); - return cc; - } - - /// NewCallback() allocates a new, single-use - /// <code>CompletionCallback</code>. - /// The <code>CompletionCallback</code> must be run in order for the memory - /// allocated by the methods to be freed. - /// NewCallback() is equivalent to NewRequiredCallback() below. - /// - /// @param method The method taking the callback. Method should be of type: - /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] b Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A, typename B> - CompletionCallback NewCallback(Method method, const A& a, const B& b) { - PP_DCHECK(object_); - return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b)); - } - - /// NewRequiredCallback() allocates a new, single-use - /// <code>CompletionCallback</code> that will always run. The - /// <code>CompletionCallback</code> must be run in order for the memory - /// allocated by the methods to be freed. - /// - /// @param method The method taking the callback. Method should be of type: - /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] b Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A, typename B> - CompletionCallback NewRequiredCallback(Method method, const A& a, - const B& b) { - CompletionCallback cc = NewCallback(method, a, b); - cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); - return cc; - } - - /// NewOptionalCallback() allocates a new, single-use - /// <code>CompletionCallback</code> that might not run if the method - /// taking it can complete synchronously. Thus, if after passing the - /// CompletionCallback to a Pepper method, the method does not return - /// PP_OK_COMPLETIONPENDING, then you should manually call the - /// CompletionCallback's Run method, or memory will be leaked. - /// - /// @param[in] method The method taking the callback. Method should be of - /// type: - /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] b Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A, typename B> - CompletionCallback NewOptionalCallback(Method method, const A& a, - const B& b) { - CompletionCallback cc = NewCallback(method, a, b); - cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); - return cc; - } - - /// NewCallback() allocates a new, single-use - /// <code>CompletionCallback</code>. - /// The <code>CompletionCallback</code> must be run in order for the memory - /// allocated by the methods to be freed. - /// NewCallback() is equivalent to NewRequiredCallback() below. - /// - /// @param method The method taking the callback. Method should be of type: - /// <code> - /// void (T::*)(int32_t result, const A& a, const B& b, const C& c) - /// </code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] b Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] c Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A, typename B, typename C> - CompletionCallback NewCallback(Method method, const A& a, const B& b, - const C& c) { - PP_DCHECK(object_); - return NewCallbackHelper(Dispatcher3<Method, A, B, C>(method, a, b, c)); - } - - /// NewRequiredCallback() allocates a new, single-use - /// <code>CompletionCallback</code> that will always run. The - /// <code>CompletionCallback</code> must be run in order for the memory - /// allocated by the methods to be freed. - /// - /// @param method The method taking the callback. Method should be of type: - /// <code> - /// void (T::*)(int32_t result, const A& a, const B& b, const C& c) - /// </code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] b Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] c Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A, typename B, typename C> - CompletionCallback NewRequiredCallback(Method method, const A& a, - const B& b, const C& c) { - CompletionCallback cc = NewCallback(method, a, b, c); - cc.set_flags(cc.flags() & ~PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); - return cc; - } - - /// NewOptionalCallback() allocates a new, single-use - /// <code>CompletionCallback</code> that might not run if the method - /// taking it can complete synchronously. Thus, if after passing the - /// CompletionCallback to a Pepper method, the method does not return - /// PP_OK_COMPLETIONPENDING, then you should manually call the - /// CompletionCallback's Run method, or memory will be leaked. - /// - /// @param[in] method The method taking the callback. Method should be of - /// type: - /// <code> - /// void (T::*)(int32_t result, const A& a, const B& b, const C& c) - /// </code> - /// - /// @param[in] a Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] b Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @param[in] c Passed to <code>method</code> when the completion callback - /// runs. - /// - /// @return A <code>CompletionCallback</code>. - template <typename Method, typename A, typename B, typename C> - CompletionCallback NewOptionalCallback(Method method, const A& a, - const B& b, const C& c) { - CompletionCallback cc = NewCallback(method, a, b, c); - cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); - return cc; - } - - private: - class BackPointer { - public: - typedef CompletionCallbackFactory<T, RefCount> FactoryType; - - BackPointer(FactoryType* factory) - : factory_(factory) { - } - - void AddRef() { - ref_.AddRef(); - } - - void Release() { - if (ref_.Release() == 0) - delete this; - } - - void DropFactory() { - factory_ = NULL; - } - - T* GetObject() { - return factory_ ? factory_->GetObject() : NULL; - } - - private: - RefCount ref_; - FactoryType* factory_; - }; - - template <typename Dispatcher> - class CallbackData { - public: - CallbackData(BackPointer* back_pointer, const Dispatcher& dispatcher) - : back_pointer_(back_pointer), - dispatcher_(dispatcher) { - back_pointer_->AddRef(); - } - - ~CallbackData() { - back_pointer_->Release(); - } - - static void Thunk(void* user_data, int32_t result) { - Self* self = static_cast<Self*>(user_data); - T* object = self->back_pointer_->GetObject(); - if (object) - self->dispatcher_(object, result); - delete self; - } - - private: - typedef CallbackData<Dispatcher> Self; - BackPointer* back_pointer_; - Dispatcher dispatcher_; - }; - - template <typename Method> - class Dispatcher0 { - public: - Dispatcher0(Method method) : method_(method) { - } - void operator()(T* object, int32_t result) { - (object->*method_)(result); - } - private: - Method method_; - }; - - template <typename Method, typename A> - class Dispatcher1 { - public: - Dispatcher1(Method method, const A& a) - : method_(method), - a_(a) { - } - void operator()(T* object, int32_t result) { - (object->*method_)(result, a_); - } - private: - Method method_; - A a_; - }; - - template <typename Method, typename A, typename B> - class Dispatcher2 { - public: - Dispatcher2(Method method, const A& a, const B& b) - : method_(method), - a_(a), - b_(b) { - } - void operator()(T* object, int32_t result) { - (object->*method_)(result, a_, b_); - } - private: - Method method_; - A a_; - B b_; - }; - - template <typename Method, typename A, typename B, typename C> - class Dispatcher3 { - public: - Dispatcher3(Method method, const A& a, const B& b, const C& c) - : method_(method), - a_(a), - b_(b), - c_(c) { - } - void operator()(T* object, int32_t result) { - (object->*method_)(result, a_, b_, c_); - } - private: - Method method_; - A a_; - B b_; - C c_; - }; - - void InitBackPointer() { - back_pointer_ = new BackPointer(this); - back_pointer_->AddRef(); - } - - void ResetBackPointer() { - back_pointer_->DropFactory(); - back_pointer_->Release(); - } - - template <typename Dispatcher> - CompletionCallback NewCallbackHelper(const Dispatcher& dispatcher) { - PP_DCHECK(object_); // Expects a non-null object! - return CompletionCallback( - &CallbackData<Dispatcher>::Thunk, - new CallbackData<Dispatcher>(back_pointer_, dispatcher)); - } - - // Disallowed: - CompletionCallbackFactory(const CompletionCallbackFactory&); - CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); - - T* object_; - BackPointer* back_pointer_; -}; - } // namespace pp #endif // PPAPI_CPP_COMPLETION_CALLBACK_H_ |