Logic opr, bitwise and comparator in equation evaluators

This commit is contained in:
Tanasart 2023-06-13 21:24:05 +02:00
parent c561c756f1
commit 0664451464
9 changed files with 334 additions and 59 deletions

View file

@ -153,7 +153,7 @@ if(OS == os_windows && gameframe_is_minimized()) exit;
#endregion
#region tween
tweenStep();
//tweenStep();
#endregion
//print("===== Step end =====");

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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}");
});

View file

@ -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));

View file

@ -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);