diff options
Diffstat (limited to 'core/make_binders.py')
-rw-r--r-- | core/make_binders.py | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/core/make_binders.py b/core/make_binders.py new file mode 100644 index 0000000000..5d35dd9337 --- /dev/null +++ b/core/make_binders.py @@ -0,0 +1,241 @@ +# -*- coding: ibm850 -*- + + +template_typed=""" +#ifdef TYPED_METHOD_BIND +template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> +class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind { +public: + + $ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$; +#ifdef DEBUG_METHODS_ENABLED + virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); } + Variant::Type _get_argument_type(int p_argument) const { + $ifret if (p_argument==-1) return Variant::get_type_for<R>();$ + $arg if (p_argument==(@-1)) return Variant::get_type_for<P@>(); + $ + return Variant::NIL; + } +#endif + virtual String get_instance_type() const { + return T::get_type_static(); + } + + virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) { + + T *instance=p_object->cast_to<T>(); + r_error.error=Variant::CallError::CALL_OK; +#ifdef DEBUG_METHODS_ENABLED + + ERR_FAIL_COND_V(!instance,Variant()); + if (p_arg_count>get_argument_count()) { + r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument=get_argument_count(); + return Variant(); + + } + if (p_arg_count<(get_argument_count()-get_default_argument_count())) { + + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument=get_argument_count()-get_default_argument_count(); + return Variant(); + } + $arg CHECK_ARG(@); + $ +#endif + $ifret Variant ret = $(instance->*method)($arg, _VC(@)$); + $ifret return Variant(ret);$ + $ifnoret return Variant();$ + } + + + MethodBind$argc$$ifret R$$ifconst C$ () { +#ifdef DEBUG_METHODS_ENABLED + _set_const($ifconst true$$ifnoconst false$); + _generate_argument_types($argc$); +#else + set_argument_count($argc$); +#endif + }; +}; + +template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> +MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) { + + MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) ); + a->method=p_method; + return a; +} +#endif +""" + +template=""" +#ifndef TYPED_METHOD_BIND +$iftempl template<$ $ifret class R$ $ifretargs ,$ $arg, class P@$ $iftempl >$ +class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind { + +public: + + StringName type_name; + $ifret R$ $ifnoret void$ (__UnexistingClass::*method)($arg, P@$) $ifconst const$; + +#ifdef DEBUG_METHODS_ENABLED + virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); } + + Variant::Type _get_argument_type(int p_argument) const { + $ifret if (p_argument==-1) return Variant::get_type_for<R>();$ + $arg if (p_argument==(@-1)) return Variant::get_type_for<P@>(); + $ + return Variant::NIL; + } +#endif + virtual String get_instance_type() const { + return type_name; + } + + virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) { + + __UnexistingClass *instance = (__UnexistingClass*)p_object; + + r_error.error=Variant::CallError::CALL_OK; +#ifdef DEBUG_METHODS_ENABLED + + ERR_FAIL_COND_V(!instance,Variant()); + if (p_arg_count>get_argument_count()) { + r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument=get_argument_count(); + return Variant(); + } + + if (p_arg_count<(get_argument_count()-get_default_argument_count())) { + + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument=get_argument_count()-get_default_argument_count(); + return Variant(); + } + + $arg CHECK_ARG(@); + $ +#endif + $ifret Variant ret = $(instance->*method)($arg, _VC(@)$); + $ifret return Variant(ret);$ + $ifnoret return Variant();$ + } + + MethodBind$argc$$ifret R$$ifconst C$ () { +#ifdef DEBUG_METHODS_ENABLED + _set_const($ifconst true$$ifnoconst false$); + _generate_argument_types($argc$); +#else + set_argument_count($argc$); +#endif + }; +}; + +template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> +MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) { + + MethodBind$argc$$ifret R$$ifconst C$ $iftempl <$ $ifret R$ $ifretargs ,$ $arg, P@$ $iftempl >$ * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$ $iftempl <$ $ifret R$ $ifretargs ,$ $arg, P@$ $iftempl >$) ); + union { + + $ifret R$ $ifnoret void$ (T::*sm)($arg, P@$) $ifconst const$; + $ifret R$ $ifnoret void$ (__UnexistingClass::*dm)($arg, P@$) $ifconst const$; + } u; + u.sm=p_method; + a->method=u.dm; + a->type_name=T::get_type_static(); + return a; +} +#endif +""" + + +def make_version(template,nargs,argmax,const,ret): + + intext=template + from_pos=0 + outtext="" + + while(True): + to_pos=intext.find("$",from_pos) + if (to_pos==-1): + outtext+=intext[from_pos:] + break + else: + outtext+=intext[from_pos:to_pos] + end=intext.find("$",to_pos+1) + if (end==-1): + break # ignore + macro=intext[to_pos+1:end] + cmd="" + data="" + + if (macro.find(" ")!=-1): + cmd=macro[0:macro.find(" ")] + data=macro[macro.find(" ")+1:] + else: + cmd=macro + + if (cmd=="argc"): + outtext+=str(nargs) + if (cmd=="ifret" and ret): + outtext+=data + if (cmd=="ifargs" and nargs): + outtext+=data + if (cmd=="ifretargs" and nargs and ret): + outtext+=data + if (cmd=="ifconst" and const): + outtext+=data + elif (cmd=="ifnoconst" and not const): + outtext+=data + elif (cmd=="ifnoret" and not ret): + outtext+=data + elif (cmd=="iftempl" and (nargs>0 or ret)): + outtext+=data + elif (cmd=="arg,"): + for i in range(1,nargs+1): + if (i>1): + outtext+=", " + outtext+=data.replace("@",str(i)) + elif (cmd=="arg"): + for i in range(1,nargs+1): + outtext+=data.replace("@",str(i)) + elif (cmd=="noarg"): + for i in range(nargs+1,argmax+1): + outtext+=data.replace("@",str(i)) + elif (cmd=="noarg"): + for i in range(nargs+1,argmax+1): + outtext+=data.replace("@",str(i)) + + from_pos=end+1 + + return outtext + + +def run(target, source, env): + + versions=5 + text="" + + for i in range(0,versions+1): + + text+=make_version(template,i,5,False,False) + text+=make_version(template_typed,i,5,False,False) + text+=make_version(template,i,5,False,True) + text+=make_version(template_typed,i,5,False,True) + text+=make_version(template,i,5,True,False) + text+=make_version(template_typed,i,5,True,False) + text+=make_version(template,i,5,True,True) + text+=make_version(template_typed,i,5,True,True) + + + f=open(target[0].path,"w") + f.write(text) + f.close() + + + + + + + |