Skip to content

How to Analyze and Access Xflow from JavaScript

lachsen edited this page Oct 9, 2013 · 1 revision

Analyze dataflows and read data results

XML3D + Xflow provide an interface, that allows to analyze the structure of dataflow and access processed results from JavaScript.

The following interface is provided by all data containers, e.g. <data>, <mesh>, <shader> and <lightshader>:

interface XML3DDataElement {
    ... existing attributes and methods ...

    /** Triggers the computation of the graph (if needed) and return resulting data.
     *
     *  @param filter Field names that programmer is interested in, if missing - all fields are requested
     *  @return Computed data.
     */
    XML3DDataResult getResult(optional in DOMString[] filter);

    /** Returns an array that contains names of all available fields that can be requested. */
    DOMString[] getOutputNames();

    /** Returns information about an output without triggering computation */
    XML3DDataChannelInfo getOutputChannelInfo(DOMString name);

    /** Returns information about the attached operator or null if no operator is attached 
        WARNING: Currently not implement
    */
    XML3DComputeInfo getComputeInfo();

    /** Returns information about the attached prototype or null if no prototype is attached 
        WARNING: Currently not implement
    */
    XML3DProtoInfo getProtoInfo();
        
    /** Returns true if the output of the child XML3DDataElement  is directly connected to this 
        XML3DDataElement(e.g. as output, prototype input or operator input) 
        WARNING: Currently not implement
    */
    boolean isOutputConnected(child, outputName);
}

The Xflow result can be accessed via this interface:

interface XML3DDataResult {
    /** Constant values for the type attribute */
    const unsigned short FLOAT = 0;
    const unsigned short FLOAT2 = 1;
    const unsigned short FLOAT3 = 2;
    const unsigned short FLOAT4 = 3;
    const unsigned short FLOAT4X4 = 4;
    const unsigned short INT = 10;
    const unsigned short INT4 = 11;
    const unsigned short BOOL = 20;
    const unsigned short TEXTURE = 30;

    /** Returns an array of names for which values exist in this result */
    getter DOMString[] getNames();

    /** Returns the value of the entry with the given name.
        The value is usually a TypedArray.
        Return null when no entry exists for the given name.
    */
    getter Object getValue(in DOMString name);

    /** Returns the type of the entry with the given name.
        Return null when no entry exists for the given name.
    */
    getter unsigned short getType(in DOMString name);
}

When calling getOutputChannelInfo() the following structure is returned:

interface XML3DDataChannelInfo{
    
    /** Constant values for the origin attribute */
    const unsigned short ORIGIN_CHILD = 1;
    const unsigned short ORIGIN_COMPUTE = 2;
    const unsigned short ORIGIN_PROTO = 3;

    /** Type of the output data. Using type enum of XML3DDataEntry */
    readonly attribute unsigned short type;

    /** The number of sequence entries for this data channel */
    readonly attribute unsigned length seqLength;

    /** the minimum key of the sequence */
    readonly attribute double seqMinKey;

    /** the maximum key of the sequence */
    readonly attribute double seqMaxKey;

    /** the origins of the channel */
    readonly attribute unsigned short origins;
    
    /** the original name of the channel (previously to renaming from filter or compute of the current node)*/
    readonly attribute DOMString originalName;
}

Listen to changes in the Xflow Graph

The XML3DDataObserver allows you to listen to changes of individual data containers. The XML3DDataObserver is declared with a callback function like this:

var observer = new XML3DDataObserver( observerCallBack );

Whereas observerCallBack is a function that when observed data containers change.

To specify, which data containers are observed, we call the observe method:

// Get a couple of <data> elements
var dataNodes = document.getElementsByTagName("data");
// Observe all changes
observer.observe(dataNodes[0]);
// Observe any change modifying the "position" value
observer.observe(dataNodes[1], "position");
// Observe any change modifying the "position" or "normal" value
observer.observe(dataNodes[2], ["position", "normal"]);

Note that the XML3DDataObserver will not invoke the callback function immediately whenever the result of any of the observed nodes changes. Instead, all changed are collected into a list of records and passed to the callback only once per frame to be aligned with the rendering of the scene.

The callback consequently has access to an array of records and can be implemented like this:

function observerCallBack(records, observer){
	for(var i = 0; i < records.length; ++i){
		var node = records[i].target; // The node of which the result has changed
		var result = records[i].result; // The data result of the observed node
		
		// Do stuff with the node and result
		
		if(somethingHappened){
			observer.disconnect(); // Stop observation of all nodes
		}
	}
}
Clone this wiki locally