make_binders.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. # -*- coding: ibm850 -*-
  2. template_typed = """
  3. #ifdef TYPED_METHOD_BIND
  4. template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
  5. class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
  6. public:
  7. $ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$;
  8. #ifdef DEBUG_METHODS_ENABLED
  9. virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
  10. Variant::Type _get_argument_type(int p_argument) const {
  11. $ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
  12. $arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE;
  13. $
  14. return Variant::NIL;
  15. }
  16. virtual PropertyInfo _gen_argument_type_info(int p_argument) const {
  17. $ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$
  18. $arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info();
  19. $
  20. return PropertyInfo();
  21. }
  22. #endif
  23. virtual String get_instance_class() const {
  24. return T::get_class_static();
  25. }
  26. virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
  27. T *instance=Object::cast_to<T>(p_object);
  28. r_error.error=Variant::CallError::CALL_OK;
  29. #ifdef DEBUG_METHODS_ENABLED
  30. ERR_FAIL_COND_V(!instance,Variant());
  31. if (p_arg_count>get_argument_count()) {
  32. r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  33. r_error.argument=get_argument_count();
  34. return Variant();
  35. }
  36. if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
  37. r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  38. r_error.argument=get_argument_count()-get_default_argument_count();
  39. return Variant();
  40. }
  41. $arg CHECK_ARG(@);
  42. $
  43. #endif
  44. $ifret Variant ret = $(instance->*method)($arg, _VC(@)$);
  45. $ifret return Variant(ret);$
  46. $ifnoret return Variant();$
  47. }
  48. #ifdef PTRCALL_ENABLED
  49. virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) {
  50. T *instance=Object::cast_to<T>(p_object);
  51. $ifret PtrToArg<R>::encode( $ (instance->*method)($arg, PtrToArg<P@>::convert(p_args[@-1])$) $ifret ,r_ret)$ ;
  52. }
  53. #endif
  54. MethodBind$argc$$ifret R$$ifconst C$ () {
  55. #ifdef DEBUG_METHODS_ENABLED
  56. _set_const($ifconst true$$ifnoconst false$);
  57. _generate_argument_types($argc$);
  58. #else
  59. set_argument_count($argc$);
  60. #endif
  61. $ifret _set_returns(true); $
  62. };
  63. };
  64. template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
  65. MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) {
  66. 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@$>) );
  67. a->method=p_method;
  68. return a;
  69. }
  70. #endif
  71. """
  72. template = """
  73. #ifndef TYPED_METHOD_BIND
  74. $iftempl template<$ $ifret class R$ $ifretargs ,$ $arg, class P@$ $iftempl >$
  75. class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind {
  76. public:
  77. StringName type_name;
  78. $ifret R$ $ifnoret void$ (__UnexistingClass::*method)($arg, P@$) $ifconst const$;
  79. #ifdef DEBUG_METHODS_ENABLED
  80. virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
  81. Variant::Type _get_argument_type(int p_argument) const {
  82. $ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
  83. $arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE;
  84. $
  85. return Variant::NIL;
  86. }
  87. virtual PropertyInfo _gen_argument_type_info(int p_argument) const {
  88. $ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$
  89. $arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info();
  90. $
  91. return PropertyInfo();
  92. }
  93. #endif
  94. virtual String get_instance_class() const {
  95. return type_name;
  96. }
  97. virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
  98. __UnexistingClass *instance = (__UnexistingClass*)p_object;
  99. r_error.error=Variant::CallError::CALL_OK;
  100. #ifdef DEBUG_METHODS_ENABLED
  101. ERR_FAIL_COND_V(!instance,Variant());
  102. if (p_arg_count>get_argument_count()) {
  103. r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  104. r_error.argument=get_argument_count();
  105. return Variant();
  106. }
  107. if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
  108. r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  109. r_error.argument=get_argument_count()-get_default_argument_count();
  110. return Variant();
  111. }
  112. $arg CHECK_ARG(@);
  113. $
  114. #endif
  115. $ifret Variant ret = $(instance->*method)($arg, _VC(@)$);
  116. $ifret return Variant(ret);$
  117. $ifnoret return Variant();$
  118. }
  119. #ifdef PTRCALL_ENABLED
  120. virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) {
  121. __UnexistingClass *instance = (__UnexistingClass*)p_object;
  122. $ifret PtrToArg<R>::encode( $ (instance->*method)($arg, PtrToArg<P@>::convert(p_args[@-1])$) $ifret ,r_ret) $ ;
  123. }
  124. #endif
  125. MethodBind$argc$$ifret R$$ifconst C$ () {
  126. #ifdef DEBUG_METHODS_ENABLED
  127. _set_const($ifconst true$$ifnoconst false$);
  128. _generate_argument_types($argc$);
  129. #else
  130. set_argument_count($argc$);
  131. #endif
  132. $ifret _set_returns(true); $
  133. };
  134. };
  135. template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
  136. MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$) $ifconst const$ ) {
  137. 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 >$) );
  138. union {
  139. $ifret R$ $ifnoret void$ (T::*sm)($arg, P@$) $ifconst const$;
  140. $ifret R$ $ifnoret void$ (__UnexistingClass::*dm)($arg, P@$) $ifconst const$;
  141. } u;
  142. u.sm=p_method;
  143. a->method=u.dm;
  144. a->type_name=T::get_class_static();
  145. return a;
  146. }
  147. #endif
  148. """
  149. def make_version(template, nargs, argmax, const, ret):
  150. intext = template
  151. from_pos = 0
  152. outtext = ""
  153. while(True):
  154. to_pos = intext.find("$", from_pos)
  155. if (to_pos == -1):
  156. outtext += intext[from_pos:]
  157. break
  158. else:
  159. outtext += intext[from_pos:to_pos]
  160. end = intext.find("$", to_pos + 1)
  161. if (end == -1):
  162. break # ignore
  163. macro = intext[to_pos + 1:end]
  164. cmd = ""
  165. data = ""
  166. if (macro.find(" ") != -1):
  167. cmd = macro[0:macro.find(" ")]
  168. data = macro[macro.find(" ") + 1:]
  169. else:
  170. cmd = macro
  171. if (cmd == "argc"):
  172. outtext += str(nargs)
  173. if (cmd == "ifret" and ret):
  174. outtext += data
  175. if (cmd == "ifargs" and nargs):
  176. outtext += data
  177. if (cmd == "ifretargs" and nargs and ret):
  178. outtext += data
  179. if (cmd == "ifconst" and const):
  180. outtext += data
  181. elif (cmd == "ifnoconst" and not const):
  182. outtext += data
  183. elif (cmd == "ifnoret" and not ret):
  184. outtext += data
  185. elif (cmd == "iftempl" and (nargs > 0 or ret)):
  186. outtext += data
  187. elif (cmd == "arg,"):
  188. for i in range(1, nargs + 1):
  189. if (i > 1):
  190. outtext += ", "
  191. outtext += data.replace("@", str(i))
  192. elif (cmd == "arg"):
  193. for i in range(1, nargs + 1):
  194. outtext += data.replace("@", str(i))
  195. elif (cmd == "noarg"):
  196. for i in range(nargs + 1, argmax + 1):
  197. outtext += data.replace("@", str(i))
  198. elif (cmd == "noarg"):
  199. for i in range(nargs + 1, argmax + 1):
  200. outtext += data.replace("@", str(i))
  201. from_pos = end + 1
  202. return outtext
  203. def run(target, source, env):
  204. versions = 11
  205. versions_ext = 6
  206. text = ""
  207. text_ext = ""
  208. for i in range(0, versions + 1):
  209. t = ""
  210. t += make_version(template, i, versions, False, False)
  211. t += make_version(template_typed, i, versions, False, False)
  212. t += make_version(template, i, versions, False, True)
  213. t += make_version(template_typed, i, versions, False, True)
  214. t += make_version(template, i, versions, True, False)
  215. t += make_version(template_typed, i, versions, True, False)
  216. t += make_version(template, i, versions, True, True)
  217. t += make_version(template_typed, i, versions, True, True)
  218. if (i >= versions_ext):
  219. text_ext += t
  220. else:
  221. text += t
  222. f = open(target[0].path, "w")
  223. f.write(text)
  224. f.close()
  225. f = open(target[1].path, "w")
  226. f.write(text_ext)
  227. f.close()