summaryrefslogtreecommitdiffstats
path: root/ppapi/cpp/module.h
blob: 07cfea9b51b5c573b2396892963963f64f6973ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// 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 moduel 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_