Pixel-Composer/scripts/node_collection/node_collection.gml

797 lines
21 KiB
Text
Raw Normal View History

2022-01-24 02:21:25 +01:00
enum COLLECTION_TAG {
group = 1,
loop = 2
}
function groupNodes(nodeArray, _group = noone, record = true, check_connect = true) {
2024-01-26 14:38:50 +01:00
#region check inline
var _ctx_nodes = [];
2023-12-18 08:27:31 +01:00
2024-01-26 14:38:50 +01:00
for(var i = 0; i < array_length(nodeArray); i++) {
var node = nodeArray[i];
var ctx = node.inline_context;
2023-12-18 08:27:31 +01:00
2024-01-26 14:38:50 +01:00
if(ctx == noone) continue;
array_push_unique(_ctx_nodes, ctx);
2023-12-18 08:27:31 +01:00
for( var k = 0, n = array_length(ctx.nodes); k < n; k++ ) {
if(array_exists(nodeArray, ctx.nodes[k])) continue;
2024-01-26 14:38:50 +01:00
noti_warning("Grouping incomplete inline group is not allowed.");
return;
2023-12-18 08:27:31 +01:00
}
2024-01-26 14:38:50 +01:00
}
#endregion
2023-12-18 08:27:31 +01:00
2023-02-14 05:32:32 +01:00
UNDO_HOLDING = true;
if(_group == noone) {
var cx = 0;
var cy = 0;
for(var i = 0; i < array_length(nodeArray); i++) {
var _node = nodeArray[i];
cx += _node.x;
cy += _node.y;
}
2024-01-26 14:38:50 +01:00
cx = value_snap(cx / array_length(nodeArray), 32);
cy = value_snap(cy / array_length(nodeArray), 32);
2023-02-14 05:32:32 +01:00
_group = new Node_Group(cx, cy, PANEL_GRAPH.getCurrentContext());
}
var _content = [];
2023-12-18 08:27:31 +01:00
2023-02-14 05:32:32 +01:00
for(var i = 0; i < array_length(nodeArray); i++) {
_group.add(nodeArray[i]);
_content[i] = nodeArray[i];
}
2023-12-18 08:27:31 +01:00
for( var i = 0, n = array_length(_ctx_nodes); i < n; i++ ) {
_group.add(_ctx_nodes[i]);
_content[i] = _ctx_nodes[i];
}
2024-01-26 14:38:50 +01:00
if(check_connect) { #region IO creation
2024-05-22 12:13:46 +02:00
var _io = { inputs: {}, outputs: {}, map: {} };
2024-01-26 14:38:50 +01:00
for(var i = 0; i < array_length(nodeArray); i++)
nodeArray[i].checkConnectGroup(_io);
var _in = _io.inputs;
var _inKey = struct_get_names(_in);
var _x, _y, m;
2023-02-14 05:32:32 +01:00
2024-01-26 14:38:50 +01:00
for( var i = 0, n = array_length(_inKey); i < n; i++ ) {
var _frm = _io.map[$ _inKey[i]];
var _tos = _in[$ _inKey[i]];
_x = 0
_y = 0;
m = array_length(_tos);
for( var j = 0; j < m; j++ ) {
var _to = _tos[j];
_x = min(_x, _to.node.x);
_y += _to.node.y;
}
_x = value_snap(_x - 64 - 128, 32);
_y = value_snap(_y / m, 32);
var _n = new Node_Group_Input(_x, _y, _group);
var _ti = array_find(GROUP_IO_TYPE_MAP, _frm.type);
2024-08-08 06:57:51 +02:00
if(_ti >= 0) _n.inputs[2].setValue(_ti);
2024-01-26 14:38:50 +01:00
_n.onValueUpdate(0);
_n.inParent.setFrom(_frm);
for( var j = 0; j < m; j++ ) {
var _to = _tos[j];
2024-08-08 06:57:51 +02:00
_to.setFrom(_n.outputs[0]);
2024-01-26 14:38:50 +01:00
}
}
var _ot = _io.outputs;
var _otKey = struct_get_names(_ot);
for( var i = 0, n = array_length(_otKey); i < n; i++ ) {
var _frm = _io.map[$ _otKey[i]];
var _tos = _ot[$ _otKey[i]];
_x = value_snap(_frm.node.x + _frm.node.w + 64, 32);
_y = value_snap(_frm.node.y, 32);
m = array_length(_tos);
var _n = new Node_Group_Output(_x, _y, _group);
2024-08-08 06:57:51 +02:00
_n.inputs[0].setFrom(_frm);
2024-01-26 14:38:50 +01:00
for( var j = 0; j < m; j++ ) {
var _to = _tos[j];
_to.setFrom(_n.outParent);
}
}
} #endregion
2023-02-14 05:32:32 +01:00
UNDO_HOLDING = false;
2024-01-26 14:38:50 +01:00
if(record) recordAction(ACTION_TYPE.group, _group, { content: _content });
2023-02-14 05:32:32 +01:00
return _group;
}
2023-02-14 05:32:32 +01:00
function upgroupNode(collection, record = true) {
2024-05-22 12:13:46 +02:00
UNDO_HOLDING = true;
var _content = [], _deleted = [];
var _node_arr = collection.getNodeList();
2024-05-22 12:13:46 +02:00
var _conn_to = collection.getJunctionTos();
2024-01-26 14:38:50 +01:00
2024-05-22 12:13:46 +02:00
var _cx = 0, _cy = 0;
var _nn = 0;
for (var i = 0, n = array_length(_node_arr); i < n; i++) {
var _node = _node_arr[i];
if(!_node.selectable) continue;
_cx += _node.x;
_cy += _node.y;
_nn++;
}
if(_nn) {
_cx = collection.x - _cx / _nn;
_cy = collection.y - _cy / _nn;
}
for (var i = array_length(_node_arr) - 1; i >= 0; i--) {
var remNode = _node_arr[i];
remNode.x += _cx;
remNode.y += _cy;
2023-02-14 05:32:32 +01:00
2024-05-22 12:13:46 +02:00
if(remNode.destroy_when_upgroup) {
var _vto = remNode.getJunctionTos();
array_push(_deleted, { node: remNode, value_to : _vto });
} else
array_push(_content, remNode);
2024-05-22 12:13:46 +02:00
collection.remove(remNode);
2023-02-14 05:32:32 +01:00
}
2024-04-08 07:13:46 +02:00
collection.destroy();
2023-02-14 05:32:32 +01:00
UNDO_HOLDING = false;
2024-05-22 12:13:46 +02:00
if(!record) return;
recordAction(ACTION_TYPE.ungroup, collection, {
content : _content,
deleted : _deleted,
connectTo : _conn_to,
});
}
2023-02-14 05:32:32 +01:00
2023-10-10 07:12:42 +02:00
function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
nodes = [];
node_length = 0;
2023-07-17 19:58:33 +02:00
ungroupable = true;
auto_render_time = false;
2023-02-19 13:49:20 +01:00
combine_render_time = true;
2023-11-08 08:38:04 +01:00
previewable = true;
reset_all_child = false;
isInstancer = false;
instanceBase = noone;
2023-02-28 09:43:01 +01:00
2023-10-07 09:09:18 +02:00
input_display_list_def = [];
2023-11-02 14:37:13 +01:00
custom_input_index = 0;
custom_output_index = 0;
2022-01-23 04:08:16 +01:00
2023-02-14 05:32:32 +01:00
metadata = new MetaDataManager();
group_input_display_list = [];
group_output_display_list = [];
attributes.input_display_list = [];
attributes.output_display_list = [];
2023-03-08 07:35:51 +01:00
2023-11-02 14:37:13 +01:00
managedRenderOrder = false;
skipDefault();
2023-10-07 09:09:18 +02:00
draw_dummy = false;
2024-08-20 10:15:53 +02:00
dummy_input = nodeValue("Add to group", self, CONNECT_TYPE.input, VALUE_TYPE.any, 0);
dummy_input.setDummy(function() /*=>*/ { var input = nodeBuild("Node_Group_Input", 0, 0, self); return input.inParent; },
function(_junc) /*=>*/ { _junc.from.destroy() }
);
dummy_input.onSetFrom = function(juncFrom) {
array_remove(juncFrom.value_to, dummy_input);
dummy_input.value_from = noone;
2023-10-07 09:09:18 +02:00
var input = nodeBuild("Node_Group_Input", 0, 0, self);
var _type = juncFrom.type;
var _tind = array_find(GROUP_IO_TYPE_MAP, _type);
2023-10-07 09:09:18 +02:00
input.attributes.inherit_type = false;
2024-08-08 06:57:51 +02:00
if(_tind != -1) input.inputs[2].setValue(_tind);
2023-10-07 09:09:18 +02:00
input.inParent.setFrom(juncFrom);
2023-10-08 04:14:35 +02:00
if(onNewInputFromGraph != noone) onNewInputFromGraph(juncFrom);
}
2023-10-07 09:09:18 +02:00
2023-10-08 04:14:35 +02:00
onNewInputFromGraph = noone;
2023-07-17 19:58:33 +02:00
tool_node = noone;
2023-09-11 16:08:58 +02:00
draw_input_overlay = true;
2023-07-17 19:58:33 +02:00
2024-08-20 10:15:53 +02:00
array_push(attributeEditors, ["Edit Input Display", function() /*=>*/ {return 0}, button(function() { dialogCall(o_dialog_group_input_order).setNode(self, CONNECT_TYPE.input); }) ]);
array_push(attributeEditors, ["Edit Output Display", function() /*=>*/ {return 0}, button(function() { dialogCall(o_dialog_group_input_order).setNode(self, CONNECT_TYPE.output); }) ]);
2023-03-19 09:17:39 +01:00
2024-07-03 05:16:46 +02:00
/////========== INSPECTOR ===========
hasInsp1 = false;
2023-06-04 18:28:29 +02:00
insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node contents");
2023-03-28 06:58:28 +02:00
insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ];
2023-03-02 07:59:14 +01:00
hasInsp2 = false;
insp2UpdateTooltip = "Clear cache";
insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ];
static inspector1Update = function() { onInspector1Update(); }
static onInspector1Update = function() { array_foreach(NodeListSort(nodes), function(n) { if(n.hasInspector1Update()) n.inspector1Update(); }); }
static hasInspector1Update = function() { INLINE return hasInsp1; }
2023-03-02 07:59:14 +01:00
static inspector2Update = function() { onInspector2Update(); }
static onInspector2Update = function() { array_foreach(NodeListSort(nodes), function(n) { if(n.hasInspector2Update()) n.inspector2Update(); }); }
static hasInspector2Update = function() { INLINE return hasInsp2; }
2024-07-03 05:16:46 +02:00
/////============ GROUP =============
will_refresh = false;
static refreshNodes = function() {
will_refresh = false;
hasInsp1 = false;
hasInsp2 = false;
node_length = array_length(nodes);
var i = 0;
repeat(node_length) {
hasInsp1 |= nodes[i].hasInspector1Update();
hasInsp2 |= nodes[i].hasInspector2Update();
i++;
}
}
2023-02-28 09:43:01 +01:00
static getNodeBase = function() { return instanceBase == noone? self : instanceBase.getNodeBase(); }
static getNodeList = function() { return instanceBase == noone? nodes : instanceBase.getNodeList(); }
2023-02-28 09:43:01 +01:00
2024-07-03 05:16:46 +02:00
static exitGroup = function() {}
static onAdd = function(_node) {}
static add = function(_node) {
array_push(getNodeList(), _node);
var list = _node.group == noone? PANEL_GRAPH.nodes_list : _node.group.getNodeList();
array_remove(list, _node);
2023-10-09 16:07:33 +02:00
2024-07-03 05:16:46 +02:00
recordAction(ACTION_TYPE.group_added, self, _node);
_node.group = self;
will_refresh = true;
node_length = array_length(nodes);
onAdd(_node);
}
static onRemove = function(_node) {}
static remove = function(_node) {
var _hide = _node.destroy_when_upgroup;
if(!_hide) {
var node_list = getNodeList();
var list = group == noone? PANEL_GRAPH.nodes_list : group.getNodeList();
2023-01-01 02:06:02 +01:00
2024-07-03 05:16:46 +02:00
array_remove(node_list, _node);
array_push(list, _node);
2023-01-01 02:06:02 +01:00
}
2024-07-03 05:16:46 +02:00
recordAction(ACTION_TYPE.group_removed, self, _node);
if(struct_has(_node, "onUngroup"))
_node.onUngroup();
if(_hide) _node.disable();
else _node.group = group;
will_refresh = true;
node_length = array_length(nodes);
onRemove(_node);
}
/////============= STEP ==============
static stepBegin = function() {
2024-07-03 05:16:46 +02:00
if(will_refresh) refreshNodes();
doStepBegin();
}
2024-07-03 05:16:46 +02:00
static step = function() {
2024-07-03 05:16:46 +02:00
if(combine_render_time) {
render_time = 0;
array_foreach(getNodeList(), function(node) { render_time += node.render_time; });
}
onStep();
}
2023-01-01 02:06:02 +01:00
2024-07-03 05:16:46 +02:00
static onStep = function() {}
/////========== JUNCTIONS ==========
static getOutputNodes = function() {
var _nodes = [];
2024-08-08 06:57:51 +02:00
for( var i = custom_output_index; i < array_length(outputs); i++ ) {
var _junc = outputs[i];
2023-06-13 14:42:06 +02:00
2023-12-19 14:30:34 +01:00
for( var j = 0; j < array_length(_junc.value_to); j++ ) {
var _to = _junc.value_to[j];
2023-06-13 14:42:06 +02:00
if(_to.value_from != _junc) continue;
array_push_unique(_nodes, _to.node);
2023-06-13 14:42:06 +02:00
}
}
return _nodes;
}
2023-06-13 14:42:06 +02:00
static preConnect = function() {
2024-07-03 05:16:46 +02:00
sortIO();
deserialize(load_map, load_scale);
}
2024-07-03 05:16:46 +02:00
static sortIO = function() {
2024-08-08 06:57:51 +02:00
var _ilen = array_length(inputs);
2024-07-03 05:16:46 +02:00
var _iarr = attributes.input_display_list;
for( var i = custom_input_index; i < _ilen; i++ )
array_push_unique(_iarr, i);
for( var i = array_length(_iarr) - 1; i >= 0; i-- ) {
if(is_array(_iarr[i])) continue;
if(_iarr[i] >= _ilen) array_delete(_iarr, i, 1);
}
input_display_list = array_merge(group_input_display_list, attributes.input_display_list);
///////////////////////////////////////////////////////////////////
2024-08-08 06:57:51 +02:00
var _olen = array_length(outputs);
2024-07-03 05:16:46 +02:00
var _oarr = attributes.output_display_list;
for( var i = custom_output_index; i < _olen; i++ )
array_push_unique(_oarr, i);
for( var i = array_length(_oarr) - 1; i >= 0; i-- ) {
if(is_array(_oarr[i])) continue;
if(_oarr[i] >= _olen) array_delete(_oarr, i, 1);
}
output_display_list = array_merge(group_output_display_list, attributes.output_display_list);
///////////////////////////////////////////////////////////////////
refreshNodeDisplay();
}
2024-07-03 05:16:46 +02:00
static preConnect = function() {
2024-07-03 05:16:46 +02:00
instanceBase = GetAppendID(struct_try_get(load_map, "instance_base", noone));
sortIO();
applyDeserialize();
}
2024-07-03 05:16:46 +02:00
/////========== RENDERING ===========
2023-10-10 07:12:42 +02:00
static getNextNodes = function() { return getNextNodesInternal(); }
static getNextNodesInternal = function() { //get node inside the group
LOG_BLOCK_START();
LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from group: {INAME}");
2023-06-01 10:32:21 +02:00
var _nodes = [];
2023-06-17 14:30:49 +02:00
if(isRenderActive()) {
2023-06-13 14:42:06 +02:00
var allReady = true;
2024-08-08 06:57:51 +02:00
for(var i = custom_input_index; i < array_length(inputs); i++) {
var _in = inputs[i].from;
2023-06-17 14:30:49 +02:00
if(!_in.isRenderActive()) continue;
2022-12-16 09:18:09 +01:00
2023-06-13 14:42:06 +02:00
if(!_in.isRenderable()) {
LOG_IF(global.FLAG.render == 1, $"Node {_in.internalName} not ready, loop skip.");
2023-06-13 14:42:06 +02:00
LOG_BLOCK_END();
return [];
}
2023-06-01 10:32:21 +02:00
}
2023-06-13 14:42:06 +02:00
_nodes = __nodeLeafList(getNodeList());
2022-12-16 09:18:09 +01:00
}
2023-03-28 06:58:28 +02:00
LOG_BLOCK_END();
return _nodes;
}
2022-12-16 09:18:09 +01:00
static getNextNodesExternal = function() { //get node connected to the parent object
LOG_IF(global.FLAG.render == 1, $"Checking next node external for {INAME}");
2023-07-28 19:41:57 +02:00
LOG_BLOCK_START();
var nextNodes = [];
2024-08-08 06:57:51 +02:00
for( var i = 0; i < array_length(outputs); i++ ) {
var _ot = outputs[i];
2023-10-19 11:34:29 +02:00
if(!_ot.forward) continue;
if(_ot.type == VALUE_TYPE.node) continue;
2023-07-28 19:41:57 +02:00
var _tos = _ot.getJunctionTo();
for( var j = 0, n = array_length(_tos); j < n; j++ ) {
var _to = _tos[j];
2023-06-01 10:32:21 +02:00
var _node = _to.node;
LOG_IF(global.FLAG.render == 1, $"Checking node {_node.internalName} : {_node.isRenderable()}");
2023-10-10 07:12:42 +02:00
if(!_node.isRenderable()) continue;
2023-06-01 10:32:21 +02:00
array_push(nextNodes, _to.node);
2023-06-01 10:32:21 +02:00
}
}
2023-07-28 19:41:57 +02:00
LOG_BLOCK_END();
2023-06-01 10:32:21 +02:00
return nextNodes;
}
2023-06-01 10:32:21 +02:00
static clearTopoSorted = function() { INLINE topoSorted = false; for( var i = 0, n = array_length(nodes); i < n; i++ ) { nodes[i].clearTopoSorted(); } }
2024-04-03 09:40:37 +02:00
static setRenderStatus = function(result) {
LOG_BLOCK_START();
LOG_IF(global.FLAG.render == 1, $"Set render status for {INAME} : {result}");
2022-12-12 09:08:03 +01:00
rendered = result;
2024-04-30 05:57:34 +02:00
if(rendered == result) {
LOG_BLOCK_END();
return;
}
2022-12-12 09:08:03 +01:00
2023-07-28 19:41:57 +02:00
if(result)
2024-08-08 06:57:51 +02:00
for( var i = custom_output_index, n = array_length(outputs); i < n; i++ ) {
var _o = outputs[i];
2023-07-28 19:41:57 +02:00
if(_o.from.rendered) continue;
2022-12-16 09:18:09 +01:00
LOG_IF(global.FLAG.render == 1, $"Set fail because {_o.from.internalName} is not rendered.");
2023-07-28 19:41:57 +02:00
rendered = false;
break;
2022-12-12 09:08:03 +01:00
}
2023-04-09 21:24:16 +02:00
2023-10-08 08:02:38 +02:00
if(rendered) exitGroup();
2023-04-09 21:24:16 +02:00
2023-02-28 09:43:01 +01:00
if(!result && group != noone)
2022-12-12 09:08:03 +01:00
group.setRenderStatus(result);
2023-07-28 19:41:57 +02:00
LOG_BLOCK_END();
}
2022-12-12 09:08:03 +01:00
static isActiveDynamic = function(frame = CURRENT_FRAME) {
if(update_on_frame) return true;
if(!rendered) return true;
2024-08-08 06:57:51 +02:00
for( var i = custom_input_index, n = array_length(inputs); i < n; i++ )
if(inputs[i].isActiveDynamic(frame) || !inputs[i].from.rendered) return true;
return false;
}
static resetRender = function(_clearCache = false) {
2024-07-03 05:16:46 +02:00
LOG_LINE_IF(global.FLAG.render == 1, $"Reset Render for group {INAME}");
2022-01-13 05:24:03 +01:00
2024-07-03 05:16:46 +02:00
setRenderStatus(false);
if(_clearCache) clearInputCache();
2022-01-29 14:25:18 +01:00
2024-07-03 05:16:46 +02:00
if(reset_all_child)
for(var i = 0, n = array_length(nodes); i < n; i++)
nodes[i].resetRender(_clearCache);
}
2022-12-10 05:06:01 +01:00
2024-07-03 05:16:46 +02:00
/////============= DRAW =============
2022-01-13 05:24:03 +01:00
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
2024-07-03 05:16:46 +02:00
if(!draw_input_overlay) return;
2022-01-13 05:24:03 +01:00
2024-08-08 06:57:51 +02:00
for(var i = custom_input_index; i < array_length(inputs); i++) {
var _in = inputs[i];
2024-07-03 05:16:46 +02:00
var _show = _in.from.getInputData(6);
if(!_show) continue;
var _hov = _in.drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
if(_hov != undefined) active &= !_hov;
}
}
2022-01-13 05:24:03 +01:00
static onPreDraw = function(_x, _y, _s, _iny, _outy) {
2023-10-07 09:09:18 +02:00
var xx = x * _s + _x;
var yy = y * _s + _y;
dummy_input.x = xx;
dummy_input.y = _iny;
var _hv = PANEL_GRAPH.pHOVER && PANEL_GRAPH.node_hovering == self && (!PREFERENCES.panel_graph_group_require_shift || key_mod_press(SHIFT));
bg_spr_add = 0.1 + (0.1 * _hv);
}
static drawNodeBase = function(xx, yy, _s) {
var _hv = PANEL_GRAPH.pHOVER && PANEL_GRAPH.node_hovering == self && (!PREFERENCES.panel_graph_group_require_shift || key_mod_press(SHIFT));
var _aa = (.25 + .5 * renderActive) * (.25 + .75 * isHighlightingInGraph()) + _hv * 0.1;
draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, getColor(), _aa);
}
2023-10-07 09:09:18 +02:00
2024-07-03 05:16:46 +02:00
static drawNodeOverlay = function(xx, yy, _mx, _my, _s) {
if(_s < 0.75) return;
2024-07-05 07:06:49 +02:00
var _bx = (xx + w * _s) - 10;
var _by = (yy + h * _s) - 10;
2024-07-03 05:16:46 +02:00
var _hv = PANEL_GRAPH.pHOVER && PANEL_GRAPH.node_hovering == self && PANEL_GRAPH._value_focus == noone;
2024-07-03 05:16:46 +02:00
_hv &= point_in_circle(_mx, _my, _bx, _by, 8);
draw_sprite_ext_add(THEME.animate_node_go, 0, _bx, _by, 1, 1, 0, _hv? COLORS._main_accent : c_white, 0.3 + _hv * 0.7);
2024-07-03 05:16:46 +02:00
if(_hv && PANEL_GRAPH.pFOCUS && mouse_press(mb_left))
panelSetContext(PANEL_GRAPH);
}
2022-01-13 05:24:03 +01:00
static onDrawJunctions = function(_x, _y, _mx, _my, _s) {
dummy_input.visible = false;
2023-03-08 07:35:51 +01:00
2023-10-07 09:09:18 +02:00
if(draw_dummy) {
dummy_input.visible = true;
dummy_input.drawJunction(_s, _mx, _my);
2023-10-07 09:09:18 +02:00
}
draw_dummy = false;
}
2023-10-07 09:09:18 +02:00
static getTool = function() {
for(var i = 0, n = array_length(nodes); i < n; i++) {
var _node = nodes[i];
2024-04-01 11:10:01 +02:00
if(!_node.active) continue;
2023-07-17 19:58:33 +02:00
if(_node.isTool) return _node.getTool();
}
return self;
}
2023-07-17 19:58:33 +02:00
2024-07-03 05:16:46 +02:00
/////============ PREVIEW ============
2023-10-09 16:07:33 +02:00
2024-08-20 10:15:53 +02:00
static getGraphPreviewSurface = function() {
for( var i = 0, n = array_length(nodes); i < n; i++ ) {
if(!nodes[i].active) continue;
if(is_instanceof(nodes[i], Node_Group_Thumbnail))
2024-08-08 06:57:51 +02:00
return nodes[i].inputs[0].getValue();
2023-10-06 11:51:11 +02:00
}
2024-08-20 10:15:53 +02:00
var _oj = array_safe_get(outputs, preview_channel);
if(!is_instanceof(_oj, NodeValue)) return noone;
2024-08-20 10:15:53 +02:00
if(_oj.from == noone) return noone;
var _fr = array_safe_get(_oj.from.inputs, 0);
return _fr.value_from == noone? noone : _fr.value_from.node.getGraphPreviewSurface();
}
2023-10-06 11:51:11 +02:00
function getPreviewingNode() {
2024-08-28 04:42:25 +02:00
var _oj = array_safe_get(outputs, preview_channel, noone);
if(_oj == noone) return self;
switch(_oj.type) {
case VALUE_TYPE.d3Mesh :
case VALUE_TYPE.d3Camera :
case VALUE_TYPE.d3Light :
case VALUE_TYPE.d3Scene :
case VALUE_TYPE.d3object :
case VALUE_TYPE.sdf :
2024-08-08 06:57:51 +02:00
var _fr = _oj.from.inputs[0];
return _fr.value_from == noone? self : _fr.value_from.node;
}
return self;
}
2024-07-03 05:16:46 +02:00
/////============= CACHE =============
static clearCache = function() { array_foreach(getNodeList(), function(node) /*=>*/ { node.clearCache(); }); }
2024-07-03 05:16:46 +02:00
/////========== INSTANCING ===========
static setInstance = function(node) { instanceBase = node; }
static resetInstance = function() { instanceBase = noone; }
2024-07-03 05:16:46 +02:00
/////========= SERIALIZATION =========
static attributeSerialize = function() {
sortIO();
var _attr = variable_clone(attributes);
_attr.custom_input_list = [];
2024-08-08 06:57:51 +02:00
for( var i = custom_input_index, n = array_length(inputs); i < n; i++ ) {
if(struct_has(inputs[i], "from"))
array_push(_attr.custom_input_list, inputs[i].from.node_id);
}
_attr.custom_output_list = [];
2024-08-08 06:57:51 +02:00
for( var i = custom_output_index, n = array_length(outputs); i < n; i++ ) {
if(struct_has(outputs[i], "from"))
array_push(_attr.custom_output_list , outputs[i].from.node_id);
}
return _attr;
}
static preApplyDeserialize = function() {
var attr = attributes;
if(LOADING_VERSION < 11690) {
2024-04-02 14:33:25 +02:00
var pr = ds_priority_create();
2024-08-08 06:57:51 +02:00
for( var i = array_length(inputs) - 1; i >= custom_input_index; i-- ) {
if(!struct_has(inputs[i].attributes, "input_priority")) continue;
2024-04-02 14:33:25 +02:00
2024-08-08 06:57:51 +02:00
var _pri = inputs[i].attributes.input_priority;
ds_priority_add(pr, inputs[i], _pri);
array_delete(inputs, i, 1);
2024-04-02 14:33:25 +02:00
}
2024-08-08 06:57:51 +02:00
repeat(ds_priority_size(pr)) array_push(inputs, ds_priority_delete_min(pr));
2024-04-02 14:33:25 +02:00
2024-08-08 06:57:51 +02:00
for( var i = array_length(outputs) - 1; i >= custom_output_index; i-- ) {
if(!struct_has(outputs[i].attributes, "output_priority")) continue;
2024-04-02 14:33:25 +02:00
2024-08-08 06:57:51 +02:00
var _pri = outputs[i].attributes.output_priority;
ds_priority_add(pr, outputs[i], _pri);
array_delete(outputs, i, 1);
2024-04-02 14:33:25 +02:00
}
2024-08-08 06:57:51 +02:00
repeat(ds_priority_size(pr)) array_push(outputs, ds_priority_delete_min(pr));
2024-04-02 14:33:25 +02:00
ds_priority_destroy(pr);
return;
}
2024-04-02 14:33:25 +02:00
if(struct_has(attr, "custom_input_list")) {
var _ilist = attr.custom_input_list;
var _inarr = {};
2024-04-02 14:33:25 +02:00
var _dilst = [];
if(APPENDING)
for( var i = 0, n = array_length(_ilist); i < n; i++ )
_ilist[i] = ds_map_try_get(APPEND_MAP, _ilist[i], _ilist[i]);
2024-08-08 06:57:51 +02:00
for( var i = array_length(inputs) - 1; i >= custom_input_index; i-- ) {
if(!struct_has(inputs[i], "from")) continue;
2024-08-08 06:57:51 +02:00
var _frNode = inputs[i].from.node_id;
if(array_exists(_ilist, _frNode)) {
2024-08-08 06:57:51 +02:00
_inarr[$ _frNode] = inputs[i];
array_delete(inputs, i, 1);
}
}
for( var i = 0, n = array_length(_ilist); i < n; i++ ) {
if(!struct_has(_inarr, _ilist[i])) continue;
var _inJunc = _inarr[$ _ilist[i]];
2024-08-08 06:57:51 +02:00
_inJunc.index = array_length(inputs);
array_push(inputs, _inJunc);
}
2024-04-02 14:33:25 +02:00
}
if(struct_has(attr, "custom_output_list")) {
var _ilist = attr.custom_output_list;
var _inarr = {};
2024-04-02 14:33:25 +02:00
if(APPENDING)
for( var i = 0, n = array_length(_ilist); i < n; i++ )
_ilist[i] = ds_map_try_get(APPEND_MAP, _ilist[i], _ilist[i]);
2024-08-08 06:57:51 +02:00
for( var i = array_length(outputs) - 1; i >= custom_output_index; i-- ) {
if(!struct_has(outputs[i], "from")) continue;
2024-08-08 06:57:51 +02:00
var _frNode = outputs[i].from.node_id;
if(array_exists(_ilist, _frNode)) {
2024-08-08 06:57:51 +02:00
_inarr[$ _frNode] = outputs[i];
array_delete(outputs, i, 1);
}
}
for( var i = 0, n = array_length(_ilist); i < n; i++ ) {
if(!struct_has(_inarr, _ilist[i])) continue;
var _outJunc = _inarr[$ _ilist[i]];
2024-08-08 06:57:51 +02:00
_outJunc.index = array_length(outputs);
array_push(outputs, _outJunc);
}
2024-04-03 09:40:37 +02:00
}
}
static processSerialize = function(_map) {
2024-04-02 05:24:55 +02:00
_map.instance_base = instanceBase? instanceBase.node_id : noone;
}
2023-02-28 09:43:01 +01:00
2024-07-03 05:16:46 +02:00
/////============ ACTION ============
static onClone = function(_newNode, target = PANEL_GRAPH.getCurrentContext()) {
2024-07-03 05:16:46 +02:00
if(instanceBase != noone) {
_newNode.instanceBase = instanceBase;
return;
}
2023-02-28 09:43:01 +01:00
2024-07-03 05:16:46 +02:00
var dups = ds_list_create();
for(var i = 0, n = array_length(nodes); i < n; i++) {
var _node = nodes[i];
var _cnode = _node.clone(target);
ds_list_add(dups, _cnode);
APPEND_MAP[? _node.node_id] = _cnode.node_id;
}
APPENDING = true;
for(var i = 0; i < ds_list_size(dups); i++) {
var _node = dups[| i];
_node.connect();
}
APPENDING = false;
ds_list_destroy(dups);
}
2024-07-03 05:16:46 +02:00
static enable = function() {
2024-07-03 05:16:46 +02:00
active = true;
array_foreach(getNodeList(), function(node) { node.enable(); });
}
2024-07-03 05:16:46 +02:00
static disable = function() {
2024-07-03 05:16:46 +02:00
active = false;
array_foreach(getNodeList(), function(node) { node.disable(); });
}
2024-07-03 05:16:46 +02:00
function onDoubleClick(panel) {
2024-07-03 05:16:46 +02:00
if(PREFERENCES.panel_graph_group_require_shift && !key_mod_press(SHIFT)) return false;
panelSetContext(panel);
if(ononDoubleClick != noone)
ononDoubleClick(panel);
return true;
}
2024-07-03 05:16:46 +02:00
static panelSetContext = function(panel) {
__temp_panel = panel;
if(PREFERENCES.graph_open_group_in_tab)
run_in(1, function() { __temp_panel.openGroupTab(self) });
else
panel.addContext(self);
}
static ononDoubleClick = noone;
static enable = function() {
2024-07-03 05:16:46 +02:00
active = true; timeline_item.active = true;
for( var i = 0, n = array_length(nodes); i < n; i++ ) nodes[i].enable();
}
2024-07-03 05:16:46 +02:00
static disable = function() {
2024-07-03 05:16:46 +02:00
active = false; timeline_item.active = false;
for( var i = 0, n = array_length(nodes); i < n; i++ ) nodes[i].disable();
}
2023-03-08 07:35:51 +01:00
2022-01-13 05:24:03 +01:00
}