15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/completion_callback.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/utility/completion_callback_factory_thread_traits.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @file 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// This file defines the API to create CompletionCallback objects that are 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// bound to member functions. 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TypeUnwrapper -------------------------------------------------------------- 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The TypeUnwrapper converts references and const references to the 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// underlying type used for storage and passing as an argument. It is for 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// internal use only. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> struct TypeUnwrapper { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef T StorageType; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> struct TypeUnwrapper<T&> { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef T StorageType; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> struct TypeUnwrapper<const T&> { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef T StorageType; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---------------------------------------------------------------------------- 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// CompletionCallbackFactory<T> may be used to create CompletionCallback 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// objects that are bound to member functions. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// If a factory is destroyed, then any pending callbacks will be cancelled 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// preventing any bound member functions from being called. The CancelAll() 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// method allows pending callbacks to be cancelled without destroying the 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// factory. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// <strong>Note: </strong><code>CompletionCallbackFactory<T></code> isn't 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// thread safe, but it is somewhat thread-friendly when used with a 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// thread-safe traits class as the second template element. However, it 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// only guarantees safety for creating a callback from another thread, the 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// callback itself needs to execute on the same thread as the thread that 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// creates/destroys the factory. With this restriction, it is safe to create 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// the <code>CompletionCallbackFactory</code> on the main thread, create 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// callbacks from any thread and pass them to CallOnMainThread(). 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// <strong>Example: </strong> 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @code 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// class MyClass { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// public: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// // If an compiler warns on following using |this| in the initializer 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// // list, use PP_ALLOW_THIS_IN_INITIALIZER_LIST macro. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// MyClass() : factory_(this) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// void OpenFile(const pp::FileRef& file) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// pp::CompletionCallback cc = factory_.NewCallback(&MyClass::DidOpen); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// int32_t rv = file_io_.Open(file, PP_FileOpenFlag_Read, cc); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// CHECK(rv == PP_OK_COMPLETIONPENDING); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// private: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// void DidOpen(int32_t result) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// if (result == PP_OK) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// // The file is open, and we can begin reading. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// // ... 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } else { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// // Failed to open the file with error given by 'result'. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// pp::CompletionCallbackFactory<MyClass> factory_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// }; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @endcode 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// <strong>Passing additional parameters to your callback</strong> 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// As a convenience, the <code>CompletionCallbackFactory</code> can optionally 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// create a closure with up to three bound parameters that it will pass to 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// your callback function. This can be useful for passing information about 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// the request to your callback function, which is especially useful if your 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// class has multiple asynchronous callbacks pending. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// For the above example, of opening a file, let's say you want to keep some 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// description associated with your request, you might implement your OpenFile 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// and DidOpen callback as follows: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @code 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// void OpenFile(const pp::FileRef& file) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// std::string message = "Opening file!"; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// pp::CompletionCallback cc = factory_.NewCallback(&MyClass::DidOpen, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// message); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// int32_t rv = file_io_.Open(file, PP_FileOpenFlag_Read, cc); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// CHECK(rv == PP_OK_COMPLETIONPENDING); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// void DidOpen(int32_t result, const std::string& message) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// // "message" will be "Opening file!". 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// ... 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @endcode 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// <strong>Optional versus required callbacks</strong> 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// When you create an "optional" callback, the browser may return the results 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// synchronously if they are available. This can allow for higher performance 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// in some cases if data is available quickly (for example, for network loads 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// where there may be a lot of data coming quickly). In this case, the 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// callback will never be run. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// When creating a new callback with the factory, there will be data allocated 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// on the heap that tracks the callback information and any bound arguments. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// This data is freed when the callback executes. In the case of optional 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// callbacks, since the browser will never issue the callback, the internal 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// tracking data will be leaked. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Therefore, if you use optional callbacks, it's important to manually 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// issue the callback to free up this data. The typical pattern is: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @code 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// pp::CompletionCallback callback = callback_factory.NewOptionalCallback( 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// &MyClass::OnDataReady); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// int32_t result = interface->GetData(callback); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// if (result != PP_OK_COMPLETIONPENDING) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// callback.Run(result); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @endcode 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Because of this additional complexity, it's generally recommended that 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// you not use optional callbacks except when performance is more important 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// (such as loading large resources from the network). In most other cases, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// the performance difference will not be worth the additional complexity, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// and most functions may never actually have the ability to complete 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// synchronously. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// <strong>Completion callbacks with output</strong> 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// For some API calls, the browser returns data to the caller via an output 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// parameter. These can be difficult to manage since the output parameter 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// must remain valid for as long as the callback is pending. Note also that 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// CancelAll (or destroying the callback factory) does <i>not</i> cancel the 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// callback from the browser's perspective, only the execution of the callback 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// in the plugin code, and the output parameter will still be written to! 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// This means that you can't use class members as output parameters without 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// risking crashes. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// To make this case easier, the CompletionCallbackFactory can allocate and 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// manage the output data for you and pass it to your callback function. This 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// makes such calls more natural and less error-prone. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// To create such a callback, use NewCallbackWithOutput and specify a callback 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// function that takes the output parameter as its second argument. Let's say 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// you're calling a function GetFile which asynchronously returns a 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// pp::FileRef. GetFile's signature will be <code>int32_t GetFile(const 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// CompletionCallbackWithOutput<pp::FileRef>& callback);</code> and your 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// calling code would look like this: 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @code 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// void RequestFile() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// file_interface->GetFile(callback_factory_.NewCallbackWithOutput( 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// &MyClass::GotFile)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// void GotFile(int32_t result, const pp::FileRef& file) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// if (result == PP_OK) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// ...use file... 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } else { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// ...handle error... 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// @endcode 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// As with regular completion callbacks, you can optionally add up to three 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// bound arguments. These are passed following the output argument. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Your callback may take the output argument as a copy (common for small 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// types like integers, a const reference (common for structures and 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// resources to avoid an extra copy), or as a non-const reference. One 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// optimization you can do if your callback function may take large arrays 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// is to accept your output argument as a non-const reference and to swap() 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// the argument with a vector of your own to store it. This means you don't 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// have to copy the buffer to consume it. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T, typename ThreadTraits = ThreadSafeThreadTraits> 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CompletionCallbackFactory { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// This constructor creates a <code>CompletionCallbackFactory</code> 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// bound to an object. If the constructor is called without an argument, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// the default value of <code>NULL</code> is used. The user then must call 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Initialize() to initialize the object. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// param[in] object Optional parameter. An object whose member functions 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// are to be bound to CompletionCallbacks created by this 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallbackFactory</code>. The default value of this 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// parameter is <code>NULL</code>. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit CompletionCallbackFactory(T* object = NULL) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : object_(object) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assume that we don't need to lock since construction should be complete 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before the pointer is used on another thread. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitBackPointer(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Destructor. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~CompletionCallbackFactory() { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assume that we don't need to lock since this object should not be used 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from multiple threads during destruction. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetBackPointer(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CancelAll() cancels all <code>CompletionCallbacks</code> allocated from 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// this factory. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelAll() { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename ThreadTraits::AutoLock lock(lock_); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetBackPointer(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitBackPointer(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Initialize() binds the <code>CallbackFactory</code> to a particular 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// object. Use this when the object is not available at 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CallbackFactory</code> creation, and the <code>NULL</code> default 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// is passed to the constructor. The object may only be initialized once, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// either by the constructor, or by a call to Initialize(). 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// This class may not be used on any thread until initialization is complete. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] object The object whose member functions are to be bound to 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// the <code>CompletionCallback</code> created by this 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallbackFactory</code>. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Initialize(T* object) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_DCHECK(object); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_DCHECK(!object_); // May only initialize once! 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_ = object; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// GetObject() returns the object that was passed at initialization to 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Intialize(). 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return the object passed to the constructor or Intialize(). 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* GetObject() { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return object_; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewCallback allocates a new, single-use <code>CompletionCallback</code>. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// The <code>CompletionCallback</code> must be run in order for the memory 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// allocated by the methods to be freed. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method to be invoked upon completion of the 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// operation. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method> 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewCallback(Method method) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NewCallbackHelper(new Dispatcher0<Method>(method)); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewOptionalCallback() allocates a new, single-use 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> that might not run if the method 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// taking it can complete synchronously. Thus, if after passing the 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CompletionCallback to a Pepper method, the method does not return 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// PP_OK_COMPLETIONPENDING, then you should manually call the 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CompletionCallback's Run method, or memory will be leaked. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method to be invoked upon completion of the 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// operation. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method> 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewOptionalCallback(Method method) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback cc = NewCallback(method); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cc; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewCallbackWithOutput() allocates a new, single-use 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> where the browser will pass an additional 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// parameter containing the result of the request. The 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> must be run in order for the memory 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// allocated by the methods to be freed. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method to be invoked upon completion of the 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// operation. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Output> 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallbackWithOutput< 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename internal::TypeUnwrapper<Output>::StorageType> 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewCallbackWithOutput(void (T::*method)(int32_t, Output)) { 2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NewCallbackWithOutputHelper(new DispatcherWithOutput0< 2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename internal::TypeUnwrapper<Output>::StorageType, 2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void (T::*)(int32_t, Output)>(method)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewCallback() allocates a new, single-use <code>CompletionCallback</code>. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// The <code>CompletionCallback</code> must be run in order for the memory 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// allocated by the methods to be freed. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method to be invoked upon completion of the 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// operation. Method should be of type: 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>void (T::*)(int32_t result, const A& a)</code> 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A> 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewCallback(Method method, const A& a) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NewCallbackHelper(new Dispatcher1<Method, A>(method, a)); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewOptionalCallback() allocates a new, single-use 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> that might not run if the method 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// taking it can complete synchronously. Thus, if after passing the 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CompletionCallback to a Pepper method, the method does not return 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// PP_OK_COMPLETIONPENDING, then you should manually call the 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CompletionCallback's Run method, or memory will be leaked. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method to be invoked upon completion of the 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// operation. Method should be of type: 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>void (T::*)(int32_t result, const A& a)</code> 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A> 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewOptionalCallback(Method method, const A& a) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback cc = NewCallback(method, a); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cc; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewCallbackWithOutput() allocates a new, single-use 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> where the browser will pass an additional 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// parameter containing the result of the request. The 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> must be run in order for the memory 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// allocated by the methods to be freed. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method to be invoked upon completion of the 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// operation. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Output, typename A> 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallbackWithOutput< 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename internal::TypeUnwrapper<Output>::StorageType> 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewCallbackWithOutput(void (T::*method)(int32_t, Output, A), 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const A& a) { 3565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NewCallbackWithOutputHelper(new DispatcherWithOutput1< 3575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename internal::TypeUnwrapper<Output>::StorageType, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (T::*)(int32_t, Output, A), 3595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename internal::TypeUnwrapper<A>::StorageType>(method, a)); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewCallback() allocates a new, single-use 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code>. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// The <code>CompletionCallback</code> must be run in order for the memory 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// allocated by the methods to be freed. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param method The method taking the callback. Method should be of type: 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code> 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] b Passed to <code>method</code> when the completion callback 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A, typename B> 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewCallback(Method method, const A& a, const B& b) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NewCallbackHelper(new Dispatcher2<Method, A, B>(method, a, b)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewOptionalCallback() allocates a new, single-use 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> that might not run if the method 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// taking it can complete synchronously. Thus, if after passing the 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CompletionCallback to a Pepper method, the method does not return 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// PP_OK_COMPLETIONPENDING, then you should manually call the 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CompletionCallback's Run method, or memory will be leaked. 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method taking the callback. Method should be of 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// type: 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>void (T::*)(int32_t result, const A& a, const B& b)</code> 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] b Passed to <code>method</code> when the completion callback 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A, typename B> 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewOptionalCallback(Method method, const A& a, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const B& b) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback cc = NewCallback(method, a, b); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cc; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewCallbackWithOutput() allocates a new, single-use 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> where the browser will pass an additional 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// parameter containing the result of the request. The 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> must be run in order for the memory 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// allocated by the methods to be freed. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method to be invoked upon completion of the 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// operation. 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] b Passed to <code>method</code> when the completion callback 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Output, typename A, typename B> 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallbackWithOutput< 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename internal::TypeUnwrapper<Output>::StorageType> 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewCallbackWithOutput(void (T::*method)(int32_t, Output, A, B), 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const A& a, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const B& b) { 4305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NewCallbackWithOutputHelper(new DispatcherWithOutput2< 4315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename internal::TypeUnwrapper<Output>::StorageType, 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (T::*)(int32_t, Output, A, B), 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename internal::TypeUnwrapper<A>::StorageType, 4345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename internal::TypeUnwrapper<B>::StorageType>(method, a, b)); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewCallback() allocates a new, single-use 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code>. 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// The <code>CompletionCallback</code> must be run in order for the memory 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// allocated by the methods to be freed. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param method The method taking the callback. Method should be of type: 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code> 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// void (T::*)(int32_t result, const A& a, const B& b, const C& c) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </code> 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] b Passed to <code>method</code> when the completion callback 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] c Passed to <code>method</code> when the completion callback 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A, typename B, typename C> 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewCallback(Method method, const A& a, const B& b, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const C& c) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NewCallbackHelper(new Dispatcher3<Method, A, B, C>(method, a, b, c)); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewOptionalCallback() allocates a new, single-use 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> that might not run if the method 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// taking it can complete synchronously. Thus, if after passing the 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CompletionCallback to a Pepper method, the method does not return 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// PP_OK_COMPLETIONPENDING, then you should manually call the 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// CompletionCallback's Run method, or memory will be leaked. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] method The method taking the callback. Method should be of 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// type: 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code> 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// void (T::*)(int32_t result, const A& a, const B& b, const C& c) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// </code> 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] b Passed to <code>method</code> when the completion callback 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] c Passed to <code>method</code> when the completion callback 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A, typename B, typename C> 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewOptionalCallback(Method method, const A& a, 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const B& b, const C& c) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback cc = NewCallback(method, a, b, c); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc.set_flags(cc.flags() | PP_COMPLETIONCALLBACK_FLAG_OPTIONAL); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cc; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// NewCallbackWithOutput() allocates a new, single-use 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> where the browser will pass an additional 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// parameter containing the result of the request. The 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// <code>CompletionCallback</code> must be run in order for the memory 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// allocated by the methods to be freed. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param method The method to be run. 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] a Passed to <code>method</code> when the completion callback 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] b Passed to <code>method</code> when the completion callback 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @param[in] c Passed to <code>method</code> when the completion callback 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// runs. 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @return A <code>CompletionCallback</code>. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Output, typename A, typename B, typename C> 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallbackWithOutput< 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename internal::TypeUnwrapper<Output>::StorageType> 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewCallbackWithOutput(void (T::*method)(int32_t, Output, A, B, C), 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const A& a, 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const B& b, 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const C& c) { 5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NewCallbackWithOutputHelper(new DispatcherWithOutput3< 5205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename internal::TypeUnwrapper<Output>::StorageType, 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (T::*)(int32_t, Output, A, B, C), 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename internal::TypeUnwrapper<A>::StorageType, 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename internal::TypeUnwrapper<B>::StorageType, 5245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename internal::TypeUnwrapper<C>::StorageType>(method, a, b, c)); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class BackPointer { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef CompletionCallbackFactory<T, ThreadTraits> FactoryType; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit BackPointer(FactoryType* factory) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : factory_(factory) { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddRef() { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_.AddRef(); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Release() { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ref_.Release() == 0) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DropFactory() { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) factory_ = NULL; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* GetObject() { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return factory_ ? factory_->GetObject() : NULL; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename ThreadTraits::RefCount ref_; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FactoryType* factory_; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Dispatcher> 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class CallbackData { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Takes ownership of the given dispatcher pointer. 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallbackData(BackPointer* back_pointer, Dispatcher* dispatcher) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : back_pointer_(back_pointer), 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispatcher_(dispatcher) { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_pointer_->AddRef(); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~CallbackData() { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_pointer_->Release(); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete dispatcher_; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher* dispatcher() { return dispatcher_; } 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Thunk(void* user_data, int32_t result) { 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Self* self = static_cast<Self*>(user_data); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* object = self->back_pointer_->GetObject(); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Please note that |object| may be NULL at this point. But we still need 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to call into Dispatcher::operator() in that case, so that it can do 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // necessary cleanup. 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*self->dispatcher_)(object, result); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete self; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef CallbackData<Dispatcher> Self; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BackPointer* back_pointer_; // We own a ref to this refcounted object. 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher* dispatcher_; // We own this pointer. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disallow copying & assignment. 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallbackData(const CallbackData<Dispatcher>&); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallbackData<Dispatcher>& operator=(const CallbackData<Dispatcher>&); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method> 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Dispatcher0 { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher0() : method_(NULL) {} 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit Dispatcher0(Method method) : method_(method) { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(T* object, int32_t result) { 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (object->*method_)(result); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Method method_; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu template <typename Output, typename Method> 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DispatcherWithOutput0 { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef Output OutputType; 6155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typedef internal::CallbackOutputTraits<Output> Traits; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatcherWithOutput0() 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(NULL), 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_() { 6207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Traits::Initialize(&output_); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatcherWithOutput0(Method method) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(method), 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_() { 6257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Traits::Initialize(&output_); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(T* object, int32_t result) { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We must call Traits::StorageToPluginArg() even if we don't need to call 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the callback anymore, otherwise we may leak resource or var references. 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (object->*method_)(result, Traits::StorageToPluginArg(output_)); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Traits::StorageToPluginArg(output_); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename Traits::StorageType* output() { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &output_; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Method method_; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename Traits::StorageType output_; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A> 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Dispatcher1 { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher1() 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(NULL), 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_() { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher1(Method method, const A& a) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(method), 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(a) { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(T* object, int32_t result) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (object->*method_)(result, a_); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Method method_; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A a_; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu template <typename Output, typename Method, typename A> 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DispatcherWithOutput1 { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef Output OutputType; 6685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typedef internal::CallbackOutputTraits<Output> Traits; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatcherWithOutput1() 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(NULL), 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(), 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_() { 6747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Traits::Initialize(&output_); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatcherWithOutput1(Method method, const A& a) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(method), 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(a), 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_() { 6807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Traits::Initialize(&output_); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(T* object, int32_t result) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We must call Traits::StorageToPluginArg() even if we don't need to call 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the callback anymore, otherwise we may leak resource or var references. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (object->*method_)(result, Traits::StorageToPluginArg(output_), a_); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Traits::StorageToPluginArg(output_); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename Traits::StorageType* output() { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &output_; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Method method_; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A a_; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename Traits::StorageType output_; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A, typename B> 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Dispatcher2 { 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher2() 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(NULL), 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(), 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b_() { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher2(Method method, const A& a, const B& b) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(method), 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(a), 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b_(b) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(T* object, int32_t result) { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (object->*method_)(result, a_, b_); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Method method_; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A a_; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B b_; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu template <typename Output, typename Method, typename A, typename B> 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DispatcherWithOutput2 { 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef Output OutputType; 7275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typedef internal::CallbackOutputTraits<Output> Traits; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatcherWithOutput2() 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(NULL), 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(), 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b_(), 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_() { 7347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Traits::Initialize(&output_); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatcherWithOutput2(Method method, const A& a, const B& b) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(method), 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(a), 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b_(b), 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_() { 7417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Traits::Initialize(&output_); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(T* object, int32_t result) { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We must call Traits::StorageToPluginArg() even if we don't need to call 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the callback anymore, otherwise we may leak resource or var references. 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (object->*method_)(result, Traits::StorageToPluginArg(output_), a_, b_); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Traits::StorageToPluginArg(output_); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename Traits::StorageType* output() { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &output_; 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Method method_; 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A a_; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B b_; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename Traits::StorageType output_; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Method, typename A, typename B, typename C> 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Dispatcher3 { 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher3() 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(NULL), 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(), 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b_(), 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c_() { 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Dispatcher3(Method method, const A& a, const B& b, const C& c) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(method), 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(a), 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b_(b), 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c_(c) { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(T* object, int32_t result) { 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (object->*method_)(result, a_, b_, c_); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Method method_; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A a_; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B b_; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C c_; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu template <typename Output, typename Method, typename A, typename B, 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename C> 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DispatcherWithOutput3 { 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef Output OutputType; 7935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typedef internal::CallbackOutputTraits<Output> Traits; 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatcherWithOutput3() 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(NULL), 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(), 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b_(), 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c_(), 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_() { 8017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Traits::Initialize(&output_); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatcherWithOutput3(Method method, const A& a, const B& b, const C& c) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : method_(method), 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_(a), 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b_(b), 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c_(c), 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_() { 8097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Traits::Initialize(&output_); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator()(T* object, int32_t result) { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We must call Traits::StorageToPluginArg() even if we don't need to call 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the callback anymore, otherwise we may leak resource or var references. 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (object) { 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (object->*method_)(result, Traits::StorageToPluginArg(output_), 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a_, b_, c_); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Traits::StorageToPluginArg(output_); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename Traits::StorageType* output() { 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &output_; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Method method_; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A a_; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) B b_; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) C c_; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename Traits::StorageType output_; 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates the back pointer object and takes a reference to it. This assumes 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either that the lock is held or that it is not needed. 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitBackPointer() { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_pointer_ = new BackPointer(this); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_pointer_->AddRef(); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Releases our reference to the back pointer object and clears the pointer. 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This assumes either that the lock is held or that it is not needed. 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetBackPointer() { 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_pointer_->DropFactory(); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_pointer_->Release(); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) back_pointer_ = NULL; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Takes ownership of the dispatcher pointer, which should be heap allocated. 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Dispatcher> 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback NewCallbackHelper(Dispatcher* dispatcher) { 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename ThreadTraits::AutoLock lock(lock_); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_DCHECK(object_); // Expects a non-null object! 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CompletionCallback( 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CallbackData<Dispatcher>::Thunk, 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CallbackData<Dispatcher>(back_pointer_, dispatcher)); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Takes ownership of the dispatcher pointer, which should be heap allocated. 8605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu template <typename Dispatcher> CompletionCallbackWithOutput< 8615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename internal::TypeUnwrapper< 8625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typename Dispatcher::OutputType>::StorageType> 8635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NewCallbackWithOutputHelper(Dispatcher* dispatcher) { 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename ThreadTraits::AutoLock lock(lock_); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_DCHECK(object_); // Expects a non-null object! 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallbackData<Dispatcher>* data = 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CallbackData<Dispatcher>(back_pointer_, dispatcher); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return CompletionCallbackWithOutput<typename Dispatcher::OutputType>( 8715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &CallbackData<Dispatcher>::Thunk, 8725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu data, 8735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu data->dispatcher()->output()); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disallowed: 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallbackFactory(const CompletionCallbackFactory&); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallbackFactory& operator=(const CompletionCallbackFactory&); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Never changed once initialized so does not need protection by the lock. 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* object_; 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Protects the back pointer. 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename ThreadTraits::Lock lock_; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Protected by the lock. This will get reset when you do CancelAll, for 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // example. 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BackPointer* back_pointer_; 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace pp 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // PPAPI_UTILITY_COMPLETION_CALLBACK_FACTORY_H_ 894