diff --git a/src/backend/functionBuilder.js b/src/backend/functionBuilder.js index f31bb56e..59591385 100644 --- a/src/backend/functionBuilder.js +++ b/src/backend/functionBuilder.js @@ -8,6 +8,81 @@ /// Properties: /// nodeMap - {Object} Object map, where nodeMap[function] = functionNode; /// -function functionBuilder() { - this.nodeMap = {}; -} +var functionBuilder = (function() { + + /// + /// Function: functionBuilder + /// + /// [Constructor] Blank constructor, which initializes the properties + /// + function functionBuilder() { + this.nodeMap = {}; + } + + /// + /// Function: addFunction + /// + /// Creates the functionNode, and add it to the nodeMap + /// + /// Parameters: + /// functionName - {String} Function name to assume, if its null, it attempts to extract from the function + /// jsFunction - {JS Function} JS Function to do conversion + /// paramTypeArray - {[String,...]} Parameter type array, assumes all parameters are "float" if null + /// returnType - {String} The return type, assumes "float" if null + /// + function addFunction( functionName, jsFunction, paramTypeArray, returnType ) { + this.addFunctionNode( new functionNode( functionName, jsFunction, paramTypeArray, returnType ) ); + } + functionBuilder.prototype.addFunction = addFunction; + + /// + /// Function: addFunctionNode + /// + /// Add the funciton node directly + /// + /// Parameters: + /// inNode - {functionNode} functionNode to add + /// + function addFunctionNode( inNode ) { + this.nodeMap[ inNode.functionName ] = inNode; + } + functionBuilder.prototype.addFunctionNode = addFunctionNode; + + /// + /// Function: traceFunctionCalls + /// + /// Trace all the depending functions being called, from a single function + /// + /// This allow for "uneeded" functions to be automatically optimized out. + /// + /// Parameters: + /// functionName - {String} Function name to trace from, default to "kernel" + /// retList - {[String,...]} Returning list of function names that is traced. Including itself. + /// + /// Returns: + /// {[String,...]} Returning list of function names that is traced. Including itself. + function traceFunctionCalls( functionName, retList ) { + functionName = functionName || "kernel"; + retList = retList || []; + + var fNode = this.nodeMap[functionName]; + if( fNode ) { + // Check if function already exists + if( retList.indexOf(functionName) >= 0 ) { + // Does nothing if already traced + } else { + retList.push(functionName); + + fNode.getWebglFunctionString(); //ensure JS trace is done + for(var i=0; i + + + + GPU.JS : FunctionBuilder unit testing + + + + + + + + + +
+
+ + + + diff --git a/test/src/internal/functionBuilder_test.js b/test/src/internal/functionBuilder_test.js new file mode 100644 index 00000000..2256f128 --- /dev/null +++ b/test/src/internal/functionBuilder_test.js @@ -0,0 +1,32 @@ +/// +/// Test the various basic functionality of functionBuilder +/// + +/// Test the function tracing of 3 layers +QUnit.test( "traceFunctionCalls: 3 layer test", function( assert ) { + assert.notEqual( functionBuilder, null, "script include check" ); + + function layerOne() { + return 42; + } + + function layerTwo() { + return layerOne() * 2; + } + + function layerThree() { + return layerTwo() * 2; + } + + // Create a function hello node + var builder = new functionBuilder(); + assert.notEqual( builder, null, "class creation check" ); + + builder.addFunction(null, layerOne); + builder.addFunction(null, layerTwo); + builder.addFunction(null, layerThree); + + assert.deepEqual( builder.traceFunctionCalls("layerOne"), ["layerOne"] ); + assert.deepEqual( builder.traceFunctionCalls("layerTwo"), ["layerTwo","layerOne"] ); + assert.deepEqual( builder.traceFunctionCalls("layerThree"), ["layerThree","layerTwo","layerOne"] ); +}); diff --git a/test/src/internal/functionNode_test.js b/test/src/internal/functionNode_test.js index 0fa81c10..e79270dc 100644 --- a/test/src/internal/functionNode_test.js +++ b/test/src/internal/functionNode_test.js @@ -1,4 +1,3 @@ -/// @file functionNode_test.js /// /// Test the various basic functionality of functionNode /// @@ -49,6 +48,8 @@ QUnit.test( "hello_inner: call a funciton inside a function", function( assert ) "float hello_inner() { return inner(); }", "webgl function conversion check" ); + + assert.deepEqual( node.calledFunctions, ["inner"] ); }); /// Test creation of function, that calls another function, with ARGS @@ -69,6 +70,8 @@ QUnit.test( "Math.round implementation: A function with arguments", function( as "float round(float a) { return floor(a+0.5); }", "webgl function conversion check" ); + + assert.deepEqual( node.calledFunctions, ["floor"] ); }); /// Test creation of function, that calls another function, with ARGS @@ -90,3 +93,16 @@ QUnit.test( "Two arguments test", function( assert ) { "webgl function conversion check" ); }); + +/// Test the creation of a hello_world function +QUnit.test( "Automatic naming support", function( assert ) { + assert.notEqual( functionNode, null, "script include check" ); + + function hello_world() { + return 42; + } + // Create a function hello node + var node = new functionNode(null, hello_world); + assert.notEqual( node, null, "class creation check" ); + assert.equal( node.functionName, "hello_world" ); +});