From 3a3f39a170330ce36c87636471a26be1dee6e2d6 Mon Sep 17 00:00:00 2001 From: Tanasart Date: Tue, 23 Apr 2024 16:53:16 +0700 Subject: [PATCH] strict --- .../load_function/load_function.gml.backup0 | 2 +- .../load_function/load_function.gml.backup1 | 2 +- .../scripts/node_data/node_data.gml.backup0 | 30 +- .../scripts/node_data/node_data.gml.backup1 | 2090 +++++++++++------ .../node_keyframe/node_keyframe.gml.backup0 | 4 +- .../node_keyframe/node_keyframe.gml.backup1 | 6 +- .../scripts/node_pin/node_pin.gml.backup0 | 4 +- .../scripts/node_pin/node_pin.gml.backup1 | 6 +- .../node_tunnel_in/node_tunnel_in.gml.backup0 | 4 +- .../node_tunnel_in/node_tunnel_in.gml.backup1 | 6 +- .../node_tunnel_out.gml.backup0 | 4 +- .../node_tunnel_out.gml.backup1 | 2 +- .../scripts/node_value/node_value.gml.backup0 | 71 +- .../scripts/node_value/node_value.gml.backup1 | 71 +- .../panel_inspector.gml.backup0 | 2 +- .../panel_inspector.gml.backup1 | 2 +- .../preferences/preferences.gml.backup0 | 2 +- .../preferences/preferences.gml.backup1 | 2 +- .../project_data/project_data.gml.backup0 | 146 ++ .../project_data/project_data.gml.backup1 | 146 ++ .../save_function/save_function.gml.backup0 | 232 ++ .../save_function/save_function.gml.backup1 | 232 ++ scripts/node_data/node_data.gml | 28 +- scripts/node_keyframe/node_keyframe.gml | 2 +- scripts/node_pin/node_pin.gml | 2 +- scripts/node_tunnel_in/node_tunnel_in.gml | 2 +- scripts/node_tunnel_out/node_tunnel_out.gml | 2 +- scripts/node_value/node_value.gml | 69 +- scripts/project_data/project_data.gml | 7 +- scripts/save_function/save_function.gml | 2 +- 30 files changed, 2337 insertions(+), 843 deletions(-) create mode 100644 #backups/scripts/project_data/project_data.gml.backup0 create mode 100644 #backups/scripts/project_data/project_data.gml.backup1 create mode 100644 #backups/scripts/save_function/save_function.gml.backup0 create mode 100644 #backups/scripts/save_function/save_function.gml.backup1 diff --git a/#backups/scripts/load_function/load_function.gml.backup0 b/#backups/scripts/load_function/load_function.gml.backup0 index cdb498602..769fb6775 100644 --- a/#backups/scripts/load_function/load_function.gml.backup0 +++ b/#backups/scripts/load_function/load_function.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-18 12:08:08 +// 2024-04-23 16:48:26 function LOAD(safe = false) { #region if(DEMO) return false; diff --git a/#backups/scripts/load_function/load_function.gml.backup1 b/#backups/scripts/load_function/load_function.gml.backup1 index 93562b8b0..8ea8c940d 100644 --- a/#backups/scripts/load_function/load_function.gml.backup1 +++ b/#backups/scripts/load_function/load_function.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-18 11:54:26 +// 2024-04-23 16:48:08 function LOAD(safe = false) { #region if(DEMO) return false; diff --git a/#backups/scripts/node_data/node_data.gml.backup0 b/#backups/scripts/node_data/node_data.gml.backup0 index ca3818bc5..a7e1a0c68 100644 --- a/#backups/scripts/node_data/node_data.gml.backup0 +++ b/#backups/scripts/node_data/node_data.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-16 12:09:31 +// 2024-04-23 16:12:42 global.loop_nodes = [ "Node_Iterate", "Node_Iterate_Each" ]; #macro INAME internalName == ""? name : internalName @@ -938,6 +938,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { static refreshNodeDisplay = function() { #region INLINE + if(IS_PLAYING) return; updateIO(); setHeight(); @@ -1446,17 +1447,17 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { var ph = surface_get_height_safe(preview_surface); var format = surface_get_format_safe(preview_surface); - var txt = $"[{pw} x {ph} "; + var txt = $"[{pw} x {ph}"; if(preview_amount) txt = $"{preview_amount} x {txt}"; switch(format) { - case surface_rgba4unorm : txt += showFormat? "4RGBA" : "4R"; break; - case surface_rgba8unorm : txt += showFormat? "8RGBA" : "8R"; break; - case surface_rgba16float : txt += showFormat? "16RGBA" : "16R"; break; - case surface_rgba32float : txt += showFormat? "32RGBA" : "32R"; break; - case surface_r8unorm : txt += showFormat? "8BW" : "8B"; break; - case surface_r16float : txt += showFormat? "16BW" : "16B"; break; - case surface_r32float : txt += showFormat? "32BW" : "32B"; break; + case surface_rgba8unorm : break; + case surface_rgba4unorm : txt += showFormat? " 4RGBA" : " 4R"; break; + case surface_rgba16float : txt += showFormat? " 16RGBA" : " 16R"; break; + case surface_rgba32float : txt += showFormat? " 32RGBA" : " 32R"; break; + case surface_r8unorm : txt += showFormat? " 8BW" : " 8B"; break; + case surface_r16float : txt += showFormat? " 16BW" : " 16B"; break; + case surface_r32float : txt += showFormat? " 32BW" : " 32B"; break; } txt += "]"; @@ -1469,32 +1470,33 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { if(!active) return; if(_s * w < 64) return; - draw_set_text(f_p2, fa_center, fa_top, COLORS.panel_graph_node_dimension); + draw_set_text(f_p3, fa_center, fa_top, COLORS.panel_graph_node_dimension); var tx = xx + w * _s / 2; var ty = yy + (h + 4) * _s - 2; if(struct_get(display_parameter, "show_dimension")) { var txt = string(getNodeDimension(_s > 0.65)); draw_text(round(tx), round(ty), txt); - ty += line_get_height(f_p2) - 2; + ty += string_height(txt) - 2; } - draw_set_font(f_p3); - if(struct_get(display_parameter, "show_compute")) { var rt = 0, unit = ""; if(render_time == 0) { draw_set_color(COLORS._main_text_sub); unit = "us"; + } else if(render_time < 1000) { rt = round(render_time / 10) * 10; unit = "us"; draw_set_color(COLORS.speed[2]); + } else if(render_time < 1000000) { rt = string_format(render_time / 1000, -1, 2); unit = "ms"; draw_set_color(COLORS.speed[1]); + } else { rt = string_format(render_time / 1000000, -1, 2); unit = "s"; @@ -1503,7 +1505,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { if(render_cached) draw_set_color(COLORS._main_text_sub); - draw_text(round(tx), round(ty), string(rt) + " " + unit); + draw_text(round(tx), round(ty), $"{rt} {unit}"); } } #endregion diff --git a/#backups/scripts/node_data/node_data.gml.backup1 b/#backups/scripts/node_data/node_data.gml.backup1 index 2ba8de8b1..ec131e3a6 100644 --- a/#backups/scripts/node_data/node_data.gml.backup1 +++ b/#backups/scripts/node_data/node_data.gml.backup1 @@ -1,147 +1,310 @@ -// 2023-08-08 14:42:15 +// 2024-04-23 11:32:21 global.loop_nodes = [ "Node_Iterate", "Node_Iterate_Each" ]; -function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x, _y) constructor { - active = true; - renderActive = true; +#macro INAME internalName == ""? name : internalName +#macro NODE_HAS_INSP1 (onInspector1Update != noone) +#macro NODE_HAS_INSP2 (onInspector2Update != noone) + +enum CACHE_USE { + none, + manual, + auto +} + +enum DYNA_INPUT_COND { + connection = 1 << 0, + zero = 1 << 1, +} + +function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { - node_id = UUID_generate(); + #region ---- main & active ---- + active = true; + renderActive = true; + + node_id = UUID_generate(); + group = _group; + manual_deletable = true; + manual_ungroupable = true; + destroy_when_upgroup = false; + + var l = _group == noone? PROJECT.nodes : _group.getNodeList(); + ds_list_add(l, self); + + active_index = -1; + active_range = [ 0, TOTAL_FRAMES - 1 ]; + + array_push(PROJECT.nodeArray, self); + + inline_context = noone; + inline_parent_object = ""; + #endregion - group = _group; - destroy_when_upgroup = false; - ds_list_add(PANEL_GRAPH.getNodeList(_group), self); - - active_index = -1; - active_range = [ 0, PROJECT.animator.frames_total - 1 ]; - - color = c_white; - icon = noone; - bg_spr = THEME.node_bg; - bg_sel_spr = THEME.node_active; - anim_priority = ds_map_size(PROJECT.nodeMap); - - static resetInternalName = function() { + static resetInternalName = function() { #region var str = string_replace_all(name, " ", "_"); str = string_replace_all(str, "/", ""); str = string_replace_all(str, "-", ""); - + + ds_map_delete(PROJECT.nodeNameMap, internalName); internalName = str + string(irandom_range(10000, 99999)); PROJECT.nodeNameMap[? internalName] = self; - } + } #endregion - if(!LOADING && !APPENDING) { + if(!LOADING && !APPENDING) { #region recordAction(ACTION_TYPE.node_added, self); PROJECT.nodeMap[? node_id] = self; PROJECT.modified = true; - //print($"Adding node {node_id} to {PROJECT.path} [{ds_map_size(PROJECT.nodeMap)}]"); - run_in(1, function() { - if(display_name != "") return; resetInternalName(); - display_name = name; //__txt_node_name(instanceof(self), name); + + if(renamed) return; + display_name = __txt_node_name(instanceof(self), name); + if(!LOCALE_DEF || TESTING) renamed = true; }); - } + + RENDER_ALL_REORDER + } #endregion - name = ""; - display_name = ""; - internalName = ""; + #region ---- display ---- + color = c_white; + icon = noone; + icon_24 = noone; + bg_spr = THEME.node_bg; + bg_sel_spr = THEME.node_active; - tooltip = ""; - x = _x; - y = _y; + name = ""; + display_name = ""; + internalName = ""; + onSetDisplayName = noone; + renamed = false; + + tooltip = ""; + x = _x; + y = _y; - w = 128; - h = 128; - min_h = 0; - draw_padding = 8; - auto_height = true; + w = 128; + h = 128; + min_w = w; + min_h = h; + fix_h = h; + will_setHeight = false; + + selectable = true; + clonable = true; + draw_padding = 4; + auto_height = true; + + display_parameter = new connectionParameter(); + + draw_name = true; + draggable = true; + + draw_boundary = [ 0, 0, 0, 0 ]; + draw_graph_culled = false; + + badgePreview = 0; + badgeInspect = 0; + + active_draw_index = -1; + + draw_droppable = false; + + junction_draw_pad_y = 32; + junction_draw_hei_y = 24; + + branch_drawing = false; + #endregion - draw_name = true; - draggable = true; + #region ---- junctions ---- + inputs = ds_list_create(); + outputs = ds_list_create(); + inputMap = ds_map_create(); + outputMap = ds_map_create(); + input_value_map = {}; + + use_display_list = true; + input_display_list = -1; + output_display_list = -1; + inspector_display_list = -1; + is_dynamic_output = false; + + inspectInput1 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + inspectInput2 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + + inspectInput1.index = -1; + inspectInput2.index = -1; + + autoUpdatedTrigger = true; + updatedInTrigger = nodeValue("Update", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, false).setVisible(true, true); + updatedOutTrigger = nodeValue("Updated", self, JUNCTION_CONNECT.output, VALUE_TYPE.trigger, false).setVisible(true, true); + + updatedInTrigger.index = -1; + updatedOutTrigger.index = -1; + + updatedInTrigger.tags = VALUE_TAG.updateInTrigger; + updatedOutTrigger.tags = VALUE_TAG.updateOutTrigger; + + insp1UpdateActive = true; + insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); + insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; + + insp2UpdateActive = true; + insp2UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); + insp2UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; + + is_dynamic_input = false; + auto_input = false; + input_display_len = 0; + input_fix_len = 0; + data_length = 1; + inputs_data = []; + input_hash = ""; + input_hash_raw = ""; + + inputs_amount = 0; + inputs_index = []; + in_cache_len = 0; + inputDisplayList = []; + + outputs_amount = 0; + outputs_index = []; + out_cache_len = 0; + + input_buttons = []; + input_button_length = 0; + + run_in(1, function() { + input_buttons = []; + + for( var i = 0; i < ds_list_size(inputs); i++ ) { + var _in = inputs[| i]; + if(!is_instanceof(_in, NodeValue)) continue; + if(_in.type != VALUE_TYPE.trigger) continue; + + if(_in.runInUI) array_push(input_buttons, _in); + } + + input_button_length = array_length(input_buttons); + }); + #endregion - inputs = ds_list_create(); - outputs = ds_list_create(); - inputMap = ds_map_create(); - outputMap = ds_map_create(); + #region --- attributes ---- + attributes.node_param_width = PREFERENCES.node_param_width; + attributes.node_width = 0; + attributes.node_height = 0; + + attributeEditors = [ + "Display", + ["Params Width", function() { return attributes.node_param_width; }, new textBox(TEXTBOX_INPUT.number, function(val) { attributes.node_param_width = val; refreshNodeDisplay(); }) ], + + "Node update", + ["Auto update", function() { return attributes.update_graph; }, new checkBox(function() { attributes.update_graph = !attributes.update_graph; }) ], + ["Update trigger", function() { return attributes.show_update_trigger; }, new checkBox(function() { attributes.show_update_trigger = !attributes.show_update_trigger; }) ], + ]; + + bufferStore = {}; + #endregion - input_display_list = -1; - output_display_list = -1; - inspector_display_list = -1; - is_dynamic_output = false; + #region ---- preview ---- + show_parameter = PREFERENCES.node_param_show; + + show_input_name = false; + show_output_name = false; - attributes = {}; - attributeEditors = []; + inspecting = false; + previewing = 0; + + preview_surface = noone; + preview_amount = 0; + previewable = true; + preview_draw = true; + preview_speed = 0; + preview_index = 0; + preview_channel = 0; + preview_alpha = 1; + preview_x = 0; + preview_y = 0; + + preview_mx = 0; + preview_my = 0; + + graph_preview_alpha = 1; + + getPreviewingNode = noone; + + preview_value = 0; + preview_array = ""; + #endregion - inspectInput1 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); - inspectInput2 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + #region ---- rendering ---- + rendered = false; + update_on_frame = false; + render_time = 0; + render_cached = false; + auto_render_time = true; + updated = false; + passiveDynamic = false; + topoSorted = false; + temp_surface = []; + force_requeue = false; + is_simulation = false; + + in_VFX = false; + + is_group_io = false; + #endregion - updateAction = nodeValue("Update", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + #region ---- timeline ---- + timeline_item = new timelineItemNode(self); + anim_priority = ds_map_size(PROJECT.nodeMap); + is_anim_timeline = false; + #endregion - show_input_name = false; - show_output_name = false; + #region ---- notification ---- + value_validation = array_create(3); - inspecting = false; - previewing = 0; + manual_updated = false; + #endregion - preview_surface = noone; - preview_amount = 0; - previewable = true; - preview_speed = 0; - preview_index = 0; - preview_channel = 0; - preview_alpha = 1; - preview_x = 0; - preview_y = 0; + #region ---- tools ---- + tools = -1; + rightTools = -1; + isTool = false; + tool_settings = []; + tool_attribute = {}; + #endregion - preview_surface_prev = noone; - preview_trans = 1; - preview_drop_x = 0; - preview_drop_y = 0; + #region ---- 3d ---- + is_3D = false; + #endregion - preview_mx = 0; - preview_my = 0; + #region ---- cache ---- + use_cache = CACHE_USE.none; + cached_manual = false; + cached_output = []; + cache_result = []; + cache_group = noone; + + clearCacheOnChange = true; + #endregion - rendered = false; - update_on_frame = false; - render_time = 0; - auto_render_time = true; - updated = false; + #region ---- log ---- + messages = []; + #endregion - use_cache = false; - clearCacheOnChange = true; - cached_output = []; - cache_result = []; - temp_surface = []; - - tools = -1; - - on_dragdrop_file = -1; - - anim_show = true; - dopesheet_color = COLORS.panel_animation_dope_blend_default; - dopesheet_y = 0; - - value_validation = array_create(3); - - error_noti_update = noone; - error_update_enabled = false; - manual_updated = false; - manual_deletable = true; - - isTool = false; - tool_settings = []; - tool_attribute = {}; - - is_dynamic_input = false; - input_display_len = 0; - input_fix_len = 0; - data_length = 1; + #region ---- serialization ---- + load_scale = false; + load_map = -1; + load_group = noone; + #endregion static createNewInput = noone; - static initTooltip = function() { - var type_self:string = instanceof(self); + static initTooltip = function() { #region + if(IS_CMD) return; + + var type_self = instanceof(self); if(!struct_has(global.NODE_GUIDE, type_self)) return; var _n = global.NODE_GUIDE[$ type_self]; @@ -159,10 +322,10 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x outputs[| i].name = _ots[i].name; outputs[| i].tooltip = _ots[i].tooltip; } - } + } #endregion run_in(1, initTooltip); - static resetDefault = function() { + static resetDefault = function() { #region var folder = instanceof(self); if(!ds_map_exists(global.PRESETS_MAP, folder)) return; @@ -176,59 +339,155 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x } doUpdate(); - } + } #endregion if(!APPENDING && !LOADING) run_in(1, method(self, resetDefault)); - static getInputJunctionIndex = function(index) { - if(input_display_list == -1) + static getInputJunctionIndex = function(index) { #region + INLINE + + if(input_display_list == -1 || !use_display_list) return index; var jun_list_arr = input_display_list[index]; - if(is_array(jun_list_arr)) return noone; + if(is_array(jun_list_arr)) return noone; if(is_struct(jun_list_arr)) return noone; + return jun_list_arr; - } + } #endregion - static getOutputJunctionIndex = function(index) { + static getOutputJunctionIndex = function(index) { #region if(output_display_list == -1) return index; return output_display_list[index]; - } + } #endregion - static setHeight = function() { - var _hi = ui(32); - var _ho = ui(32); + static updateIO = function() { #region + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) + inputs[| i].visible_in_list = false; - for( var i = 0; i < ds_list_size(inputs); i++ ) { - if(inputs[| i].isVisible()) _hi += 24; + inputs_amount = (input_display_list == -1 || !use_display_list)? ds_list_size(inputs) : array_length(input_display_list); + inputs_index = []; + + for( var i = 0; i < inputs_amount; i++ ) { + var _input = getInputJunctionIndex(i); + if(_input == noone) continue; + + var _inp = inputs[| _input]; + if(!is_struct(_inp) || !is_instanceof(_inp, NodeValue)) continue; + + array_push(inputs_index, _input); + _inp.visible_in_list = true; + } + inputs_amount = array_length(inputs_index); + + outputs_amount = output_display_list == -1? ds_list_size(outputs) : array_length(output_display_list); + outputs_index = array_create_ext(outputs_amount, function(index) { return getOutputJunctionIndex(index); }); + } #endregion + + static setDimension = function(_w = 128, _h = 128, _apply = true) { #region + INLINE + + min_w = _w; + min_h = _h; + + if(_apply) { + w = _w; + h = _h; + } + } #endregion + + static setHeight = function() { #region + w = show_parameter? attributes.node_param_width : min_w; + + if(!auto_height) return; + junction_draw_hei_y = show_parameter? 32 : 24; + junction_draw_pad_y = show_parameter? min_h : 32; + + var _hi = junction_draw_pad_y + show_parameter * 4; + var _ho = junction_draw_pad_y + show_parameter * 4; + + var _prev_surf = previewable && preview_draw && + ( is_surface(getGraphPreviewSurface()) || + (preview_channel >= 0 && preview_channel < ds_list_size(outputs) && outputs[| preview_channel].type == VALUE_TYPE.surface) + ); + + for( var i = 0; i < ds_list_size(inputs); i++ ) { + var _inp = inputs[| i]; + if(is_instanceof(_inp, NodeValue) && _inp.isVisible()) + _hi += junction_draw_hei_y; } - for( var i = 0; i < ds_list_size(outputs); i++ ) { - if(outputs[| i].isVisible()) _ho += 24; - } + for( var i = 0; i < ds_list_size(outputs); i++ ) + if(outputs[| i].isVisible()) _ho += junction_draw_hei_y; - h = max(min_h, (preview_surface && previewable)? 128 : 0, _hi, _ho); - } + h = max(min_h, _prev_surf * 128, _hi, _ho, attributes.node_height); + fix_h = h; + + } #endregion - onSetDisplayName = noone; - static setDisplayName = function(_name) { + static setDisplayName = function(_name) { #region + renamed = true; display_name = _name; internalName = string_replace_all(display_name, " ", "_"); refreshNodeMap(); if(onSetDisplayName != noone) onSetDisplayName(); - } + + return self; + } #endregion - static setIsDynamicInput = function(_data_length = 1) { - is_dynamic_input = true; + static setIsDynamicInput = function(_data_length = 1, _auto_input = true, _dynamic_input_cond = DYNA_INPUT_COND.connection) { #region + is_dynamic_input = true; + auto_input = _auto_input; input_display_len = input_display_list == -1? 0 : array_length(input_display_list); input_fix_len = ds_list_size(inputs); data_length = _data_length; - } + + dynamic_input_cond = _dynamic_input_cond; + } #endregion - static getOutput = function(junc = noone) { + static createNewInput = -1; + + static refreshDynamicInput = function() { #region + var _in = ds_list_create(); + + for( var i = 0; i < input_fix_len; i++ ) + ds_list_add(_in, inputs[| i]); + + array_resize(input_display_list, input_display_len); + + for( var i = input_fix_len; i < ds_list_size(inputs); i += data_length ) { + var _active = false; + if(dynamic_input_cond & DYNA_INPUT_COND.connection) + _active |= inputs[| i].value_from != noone; + if(dynamic_input_cond & DYNA_INPUT_COND.zero) { + var _val = inputs[| i].getValue(); + _active |= _val != 0 || _val != ""; + } + + if(_active) { + for( var j = 0; j < data_length; j++ ) { + ds_list_add(_in, inputs[| i + j]); + array_push(input_display_list, i + j); + } + } else { + for( var j = 0; j < data_length; j++ ) + delete inputs[| i + j]; + } + } + + for( var i = 0; i < ds_list_size(_in); i++ ) + _in[| i].index = i; + + ds_list_destroy(inputs); + inputs = _in; + + createNewInput(); + } #endregion + + static getOutput = function(junc = noone) { #region for( var i = 0; i < ds_list_size(outputs); i++ ) { if(!outputs[| i].visible) continue; if(junc != noone && !junc.isConnectable(outputs[| i], true)) continue; @@ -236,10 +495,10 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x return outputs[| i]; } return noone; - } + } #endregion - static getInput = function(junc = noone) { - for( var i = 0; i < ds_list_size(inputs); i++ ) { + static getInput = function(junc = noone, shift = input_fix_len) { #region + for( var i = shift; i < ds_list_size(inputs); i++ ) { if(!inputs[| i].visible) continue; if(inputs[| i].value_from != noone) continue; if(junc != noone && !inputs[| i].isConnectable(junc, true)) continue; @@ -247,147 +506,181 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x return inputs[| i]; } return noone; - } + } #endregion - static getFullName = function() { - return display_name == ""? name : "[" + name + "] " + display_name; - } + static getFullName = function() { #region + INLINE + return renamed? "[" + name + "] " + display_name : name; + } #endregion - static addInput = function(junctionFrom) { - var targ = getInput(junctionFrom); + static getDisplayName = function() { #region + INLINE + return renamed? display_name : name; + } #endregion + + static addInput = function(junctionFrom, shift = input_fix_len) { #region + var targ = getInput(junctionFrom, shift); if(targ == noone) return; targ.setFrom(junctionFrom); - } + } #endregion - static isAnimated = function() { - for(var i = 0; i < ds_list_size(inputs); i++) { - if(inputs[| i].isAnimated()) - return true; - } + static isActiveDynamic = function(frame = CURRENT_FRAME) { #region + if(update_on_frame) return true; + if(!rendered) return true; + + force_requeue = false; + for(var i = 0; i < ds_list_size(inputs); i++) + if(inputs[| i].isActiveDynamic(frame)) return true; + return false; - } + } #endregion - static isInLoop = function() { + static isInLoop = function() { #region return array_exists(global.loop_nodes, instanceof(group)); - } + } #endregion - static move = function(_x, _y) { + static move = function(_x, _y, _s) { #region if(x == _x && y == _y) return; x = _x; y = _y; if(!LOADING) PROJECT.modified = true; - } + } #endregion - insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); - insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; + #region ++++ inspector update ++++ + static onInspector1Update = noone; + static inspector1Update = function() { INLINE onInspector1Update(); } + static hasInspector1Update = function() { INLINE return NODE_HAS_INSP1; } - static inspector1Update = function() { - if(error_update_enabled && error_noti_update != noone) - noti_remove(error_noti_update); - error_noti_update = noone; - - onInspector1Update(); - } - static onInspector1Update = noone; - static hasInspector1Update = function() { return onInspector1Update != noone; } + static onInspector2Update = noone; + static inspector2Update = function() { INLINE onInspector2Update(); } + static hasInspector2Update = function() { INLINE return NODE_HAS_INSP2; } + #endregion - insp2UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); - insp2UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; - - static inspector2Update = function() { onInspector2Update(); } - static onInspector2Update = noone; - static hasInspector2Update = function() { return onInspector2Update != noone; } - - static stepBegin = function() { + static stepBegin = function() { #region if(use_cache) cacheArrayCheck(); - var willUpdate = false; - - if(PROJECT.animator.frame_progress) { - if(update_on_frame) willUpdate = true; - if(isAnimated()) willUpdate = true; - - if(willUpdate) { - setRenderStatus(false); - UPDATE |= RENDER_TYPE.partial; - } - } - - if(auto_height) - setHeight(); doStepBegin(); - if(hasInspector1Update()) inspectInput1.name = insp1UpdateTooltip; - if(hasInspector2Update()) inspectInput2.name = insp2UpdateTooltip; - } + if(NODE_HAS_INSP1) inspectInput1.name = insp1UpdateTooltip; + if(NODE_HAS_INSP2) inspectInput2.name = insp2UpdateTooltip; + + if(attributes.show_update_trigger) { + if(updatedInTrigger.getValue()) { + getInputs(); + update(); + + updatedInTrigger.setValue(false); + } + updatedOutTrigger.setValue(false); + } + + if(will_setHeight) { + setHeight(); + will_setHeight = false; + } + + if(is_3D) USE_DEPTH = true; + if(is_simulation) PROJECT.animator.is_simulating = true; + } #endregion + static doStepBegin = function() {} - static triggerCheck = function() { - _triggerCheck(); - } - - static _triggerCheck = function() { - for( var i = 0; i < ds_list_size(inputs); i++ ) { - if(inputs[| i].type != VALUE_TYPE.trigger) continue; - if(!is_instanceof(inputs[| i].editWidget, buttonClass)) continue; + static triggerCheck = function() { #region + var i = 0; + + repeat( input_button_length ) { + var _in = input_buttons[i++]; - var trig = inputs[| i].getValue(); - if(trig) { - inputs[| i].editWidget.onClick(); - inputs[| i].setValue(false); + if(_in.getStaticValue()) { + _in.editWidget.onClick(); + _in.setValue(false); } } - if(hasInspector1Update()) { - var trig = inspectInput1.getValue(); - if(trig) { - inspectInput1.editWidget.onClick(); - inspectInput1.setValue(false); - } + if(NODE_HAS_INSP1 && inspectInput1.getStaticValue()) { + onInspector1Update(); + inspectInput1.setValue(false); } - if(hasInspector2Update()) { - var trig = inspectInput2.getValue(); - if(trig) { - inspectInput2.editWidget.onClick(); - inspectInput2.setValue(false); - } + if(NODE_HAS_INSP2 && inspectInput2.getStaticValue()) { + onInspector2Update(); + inspectInput2.setValue(false); } - } + } #endregion static step = function() {} static focusStep = function() {} static inspectorStep = function() {} - static doUpdate = function() { - if(SAFE_MODE) return; - if(NODE_EXTRACT) return; + static getInputData = function(index, def = 0) { #region + INLINE - var sBase = surface_get_target(); - LOG_BLOCK_START(); - LOG_IF(global.FLAG.render, $">>>>>>>>>> DoUpdate called from {internalName} <<<<<<<<<<"); + return array_safe_get_fast(inputs_data, index, def); + } #endregion + + static setInputData = function(index, value) { #region + INLINE - try { - var t = get_timer(); + inputs_data[index] = value; + var _inp = inputs[| index]; + if(is_struct(_inp)) input_value_map[$ _inp.internalName] = value; + } #endregion + + static getInputs = function(frame = CURRENT_FRAME) { #region + inputs_data = array_verify(inputs_data, ds_list_size(inputs)); + + for(var i = 0; i < ds_list_size(inputs); i++) { + if(!is_instanceof(inputs[| i], NodeValue)) continue; - if(!is_instanceof(self, Node_Collection)) - setRenderStatus(true); - - update(); ///UPDATE - - if(!is_instanceof(self, Node_Collection)) - render_time = get_timer() - t; - } catch(exception) { - var sCurr = surface_get_target(); - while(surface_get_target() != sBase) - surface_reset_target(); + var val = inputs[| i].getValue(frame); + setInputData(i, val); + } + } #endregion + + static forceUpdate = function() { #region + input_hash = ""; + doUpdate(); + } #endregion + + static postUpdate = function(frame = CURRENT_FRAME) {} + + static doUpdate = function(frame = CURRENT_FRAME) { #region + if(PROJECT.safeMode) return; + if(NODE_EXTRACT) return; + + var render_timer = get_timer(); + + if(cached_manual || (use_cache == CACHE_USE.auto && recoverCache())) { + render_cached = true; - log_warning("RENDER", exception_print(exception), self); + if(!is_instanceof(self, Node_Collection)) setRenderStatus(true); + } else { + render_cached = false; + getInputs(frame); + + LOG_BLOCK_START(); + LOG_IF(global.FLAG.render == 1, $">>>>>>>>>> DoUpdate called from {INAME} <<<<<<<<<<"); + + if(!is_instanceof(self, Node_Collection)) setRenderStatus(true); + var sBase = surface_get_target(); + + try { + update(frame); + } catch(exception) { + var sCurr = surface_get_target(); + while(surface_get_target() != sBase) + surface_reset_target(); + + log_warning("RENDER", exception_print(exception), self); + } } - if(!use_cache && PROJECT.onion_skin) { + postUpdate(frame); + cached_manual = false; + + if(!use_cache && PROJECT.onion_skin.enabled) { for( var i = 0; i < ds_list_size(outputs); i++ ) { if(outputs[| i].type != VALUE_TYPE.surface) continue; cacheCurrentFrame(outputs[| i].getValue()); @@ -395,39 +688,53 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x } } - if(hasInspector1Update()) { - var trigger = inspectInput1.getValue(); - if(trigger) onInspector1Update(); - } + if(NODE_HAS_INSP1 && inspectInput1.getValue()) onInspector1Update(); + if(NODE_HAS_INSP2 && inspectInput2.getValue()) onInspector2Update(); - if(hasInspector2Update()) { - var trigger = inspectInput2.getValue(); - if(trigger) onInspector2Update(); - } + updatedOutTrigger.setValue(true); + + if(!is_instanceof(self, Node_Collection)) + render_time = get_timer() - render_timer; + + refreshNodeDisplay(); LOG_BLOCK_END(); - } + } #endregion - static valueUpdate = function(index) { - if(error_update_enabled && error_noti_update == noone) - error_noti_update = noti_error(getFullName() + " node require manual execution.",, self); + static cacheCheck = function() { #region + INLINE + + if(cache_group) cache_group.enableNodeGroup(); + if(group != noone) group.cacheCheck(); + } #endregion + + static valueUpdate = function(index) { #region onValueUpdate(index); - } + + if(is_dynamic_input) will_setHeight = true; + cacheCheck(); + } #endregion + + static valueFromUpdate = function(index) { #region + onValueFromUpdate(index); + + if(is_dynamic_input) will_setHeight = true; + cacheCheck(); + } #endregion static onValueUpdate = function(index = 0) {} static onValueFromUpdate = function(index) {} - static triggerRender = function() { + static triggerRender = function() { #region LOG_BLOCK_START(); - LOG_IF(global.FLAG.render, $"Trigger render for {internalName}"); + LOG_IF(global.FLAG.render == 1, $"Trigger render for {self}"); - setRenderStatus(false); - UPDATE |= RENDER_TYPE.partial; + resetRender(false); + RENDER_PARTIAL - if(is_instanceof(group, Node_Collection) && group.reset_all_child) { - group.resetRender(); + if(is_instanceof(group, Node_Collection)) { + group.triggerRender(); } else { - resetRender(); var nodes = getNextNodesRaw(); for(var i = 0; i < array_length(nodes); i++) @@ -435,291 +742,582 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x } LOG_BLOCK_END(); - } + } #endregion - static resetRender = function() { setRenderStatus(false); } - static isRenderActive = function() { return renderActive || (PREF_MAP[? "render_all_export"] && PROJECT.animator.rendering); } + static clearTopoSorted = function() { INLINE topoSorted = false; } - static isRenderable = function(log = false) { //Check if every input is ready (updated) - if(!active) return false; - if(!isRenderActive()) return false; + static forwardPassiveDynamic = function() { #region + rendered = false; - //if(group && struct_has(group, "iterationStatus") && group.iterationStatus() == ITERATION_STATUS.complete) return false; - - for(var j = 0; j < ds_list_size(inputs); j++) { - var _in = inputs[| j]; - if( _in.type == VALUE_TYPE.node) continue; + for( var i = 0, n = ds_list_size(outputs); i < n; i++ ) { + var _outp = outputs[| i]; - var val_from = _in.value_from; - if( val_from == noone) continue; - if(!val_from.node.active) continue; - if(!val_from.node.isRenderActive()) continue; - if!(val_from.node.rendered || val_from.node.update_on_frame) { - LOG_LINE_IF(global.FLAG.render, $"Node {internalName} is not renderable because input {val_from.node.internalName} is not rendered ({val_from.node.rendered})"); - return false; + for(var j = 0; j < array_length(_outp.value_to); j++) { + var _to = _outp.value_to[j]; + if(!_to.node.active || _to.value_from != _outp) continue; + + //LOG_IF(global.FLAG.render == 1, $"|| Forwarding dynamic to {_to.node.name} ||"); + _to.node.passiveDynamic = true; + _to.node.rendered = false; } } + } #endregion + + static resetRender = function(_clearCache = false) { #region + setRenderStatus(false); + if(_clearCache) clearInputCache(); + } #endregion + + static isLeaf = function() { #region + INLINE + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _inp = inputs[| i]; + if(!_inp.isLeaf()) return false; + } return true; - } + } #endregion - static getNextNodesRaw = function() { return getNextNodes(); } + static isLeafList = function(list = noone) { #region + INLINE + + if(list == noone) return isLeaf(); + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _inp = inputs[| i]; + if(!_inp.isLeafList(list)) return false; + } + + return true; + } #endregion - static getNextNodes = function() { + static isRenderActive = function() { return renderActive || (PREFERENCES.render_all_export && IS_RENDERING); } + + static isRenderable = function(log = false) { #region //Check if every input is ready (updated) + if(!active) return false; + if(!isRenderActive()) return false; + + for(var j = 0; j < ds_list_size(inputs); j++) + if(!inputs[| j].isRendered()) return false; + + return true; + } #endregion + + static setRenderStatus = function(result) { #region + INLINE + + if(rendered == result) return; + LOG_LINE_IF(global.FLAG.render == 1, $"Set render status for {self} : {result}"); + + rendered = result; + } #endregion + + static getPreviousNodes = function() { #region + var prev = []; + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _in = inputs[| i]; + + if(_in.value_from != noone) { + if(in_VFX && !_in.value_from.node.in_VFX) { + array_push(in_VFX.prev_nodes, _in.value_from.node); + array_push(prev, in_VFX); + continue; + } + + array_push_unique(prev, _in.value_from.node); + } + + if(_in.value_from_loop != noone) + array_push_unique(prev, _in.value_from_loop); + } + + onGetPreviousNodes(prev); + return prev; + } #endregion + + static onGetPreviousNodes = function(arr) {} + + static getNextNodes = function() { #region var nodes = []; var nodeNames = []; LOG_BLOCK_START(); - LOG_IF(global.FLAG.render, $"→→→→→ Call get next node from: {internalName}"); + LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from: {INAME}"); LOG_BLOCK_START(); for(var i = 0; i < ds_list_size(outputs); i++) { var _ot = outputs[| i]; - if(!_ot.forward) continue; + if(!_ot.forward) continue; + for( var j = 0, n = array_length(_ot.value_to_loop); j < n; j++ ) { + var _to = _ot.value_to_loop[j]; + if(!_to.active) continue; + if(!_to.bypassNextNode()) continue; + + LOG_BLOCK_END(); + LOG_BLOCK_END(); + + return _to.getNextNodes(); + } + var _tos = _ot.getJunctionTo(); - for( var j = 0; j < array_length(_tos); j++ ) { var _to = _tos[j]; array_push(nodes, _to.node); array_push(nodeNames, _to.node.internalName); - //LOG_IF(global.FLAG.render, $"→→ Check output: {_ot.name} connect to node {_to.node.internalName}"); + //LOG_IF(global.FLAG.render == 1, $"→→ Check output: {_ot.name} connect to node {_to.node.internalName}"); } } - LOG_IF(global.FLAG.render, $"→→ Push {nodeNames} to stack."); + LOG_IF(global.FLAG.render == 1, $"→→ Push {nodeNames} to queue."); LOG_BLOCK_END(); LOG_BLOCK_END(); return nodes; - } + } #endregion - static isTerminal = function() { + static getNextNodesRaw = function() { #region + var nodes = []; + + for(var i = 0; i < ds_list_size(outputs); i++) { + var _ot = outputs[| i]; + if(!_ot.forward) continue; + if(_ot.type == VALUE_TYPE.node) continue; + + for( var j = 0, n = array_length(_ot.value_to_loop); j < n; j++ ) { + var _to = _ot.value_to_loop[j]; + if(!_to.active) continue; + if(!_to.bypassNextNode()) continue; + + return _to.getNextNodes(); + } + + var _tos = _ot.getJunctionTo(); + for( var j = 0; j < array_length(_tos); j++ ) + array_push(nodes, _tos[j].node); + } + + return nodes; + } #endregion + + static isTerminal = function() { #region for( var i = 0; i < ds_list_size(outputs); i++ ) { var _to = outputs[| i].getJunctionTo(); if(array_length(_to)) return false; } return true; - } + } #endregion static onInspect = function() {} - static setRenderStatus = function(result) { - LOG_LINE_IF(global.FLAG.render, $"Set render status for {internalName} : {result}"); - - rendered = result; - } - - static pointIn = function(_x, _y, _mx, _my, _s) { + static pointIn = function(_x, _y, _mx, _my, _s) { #region var xx = x * _s + _x; var yy = y * _s + _y; return point_in_rectangle(_mx, _my, xx, yy, xx + w * _s, yy + h * _s); - } + } #endregion - draw_graph_culled = false; - static cullCheck = function(_x, _y, _s, minx, miny, maxx, maxy) { + static cullCheck = function(_x, _y, _s, minx, miny, maxx, maxy) { #region var x0 = x * _s + _x; var y0 = y * _s + _y; var x1 = (x + w) * _s + _x; var y1 = (y + h) * _s + _y; + draw_boundary[0] = minx; + draw_boundary[1] = miny; + draw_boundary[2] = maxx; + draw_boundary[3] = maxy; + draw_graph_culled = !rectangle_in_rectangle(minx, miny, maxx, maxy, x0, y0, x1, y1); - } + } #endregion - static preDraw = function(_x, _y, _s) { + static refreshNodeDisplay = function() { #region + INLINE + + updateIO(); + setHeight(); + getJunctionList(); + } run_in(1, function() { refreshNodeDisplay(); }); #endregion + + static getJunctionList = function() { #region + var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list); + inputDisplayList = []; + + for(var i = 0; i < amo; i++) { + var ind = getInputJunctionIndex(i); + if(ind == noone) continue; + + var jun = ds_list_get(inputs, ind, noone); + if(jun == noone || is_undefined(jun)) continue; + if(!jun.isVisible()) continue; + + array_push(inputDisplayList, jun); + } + }#endregion + + static preDraw = function(_x, _y, _s) { #region var xx = x * _s + _x; var yy = y * _s + _y; var jun; - var inspCount = hasInspector1Update() + hasInspector2Update(); + var inspCount = NODE_HAS_INSP1 + NODE_HAS_INSP2; var ind = 1; - if(hasInspector1Update()) { + if(NODE_HAS_INSP1) { inspectInput1.x = xx + w * _s * ind / (inspCount + 1); inspectInput1.y = yy; ind++; } - if(hasInspector2Update()) { + if(NODE_HAS_INSP2) { inspectInput2.x = xx + w * _s * ind / (inspCount + 1); inspectInput2.y = yy; ind++; } - var inamo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list); - var _in = yy + ui(32) * _s; + updatedInTrigger.x = xx; + updatedInTrigger.y = yy + 10; - for(var i = 0; i < inamo; i++) { - var idx = getInputJunctionIndex(i); - if(idx == noone) continue; + updatedOutTrigger.x = xx + w * _s; + updatedOutTrigger.y = yy + 10; + + if(in_cache_len != array_length(inputDisplayList) || out_cache_len != ds_list_size(outputs)) { + refreshNodeDisplay(); - jun = ds_list_get(inputs, idx, noone); - if(jun == noone || is_undefined(jun)) continue; + in_cache_len = array_length(inputDisplayList); + out_cache_len = ds_list_size(outputs); + } + + var _iny = yy + (junction_draw_pad_y + junction_draw_hei_y * 0.5 * show_parameter) * _s; + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + jun = inputs[| i]; jun.x = xx; - jun.y = _in; - _in += 24 * _s * jun.isVisible(); + jun.y = _iny; } - var outamo = output_display_list == -1? ds_list_size(outputs) : array_length(output_display_list); + for(var i = 0; i < in_cache_len; i++) { + jun = inputDisplayList[i]; + + jun.x = xx; + jun.y = _iny; + _iny += junction_draw_hei_y * _s; + } - xx = xx + w * _s; - _in = yy + ui(32) * _s; - for(var i = 0; i < outamo; i++) { - var idx = getOutputJunctionIndex(i); + xx = xx + w * _s; + var _outy = yy + (junction_draw_pad_y + junction_draw_hei_y * 0.5 * show_parameter) * _s; + + for(var i = 0; i < outputs_amount; i++) { + var idx = outputs_index[i]; jun = outputs[| idx]; jun.x = xx; - jun.y = _in; - _in += 24 * _s * jun.isVisible(); + jun.y = _outy; + _outy += junction_draw_hei_y * _s * jun.isVisible(); } - } + + onPreDraw(_x, _y, _s, _iny, _outy); + } #endregion - static drawNodeBase = function(xx, yy, _s) { + static onPreDraw = function(_x, _y, _s, _iny, _outy) {} + + static isHighlightingInGraph = function() { #region + var high = display_parameter.highlight; + var _selc = active_draw_index == 0 || branch_drawing; + return !high || _selc; + } #endregion + + static getColor = function() { #region + INLINE + return attributes.color == -1? color : attributes.color; + } #endregion + + static drawNodeBase = function(xx, yy, _s) { #region if(draw_graph_culled) return; if(!active) return; + var aa = 0.25 + 0.5 * renderActive; - draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, color, aa); - } - - static drawGetBbox = function(xx, yy, _s) { - var x0 = xx + draw_padding * _s; - var x1 = xx + (w - draw_padding) * _s; - var y0 = yy + 20 * draw_name + draw_padding * _s; - var y1 = yy + (h - draw_padding) * _s; + if(!isHighlightingInGraph()) aa *= 0.25; + var cc = getColor(); - return BBOX().fromPoints(x0, y0, x1, y1); - } + draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, cc, aa); + } #endregion - static drawNodeName = function(xx, yy, _s) { - if(draw_graph_culled) return; - if(!active) return; + __draw_bbox = BBOX(); + static drawGetBbox = function(xx, yy, _s) { #region + var pad_label = draw_name && display_parameter.avoid_label; - draw_name = false; - var _name = display_name == ""? name : display_name; + var _w = w; + var _h = show_parameter? min_h : h; + + _w *= _s; + _h *= _s; + + _w -= draw_padding * 2; + _h -= draw_padding * 2 + 20 * pad_label; + + var _xc = xx + w * _s / 2; + var _yc = yy + _h / 2 + pad_label * 20 + draw_padding; + + _w *= display_parameter.preview_scale / 100; + _h *= display_parameter.preview_scale / 100; + + var x0 = _xc - _w / 2; + var x1 = _xc + _w / 2; + var y0 = _yc - _h / 2; + var y1 = _yc + _h / 2; + + return __draw_bbox.fromPoints(x0, y0, x1, y1); + } #endregion + + static drawNodeName = function(xx, yy, _s) { #region + + var _name = renamed? display_name : name; if(_name == "") return; - if(_s < 0.75) return; + draw_name = true; var aa = 0.25 + 0.5 * renderActive; - draw_sprite_stretched_ext(THEME.node_bg_name, 0, xx, yy, w * _s, ui(20), color, aa); + if(!isHighlightingInGraph()) aa *= 0.25; + var cc = getColor(); + + draw_sprite_stretched_ext(THEME.node_bg_name, 0, xx, yy, w * _s, ui(20), cc, aa); var cc = COLORS._main_text; - if(PREF_MAP[? "node_show_render_status"] && !rendered) + if(PREFERENCES.node_show_render_status && !rendered) cc = isRenderable()? COLORS._main_value_positive : COLORS._main_value_negative; draw_set_text(f_p1, fa_left, fa_center, cc); - if(hasInspector1Update()) icon = THEME.refresh_s; + if(NODE_HAS_INSP1) icon = THEME.refresh_16; var ts = clamp(power(_s, 0.5), 0.5, 1); var aa = 0.5 + 0.5 * renderActive; + if(!isHighlightingInGraph()) aa *= 0.25; + draw_set_alpha(aa); if(icon && _s > 0.75) { draw_sprite_ui_uniform(icon, 0, xx + ui(12), yy + ui(10),,, aa); - draw_text_cut(xx + ui(24), yy + ui(10), _name, w * _s - ui(24), ts); + draw_text_cut(round(xx + ui(24)), round(yy + ui(10)), _name, w * _s - ui(24), ts); } else - draw_text_cut(xx + ui(8), yy + ui(10), _name, w * _s - ui(8), ts); + draw_text_cut(round(xx + ui(8)), round(yy + ui(10)), _name, w * _s - ui(8), ts); draw_set_alpha(1); - } + } #endregion - static drawJunctions = function(_x, _y, _mx, _my, _s) { + static drawJunctionWidget = function(_x, _y, _mx, _my, _s, _hover, _focus) { #region + + var hover = noone; + + var wh = junction_draw_hei_y * _s; + var ww = w * _s * 0.5; + var wt = w * _s * 0.25; + var wx = _x + w * _s - ww - 8; + var lx = _x + 12 * _s; + + var _m = [ _mx, _my ]; + var rx = PANEL_GRAPH.x; + var ry = PANEL_GRAPH.y; + + var jy = _y + junction_draw_pad_y * _s + wh / 2; + + var boundH = _x > draw_boundary[0] - w * _s && _x < draw_boundary[2]; + var boundV = 1;//_y > draw_boundary[1] - h * _s && _y < draw_boundary[3]; + var extY = 0; + var drawText = _s > 0.5; + + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; + var wd = jun.graphWidget; + + jun.y = jy; + + if(drawText) { + draw_set_text(f_sdf, fa_left, fa_center, jun.color_display); + draw_text_add(lx, jun.y, jun.getName(), _s * 0.25); + + } else { + draw_set_color(jun.color_display); + draw_rectangle(lx, jun.y - 1 * _s, lx + wt, jun.y + 4 * _s, false); + } + + if(jun.value_from || wd == noone) { + jy += wh; + continue; + } + + var _param = jun.graphWidgetP; + + _param.w = ww; + _param.h = wh - 4 * _s; + _param.x = wx; + _param.y = jy - _param.h / 2; + + _param.data = jun.showValue(); + _param.m = _m; + _param.rx = rx; + _param.ry = ry; + _param.s = wh; + _param.font = f_p2; + + if(is_instanceof(jun, checkBox)) + _param.halign = fa_center; + + wd.setInteract(wh > line_get_height(f_p2)); + wd.setFocusHover(_focus, _hover); + var _h = wd.drawParam(_param); + jun.graphWidgetH = _h / _s; + + extY += max(0, (jun.graphWidgetH + 4) - junction_draw_hei_y); + + if(wd.isHovering()) draggable = false; + + jy += (jun.graphWidgetH + 4) * _s; + } + + h = fix_h + extY; + } #endregion + + static drawJunctions = function(_x, _y, _mx, _my, _s) { #region if(!active) return; var hover = noone; - var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list); - var jun; - for(var i = 0; i < amo; i++) { - var ind = getInputJunctionIndex(i); - if(ind == noone) continue; - jun = ds_list_get(inputs, ind, noone); - if(jun == noone || is_undefined(jun)) continue; + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; if(jun.drawJunction(_s, _mx, _my)) hover = jun; } for(var i = 0; i < ds_list_size(outputs); i++) { - jun = outputs[| i]; + var jun = outputs[| i]; + if(!jun.isVisible()) continue; if(jun.drawJunction(_s, _mx, _my)) hover = jun; } - if(hasInspector1Update() && inspectInput1.drawJunction(_s, _mx, _my)) + if(NODE_HAS_INSP1 && inspectInput1.drawJunction(_s, _mx, _my)) hover = inspectInput1; - if(hasInspector2Update() && inspectInput2.drawJunction(_s, _mx, _my)) + if(NODE_HAS_INSP2 && inspectInput2.drawJunction(_s, _mx, _my)) hover = inspectInput2; + if(attributes.show_update_trigger) { + if(updatedInTrigger.drawJunction(_s, _mx, _my)) hover = updatedInTrigger; + if(updatedOutTrigger.drawJunction(_s, _mx, _my)) hover = updatedOutTrigger; + } + + onDrawJunctions(_x, _y, _mx, _my, _s); + return hover; - } + } #endregion - static drawJunctionNames = function(_x, _y, _mx, _my, _s) { + static drawJunctions_fast = function(_x, _y, _mx, _my, _s) { #region + if(!active) return; + var hover = noone; + + _s = _s * 6; + + draw_set_circle_precision(4); + + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; + + if(jun.drawJunction_fast(_s, _mx, _my)) + hover = jun; + } + + for(var i = 0; i < ds_list_size(outputs); i++) { + var jun = outputs[| i]; + + if(jun.drawJunction_fast(_s, _mx, _my)) + hover = jun; + } + + if(NODE_HAS_INSP1 && inspectInput1.drawJunction_fast(_s, _mx, _my)) + hover = inspectInput1; + + if(NODE_HAS_INSP2 && inspectInput2.drawJunction_fast(_s, _mx, _my)) + hover = inspectInput2; + + if(attributes.show_update_trigger) { + if(updatedInTrigger.drawJunction_fast(_s, _mx, _my)) hover = updatedInTrigger; + if(updatedOutTrigger.drawJunction_fast(_s, _mx, _my)) hover = updatedOutTrigger; + } + + onDrawJunctions(_x, _y, _mx, _my, _s / 6); + + return hover; + } #endregion + + static onDrawJunctions = function(_x, _y, _mx, _my, _s) {} + + static drawJunctionNames = function(_x, _y, _mx, _my, _s) { #region if(draw_graph_culled) return; if(!active) return; + var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list); var jun; var xx = x * _s + _x; var yy = y * _s + _y; - show_input_name = PANEL_GRAPH.pHOVER && point_in_rectangle(_mx, _my, xx - 8 * _s, yy + 20 * _s, xx + 8 * _s, yy + h * _s); - show_output_name = PANEL_GRAPH.pHOVER && point_in_rectangle(_mx, _my, xx + (w - 8) * _s, yy + 20 * _s, xx + (w + 8) * _s, yy + h * _s); + var _hov = PANEL_GRAPH.pHOVER && (PANEL_GRAPH.node_hovering == noone || PANEL_GRAPH.node_hovering == self); + show_input_name = _hov && point_in_rectangle(_mx, _my, xx - 8 * _s, yy + 20 * _s, xx + 8 * _s, yy + h * _s); + show_output_name = _hov && point_in_rectangle(_mx, _my, xx + (w - 8) * _s, yy + 20 * _s, xx + (w + 8) * _s, yy + h * _s); if(show_input_name) { - for(var i = 0; i < amo; i++) { - var ind = getInputJunctionIndex(i); - if(ind == noone) continue; - if(!inputs[| ind]) continue; - - inputs[| ind].drawNameBG(_s); + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; + jun.drawNameBG(_s); } - for(var i = 0; i < amo; i++) { - var ind = getInputJunctionIndex(i); - if(ind == noone) continue; - if(!inputs[| ind]) continue; - - inputs[| ind].drawName(_s, _mx, _my); + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; + jun.drawName(_s, _mx, _my); } } if(show_output_name) { for(var i = 0; i < ds_list_size(outputs); i++) - outputs[| i].drawNameBG(_s); + if(outputs[| i].visible) outputs[| i].drawNameBG(_s); for(var i = 0; i < ds_list_size(outputs); i++) - outputs[| i].drawName(_s, _mx, _my); + if(outputs[| i].visible) outputs[| i].drawName(_s, _mx, _my); } - if(hasInspector1Update() && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput1.x, inspectInput1.y, 10)) { + if(NODE_HAS_INSP1 && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput1.x, inspectInput1.y, 10)) { inspectInput1.drawNameBG(_s); inspectInput1.drawName(_s, _mx, _my); } - if(hasInspector2Update() && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput2.x, inspectInput2.y, 10)) { + if(NODE_HAS_INSP2 && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput2.x, inspectInput2.y, 10)) { inspectInput2.drawNameBG(_s); inspectInput2.drawName(_s, _mx, _my); } - } + } #endregion - static drawConnections = function(_x, _y, _s, mx, my, _active, aa = 1, minx = undefined, miny = undefined, maxx = undefined, maxy = undefined) { + static drawConnections = function(params = {}) { #region if(!active) return; var hovering = noone; var drawLineIndex = 1; + var high = params.highlight; // 0 + var bg = params.bg; // 0 + for(var i = 0; i < ds_list_size(outputs); i++) { var jun = outputs[| i]; var connected = false; - for( var j = 0; j < ds_list_size(jun.value_to); j++ ) { - if(jun.value_to[| j].value_from == jun) + for( var j = 0; j < array_length(jun.value_to); j++ ) { + if(jun.value_to[j].value_from == jun) connected = true; } @@ -727,13 +1325,24 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x jun.drawLineIndex = drawLineIndex; drawLineIndex += 0.5; } + + if(high) { + jun.draw_blend_color = bg; + jun.draw_blend = PREFERENCES.connection_line_highlight_fade; + } else { + jun.draw_blend_color = bg; + jun.draw_blend = -1; + } + } var st = 0; - if(hasInspector1Update()) st = -1; - if(hasInspector2Update()) st = -2; + if(NODE_HAS_INSP1) st = -1; + if(NODE_HAS_INSP2) st = -2; + + var _inputs = array_create(ds_list_size(inputs)); + var _len = 0; - var _inputs = []; var drawLineIndex = 1; for(var i = st; i < ds_list_size(inputs); i++) { var jun; @@ -741,39 +1350,64 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x else if(i == -2) jun = inspectInput2; else jun = inputs[| i]; - if(jun.value_from == noone) continue; + if(high) { + jun.draw_blend_color = bg; + jun.draw_blend = PREFERENCES.connection_line_highlight_fade; + } else { + jun.draw_blend_color = bg; + jun.draw_blend = -1; + } + + if(jun.isLeaf()) continue; if(!jun.value_from.node.active) continue; if(!jun.isVisible()) continue; - if(i >= 0) - array_push(_inputs, jun); + if(i >= 0) _inputs[_len++] = jun; } - var len = array_length(_inputs); - for( var i = 0; i < len; i++ ) - _inputs[i].drawLineIndex = 1 + (i > len / 2? (len - 1 - i) : i) * 0.5; - - for(var i = st; i < ds_list_size(inputs); i++) { - var jun; - if(i == -1) jun = inspectInput1; - else if(i == -2) jun = inspectInput2; - else jun = inputs[| i]; + for( var i = 0; i < _len; i++ ) { + var jun = _inputs[i]; - var hov = jun.drawConnections(_x, _y, _s, mx, my, _active, aa, minx, miny, maxx, maxy); + jun.drawLineIndex = 1 + (i > _len / 2? (_len - 1 - i) : i) * 0.5; + var hov = jun.drawConnections(params); if(hov) hovering = hov; } + if(attributes.show_update_trigger) { + if(updatedInTrigger.drawConnections(params)) hovering = updatedInTrigger; + if(updatedOutTrigger.drawConnections(params)) hovering = updatedOutTrigger; + } + return hovering; - } + } #endregion - static drawPreview = function(xx, yy, _s) { - if(draw_graph_culled) return; - if(!active) return; - + static getGraphPreviewSurface = function() { #region var _node = outputs[| preview_channel]; - if(_node.type != VALUE_TYPE.surface) return; + if(!is_instanceof(_node, NodeValue)) return noone; + + switch(_node.type) { + case VALUE_TYPE.surface : + case VALUE_TYPE.dynaSurface : + var val = _node.showValue(); + return val; + } + + return noone; + } #endregion + + __preview_surf = false; + __preview_sw = noone; + __preview_sh = noone; + + static setPreview = function(_surf) { #region + preview_surface = _surf; + __preview_surf = is_surface(_surf); + } #endregion + + static drawPreview = function(xx, yy, _s) { #region + var surf = getGraphPreviewSurface(); + if(surf == noone) return; - var surf = _node.getValue(); preview_amount = 0; if(is_array(surf)) { if(array_length(surf) == 0) return; @@ -789,148 +1423,146 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x surf = surf[preview_index]; } - preview_surface = is_surface(surf)? surf : noone; - if(preview_surface == noone) return; + setPreview(surf); + if(!__preview_surf) return; - var pw = surface_get_width(preview_surface); - var ph = surface_get_height(preview_surface); - var ps = min((w * _s - 8) / pw, (h * _s - 8) / ph); - var px = xx + w * _s / 2 - pw * ps / 2; - var py = yy + h * _s / 2 - ph * ps / 2; - var aa = 0.5 + 0.5 * renderActive; + __preview_sw = surface_get_width_safe(preview_surface); + __preview_sh = surface_get_height_safe(preview_surface); - if(preview_trans == 1) { - draw_surface_ext_safe(preview_surface, px, py, ps, ps, 0, c_white, aa); - return; - } + var bbox = drawGetBbox(xx, yy, _s); + var aa = 0.5 + 0.5 * renderActive; + if(!isHighlightingInGraph()) aa *= 0.25; - if(preview_trans < 1 && is_surface(preview_surface_prev)) { - preview_trans = lerp_float(preview_trans, 1, 8); - var _pw = surface_get_width(preview_surface_prev); - var _ph = surface_get_height(preview_surface_prev); - var _ps = min((w * _s - 8) / _pw, (h * _s - 8) / _ph); - var _px = xx + w * _s / 2 - _pw * _ps / 2; - var _py = yy + h * _s / 2 - _ph * _ps / 2; - - draw_surface_ext_safe(preview_surface_prev, _px, _py, _ps, _ps, 0, c_white, aa); - - shader_set(sh_trans_node_prev_drop); - shader_set_f("dimension", _pw, _ph); - shader_set_f("position", (preview_drop_x - px) / (_pw * _ps), (preview_drop_y - py) / (_ph * _ps)); - shader_set_f("prog", preview_trans); - draw_surface_ext_safe(preview_surface, px, py, ps, ps, 0, c_white, aa); - shader_reset(); - } else if(is_surface(preview_surface_prev)) - surface_free(preview_surface_prev); - } + var _sw = __preview_sw; + var _sh = __preview_sh; + var _ss = min(bbox.w / _sw, bbox.h / _sh); + draw_surface_ext_safe(preview_surface, bbox.xc - _sw * _ss / 2, bbox.yc - _sh * _ss / 2, _ss, _ss); + } #endregion - static previewDropAnimation = function() { - preview_surface_prev = surface_clone(preview_surface); - preview_trans = 0; - preview_drop_x = preview_mx; - preview_drop_y = preview_my; - } - - static getNodeDimension = function(showFormat = true) { - if(!is_surface(preview_surface)) { - if(ds_list_size(outputs)) - return "[" + array_shape(outputs[| 0].getValue()) + "]"; - return ""; - } + static getNodeDimension = function(showFormat = true) { #region + if(!__preview_surf) return preview_array; - var pw = surface_get_width(preview_surface); - var ph = surface_get_height(preview_surface); - var format = surface_get_format(preview_surface); + var pw = surface_get_width_safe(preview_surface); + var ph = surface_get_height_safe(preview_surface); + var format = surface_get_format_safe(preview_surface); - var txt = "[" + string(pw) + " x " + string(ph) + " "; - if(preview_amount) txt = string(preview_amount) + " x " + txt; + var txt = $"[{pw} x {ph}"; + if(preview_amount) txt = $"{preview_amount} x {txt}"; switch(format) { - case surface_rgba4unorm : txt += showFormat? "4RGBA" : "4R"; break; - case surface_rgba8unorm : txt += showFormat? "8RGBA" : "8R"; break; - case surface_rgba16float : txt += showFormat? "16RGBA" : "16R"; break; - case surface_rgba32float : txt += showFormat? "32RGBA" : "32R"; break; - case surface_r8unorm : txt += showFormat? "8BW" : "8B"; break; - case surface_r16float : txt += showFormat? "16BW" : "16B"; break; - case surface_r32float : txt += showFormat? "32BW" : "32B"; break; + case surface_rgba8unorm : break; + case surface_rgba4unorm : txt += showFormat? " 4RGBA" : " 4R"; break; + case surface_rgba16float : txt += showFormat? " 16RGBA" : " 16R"; break; + case surface_rgba32float : txt += showFormat? " 32RGBA" : " 32R"; break; + case surface_r8unorm : txt += showFormat? " 8BW" : " 8B"; break; + case surface_r16float : txt += showFormat? " 16BW" : " 16B"; break; + case surface_r32float : txt += showFormat? " 32BW" : " 32B"; break; } txt += "]"; return txt; - } + } #endregion - static drawDimension = function(xx, yy, _s) { + static drawDimension = function(xx, yy, _s) { #region if(draw_graph_culled) return; if(!active) return; if(_s * w < 64) return; - draw_set_text(f_p2, fa_center, fa_top, COLORS.panel_graph_node_dimension); + draw_set_text(f_p3, fa_center, fa_top, COLORS.panel_graph_node_dimension); var tx = xx + w * _s / 2; var ty = yy + (h + 4) * _s - 2; - if(PANEL_GRAPH.show_dimension) { + if(struct_get(display_parameter, "show_dimension")) { var txt = string(getNodeDimension(_s > 0.65)); draw_text(round(tx), round(ty), txt); ty += string_height(txt) - 2; } - draw_set_font(f_p3); - - if(PANEL_GRAPH.show_compute) { - var rt, unit; - if(render_time < 1000) { + if(struct_get(display_parameter, "show_compute")) { + var rt = 0, unit = ""; + + if(render_time == 0) { + draw_set_color(COLORS._main_text_sub); + unit = "us"; + + } else if(render_time < 1000) { rt = round(render_time / 10) * 10; unit = "us"; draw_set_color(COLORS.speed[2]); + } else if(render_time < 1000000) { rt = string_format(render_time / 1000, -1, 2); unit = "ms"; draw_set_color(COLORS.speed[1]); + } else { rt = string_format(render_time / 1000000, -1, 2); unit = "s"; draw_set_color(COLORS.speed[0]); } - draw_text(round(tx), round(ty), string(rt) + " " + unit); + + if(render_cached) draw_set_color(COLORS._main_text_sub); + + draw_text(round(tx), round(ty), $"{rt} {unit}"); } - } + } #endregion - static drawNode = function(_x, _y, _mx, _my, _s) { + static groupCheck = function(_x, _y, _s, _mx, _my) {} + + static drawNodeBG = function(_x, _y, _mx, _my, _s, display_parameter = noone) { return false; } + + static drawNode = function(_x, _y, _mx, _my, _s, display_parameter = noone) { #region if(draw_graph_culled) return; if(!active) return; + if(display_parameter != noone) + self.display_parameter = display_parameter; + var xx = x * _s + _x; var yy = y * _s + _y; preview_mx = _mx; preview_my = _my; - if(value_validation[VALIDATION.error] || error_noti_update != noone) - draw_sprite_stretched_ext(THEME.node_glow, 0, xx - 9, yy - 9, w * _s + 18, h * _s + 18, COLORS._main_value_negative, 1); + if(value_validation[VALIDATION.error]) + draw_sprite_stretched_ext(THEME.node_glow_border, 0, xx - 9, yy - 9, w * _s + 18, h * _s + 18, COLORS._main_value_negative, 1); drawNodeBase(xx, yy, _s); - if(previewable && ds_list_size(outputs) > 0) { - if(preview_channel >= ds_list_size(outputs)) - preview_channel = 0; - drawPreview(xx, yy, _s); - } drawDimension(xx, yy, _s); - onDrawNode(xx, yy, _mx, _my, _s, PANEL_GRAPH.node_hovering == self, PANEL_GRAPH.node_focus == self); - drawNodeName(xx, yy, _s); + draggable = true; + + if(previewable) { + if(preview_draw) drawPreview(xx, yy, _s); + + try { + var _hover = PANEL_GRAPH.node_hovering == self; + var _focus = PANEL_GRAPH.getFocusingNode() == self; + + onDrawNode(xx, yy, _mx, _my, _s, _hover, _focus); + } + catch(e) { log_warning("NODE onDrawNode", exception_print(e)); } + } + + if(show_parameter) + drawJunctionWidget(xx, yy, _mx, _my, _s, _hover, _focus); + + draw_name = false; + if(_s >= 0.75) drawNodeName(xx, yy, _s); if(active_draw_index > -1) { draw_sprite_stretched_ext(bg_sel_spr, 0, xx, yy, round(w * _s), round(h * _s), active_draw_index > 1? COLORS.node_border_file_drop : COLORS._main_accent, 1); active_draw_index = -1; } - if(draw_droppable) + if(draw_droppable) { draw_sprite_stretched_ext(THEME.ui_panel_active, 0, xx, yy, w * _s, h * _s, COLORS._main_value_positive, 1); - draw_droppable = false; + draw_droppable = false; + } - return drawJunctions(xx, yy, _mx, _my, _s); - } + return _s > 0.5? drawJunctions(xx, yy, _mx, _my, _s) : drawJunctions_fast(xx, yy, _mx, _my, _s); + } #endregion static onDrawNodeBehind = function(_x, _y, _mx, _my, _s) {} @@ -938,9 +1570,9 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x static onDrawHover = function(_x, _y, _mx, _my, _s) {} - badgePreview = 0; - badgeInspect = 0; - static drawBadge = function(_x, _y, _s) { + static drawPreviewBackground = function(_x, _y, _mx, _my, _s) { return false; } + + static drawBadge = function(_x, _y, _s) { #region if(!active) return; var xx = x * _s + _x + w * _s; var yy = y * _s + _y; @@ -949,7 +1581,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x badgeInspect = lerp_float(badgeInspect, inspecting, 2); if(badgePreview > 0) { - draw_sprite_ext(THEME.node_state, 0, xx, yy, badgePreview, badgePreview, 0, c_white, 1); + draw_sprite_ext(THEME.node_state, is_3D? 3 : 0, xx, yy, badgePreview, badgePreview, 0, c_white, 1); xx -= 28 * badgePreview; } @@ -965,37 +1597,57 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x inspecting = false; previewing = 0; - } + } #endregion - active_draw_index = -1; - static drawActive = function(_x, _y, _s, ind = 0) { - active_draw_index = ind; - } + static drawBranch = function(_depth = 0) { #region + if(branch_drawing) return; + branch_drawing = true; + + if(!PREFERENCES.connection_line_highlight_all && _depth == 1) return; + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + if(inputs[| i].isLeaf()) continue; + inputs[| i].value_from.node.drawBranch(_depth + 1); + } + } #endregion - static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) {} + static drawActive = function(_x, _y, _s, ind = 0) { #region + active_draw_index = ind; + if(display_parameter.highlight) drawBranch(); + } #endregion + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} + + static drawPreviewToolOverlay = function(hover, active, _mx, _my, _panel) { return false; } static drawAnimationTimeline = function(_w, _h, _s) {} - static enable = function() { active = true; } - static disable = function() { active = false; } + static getAnimationCacheExist = function(frame) { return cacheExist(frame); } - static destroy = function(_merge = false) { + static enable = function() { INLINE active = true; timeline_item.active = true; } + static disable = function() { INLINE active = false; timeline_item.active = false; } + + static onDestroy = function() {} + + static destroy = function(_merge = false, record = true) { #region if(!active) return; disable(); - if(PANEL_GRAPH.node_hover == self) PANEL_GRAPH.node_hover = noone; - if(PANEL_GRAPH.node_focus == self) PANEL_GRAPH.node_focus = noone; - if(PANEL_INSPECTOR.inspecting == self) PANEL_INSPECTOR.inspecting = noone; + ds_list_remove(group == noone? PROJECT.nodes : group.getNodeList(), self); + + if(PANEL_GRAPH.node_hover == self) PANEL_GRAPH.node_hover = noone; + PANEL_GRAPH.nodes_selecting = []; + + if(PANEL_INSPECTOR.inspecting == self) PANEL_INSPECTOR.inspecting = noone; PANEL_PREVIEW.removeNodePreview(self); - PANEL_ANIMATION.updatePropertyList(); for(var i = 0; i < ds_list_size(outputs); i++) { var jun = outputs[| i]; - for(var j = 0; j < ds_list_size(jun.value_to); j++) { - var _vt = jun.value_to[| j]; - if(_vt.value_from == noone) break; + for(var j = 0; j < array_length(jun.value_to); j++) { + var _vt = jun.value_to[j]; + if(_vt.isLeaf()) break; if(_vt.value_from.node != self) break; _vt.removeFrom(false); @@ -1003,12 +1655,12 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(!_merge) continue; for( var k = 0; k < ds_list_size(inputs); k++ ) { - if(inputs[| k].value_from == noone) continue; + if(inputs[| k].isLeaf()) continue; if(_vt.setFrom(inputs[| k].value_from)) break; } } - ds_list_clear(jun.value_to); + jun.value_to = []; } for( var i = 0; i < ds_list_size(inputs); i++ ) @@ -1018,15 +1670,28 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x outputs[| i].destroy(); onDestroy(); - } + if(group) group.refreshNodes(); + + if(record) recordAction(ACTION_TYPE.node_delete, self); + + RENDER_ALL_REORDER + } #endregion - static restore = function() { + static onRestore = function() {} + + static restore = function() { #region if(active) return; enable(); + ds_list_add(group == noone? PROJECT.nodes : group.getNodeList(), self); - } + + onRestore(); + if(group) group.refreshNodes(); + + RENDER_ALL_REORDER + } #endregion - static onValidate = function() { + static onValidate = function() { #region value_validation[VALIDATION.pass] = 0; value_validation[VALIDATION.warning] = 0; value_validation[VALIDATION.error] = 0; @@ -1036,71 +1701,70 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(jun.value_validation) value_validation[jun.value_validation]++; } - } + } #endregion - static onDestroy = function() {} - - static clearInputCache = function() { + static clearInputCache = function() { #region for( var i = 0; i < ds_list_size(inputs); i++ ) inputs[| i].cache_value[0] = false; - } + } #endregion - static cacheArrayCheck = function() { - if(array_length(cached_output) != PROJECT.animator.frames_total) - array_resize(cached_output, PROJECT.animator.frames_total); - if(array_length(cache_result) != PROJECT.animator.frames_total) - array_resize(cache_result, PROJECT.animator.frames_total); - } + static cacheArrayCheck = function() { #region + cached_output = array_verify(cached_output, TOTAL_FRAMES); + cache_result = array_verify(cache_result, TOTAL_FRAMES); + } #endregion - static cacheCurrentFrame = function(_frame) { + static cacheCurrentFrame = function(_frame) { #region cacheArrayCheck(); - if(PROJECT.animator.current_frame < 0) return; - if(PROJECT.animator.current_frame >= array_length(cached_output)) return; + if(CURRENT_FRAME < 0) return; + if(CURRENT_FRAME >= array_length(cached_output)) return; - surface_array_free(cached_output[PROJECT.animator.current_frame]); - cached_output[PROJECT.animator.current_frame] = surface_array_clone(_frame); + surface_array_free(cached_output[CURRENT_FRAME]); + cached_output[CURRENT_FRAME] = surface_array_clone(_frame); - array_safe_set(cache_result, PROJECT.animator.current_frame, true); + array_safe_set(cache_result, CURRENT_FRAME, true); - return cached_output[PROJECT.animator.current_frame]; - } + return cached_output[CURRENT_FRAME]; + } #endregion - static cacheExist = function(frame = PROJECT.animator.current_frame) { + static cacheExist = function(frame = CURRENT_FRAME) { #region if(frame < 0) return false; if(frame >= array_length(cached_output)) return false; if(frame >= array_length(cache_result)) return false; - if(!array_safe_get(cache_result, frame, false)) return false; + if(!array_safe_get_fast(cache_result, frame, false)) return false; - var s = array_safe_get(cached_output, frame); + var s = array_safe_get_fast(cached_output, frame); return is_array(s) || surface_exists(s); - } + } #endregion - static getCacheFrame = function(frame = PROJECT.animator.current_frame) { + static getCacheFrame = function(frame = CURRENT_FRAME) { #region if(frame < 0) return false; if(!cacheExist(frame)) return noone; - var surf = array_safe_get(cached_output, frame); + var surf = array_safe_get_fast(cached_output, frame); return surf; - } + } #endregion - static recoverCache = function(frame = PROJECT.animator.current_frame) { + static recoverCache = function(frame = CURRENT_FRAME) { #region if(!cacheExist(frame)) return false; - var _s = cached_output[PROJECT.animator.current_frame]; + var _s = cached_output[CURRENT_FRAME]; outputs[| 0].setValue(_s); return true; - } - static clearCache = function() { + } #endregion + + static clearCache = function(_force = false) { #region clearInputCache(); - if(!clearCacheOnChange) return; - if(!use_cache) return; - if(!isRenderActive()) return; + if(!_force) { + if(!use_cache) return; + if(!clearCacheOnChange) return; + if(!isRenderActive()) return; + } - if(array_length(cached_output) != PROJECT.animator.frames_total) - array_resize(cached_output, PROJECT.animator.frames_total); + if(array_length(cached_output) != TOTAL_FRAMES) + array_resize(cached_output, TOTAL_FRAMES); for(var i = 0; i < array_length(cached_output); i++) { var _s = cached_output[i]; if(is_surface(_s)) @@ -1108,95 +1772,91 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x cached_output[i] = 0; cache_result[i] = false; } - } + } #endregion - static clearCacheForward = function() { - _clearCacheForward(); - } + static clearCacheForward = function() { #region + _clearCacheForward(); + } #endregion - static _clearCacheForward = function() { + static _clearCacheForward = function() { #region if(!isRenderActive()) return; clearCache(); var arr = getNextNodesRaw(); for( var i = 0, n = array_length(arr); i < n; i++ ) arr[i]._clearCacheForward(); + } #endregion + + static cachedPropagate = function(_group = group) { #region + if(group != _group) return; + setRenderStatus(true); - //for( var i = 0; i < ds_list_size(outputs); i++ ) - //for( var j = 0; j < ds_list_size(outputs[| i].value_to); j++ ) - // outputs[| i].value_to[| j].node._clearCacheForward(); - } + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _input = inputs[| i]; + if(_input.isLeaf()) continue; + + _input.value_from.node.cachedPropagate(_group); + } + } #endregion - static clearInputCache = function() { - for( var i = 0; i < ds_list_size(inputs); i++ ) + static clearInputCache = function() { #region + for( var i = 0; i < ds_list_size(inputs); i++ ) { + if(!is_instanceof(inputs[| i], NodeValue)) continue; inputs[| i].resetCache(); - } + } + } #endregion - static checkConnectGroup = function(_type = "group") { - var _y = y; - var nodes = []; - + static checkConnectGroup = function(_io) { #region + var _y = y; + var _n = noone; + for(var i = 0; i < ds_list_size(inputs); i++) { var _in = inputs[| i]; - if(_in.value_from == noone) continue; - if(_in.value_from.node.group == group) continue; - var input_node = noone; + if(_in.isLeaf()) continue; + if(_in.value_from.node.group == group) continue; - switch(_type) { - case "group" : input_node = new Node_Group_Input(x - w - 64, _y, group); break; - case "loop" : input_node = new Node_Iterator_Input(x - w - 64, _y, group); break; - case "feedback" : input_node = new Node_Feedback_Input(x - w - 64, _y, group); break; - } - - if(input_node == noone) continue; + var _ind = string(_in.value_from); + _io.map[$ _ind] = _in.value_from; - array_push(nodes, input_node); - input_node.inputs[| 2].setValue(_in.type); - input_node.inParent.setFrom(_in.value_from); - input_node.onValueUpdate(0); - _in.setFrom(input_node.outputs[| 0]); - - _y += 64; + if(struct_has(_io.inputs, _ind)) + array_push(_io.inputs[$ _ind ], _in); + else + _io.inputs[$ _ind ] = [ _in ]; } for(var i = 0; i < ds_list_size(outputs); i++) { var _ou = outputs[| i]; - for(var j = 0; j < ds_list_size(_ou.value_to); j++) { - var _to = _ou.value_to[| j]; - if(_to.value_from != _ou) continue; - if(!_to.node.active) continue; + + for(var j = 0; j < array_length(_ou.value_to); j++) { + var _to = _ou.value_to[j]; + if(_to.value_from != _ou) continue; + if(!_to.node.active) continue; if(_to.node.group == group) continue; - var output_node = noone; - switch(_type) { - case "group" : output_node = new Node_Group_Output(x + w + 64, y, group); break; - case "loop" : output_node = new Node_Iterator_Output(x + w + 64, y, group); break; - case "feedback" : output_node = new Node_Feedback_Output(x + w + 64, y, group); break; - } - - if(output_node == noone) continue; + var _ind = string(_ou); + _io.map[$ _ind] = _ou; - array_push(nodes, output_node); - _to.setFrom(output_node.outParent); - output_node.inputs[| 0].setFrom(_ou); + if(struct_has(_io.outputs, _ind)) + array_push(_io.outputs[$ _ind ], _to); + else + _io.outputs[$ _ind ] = [ _to ]; } } - - return nodes; - } + } #endregion - static isNotUsingTool = function() { - return PANEL_PREVIEW.tool_current == noone; - } + static isNotUsingTool = function() { return PANEL_PREVIEW.tool_current == noone; } - static isUsingTool = function(index, subtool = noone) { + static isUsingTool = function(index = undefined, subtool = noone) { #region if(tools == -1) return false; var _tool = PANEL_PREVIEW.tool_current; - if(_tool == noone) + if(_tool == noone) //not using any tool return false; + if(index == undefined) //using any tool + return true; + if(is_real(index) && _tool != tools[index]) return false; @@ -1207,15 +1867,15 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x return true; return _tool.selecting == subtool; - } + } #endregion - static clone = function(target = PANEL_GRAPH.getCurrentContext()) { + static clone = function(target = PANEL_GRAPH.getCurrentContext()) { #region CLONING = true; var _type = instanceof(self); var _node = nodeBuild(_type, x, y, target); CLONING = false; - PROJECT.version = SAVE_VERSION; + LOADING_VERSION = SAVE_VERSION; if(!_node) return; @@ -1228,58 +1888,67 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x PROJECT.nodeMap[? node_id] = self; PROJECT.nodeMap[? _nid] = _node; - PANEL_ANIMATION.updatePropertyList(); CLONING = false; + refreshTimeline(); onClone(_node, target); return _node; - } + } #endregion static onClone = function(_NewNode, target = PANEL_GRAPH.getCurrentContext()) {} - draw_droppable = false; - static droppable = function(dragObj) { + static droppable = function(dragObj) { #region for( var i = 0; i < ds_list_size(inputs); i++ ) { if(dragObj.type == inputs[| i].drop_key) return true; } return false; - } + } #endregion - static onDrop = function(dragObj) { + on_drop_file = noone; + static onDrop = function(dragObj) { #region + if(dragObj.type == "Asset" && is_callable(on_drop_file)) { + on_drop_file(dragObj.data.path); + return; + } + for( var i = 0; i < ds_list_size(inputs); i++ ) { if(dragObj.type == inputs[| i].drop_key) { inputs[| i].setValue(dragObj.data); - previewDropAnimation(); return; } } - } + } #endregion - static getPreviewValue = function() { - if(preview_channel > ds_list_size(outputs)) return noone; - return outputs[| preview_channel]; - } - - static getPreviewBoundingBox = function() { - var _node = getPreviewValue(); - if(_node == undefined) return noone; - if(_node.type != VALUE_TYPE.surface) return noone; + static getPreviewValues = function() { #region + if(preview_channel >= ds_list_size(outputs)) return noone; - var _surf = _node.getValue(); + switch(outputs[| preview_channel].type) { + case VALUE_TYPE.surface : + case VALUE_TYPE.dynaSurface : + break; + default : + return noone; + } + + return outputs[| preview_channel].getValue(); + } #endregion + + static getPreviewBoundingBox = function() { #region + var _surf = getPreviewValues(); if(is_array(_surf)) - _surf = array_safe_get(_surf, preview_index, noone); + _surf = array_safe_get_fast(_surf, preview_index, noone); if(!is_surface(_surf)) return noone; - return BBOX().fromWH(preview_x, preview_y, surface_get_width(_surf), surface_get_height(_surf)); - } + return BBOX().fromWH(preview_x, preview_y, surface_get_width_safe(_surf), surface_get_height_safe(_surf)); + } #endregion - static getTool = function() { - return self; - } + static getTool = function() { return self; } - static setTool = function(tool) { + static getToolSettings = function() { return tool_settings; } + + static setTool = function(tool) { #region if(!tool) { isTool = false; return; @@ -1289,10 +1958,13 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x group.nodes[| i].isTool = false; isTool = true; - } + } #endregion - #region[#88ffe916] === Save Load === - static serialize = function(scale = false, preset = false) { + static drawTools = function(_mx, _my, xx, yy, tool_size, hover, focus) { return 0; } + + static serialize = function(scale = false, preset = false) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SERIALIZE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + if(!active) return; + var _map = {}; //print(" > Serializing: " + name); @@ -1305,8 +1977,10 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x _map.y = y; _map.type = instanceof(self); _map.group = group == noone? group : group.node_id; - _map.preview = previewable; _map.tool = isTool; + + _map.previewable = previewable; + _map.show_parameter = show_parameter; } _map.attri = attributeSerialize(); @@ -1329,29 +2003,39 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var _trigger = []; array_push(_trigger, inspectInput1.serialize(scale, preset)); array_push(_trigger, inspectInput2.serialize(scale, preset)); + array_push(_trigger, updatedInTrigger.serialize(scale, preset)); + array_push(_trigger, updatedOutTrigger.serialize(scale, preset)); + _map.inspectInputs = _trigger; + _map.renamed = renamed; + + _map.buffer = {}; + var _bufferKey = struct_key(bufferStore); + for( var i = 0, n = array_length(_bufferKey); i < n; i++ ) { + var _key = _bufferKey[i]; + _map.buffer[$ _key] = buffer_serialize(bufferStore[$ _key]); + } doSerialize(_map); processSerialize(_map); return _map; - } + } #endregion static attributeSerialize = function() { return attributes; } static doSerialize = function(_map) {} static processSerialize = function(_map) {} - load_scale = false; - load_map = -1; - static deserialize = function(_map, scale = false, preset = false) { - load_map = _map; + static deserialize = function(_map, scale = false, preset = false) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESERIALIZE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + load_map = _map; load_scale = scale; + renamed = struct_try_get(load_map, "renamed", false); if(!preset) { if(APPENDING) APPEND_MAP[? load_map.id] = node_id; else node_id = load_map.id; PROJECT.nodeMap[? node_id] = self; - //print($"D Adding node {node_id} to {PROJECT.path} [{ds_map_size(PROJECT.nodeMap)}]"); + //print($"Adding node {node_id} to {PROJECT.path} [{ds_map_size(PROJECT.nodeMap)}]"); if(struct_has(load_map, "name")) setDisplayName(load_map.name); @@ -1360,19 +2044,30 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(internalName == "") resetInternalName(); - _group = struct_try_get(load_map, "group", noone); - if(_group == -1) _group = noone; + load_group = struct_try_get(load_map, "group", noone); + if(load_group == -1) load_group = noone; x = struct_try_get(load_map, "x"); y = struct_try_get(load_map, "y"); - renderActive = struct_try_get(load_map, "render", true); - previewable = struct_try_get(load_map, "preview", previewable); - isTool = struct_try_get(load_map, "tool"); + renderActive = struct_try_get(load_map, "render", true); + previewable = struct_try_get(load_map, "previewable", previewable); + isTool = struct_try_get(load_map, "tool"); + show_parameter = struct_try_get(load_map, "show_parameter"); } if(struct_has(load_map, "attri")) attributeDeserialize(load_map.attri); + if(struct_has(load_map, "buffer")) { + var _bufferKey = struct_key(bufferStore); + for( var i = 0, n = array_length(_bufferKey); i < n; i++ ) { + var _key = _bufferKey[i]; + if(!struct_has(bufferStore, _key)) continue; + + bufferStore[$ _key] = buffer_deserialize(load_map.buffer[$ _key]); + } + } + if(is_dynamic_input) { inputBalance(); inputGenerate(); @@ -1386,17 +2081,19 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x triggerRender(); } - } + } #endregion - static inputBalance = function() { //Cross version compatibility for dynamic input nodes + static inputBalance = function() { #region //Cross version compatibility for dynamic input nodes if(!struct_has(load_map, "data_length")) return; var _input_fix_len = load_map.input_fix_len; var _data_length = load_map.data_length; - print($"Balancing IO: {input_fix_len} => {load_map.input_fix_len} : {data_length} => {load_map.data_length}"); - print($"IO size before: {array_length(load_map.inputs)}"); + //print($"Balancing IO: {input_fix_len} => {load_map.input_fix_len} : {data_length} => {load_map.data_length}"); + //print($"IO size before: {array_length(load_map.inputs)}"); + //for( var i = 0, n = array_length(load_map.inputs); i < n; i++ ) + // print($"{i}: {load_map.inputs[i].name}"); var _dynamic_inputs = (array_length(load_map.inputs) - _input_fix_len) / _data_length; if(frac(_dynamic_inputs) != 0) { @@ -1409,20 +2106,24 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var _pad_dyna = data_length - _data_length; - for( var i = _dynamic_inputs - 1; i >= 0; i-- ) { + for( var i = _dynamic_inputs; i >= 1; i-- ) { var _ind = _input_fix_len + i * _data_length; - repeat(_pad_dyna) - array_insert(load_map.inputs, _ind, noone); + if(_pad_dyna > 0) + repeat(_pad_dyna) array_insert(load_map.inputs, _ind, noone); + else + array_delete(load_map.inputs, _ind + _pad_dyna, -_pad_dyna); } var _pad_fix = input_fix_len - _input_fix_len; repeat(_pad_fix) array_insert(load_map.inputs, _input_fix_len, noone); - print($"IO size after: {array_length(load_map.inputs)}"); - } + //print($"IO size after: {array_length(load_map.inputs)}"); + //for( var i = 0, n = array_length(load_map.inputs); i < n; i++ ) + // print($"{i}: {load_map.inputs[i] == noone? "noone" : load_map.inputs[i].name}"); + } #endregion - static inputGenerate = function() { //Generate input for dynamic input nodes + static inputGenerate = function() { #region //Generate input for dynamic input nodes if(createNewInput == noone) return; @@ -1430,22 +2131,30 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x //print($"Node {name} create {_dynamic_inputs} inputs for data length {data_length}"); repeat(_dynamic_inputs) createNewInput(); - } + } #endregion - static attributeDeserialize = function(attr) { - struct_override(attributes, attr); - } - - static postDeserialize = function() {} - static processDeserialize = function() {} + static attributeDeserialize = function(attr) { #region + if(struct_has(attributes, "use_project_dimension") && !struct_has(attr, "use_project_dimension")) + attributes.use_project_dimension = false; + + struct_append(attributes, attr); + } #endregion + + static processDeserialize = function() {} + static postDeserialize = function() {} + + static applyDeserialize = function(preset = false) { #region + preApplyDeserialize(); - static applyDeserialize = function(preset = false) { var _inputs = load_map.inputs; var amo = min(ds_list_size(inputs), array_length(_inputs)); + //print($"Applying deserialzie for {name}"); + for(var i = 0; i < amo; i++) { if(inputs[| i] == noone || _inputs[i] == noone) continue; - print($"Apply deserialize {_inputs[i].name} to {inputs[| i].name}"); + + //print($" Apply {i} : {inputs[| i].name}"); inputs[| i].applyDeserialize(_inputs[i], load_scale, preset); } @@ -1455,6 +2164,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x for(var i = 0; i < amo; i++) { if(outputs[| i] == noone) continue; + outputs[| i].applyDeserialize(_outputs[i], load_scale, preset); } } @@ -1463,56 +2173,66 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var insInp = load_map.inspectInputs; inspectInput1.applyDeserialize(insInp[0], load_scale, preset); inspectInput2.applyDeserialize(insInp[1], load_scale, preset); + + if(array_length(insInp) > 2) updatedInTrigger.applyDeserialize(insInp[2], load_scale, preset); + if(array_length(insInp) > 3) updatedOutTrigger.applyDeserialize(insInp[3], load_scale, preset); } + //print($"Applying deserialzie for {name} complete"); + doApplyDeserialize(); - } + } #endregion - static doApplyDeserialize = function() {} + static preApplyDeserialize = function() {} + static doApplyDeserialize = function() {} - static loadGroup = function(context = PANEL_GRAPH.getCurrentContext()) { - if(_group == noone) { - var c = context; - if(c != noone) c.add(self); + static loadGroup = function(context = noone) { #region + if(load_group == noone) { + if(context != noone) context.add(self); } else { - if(APPENDING) _group = GetAppendID(_group); + if(APPENDING) load_group = GetAppendID(load_group); - if(ds_map_exists(PROJECT.nodeMap, _group)) { - if(struct_has(PROJECT.nodeMap[? _group], "add")) - PROJECT.nodeMap[? _group].add(self); + if(ds_map_exists(PROJECT.nodeMap, load_group)) { + if(struct_has(PROJECT.nodeMap[? load_group], "add")) + PROJECT.nodeMap[? load_group].add(self); else { - var txt = $"Group load failed. Node ID {_group} is not a group."; + var txt = $"Group load failed. Node ID {load_group} is not a group."; throw(txt); } } else { - var txt = $"Group load failed. Can't find node ID {_group}"; + var txt = $"Group load failed. Can't find node ID {load_group}"; throw(txt); } } - } + + onLoadGroup(); + } #endregion - static connect = function(log = false) { + static onLoadGroup = function() {} + + static connect = function(log = false) { #region var connected = true; for(var i = 0; i < ds_list_size(inputs); i++) connected &= inputs[| i].connect(log); - if(struct_has(load_map, "inspectInputs")) { - inspectInput1.connect(log); - inspectInput2.connect(log); - } + inspectInput1.connect(log); + inspectInput2.connect(log); + updatedInTrigger.connect(log); if(!connected) ds_queue_enqueue(CONNECTION_CONFLICT, self); + refreshTimeline(); return connected; - } + } #endregion static preConnect = function() {} static postConnect = function() {} - #endregion + + static postLoad = function() {} static resetAnimation = function() {} - static cleanUp = function() { + static cleanUp = function() { #region for( var i = 0; i < ds_list_size(inputs); i++ ) inputs[| i].cleanUp(); for( var i = 0; i < ds_list_size(outputs); i++ ) @@ -1528,24 +2248,26 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x surface_free(temp_surface[i]); onCleanUp(); - } + } #endregion static onCleanUp = function() {} // helper function - static attrDepth = function() { + static attrDepth = function() { #region if(struct_has(attributes, "color_depth")) { var form = attributes.color_depth; if(inputs[| 0].type == VALUE_TYPE.surface) form--; if(form >= 0) - return array_safe_get(global.SURFACE_FORMAT, form, surface_rgba8unorm); + return array_safe_get_fast(global.SURFACE_FORMAT, form, surface_rgba8unorm); } - var _s = inputs[| 0].getValue(); + var _s = getInputData(0); while(is_array(_s) && array_length(_s)) _s = _s[0]; if(!is_surface(_s)) return surface_rgba8unorm; return surface_get_format(_s); - } + } #endregion + + static toString = function() { return $"Node [{internalName}]: {node_id}"; } } \ No newline at end of file diff --git a/#backups/scripts/node_keyframe/node_keyframe.gml.backup0 b/#backups/scripts/node_keyframe/node_keyframe.gml.backup0 index b32e7be10..926dfa0e2 100644 --- a/#backups/scripts/node_keyframe/node_keyframe.gml.backup0 +++ b/#backups/scripts/node_keyframe/node_keyframe.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-20 09:03:18 +// 2024-04-23 16:53:10 enum KEY_TYPE { normal, adder } enum CURVE_TYPE { linear, bezier, cut } enum DRIVER_TYPE { none, linear, wiggle, sine } @@ -428,6 +428,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { static processType = function(_val) { #region INLINE + if(PROJECT.attributes.strict) return _val; var _res = _val; if(!sep_axis && typeArray(prop.display_type) && is_array(_val)) { @@ -444,7 +445,6 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { if(is_array(_val)) return _val; if(is_struct(_val)) return _val; - //if(is_undefined(_val)) return 0; switch(prop.type) { case VALUE_TYPE.integer : return prop.unit.mode == VALUE_UNIT.constant? round(_val) : _val; diff --git a/#backups/scripts/node_keyframe/node_keyframe.gml.backup1 b/#backups/scripts/node_keyframe/node_keyframe.gml.backup1 index 6444ad653..ec6d25c0f 100644 --- a/#backups/scripts/node_keyframe/node_keyframe.gml.backup1 +++ b/#backups/scripts/node_keyframe/node_keyframe.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-20 09:02:54 +// 2024-04-23 16:51:49 enum KEY_TYPE { normal, adder } enum CURVE_TYPE { linear, bezier, cut } enum DRIVER_TYPE { none, linear, wiggle, sine } @@ -428,6 +428,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { static processType = function(_val) { #region INLINE + if(PROJECT.attributes.strict) return _val; var _res = _val; if(!sep_axis && typeArray(prop.display_type) && is_array(_val)) { @@ -444,13 +445,12 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { if(is_array(_val)) return _val; if(is_struct(_val)) return _val; - //if(is_undefined(_val)) return 0; switch(prop.type) { case VALUE_TYPE.integer : return prop.unit.mode == VALUE_UNIT.constant? round(_val) : _val; case VALUE_TYPE.float : return _val; case VALUE_TYPE.text : return is_string(_val)? _val : string_real(_val); - case VALUE_TYPE.color : return _val; + case VALUE_TYPE.color : return is_real(_val)? cola(_val) : _val; case VALUE_TYPE.surface : return is_string(_val)? get_asset(_val) : _val; } diff --git a/#backups/scripts/node_pin/node_pin.gml.backup0 b/#backups/scripts/node_pin/node_pin.gml.backup0 index 7fe2f4b71..b32d2f0cb 100644 --- a/#backups/scripts/node_pin/node_pin.gml.backup0 +++ b/#backups/scripts/node_pin/node_pin.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-22 14:53:29 +// 2024-04-23 11:37:03 function Node_Pin(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Pin"; setDimension(32, 32); @@ -96,7 +96,7 @@ function Node_Pin(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { if(renamed && display_name != "" && display_name != "Pin") { draw_set_text(f_sdf, fa_center, fa_bottom, COLORS._main_text); - draw_text_transformed(xx, yy - 12, display_name, _s * 0.4, _s * 0.4, 0); + draw_text_transformed(xx, yy - 12 * _s, display_name, _s * 0.4, _s * 0.4, 0); } return drawJunctions(_x, _y, _mx, _my, _s); diff --git a/#backups/scripts/node_pin/node_pin.gml.backup1 b/#backups/scripts/node_pin/node_pin.gml.backup1 index 30565b760..74df5f43a 100644 --- a/#backups/scripts/node_pin/node_pin.gml.backup1 +++ b/#backups/scripts/node_pin/node_pin.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-22 14:45:48 +// 2024-04-23 11:37:02 function Node_Pin(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Pin"; setDimension(32, 32); @@ -95,8 +95,8 @@ function Node_Pin(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { hover_scale_to = 0; if(renamed && display_name != "" && display_name != "Pin") { - draw_set_text(f_p0, fa_center, fa_bottom, COLORS._main_text); - draw_text_transformed(xx, yy - 12, display_name, _s, _s, 0); + draw_set_text(f_sdf, fa_center, fa_bottom, COLORS._main_text); + draw_text_transformed(xx, yy - 12 * _s, display_name, _s * 0.4, _s * 0.4, 0); } return drawJunctions(_x, _y, _mx, _my, _s); diff --git a/#backups/scripts/node_tunnel_in/node_tunnel_in.gml.backup0 b/#backups/scripts/node_tunnel_in/node_tunnel_in.gml.backup0 index 666a8c90d..1926b2613 100644 --- a/#backups/scripts/node_tunnel_in/node_tunnel_in.gml.backup0 +++ b/#backups/scripts/node_tunnel_in/node_tunnel_in.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-22 19:31:48 +// 2024-04-23 11:37:11 function Node_Tunnel_In(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Tunnel In"; color = COLORS.node_blend_tunnel; @@ -245,7 +245,7 @@ function Node_Tunnel_In(_x, _y, _group = noone) : Node(_x, _y, _group) construct hover_scale_to = 0; draw_set_text(f_sdf, fa_center, fa_bottom, COLORS._main_text); - draw_text_transformed(xx, yy - 12, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); + draw_text_transformed(xx, yy - 12 * _s, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); return drawJunctions(_x, _y, _mx, _my, _s); } #endregion diff --git a/#backups/scripts/node_tunnel_in/node_tunnel_in.gml.backup1 b/#backups/scripts/node_tunnel_in/node_tunnel_in.gml.backup1 index 1e1f23844..899eff669 100644 --- a/#backups/scripts/node_tunnel_in/node_tunnel_in.gml.backup1 +++ b/#backups/scripts/node_tunnel_in/node_tunnel_in.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-22 19:31:03 +// 2024-04-23 11:37:09 function Node_Tunnel_In(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Tunnel In"; color = COLORS.node_blend_tunnel; @@ -211,7 +211,7 @@ function Node_Tunnel_In(_x, _y, _group = noone) : Node(_x, _y, _group) construct #region draw arc var prev_s = preview_connecting? 1 + sin(current_time / 100) * 0.1 : 1; - preview_scale = lerp_float(preview_scale, prev_s, 5); + preview_scale = lerp_float(preview_scale, prev_s, 5); preview_connecting = false; shader_set(sh_node_arc); @@ -245,7 +245,7 @@ function Node_Tunnel_In(_x, _y, _group = noone) : Node(_x, _y, _group) construct hover_scale_to = 0; draw_set_text(f_sdf, fa_center, fa_bottom, COLORS._main_text); - draw_text_transformed(xx, yy - 12, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); + draw_text_transformed(xx, yy - 12 * _s, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); return drawJunctions(_x, _y, _mx, _my, _s); } #endregion diff --git a/#backups/scripts/node_tunnel_out/node_tunnel_out.gml.backup0 b/#backups/scripts/node_tunnel_out/node_tunnel_out.gml.backup0 index a90fbc1a8..6135c2d57 100644 --- a/#backups/scripts/node_tunnel_out/node_tunnel_out.gml.backup0 +++ b/#backups/scripts/node_tunnel_out/node_tunnel_out.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-22 19:32:35 +// 2024-04-23 11:37:07 function Node_Tunnel_Out(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Tunnel Out"; color = COLORS.node_blend_tunnel; @@ -179,7 +179,7 @@ function Node_Tunnel_Out(_x, _y, _group = noone) : Node(_x, _y, _group) construc hover_scale_to = 0; draw_set_text(f_sdf, fa_center, fa_bottom, COLORS._main_text); - draw_text_transformed(xx, yy - 12, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); + draw_text_transformed(xx, yy - 12 * _s, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); return drawJunctions(_x, _y, _mx, _my, _s); } #endregion diff --git a/#backups/scripts/node_tunnel_out/node_tunnel_out.gml.backup1 b/#backups/scripts/node_tunnel_out/node_tunnel_out.gml.backup1 index 22e1e4e21..a90fbc1a8 100644 --- a/#backups/scripts/node_tunnel_out/node_tunnel_out.gml.backup1 +++ b/#backups/scripts/node_tunnel_out/node_tunnel_out.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-22 19:32:21 +// 2024-04-22 19:32:35 function Node_Tunnel_Out(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Tunnel Out"; color = COLORS.node_blend_tunnel; diff --git a/#backups/scripts/node_value/node_value.gml.backup0 b/#backups/scripts/node_value/node_value.gml.backup0 index 6ce4b7359..6b7296835 100644 --- a/#backups/scripts/node_value/node_value.gml.backup0 +++ b/#backups/scripts/node_value/node_value.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-23 09:27:33 +// 2024-04-23 16:49:02 #region ---- global names ---- global.junctionEndName = [ "Hold", "Loop", "Ping pong", "Wrap" ]; @@ -526,6 +526,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru #region ---- main ---- active = true; + from = noone; node = _node; x = node.x; y = node.y; @@ -1615,7 +1616,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru static getStaticValue = function() { INLINE return ds_list_empty(animator.values)? 0 : animator.values[| 0].value; } - static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { #region + static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { #region //Get value if(type == VALUE_TYPE.trigger) return _getValue(_time, false, 0, false); @@ -1662,36 +1663,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return val; } #endregion - static __getAnimValue = function(_time = CURRENT_FRAME) { #region - - if(value_tag == "dimension" && node.attributes.use_project_dimension) - return PROJECT.attributes.surface_dimension; - - if(!is_anim) { - if(sep_axis) { - if(ds_list_empty(animators[i].values)) return 0; - - var val = array_verify(val, array_length(animators)); - for( var i = 0, n = array_length(animators); i < n; i++ ) - val[i] = animators[i].processType(animators[i].values[| 0].value); - return val; - } - - if(ds_list_empty(animator.values)) return 0; - - return animator.processType(animator.values[| 0].value); - } - - if(sep_axis) { - var val = []; - for( var i = 0, n = array_length(animators); i < n; i++ ) - val[i] = animators[i].getValue(_time); - return val; - } - - return animator.getValue(_time); - } #endregion - static arrayBalance = function(val) { #region // Balance array (generate uniform array from single values) if(!is_array(def_val)) return val; @@ -1774,6 +1745,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } } #endregion + if(PROJECT.attributes.strict) return val; + val = arrayBalance(val); if(isArray(val) && array_length(val) < 1024) { #region Process data @@ -1826,6 +1799,36 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } } #endregion + static __getAnimValue = function(_time = CURRENT_FRAME) { #region + + if(value_tag == "dimension" && node.attributes.use_project_dimension) + return PROJECT.attributes.surface_dimension; + + if(!is_anim) { + if(sep_axis) { + if(ds_list_empty(animators[i].values)) return 0; + + var val = array_verify(val, array_length(animators)); + for( var i = 0, n = array_length(animators); i < n; i++ ) + val[i] = animators[i].processType(animators[i].values[| 0].value); + return val; + } + + if(ds_list_empty(animator.values)) return 0; + + return animator.processType(animator.values[| 0].value); + } + + if(sep_axis) { + var val = []; + for( var i = 0, n = array_length(animators); i < n; i++ ) + val[i] = animators[i].getValue(_time); + return val; + } + + return animator.getValue(_time); + } #endregion + static setAnim = function(anim, record = false) { #region if(is_anim == anim) return; if(record) { @@ -2143,9 +2146,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru static isRendered = function() { #region if(type == VALUE_TYPE.node) return true; - if( value_from == noone) return true; + if(value_from == noone) return true; - var controlNode = struct_has(value_from, "from")? value_from.from : value_from.node; + var controlNode = value_from.from? value_from.from : value_from.node; if(!controlNode.active) return true; if(!controlNode.isRenderActive()) return true; diff --git a/#backups/scripts/node_value/node_value.gml.backup1 b/#backups/scripts/node_value/node_value.gml.backup1 index b8bf2c881..cbbf88ed9 100644 --- a/#backups/scripts/node_value/node_value.gml.backup1 +++ b/#backups/scripts/node_value/node_value.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-23 09:26:39 +// 2024-04-23 16:40:38 #region ---- global names ---- global.junctionEndName = [ "Hold", "Loop", "Ping pong", "Wrap" ]; @@ -526,6 +526,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru #region ---- main ---- active = true; + from = noone; node = _node; x = node.x; y = node.y; @@ -1615,7 +1616,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru static getStaticValue = function() { INLINE return ds_list_empty(animator.values)? 0 : animator.values[| 0].value; } - static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { #region + static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { #region //Get value if(type == VALUE_TYPE.trigger) return _getValue(_time, false, 0, false); @@ -1662,36 +1663,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return val; } #endregion - static __getAnimValue = function(_time = CURRENT_FRAME) { #region - - if(value_tag == "dimension" && node.attributes.use_project_dimension) - return PROJECT.attributes.surface_dimension; - - if(!is_anim) { - if(sep_axis) { - if(ds_list_empty(animators[i].values)) return 0; - - var val = array_verify(val, array_length(animators)); - for( var i = 0, n = array_length(animators); i < n; i++ ) - val[i] = animators[i].processType(animators[i].values[| 0].value); - return val; - } - - if(ds_list_empty(animator.values)) return 0; - - return animator.processType(animator.values[| 0].value); - } - - if(sep_axis) { - var val = []; - for( var i = 0, n = array_length(animators); i < n; i++ ) - val[i] = animators[i].getValue(_time); - return val; - } - - return animator.getValue(_time); - } #endregion - static arrayBalance = function(val) { #region // Balance array (generate uniform array from single values) if(!is_array(def_val)) return val; @@ -1774,6 +1745,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } } #endregion + if(PROJECT.strict) return val; + val = arrayBalance(val); if(isArray(val) && array_length(val) < 1024) { #region Process data @@ -1826,6 +1799,36 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } } #endregion + static __getAnimValue = function(_time = CURRENT_FRAME) { #region + + if(value_tag == "dimension" && node.attributes.use_project_dimension) + return PROJECT.attributes.surface_dimension; + + if(!is_anim) { + if(sep_axis) { + if(ds_list_empty(animators[i].values)) return 0; + + var val = array_verify(val, array_length(animators)); + for( var i = 0, n = array_length(animators); i < n; i++ ) + val[i] = animators[i].processType(animators[i].values[| 0].value); + return val; + } + + if(ds_list_empty(animator.values)) return 0; + + return animator.processType(animator.values[| 0].value); + } + + if(sep_axis) { + var val = []; + for( var i = 0, n = array_length(animators); i < n; i++ ) + val[i] = animators[i].getValue(_time); + return val; + } + + return animator.getValue(_time); + } #endregion + static setAnim = function(anim, record = false) { #region if(is_anim == anim) return; if(record) { @@ -2143,9 +2146,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru static isRendered = function() { #region if(type == VALUE_TYPE.node) return true; - if( value_from == noone) return true; + if(value_from == noone) return true; - var controlNode = struct_has(value_from, "from")? value_from.from : value_from.node; + var controlNode = value_from.from? value_from.from : value_from.node; if(!controlNode.active) return true; if(!controlNode.isRenderActive()) return true; diff --git a/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 b/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 index 859c26610..af6a0eefe 100644 --- a/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 +++ b/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-21 14:43:36 +// 2024-04-23 16:50:47 #region funtion calls function __fnInit_Inspector() { __registerFunction("inspector_copy_prop", panel_inspector_copy_prop); diff --git a/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 b/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 index 93e0cb057..2710cd2d4 100644 --- a/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 +++ b/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 12:50:09 +// 2024-04-23 16:49:06 #region funtion calls function __fnInit_Inspector() { __registerFunction("inspector_copy_prop", panel_inspector_copy_prop); diff --git a/#backups/scripts/preferences/preferences.gml.backup0 b/#backups/scripts/preferences/preferences.gml.backup0 index 28a75b885..2a7fa1e8b 100644 --- a/#backups/scripts/preferences/preferences.gml.backup0 +++ b/#backups/scripts/preferences/preferences.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-22 17:51:56 +// 2024-04-23 15:29:21 #region preference globalvar PREFERENCES, PREFERENCES_DEF, HOTKEYS_DATA; PREFERENCES = {}; diff --git a/#backups/scripts/preferences/preferences.gml.backup1 b/#backups/scripts/preferences/preferences.gml.backup1 index 0c716d4c8..08f59cc8a 100644 --- a/#backups/scripts/preferences/preferences.gml.backup1 +++ b/#backups/scripts/preferences/preferences.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-22 17:28:13 +// 2024-04-23 11:00:26 #region preference globalvar PREFERENCES, PREFERENCES_DEF, HOTKEYS_DATA; PREFERENCES = {}; diff --git a/#backups/scripts/project_data/project_data.gml.backup0 b/#backups/scripts/project_data/project_data.gml.backup0 new file mode 100644 index 000000000..26d7daf79 --- /dev/null +++ b/#backups/scripts/project_data/project_data.gml.backup0 @@ -0,0 +1,146 @@ +// 2024-04-23 16:49:39 +#region global + globalvar PROJECTS, PROJECT; + PROJECT = noone; +#endregion + +#region project + function Project() constructor { + active = true; /// @is {bool} + + meta = __getdefaultMetaData(); + path = ""; /// @is {string} + thumbnail = ""; + version = SAVE_VERSION; /// @is {number} + seed = irandom_range(100000, 999999); /// @is {number} + + modified = false; /// @is {bool} + readonly = false; /// @is {bool} + safeMode = false; + + nodes = ds_list_create(); + nodeArray = []; + nodeMap = ds_map_create(); + nodeNameMap = ds_map_create(); + nodeTopo = ds_list_create(); + + animator = new AnimationManager(); + globalNode = new Node_Global(); + nodeController = new __Node_Controller(self); + + previewGrid = { #region + show : false, + snap : false, + size : [ 16, 16 ], + opacity : 0.5, + color : COLORS.panel_preview_grid, + } #endregion + + graphGrid = { #region + show : true, + show_origin : false, + snap : true, + size : 16, + opacity : 0.05, + color : c_white, + highlight : 12, + } #endregion + + addons = {}; + + onion_skin = { #region + enabled: false, + range: [ -1, 1 ], + step: 1, + color: [ c_red, c_blue ], + alpha: 0.5, + on_top: true, + }; #endregion + + #region =================== ATTRIBUTES =================== + attributes = { + strict : false, + surface_dimension : [ 32, 32 ], + palette : [ cola(c_black), cola(c_white) ], + palette_fix : false, + } + + attributeEditor = [ + [ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; RENDER_ALL return true; }), + function(junc) { + if(!is_struct(junc)) return; + if(!is_instanceof(junc, NodeValue)) return; + + var attr = attributes.surface_dimension; + var _val = junc.getValue(); + var _res = [ attr[0], attr[1] ]; + + switch(junc.type) { + case VALUE_TYPE.float : + case VALUE_TYPE.integer : + if(is_real(_val)) + _res = [ _val, _val ]; + else if(is_array(_val) && array_length(_val) >= 2) { + _res[0] = is_real(_val[0])? _val[0] : 1; + _res[1] = is_real(_val[1])? _val[1] : 1; + } + break; + + case VALUE_TYPE.surface : + if(is_array(_val)) _val = array_safe_get_fast(_val, 0); + if(is_surface(_val)) + _res = surface_get_dimension(_val); + break; + } + + attr[0] = _res[0]; + attr[1] = _res[1]; + } ], + + [ "Palette", "palette", new buttonPalette(function(pal) { setPalette(pal); RENDER_ALL return true; }), + function(junc) { + if(!is_struct(junc)) return; + if(!is_instanceof(junc, NodeValue)) return; + if(junc.type != VALUE_TYPE.color) return; + if(junc.display_type != VALUE_DISPLAY.palette) return; + + setPalette(junc.getValue()); + } + ], + + [ "Strict", "strict", new checkBox(function() { attributes.strict = !attributes.strict; RENDER_ALL return true; }), function() {} ], + ]; + + static setPalette = function(pal = noone) { + if(pal != noone) attributes.palette = pal; + palettes = paletteToArray(attributes.palette); + } setPalette(); + #endregion + + timelines = new timelineItemGroup(); + + notes = []; + + static cleanup = function() { #region + if(!ds_map_empty(nodeMap)) + array_map(ds_map_keys_to_array(nodeMap), function(_key, _ind) { + var _node = nodeMap[? _key]; + _node.active = false; + _node.cleanUp(); + }); + + ds_list_destroy(nodes); + ds_map_destroy(nodeMap); + ds_map_destroy(nodeNameMap); + + gc_collect(); + } #endregion + + static toString = function() { return $"ProjectObject [{path}]"; } + } + + function __initProject() { + PROJECT = new Project(); + PROJECTS = [ PROJECT ]; + } +#endregion \ No newline at end of file diff --git a/#backups/scripts/project_data/project_data.gml.backup1 b/#backups/scripts/project_data/project_data.gml.backup1 new file mode 100644 index 000000000..c648488a7 --- /dev/null +++ b/#backups/scripts/project_data/project_data.gml.backup1 @@ -0,0 +1,146 @@ +// 2024-04-23 16:49:37 +#region global + globalvar PROJECTS, PROJECT; + PROJECT = noone; +#endregion + +#region project + function Project() constructor { + active = true; /// @is {bool} + + meta = __getdefaultMetaData(); + path = ""; /// @is {string} + thumbnail = ""; + version = SAVE_VERSION; /// @is {number} + seed = irandom_range(100000, 999999); /// @is {number} + + modified = false; /// @is {bool} + readonly = false; /// @is {bool} + safeMode = false; + + nodes = ds_list_create(); + nodeArray = []; + nodeMap = ds_map_create(); + nodeNameMap = ds_map_create(); + nodeTopo = ds_list_create(); + + animator = new AnimationManager(); + globalNode = new Node_Global(); + nodeController = new __Node_Controller(self); + + previewGrid = { #region + show : false, + snap : false, + size : [ 16, 16 ], + opacity : 0.5, + color : COLORS.panel_preview_grid, + } #endregion + + graphGrid = { #region + show : true, + show_origin : false, + snap : true, + size : 16, + opacity : 0.05, + color : c_white, + highlight : 12, + } #endregion + + addons = {}; + + onion_skin = { #region + enabled: false, + range: [ -1, 1 ], + step: 1, + color: [ c_red, c_blue ], + alpha: 0.5, + on_top: true, + }; #endregion + + #region =================== ATTRIBUTES =================== + attributes = { + strict : false, + surface_dimension : [ 32, 32 ], + palette : [ cola(c_black), cola(c_white) ], + palette_fix : false, + } + + attributeEditor = [ + [ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; RENDER_ALL return true; }), + function(junc) { + if(!is_struct(junc)) return; + if(!is_instanceof(junc, NodeValue)) return; + + var attr = attributes.surface_dimension; + var _val = junc.getValue(); + var _res = [ attr[0], attr[1] ]; + + switch(junc.type) { + case VALUE_TYPE.float : + case VALUE_TYPE.integer : + if(is_real(_val)) + _res = [ _val, _val ]; + else if(is_array(_val) && array_length(_val) >= 2) { + _res[0] = is_real(_val[0])? _val[0] : 1; + _res[1] = is_real(_val[1])? _val[1] : 1; + } + break; + + case VALUE_TYPE.surface : + if(is_array(_val)) _val = array_safe_get_fast(_val, 0); + if(is_surface(_val)) + _res = surface_get_dimension(_val); + break; + } + + attr[0] = _res[0]; + attr[1] = _res[1]; + } ], + + [ "Palette", "palette", new buttonPalette(function(pal) { setPalette(pal); RENDER_ALL return true; }), + function(junc) { + if(!is_struct(junc)) return; + if(!is_instanceof(junc, NodeValue)) return; + if(junc.type != VALUE_TYPE.color) return; + if(junc.display_type != VALUE_DISPLAY.palette) return; + + setPalette(junc.getValue()); + } + ], + + [ "Strict", "strict", new checkBox(function() { attributes.strict = !attributes.strict; RENDER_ALL return true; }), function() {} ], + ]; + + static setPalette = function(pal = noone) { + if(pal != noone) attributes.palette = pal; + palettes = paletteToArray(attributes.palette); + } setPalette(); + #endregion + + timelines = new timelineItemGroup(); + + notes = []; + + static cleanup = function() { #region + if(!ds_map_empty(nodeMap)) + array_map(ds_map_keys_to_array(nodeMap), function(_key, _ind) { + var _node = nodeMap[? _key]; + _node.active = false; + _node.cleanUp(); + }); + + ds_list_destroy(nodes); + ds_map_destroy(nodeMap); + ds_map_destroy(nodeNameMap); + + gc_collect(); + } #endregion + + static toString = function() { return $"ProjectObject [{path}]"; } + } + + function __initProject() { + PROJECT = new Project(); + PROJECTS = [ PROJECT ]; + } +#endregion \ No newline at end of file diff --git a/#backups/scripts/save_function/save_function.gml.backup0 b/#backups/scripts/save_function/save_function.gml.backup0 new file mode 100644 index 000000000..66867428c --- /dev/null +++ b/#backups/scripts/save_function/save_function.gml.backup0 @@ -0,0 +1,232 @@ +// 2024-04-23 16:48:30 +globalvar SAVING; +SAVING = false; + +function NEW() { #region + CALL("new"); + + PROJECT = new Project(); + array_push(PROJECTS, PROJECT); + + var graph = new Panel_Graph(PROJECT); + PANEL_GRAPH.panel.setContent(graph, true); + PANEL_GRAPH = graph; +} #endregion + +function save_serialize(project = PROJECT, _outMap = false) { #region + var _map = {}; + _map.version = SAVE_VERSION; + + var _node_list = []; + var _key = ds_map_find_first(project.nodeMap); + + repeat(ds_map_size(project.nodeMap)) { + var _node = project.nodeMap[? _key]; + + if(_node.active) + array_push(_node_list, _node.serialize()); + + _key = ds_map_find_next(project.nodeMap, _key); + } + _map.nodes = _node_list; + + var _anim_map = {}; + _anim_map.frames_total = project.animator.frames_total; + _anim_map.framerate = project.animator.framerate; + _anim_map.frame_range = project.animator.frame_range; + _map.animator = _anim_map; + + _map.metadata = PROJECT.meta.serialize(); + _map.global_node = project.globalNode.serialize(); + _map.onion_skin = project.onion_skin; + + _map.previewGrid = project.previewGrid; + _map.graphGrid = project.graphGrid; + _map.attributes = project.attributes; + + _map.timelines = project.timelines.serialize(); + _map.notes = array_map(project.notes, function(note) { return note.serialize(); } ); + + var prev = PANEL_PREVIEW.getNodePreviewSurface(); + if(!is_surface(prev)) _map.preview = ""; + else _map.preview = surface_encode(surface_size_lim(prev, 128, 128)); + + var _addon = {}; + with(_addon_custom) { + var _ser = lua_call(thread, "serialize"); + _addon[$ name] = PREFERENCES.save_file_minify? json_stringify_minify(_ser) : json_stringify(_ser); + } + _map.addon = _addon; + + if(_outMap) return _map; + + return PREFERENCES.save_file_minify? json_stringify_minify(_map) : json_stringify(_map, true); +} #endregion + +function SET_PATH(project, path) { #region + if(path == "") { + project.readonly = false; + } else if(!project.readonly) { + ds_list_remove(RECENT_FILES, path); + ds_list_insert(RECENT_FILES, 0, path); + while(ds_list_size(RECENT_FILES) > 64) + ds_list_delete(RECENT_FILES, ds_list_size(RECENT_FILES) - 1); + RECENT_SAVE(); + RECENT_REFRESH(); + //project.path = filename_name(path); + } + + project.path = path; +} #endregion + +function SAVE_ALL() { #region + for( var i = 0, n = array_length(PROJECTS); i < n; i++ ) + SAVE(PROJECTS[i]); +} #endregion + +function SAVE(project = PROJECT) { #region + if(DEMO) return false; + + if(project.path == "" || project.readonly) + return SAVE_AS(project); + return SAVE_AT(project, project.path); +} #endregion + +function SAVE_AS(project = PROJECT) { #region + if(DEMO) return false; + + var path = get_save_filename("Pixel Composer project (.pxc)|*.pxc|Compressed Pixel Composer project (.cpxc)|*.cpxc", ""); + key_release(); + if(path == "") return false; + + if(filename_ext(path) != ".pxc" && filename_ext(path) != ".cpxc") + path += ".pxc"; + + if(file_exists_empty(path)) + log_warning("SAVE", "Overrided file : " + path); + SAVE_AT(project, path); + SET_PATH(project, path); + + return true; +} #endregion + +function SAVE_AT(project = PROJECT, path = "", log = "save at ") { #region + CALL("save"); + + if(DEMO) return false; + + SAVING = true; + //if(TESTING && string_char_at(filename_name(path), 1) != "[") + // path = $"{filename_dir(path)}/[{VERSION_STRING}] {filename_name(path)}"; + + if(file_exists_empty(path)) file_delete(path); + var _ext = filename_ext(path); + if(_ext == ".pxc") file_text_write_all(path, save_serialize(project)); + else if(_ext == ".cpxc") buffer_save(buffer_compress_string(save_serialize(project)), path); + + SAVING = false; + project.readonly = false; + project.modified = false; + + log_message("FILE", log + path, THEME.noti_icon_file_save); + PANEL_MENU.setNotiIcon(THEME.noti_icon_file_save); + + return true; +} #endregion + +/////////////////////////////////////////////////////// COLLECTION /////////////////////////////////////////////////////// + +function SAVE_COLLECTIONS(_list, _path, save_surface = true, metadata = noone, context = PANEL_GRAPH.getCurrentContext()) { #region + var _content = {}; + _content.version = SAVE_VERSION; + + var _nodes = []; + var cx = 0; + var cy = 0; + for(var i = 0; i < ds_list_size(_list); i++) { + cx += _list[| i].x; + cy += _list[| i].y; + } + cx = round((cx / ds_list_size(_list)) / 32) * 32; + cy = round((cy / ds_list_size(_list)) / 32) * 32; + + if(save_surface) { + var preview_surface = PANEL_PREVIEW.getNodePreviewSurface(); + if(is_surface(preview_surface)) { + var icon_path = string_copy(_path, 1, string_length(_path) - 5) + ".png"; + surface_save_safe(preview_surface, icon_path); + } + } + + for(var i = 0; i < ds_list_size(_list); i++) + SAVE_NODE(_nodes, _list[| i], cx, cy, true, context); + _content.nodes = _nodes; + + json_save_struct(_path, _content, !PREFERENCES.save_file_minify); + + if(metadata != noone) { + var _meta = metadata.serialize(); + var _dir = filename_dir(_path); + var _name = filename_name_only(_path); + var _mpath = $"{_dir}/{_name}.meta"; + + json_save_struct(_mpath, _meta, true); + } + + var pane = findPanel("Panel_Collection"); + if(pane) pane.refreshContext(); + + log_message("COLLECTION", "save collection at " + _path, THEME.noti_icon_file_save); + PANEL_MENU.setNotiIcon(THEME.noti_icon_file_save); +} #endregion + +function SAVE_COLLECTION(_node, _path, save_surface = true, metadata = noone, context = PANEL_GRAPH.getCurrentContext()) { #region + if(save_surface) { + var preview_surface = PANEL_PREVIEW.getNodePreviewSurface(); + if(is_surface(preview_surface)) { + var icon_path = string_replace(_path, filename_ext(_path), "") + ".png"; + surface_save_safe(preview_surface, icon_path); + } + } + + var _content = {}; + _content.version = SAVE_VERSION; + + var _nodes = []; + SAVE_NODE(_nodes, _node, _node.x, _node.y, true, context); + _content.nodes = _nodes; + + json_save_struct(_path, _content, !PREFERENCES.save_file_minify); + + if(metadata != noone) { + var _meta = metadata.serialize(); + var _dir = filename_dir(_path); + var _name = filename_name_only(_path); + var _mpath = $"{_dir}/{_name}.meta"; + + _meta.version = SAVE_VERSION; + json_save_struct(_mpath, _meta, true); + } + + var pane = findPanel("Panel_Collection"); + if(pane) pane.refreshContext(); + + log_message("COLLECTION", "save collection at " + _path, THEME.noti_icon_file_save); + PANEL_MENU.setNotiIcon(THEME.noti_icon_file_save); +} #endregion + +function SAVE_NODE(_arr, _node, dx = 0, dy = 0, scale = false, context = PANEL_GRAPH.getCurrentContext()) { #region + if(struct_has(_node, "nodes")) { + for(var i = 0; i < ds_list_size(_node.nodes); i++) + SAVE_NODE(_arr, _node.nodes[| i], dx, dy, scale, context); + } + + var m = _node.serialize(scale); + m.x -= dx; + m.y -= dy; + + var c = context == noone? noone : context.node_id; + if(m.group == c) m.group = noone; + + array_push(_arr, m); +} #endregion \ No newline at end of file diff --git a/#backups/scripts/save_function/save_function.gml.backup1 b/#backups/scripts/save_function/save_function.gml.backup1 new file mode 100644 index 000000000..8d5b4811b --- /dev/null +++ b/#backups/scripts/save_function/save_function.gml.backup1 @@ -0,0 +1,232 @@ +// 2024-04-23 16:48:01 +globalvar SAVING; +SAVING = false; + +function NEW() { #region + CALL("new"); + + PROJECT = new Project(); + array_push(PROJECTS, PROJECT); + + var graph = new Panel_Graph(PROJECT); + PANEL_GRAPH.panel.setContent(graph, true); + PANEL_GRAPH = graph; +} #endregion + +function save_serialize(project = PROJECT, _outMap = false) { #region + var _map = {}; + _map.version = SAVE_VERSION; + + var _node_list = []; + var _key = ds_map_find_first(project.nodeMap); + + repeat(ds_map_size(project.nodeMap)) { + var _node = project.nodeMap[? _key]; + + if(_node.active) + array_push(_node_list, _node.serialize()); + + _key = ds_map_find_next(project.nodeMap, _key); + } + _map.nodes = _node_list; + + var _anim_map = {}; + _anim_map.frames_total = project.animator.frames_total; + _anim_map.framerate = project.animator.framerate; + _anim_map.frame_range = project.animator.frame_range; + _map.animator = _anim_map; + + _map.metadata = PROJECT.meta.serialize(); + _map.global_node = project.globalNode.serialize(); + _map.onion_skin = project.onion_skin; + + _map.previewGrid = project.previewGrid; + _map.graphGrid = project.graphGrid; + _map.attributes = project.attributes; + + _map.timelines = project.timelines.serialize(); + _map.notes = array_map(project.notes, function(note) { return note.serialize(); } ); + + var prev = PANEL_PREVIEW.getNodePreviewSurface(); + if(!is_surface(prev)) _map.preview = ""; + else _map.preview = surface_encode(surface_size_lim(prev, 128, 128)); + + var _addon = {}; + with(_addon_custom) { + var _ser = lua_call(thread, "serialize"); + _addon[$ name] = PREFERENCES.save_file_minify? json_stringify_minify(_ser) : json_stringify(_ser); + } + _map.addon = _addon; + + if(_outMap) return _map; + + return PREFERENCES.save_file_minify? json_stringify_minify(_map) : json_stringify(_map, true); +} #endregion + +function SET_PATH(project, path) { #region + if(path == "") { + project.readonly = false; + } else if(!project.readonly) { + ds_list_remove(RECENT_FILES, path); + ds_list_insert(RECENT_FILES, 0, path); + while(ds_list_size(RECENT_FILES) > 64) + ds_list_delete(RECENT_FILES, ds_list_size(RECENT_FILES) - 1); + RECENT_SAVE(); + RECENT_REFRESH(); + //project.path = filename_name(path); + } + + project.path = path; +} #endregion + +function SAVE_ALL() { #region + for( var i = 0, n = array_length(PROJECTS); i < n; i++ ) + SAVE(PROJECTS[i]); +} #endregion + +function SAVE(project = PROJECT) { #region + if(DEMO) return false; + + if(project.path == "" || project.readonly) + return SAVE_AS(project); + return SAVE_AT(project, project.path); +} #endregion + +function SAVE_AS(project = PROJECT) { #region + if(DEMO) return false; + + var path = get_save_filename("Pixel Composer project (.pxc)|*.pxc|Compressed Pixel Composer project (.cpxc)|*.cpxc", ""); + key_release(); + if(path == "") return false; + + if(filename_ext(path) != ".pxc" && filename_ext(path) != ".cpxc") + path += ".pxc"; + + if(file_exists_empty(path)) + log_warning("SAVE", "Overrided file : " + path); + SAVE_AT(project, path); + SET_PATH(project, path); + + return true; +} #endregion + +function SAVE_AT(project = PROJECT, path = "", log = "save at ") { #region + CALL("save"); + + if(DEMO) return false; + + SAVING = true; + //if(TESTING && string_char_at(filename_name(path), 1) != "[") + // path = $"{filename_dir(path)}/[{VERSION_STRING}] {filename_name(path)}"; + + if(file_exists_empty(path)) file_delete(path); + var _ext = filename_ext(path); + if(_ext == ".pxc") file_text_write_all(path, save_serialize(project)); + else if(_ext == ".cpxc") buffer_save(buffer_compress_string(save_serialize(project)), path); + + SAVING = false; + project.readonly = false; + project.modified = false; + + log_message("FILE", log + path, THEME.noti_icon_file_save); + PANEL_MENU.setNotiIcon(THEME.noti_icon_file_save); + + return true; +} #endregion + +/////////////////////////////////////////////////////// COLLECTION /////////////////////////////////////////////////////// + +function SAVE_COLLECTIONS(_list, _path, save_surface = true, metadata = noone, context = PANEL_GRAPH.getCurrentContext()) { #region + var _content = {}; + _content.version = SAVE_VERSION; + + var _nodes = []; + var cx = 0; + var cy = 0; + for(var i = 0; i < ds_list_size(_list); i++) { + cx += _list[| i].x; + cy += _list[| i].y; + } + cx = round((cx / ds_list_size(_list)) / 32) * 32; + cy = round((cy / ds_list_size(_list)) / 32) * 32; + + if(save_surface) { + var preview_surface = PANEL_PREVIEW.getNodePreviewSurface(); + if(is_surface(preview_surface)) { + var icon_path = string_copy(_path, 1, string_length(_path) - 5) + ".png"; + surface_save_safe(preview_surface, icon_path); + } + } + + for(var i = 0; i < ds_list_size(_list); i++) + SAVE_NODE(_nodes, _list[| i], cx, cy, true, context); + _content.nodes = _nodes; + + json_save_struct(_path, _content, !PREFERENCES.save_file_minify); + + if(metadata != noone) { + var _meta = metadata.serialize(); + var _dir = filename_dir(_path); + var _name = filename_name_only(_path); + var _mpath = $"{_dir}/{_name}.meta"; + + json_save_struct(_mpath, _meta, true); + } + + var pane = findPanel("Panel_Collection"); + if(pane) pane.refreshContext(); + + log_message("COLLECTION", "save collection at " + _path, THEME.noti_icon_file_save); + PANEL_MENU.setNotiIcon(THEME.noti_icon_file_save); +} #endregion + +function SAVE_COLLECTION(_node, _path, save_surface = true, metadata = noone, context = PANEL_GRAPH.getCurrentContext()) { #region + if(save_surface) { + var preview_surface = PANEL_PREVIEW.getNodePreviewSurface(); + if(is_surface(preview_surface)) { + var icon_path = string_replace(_path, filename_ext(_path), "") + ".png"; + surface_save_safe(preview_surface, icon_path); + } + } + + var _content = {}; + _content.version = SAVE_VERSION; + + var _nodes = []; + SAVE_NODE(_nodes, _node, _node.x, _node.y, true, context); + _content.nodes = _nodes; + + json_save_struct(_path, _content, !PREFERENCES.save_file_minify); + + if(metadata != noone) { + var _meta = metadata.serialize(); + var _dir = filename_dir(_path); + var _name = filename_name_only(_path); + var _mpath = $"{_dir}/{_name}.meta"; + + _meta.version = SAVE_VERSION; + json_save_struct(_mpath, _meta, true); + } + + var pane = findPanel("Panel_Collection"); + if(pane) pane.refreshContext(); + + log_message("COLLECTION", "save collection at " + _path, THEME.noti_icon_file_save); + PANEL_MENU.setNotiIcon(THEME.noti_icon_file_save); +} #endregion + +function SAVE_NODE(_arr, _node, dx = 0, dy = 0, scale = false, context = PANEL_GRAPH.getCurrentContext()) { #region + if(struct_has(_node, "nodes")) { + for(var i = 0; i < ds_list_size(_node.nodes); i++) + SAVE_NODE(_arr, _node.nodes[| i], dx, dy, scale, context); + } + + var m = _node.serialize(scale); + m.x -= dx; + m.y -= dy; + + var c = context == noone? noone : context.node_id; + if(m.group == c) m.group = noone; + + array_push(_arr, m); +} #endregion \ No newline at end of file diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 91fe2131d..98713562c 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -937,6 +937,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { static refreshNodeDisplay = function() { #region INLINE + if(IS_PLAYING) return; updateIO(); setHeight(); @@ -1445,17 +1446,17 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { var ph = surface_get_height_safe(preview_surface); var format = surface_get_format_safe(preview_surface); - var txt = $"[{pw} x {ph} "; + var txt = $"[{pw} x {ph}"; if(preview_amount) txt = $"{preview_amount} x {txt}"; switch(format) { - case surface_rgba4unorm : txt += showFormat? "4RGBA" : "4R"; break; - case surface_rgba8unorm : txt += showFormat? "8RGBA" : "8R"; break; - case surface_rgba16float : txt += showFormat? "16RGBA" : "16R"; break; - case surface_rgba32float : txt += showFormat? "32RGBA" : "32R"; break; - case surface_r8unorm : txt += showFormat? "8BW" : "8B"; break; - case surface_r16float : txt += showFormat? "16BW" : "16B"; break; - case surface_r32float : txt += showFormat? "32BW" : "32B"; break; + case surface_rgba8unorm : break; + case surface_rgba4unorm : txt += showFormat? " 4RGBA" : " 4R"; break; + case surface_rgba16float : txt += showFormat? " 16RGBA" : " 16R"; break; + case surface_rgba32float : txt += showFormat? " 32RGBA" : " 32R"; break; + case surface_r8unorm : txt += showFormat? " 8BW" : " 8B"; break; + case surface_r16float : txt += showFormat? " 16BW" : " 16B"; break; + case surface_r32float : txt += showFormat? " 32BW" : " 32B"; break; } txt += "]"; @@ -1468,32 +1469,33 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { if(!active) return; if(_s * w < 64) return; - draw_set_text(f_p2, fa_center, fa_top, COLORS.panel_graph_node_dimension); + draw_set_text(f_p3, fa_center, fa_top, COLORS.panel_graph_node_dimension); var tx = xx + w * _s / 2; var ty = yy + (h + 4) * _s - 2; if(struct_get(display_parameter, "show_dimension")) { var txt = string(getNodeDimension(_s > 0.65)); draw_text(round(tx), round(ty), txt); - ty += line_get_height(f_p2) - 2; + ty += string_height(txt) - 2; } - draw_set_font(f_p3); - if(struct_get(display_parameter, "show_compute")) { var rt = 0, unit = ""; if(render_time == 0) { draw_set_color(COLORS._main_text_sub); unit = "us"; + } else if(render_time < 1000) { rt = round(render_time / 10) * 10; unit = "us"; draw_set_color(COLORS.speed[2]); + } else if(render_time < 1000000) { rt = string_format(render_time / 1000, -1, 2); unit = "ms"; draw_set_color(COLORS.speed[1]); + } else { rt = string_format(render_time / 1000000, -1, 2); unit = "s"; @@ -1502,7 +1504,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { if(render_cached) draw_set_color(COLORS._main_text_sub); - draw_text(round(tx), round(ty), string(rt) + " " + unit); + draw_text(round(tx), round(ty), $"{rt} {unit}"); } } #endregion diff --git a/scripts/node_keyframe/node_keyframe.gml b/scripts/node_keyframe/node_keyframe.gml index 2f5f1e812..71f30d675 100644 --- a/scripts/node_keyframe/node_keyframe.gml +++ b/scripts/node_keyframe/node_keyframe.gml @@ -427,6 +427,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { static processType = function(_val) { #region INLINE + if(PROJECT.attributes.strict) return _val; var _res = _val; if(!sep_axis && typeArray(prop.display_type) && is_array(_val)) { @@ -443,7 +444,6 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { if(is_array(_val)) return _val; if(is_struct(_val)) return _val; - //if(is_undefined(_val)) return 0; switch(prop.type) { case VALUE_TYPE.integer : return prop.unit.mode == VALUE_UNIT.constant? round(_val) : _val; diff --git a/scripts/node_pin/node_pin.gml b/scripts/node_pin/node_pin.gml index 695ec9da4..0dad121d5 100644 --- a/scripts/node_pin/node_pin.gml +++ b/scripts/node_pin/node_pin.gml @@ -95,7 +95,7 @@ function Node_Pin(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { if(renamed && display_name != "" && display_name != "Pin") { draw_set_text(f_sdf, fa_center, fa_bottom, COLORS._main_text); - draw_text_transformed(xx, yy - 12, display_name, _s * 0.4, _s * 0.4, 0); + draw_text_transformed(xx, yy - 12 * _s, display_name, _s * 0.4, _s * 0.4, 0); } return drawJunctions(_x, _y, _mx, _my, _s); diff --git a/scripts/node_tunnel_in/node_tunnel_in.gml b/scripts/node_tunnel_in/node_tunnel_in.gml index 292bb63dc..b3c4d3bba 100644 --- a/scripts/node_tunnel_in/node_tunnel_in.gml +++ b/scripts/node_tunnel_in/node_tunnel_in.gml @@ -244,7 +244,7 @@ function Node_Tunnel_In(_x, _y, _group = noone) : Node(_x, _y, _group) construct hover_scale_to = 0; draw_set_text(f_sdf, fa_center, fa_bottom, COLORS._main_text); - draw_text_transformed(xx, yy - 12, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); + draw_text_transformed(xx, yy - 12 * _s, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); return drawJunctions(_x, _y, _mx, _my, _s); } #endregion diff --git a/scripts/node_tunnel_out/node_tunnel_out.gml b/scripts/node_tunnel_out/node_tunnel_out.gml index 8ea75991a..5202a57fe 100644 --- a/scripts/node_tunnel_out/node_tunnel_out.gml +++ b/scripts/node_tunnel_out/node_tunnel_out.gml @@ -178,7 +178,7 @@ function Node_Tunnel_Out(_x, _y, _group = noone) : Node(_x, _y, _group) construc hover_scale_to = 0; draw_set_text(f_sdf, fa_center, fa_bottom, COLORS._main_text); - draw_text_transformed(xx, yy - 12, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); + draw_text_transformed(xx, yy - 12 * _s, string(inputs[| 0].getValue()), _s * 0.4, _s * 0.4, 0); return drawJunctions(_x, _y, _mx, _my, _s); } #endregion diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 3d9efbb51..d86d19067 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -525,6 +525,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru #region ---- main ---- active = true; + from = noone; node = _node; x = node.x; y = node.y; @@ -1614,7 +1615,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru static getStaticValue = function() { INLINE return ds_list_empty(animator.values)? 0 : animator.values[| 0].value; } - static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { #region + static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { #region //Get value if(type == VALUE_TYPE.trigger) return _getValue(_time, false, 0, false); @@ -1661,36 +1662,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru return val; } #endregion - static __getAnimValue = function(_time = CURRENT_FRAME) { #region - - if(value_tag == "dimension" && node.attributes.use_project_dimension) - return PROJECT.attributes.surface_dimension; - - if(!is_anim) { - if(sep_axis) { - if(ds_list_empty(animators[i].values)) return 0; - - var val = array_verify(val, array_length(animators)); - for( var i = 0, n = array_length(animators); i < n; i++ ) - val[i] = animators[i].processType(animators[i].values[| 0].value); - return val; - } - - if(ds_list_empty(animator.values)) return 0; - - return animator.processType(animator.values[| 0].value); - } - - if(sep_axis) { - var val = []; - for( var i = 0, n = array_length(animators); i < n; i++ ) - val[i] = animators[i].getValue(_time); - return val; - } - - return animator.getValue(_time); - } #endregion - static arrayBalance = function(val) { #region // Balance array (generate uniform array from single values) if(!is_array(def_val)) return val; @@ -1773,6 +1744,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } } #endregion + if(PROJECT.attributes.strict) return val; + val = arrayBalance(val); if(isArray(val) && array_length(val) < 1024) { #region Process data @@ -1825,6 +1798,36 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } } #endregion + static __getAnimValue = function(_time = CURRENT_FRAME) { #region + + if(value_tag == "dimension" && node.attributes.use_project_dimension) + return PROJECT.attributes.surface_dimension; + + if(!is_anim) { + if(sep_axis) { + if(ds_list_empty(animators[i].values)) return 0; + + var val = array_verify(val, array_length(animators)); + for( var i = 0, n = array_length(animators); i < n; i++ ) + val[i] = animators[i].processType(animators[i].values[| 0].value); + return val; + } + + if(ds_list_empty(animator.values)) return 0; + + return animator.processType(animator.values[| 0].value); + } + + if(sep_axis) { + var val = []; + for( var i = 0, n = array_length(animators); i < n; i++ ) + val[i] = animators[i].getValue(_time); + return val; + } + + return animator.getValue(_time); + } #endregion + static setAnim = function(anim, record = false) { #region if(is_anim == anim) return; if(record) { @@ -2142,9 +2145,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru static isRendered = function() { #region if(type == VALUE_TYPE.node) return true; - if( value_from == noone) return true; + if(value_from == noone) return true; - var controlNode = struct_has(value_from, "from")? value_from.from : value_from.node; + var controlNode = value_from.from? value_from.from : value_from.node; if(!controlNode.active) return true; if(!controlNode.isRenderActive()) return true; diff --git a/scripts/project_data/project_data.gml b/scripts/project_data/project_data.gml index 3f5da919c..cfa24a08b 100644 --- a/scripts/project_data/project_data.gml +++ b/scripts/project_data/project_data.gml @@ -58,13 +58,14 @@ #region =================== ATTRIBUTES =================== attributes = { + strict : false, surface_dimension : [ 32, 32 ], palette : [ cola(c_black), cola(c_white) ], palette_fix : false, } attributeEditor = [ - [ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; RENDER_ALL return true; }), + [ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; RENDER_ALL return true; }), function(junc) { if(!is_struct(junc)) return; if(!is_instanceof(junc, NodeValue)) return; @@ -95,7 +96,7 @@ attr[1] = _res[1]; } ], - [ "Palette", "palette", new buttonPalette(function(pal) { setPalette(pal); RENDER_ALL return true; }), + [ "Palette", "palette", new buttonPalette(function(pal) { setPalette(pal); RENDER_ALL return true; }), function(junc) { if(!is_struct(junc)) return; if(!is_instanceof(junc, NodeValue)) return; @@ -105,6 +106,8 @@ setPalette(junc.getValue()); } ], + + [ "Strict", "strict", new checkBox(function() { attributes.strict = !attributes.strict; RENDER_ALL return true; }), function() {} ], ]; static setPalette = function(pal = noone) { diff --git a/scripts/save_function/save_function.gml b/scripts/save_function/save_function.gml index d3edcb683..fd62fee90 100644 --- a/scripts/save_function/save_function.gml +++ b/scripts/save_function/save_function.gml @@ -44,7 +44,7 @@ function save_serialize(project = PROJECT, _outMap = false) { #region _map.attributes = project.attributes; _map.timelines = project.timelines.serialize(); - _map.notes = array_map(project.notes, function(note) { return node.serialize(); } ); + _map.notes = array_map(project.notes, function(note) { return note.serialize(); } ); var prev = PANEL_PREVIEW.getNodePreviewSurface(); if(!is_surface(prev)) _map.preview = "";