| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef PPAPI_CPP_MODULE_H_ | 
 | #define PPAPI_CPP_MODULE_H_ | 
 |  | 
 | #include <map> | 
 | #include <string> | 
 |  | 
 | #include "ppapi/c/pp_instance.h" | 
 | #include "ppapi/c/pp_module.h" | 
 | #include "ppapi/c/pp_stdint.h" | 
 | #include "ppapi/c/ppb.h" | 
 | #include "ppapi/c/ppb_core.h" | 
 | #include "ppapi/cpp/core.h" | 
 |  | 
 |  | 
 | /// @file | 
 | /// This file defines a Module class. | 
 | namespace pp { | 
 |  | 
 | class Instance; | 
 |  | 
 | /// The Module class.  The browser calls CreateInstance() to create | 
 | /// an instance of your module on the web page.  The browser creates a new | 
 | /// instance for each <code>\<embed></code> tag with | 
 | /// <code>type="application/x-nacl"</code> | 
 | class Module { | 
 |  public: | 
 |   typedef std::map<PP_Instance, Instance*> InstanceMap; | 
 |  | 
 |   // You may not call any other PP functions from the constructor, put them | 
 |   // in Init instead. Various things will not be set up until the constructor | 
 |   // completes. | 
 |   Module(); | 
 |   virtual ~Module(); | 
 |  | 
 |   /// Get() returns the global instance of this module object, or NULL if the | 
 |   /// module is not initialized yet. | 
 |   /// | 
 |   /// @return The global instance of the module object. | 
 |   static Module* Get(); | 
 |  | 
 |   /// Init() is automatically called after the object is created. This is where | 
 |   /// you can put functions that rely on other parts of the API, now that the | 
 |   /// module has been created. | 
 |   /// | 
 |   /// @return true if successful, otherwise false. | 
 |   virtual bool Init(); | 
 |  | 
 |   /// The pp_module() function returns the internal module handle. | 
 |   /// | 
 |   /// @return A <code>PP_Module</code> internal module handle. | 
 |   PP_Module pp_module() const { return pp_module_; } | 
 |  | 
 |   /// The get_browser_interface() function returns the internal | 
 |   /// <code>get_browser_interface</code> pointer. | 
 |   /// | 
 |   /// @return A <code>PPB_GetInterface</code> internal pointer. | 
 |   // TODO(sehr): This should be removed once the NaCl browser plugin no longer | 
 |   // needs it. | 
 |   PPB_GetInterface get_browser_interface() const { | 
 |     return get_browser_interface_; | 
 |   } | 
 |  | 
 |   /// The core() function returns the core interface for doing basic | 
 |   /// global operations. The return value is guaranteed to be non-NULL once the | 
 |   /// module has successfully initialized and during the Init() call. | 
 |   /// | 
 |   /// It will be NULL before Init() has been called. | 
 |   /// | 
 |   /// @return The core interface for doing basic global operations. | 
 |   Core* core() { return core_; } | 
 |  | 
 |   /// GetPluginInterface() implements <code>GetInterface</code> for the browser | 
 |   /// to get module interfaces. If you need to provide your own implementations | 
 |   /// of new interfaces, use AddPluginInterface() which this function will use. | 
 |   /// | 
 |   /// @param[in] interface_name The module interface for the browser to get. | 
 |   const void* GetPluginInterface(const char* interface_name); | 
 |  | 
 |   /// GetBrowserInterface() returns interfaces which the browser implements | 
 |   /// (i.e. PPB interfaces). | 
 |   /// @param[in] interface_name The browser interface for the module to get. | 
 |   const void* GetBrowserInterface(const char* interface_name); | 
 |  | 
 |   /// InstanceForPPInstance() returns the object associated with this | 
 |   /// <code>PP_Instance</code>, or NULL if one is not found. This should only | 
 |   /// be called from the main thread! This instance object may be destroyed at | 
 |   /// any time on the main thread, so using it on other threads may cause a | 
 |   /// crash. | 
 |   /// | 
 |   /// @param[in] instance This <code>PP_Instance</code>. | 
 |   /// | 
 |   /// @return The object associated with this <code>PP_Instance</code>, | 
 |   /// or NULL if one is not found. | 
 |   Instance* InstanceForPPInstance(PP_Instance instance); | 
 |  | 
 |   /// AddPluginInterface() adds a handler for a provided interface name. When | 
 |   /// the browser requests that interface name, the provided | 
 |   /// <code>vtable</code> will be returned. | 
 |   /// | 
 |   /// In general, modules will not need to call this directly. Instead, the | 
 |   /// C++ wrappers for each interface will register themselves with this | 
 |   /// function. | 
 |   /// | 
 |   /// This function may be called more than once with the same interface name | 
 |   /// and vtable with no effect. However, it may not be used to register a | 
 |   /// different vtable for an already-registered interface. It will assert for | 
 |   /// a different registration for an already-registered interface in debug | 
 |   /// mode, and just ignore the registration in release mode. | 
 |   /// | 
 |   /// @param[in] interface_name The interface name that will receive a handler. | 
 |   /// @param[in,out] vtable The vtable to return for | 
 |   /// <code>interface_name</code>. | 
 |   void AddPluginInterface(const std::string& interface_name, | 
 |                           const void* vtable); | 
 |  | 
 |   // InternalInit() sets the browser interface and calls the regular Init() | 
 |   /// function that can be overridden by the base classes. | 
 |   /// | 
 |   /// @param[in] mod A <code>PP_Module</code>. | 
 |   /// @param[in] get_browser_interface The browser interface to set. | 
 |   /// | 
 |   /// @return true if successful, otherwise false. | 
 |   // TODO(brettw) make this private when I can figure out how to make the | 
 |   // initialize function a friend. | 
 |   bool InternalInit(PP_Module mod, | 
 |                     PPB_GetInterface get_browser_interface); | 
 |  | 
 |   /// The current_instances() function allows iteration over the | 
 |   /// current instances in the module. | 
 |   /// | 
 |   /// @return An <code>InstanceMap</code> of all instances in the module. | 
 |   const InstanceMap& current_instances() const { return current_instances_; } | 
 |  | 
 |  protected: | 
 |   /// CreateInstance() should be overridden to create your own module type. | 
 |   /// | 
 |   /// @param[in] instance A <code>PP_Instance</code>. | 
 |   /// | 
 |   /// @return The resulting instance. | 
 |   virtual Instance* CreateInstance(PP_Instance instance) = 0; | 
 |  | 
 |  private: | 
 |   friend PP_Bool Instance_DidCreate(PP_Instance pp_instance, | 
 |                                     uint32_t argc, | 
 |                                     const char* argn[], | 
 |                                     const char* argv[]); | 
 |   friend void Instance_DidDestroy(PP_Instance instance); | 
 |  | 
 |   // Unimplemented (disallow copy and assign). | 
 |   Module(const Module&); | 
 |   Module& operator=(const Module&); | 
 |  | 
 |   // Instance tracking. | 
 |   InstanceMap current_instances_; | 
 |  | 
 |   PP_Module pp_module_; | 
 |   PPB_GetInterface get_browser_interface_; | 
 |  | 
 |   Core* core_; | 
 |  | 
 |   // All additional interfaces this plugin can handle as registered by | 
 |   // AddPluginInterface. | 
 |   typedef std::map<std::string, const void*> InterfaceMap; | 
 |   InterfaceMap additional_interfaces_; | 
 | }; | 
 |  | 
 | }  // namespace pp | 
 |  | 
 | #endif  // PPAPI_CPP_MODULE_H_ |