wrapmacros.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //
  2. // Copyright (c) 2008-2016 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. // Only use this file if the portable (wrapped) code has been specifically requested
  24. #ifdef AS_MAX_PORTABILITY
  25. //the template wrapper code
  26. #include "wrap16.h"
  27. //can help solve potential ... problems if we need it at the start: http://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros
  28. //Overview of the process:
  29. //take the original funciton that registers a function for the angelscript engine:
  30. //(RegisterGlobalFunction, RegisterObjectMethod, ...)
  31. //Define it as a macro. Redefine the asFUNCTION family of macros to extract the arguments passed to them
  32. //and pass an F, M, FPR, or MPR depending on which macro was chosen as another argument before the original
  33. //contents of the asFUNCTION macro
  34. //Use the ## operator to paste the F, M, FPR< or MPR allong with the asECallConvTypes name to form the name of another macro
  35. //This other macro will then bundle the arguments back into the original RegisterGlobalFunction... call, but will use the
  36. //wrap macros from the wrap16.h and wrap.h files instead of the original asFUNCTION... call, and will specify the asCALL_GENERIC
  37. //calling convention
  38. //***NOTE***: not all of the possibly calling convention/method combinations have been finished, and those that Urho does not use are untested
  39. #define asFUNCTION(f) F, f
  40. //define a new macro (taken from angelscript.h) to use in place of the original asFUNCTION macro
  41. #define _asFUNCTION(f) asFunctionPtr(f)
  42. //#define asMETHOD(cls, f) cls, M, f
  43. #define asMETHOD(cls, f) M, (cls,f) //package class and function for UNWRAPping later
  44. #define UNWRAP(x,y) x,y// try -fmacro-backtrace-limit=0 on compile
  45. //define a new macro (taken from angelscript.h) to use in place of the original asMETHOD macro
  46. #define _asMETHOD(c,m) asSMethodPtr<sizeof(void (c::*)())>::Convert((void (c::*)())(&c::m))
  47. #define RegisterGlobalFunction(...) RegGlobalIndirect(__VA_ARGS__)
  48. #define RegGlobalIndirect(decl, F, func, kind) RegisterGlobalFunction##F##kind (decl,func) // ... = decl or it = decl, cls for asCall_ThisCall
  49. #define RegisterGlobalFunctionFasCALL_CDECL(decl,fun) RegisterGlobalFunction(decl, WRAP_FN(fun), asCALL_GENERIC); //assert(r >= 0);
  50. #define RegisterGlobalFunctionFasCALL_STDCALL(decl,fun) RegisterGlobalFunction(decl, WRAP_FN(fun), asCALL_GENERIC); //assert(r >= 0);
  51. #define RegisterGlobalFunctionMasCALL_THISCALL_ASGLOBAL(decl,fun) RegisterGlobalFunctionMasCALL_THISCALL_ASGLOBAL_2(decl,UNWRAP fun)
  52. #define RegisterGlobalFunctionMasCALL_THISCALL_ASGLOBAL_2(decl, ...) RegisterGlobalFunction(decl, WRAP_MFN(__VA_ARGS__), asCALL_GENERIC); //assert(r >= 0);
  53. #define RegisterGlobalFunctionFasCALL_GENERIC(decl,fun) RegisterGlobalFunction(decl, asFunctionPtr(fun), asCALL_GENERIC); //assert(r >= 0);
  54. //object indirects
  55. #define RegisterObjectMethod(...) RegObjectMethodIndirect(__VA_ARGS__)
  56. //#define RegObjectIndirect(clsdcl,decl, F, func, kind) RegObjectIndirect_2(clsdcl,decl, F, UNWRAP func, kind)
  57. #define RegObjectMethodIndirect(clsdcl,decl, F, clsfunc, kind) RegisterObjectMethod##F##kind (clsdcl,decl,clsfunc) // ... = decl or it = decl, cls for asCall_ThisCall
  58. #define RegisterObjectMethodMasCALL_THISCALL(clsdcl,decl,clsfunc) RegisterObjectMethodMasCALL_THISCALL_2(clsdcl,decl,UNWRAP clsfunc)
  59. #define RegisterObjectMethodMasCALL_THISCALL_2(clsdcl,decl,...) RegisterObjectMethodMasCALL_THISCALL_3(clsdcl,decl, WRAP_MFN(__VA_ARGS__));
  60. #define RegisterObjectMethodMasCALL_THISCALL_3(clsdcl,decl,fn) RegisterObjectMethod(clsdcl,decl, fn, asCALL_GENERIC); //assert(r >= 0);
  61. #define RegisterObjectMethodFasCALL_CDECL_OBJLAST(clsdcl,decl,fun) RegisterObjectMethod(clsdcl,decl, WRAP_OBJ_LAST(fun), asCALL_GENERIC); //assert(r >= 0);
  62. #define RegisterObjectMethodFasCALL_CDECL_OBJFIRST(clsdcl,decl,fun) RegisterObjectMethod(clsdcl,decl, WRAP_OBJ_FIRST(fun), asCALL_GENERIC); //assert(r >= 0);
  63. //#define RegisterObjectMethodMasCALL_CDECL_OBJECTFIRST(decl,cls,fun) RegisterObjectMethodMasCALL_THISCALL_ASGLOBAL_2(decl,UNWRAP fun)
  64. //#define RegisterObjectMethodMasCALL_THISCALL_ASGLOBAL_2(decl, ...) RegisterObjectMethod(decl, WRAP_MFN(__VA_ARGS__), asCALL_GENERIC); //assert(r >= 0);
  65. #define RegisterObjectMethodFasCALL_GENERIC(clsdcl,decl,fun) RegisterObjectMethod(clsdcl,decl, asMethodPtr(fun), asCALL_GENERIC); //assert(r >= 0);
  66. ////note:unfortunately, the WrapCon methods are for creating the constructor wrapper, which typically seems to be done anyways, so we should just handle it like Register Object Method with 1 extra parameter
  67. //#define RegisterObjectBehaviour(...) RegObjectBehaviorIndirect(__VA__ARGS__)
  68. //#define RegObjectBehaviorIndirect(clsdcl,behavior,decl,fn,kind) RegisterObjectBehavior##behavior(clsdcl,behavior,decl,fn,kind)
  69. //#define RegisterObjectBehaviorasBEHAVE_CONSTRUCT(clsdcl,behavior,decl,fn,kind) RegisterObjectConstructor##F##kind (clsdcl,behavior,decl,fn)
  70. //#define RegisterObjectConstructorFasCALL_CDECL_OBJECTLAST(clsdcl,behavior,decl,fn) RegisterObjectBehavior(clsdcl,behavior,decl,WRAP_OBJ_LAST(fn),asCALL_GENERIC)
  71. ////RegisterObjectConstructorF##kind (clsdcl,decl,clsfunc)
  72. //NOTE: Angelscript uses the British English spelling __iour!
  73. #define RegisterObjectBehaviour(...) RegObjectBehaviorIndirect(__VA_ARGS__)
  74. //#define RegObjectIndirect(clsdcl,behavior,decl, F, func, kind) RegObjectIndirect_2(clsdcl,behavior,decl, F, UNWRAP func, kind)
  75. #define RegObjectBehaviorIndirect(clsdcl,behavior,decl, F, clsfunc, kind) RegisterObjectBehavior##F##kind (clsdcl,behavior,decl,clsfunc) // ... = decl or it = decl, cls for asCall_ThisCall
  76. #define RegisterObjectBehaviorMasCALL_THISCALL(clsdcl,behavior,decl,clsfunc) RegisterObjectBehaviorMasCALL_THISCALL_2(clsdcl,behavior,decl,UNWRAP clsfunc)
  77. #define RegisterObjectBehaviorMasCALL_THISCALL_2(clsdcl,behavior,decl,...) RegisterObjectBehaviour(clsdcl,behavior,decl, WRAP_MFN(__VA_ARGS__), asCALL_GENERIC); //assert(r >= 0);
  78. #define RegisterObjectBehaviorFasCALL_CDECL_OBJLAST(clsdcl,behavior,decl,...) RegisterObjectBehaviour(clsdcl,behavior,decl, WRAP_OBJ_LAST(__VA_ARGS__), asCALL_GENERIC); //assert(r >= 0);
  79. #define RegisterObjectBehaviorFasCALL_CDECL_OBJFIRST(clsdcl,behavior,decl,...) RegisterObjectBehaviour(clsdcl,behavior,decl, WRAP_OBJ_FIRST(__VA_ARGS__), asCALL_GENERIC); //assert(r >= 0);
  80. //#define RegisterObjectBehaviorMasCALL_CDECL_OBJECTFIRST(decl,cls,fun) RegisterObjectBehaviorMasCALL_THISCALL_ASGLOBAL_2(decl,UNWRAP fun)
  81. //#define RegisterObjectBehaviorMasCALL_THISCALL_ASGLOBAL_2(decl, ...) RegisterObjectBehavior(decl, WRAP_MFN(__VA_ARGS__), asCALL_GENERIC); //assert(r >= 0);
  82. #define RegisterObjectBehaviorFasCALL_CDECL(clsdcl,behavior,decl,...) RegisterObjectBehaviour(clsdcl,behavior,decl, WRAP_FN(__VA_ARGS__),asCALL_GENERIC);
  83. #define RegisterObjectBehaviorFasCALL_GENERIC(clsdcl,behavior,decl,fun) RegisterObjectBehaviour(clsdcl,behavior,decl, asFunctionPtr(fun), asCALL_GENERIC); //assert(r >= 0);
  84. //Parameter-Return versions:
  85. #define asFUNCTIONPR(f,p,r) FPR, (f,p,r)
  86. #define UNWRAP3(x,y,z) x,y,z
  87. #define UNWRAP4(x,y,z,w) x,y,z,w
  88. #define asMETHODPR(cls,f,p,r) MPR, (cls,f,p,r)
  89. //define a new macro (taken from angelscript.h) to use in place of the original asFUNCTIONPR macro
  90. #if (defined(_MSC_VER) && _MSC_VER <= 1200) || (defined(__BORLANDC__) && __BORLANDC__ < 0x590)
  91. // MSVC 6 has a bug that prevents it from properly compiling using the correct asFUNCTIONPR with operator >
  92. // so we need to use ordinary C style cast instead of static_cast. The drawback is that the compiler can't
  93. // check that the cast is really valid.
  94. // BCC v5.8 (C++Builder 2006) and earlier have a similar bug which forces us to fall back to a C-style cast.
  95. #define _asFUNCTIONPR(f,p,r) asFunctionPtr((void (*)())((r (*)p)(f)))
  96. #elif (defined(_MSC_VER) && _MSC_VER >= 1900)
  97. // Urho3D: VS2015 does not compile the C-style cast of the function pointer
  98. #define _asFUNCTIONPR(f,p,r) asFunctionPtr(reinterpret_cast<void (*)()>(static_cast<r (*)p>(f)))
  99. #else
  100. #define _asFUNCTIONPR(f,p,r) asFunctionPtr((void (*)())(static_cast<r (*)p>(f)))
  101. #endif
  102. //define a new macro (taken from angelscript.h) to use in place of the original asMETHODPR macro
  103. #define _asMETHODPR(c,m,p,r) asSMethodPtr<sizeof(void (c::*)())>::Convert(AS_METHOD_AMBIGUITY_CAST(r (c::*)p)(&c::m))
  104. #define RegisterGlobalFunctionFPRasCALL_CDECL(decl,fun) RegisterGlobalFunctionFPRasCALL_CDECL_2(decl, UNWRAP3 fun);
  105. #define RegisterGlobalFunctionFPRasCALL_CDECL_2(decl,...) RegisterGlobalFunction(decl, WRAP_FN_PR(__VA_ARGS__), asCALL_GENERIC);
  106. #define RegisterGlobalFunctionFPRasCALL_STDCALL(decl,fun) RegisterGlobalFunctionFPRasCALL_STDCALL_2(decl, UNWRAP3 fun);
  107. #define RegisterGlobalFunctionFPRasCALL_STDCALL_2(decl,...) RegisterGlobalFunction(decl, WRAP_FN_PR(__VA_ARGS__), asCALL_GENERIC);
  108. #define RegisterGlobalFunctionMPRasCALL_THISCALL_ASGLOBAL(decl,fun) RegisterGlobalFunctionMasCALL_THISCALL_ASGLOBAL_2(decl,UNWRAP4 fun)
  109. #define RegisterGlobalFunctionMPRasCALL_THISCALL_ASGLOBAL_2(decl, ...) RegisterGlobalFunction(decl, WRAP_MFN_PR(__VA_ARGS__), asCALL_GENERIC);
  110. #define RegisterGlobalFunctionFPRasCALL_GENERIC(decl,fun) RegisterGlobalFunctionFPRasCALL_GENERIC_2(decl, UNWRAP3 fun);
  111. #define RegisterGlobalFunctionFPRasCALL_GENERIC_2(decl,...) RegisterGlobalFunction(decl, _asFUNCTIONPR(__VA_ARGS__), asCALL_GENERIC);
  112. #define RegisterObjectMethodMPRasCALL_THISCALL(clsdcl,decl,clsfunc) RegisterObjectMethodMPRasCALL_THISCALL_2(clsdcl,decl,UNWRAP4 clsfunc)
  113. #define RegisterObjectMethodMPRasCALL_THISCALL_2(clsdcl,decl,...) RegisterObjectMethod(clsdcl,decl, WRAP_MFN_PR(__VA_ARGS__), asCALL_GENERIC);
  114. #define RegisterObjectMethodFPRasCALL_CDECL_OBJLAST(clsdcl,decl,fun) RegisterObjectMethodFPRasCALL_CDECL_OBJLAST_2(clsdcl,decl, UNWRAP3 fun);
  115. #define RegisterObjectMethodFPRasCALL_CDECL_OBJLAST_2(clsdcl,decl,...) RegisterObjectMethod(clsdcl,decl, WRAP_OBJ_LAST_PR(__VA_ARGS__), asCALL_GENERIC);
  116. #define RegisterObjectMethodFPRasCALL_CDECL_OBJFIRST(clsdcl,decl,fun) RegisterObjectMethodFPRasCALL_CDECL_OBJFIRST_2(clsdcl,decl, UNWRAP3 fun);
  117. #define RegisterObjectMethodFPRasCALL_CDECL_OBJFIRST_2(clsdcl,decl,...) RegisterObjectMethod(clsdcl,decl, WRAP_OBJ_FIRST_PR(__VA_ARGS__), asCALL_GENERIC);
  118. #define RegisterObjectMethodFPRasCALL_GENERIC(clsdcl,decl,fun) RegisterObjectMethodFPRasCALL_GENERIC_2(clsdcl,decl, UNWRAP3 fun);
  119. #define RegisterObjectMethodFPRasCALL_GENERIC_2(clsdcl,decl,...) RegisterObjectMethod(clsdcl,decl, _asFUNCTIONPR(__VA_ARGS__), asCALL_GENERIC);
  120. #define RegisterObjectBehaviorMPRasCALL_THISCALL(clsdcl,behavior,decl,clsfunc) RegisterObjectBehaviorMPRasCALL_THISCALL_2(clsdcl,behavior,decl,UNWRAP4 clsfunc)
  121. #define RegisterObjectBehaviorMPRasCALL_THISCALL_2(clsdcl,behavior,decl,...) RegisterObjectBehaviour(clsdcl,behavior,decl, WRAP_MFN_PR(__VA_ARGS__), asCALL_GENERIC);
  122. #define RegisterObjectBehaviorFPRasCALL_CDECL_OBJLAST(clsdcl,behavior,decl,clsfunc) RegisterObjectBehaviour(clsdcl,behavior,decl, WRAP_OBJ_LAST_PR clsfunc, asCALL_GENERIC);
  123. #define RegisterObjectBehaviorFPRasCALL_CDECL_OBJFIRST(clsdcl,behavior,decl,...) RegisterObjectBehaviour(clsdcl,behavior,decl, WRAP_OBJ_FIRST_PR(__VA_ARGS__), asCALL_GENERIC);
  124. #define RegisterObjectBehaviorFPRasCALL_GENERIC(clsdcl,behavior,decl,...) RegisterObjectBehaviour(clsdcl,behavior,decl, _asFUNCTIONPR(__VA_ARGS__), asCALL_GENERIC);
  125. #define RegisterObjectBehaviorFPRasCALL_CDECL(clsdcl,behavior,decl,clsfunc) RegisterObjectBehaviour(clsdcl,behavior,decl, WRAP_FN_PR clsfunc, asCALL_GENERIC);
  126. #define RegisterStringFactory(...) EV(RegisterStringFactory_2(__VA_ARGS__))
  127. #define RegisterStringFactory_2(str,F,params,kind) RegisterStringFactory(str, WRAP_FN (params), asCALL_GENERIC);
  128. /*#define SetExceptionCallback(...) SetExceptionCallback_2(__VA_ARGS__)
  129. #define SetExceptionCallback_2(M,params,obj,kind) SetExceptionCallback(WRAP_MFN params, obj, asCALL_GENERIC);
  130. #define SetMessageCallback(...) SetMessageCallback_2(__VA_ARGS__)
  131. #define SetMessageCallback_2(M,params,obj,kind) SetMessageCallback(WRAP_MFN params, obj, asCALL_GENERIC);
  132. */
  133. #endif