# -*- coding: ibm850 -*- template_typed = """ #ifdef TYPED_METHOD_BIND template 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); } virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const { $ifret if (p_arg==-1) return GetTypeInfo::METADATA;$ $arg if (p_arg==(@-1)) return GetTypeInfo::METADATA; $ return GodotTypeInfo::METADATA_NONE; } Variant::Type _get_argument_type(int p_argument) const { $ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo::VARIANT_TYPE;$ $arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo::VARIANT_TYPE; $ return Variant::NIL; } virtual PropertyInfo _gen_argument_type_info(int p_argument) const { $ifret if (p_argument==-1) return GetTypeInfo::get_class_info();$ $arg if (p_argument==(@-1)) return GetTypeInfo::get_class_info(); $ return PropertyInfo(); } #endif virtual String get_instance_class() const { return T::get_class_static(); } virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) { T *instance=Object::cast_to(p_object); r_error.error=Callable::CallError::CALL_OK; #ifdef DEBUG_METHODS_ENABLED ERR_FAIL_COND_V(!instance,Variant()); if (p_arg_count>get_argument_count()) { r_error.error=Callable::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=Callable::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();$ } #ifdef PTRCALL_ENABLED virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) { T *instance=Object::cast_to(p_object); $ifret PtrToArg::encode( $ (instance->*method)($arg, PtrToArg::convert(p_args[@-1])$) $ifret ,r_ret)$ ; } #endif 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 $ifret _set_returns(true); $ } }; template MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) { MethodBind$argc$$ifret R$$ifconst C$ * a = memnew( (MethodBind$argc$$ifret R$$ifconst C$) ); 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); } virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const { $ifret if (p_arg==-1) return GetTypeInfo::METADATA;$ $arg if (p_arg==(@-1)) return GetTypeInfo::METADATA; $ return GodotTypeInfo::METADATA_NONE; } Variant::Type _get_argument_type(int p_argument) const { $ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo::VARIANT_TYPE;$ $arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo::VARIANT_TYPE; $ return Variant::NIL; } virtual PropertyInfo _gen_argument_type_info(int p_argument) const { $ifret if (p_argument==-1) return GetTypeInfo::get_class_info();$ $arg if (p_argument==(@-1)) return GetTypeInfo::get_class_info(); $ return PropertyInfo(); } #endif virtual String get_instance_class() const { return type_name; } virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) { __UnexistingClass *instance = (__UnexistingClass*)p_object; r_error.error=Callable::CallError::CALL_OK; #ifdef DEBUG_METHODS_ENABLED ERR_FAIL_COND_V(!instance,Variant()); if (p_arg_count>get_argument_count()) { r_error.error=Callable::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=Callable::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();$ } #ifdef PTRCALL_ENABLED virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) { __UnexistingClass *instance = (__UnexistingClass*)p_object; $ifret PtrToArg::encode( $ (instance->*method)($arg, PtrToArg::convert(p_args[@-1])$) $ifret ,r_ret) $ ; } #endif 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 $ifret _set_returns(true); $ } }; template 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_class_static(); return a; } #endif """ template_typed_free_func = """ #ifdef TYPED_METHOD_BIND template class FunctionBind$argc$$ifret R$$ifconst C$ : public MethodBind { public: $ifret R$ $ifnoret void$ (*method) ($ifconst const$ T *$ifargs , $$arg, P@$); #ifdef DEBUG_METHODS_ENABLED virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); } virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const { $ifret if (p_arg==-1) return GetTypeInfo::METADATA;$ $arg if (p_arg==(@-1)) return GetTypeInfo::METADATA; $ return GodotTypeInfo::METADATA_NONE; } Variant::Type _get_argument_type(int p_argument) const { $ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo::VARIANT_TYPE;$ $arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo::VARIANT_TYPE; $ return Variant::NIL; } virtual PropertyInfo _gen_argument_type_info(int p_argument) const { $ifret if (p_argument==-1) return GetTypeInfo::get_class_info();$ $arg if (p_argument==(@-1)) return GetTypeInfo::get_class_info(); $ return PropertyInfo(); } #endif virtual String get_instance_class() const { return T::get_class_static(); } virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) { T *instance=Object::cast_to(p_object); r_error.error=Callable::CallError::CALL_OK; #ifdef DEBUG_METHODS_ENABLED ERR_FAIL_COND_V(!instance,Variant()); if (p_arg_count>get_argument_count()) { r_error.error=Callable::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=Callable::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 = $(method)(instance$ifargs , $$arg, _VC(@)$); $ifret return Variant(ret);$ $ifnoret return Variant();$ } #ifdef PTRCALL_ENABLED virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) { T *instance=Object::cast_to(p_object); $ifret PtrToArg::encode( $ (method)(instance$ifargs , $$arg, PtrToArg::convert(p_args[@-1])$) $ifret ,r_ret)$ ; } #endif FunctionBind$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 $ifret _set_returns(true); $ } }; template MethodBind* create_method_bind($ifret R$ $ifnoret void$ (*p_method)($ifconst const$ T *$ifargs , $$arg, P@$) ) { FunctionBind$argc$$ifret R$$ifconst C$ * a = memnew( (FunctionBind$argc$$ifret R$$ifconst C$) ); a->method=p_method; 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)) from_pos = end + 1 return outtext def run(target, source, env): versions = 15 versions_ext = 6 text = "" text_ext = "" text_free_func = "#ifndef METHOD_BIND_FREE_FUNC_H\n#define METHOD_BIND_FREE_FUNC_H\n" text_free_func += "\n//including this header file allows method binding to use free functions\n" text_free_func += ( "//note that the free function must have a pointer to an instance of the class as its first parameter\n" ) for i in range(0, versions + 1): t = "" t += make_version(template, i, versions, False, False) t += make_version(template_typed, i, versions, False, False) t += make_version(template, i, versions, False, True) t += make_version(template_typed, i, versions, False, True) t += make_version(template, i, versions, True, False) t += make_version(template_typed, i, versions, True, False) t += make_version(template, i, versions, True, True) t += make_version(template_typed, i, versions, True, True) if i >= versions_ext: text_ext += t else: text += t text_free_func += make_version(template_typed_free_func, i, versions, False, False) text_free_func += make_version(template_typed_free_func, i, versions, False, True) text_free_func += make_version(template_typed_free_func, i, versions, True, False) text_free_func += make_version(template_typed_free_func, i, versions, True, True) text_free_func += "#endif" with open(target[0], "w") as f: f.write(text) with open(target[1], "w") as f: f.write(text_ext) with open(target[2], "w") as f: f.write(text_free_func) if __name__ == "__main__": from platform_methods import subprocess_main subprocess_main(globals())