litegraph.js
litegraph.js copied to clipboard
Inputs are not updated before actions
The input data of connected nodes are not updated until after the onAction event. I have even tried moving the trigger to after I set the output data of the node.
Lachee Console Node
//Show value inside the debug console
function LConsole()
{
//this.mode = LiteGraph.ON_EVENT;
this.size = [80,30];
this.addInput("log", LiteGraph.EVENT);
this.addInput("cnt", 0, { label: "Message"});
this.cnt = "";
}
LConsole.title = "Lachee Console";
LConsole.desc = "Show value inside the console";
LConsole.prototype.onAction = function(action, param)
{
console.log("Action:", action );
console.log("Params:", param );
console.log("Self:", this );
console.log("CNT: " + this.cnt );
console.log("A: ", this.getInputData(0));
console.log("B: ", this.getInputData(1));
this.inputs[1].label = this.cnt;
}
LConsole.prototype.onExecute = function()
{
if (this.inputs[1])
this.cnt = this.getInputData(1);
}
LConsole.prototype.onDrawBackground = function(ctx)
{
//show the current value
this.inputs[1].label = this.cnt;
}
LiteGraph.registerNodeType("basic/lconsole", LConsole );
On Message Node
function OnMessageEvent()
{
this.addOutput("on_message", LiteGraph.EVENT);
this.addOutput("author", 0);
this.addOutput("content", 0);
this.author = "Lachee";
this.content = ".ping";
this.triggered = false;
this.clonable = false;
this.resizable = false;
this.color = LGraphCanvas.node_colors.purple.color;
this.bgcolor = LGraphCanvas.node_colors.purple.bgcolor;
}
OnMessageEvent.title = "On Message";
OnMessageEvent.desc = "Occurs when a message is sent";
OnMessageEvent.on_color = "#AAA";
OnMessageEvent.off_color = "#222";
OnMessageEvent.prototype.onStart = function() {}
OnMessageEvent.prototype.onDrawBackground = function()
{
this.boxcolor = this.triggered ? OnMessageEvent.on_color : OnMessageEvent.off_color;
this.triggered = false;
}
OnMessageEvent.prototype.onExecute = function()
{
var dt = this.graph.elapsed_time * 1000; //in ms
var trigger = message_queue.length != 0;
if (trigger)
{
console.log("TRIGGER");
this.setOutputData(1, "Lachee");
this.setOutputData(2, message_queue[0]);
this.trigger("on_message", message_queue[0]);
message_queue = [];
this.triggered = true;
}
}
Yes, this is a problem of the current architecture.
Nodes onExecute is executed constantly (when the runStep method is called for the graph), but onAction is executed when the event is triggered, and it propagates, but it only calls onAction, not onExecute.
This means that there are two separate flows of execution, the constant onExecute (the data flow) and the propagated from an event (the event flow).
So if you want to blend data using both simultaneously you will have to run the whole graph before triggering the event, which is not very efficient (all nodes will be executed) but it would solve the problem:
node.onAction = function(event,param){
this.setOutputData(0,"data")
this.graph.runStep(); //make that data flow
this.trigger(0); //trigger event
}
Let me know if that works for you
Its unfortunate that the flow separates. I would have assumed getInputData would have forced a fetch if required, but I suppose there is no easy way to do that.
I have tried the this.graph.runStep();
, however all my attempts has either cause it to not work or cause a infinite loop :confused:
I will research on the topic this week, I could create a function that executes from Node triggering the event to the node receiving the event.
Ask me about it in one week
Its unfortunate that the flow separates. I would have assumed getInputData would have forced a fetch if required, but I suppose there is no easy way to do that.
That could be done, but fetching the input data from a previous node wouldnt solve it if that data passes through several nodes. The only solution is to force the data to flow between two nodes.
I have a early stage solution for this, currently in debug but promising.
Just for triggered/actioned nodes, I'm calling a refreshAncestors function that read the ancestors tree and execute the nodes, ensuring that all the data needed is updated. There are some checks to prevent recursions and double-execution. https://github.com/atlasan/litegraph.js/blob/cbd9813d8234d4b4688c0746a8cfd8dd380b7659/src/litegraph.js#L3608 https://github.com/atlasan/litegraph.js/blob/cbd9813d8234d4b4688c0746a8cfd8dd380b7659/src/litegraph.js#L3096
Was this ever implemented? It would be interesting to be able to execute backwards the inputs of the event nodes, so that they can get fresh values without needing to run the entire tree. From what I understand, that's what Blueprints does. In the end most javascript applications will be more event-based than frame-based