mirror of
https://github.com/godotengine/godot-visual-script.git
synced 2026-01-04 18:10:07 +03:00
Codebase Enhancements and Performance Improvements
We've made several updates to improve our codebase and application performance. - Clang format was applied for better readability and consistency, aiding other developers in understanding and contributing to the code. - We resolved issues that were causing visual script compilation failure. The visual script now compiles successfully, ensuring application functionality. - Broken sections within the codebase were fixed, improving overall stability. - Built-in functions from the visual script were removed to simplify the code and enhance readability. - Generic search performance was improved to provide faster results, enhancing user experience. - Missing flow nodes were added to the Visual Script, ensuring all necessary components are present for correct functioning. In an effort to streamline the codebase: - `VisualScriptComment` class and related code were removed, reducing complexity and improving maintainability. - Error messages were optimized for quicker feedback when errors occur. - Licenses were updated to reflect recent changes, ensuring legal compliance and project transparency. - The `get_global_name()` override in `visual_script.h` was fixed, and `TYPE_BUILTIN_FUNC` in `visual_script_expression.h` was removed, improving code functionality. - Search logic was refactored to avoid double searching, enhancing performance. - Documentation was updated to reflect recent changes, providing accurate information to users and developers. - Property selection logic in `VisualScriptPropertySelector` was refactored for easier understanding and modification. - Code was refactored to avoid variable shadowing, improving readability and reducing potential errors. - `.clang-format` and `.clang-tidy` configuration files were added to ensure consistent code styling. To make the code more robust and easier to understand: - Variable names were corrected for clarity, and error handling in `visual_script_expression.cpp` was improved. - Function and variable names were refactored for better readability and maintainability. - Member editing logic in `VisualScriptEditor` was simplified. - Name variables were updated to be unique, avoiding potential conflicts and errors. - The `VisualScriptSubCall` class was refactored for simplicity and ease of understanding. For macOS workflow: - It was updated to use the latest version and correct path for installing Vulkan SDK, enabling the application to leverage the latest features and improvements from the Vulkan SDK. - Mac Vulkan SDK was installed to support Vulkan-based functionalities. Lastly, we made necessary changes to pass CI/CD tests, ensuring the code quality and stability of the application.
This commit is contained in:
@@ -1,36 +1,37 @@
|
||||
/*************************************************************************/
|
||||
/* visual_script_expression.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
/**************************************************************************/
|
||||
/* visual_script_expression.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "visual_script_expression.h"
|
||||
|
||||
bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_value) {
|
||||
bool VisualScriptExpression::_set(const StringName &p_name,
|
||||
const Variant &p_value) {
|
||||
if (String(p_name) == "expression") {
|
||||
expression = p_value;
|
||||
expression_dirty = true;
|
||||
@@ -89,7 +90,8 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VisualScriptExpression::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
bool VisualScriptExpression::_get(const StringName &p_name,
|
||||
Variant &r_ret) const {
|
||||
if (String(p_name) == "expression") {
|
||||
r_ret = expression;
|
||||
return true;
|
||||
@@ -130,20 +132,27 @@ bool VisualScriptExpression::_get(const StringName &p_name, Variant &r_ret) cons
|
||||
return false;
|
||||
}
|
||||
|
||||
void VisualScriptExpression::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
void VisualScriptExpression::_get_property_list(
|
||||
List<PropertyInfo> *p_list) const {
|
||||
String argt = "Any";
|
||||
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
|
||||
argt += "," + Variant::get_type_name(Variant::Type(i));
|
||||
}
|
||||
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "expression", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "out_type", PROPERTY_HINT_ENUM, argt));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,64,1"));
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "expression",
|
||||
PROPERTY_HINT_NONE, "",
|
||||
PROPERTY_USAGE_NO_EDITOR));
|
||||
p_list->push_back(
|
||||
PropertyInfo(Variant::INT, "out_type", PROPERTY_HINT_ENUM, argt));
|
||||
p_list->push_back(
|
||||
PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,64,1"));
|
||||
p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced"));
|
||||
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "input_" + itos(i) + "/type", PROPERTY_HINT_ENUM, argt));
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name"));
|
||||
p_list->push_back(PropertyInfo(Variant::INT, "input_" + itos(i) + "/type",
|
||||
PROPERTY_HINT_ENUM, argt));
|
||||
p_list->push_back(
|
||||
PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,25 +172,21 @@ int VisualScriptExpression::get_input_value_port_count() const {
|
||||
return inputs.size();
|
||||
}
|
||||
|
||||
int VisualScriptExpression::get_output_value_port_count() const {
|
||||
return 1;
|
||||
}
|
||||
int VisualScriptExpression::get_output_value_port_count() const { return 1; }
|
||||
|
||||
PropertyInfo VisualScriptExpression::get_input_value_port_info(int p_idx) const {
|
||||
PropertyInfo
|
||||
VisualScriptExpression::get_input_value_port_info(int p_idx) const {
|
||||
return PropertyInfo(inputs[p_idx].type, inputs[p_idx].name);
|
||||
}
|
||||
|
||||
PropertyInfo VisualScriptExpression::get_output_value_port_info(int p_idx) const {
|
||||
PropertyInfo
|
||||
VisualScriptExpression::get_output_value_port_info(int p_idx) const {
|
||||
return PropertyInfo(output_type, "result");
|
||||
}
|
||||
|
||||
String VisualScriptExpression::get_caption() const {
|
||||
return RTR("Expression");
|
||||
}
|
||||
String VisualScriptExpression::get_caption() const { return RTR("Expression"); }
|
||||
|
||||
String VisualScriptExpression::get_text() const {
|
||||
return expression;
|
||||
}
|
||||
String VisualScriptExpression::get_text() const { return expression; }
|
||||
|
||||
Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
while (true) {
|
||||
@@ -339,7 +344,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
} else if (ch == '"') {
|
||||
break;
|
||||
} else if (ch == '\\') {
|
||||
//escaped characters...
|
||||
// escaped characters...
|
||||
|
||||
char32_t next = GET_CHAR();
|
||||
if (next == 0) {
|
||||
@@ -412,29 +417,34 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
prev = res;
|
||||
continue;
|
||||
} else {
|
||||
_set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
|
||||
_set_error(
|
||||
"Invalid UTF-16 sequence in string, unpaired lead surrogate");
|
||||
r_token.type = TK_ERROR;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
} else if ((res & 0xfffffc00) == 0xdc00) {
|
||||
if (prev == 0) {
|
||||
_set_error("Invalid UTF-16 sequence in string, unpaired trail surrogate");
|
||||
_set_error("Invalid UTF-16 sequence in string, unpaired trail "
|
||||
"surrogate");
|
||||
r_token.type = TK_ERROR;
|
||||
return ERR_PARSE_ERROR;
|
||||
} else {
|
||||
res = (prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
|
||||
res =
|
||||
(prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
|
||||
prev = 0;
|
||||
}
|
||||
}
|
||||
if (prev != 0) {
|
||||
_set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
|
||||
_set_error(
|
||||
"Invalid UTF-16 sequence in string, unpaired lead surrogate");
|
||||
r_token.type = TK_ERROR;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
str += res;
|
||||
} else {
|
||||
if (prev != 0) {
|
||||
_set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
|
||||
_set_error(
|
||||
"Invalid UTF-16 sequence in string, unpaired lead surrogate");
|
||||
r_token.type = TK_ERROR;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
@@ -442,7 +452,8 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
}
|
||||
}
|
||||
if (prev != 0) {
|
||||
_set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
|
||||
_set_error(
|
||||
"Invalid UTF-16 sequence in string, unpaired lead surrogate");
|
||||
r_token.type = TK_ERROR;
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
@@ -458,7 +469,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
}
|
||||
|
||||
if (is_digit(cchar)) {
|
||||
//a number
|
||||
// a number
|
||||
|
||||
String num;
|
||||
#define READING_SIGN 0
|
||||
@@ -477,7 +488,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
switch (reading) {
|
||||
case READING_INT: {
|
||||
if (is_digit(c)) {
|
||||
//pass
|
||||
// pass
|
||||
} else if (c == '.') {
|
||||
reading = READING_DEC;
|
||||
is_float = true;
|
||||
@@ -536,13 +547,14 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
String id;
|
||||
bool first = true;
|
||||
|
||||
while (is_ascii_char(cchar) || cchar == '_' || (!first && is_digit(cchar))) {
|
||||
while (is_ascii_char(cchar) || cchar == '_' ||
|
||||
(!first && is_digit(cchar))) {
|
||||
id += String::chr(cchar);
|
||||
cchar = GET_CHAR();
|
||||
first = false;
|
||||
}
|
||||
|
||||
str_ofs--; //go back one
|
||||
str_ofs--; // go back one
|
||||
|
||||
if (id == "in") {
|
||||
r_token.type = TK_OP_IN;
|
||||
@@ -584,13 +596,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
}
|
||||
}
|
||||
|
||||
VisualScriptBuiltinFunc::BuiltinFunc bifunc = VisualScriptBuiltinFunc::find_function(id);
|
||||
if (bifunc != VisualScriptBuiltinFunc::FUNC_MAX) {
|
||||
r_token.type = TK_BUILTIN_FUNC;
|
||||
r_token.value = bifunc;
|
||||
return OK;
|
||||
}
|
||||
|
||||
r_token.type = TK_IDENTIFIER;
|
||||
r_token.value = id;
|
||||
}
|
||||
@@ -609,8 +614,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
const char *VisualScriptExpression::token_name[TK_MAX] = {
|
||||
"CURLY BRACKET OPEN",
|
||||
const char *VisualScriptExpression::token_name[TK_MAX] = { "CURLY BRACKET OPEN",
|
||||
"CURLY BRACKET CLOSE",
|
||||
"BRACKET OPEN",
|
||||
"BRACKET CLOSE",
|
||||
@@ -646,14 +650,13 @@ const char *VisualScriptExpression::token_name[TK_MAX] = {
|
||||
"OP BIT XOR",
|
||||
"OP BIT INVERT",
|
||||
"EOF",
|
||||
"ERROR"
|
||||
};
|
||||
"ERROR" };
|
||||
|
||||
VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
Vector<Expression> expression;
|
||||
Vector<Expression> parse_expression;
|
||||
|
||||
while (true) {
|
||||
//keep appending stuff to expression
|
||||
// keep appending stuff to expression
|
||||
ENode *expr = nullptr;
|
||||
|
||||
Token tk;
|
||||
@@ -664,7 +667,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
|
||||
switch (tk.type) {
|
||||
case TK_CURLY_BRACKET_OPEN: {
|
||||
//a dictionary
|
||||
// a dictionary
|
||||
DictionaryNode *dn = alloc_node<DictionaryNode>();
|
||||
|
||||
while (true) {
|
||||
@@ -673,8 +676,8 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
if (tk.type == TK_CURLY_BRACKET_CLOSE) {
|
||||
break;
|
||||
}
|
||||
str_ofs = cofs; //revert
|
||||
//parse an expression
|
||||
str_ofs = cofs; // revert
|
||||
// parse an expression
|
||||
ENode *expr2 = _parse_expression();
|
||||
if (!expr2) {
|
||||
return nullptr;
|
||||
@@ -697,7 +700,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
cofs = str_ofs;
|
||||
_get_token(tk);
|
||||
if (tk.type == TK_COMMA) {
|
||||
//all good
|
||||
// all good
|
||||
} else if (tk.type == TK_CURLY_BRACKET_CLOSE) {
|
||||
str_ofs = cofs;
|
||||
} else {
|
||||
@@ -708,7 +711,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
expr = dn;
|
||||
} break;
|
||||
case TK_BRACKET_OPEN: {
|
||||
//an array
|
||||
// an array
|
||||
|
||||
ArrayNode *an = alloc_node<ArrayNode>();
|
||||
|
||||
@@ -718,8 +721,8 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
if (tk.type == TK_BRACKET_CLOSE) {
|
||||
break;
|
||||
}
|
||||
str_ofs = cofs; //revert
|
||||
//parse an expression
|
||||
str_ofs = cofs; // revert
|
||||
// parse an expression
|
||||
ENode *expr2 = _parse_expression();
|
||||
if (!expr2) {
|
||||
return nullptr;
|
||||
@@ -729,7 +732,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
cofs = str_ofs;
|
||||
_get_token(tk);
|
||||
if (tk.type == TK_COMMA) {
|
||||
//all good
|
||||
// all good
|
||||
} else if (tk.type == TK_BRACKET_CLOSE) {
|
||||
str_ofs = cofs;
|
||||
} else {
|
||||
@@ -740,7 +743,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
expr = an;
|
||||
} break;
|
||||
case TK_PARENTHESIS_OPEN: {
|
||||
//a suexpression
|
||||
// a suexpression
|
||||
ENode *e = _parse_expression();
|
||||
if (error_set) {
|
||||
return nullptr;
|
||||
@@ -769,7 +772,10 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
input->index = index;
|
||||
expr = input;
|
||||
} else {
|
||||
_set_error("Invalid input identifier '" + what + "'. For script variables, use self (locals are for inputs)." + what);
|
||||
_set_error(
|
||||
"Invalid input identifier '" + what +
|
||||
"'. For script variables, use self (locals are for inputs)." +
|
||||
what);
|
||||
return nullptr;
|
||||
}
|
||||
} break;
|
||||
@@ -783,7 +789,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
expr = constant;
|
||||
} break;
|
||||
case TK_BASIC_TYPE: {
|
||||
//constructor..
|
||||
// constructor..
|
||||
|
||||
Variant::Type bt = Variant::Type(int(tk.value));
|
||||
_get_token(tk);
|
||||
@@ -801,8 +807,8 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
if (tk.type == TK_PARENTHESIS_CLOSE) {
|
||||
break;
|
||||
}
|
||||
str_ofs = cofs; //revert
|
||||
//parse an expression
|
||||
str_ofs = cofs; // revert
|
||||
// parse an expression
|
||||
ENode *expr2 = _parse_expression();
|
||||
if (!expr2) {
|
||||
return nullptr;
|
||||
@@ -813,7 +819,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
cofs = str_ofs;
|
||||
_get_token(tk);
|
||||
if (tk.type == TK_COMMA) {
|
||||
//all good
|
||||
// all good
|
||||
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
|
||||
str_ofs = cofs;
|
||||
} else {
|
||||
@@ -823,65 +829,19 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
|
||||
expr = constructor;
|
||||
|
||||
} break;
|
||||
case TK_BUILTIN_FUNC: {
|
||||
//builtin function
|
||||
|
||||
_get_token(tk);
|
||||
if (tk.type != TK_PARENTHESIS_OPEN) {
|
||||
_set_error("Expected '('");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BuiltinFuncNode *bifunc = alloc_node<BuiltinFuncNode>();
|
||||
bifunc->func = VisualScriptBuiltinFunc::BuiltinFunc(int(tk.value));
|
||||
|
||||
while (true) {
|
||||
int cofs = str_ofs;
|
||||
_get_token(tk);
|
||||
if (tk.type == TK_PARENTHESIS_CLOSE) {
|
||||
break;
|
||||
}
|
||||
str_ofs = cofs; //revert
|
||||
//parse an expression
|
||||
ENode *expr2 = _parse_expression();
|
||||
if (!expr2) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bifunc->arguments.push_back(expr2);
|
||||
|
||||
cofs = str_ofs;
|
||||
_get_token(tk);
|
||||
if (tk.type == TK_COMMA) {
|
||||
//all good
|
||||
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
|
||||
str_ofs = cofs;
|
||||
} else {
|
||||
_set_error("Expected ',' or ')'");
|
||||
}
|
||||
}
|
||||
|
||||
int expected_args = VisualScriptBuiltinFunc::get_func_argument_count(bifunc->func);
|
||||
if (bifunc->arguments.size() != expected_args) {
|
||||
_set_error("Builtin func '" + VisualScriptBuiltinFunc::get_func_name(bifunc->func) + "' expects " + itos(expected_args) + " arguments.");
|
||||
}
|
||||
|
||||
expr = bifunc;
|
||||
|
||||
} break;
|
||||
case TK_OP_SUB: {
|
||||
Expression e;
|
||||
e.is_op = true;
|
||||
e.op = Variant::OP_NEGATE;
|
||||
expression.push_back(e);
|
||||
parse_expression.push_back(e);
|
||||
continue;
|
||||
} break;
|
||||
case TK_OP_NOT: {
|
||||
Expression e;
|
||||
e.is_op = true;
|
||||
e.op = Variant::OP_NOT;
|
||||
expression.push_back(e);
|
||||
parse_expression.push_back(e);
|
||||
continue;
|
||||
} break;
|
||||
|
||||
@@ -891,7 +851,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
} break;
|
||||
}
|
||||
|
||||
//before going to operators, must check indexing!
|
||||
// before going to operators, must check indexing!
|
||||
|
||||
while (true) {
|
||||
int cofs2 = str_ofs;
|
||||
@@ -904,7 +864,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
|
||||
switch (tk.type) {
|
||||
case TK_BRACKET_OPEN: {
|
||||
//value indexing
|
||||
// value indexing
|
||||
|
||||
IndexNode *index = alloc_node<IndexNode>();
|
||||
index->base = expr;
|
||||
@@ -925,7 +885,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
|
||||
} break;
|
||||
case TK_PERIOD: {
|
||||
//named indexing or function call
|
||||
// named indexing or function call
|
||||
_get_token(tk);
|
||||
if (tk.type != TK_IDENTIFIER) {
|
||||
_set_error("Expected identifier after '.'");
|
||||
@@ -937,7 +897,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
int cofs = str_ofs;
|
||||
_get_token(tk);
|
||||
if (tk.type == TK_PARENTHESIS_OPEN) {
|
||||
//function call
|
||||
// function call
|
||||
CallNode *func_call = alloc_node<CallNode>();
|
||||
func_call->method = identifier;
|
||||
func_call->base = expr;
|
||||
@@ -948,8 +908,8 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
if (tk.type == TK_PARENTHESIS_CLOSE) {
|
||||
break;
|
||||
}
|
||||
str_ofs = cofs3; //revert
|
||||
//parse an expression
|
||||
str_ofs = cofs3; // revert
|
||||
// parse an expression
|
||||
ENode *expr2 = _parse_expression();
|
||||
if (!expr2) {
|
||||
return nullptr;
|
||||
@@ -960,7 +920,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
cofs3 = str_ofs;
|
||||
_get_token(tk);
|
||||
if (tk.type == TK_COMMA) {
|
||||
//all good
|
||||
// all good
|
||||
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
|
||||
str_ofs = cofs3;
|
||||
} else {
|
||||
@@ -970,7 +930,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
|
||||
expr = func_call;
|
||||
} else {
|
||||
//named indexing
|
||||
// named indexing
|
||||
str_ofs = cofs;
|
||||
|
||||
NamedIndexNode *index = alloc_node<NamedIndexNode>();
|
||||
@@ -991,15 +951,15 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
}
|
||||
}
|
||||
|
||||
//push expression
|
||||
// push expression
|
||||
{
|
||||
Expression e;
|
||||
e.is_op = false;
|
||||
e.node = expr;
|
||||
expression.push_back(e);
|
||||
parse_expression.push_back(e);
|
||||
}
|
||||
|
||||
//ok finally look for an operator
|
||||
// ok finally look for an operator
|
||||
|
||||
int cofs = str_ofs;
|
||||
_get_token(tk);
|
||||
@@ -1077,29 +1037,30 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
};
|
||||
}
|
||||
|
||||
if (op == Variant::OP_MAX) { //stop appending stuff
|
||||
if (op == Variant::OP_MAX) { // stop appending stuff
|
||||
str_ofs = cofs;
|
||||
break;
|
||||
}
|
||||
|
||||
//push operator and go on
|
||||
// push operator and go on
|
||||
{
|
||||
Expression e;
|
||||
e.is_op = true;
|
||||
e.op = op;
|
||||
expression.push_back(e);
|
||||
parse_expression.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reduce the set of expressions and place them in an operator tree, respecting precedence */
|
||||
/* Reduce the set of expressions and place them in an operator tree,
|
||||
* respecting precedence */
|
||||
|
||||
while (expression.size() > 1) {
|
||||
while (parse_expression.size() > 1) {
|
||||
int next_op = -1;
|
||||
int min_priority = 0xFFFFF;
|
||||
bool is_unary = false;
|
||||
|
||||
for (int i = 0; i < expression.size(); i++) {
|
||||
if (!expression[i].is_op) {
|
||||
for (int i = 0; i < parse_expression.size(); i++) {
|
||||
if (!parse_expression[i].is_op) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1107,7 +1068,7 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
|
||||
bool unary = false;
|
||||
|
||||
switch (expression[i].op) {
|
||||
switch (parse_expression[i].op) {
|
||||
case Variant::OP_BIT_NEGATE:
|
||||
priority = 0;
|
||||
unary = true;
|
||||
@@ -1187,7 +1148,8 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
break;
|
||||
|
||||
default: {
|
||||
_set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op));
|
||||
_set_error("Parser bug, invalid operator in expression: " +
|
||||
itos(parse_expression[i].op));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -1210,41 +1172,41 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
// OK! create operator..
|
||||
if (is_unary) {
|
||||
int expr_pos = next_op;
|
||||
while (expression[expr_pos].is_op) {
|
||||
while (parse_expression[expr_pos].is_op) {
|
||||
expr_pos++;
|
||||
if (expr_pos == expression.size()) {
|
||||
//can happen..
|
||||
// can happen..
|
||||
_set_error("Unexpected end of expression...");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//consecutively do unary operators
|
||||
// consecutively do unary operators
|
||||
for (int i = expr_pos - 1; i >= next_op; i--) {
|
||||
OperatorNode *op = alloc_node<OperatorNode>();
|
||||
op->op = expression[i].op;
|
||||
op->nodes[0] = expression[i + 1].node;
|
||||
op->op = parse_expression[i].op;
|
||||
op->nodes[0] = parse_expression[i + 1].node;
|
||||
op->nodes[1] = nullptr;
|
||||
expression.write[i].is_op = false;
|
||||
expression.write[i].node = op;
|
||||
expression.remove_at(i + 1);
|
||||
parse_expression.write[i].is_op = false;
|
||||
parse_expression.write[i].node = op;
|
||||
parse_expression.remove_at(i + 1);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (next_op < 1 || next_op >= (expression.size() - 1)) {
|
||||
if (next_op < 1 || next_op >= (parse_expression.size() - 1)) {
|
||||
_set_error("Parser bug...");
|
||||
ERR_FAIL_V(nullptr);
|
||||
}
|
||||
|
||||
OperatorNode *op = alloc_node<OperatorNode>();
|
||||
op->op = expression[next_op].op;
|
||||
op->op = parse_expression[next_op].op;
|
||||
|
||||
if (expression[next_op - 1].is_op) {
|
||||
if (parse_expression[next_op - 1].is_op) {
|
||||
_set_error("Parser bug...");
|
||||
ERR_FAIL_V(nullptr);
|
||||
}
|
||||
|
||||
if (expression[next_op + 1].is_op) {
|
||||
if (parse_expression[next_op + 1].is_op) {
|
||||
// this is not invalid and can really appear
|
||||
// but it becomes invalid anyway because no binary op
|
||||
// can be followed by a unary op in a valid combination,
|
||||
@@ -1254,17 +1216,17 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
op->nodes[0] = expression[next_op - 1].node; //expression goes as left
|
||||
op->nodes[1] = expression[next_op + 1].node; //next expression goes as right
|
||||
op->nodes[0] = parse_expression[next_op - 1].node; // expression goes as left
|
||||
op->nodes[1] = parse_expression[next_op + 1].node; // next expression goes as right
|
||||
|
||||
//replace all 3 nodes by this operator and make it an expression
|
||||
expression.write[next_op - 1].node = op;
|
||||
expression.remove_at(next_op);
|
||||
expression.remove_at(next_op);
|
||||
// replace all 3 nodes by this operator and make it an expression
|
||||
parse_expression.write[next_op - 1].node = op;
|
||||
parse_expression.remove_at(next_op);
|
||||
parse_expression.remove_at(next_op);
|
||||
}
|
||||
}
|
||||
|
||||
return expression[0].node;
|
||||
return parse_expression[0].node;
|
||||
}
|
||||
|
||||
bool VisualScriptExpression::_compile_expression() {
|
||||
@@ -1302,16 +1264,20 @@ public:
|
||||
VisualScriptInstance *instance = nullptr;
|
||||
VisualScriptExpression *expression = nullptr;
|
||||
|
||||
//virtual int get_working_memory_size() const override { return 0; }
|
||||
//execute by parsing the tree directly
|
||||
virtual bool _execute(const Variant **p_inputs, VisualScriptExpression::ENode *p_node, Variant &r_ret, String &r_error_str, Callable::CallError &ce) {
|
||||
// virtual int get_working_memory_size() const override { return 0; }
|
||||
// execute by parsing the tree directly
|
||||
virtual bool _execute(const Variant **p_inputs,
|
||||
VisualScriptExpression::ENode *p_node, Variant &r_ret,
|
||||
String &r_error_str, Callable::CallError &ce) {
|
||||
switch (p_node->type) {
|
||||
case VisualScriptExpression::ENode::TYPE_INPUT: {
|
||||
const VisualScriptExpression::InputNode *in = static_cast<const VisualScriptExpression::InputNode *>(p_node);
|
||||
const VisualScriptExpression::InputNode *in =
|
||||
static_cast<const VisualScriptExpression::InputNode *>(p_node);
|
||||
r_ret = *p_inputs[in->index];
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_CONSTANT: {
|
||||
const VisualScriptExpression::ConstantNode *c = static_cast<const VisualScriptExpression::ConstantNode *>(p_node);
|
||||
const VisualScriptExpression::ConstantNode *c =
|
||||
static_cast<const VisualScriptExpression::ConstantNode *>(p_node);
|
||||
r_ret = c->value;
|
||||
|
||||
} break;
|
||||
@@ -1319,7 +1285,8 @@ public:
|
||||
r_ret = instance->get_owner_ptr();
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_OPERATOR: {
|
||||
const VisualScriptExpression::OperatorNode *op = static_cast<const VisualScriptExpression::OperatorNode *>(p_node);
|
||||
const VisualScriptExpression::OperatorNode *op =
|
||||
static_cast<const VisualScriptExpression::OperatorNode *>(p_node);
|
||||
|
||||
Variant a;
|
||||
bool ret = _execute(p_inputs, op->nodes[0], a, r_error_str, ce);
|
||||
@@ -1339,16 +1306,20 @@ public:
|
||||
bool valid = true;
|
||||
Variant::evaluate(op->op, a, b, r_ret, valid);
|
||||
if (!valid) {
|
||||
r_error_str = "Invalid operands to operator " + Variant::get_operator_name(op->op) + ": " + Variant::get_type_name(a.get_type()) + " and " + Variant::get_type_name(b.get_type()) + ".";
|
||||
r_error_str = "Invalid operands to operator " +
|
||||
Variant::get_operator_name(op->op) + ": " +
|
||||
Variant::get_type_name(a.get_type()) + " and " +
|
||||
Variant::get_type_name(b.get_type()) + ".";
|
||||
return true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_INDEX: {
|
||||
const VisualScriptExpression::IndexNode *index = static_cast<const VisualScriptExpression::IndexNode *>(p_node);
|
||||
const VisualScriptExpression::IndexNode *index =
|
||||
static_cast<const VisualScriptExpression::IndexNode *>(p_node);
|
||||
|
||||
Variant base;
|
||||
bool ret = _execute(p_inputs, index->base, base, r_error_str, ce);
|
||||
Variant expression_base;
|
||||
bool ret = _execute(p_inputs, index->base, expression_base, r_error_str, ce);
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
@@ -1361,32 +1332,39 @@ public:
|
||||
}
|
||||
|
||||
bool valid;
|
||||
r_ret = base.get(idx, &valid);
|
||||
r_ret = expression_base.get(idx, &valid);
|
||||
if (!valid) {
|
||||
r_error_str = "Invalid index of type " + Variant::get_type_name(idx.get_type()) + " for base of type " + Variant::get_type_name(base.get_type()) + ".";
|
||||
r_error_str = "Invalid index of type " +
|
||||
Variant::get_type_name(idx.get_type()) +
|
||||
" for base of type " +
|
||||
Variant::get_type_name(expression_base.get_type()) + ".";
|
||||
return true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_NAMED_INDEX: {
|
||||
const VisualScriptExpression::NamedIndexNode *index = static_cast<const VisualScriptExpression::NamedIndexNode *>(p_node);
|
||||
const VisualScriptExpression::NamedIndexNode *index =
|
||||
static_cast<const VisualScriptExpression::NamedIndexNode *>(p_node);
|
||||
|
||||
Variant base;
|
||||
bool ret = _execute(p_inputs, index->base, base, r_error_str, ce);
|
||||
Variant typed_named_expression_base;
|
||||
bool ret = _execute(p_inputs, index->base, typed_named_expression_base, r_error_str, ce);
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool valid;
|
||||
r_ret = base.get_named(index->name, valid);
|
||||
r_ret = typed_named_expression_base.get_named(index->name, valid);
|
||||
if (!valid) {
|
||||
r_error_str = "Invalid index '" + String(index->name) + "' for base of type " + Variant::get_type_name(base.get_type()) + ".";
|
||||
r_error_str = "Invalid index '" + String(index->name) +
|
||||
"' for base of type " +
|
||||
Variant::get_type_name(typed_named_expression_base.get_type()) + ".";
|
||||
return true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_ARRAY: {
|
||||
const VisualScriptExpression::ArrayNode *array = static_cast<const VisualScriptExpression::ArrayNode *>(p_node);
|
||||
const VisualScriptExpression::ArrayNode *array =
|
||||
static_cast<const VisualScriptExpression::ArrayNode *>(p_node);
|
||||
|
||||
Array arr;
|
||||
arr.resize(array->array.size());
|
||||
@@ -1403,18 +1381,21 @@ public:
|
||||
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_DICTIONARY: {
|
||||
const VisualScriptExpression::DictionaryNode *dictionary = static_cast<const VisualScriptExpression::DictionaryNode *>(p_node);
|
||||
const VisualScriptExpression::DictionaryNode *dictionary =
|
||||
static_cast<const VisualScriptExpression::DictionaryNode *>(p_node);
|
||||
|
||||
Dictionary d;
|
||||
for (int i = 0; i < dictionary->dict.size(); i += 2) {
|
||||
Variant key;
|
||||
bool ret = _execute(p_inputs, dictionary->dict[i + 0], key, r_error_str, ce);
|
||||
bool ret =
|
||||
_execute(p_inputs, dictionary->dict[i + 0], key, r_error_str, ce);
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Variant value;
|
||||
ret = _execute(p_inputs, dictionary->dict[i + 1], value, r_error_str, ce);
|
||||
ret =
|
||||
_execute(p_inputs, dictionary->dict[i + 1], value, r_error_str, ce);
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
@@ -1425,7 +1406,8 @@ public:
|
||||
r_ret = d;
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_CONSTRUCTOR: {
|
||||
const VisualScriptExpression::ConstructorNode *constructor = static_cast<const VisualScriptExpression::ConstructorNode *>(p_node);
|
||||
const VisualScriptExpression::ConstructorNode *constructor =
|
||||
static_cast<const VisualScriptExpression::ConstructorNode *>(p_node);
|
||||
|
||||
Vector<Variant> arr;
|
||||
Vector<const Variant *> argp;
|
||||
@@ -1434,7 +1416,8 @@ public:
|
||||
|
||||
for (int i = 0; i < constructor->arguments.size(); i++) {
|
||||
Variant value;
|
||||
bool ret = _execute(p_inputs, constructor->arguments[i], value, r_error_str, ce);
|
||||
bool ret = _execute(p_inputs, constructor->arguments[i], value,
|
||||
r_error_str, ce);
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
@@ -1442,45 +1425,22 @@ public:
|
||||
argp.write[i] = &arr[i];
|
||||
}
|
||||
|
||||
Variant::construct(constructor->data_type, r_ret, (const Variant **)argp.ptr(), argp.size(), ce);
|
||||
Variant::construct(constructor->data_type, r_ret,
|
||||
(const Variant **)argp.ptr(), argp.size(), ce);
|
||||
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
r_error_str = "Invalid arguments to construct '" + Variant::get_type_name(constructor->data_type) + "'.";
|
||||
return true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_BUILTIN_FUNC: {
|
||||
const VisualScriptExpression::BuiltinFuncNode *bifunc = static_cast<const VisualScriptExpression::BuiltinFuncNode *>(p_node);
|
||||
|
||||
Vector<Variant> arr;
|
||||
Vector<const Variant *> argp;
|
||||
arr.resize(bifunc->arguments.size());
|
||||
argp.resize(bifunc->arguments.size());
|
||||
|
||||
for (int i = 0; i < bifunc->arguments.size(); i++) {
|
||||
Variant value;
|
||||
bool ret = _execute(p_inputs, bifunc->arguments[i], value, r_error_str, ce);
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
arr.write[i] = value;
|
||||
argp.write[i] = &arr[i];
|
||||
}
|
||||
|
||||
VisualScriptBuiltinFunc::exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str);
|
||||
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
r_error_str = "Builtin Call Failed. " + r_error_str;
|
||||
r_error_str = "Invalid arguments to construct '" +
|
||||
Variant::get_type_name(constructor->data_type) + "'.";
|
||||
return true;
|
||||
}
|
||||
|
||||
} break;
|
||||
case VisualScriptExpression::ENode::TYPE_CALL: {
|
||||
const VisualScriptExpression::CallNode *call = static_cast<const VisualScriptExpression::CallNode *>(p_node);
|
||||
const VisualScriptExpression::CallNode *call =
|
||||
static_cast<const VisualScriptExpression::CallNode *>(p_node);
|
||||
|
||||
Variant base;
|
||||
bool ret = _execute(p_inputs, call->base, base, r_error_str, ce);
|
||||
Variant call_expression_base;
|
||||
bool ret = _execute(p_inputs, call->base, call_expression_base, r_error_str, ce);
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
@@ -1492,7 +1452,8 @@ public:
|
||||
|
||||
for (int i = 0; i < call->arguments.size(); i++) {
|
||||
Variant value;
|
||||
bool ret2 = _execute(p_inputs, call->arguments[i], value, r_error_str, ce);
|
||||
bool ret2 =
|
||||
_execute(p_inputs, call->arguments[i], value, r_error_str, ce);
|
||||
if (ret2) {
|
||||
return true;
|
||||
}
|
||||
@@ -1500,7 +1461,8 @@ public:
|
||||
argp.write[i] = &arr[i];
|
||||
}
|
||||
|
||||
base.callp(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce);
|
||||
call_expression_base.callp(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret,
|
||||
ce);
|
||||
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
r_error_str = "On call to '" + String(call->method) + "':";
|
||||
@@ -1512,21 +1474,28 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) override {
|
||||
virtual int step(const Variant **p_inputs, Variant **p_outputs,
|
||||
StartMode p_start_mode, Variant *p_working_mem,
|
||||
Callable::CallError &r_error, String &r_error_str) override {
|
||||
if (!expression->root || expression->error_set) {
|
||||
r_error_str = expression->error_str;
|
||||
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool error = _execute(p_inputs, expression->root, *p_outputs[0], r_error_str, r_error);
|
||||
bool error = _execute(p_inputs, expression->root, *p_outputs[0],
|
||||
r_error_str, r_error);
|
||||
if (error && r_error.error == Callable::CallError::CALL_OK) {
|
||||
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (!error && expression->output_type != Variant::NIL && !Variant::can_convert_strict(p_outputs[0]->get_type(), expression->output_type)) {
|
||||
r_error_str += "Can't convert expression result from " + Variant::get_type_name(p_outputs[0]->get_type()) + " to " + Variant::get_type_name(expression->output_type) + ".";
|
||||
if (!error && expression->output_type != Variant::NIL &&
|
||||
!Variant::can_convert_strict(p_outputs[0]->get_type(),
|
||||
expression->output_type)) {
|
||||
r_error_str += "Can't convert expression result from " +
|
||||
Variant::get_type_name(p_outputs[0]->get_type()) + " to " +
|
||||
Variant::get_type_name(expression->output_type) + ".";
|
||||
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
|
||||
}
|
||||
#endif
|
||||
@@ -1535,9 +1504,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
VisualScriptNodeInstance *VisualScriptExpression::instantiate(VisualScriptInstance *p_instance) {
|
||||
VisualScriptNodeInstance *
|
||||
VisualScriptExpression::instantiate(VisualScriptInstance *p_instance) {
|
||||
_compile_expression();
|
||||
VisualScriptNodeInstanceExpression *instance = memnew(VisualScriptNodeInstanceExpression);
|
||||
VisualScriptNodeInstanceExpression *instance =
|
||||
memnew(VisualScriptNodeInstanceExpression);
|
||||
instance->instance = p_instance;
|
||||
instance->expression = this;
|
||||
return instance;
|
||||
@@ -1556,8 +1527,7 @@ void VisualScriptExpression::reset_state() {
|
||||
inputs.clear();
|
||||
}
|
||||
|
||||
VisualScriptExpression::VisualScriptExpression() {
|
||||
}
|
||||
VisualScriptExpression::VisualScriptExpression() {}
|
||||
|
||||
VisualScriptExpression::~VisualScriptExpression() {
|
||||
if (nodes) {
|
||||
@@ -1566,5 +1536,6 @@ VisualScriptExpression::~VisualScriptExpression() {
|
||||
}
|
||||
|
||||
void register_visual_script_expression_node() {
|
||||
VisualScriptLanguage::singleton->add_register_func("operators/expression", create_node_generic<VisualScriptExpression>);
|
||||
VisualScriptLanguage::singleton->add_register_func(
|
||||
"operators/expression", create_node_generic<VisualScriptExpression>);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user