engineAPI.h 130 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722
  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. return (startArgc + index) < argc
  467. ? EngineUnmarshallData< IthArgType<index> >()( argv[ startArgc + index ] )
  468. : std::get<index + method_offset>(defaultArgs.mArgs);
  469. }
  470. template<size_t ...I>
  471. static R dispatchHelper(S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs, Seq<I...>){
  472. return fn(SelfType::getRealArgValue<I>(argc, argv, defaultArgs) ...);
  473. }
  474. template<typename Frame, size_t ...I>
  475. static R dispatchHelper(S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs, Seq<I...>){
  476. return (frame->*fn)(SelfType::getRealArgValue<I,1>(argc, argv, defaultArgs) ...);
  477. }
  478. using SeqType = typename Gens<sizeof...(ArgTs)>::type;
  479. };
  480. }
  481. }
  482. template< S32 startArgc, typename T >
  483. struct _EngineConsoleThunk {};
  484. template< S32 startArgc, typename R, typename ...ArgTs >
  485. struct _EngineConsoleThunk< startArgc, R(ArgTs...) >
  486. {
  487. private:
  488. using Helper = engineAPI::detail::ThunkHelpers<startArgc, R, ArgTs...>;
  489. using SeqType = typename Helper::SeqType;
  490. public:
  491. typedef typename Helper::FunctionType FunctionType;
  492. typedef typename Helper::ReturnType ReturnType;
  493. template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>;
  494. static constexpr S32 NUM_ARGS = Helper::NUM_ARGS;
  495. static ReturnType thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs)
  496. {
  497. return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType()));
  498. }
  499. template< typename Frame >
  500. static ReturnType thunk( S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs)
  501. {
  502. return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType()));
  503. }
  504. };
  505. // Have to do a partial specialization for void-returning functions :(
  506. template<S32 startArgc, typename ...ArgTs>
  507. struct _EngineConsoleThunk<startArgc, void(ArgTs...)> {
  508. private:
  509. using Helper = engineAPI::detail::ThunkHelpers<startArgc, void, ArgTs...>;
  510. using SeqType = typename Helper::SeqType;
  511. public:
  512. typedef typename Helper::FunctionType FunctionType;
  513. typedef typename Helper::ReturnType ReturnType;
  514. template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>;
  515. static constexpr S32 NUM_ARGS = Helper::NUM_ARGS;
  516. static void thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs)
  517. {
  518. Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType());
  519. }
  520. template< typename Frame >
  521. static void thunk( S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs)
  522. {
  523. Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType());
  524. }
  525. };
  526. /// @}
  527. /// @name API Definition Macros
  528. ///
  529. /// The macros in this group allow to create engine API functions that work both with the
  530. /// legacy console system as well as with the new engine export system. As such, they only
  531. /// support those function features that are available in both systems. This means that for
  532. /// console-style variadic functions, the ConsoleXXX must be used and that for overloaded
  533. /// and/or C-style variadic functions as well as for placing functions in export scopes,
  534. /// DEFINE_CALLIN must be used directly.
  535. ///
  536. /// When the console system is removed, the console thunking functionality will be removed
  537. /// from these macros but otherwise they will remain unchanged and in place.
  538. ///
  539. /// @{
  540. // Helpers to implement initialization checks. Pulled out into separate macros so this can be deactivated easily.
  541. // Especially important for the initialize() function itself.
  542. #define _CHECK_ENGINE_INITIALIZED_IMPL( fnName, returnType ) \
  543. if( !engineAPI::gIsInitialized ) \
  544. { \
  545. Con::errorf( "EngineAPI: Engine not initialized when calling " #fnName ); \
  546. return EngineTypeTraits< returnType >::ReturnValue( EngineTypeTraits< returnType >::ReturnValueType() ); \
  547. }
  548. #define _CHECK_ENGINE_INITIALIZED( fnName, returnType ) _CHECK_ENGINE_INITIALIZED_IMPL( fnName, returnType )
  549. /// Define a call-in point for calling into the engine.
  550. ///
  551. /// @param name The name of the function as it should be seen by the control layer.
  552. /// @param returnType The value type returned to the control layer.
  553. /// @param args The argument list as it would appear on the function definition
  554. /// @param defaultArgs The list of default argument values.
  555. /// @param usage The usage doc string for the engine API reference.
  556. ///
  557. /// @code
  558. /// DefineEngineFunction( myFunction, int, ( float f, const String& s ), ( "value for s" ), "This is my function." )
  559. /// {
  560. /// return int( f ) + dAtoi( s );
  561. /// }
  562. /// @endcode
  563. #define DefineEngineFunction( name, returnType, args, defaultArgs, usage ) \
  564. static inline returnType _fn ## name ## impl args; \
  565. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \
  566. ( _EngineFunctionTrampoline< returnType args >::Args a ) \
  567. { \
  568. _CHECK_ENGINE_INITIALIZED( name, returnType ); \
  569. return EngineTypeTraits< returnType >::ReturnValue( \
  570. _EngineFunctionTrampoline< returnType args >::jmp( _fn ## name ## impl, a ) \
  571. ); \
  572. } \
  573. static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs; \
  574. static EngineFunctionInfo _fn ## name ## FunctionInfo( \
  575. #name, \
  576. &_SCOPE<>()(), \
  577. usage, \
  578. #returnType " " #name #args, \
  579. "fn" #name, \
  580. TYPE< returnType args >(), \
  581. &_fn ## name ## DefaultArgs, \
  582. ( void* ) &fn ## name, \
  583. 0 \
  584. ); \
  585. static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv ) \
  586. { \
  587. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
  588. argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \
  589. ) ); \
  590. } \
  591. static ConsoleFunctionHeader _ ## name ## header \
  592. ( #returnType, #args, #defaultArgs ); \
  593. static ConsoleConstructor \
  594. _ ## name ## obj( NULL, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## name ## caster ), usage, \
  595. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  596. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS, \
  597. false, &_ ## name ## header \
  598. ); \
  599. static inline returnType _fn ## name ## impl args
  600. // The next thing is a bit tricky. DefineEngineMethod allows to make the 'object' (=this) argument to the function
  601. // implicit which presents quite an obstacle for the macro internals as the engine export system requires the
  602. // name of a DLL symbol that represents an extern "C" function with an explicit first object pointer argument.
  603. //
  604. // Even if we ignored the fact that we don't have a guarantee how the various C++ compilers implement implicit 'this' arguments,
  605. // 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
  606. // get to the function symbol name (let alone the fact that typing this method correctly would be tricky).
  607. //
  608. // So, the trick employed here is to package all but the implicit 'this' argument in a structure and then define an
  609. // extern "C" function that takes the object pointer as a first argument and the struct type as the second argument.
  610. // This will result in a function with an identical stack call frame layout to the function we want.
  611. //
  612. // Unfortunately, that still requires that function to chain on to the real user-defined function. To do this
  613. // cleanly and portably, _EngineMethodTrampoline is used to unpack and jump the call from extern "C" into C++ space.
  614. // In optimized builds, the compiler should be smart enough to pretty much optimize all our trickery here away.
  615. #define _DefineMethodTrampoline( className, name, returnType, args ) \
  616. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType \
  617. fn ## className ## _ ## name ( className* object, _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::Args a ) \
  618. { \
  619. _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
  620. return EngineTypeTraits< returnType >::ReturnValue( \
  621. _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::jmp( object, a ) \
  622. ); \
  623. }
  624. /// Define a call-in point for calling a method on an engine object.
  625. ///
  626. /// @param name The name of the C++ class.
  627. /// @param name The name of the method as it should be seen by the control layer.
  628. /// @param returnType The value type returned to the control layer.
  629. /// @param args The argument list as it would appear on the function definition
  630. /// @param defaultArgs The list of default argument values.
  631. /// @param usage The usage doc string for the engine API reference.
  632. ///
  633. /// @code
  634. /// DefineEngineMethod( MyClass, myMethod, int, ( float f, const String& s ), ( "value for s" ), "This is my method." )
  635. /// {
  636. /// return object->someMethod( f, s );
  637. /// }
  638. /// @endcode
  639. #define DefineEngineMethod( className, name, returnType, args, defaultArgs, usage ) \
  640. struct _ ## className ## name ## frame \
  641. { \
  642. typedef className ObjectType; \
  643. className* object; \
  644. inline returnType _exec args const; \
  645. }; \
  646. _DefineMethodTrampoline( className, name, returnType, args ); \
  647. static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType > \
  648. _fn ## className ## name ## DefaultArgs defaultArgs; \
  649. static EngineFunctionInfo _fn ## className ## name ## FunctionInfo( \
  650. #name, \
  651. &_SCOPE< className >()(), \
  652. usage, \
  653. "virtual " #returnType " " #name #args, \
  654. "fn" #className "_" #name, \
  655. TYPE< _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::FunctionType >(), \
  656. &_fn ## className ## name ## DefaultArgs, \
  657. ( void* ) &fn ## className ## _ ## name, \
  658. 0 \
  659. ); \
  660. static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv ) \
  661. { \
  662. _ ## className ## name ## frame frame; \
  663. frame.object = static_cast< className* >( object ); \
  664. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 2, returnType args >::thunk( \
  665. argc, argv, &_ ## className ## name ## frame::_exec, &frame, _fn ## className ## name ## DefaultArgs \
  666. ) ); \
  667. } \
  668. static ConsoleFunctionHeader _ ## className ## name ## header \
  669. ( #returnType, #args, #defaultArgs ); \
  670. static ConsoleConstructor \
  671. className ## name ## obj( #className, #name, \
  672. _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
  673. _EngineConsoleThunk< 2, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  674. _EngineConsoleThunk< 2, returnType args >::NUM_ARGS, \
  675. false, &_ ## className ## name ## header \
  676. ); \
  677. returnType _ ## className ## name ## frame::_exec args const
  678. /// Define a call-in point for calling into the engine. Unlike with DefineEngineFunction, the statically
  679. /// callable function will be confined to the namespace of the given class.
  680. ///
  681. /// @param name The name of the C++ class (or a registered export scope).
  682. /// @param name The name of the method as it should be seen by the control layer.
  683. /// @param returnType The value type returned to the control layer.
  684. /// @param args The argument list as it would appear on the function definition
  685. /// @param defaultArgs The list of default argument values.
  686. /// @param usage The usage doc string for the engine API reference.
  687. ///
  688. /// @code
  689. /// DefineEngineStaticMethod( MyClass, myMethod, int, ( float f, string s ), ( "value for s" ), "This is my method." )
  690. /// {
  691. /// }
  692. /// @endcode
  693. #define DefineEngineStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
  694. static inline returnType _fn ## className ## name ## impl args; \
  695. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \
  696. ( _EngineFunctionTrampoline< returnType args >::Args a ) \
  697. { \
  698. _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
  699. return EngineTypeTraits< returnType >::ReturnValue( \
  700. _EngineFunctionTrampoline< returnType args >::jmp( _fn ## className ## name ## impl, a ) \
  701. ); \
  702. } \
  703. static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs; \
  704. static EngineFunctionInfo _fn ## name ## FunctionInfo( \
  705. #name, \
  706. &_SCOPE< className >()(), \
  707. usage, \
  708. #returnType " " #name #args, \
  709. "fn" #className "_" #name, \
  710. TYPE< returnType args >(), \
  711. &_fn ## className ## name ## DefaultArgs, \
  712. ( void* ) &fn ## className ## _ ## name, \
  713. 0 \
  714. ); \
  715. static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
  716. { \
  717. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
  718. argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \
  719. ) ); \
  720. } \
  721. static ConsoleFunctionHeader _ ## className ## name ## header \
  722. ( #returnType, #args, #defaultArgs, true ); \
  723. static ConsoleConstructor \
  724. _ ## className ## name ## obj( #className, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
  725. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  726. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS, \
  727. false, &_ ## className ## name ## header \
  728. ); \
  729. static inline returnType _fn ## className ## name ## impl args
  730. // Convenience macros to allow defining functions that use the new marshalling features
  731. // while being only visible in the console interop. When we drop the console system,
  732. // these macros can be removed and all definitions that make use of them can be removed
  733. // as well.
  734. #define DefineConsoleFunction( name, returnType, args, defaultArgs, usage ) \
  735. static inline returnType _fn ## name ## impl args; \
  736. static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs; \
  737. static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv ) \
  738. { \
  739. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
  740. argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \
  741. ) ); \
  742. } \
  743. static ConsoleFunctionHeader _ ## name ## header \
  744. ( #returnType, #args, #defaultArgs ); \
  745. static ConsoleConstructor \
  746. _ ## name ## obj( NULL, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## name ## caster ), usage, \
  747. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  748. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS, \
  749. false, &_ ## name ## header \
  750. ); \
  751. static inline returnType _fn ## name ## impl args
  752. #define DefineConsoleMethod( className, name, returnType, args, defaultArgs, usage ) \
  753. struct _ ## className ## name ## frame \
  754. { \
  755. typedef className ObjectType; \
  756. className* object; \
  757. inline returnType _exec args const; \
  758. }; \
  759. static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType > \
  760. _fn ## className ## name ## DefaultArgs defaultArgs; \
  761. static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv ) \
  762. { \
  763. _ ## className ## name ## frame frame; \
  764. frame.object = static_cast< className* >( object ); \
  765. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 2, returnType args >::thunk( \
  766. argc, argv, &_ ## className ## name ## frame::_exec, &frame, _fn ## className ## name ## DefaultArgs \
  767. ) ); \
  768. } \
  769. static ConsoleFunctionHeader _ ## className ## name ## header \
  770. ( #returnType, #args, #defaultArgs ); \
  771. static ConsoleConstructor \
  772. className ## name ## obj( #className, #name, \
  773. _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
  774. _EngineConsoleThunk< 2, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  775. _EngineConsoleThunk< 2, returnType args >::NUM_ARGS, \
  776. false, &_ ## className ## name ## header \
  777. ); \
  778. returnType _ ## className ## name ## frame::_exec args const
  779. #define DefineConsoleStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
  780. static inline returnType _fn ## className ## name ## impl args; \
  781. static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs; \
  782. static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
  783. { \
  784. return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
  785. argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \
  786. ) ); \
  787. } \
  788. static ConsoleFunctionHeader _ ## className ## name ## header \
  789. ( #returnType, #args, #defaultArgs, true ); \
  790. static ConsoleConstructor \
  791. _ ## className ## name ## obj( #className, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
  792. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs, \
  793. _EngineConsoleThunk< 1, returnType args >::NUM_ARGS, \
  794. false, &_ ## className ## name ## header \
  795. ); \
  796. static inline returnType _fn ## className ## name ## impl args
  797. // The following three macros are only temporary. They allow to define engineAPI functions using the framework
  798. // here in this file while being visible only in the new API. When the console interop is removed, these macros
  799. // can be removed and all their uses be replaced with their corresponding versions that now still include support
  800. // for the console (e.g. DefineNewEngineFunction should become DefineEngineFunction).
  801. #define DefineNewEngineFunction( name, returnType, args, defaultArgs, usage ) \
  802. static inline returnType _fn ## name ## impl args; \
  803. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \
  804. ( _EngineFunctionTrampoline< returnType args >::Args a ) \
  805. { \
  806. _CHECK_ENGINE_INITIALIZED( name, returnType ); \
  807. return EngineTypeTraits< returnType >::ReturnValue( \
  808. _EngineFunctionTrampoline< returnType args >::jmp( _fn ## name ## impl, a ) \
  809. ); \
  810. } \
  811. static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs; \
  812. static EngineFunctionInfo _fn ## name ## FunctionInfo( \
  813. #name, \
  814. &_SCOPE<>()(), \
  815. usage, \
  816. #returnType " " #name #args, \
  817. "fn" #name, \
  818. TYPE< returnType args >(), \
  819. &_fn ## name ## DefaultArgs, \
  820. ( void* ) &fn ## name, \
  821. 0 \
  822. ); \
  823. static inline returnType _fn ## name ## impl args
  824. #define DefineNewEngineMethod( className, name, returnType, args, defaultArgs, usage ) \
  825. struct _ ## className ## name ## frame \
  826. { \
  827. typedef className ObjectType; \
  828. className* object; \
  829. inline returnType _exec args const; \
  830. }; \
  831. _DefineMethodTrampoline( className, name, returnType, args ); \
  832. static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType > \
  833. _fn ## className ## name ## DefaultArgs defaultArgs; \
  834. static EngineFunctionInfo _fn ## className ## name ## FunctionInfo( \
  835. #name, \
  836. &_SCOPE< className >()(), \
  837. usage, \
  838. "virtual " #returnType " " #name #args, \
  839. "fn" #className "_" #name, \
  840. TYPE< _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::FunctionType >(), \
  841. &_fn ## className ## name ## DefaultArgs, \
  842. ( void* ) &fn ## className ## _ ## name, \
  843. 0 \
  844. ); \
  845. returnType _ ## className ## name ## frame::_exec args const
  846. #define DefineNewEngineStaticMethod( className, name, returnType, args, defaultArgs, usage ) \
  847. static inline returnType _fn ## className ## name ## impl args; \
  848. TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \
  849. ( _EngineFunctionTrampoline< returnType args >::Args a ) \
  850. { \
  851. _CHECK_ENGINE_INITIALIZED( className::name, returnType ); \
  852. return EngineTypeTraits< returnType >::ReturnValue( \
  853. _EngineFunctionTrampoline< returnType args >::jmp( _fn ## className ## name ## impl, a ) \
  854. ); \
  855. } \
  856. static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs; \
  857. static EngineFunctionInfo _fn ## name ## FunctionInfo( \
  858. #name, \
  859. &_SCOPE< className >()(), \
  860. usage, \
  861. #returnType " " #name #args, \
  862. "fn" #className "_" #name, \
  863. TYPE< returnType args >(), \
  864. &_fn ## className ## name ## DefaultArgs, \
  865. ( void* ) &fn ## className ## _ ## name, \
  866. 0 \
  867. ); \
  868. static inline returnType _fn ## className ## name ## impl args
  869. /// @}
  870. //=============================================================================
  871. // Callbacks.
  872. //=============================================================================
  873. /// Matching implement for DECLARE_CALLBACK.
  874. ///
  875. ///
  876. /// @warn With the new interop system, method-style callbacks <em>must not</em> be triggered on object
  877. /// that are being created! This is because the control layer will likely not yet have a fully valid wrapper
  878. /// object in place for the EngineObject under construction.
  879. #define IMPLEMENT_CALLBACK( class, name, returnType, args, argNames, usageString ) \
  880. struct _ ## class ## name ## frame { typedef class ObjectType; }; \
  881. TORQUE_API _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name; \
  882. TORQUE_API void set_cb ## class ## _ ## name( \
  883. _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType fn ) \
  884. { cb ## class ## _ ## name = fn; } \
  885. _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name; \
  886. namespace { \
  887. ::EngineFunctionInfo _cb ## class ## name( \
  888. #name, \
  889. &::_SCOPE< class >()(), \
  890. usageString, \
  891. "virtual " #returnType " " #name #args, \
  892. "cb" #class "_" #name, \
  893. ::TYPE< _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType >(), \
  894. NULL, \
  895. ( void* ) &cb ## class ## _ ## name, \
  896. EngineFunctionCallout \
  897. ); \
  898. } \
  899. returnType class::name ## _callback args \
  900. { \
  901. if( cb ## class ## _ ## name ) { \
  902. _EngineCallbackHelper cbh( this, reinterpret_cast< const void* >( cb ## class ## _ ## name ) ); \
  903. return returnType( cbh.call< returnType > argNames ); \
  904. } \
  905. if( engineAPI::gUseConsoleInterop ) \
  906. { \
  907. static StringTableEntry sName = StringTable->insert( #name ); \
  908. _EngineConsoleCallbackHelper cbh( sName, this ); \
  909. return returnType( cbh.call< returnType > argNames ); \
  910. } \
  911. return returnType(); \
  912. } \
  913. namespace { \
  914. ConsoleFunctionHeader _ ## class ## name ## header( \
  915. #returnType, #args, "" ); \
  916. ConsoleConstructor _ ## class ## name ## obj( #class, #name, usageString, &_ ## class ## name ## header ); \
  917. }
  918. /// Used to define global callbacks not associated with
  919. /// any particular class or namespace.
  920. #define IMPLEMENT_GLOBAL_CALLBACK( name, returnType, args, argNames, usageString ) \
  921. DEFINE_CALLOUT( cb ## name, name,, returnType, args, 0, usageString ); \
  922. returnType name ## _callback args \
  923. { \
  924. if( cb ## name ) \
  925. return returnType( cb ## name argNames ); \
  926. if( engineAPI::gUseConsoleInterop ) \
  927. { \
  928. static StringTableEntry sName = StringTable->insert( #name ); \
  929. _EngineConsoleCallbackHelper cbh( sName, NULL ); \
  930. return returnType( cbh.call< returnType > argNames ); \
  931. } \
  932. return returnType(); \
  933. } \
  934. namespace { \
  935. ConsoleFunctionHeader _ ## name ## header( \
  936. #returnType, #args, "" ); \
  937. ConsoleConstructor _ ## name ## obj( NULL, #name, usageString, &_ ## name ## header ); \
  938. }
  939. // Again, temporary macros to allow splicing the API while we still have the console interop around.
  940. #define IMPLEMENT_CONSOLE_CALLBACK( class, name, returnType, args, argNames, usageString ) \
  941. returnType class::name ## _callback args \
  942. { \
  943. if( engineAPI::gUseConsoleInterop ) \
  944. { \
  945. static StringTableEntry sName = StringTable->insert( #name ); \
  946. _EngineConsoleCallbackHelper cbh( sName, this ); \
  947. return returnType( cbh.call< returnType > argNames ); \
  948. } \
  949. return returnType(); \
  950. } \
  951. namespace { \
  952. ConsoleFunctionHeader _ ## class ## name ## header( \
  953. #returnType, #args, "" ); \
  954. ConsoleConstructor _ ## class ## name ## obj( #class, #name, usageString, &_ ## class ## name ## header ); \
  955. }
  956. #define IMPLEMENT_NEW_CALLBACK( class, name, returnType, args, argNames, usageString ) \
  957. struct _ ## class ## name ## frame { typedef class ObjectType; }; \
  958. TORQUE_API _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name; \
  959. TORQUE_API void set_cb ## class ## _ ## name( \
  960. _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType fn ) \
  961. { cb ## class ## _ ## name = fn; } \
  962. _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name; \
  963. namespace { \
  964. ::EngineFunctionInfo _cb ## class ## name( \
  965. #name, \
  966. &::_SCOPE< class >()(), \
  967. usageString, \
  968. "virtual " #returnType " " #name #args, \
  969. "cb" #class "_" #name, \
  970. ::TYPE< _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType >(), \
  971. NULL, \
  972. &cb ## class ## _ ## name, \
  973. EngineFunctionCallout \
  974. ); \
  975. } \
  976. returnType class::name ## _callback args \
  977. { \
  978. if( cb ## class ## _ ## name ) { \
  979. _EngineCallbackHelper cbh( this, reinterpret_cast< const void* >( cb ## class ## _ ## name ) ); \
  980. return returnType( cbh.call< returnType > argNames ); \
  981. } \
  982. return returnType(); \
  983. }
  984. // Internal helper class for doing call-outs in the new interop.
  985. struct _EngineCallbackHelper
  986. {
  987. protected:
  988. EngineObject* mThis;
  989. const void* mFn;
  990. public:
  991. _EngineCallbackHelper( EngineObject* pThis, const void* fn )
  992. : mThis( pThis ),
  993. mFn( fn ) {}
  994. template< typename R >
  995. R call() const
  996. {
  997. typedef R( FunctionType )( EngineObject* );
  998. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis ) );
  999. }
  1000. template< typename R, typename A >
  1001. R call( A a ) const
  1002. {
  1003. typedef R( FunctionType )( EngineObject*, A );
  1004. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a ) );
  1005. }
  1006. template< typename R, typename A, typename B >
  1007. R call( A a, B b ) const
  1008. {
  1009. typedef R( FunctionType )( EngineObject*, A, B );
  1010. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b ) );
  1011. }
  1012. template< typename R, typename A, typename B, typename C >
  1013. R call( A a, B b, C c ) const
  1014. {
  1015. typedef R( FunctionType )( EngineObject*, A, B, C );
  1016. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c ) );
  1017. }
  1018. template< typename R, typename A, typename B, typename C, typename D >
  1019. R call( A a, B b, C c, D d ) const
  1020. {
  1021. typedef R( FunctionType )( EngineObject*, A, B, C, D );
  1022. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d ) );
  1023. }
  1024. template< typename R, typename A, typename B, typename C, typename D, typename E >
  1025. R call( A a, B b, C c, D d, E e ) const
  1026. {
  1027. typedef R( FunctionType )( EngineObject*, A, B, C, D, E );
  1028. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e ) );
  1029. }
  1030. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
  1031. R call( A a, B b, C c, D d, E e, F f ) const
  1032. {
  1033. typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F );
  1034. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f ) );
  1035. }
  1036. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
  1037. R call( A a, B b, C c, D d, E e, F f, G g ) const
  1038. {
  1039. typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G );
  1040. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g ) );
  1041. }
  1042. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
  1043. R call( A a, B b, C c, D d, E e, F f, G g, H h ) const
  1044. {
  1045. typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H );
  1046. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h ) );
  1047. }
  1048. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
  1049. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i ) const
  1050. {
  1051. typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I );
  1052. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h, i ) );
  1053. }
  1054. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
  1055. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) const
  1056. {
  1057. typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J );
  1058. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j ) );
  1059. }
  1060. 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 >
  1061. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) const
  1062. {
  1063. typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J, K );
  1064. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j, k ) );
  1065. }
  1066. 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 >
  1067. 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 ) const
  1068. {
  1069. typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J, K, L );
  1070. return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j, k, l ) );
  1071. }
  1072. };
  1073. #include "console/stringStack.h"
  1074. // Internal helper for callback support in legacy console system.
  1075. struct _BaseEngineConsoleCallbackHelper
  1076. {
  1077. public:
  1078. /// Matches up to storeArgs.
  1079. static const U32 MAX_ARGUMENTS = 11;
  1080. SimObject* mThis;
  1081. S32 mInitialArgc;
  1082. S32 mArgc;
  1083. StringTableEntry mCallbackName;
  1084. ConsoleValueRef mArgv[ MAX_ARGUMENTS + 2 ];
  1085. ConsoleValueRef _exec();
  1086. ConsoleValueRef _execLater(SimConsoleThreadExecEvent *evt);
  1087. _BaseEngineConsoleCallbackHelper() {;}
  1088. };
  1089. // Base helper for console callbacks
  1090. struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper
  1091. {
  1092. public:
  1093. _EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis )
  1094. {
  1095. mThis = pThis;
  1096. mArgc = mInitialArgc = pThis ? 2 : 1 ;
  1097. mCallbackName = callbackName;
  1098. }
  1099. template< typename R >
  1100. R call()
  1101. {
  1102. if (Con::isMainThread())
  1103. {
  1104. ConsoleStackFrameSaver sav; sav.save();
  1105. CSTK.reserveValues(mArgc, mArgv);
  1106. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1107. return R( EngineUnmarshallData< R >()( _exec() ) );
  1108. }
  1109. else
  1110. {
  1111. SimConsoleThreadExecCallback cb;
  1112. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc, NULL, false, &cb);
  1113. evt->populateArgs(mArgv);
  1114. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1115. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1116. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1117. }
  1118. }
  1119. template< typename R, typename A >
  1120. R call( A a )
  1121. {
  1122. if (Con::isMainThread())
  1123. {
  1124. ConsoleStackFrameSaver sav; sav.save();
  1125. CSTK.reserveValues(mArgc+1, mArgv);
  1126. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1127. EngineMarshallData( a, mArgc, mArgv );
  1128. return R( EngineUnmarshallData< R >()( _exec() ) );
  1129. }
  1130. else
  1131. {
  1132. SimConsoleThreadExecCallback cb;
  1133. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, false, &cb);
  1134. evt->populateArgs(mArgv);
  1135. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1136. EngineMarshallData( a, mArgc, mArgv );
  1137. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1138. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1139. }
  1140. }
  1141. template< typename R, typename A, typename B >
  1142. R call( A a, B b )
  1143. {
  1144. if (Con::isMainThread())
  1145. {
  1146. ConsoleStackFrameSaver sav; sav.save();
  1147. CSTK.reserveValues(mArgc+2, mArgv);
  1148. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1149. EngineMarshallData( a, mArgc, mArgv );
  1150. EngineMarshallData( b, mArgc, mArgv );
  1151. return R( EngineUnmarshallData< R >()( _exec() ) );
  1152. }
  1153. else
  1154. {
  1155. SimConsoleThreadExecCallback cb;
  1156. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, false, &cb);
  1157. evt->populateArgs(mArgv);
  1158. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1159. EngineMarshallData( a, mArgc, mArgv );
  1160. EngineMarshallData( b, mArgc, mArgv );
  1161. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1162. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1163. }
  1164. }
  1165. template< typename R, typename A, typename B, typename C >
  1166. R call( A a, B b, C c )
  1167. {
  1168. if (Con::isMainThread())
  1169. {
  1170. ConsoleStackFrameSaver sav; sav.save();
  1171. CSTK.reserveValues(mArgc+3, mArgv);
  1172. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1173. EngineMarshallData( a, mArgc, mArgv );
  1174. EngineMarshallData( b, mArgc, mArgv );
  1175. EngineMarshallData( c, mArgc, mArgv );
  1176. return R( EngineUnmarshallData< R >()( _exec() ) );
  1177. }
  1178. else
  1179. {
  1180. SimConsoleThreadExecCallback cb;
  1181. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, false, &cb);
  1182. evt->populateArgs(mArgv);
  1183. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1184. EngineMarshallData( a, mArgc, mArgv );
  1185. EngineMarshallData( b, mArgc, mArgv );
  1186. EngineMarshallData( c, mArgc, mArgv );
  1187. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1188. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1189. }
  1190. }
  1191. template< typename R, typename A, typename B, typename C, typename D >
  1192. R call( A a, B b, C c, D d )
  1193. {
  1194. if (Con::isMainThread())
  1195. {
  1196. ConsoleStackFrameSaver sav; sav.save();
  1197. CSTK.reserveValues(mArgc+4, mArgv);
  1198. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1199. EngineMarshallData( a, mArgc, mArgv );
  1200. EngineMarshallData( b, mArgc, mArgv );
  1201. EngineMarshallData( c, mArgc, mArgv );
  1202. EngineMarshallData( d, mArgc, mArgv );
  1203. return R( EngineUnmarshallData< R >()( _exec() ) );
  1204. }
  1205. else
  1206. {
  1207. SimConsoleThreadExecCallback cb;
  1208. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, false, &cb);
  1209. evt->populateArgs(mArgv);
  1210. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1211. EngineMarshallData( a, mArgc, mArgv );
  1212. EngineMarshallData( b, mArgc, mArgv );
  1213. EngineMarshallData( c, mArgc, mArgv );
  1214. EngineMarshallData( d, mArgc, mArgv );
  1215. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1216. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1217. }
  1218. }
  1219. template< typename R, typename A, typename B, typename C, typename D, typename E >
  1220. R call( A a, B b, C c, D d, E e )
  1221. {
  1222. if (Con::isMainThread())
  1223. {
  1224. ConsoleStackFrameSaver sav; sav.save();
  1225. CSTK.reserveValues(mArgc+5, mArgv);
  1226. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1227. EngineMarshallData( a, mArgc, mArgv );
  1228. EngineMarshallData( b, mArgc, mArgv );
  1229. EngineMarshallData( c, mArgc, mArgv );
  1230. EngineMarshallData( d, mArgc, mArgv );
  1231. EngineMarshallData( e, mArgc, mArgv );
  1232. return R( EngineUnmarshallData< R >()( _exec() ) );
  1233. }
  1234. else
  1235. {
  1236. SimConsoleThreadExecCallback cb;
  1237. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, false, &cb);
  1238. evt->populateArgs(mArgv);
  1239. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1240. EngineMarshallData( a, mArgc, mArgv );
  1241. EngineMarshallData( b, mArgc, mArgv );
  1242. EngineMarshallData( c, mArgc, mArgv );
  1243. EngineMarshallData( d, mArgc, mArgv );
  1244. EngineMarshallData( e, mArgc, mArgv );
  1245. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1246. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1247. }
  1248. }
  1249. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
  1250. R call( A a, B b, C c, D d, E e, F f )
  1251. {
  1252. if (Con::isMainThread())
  1253. {
  1254. ConsoleStackFrameSaver sav; sav.save();
  1255. CSTK.reserveValues(mArgc+6, mArgv);
  1256. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1257. EngineMarshallData( a, mArgc, mArgv );
  1258. EngineMarshallData( b, mArgc, mArgv );
  1259. EngineMarshallData( c, mArgc, mArgv );
  1260. EngineMarshallData( d, mArgc, mArgv );
  1261. EngineMarshallData( e, mArgc, mArgv );
  1262. EngineMarshallData( f, mArgc, mArgv );
  1263. return R( EngineUnmarshallData< R >()( _exec() ) );
  1264. }
  1265. else
  1266. {
  1267. SimConsoleThreadExecCallback cb;
  1268. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, false, &cb);
  1269. evt->populateArgs(mArgv);
  1270. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1271. EngineMarshallData( a, mArgc, mArgv );
  1272. EngineMarshallData( b, mArgc, mArgv );
  1273. EngineMarshallData( c, mArgc, mArgv );
  1274. EngineMarshallData( d, mArgc, mArgv );
  1275. EngineMarshallData( e, mArgc, mArgv );
  1276. EngineMarshallData( f, mArgc, mArgv );
  1277. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1278. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1279. }
  1280. }
  1281. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
  1282. R call( A a, B b, C c, D d, E e, F f, G g )
  1283. {
  1284. if (Con::isMainThread())
  1285. {
  1286. ConsoleStackFrameSaver sav; sav.save();
  1287. CSTK.reserveValues(mArgc+7, mArgv);
  1288. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1289. EngineMarshallData( a, mArgc, mArgv );
  1290. EngineMarshallData( b, mArgc, mArgv );
  1291. EngineMarshallData( c, mArgc, mArgv );
  1292. EngineMarshallData( d, mArgc, mArgv );
  1293. EngineMarshallData( e, mArgc, mArgv );
  1294. EngineMarshallData( f, mArgc, mArgv );
  1295. EngineMarshallData( g, mArgc, mArgv );
  1296. return R( EngineUnmarshallData< R >()( _exec() ) );
  1297. }
  1298. else
  1299. {
  1300. SimConsoleThreadExecCallback cb;
  1301. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, false, &cb);
  1302. evt->populateArgs(mArgv);
  1303. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1304. EngineMarshallData( a, mArgc, mArgv );
  1305. EngineMarshallData( b, mArgc, mArgv );
  1306. EngineMarshallData( c, mArgc, mArgv );
  1307. EngineMarshallData( d, mArgc, mArgv );
  1308. EngineMarshallData( e, mArgc, mArgv );
  1309. EngineMarshallData( f, mArgc, mArgv );
  1310. EngineMarshallData( g, mArgc, mArgv );
  1311. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1312. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1313. }
  1314. }
  1315. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
  1316. R call( A a, B b, C c, D d, E e, F f, G g, H h )
  1317. {
  1318. if (Con::isMainThread())
  1319. {
  1320. ConsoleStackFrameSaver sav; sav.save();
  1321. CSTK.reserveValues(mArgc+8, mArgv);
  1322. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1323. EngineMarshallData( a, mArgc, mArgv );
  1324. EngineMarshallData( b, mArgc, mArgv );
  1325. EngineMarshallData( c, mArgc, mArgv );
  1326. EngineMarshallData( d, mArgc, mArgv );
  1327. EngineMarshallData( e, mArgc, mArgv );
  1328. EngineMarshallData( f, mArgc, mArgv );
  1329. EngineMarshallData( g, mArgc, mArgv );
  1330. EngineMarshallData( h, mArgc, mArgv );
  1331. return R( EngineUnmarshallData< R >()( _exec() ) );
  1332. }
  1333. else
  1334. {
  1335. SimConsoleThreadExecCallback cb;
  1336. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, false, &cb);
  1337. evt->populateArgs(mArgv);
  1338. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1339. EngineMarshallData( a, mArgc, mArgv );
  1340. EngineMarshallData( b, mArgc, mArgv );
  1341. EngineMarshallData( c, mArgc, mArgv );
  1342. EngineMarshallData( d, mArgc, mArgv );
  1343. EngineMarshallData( e, mArgc, mArgv );
  1344. EngineMarshallData( f, mArgc, mArgv );
  1345. EngineMarshallData( g, mArgc, mArgv );
  1346. EngineMarshallData( h, mArgc, mArgv );
  1347. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1348. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1349. }
  1350. }
  1351. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
  1352. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
  1353. {
  1354. if (Con::isMainThread())
  1355. {
  1356. ConsoleStackFrameSaver sav; sav.save();
  1357. CSTK.reserveValues(mArgc+9, mArgv);
  1358. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1359. EngineMarshallData( a, mArgc, mArgv );
  1360. EngineMarshallData( b, mArgc, mArgv );
  1361. EngineMarshallData( c, mArgc, mArgv );
  1362. EngineMarshallData( d, mArgc, mArgv );
  1363. EngineMarshallData( e, mArgc, mArgv );
  1364. EngineMarshallData( f, mArgc, mArgv );
  1365. EngineMarshallData( g, mArgc, mArgv );
  1366. EngineMarshallData( h, mArgc, mArgv );
  1367. EngineMarshallData( i, mArgc, mArgv );
  1368. return R( EngineUnmarshallData< R >()( _exec() ) );
  1369. }
  1370. else
  1371. {
  1372. SimConsoleThreadExecCallback cb;
  1373. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, false, &cb);
  1374. evt->populateArgs(mArgv);
  1375. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1376. EngineMarshallData( a, mArgc, mArgv );
  1377. EngineMarshallData( b, mArgc, mArgv );
  1378. EngineMarshallData( c, mArgc, mArgv );
  1379. EngineMarshallData( d, mArgc, mArgv );
  1380. EngineMarshallData( e, mArgc, mArgv );
  1381. EngineMarshallData( f, mArgc, mArgv );
  1382. EngineMarshallData( g, mArgc, mArgv );
  1383. EngineMarshallData( h, mArgc, mArgv );
  1384. EngineMarshallData( i, mArgc, mArgv );
  1385. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1386. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1387. }
  1388. }
  1389. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
  1390. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
  1391. {
  1392. if (Con::isMainThread())
  1393. {
  1394. ConsoleStackFrameSaver sav; sav.save();
  1395. CSTK.reserveValues(mArgc+10, mArgv);
  1396. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1397. EngineMarshallData( a, mArgc, mArgv );
  1398. EngineMarshallData( b, mArgc, mArgv );
  1399. EngineMarshallData( c, mArgc, mArgv );
  1400. EngineMarshallData( d, mArgc, mArgv );
  1401. EngineMarshallData( e, mArgc, mArgv );
  1402. EngineMarshallData( f, mArgc, mArgv );
  1403. EngineMarshallData( g, mArgc, mArgv );
  1404. EngineMarshallData( h, mArgc, mArgv );
  1405. EngineMarshallData( i, mArgc, mArgv );
  1406. EngineMarshallData( j, mArgc, mArgv );
  1407. return R( EngineUnmarshallData< R >()( _exec() ) );
  1408. }
  1409. else
  1410. {
  1411. SimConsoleThreadExecCallback cb;
  1412. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, false, &cb);
  1413. evt->populateArgs(mArgv);
  1414. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1415. EngineMarshallData( a, mArgc, mArgv );
  1416. EngineMarshallData( b, mArgc, mArgv );
  1417. EngineMarshallData( c, mArgc, mArgv );
  1418. EngineMarshallData( d, mArgc, mArgv );
  1419. EngineMarshallData( e, mArgc, mArgv );
  1420. EngineMarshallData( f, mArgc, mArgv );
  1421. EngineMarshallData( g, mArgc, mArgv );
  1422. EngineMarshallData( h, mArgc, mArgv );
  1423. EngineMarshallData( i, mArgc, mArgv );
  1424. EngineMarshallData( j, mArgc, mArgv );
  1425. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1426. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1427. }
  1428. }
  1429. 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 >
  1430. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
  1431. {
  1432. if (Con::isMainThread())
  1433. {
  1434. ConsoleStackFrameSaver sav; sav.save();
  1435. CSTK.reserveValues(mArgc+11, mArgv);
  1436. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1437. EngineMarshallData( a, mArgc, mArgv );
  1438. EngineMarshallData( b, mArgc, mArgv );
  1439. EngineMarshallData( c, mArgc, mArgv );
  1440. EngineMarshallData( d, mArgc, mArgv );
  1441. EngineMarshallData( e, mArgc, mArgv );
  1442. EngineMarshallData( f, mArgc, mArgv );
  1443. EngineMarshallData( g, mArgc, mArgv );
  1444. EngineMarshallData( h, mArgc, mArgv );
  1445. EngineMarshallData( i, mArgc, mArgv );
  1446. EngineMarshallData( j, mArgc, mArgv );
  1447. EngineMarshallData( k, mArgc, mArgv );
  1448. return R( EngineUnmarshallData< R >()( _exec() ) );
  1449. }
  1450. else
  1451. {
  1452. SimConsoleThreadExecCallback cb;
  1453. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, false, &cb);
  1454. evt->populateArgs(mArgv);
  1455. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1456. EngineMarshallData( a, mArgc, mArgv );
  1457. EngineMarshallData( b, mArgc, mArgv );
  1458. EngineMarshallData( c, mArgc, mArgv );
  1459. EngineMarshallData( d, mArgc, mArgv );
  1460. EngineMarshallData( e, mArgc, mArgv );
  1461. EngineMarshallData( f, mArgc, mArgv );
  1462. EngineMarshallData( g, mArgc, mArgv );
  1463. EngineMarshallData( h, mArgc, mArgv );
  1464. EngineMarshallData( i, mArgc, mArgv );
  1465. EngineMarshallData( j, mArgc, mArgv );
  1466. EngineMarshallData( k, mArgc, mArgv );
  1467. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1468. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1469. }
  1470. }
  1471. 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 >
  1472. 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 )
  1473. {
  1474. if (Con::isMainThread())
  1475. {
  1476. ConsoleStackFrameSaver sav; sav.save();
  1477. CSTK.reserveValues(mArgc+12, mArgv);
  1478. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1479. EngineMarshallData( a, mArgc, mArgv );
  1480. EngineMarshallData( b, mArgc, mArgv );
  1481. EngineMarshallData( c, mArgc, mArgv );
  1482. EngineMarshallData( d, mArgc, mArgv );
  1483. EngineMarshallData( e, mArgc, mArgv );
  1484. EngineMarshallData( f, mArgc, mArgv );
  1485. EngineMarshallData( g, mArgc, mArgv );
  1486. EngineMarshallData( h, mArgc, mArgv );
  1487. EngineMarshallData( i, mArgc, mArgv );
  1488. EngineMarshallData( j, mArgc, mArgv );
  1489. EngineMarshallData( k, mArgc, mArgv );
  1490. EngineMarshallData( l, mArgc, mArgv );
  1491. return R( EngineUnmarshallData< R >()( _exec() ) );
  1492. }
  1493. else
  1494. {
  1495. SimConsoleThreadExecCallback cb;
  1496. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+12, NULL, false, &cb);
  1497. evt->populateArgs(mArgv);
  1498. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1499. EngineMarshallData( a, mArgc, mArgv );
  1500. EngineMarshallData( b, mArgc, mArgv );
  1501. EngineMarshallData( c, mArgc, mArgv );
  1502. EngineMarshallData( d, mArgc, mArgv );
  1503. EngineMarshallData( e, mArgc, mArgv );
  1504. EngineMarshallData( f, mArgc, mArgv );
  1505. EngineMarshallData( g, mArgc, mArgv );
  1506. EngineMarshallData( h, mArgc, mArgv );
  1507. EngineMarshallData( i, mArgc, mArgv );
  1508. EngineMarshallData( j, mArgc, mArgv );
  1509. EngineMarshallData( k, mArgc, mArgv );
  1510. EngineMarshallData( l, mArgc, mArgv );
  1511. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1512. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1513. }
  1514. }
  1515. };
  1516. // Override for when first parameter is presumably a SimObject*, in which case A will be absorbed as the callback
  1517. template<typename P1> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper
  1518. {
  1519. public:
  1520. _EngineConsoleExecCallbackHelper( SimObject* pThis )
  1521. {
  1522. mThis = pThis;
  1523. mArgc = mInitialArgc = 2;
  1524. mCallbackName = NULL;
  1525. }
  1526. template< typename R, typename A >
  1527. R call( A a )
  1528. {
  1529. if (Con::isMainThread())
  1530. {
  1531. ConsoleStackFrameSaver sav; sav.save();
  1532. CSTK.reserveValues(mArgc+0, mArgv);
  1533. mArgv[ 0 ].value->setStackStringValue(a);
  1534. return R( EngineUnmarshallData< R >()( _exec() ) );
  1535. }
  1536. else
  1537. {
  1538. SimConsoleThreadExecCallback cb;
  1539. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+0, NULL, true, &cb);
  1540. evt->populateArgs(mArgv);
  1541. mArgv[ 0 ].value->setStackStringValue(a);
  1542. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1543. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1544. }
  1545. }
  1546. template< typename R, typename A, typename B >
  1547. R call( A a, B b )
  1548. {
  1549. if (Con::isMainThread())
  1550. {
  1551. ConsoleStackFrameSaver sav; sav.save();
  1552. CSTK.reserveValues(mArgc+1, mArgv);
  1553. mArgv[ 0 ].value->setStackStringValue(a);
  1554. EngineMarshallData( b, mArgc, mArgv );
  1555. return R( EngineUnmarshallData< R >()( _exec() ) );
  1556. }
  1557. else
  1558. {
  1559. SimConsoleThreadExecCallback cb;
  1560. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, true, &cb);
  1561. evt->populateArgs(mArgv);
  1562. mArgv[ 0 ].value->setStackStringValue(a);
  1563. EngineMarshallData( b, mArgc, mArgv );
  1564. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1565. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1566. }
  1567. }
  1568. template< typename R, typename A, typename B, typename C >
  1569. R call( A a, B b, C c )
  1570. {
  1571. if (Con::isMainThread())
  1572. {
  1573. ConsoleStackFrameSaver sav; sav.save();
  1574. CSTK.reserveValues(mArgc+2, mArgv);
  1575. mArgv[ 0 ].value->setStackStringValue(a);
  1576. EngineMarshallData( b, mArgc, mArgv );
  1577. EngineMarshallData( c, mArgc, mArgv );
  1578. return R( EngineUnmarshallData< R >()( _exec() ) );
  1579. }
  1580. else
  1581. {
  1582. SimConsoleThreadExecCallback cb;
  1583. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, true, &cb);
  1584. evt->populateArgs(mArgv);
  1585. mArgv[ 0 ].value->setStackStringValue(a);
  1586. EngineMarshallData( b, mArgc, mArgv );
  1587. EngineMarshallData( c, mArgc, mArgv );
  1588. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1589. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1590. }
  1591. }
  1592. template< typename R, typename A, typename B, typename C, typename D >
  1593. R call( A a, B b, C c, D d )
  1594. {
  1595. if (Con::isMainThread())
  1596. {
  1597. ConsoleStackFrameSaver sav; sav.save();
  1598. CSTK.reserveValues(mArgc+3, mArgv);
  1599. mArgv[ 0 ].value->setStackStringValue(a);
  1600. EngineMarshallData( b, mArgc, mArgv );
  1601. EngineMarshallData( c, mArgc, mArgv );
  1602. EngineMarshallData( d, mArgc, mArgv );
  1603. return R( EngineUnmarshallData< R >()( _exec() ) );
  1604. }
  1605. else
  1606. {
  1607. SimConsoleThreadExecCallback cb;
  1608. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, true, &cb);
  1609. evt->populateArgs(mArgv);
  1610. mArgv[ 0 ].value->setStackStringValue(a);
  1611. EngineMarshallData( b, mArgc, mArgv );
  1612. EngineMarshallData( c, mArgc, mArgv );
  1613. EngineMarshallData( d, mArgc, mArgv );
  1614. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1615. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1616. }
  1617. }
  1618. template< typename R, typename A, typename B, typename C, typename D, typename E >
  1619. R call( A a, B b, C c, D d, E e )
  1620. {
  1621. if (Con::isMainThread())
  1622. {
  1623. ConsoleStackFrameSaver sav; sav.save();
  1624. CSTK.reserveValues(mArgc+4, mArgv);
  1625. mArgv[ 0 ].value->setStackStringValue(a);
  1626. EngineMarshallData( b, mArgc, mArgv );
  1627. EngineMarshallData( c, mArgc, mArgv );
  1628. EngineMarshallData( d, mArgc, mArgv );
  1629. EngineMarshallData( e, mArgc, mArgv );
  1630. return R( EngineUnmarshallData< R >()( _exec() ) );
  1631. }
  1632. else
  1633. {
  1634. SimConsoleThreadExecCallback cb;
  1635. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, true, &cb);
  1636. evt->populateArgs(mArgv);
  1637. mArgv[ 0 ].value->setStackStringValue(a);
  1638. EngineMarshallData( b, mArgc, mArgv );
  1639. EngineMarshallData( c, mArgc, mArgv );
  1640. EngineMarshallData( d, mArgc, mArgv );
  1641. EngineMarshallData( e, mArgc, mArgv );
  1642. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1643. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1644. }
  1645. }
  1646. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
  1647. R call( A a, B b, C c, D d, E e, F f )
  1648. {
  1649. if (Con::isMainThread())
  1650. {
  1651. ConsoleStackFrameSaver sav; sav.save();
  1652. CSTK.reserveValues(mArgc+5, mArgv);
  1653. mArgv[ 0 ].value->setStackStringValue(a);
  1654. EngineMarshallData( b, mArgc, mArgv );
  1655. EngineMarshallData( c, mArgc, mArgv );
  1656. EngineMarshallData( d, mArgc, mArgv );
  1657. EngineMarshallData( e, mArgc, mArgv );
  1658. EngineMarshallData( f, mArgc, mArgv );
  1659. return R( EngineUnmarshallData< R >()( _exec() ) );
  1660. }
  1661. else
  1662. {
  1663. SimConsoleThreadExecCallback cb;
  1664. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, true, &cb);
  1665. evt->populateArgs(mArgv);
  1666. mArgv[ 0 ].value->setStackStringValue(a);
  1667. EngineMarshallData( b, mArgc, mArgv );
  1668. EngineMarshallData( c, mArgc, mArgv );
  1669. EngineMarshallData( d, mArgc, mArgv );
  1670. EngineMarshallData( e, mArgc, mArgv );
  1671. EngineMarshallData( f, mArgc, mArgv );
  1672. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1673. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1674. }
  1675. }
  1676. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
  1677. R call( A a, B b, C c, D d, E e, F f, G g )
  1678. {
  1679. if (Con::isMainThread())
  1680. {
  1681. ConsoleStackFrameSaver sav; sav.save();
  1682. CSTK.reserveValues(mArgc+6, mArgv);
  1683. mArgv[ 0 ].value->setStackStringValue(a);
  1684. EngineMarshallData( b, mArgc, mArgv );
  1685. EngineMarshallData( c, mArgc, mArgv );
  1686. EngineMarshallData( d, mArgc, mArgv );
  1687. EngineMarshallData( e, mArgc, mArgv );
  1688. EngineMarshallData( f, mArgc, mArgv );
  1689. EngineMarshallData( g, mArgc, mArgv );
  1690. return R( EngineUnmarshallData< R >()( _exec() ) );
  1691. }
  1692. else
  1693. {
  1694. SimConsoleThreadExecCallback cb;
  1695. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, true, &cb);
  1696. evt->populateArgs(mArgv);
  1697. mArgv[ 0 ].value->setStackStringValue(a);
  1698. EngineMarshallData( b, mArgc, mArgv );
  1699. EngineMarshallData( c, mArgc, mArgv );
  1700. EngineMarshallData( d, mArgc, mArgv );
  1701. EngineMarshallData( e, mArgc, mArgv );
  1702. EngineMarshallData( f, mArgc, mArgv );
  1703. EngineMarshallData( g, mArgc, mArgv );
  1704. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1705. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1706. }
  1707. }
  1708. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
  1709. R call( A a, B b, C c, D d, E e, F f, G g, H h )
  1710. {
  1711. if (Con::isMainThread())
  1712. {
  1713. ConsoleStackFrameSaver sav; sav.save();
  1714. CSTK.reserveValues(mArgc+7, mArgv);
  1715. mArgv[ 0 ].value->setStackStringValue(a);
  1716. EngineMarshallData( b, mArgc, mArgv );
  1717. EngineMarshallData( c, mArgc, mArgv );
  1718. EngineMarshallData( d, mArgc, mArgv );
  1719. EngineMarshallData( e, mArgc, mArgv );
  1720. EngineMarshallData( f, mArgc, mArgv );
  1721. EngineMarshallData( g, mArgc, mArgv );
  1722. EngineMarshallData( h, mArgc, mArgv );
  1723. return R( EngineUnmarshallData< R >()( _exec() ) );
  1724. }
  1725. else
  1726. {
  1727. SimConsoleThreadExecCallback cb;
  1728. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, true, &cb);
  1729. evt->populateArgs(mArgv);
  1730. mArgv[ 0 ].value->setStackStringValue(a);
  1731. EngineMarshallData( b, mArgc, mArgv );
  1732. EngineMarshallData( c, mArgc, mArgv );
  1733. EngineMarshallData( d, mArgc, mArgv );
  1734. EngineMarshallData( e, mArgc, mArgv );
  1735. EngineMarshallData( f, mArgc, mArgv );
  1736. EngineMarshallData( g, mArgc, mArgv );
  1737. EngineMarshallData( h, mArgc, mArgv );
  1738. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1739. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1740. }
  1741. }
  1742. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
  1743. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
  1744. {
  1745. if (Con::isMainThread())
  1746. {
  1747. ConsoleStackFrameSaver sav; sav.save();
  1748. CSTK.reserveValues(mArgc+8, mArgv);
  1749. mArgv[ 0 ].value->setStackStringValue(a);
  1750. EngineMarshallData( b, mArgc, mArgv );
  1751. EngineMarshallData( c, mArgc, mArgv );
  1752. EngineMarshallData( d, mArgc, mArgv );
  1753. EngineMarshallData( e, mArgc, mArgv );
  1754. EngineMarshallData( f, mArgc, mArgv );
  1755. EngineMarshallData( g, mArgc, mArgv );
  1756. EngineMarshallData( h, mArgc, mArgv );
  1757. EngineMarshallData( i, mArgc, mArgv );
  1758. return R( EngineUnmarshallData< R >()( _exec() ) );
  1759. }
  1760. else
  1761. {
  1762. SimConsoleThreadExecCallback cb;
  1763. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, true, &cb);
  1764. evt->populateArgs(mArgv);
  1765. mArgv[ 0 ].value->setStackStringValue(a);
  1766. EngineMarshallData( b, mArgc, mArgv );
  1767. EngineMarshallData( c, mArgc, mArgv );
  1768. EngineMarshallData( d, mArgc, mArgv );
  1769. EngineMarshallData( e, mArgc, mArgv );
  1770. EngineMarshallData( f, mArgc, mArgv );
  1771. EngineMarshallData( g, mArgc, mArgv );
  1772. EngineMarshallData( h, mArgc, mArgv );
  1773. EngineMarshallData( i, mArgc, mArgv );
  1774. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1775. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1776. }
  1777. }
  1778. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
  1779. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
  1780. {
  1781. if (Con::isMainThread())
  1782. {
  1783. ConsoleStackFrameSaver sav; sav.save();
  1784. CSTK.reserveValues(mArgc+9, mArgv);
  1785. mArgv[ 0 ].value->setStackStringValue(a);
  1786. EngineMarshallData( b, mArgc, mArgv );
  1787. EngineMarshallData( c, mArgc, mArgv );
  1788. EngineMarshallData( d, mArgc, mArgv );
  1789. EngineMarshallData( e, mArgc, mArgv );
  1790. EngineMarshallData( f, mArgc, mArgv );
  1791. EngineMarshallData( g, mArgc, mArgv );
  1792. EngineMarshallData( h, mArgc, mArgv );
  1793. EngineMarshallData( i, mArgc, mArgv );
  1794. EngineMarshallData( j, mArgc, mArgv );
  1795. return R( EngineUnmarshallData< R >()( _exec() ) );
  1796. }
  1797. else
  1798. {
  1799. SimConsoleThreadExecCallback cb;
  1800. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, true, &cb);
  1801. evt->populateArgs(mArgv);
  1802. mArgv[ 0 ].value->setStackStringValue(a);
  1803. EngineMarshallData( b, mArgc, mArgv );
  1804. EngineMarshallData( c, mArgc, mArgv );
  1805. EngineMarshallData( d, mArgc, mArgv );
  1806. EngineMarshallData( e, mArgc, mArgv );
  1807. EngineMarshallData( f, mArgc, mArgv );
  1808. EngineMarshallData( g, mArgc, mArgv );
  1809. EngineMarshallData( h, mArgc, mArgv );
  1810. EngineMarshallData( i, mArgc, mArgv );
  1811. EngineMarshallData( j, mArgc, mArgv );
  1812. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1813. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1814. }
  1815. }
  1816. 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 >
  1817. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
  1818. {
  1819. if (Con::isMainThread())
  1820. {
  1821. ConsoleStackFrameSaver sav; sav.save();
  1822. CSTK.reserveValues(mArgc+10, mArgv);
  1823. mArgv[ 0 ].value->setStackStringValue(a);
  1824. EngineMarshallData( b, mArgc, mArgv );
  1825. EngineMarshallData( c, mArgc, mArgv );
  1826. EngineMarshallData( d, mArgc, mArgv );
  1827. EngineMarshallData( e, mArgc, mArgv );
  1828. EngineMarshallData( f, mArgc, mArgv );
  1829. EngineMarshallData( g, mArgc, mArgv );
  1830. EngineMarshallData( h, mArgc, mArgv );
  1831. EngineMarshallData( i, mArgc, mArgv );
  1832. EngineMarshallData( j, mArgc, mArgv );
  1833. EngineMarshallData( k, mArgc, mArgv );
  1834. return R( EngineUnmarshallData< R >()( _exec() ) );
  1835. }
  1836. else
  1837. {
  1838. SimConsoleThreadExecCallback cb;
  1839. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, true, &cb);
  1840. evt->populateArgs(mArgv);
  1841. mArgv[ 0 ].value->setStackStringValue(a);
  1842. EngineMarshallData( b, mArgc, mArgv );
  1843. EngineMarshallData( c, mArgc, mArgv );
  1844. EngineMarshallData( d, mArgc, mArgv );
  1845. EngineMarshallData( e, mArgc, mArgv );
  1846. EngineMarshallData( f, mArgc, mArgv );
  1847. EngineMarshallData( g, mArgc, mArgv );
  1848. EngineMarshallData( h, mArgc, mArgv );
  1849. EngineMarshallData( i, mArgc, mArgv );
  1850. EngineMarshallData( j, mArgc, mArgv );
  1851. EngineMarshallData( k, mArgc, mArgv );
  1852. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1853. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1854. }
  1855. }
  1856. 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 >
  1857. 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 )
  1858. {
  1859. if (Con::isMainThread())
  1860. {
  1861. ConsoleStackFrameSaver sav; sav.save();
  1862. CSTK.reserveValues(mArgc+11, mArgv);
  1863. mArgv[ 0 ].value->setStackStringValue(a);
  1864. EngineMarshallData( b, mArgc, mArgv );
  1865. EngineMarshallData( c, mArgc, mArgv );
  1866. EngineMarshallData( d, mArgc, mArgv );
  1867. EngineMarshallData( e, mArgc, mArgv );
  1868. EngineMarshallData( f, mArgc, mArgv );
  1869. EngineMarshallData( g, mArgc, mArgv );
  1870. EngineMarshallData( h, mArgc, mArgv );
  1871. EngineMarshallData( i, mArgc, mArgv );
  1872. EngineMarshallData( j, mArgc, mArgv );
  1873. EngineMarshallData( k, mArgc, mArgv );
  1874. EngineMarshallData( l, mArgc, mArgv );
  1875. return R( EngineUnmarshallData< R >()( _exec() ) );
  1876. }
  1877. else
  1878. {
  1879. SimConsoleThreadExecCallback cb;
  1880. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, true, &cb);
  1881. evt->populateArgs(mArgv);
  1882. mArgv[ 0 ].value->setStackStringValue(a);
  1883. EngineMarshallData( b, mArgc, mArgv );
  1884. EngineMarshallData( c, mArgc, mArgv );
  1885. EngineMarshallData( d, mArgc, mArgv );
  1886. EngineMarshallData( e, mArgc, mArgv );
  1887. EngineMarshallData( f, mArgc, mArgv );
  1888. EngineMarshallData( g, mArgc, mArgv );
  1889. EngineMarshallData( h, mArgc, mArgv );
  1890. EngineMarshallData( i, mArgc, mArgv );
  1891. EngineMarshallData( j, mArgc, mArgv );
  1892. EngineMarshallData( k, mArgc, mArgv );
  1893. EngineMarshallData( l, mArgc, mArgv );
  1894. Sim::postEvent(mThis, evt, Sim::getCurrentTime());
  1895. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1896. }
  1897. }
  1898. };
  1899. // Override for when first parameter is const char*
  1900. template<> struct _EngineConsoleExecCallbackHelper<const char*> : public _BaseEngineConsoleCallbackHelper
  1901. {
  1902. _EngineConsoleExecCallbackHelper( const char *callbackName )
  1903. {
  1904. mThis = NULL;
  1905. mArgc = mInitialArgc = 1;
  1906. mCallbackName = StringTable->insert(callbackName);
  1907. }
  1908. template< typename R >
  1909. R call()
  1910. {
  1911. if (Con::isMainThread())
  1912. {
  1913. ConsoleStackFrameSaver sav; sav.save();
  1914. CSTK.reserveValues(mArgc, mArgv);
  1915. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1916. return R( EngineUnmarshallData< R >()( _exec() ) );
  1917. }
  1918. else
  1919. {
  1920. SimConsoleThreadExecCallback cb;
  1921. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc, NULL, false, &cb);
  1922. evt->populateArgs(mArgv);
  1923. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1924. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1925. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1926. }
  1927. }
  1928. template< typename R, typename A >
  1929. R call( A a )
  1930. {
  1931. if (Con::isMainThread())
  1932. {
  1933. ConsoleStackFrameSaver sav; sav.save();
  1934. CSTK.reserveValues(mArgc+1, mArgv);
  1935. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1936. EngineMarshallData( a, mArgc, mArgv );
  1937. return R( EngineUnmarshallData< R >()( _exec() ) );
  1938. }
  1939. else
  1940. {
  1941. SimConsoleThreadExecCallback cb;
  1942. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, false, &cb);
  1943. evt->populateArgs(mArgv);
  1944. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1945. EngineMarshallData( a, mArgc, mArgv );
  1946. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1947. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1948. }
  1949. }
  1950. template< typename R, typename A, typename B >
  1951. R call( A a, B b )
  1952. {
  1953. if (Con::isMainThread())
  1954. {
  1955. ConsoleStackFrameSaver sav; sav.save();
  1956. CSTK.reserveValues(mArgc+2, mArgv);
  1957. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1958. EngineMarshallData( a, mArgc, mArgv );
  1959. EngineMarshallData( b, mArgc, mArgv );
  1960. return R( EngineUnmarshallData< R >()( _exec() ) );
  1961. }
  1962. else
  1963. {
  1964. SimConsoleThreadExecCallback cb;
  1965. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, false, &cb);
  1966. evt->populateArgs(mArgv);
  1967. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1968. EngineMarshallData( a, mArgc, mArgv );
  1969. EngineMarshallData( b, mArgc, mArgv );
  1970. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1971. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1972. }
  1973. }
  1974. template< typename R, typename A, typename B, typename C >
  1975. R call( A a, B b, C c )
  1976. {
  1977. if (Con::isMainThread())
  1978. {
  1979. ConsoleStackFrameSaver sav; sav.save();
  1980. CSTK.reserveValues(mArgc+3, mArgv);
  1981. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1982. EngineMarshallData( a, mArgc, mArgv );
  1983. EngineMarshallData( b, mArgc, mArgv );
  1984. EngineMarshallData( c, mArgc, mArgv );
  1985. return R( EngineUnmarshallData< R >()( _exec() ) );
  1986. }
  1987. else
  1988. {
  1989. SimConsoleThreadExecCallback cb;
  1990. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, false, &cb);
  1991. evt->populateArgs(mArgv);
  1992. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  1993. EngineMarshallData( a, mArgc, mArgv );
  1994. EngineMarshallData( b, mArgc, mArgv );
  1995. EngineMarshallData( c, mArgc, mArgv );
  1996. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  1997. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  1998. }
  1999. }
  2000. template< typename R, typename A, typename B, typename C, typename D >
  2001. R call( A a, B b, C c, D d )
  2002. {
  2003. if (Con::isMainThread())
  2004. {
  2005. ConsoleStackFrameSaver sav; sav.save();
  2006. CSTK.reserveValues(mArgc+4, mArgv);
  2007. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2008. EngineMarshallData( a, mArgc, mArgv );
  2009. EngineMarshallData( b, mArgc, mArgv );
  2010. EngineMarshallData( c, mArgc, mArgv );
  2011. EngineMarshallData( d, mArgc, mArgv );
  2012. return R( EngineUnmarshallData< R >()( _exec() ) );
  2013. }
  2014. else
  2015. {
  2016. SimConsoleThreadExecCallback cb;
  2017. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, false, &cb);
  2018. evt->populateArgs(mArgv);
  2019. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2020. EngineMarshallData( a, mArgc, mArgv );
  2021. EngineMarshallData( b, mArgc, mArgv );
  2022. EngineMarshallData( c, mArgc, mArgv );
  2023. EngineMarshallData( d, mArgc, mArgv );
  2024. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2025. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2026. }
  2027. }
  2028. template< typename R, typename A, typename B, typename C, typename D, typename E >
  2029. R call( A a, B b, C c, D d, E e )
  2030. {
  2031. if (Con::isMainThread())
  2032. {
  2033. ConsoleStackFrameSaver sav; sav.save();
  2034. CSTK.reserveValues(mArgc+5, mArgv);
  2035. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2036. EngineMarshallData( a, mArgc, mArgv );
  2037. EngineMarshallData( b, mArgc, mArgv );
  2038. EngineMarshallData( c, mArgc, mArgv );
  2039. EngineMarshallData( d, mArgc, mArgv );
  2040. EngineMarshallData( e, mArgc, mArgv );
  2041. return R( EngineUnmarshallData< R >()( _exec() ) );
  2042. }
  2043. else
  2044. {
  2045. SimConsoleThreadExecCallback cb;
  2046. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, false, &cb);
  2047. evt->populateArgs(mArgv);
  2048. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2049. EngineMarshallData( a, mArgc, mArgv );
  2050. EngineMarshallData( b, mArgc, mArgv );
  2051. EngineMarshallData( c, mArgc, mArgv );
  2052. EngineMarshallData( d, mArgc, mArgv );
  2053. EngineMarshallData( e, mArgc, mArgv );
  2054. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2055. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2056. }
  2057. }
  2058. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
  2059. R call( A a, B b, C c, D d, E e, F f )
  2060. {
  2061. if (Con::isMainThread())
  2062. {
  2063. ConsoleStackFrameSaver sav; sav.save();
  2064. CSTK.reserveValues(mArgc+6, mArgv);
  2065. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2066. EngineMarshallData( a, mArgc, mArgv );
  2067. EngineMarshallData( b, mArgc, mArgv );
  2068. EngineMarshallData( c, mArgc, mArgv );
  2069. EngineMarshallData( d, mArgc, mArgv );
  2070. EngineMarshallData( e, mArgc, mArgv );
  2071. EngineMarshallData( f, mArgc, mArgv );
  2072. return R( EngineUnmarshallData< R >()( _exec() ) );
  2073. }
  2074. else
  2075. {
  2076. SimConsoleThreadExecCallback cb;
  2077. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, false, &cb);
  2078. evt->populateArgs(mArgv);
  2079. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2080. EngineMarshallData( a, mArgc, mArgv );
  2081. EngineMarshallData( b, mArgc, mArgv );
  2082. EngineMarshallData( c, mArgc, mArgv );
  2083. EngineMarshallData( d, mArgc, mArgv );
  2084. EngineMarshallData( e, mArgc, mArgv );
  2085. EngineMarshallData( f, mArgc, mArgv );
  2086. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2087. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2088. }
  2089. }
  2090. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
  2091. R call( A a, B b, C c, D d, E e, F f, G g )
  2092. {
  2093. if (Con::isMainThread())
  2094. {
  2095. ConsoleStackFrameSaver sav; sav.save();
  2096. CSTK.reserveValues(mArgc+7, mArgv);
  2097. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2098. EngineMarshallData( a, mArgc, mArgv );
  2099. EngineMarshallData( b, mArgc, mArgv );
  2100. EngineMarshallData( c, mArgc, mArgv );
  2101. EngineMarshallData( d, mArgc, mArgv );
  2102. EngineMarshallData( e, mArgc, mArgv );
  2103. EngineMarshallData( f, mArgc, mArgv );
  2104. EngineMarshallData( g, mArgc, mArgv );
  2105. return R( EngineUnmarshallData< R >()( _exec() ) );
  2106. }
  2107. else
  2108. {
  2109. SimConsoleThreadExecCallback cb;
  2110. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, false, &cb);
  2111. evt->populateArgs(mArgv);
  2112. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2113. EngineMarshallData( a, mArgc, mArgv );
  2114. EngineMarshallData( b, mArgc, mArgv );
  2115. EngineMarshallData( c, mArgc, mArgv );
  2116. EngineMarshallData( d, mArgc, mArgv );
  2117. EngineMarshallData( e, mArgc, mArgv );
  2118. EngineMarshallData( f, mArgc, mArgv );
  2119. EngineMarshallData( g, mArgc, mArgv );
  2120. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2121. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2122. }
  2123. }
  2124. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
  2125. R call( A a, B b, C c, D d, E e, F f, G g, H h )
  2126. {
  2127. if (Con::isMainThread())
  2128. {
  2129. ConsoleStackFrameSaver sav; sav.save();
  2130. CSTK.reserveValues(mArgc+8, mArgv);
  2131. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2132. EngineMarshallData( a, mArgc, mArgv );
  2133. EngineMarshallData( b, mArgc, mArgv );
  2134. EngineMarshallData( c, mArgc, mArgv );
  2135. EngineMarshallData( d, mArgc, mArgv );
  2136. EngineMarshallData( e, mArgc, mArgv );
  2137. EngineMarshallData( f, mArgc, mArgv );
  2138. EngineMarshallData( g, mArgc, mArgv );
  2139. EngineMarshallData( h, mArgc, mArgv );
  2140. return R( EngineUnmarshallData< R >()( _exec() ) );
  2141. }
  2142. else
  2143. {
  2144. SimConsoleThreadExecCallback cb;
  2145. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, false, &cb);
  2146. evt->populateArgs(mArgv);
  2147. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2148. EngineMarshallData( a, mArgc, mArgv );
  2149. EngineMarshallData( b, mArgc, mArgv );
  2150. EngineMarshallData( c, mArgc, mArgv );
  2151. EngineMarshallData( d, mArgc, mArgv );
  2152. EngineMarshallData( e, mArgc, mArgv );
  2153. EngineMarshallData( f, mArgc, mArgv );
  2154. EngineMarshallData( g, mArgc, mArgv );
  2155. EngineMarshallData( h, mArgc, mArgv );
  2156. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2157. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2158. }
  2159. }
  2160. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
  2161. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
  2162. {
  2163. if (Con::isMainThread())
  2164. {
  2165. ConsoleStackFrameSaver sav; sav.save();
  2166. CSTK.reserveValues(mArgc+9, mArgv);
  2167. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2168. EngineMarshallData( a, mArgc, mArgv );
  2169. EngineMarshallData( b, mArgc, mArgv );
  2170. EngineMarshallData( c, mArgc, mArgv );
  2171. EngineMarshallData( d, mArgc, mArgv );
  2172. EngineMarshallData( e, mArgc, mArgv );
  2173. EngineMarshallData( f, mArgc, mArgv );
  2174. EngineMarshallData( g, mArgc, mArgv );
  2175. EngineMarshallData( h, mArgc, mArgv );
  2176. EngineMarshallData( i, mArgc, mArgv );
  2177. return R( EngineUnmarshallData< R >()( _exec() ) );
  2178. }
  2179. else
  2180. {
  2181. SimConsoleThreadExecCallback cb;
  2182. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, false, &cb);
  2183. evt->populateArgs(mArgv);
  2184. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2185. EngineMarshallData( a, mArgc, mArgv );
  2186. EngineMarshallData( b, mArgc, mArgv );
  2187. EngineMarshallData( c, mArgc, mArgv );
  2188. EngineMarshallData( d, mArgc, mArgv );
  2189. EngineMarshallData( e, mArgc, mArgv );
  2190. EngineMarshallData( f, mArgc, mArgv );
  2191. EngineMarshallData( g, mArgc, mArgv );
  2192. EngineMarshallData( h, mArgc, mArgv );
  2193. EngineMarshallData( i, mArgc, mArgv );
  2194. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2195. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2196. }
  2197. }
  2198. template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
  2199. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
  2200. {
  2201. if (Con::isMainThread())
  2202. {
  2203. ConsoleStackFrameSaver sav; sav.save();
  2204. CSTK.reserveValues(mArgc+10, mArgv);
  2205. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2206. EngineMarshallData( a, mArgc, mArgv );
  2207. EngineMarshallData( b, mArgc, mArgv );
  2208. EngineMarshallData( c, mArgc, mArgv );
  2209. EngineMarshallData( d, mArgc, mArgv );
  2210. EngineMarshallData( e, mArgc, mArgv );
  2211. EngineMarshallData( f, mArgc, mArgv );
  2212. EngineMarshallData( g, mArgc, mArgv );
  2213. EngineMarshallData( h, mArgc, mArgv );
  2214. EngineMarshallData( i, mArgc, mArgv );
  2215. EngineMarshallData( j, mArgc, mArgv );
  2216. return R( EngineUnmarshallData< R >()( _exec() ) );
  2217. }
  2218. else
  2219. {
  2220. SimConsoleThreadExecCallback cb;
  2221. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, false, &cb);
  2222. evt->populateArgs(mArgv);
  2223. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2224. EngineMarshallData( a, mArgc, mArgv );
  2225. EngineMarshallData( b, mArgc, mArgv );
  2226. EngineMarshallData( c, mArgc, mArgv );
  2227. EngineMarshallData( d, mArgc, mArgv );
  2228. EngineMarshallData( e, mArgc, mArgv );
  2229. EngineMarshallData( f, mArgc, mArgv );
  2230. EngineMarshallData( g, mArgc, mArgv );
  2231. EngineMarshallData( h, mArgc, mArgv );
  2232. EngineMarshallData( i, mArgc, mArgv );
  2233. EngineMarshallData( j, mArgc, mArgv );
  2234. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2235. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2236. }
  2237. }
  2238. 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 >
  2239. R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
  2240. {
  2241. if (Con::isMainThread())
  2242. {
  2243. ConsoleStackFrameSaver sav; sav.save();
  2244. CSTK.reserveValues(mArgc+11, mArgv);
  2245. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2246. EngineMarshallData( a, mArgc, mArgv );
  2247. EngineMarshallData( b, mArgc, mArgv );
  2248. EngineMarshallData( c, mArgc, mArgv );
  2249. EngineMarshallData( d, mArgc, mArgv );
  2250. EngineMarshallData( e, mArgc, mArgv );
  2251. EngineMarshallData( f, mArgc, mArgv );
  2252. EngineMarshallData( g, mArgc, mArgv );
  2253. EngineMarshallData( h, mArgc, mArgv );
  2254. EngineMarshallData( i, mArgc, mArgv );
  2255. EngineMarshallData( j, mArgc, mArgv );
  2256. EngineMarshallData( k, mArgc, mArgv );
  2257. return R( EngineUnmarshallData< R >()( _exec() ) );
  2258. }
  2259. else
  2260. {
  2261. SimConsoleThreadExecCallback cb;
  2262. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, false, &cb);
  2263. evt->populateArgs(mArgv);
  2264. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2265. EngineMarshallData( a, mArgc, mArgv );
  2266. EngineMarshallData( b, mArgc, mArgv );
  2267. EngineMarshallData( c, mArgc, mArgv );
  2268. EngineMarshallData( d, mArgc, mArgv );
  2269. EngineMarshallData( e, mArgc, mArgv );
  2270. EngineMarshallData( f, mArgc, mArgv );
  2271. EngineMarshallData( g, mArgc, mArgv );
  2272. EngineMarshallData( h, mArgc, mArgv );
  2273. EngineMarshallData( i, mArgc, mArgv );
  2274. EngineMarshallData( j, mArgc, mArgv );
  2275. EngineMarshallData( k, mArgc, mArgv );
  2276. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2277. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2278. }
  2279. }
  2280. 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 >
  2281. 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 )
  2282. {
  2283. if (Con::isMainThread())
  2284. {
  2285. ConsoleStackFrameSaver sav; sav.save();
  2286. CSTK.reserveValues(mArgc+12, mArgv);
  2287. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2288. EngineMarshallData( a, mArgc, mArgv );
  2289. EngineMarshallData( b, mArgc, mArgv );
  2290. EngineMarshallData( c, mArgc, mArgv );
  2291. EngineMarshallData( d, mArgc, mArgv );
  2292. EngineMarshallData( e, mArgc, mArgv );
  2293. EngineMarshallData( f, mArgc, mArgv );
  2294. EngineMarshallData( g, mArgc, mArgv );
  2295. EngineMarshallData( h, mArgc, mArgv );
  2296. EngineMarshallData( i, mArgc, mArgv );
  2297. EngineMarshallData( j, mArgc, mArgv );
  2298. EngineMarshallData( k, mArgc, mArgv );
  2299. EngineMarshallData( l, mArgc, mArgv );
  2300. return R( EngineUnmarshallData< R >()( _exec() ) );
  2301. }
  2302. else
  2303. {
  2304. SimConsoleThreadExecCallback cb;
  2305. SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+12, NULL, false, &cb);
  2306. evt->populateArgs(mArgv);
  2307. mArgv[ 0 ].value->setStackStringValue(mCallbackName);
  2308. EngineMarshallData( a, mArgc, mArgv );
  2309. EngineMarshallData( b, mArgc, mArgv );
  2310. EngineMarshallData( c, mArgc, mArgv );
  2311. EngineMarshallData( d, mArgc, mArgv );
  2312. EngineMarshallData( e, mArgc, mArgv );
  2313. EngineMarshallData( f, mArgc, mArgv );
  2314. EngineMarshallData( g, mArgc, mArgv );
  2315. EngineMarshallData( h, mArgc, mArgv );
  2316. EngineMarshallData( i, mArgc, mArgv );
  2317. EngineMarshallData( j, mArgc, mArgv );
  2318. EngineMarshallData( k, mArgc, mArgv );
  2319. EngineMarshallData( l, mArgc, mArgv );
  2320. Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
  2321. return R( EngineUnmarshallData< R >()( cb.waitForResult() ) );
  2322. }
  2323. }
  2324. };
  2325. // Re-enable some VC warnings we disabled for this file.
  2326. #pragma warning( pop ) // 4510 and 4610
  2327. #endif // !_ENGINEAPI_H_