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