engineAPI.h 126 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  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
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell 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
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _ENGINEAPI_H_
  23. #define _ENGINEAPI_H_
  24. #include <tuple>
  25. #include <utility>
  26. #ifndef _CONSOLETYPES_H_
  27. #include "console/consoleTypes.h"
  28. #endif
  29. #ifndef _CONSOLE_H_
  30. #include "console/console.h"
  31. #endif
  32. #ifndef _STRINGFUNCTIONS_H_
  33. #include "core/strings/stringFunctions.h"
  34. #endif
  35. #ifndef _SIMOBJECT_H_
  36. #include "console/simObject.h"
  37. #endif
  38. #ifndef _ENGINEFUNCTIONS_H_
  39. #include "console/engineFunctions.h"
  40. #endif
  41. // Whatever types are used in API definitions, their DECLAREs must be visible to the
  42. // macros. We include the basic primitive and struct types here.
  43. #ifndef _ENGINEPRIMITIVES_H_
  44. #include "console/enginePrimitives.h"
  45. #endif
  46. #ifndef _ENGINESTRUCTS_H_
  47. #include "console/engineStructs.h"
  48. #endif
  49. // Needed for the executef macros. Blame GCC.
  50. #ifndef _SIMEVENTS_H_
  51. #include "console/simEvents.h"
  52. #endif
  53. /// @file
  54. /// Definitions for exposing engine functionality to the control layer.
  55. ///
  56. /// This file provides a convenience layer around the underlying engine interop system (which at
  57. /// the moment still includes the legacy TorqueScript interop a.k.a. "console system"). The
  58. /// macros exposed here will automatically take care of all marshalling, value type constraints,
  59. /// reflection info instancing, etc. involved in defining engine API call-ins and call-outs.
  60. ///
  61. /// @note At the moment, this file supplies both the legacy TorqueScript console system as well
  62. /// as the new engine export system with the structures and information they need. In the
  63. /// near future, the console-based parts will get purged. This will not result in visible
  64. /// changes to users of the functionality here except for the string-based marshalling
  65. /// functions currently exposed (which will also disappear).
  66. //TODO: Disable warning for extern "C" functions returning UDTs for now; need to take a closer look at this
  67. #pragma warning( disable : 4190 )
  68. // Disable some VC warnings that are irrelevant to us.
  69. #pragma warning( push )
  70. #pragma warning( disable : 4510 ) // default constructor could not be generated; all the Args structures are never constructed by us
  71. #pragma warning( disable : 4610 ) // can never be instantiated; again Args is never constructed by us
  72. namespace engineAPI {
  73. /// Flag for enabling legacy console behavior in the interop system while
  74. /// we still have it around. Will disappear along with console.
  75. extern bool gUseConsoleInterop;
  76. /// Flag to allow engine functions to detect whether the engine had been
  77. /// initialized or shut down.
  78. extern bool gIsInitialized;
  79. }
  80. //FIXME: this allows const char* to be used as a struct field type
  81. // Temp support for allowing const char* to remain in the API functions as long as we
  82. // still have the console system around. When that is purged, these definitions should
  83. // be deleted and all const char* uses be replaced with String.
  84. template<> struct EngineTypeTraits< const char* > : public EngineTypeTraits< String > {};
  85. template<> inline const EngineTypeInfo* TYPE< const char* >() { return TYPE< String >(); }
  86. /// @name Marshalling
  87. ///
  88. /// Functions for converting to/from string-based data representations.
  89. ///
  90. /// @note This functionality is specific to the console interop.
  91. /// @{
  92. /// Marshal a single piece of data from native into client form.
  93. template< typename T >
  94. inline const char* EngineMarshallData( const T& value )
  95. {
  96. return castConsoleTypeToString( value );
  97. }
  98. inline const char* EngineMarshallData( bool value )
  99. {
  100. if( value )
  101. return "1";
  102. else
  103. return "0";
  104. }
  105. inline const char* EngineMarshallData( const char* str )
  106. {
  107. // The API assumes that if you pass a plain "const char*" through it, then you are referring
  108. // to string storage with non-local lifetime that can be safely passed to the control layer.
  109. return str;
  110. }
  111. template< typename T >
  112. inline const char* EngineMarshallData( T* object )
  113. {
  114. return ( object ? object->getIdString() : "0" );
  115. }
  116. template< typename T >
  117. inline const char* EngineMarshallData( const T* object )
  118. {
  119. return ( object ? object->getIdString() : "0" );
  120. }
  121. inline const char* EngineMarshallData( U32 value )
  122. {
  123. return EngineMarshallData( S32( value ) );
  124. }
  125. /// Marshal data from native into client form stored directly in
  126. /// client function invocation vector.
  127. template< typename T >
  128. inline void EngineMarshallData( const T& arg, S32& argc, ConsoleValueRef *argv )
  129. {
  130. argv[ argc ] = castConsoleTypeToString( arg );
  131. argc ++;
  132. }
  133. inline void EngineMarshallData( bool arg, S32& argc, ConsoleValueRef *argv )
  134. {
  135. if( arg )
  136. argv[ argc ] = 1;
  137. else
  138. argv[ argc ] = 0;
  139. argc ++;
  140. }
  141. inline void EngineMarshallData( S32 arg, S32& argc, ConsoleValueRef *argv )
  142. {
  143. argv[ argc ] = arg;
  144. argc ++;
  145. }
  146. inline void EngineMarshallData( U32 arg, S32& argc, ConsoleValueRef *argv )
  147. {
  148. EngineMarshallData( S32( arg ), argc, argv );
  149. }
  150. inline void EngineMarshallData( F32 arg, S32& argc, ConsoleValueRef *argv )
  151. {
  152. argv[ argc ] = arg;
  153. argc ++;
  154. }
  155. inline void EngineMarshallData( const char* arg, S32& argc, ConsoleValueRef *argv )
  156. {
  157. argv[ argc ] = arg;
  158. argc ++;
  159. }
  160. inline void EngineMarshallData( char* arg, S32& argc, ConsoleValueRef *argv )
  161. {
  162. argv[ argc ] = arg;
  163. argc ++;
  164. }
  165. template< typename T >
  166. inline void EngineMarshallData( T* object, S32& argc, ConsoleValueRef *argv )
  167. {
  168. argv[ argc ] = object ? object->getId() : 0;
  169. argc ++;
  170. }
  171. template< typename T >
  172. inline void EngineMarshallData( const T* object, S32& argc, ConsoleValueRef *argv )
  173. {
  174. argv[ argc ] = object ? object->getId() : 0;
  175. argc ++;
  176. }
  177. /// Unmarshal data from client form to engine form.
  178. ///
  179. /// This is wrapped in an a struct as partial specializations on function
  180. /// templates are not allowed in C++.
  181. template< typename T >
  182. struct EngineUnmarshallData
  183. {
  184. T operator()( const char* str ) const
  185. {
  186. T value;
  187. castConsoleTypeFromString( value, str );
  188. return value;
  189. }
  190. };
  191. template<>
  192. struct EngineUnmarshallData< S32 >
  193. {
  194. S32 operator()( ConsoleValueRef &ref ) const
  195. {
  196. return (S32)ref;
  197. }
  198. S32 operator()( const char* str ) const
  199. {
  200. return dAtoi( str );
  201. }
  202. };
  203. template<>
  204. struct EngineUnmarshallData< U32 >
  205. {
  206. U32 operator()( ConsoleValueRef &ref ) const
  207. {
  208. return (U32)((S32)ref);
  209. }
  210. U32 operator()( const char* str ) const
  211. {
  212. return dAtoui( str );
  213. }
  214. };
  215. template<>
  216. struct EngineUnmarshallData< F32 >
  217. {
  218. F32 operator()( ConsoleValueRef &ref ) const
  219. {
  220. return (F32)ref;
  221. }
  222. F32 operator()( const char* str ) const
  223. {
  224. return dAtof( str );
  225. }
  226. };
  227. template<>
  228. struct EngineUnmarshallData< U8 >
  229. {
  230. U8 operator()( ConsoleValueRef &ref ) const
  231. {
  232. return (U8)((S32)ref);
  233. }
  234. U8 operator()( const char* str ) const
  235. {
  236. return dAtoui( str );
  237. }
  238. };
  239. template<>
  240. struct EngineUnmarshallData< const char* >
  241. {
  242. const char* operator()( ConsoleValueRef &ref ) const
  243. {
  244. return ref.getStringValue();
  245. }
  246. const char* operator()( const char* str ) const
  247. {
  248. return str;
  249. }
  250. };
  251. template< typename T >
  252. struct EngineUnmarshallData< T* >
  253. {
  254. T* operator()( ConsoleValueRef &ref ) const
  255. {
  256. return dynamic_cast< T* >( Sim::findObject( ref.getStringValue() ) );
  257. }
  258. T* operator()( const char* str ) const
  259. {
  260. return dynamic_cast< T* >( Sim::findObject( str ) );
  261. }
  262. };
  263. template<>
  264. struct EngineUnmarshallData< void >
  265. {
  266. void operator()( ConsoleValueRef& ) const {}
  267. void operator()( const char* ) const {}
  268. };
  269. template<>
  270. struct EngineUnmarshallData< ConsoleValueRef >
  271. {
  272. ConsoleValueRef operator()( ConsoleValueRef ref ) const
  273. {
  274. return ref;
  275. }
  276. };
  277. /// @}
  278. /// @name C to C++ Trampolines
  279. ///
  280. /// The trampolines serve two purposes:
  281. ///
  282. /// For one, they ensure that no matter what argument types are specified by users of the engine API macros, the correct
  283. /// argument value types are enforced on the functions exported by the engine. Let's say, for example, the user writes
  284. /// a function that takes a "Point3F direction" argument, then the template machinery here will automatically expose an
  285. /// API function that takes a "Point3F& direction" argument.
  286. ///
  287. /// Secondly, the templates jump the incoming calls from extern "C" space into C++ space. This is mostly relevant for
  288. /// methods only as they will need an implicit object type argument.
  289. ///
  290. /// @{
  291. // Helper type to factor out commonalities between function and method trampolines.
  292. template<typename T> struct _EngineTrampoline {
  293. struct Args {};
  294. };
  295. template< typename R, typename ...ArgTs >
  296. struct _EngineTrampoline< R( ArgTs ... ) >
  297. {
  298. typedef std::tuple<ArgTs ...> Args;
  299. std::tuple<ArgTs ...> argT;
  300. };
  301. template< typename T >
  302. struct _EngineFunctionTrampolineBase : public _EngineTrampoline< T >
  303. {
  304. typedef T FunctionType;
  305. };
  306. // Trampolines for any call-ins that aren't methods.
  307. template< typename T >
  308. struct _EngineFunctionTrampoline {};
  309. template< typename R, typename ...ArgTs >
  310. struct _EngineFunctionTrampoline< R(ArgTs...) > : public _EngineFunctionTrampolineBase< R(ArgTs...) >
  311. {
  312. private:
  313. using Super = _EngineFunctionTrampolineBase< R(ArgTs...) >;
  314. using ArgsType = typename Super::Args;
  315. template<size_t ...> struct Seq {};
  316. template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {};
  317. template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; };
  318. template<size_t ...I>
  319. static R dispatchHelper(typename Super::FunctionType fn, const ArgsType& args, Seq<I...>) {
  320. return R( fn(std::get<I>(args) ...) );
  321. }
  322. using SeqType = typename Gens<sizeof...(ArgTs)>::type;
  323. public:
  324. static R jmp(typename Super::FunctionType fn, const ArgsType& args )
  325. {
  326. return dispatchHelper(fn, args, SeqType());
  327. }
  328. };
  329. // Trampolines for engine methods
  330. template< typename T >
  331. struct _EngineMethodTrampolineBase : public _EngineTrampoline< T > {};
  332. template< typename Frame, typename T >
  333. struct _EngineMethodTrampoline {};
  334. template< typename Frame, typename R, typename ...ArgTs >
  335. struct _EngineMethodTrampoline< Frame, R(ArgTs ...) > : public _EngineMethodTrampolineBase< R(ArgTs ...) >
  336. {
  337. using FunctionType = R( typename Frame::ObjectType*, ArgTs ...);
  338. private:
  339. using Super = _EngineMethodTrampolineBase< R(ArgTs ...) >;
  340. using ArgsType = typename _EngineFunctionTrampolineBase< R(ArgTs ...) >::Args;
  341. template<size_t ...> struct Seq {};
  342. template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {};
  343. template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; };
  344. template<size_t ...I>
  345. static R dispatchHelper(Frame f, const ArgsType& args, Seq<I...>) {
  346. return R( f._exec(std::get<I>(args) ...) );
  347. }
  348. using SeqType = typename Gens<sizeof...(ArgTs)>::type;
  349. public:
  350. static R jmp( typename Frame::ObjectType* object, const ArgsType& args )
  351. {
  352. Frame f;
  353. f.object = object;
  354. return dispatchHelper(f, args, SeqType());
  355. }
  356. };
  357. /// @}
  358. /// @name Thunking
  359. ///
  360. /// Internal functionality for thunks placed between TorqueScript calls of engine functions and their native
  361. /// implementations.
  362. ///
  363. /// @note The functionality in this group is specific to the console interop system.
  364. /// @{
  365. // Helper function to return data from a thunk.
  366. template< typename T >
  367. inline const char* _EngineConsoleThunkReturnValue( const T& value )
  368. {
  369. return EngineMarshallData( value );
  370. }
  371. inline bool _EngineConsoleThunkReturnValue( bool value )
  372. {
  373. return value;
  374. }
  375. inline S32 _EngineConsoleThunkReturnValue( S32 value )
  376. {
  377. return value;
  378. }
  379. inline F32 _EngineConsoleThunkReturnValue( F32 value )
  380. {
  381. return value;
  382. }
  383. inline const char* _EngineConsoleThunkReturnValue( const String& str )
  384. {
  385. return Con::getReturnBuffer( str );
  386. }
  387. inline const char* _EngineConsoleThunkReturnValue( const char* value )
  388. {
  389. return EngineMarshallData( value );
  390. }
  391. template< typename T >
  392. inline const char* _EngineConsoleThunkReturnValue( T* value )
  393. {
  394. return ( value ? value->getIdString() : "" );
  395. }
  396. template< typename T >
  397. inline const char* _EngineConsoleThunkReturnValue( const T* value )
  398. {
  399. return ( value ? value->getIdString() : "" );
  400. }
  401. // Helper class to determine the type of callback registered with the console system.
  402. template< typename R >
  403. struct _EngineConsoleThunkType
  404. {
  405. typedef const char* ReturnType;
  406. typedef StringCallback CallbackType;
  407. };
  408. template<>
  409. struct _EngineConsoleThunkType< S32 >
  410. {
  411. typedef S32 ReturnType;
  412. typedef IntCallback CallbackType;
  413. };
  414. template<>
  415. struct _EngineConsoleThunkType< U32 >
  416. {
  417. typedef U32 ReturnType;
  418. typedef IntCallback CallbackType;
  419. };
  420. template<>
  421. struct _EngineConsoleThunkType< F32 >
  422. {
  423. typedef F32 ReturnType;
  424. typedef FloatCallback CallbackType;
  425. };
  426. template<>
  427. struct _EngineConsoleThunkType< bool >
  428. {
  429. typedef bool ReturnType;
  430. typedef BoolCallback CallbackType;
  431. };
  432. template<>
  433. struct _EngineConsoleThunkType< void >
  434. {
  435. typedef void ReturnType;
  436. typedef VoidCallback CallbackType;
  437. };
  438. // Helper struct to count the number of parameters in a function list.
  439. // The setup through operator () allows omitting the the argument list entirely.
  440. struct _EngineConsoleThunkCountArgs
  441. {
  442. template<typename ...ArgTs> U32 operator()(ArgTs... args){
  443. return sizeof...(ArgTs);
  444. }
  445. operator U32() const{ // FIXME: WHAT IS THIS?? I'm pretty sure it's incorrect, and it's the version that is invoked by all the macros
  446. return 0;
  447. }
  448. };
  449. // Encapsulation of a legacy console function invocation.
  450. namespace engineAPI{
  451. namespace detail{
  452. template<S32 startArgc, typename R, typename ...ArgTs>
  453. struct ThunkHelpers {
  454. using SelfType = ThunkHelpers<startArgc, R, ArgTs...>;
  455. using FunctionType = R(*)(ArgTs...);
  456. template<typename Frame> using MethodType = R(Frame::*)(ArgTs ...) const;
  457. template<size_t I> using IthArgType = typename std::tuple_element<I, std::tuple<ArgTs ...> >::type;
  458. template<size_t ...> struct Seq {};
  459. template<size_t N, size_t ...S> struct Gens : Gens<N-1, N-1, S...> {};
  460. template<size_t ...I> struct Gens<0, I...>{ typedef Seq<I...> type; };
  461. typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
  462. static constexpr S32 NUM_ARGS = sizeof...(ArgTs) + startArgc;
  463. template<size_t index, size_t method_offset = 0, typename ...RealArgTs>
  464. static IthArgType<index> getRealArgValue(S32 argc, ConsoleValueRef *argv, const _EngineFunctionDefaultArguments< void(RealArgTs...) >& defaultArgs)
  465. {
  466. if((startArgc + index) < argc)
  467. {
  468. return EngineUnmarshallData< IthArgType<index> >()( argv[ startArgc + index ] );
  469. } else {
  470. return std::get<index + method_offset>(defaultArgs.mArgs);
  471. }
  472. }
  473. template<size_t ...I>
  474. static R dispatchHelper(S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs, Seq<I...>){
  475. return fn(SelfType::getRealArgValue<I>(argc, argv, defaultArgs) ...);
  476. }
  477. template<typename Frame, size_t ...I>
  478. static R dispatchHelper(S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs, Seq<I...>){
  479. return (frame->*fn)(SelfType::getRealArgValue<I,1>(argc, argv, defaultArgs) ...);
  480. }
  481. using SeqType = typename Gens<sizeof...(ArgTs)>::type;
  482. };
  483. }
  484. }
  485. template< S32 startArgc, typename T >
  486. struct _EngineConsoleThunk {};
  487. template< S32 startArgc, typename R, typename ...ArgTs >
  488. struct _EngineConsoleThunk< startArgc, R(ArgTs...) >
  489. {
  490. private:
  491. using Helper = engineAPI::detail::ThunkHelpers<startArgc, R, ArgTs...>;
  492. using SeqType = typename Helper::SeqType;
  493. public:
  494. typedef typename Helper::FunctionType FunctionType;
  495. typedef typename Helper::ReturnType ReturnType;
  496. template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>;
  497. static constexpr S32 NUM_ARGS = Helper::NUM_ARGS;
  498. static ReturnType thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs)
  499. {
  500. return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType()));
  501. }
  502. template< typename Frame >
  503. static ReturnType thunk( S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs)
  504. {
  505. return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType()));
  506. }
  507. };
  508. // Have to do a partial specialization for void-returning functions :(
  509. template<S32 startArgc, typename ...ArgTs>
  510. struct _EngineConsoleThunk<startArgc, void(ArgTs...)> {
  511. private:
  512. using Helper = engineAPI::detail::ThunkHelpers<startArgc, void, ArgTs...>;
  513. using SeqType = typename Helper::SeqType;
  514. public:
  515. typedef typename Helper::FunctionType FunctionType;
  516. typedef typename Helper::ReturnType ReturnType;
  517. template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>;
  518. static constexpr S32 NUM_ARGS = Helper::NUM_ARGS;
  519. static void thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs)
  520. {
  521. Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType());
  522. }
  523. template< typename Frame >
  524. static void thunk( S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs)
  525. {
  526. Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType());
  527. }
  528. };
  529. /// @}
  530. /// @name API Definition Macros
  531. ///
  532. /// The macros in this group allow to create engine API functions that work both with the
  533. /// legacy console system as well as with the new engine export system. As such, they only
  534. /// support those function features that are available in both systems. This means that for
  535. /// console-style variadic functions, the ConsoleXXX must be used and that for overloaded
  536. /// and/or C-style variadic functions as well as for placing functions in export scopes,
  537. /// DEFINE_CALLIN must be used directly.
  538. ///
  539. /// When the console system is removed, the console thunking functionality will be removed
  540. /// from these macros but otherwise they will remain unchanged and in place.
  541. ///
  542. /// @{
  543. // Helpers to implement initialization checks. Pulled out into separate macros so this can be deactivated easily.
  544. // Especially important for the initialize() function itself.
  545. #define _CHECK_ENGINE_INITIALIZED_IMPL( fnName, returnType ) \
  546. if( !engineAPI::gIsInitialized ) \
  547. { \
  548. Con::errorf( "EngineAPI: Engine not initialized when calling " #fnName ); \
  549. return EngineTypeTraits< returnType >::ReturnValue( EngineTypeTraits< returnType >::ReturnValueType() ); \
  550. }
  551. #define _CHECK_ENGINE_INITIALIZED( fnName, returnType ) _CHECK_ENGINE_INITIALIZED_IMPL( fnName, returnType )
  552. /// Define a call-in point for calling into the engine.
  553. ///
  554. /// @param name The name of the function as it should be seen by the control layer.
  555. /// @param returnType The value type returned to the control layer.
  556. /// @param args The argument list as it would appear on the function definition
  557. /// @param defaultArgs The list of default argument values.
  558. /// @param usage The usage doc string for the engine API reference.
  559. ///
  560. /// @code
  561. /// DefineEngineFunction( myFunction, int, ( float f, const String& s ), ( "value for s" ), "This is my function." )
  562. /// {
  563. /// return int( f ) + dAtoi( s );
  564. /// }
  565. /// @endcode
  566. #define DefineEngineFunction( name, returnType, args, defaultArgs, usage ) \
  567. static inline returnType _fn ## name ## impl args; \
  568. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \
  569. ( _EngineFunctionTrampoline< returnType args >::Args a ) \
  570. { \
  571. _CHECK_ENGINE_INITIALIZED( name, returnType ); \
  572. return EngineTypeTraits< returnType >::ReturnValue( \
  573. _EngineFunctionTrampoline< returnType args >::jmp( _fn ## name ## impl, a ) \
  574. ); \
  575. } \
  576. static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs; \
  577. static EngineFunctionInfo _fn ## name ## FunctionInfo( \
  578. #name, \
  579. &_SCOPE<>()(), \
  580. usage, \
  581. #returnType " " #name #args, \
  582. "fn" #name, \
  583. TYPE< returnType args >(), \
  584. &_fn ## name ## DefaultArgs, \
  585. ( void* ) &fn ## name, \
  586. 0 \
  587. ); \
  588. static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv ) \
  589. { \
  590. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
  591. argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \
  592. ) ); \
  593. } \
  594. static ConsoleFunctionHeader _ ## name ## header \
  595. ( #returnType, #args, #defaultArgs ); \
  596. static ConsoleConstructor \
  597. _ ## name ## obj( NULL, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## name ## caster ), usage, \
  598. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  599. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS, \
  600. false, &_ ## name ## header \
  601. ); \
  602. static inline returnType _fn ## name ## impl args
  603. // The next thing is a bit tricky. DefineEngineMethod allows to make the 'object' (=this) argument to the function
  604. // implicit which presents quite an obstacle for the macro internals as the engine export system requires the
  605. // name of a DLL symbol that represents an extern "C" function with an explicit first object pointer argument.
  606. //
  607. // Even if we ignored the fact that we don't have a guarantee how the various C++ compilers implement implicit 'this' arguments,
  608. // we could still not just use a C++ method for this as then we would have to get past the C++ compiler's mangling to
  609. // get to the function symbol name (let alone the fact that typing this method correctly would be tricky).
  610. //
  611. // So, the trick employed here is to package all but the implicit 'this' argument in a structure and then define an
  612. // extern "C" function that takes the object pointer as a first argument and the struct type as the second argument.
  613. // This will result in a function with an identical stack call frame layout to the function we want.
  614. //
  615. // Unfortunately, that still requires that function to chain on to the real user-defined function. To do this
  616. // cleanly and portably, _EngineMethodTrampoline is used to unpack and jump the call from extern "C" into C++ space.
  617. // In optimized builds, the compiler should be smart enough to pretty much optimize all our trickery here away.
  618. #define _DefineMethodTrampoline( className, name, returnType, args ) \
  619. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType \
  620. fn ## className ## _ ## name ( className* object, _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::Args a ) \
  621. { \
  622. _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
  623. return EngineTypeTraits< returnType >::ReturnValue( \
  624. _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::jmp( object, a ) \
  625. ); \
  626. }
  627. /// Define a call-in point for calling a method on an engine object.
  628. ///
  629. /// @param name The name of the C++ class.
  630. /// @param name The name of the method as it should be seen by the control layer.
  631. /// @param returnType The value type returned to the control layer.
  632. /// @param args The argument list as it would appear on the function definition
  633. /// @param defaultArgs The list of default argument values.
  634. /// @param usage The usage doc string for the engine API reference.
  635. ///
  636. /// @code
  637. /// DefineEngineMethod( MyClass, myMethod, int, ( float f, const String& s ), ( "value for s" ), "This is my method." )
  638. /// {
  639. /// return object->someMethod( f, s );
  640. /// }
  641. /// @endcode
  642. #define DefineEngineMethod( className, name, returnType, args, defaultArgs, usage ) \
  643. struct _ ## className ## name ## frame \
  644. { \
  645. typedef className ObjectType; \
  646. className* object; \
  647. inline returnType _exec args const; \
  648. }; \
  649. _DefineMethodTrampoline( className, name, returnType, args ); \
  650. static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType > \
  651. _fn ## className ## name ## DefaultArgs defaultArgs; \
  652. static EngineFunctionInfo _fn ## className ## name ## FunctionInfo( \
  653. #name, \
  654. &_SCOPE< className >()(), \
  655. usage, \
  656. "virtual " #returnType " " #name #args, \
  657. "fn" #className "_" #name, \
  658. TYPE< _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::FunctionType >(), \
  659. &_fn ## className ## name ## DefaultArgs, \
  660. ( void* ) &fn ## className ## _ ## name, \
  661. 0 \
  662. ); \
  663. static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv ) \
  664. { \
  665. _ ## className ## name ## frame frame; \
  666. frame.object = static_cast< className* >( object ); \
  667. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 2, returnType args >::thunk( \
  668. argc, argv, &_ ## className ## name ## frame::_exec, &frame, _fn ## className ## name ## DefaultArgs \
  669. ) ); \
  670. } \
  671. static ConsoleFunctionHeader _ ## className ## name ## header \
  672. ( #returnType, #args, #defaultArgs ); \
  673. static ConsoleConstructor \
  674. className ## name ## obj( #className, #name, \
  675. _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
  676. _EngineConsoleThunk< 2, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  677. _EngineConsoleThunk< 2, returnType args >::NUM_ARGS, \
  678. false, &_ ## className ## name ## header \
  679. ); \
  680. returnType _ ## className ## name ## frame::_exec args const
  681. /// Define a call-in point for calling into the engine. Unlike with DefineEngineFunction, the statically
  682. /// callable function will be confined to the namespace of the given class.
  683. ///
  684. /// @param name The name of the C++ class (or a registered export scope).
  685. /// @param name The name of the method as it should be seen by the control layer.
  686. /// @param returnType The value type returned to the control layer.
  687. /// @param args The argument list as it would appear on the function definition
  688. /// @param defaultArgs The list of default argument values.
  689. /// @param usage The usage doc string for the engine API reference.
  690. ///
  691. /// @code
  692. /// DefineEngineStaticMethod( MyClass, myMethod, int, ( float f, string s ), ( "value for s" ), "This is my method." )
  693. /// {
  694. /// }
  695. /// @endcode
  696. #define DefineEngineStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
  697. static inline returnType _fn ## className ## name ## impl args; \
  698. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \
  699. ( _EngineFunctionTrampoline< returnType args >::Args a ) \
  700. { \
  701. _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
  702. return EngineTypeTraits< returnType >::ReturnValue( \
  703. _EngineFunctionTrampoline< returnType args >::jmp( _fn ## className ## name ## impl, a ) \
  704. ); \
  705. } \
  706. static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs; \
  707. static EngineFunctionInfo _fn ## name ## FunctionInfo( \
  708. #name, \
  709. &_SCOPE< className >()(), \
  710. usage, \
  711. #returnType " " #name #args, \
  712. "fn" #className "_" #name, \
  713. TYPE< returnType args >(), \
  714. &_fn ## className ## name ## DefaultArgs, \
  715. ( void* ) &fn ## className ## _ ## name, \
  716. 0 \
  717. ); \
  718. static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
  719. { \
  720. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
  721. argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \
  722. ) ); \
  723. } \
  724. static ConsoleFunctionHeader _ ## className ## name ## header \
  725. ( #returnType, #args, #defaultArgs, true ); \
  726. static ConsoleConstructor \
  727. _ ## className ## name ## obj( #className, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
  728. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  729. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS, \
  730. false, &_ ## className ## name ## header \
  731. ); \
  732. static inline returnType _fn ## className ## name ## impl args
  733. // Convenience macros to allow defining functions that use the new marshalling features
  734. // while being only visible in the console interop. When we drop the console system,
  735. // these macros can be removed and all definitions that make use of them can be removed
  736. // as well.
  737. #define DefineConsoleFunction( name, returnType, args, defaultArgs, usage ) \
  738. static inline returnType _fn ## name ## impl args; \
  739. static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs; \
  740. static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv ) \
  741. { \
  742. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
  743. argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \
  744. ) ); \
  745. } \
  746. static ConsoleFunctionHeader _ ## name ## header \
  747. ( #returnType, #args, #defaultArgs ); \
  748. static ConsoleConstructor \
  749. _ ## name ## obj( NULL, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## name ## caster ), usage, \
  750. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  751. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS, \
  752. false, &_ ## name ## header \
  753. ); \
  754. static inline returnType _fn ## name ## impl args
  755. #define DefineConsoleMethod( className, name, returnType, args, defaultArgs, usage ) \
  756. struct _ ## className ## name ## frame \
  757. { \
  758. typedef className ObjectType; \
  759. className* object; \
  760. inline returnType _exec args const; \
  761. }; \
  762. static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType > \
  763. _fn ## className ## name ## DefaultArgs defaultArgs; \
  764. static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv ) \
  765. { \
  766. _ ## className ## name ## frame frame; \
  767. frame.object = static_cast< className* >( object ); \
  768. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 2, returnType args >::thunk( \
  769. argc, argv, &_ ## className ## name ## frame::_exec, &frame, _fn ## className ## name ## DefaultArgs \
  770. ) ); \
  771. } \
  772. static ConsoleFunctionHeader _ ## className ## name ## header \
  773. ( #returnType, #args, #defaultArgs ); \
  774. static ConsoleConstructor \
  775. className ## name ## obj( #className, #name, \
  776. _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
  777. _EngineConsoleThunk< 2, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  778. _EngineConsoleThunk< 2, returnType args >::NUM_ARGS, \
  779. false, &_ ## className ## name ## header \
  780. ); \
  781. returnType _ ## className ## name ## frame::_exec args const
  782. #define DefineConsoleStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
  783. static inline returnType _fn ## className ## name ## impl args; \
  784. static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs; \
  785. static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
  786. { \
  787. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
  788. argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \
  789. ) ); \
  790. } \
  791. static ConsoleFunctionHeader _ ## className ## name ## header \
  792. ( #returnType, #args, #defaultArgs, true ); \
  793. static ConsoleConstructor \
  794. _ ## className ## name ## obj( #className, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
  795. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  796. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS, \
  797. false, &_ ## className ## name ## header \
  798. ); \
  799. static inline returnType _fn ## className ## name ## impl args
  800. // The following three macros are only temporary. They allow to define engineAPI functions using the framework
  801. // here in this file while being visible only in the new API. When the console interop is removed, these macros
  802. // can be removed and all their uses be replaced with their corresponding versions that now still include support
  803. // for the console (e.g. DefineNewEngineFunction should become DefineEngineFunction).
  804. #define DefineNewEngineFunction( name, returnType, args, defaultArgs, usage ) \
  805. static inline returnType _fn ## name ## impl args; \
  806. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \
  807. ( _EngineFunctionTrampoline< returnType args >::Args a ) \
  808. { \
  809. _CHECK_ENGINE_INITIALIZED( name, returnType ); \
  810. return EngineTypeTraits< returnType >::ReturnValue( \
  811. _EngineFunctionTrampoline< returnType args >::jmp( _fn ## name ## impl, a ) \
  812. ); \
  813. } \
  814. static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs; \
  815. static EngineFunctionInfo _fn ## name ## FunctionInfo( \
  816. #name, \
  817. &_SCOPE<>()(), \
  818. usage, \
  819. #returnType " " #name #args, \
  820. "fn" #name, \
  821. TYPE< returnType args >(), \
  822. &_fn ## name ## DefaultArgs, \
  823. ( void* ) &fn ## name, \
  824. 0 \
  825. ); \
  826. static inline returnType _fn ## name ## impl args
  827. #define DefineNewEngineMethod( className, name, returnType, args, defaultArgs, usage ) \
  828. struct _ ## className ## name ## frame \
  829. { \
  830. typedef className ObjectType; \
  831. className* object; \
  832. inline returnType _exec args const; \
  833. }; \
  834. _DefineMethodTrampoline( className, name, returnType, args ); \
  835. static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType > \
  836. _fn ## className ## name ## DefaultArgs defaultArgs; \
  837. static EngineFunctionInfo _fn ## className ## name ## FunctionInfo( \
  838. #name, \
  839. &_SCOPE< className >()(), \
  840. usage, \
  841. "virtual " #returnType " " #name #args, \
  842. "fn" #className "_" #name, \
  843. TYPE< _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::FunctionType >(), \
  844. &_fn ## className ## name ## DefaultArgs, \
  845. ( void* ) &fn ## className ## _ ## name, \
  846. 0 \
  847. ); \
  848. returnType _ ## className ## name ## frame::_exec args const
  849. #define DefineNewEngineStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
  850. static inline returnType _fn ## className ## name ## impl args; \
  851. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \
  852. ( _EngineFunctionTrampoline< returnType args >::Args a ) \
  853. { \
  854. _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
  855. return EngineTypeTraits< returnType >::ReturnValue( \
  856. _EngineFunctionTrampoline< returnType args >::jmp( _fn ## className ## name ## impl, a ) \
  857. ); \
  858. } \
  859. static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs; \
  860. static EngineFunctionInfo _fn ## name ## FunctionInfo( \
  861. #name, \
  862. &_SCOPE< className >()(), \
  863. usage, \
  864. #returnType " " #name #args, \
  865. "fn" #className "_" #name, \
  866. TYPE< returnType args >(), \
  867. &_fn ## className ## name ## DefaultArgs, \
  868. ( void* ) &fn ## className ## _ ## name, \
  869. 0 \
  870. ); \
  871. static inline returnType _fn ## className ## name ## impl args
  872. /// @}
  873. //=============================================================================
  874. // Callbacks.
  875. //=============================================================================
  876. /// Matching implement for DECLARE_CALLBACK.
  877. ///
  878. ///
  879. /// @warn With the new interop system, method-style callbacks <em>must not</em> be triggered on object
  880. /// that are being created! This is because the control layer will likely not yet have a fully valid wrapper
  881. /// object in place for the EngineObject under construction.
  882. #define IMPLEMENT_CALLBACK( class, name, returnType, args, argNames, usageString ) \
  883. struct _ ## class ## name ## frame { typedef class ObjectType; }; \
  884. TORQUE_API _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name; \
  885. TORQUE_API void set_cb ## class ## _ ## name( \
  886. _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType fn ) \
  887. { cb ## class ## _ ## name = fn; } \
  888. _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name; \
  889. namespace { \
  890. ::EngineFunctionInfo _cb ## class ## name( \
  891. #name, \
  892. &::_SCOPE< class >()(), \
  893. usageString, \
  894. "virtual " #returnType " " #name #args, \
  895. "cb" #class "_" #name, \
  896. ::TYPE< _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType >(), \
  897. NULL, \
  898. ( void* ) &cb ## class ## _ ## name, \
  899. EngineFunctionCallout \
  900. ); \
  901. } \
  902. returnType class::name ## _callback args \
  903. { \
  904. if( cb ## class ## _ ## name ) { \
  905. _EngineCallbackHelper cbh( this, reinterpret_cast< const void* >( cb ## class ## _ ## name ) ); \
  906. return returnType( cbh.call< returnType > argNames ); \
  907. } \
  908. if( engineAPI::gUseConsoleInterop ) \
  909. { \
  910. static StringTableEntry sName = StringTable->insert( #name ); \
  911. _EngineConsoleCallbackHelper cbh( sName, this ); \
  912. return returnType( cbh.call< returnType > argNames ); \
  913. } \
  914. return returnType(); \
  915. } \
  916. namespace { \
  917. ConsoleFunctionHeader _ ## class ## name ## header( \
  918. #returnType, #args, "" ); \
  919. ConsoleConstructor _ ## class ## name ## obj( #class, #name, usageString, &_ ## class ## name ## header ); \
  920. }
  921. /// Used to define global callbacks not associated with
  922. /// any particular class or namespace.
  923. #define IMPLEMENT_GLOBAL_CALLBACK( name, returnType, args, argNames, usageString ) \
  924. DEFINE_CALLOUT( cb ## name, name,, returnType, args, 0, usageString ); \
  925. returnType name ## _callback args \
  926. { \
  927. if( cb ## name ) \
  928. return returnType( cb ## name argNames ); \
  929. if( engineAPI::gUseConsoleInterop ) \
  930. { \
  931. static StringTableEntry sName = StringTable->insert( #name ); \
  932. _EngineConsoleCallbackHelper cbh( sName, NULL ); \
  933. return returnType( cbh.call< returnType > argNames ); \
  934. } \
  935. return returnType(); \
  936. } \
  937. namespace { \
  938. ConsoleFunctionHeader _ ## name ## header( \
  939. #returnType, #args, "" ); \
  940. ConsoleConstructor _ ## name ## obj( NULL, #name, usageString, &_ ## name ## header ); \
  941. }
  942. // Again, temporary macros to allow splicing the API while we still have the console interop around.
  943. #define IMPLEMENT_CONSOLE_CALLBACK( class, name, returnType, args, argNames, usageString ) \
  944. returnType class::name ## _callback args \
  945. { \
  946. if( engineAPI::gUseConsoleInterop ) \
  947. { \
  948. static StringTableEntry sName = StringTable->insert( #name ); \
  949. _EngineConsoleCallbackHelper cbh( sName, this ); \
  950. return returnType( cbh.call< returnType > argNames ); \
  951. } \
  952. return returnType(); \
  953. } \
  954. namespace { \
  955. ConsoleFunctionHeader _ ## class ## name ## header( \
  956. #returnType, #args, "" ); \
  957. ConsoleConstructor _ ## class ## name ## obj( #class, #name, usageString, &_ ## class ## name ## header ); \
  958. }
  959. #define IMPLEMENT_NEW_CALLBACK( class, name, returnType, args, argNames, usageString ) \
  960. struct _ ## class ## name ## frame { typedef class ObjectType; }; \
  961. TORQUE_API _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name; \
  962. TORQUE_API void set_cb ## class ## _ ## name( \
  963. _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType fn ) \
  964. { cb ## class ## _ ## name = fn; } \
  965. _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name; \
  966. namespace { \
  967. ::EngineFunctionInfo _cb ## class ## name( \
  968. #name, \
  969. &::_SCOPE< class >()(), \
  970. usageString, \
  971. "virtual " #returnType " " #name #args, \
  972. "cb" #class "_" #name, \
  973. ::TYPE< _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType >(), \
  974. NULL, \
  975. &cb ## class ## _ ## name, \
  976. EngineFunctionCallout \
  977. ); \
  978. } \
  979. returnType class::name ## _callback args \
  980. { \
  981. if( cb ## class ## _ ## name ) { \
  982. _EngineCallbackHelper cbh( this, reinterpret_cast< const void* >( cb ## class ## _ ## name ) ); \
  983. return returnType( cbh.call< returnType > argNames ); \
  984. } \
  985. return returnType(); \
  986. }
  987. // Internal helper class for doing call-outs in the new interop.
  988. struct _EngineCallbackHelper
  989. {
  990. protected:
  991. EngineObject* mThis;
  992. const void* mFn;
  993. public:
  994. _EngineCallbackHelper( EngineObject* pThis, const void* fn )
  995. : mThis( pThis ),
  996. mFn( fn ) {}
  997. template< typename R, typename ...ArgTs >
  998. R call(ArgTs ...args) const
  999. {
  1000. typedef R( FunctionType )( EngineObject*, ArgTs... );
  1001. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, args... ) );
  1002. }
  1003. };
  1004. #include "console/stringStack.h"
  1005. // Internal helper for callback support in legacy console system.
  1006. struct _BaseEngineConsoleCallbackHelper
  1007. {
  1008. public:
  1009. /// Matches up to storeArgs.
  1010. static const U32 MAX_ARGUMENTS = 11;
  1011. SimObject* mThis;
  1012. S32 mInitialArgc;
  1013. S32 mArgc;
  1014. StringTableEntry mCallbackName;
  1015. ConsoleValueRef mArgv[ MAX_ARGUMENTS + 2 ];
  1016. ConsoleValueRef _exec();
  1017. ConsoleValueRef _execLater(SimConsoleThreadExecEvent *evt);
  1018. _BaseEngineConsoleCallbackHelper() {;}
  1019. };
  1020. // Base helper for console callbacks
  1021. struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper
  1022. {
  1023. public:
  1024. _EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis )
  1025. {
  1026. mThis = pThis;
  1027. mArgc = mInitialArgc = pThis ? 2 : 1 ;
  1028. mCallbackName = callbackName;
  1029. }
  1030. template< typename R >
  1031. R call()
  1032. {
  1033. if (Con::isMainThread())
  1034. {
  1035. ConsoleStackFrameSaver sav; sav.save();
  1036. CSTK.reserveValues(mArgc, mArgv);
  1037. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1038. return R( EngineUnmarshallData< R >()( _exec() ) );
  1039. }
  1040. else
  1041. {
  1042. SimConsoleThreadExecCallback cb;
  1043. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc, NULL, false, &cb);
  1044. evt->populateArgs(mArgv);
  1045. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1046. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1047. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1048. }
  1049. }
  1050. template< typename R, typename A >
  1051. R call( A a )
  1052. {
  1053. if (Con::isMainThread())
  1054. {
  1055. ConsoleStackFrameSaver sav; sav.save();
  1056. CSTK.reserveValues(mArgc+1, mArgv);
  1057. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1058. EngineMarshallData( a, mArgc, mArgv );
  1059. return R( EngineUnmarshallData< R >()( _exec() ) );
  1060. }
  1061. else
  1062. {
  1063. SimConsoleThreadExecCallback cb;
  1064. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, false, &cb);
  1065. evt->populateArgs(mArgv);
  1066. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1067. EngineMarshallData( a, mArgc, mArgv );
  1068. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1069. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1070. }
  1071. }
  1072. template< typename R, typename A, typename B >
  1073. R call( A a, B b )
  1074. {
  1075. if (Con::isMainThread())
  1076. {
  1077. ConsoleStackFrameSaver sav; sav.save();
  1078. CSTK.reserveValues(mArgc+2, mArgv);
  1079. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1080. EngineMarshallData( a, mArgc, mArgv );
  1081. EngineMarshallData( b, mArgc, mArgv );
  1082. return R( EngineUnmarshallData< R >()( _exec() ) );
  1083. }
  1084. else
  1085. {
  1086. SimConsoleThreadExecCallback cb;
  1087. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, false, &cb);
  1088. evt->populateArgs(mArgv);
  1089. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1090. EngineMarshallData( a, mArgc, mArgv );
  1091. EngineMarshallData( b, mArgc, mArgv );
  1092. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1093. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1094. }
  1095. }
  1096. template< typename R, typename A, typename B, typename C >
  1097. R call( A a, B b, C c )
  1098. {
  1099. if (Con::isMainThread())
  1100. {
  1101. ConsoleStackFrameSaver sav; sav.save();
  1102. CSTK.reserveValues(mArgc+3, mArgv);
  1103. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1104. EngineMarshallData( a, mArgc, mArgv );
  1105. EngineMarshallData( b, mArgc, mArgv );
  1106. EngineMarshallData( c, mArgc, mArgv );
  1107. return R( EngineUnmarshallData< R >()( _exec() ) );
  1108. }
  1109. else
  1110. {
  1111. SimConsoleThreadExecCallback cb;
  1112. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, false, &cb);
  1113. evt->populateArgs(mArgv);
  1114. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1115. EngineMarshallData( a, mArgc, mArgv );
  1116. EngineMarshallData( b, mArgc, mArgv );
  1117. EngineMarshallData( c, mArgc, mArgv );
  1118. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1119. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1120. }
  1121. }
  1122. template< typename R, typename A, typename B, typename C, typename D >
  1123. R call( A a, B b, C c, D d )
  1124. {
  1125. if (Con::isMainThread())
  1126. {
  1127. ConsoleStackFrameSaver sav; sav.save();
  1128. CSTK.reserveValues(mArgc+4, mArgv);
  1129. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1130. EngineMarshallData( a, mArgc, mArgv );
  1131. EngineMarshallData( b, mArgc, mArgv );
  1132. EngineMarshallData( c, mArgc, mArgv );
  1133. EngineMarshallData( d, mArgc, mArgv );
  1134. return R( EngineUnmarshallData< R >()( _exec() ) );
  1135. }
  1136. else
  1137. {
  1138. SimConsoleThreadExecCallback cb;
  1139. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, false, &cb);
  1140. evt->populateArgs(mArgv);
  1141. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1142. EngineMarshallData( a, mArgc, mArgv );
  1143. EngineMarshallData( b, mArgc, mArgv );
  1144. EngineMarshallData( c, mArgc, mArgv );
  1145. EngineMarshallData( d, mArgc, mArgv );
  1146. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1147. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1148. }
  1149. }
  1150. template< typename R, typename A, typename B, typename C, typename D, typename E >
  1151. R call( A a, B b, C c, D d, E e )
  1152. {
  1153. if (Con::isMainThread())
  1154. {
  1155. ConsoleStackFrameSaver sav; sav.save();
  1156. CSTK.reserveValues(mArgc+5, mArgv);
  1157. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1158. EngineMarshallData( a, mArgc, mArgv );
  1159. EngineMarshallData( b, mArgc, mArgv );
  1160. EngineMarshallData( c, mArgc, mArgv );
  1161. EngineMarshallData( d, mArgc, mArgv );
  1162. EngineMarshallData( e, mArgc, mArgv );
  1163. return R( EngineUnmarshallData< R >()( _exec() ) );
  1164. }
  1165. else
  1166. {
  1167. SimConsoleThreadExecCallback cb;
  1168. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, false, &cb);
  1169. evt->populateArgs(mArgv);
  1170. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1171. EngineMarshallData( a, mArgc, mArgv );
  1172. EngineMarshallData( b, mArgc, mArgv );
  1173. EngineMarshallData( c, mArgc, mArgv );
  1174. EngineMarshallData( d, mArgc, mArgv );
  1175. EngineMarshallData( e, mArgc, mArgv );
  1176. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1177. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1178. }
  1179. }
  1180. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
  1181. R call( A a, B b, C c, D d, E e, F f )
  1182. {
  1183. if (Con::isMainThread())
  1184. {
  1185. ConsoleStackFrameSaver sav; sav.save();
  1186. CSTK.reserveValues(mArgc+6, mArgv);
  1187. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1188. EngineMarshallData( a, mArgc, mArgv );
  1189. EngineMarshallData( b, mArgc, mArgv );
  1190. EngineMarshallData( c, mArgc, mArgv );
  1191. EngineMarshallData( d, mArgc, mArgv );
  1192. EngineMarshallData( e, mArgc, mArgv );
  1193. EngineMarshallData( f, mArgc, mArgv );
  1194. return R( EngineUnmarshallData< R >()( _exec() ) );
  1195. }
  1196. else
  1197. {
  1198. SimConsoleThreadExecCallback cb;
  1199. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, false, &cb);
  1200. evt->populateArgs(mArgv);
  1201. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1202. EngineMarshallData( a, mArgc, mArgv );
  1203. EngineMarshallData( b, mArgc, mArgv );
  1204. EngineMarshallData( c, mArgc, mArgv );
  1205. EngineMarshallData( d, mArgc, mArgv );
  1206. EngineMarshallData( e, mArgc, mArgv );
  1207. EngineMarshallData( f, mArgc, mArgv );
  1208. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1209. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1210. }
  1211. }
  1212. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
  1213. R call( A a, B b, C c, D d, E e, F f, G g )
  1214. {
  1215. if (Con::isMainThread())
  1216. {
  1217. ConsoleStackFrameSaver sav; sav.save();
  1218. CSTK.reserveValues(mArgc+7, mArgv);
  1219. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1220. EngineMarshallData( a, mArgc, mArgv );
  1221. EngineMarshallData( b, mArgc, mArgv );
  1222. EngineMarshallData( c, mArgc, mArgv );
  1223. EngineMarshallData( d, mArgc, mArgv );
  1224. EngineMarshallData( e, mArgc, mArgv );
  1225. EngineMarshallData( f, mArgc, mArgv );
  1226. EngineMarshallData( g, mArgc, mArgv );
  1227. return R( EngineUnmarshallData< R >()( _exec() ) );
  1228. }
  1229. else
  1230. {
  1231. SimConsoleThreadExecCallback cb;
  1232. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, false, &cb);
  1233. evt->populateArgs(mArgv);
  1234. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1235. EngineMarshallData( a, mArgc, mArgv );
  1236. EngineMarshallData( b, mArgc, mArgv );
  1237. EngineMarshallData( c, mArgc, mArgv );
  1238. EngineMarshallData( d, mArgc, mArgv );
  1239. EngineMarshallData( e, mArgc, mArgv );
  1240. EngineMarshallData( f, mArgc, mArgv );
  1241. EngineMarshallData( g, mArgc, mArgv );
  1242. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1243. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1244. }
  1245. }
  1246. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
  1247. R call( A a, B b, C c, D d, E e, F f, G g, H h )
  1248. {
  1249. if (Con::isMainThread())
  1250. {
  1251. ConsoleStackFrameSaver sav; sav.save();
  1252. CSTK.reserveValues(mArgc+8, mArgv);
  1253. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1254. EngineMarshallData( a, mArgc, mArgv );
  1255. EngineMarshallData( b, mArgc, mArgv );
  1256. EngineMarshallData( c, mArgc, mArgv );
  1257. EngineMarshallData( d, mArgc, mArgv );
  1258. EngineMarshallData( e, mArgc, mArgv );
  1259. EngineMarshallData( f, mArgc, mArgv );
  1260. EngineMarshallData( g, mArgc, mArgv );
  1261. EngineMarshallData( h, mArgc, mArgv );
  1262. return R( EngineUnmarshallData< R >()( _exec() ) );
  1263. }
  1264. else
  1265. {
  1266. SimConsoleThreadExecCallback cb;
  1267. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, false, &cb);
  1268. evt->populateArgs(mArgv);
  1269. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1270. EngineMarshallData( a, mArgc, mArgv );
  1271. EngineMarshallData( b, mArgc, mArgv );
  1272. EngineMarshallData( c, mArgc, mArgv );
  1273. EngineMarshallData( d, mArgc, mArgv );
  1274. EngineMarshallData( e, mArgc, mArgv );
  1275. EngineMarshallData( f, mArgc, mArgv );
  1276. EngineMarshallData( g, mArgc, mArgv );
  1277. EngineMarshallData( h, mArgc, mArgv );
  1278. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1279. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1280. }
  1281. }
  1282. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
  1283. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
  1284. {
  1285. if (Con::isMainThread())
  1286. {
  1287. ConsoleStackFrameSaver sav; sav.save();
  1288. CSTK.reserveValues(mArgc+9, mArgv);
  1289. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1290. EngineMarshallData( a, mArgc, mArgv );
  1291. EngineMarshallData( b, mArgc, mArgv );
  1292. EngineMarshallData( c, mArgc, mArgv );
  1293. EngineMarshallData( d, mArgc, mArgv );
  1294. EngineMarshallData( e, mArgc, mArgv );
  1295. EngineMarshallData( f, mArgc, mArgv );
  1296. EngineMarshallData( g, mArgc, mArgv );
  1297. EngineMarshallData( h, mArgc, mArgv );
  1298. EngineMarshallData( i, mArgc, mArgv );
  1299. return R( EngineUnmarshallData< R >()( _exec() ) );
  1300. }
  1301. else
  1302. {
  1303. SimConsoleThreadExecCallback cb;
  1304. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, false, &cb);
  1305. evt->populateArgs(mArgv);
  1306. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1307. EngineMarshallData( a, mArgc, mArgv );
  1308. EngineMarshallData( b, mArgc, mArgv );
  1309. EngineMarshallData( c, mArgc, mArgv );
  1310. EngineMarshallData( d, mArgc, mArgv );
  1311. EngineMarshallData( e, mArgc, mArgv );
  1312. EngineMarshallData( f, mArgc, mArgv );
  1313. EngineMarshallData( g, mArgc, mArgv );
  1314. EngineMarshallData( h, mArgc, mArgv );
  1315. EngineMarshallData( i, mArgc, mArgv );
  1316. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1317. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1318. }
  1319. }
  1320. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
  1321. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
  1322. {
  1323. if (Con::isMainThread())
  1324. {
  1325. ConsoleStackFrameSaver sav; sav.save();
  1326. CSTK.reserveValues(mArgc+10, mArgv);
  1327. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1328. EngineMarshallData( a, mArgc, mArgv );
  1329. EngineMarshallData( b, mArgc, mArgv );
  1330. EngineMarshallData( c, mArgc, mArgv );
  1331. EngineMarshallData( d, mArgc, mArgv );
  1332. EngineMarshallData( e, mArgc, mArgv );
  1333. EngineMarshallData( f, mArgc, mArgv );
  1334. EngineMarshallData( g, mArgc, mArgv );
  1335. EngineMarshallData( h, mArgc, mArgv );
  1336. EngineMarshallData( i, mArgc, mArgv );
  1337. EngineMarshallData( j, mArgc, mArgv );
  1338. return R( EngineUnmarshallData< R >()( _exec() ) );
  1339. }
  1340. else
  1341. {
  1342. SimConsoleThreadExecCallback cb;
  1343. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, false, &cb);
  1344. evt->populateArgs(mArgv);
  1345. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1346. EngineMarshallData( a, mArgc, mArgv );
  1347. EngineMarshallData( b, mArgc, mArgv );
  1348. EngineMarshallData( c, mArgc, mArgv );
  1349. EngineMarshallData( d, mArgc, mArgv );
  1350. EngineMarshallData( e, mArgc, mArgv );
  1351. EngineMarshallData( f, mArgc, mArgv );
  1352. EngineMarshallData( g, mArgc, mArgv );
  1353. EngineMarshallData( h, mArgc, mArgv );
  1354. EngineMarshallData( i, mArgc, mArgv );
  1355. EngineMarshallData( j, mArgc, mArgv );
  1356. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1357. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1358. }
  1359. }
  1360. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
  1361. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
  1362. {
  1363. if (Con::isMainThread())
  1364. {
  1365. ConsoleStackFrameSaver sav; sav.save();
  1366. CSTK.reserveValues(mArgc+11, mArgv);
  1367. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1368. EngineMarshallData( a, mArgc, mArgv );
  1369. EngineMarshallData( b, mArgc, mArgv );
  1370. EngineMarshallData( c, mArgc, mArgv );
  1371. EngineMarshallData( d, mArgc, mArgv );
  1372. EngineMarshallData( e, mArgc, mArgv );
  1373. EngineMarshallData( f, mArgc, mArgv );
  1374. EngineMarshallData( g, mArgc, mArgv );
  1375. EngineMarshallData( h, mArgc, mArgv );
  1376. EngineMarshallData( i, mArgc, mArgv );
  1377. EngineMarshallData( j, mArgc, mArgv );
  1378. EngineMarshallData( k, mArgc, mArgv );
  1379. return R( EngineUnmarshallData< R >()( _exec() ) );
  1380. }
  1381. else
  1382. {
  1383. SimConsoleThreadExecCallback cb;
  1384. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, false, &cb);
  1385. evt->populateArgs(mArgv);
  1386. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1387. EngineMarshallData( a, mArgc, mArgv );
  1388. EngineMarshallData( b, mArgc, mArgv );
  1389. EngineMarshallData( c, mArgc, mArgv );
  1390. EngineMarshallData( d, mArgc, mArgv );
  1391. EngineMarshallData( e, mArgc, mArgv );
  1392. EngineMarshallData( f, mArgc, mArgv );
  1393. EngineMarshallData( g, mArgc, mArgv );
  1394. EngineMarshallData( h, mArgc, mArgv );
  1395. EngineMarshallData( i, mArgc, mArgv );
  1396. EngineMarshallData( j, mArgc, mArgv );
  1397. EngineMarshallData( k, mArgc, mArgv );
  1398. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1399. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1400. }
  1401. }
  1402. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L >
  1403. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l )
  1404. {
  1405. if (Con::isMainThread())
  1406. {
  1407. ConsoleStackFrameSaver sav; sav.save();
  1408. CSTK.reserveValues(mArgc+12, mArgv);
  1409. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1410. EngineMarshallData( a, mArgc, mArgv );
  1411. EngineMarshallData( b, mArgc, mArgv );
  1412. EngineMarshallData( c, mArgc, mArgv );
  1413. EngineMarshallData( d, mArgc, mArgv );
  1414. EngineMarshallData( e, mArgc, mArgv );
  1415. EngineMarshallData( f, mArgc, mArgv );
  1416. EngineMarshallData( g, mArgc, mArgv );
  1417. EngineMarshallData( h, mArgc, mArgv );
  1418. EngineMarshallData( i, mArgc, mArgv );
  1419. EngineMarshallData( j, mArgc, mArgv );
  1420. EngineMarshallData( k, mArgc, mArgv );
  1421. EngineMarshallData( l, mArgc, mArgv );
  1422. return R( EngineUnmarshallData< R >()( _exec() ) );
  1423. }
  1424. else
  1425. {
  1426. SimConsoleThreadExecCallback cb;
  1427. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+12, NULL, false, &cb);
  1428. evt->populateArgs(mArgv);
  1429. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1430. EngineMarshallData( a, mArgc, mArgv );
  1431. EngineMarshallData( b, mArgc, mArgv );
  1432. EngineMarshallData( c, mArgc, mArgv );
  1433. EngineMarshallData( d, mArgc, mArgv );
  1434. EngineMarshallData( e, mArgc, mArgv );
  1435. EngineMarshallData( f, mArgc, mArgv );
  1436. EngineMarshallData( g, mArgc, mArgv );
  1437. EngineMarshallData( h, mArgc, mArgv );
  1438. EngineMarshallData( i, mArgc, mArgv );
  1439. EngineMarshallData( j, mArgc, mArgv );
  1440. EngineMarshallData( k, mArgc, mArgv );
  1441. EngineMarshallData( l, mArgc, mArgv );
  1442. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1443. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1444. }
  1445. }
  1446. };
  1447. // Override for when first parameter is presumably a SimObject*, in which case A will be absorbed as the callback
  1448. template<typename P1> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper
  1449. {
  1450. public:
  1451. _EngineConsoleExecCallbackHelper( SimObject* pThis )
  1452. {
  1453. mThis = pThis;
  1454. mArgc = mInitialArgc = 2;
  1455. mCallbackName = NULL;
  1456. }
  1457. template< typename R, typename A >
  1458. R call( A a )
  1459. {
  1460. if (Con::isMainThread())
  1461. {
  1462. ConsoleStackFrameSaver sav; sav.save();
  1463. CSTK.reserveValues(mArgc+0, mArgv);
  1464. mArgv[ 0 ].value->setStackStringValue(a);
  1465. return R( EngineUnmarshallData< R >()( _exec() ) );
  1466. }
  1467. else
  1468. {
  1469. SimConsoleThreadExecCallback cb;
  1470. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+0, NULL, true, &cb);
  1471. evt->populateArgs(mArgv);
  1472. mArgv[ 0 ].value->setStackStringValue(a);
  1473. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1474. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1475. }
  1476. }
  1477. template< typename R, typename A, typename B >
  1478. R call( A a, B b )
  1479. {
  1480. if (Con::isMainThread())
  1481. {
  1482. ConsoleStackFrameSaver sav; sav.save();
  1483. CSTK.reserveValues(mArgc+1, mArgv);
  1484. mArgv[ 0 ].value->setStackStringValue(a);
  1485. EngineMarshallData( b, mArgc, mArgv );
  1486. return R( EngineUnmarshallData< R >()( _exec() ) );
  1487. }
  1488. else
  1489. {
  1490. SimConsoleThreadExecCallback cb;
  1491. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, true, &cb);
  1492. evt->populateArgs(mArgv);
  1493. mArgv[ 0 ].value->setStackStringValue(a);
  1494. EngineMarshallData( b, mArgc, mArgv );
  1495. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1496. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1497. }
  1498. }
  1499. template< typename R, typename A, typename B, typename C >
  1500. R call( A a, B b, C c )
  1501. {
  1502. if (Con::isMainThread())
  1503. {
  1504. ConsoleStackFrameSaver sav; sav.save();
  1505. CSTK.reserveValues(mArgc+2, mArgv);
  1506. mArgv[ 0 ].value->setStackStringValue(a);
  1507. EngineMarshallData( b, mArgc, mArgv );
  1508. EngineMarshallData( c, mArgc, mArgv );
  1509. return R( EngineUnmarshallData< R >()( _exec() ) );
  1510. }
  1511. else
  1512. {
  1513. SimConsoleThreadExecCallback cb;
  1514. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, true, &cb);
  1515. evt->populateArgs(mArgv);
  1516. mArgv[ 0 ].value->setStackStringValue(a);
  1517. EngineMarshallData( b, mArgc, mArgv );
  1518. EngineMarshallData( c, mArgc, mArgv );
  1519. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1520. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1521. }
  1522. }
  1523. template< typename R, typename A, typename B, typename C, typename D >
  1524. R call( A a, B b, C c, D d )
  1525. {
  1526. if (Con::isMainThread())
  1527. {
  1528. ConsoleStackFrameSaver sav; sav.save();
  1529. CSTK.reserveValues(mArgc+3, mArgv);
  1530. mArgv[ 0 ].value->setStackStringValue(a);
  1531. EngineMarshallData( b, mArgc, mArgv );
  1532. EngineMarshallData( c, mArgc, mArgv );
  1533. EngineMarshallData( d, mArgc, mArgv );
  1534. return R( EngineUnmarshallData< R >()( _exec() ) );
  1535. }
  1536. else
  1537. {
  1538. SimConsoleThreadExecCallback cb;
  1539. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, true, &cb);
  1540. evt->populateArgs(mArgv);
  1541. mArgv[ 0 ].value->setStackStringValue(a);
  1542. EngineMarshallData( b, mArgc, mArgv );
  1543. EngineMarshallData( c, mArgc, mArgv );
  1544. EngineMarshallData( d, mArgc, mArgv );
  1545. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1546. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1547. }
  1548. }
  1549. template< typename R, typename A, typename B, typename C, typename D, typename E >
  1550. R call( A a, B b, C c, D d, E e )
  1551. {
  1552. if (Con::isMainThread())
  1553. {
  1554. ConsoleStackFrameSaver sav; sav.save();
  1555. CSTK.reserveValues(mArgc+4, mArgv);
  1556. mArgv[ 0 ].value->setStackStringValue(a);
  1557. EngineMarshallData( b, mArgc, mArgv );
  1558. EngineMarshallData( c, mArgc, mArgv );
  1559. EngineMarshallData( d, mArgc, mArgv );
  1560. EngineMarshallData( e, mArgc, mArgv );
  1561. return R( EngineUnmarshallData< R >()( _exec() ) );
  1562. }
  1563. else
  1564. {
  1565. SimConsoleThreadExecCallback cb;
  1566. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, true, &cb);
  1567. evt->populateArgs(mArgv);
  1568. mArgv[ 0 ].value->setStackStringValue(a);
  1569. EngineMarshallData( b, mArgc, mArgv );
  1570. EngineMarshallData( c, mArgc, mArgv );
  1571. EngineMarshallData( d, mArgc, mArgv );
  1572. EngineMarshallData( e, mArgc, mArgv );
  1573. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1574. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1575. }
  1576. }
  1577. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
  1578. R call( A a, B b, C c, D d, E e, F f )
  1579. {
  1580. if (Con::isMainThread())
  1581. {
  1582. ConsoleStackFrameSaver sav; sav.save();
  1583. CSTK.reserveValues(mArgc+5, mArgv);
  1584. mArgv[ 0 ].value->setStackStringValue(a);
  1585. EngineMarshallData( b, mArgc, mArgv );
  1586. EngineMarshallData( c, mArgc, mArgv );
  1587. EngineMarshallData( d, mArgc, mArgv );
  1588. EngineMarshallData( e, mArgc, mArgv );
  1589. EngineMarshallData( f, mArgc, mArgv );
  1590. return R( EngineUnmarshallData< R >()( _exec() ) );
  1591. }
  1592. else
  1593. {
  1594. SimConsoleThreadExecCallback cb;
  1595. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, true, &cb);
  1596. evt->populateArgs(mArgv);
  1597. mArgv[ 0 ].value->setStackStringValue(a);
  1598. EngineMarshallData( b, mArgc, mArgv );
  1599. EngineMarshallData( c, mArgc, mArgv );
  1600. EngineMarshallData( d, mArgc, mArgv );
  1601. EngineMarshallData( e, mArgc, mArgv );
  1602. EngineMarshallData( f, mArgc, mArgv );
  1603. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1604. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1605. }
  1606. }
  1607. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
  1608. R call( A a, B b, C c, D d, E e, F f, G g )
  1609. {
  1610. if (Con::isMainThread())
  1611. {
  1612. ConsoleStackFrameSaver sav; sav.save();
  1613. CSTK.reserveValues(mArgc+6, mArgv);
  1614. mArgv[ 0 ].value->setStackStringValue(a);
  1615. EngineMarshallData( b, mArgc, mArgv );
  1616. EngineMarshallData( c, mArgc, mArgv );
  1617. EngineMarshallData( d, mArgc, mArgv );
  1618. EngineMarshallData( e, mArgc, mArgv );
  1619. EngineMarshallData( f, mArgc, mArgv );
  1620. EngineMarshallData( g, mArgc, mArgv );
  1621. return R( EngineUnmarshallData< R >()( _exec() ) );
  1622. }
  1623. else
  1624. {
  1625. SimConsoleThreadExecCallback cb;
  1626. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, true, &cb);
  1627. evt->populateArgs(mArgv);
  1628. mArgv[ 0 ].value->setStackStringValue(a);
  1629. EngineMarshallData( b, mArgc, mArgv );
  1630. EngineMarshallData( c, mArgc, mArgv );
  1631. EngineMarshallData( d, mArgc, mArgv );
  1632. EngineMarshallData( e, mArgc, mArgv );
  1633. EngineMarshallData( f, mArgc, mArgv );
  1634. EngineMarshallData( g, mArgc, mArgv );
  1635. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1636. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1637. }
  1638. }
  1639. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
  1640. R call( A a, B b, C c, D d, E e, F f, G g, H h )
  1641. {
  1642. if (Con::isMainThread())
  1643. {
  1644. ConsoleStackFrameSaver sav; sav.save();
  1645. CSTK.reserveValues(mArgc+7, mArgv);
  1646. mArgv[ 0 ].value->setStackStringValue(a);
  1647. EngineMarshallData( b, mArgc, mArgv );
  1648. EngineMarshallData( c, mArgc, mArgv );
  1649. EngineMarshallData( d, mArgc, mArgv );
  1650. EngineMarshallData( e, mArgc, mArgv );
  1651. EngineMarshallData( f, mArgc, mArgv );
  1652. EngineMarshallData( g, mArgc, mArgv );
  1653. EngineMarshallData( h, mArgc, mArgv );
  1654. return R( EngineUnmarshallData< R >()( _exec() ) );
  1655. }
  1656. else
  1657. {
  1658. SimConsoleThreadExecCallback cb;
  1659. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, true, &cb);
  1660. evt->populateArgs(mArgv);
  1661. mArgv[ 0 ].value->setStackStringValue(a);
  1662. EngineMarshallData( b, mArgc, mArgv );
  1663. EngineMarshallData( c, mArgc, mArgv );
  1664. EngineMarshallData( d, mArgc, mArgv );
  1665. EngineMarshallData( e, mArgc, mArgv );
  1666. EngineMarshallData( f, mArgc, mArgv );
  1667. EngineMarshallData( g, mArgc, mArgv );
  1668. EngineMarshallData( h, mArgc, mArgv );
  1669. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1670. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1671. }
  1672. }
  1673. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
  1674. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
  1675. {
  1676. if (Con::isMainThread())
  1677. {
  1678. ConsoleStackFrameSaver sav; sav.save();
  1679. CSTK.reserveValues(mArgc+8, mArgv);
  1680. mArgv[ 0 ].value->setStackStringValue(a);
  1681. EngineMarshallData( b, mArgc, mArgv );
  1682. EngineMarshallData( c, mArgc, mArgv );
  1683. EngineMarshallData( d, mArgc, mArgv );
  1684. EngineMarshallData( e, mArgc, mArgv );
  1685. EngineMarshallData( f, mArgc, mArgv );
  1686. EngineMarshallData( g, mArgc, mArgv );
  1687. EngineMarshallData( h, mArgc, mArgv );
  1688. EngineMarshallData( i, mArgc, mArgv );
  1689. return R( EngineUnmarshallData< R >()( _exec() ) );
  1690. }
  1691. else
  1692. {
  1693. SimConsoleThreadExecCallback cb;
  1694. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, true, &cb);
  1695. evt->populateArgs(mArgv);
  1696. mArgv[ 0 ].value->setStackStringValue(a);
  1697. EngineMarshallData( b, mArgc, mArgv );
  1698. EngineMarshallData( c, mArgc, mArgv );
  1699. EngineMarshallData( d, mArgc, mArgv );
  1700. EngineMarshallData( e, mArgc, mArgv );
  1701. EngineMarshallData( f, mArgc, mArgv );
  1702. EngineMarshallData( g, mArgc, mArgv );
  1703. EngineMarshallData( h, mArgc, mArgv );
  1704. EngineMarshallData( i, mArgc, mArgv );
  1705. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1706. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1707. }
  1708. }
  1709. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
  1710. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
  1711. {
  1712. if (Con::isMainThread())
  1713. {
  1714. ConsoleStackFrameSaver sav; sav.save();
  1715. CSTK.reserveValues(mArgc+9, mArgv);
  1716. mArgv[ 0 ].value->setStackStringValue(a);
  1717. EngineMarshallData( b, mArgc, mArgv );
  1718. EngineMarshallData( c, mArgc, mArgv );
  1719. EngineMarshallData( d, mArgc, mArgv );
  1720. EngineMarshallData( e, mArgc, mArgv );
  1721. EngineMarshallData( f, mArgc, mArgv );
  1722. EngineMarshallData( g, mArgc, mArgv );
  1723. EngineMarshallData( h, mArgc, mArgv );
  1724. EngineMarshallData( i, mArgc, mArgv );
  1725. EngineMarshallData( j, mArgc, mArgv );
  1726. return R( EngineUnmarshallData< R >()( _exec() ) );
  1727. }
  1728. else
  1729. {
  1730. SimConsoleThreadExecCallback cb;
  1731. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, true, &cb);
  1732. evt->populateArgs(mArgv);
  1733. mArgv[ 0 ].value->setStackStringValue(a);
  1734. EngineMarshallData( b, mArgc, mArgv );
  1735. EngineMarshallData( c, mArgc, mArgv );
  1736. EngineMarshallData( d, mArgc, mArgv );
  1737. EngineMarshallData( e, mArgc, mArgv );
  1738. EngineMarshallData( f, mArgc, mArgv );
  1739. EngineMarshallData( g, mArgc, mArgv );
  1740. EngineMarshallData( h, mArgc, mArgv );
  1741. EngineMarshallData( i, mArgc, mArgv );
  1742. EngineMarshallData( j, mArgc, mArgv );
  1743. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1744. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1745. }
  1746. }
  1747. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
  1748. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
  1749. {
  1750. if (Con::isMainThread())
  1751. {
  1752. ConsoleStackFrameSaver sav; sav.save();
  1753. CSTK.reserveValues(mArgc+10, mArgv);
  1754. mArgv[ 0 ].value->setStackStringValue(a);
  1755. EngineMarshallData( b, mArgc, mArgv );
  1756. EngineMarshallData( c, mArgc, mArgv );
  1757. EngineMarshallData( d, mArgc, mArgv );
  1758. EngineMarshallData( e, mArgc, mArgv );
  1759. EngineMarshallData( f, mArgc, mArgv );
  1760. EngineMarshallData( g, mArgc, mArgv );
  1761. EngineMarshallData( h, mArgc, mArgv );
  1762. EngineMarshallData( i, mArgc, mArgv );
  1763. EngineMarshallData( j, mArgc, mArgv );
  1764. EngineMarshallData( k, mArgc, mArgv );
  1765. return R( EngineUnmarshallData< R >()( _exec() ) );
  1766. }
  1767. else
  1768. {
  1769. SimConsoleThreadExecCallback cb;
  1770. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, true, &cb);
  1771. evt->populateArgs(mArgv);
  1772. mArgv[ 0 ].value->setStackStringValue(a);
  1773. EngineMarshallData( b, mArgc, mArgv );
  1774. EngineMarshallData( c, mArgc, mArgv );
  1775. EngineMarshallData( d, mArgc, mArgv );
  1776. EngineMarshallData( e, mArgc, mArgv );
  1777. EngineMarshallData( f, mArgc, mArgv );
  1778. EngineMarshallData( g, mArgc, mArgv );
  1779. EngineMarshallData( h, mArgc, mArgv );
  1780. EngineMarshallData( i, mArgc, mArgv );
  1781. EngineMarshallData( j, mArgc, mArgv );
  1782. EngineMarshallData( k, mArgc, mArgv );
  1783. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1784. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1785. }
  1786. }
  1787. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L >
  1788. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l )
  1789. {
  1790. if (Con::isMainThread())
  1791. {
  1792. ConsoleStackFrameSaver sav; sav.save();
  1793. CSTK.reserveValues(mArgc+11, mArgv);
  1794. mArgv[ 0 ].value->setStackStringValue(a);
  1795. EngineMarshallData( b, mArgc, mArgv );
  1796. EngineMarshallData( c, mArgc, mArgv );
  1797. EngineMarshallData( d, mArgc, mArgv );
  1798. EngineMarshallData( e, mArgc, mArgv );
  1799. EngineMarshallData( f, mArgc, mArgv );
  1800. EngineMarshallData( g, mArgc, mArgv );
  1801. EngineMarshallData( h, mArgc, mArgv );
  1802. EngineMarshallData( i, mArgc, mArgv );
  1803. EngineMarshallData( j, mArgc, mArgv );
  1804. EngineMarshallData( k, mArgc, mArgv );
  1805. EngineMarshallData( l, mArgc, mArgv );
  1806. return R( EngineUnmarshallData< R >()( _exec() ) );
  1807. }
  1808. else
  1809. {
  1810. SimConsoleThreadExecCallback cb;
  1811. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, true, &cb);
  1812. evt->populateArgs(mArgv);
  1813. mArgv[ 0 ].value->setStackStringValue(a);
  1814. EngineMarshallData( b, mArgc, mArgv );
  1815. EngineMarshallData( c, mArgc, mArgv );
  1816. EngineMarshallData( d, mArgc, mArgv );
  1817. EngineMarshallData( e, mArgc, mArgv );
  1818. EngineMarshallData( f, mArgc, mArgv );
  1819. EngineMarshallData( g, mArgc, mArgv );
  1820. EngineMarshallData( h, mArgc, mArgv );
  1821. EngineMarshallData( i, mArgc, mArgv );
  1822. EngineMarshallData( j, mArgc, mArgv );
  1823. EngineMarshallData( k, mArgc, mArgv );
  1824. EngineMarshallData( l, mArgc, mArgv );
  1825. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1826. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1827. }
  1828. }
  1829. };
  1830. // Override for when first parameter is const char*
  1831. template<> struct _EngineConsoleExecCallbackHelper<const char*> : public _BaseEngineConsoleCallbackHelper
  1832. {
  1833. _EngineConsoleExecCallbackHelper( const char *callbackName )
  1834. {
  1835. mThis = NULL;
  1836. mArgc = mInitialArgc = 1;
  1837. mCallbackName = StringTable->insert(callbackName);
  1838. }
  1839. template< typename R >
  1840. R call()
  1841. {
  1842. if (Con::isMainThread())
  1843. {
  1844. ConsoleStackFrameSaver sav; sav.save();
  1845. CSTK.reserveValues(mArgc, mArgv);
  1846. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1847. return R( EngineUnmarshallData< R >()( _exec() ) );
  1848. }
  1849. else
  1850. {
  1851. SimConsoleThreadExecCallback cb;
  1852. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc, NULL, false, &cb);
  1853. evt->populateArgs(mArgv);
  1854. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1855. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1856. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1857. }
  1858. }
  1859. template< typename R, typename A >
  1860. R call( A a )
  1861. {
  1862. if (Con::isMainThread())
  1863. {
  1864. ConsoleStackFrameSaver sav; sav.save();
  1865. CSTK.reserveValues(mArgc+1, mArgv);
  1866. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1867. EngineMarshallData( a, mArgc, mArgv );
  1868. return R( EngineUnmarshallData< R >()( _exec() ) );
  1869. }
  1870. else
  1871. {
  1872. SimConsoleThreadExecCallback cb;
  1873. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, false, &cb);
  1874. evt->populateArgs(mArgv);
  1875. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1876. EngineMarshallData( a, mArgc, mArgv );
  1877. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1878. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1879. }
  1880. }
  1881. template< typename R, typename A, typename B >
  1882. R call( A a, B b )
  1883. {
  1884. if (Con::isMainThread())
  1885. {
  1886. ConsoleStackFrameSaver sav; sav.save();
  1887. CSTK.reserveValues(mArgc+2, mArgv);
  1888. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1889. EngineMarshallData( a, mArgc, mArgv );
  1890. EngineMarshallData( b, mArgc, mArgv );
  1891. return R( EngineUnmarshallData< R >()( _exec() ) );
  1892. }
  1893. else
  1894. {
  1895. SimConsoleThreadExecCallback cb;
  1896. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, false, &cb);
  1897. evt->populateArgs(mArgv);
  1898. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1899. EngineMarshallData( a, mArgc, mArgv );
  1900. EngineMarshallData( b, mArgc, mArgv );
  1901. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1902. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1903. }
  1904. }
  1905. template< typename R, typename A, typename B, typename C >
  1906. R call( A a, B b, C c )
  1907. {
  1908. if (Con::isMainThread())
  1909. {
  1910. ConsoleStackFrameSaver sav; sav.save();
  1911. CSTK.reserveValues(mArgc+3, mArgv);
  1912. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1913. EngineMarshallData( a, mArgc, mArgv );
  1914. EngineMarshallData( b, mArgc, mArgv );
  1915. EngineMarshallData( c, mArgc, mArgv );
  1916. return R( EngineUnmarshallData< R >()( _exec() ) );
  1917. }
  1918. else
  1919. {
  1920. SimConsoleThreadExecCallback cb;
  1921. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, false, &cb);
  1922. evt->populateArgs(mArgv);
  1923. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1924. EngineMarshallData( a, mArgc, mArgv );
  1925. EngineMarshallData( b, mArgc, mArgv );
  1926. EngineMarshallData( c, mArgc, mArgv );
  1927. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1928. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1929. }
  1930. }
  1931. template< typename R, typename A, typename B, typename C, typename D >
  1932. R call( A a, B b, C c, D d )
  1933. {
  1934. if (Con::isMainThread())
  1935. {
  1936. ConsoleStackFrameSaver sav; sav.save();
  1937. CSTK.reserveValues(mArgc+4, mArgv);
  1938. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1939. EngineMarshallData( a, mArgc, mArgv );
  1940. EngineMarshallData( b, mArgc, mArgv );
  1941. EngineMarshallData( c, mArgc, mArgv );
  1942. EngineMarshallData( d, mArgc, mArgv );
  1943. return R( EngineUnmarshallData< R >()( _exec() ) );
  1944. }
  1945. else
  1946. {
  1947. SimConsoleThreadExecCallback cb;
  1948. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, false, &cb);
  1949. evt->populateArgs(mArgv);
  1950. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1951. EngineMarshallData( a, mArgc, mArgv );
  1952. EngineMarshallData( b, mArgc, mArgv );
  1953. EngineMarshallData( c, mArgc, mArgv );
  1954. EngineMarshallData( d, mArgc, mArgv );
  1955. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1956. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1957. }
  1958. }
  1959. template< typename R, typename A, typename B, typename C, typename D, typename E >
  1960. R call( A a, B b, C c, D d, E e )
  1961. {
  1962. if (Con::isMainThread())
  1963. {
  1964. ConsoleStackFrameSaver sav; sav.save();
  1965. CSTK.reserveValues(mArgc+5, mArgv);
  1966. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1967. EngineMarshallData( a, mArgc, mArgv );
  1968. EngineMarshallData( b, mArgc, mArgv );
  1969. EngineMarshallData( c, mArgc, mArgv );
  1970. EngineMarshallData( d, mArgc, mArgv );
  1971. EngineMarshallData( e, mArgc, mArgv );
  1972. return R( EngineUnmarshallData< R >()( _exec() ) );
  1973. }
  1974. else
  1975. {
  1976. SimConsoleThreadExecCallback cb;
  1977. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, false, &cb);
  1978. evt->populateArgs(mArgv);
  1979. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1980. EngineMarshallData( a, mArgc, mArgv );
  1981. EngineMarshallData( b, mArgc, mArgv );
  1982. EngineMarshallData( c, mArgc, mArgv );
  1983. EngineMarshallData( d, mArgc, mArgv );
  1984. EngineMarshallData( e, mArgc, mArgv );
  1985. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1986. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1987. }
  1988. }
  1989. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
  1990. R call( A a, B b, C c, D d, E e, F f )
  1991. {
  1992. if (Con::isMainThread())
  1993. {
  1994. ConsoleStackFrameSaver sav; sav.save();
  1995. CSTK.reserveValues(mArgc+6, mArgv);
  1996. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1997. EngineMarshallData( a, mArgc, mArgv );
  1998. EngineMarshallData( b, mArgc, mArgv );
  1999. EngineMarshallData( c, mArgc, mArgv );
  2000. EngineMarshallData( d, mArgc, mArgv );
  2001. EngineMarshallData( e, mArgc, mArgv );
  2002. EngineMarshallData( f, mArgc, mArgv );
  2003. return R( EngineUnmarshallData< R >()( _exec() ) );
  2004. }
  2005. else
  2006. {
  2007. SimConsoleThreadExecCallback cb;
  2008. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, false, &cb);
  2009. evt->populateArgs(mArgv);
  2010. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2011. EngineMarshallData( a, mArgc, mArgv );
  2012. EngineMarshallData( b, mArgc, mArgv );
  2013. EngineMarshallData( c, mArgc, mArgv );
  2014. EngineMarshallData( d, mArgc, mArgv );
  2015. EngineMarshallData( e, mArgc, mArgv );
  2016. EngineMarshallData( f, mArgc, mArgv );
  2017. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2018. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2019. }
  2020. }
  2021. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
  2022. R call( A a, B b, C c, D d, E e, F f, G g )
  2023. {
  2024. if (Con::isMainThread())
  2025. {
  2026. ConsoleStackFrameSaver sav; sav.save();
  2027. CSTK.reserveValues(mArgc+7, mArgv);
  2028. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2029. EngineMarshallData( a, mArgc, mArgv );
  2030. EngineMarshallData( b, mArgc, mArgv );
  2031. EngineMarshallData( c, mArgc, mArgv );
  2032. EngineMarshallData( d, mArgc, mArgv );
  2033. EngineMarshallData( e, mArgc, mArgv );
  2034. EngineMarshallData( f, mArgc, mArgv );
  2035. EngineMarshallData( g, mArgc, mArgv );
  2036. return R( EngineUnmarshallData< R >()( _exec() ) );
  2037. }
  2038. else
  2039. {
  2040. SimConsoleThreadExecCallback cb;
  2041. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, false, &cb);
  2042. evt->populateArgs(mArgv);
  2043. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2044. EngineMarshallData( a, mArgc, mArgv );
  2045. EngineMarshallData( b, mArgc, mArgv );
  2046. EngineMarshallData( c, mArgc, mArgv );
  2047. EngineMarshallData( d, mArgc, mArgv );
  2048. EngineMarshallData( e, mArgc, mArgv );
  2049. EngineMarshallData( f, mArgc, mArgv );
  2050. EngineMarshallData( g, mArgc, mArgv );
  2051. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2052. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2053. }
  2054. }
  2055. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
  2056. R call( A a, B b, C c, D d, E e, F f, G g, H h )
  2057. {
  2058. if (Con::isMainThread())
  2059. {
  2060. ConsoleStackFrameSaver sav; sav.save();
  2061. CSTK.reserveValues(mArgc+8, mArgv);
  2062. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2063. EngineMarshallData( a, mArgc, mArgv );
  2064. EngineMarshallData( b, mArgc, mArgv );
  2065. EngineMarshallData( c, mArgc, mArgv );
  2066. EngineMarshallData( d, mArgc, mArgv );
  2067. EngineMarshallData( e, mArgc, mArgv );
  2068. EngineMarshallData( f, mArgc, mArgv );
  2069. EngineMarshallData( g, mArgc, mArgv );
  2070. EngineMarshallData( h, mArgc, mArgv );
  2071. return R( EngineUnmarshallData< R >()( _exec() ) );
  2072. }
  2073. else
  2074. {
  2075. SimConsoleThreadExecCallback cb;
  2076. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, false, &cb);
  2077. evt->populateArgs(mArgv);
  2078. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2079. EngineMarshallData( a, mArgc, mArgv );
  2080. EngineMarshallData( b, mArgc, mArgv );
  2081. EngineMarshallData( c, mArgc, mArgv );
  2082. EngineMarshallData( d, mArgc, mArgv );
  2083. EngineMarshallData( e, mArgc, mArgv );
  2084. EngineMarshallData( f, mArgc, mArgv );
  2085. EngineMarshallData( g, mArgc, mArgv );
  2086. EngineMarshallData( h, mArgc, mArgv );
  2087. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2088. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2089. }
  2090. }
  2091. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
  2092. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
  2093. {
  2094. if (Con::isMainThread())
  2095. {
  2096. ConsoleStackFrameSaver sav; sav.save();
  2097. CSTK.reserveValues(mArgc+9, mArgv);
  2098. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2099. EngineMarshallData( a, mArgc, mArgv );
  2100. EngineMarshallData( b, mArgc, mArgv );
  2101. EngineMarshallData( c, mArgc, mArgv );
  2102. EngineMarshallData( d, mArgc, mArgv );
  2103. EngineMarshallData( e, mArgc, mArgv );
  2104. EngineMarshallData( f, mArgc, mArgv );
  2105. EngineMarshallData( g, mArgc, mArgv );
  2106. EngineMarshallData( h, mArgc, mArgv );
  2107. EngineMarshallData( i, mArgc, mArgv );
  2108. return R( EngineUnmarshallData< R >()( _exec() ) );
  2109. }
  2110. else
  2111. {
  2112. SimConsoleThreadExecCallback cb;
  2113. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, false, &cb);
  2114. evt->populateArgs(mArgv);
  2115. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2116. EngineMarshallData( a, mArgc, mArgv );
  2117. EngineMarshallData( b, mArgc, mArgv );
  2118. EngineMarshallData( c, mArgc, mArgv );
  2119. EngineMarshallData( d, mArgc, mArgv );
  2120. EngineMarshallData( e, mArgc, mArgv );
  2121. EngineMarshallData( f, mArgc, mArgv );
  2122. EngineMarshallData( g, mArgc, mArgv );
  2123. EngineMarshallData( h, mArgc, mArgv );
  2124. EngineMarshallData( i, mArgc, mArgv );
  2125. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2126. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2127. }
  2128. }
  2129. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
  2130. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
  2131. {
  2132. if (Con::isMainThread())
  2133. {
  2134. ConsoleStackFrameSaver sav; sav.save();
  2135. CSTK.reserveValues(mArgc+10, mArgv);
  2136. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2137. EngineMarshallData( a, mArgc, mArgv );
  2138. EngineMarshallData( b, mArgc, mArgv );
  2139. EngineMarshallData( c, mArgc, mArgv );
  2140. EngineMarshallData( d, mArgc, mArgv );
  2141. EngineMarshallData( e, mArgc, mArgv );
  2142. EngineMarshallData( f, mArgc, mArgv );
  2143. EngineMarshallData( g, mArgc, mArgv );
  2144. EngineMarshallData( h, mArgc, mArgv );
  2145. EngineMarshallData( i, mArgc, mArgv );
  2146. EngineMarshallData( j, mArgc, mArgv );
  2147. return R( EngineUnmarshallData< R >()( _exec() ) );
  2148. }
  2149. else
  2150. {
  2151. SimConsoleThreadExecCallback cb;
  2152. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, false, &cb);
  2153. evt->populateArgs(mArgv);
  2154. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2155. EngineMarshallData( a, mArgc, mArgv );
  2156. EngineMarshallData( b, mArgc, mArgv );
  2157. EngineMarshallData( c, mArgc, mArgv );
  2158. EngineMarshallData( d, mArgc, mArgv );
  2159. EngineMarshallData( e, mArgc, mArgv );
  2160. EngineMarshallData( f, mArgc, mArgv );
  2161. EngineMarshallData( g, mArgc, mArgv );
  2162. EngineMarshallData( h, mArgc, mArgv );
  2163. EngineMarshallData( i, mArgc, mArgv );
  2164. EngineMarshallData( j, mArgc, mArgv );
  2165. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2166. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2167. }
  2168. }
  2169. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
  2170. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
  2171. {
  2172. if (Con::isMainThread())
  2173. {
  2174. ConsoleStackFrameSaver sav; sav.save();
  2175. CSTK.reserveValues(mArgc+11, mArgv);
  2176. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2177. EngineMarshallData( a, mArgc, mArgv );
  2178. EngineMarshallData( b, mArgc, mArgv );
  2179. EngineMarshallData( c, mArgc, mArgv );
  2180. EngineMarshallData( d, mArgc, mArgv );
  2181. EngineMarshallData( e, mArgc, mArgv );
  2182. EngineMarshallData( f, mArgc, mArgv );
  2183. EngineMarshallData( g, mArgc, mArgv );
  2184. EngineMarshallData( h, mArgc, mArgv );
  2185. EngineMarshallData( i, mArgc, mArgv );
  2186. EngineMarshallData( j, mArgc, mArgv );
  2187. EngineMarshallData( k, mArgc, mArgv );
  2188. return R( EngineUnmarshallData< R >()( _exec() ) );
  2189. }
  2190. else
  2191. {
  2192. SimConsoleThreadExecCallback cb;
  2193. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, false, &cb);
  2194. evt->populateArgs(mArgv);
  2195. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2196. EngineMarshallData( a, mArgc, mArgv );
  2197. EngineMarshallData( b, mArgc, mArgv );
  2198. EngineMarshallData( c, mArgc, mArgv );
  2199. EngineMarshallData( d, mArgc, mArgv );
  2200. EngineMarshallData( e, mArgc, mArgv );
  2201. EngineMarshallData( f, mArgc, mArgv );
  2202. EngineMarshallData( g, mArgc, mArgv );
  2203. EngineMarshallData( h, mArgc, mArgv );
  2204. EngineMarshallData( i, mArgc, mArgv );
  2205. EngineMarshallData( j, mArgc, mArgv );
  2206. EngineMarshallData( k, mArgc, mArgv );
  2207. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2208. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2209. }
  2210. }
  2211. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L >
  2212. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l )
  2213. {
  2214. if (Con::isMainThread())
  2215. {
  2216. ConsoleStackFrameSaver sav; sav.save();
  2217. CSTK.reserveValues(mArgc+12, mArgv);
  2218. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2219. EngineMarshallData( a, mArgc, mArgv );
  2220. EngineMarshallData( b, mArgc, mArgv );
  2221. EngineMarshallData( c, mArgc, mArgv );
  2222. EngineMarshallData( d, mArgc, mArgv );
  2223. EngineMarshallData( e, mArgc, mArgv );
  2224. EngineMarshallData( f, mArgc, mArgv );
  2225. EngineMarshallData( g, mArgc, mArgv );
  2226. EngineMarshallData( h, mArgc, mArgv );
  2227. EngineMarshallData( i, mArgc, mArgv );
  2228. EngineMarshallData( j, mArgc, mArgv );
  2229. EngineMarshallData( k, mArgc, mArgv );
  2230. EngineMarshallData( l, mArgc, mArgv );
  2231. return R( EngineUnmarshallData< R >()( _exec() ) );
  2232. }
  2233. else
  2234. {
  2235. SimConsoleThreadExecCallback cb;
  2236. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+12, NULL, false, &cb);
  2237. evt->populateArgs(mArgv);
  2238. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2239. EngineMarshallData( a, mArgc, mArgv );
  2240. EngineMarshallData( b, mArgc, mArgv );
  2241. EngineMarshallData( c, mArgc, mArgv );
  2242. EngineMarshallData( d, mArgc, mArgv );
  2243. EngineMarshallData( e, mArgc, mArgv );
  2244. EngineMarshallData( f, mArgc, mArgv );
  2245. EngineMarshallData( g, mArgc, mArgv );
  2246. EngineMarshallData( h, mArgc, mArgv );
  2247. EngineMarshallData( i, mArgc, mArgv );
  2248. EngineMarshallData( j, mArgc, mArgv );
  2249. EngineMarshallData( k, mArgc, mArgv );
  2250. EngineMarshallData( l, mArgc, mArgv );
  2251. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2252. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2253. }
  2254. }
  2255. };
  2256. // Re-enable some VC warnings we disabled for this file.
  2257. #pragma warning( pop ) // 4510 and 4610
  2258. #endif // !_ENGINEAPI_H_