From 0664451464fa0b2558e87cbe03f2b0bf1ba16b76 Mon Sep 17 00:00:00 2001 From: Tanasart <22589759+Ttanasart-pt@users.noreply.github.com> Date: Tue, 13 Jun 2023 21:24:05 +0200 Subject: [PATCH] Logic opr, bitwise and comparator in equation evaluators --- objects/o_main/Step_0.gml | 2 +- scripts/directory_object/directory_object.gml | 2 + scripts/node_boolean/node_boolean.gml | 65 +++++++- scripts/node_data/node_data.gml | 8 +- .../node_logic_operate/node_logic_operate.gml | 142 ++++++++++++++++-- scripts/panel_graph/panel_graph.gml | 2 + .../panel_graph_export_image_dialog.gml | 2 +- scripts/string_eval/string_eval.gml | 124 +++++++++++---- scripts/string_eval_tree/string_eval_tree.gml | 46 ++++-- 9 files changed, 334 insertions(+), 59 deletions(-) diff --git a/objects/o_main/Step_0.gml b/objects/o_main/Step_0.gml index a217eb388..643daf23a 100644 --- a/objects/o_main/Step_0.gml +++ b/objects/o_main/Step_0.gml @@ -153,7 +153,7 @@ if(OS == os_windows && gameframe_is_minimized()) exit; #endregion #region tween - tweenStep(); + //tweenStep(); #endregion //print("===== Step end ====="); diff --git a/scripts/directory_object/directory_object.gml b/scripts/directory_object/directory_object.gml index 24cf38d86..92e11ca39 100644 --- a/scripts/directory_object/directory_object.gml +++ b/scripts/directory_object/directory_object.gml @@ -22,6 +22,7 @@ function FileObject(_name, _path) constructor { retrive_data = false; thumbnail_data = -1; thumbnail = noone; + size = file_size(path); static getName = function() { return name; } @@ -33,6 +34,7 @@ function FileObject(_name, _path) constructor { } static getThumbnail = function() { + if(size > 100000) return noone; if(!retrive_data) getMetadata(); if(thumbnail_data == -1) return noone; diff --git a/scripts/node_boolean/node_boolean.gml b/scripts/node_boolean/node_boolean.gml index a8d75ab4e..6d4800a8e 100644 --- a/scripts/node_boolean/node_boolean.gml +++ b/scripts/node_boolean/node_boolean.gml @@ -3,8 +3,10 @@ function Node_Boolean(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c color = COLORS.node_blend_number; previewable = false; - w = 96; - min_h = 32 + 24 * 1; + w = 64; + min_h = 64; + hover_state = 0; + hover_state_to = 0; wd_checkBox = new checkBox( function() { inputs[| 0].setValue(!inputs[| 0].getValue()); } ); wd_checkBox.spr = THEME.node_checkbox; @@ -12,18 +14,75 @@ function Node_Boolean(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c inputs[| 0] = nodeValue("Value", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) .setVisible(true, true); + inputs[| 1] = nodeValue("Hide Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 2] = nodeValue("Name location", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1) + .setDisplay(VALUE_DISPLAY.enum_button, [ "Top", "Bottom" ]); + outputs[| 0] = nodeValue("Boolean", self, JUNCTION_CONNECT.output, VALUE_TYPE.boolean, false); + input_display_list = [ 0, + ["Display", false], 1, 2, + ] + function process_data(_output, _data, _output_index, _array_index = 0) { return _data[0]; } + static pointIn = function(_x, _y, _mx, _my, _s) { + var align = inputs[| 2].getValue(); + var xx = x * _s + _x; + var yy = (y - (!align * 20)) * _s + _y; + + return point_in_rectangle(_mx, _my, xx, yy, xx + w * _s, yy + (h + 20) * _s); + } + + static onDrawHover = function(xx, yy, _mx, _my, _s, _hover = false, _focus = false) { + hover_state_to = 1; + } + + static drawNodeBase = function(xx, yy, _s) { + if(!active) return; + var hid = inputs[| 1].getValue(); + + if(hid) { + hover_state = lerp_float(hover_state, hover_state_to, 3); + hover_state_to = 0; + } else + hover_state = 1; + + var aa = (0.25 + 0.5 * renderActive) * hover_state; + draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, color, aa); + } + + static drawNodeName = function(xx, yy, _s) { + draw_name = false; + if(!active) return; + if(_s < 0.75) return; + + var _name = display_name == ""? name : display_name; + if(_name == "") return; + + var hid = inputs[| 1].getValue(); + var align = inputs[| 2].getValue(); + + if(align == 0) { + draw_set_text(f_p2, fa_center, fa_bottom, COLORS._main_text); + draw_text_ext_add(xx + w * _s / 2, yy - 2 + hid * ((1 - hover_state) * 8), _name, -1, 128 * _s); + } else if(align == 1) { + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text); + draw_text_ext_add(xx + w * _s / 2, yy + h * _s - hid * ((1 - hover_state) * 8), _name, -1, 128 * _s); + } + } + + static drawDimension = function(xx, yy, _s) {} + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { draw_set_text(f_h5, fa_center, fa_center, COLORS._main_text); var val = inputs[| 0].getValue(); var bbox = drawGetBbox(xx, yy, _s); wd_checkBox.setActiveFocus(_focus, _hover); - wd_checkBox.draw(bbox.xc, bbox.yc, val, [ _mx, _my ], bbox.h + 8 * _s, fa_center, fa_center); + wd_checkBox.draw(bbox.xc, bbox.yc, val, [ _mx, _my ], bbox.h - 8 * _s, fa_center, fa_center); } } diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 3df379629..f798b837b 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -746,11 +746,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x thicken |= _active && PANEL_GRAPH.junction_hovering == jun && PANEL_GRAPH._junction_hovering == noone; thicken |= instance_exists(o_dialog_add_node) && o_dialog_add_node.junction_hovering == jun; - if(PREF_MAP[? "connection_line_transition"]) { - jun.draw_line_thick.set(thicken? 2 : 1); - th *= jun.draw_line_thick.get(); - } else - th *= thicken? 2 : 1; + th *= thicken? 2 : 1; var corner = PREF_MAP[? "connection_line_corner"] * _s; var ty = LINE_STYLE.solid; @@ -967,6 +963,8 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x static onDrawNode = function(xx, yy, _mx, _my, _s, _hover = false, _focus = false) {} + static onDrawHover = function(_x, _y, _mx, _my, _s) {} + badgePreview = 0; badgeInspect = 0; static drawBadge = function(_x, _y, _s) { diff --git a/scripts/node_logic_operate/node_logic_operate.gml b/scripts/node_logic_operate/node_logic_operate.gml index dda7f9b9d..8e8cc38a8 100644 --- a/scripts/node_logic_operate/node_logic_operate.gml +++ b/scripts/node_logic_operate/node_logic_operate.gml @@ -38,16 +38,110 @@ function Node_Logic(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { inputs[| 1] = nodeValue("a", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) .setVisible(true, true); - - inputs[| 2] = nodeValue("b", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) - .setVisible(true, true); - + input_display_list = [ - 0, 1, 2, + 0, 1, ] outputs[| 0] = nodeValue("Result", self, JUNCTION_CONNECT.output, VALUE_TYPE.boolean, false); + input_fix_len = ds_list_size(inputs); + input_display_len = array_length(input_display_list); + data_length = 1; + + function createNewInput() { + print("Create") + var index = ds_list_size(inputs); + + var jname = chr(ord("a") + index - 1); + inputs[| index] = nodeValue(jname, self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false ) + .setVisible(true, true); + + array_push(input_display_list, index); + return inputs[| index]; + } + + if!(LOADING || APPENDING) + createNewInput(); + + static refreshDynamicInput = function() { + 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 ) { + if(inputs[| i].value_from) { + ds_list_add(_in, inputs[| i]); + array_push(input_display_list, i); + } else + delete inputs[| i]; + } + + for( var i = 0; i < ds_list_size(_in); i++ ) + _in[| i].index = i; + + ds_list_destroy(inputs); + inputs = _in; + + createNewInput(); + } + + static trimInputs = function(amo) { + if(ds_list_size(inputs) < amo + 1) { + while(ds_list_size(inputs) < amo + 1) + createNewInput(); + } else { + while(ds_list_size(inputs) > amo + 1) + ds_list_delete(inputs, amo + 1); + } + array_resize(input_display_list, amo + 1); + } + + static onValueUpdate = function(index) { + if(index != 0) return; + + var mode = inputs[| 0].getValue(); + switch(mode) { + case LOGIC_OPERATOR.lnot : + trimInputs(1); + return; + case LOGIC_OPERATOR.lnand : + case LOGIC_OPERATOR.lnor : + case LOGIC_OPERATOR.lxor : + trimInputs(2); + return; + + case LOGIC_OPERATOR.land : + case LOGIC_OPERATOR.lor : + while(ds_list_size(inputs) < 3) + createNewInput(); + return; + } + } + + static onValueFromUpdate = function(index) { + if(LOADING || APPENDING) return; + + var mode = inputs[| 0].getValue(); + switch(mode) { + case LOGIC_OPERATOR.lnot : + trimInputs(1); + return; + case LOGIC_OPERATOR.lnand : + case LOGIC_OPERATOR.lnor : + case LOGIC_OPERATOR.lxor : + trimInputs(2); + return; + } + + if(index < input_fix_len) return; + + refreshDynamicInput(); + } + static _eval = function(mode, a, b) { switch(mode) { case LOGIC_OPERATOR.land : return bool(a) && bool(b); @@ -56,7 +150,7 @@ function Node_Logic(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { case LOGIC_OPERATOR.lnand : return !(bool(a) && bool(b)); case LOGIC_OPERATOR.lnor : return !(bool(a) || bool(b)); - case LOGIC_OPERATOR.lxor : return bool(a) ^^ bool(b); + case LOGIC_OPERATOR.lxor : return bool(a) ^^ bool(b); } return false; } @@ -64,10 +158,10 @@ function Node_Logic(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { static step = function() { var mode = inputs[| 0].getValue(); - inputs[| 2].setVisible(mode != LOGIC_OPERATOR.lnot, mode != LOGIC_OPERATOR.lnot); + //inputs[| 2].setVisible(mode != LOGIC_OPERATOR.lnot, mode != LOGIC_OPERATOR.lnot); } - function evalLogicArray(mode, a, b) { + function evalLogicArray(mode, a, b = false) { var as = is_array(a); var bs = is_array(b); @@ -93,8 +187,29 @@ function Node_Logic(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { function update(frame = ANIMATOR.current_frame) { var mode = inputs[| 0].getValue(); var a = inputs[| 1].getValue(); - var b = inputs[| 2].getValue(); - var val = evalLogicArray(mode, a, b); + var val; + + switch(mode) { + case LOGIC_OPERATOR.lnot : + val = evalLogicArray(mode, a); + break; + case LOGIC_OPERATOR.lnand : + case LOGIC_OPERATOR.lnor : + case LOGIC_OPERATOR.lxor : + var b = inputs[| 2].getValue(); + val = evalLogicArray(mode, a, b); + break; + + case LOGIC_OPERATOR.land : + case LOGIC_OPERATOR.lor : + var val = a; + var to = max(2, ds_list_size(inputs) - 1); + for( var i = 2; i < to; i++ ) { + var b = inputs[| i].getValue(); + val = evalLogicArray(mode, val, b); + } + } + outputs[| 0].setValue(val); } @@ -116,4 +231,11 @@ function Node_Logic(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { var ss = string_scale(str, bbox.w, bbox.h); draw_text_transformed(bbox.xc, bbox.yc, str, ss, ss, 0); } + + static postDeserialize = function() { + var _inputs = load_map.inputs; + + for(var i = input_fix_len; i < array_length(_inputs); i += data_length) + createNewInput(); + } } \ No newline at end of file diff --git a/scripts/panel_graph/panel_graph.gml b/scripts/panel_graph/panel_graph.gml index ca5516da1..e47c64daf 100644 --- a/scripts/panel_graph/panel_graph.gml +++ b/scripts/panel_graph/panel_graph.gml @@ -422,6 +422,8 @@ function Panel_Graph() : PanelContent() constructor { node_hovering = noone; } + + if(node_hovering) node_hovering.onDrawHover(gr_x, gr_y, mx, my, graph_s); #endregion //print("Hover time: " + string(current_time - t)); t = current_time; diff --git a/scripts/panel_graph_export_image_dialog/panel_graph_export_image_dialog.gml b/scripts/panel_graph_export_image_dialog/panel_graph_export_image_dialog.gml index 0d9ab44bb..c555c5213 100644 --- a/scripts/panel_graph_export_image_dialog/panel_graph_export_image_dialog.gml +++ b/scripts/panel_graph_export_image_dialog/panel_graph_export_image_dialog.gml @@ -56,7 +56,7 @@ function Panel_Graph_Export_Image(targetPanel) : PanelContent() constructor { var path = get_save_filename("*.png", "Screenshot"); if(path == -1) return; - if(!filename_ext(path) != ".png") path += ".png"; + if(filename_ext(path) != ".png") path += ".png"; surface_save(surface, path); noti_status($"Graph image exported at {path}"); }); diff --git a/scripts/string_eval/string_eval.gml b/scripts/string_eval/string_eval.gml index 6154c2f45..ae08b67ba 100644 --- a/scripts/string_eval/string_eval.gml +++ b/scripts/string_eval/string_eval.gml @@ -1,12 +1,29 @@ #region data global.EQUATION_PRES = ds_map_create(); - global.EQUATION_PRES[? "+"] = 1; - global.EQUATION_PRES[? "-"] = 1; - global.EQUATION_PRES[? "_"] = 9; //unary negative - global.EQUATION_PRES[? "*"] = 2; - global.EQUATION_PRES[? "/"] = 2; - global.EQUATION_PRES[? "^"] = 3; - global.EQUATION_PRES[? "|"] = 5; //array accerssor symbol + global.EQUATION_PRES[? "+"] = 1; + global.EQUATION_PRES[? "-"] = 1; + global.EQUATION_PRES[? "_"] = 9; //unary negative + global.EQUATION_PRES[? "*"] = 2; + global.EQUATION_PRES[? "/"] = 2; + global.EQUATION_PRES[? "$"] = 3; + + global.EQUATION_PRES[? "&"] = 5; + global.EQUATION_PRES[? "|"] = 4; + global.EQUATION_PRES[? "^"] = 3; + global.EQUATION_PRES[? "<"] = 3; + global.EQUATION_PRES[? "»"] = 6; + global.EQUATION_PRES[? "«"] = 6; + global.EQUATION_PRES[? "~"] = 9; + + global.EQUATION_PRES[? "="] = -1; //== + global.EQUATION_PRES[? "≠"] = -1; //!= + global.EQUATION_PRES[? "<"] = 0; + global.EQUATION_PRES[? ">"] = 0; + global.EQUATION_PRES[? "≤"] = 0; + global.EQUATION_PRES[? "≥"] = 0; + + global.EQUATION_PRES[? "@"] = 5; //array accerssor symbol + global.EQUATION_PRES[? "sin"] = 5; global.EQUATION_PRES[? "cos"] = 5; global.EQUATION_PRES[? "tan"] = 5; @@ -16,14 +33,31 @@ global.EQUATION_PRES[? "floor"] = 5; #endregion +function functionStringClean(fx) { + fx = string_replace_all(fx, " ", ""); + fx = string_replace_all(fx, "\n", ""); + fx = string_replace_all(fx, "**", "$"); + fx = string_replace_all(fx, "<<", "«"); + fx = string_replace_all(fx, ">>", "»"); + + fx = string_replace_all(fx, "==", "="); + fx = string_replace_all(fx, "!=", "≠"); + fx = string_replace_all(fx, "<>", "≠"); + fx = string_replace_all(fx, ">=", "≥"); + fx = string_replace_all(fx, "<=", "≤"); + + fx = string_replace_all(fx, "[", "@["); //add array accessor symbol arr[i] = arr@[i] = arr @ (i) + + return fx; +} + #region evaluator function evaluateFunction(fx, params = {}) { var pres = global.EQUATION_PRES; var vl = ds_stack_create(); var op = ds_stack_create(); - fx = string_replace_all(fx, " ", ""); - fx = string_replace_all(fx, "\n", ""); + fx = functionStringClean(fx); var len = string_length(fx); var l = 1; @@ -97,30 +131,62 @@ function evalToken(operator, vl) { if(ds_stack_empty(vl)) return 0; - switch(operator) { + + var v1 = 0, v2 = 0; + + switch(operator) { //binary case "+": - if(ds_stack_size(vl) >= 2) - return ds_stack_pop(vl) + ds_stack_pop(vl); + case "*": + case "$": + case "/": + case "&": + case "|": + case "^": + case "»": + case "«": + case "=": + case "≠": + case "<": + case ">": + case "≤": + case "≥": + if(ds_stack_size(vl) < 2) return 0; + + v1 = ds_stack_pop(vl); + v2 = ds_stack_pop(vl); + + //print($"{v2} {operator} {v1}"); + //print($"symbol : {operator}"); + //print("===================="); + } + + switch(operator) { + case "+": return v2 + v1; case "-": if(ds_stack_size(vl) >= 2) return -ds_stack_pop(vl) + ds_stack_pop(vl); - else - return -ds_stack_pop(vl); - case "_": - return -ds_stack_pop(vl); - case "*": - if(ds_stack_size(vl) >= 2) - return ds_stack_pop(vl) * ds_stack_pop(vl); - case "^": - if(ds_stack_size(vl) < 2) return 1; - var ex = ds_stack_pop(vl); - var bs = ds_stack_pop(vl); - return power(bs, ex); - case "/": - if(ds_stack_size(vl) < 2) return 0; - var _d = ds_stack_pop(vl); - if(_d == 0) return 0; - return ds_stack_pop(vl) / _d; + return -ds_stack_pop(vl); + case "_": return -ds_stack_pop(vl); + case "*": return v2 * v1; + case "$": return power(v2, v1); + case "/": return v1 == 0? 0 : v2 / v1; + + case "&": return v2 & v1; + case "|": return v2 | v1; + case "^": return v2 ^ v1; + case "»": return v2 >> v1; + case "«": return v2 << v1; + case "~": + if(ds_stack_size(vl) >= 1) + return ~ds_stack_pop(vl); + return 0; + + case "=": return v2 == v1; + case "≠": return v2 != v1; + case "<": return v2 < v1; + case ">": return v2 > v1; + case "≤": return v2 <= v1; + case "≥": return v2 >= v1; case "sin" : if(ds_stack_size(vl) >= 1) return sin(ds_stack_pop(vl)); case "cos" : if(ds_stack_size(vl) >= 1) return cos(ds_stack_pop(vl)); diff --git a/scripts/string_eval_tree/string_eval_tree.gml b/scripts/string_eval_tree/string_eval_tree.gml index ef897b1a9..6190e71dd 100644 --- a/scripts/string_eval_tree/string_eval_tree.gml +++ b/scripts/string_eval_tree/string_eval_tree.gml @@ -49,7 +49,7 @@ static validate = function() { switch(symbol) { - case "|": return _validate(l); + case "@": return _validate(l); } return _validate(l) && _validate(r); @@ -71,7 +71,7 @@ static isAnimated = function() { var anim = EXPRESS_TREE_ANIM.none; anim = max(anim, _isAnimated(l)); - if(symbol != "|") + if(symbol != "@") anim = max(anim, _isAnimated(r)); return anim; @@ -79,7 +79,7 @@ static eval = function(inp = 0) { var v1 = getVal(l, inp); - var v2 = getVal(r, inp, symbol == "|"); + var v2 = getVal(r, inp, symbol == "@"); //print($"{string(v1)} {symbol} {string(v2)}"); //print($"symbol : {symbol}"); @@ -88,14 +88,28 @@ //print("===================="); switch(symbol) { - case "+": return (is_real(v1) && is_real(v2))? v1 + v2 : 0; case "-": return (is_real(v1) && is_real(v2))? v1 - v2 : 0; case "_": return is_real(v1)? -v1 : 0; case "*": return (is_real(v1) && is_real(v2))? v1 * v2 : 0; - case "^": return (is_real(v1) && is_real(v2))? power(v1, v2) : 0; + case "$": return (is_real(v1) && is_real(v2))? power(v1, v2) : 0; case "/": return (is_real(v1) && is_real(v2))? v1 / v2 : 0; - case "|": + + case "&": return (is_real(v1) && is_real(v2))? v1 & v2 : 0; + case "|": return (is_real(v1) && is_real(v2))? v1 | v2 : 0; + case "^": return (is_real(v1) && is_real(v2))? v1 ^ v2 : 0; + case "«": return (is_real(v1) && is_real(v2))? v1 << v2 : 0; + case "»": return (is_real(v1) && is_real(v2))? v1 >> v2 : 0; + case "~": return is_real(v1)? ~v1 : 0; + + case "=": return (is_real(v1) && is_real(v2))? v1 == v2 : 0; + case "≠": return (is_real(v1) && is_real(v2))? v1 != v2 : 0; + case "≤": return (is_real(v1) && is_real(v2))? v1 <= v2 : 0; + case "≥": return (is_real(v1) && is_real(v2))? v1 >= v2 : 0; + case ">": return (is_real(v1) && is_real(v2))? v1 > v2 : 0; + case "<": return (is_real(v1) && is_real(v2))? v1 < v2 : 0; + + case "@": var val = is_real(v2)? array_safe_get(v1, v2) : 0; return val; @@ -119,9 +133,7 @@ var vl = ds_stack_create(); var op = ds_stack_create(); - fx = string_replace_all(fx, " ", ""); - fx = string_replace_all(fx, "\n", ""); - fx = string_replace_all(fx, "[", "|["); //add array accessor symbol arr[i] = arr|[i] = arr | (i) + fx = functionStringClean(fx); var len = string_length(fx); var l = 1; @@ -215,9 +227,23 @@ case "+": //binary operators case "*": - case "^": + case "$": case "/": + case "@": + case "|": + case "&": + case "^": + case "»": + case "«": + + case "=": + case "≠": + case "≤": + case "≥": + case "<": + case ">": + if(ds_stack_size(vl) >= 2) { var _v1 = ds_stack_pop(vl); var _v2 = ds_stack_pop(vl);