fixes in performance

This commit is contained in:
tamat
2018-03-08 09:57:03 +01:00
parent ac252fa6e6
commit 02199be571
13 changed files with 1138 additions and 588 deletions

View File

@@ -126,6 +126,12 @@ var LiteGraph = global.LiteGraph = {
DEFAULT_POSITION: [100,100],//default node position
node_images_path: "",
VALID_SHAPES: ["box","round","circle"],
BOX_SHAPE: 1,
ROUND_SHAPE: 2,
CIRCLE_SHAPE: 3,
//enums
INPUT: 1,
OUTPUT: 2,
@@ -135,8 +141,8 @@ var LiteGraph = global.LiteGraph = {
ALWAYS: 0,
ON_EVENT: 1,
ON_TRIGGER: 1, //the same
NEVER: 2,
ON_TRIGGER: 3,
proxy: null, //used to redirect calls
@@ -178,6 +184,24 @@ var LiteGraph = global.LiteGraph = {
for(var i in LGraphNode.prototype)
if(!base_class.prototype[i])
base_class.prototype[i] = LGraphNode.prototype[i];
Object.defineProperty( base_class.prototype, "shape",{
set: function(v) {
switch(v)
{
case "box": this._shape = LiteGraph.BOX_SHAPE; break;
case "round": this._shape = LiteGraph.ROUND_SHAPE; break;
case "circle": this._shape = LiteGraph.CIRCLE_SHAPE; break;
default:
this._shape = v;
}
},
get: function(v)
{
return this._shape;
},
enumerable: true
});
this.registered_node_types[ type ] = base_class;
if(base_class.constructor.name)
@@ -815,8 +839,13 @@ LGraph.prototype.sendActionToCanvas = function(action, params)
LGraph.prototype.add = function(node, skip_compute_order)
{
if(!node || (node.id != -1 && this._nodes_by_id[node.id] != null))
return; //already added
if(!node)
return;
if(node.id != -1 && this._nodes_by_id[node.id] != null)
{
console.warn("LiteGraph: there is already a node with this ID, changing it");
node.id = ++this.last_node_id;
}
if(this._nodes.length >= LiteGraph.MAX_NUMBER_OF_NODES)
throw("LiteGraph: max number of nodes in a graph reached");
@@ -1405,6 +1434,7 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
+ skip_title_render
+ clip_area
+ unsafe_execution: not allowed for safe execution
+ skip_repeated_outputs: when adding new outputs, it wont show if there is one already connected
supported callbacks:
+ onAdded: when added to graph
@@ -1899,10 +1929,10 @@ LGraphNode.prototype.trigger = function( action, param )
for(var i = 0; i < this.outputs.length; ++i)
{
var output = this.outputs[ slot ];
var output = this.outputs[ i ];
if(!output || output.type !== LiteGraph.EVENT || (action && output.name != action) )
continue;
this.triggerSlot( slot, param );
this.triggerSlot( i, param );
}
}
@@ -2890,6 +2920,7 @@ LGraphCanvas.prototype.closeSubgraph = function()
if(!this._graph_stack || this._graph_stack.length == 0)
return;
var graph = this._graph_stack.pop();
this.selected_nodes = {};
graph.attachCanvas(this);
this.setDirty(true,true);
}
@@ -3708,8 +3739,12 @@ LGraphCanvas.prototype.processKey = function(e)
var block_default = false;
if(e.target.localName == "input")
return;
if(e.type == "keydown")
{
console.log(e);
//select all Control A
if(e.keyCode == 65 && e.ctrlKey)
{
@@ -3717,6 +3752,40 @@ LGraphCanvas.prototype.processKey = function(e)
block_default = true;
}
if(e.code == "KeyC" && (e.metaKey || e.ctrlKey) && !e.shiftKey ) //copy
{
if(this.selected_nodes)
{
var nodes_data = [];
for(var i in this.selected_nodes)
nodes_data.push( this.selected_nodes[i].serialize() );
localStorage.setItem( "litegrapheditor_clipboard", JSON.stringify(nodes_data) );
block_default = true;
}
}
if(e.code == "KeyV" && (e.metaKey || e.ctrlKey) && !e.shiftKey ) //paste
{
var data = localStorage.getItem( "litegrapheditor_clipboard" );
if(data)
{
var nodes_data = JSON.parse(data);
for(var i = 0; i < nodes_data.length; ++i)
{
var node_data = nodes_data[i];
var node = LiteGraph.createNode( node_data.type );
if(node)
{
node.configure(node_data);
node.pos[0] += 5;
node.pos[1] += 5;
this.graph.add( node );
}
}
}
}
//delete or backspace
if(e.keyCode == 46 || e.keyCode == 8)
{
@@ -4231,6 +4300,14 @@ LGraphCanvas.prototype.drawBackCanvas = function()
if(this.clear_background)
ctx.clearRect(0,0,canvas.width, canvas.height);
if(this._graph_stack && this._graph_stack.length)
{
ctx.strokeStyle = this._graph_stack[ this._graph_stack.length - 1].bgcolor;
ctx.lineWidth = 10;
ctx.strokeRect(1,1,canvas.width-2,canvas.height-2);
ctx.lineWidth = 1;
}
//reset in case of error
ctx.restore();
ctx.setTransform(1, 0, 0, 1, 0, 0);
@@ -4316,6 +4393,8 @@ LGraphCanvas.prototype.drawBackCanvas = function()
this.dirty_canvas = true; //to force to repaint the front canvas with the bgcanvas
}
var temp_vec2 = new Float32Array(2);
/* Renders the LGraphNode on the canvas */
LGraphCanvas.prototype.drawNode = function(node, ctx )
{
@@ -4381,8 +4460,9 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
ctx.globalAlpha = editor_alpha;
//clip if required (mask)
var shape = node.shape || "box";
var size = new Float32Array(node.size);
var shape = node._shape || LiteGraph.BOX_SHAPE;
var size = temp_vec2;
temp_vec2.set( node.size );
if(node.flags.collapsed)
{
size[0] = LiteGraph.NODE_COLLAPSED_WIDTH;
@@ -4393,16 +4473,16 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
if(node.flags.clip_area)
{
ctx.save();
if(shape == "box")
if(shape == LiteGraph.BOX_SHAPE)
{
ctx.beginPath();
ctx.rect(0,0,size[0], size[1]);
}
else if (shape == "round")
else if (shape == LiteGraph.ROUND_SHAPE)
{
ctx.roundRect(0,0,size[0], size[1],10);
}
else if (shape == "circle")
else if (shape == LiteGraph.CIRCLE_SHAPE)
{
ctx.beginPath();
ctx.arc(size[0] * 0.5, size[1] * 0.5, size[0] * 0.5, 0, Math.PI*2);
@@ -4540,8 +4620,8 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
var title_height = LiteGraph.NODE_TITLE_HEIGHT;
//render depending on shape
var shape = node.shape || "box";
if(shape == "box")
var shape = node._shape || LiteGraph.BOX_SHAPE;
if(shape == LiteGraph.BOX_SHAPE)
{
ctx.beginPath();
ctx.rect(0,no_title ? 0 : -title_height, size[0]+1, no_title ? size[1] : size[1] + title_height);
@@ -4555,12 +4635,12 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
ctx.strokeStyle = fgcolor;
}
}
else if (node.shape == "round")
else if (shape == LiteGraph.ROUND_SHAPE)
{
ctx.roundRect(0,no_title ? 0 : -title_height,size[0], no_title ? size[1] : size[1] + title_height, 10);
ctx.fill();
}
else if (node.shape == "circle")
else if (shape == LiteGraph.CIRCLE_SHAPE)
{
ctx.beginPath();
ctx.arc(size[0] * 0.5, size[1] * 0.5, size[0] * 0.5, 0, Math.PI*2);
@@ -4587,25 +4667,33 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
ctx.fillStyle = fgcolor || LiteGraph.NODE_DEFAULT_COLOR;
var old_alpha = ctx.globalAlpha;
ctx.globalAlpha = 0.5 * old_alpha;
if(shape == "box")
if(shape == LiteGraph.BOX_SHAPE)
{
ctx.beginPath();
ctx.rect(0, -title_height, size[0]+1, title_height);
ctx.fill()
//ctx.stroke();
}
else if (shape == "round")
else if (shape == LiteGraph.ROUND_SHAPE)
{
ctx.roundRect(0,-title_height,size[0], title_height,10,0);
//ctx.fillRect(0,8,size[0],NODE_TITLE_HEIGHT - 12);
ctx.fill();
//ctx.stroke();
}
/*
else if (shape == LiteGraph.CIRCLE_SHAPE)
{
ctx.beginPath();
ctx.arc(title_height *0.5, title_height * -0.5, (title_height - 6) *0.5,0,Math.PI*2);
ctx.fill();
}
*/
//title box
ctx.fillStyle = node.boxcolor || LiteGraph.NODE_DEFAULT_BOXCOLOR;
ctx.beginPath();
if (shape == "round")
if (shape == LiteGraph.ROUND_SHAPE || shape == LiteGraph.CIRCLE_SHAPE)
ctx.arc(title_height *0.5, title_height * -0.5, (title_height - 6) *0.5,0,Math.PI*2);
else
ctx.rect(3,-title_height + 3,title_height - 6,title_height - 6);
@@ -4633,8 +4721,8 @@ LGraphCanvas.prototype.drawNodeCollapsed = function(node, ctx, fgcolor, bgcolor)
var collapsed_radius = LiteGraph.NODE_COLLAPSED_RADIUS;
//circle shape
var shape = node.shape || "box";
if(shape == "circle")
var shape = node._shape || LiteGraph.BOX_SHAPE;
if(shape == LiteGraph.CIRCLE_SHAPE)
{
ctx.beginPath();
ctx.arc(node.size[0] * 0.5, node.size[1] * 0.5, collapsed_radius,0,Math.PI * 2);
@@ -4647,7 +4735,7 @@ LGraphCanvas.prototype.drawNodeCollapsed = function(node, ctx, fgcolor, bgcolor)
ctx.arc(node.size[0] * 0.5, node.size[1] * 0.5, collapsed_radius * 0.5,0,Math.PI * 2);
ctx.fill();
}
else if(shape == "round") //rounded box
else if(shape == LiteGraph.ROUND_SHAPE) //rounded box
{
ctx.beginPath();
ctx.roundRect(node.size[0] * 0.5 - collapsed_radius, node.size[1] * 0.5 - collapsed_radius, 2*collapsed_radius,2*collapsed_radius,5);
@@ -5027,7 +5115,10 @@ LGraphCanvas.showMenuNodeOptionalInputs = function( v, options, e, prev_menu, no
var label = entry[0];
if(entry[2] && entry[2].label)
label = entry[2].label;
entries.push({content: label, value: entry});
var data = {content: label, value: entry};
if(entry[1] == LiteGraph.ACTION)
data.className = "event";
entries.push(data);
}
if(this.onMenuNodeInputs)
@@ -5047,7 +5138,10 @@ LGraphCanvas.showMenuNodeOptionalInputs = function( v, options, e, prev_menu, no
v.callback.call( that, node, v, e, prev );
if(v.value)
{
node.addInput(v.value[0],v.value[1], v.value[2]);
node.setDirtyCanvas(true,true);
}
}
return false;
@@ -5077,7 +5171,7 @@ LGraphCanvas.showMenuNodeOptionalOutputs = function( v, options, e, prev_menu, n
continue;
}
if(node.findOutputSlot(entry[0]) != -1)
if(node.flags && node.flags.skip_repeated_outputs && node.findOutputSlot(entry[0]) != -1)
continue; //skip the ones already on
var label = entry[0];
if(entry[2] && entry[2].label)
@@ -5118,7 +5212,11 @@ LGraphCanvas.showMenuNodeOptionalOutputs = function( v, options, e, prev_menu, n
return false;
}
else
{
node.addOutput( v.value[0], v.value[1], v.value[2]);
node.setDirtyCanvas(true,true);
}
}
return false;
@@ -5283,10 +5381,7 @@ LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options
input_html = "<input autofocus type='checkbox' class='value' "+(node.properties[property] ? "checked" : "")+"/>";
}
var dialog = document.createElement("div");
dialog.className = "graphdialog";
dialog.innerHTML = "<span class='name'>" + property + "</span>"+input_html+"<button>OK</button>";
var dialog = this.createDialog( "<span class='name'>" + property + "</span>"+input_html+"<button>OK</button>" , options );
if(type == "enum" && info.values)
{
@@ -5323,6 +5418,35 @@ LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options
}
}
var button = dialog.querySelector("button");
button.addEventListener("click", inner );
function inner()
{
setValue( input.value );
}
function setValue(value)
{
if(typeof( node.properties[ property ] ) == "number")
value = Number(value);
node.properties[ property ] = value;
if(node.onPropertyChanged)
node.onPropertyChanged( property, value );
dialog.close();
node.setDirtyCanvas(true,true);
}
}
LGraphCanvas.prototype.createDialog = function( html, options )
{
options = options || {};
var dialog = document.createElement("div");
dialog.className = "graphdialog";
dialog.innerHTML = html;
var rect = this.canvas.getClientRects()[0];
var offsetx = -20;
var offsety = -20;
@@ -5351,28 +5475,15 @@ LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options
dialog.style.left = offsetx + "px";
dialog.style.top = offsety + "px";
var button = dialog.querySelector("button");
button.addEventListener("click", inner );
this.canvas.parentNode.appendChild( dialog );
function inner()
dialog.close = function()
{
setValue( input.value );
if(this.parentNode)
this.parentNode.removeChild( this );
}
function setValue(value)
{
if(typeof( node.properties[ property ] ) == "number")
value = Number(value);
node.properties[ property ] = value;
if(node.onPropertyChanged)
node.onPropertyChanged( property, value );
dialog.parentNode.removeChild( dialog );
node.setDirtyCanvas(true,true);
}
return dialog;
}
LGraphCanvas.onMenuNodeCollapse = function( value, options, e, menu, node )
@@ -5388,7 +5499,7 @@ LGraphCanvas.onMenuNodePin = function( value, options, e, menu, node )
LGraphCanvas.onMenuNodeMode = function( value, options, e, menu, node )
{
new LiteGraph.ContextMenu(["Always","On Event","Never"], {event: e, callback: inner_clicked, parentMenu: prev_menu, node: node });
new LiteGraph.ContextMenu(["Always","On Event","On Trigger","Never"], {event: e, callback: inner_clicked, parentMenu: menu, node: node });
function inner_clicked(v)
{
@@ -5397,6 +5508,7 @@ LGraphCanvas.onMenuNodeMode = function( value, options, e, menu, node )
switch(v)
{
case "On Event": node.mode = LiteGraph.ON_EVENT; break;
case "On Trigger": node.mode = LiteGraph.ON_TRIGGER; break;
case "Never": node.mode = LiteGraph.NEVER; break;
case "Always":
default:
@@ -5443,7 +5555,7 @@ LGraphCanvas.onMenuNodeShapes = function( value, options, e, menu, node )
if(!node)
throw("no node passed");
new LiteGraph.ContextMenu(["box","round"], { event: e, callback: inner_clicked, parentMenu: menu, node: node });
new LiteGraph.ContextMenu( LiteGraph.VALID_SHAPES, { event: e, callback: inner_clicked, parentMenu: menu, node: node });
function inner_clicked(v)
{
@@ -5478,9 +5590,13 @@ LGraphCanvas.onMenuNodeClone = function( value, options, e, menu, node )
}
LGraphCanvas.node_colors = {
"red": { color:"#FAA", bgcolor:"#A44" },
"green": { color:"#AFA", bgcolor:"#4A4" },
"blue": { color:"#AAF", bgcolor:"#44A" },
"red": { color:"#FAA", bgcolor:"#944" },
"green": { color:"#AFA", bgcolor:"#494" },
"blue": { color:"#AAF", bgcolor:"#449" },
"cyan": { color:"#AFF", bgcolor:"#499" },
"purple": { color:"#FAF", bgcolor:"#949" },
"yellow": { color:"#FFA", bgcolor:"#994" },
"black": { color:"#777", bgcolor:"#000" },
"white": { color:"#FFF", bgcolor:"#AAA" }
};
@@ -5588,10 +5704,15 @@ LGraphCanvas.prototype.processContextMenu = function( node, event )
if(slot)
{
menu_info = slot.locked ? [ "Cannot remove" ] : { "Remove Slot": slot };
options.title = slot.input ? slot.input.type : slot.output.type;
if(slot.input && slot.input.type == LiteGraph.EVENT)
menu_info = [];
menu_info.push( slot.locked ? "Cannot remove" : { content: "Remove Slot", slot: slot } );
menu_info.push( { content: "Rename Slot", slot: slot } );
options.title = (slot.input ? slot.input.type : slot.output.type) || "*";
if(slot.input && slot.input.type == LiteGraph.ACTION)
options.title = "Action";
if(slot.output && slot.output.type == LiteGraph.EVENT)
options.title = "Event";
}
else
menu_info = node ? this.getNodeMenuOptions(node) : this.getCanvasMenuOptions();
@@ -5607,14 +5728,31 @@ LGraphCanvas.prototype.processContextMenu = function( node, event )
if(!v)
return;
if(v == slot)
if(v.content == "Remove Slot")
{
if(v.input)
node.removeInput( slot.slot );
else if(v.output)
node.removeOutput( slot.slot );
var info = v.slot;
if(info.input)
node.removeInput( info.slot );
else if(info.output)
node.removeOutput( info.slot );
return;
}
else if( v.content == "Rename Slot")
{
var info = v.slot;
var dialog = that.createDialog( "<span class='name'>Name</span><input type='text'/><button>OK</button>" , options );
var input = dialog.querySelector("input");
dialog.querySelector("button").addEventListener("click",function(e){
if(input.value)
{
var slot_info = info.input ? node.getInputInfo( info.slot ) : node.getOutputInfo( info.slot );
if( slot_info )
slot_info.label = input.value;
that.setDirty(true);
}
dialog.close();
});
}
//if(v.callback)
// return v.callback.call(that, node, options, e, menu, that, event );
@@ -5933,6 +6071,9 @@ ContextMenu.prototype.addItem = function( name, value, options )
}
else
element.dataset["value"] = value;
if(value.className)
element.className += " " + value.className;
}
this.root.appendChild(element);