Draft

Linking Sketches

Your browser does not support this tag.     Your browser does not support this tag.     Your browser does not support this tag.
Information for the Right sketch
x/y: /

Message from Javascript:

The Pomax Guide describes how to connect sketches on a web page. This page describes how to connect any number of sketches (and optionally with Javascript).

If you move the mouse cursor across the left sketch (without pressing a button), you observe horizontal and vertical lines intersecting at the cursor. The same lines are drawn on the other sketches. If you move the cursor across the middle sketch, a square is draw on all three sketches. If you move the mouse cursor across the right sketch, a circle will be drawn at the cursor. The same circle is drawn on the other sketches. In addition the circle's coordinates are recorded in text fields on the .html page. (If you press a button while moving the mouse, the movement is ignored.) Finally, if you type some values in those text fields and click the "Draw Circle", a circle is drawn at that point in the right sketch which is then duplicated on the other sketches. These actions are possible because Javascript was used to link the three sketches and the right sketch with Javascript.

This page shows one Processing.js technique to carry out the linking. Each sketch contains some customized code for completing the links. An alternative uses an almost generic file to carry out the linking. It is used by each of the sketches.

What is necessary to get the sketches to see each other? It begins with the canvas statements:

<canvas id="leftSketch" data-processing-sources="Left.pde"> 
                 Your browser does not support this tag.</canvas> 
<canvas id="middleSketch" data-processing-sources="Middle.pde">
                 Your browser does not support this tag.</canvas> 
<canvas id="rightSketch" data-processing-sources="Right.pde">  
                 Your browser does not support this tag.</canvas> 

The most important part other than naming the sketch files is the id names. They are referred to in the Javascript function bindProcessingJS, which is an expanded version of that used by Pomax. The code segment begins with declarations setting up an array with the links to the sketches and another array containing the ids.

     var pjsLeft = null;
     var pjsMiddle = null;
     var pjsRight = null;
     var pjs = [pjsLeft, pjsMiddle, pjsRight];  // links to sketches
     var idArray = ["leftSketch", "middleSketch", "rightSketch"];

     /**
      * Make connections to the sketches
      */
     function bindProcessingJs() { 
        var bound = true;   
        // Connect to the sketches
        for (i = 0; i < pjs.length; i++) {
           if (pjs[i] == null) {
             pjs[i] = Processing.getInstanceById(idArray[i]);
             if (pjs[i] == null)
               bound = false;
           }
        }   
        // Do we have the connections?      
        if (!bound) {
           // Repeat this procedure if any of the sketches is still unbound
           setTimeout(bindProcessingJs, 250);
        } else {
           try {  // primarily as debugging aid
             // Provide the links to the sketches
              for (i = 0; i < pjs.length; i++) {
                 pjs[i].setLinkSketch(pjs, this);
              }
           } catch(e) {
              alert("Error: " + e + " " + pjsLeft + " " + pjsMiddle + " " + pjsRight);
           }
           showMessageJS("Linking the sketches is complete.  Try moving the cursor over sketches");
        }   
     }  // bindProcessingJS

Two arrays are used to allow processing an arbitary number of sketches. The pjs array contains links to the sketches. The idArray contains the list of the ids (as named in the canvas statements). Actually, the first 4 lines could be replalced by

     var pjs = [null, null, null];

The original method has a small advantage in clarifying what the elements of pjs represent.

Lets take a look at the function, bindProcessingJs(). The bound variable is assumed to be true but will be changed to false if any of the links fails.

The first loop iterates through the sketches. If the link is still null, it attempts to establish the link using the function Processing.getInstanceById(...). It is difficult to find a precise reference for this function but Pomax says "This is the pivotal function on the Javascript side of things. It gives you a direct reference to your sketch, and everything in it, so that you can call any function and examine and modify any variable that is in the sketch." If the functions fails to make the connection, bound is set false.

