Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef PPAPI_CPP_MODULE_H_ |
| 6 | #define PPAPI_CPP_MODULE_H_ |
| 7 | |
| 8 | #include <map> |
| 9 | #include <string> |
| 10 | |
| 11 | #include "ppapi/c/pp_instance.h" |
| 12 | #include "ppapi/c/pp_module.h" |
| 13 | #include "ppapi/c/pp_stdint.h" |
| 14 | #include "ppapi/c/ppb.h" |
| 15 | #include "ppapi/c/ppb_core.h" |
| 16 | #include "ppapi/cpp/core.h" |
| 17 | |
| 18 | |
| 19 | /// @file |
| 20 | /// This file defines a Module class. |
| 21 | namespace pp { |
| 22 | |
| 23 | class Instance; |
| 24 | |
| 25 | /// The Module class. The browser calls CreateInstance() to create |
| 26 | /// an instance of your module on the web page. The browser creates a new |
| 27 | /// instance for each <code>\<embed></code> tag with |
| 28 | /// <code>type="application/x-nacl"</code> |
| 29 | class Module { |
| 30 | public: |
| 31 | typedef std::map<PP_Instance, Instance*> InstanceMap; |
| 32 | |
| 33 | // You may not call any other PP functions from the constructor, put them |
| 34 | // in Init instead. Various things will not be set up until the constructor |
| 35 | // completes. |
| 36 | Module(); |
| 37 | virtual ~Module(); |
| 38 | |
| 39 | /// Get() returns the global instance of this module object, or NULL if the |
| 40 | /// module is not initialized yet. |
| 41 | /// |
| 42 | /// @return The global instance of the module object. |
| 43 | static Module* Get(); |
| 44 | |
| 45 | /// Init() is automatically called after the object is created. This is where |
| 46 | /// you can put functions that rely on other parts of the API, now that the |
| 47 | /// module has been created. |
| 48 | /// |
| 49 | /// @return true if successful, otherwise false. |
| 50 | virtual bool Init(); |
| 51 | |
| 52 | /// The pp_module() function returns the internal module handle. |
| 53 | /// |
| 54 | /// @return A <code>PP_Module</code> internal module handle. |
| 55 | PP_Module pp_module() const { return pp_module_; } |
| 56 | |
| 57 | /// The get_browser_interface() function returns the internal |
| 58 | /// <code>get_browser_interface</code> pointer. |
| 59 | /// |
| 60 | /// @return A <code>PPB_GetInterface</code> internal pointer. |
| 61 | // TODO(sehr): This should be removed once the NaCl browser plugin no longer |
| 62 | // needs it. |
| 63 | PPB_GetInterface get_browser_interface() const { |
| 64 | return get_browser_interface_; |
| 65 | } |
| 66 | |
| 67 | /// The core() function returns the core interface for doing basic |
| 68 | /// global operations. The return value is guaranteed to be non-NULL once the |
| 69 | /// module has successfully initialized and during the Init() call. |
| 70 | /// |
| 71 | /// It will be NULL before Init() has been called. |
| 72 | /// |
| 73 | /// @return The core interface for doing basic global operations. |
| 74 | Core* core() { return core_; } |
| 75 | |
| 76 | /// GetPluginInterface() implements <code>GetInterface</code> for the browser |
| 77 | /// to get module interfaces. If you need to provide your own implementations |
| 78 | /// of new interfaces, use AddPluginInterface() which this function will use. |
| 79 | /// |
| 80 | /// @param[in] interface_name The module interface for the browser to get. |
| 81 | const void* GetPluginInterface(const char* interface_name); |
| 82 | |
| 83 | /// GetBrowserInterface() returns interfaces which the browser implements |
| 84 | /// (i.e. PPB interfaces). |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 85 | /// @param[in] interface_name The browser interface for the module to get. |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 86 | const void* GetBrowserInterface(const char* interface_name); |
| 87 | |
| 88 | /// InstanceForPPInstance() returns the object associated with this |
| 89 | /// <code>PP_Instance</code>, or NULL if one is not found. This should only |
| 90 | /// be called from the main thread! This instance object may be destroyed at |
| 91 | /// any time on the main thread, so using it on other threads may cause a |
| 92 | /// crash. |
| 93 | /// |
| 94 | /// @param[in] instance This <code>PP_Instance</code>. |
| 95 | /// |
| 96 | /// @return The object associated with this <code>PP_Instance</code>, |
| 97 | /// or NULL if one is not found. |
| 98 | Instance* InstanceForPPInstance(PP_Instance instance); |
| 99 | |
| 100 | /// AddPluginInterface() adds a handler for a provided interface name. When |
| 101 | /// the browser requests that interface name, the provided |
| 102 | /// <code>vtable</code> will be returned. |
| 103 | /// |
| 104 | /// In general, modules will not need to call this directly. Instead, the |
| 105 | /// C++ wrappers for each interface will register themselves with this |
| 106 | /// function. |
| 107 | /// |
| 108 | /// This function may be called more than once with the same interface name |
| 109 | /// and vtable with no effect. However, it may not be used to register a |
| 110 | /// different vtable for an already-registered interface. It will assert for |
| 111 | /// a different registration for an already-registered interface in debug |
| 112 | /// mode, and just ignore the registration in release mode. |
| 113 | /// |
| 114 | /// @param[in] interface_name The interface name that will receive a handler. |
| 115 | /// @param[in,out] vtable The vtable to return for |
| 116 | /// <code>interface_name</code>. |
| 117 | void AddPluginInterface(const std::string& interface_name, |
| 118 | const void* vtable); |
| 119 | |
| 120 | // InternalInit() sets the browser interface and calls the regular Init() |
| 121 | /// function that can be overridden by the base classes. |
| 122 | /// |
| 123 | /// @param[in] mod A <code>PP_Module</code>. |
| 124 | /// @param[in] get_browser_interface The browser interface to set. |
| 125 | /// |
| 126 | /// @return true if successful, otherwise false. |
| 127 | // TODO(brettw) make this private when I can figure out how to make the |
| 128 | // initialize function a friend. |
| 129 | bool InternalInit(PP_Module mod, |
| 130 | PPB_GetInterface get_browser_interface); |
| 131 | |
| 132 | /// The current_instances() function allows iteration over the |
| 133 | /// current instances in the module. |
| 134 | /// |
| 135 | /// @return An <code>InstanceMap</code> of all instances in the module. |
| 136 | const InstanceMap& current_instances() const { return current_instances_; } |
| 137 | |
| 138 | protected: |
| 139 | /// CreateInstance() should be overridden to create your own module type. |
| 140 | /// |
| 141 | /// @param[in] instance A <code>PP_Instance</code>. |
| 142 | /// |
| 143 | /// @return The resulting instance. |
| 144 | virtual Instance* CreateInstance(PP_Instance instance) = 0; |
| 145 | |
| 146 | private: |
| 147 | friend PP_Bool Instance_DidCreate(PP_Instance pp_instance, |
| 148 | uint32_t argc, |
| 149 | const char* argn[], |
| 150 | const char* argv[]); |
| 151 | friend void Instance_DidDestroy(PP_Instance instance); |
| 152 | |
| 153 | // Unimplemented (disallow copy and assign). |
| 154 | Module(const Module&); |
| 155 | Module& operator=(const Module&); |
| 156 | |
| 157 | // Instance tracking. |
| 158 | InstanceMap current_instances_; |
| 159 | |
| 160 | PP_Module pp_module_; |
| 161 | PPB_GetInterface get_browser_interface_; |
| 162 | |
| 163 | Core* core_; |
| 164 | |
| 165 | // All additional interfaces this plugin can handle as registered by |
| 166 | // AddPluginInterface. |
| 167 | typedef std::map<std::string, const void*> InterfaceMap; |
| 168 | InterfaceMap additional_interfaces_; |
| 169 | }; |
| 170 | |
| 171 | } // namespace pp |
| 172 | |
| 173 | #endif // PPAPI_CPP_MODULE_H_ |