make_binders.py 6.5 KB

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