make_binders.py 7.7 KB

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