diff options
Diffstat (limited to 'modules/gdscript/gd_functions.cpp')
-rw-r--r-- | modules/gdscript/gd_functions.cpp | 1218 |
1 files changed, 1218 insertions, 0 deletions
diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp new file mode 100644 index 0000000000..2930d9322c --- /dev/null +++ b/modules/gdscript/gd_functions.cpp @@ -0,0 +1,1218 @@ +/*************************************************************************/ +/* gd_functions.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* 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 "gd_functions.h" +#include "math_funcs.h" +#include "object_type_db.h" +#include "reference.h" +#include "gd_script.h" +#include "os/os.h" + +const char *GDFunctions::get_func_name(Function p_func) { + + ERR_FAIL_INDEX_V(p_func,FUNC_MAX,""); + + static const char *_names[FUNC_MAX]={ + "sin", + "cos", + "tan", + "sinh", + "cosh", + "tanh", + "asin", + "acos", + "atan", + "atan2", + "sqrt", + "fmod", + "fposmod", + "floor", + "ceil", + "round", + "abs", + "sign", + "pow", + "log", + "exp", + "is_nan", + "is_inf", + "ease", + "decimals", + "stepify", + "lerp", + "dectime", + "randomize", + "randi", + "randf", + "rand_range", + "rand_seed", + "deg2rad", + "rad2deg", + "linear2db", + "db2linear", + "max", + "min", + "clamp", + "nearest_po2", + "weakref", + "convert", + "typeof", + "str", + "print", + "printt", + "printerr", + "printraw", + "range", + "load", + "inst2dict", + "dict2inst", + "print_stack", + }; + + return _names[p_func]; + +} + +void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Variant &r_ret,Variant::CallError &r_error) { + + r_error.error=Variant::CallError::CALL_OK; +#ifdef DEBUG_ENABLED + +#define VALIDATE_ARG_COUNT(m_count) \ + if (p_arg_count<m_count) {\ + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;\ + r_error.argument=m_count;\ + return;\ + }\ + if (p_arg_count>m_count) {\ + r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;\ + r_error.argument=m_count;\ + return;\ + } + +#define VALIDATE_ARG_NUM(m_arg) \ + if (!p_args[m_arg]->is_num()) {\ + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\ + r_error.argument=m_arg;\ + r_error.expected=Variant::REAL;\ + return;\ + } + +#else + +#define VALIDATE_ARG_COUNT(m_count) +#define VALIDATE_ARG_NUM(m_arg) +#endif + + //using a switch, so the compiler generates a jumptable + + switch(p_func) { + + case MATH_SIN: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::sin(*p_args[0]); + } break; + case MATH_COS: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::cos(*p_args[0]); + } break; + case MATH_TAN: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::tan(*p_args[0]); + } break; + case MATH_SINH: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::sinh(*p_args[0]); + } break; + case MATH_COSH: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::cosh(*p_args[0]); + } break; + case MATH_TANH: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::tanh(*p_args[0]); + } break; + case MATH_ASIN: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::asin(*p_args[0]); + } break; + case MATH_ACOS: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::acos(*p_args[0]); + } break; + case MATH_ATAN: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::atan(*p_args[0]); + } break; + case MATH_ATAN2: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret=Math::atan2(*p_args[0],*p_args[1]); + } break; + case MATH_SQRT: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::sqrt(*p_args[0]); + } break; + case MATH_FMOD: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret=Math::fmod(*p_args[0],*p_args[1]); + } break; + case MATH_FPOSMOD: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret=Math::fposmod(*p_args[0],*p_args[1]); + } break; + case MATH_FLOOR: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::floor(*p_args[0]); + } break; + case MATH_CEIL: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::ceil(*p_args[0]); + } break; + case MATH_ROUND: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::round(*p_args[0]); + } break; + case MATH_ABS: { + VALIDATE_ARG_COUNT(1); + if (p_args[0]->get_type()==Variant::INT) { + + int64_t i = *p_args[0]; + r_ret=ABS(i); + } else if (p_args[0]->get_type()==Variant::REAL) { + + real_t r = *p_args[0]; + r_ret=Math::abs(r); + } else { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::REAL; + } + } break; + case MATH_SIGN: { + VALIDATE_ARG_COUNT(1); + if (p_args[0]->get_type()==Variant::INT) { + + int64_t i = *p_args[0]; + r_ret= i < 0 ? -1 : ( i > 0 ? +1 : 0); + } else if (p_args[0]->get_type()==Variant::REAL) { + + real_t r = *p_args[0]; + r_ret= r < 0.0 ? -1.0 : ( r > 0.0 ? +1.0 : 0.0); + } else { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::REAL; + } + } break; + case MATH_POW: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret=Math::pow(*p_args[0],*p_args[1]); + } break; + case MATH_LOG: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::log(*p_args[0]); + } break; + case MATH_EXP: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::exp(*p_args[0]); + } break; + case MATH_ISNAN: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::is_nan(*p_args[0]); + } break; + case MATH_ISINF: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::is_inf(*p_args[0]); + } break; + case MATH_EASE: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret=Math::ease(*p_args[0],*p_args[1]); + } break; + case MATH_DECIMALS: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::decimals(*p_args[0]); + } break; + case MATH_STEPIFY: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret=Math::stepify(*p_args[0],*p_args[1]); + } break; + case MATH_LERP: { + VALIDATE_ARG_COUNT(3); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + VALIDATE_ARG_NUM(2); + r_ret=Math::lerp(*p_args[0],*p_args[1],*p_args[2]); + } break; + case MATH_DECTIME: { + VALIDATE_ARG_COUNT(3); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + VALIDATE_ARG_NUM(2); + r_ret=Math::dectime(*p_args[0],*p_args[1],*p_args[2]); + } break; + case MATH_RANDOMIZE: { + Math::randomize(); + r_ret=Variant(); + } break; + case MATH_RAND: { + r_ret=Math::rand(); + } break; + case MATH_RANDF: { + r_ret=Math::randf(); + } break; + case MATH_RANDOM: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + r_ret=Math::random(*p_args[0],*p_args[1]); + } break; + case MATH_RANDSEED: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + uint32_t seed=*p_args[0]; + int ret = Math::rand_from_seed(&seed); + Array reta; + reta.push_back(ret); + reta.push_back(seed); + r_ret=reta; + + } break; + case MATH_DEG2RAD: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::deg2rad(*p_args[0]); + } break; + case MATH_RAD2DEG: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::rad2deg(*p_args[0]); + } break; + case MATH_LINEAR2DB: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::linear2db(*p_args[0]); + } break; + case MATH_DB2LINEAR: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + r_ret=Math::db2linear(*p_args[0]); + } break; + case LOGIC_MAX: { + VALIDATE_ARG_COUNT(2); + if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT) { + + int64_t a = *p_args[0]; + int64_t b = *p_args[1]; + r_ret=MAX(a,b); + } else { + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + + real_t a = *p_args[0]; + real_t b = *p_args[1]; + + r_ret=MAX(a,b); + } + + } break; + case LOGIC_MIN: { + VALIDATE_ARG_COUNT(2); + if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT) { + + int64_t a = *p_args[0]; + int64_t b = *p_args[1]; + r_ret=MIN(a,b); + } else { + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + + real_t a = *p_args[0]; + real_t b = *p_args[1]; + + r_ret=MIN(a,b); + } + } break; + case LOGIC_CLAMP: { + VALIDATE_ARG_COUNT(3); + if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT && p_args[2]->get_type()==Variant::INT) { + + int64_t a = *p_args[0]; + int64_t b = *p_args[1]; + int64_t c = *p_args[2]; + r_ret=CLAMP(a,b,c); + } else { + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + VALIDATE_ARG_NUM(2); + + real_t a = *p_args[0]; + real_t b = *p_args[1]; + real_t c = *p_args[2]; + + r_ret=CLAMP(a,b,c); + } + } break; + case LOGIC_NEAREST_PO2: { + VALIDATE_ARG_COUNT(1); + VALIDATE_ARG_NUM(0); + int64_t num = *p_args[0]; + r_ret = nearest_power_of_2(num); + } break; + case OBJ_WEAKREF: { + VALIDATE_ARG_COUNT(1); + if (p_args[0]->get_type()!=Variant::OBJECT) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::OBJECT; + return; + + } + + if (p_args[0]->is_ref()) { + + REF r = *p_args[0]; + if (!r.is_valid()) { + r_ret=Variant(); + return; + } + + Ref<WeakRef> wref = memnew( WeakRef ); + wref->set_ref(r); + r_ret=wref; + } else { + Object *obj = *p_args[0]; + if (!obj) { + r_ret=Variant(); + return; + } + Ref<WeakRef> wref = memnew( WeakRef ); + wref->set_obj(obj); + r_ret=wref; + } + + + + + } break; + case TYPE_CONVERT: { + VALIDATE_ARG_COUNT(2); + VALIDATE_ARG_NUM(1); + int type=*p_args[1]; + if (type<0 || type>=Variant::VARIANT_MAX) { + + ERR_PRINT("Invalid type argument to convert()"); + r_ret=Variant::NIL; + + } else { + + + r_ret=Variant::construct(Variant::Type(type),p_args,1,r_error); + } + } break; + case TYPE_OF: { + + VALIDATE_ARG_COUNT(1); + r_ret = p_args[0]->get_type(); + + } break; + case TEXT_STR: { + + String str; + for(int i=0;i<p_arg_count;i++) { + + String os = p_args[i]->operator String();; + if (i==0) + str=os; + else + str+=os; + } + + r_ret=str; + + } break; + case TEXT_PRINT: { + + String str; + for(int i=0;i<p_arg_count;i++) { + + str+=p_args[i]->operator String(); + } + + //str+="\n"; + print_line(str); + r_ret=Variant(); + + + } break; + case TEXT_PRINT_TABBED: { + + String str; + for(int i=0;i<p_arg_count;i++) { + + if (i) + str+="\t"; + str+=p_args[i]->operator String(); + } + + //str+="\n"; + print_line(str); + r_ret=Variant(); + + + } break; + + case TEXT_PRINTERR: { + + String str; + for(int i=0;i<p_arg_count;i++) { + + str+=p_args[i]->operator String(); + } + + //str+="\n"; + OS::get_singleton()->printerr("%s\n",str.utf8().get_data()); + r_ret=Variant(); + + } break; + case TEXT_PRINTRAW: { + String str; + for(int i=0;i<p_arg_count;i++) { + + str+=p_args[i]->operator String(); + } + + //str+="\n"; + OS::get_singleton()->print("%s\n",str.utf8().get_data()); + r_ret=Variant(); + + } break; + case GEN_RANGE: { + + + + switch(p_arg_count) { + + case 0: { + + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument=1; + + } break; + case 1: { + + VALIDATE_ARG_NUM(0); + int count=*p_args[0]; + Array arr(true); + if (count<=0) { + r_ret=arr; + return; + } + Error err = arr.resize(count); + if (err!=OK) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_ret=Variant(); + return; + } + + for(int i=0;i<count;i++) { + arr[i]=i; + } + + r_ret=arr; + } break; + case 2: { + + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + + int from=*p_args[0]; + int to=*p_args[1]; + + Array arr(true); + if (from>=to) { + r_ret=arr; + return; + } + Error err = arr.resize(to-from); + if (err!=OK) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_ret=Variant(); + return; + } + for(int i=from;i<to;i++) + arr[i-from]=i; + r_ret=arr; + } break; + case 3: { + + VALIDATE_ARG_NUM(0); + VALIDATE_ARG_NUM(1); + VALIDATE_ARG_NUM(2); + + int from=*p_args[0]; + int to=*p_args[1]; + int incr=*p_args[2]; + if (incr==0) { + + ERR_EXPLAIN("step argument is zero!"); + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + ERR_FAIL(); + } + + Array arr(true); + if (from>=to && incr>0) { + r_ret=arr; + return; + } + if (from<=to && incr<0) { + r_ret=arr; + return; + } + + //calculate how many + int count=0; + if (incr>0) { + + count=((to-from-1)/incr)+1; + } else { + + count=((from-to-1)/-incr)+1; + } + + + Error err = arr.resize(count); + + if (err!=OK) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_ret=Variant(); + return; + } + + if (incr>0) { + int idx=0; + for(int i=from;i<to;i+=incr) { + arr[idx++]=i; + } + } else { + + int idx=0; + for(int i=from;i>to;i+=incr) { + arr[idx++]=i; + } + } + + r_ret=arr; + } break; + default: { + + r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument=3; + } break; + } + + } break; + case RESOURCE_LOAD: { + VALIDATE_ARG_COUNT(1); + if (p_args[0]->get_type()!=Variant::STRING) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_ret=Variant(); + } + r_ret=ResourceLoader::load(*p_args[0]); + + } + case INST2DICT: { + + VALIDATE_ARG_COUNT(1); + + if (p_args[0]->get_type()==Variant::NIL) { + r_ret=Variant(); + } else if (p_args[0]->get_type()!=Variant::OBJECT) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_ret=Variant(); + } else { + + Object *obj = *p_args[0]; + if (!obj) { + r_ret=Variant(); + + } else if (!obj->get_script_instance() || obj->get_script_instance()->get_language()!=GDScriptLanguage::get_singleton()) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::DICTIONARY; + ERR_PRINT("Not a script with an instance"); + + } else { + + GDInstance *ins = static_cast<GDInstance*>(obj->get_script_instance()); + Ref<GDScript> base = ins->get_script(); + if (base.is_null()) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::DICTIONARY; + ERR_PRINT("Not based on a script"); + return; + + } + + + GDScript *p = base.ptr(); + Vector<StringName> sname; + + while(p->_owner) { + + sname.push_back(p->name); + p=p->_owner; + } + sname.invert(); + + + if (!p->path.is_resource_file()) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::DICTIONARY; + print_line("PATH: "+p->path); + ERR_PRINT("Not based on a resource file"); + + return; + } + + NodePath cp(sname,Vector<StringName>(),false); + + Dictionary d(true); + d["@subpath"]=cp; + d["@path"]=p->path; + + + p = base.ptr(); + + while(p) { + + for(Set<StringName>::Element *E=p->members.front();E;E=E->next()) { + + Variant value; + if (ins->get(E->get(),value)) { + + String k = E->get(); + if (!d.has(k)) { + d[k]=value; + } + } + } + + p=p->_base; + } + + r_ret=d; + + } + } + + } break; + case DICT2INST: { + + VALIDATE_ARG_COUNT(1); + + if (p_args[0]->get_type()!=Variant::DICTIONARY) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::DICTIONARY; + return; + } + + Dictionary d = *p_args[0]; + + if (!d.has("@path")) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::OBJECT; + return; + } + + Ref<Script> scr = ResourceLoader::load(d["@path"]); + if (!scr.is_valid()) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::OBJECT; + return; + } + + Ref<GDScript> gdscr = scr; + + if (!gdscr.is_valid()) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::OBJECT; + return; + } + + NodePath sub; + if (d.has("@subpath")) { + sub=d["@subpath"]; + } + + for(int i=0;i<sub.get_name_count();i++) { + + gdscr = gdscr->subclasses[ sub.get_name(i)]; + if (!gdscr.is_valid()) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::OBJECT; + return; + } + } + + + r_ret = gdscr->_new(NULL,0,r_error); + + } break; + + case PRINT_STACK: { + + ScriptLanguage* script = GDScriptLanguage::get_singleton(); + for (int i=0; i < script->debug_get_stack_level_count(); i++) { + + print_line("Frame "+itos(i)+" - "+script->debug_get_stack_level_source(i)+":"+itos(script->debug_get_stack_level_line(i))+" in function '"+script->debug_get_stack_level_function(i)+"'"); + }; + } break; + + case FUNC_MAX: { + + ERR_FAIL_V(); + } break; + + } + +} + +bool GDFunctions::is_deterministic(Function p_func) { + + //man i couldn't have chosen a worse function name, + //way too controversial.. + + switch(p_func) { + + case MATH_SIN: + case MATH_COS: + case MATH_TAN: + case MATH_SINH: + case MATH_COSH: + case MATH_TANH: + case MATH_ASIN: + case MATH_ACOS: + case MATH_ATAN: + case MATH_ATAN2: + case MATH_SQRT: + case MATH_FMOD: + case MATH_FPOSMOD: + case MATH_FLOOR: + case MATH_CEIL: + case MATH_ROUND: + case MATH_ABS: + case MATH_SIGN: + case MATH_POW: + case MATH_LOG: + case MATH_EXP: + case MATH_ISNAN: + case MATH_ISINF: + case MATH_EASE: + case MATH_DECIMALS: + case MATH_STEPIFY: + case MATH_LERP: + case MATH_DECTIME: + case MATH_DEG2RAD: + case MATH_RAD2DEG: + case MATH_LINEAR2DB: + case MATH_DB2LINEAR: + case LOGIC_MAX: + case LOGIC_MIN: + case LOGIC_CLAMP: + case LOGIC_NEAREST_PO2: + case TYPE_CONVERT: + case TYPE_OF: + case TEXT_STR: +// enable for debug only, otherwise not desirable - case GEN_RANGE: + return true; + default: + return false; + + } + + return false; + + +} + +MethodInfo GDFunctions::get_info(Function p_func) { + +#ifdef TOOLS_ENABLED + //using a switch, so the compiler generates a jumptable + + switch(p_func) { + + case MATH_SIN: { + MethodInfo mi("sin",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + + } break; + case MATH_COS: { + MethodInfo mi("cos",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_TAN: { + MethodInfo mi("tan",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_SINH: { + MethodInfo mi("sinh",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_COSH: { + MethodInfo mi("cosh",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_TANH: { + MethodInfo mi("tanh",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_ASIN: { + MethodInfo mi("asin",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_ACOS: { + MethodInfo mi("acos",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_ATAN: { + MethodInfo mi("atan",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_ATAN2: { + MethodInfo mi("atan2",PropertyInfo(Variant::REAL,"x"),PropertyInfo(Variant::REAL,"y")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_SQRT: { + MethodInfo mi("sqrt",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_FMOD: { + MethodInfo mi("fmod",PropertyInfo(Variant::REAL,"x"),PropertyInfo(Variant::REAL,"y")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_FPOSMOD: { + MethodInfo mi("fposmod",PropertyInfo(Variant::REAL,"x"),PropertyInfo(Variant::REAL,"y")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_FLOOR: { + MethodInfo mi("floor",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_CEIL: { + MethodInfo mi("ceil",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_ROUND: { + MethodInfo mi("round",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_ABS: { + MethodInfo mi("abs",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_SIGN: { + MethodInfo mi("sign",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_POW: { + MethodInfo mi("pow",PropertyInfo(Variant::REAL,"x"),PropertyInfo(Variant::REAL,"y")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_LOG: { + MethodInfo mi("log",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_EXP: { + MethodInfo mi("exp",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_ISNAN: { + MethodInfo mi("isnan",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_ISINF: { + MethodInfo mi("isinf",PropertyInfo(Variant::REAL,"s")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_EASE: { + MethodInfo mi("ease",PropertyInfo(Variant::REAL,"s"),PropertyInfo(Variant::REAL,"curve")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_DECIMALS: { + MethodInfo mi("decimals",PropertyInfo(Variant::REAL,"step")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_STEPIFY: { + MethodInfo mi("stepify",PropertyInfo(Variant::REAL,"s"),PropertyInfo(Variant::REAL,"step")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_LERP: { + MethodInfo mi("lerp",PropertyInfo(Variant::REAL,"a"),PropertyInfo(Variant::REAL,"b"), PropertyInfo(Variant::REAL,"c")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_DECTIME: { + MethodInfo mi("dectime",PropertyInfo(Variant::REAL,"value"),PropertyInfo(Variant::REAL,"amount"),PropertyInfo(Variant::REAL,"step")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_RANDOMIZE: { + MethodInfo mi("randomize"); + mi.return_val.type=Variant::NIL; + return mi; + } break; + case MATH_RAND: { + MethodInfo mi("rand"); + mi.return_val.type=Variant::INT; + return mi; + } break; + case MATH_RANDF: { + MethodInfo mi("randf"); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_RANDOM: { + MethodInfo mi("rand_range",PropertyInfo(Variant::REAL,"from"),PropertyInfo(Variant::REAL,"to")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_RANDSEED: { + MethodInfo mi("rand_seed",PropertyInfo(Variant::REAL,"seed")); + mi.return_val.type=Variant::ARRAY; + return mi; + } break; + case MATH_DEG2RAD: { + MethodInfo mi("deg2rad",PropertyInfo(Variant::REAL,"deg")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_RAD2DEG: { + MethodInfo mi("rad2deg",PropertyInfo(Variant::REAL,"rad")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_LINEAR2DB: { + MethodInfo mi("linear2db",PropertyInfo(Variant::REAL,"nrg")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case MATH_DB2LINEAR: { + MethodInfo mi("db2linear",PropertyInfo(Variant::REAL,"db")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case LOGIC_MAX: { + MethodInfo mi("max",PropertyInfo(Variant::REAL,"a"),PropertyInfo(Variant::REAL,"b")); + mi.return_val.type=Variant::REAL; + return mi; + + } break; + case LOGIC_MIN: { + MethodInfo mi("min",PropertyInfo(Variant::REAL,"a"),PropertyInfo(Variant::REAL,"b")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case LOGIC_CLAMP: { + MethodInfo mi("clamp",PropertyInfo(Variant::REAL,"val"),PropertyInfo(Variant::REAL,"min"),PropertyInfo(Variant::REAL,"max")); + mi.return_val.type=Variant::REAL; + return mi; + } break; + case LOGIC_NEAREST_PO2: { + MethodInfo mi("nearest_po2",PropertyInfo(Variant::INT,"val")); + mi.return_val.type=Variant::INT; + return mi; + } break; + case OBJ_WEAKREF: { + + MethodInfo mi("weakref",PropertyInfo(Variant::OBJECT,"obj")); + mi.return_val.type=Variant::OBJECT; + return mi; + + } break; + case TYPE_CONVERT: { + + MethodInfo mi("convert",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::INT,"type")); + mi.return_val.type=Variant::OBJECT; + return mi; + } break; + case TYPE_OF: { + MethodInfo mi("typeof",PropertyInfo(Variant::NIL,"what")); + mi.return_val.type=Variant::INT; + }; + case TEXT_STR: { + + MethodInfo mi("str",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"...")); + mi.return_val.type=Variant::STRING; + return mi; + + } break; + case TEXT_PRINT: { + + MethodInfo mi("print",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"...")); + mi.return_val.type=Variant::NIL; + return mi; + + } break; + case TEXT_PRINT_TABBED: { + + MethodInfo mi("printt",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"...")); + mi.return_val.type=Variant::NIL; + return mi; + + } break; + case TEXT_PRINTERR: { + + MethodInfo mi("printerr",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"...")); + mi.return_val.type=Variant::NIL; + return mi; + + } break; + case TEXT_PRINTRAW: { + + MethodInfo mi("printraw",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"...")); + mi.return_val.type=Variant::NIL; + return mi; + + } break; + case GEN_RANGE: { + + MethodInfo mi("range",PropertyInfo(Variant::NIL,"...")); + mi.return_val.type=Variant::ARRAY; + return mi; + } break; + case RESOURCE_LOAD: { + + MethodInfo mi("load",PropertyInfo(Variant::STRING,"path")); + mi.return_val.type=Variant::OBJECT; + return mi; + } break; + case INST2DICT: { + + MethodInfo mi("inst2dict",PropertyInfo(Variant::OBJECT,"inst")); + mi.return_val.type=Variant::DICTIONARY; + return mi; + } break; + case DICT2INST: { + + MethodInfo mi("dict2inst",PropertyInfo(Variant::DICTIONARY,"dict")); + mi.return_val.type=Variant::OBJECT; + return mi; + } break; + + case PRINT_STACK: { + MethodInfo mi("print_stack"); + mi.return_val.type=Variant::NIL; + return mi; + } break; + + case FUNC_MAX: { + + ERR_FAIL_V(MethodInfo()); + } break; + + } +#endif + + return MethodInfo(); +} |