Because Javascript may load and run before the sketches are loaded, there is a good possibility that the attempts to create links will fail initially. Hence the next section checks to see if all the links have been made (bound is still true.) If not, it tries again in 250 microseconds. But if all of the links have been established, it moves on and provides the links to the sketches. The sketches have customized versions of a method setLinkSketch that gets the links. The entire array of links is provided but a particular sketch only needs to record the links it needs. Likewise, the link back to Javascript is sent. A sketch needs to save it only if wants to communicate back to the Javascript on the web page. (The alternative, uses a generic setLinkSketch that is used by all the sketches and saves all the links rather or not they are needed.) The try/catch construction may be a help while debugging.

The setLinkSketch(...) function for the left sketch is as follows and allows the sketch to link to the middle and right hand sketch:

  void setLinkSketch(Object[] pjs, JavaScript js) {
    pjsMiddle = pjs[1];
    pjsRight = pjs[2];
  }  // setLinkSketch

The setLinkSketch for the middle sketch is similar except it saves the link for the left hand sketch instead of the middle sketch.

While all three sketches declare a interface for JavaScript, only the right hand sketch actually puts to good use. This interface allows the right hand sketch to send information back to Javascript in the web page. The showXYCoordinatesJS function writes the coordinates of the circle into the text fields in the webpage.

  interface JavaScript {
    void showXYCoordinatesJS(int x, int y); 
  }  // interface JavaScript
  JavaScript Javascript;

Then the setLinkSketch method for the right sketch saves the link to Javascript as well as links to the other two sketches.

  void setLinkSketch(Object[] pjs, JavaScript js) {
    pjsLeft = pjs[0];
    pjsMiddle = pjs[1];
    javascript = js;
  }  // setLinkSketch

  Object pjsLeft, pjsMiddle;

An important comment: While in this situation it was not necessary, in many situations one of the sketches might want to supply initialization information to the other sketches or possibly to the .html page. The setLinkSketch methods are the perfect place to add this code as it cannot be accomplished before the controlling sketch has a link to the other sketches and to JavaScript.

The final question is now that the links are known to the sketches, how does it use them to provide information to the other sketches or to the .html file? It is pretty straight forward. The following example is from the right sketch. xCircle and yCircle are sent to the other two sketches as well as to Javascript.

   void mouseMoved() {
    xCircle = mouseX;
    yCircle = mouseY;
    if (pjsLeft != null) {
      pjsLeft.drawCircle(xCircle, yCircle);
    }
    if (pjsMiddle != null) {
      pjsMiddle.drawCircle(xCircle, yCircle);
    }
    if (javascript != null) {
      javascript.showXYCoordinatesJS(xCircle, yCircle);
    }
    redraw();
  }  // mouseMoved

"pjsLeft" links to left sketch, the "drawCircle" method is declared in that sketch and as expected, draws the circle. Likewise for the middle sketch. "Javascript" is the link to the Javascript code and "showXYCoordinatesJS" writes the two values into the corresponding text fields. The sketch is redrawn because noLoop() is used in the setup method and the sketch is redrawn only when something changes.

Finally some optional code that may be useful. Debugging multiple .pde files that are to be displayed on the same page may be a challenge. The Processing IDE cannot be used to run the resulting page because some names appear in both files. The "message" text field and "showMessageJS" and "appendMessageJS" methods may help a little. The "showMessageJS" was called near the end of the bindProcessingJS function. When either of these functions are called, the parameter is displayed or appended to the message text field. This can be used to display useful error messages created by Javascript (and hence by Processing.js). These functions could be called by the right hand sketch if their prototype was added to the Javascript interface in that file. But there is a very important limitation: These functions cannot be called before the message text field is actually created. Doing so causes an error compounding the debugging problems! Because of this, the code displaying "Linking the sketches" message shown below the sketches was inserted near the end of the html file after the page was completely built. The function is also called at the end of bindJavascriptJS which happens after the web page is complete. and linking is accomplished.

The complete code for the 4 files can be obtained from the following links:
LinkSketches.html (stored as a text file for convenient display)
Left.pde
Middle.pde
Right.pde

LinkSketchesAlt.html An alternative technique


Reference: http://processingjs.org/articles/PomaxGuide.html