engineAPI.h 130 KB

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