| {{+bindTo:partials.standard_nacl_article}} |
| |
| <section id="progress-events"> |
| <span id="devcycle-progress-events"></span><h1 id="progress-events"><span id="devcycle-progress-events"></span>Progress Events</h1> |
| <div class="contents local" id="contents" style="display: none"> |
| <ul class="small-gap"> |
| <li><a class="reference internal" href="#module-loading-and-progress-events" id="id3">Module loading and progress events</a></li> |
| <li><a class="reference internal" href="#handling-progress-events" id="id4">Handling progress events</a></li> |
| <li><a class="reference internal" href="#displaying-load-status" id="id5">Displaying load status</a></li> |
| <li><a class="reference internal" href="#the-lasterror-attribute" id="id6">The <code>lastError</code> attribute</a></li> |
| <li><a class="reference internal" href="#the-readystate-attribute" id="id7">The <code>readyState</code> attribute</a></li> |
| <li><a class="reference internal" href="#the-exitstatus-attribute" id="id8">The <code>exitStatus</code> attribute</a></li> |
| </ul> |
| |
| </div><p>There are five types of events that developers can respond to in Native Client: |
| progress, message, view change, focus, and input events (each described in the |
| glossary below). This section describes how to monitor progress events (events |
| that occur during the loading and execution of a Native Client module). This |
| section assumes you are familiar with the material presented in the |
| <a class="reference internal" href="/native-client/overview.html"><em>Technical Overview</em></a>.</p> |
| <aside class="note"> |
| The load_progress example illustrates progress event handling. You can find |
| this code in the <code>/pepper_<version>/examples/tutorial/load_progress/</code> |
| directory in the Native Client SDK download. |
| </aside> |
| <h2 id="module-loading-and-progress-events">Module loading and progress events</h2> |
| <p>The Native Client runtime reports a set of state changes during the module |
| loading process by means of DOM progress events. This set of events is a direct |
| port of the proposed W3C <a class="reference external" href="http://www.w3.org/TR/progress-events/">Progress Events</a> standard (except for the <code>crash</code> |
| event which is an extension of the W3C standard). The following table lists the |
| events types reported by the Native Client runtime:</p> |
| <table border="1" class="docutils"> |
| <colgroup> |
| </colgroup> |
| <thead valign="bottom"> |
| <tr class="row-odd"><th class="head">Event</th> |
| <th class="head">Times |
| triggered</th> |
| <th class="head">When |
| triggered</th> |
| <th class="head">How you might |
| respond</th> |
| </tr> |
| </thead> |
| <tbody valign="top"> |
| <tr class="row-even"><td><dl class="first last docutils"> |
| <dt><code>loadstart</code></dt> |
| <dd>Native Client has started to |
| load a Native Client module.</dd> |
| </dl> |
| </td> |
| <td>once</td> |
| <td>The |
| first |
| progress |
| event |
| after the |
| Native Client |
| module is |
| instantiated |
| and |
| initialized.</td> |
| <td>Display a |
| status |
| message, such |
| as |
| “Loading...”</td> |
| </tr> |
| <tr class="row-odd"><td><dl class="first last docutils"> |
| <dt><code>progress</code></dt> |
| <dd>Part of the module has been |
| loaded.</dd> |
| </dl> |
| </td> |
| <td>zero or |
| more</td> |
| <td>After |
| <code>loadstart</code> |
| has been |
| dispatched.</td> |
| <td>Display a |
| progress bar.</td> |
| </tr> |
| <tr class="row-even"><td><dl class="first last docutils"> |
| <dt><code>error</code></dt> |
| <dd>The Native Client module failed |
| to start execution (includes any |
| error before or during |
| initialization of the module). |
| The <code>lastError</code> attribute |
| (mentioned later) provides |
| details on the error |
| (initialization failed, sel_ldr |
| did not start, and so on).</dd> |
| </dl> |
| </td> |
| <td>zero or |
| once</td> |
| <td>After the last |
| <code>progress</code> |
| event has been |
| dispatched, |
| or after |
| <code>loadstart</code> |
| if no |
| <code>progress</code> |
| event was |
| dispatched.</td> |
| <td>Inform user |
| that the |
| application |
| failed to |
| load.</td> |
| </tr> |
| <tr class="row-odd"><td><dl class="first last docutils"> |
| <dt><code>abort</code></dt> |
| <dd>Loading of the NativeClient |
| module was aborted by the user.</dd> |
| </dl> |
| </td> |
| <td>zero or |
| once</td> |
| <td>After the last |
| <code>progress</code> |
| event has been |
| dispatched, or |
| after |
| <code>loadstart</code> |
| if no |
| <code>progress</code> |
| event was |
| dispatched.</td> |
| <td>It’s not |
| likely you |
| will want to |
| respond to |
| this event.</td> |
| </tr> |
| <tr class="row-even"><td><dl class="first last docutils"> |
| <dt><code>load</code></dt> |
| <dd>The Native Client module was |
| successfully loaded, and |
| execution was started. |
| (The module was initialized |
| successfully.)</dd> |
| </dl> |
| </td> |
| <td>zero or |
| once</td> |
| <td>After the |
| last |
| <code>progress</code> |
| event has been |
| dispatched, or |
| after |
| <code>loadstart</code> |
| if no |
| <code>progress</code> |
| event was |
| dispatched.</td> |
| <td>Remove the |
| progress bar.</td> |
| </tr> |
| <tr class="row-odd"><td><dl class="first last docutils"> |
| <dt><code>loadend</code></dt> |
| <dd>Loading of the Native Client |
| module has stopped. Load |
| succeeded (<code>load</code>), failed |
| (<code>error</code>), or was aborted |
| (<code>abort</code>).</dd> |
| </dl> |
| </td> |
| <td>once</td> |
| <td>After an |
| <code>error</code>, |
| <code>abort</code>, or |
| <code>load</code> |
| event was |
| dispatched.</td> |
| <td>Indicate |
| loading is |
| over |
| (regardless of |
| failure or |
| not).</td> |
| </tr> |
| <tr class="row-even"><td><dl class="first last docutils"> |
| <dt><code>crash</code></dt> |
| <dd>The Native Client module is not |
| responding (died on an |
| <code>assert()</code> or <code>exit()</code>) |
| after a successful load. This |
| event is unique to Native Client |
| and is not part of the W3C |
| Progress Events standard. The |
| <code>exitStatus</code> attribute |
| provides the numeric exit |
| status.</dd> |
| </dl> |
| </td> |
| <td>zero or |
| once</td> |
| <td>After a |
| <code>loadend</code>.</td> |
| <td>Notify user |
| that the |
| module did |
| something |
| illegal.</td> |
| </tr> |
| </tbody> |
| </table> |
| <p>The sequence of events for a successful module load is as follows:</p> |
| <table border="1" class="docutils"> |
| <colgroup> |
| </colgroup> |
| <thead valign="bottom"> |
| <tr class="row-odd"><th class="head">Event is dispatched</th> |
| <th class="head">... then this task is attempted</th> |
| </tr> |
| </thead> |
| <tbody valign="top"> |
| <tr class="row-even"><td><code>loadstart</code></td> |
| <td>load the manifest file</td> |
| </tr> |
| <tr class="row-odd"><td><code>progress</code> (first time)</td> |
| <td>load the module</td> |
| </tr> |
| <tr class="row-even"><td><code>progress</code> (subsequent times)</td> |
| <td> </td> |
| </tr> |
| <tr class="row-odd"><td><code>load</code></td> |
| <td>start executing the module</td> |
| </tr> |
| <tr class="row-even"><td><code>loadend</code></td> |
| <td> </td> |
| </tr> |
| </tbody> |
| </table> |
| <p>Errors that occur during loading are logged to the JavaScript console in Google |
| Chrome (select the menu icon <img alt="menu-icon" src="/native-client/images/menu-icon.png" /> > Tools > JavaScript console).</p> |
| <h2 id="handling-progress-events">Handling progress events</h2> |
| <p>You should add event listeners in a <code><script></code> element to listen for these |
| events before the <code><embed></code> element is parsed. For example, the following code |
| adds a listener for the <code>load</code> event to a parent <code><div></code> element that also |
| contains the Native Client <code><embed></code> element. First, the listener is |
| attached. Then, when the listener <code><div></code> receives the <code>load</code> event, the |
| JavaScript <code>moduleDidLoad()</code> function is called. The following code is |
| excerpted from the example in <code>getting_started/part1/</code>:</p> |
| <pre class="prettyprint"> |
| <!-- |
| Load the published pexe. |
| Note: Since this module does not use any real-estate in the browser, its |
| width and height are set to 0. |
| |
| Note: The <embed> element is wrapped inside a <div>, which has both a 'load' |
| and a 'message' event listener attached. This wrapping method is used |
| instead of attaching the event listeners directly to the <embed> element to |
| ensure that the listeners are active before the NaCl module 'load' event |
| fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or |
| pp::Instance.PostMessage() (in C++) from within the initialization code in |
| your module. |
| --> |
| <div id="listener"> |
| <script type="text/javascript"> |
| var listener = document.getElementById('listener'); |
| listener.addEventListener('load', moduleDidLoad, true); |
| listener.addEventListener('message', handleMessage, true); |
| </script> |
| |
| <embed id="hello_tutorial" |
| width=0 height=0 |
| src="hello_tutorial.nmf" |
| type="application/x-pnacl" /> |
| </div> |
| </pre> |
| <p>Event listeners can be added to any DOM object. Since listeners set at the |
| outermost scope capture events for their contained elements, you can set |
| listeners on outer elements (including the <code><body></code> element) to handle events |
| from inner elements. For more information, see the W3 specifications for <a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture">event |
| flow capture</a> and |
| <a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">event listener registration</a>.</p> |
| <h2 id="displaying-load-status">Displaying load status</h2> |
| <p>One common response to progress events is to display the percentage of the |
| module that has been loaded. In the load_progress example, when the <code>progress</code> |
| event is triggered the <code>moduleLoadProgress</code> function is called. This function |
| uses the <code>lengthComputable</code>, <code>loaded</code>, and <code>total</code> attributes (described |
| in the proposed W3C <a class="reference external" href="http://www.w3.org/TR/progress-events/">Progress Events</a> |
| standard) of the event to calculate the percentage of the module that has |
| loaded.</p> |
| <pre class="prettyprint"> |
| function moduleLoadProgress(event) { |
| var loadPercent = 0.0; |
| var loadPercentString; |
| if (event.lengthComputable && event.total > 0) { |
| loadPercent = event.loaded / event.total * 100.0; |
| loadPercentString = loadPercent + '%'; |
| common.logMessage('progress: ' + event.url + ' ' + loadPercentString + |
| ' (' + event.loaded + ' of ' + event.total + ' bytes)'); |
| } else { |
| // The total length is not yet known. |
| common.logMessage('progress: Computing...'); |
| } |
| } |
| </pre> |
| <h2 id="the-lasterror-attribute">The <code>lastError</code> attribute</h2> |
| <p>The <code><embed></code> element has a <code>lastError</code> attribute that is set to an |
| informative string whenever a load failure (an <code>error</code> or <code>abort</code> event) |
| occurs.</p> |
| <p>The following code adds an event listener before the <code><embed></code> element to |
| capture and handle an error in loading the Native Client module. The |
| <code>handleError()</code> function listens for an <code>error</code> event. When an error occurs, |
| this function prints the contents of the <code>lastError</code> attribute |
| (<code>embed_element.lastError</code>) as an alert.</p> |
| <pre class="prettyprint"> |
| function domContentLoaded(name, tc, config, width, height) { |
| var listener = document.getElementById('listener'); |
| ... |
| listener.addEventListener('error', moduleLoadError, true); |
| ... |
| common.createNaClModule(name, tc, config, width, height); |
| } |
| |
| function moduleLoadError() { |
| common.logMessage('error: ' + common.naclModule.lastError); |
| } |
| </pre> |
| <h2 id="the-readystate-attribute">The <code>readyState</code> attribute</h2> |
| <p>You can use the <code>readyState</code> attribute to monitor the loading process. This |
| attribute is particularly useful if you don’t care about the details of |
| individual progress events or when you want to poll for current load state |
| without registering listeners. The value of <code>readyState</code> progresses as follows |
| for a successful load:</p> |
| <table border="1" class="docutils"> |
| <colgroup> |
| </colgroup> |
| <thead valign="bottom"> |
| <tr class="row-odd"><th class="head">Event</th> |
| <th class="head"><code>readyState</code> value</th> |
| </tr> |
| </thead> |
| <tbody valign="top"> |
| <tr class="row-even"><td>(before any events)</td> |
| <td><code>undefined</code></td> |
| </tr> |
| <tr class="row-odd"><td><code>loadstart</code></td> |
| <td>1</td> |
| </tr> |
| <tr class="row-even"><td><code>progress</code></td> |
| <td>3</td> |
| </tr> |
| <tr class="row-odd"><td><code>load</code></td> |
| <td>4</td> |
| </tr> |
| <tr class="row-even"><td><code>loadend</code></td> |
| <td>4</td> |
| </tr> |
| </tbody> |
| </table> |
| <p>The following code demonstrates how to monitor the loading process using the |
| <code>readyState</code> attribute. As before, the script that adds the event listeners |
| precedes the <code><embed></code> element so that the event listeners are in place before |
| the progress events are generated.</p> |
| <pre class="prettyprint"> |
| <html> |
| ... |
| <body id="body"> |
| <div id="status_div"> |
| </div> |
| <div id="listener_div"> |
| <script type="text/javascript"> |
| var stat = document.getElementById('status_div'); |
| function handleEvent(e) { |
| var embed_element = document.getElementById('my_embed'); |
| stat.innerHTML += |
| '<br>' + e.type + ': readyState = ' + embed_element.readyState; |
| } |
| var listener_element = document.getElementById('listener_div'); |
| listener_element.addEventListener('loadstart', handleEvent, true); |
| listener_element.addEventListener('progress', handleEvent, true); |
| listener_element.addEventListener('load', handleEvent, true); |
| listener_element.addEventListener('loadend', handleEvent, true); |
| </script> |
| <embed |
| name="naclModule" |
| id="my_embed" |
| width=0 height=0 |
| src="my_example.nmf" |
| type="application/x-pnacl" /> |
| </div> |
| </body> |
| </html> |
| </pre> |
| <h2 id="the-exitstatus-attribute">The <code>exitStatus</code> attribute</h2> |
| <p>This read-only attribute is set if the application calls <code>exit(n)</code>, |
| <code>abort()</code>, or crashes. Since NaCl modules are event handlers, there is no |
| need to call <code>exit(n)</code> in normal execution. If the module does exit or |
| crash, the <code>crash</code> progress event is issued and the <code>exitStatus</code> attribute |
| will contain the numeric value of the exit status:</p> |
| <ul class="small-gap"> |
| <li>In the case of explicit calls to <code>exit(n)</code>, the numeric value will be |
| <code>n</code> (between 0 and 255).</li> |
| <li>In the case of crashes and calls to <code>abort()</code>, the numeric value will |
| be non-zero, but the exact value will depend on the chosen libc and the |
| target architecture, and may change in the future. Applications should not |
| rely on the <code>exitStatus</code> value being stable in these cases, but the value |
| may nevertheless be useful for temporary debugging.</li> |
| </ul> |
| </section> |
| |
| {{/partials.standard_nacl_article}} |