diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-09-06 19:12:28 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-09-06 19:14:47 -0300 |
commit | 23ababdcd57079182172b1c5467fcd6bb0f303d3 (patch) | |
tree | 015d23f2691e7be8a89998aef9100492ffef324e /modules | |
parent | 78275aad871031ea0a4e20b901ba60d741415300 (diff) |
Changed Vector3.snap from fmod to stepify, which makes more sense, fixes #6399
Diffstat (limited to 'modules')
-rw-r--r-- | modules/visual_script/visual_script.cpp | 3 | ||||
-rw-r--r-- | modules/visual_script/visual_script_builtin_funcs.cpp | 782 | ||||
-rw-r--r-- | modules/visual_script/visual_script_builtin_funcs.h | 5 | ||||
-rw-r--r-- | modules/visual_script/visual_script_expression.cpp | 83 | ||||
-rw-r--r-- | modules/visual_script/visual_script_expression.h | 11 |
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); |