summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/visual_script/visual_script.cpp3
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp782
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h5
-rw-r--r--modules/visual_script/visual_script_expression.cpp83
-rw-r--r--modules/visual_script/visual_script_expression.h11
5 files changed, 506 insertions, 378 deletions
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index d0a933a11c..94f9a6a6b5 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -1417,7 +1417,8 @@ bool VisualScriptInstance::get(const StringName& p_name, Variant &r_ret) const {
if (!E)
return false;
- return E->get();
+ r_ret=E->get();
+ return true;
}
void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const{
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index 1d0bca0b30..24a44d3506 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -65,6 +65,21 @@ const char* VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"bytes2var",
};
+VisualScriptBuiltinFunc::BuiltinFunc VisualScriptBuiltinFunc::find_function(const String& p_string) {
+
+ for(int i=0;i<FUNC_MAX;i++) {
+ if (p_string==func_name[i])
+ return BuiltinFunc(i);
+ }
+
+ return FUNC_MAX;
+}
+
+String VisualScriptBuiltinFunc::get_func_name(BuiltinFunc p_func) {
+
+ ERR_FAIL_INDEX_V(p_func,FUNC_MAX,String());
+ return func_name[p_func];
+}
int VisualScriptBuiltinFunc::get_output_sequence_port_count() const {
@@ -88,10 +103,10 @@ bool VisualScriptBuiltinFunc::has_input_sequence_port() const{
}
-int VisualScriptBuiltinFunc::get_input_value_port_count() const{
+int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
- switch(func) {
+ switch(p_func) {
case MATH_RANDOMIZE:
case MATH_RAND:
@@ -157,6 +172,11 @@ int VisualScriptBuiltinFunc::get_input_value_port_count() const{
}
return 0;
}
+
+int VisualScriptBuiltinFunc::get_input_value_port_count() const{
+
+ return get_func_argument_count(func);
+}
int VisualScriptBuiltinFunc::get_output_value_port_count() const{
switch(func) {
@@ -560,118 +580,124 @@ VisualScriptBuiltinFunc::BuiltinFunc VisualScriptBuiltinFunc::get_func() {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\
r_error.argument=m_arg;\
r_error.expected=Variant::REAL;\
- return 0;\
+ return;\
}
-class VisualScriptNodeInstanceBuiltinFunc : public VisualScriptNodeInstance {
-public:
- VisualScriptBuiltinFunc *node;
- VisualScriptInstance *instance;
+void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func,const Variant** p_inputs,Variant* r_return,Variant::CallError& r_error,String& r_error_str) {
- VisualScriptBuiltinFunc::BuiltinFunc func;
+ switch(p_func) {
+ case VisualScriptBuiltinFunc::MATH_SIN: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::sin(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_COS: {
- //virtual int get_working_memory_size() const { return 0; }
- //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
- //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::cos(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_TAN: {
- virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::tan(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_SINH: {
- switch(func) {
- case VisualScriptBuiltinFunc::MATH_SIN: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::sinh(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_COSH: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::sin(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_COS: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::cosh(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_TANH: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::cos(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_TAN: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::tanh(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_ASIN: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::tan(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_SINH: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::asin(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_ACOS: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::sinh(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_COSH: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::acos(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_ATAN: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::cosh(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_TANH: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::atan(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_ATAN2: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::tanh(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_ASIN: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return=Math::atan2(*p_inputs[0],*p_inputs[1]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_SQRT: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::asin(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_ACOS: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::sqrt(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_FMOD: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::acos(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_ATAN: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return=Math::fmod(*p_inputs[0],*p_inputs[1]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_FPOSMOD: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::atan(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_ATAN2: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return=Math::fposmod(*p_inputs[0],*p_inputs[1]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_FLOOR: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *p_outputs[0]=Math::atan2(*p_inputs[0],*p_inputs[1]);
- } break;
- case VisualScriptBuiltinFunc::MATH_SQRT: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::floor(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_CEIL: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::sqrt(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_FMOD: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::ceil(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_ROUND: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *p_outputs[0]=Math::fmod(*p_inputs[0],*p_inputs[1]);
- } break;
- case VisualScriptBuiltinFunc::MATH_FPOSMOD: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::round(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_ABS: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *p_outputs[0]=Math::fposmod(*p_inputs[0],*p_inputs[1]);
- } break;
- case VisualScriptBuiltinFunc::MATH_FLOOR: {
+ if (p_inputs[0]->get_type()==Variant::INT) {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::floor(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_CEIL: {
+ int64_t i = *p_inputs[0];
+ *r_return=ABS(i);
+ } else if (p_inputs[0]->get_type()==Variant::REAL) {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::ceil(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_ROUND: {
+ real_t r = *p_inputs[0];
+ *r_return=Math::abs(r);
+ } else {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::round(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_ABS: {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=0;
+ r_error.expected=Variant::REAL;
+
+ }
+ } break;
+ case VisualScriptBuiltinFunc::MATH_SIGN: {
if (p_inputs[0]->get_type()==Variant::INT) {
int64_t i = *p_inputs[0];
- *p_outputs[0]=ABS(i);
+ *r_return= i < 0 ? -1 : ( i > 0 ? +1 : 0);
} else if (p_inputs[0]->get_type()==Variant::REAL) {
real_t r = *p_inputs[0];
- *p_outputs[0]=Math::abs(r);
+ *r_return= r < 0.0 ? -1.0 : ( r > 0.0 ? +1.0 : 0.0);
} else {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
@@ -679,410 +705,412 @@ public:
r_error.expected=Variant::REAL;
}
- } break;
- case VisualScriptBuiltinFunc::MATH_SIGN: {
+ } break;
+ case VisualScriptBuiltinFunc::MATH_POW: {
- if (p_inputs[0]->get_type()==Variant::INT) {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return=Math::pow(*p_inputs[0],*p_inputs[1]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_LOG: {
- int64_t i = *p_inputs[0];
- *p_outputs[0]= i < 0 ? -1 : ( i > 0 ? +1 : 0);
- } else if (p_inputs[0]->get_type()==Variant::REAL) {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::log(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_EXP: {
- real_t r = *p_inputs[0];
- *p_outputs[0]= r < 0.0 ? -1.0 : ( r > 0.0 ? +1.0 : 0.0);
- } else {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::exp(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_ISNAN: {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=0;
- r_error.expected=Variant::REAL;
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::is_nan(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_ISINF: {
- }
- } break;
- case VisualScriptBuiltinFunc::MATH_POW: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::is_inf(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_EASE: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *p_outputs[0]=Math::pow(*p_inputs[0],*p_inputs[1]);
- } break;
- case VisualScriptBuiltinFunc::MATH_LOG: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return=Math::ease(*p_inputs[0],*p_inputs[1]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_DECIMALS: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::log(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_EXP: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::step_decimals(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_STEPIFY: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::exp(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_ISNAN: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return=Math::stepify(*p_inputs[0],*p_inputs[1]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_LERP: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::is_nan(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_ISINF: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return=Math::lerp(*p_inputs[0],*p_inputs[1],*p_inputs[2]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_DECTIME: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::is_inf(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_EASE: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return=Math::dectime(*p_inputs[0],*p_inputs[1],*p_inputs[2]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_RANDOMIZE: {
+ Math::randomize();
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *p_outputs[0]=Math::ease(*p_inputs[0],*p_inputs[1]);
- } break;
- case VisualScriptBuiltinFunc::MATH_DECIMALS: {
+ } break;
+ case VisualScriptBuiltinFunc::MATH_RAND: {
+ *r_return=Math::rand();
+ } break;
+ case VisualScriptBuiltinFunc::MATH_RANDF: {
+ *r_return=Math::randf();
+ } break;
+ case VisualScriptBuiltinFunc::MATH_RANDOM: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::step_decimals(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_STEPIFY: {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ *r_return=Math::random(*p_inputs[0],*p_inputs[1]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_SEED: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *p_outputs[0]=Math::stepify(*p_inputs[0],*p_inputs[1]);
- } break;
- case VisualScriptBuiltinFunc::MATH_LERP: {
+ VALIDATE_ARG_NUM(0);
+ uint32_t seed=*p_inputs[0];
+ Math::seed(seed);
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *p_outputs[0]=Math::lerp(*p_inputs[0],*p_inputs[1],*p_inputs[2]);
- } break;
- case VisualScriptBuiltinFunc::MATH_DECTIME: {
+ } break;
+ case VisualScriptBuiltinFunc::MATH_RANDSEED: {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
- *p_outputs[0]=Math::dectime(*p_inputs[0],*p_inputs[1],*p_inputs[2]);
- } break;
- case VisualScriptBuiltinFunc::MATH_RANDOMIZE: {
- Math::randomize();
-
- } break;
- case VisualScriptBuiltinFunc::MATH_RAND: {
- *p_outputs[0]=Math::rand();
- } break;
- case VisualScriptBuiltinFunc::MATH_RANDF: {
- *p_outputs[0]=Math::randf();
- } break;
- case VisualScriptBuiltinFunc::MATH_RANDOM: {
+ VALIDATE_ARG_NUM(0);
+ uint32_t seed=*p_inputs[0];
+ int ret = Math::rand_from_seed(&seed);
+ Array reta;
+ reta.push_back(ret);
+ reta.push_back(seed);
+ *r_return=reta;
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- *p_outputs[0]=Math::random(*p_inputs[0],*p_inputs[1]);
- } break;
- case VisualScriptBuiltinFunc::MATH_SEED: {
+ } break;
+ case VisualScriptBuiltinFunc::MATH_DEG2RAD: {
- VALIDATE_ARG_NUM(0);
- uint32_t seed=*p_inputs[0];
- Math::seed(seed);
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::deg2rad(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_RAD2DEG: {
- } break;
- case VisualScriptBuiltinFunc::MATH_RANDSEED: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::rad2deg(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_LINEAR2DB: {
- VALIDATE_ARG_NUM(0);
- uint32_t seed=*p_inputs[0];
- int ret = Math::rand_from_seed(&seed);
- Array reta;
- reta.push_back(ret);
- reta.push_back(seed);
- *p_outputs[0]=reta;
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::linear2db(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_DB2LINEAR: {
- } break;
- case VisualScriptBuiltinFunc::MATH_DEG2RAD: {
+ VALIDATE_ARG_NUM(0);
+ *r_return=Math::db2linear(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::LOGIC_MAX: {
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::deg2rad(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_RAD2DEG: {
+ if (p_inputs[0]->get_type()==Variant::INT && p_inputs[1]->get_type()==Variant::INT) {
+ int64_t a = *p_inputs[0];
+ int64_t b = *p_inputs[1];
+ *r_return=MAX(a,b);
+ } else {
VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::rad2deg(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_LINEAR2DB: {
+ VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::linear2db(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::MATH_DB2LINEAR: {
+ real_t a = *p_inputs[0];
+ real_t b = *p_inputs[1];
+
+ *r_return=MAX(a,b);
+ }
+ } break;
+ case VisualScriptBuiltinFunc::LOGIC_MIN: {
+
+ if (p_inputs[0]->get_type()==Variant::INT && p_inputs[1]->get_type()==Variant::INT) {
+
+ int64_t a = *p_inputs[0];
+ int64_t b = *p_inputs[1];
+ *r_return=MIN(a,b);
+ } else {
VALIDATE_ARG_NUM(0);
- *p_outputs[0]=Math::db2linear(*p_inputs[0]);
- } break;
- case VisualScriptBuiltinFunc::LOGIC_MAX: {
+ VALIDATE_ARG_NUM(1);
- if (p_inputs[0]->get_type()==Variant::INT && p_inputs[1]->get_type()==Variant::INT) {
+ real_t a = *p_inputs[0];
+ real_t b = *p_inputs[1];
- int64_t a = *p_inputs[0];
- int64_t b = *p_inputs[1];
- *p_outputs[0]=MAX(a,b);
- } else {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
+ *r_return=MIN(a,b);
+ }
+ } break;
+ case VisualScriptBuiltinFunc::LOGIC_CLAMP: {
- real_t a = *p_inputs[0];
- real_t b = *p_inputs[1];
+ if (p_inputs[0]->get_type()==Variant::INT && p_inputs[1]->get_type()==Variant::INT && p_inputs[2]->get_type()==Variant::INT) {
- *p_outputs[0]=MAX(a,b);
- }
+ int64_t a = *p_inputs[0];
+ int64_t b = *p_inputs[1];
+ int64_t c = *p_inputs[2];
+ *r_return=CLAMP(a,b,c);
+ } else {
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
- } break;
- case VisualScriptBuiltinFunc::LOGIC_MIN: {
+ real_t a = *p_inputs[0];
+ real_t b = *p_inputs[1];
+ real_t c = *p_inputs[2];
- if (p_inputs[0]->get_type()==Variant::INT && p_inputs[1]->get_type()==Variant::INT) {
+ *r_return=CLAMP(a,b,c);
+ }
+ } break;
+ case VisualScriptBuiltinFunc::LOGIC_NEAREST_PO2: {
- int64_t a = *p_inputs[0];
- int64_t b = *p_inputs[1];
- *p_outputs[0]=MIN(a,b);
- } else {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(0);
+ int64_t num = *p_inputs[0];
+ *r_return = nearest_power_of_2(num);
+ } break;
+ case VisualScriptBuiltinFunc::OBJ_WEAKREF: {
- real_t a = *p_inputs[0];
- real_t b = *p_inputs[1];
+ if (p_inputs[0]->get_type()!=Variant::OBJECT) {
- *p_outputs[0]=MIN(a,b);
- }
- } break;
- case VisualScriptBuiltinFunc::LOGIC_CLAMP: {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=0;
+ r_error.expected=Variant::OBJECT;
- if (p_inputs[0]->get_type()==Variant::INT && p_inputs[1]->get_type()==Variant::INT && p_inputs[2]->get_type()==Variant::INT) {
+ return;
- int64_t a = *p_inputs[0];
- int64_t b = *p_inputs[1];
- int64_t c = *p_inputs[2];
- *p_outputs[0]=CLAMP(a,b,c);
- } else {
- VALIDATE_ARG_NUM(0);
- VALIDATE_ARG_NUM(1);
- VALIDATE_ARG_NUM(2);
+ }
- real_t a = *p_inputs[0];
- real_t b = *p_inputs[1];
- real_t c = *p_inputs[2];
+ if (p_inputs[0]->is_ref()) {
- *p_outputs[0]=CLAMP(a,b,c);
+ REF r = *p_inputs[0];
+ if (!r.is_valid()) {
+
+ return;
}
- } break;
- case VisualScriptBuiltinFunc::LOGIC_NEAREST_PO2: {
- VALIDATE_ARG_NUM(0);
- int64_t num = *p_inputs[0];
- *p_outputs[0] = nearest_power_of_2(num);
- } break;
- case VisualScriptBuiltinFunc::OBJ_WEAKREF: {
+ Ref<WeakRef> wref = memnew( WeakRef );
+ wref->set_ref(r);
+ *r_return=wref;
+ } else {
+ Object *obj = *p_inputs[0];
+ if (!obj) {
- if (p_inputs[0]->get_type()!=Variant::OBJECT) {
+ return;
+ }
+ Ref<WeakRef> wref = memnew( WeakRef );
+ wref->set_obj(obj);
+ *r_return=wref;
+ }
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=0;
- r_error.expected=Variant::OBJECT;
- return 0;
- }
- if (p_inputs[0]->is_ref()) {
+ } break;
+ case VisualScriptBuiltinFunc::FUNC_FUNCREF: {
- REF r = *p_inputs[0];
- if (!r.is_valid()) {
+ if (p_inputs[0]->get_type()!=Variant::OBJECT) {
- return 0;
- }
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=0;
+ r_error.expected=Variant::OBJECT;
- Ref<WeakRef> wref = memnew( WeakRef );
- wref->set_ref(r);
- *p_outputs[0]=wref;
- } else {
- Object *obj = *p_inputs[0];
- if (!obj) {
-
- return 0;
- }
- Ref<WeakRef> wref = memnew( WeakRef );
- wref->set_obj(obj);
- *p_outputs[0]=wref;
- }
+ return;
+ }
+ if (p_inputs[1]->get_type()!=Variant::STRING && p_inputs[1]->get_type()!=Variant::NODE_PATH) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=1;
+ r_error.expected=Variant::STRING;
+ return;
- } break;
- case VisualScriptBuiltinFunc::FUNC_FUNCREF: {
+ }
- if (p_inputs[0]->get_type()!=Variant::OBJECT) {
+ Ref<FuncRef> fr = memnew( FuncRef);
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=0;
- r_error.expected=Variant::OBJECT;
+ fr->set_instance(*p_inputs[0]);
+ fr->set_function(*p_inputs[1]);
- return 0;
+ *r_return=fr;
- }
- if (p_inputs[1]->get_type()!=Variant::STRING && p_inputs[1]->get_type()!=Variant::NODE_PATH) {
+ } break;
+ case VisualScriptBuiltinFunc::TYPE_CONVERT: {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=1;
- r_error.expected=Variant::STRING;
+ VALIDATE_ARG_NUM(1);
+ int type=*p_inputs[1];
+ if (type<0 || type>=Variant::VARIANT_MAX) {
- return 0;
+ r_error_str=RTR("Invalid type argument to convert(), use TYPE_* constants.");
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=0;
+ r_error.expected=Variant::INT;
+ return;
- }
+ } else {
- Ref<FuncRef> fr = memnew( FuncRef);
- fr->set_instance(*p_inputs[0]);
- fr->set_function(*p_inputs[1]);
+ *r_return=Variant::construct(Variant::Type(type),p_inputs,1,r_error);
+ }
+ } break;
+ case VisualScriptBuiltinFunc::TYPE_OF: {
- *p_outputs[0]=fr;
- } break;
- case VisualScriptBuiltinFunc::TYPE_CONVERT: {
+ *r_return = p_inputs[0]->get_type();
- VALIDATE_ARG_NUM(1);
- int type=*p_inputs[1];
- if (type<0 || type>=Variant::VARIANT_MAX) {
+ } break;
+ case VisualScriptBuiltinFunc::TYPE_EXISTS: {
- *p_outputs[0]=RTR("Invalid type argument to convert(), use TYPE_* constants.");
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=0;
- r_error.expected=Variant::INT;
- return 0;
- } else {
+ *r_return = ObjectTypeDB::type_exists(*p_inputs[0]);
+ } break;
+ case VisualScriptBuiltinFunc::TEXT_STR: {
- *p_outputs[0]=Variant::construct(Variant::Type(type),p_inputs,1,r_error);
- }
- } break;
- case VisualScriptBuiltinFunc::TYPE_OF: {
+ String str = *p_inputs[0];
+
+ *r_return=str;
+ } break;
+ case VisualScriptBuiltinFunc::TEXT_PRINT: {
- *p_outputs[0] = p_inputs[0]->get_type();
+ String str = *p_inputs[0];
+ print_line(str);
- } break;
- case VisualScriptBuiltinFunc::TYPE_EXISTS: {
+ } break;
- *p_outputs[0] = ObjectTypeDB::type_exists(*p_inputs[0]);
+ case VisualScriptBuiltinFunc::TEXT_PRINTERR: {
- } break;
- case VisualScriptBuiltinFunc::TEXT_STR: {
+ String str = *p_inputs[0];
- String str = *p_inputs[0];
+ //str+="\n";
+ OS::get_singleton()->printerr("%s\n",str.utf8().get_data());
- *p_outputs[0]=str;
- } break;
- case VisualScriptBuiltinFunc::TEXT_PRINT: {
+ } break;
+ case VisualScriptBuiltinFunc::TEXT_PRINTRAW: {
+ String str = *p_inputs[0];
- String str = *p_inputs[0];
- print_line(str);
+ //str+="\n";
+ OS::get_singleton()->print("%s",str.utf8().get_data());
- } break;
+ } break;
+ case VisualScriptBuiltinFunc::VAR_TO_STR: {
- case VisualScriptBuiltinFunc::TEXT_PRINTERR: {
+ String vars;
+ VariantWriter::write_to_string(*p_inputs[0],vars);
+ *r_return=vars;
+ } break;
+ case VisualScriptBuiltinFunc::STR_TO_VAR: {
- String str = *p_inputs[0];
+ if (p_inputs[0]->get_type()!=Variant::STRING) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=0;
+ r_error.expected=Variant::STRING;
- //str+="\n";
- OS::get_singleton()->printerr("%s\n",str.utf8().get_data());
+ return;
+ }
+ VariantParser::StreamString ss;
+ ss.s=*p_inputs[0];
- } break;
- case VisualScriptBuiltinFunc::TEXT_PRINTRAW: {
- String str = *p_inputs[0];
+ String errs;
+ int line;
+ Error err = VariantParser::parse(&ss,*r_return,errs,line);
- //str+="\n";
- OS::get_singleton()->print("%s",str.utf8().get_data());
+ if (err!=OK) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=0;
+ r_error.expected=Variant::STRING;
+ *r_return="Parse error at line "+itos(line)+": "+errs;
+ return;
+ }
+ } break;
+ case VisualScriptBuiltinFunc::VAR_TO_BYTES: {
- } break;
- case VisualScriptBuiltinFunc::VAR_TO_STR: {
- String vars;
- VariantWriter::write_to_string(*p_inputs[0],vars);
- *p_outputs[0]=vars;
- } break;
- case VisualScriptBuiltinFunc::STR_TO_VAR: {
+ ByteArray barr;
+ int len;
+ Error err = encode_variant(*p_inputs[0],NULL,len);
+ if (err) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=0;
+ r_error.expected=Variant::NIL;
+ r_error_str="Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
+ return;
+ }
- if (p_inputs[0]->get_type()!=Variant::STRING) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=0;
- r_error.expected=Variant::STRING;
+ barr.resize(len);
+ {
+ ByteArray::Write w = barr.write();
+ encode_variant(*p_inputs[0],w.ptr(),len);
- return 0;
- }
+ }
+ *r_return=barr;
+ } break;
+ case VisualScriptBuiltinFunc::BYTES_TO_VAR: {
- VariantParser::StreamString ss;
- ss.s=*p_inputs[0];
+ if (p_inputs[0]->get_type()!=Variant::RAW_ARRAY) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=0;
+ r_error.expected=Variant::RAW_ARRAY;
- String errs;
- int line;
- Error err = VariantParser::parse(&ss,*p_outputs[0],errs,line);
+ return;
+ }
+ ByteArray varr=*p_inputs[0];
+ Variant ret;
+ {
+ ByteArray::Read r=varr.read();
+ Error err = decode_variant(ret,r.ptr(),varr.size(),NULL);
if (err!=OK) {
+ r_error_str=RTR("Not enough bytes for decoding bytes, or invalid format.");
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0;
- r_error.expected=Variant::STRING;
- *p_outputs[0]="Parse error at line "+itos(line)+": "+errs;
- return 0;
+ r_error.expected=Variant::RAW_ARRAY;
+ return;
}
- } break;
- case VisualScriptBuiltinFunc::VAR_TO_BYTES: {
+ }
+ *r_return=ret;
- ByteArray barr;
- int len;
- Error err = encode_variant(*p_inputs[0],NULL,len);
- if (err) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=0;
- r_error.expected=Variant::NIL;
- *p_outputs[0]="Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
- return 0;
- }
+ } break;
+ default: {}
+ }
- barr.resize(len);
- {
- ByteArray::Write w = barr.write();
- encode_variant(*p_inputs[0],w.ptr(),len);
+}
- }
- *p_outputs[0]=barr;
- } break;
- case VisualScriptBuiltinFunc::BYTES_TO_VAR: {
- if (p_inputs[0]->get_type()!=Variant::RAW_ARRAY) {
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=0;
- r_error.expected=Variant::RAW_ARRAY;
+class VisualScriptNodeInstanceBuiltinFunc : public VisualScriptNodeInstance {
+public:
- return 0;
- }
+ VisualScriptBuiltinFunc *node;
+ VisualScriptInstance *instance;
- ByteArray varr=*p_inputs[0];
- Variant ret;
- {
- ByteArray::Read r=varr.read();
- Error err = decode_variant(ret,r.ptr(),varr.size(),NULL);
- if (err!=OK) {
- *p_outputs[0]=RTR("Not enough bytes for decoding bytes, or invalid format.");
- r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument=0;
- r_error.expected=Variant::RAW_ARRAY;
- return 0;
- }
+ VisualScriptBuiltinFunc::BuiltinFunc func;
- }
- *p_outputs[0]=ret;
+ //virtual int get_working_memory_size() const { return 0; }
+ //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
+ //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
+
+ virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
- } break;
- default: {}
- }
+ VisualScriptBuiltinFunc::exec_func(func,p_inputs,p_outputs[0],r_error,r_error_str);
return 0;
}
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index ebf227a192..000230d84f 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -68,6 +68,11 @@ public:
FUNC_MAX
};
+ static int get_func_argument_count(BuiltinFunc p_func);
+ static String get_func_name(BuiltinFunc p_func);
+ static void exec_func(BuiltinFunc p_func, const Variant** p_inputs, Variant* r_return, Variant::CallError& r_error, String& r_error_str);
+ static BuiltinFunc find_function(const String& p_string);
+
private:
static const char* func_name[FUNC_MAX];
BuiltinFunc func;
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index b53e81f23f..f486cf1ab1 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -577,6 +577,13 @@ 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;
}
@@ -603,6 +610,7 @@ const char* VisualScriptExpression::token_name[TK_MAX]={
"PARENTHESIS OPEN",
"PARENTHESIS CLOSE",
"IDENTIFIER",
+"BUILTIN FUNC",
"SELF",
"CONSTANT",
"BASIC TYPE",
@@ -814,6 +822,53 @@ VisualScriptExpression::ENode* VisualScriptExpression::_parse_expression() {
expr=constructor;
} break;
+ case TK_BUILTIN_FUNC: {
+ //builtin function
+
+ Variant::Type bt = Variant::Type(int(tk.value));
+ _get_token(tk);
+ if (tk.type!=TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '('");
+ return NULL;
+ }
+
+ 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* expr=_parse_expression();
+ if (!expr)
+ return NULL;
+
+ bifunc->arguments.push_back(expr);
+
+ 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;
@@ -1338,6 +1393,34 @@ public:
} 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[i]=value;
+ argp[i]=&arr[i];
+ }
+
+
+ VisualScriptBuiltinFunc::exec_func(bifunc->func,argp.ptr(),&r_ret,ce,r_error_str);
+
+ if (ce.error!=Variant::CallError::CALL_OK) {
+ r_error_str="Builtin Call Failed. "+r_error_str;
+ return true;
+ }
+
+ } break;
case VisualScriptExpression::ENode::TYPE_CALL: {
const VisualScriptExpression::CallNode *call = static_cast<const VisualScriptExpression::CallNode*>(p_node);
diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h
index 90b955b5da..4edae133c7 100644
--- a/modules/visual_script/visual_script_expression.h
+++ b/modules/visual_script/visual_script_expression.h
@@ -2,6 +2,7 @@
#define VISUALSCRIPTEXPRESSION_H
#include "visual_script.h"
+#include "visual_script_builtin_funcs.h"
class VisualScriptExpression : public VisualScriptNode {
@@ -35,6 +36,7 @@ friend class VisualScriptNodeInstanceExpression;
TK_PARENTHESIS_OPEN,
TK_PARENTHESIS_CLOSE,
TK_IDENTIFIER,
+ TK_BUILTIN_FUNC,
TK_SELF,
TK_CONSTANT,
TK_BASIC_TYPE,
@@ -101,6 +103,7 @@ friend class VisualScriptNodeInstanceExpression;
TYPE_ARRAY,
TYPE_DICTIONARY,
TYPE_CONSTRUCTOR,
+ TYPE_BUILTIN_FUNC,
TYPE_CALL
};
@@ -214,6 +217,14 @@ friend class VisualScriptNodeInstanceExpression;
};
+ struct BuiltinFuncNode : public ENode {
+ VisualScriptBuiltinFunc::BuiltinFunc func;
+ Vector<ENode*> arguments;
+ BuiltinFuncNode() {
+ type=TYPE_BUILTIN_FUNC;
+ }
+ };
+
template<class T>
T* alloc_node() {
T* node = memnew(T);