summaryrefslogtreecommitdiffstats
path: root/native_client_sdk
diff options
context:
space:
mode:
authorbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-19 18:26:40 +0000
committerbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-19 18:26:40 +0000
commitcee673111dd5ee539290521bf1d869c62c2e2189 (patch)
treeccb5d584ed0823b4ac3a2eb0b421780a7c38d7ac /native_client_sdk
parent0795982840095652cb7e0e64b227dfff861ebb77 (diff)
downloadchromium_src-cee673111dd5ee539290521bf1d869c62c2e2189.zip
chromium_src-cee673111dd5ee539290521bf1d869c62c2e2189.tar.gz
chromium_src-cee673111dd5ee539290521bf1d869c62c2e2189.tar.bz2
[NaCl SDK] Make input_events do what mt_input_events was doing.
mt_input_events is still useful -- and it is not significantly more difficult than input_events. But it is a lot of duplicated code. So let's just keep mt_input_events and rename it input_events. BUG=none R=noelallen@chromium.org NOTRY=true Review URL: https://chromiumcodereview.appspot.com/11617010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173955 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
-rw-r--r--native_client_sdk/src/examples/input_events/custom_events.cc (renamed from native_client_sdk/src/examples/multithreaded_input_events/custom_events.cc)0
-rw-r--r--native_client_sdk/src/examples/input_events/custom_events.h (renamed from native_client_sdk/src/examples/multithreaded_input_events/custom_events.h)0
-rw-r--r--native_client_sdk/src/examples/input_events/example.dsc22
-rw-r--r--native_client_sdk/src/examples/input_events/example.js13
-rw-r--r--native_client_sdk/src/examples/input_events/index.html18
-rw-r--r--native_client_sdk/src/examples/input_events/input_events.cc404
-rw-r--r--native_client_sdk/src/examples/input_events/shared_queue.h (renamed from native_client_sdk/src/examples/multithreaded_input_events/shared_queue.h)0
-rw-r--r--native_client_sdk/src/examples/multithreaded_input_events/example.dsc30
-rw-r--r--native_client_sdk/src/examples/multithreaded_input_events/example.js37
-rw-r--r--native_client_sdk/src/examples/multithreaded_input_events/index.html43
-rw-r--r--native_client_sdk/src/examples/multithreaded_input_events/mt_input_events.cc354
11 files changed, 278 insertions, 643 deletions
diff --git a/native_client_sdk/src/examples/multithreaded_input_events/custom_events.cc b/native_client_sdk/src/examples/input_events/custom_events.cc
index 9e22808..9e22808 100644
--- a/native_client_sdk/src/examples/multithreaded_input_events/custom_events.cc
+++ b/native_client_sdk/src/examples/input_events/custom_events.cc
diff --git a/native_client_sdk/src/examples/multithreaded_input_events/custom_events.h b/native_client_sdk/src/examples/input_events/custom_events.h
index 2f7b10c..2f7b10c 100644
--- a/native_client_sdk/src/examples/multithreaded_input_events/custom_events.h
+++ b/native_client_sdk/src/examples/input_events/custom_events.h
diff --git a/native_client_sdk/src/examples/input_events/example.dsc b/native_client_sdk/src/examples/input_events/example.dsc
index 69b3800..759d9e6a 100644
--- a/native_client_sdk/src/examples/input_events/example.dsc
+++ b/native_client_sdk/src/examples/input_events/example.dsc
@@ -1,10 +1,15 @@
{
- 'TOOLS': ['newlib', 'glibc', 'pnacl', 'win', 'linux'],
+ 'TOOLS': ['newlib', 'glibc', 'pnacl'],
'TARGETS': [
{
'NAME' : 'input_events',
'TYPE' : 'main',
- 'SOURCES' : ['input_events.cc'],
+ 'SOURCES' : [
+ 'custom_events.cc',
+ 'custom_events.h',
+ 'input_events.cc',
+ 'shared_queue.h',
+ ],
'LIBS': ['ppapi_cpp', 'ppapi', 'pthread']
}
],
@@ -12,12 +17,13 @@
'DEST': 'examples',
'NAME': 'input_events',
'TITLE': 'Input Events',
- 'DESC': """
-The Input Events example demonstrates how to handle events triggered by
-the user. This example allows a user to interact with a square representing a
-module instance. Events are displayed on the screen as the user clicks,
-scrolls, types, inside or outside of the square.""",
- 'FOCUS': 'Keyboard and mouse input, view change, and focus events.',
+ 'DESC': """The Input Events example shows how to handle input events in a
+multi-threaded application. The main thread converts input events to
+non-pepper events and puts them on a queue. The worker thread pulls them off of
+the queue, converts them to a string, and then uses CallOnMainThread so that
+PostMessage can be send the result of the worker thread to the browser.""",
+ 'FOCUS': """Multi-threading, keyboard and mouse input, view change, and focus
+events.""",
'GROUP': 'API',
}
diff --git a/native_client_sdk/src/examples/input_events/example.js b/native_client_sdk/src/examples/input_events/example.js
index 6342a72..eb335f0 100644
--- a/native_client_sdk/src/examples/input_events/example.js
+++ b/native_client_sdk/src/examples/input_events/example.js
@@ -11,6 +11,11 @@ function moduleDidLoad() {
}
// Called by the common.js module.
+function attachListeners() {
+ document.getElementById('killButton').addEventListener('click', cancelQueue);
+}
+
+// Called by the common.js module.
function handleMessage(message) {
// Show last |kMaxArraySize| events in html.
messageArray.push(message.data);
@@ -22,3 +27,11 @@ function handleMessage(message) {
// Print event to console.
console.log(message.data);
}
+
+function cancelQueue() {
+ if (common.naclModule == null) {
+ console.log('Module is not loaded.');
+ return;
+ }
+ common.naclModule.postMessage('CANCEL');
+}
diff --git a/native_client_sdk/src/examples/input_events/index.html b/native_client_sdk/src/examples/input_events/index.html
index 17077f7..e0fa20c 100644
--- a/native_client_sdk/src/examples/input_events/index.html
+++ b/native_client_sdk/src/examples/input_events/index.html
@@ -6,6 +6,7 @@ Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<head>
+ <title><TITLE></title>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">
<title><TITLE></title>
@@ -15,12 +16,21 @@ found in the LICENSE file.
<body data-name="<NAME>" data-tc="<tc>" data-path="<path>">
<h1><TITLE></h1>
<h2>Status: <code id="statusField">NO-STATUS</code></h2>
+ <button id="killButton">Kill worker thread and queue</button>
<p>This example demonstrates handling of input events in PPAPI.</p>
- <p>Each time an input event happens in the context of the gray box, the
- embedded NaCl module posts a message describing the event back to JavaScript,
- which prints a message to the JavaScript console in Chrome and to a string on
- the page.</p>
+ <p>Each time an input event happens in the context of the gray box, the main
+ thread in the embedded NaCl module converts it from a Pepper input event to a
+ non-Pepper event and puts this custom event onto a shared queue. A worker
+ thread in the embedded NaCl module reads events from the queue, and converts
+ each event to a string and then uses CallOnMainThread to post a message
+ describing the event back to JavaScript, which prints a message to the
+ JavaScript console in Chrome and to a string on the page.</p>
+ <p>If you press the 'Kill worker thread and queue' button, then the main
+ thread (which puts events on the queue) will call CancelQueue, indicating
+ that the main thread will no longer put events on the queue. When the worker
+ sees that the shared queue has been cancelled, the worker thread will
+ terminate.</p>
<!-- The NaCl plugin will be embedded inside the element with id "listener".
See common.js.-->
diff --git a/native_client_sdk/src/examples/input_events/input_events.cc b/native_client_sdk/src/examples/input_events/input_events.cc
index a84822b..5ff49ba 100644
--- a/native_client_sdk/src/examples/input_events/input_events.cc
+++ b/native_client_sdk/src/examples/input_events/input_events.cc
@@ -10,92 +10,88 @@
#include <sstream>
#include <string>
-// NaCl
+// PPAPI headers
+#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/point.h"
#include "ppapi/cpp/var.h"
+#include "ppapi/utility/completion_callback_factory.h"
-namespace {
+#include "custom_events.h"
+#include "shared_queue.h"
+
+namespace event_queue {
const char* const kDidChangeView = "DidChangeView";
const char* const kHandleInputEvent = "DidHandleInputEvent";
const char* const kDidChangeFocus = "DidChangeFocus";
const char* const kHaveFocus = "HaveFocus";
const char* const kDontHaveFocus = "DontHaveFocus";
+const char* const kCancelMessage = "CANCEL";
-// Convert a given modifier to a descriptive string. Note that the actual
-// declared type of modifier in each of the event classes is uint32_t, but it is
-// expected to be interpreted as a bitfield of 'or'ed PP_InputEvent_Modifier
-// values.
-std::string ModifierToString(uint32_t modifier) {
- std::string s;
- if (modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) {
- s += "shift ";
- }
- if (modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
- s += "ctrl ";
+// Convert a pepper inputevent modifier value into a
+// custom event modifier.
+unsigned int ConvertEventModifier(uint32_t pp_modifier) {
+ unsigned int custom_modifier = 0;
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) {
+ custom_modifier |= kShiftKeyModifier;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) {
- s += "alt ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
+ custom_modifier |= kControlKeyModifier;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_METAKEY) {
- s += "meta ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) {
+ custom_modifier |= kAltKeyModifier;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) {
- s += "keypad ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_METAKEY) {
+ custom_modifier |= kMetaKeyModifer;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) {
- s += "autorepeat ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) {
+ custom_modifier |= kKeyPadModifier;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
- s += "left-button-down ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) {
+ custom_modifier |= kAutoRepeatModifier;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) {
- s += "middle-button-down ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
+ custom_modifier |= kLeftButtonModifier;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) {
- s += "right-button-down ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) {
+ custom_modifier |= kMiddleButtonModifier;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) {
- s += "caps-lock ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) {
+ custom_modifier |= kRightButtonModifier;
}
- if (modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) {
- s += "num-lock ";
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) {
+ custom_modifier |= kCapsLockModifier;
}
- return s;
-}
-
-std::string MouseButtonToString(PP_InputEvent_MouseButton button) {
- switch (button) {
- case PP_INPUTEVENT_MOUSEBUTTON_NONE:
- return "None";
- case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
- return "Left";
- case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
- return "Middle";
- case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
- return "Right";
- default:
- std::ostringstream stream;
- stream << "Unrecognized ("
- << static_cast<int32_t>(button)
- << ")";
- return stream.str();
+ if (pp_modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) {
+ custom_modifier |= kNumLockModifier;
}
+ return custom_modifier;
}
-} // namespace
-
class EventInstance : public pp::Instance {
public:
explicit EventInstance(PP_Instance instance)
- : pp::Instance(instance) {
+ : pp::Instance(instance),
+ event_thread_(NULL),
+ callback_factory_(this) {
RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL
| PP_INPUTEVENT_CLASS_TOUCH);
RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
}
- virtual ~EventInstance() {}
+
+ // Not guaranteed to be called in Pepper, but a good idea to cancel the
+ // queue and signal to workers to die if it is called.
+ virtual ~EventInstance() {
+ CancelQueueAndWaitForWorker();
+ }
+
+ // Create the 'worker thread'.
+ bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
+ pthread_create(&event_thread_, NULL, ProcessEventOnWorkerThread, this);
+ return true;
+ }
/// Clicking outside of the instance's bounding box
/// will create a DidChangeFocus event (the NaCl instance is
@@ -117,148 +113,219 @@ class EventInstance : public pp::Instance {
PostMessage(pp::Var(kDidChangeView));
}
- void GotKeyEvent(const pp::KeyboardInputEvent& key_event,
- const std::string& kind) {
- std::ostringstream stream;
- stream << pp_instance() << ":"
- << " Key event:" << kind
- << " modifier:" << ModifierToString(key_event.GetModifiers())
- << " key_code:" << key_event.GetKeyCode()
- << " time:" << key_event.GetTimeStamp()
- << " text:" << key_event.GetCharacterText().DebugString()
- << "\n";
- PostMessage(stream.str());
- }
-
- void GotMouseEvent(const pp::MouseInputEvent& mouse_event,
- const std::string& kind) {
- std::ostringstream stream;
- stream << pp_instance() << ":"
- << " Mouse event:" << kind
- << " modifier:" << ModifierToString(mouse_event.GetModifiers())
- << " button:" << MouseButtonToString(mouse_event.GetButton())
- << " x:" << mouse_event.GetPosition().x()
- << " y:" << mouse_event.GetPosition().y()
- << " click_count:" << mouse_event.GetClickCount()
- << " time:" << mouse_event.GetTimeStamp()
- << "\n";
- PostMessage(stream.str());
- }
-
- void GotWheelEvent(const pp::WheelInputEvent& wheel_event) {
- std::ostringstream stream;
- stream << pp_instance() << ": Wheel event."
- << " modifier:" << ModifierToString(wheel_event.GetModifiers())
- << " deltax:" << wheel_event.GetDelta().x()
- << " deltay:" << wheel_event.GetDelta().y()
- << " wheel_ticks_x:" << wheel_event.GetTicks().x()
- << " wheel_ticks_y:"<< wheel_event.GetTicks().y()
- << " scroll_by_page: "
- << (wheel_event.GetScrollByPage() ? "true" : "false")
- << "\n";
- PostMessage(stream.str());
- }
-
- void GotTouchEvent(const pp::TouchInputEvent& touch_event,
- const std::string& kind) {
- std::ostringstream stream;
- stream << pp_instance() << ":"
- << " Touch event:" << kind
- << " modifier:" << ModifierToString(touch_event.GetModifiers());
- uint32_t touch_count =
- touch_event.GetTouchCount(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES);
- for (uint32_t i = 0; i < touch_count; ++i) {
- pp::TouchPoint point =
- touch_event.GetTouchByIndex(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, i);
- stream << " x[" << point.id() << "]:" << point.position().x();
- stream << " y[" << point.id() << "]:" << point.position().y();
- stream << " radius_x[" << point.id() << "]:" << point.radii().x();
- stream << " radius_y[" << point.id() << "]:" << point.radii().y();
- stream << " angle[" << point.id() << "]:" << point.rotation_angle();
- stream << " pressure[" << point.id() << "]:" << point.pressure();
+ /// Called by the browser to handle the postMessage() call in Javascript.
+ /// Detects which method is being called from the message contents, and
+ /// calls the appropriate function. Posts the result back to the browser
+ /// asynchronously.
+ /// @param[in] var_message The message posted by the browser. The only
+ /// supported message is |kCancelMessage|. If we receive this, we
+ /// cancel the shared queue.
+ virtual void HandleMessage(const pp::Var& var_message) {
+ std::string message = var_message.AsString();
+ if (kCancelMessage == message) {
+ std::string reply = "Received cancel : only Focus events will be "
+ "displayed. Worker thread for mouse/wheel/keyboard will exit.";
+ PostMessage(pp::Var(reply));
+ printf("Calling cancel queue\n");
+ CancelQueueAndWaitForWorker();
}
- PostMessage(stream.str());
}
- // Handle an incoming input event by switching on type and dispatching
- // to the appropriate subtype handler.
- //
- // HandleInputEvent operates on the main Pepper thread. In large
- // real-world applications, you'll want to create a separate thread
- // that puts events in a queue and handles them independant of the main
- // thread so as not to slow down the browser. There is an additional
- // version of this example in the examples directory that demonstrates
- // this best practice.
+ // HandleInputEvent operates on the main Pepper thread. Here we
+ // illustrate copying the Pepper input event to our own custom event type.
+ // Since we need to use Pepper API calls to convert it, we must do the
+ // conversion on the main thread. Once we have converted it to our own
+ // event type, we push that into a thread-safe queue and quickly return.
+ // The worker thread can process the custom event and do whatever
+ // (possibly slow) things it wants to do without making the browser
+ // become unresponsive.
+ // We dynamically allocate a sub-class of our custom event (Event)
+ // so that the queue can contain an Event*.
virtual bool HandleInputEvent(const pp::InputEvent& event) {
- PostMessage(pp::Var(kHandleInputEvent));
+ Event* event_ptr = NULL;
switch (event.GetType()) {
+ case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
+ case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
+ case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
+ case PP_INPUTEVENT_TYPE_IME_TEXT:
+ // these cases are not handled...fall through below...
case PP_INPUTEVENT_TYPE_UNDEFINED:
break;
case PP_INPUTEVENT_TYPE_MOUSEDOWN:
- GotMouseEvent(pp::MouseInputEvent(event), "Down");
- break;
case PP_INPUTEVENT_TYPE_MOUSEUP:
- GotMouseEvent(pp::MouseInputEvent(event), "Up");
- break;
case PP_INPUTEVENT_TYPE_MOUSEMOVE:
- GotMouseEvent(pp::MouseInputEvent(event), "Move");
- break;
case PP_INPUTEVENT_TYPE_MOUSEENTER:
- GotMouseEvent(pp::MouseInputEvent(event), "Enter");
- break;
case PP_INPUTEVENT_TYPE_MOUSELEAVE:
- GotMouseEvent(pp::MouseInputEvent(event), "Leave");
+ {
+ pp::MouseInputEvent mouse_event(event);
+ PP_InputEvent_MouseButton pp_button = mouse_event.GetButton();
+ MouseEvent::MouseButton mouse_button = MouseEvent::kNone;
+ switch (pp_button) {
+ case PP_INPUTEVENT_MOUSEBUTTON_NONE:
+ mouse_button = MouseEvent::kNone;
+ break;
+ case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
+ mouse_button = MouseEvent::kLeft;
+ break;
+ case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
+ mouse_button = MouseEvent::kMiddle;
+ break;
+ case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
+ mouse_button = MouseEvent::kRight;
+ break;
+ }
+ event_ptr = new MouseEvent(
+ ConvertEventModifier(mouse_event.GetModifiers()),
+ mouse_button, mouse_event.GetPosition().x(),
+ mouse_event.GetPosition().y(), mouse_event.GetClickCount(),
+ mouse_event.GetTimeStamp());
+ }
break;
case PP_INPUTEVENT_TYPE_WHEEL:
- GotWheelEvent(pp::WheelInputEvent(event));
+ {
+ pp::WheelInputEvent wheel_event(event);
+ event_ptr = new WheelEvent(
+ ConvertEventModifier(wheel_event.GetModifiers()),
+ wheel_event.GetDelta().x(), wheel_event.GetDelta().y(),
+ wheel_event.GetTicks().x(), wheel_event.GetTicks().y(),
+ wheel_event.GetScrollByPage(), wheel_event.GetTimeStamp());
+ }
break;
case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
- GotKeyEvent(pp::KeyboardInputEvent(event), "RawKeyDown");
- break;
case PP_INPUTEVENT_TYPE_KEYDOWN:
- GotKeyEvent(pp::KeyboardInputEvent(event), "Down");
- break;
case PP_INPUTEVENT_TYPE_KEYUP:
- GotKeyEvent(pp::KeyboardInputEvent(event), "Up");
- break;
case PP_INPUTEVENT_TYPE_CHAR:
- GotKeyEvent(pp::KeyboardInputEvent(event), "Character");
- break;
case PP_INPUTEVENT_TYPE_CONTEXTMENU:
- GotKeyEvent(pp::KeyboardInputEvent(event), "Context");
- break;
- // Note that if we receive an IME event we just send a message back
- // to the browser to indicate we have received it.
- case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
- PostMessage(pp::Var("PP_INPUTEVENT_TYPE_IME_COMPOSITION_START"));
- break;
- case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
- PostMessage(pp::Var("PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE"));
- break;
- case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
- PostMessage(pp::Var("PP_INPUTEVENT_TYPE_IME_COMPOSITION_END"));
- break;
- case PP_INPUTEVENT_TYPE_IME_TEXT:
- PostMessage(pp::Var("PP_INPUTEVENT_TYPE_IME_COMPOSITION_TEXT"));
+ {
+ pp::KeyboardInputEvent key_event(event);
+ event_ptr = new KeyEvent(
+ ConvertEventModifier(key_event.GetModifiers()),
+ key_event.GetKeyCode(), key_event.GetTimeStamp(),
+ key_event.GetCharacterText().DebugString());
+ }
break;
case PP_INPUTEVENT_TYPE_TOUCHSTART:
- GotTouchEvent(pp::TouchInputEvent(event), "Start");
- break;
case PP_INPUTEVENT_TYPE_TOUCHMOVE:
- GotTouchEvent(pp::TouchInputEvent(event), "Move");
- break;
case PP_INPUTEVENT_TYPE_TOUCHEND:
- GotTouchEvent(pp::TouchInputEvent(event), "End");
- break;
case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
- GotTouchEvent(pp::TouchInputEvent(event), "Cancel");
+ {
+ pp::TouchInputEvent touch_event(event);
+
+ TouchEvent::Kind touch_kind = TouchEvent::kNone;
+ if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHSTART)
+ touch_kind = TouchEvent::kStart;
+ else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHMOVE)
+ touch_kind = TouchEvent::kMove;
+ else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHEND)
+ touch_kind = TouchEvent::kEnd;
+ else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHCANCEL)
+ touch_kind = TouchEvent::kCancel;
+
+ TouchEvent* touch_event_ptr = new TouchEvent(
+ ConvertEventModifier(touch_event.GetModifiers()),
+ touch_kind, touch_event.GetTimeStamp());
+ event_ptr = touch_event_ptr;
+
+ uint32_t touch_count =
+ touch_event.GetTouchCount(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES);
+ for (uint32_t i = 0; i < touch_count; ++i) {
+ pp::TouchPoint point = touch_event.GetTouchByIndex(
+ PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, i);
+ touch_event_ptr->AddTouch(point.id(), point.position().x(),
+ point.position().y(), point.radii().x(), point.radii().y(),
+ point.rotation_angle(), point.pressure());
+ }
+ }
break;
default:
- assert(false);
- return false;
+ {
+ // For any unhandled events, send a message to the browser
+ // so that the user is aware of these and can investigate.
+ std::stringstream oss;
+ oss << "Default (unhandled) event, type=" << event.GetType();
+ PostMessage(oss.str());
+ }
+ break;
}
+ event_queue_.Push(event_ptr);
return true;
}
+
+ // Return an event from the thread-safe queue, waiting for a new event
+ // to occur if the queue is empty. Set |was_queue_cancelled| to indicate
+ // whether the queue was cancelled. If it was cancelled, then the
+ // Event* will be NULL.
+ const Event* GetEventFromQueue(bool *was_queue_cancelled) {
+ Event* event = NULL;
+ QueueGetResult result = event_queue_.GetItem(&event, kWait);
+ if (result == kQueueWasCancelled) {
+ *was_queue_cancelled = true;
+ return NULL;
+ }
+ *was_queue_cancelled = false;
+ return event;
+ }
+
+ // This method is called from the worker thread using CallOnMainThread.
+ // It is not static, and allows PostMessage to be called.
+ void* PostStringToBrowser(int32_t result, std::string data_to_send) {
+ PostMessage(pp::Var(data_to_send));
+ return 0;
+ }
+
+ // |ProcessEventOnWorkerThread| is a static method that is run
+ // by a thread. It pulls events from the queue, converts
+ // them to a string, and calls CallOnMainThread so that
+ // PostStringToBrowser will be called, which will call PostMessage
+ // to send the converted event back to the browser.
+ static void* ProcessEventOnWorkerThread(void* param) {
+ EventInstance* event_instance = static_cast<EventInstance*>(param);
+ while (1) {
+ // Grab a generic Event* so that down below we can call
+ // event->ToString(), which will use the correct virtual method
+ // to convert the event to a string. This 'conversion' is
+ // the 'work' being done on the worker thread. In an application
+ // the work might involve changing application state based on
+ // the event that was processed.
+ bool queue_cancelled;
+ const Event* event = event_instance->GetEventFromQueue(&queue_cancelled);
+ if (queue_cancelled) {
+ printf("Queue was cancelled, worker thread exiting\n");
+ pthread_exit(NULL);
+ }
+ std::string event_string = event->ToString();
+ delete event;
+ // Need to invoke callback on main thread.
+ pp::Module::Get()->core()->CallOnMainThread(
+ 0,
+ event_instance->callback_factory().NewCallback(
+ &EventInstance::PostStringToBrowser,
+ event_string));
+ } // end of while loop.
+ return 0;
+ }
+
+ // Return the callback factory.
+ // Allows the static method (ProcessEventOnWorkerThread) to use
+ // the |event_instance| pointer to get the factory.
+ pp::CompletionCallbackFactory<EventInstance>& callback_factory() {
+ return callback_factory_;
+ }
+
+ private:
+ // Cancels the queue (which will cause the thread to exit).
+ // Wait for the thread. Set |event_thread_| to NULL so we only
+ // execute the body once.
+ void CancelQueueAndWaitForWorker() {
+ if (event_thread_) {
+ event_queue_.CancelQueue();
+ pthread_join(event_thread_, NULL);
+ event_thread_ = NULL;
+ }
+ }
+ pthread_t event_thread_;
+ LockingQueue<Event*> event_queue_;
+ pp::CompletionCallbackFactory<EventInstance> callback_factory_;
};
// The EventModule provides an implementation of pp::Module that creates
@@ -274,11 +341,14 @@ class EventModule : public pp::Module {
}
};
+} // namespace
+
// Implement the required pp::CreateModule function that creates our specific
// kind of Module (in this case, EventModule). This is part of the glue code
// that makes our example accessible to ppapi.
namespace pp {
Module* CreateModule() {
- return new EventModule();
+ return new event_queue::EventModule();
}
}
+
diff --git a/native_client_sdk/src/examples/multithreaded_input_events/shared_queue.h b/native_client_sdk/src/examples/input_events/shared_queue.h
index 48b70b3..48b70b3 100644
--- a/native_client_sdk/src/examples/multithreaded_input_events/shared_queue.h
+++ b/native_client_sdk/src/examples/input_events/shared_queue.h
diff --git a/native_client_sdk/src/examples/multithreaded_input_events/example.dsc b/native_client_sdk/src/examples/multithreaded_input_events/example.dsc
deleted file mode 100644
index 8b61418..0000000
--- a/native_client_sdk/src/examples/multithreaded_input_events/example.dsc
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- 'TOOLS': ['newlib', 'glibc', 'pnacl'],
- 'TARGETS': [
- {
- 'NAME' : 'mt_input_events',
- 'TYPE' : 'main',
- 'SOURCES' : [
- 'custom_events.cc',
- 'custom_events.h',
- 'mt_input_events.cc',
- 'shared_queue.h',
- ],
- 'LIBS': ['ppapi_cpp', 'ppapi', 'pthread']
- }
- ],
- 'DATA': ['example.js'],
- 'DEST': 'examples',
- 'NAME': 'mt_input_events',
- 'TITLE': 'Multi-threaded Input Events',
- 'DESC': """
-The Multithreaded Input Events example combines HTML, Javascript,
-and C++ (the C++ is compiled to create a .nexe file).
-The C++ shows how to handle input events in a multi-threaded application.
-The main thread converts input events to non-pepper events and puts them on
-a queue. The worker thread pulls them off of the queue, converts them to a
-string, and then uses CallOnMainThread so that PostMessage can be send the
-result of the worker thread to the browser.""",
- 'INFO': 'Multithreaded event handling.'
-}
-
diff --git a/native_client_sdk/src/examples/multithreaded_input_events/example.js b/native_client_sdk/src/examples/multithreaded_input_events/example.js
deleted file mode 100644
index eb335f0..0000000
--- a/native_client_sdk/src/examples/multithreaded_input_events/example.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-var kMaxArraySize = 20;
-var messageArray = new Array();
-
-// Called by the common.js module.
-function moduleDidLoad() {
- common.naclModule.style.backgroundColor = 'gray';
-}
-
-// Called by the common.js module.
-function attachListeners() {
- document.getElementById('killButton').addEventListener('click', cancelQueue);
-}
-
-// Called by the common.js module.
-function handleMessage(message) {
- // Show last |kMaxArraySize| events in html.
- messageArray.push(message.data);
- if (messageArray.length > kMaxArraySize) {
- messageArray.shift();
- }
- var newData = messageArray.join('<BR>');
- document.getElementById('eventString').innerHTML = newData;
- // Print event to console.
- console.log(message.data);
-}
-
-function cancelQueue() {
- if (common.naclModule == null) {
- console.log('Module is not loaded.');
- return;
- }
- common.naclModule.postMessage('CANCEL');
-}
diff --git a/native_client_sdk/src/examples/multithreaded_input_events/index.html b/native_client_sdk/src/examples/multithreaded_input_events/index.html
deleted file mode 100644
index e0fa20c..0000000
--- a/native_client_sdk/src/examples/multithreaded_input_events/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-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.
--->
-<head>
- <title><TITLE></title>
- <meta http-equiv="Pragma" content="no-cache">
- <meta http-equiv="Expires" content="-1">
- <title><TITLE></title>
- <script type="text/javascript" src="common.js"></script>
- <script type="text/javascript" src="example.js"></script>
-</head>
-<body data-name="<NAME>" data-tc="<tc>" data-path="<path>">
- <h1><TITLE></h1>
- <h2>Status: <code id="statusField">NO-STATUS</code></h2>
- <button id="killButton">Kill worker thread and queue</button>
-
- <p>This example demonstrates handling of input events in PPAPI.</p>
- <p>Each time an input event happens in the context of the gray box, the main
- thread in the embedded NaCl module converts it from a Pepper input event to a
- non-Pepper event and puts this custom event onto a shared queue. A worker
- thread in the embedded NaCl module reads events from the queue, and converts
- each event to a string and then uses CallOnMainThread to post a message
- describing the event back to JavaScript, which prints a message to the
- JavaScript console in Chrome and to a string on the page.</p>
- <p>If you press the 'Kill worker thread and queue' button, then the main
- thread (which puts events on the queue) will call CancelQueue, indicating
- that the main thread will no longer put events on the queue. When the worker
- sees that the shared queue has been cancelled, the worker thread will
- terminate.</p>
-
- <!-- The NaCl plugin will be embedded inside the element with id "listener".
- See common.js.-->
- <div id="listener"></div>
- <h2>Events</h2>
- <pre>
- <p><b id='eventString'>None</b></p>
- </pre>
-</body>
-</html>
diff --git a/native_client_sdk/src/examples/multithreaded_input_events/mt_input_events.cc b/native_client_sdk/src/examples/multithreaded_input_events/mt_input_events.cc
deleted file mode 100644
index d0adb31..0000000
--- a/native_client_sdk/src/examples/multithreaded_input_events/mt_input_events.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-// 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.
-
-// C headers
-#include <cassert>
-#include <cstdio>
-
-// C++ headers
-#include <sstream>
-#include <string>
-
-// PPAPI headers
-#include "ppapi/cpp/completion_callback.h"
-#include "ppapi/cpp/input_event.h"
-#include "ppapi/cpp/instance.h"
-#include "ppapi/cpp/module.h"
-#include "ppapi/cpp/point.h"
-#include "ppapi/cpp/var.h"
-#include "ppapi/utility/completion_callback_factory.h"
-
-#include "custom_events.h"
-#include "shared_queue.h"
-
-namespace event_queue {
-const char* const kDidChangeView = "DidChangeView";
-const char* const kHandleInputEvent = "DidHandleInputEvent";
-const char* const kDidChangeFocus = "DidChangeFocus";
-const char* const kHaveFocus = "HaveFocus";
-const char* const kDontHaveFocus = "DontHaveFocus";
-const char* const kCancelMessage = "CANCEL";
-
-// Convert a pepper inputevent modifier value into a
-// custom event modifier.
-unsigned int ConvertEventModifier(uint32_t pp_modifier) {
- unsigned int custom_modifier = 0;
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_SHIFTKEY) {
- custom_modifier |= kShiftKeyModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
- custom_modifier |= kControlKeyModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_ALTKEY) {
- custom_modifier |= kAltKeyModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_METAKEY) {
- custom_modifier |= kMetaKeyModifer;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_ISKEYPAD) {
- custom_modifier |= kKeyPadModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) {
- custom_modifier |= kAutoRepeatModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
- custom_modifier |= kLeftButtonModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) {
- custom_modifier |= kMiddleButtonModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) {
- custom_modifier |= kRightButtonModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) {
- custom_modifier |= kCapsLockModifier;
- }
- if (pp_modifier & PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) {
- custom_modifier |= kNumLockModifier;
- }
- return custom_modifier;
-}
-
-class EventInstance : public pp::Instance {
- public:
- explicit EventInstance(PP_Instance instance)
- : pp::Instance(instance),
- event_thread_(NULL),
- callback_factory_(this) {
- RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL
- | PP_INPUTEVENT_CLASS_TOUCH);
- RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
- }
-
- // Not guaranteed to be called in Pepper, but a good idea to cancel the
- // queue and signal to workers to die if it is called.
- virtual ~EventInstance() {
- CancelQueueAndWaitForWorker();
- }
-
- // Create the 'worker thread'.
- bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
- pthread_create(&event_thread_, NULL, ProcessEventOnWorkerThread, this);
- return true;
- }
-
- /// Clicking outside of the instance's bounding box
- /// will create a DidChangeFocus event (the NaCl instance is
- /// out of focus). Clicking back inside the instance's
- /// bounding box will create another DidChangeFocus event
- /// (the NaCl instance is back in focus). The default is
- /// that the instance is out of focus.
- void DidChangeFocus(bool focus) {
- PostMessage(pp::Var(kDidChangeFocus));
- if (focus == true) {
- PostMessage(pp::Var(kHaveFocus));
- } else {
- PostMessage(pp::Var(kDontHaveFocus));
- }
- }
-
- /// Scrolling the mouse wheel causes a DidChangeView event.
- void DidChangeView(const pp::View& view) {
- PostMessage(pp::Var(kDidChangeView));
- }
-
- /// Called by the browser to handle the postMessage() call in Javascript.
- /// Detects which method is being called from the message contents, and
- /// calls the appropriate function. Posts the result back to the browser
- /// asynchronously.
- /// @param[in] var_message The message posted by the browser. The only
- /// supported message is |kCancelMessage|. If we receive this, we
- /// cancel the shared queue.
- virtual void HandleMessage(const pp::Var& var_message) {
- std::string message = var_message.AsString();
- if (kCancelMessage == message) {
- std::string reply = "Received cancel : only Focus events will be "
- "displayed. Worker thread for mouse/wheel/keyboard will exit.";
- PostMessage(pp::Var(reply));
- printf("Calling cancel queue\n");
- CancelQueueAndWaitForWorker();
- }
- }
-
- // HandleInputEvent operates on the main Pepper thread. Here we
- // illustrate copying the Pepper input event to our own custom event type.
- // Since we need to use Pepper API calls to convert it, we must do the
- // conversion on the main thread. Once we have converted it to our own
- // event type, we push that into a thread-safe queue and quickly return.
- // The worker thread can process the custom event and do whatever
- // (possibly slow) things it wants to do without making the browser
- // become unresponsive.
- // We dynamically allocate a sub-class of our custom event (Event)
- // so that the queue can contain an Event*.
- virtual bool HandleInputEvent(const pp::InputEvent& event) {
- Event* event_ptr = NULL;
- switch (event.GetType()) {
- case PP_INPUTEVENT_TYPE_IME_COMPOSITION_START:
- case PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE:
- case PP_INPUTEVENT_TYPE_IME_COMPOSITION_END:
- case PP_INPUTEVENT_TYPE_IME_TEXT:
- // these cases are not handled...fall through below...
- case PP_INPUTEVENT_TYPE_UNDEFINED:
- break;
- case PP_INPUTEVENT_TYPE_MOUSEDOWN:
- case PP_INPUTEVENT_TYPE_MOUSEUP:
- case PP_INPUTEVENT_TYPE_MOUSEMOVE:
- case PP_INPUTEVENT_TYPE_MOUSEENTER:
- case PP_INPUTEVENT_TYPE_MOUSELEAVE:
- {
- pp::MouseInputEvent mouse_event(event);
- PP_InputEvent_MouseButton pp_button = mouse_event.GetButton();
- MouseEvent::MouseButton mouse_button = MouseEvent::kNone;
- switch (pp_button) {
- case PP_INPUTEVENT_MOUSEBUTTON_NONE:
- mouse_button = MouseEvent::kNone;
- break;
- case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
- mouse_button = MouseEvent::kLeft;
- break;
- case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
- mouse_button = MouseEvent::kMiddle;
- break;
- case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
- mouse_button = MouseEvent::kRight;
- break;
- }
- event_ptr = new MouseEvent(
- ConvertEventModifier(mouse_event.GetModifiers()),
- mouse_button, mouse_event.GetPosition().x(),
- mouse_event.GetPosition().y(), mouse_event.GetClickCount(),
- mouse_event.GetTimeStamp());
- }
- break;
- case PP_INPUTEVENT_TYPE_WHEEL:
- {
- pp::WheelInputEvent wheel_event(event);
- event_ptr = new WheelEvent(
- ConvertEventModifier(wheel_event.GetModifiers()),
- wheel_event.GetDelta().x(), wheel_event.GetDelta().y(),
- wheel_event.GetTicks().x(), wheel_event.GetTicks().y(),
- wheel_event.GetScrollByPage(), wheel_event.GetTimeStamp());
- }
- break;
- case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
- case PP_INPUTEVENT_TYPE_KEYDOWN:
- case PP_INPUTEVENT_TYPE_KEYUP:
- case PP_INPUTEVENT_TYPE_CHAR:
- case PP_INPUTEVENT_TYPE_CONTEXTMENU:
- {
- pp::KeyboardInputEvent key_event(event);
- event_ptr = new KeyEvent(
- ConvertEventModifier(key_event.GetModifiers()),
- key_event.GetKeyCode(), key_event.GetTimeStamp(),
- key_event.GetCharacterText().DebugString());
- }
- break;
- case PP_INPUTEVENT_TYPE_TOUCHSTART:
- case PP_INPUTEVENT_TYPE_TOUCHMOVE:
- case PP_INPUTEVENT_TYPE_TOUCHEND:
- case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
- {
- pp::TouchInputEvent touch_event(event);
-
- TouchEvent::Kind touch_kind = TouchEvent::kNone;
- if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHSTART)
- touch_kind = TouchEvent::kStart;
- else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHMOVE)
- touch_kind = TouchEvent::kMove;
- else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHEND)
- touch_kind = TouchEvent::kEnd;
- else if (event.GetType() == PP_INPUTEVENT_TYPE_TOUCHCANCEL)
- touch_kind = TouchEvent::kCancel;
-
- TouchEvent* touch_event_ptr = new TouchEvent(
- ConvertEventModifier(touch_event.GetModifiers()),
- touch_kind, touch_event.GetTimeStamp());
- event_ptr = touch_event_ptr;
-
- uint32_t touch_count =
- touch_event.GetTouchCount(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES);
- for (uint32_t i = 0; i < touch_count; ++i) {
- pp::TouchPoint point = touch_event.GetTouchByIndex(
- PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, i);
- touch_event_ptr->AddTouch(point.id(), point.position().x(),
- point.position().y(), point.radii().x(), point.radii().y(),
- point.rotation_angle(), point.pressure());
- }
- }
- break;
- default:
- {
- // For any unhandled events, send a message to the browser
- // so that the user is aware of these and can investigate.
- std::stringstream oss;
- oss << "Default (unhandled) event, type=" << event.GetType();
- PostMessage(oss.str());
- }
- break;
- }
- event_queue_.Push(event_ptr);
- return true;
- }
-
- // Return an event from the thread-safe queue, waiting for a new event
- // to occur if the queue is empty. Set |was_queue_cancelled| to indicate
- // whether the queue was cancelled. If it was cancelled, then the
- // Event* will be NULL.
- const Event* GetEventFromQueue(bool *was_queue_cancelled) {
- Event* event;
- QueueGetResult result = event_queue_.GetItem(&event, kWait);
- if (result == kQueueWasCancelled) {
- *was_queue_cancelled = true;
- return NULL;
- }
- *was_queue_cancelled = false;
- return event;
- }
-
- // This method is called from the worker thread using CallOnMainThread.
- // It is not static, and allows PostMessage to be called.
- void* PostStringToBrowser(int32_t result, std::string data_to_send) {
- PostMessage(pp::Var(data_to_send));
- return 0;
- }
-
- // |ProcessEventOnWorkerThread| is a static method that is run
- // by a thread. It pulls events from the queue, converts
- // them to a string, and calls CallOnMainThread so that
- // PostStringToBrowser will be called, which will call PostMessage
- // to send the converted event back to the browser.
- static void* ProcessEventOnWorkerThread(void* param) {
- EventInstance* event_instance = static_cast<EventInstance*>(param);
- while (1) {
- // Grab a generic Event* so that down below we can call
- // event->ToString(), which will use the correct virtual method
- // to convert the event to a string. This 'conversion' is
- // the 'work' being done on the worker thread. In an application
- // the work might involve changing application state based on
- // the event that was processed.
- bool queue_cancelled;
- const Event* event = event_instance->GetEventFromQueue(&queue_cancelled);
- if (queue_cancelled) {
- printf("Queue was cancelled, worker thread exiting\n");
- pthread_exit(NULL);
- }
- std::string event_string = event->ToString();
- delete event;
- // Need to invoke callback on main thread.
- pp::Module::Get()->core()->CallOnMainThread(
- 0,
- event_instance->callback_factory().NewCallback(
- &EventInstance::PostStringToBrowser,
- event_string));
- } // end of while loop.
- return 0;
- }
-
- // Return the callback factory.
- // Allows the static method (ProcessEventOnWorkerThread) to use
- // the |event_instance| pointer to get the factory.
- pp::CompletionCallbackFactory<EventInstance>& callback_factory() {
- return callback_factory_;
- }
-
- private:
- // Cancels the queue (which will cause the thread to exit).
- // Wait for the thread. Set |event_thread_| to NULL so we only
- // execute the body once.
- void CancelQueueAndWaitForWorker() {
- if (event_thread_) {
- event_queue_.CancelQueue();
- pthread_join(event_thread_, NULL);
- event_thread_ = NULL;
- }
- }
- pthread_t event_thread_;
- LockingQueue<Event*> event_queue_;
- pp::CompletionCallbackFactory<EventInstance> callback_factory_;
-};
-
-// The EventModule provides an implementation of pp::Module that creates
-// EventInstance objects when invoked. This is part of the glue code that makes
-// our example accessible to ppapi.
-class EventModule : public pp::Module {
- public:
- EventModule() : pp::Module() {}
- virtual ~EventModule() {}
-
- virtual pp::Instance* CreateInstance(PP_Instance instance) {
- return new EventInstance(instance);
- }
-};
-
-} // namespace
-
-// Implement the required pp::CreateModule function that creates our specific
-// kind of Module (in this case, EventModule). This is part of the glue code
-// that makes our example accessible to ppapi.
-namespace pp {
- Module* CreateModule() {
- return new event_queue::EventModule();
- }
-}
-