158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// @file hello_tutorial.cc
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// This example demonstrates loading, running and scripting a very simple NaCl
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// module.  To load the NaCl module, the browser first looks for the
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// CreateModule() factory method (at the end of this file).  It calls
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// CreateModule() once to load the module code.  After the code is loaded,
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// CreateModule() is not called again.
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)///
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)/// Once the code is loaded, the browser calls the CreateInstance()
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// method on the object returned by CreateModule().  It calls CreateInstance()
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// each time it encounters an <embed> tag that references your NaCl module.
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)///
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// The browser can talk to your NaCl module via the postMessage() Javascript
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// function.  When you call postMessage() on your NaCl module from the browser,
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// this becomes a call to the HandleMessage() method of your pp::Instance
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// subclass.  You can send messages back to the browser by calling the
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// PostMessage() method on your pp::Instance.  Note that these two methods
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// (postMessage() in Javascript and PostMessage() in C++) are asynchronous.
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// This means they return immediately - there is no waiting for the message
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// to be handled.  This has implications in your program design, particularly
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// when mutating property values that are exposed to both the browser and the
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// NaCl module.
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ppapi/cpp/instance.h"
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ppapi/cpp/module.h"
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ppapi/cpp/var.h"
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// The Instance class.  One of these exists for each instance of your NaCl
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// module on the web page.  The browser will ask the Module object to create
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// a new Instance for each occurrence of the <embed> tag that has these
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// attributes:
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)///     src="hello_tutorial.nmf"
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)///     type="application/x-pnacl"
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// To communicate with the browser, you must override HandleMessage() to
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// receive messages from the browser, and use PostMessage() to send messages
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// back to the browser.  Note that this interface is asynchronous.
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class HelloTutorialInstance : public pp::Instance {
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// The constructor creates the plugin-side instance.
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// @param[in] instance the handle to the browser-side plugin instance.
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  explicit HelloTutorialInstance(PP_Instance instance) : pp::Instance(instance)
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  {}
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~HelloTutorialInstance() {}
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// Handler for messages coming in from the browser via postMessage().  The
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// @a var_message can contain be any pp:Var type; for example int, string
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  /// Array or Dictinary. Please see the pp:Var documentation for more details.
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// @param[in] var_message The message posted by the browser.
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void HandleMessage(const pp::Var& var_message) {
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(sdk_user): 1. Make this function handle the incoming message.
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// The Module class.  The browser calls the CreateInstance() method to create
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// an instance of your NaCl module on the web page.  The browser creates a new
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)/// instance for each <embed> tag with type="application/x-pnacl".
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class HelloTutorialModule : public pp::Module {
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  HelloTutorialModule() : pp::Module() {}
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~HelloTutorialModule() {}
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// Create and return a HelloTutorialInstance object.
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// @param[in] instance The browser-side instance.
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  /// @return the plugin-side instance.
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual pp::Instance* CreateInstance(PP_Instance instance) {
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return new HelloTutorialInstance(instance);
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace pp {
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// Factory function called by the browser when the module is first loaded.
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// The browser keeps a singleton of this module.  It calls the
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// CreateInstance() method on the object you return to make instances.  There
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// is one instance per <embed> tag on the page.  This is the main binding
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/// point for your NaCl module with the browser.
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)Module* CreateModule() {
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return new HelloTutorialModule();
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace pp
83