1// Copyright (c) 2013 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/// @file hello_tutorial.cc
6/// This example demonstrates loading, running and scripting a very simple NaCl
7/// module.  To load the NaCl module, the browser first looks for the
8/// CreateModule() factory method (at the end of this file).  It calls
9/// CreateModule() once to load the module code.  After the code is loaded,
10/// CreateModule() is not called again.
11///
12/// Once the code is loaded, the browser calls the CreateInstance()
13/// method on the object returned by CreateModule().  It calls CreateInstance()
14/// each time it encounters an <embed> tag that references your NaCl module.
15///
16/// The browser can talk to your NaCl module via the postMessage() Javascript
17/// function.  When you call postMessage() on your NaCl module from the browser,
18/// this becomes a call to the HandleMessage() method of your pp::Instance
19/// subclass.  You can send messages back to the browser by calling the
20/// PostMessage() method on your pp::Instance.  Note that these two methods
21/// (postMessage() in Javascript and PostMessage() in C++) are asynchronous.
22/// This means they return immediately - there is no waiting for the message
23/// to be handled.  This has implications in your program design, particularly
24/// when mutating property values that are exposed to both the browser and the
25/// NaCl module.
26
27#include "ppapi/cpp/instance.h"
28#include "ppapi/cpp/module.h"
29#include "ppapi/cpp/var.h"
30
31/// The Instance class.  One of these exists for each instance of your NaCl
32/// module on the web page.  The browser will ask the Module object to create
33/// a new Instance for each occurrence of the <embed> tag that has these
34/// attributes:
35///     src="hello_tutorial.nmf"
36///     type="application/x-pnacl"
37/// To communicate with the browser, you must override HandleMessage() to
38/// receive messages from the browser, and use PostMessage() to send messages
39/// back to the browser.  Note that this interface is asynchronous.
40class HelloTutorialInstance : public pp::Instance {
41 public:
42  /// The constructor creates the plugin-side instance.
43  /// @param[in] instance the handle to the browser-side plugin instance.
44  explicit HelloTutorialInstance(PP_Instance instance) : pp::Instance(instance)
45  {}
46  virtual ~HelloTutorialInstance() {}
47
48  /// Handler for messages coming in from the browser via postMessage().  The
49  /// @a var_message can contain be any pp:Var type; for example int, string
50  /// Array or Dictinary. Please see the pp:Var documentation for more details.
51  /// @param[in] var_message The message posted by the browser.
52  virtual void HandleMessage(const pp::Var& var_message) {
53    // TODO(sdk_user): 1. Make this function handle the incoming message.
54  }
55};
56
57/// The Module class.  The browser calls the CreateInstance() method to create
58/// an instance of your NaCl module on the web page.  The browser creates a new
59/// instance for each <embed> tag with type="application/x-pnacl".
60class HelloTutorialModule : public pp::Module {
61 public:
62  HelloTutorialModule() : pp::Module() {}
63  virtual ~HelloTutorialModule() {}
64
65  /// Create and return a HelloTutorialInstance object.
66  /// @param[in] instance The browser-side instance.
67  /// @return the plugin-side instance.
68  virtual pp::Instance* CreateInstance(PP_Instance instance) {
69    return new HelloTutorialInstance(instance);
70  }
71};
72
73namespace pp {
74/// Factory function called by the browser when the module is first loaded.
75/// The browser keeps a singleton of this module.  It calls the
76/// CreateInstance() method on the object you return to make instances.  There
77/// is one instance per <embed> tag on the page.  This is the main binding
78/// point for your NaCl module with the browser.
79Module* CreateModule() {
80  return new HelloTutorialModule();
81}
82}  // namespace pp
83