- [Loop] Loop now use subgraph update for better static performance.

This commit is contained in:
Tanasart 2023-11-19 19:33:42 +07:00
parent 538e206cfb
commit 8e9b2b61dc
8 changed files with 73 additions and 95 deletions

View file

@ -5,7 +5,23 @@ enum ITERATION_STATUS {
}
function Node_Iterator(_x, _y, _group = noone) : Node_Collection(_x, _y, _group) constructor {
willRestart = false; //in the next getNextNode, reset all child nodes, use in loop.
color = COLORS.node_blend_loop;
icon = THEME.loop;
willRestart = false; //in the next getNextNode, reset all child nodes, use in loop.
managedRenderOrder = true;
reset_all_child = true;
combine_render_time = false;
loop_start_time = 0;
iterated = 0;
static isActiveDynamic = function(frame = CURRENT_FRAME) { #region
for( var i = 0, n = ds_list_size(nodes); i < n; i++ )
if(nodes[| i].isActiveDynamic(frame)) return true;
return false;
} #endregion
static initLoop = function() { #region
resetRender();

View file

@ -1,6 +1,6 @@
#region save
globalvar LOADING, APPENDING, CLONING;
globalvar CONNECTION_CONFLICT, ALWAYS_FULL;
globalvar CONNECTION_CONFLICT;
globalvar MESSAGE;
LOADING = false;
@ -11,7 +11,6 @@
CONNECTION_CONFLICT = ds_queue_create();
randomize();
ALWAYS_FULL = false;
#endregion
#region main

View file

@ -3,19 +3,19 @@ function Node_Feedback(_x, _y, _group = noone) : Node_Collection(_x, _y, _group)
color = COLORS.node_blend_feedback;
icon = THEME.feedback;
update_on_frame = true;
reset_all_child = true;
update_on_frame = true;
reset_all_child = true;
if(!LOADING && !APPENDING && !CLONING) {
if(!LOADING && !APPENDING && !CLONING) { #region
var input = nodeBuild("Node_Feedback_Input", -256, -32, self);
var output = nodeBuild("Node_Feedback_Output", 256, -32, self);
input.inputs[| 2].setValue(4);
output.inputs[| 0].setFrom(input.outputs[| 0]);
output.inputs[| 1].setFrom(input.outputs[| 1]);
}
} #endregion
static getNextNodes = function() {
static getNextNodes = function() { #region
var allReady = true;
for(var i = custom_input_index; i < ds_list_size(inputs); i++) {
var _in = inputs[| i].from;
@ -27,7 +27,5 @@ function Node_Feedback(_x, _y, _group = noone) : Node_Collection(_x, _y, _group)
if(!allReady) return [];
return __nodeLeafList(getNodeList());
}
PATCH_STATIC
} #endregion
}

View file

@ -1,29 +1,18 @@
function Node_Iterate(_x, _y, _group = noone) : Node_Iterator(_x, _y, _group) constructor {
name = "Loop";
color = COLORS.node_blend_loop;
icon = THEME.loop;
reset_all_child = true;
combine_render_time = false;
managedRenderOrder = true;
iterated = 0;
name = "Loop";
inputs[| 0] = nodeValue("Repeat", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1 )
.uncache();
custom_input_index = ds_list_size(inputs);
loop_start_time = 0;
ALWAYS_FULL = true;
if(!LOADING && !APPENDING && !CLONING) {
if(!LOADING && !APPENDING && !CLONING) { #region
var input = nodeBuild("Node_Iterator_Input", -256, -32, self);
var output = nodeBuild("Node_Iterator_Output", 256, -32, self);
input.inputs[| 2].setValue(4);
output.inputs[| 1].setFrom(input.outputs[| 1]);
}
} #endregion
static getIterationCount = function() { return getInputData(0); }
PATCH_STATIC
}

View file

@ -1,12 +1,5 @@
function Node_Iterate_Each(_x, _y, _group = noone) : Node_Iterator(_x, _y, _group) constructor {
name = "Loop Array";
color = COLORS.node_blend_loop;
icon = THEME.loop;
reset_all_child = true;
combine_render_time = false;
managedRenderOrder = true;
iterated = 0;
name = "Loop Array";
inputs[| 0] = nodeValue("Array", self, JUNCTION_CONNECT.input, VALUE_TYPE.any, [] )
.setVisible(true, true);
@ -15,22 +8,20 @@ function Node_Iterate_Each(_x, _y, _group = noone) : Node_Iterator(_x, _y, _grou
custom_input_index = ds_list_size(inputs);
custom_output_index = ds_list_size(inputs);
loop_start_time = 0;
ALWAYS_FULL = true;
if(!LOADING && !APPENDING && !CLONING) {
if(!LOADING && !APPENDING && !CLONING) { #region
var input = nodeBuild("Node_Iterator_Each_Input", -256, -32, self);
var output = nodeBuild("Node_Iterator_Each_Output", 256, -32, self);
output.inputs[| 0].setFrom(input.outputs[| 0]);
}
} #endregion
static onStep = function() {
static onStep = function() { #region
var type = inputs[| 0].isLeaf()? VALUE_TYPE.any : inputs[| 0].value_from.type;
inputs[| 0].setType(type);
}
} #endregion
static doInitLoop = function() {
static doInitLoop = function() { #region
var arrIn = getInputData(0);
var arrOut = outputs[| 0].getValue();
@ -38,15 +29,13 @@ function Node_Iterate_Each(_x, _y, _group = noone) : Node_Iterator(_x, _y, _grou
surface_array_free(arrOut);
outputs[| 0].setValue([])
}
}
} #endregion
static getIterationCount = function() {
static getIterationCount = function() { #region
var arrIn = getInputData(0);
var maxIter = is_array(arrIn)? array_length(arrIn) : 0;
if(!is_real(maxIter)) maxIter = 1;
return maxIter;
}
PATCH_STATIC
} #endregion
}

View file

@ -1,14 +1,5 @@
//Make an iterator_* parent???
function Node_Iterate_Filter(_x, _y, _group = noone) : Node_Iterator(_x, _y, _group) constructor {
name = "Filter Array";
color = COLORS.node_blend_loop;
icon = THEME.loop;
reset_all_child = true;
combine_render_time = false;
managedRenderOrder = true;
iterated = 0;
name = "Filter Array";
inputs[| 0] = nodeValue("Array", self, JUNCTION_CONNECT.input, VALUE_TYPE.any, [] )
.setVisible(true, true);
@ -17,36 +8,32 @@ function Node_Iterate_Filter(_x, _y, _group = noone) : Node_Iterator(_x, _y, _gr
custom_input_index = ds_list_size(inputs);
custom_output_index = ds_list_size(inputs);
loop_start_time = 0;
ALWAYS_FULL = true;
if(!LOADING && !APPENDING && !CLONING) {
if(!LOADING && !APPENDING && !CLONING) { #region
var input = nodeBuild("Node_Iterator_Filter_Input", -256, -32, self);
var output = nodeBuild("Node_Iterator_Filter_Output", 256, -32, self);
output.inputs[| 0].setFrom(input.outputs[| 0]);
}
} #endregion
static onStep = function() {
static onStep = function() { #region
var type = inputs[| 0].isLeaf()? VALUE_TYPE.any : inputs[| 0].value_from.type;
inputs[| 0].setType(type);
}
} #endregion
static doInitLoop = function() {
static doInitLoop = function() { #region
var arrIn = getInputData(0);
var arrOut = outputs[| 0].getValue();
surface_array_free(arrOut);
outputs[| 0].setValue([])
}
} #endregion
static getIterationCount = function() {
static getIterationCount = function() { #region
var arrIn = getInputData(0);
var maxIter = is_array(arrIn)? array_length(arrIn) : 0;
if(!is_real(maxIter)) maxIter = 1;
return maxIter;
}
PATCH_STATIC
} #endregion
}

View file

@ -1,5 +1,5 @@
function Node_Iterate_Sort(_x, _y, _group = noone) : Node_Collection(_x, _y, _group) constructor {
name = "Sort Array";
name = "Sort Array";
color = COLORS.node_blend_loop;
icon = THEME.loop;
@ -17,7 +17,6 @@ function Node_Iterate_Sort(_x, _y, _group = noone) : Node_Collection(_x, _y, _gr
custom_input_index = ds_list_size(inputs);
custom_output_index = ds_list_size(inputs);
loop_start_time = 0;
ALWAYS_FULL = true;
inputNodes = [ noone, noone ];
outputNode = noone;
@ -33,6 +32,13 @@ function Node_Iterate_Sort(_x, _y, _group = noone) : Node_Collection(_x, _y, _gr
var output = nodeBuild("Node_Iterator_Sort_Output", 256, -32, self);
} #endregion
static isActiveDynamic = function(frame = CURRENT_FRAME) { #region
for( var i = 0, n = ds_list_size(nodes); i < n; i++ )
if(nodes[| i].isActiveDynamic(frame)) return true;
return false;
} #endregion
static getNextNodes = function() { return getNextNodesExternal(); }
static onStep = function() { #region

View file

@ -44,15 +44,6 @@ function __nodeLeafList(_list) { #region
return nodes;
} #endregion
function __nodeManualManaged(_node) { #region
var gr = _node.group;
while(gr != noone) {
if(gr.managedRenderOrder) return true;
gr = gr.group;
}
return false;
} #endregion
function ResetAllNodesRender() { #region
LOG_IF(global.FLAG.render == 1, $"XXXXXXXXXXXXXXXXXXXX RESETTING ALL NODES [frame {CURRENT_FRAME}] XXXXXXXXXXXXXXXXXXXX");
@ -128,7 +119,7 @@ function __sortGraph(_list, _nodeList) { #region
ds_list_add(_list, _node);
_node.topoSorted = true;
if(is_instanceof(_node, Node_Collection))
if(is_instanceof(_node, Node_Collection) && !_node.managedRenderOrder)
__sortGraph(_list, _node.nodes);
} else {
ds_stack_push(_st, _node);
@ -138,6 +129,22 @@ function __sortGraph(_list, _nodeList) { #region
}
} #endregion
function __nodeIsRenderLeaf(_node) { #region
if(is_undefined(_node)) { LOG_IF(global.FLAG.render == 1, $"Skip undefiend [{_node}]"); return false; }
if(!is_instanceof(_node, Node)) { LOG_IF(global.FLAG.render == 1, $"Skip non-node [{_node}]"); return false; }
if(array_exists(global.group_io, instanceof(_node))) { LOG_IF(global.FLAG.render == 1, $"Skip group IO [{_node.internalName}]"); return false; }
if(!_node.active) { LOG_IF(global.FLAG.render == 1, $"Skip inactive [{_node.internalName}]"); return false; }
if(!_node.isRenderActive()) { LOG_IF(global.FLAG.render == 1, $"Skip non-renderActive [{_node.internalName}]"); return false; }
if(!_node.attributes.update_graph) { LOG_IF(global.FLAG.render == 1, $"Skip non-auto update [{_node.internalName}]"); return false; }
if(_node.passiveDynamic) { _node.forwardPassiveDynamic(); LOG_IF(global.FLAG.render == 1, $"Skip passive dynamic [{_node.internalName}]"); return false; }
if(_node.rendered && !_node.isActiveDynamic()) { LOG_IF(global.FLAG.render == 1, $"Skip rendered static [{_node.internalName}]"); return false; }
return true;
} #endregion
function Render(partial = false, runAction = false) { #region
LOG_BLOCK_START();
LOG_IF(global.FLAG.render, $"============================== RENDER START [{partial? "PARTIAL" : "FULL"}] [frame {CURRENT_FRAME}] ==============================");
@ -151,7 +158,7 @@ function Render(partial = false, runAction = false) { #region
var rendering = noone;
var error = 0;
var reset_all = !partial || ALWAYS_FULL;
var reset_all = !partial;
if(reset_all) {
var _key = ds_map_find_first(PROJECT.nodeMap);
@ -174,23 +181,10 @@ function Render(partial = false, runAction = false) { #region
for( var i = 0, n = ds_list_size(PROJECT.nodeTopo); i < n; i++ ) {
var _node = PROJECT.nodeTopo[| i];
if(is_undefined(_node)) { LOG_IF(global.FLAG.render == 1, $"Skip undefiend [{_node}]"); continue; }
if(!is_instanceof(_node, Node)) { LOG_IF(global.FLAG.render == 1, $"Skip non-node [{_node}]"); continue; }
_node.render_time = 0;
if(array_exists(global.group_io, instanceof(_node))) {
LOG_IF(global.FLAG.render == 1, $"Skip group IO [{_node.internalName}]"); continue; }
if(!_node.active) { LOG_IF(global.FLAG.render == 1, $"Skip inactive [{_node.internalName}]"); continue; }
if(!_node.isRenderActive()) { LOG_IF(global.FLAG.render == 1, $"Skip non-renderActive [{_node.internalName}]"); continue; }
if(!_node.attributes.update_graph) { LOG_IF(global.FLAG.render == 1, $"Skip non-auto update [{_node.internalName}]"); continue; }
if(__nodeManualManaged(_node)) { LOG_IF(global.FLAG.render == 1, $"Skip in-loop [{_node.internalName}]"); continue; }
if(_node.passiveDynamic) {
_node.forwardPassiveDynamic(); LOG_IF(global.FLAG.render == 1, $"Skip passive dynamic [{_node.internalName}]"); continue; }
if(_node.rendered && !_node.isActiveDynamic()) { LOG_IF(global.FLAG.render == 1, $"Skip rendered static [{_node.internalName}]"); continue; }
if(!__nodeIsRenderLeaf(_node))
continue;
LOG_IF(global.FLAG.render == 1, $" Found leaf [{_node.internalName}]");
RENDER_QUEUE.enqueue(_node);