Skip to content

CallbackJS

Marc Capdevielle edited this page Oct 8, 2010 · 4 revisions

Javascript callbacks

Introduction

When extending the Javascript APIs (see ExtendJS for more info), the Javascript APIs must use background threads to handle long and expensive calls.

This is to prevent locking the main thread which is responsible of reacting to user events, executing Javascript code, propagating VRML events and doing all the graphic rendering.

Javascript side

To be able to notify some Javascript code that a background thread as terminated its work, one must use Javascript callbacks.

Look at the following Javascript example of the Browser.setTimeout() method that calls a methods after a given amount of time:

   function initialize () {
     // call the myCallback in 2 seconds with two parameters
     Browser.setTimeout (myCallback, 2000, 'hello', 'world');
   }
   function myCallback (firstArg, secondArg, now) {
      Browser.print ('callback called with arg1:'+firstArg+' arg2:'+arg2+' at  time '+now);
   }

The initialize() method returns immediately after the call to Browser.setTimeout(). The player will then automaticaly call the myCallback() method after the given amount of time has elapsed.

Implementation

To call a javascript callback, the calling code must retain a reference to the Script node that called the function and the ID of the function that must be called in the Script.

It must then register the call to the callback by calling the addCallback of the Script with the ID and the arguments for the callback.

Then a call to the MiniPlayer.wakeUpCanvas() static method must be done to force the main thread to wake up (in case it was sleeping, which is normaly always the case when no animation or event propagation occurs).

To illustrate this, we will build a naive implementation of the Browser.setTimeout() method that will just spawn a thread that will sleep the given amount of time and then call Javascript callback.

         case 0: // delayCall (int cb, int delay, [args])
             final Script script = c.script; // keep a ref to the current Script
             final int cb = registers[r].getInt (); // keep the ID of the JS callback
             final int delay = registers[r+1].getInt (); // keep the delay
             // Keep all the optional parameters
             final Register[] params = new Register[nbParams-2];
             for (int i = 0; i<nbParams-2; i++) {
                 params[i] = new Register ();
                 params[i].set (registers[r+2+i]);
             }
             new Thread () {
                 public void run () {
                     // sleep the given delay
                     Thread.sleep (delay);
                     // ask the Script to call the callback with given parameters
                     script.addCallback (cb, params);
                     // wakeup the main thread
                     MiniPlayer.wakeUpCanvas ();
                 }
             }.start();
             break;
Clone this wiki locally