OLD | NEW |
(Empty) | |
| 1 {{+bindTo:partials.standard_nacl_article}} |
| 2 |
| 3 <section id="progress-events"> |
| 4 <span id="devcycle-progress-events"></span><h1 id="progress-events"><span id="de
vcycle-progress-events"></span>Progress Events</h1> |
| 5 <div class="contents local topic" id="contents"> |
| 6 <ul class="small-gap"> |
| 7 <li><a class="reference internal" href="#module-loading-and-progress-events" id=
"id3">Module loading and progress events</a></li> |
| 8 <li><a class="reference internal" href="#handling-progress-events" id="id4">Hand
ling progress events</a></li> |
| 9 <li><a class="reference internal" href="#displaying-load-status" id="id5">Displa
ying load status</a></li> |
| 10 <li><a class="reference internal" href="#the-lasterror-attribute" id="id6">The <
code>lastError</code> attribute</a></li> |
| 11 <li><a class="reference internal" href="#the-readystate-attribute" id="id7">The
<code>readyState</code> attribute</a></li> |
| 12 <li><a class="reference internal" href="#the-exitstatus-attribute" id="id8">The
<code>exitStatus</code> attribute</a></li> |
| 13 </ul> |
| 14 </div> |
| 15 <p>There are five types of events that developers can respond to in Native Clien
t: |
| 16 progress, message, view change, focus, and input events (each described in the |
| 17 glossary below). This chapter describes how to monitor progress events (events |
| 18 that occur during the loading and execution of a Native Client module). This |
| 19 chapter assumes you are familiar with the material presented in the |
| 20 <a class="reference internal" href="/native-client/overview.html"><em>Technical
Overview</em></a>.</p> |
| 21 <aside class="note"> |
| 22 The load_progress example illustrates progress event handling. You can find |
| 23 this code in the <code>/examples/tutorial/load_progress/</code> directory in the
Native |
| 24 Client SDK download. |
| 25 </aside> |
| 26 <section id="module-loading-and-progress-events"> |
| 27 <h2 id="module-loading-and-progress-events">Module loading and progress events</
h2> |
| 28 <p>The Native Client runtime reports a set of state changes during the module |
| 29 loading process by means of DOM progress events. This set of events is a direct |
| 30 port of the proposed W3C <a class="reference external" href="http://www.w3.org/T
R/progress-events/">Progress Events</a> standard (except for the <code>crash</co
de> |
| 31 event which is an extension of the W3C standard). The following table lists the |
| 32 events types reported by the Native Client runtime:</p> |
| 33 <table border="1" class="docutils"> |
| 34 <colgroup> |
| 35 </colgroup> |
| 36 <thead valign="bottom"> |
| 37 <tr class="row-odd"><th class="head">Event</th> |
| 38 <th class="head">Description</th> |
| 39 <th class="head">Number of |
| 40 times |
| 41 triggered</th> |
| 42 <th class="head">When event is |
| 43 triggered</th> |
| 44 <th class="head">How you might |
| 45 react to |
| 46 event</th> |
| 47 </tr> |
| 48 </thead> |
| 49 <tbody valign="top"> |
| 50 <tr class="row-even"><td><code>loadstart</code></td> |
| 51 <td>Native Client has |
| 52 started to load a |
| 53 Native Client |
| 54 module.</td> |
| 55 <td>once</td> |
| 56 <td>This is the |
| 57 first |
| 58 progress |
| 59 event |
| 60 triggered |
| 61 after the |
| 62 Native Client |
| 63 module is |
| 64 instantiated |
| 65 and |
| 66 initialized.</td> |
| 67 <td>Display a |
| 68 status |
| 69 message, such |
| 70 as |
| 71 “Loading...”</td> |
| 72 </tr> |
| 73 <tr class="row-odd"><td><code>progress</code></td> |
| 74 <td>Part of the module |
| 75 has been loaded.</td> |
| 76 <td>zero or |
| 77 more</td> |
| 78 <td>After |
| 79 <code>loadstart</code> |
| 80 has been |
| 81 dispatched.</td> |
| 82 <td>Display a |
| 83 progress bar.</td> |
| 84 </tr> |
| 85 <tr class="row-even"><td><code>error</code></td> |
| 86 <td>The Native Client |
| 87 module failed to |
| 88 start execution |
| 89 (includes any |
| 90 error before or |
| 91 during |
| 92 initialization of |
| 93 the module). The |
| 94 <code>lastError</code> |
| 95 attribute |
| 96 (mentioned later) |
| 97 provides details |
| 98 on the error |
| 99 (initialization |
| 100 failed, sel_ldr |
| 101 did not start, |
| 102 and so on).</td> |
| 103 <td>zero or |
| 104 once</td> |
| 105 <td>After the |
| 106 last |
| 107 <code>progress</code> |
| 108 event has |
| 109 been |
| 110 dispatched, |
| 111 or after |
| 112 <code>loadstart</code> |
| 113 if no |
| 114 <code>progress</code> |
| 115 event was |
| 116 dispatched.</td> |
| 117 <td>Inform user |
| 118 that the |
| 119 application |
| 120 failed to |
| 121 load.</td> |
| 122 </tr> |
| 123 <tr class="row-odd"><td><code>abort</code></td> |
| 124 <td>Loading of the |
| 125 Native Client |
| 126 module was |
| 127 aborted by the |
| 128 user.</td> |
| 129 <td>zero or |
| 130 once</td> |
| 131 <td>After the |
| 132 last |
| 133 <code>progress</code> |
| 134 event has |
| 135 been |
| 136 dispatched, |
| 137 or after |
| 138 <code>loadstart</code> |
| 139 if no |
| 140 <code>progress</code> |
| 141 event was |
| 142 dispatched.</td> |
| 143 <td>It’s not |
| 144 likely you |
| 145 will want to |
| 146 respond to |
| 147 this event.</td> |
| 148 </tr> |
| 149 <tr class="row-even"><td><code>load</code></td> |
| 150 <td>The Native Client |
| 151 module was |
| 152 successfully |
| 153 loaded, and |
| 154 execution was |
| 155 started. (The |
| 156 module was |
| 157 initialized |
| 158 successfully.)</td> |
| 159 <td>zero or |
| 160 once</td> |
| 161 <td>After the |
| 162 last |
| 163 <code>progress</code> |
| 164 event has |
| 165 been |
| 166 dispatched, |
| 167 or after |
| 168 <code>loadstart</code> |
| 169 if no |
| 170 <code>progress</code> |
| 171 event was |
| 172 dispatched.</td> |
| 173 <td>Remove the |
| 174 progress bar.</td> |
| 175 </tr> |
| 176 <tr class="row-odd"><td><code>loadend</code></td> |
| 177 <td>Loading of the |
| 178 Native Client |
| 179 module has |
| 180 stopped. Load |
| 181 succeeded |
| 182 (<code>load</code>), |
| 183 failed |
| 184 (<code>error</code>), or |
| 185 was aborted |
| 186 (<code>abort</code>).</td> |
| 187 <td>once</td> |
| 188 <td>After an |
| 189 <code>error</code>, |
| 190 <code>abort</code>, or |
| 191 <code>load</code> |
| 192 event was |
| 193 dispatched.</td> |
| 194 <td>Indicate |
| 195 loading is |
| 196 over |
| 197 (regardless |
| 198 of failure or |
| 199 not).</td> |
| 200 </tr> |
| 201 <tr class="row-even"><td><code>crash</code></td> |
| 202 <td>The Native Client |
| 203 module is not |
| 204 responding (died |
| 205 on an |
| 206 <code>assert()</code> or |
| 207 <code>exit()</code>) after |
| 208 a successful |
| 209 load. This event |
| 210 is unique to |
| 211 Native Client and |
| 212 is not part of |
| 213 the W3C Progress |
| 214 Events standard. |
| 215 The <code>exitStatus</code> |
| 216 attribute provides |
| 217 the numeric exit |
| 218 status value.</td> |
| 219 <td>zero or |
| 220 once</td> |
| 221 <td>After a |
| 222 <code>loadend</code>.</td> |
| 223 <td>Notify user |
| 224 that the |
| 225 module did |
| 226 something |
| 227 illegal.</td> |
| 228 </tr> |
| 229 </tbody> |
| 230 </table> |
| 231 <p>The sequence of events for a successful module load is as follows:</p> |
| 232 <table border="1" class="docutils"> |
| 233 <colgroup> |
| 234 </colgroup> |
| 235 <thead valign="bottom"> |
| 236 <tr class="row-odd"><th class="head">Event is dispatched</th> |
| 237 <th class="head">... then this task is attempted</th> |
| 238 </tr> |
| 239 </thead> |
| 240 <tbody valign="top"> |
| 241 <tr class="row-even"><td><code>loadstart</code></td> |
| 242 <td>load the manifest file</td> |
| 243 </tr> |
| 244 <tr class="row-odd"><td><code>progress</code> (first time)</td> |
| 245 <td>load the module</td> |
| 246 </tr> |
| 247 <tr class="row-even"><td><code>progress</code> (subsequent times)</td> |
| 248 <td> </td> |
| 249 </tr> |
| 250 <tr class="row-odd"><td><code>load</code></td> |
| 251 <td>start executing the module</td> |
| 252 </tr> |
| 253 <tr class="row-even"><td><code>loadend</code></td> |
| 254 <td> </td> |
| 255 </tr> |
| 256 </tbody> |
| 257 </table> |
| 258 <p>Errors that occur during loading are logged to the JavaScript console in Goog
le |
| 259 Chrome (select the menu icon <img alt="menu-icon" src="/native-client/images/men
u-icon.png" /> > Tools > JavaScript console).</p> |
| 260 </section><section id="handling-progress-events"> |
| 261 <h2 id="handling-progress-events">Handling progress events</h2> |
| 262 <p>You should add event listeners in a <code><script></code> element to li
sten for these |
| 263 events before the <code><embed></code> element is parsed. For example, the
following code |
| 264 adds a listener for the <code>load</code> event to a parent <code><div></c
ode> element that also |
| 265 contains the Native Client <code><embed></code> element. First, the listen
er is |
| 266 attached. Then, when the listener <code><div></code> receives the <code>lo
ad</code> event, the |
| 267 JavaScript <code>moduleDidLoad()</code> function is called. The following code i
s |
| 268 excerpted from the example in <code>getting_started/part1/</code>:</p> |
| 269 <pre class="prettyprint"> |
| 270 <!-- |
| 271 Load the published pexe. |
| 272 Note: Since this module does not use any real-estate in the browser, its |
| 273 width and height are set to 0. |
| 274 |
| 275 Note: The <embed> element is wrapped inside a <div>, which has both
a 'load' |
| 276 and a 'message' event listener attached. This wrapping method is used |
| 277 instead of attaching the event listeners directly to the <embed> element t
o |
| 278 ensure that the listeners are active before the NaCl module 'load' event |
| 279 fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or |
| 280 pp::Instance.PostMessage() (in C++) from within the initialization code in |
| 281 your module. |
| 282 --> |
| 283 <div id="listener"> |
| 284 <script type="text/javascript"> |
| 285 var listener = document.getElementById('listener'); |
| 286 listener.addEventListener('load', moduleDidLoad, true); |
| 287 listener.addEventListener('message', handleMessage, true); |
| 288 </script> |
| 289 |
| 290 <embed id="hello_tutorial" |
| 291 width=0 height=0 |
| 292 src="hello_tutorial.nmf" |
| 293 type="application/x-pnacl" /> |
| 294 </div> |
| 295 </pre> |
| 296 <p>Event listeners can be added to any DOM object. Since listeners set at the |
| 297 outermost scope capture events for their contained elements, you can set |
| 298 listeners on outer elements (including the <code><body></code> element) to
handle events |
| 299 from inner elements. For more information, see the W3 specifications for <a clas
s="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html
#Events-flow-capture">event |
| 300 flow capture</a> and |
| 301 <a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/even
ts.html#Events-registration">event listener registration</a>.</p> |
| 302 </section><section id="displaying-load-status"> |
| 303 <h2 id="displaying-load-status">Displaying load status</h2> |
| 304 <p>One common response to progress events is to display the percentage of the |
| 305 module that has been loaded. In the load_progress example, when the <code>progre
ss</code> |
| 306 event is triggered the <code>moduleLoadProgress</code> function is called. This
function |
| 307 uses the <code>lengthComputable</code>, <code>loaded</code>, and <code>total</co
de> attributes (described |
| 308 in the proposed W3C <a class="reference external" href="http://www.w3.org/TR/pro
gress-events/">Progress Events</a> |
| 309 standard) of the event to calculate the percentage of the module that has |
| 310 loaded.</p> |
| 311 <pre class="prettyprint"> |
| 312 function moduleLoadProgress(event) { |
| 313 var loadPercent = 0.0; |
| 314 var loadPercentString; |
| 315 if (event.lengthComputable && event.total > 0) { |
| 316 loadPercent = event.loaded / event.total * 100.0; |
| 317 loadPercentString = loadPercent + '%'; |
| 318 common.logMessage('progress: ' + event.url + ' ' + loadPercentString + |
| 319 ' (' + event.loaded + ' of ' + event.total + ' bytes)'); |
| 320 } else { |
| 321 // The total length is not yet known. |
| 322 common.logMessage('progress: Computing...'); |
| 323 } |
| 324 } |
| 325 </pre> |
| 326 </section><section id="the-lasterror-attribute"> |
| 327 <h2 id="the-lasterror-attribute">The <code>lastError</code> attribute</h2> |
| 328 <p>The <code><embed></code> element has a <code>lastError</code> attribute
that is set to an |
| 329 informative string whenever a load failure (an <code>error</code> or <code>abort
</code> event) |
| 330 occurs.</p> |
| 331 <p>The following code adds an event listener before the <code><embed></cod
e> element to |
| 332 capture and handle an error in loading the Native Client module. The |
| 333 <code>handleError()</code> function listens for an <code>error</code> event. Whe
n an error occurs, |
| 334 this function prints the contents of the <code>lastError</code> attribute |
| 335 (<code>embed_element.lastError</code>) as an alert.</p> |
| 336 <pre class="prettyprint"> |
| 337 function domContentLoaded(name, tc, config, width, height) { |
| 338 var listener = document.getElementById('listener'); |
| 339 ... |
| 340 listener.addEventListener('error', moduleLoadError, true); |
| 341 ... |
| 342 common.createNaClModule(name, tc, config, width, height); |
| 343 } |
| 344 |
| 345 function moduleLoadError() { |
| 346 common.logMessage('error: ' + common.naclModule.lastError); |
| 347 } |
| 348 </pre> |
| 349 </section><section id="the-readystate-attribute"> |
| 350 <h2 id="the-readystate-attribute">The <code>readyState</code> attribute</h2> |
| 351 <p>You can use the <code>readyState</code> attribute to monitor the loading proc
ess. This |
| 352 attribute is particularly useful if you don’t care about the details of |
| 353 individual progress events or when you want to poll for current load state |
| 354 without registering listeners. The value of <code>readyState</code> progresses a
s follows |
| 355 for a successful load:</p> |
| 356 <table border="1" class="docutils"> |
| 357 <colgroup> |
| 358 </colgroup> |
| 359 <thead valign="bottom"> |
| 360 <tr class="row-odd"><th class="head">Event</th> |
| 361 <th class="head"><code>readyState</code> value</th> |
| 362 </tr> |
| 363 </thead> |
| 364 <tbody valign="top"> |
| 365 <tr class="row-even"><td>(before any events)</td> |
| 366 <td><code>undefined</code></td> |
| 367 </tr> |
| 368 <tr class="row-odd"><td><code>loadstart</code></td> |
| 369 <td>1</td> |
| 370 </tr> |
| 371 <tr class="row-even"><td><code>progress</code></td> |
| 372 <td>3</td> |
| 373 </tr> |
| 374 <tr class="row-odd"><td><code>load</code></td> |
| 375 <td>4</td> |
| 376 </tr> |
| 377 <tr class="row-even"><td><code>loadend</code></td> |
| 378 <td>4</td> |
| 379 </tr> |
| 380 </tbody> |
| 381 </table> |
| 382 <p>The following code demonstrates how to monitor the loading process using the |
| 383 <code>readyState</code> attribute. As before, the script that adds the event lis
teners |
| 384 precedes the <code><embed></code> element so that the event listeners are
in place before |
| 385 the progress events are generated.</p> |
| 386 <pre class="prettyprint"> |
| 387 <html> |
| 388 ... |
| 389 <body id="body"> |
| 390 <div id="status_div"> |
| 391 </div> |
| 392 <div id="listener_div"> |
| 393 <script type="text/javascript"> |
| 394 var stat = document.getElementById('status_div'); |
| 395 function handleEvent(e) { |
| 396 var embed_element = document.getElementById('my_embed'); |
| 397 stat.innerHTML += |
| 398 '<br>' + e.type + ': readyState = ' + embed_element.readyState; |
| 399 } |
| 400 var listener_element = document.getElementById('listener_div'); |
| 401 listener_element.addEventListener('loadstart', handleEvent, true); |
| 402 listener_element.addEventListener('progress', handleEvent, true); |
| 403 listener_element.addEventListener('load', handleEvent, true); |
| 404 listener_element.addEventListener('loadend', handleEvent, true); |
| 405 </script> |
| 406 <embed |
| 407 name="naclModule" |
| 408 id="my_embed" |
| 409 width=0 height=0 |
| 410 src="my_example.nmf" |
| 411 type="application/x-pnacl" /> |
| 412 </div> |
| 413 </body> |
| 414 </html> |
| 415 </pre> |
| 416 </section><section id="the-exitstatus-attribute"> |
| 417 <h2 id="the-exitstatus-attribute">The <code>exitStatus</code> attribute</h2> |
| 418 <p>This read-only attribute is set if the application calls <code>exit(n)</code>
, |
| 419 <code>abort()</code>, or crashes. Since NaCl modules are event handlers, there i
s no |
| 420 need to call <code>exit(n)</code> in normal execution. If the module does exit o
r |
| 421 crash, the <code>crash</code> progress event is issued and the <code>exitStatus<
/code> attribute |
| 422 will contain the numeric value of the exit status:</p> |
| 423 <ul class="small-gap"> |
| 424 <li>In the case of explicit calls to <code>exit(n)</code>, the numeric value wil
l be |
| 425 <code>n</code> (between 0 and 255).</li> |
| 426 <li>In the case of crashes and calls to <code>abort()</code>, the numeric value
will |
| 427 be non-zero, but the exact value will depend on the chosen libc and the |
| 428 target architecture, and may change in the future. Applications should not |
| 429 rely on the <code>exitStatus</code> value being stable in these cases, but the v
alue |
| 430 may nevertheless be useful for temporary debugging.</li> |
| 431 </ul> |
| 432 </section></section> |
| 433 |
| 434 {{/partials.standard_nacl_article}} |
OLD | NEW |