added method to create nodes from functions, wrapFunctionAsNode

This commit is contained in:
tamat
2018-03-28 16:35:52 +02:00
parent e54e2409d1
commit 7485fc68aa
11 changed files with 822 additions and 498 deletions

View File

@@ -126,7 +126,7 @@ var LiteGraph = global.LiteGraph = {
DEFAULT_POSITION: [100,100],//default node position
node_images_path: "",
VALID_SHAPES: ["box","round","circle"],
VALID_SHAPES: ["box","round"], //,"circle"
BOX_SHAPE: 1,
ROUND_SHAPE: 2,
@@ -218,6 +218,35 @@ var LiteGraph = global.LiteGraph = {
}
},
/**
* create a new node type by passing a function, it wraps it with a propper class
* @method wrapFunctionAsNode
* @param {String} name node name with namespace (p.e.: 'math/sum')
* @param {Function} func
* @param {Array} param_types [optional] an array containing the type of every parameter, otherwise parameters will accept any type
* @param {String} return_type [optional] string with the return type, otherwise it will be generic
*/
wrapFunctionAsNode: function( name, func, param_types, return_type )
{
var params = Array(func.length);
var code = "";
var names = LiteGraph.getParameterNames( func );
for(var i = 0; i < names.length; ++i)
code += "this.addInput('"+names[i]+"',"+(param_types && param_types[i] ? "'" + param_types[i] + "'" : "0") + ");\n";
code += "this.addOutput('out',"+( return_type ? "'" + return_type + "'" : 0 )+");\n";
var classobj = Function(code);
classobj.title = name.split("/").pop();
classobj.desc = "Generated from " + func.name;
classobj.prototype.onExecute = function onExecute()
{
for(var i = 0; i < params.length; ++i)
params[i] = this.getInputData(i);
var r = func.apply( this, params );
this.setOutputData(0,r);
}
this.registerNodeType( name, classobj );
},
/**
* Adds this method to all nodetypes, existing and to be created
* (You can add it to LGraphNode.prototype but then existing node types wont have it)
@@ -258,7 +287,7 @@ var LiteGraph = global.LiteGraph = {
title = title || base_class.title || type;
var node = new base_class( name );
var node = new base_class( title );
node.type = type;
if(!node.title) node.title = title;
@@ -391,16 +420,36 @@ var LiteGraph = global.LiteGraph = {
if( !type_a || //generic output
!type_b || //generic input
type_a == type_b || //same type (is valid for triggers)
(type_a !== LiteGraph.EVENT && type_b !== LiteGraph.EVENT && type_a.toLowerCase() == type_b.toLowerCase()) ) //same type
return true;
type_a == LiteGraph.EVENT && type_b == LiteGraph.ACTION )
return true;
type_a = type_a.toLowerCase();
type_b = type_b.toLowerCase();
if( type_a.indexOf(",") == -1 && type_b.indexOf(",") == -1 )
return type_a == type_b;
var supported_types_a = type_a.split(",");
var supported_types_b = type_b.split(",");
for(var i = 0; i < supported_types_a.length; ++i)
for(var j = 0; j < supported_types_b.length; ++j)
if( supported_types_a[i] == supported_types_b[i] )
return true;
return false;
}
};
//timer that works everywhere
if(typeof(performance) != "undefined")
LiteGraph.getTime = function getTime() { return performance.now(); }
LiteGraph.getTime = performance.now.bind(performance);
else if(typeof(Date) != "undefined" && Date.now)
LiteGraph.getTime = Date.now.bind(Date);
else if(typeof(process) != "undefined")
LiteGraph.getTime = function(){
var t = process.hrtime();
return t[0]*0.001 + t[1]*(1e-6);
}
else
LiteGraph.getTime = function getTime() { return Date.now(); }
LiteGraph.getTime = function getTime() { return (new Date).getTime(); }
@@ -418,7 +467,7 @@ else
* @constructor
*/
global.LGraph = LiteGraph.LGraph = function LGraph()
function LGraph()
{
if (LiteGraph.debug)
console.log("Graph created");
@@ -426,6 +475,8 @@ global.LGraph = LiteGraph.LGraph = function LGraph()
this.clear();
}
global.LGraph = LiteGraph.LGraph = LGraph;
//default supported types
LGraph.supported_types = ["number","string","boolean"];
@@ -1468,11 +1519,13 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
* @param {String} name a name for the node
*/
global.LGraphNode = LiteGraph.LGraphNode = function LGraphNode(title)
function LGraphNode(title)
{
this._ctor();
}
global.LGraphNode = LiteGraph.LGraphNode = LGraphNode;
LGraphNode.prototype._ctor = function( title )
{
this.title = title || "Unnamed";
@@ -2211,9 +2264,14 @@ LGraphNode.prototype.computeSize = function( minHeight, out )
* @method getBounding
* @return {Float32Array[4]} the total size
*/
LGraphNode.prototype.getBounding = function()
LGraphNode.prototype.getBounding = function( out )
{
return new Float32Array([this.pos[0] - 4, this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, this.pos[0] + this.size[0] + 4, this.pos[1] + this.size[1] + LGraph.NODE_TITLE_HEIGHT]);
out = out || new Float32Array(4);
out[0] = this.pos[0] - 4;
out[1] = this.pos[1] - LiteGraph.NODE_TITLE_HEIGHT;
out[2] = this.pos[0] + this.size[0] + 4;
out[3] = this.pos[1] + this.size[1] + LGraph.NODE_TITLE_HEIGHT;
return out;
}
/**
@@ -2761,7 +2819,7 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas)
* @param {LGraph} graph [optional]
* @param {Object} options [optional] { skip_rendering, autoresize }
*/
global.LGraphCanvas = LiteGraph.LGraphCanvas = function LGraphCanvas( canvas, graph, options )
function LGraphCanvas( canvas, graph, options )
{
options = options || {};
@@ -2813,6 +2871,8 @@ global.LGraphCanvas = LiteGraph.LGraphCanvas = function LGraphCanvas( canvas, gr
this.autoresize = options.autoresize;
}
global.LGraphCanvas = LiteGraph.LGraphCanvas = LGraphCanvas;
LGraphCanvas.link_type_colors = {"-1":"#F85",'number':"#AAC","node":"#DCA"};
@@ -3610,8 +3670,8 @@ LGraphCanvas.prototype.processMouseUp = function(e)
if(this.connecting_output.type == LiteGraph.EVENT)
this.connecting_node.connect( this.connecting_slot, node, LiteGraph.EVENT );
else
if(input && !input.link && input.type == this.connecting_output.type) //toLowerCase missing
this.connecting_node.connect(this.connecting_slot, node, 0);
if(input && !input.link && LiteGraph.isValidConnection( input.type && this.connecting_output.type ) )
this.connecting_node.connect( this.connecting_slot, node, 0 );
}
}
}
@@ -3744,7 +3804,8 @@ LGraphCanvas.prototype.processKey = function(e)
if(e.type == "keydown")
{
console.log(e);
//console.log(e); //debug
//select all Control A
if(e.keyCode == 65 && e.ctrlKey)
{
@@ -4092,6 +4153,7 @@ LGraphCanvas.prototype.sendToBack = function(n)
LGraphCanvas.prototype.computeVisibleNodes = function()
{
var temp = new Float32Array(4);
var visible_nodes = [];
for(var i = 0, l = this.graph._nodes.length; i < l; ++i)
{
@@ -4101,7 +4163,7 @@ LGraphCanvas.prototype.computeVisibleNodes = function()
if(this.live_mode && !n.onDrawBackground && !n.onDrawForeground)
continue;
if(!overlapBounding(this.visible_area, n.getBounding() ))
if(!overlapBounding( this.visible_area, n.getBounding( temp ) ))
continue; //out of the visible area
visible_nodes.push(n);
@@ -6256,15 +6318,17 @@ LiteGraph.extendClass = function ( target, origin )
}
}
/*
LiteGraph.createNodetypeWrapper = function( class_object )
{
//create Nodetype object
}
//LiteGraph.registerNodeType("scene/global", LGraphGlobal );
*/
LiteGraph.getParameterNames = function(func) {
return (func + '')
.replace(/[/][/].*$/mg,'') // strip single-line comments
.replace(/\s+/g, '') // strip white space
.replace(/[/][*][^/*]*[*][/]/g, '') // strip multi-line comments /**/
.split('){', 1)[0].replace(/^[^(]*[(]/, '') // extract the parameters
.replace(/=[^,]+/g, '') // strip any ES6 defaults
.split(',').filter(Boolean); // split & filter [""]
}
if(typeof(window) !== undefined && !window["requestAnimationFrame"] )
if( typeof(window) != "undefined" && !window["requestAnimationFrame"] )
{
window.requestAnimationFrame = window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
@@ -6274,6 +6338,9 @@ if(typeof(window) !== undefined && !window["requestAnimationFrame&q
}
})(this);
if(typeof(exports) != "undefined")
exports.LiteGraph = this.LiteGraph;
</pre>
</div>