Version 17, last updated by slim at March 18, 2007 22:27 UTC

Dynamically constructs an infotron from a javascript blueprint. It can also destruct the constructed infotron.

Sample Declaration

<div id="atomic_konstructor"
    impl="~01A13E7DA4AC6944339D713FA5A32773A6"
    script="http://localhost/AtomicConstructor.js">
</div>

Input Terminals

  • request_in: (expected message type: array - i.e. [request_id, op_code, blueprint_uuid, property_value_map])

Output Terminals

  • response_out: (message type: array - i.e. [request_id, op_code, id, input_terminals, output_terminals ])

Properties

  • N/A

Demos that use it

  • N/A

How does it work?

Using the Star API it creates a new infotron instance of the specified blueprint. If the specified blueprint has not been loaded, a "bpmiss" event is dispatched. It is then upto whoever is supposed to handle the "bpmiss" event to load the missing blueprint. When the blueprint gets loaded, this infotron notices it and continues on its way to send out a response out through the "response_out" terminal. The response contains, among other things, a list of input and ouput terminals to which channels can be established.

Source


/*
  Atomic JavaScript Constructor

  [id, infotron_id, iterms, oterms]

  Seung Chan Lim ( slim@maya.com )
*/
BLUEPRINT(
"~01A13E7DA4AC6944339D713FA5A32773A6",
[
 ["request_in", "onRequest", -1]
],
[
 "response_out"
],
	  
function(props)
{
  var Blueprint = function(id, props, bp_uuid)
    {
      var self = this;

      this.__init__(id, bp_uuid);   
      this._uid = 0;
      this._HANDLER = {"construct" : this._construct,
		    "destruct" : this._destruct};
      this._ids = {};

      function _onBpLoad(bp)
      {
	var i, n,  ids, id, bp_iterms;
	var iterms = [];
       	self.info(bp.uuid + " got loaded!");
	
	ids = self._ids[bp.uuid];
	
	if (ids) {
	  bp_iterms = bp.iterms;
	  iterms = self._flattenIterms(bp.iterms);
	  
	  n = ids.length;
	  
	  for (i = 0; i < n; i ++) {	  
	    id = ids[i];
	    self.postMessage("response_out", [id[0], "construct", id[1], iterms, bp.oterms]);
	  }
	}
      }

      __star.addEventListener("afterbpload", _onBpLoad);

    };

  Blueprint.prototype = new Infotron;


    Blueprint.prototype._flattenIterms = function(iterms)
    {
      var i, n;
      var l = [];

      n = iterms.length;
	
      for (i =0; i < n; i ++) {
	l.push(iterms[i][0]);
      }

      return l;
    }

    Blueprint.prototype._construct = function(req_id, bp, iprops, xprops)
    {
      var i, n, e, o, arr, cbs;
      var d = this.dom_node.ownerDocument || __d;
	
	o = d.createElement("DIV");

	if (xprops) {
	  o.className = xprops["css_prefix"] || "";

	  if (xprops["id"]) {
	    o.id = xprops["id"];
	  }
	}

	if (!o.id) {
	  o.id = this.dom_node.id + "_" + new String(this._uid) + "_" + 
	    new String((new Date()).valueOf()) ;
	}

        this._uid += 1;
	o.setAttribute("impl", bp);
	this.dom_node.parentNode.appendChild(o);

	arr = __star.addInfotron(o.id, bp, iprops);

	if (!arr) {
	  if (!this._ids[bp]) {
	    this._ids[bp] = [];
	  }

	  this._ids[bp].push([req_id, o.id]);

	  // here onMissingImpl is called immediately before waiting for a 
	  // message to arrive	  
	  __star.dispatchEvent({type:"bpmiss", context:[o.id, bp]});
	} else {

	    // send out the available input and output terminals

	  return [req_id, "construct", o.id, this._flattenIterms(arr[0]), arr[1]];
	    /*****************************************************************/
	}
    }

    Blueprint.prototype._destruct = function(req_id, id)
    {
      this.info("destroying " + id);
	__star.removeInfotron(id, 1);
	
	return [req_id, "destruct", id];
    }
    
    Blueprint.prototype.onRequest = function(msg)
    {
	var resp, id;
	
	id = msg[0];
	op = msg[1];
	args = msg[2];

	try {
	  resp = this._HANDLER[op].apply(this, ([id]).concat(args));
	} catch (ex) {
	  this.error(ex, "Error handling " + op);
	}

	if (resp != undefined) {
	  this.postMessage("response_out", resp);
	}
    };

    return Blueprint;
}, 
"Atomic Constructor")