engineAPI.h

Engine/source/console/engineAPI.h

Definitions for exposing engine functionality to the control layer.

More...

Classes:

class

Unmarshal data from client form to engine form.

Namespaces:

namespace

API Definition Macros

The macros in this group allow to create engine API functions that work both with the legacy console system as well as with the new engine export system.

As such, they only support those function features that are available in both systems. This means that for console-style variadic functions, the ConsoleXXX must be used and that for overloaded and/or C-style variadic functions as well as for placing functions in export scopes, DEFINE_CALLIN must be used directly.

When the console system is removed, the console thunking functionality will be removed from these macros but otherwise they will remain unchanged and in place.

define
_CHECK_ENGINE_INITIALIZED(fnName, returnType) ( fnName, returnType )
define
_CHECK_ENGINE_INITIALIZED_IMPL(fnName, returnType)       ( ! )                                                                                           \
      {                                                                                                                          \
         ( "EngineAPI: Engine not initialized when calling " #fnName );                                               \
         return < returnType >::ReturnValue( < returnType >::ReturnValueType() );                \
      }
define
_DefineMethodTrampoline(className, name, returnType, args)    TORQUE_API < returnType >::ReturnValueType \
      fn ## className ## _ ## name ( className* object, < _ ## className ## name ## frame, returnType args >::Args a )   \
   {                                                                                                                                            \
      ( className::name, returnType );                                                                                 \
      return < returnType >::ReturnValue(                                                                                       \
         < _ ## className ## name ## frame, returnType args >::jmp( object, a )                                          \
      );                                                                                                                                        \
   }
define
DefineConsoleFunction(name, returnType, args, defaultArgs, usage)    static inline returnType _fn ## name ## impl args;                                                                            \
   static <  args > _fn ## name ## DefaultArgs defaultArgs;                                   \
   static < returnType >:: _ ## name ## caster( *,  argc,  *argv )       \
   {                                                                                                                             \
      return < returnType >::( < 1, returnType args >::thunk(                \
         argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs                                                            \
      ) );                                                                                                                       \
   }                                                                                                                             \
   static  _ ## name ## header                                                                              \
      ( #returnType, #args, #defaultArgs );                                                                                      \
   static                                                                                                      \
      _ ## name ## obj( , #name, < returnType >::CallbackType( _ ## name ## caster ), usage,          \
         < 1, returnType args >::NUM_ARGS - () defaultArgs,                       \
         < 1, returnType args >::NUM_ARGS,                                                                    \
         false, &_ ## name ## header                                                                                             \
      );                                                                                                                         \
   static inline returnType _fn ## name ## impl args
define
DefineConsoleMethod(className, name, returnType, args, defaultArgs, usage)    struct _ ## className ## name ## frame                                                                                                       \
   {                                                                                                                                            \
      typedef className ObjectType;                                                                                                             \
      className* object;                                                                                                                        \
      inline returnType _exec args ;                                                                                                       \
   };                                                                                                                                           \
   static < < _ ## className ## name ## frame,  args >::FunctionType >                \
      _fn ## className ## name ## DefaultArgs defaultArgs;                                                                                      \
   static < returnType >:: _ ## className ## name ## caster( * object,  argc,  *argv )  \
   {                                                                                                                                            \
      _ ## className ## name ## frame frame;                                                                                                    \
      frame.object = static_cast< className* >( object );                                                                                       \
      return < returnType >::( < 2, returnType args >::thunk(                               \
         argc, argv, &_ ## className ## name ## frame::_exec, &frame, _fn ## className ## name ## DefaultArgs                                   \
      ) );                                                                                                                                      \
   }                                                                                                                                            \
   static  _ ## className ## name ## header                                                                                \
      ( #returnType, #args, #defaultArgs );                                                                                                     \
   static                                                                                                                     \
      className ## name ## obj( #className, #name,                                                                                              \
         < returnType >::CallbackType( _ ## className ## name ## caster ), usage,                                        \
         < 2, returnType args >::NUM_ARGS - () defaultArgs,                                      \
         < 2, returnType args >::NUM_ARGS,                                                                                   \
         false, &_ ## className ## name ## header                                                                                               \
      );                                                                                                                                        \
   returnType _ ## className ## name ## frame::_exec args 
define
DefineConsoleStaticMethod(className, name, returnType, args, defaultArgs, usage)    static inline returnType _fn ## className ## name ## impl args;                                                                     \
   static <  args > _fn ## className ## name ## DefaultArgs defaultArgs;                            \
   static < returnType >:: _ ## className ## name ## caster( *,  argc,  *argv )\
   {                                                                                                                                   \
      return < returnType >::( < 1, returnType args >::thunk(                      \
         argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs                                        \
      ) );                                                                                                                             \
   }                                                                                                                                   \
   static  _ ## className ## name ## header                                                                       \
      ( #returnType, #args, #defaultArgs, true );                                                                                      \
   static                                                                                                            \
      _ ## className ## name ## obj( #className, #name, < returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
         < 1, returnType args >::NUM_ARGS - () defaultArgs,                             \
         < 1, returnType args >::NUM_ARGS,                                                                          \
         false, &_ ## className ## name ## header                                                                                      \
      );                                                                                                                               \
   static inline returnType _fn ## className ## name ## impl args
define
DefineEngineFunction(name, returnType, args, defaultArgs, usage) 

Define a call-in point for calling into the engine.

define
DefineEngineMethod(className, name, returnType, args, defaultArgs, usage) 

Define a call-in point for calling a method on an engine object.

define
DefineEngineStaticMethod(className, name, returnType, args, defaultArgs, usage) 

Define a call-in point for calling into the engine.

define
DefineNewEngineFunction(name, returnType, args, defaultArgs, usage)    static inline returnType _fn ## name ## impl args;                                                                            \
   TORQUE_API < returnType >::ReturnValueType fn ## name                                                         \
      ( < returnType args >::Args a )                                                                   \
   {                                                                                                                             \
      ( name, returnType );                                                                             \
      return < returnType >::ReturnValue(                                                                        \
         < returnType args >::jmp( _fn ## name ## impl, a )                                             \
      );                                                                                                                         \
   }                                                                                                                             \
   static <  args > _fn ## name ## DefaultArgs defaultArgs;                                   \
   static  _fn ## name ## FunctionInfo(                                                                        \
      #name,                                                                                                                     \
      &<>()(),                                                                                                             \
      usage,                                                                                                                     \
      #returnType " " #name #args,                                                                                               \
      "fn" #name,                                                                                                                \
      < returnType args >(),                                                                                                 \
      &_fn ## name ## DefaultArgs,                                                                                               \
      ( * ) &fn ## name,                                                                                                     \
      0                                                                                                                          \
   );                                                                                                                            \
   static inline returnType _fn ## name ## impl args
define
DefineNewEngineMethod(className, name, returnType, args, defaultArgs, usage)    struct _ ## className ## name ## frame                                                                                                       \
   {                                                                                                                                            \
      typedef className ObjectType;                                                                                                             \
      className* object;                                                                                                                        \
      inline returnType _exec args ;                                                                                                       \
   };                                                                                                                                           \
   ( className, name, returnType, args );                                                                                \
   static < < _ ## className ## name ## frame,  args >::FunctionType >                \
      _fn ## className ## name ## DefaultArgs defaultArgs;                                                                                      \
   static  _fn ## className ## name ## FunctionInfo(                                                                          \
      #name,                                                                                                                                    \
      &< className >()(),                                                                                                                 \
      usage,                                                                                                                                    \
      "virtual " #returnType " " #name #args,                                                                                                   \
      "fn" #className "_" #name,                                                                                                                \
      < < _ ## className ## name ## frame, returnType args >::FunctionType >(),                                      \
      &_fn ## className ## name ## DefaultArgs,                                                                                                 \
      ( * ) &fn ## className ## _ ## name,                                                                                                  \
      0                                                                                                                                         \
   );                                                                                                                                           \
   returnType _ ## className ## name ## frame::_exec args 
define
DefineNewEngineStaticMethod(className, name, returnType, args, defaultArgs, usage)    static inline returnType _fn ## className ## name ## impl args;                                                                     \
   TORQUE_API < returnType >::ReturnValueType fn ## className ## _ ## name                                             \
      ( < returnType args >::Args a )                                                                         \
   {                                                                                                                                   \
      ( className::name, returnType );                                                                        \
      return < returnType >::ReturnValue(                                                                              \
         < returnType args >::jmp( _fn ## className ## name ## impl, a )                                      \
      );                                                                                                                               \
   }                                                                                                                                   \
   static <  args > _fn ## className ## name ## DefaultArgs defaultArgs;                            \
   static  _fn ## name ## FunctionInfo(                                                                              \
      #name,                                                                                                                           \
      &< className >()(),                                                                                                        \
      usage,                                                                                                                           \
      #returnType " " #name #args,                                                                                                     \
      "fn" #className "_" #name,                                                                                                       \
      < returnType args >(),                                                                                                       \
      &_fn ## className ## name ## DefaultArgs,                                                                                        \
      ( * ) &fn ## className ## _ ## name,                                                                                         \
      0                                                                                                                                \
   );                                                                                                                                  \
   static inline returnType _fn ## className ## name ## impl args

Marshalling

Functions for converting to/from string-based data representations.

note:

This functionality is specific to the console interop.

EngineMarshallData(bool arg, S32 & argc, ConsoleValueRef * argv)
const char *
EngineMarshallData(bool value)
EngineMarshallData(char * arg, S32 & argc, ConsoleValueRef * argv)
EngineMarshallData(const char * arg, S32 & argc, ConsoleValueRef * argv)
const char *
EngineMarshallData(const T & arg, S32 & argc, ConsoleValueRef * argv)

Marshal data from native into client form stored directly in client function invocation vector.

const char *

Marshal a single piece of data from native into client form.

const char *
EngineMarshallData(const T * object, S32 & argc, ConsoleValueRef * argv)
const char *
EngineMarshallData(T * object, S32 & argc, ConsoleValueRef * argv)

Thunking

Internal functionality for thunks placed between TorqueScript calls of engine functions and their native implementations.

note:

The functionality in this group is specific to the console interop system.

Public Defines

define
IMPLEMENT_CALLBACK(class, name, returnType, args, argNames, usageString) 

Matching implement for DECLARE_CALLBACK.

define
IMPLEMENT_CONSOLE_CALLBACK(class, name, returnType, args, argNames, usageString)    returnType class::name ## _callback args                                                                                                  \
   {                                                                                                                                         \
      (  )                                                                                                    \
      {                                                                                                                                      \
         static  sName = ->insert( #name );                                                                       \
          cbh( sName, this );                                                                                    \
         return returnType( cbh.call< returnType > argNames );                                                                               \
      }                                                                                                                                      \
      return returnType();                                                                                                                   \
   }                                                                                                                                         \
   namespace {                                                                                                                               \
       _ ## class ## name ## header(                                                                                    \
         #returnType, #args, "" );                                                                                                           \
       _ ## class ## name ## obj( #class, #name, usageString, &_ ## class ## name ## header );                             \
   }
define
IMPLEMENT_GLOBAL_CALLBACK(name, returnType, args, argNames, usageString)    ( cb ## name, name,, returnType, args, 0, usageString );                                                                    \
   returnType name ## _callback args                                                                                                         \
   {                                                                                                                                         \
      ( cb ## name )                                                                                                                       \
         return returnType( cb ## name argNames );                                                                                           \
      (  )                                                                                                    \
      {                                                                                                                                      \
         static  sName = ->insert( #name );                                                                       \
          cbh( sName,  );                                                                                    \
         return returnType( cbh.call< returnType > argNames );                                                                               \
      }                                                                                                                                      \
      return returnType();                                                                                                                   \
   }                                                                                                                                         \
   namespace {                                                                                                                               \
       _ ## name ## header(                                                                                             \
         #returnType, #args, "" );                                                                                                           \
       _ ## name ## obj( , #name, usageString, &_ ## name ## header );                                                 \
   }

Used to define global callbacks not associated with any particular class or namespace.

define
IMPLEMENT_NEW_CALLBACK(class, name, returnType, args, argNames, usageString)    struct _ ## class ## name ## frame { typedef class ObjectType; };                                                                         \
   TORQUE_API < _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name;               \
   TORQUE_API  set_cb ## class ## _ ## name(                                                                                             \
      < _ ## class ## name ## frame, returnType args >::FunctionType fn )                                             \
      { cb ## class ## _ ## name = fn; }                                                                                                     \
   < _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name;                          \
   namespace {                                                                                                                               \
      :: _cb ## class ## name(                                                                                             \
         #name,                                                                                                                              \
         &::< class >()(),                                                                                                             \
         usageString,                                                                                                                        \
         "virtual " #returnType " " #name #args,                                                                                             \
         "cb" #class "_" #name,                                                                                                              \
         ::< < _ ## class ## name ## frame, returnType args >::FunctionType >(),                                  \
         ,                                                                                                                               \
         &cb ## class ## _ ## name,                                                                                                          \
                                                                                                                        \
      );                                                                                                                                     \
   }                                                                                                                                         \
   returnType class::name ## _callback args                                                                                                  \
   {                                                                                                                                         \
      ( cb ## class ## _ ## name ) {                                                                                                       \
          cbh( this, reinterpret_cast<  * >( cb ## class ## _ ## name ) );                                     \
         return returnType( cbh.call< returnType > argNames );                                                                               \
      }                                                                                                                                      \
      return returnType();                                                                                                                   \
   }

Detailed Description

Definitions for exposing engine functionality to the control layer.

This file provides a convenience layer around the underlying engine interop system (which at the moment still includes the legacy TorqueScript interop a.k.a. "console system"). The macros exposed here will automatically take care of all marshalling, value type constraints, reflection info instancing, etc. involved in defining engine API call-ins and call-outs.

note:

At the moment, this file supplies both the legacy TorqueScript console system as well as the new engine export system with the structures and information they need. In the near future, the console-based parts will get purged. This will not result in visible changes to users of the functionality here except for the string-based marshalling functions currently exposed (which will also disappear).

API Definition Macros

The macros in this group allow to create engine API functions that work both with the legacy console system as well as with the new engine export system.

As such, they only support those function features that are available in both systems. This means that for console-style variadic functions, the ConsoleXXX must be used and that for overloaded and/or C-style variadic functions as well as for placing functions in export scopes, DEFINE_CALLIN must be used directly.

When the console system is removed, the console thunking functionality will be removed from these macros but otherwise they will remain unchanged and in place.

_CHECK_ENGINE_INITIALIZED(fnName, returnType) ( fnName, returnType )
_CHECK_ENGINE_INITIALIZED_IMPL(fnName, returnType)       ( ! )                                                                                           \
      {                                                                                                                          \
         ( "EngineAPI: Engine not initialized when calling " #fnName );                                               \
         return < returnType >::ReturnValue( < returnType >::ReturnValueType() );                \
      }
_DefineMethodTrampoline(className, name, returnType, args)    TORQUE_API < returnType >::ReturnValueType \
      fn ## className ## _ ## name ( className* object, < _ ## className ## name ## frame, returnType args >::Args a )   \
   {                                                                                                                                            \
      ( className::name, returnType );                                                                                 \
      return < returnType >::ReturnValue(                                                                                       \
         < _ ## className ## name ## frame, returnType args >::jmp( object, a )                                          \
      );                                                                                                                                        \
   }
DefineConsoleFunction(name, returnType, args, defaultArgs, usage)    static inline returnType _fn ## name ## impl args;                                                                            \
   static <  args > _fn ## name ## DefaultArgs defaultArgs;                                   \
   static < returnType >:: _ ## name ## caster( *,  argc,  *argv )       \
   {                                                                                                                             \
      return < returnType >::( < 1, returnType args >::thunk(                \
         argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs                                                            \
      ) );                                                                                                                       \
   }                                                                                                                             \
   static  _ ## name ## header                                                                              \
      ( #returnType, #args, #defaultArgs );                                                                                      \
   static                                                                                                      \
      _ ## name ## obj( , #name, < returnType >::CallbackType( _ ## name ## caster ), usage,          \
         < 1, returnType args >::NUM_ARGS - () defaultArgs,                       \
         < 1, returnType args >::NUM_ARGS,                                                                    \
         false, &_ ## name ## header                                                                                             \
      );                                                                                                                         \
   static inline returnType _fn ## name ## impl args
DefineConsoleMethod(className, name, returnType, args, defaultArgs, usage)    struct _ ## className ## name ## frame                                                                                                       \
   {                                                                                                                                            \
      typedef className ObjectType;                                                                                                             \
      className* object;                                                                                                                        \
      inline returnType _exec args ;                                                                                                       \
   };                                                                                                                                           \
   static < < _ ## className ## name ## frame,  args >::FunctionType >                \
      _fn ## className ## name ## DefaultArgs defaultArgs;                                                                                      \
   static < returnType >:: _ ## className ## name ## caster( * object,  argc,  *argv )  \
   {                                                                                                                                            \
      _ ## className ## name ## frame frame;                                                                                                    \
      frame.object = static_cast< className* >( object );                                                                                       \
      return < returnType >::( < 2, returnType args >::thunk(                               \
         argc, argv, &_ ## className ## name ## frame::_exec, &frame, _fn ## className ## name ## DefaultArgs                                   \
      ) );                                                                                                                                      \
   }                                                                                                                                            \
   static  _ ## className ## name ## header                                                                                \
      ( #returnType, #args, #defaultArgs );                                                                                                     \
   static                                                                                                                     \
      className ## name ## obj( #className, #name,                                                                                              \
         < returnType >::CallbackType( _ ## className ## name ## caster ), usage,                                        \
         < 2, returnType args >::NUM_ARGS - () defaultArgs,                                      \
         < 2, returnType args >::NUM_ARGS,                                                                                   \
         false, &_ ## className ## name ## header                                                                                               \
      );                                                                                                                                        \
   returnType _ ## className ## name ## frame::_exec args 
DefineConsoleStaticMethod(className, name, returnType, args, defaultArgs, usage)    static inline returnType _fn ## className ## name ## impl args;                                                                     \
   static <  args > _fn ## className ## name ## DefaultArgs defaultArgs;                            \
   static < returnType >:: _ ## className ## name ## caster( *,  argc,  *argv )\
   {                                                                                                                                   \
      return < returnType >::( < 1, returnType args >::thunk(                      \
         argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs                                        \
      ) );                                                                                                                             \
   }                                                                                                                                   \
   static  _ ## className ## name ## header                                                                       \
      ( #returnType, #args, #defaultArgs, true );                                                                                      \
   static                                                                                                            \
      _ ## className ## name ## obj( #className, #name, < returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
         < 1, returnType args >::NUM_ARGS - () defaultArgs,                             \
         < 1, returnType args >::NUM_ARGS,                                                                          \
         false, &_ ## className ## name ## header                                                                                      \
      );                                                                                                                               \
   static inline returnType _fn ## className ## name ## impl args
DefineEngineFunction(name, returnType, args, defaultArgs, usage) 

Define a call-in point for calling into the engine.

Parameters:

name

The name of the function as it should be seen by the control layer.

returnType

The value type returned to the control layer.

args

The argument list as it would appear on the function definition

defaultArgs

The list of default argument values.

usage

The usage doc string for the engine API reference.

DefineEngineFunction( myFunction, int, ( float f, const String& s ), ( "value for s" ), "This is my function." )
{
   return int( f ) + dAtoi( s );
}

DefineEngineMethod(className, name, returnType, args, defaultArgs, usage) 

Define a call-in point for calling a method on an engine object.

Parameters:

name

The name of the C++ class.

name

The name of the method as it should be seen by the control layer.

returnType

The value type returned to the control layer.

args

The argument list as it would appear on the function definition

defaultArgs

The list of default argument values.

usage

The usage doc string for the engine API reference.

DefineEngineMethod( MyClass, myMethod, int, ( float f, const String& s ), ( "value for s" ), "This is my method." )
{
   return object->someMethod( f, s );
}

DefineEngineStaticMethod(className, name, returnType, args, defaultArgs, usage) 

Define a call-in point for calling into the engine.

Unlike with DefineEngineFunction, the statically callable function will be confined to the namespace of the given class.

Parameters:

name

The name of the C++ class (or a registered export scope).

name

The name of the method as it should be seen by the control layer.

returnType

The value type returned to the control layer.

args

The argument list as it would appear on the function definition

defaultArgs

The list of default argument values.

usage

The usage doc string for the engine API reference.

DefineEngineStaticMethod( MyClass, myMethod, int, ( float f, string s ), ( "value for s" ), "This is my method." )
{
}

DefineNewEngineFunction(name, returnType, args, defaultArgs, usage)    static inline returnType _fn ## name ## impl args;                                                                            \
   TORQUE_API < returnType >::ReturnValueType fn ## name                                                         \
      ( < returnType args >::Args a )                                                                   \
   {                                                                                                                             \
      ( name, returnType );                                                                             \
      return < returnType >::ReturnValue(                                                                        \
         < returnType args >::jmp( _fn ## name ## impl, a )                                             \
      );                                                                                                                         \
   }                                                                                                                             \
   static <  args > _fn ## name ## DefaultArgs defaultArgs;                                   \
   static  _fn ## name ## FunctionInfo(                                                                        \
      #name,                                                                                                                     \
      &<>()(),                                                                                                             \
      usage,                                                                                                                     \
      #returnType " " #name #args,                                                                                               \
      "fn" #name,                                                                                                                \
      < returnType args >(),                                                                                                 \
      &_fn ## name ## DefaultArgs,                                                                                               \
      ( * ) &fn ## name,                                                                                                     \
      0                                                                                                                          \
   );                                                                                                                            \
   static inline returnType _fn ## name ## impl args
DefineNewEngineMethod(className, name, returnType, args, defaultArgs, usage)    struct _ ## className ## name ## frame                                                                                                       \
   {                                                                                                                                            \
      typedef className ObjectType;                                                                                                             \
      className* object;                                                                                                                        \
      inline returnType _exec args ;                                                                                                       \
   };                                                                                                                                           \
   ( className, name, returnType, args );                                                                                \
   static < < _ ## className ## name ## frame,  args >::FunctionType >                \
      _fn ## className ## name ## DefaultArgs defaultArgs;                                                                                      \
   static  _fn ## className ## name ## FunctionInfo(                                                                          \
      #name,                                                                                                                                    \
      &< className >()(),                                                                                                                 \
      usage,                                                                                                                                    \
      "virtual " #returnType " " #name #args,                                                                                                   \
      "fn" #className "_" #name,                                                                                                                \
      < < _ ## className ## name ## frame, returnType args >::FunctionType >(),                                      \
      &_fn ## className ## name ## DefaultArgs,                                                                                                 \
      ( * ) &fn ## className ## _ ## name,                                                                                                  \
      0                                                                                                                                         \
   );                                                                                                                                           \
   returnType _ ## className ## name ## frame::_exec args 
DefineNewEngineStaticMethod(className, name, returnType, args, defaultArgs, usage)    static inline returnType _fn ## className ## name ## impl args;                                                                     \
   TORQUE_API < returnType >::ReturnValueType fn ## className ## _ ## name                                             \
      ( < returnType args >::Args a )                                                                         \
   {                                                                                                                                   \
      ( className::name, returnType );                                                                        \
      return < returnType >::ReturnValue(                                                                              \
         < returnType args >::jmp( _fn ## className ## name ## impl, a )                                      \
      );                                                                                                                               \
   }                                                                                                                                   \
   static <  args > _fn ## className ## name ## DefaultArgs defaultArgs;                            \
   static  _fn ## name ## FunctionInfo(                                                                              \
      #name,                                                                                                                           \
      &< className >()(),                                                                                                        \
      usage,                                                                                                                           \
      #returnType " " #name #args,                                                                                                     \
      "fn" #className "_" #name,                                                                                                       \
      < returnType args >(),                                                                                                       \
      &_fn ## className ## name ## DefaultArgs,                                                                                        \
      ( * ) &fn ## className ## _ ## name,                                                                                         \
      0                                                                                                                                \
   );                                                                                                                                  \
   static inline returnType _fn ## className ## name ## impl args

Marshalling

Functions for converting to/from string-based data representations.

note:

This functionality is specific to the console interop.

EngineMarshallData(bool arg, S32 & argc, ConsoleValueRef * argv)

EngineMarshallData(bool value)

EngineMarshallData(char * arg, S32 & argc, ConsoleValueRef * argv)

EngineMarshallData(const char * arg, S32 & argc, ConsoleValueRef * argv)

EngineMarshallData(const char * str)

EngineMarshallData(const T & arg, S32 & argc, ConsoleValueRef * argv)

Marshal data from native into client form stored directly in client function invocation vector.

EngineMarshallData(const T & value)

Marshal a single piece of data from native into client form.

EngineMarshallData(const T * object)

EngineMarshallData(const T * object, S32 & argc, ConsoleValueRef * argv)

EngineMarshallData(F32 arg, S32 & argc, ConsoleValueRef * argv)

EngineMarshallData(S32 arg, S32 & argc, ConsoleValueRef * argv)

EngineMarshallData(T * object)

EngineMarshallData(T * object, S32 & argc, ConsoleValueRef * argv)

EngineMarshallData(U32 arg, S32 & argc, ConsoleValueRef * argv)

EngineMarshallData(U32 value)

Thunking

Internal functionality for thunks placed between TorqueScript calls of engine functions and their native implementations.

note:

The functionality in this group is specific to the console interop system.

_EngineConsoleThunkReturnValue(bool value)

_EngineConsoleThunkReturnValue(const char * value)

_EngineConsoleThunkReturnValue(const String & str)

_EngineConsoleThunkReturnValue(const T & value)

_EngineConsoleThunkReturnValue(const T * value)

_EngineConsoleThunkReturnValue(F32 value)

_EngineConsoleThunkReturnValue(S32 value)

_EngineConsoleThunkReturnValue(T * value)

Public Defines

IMPLEMENT_CALLBACK(class, name, returnType, args, argNames, usageString) 

Matching implement for DECLARE_CALLBACK.

@warn With the new interop system, method-style callbacks must not be triggered on object that are being created! This is because the control layer will likely not yet have a fully valid wrapper object in place for the EngineObject under construction.

IMPLEMENT_CONSOLE_CALLBACK(class, name, returnType, args, argNames, usageString)    returnType class::name ## _callback args                                                                                                  \
   {                                                                                                                                         \
      (  )                                                                                                    \
      {                                                                                                                                      \
         static  sName = ->insert( #name );                                                                       \
          cbh( sName, this );                                                                                    \
         return returnType( cbh.call< returnType > argNames );                                                                               \
      }                                                                                                                                      \
      return returnType();                                                                                                                   \
   }                                                                                                                                         \
   namespace {                                                                                                                               \
       _ ## class ## name ## header(                                                                                    \
         #returnType, #args, "" );                                                                                                           \
       _ ## class ## name ## obj( #class, #name, usageString, &_ ## class ## name ## header );                             \
   }
IMPLEMENT_GLOBAL_CALLBACK(name, returnType, args, argNames, usageString)    ( cb ## name, name,, returnType, args, 0, usageString );                                                                    \
   returnType name ## _callback args                                                                                                         \
   {                                                                                                                                         \
      ( cb ## name )                                                                                                                       \
         return returnType( cb ## name argNames );                                                                                           \
      (  )                                                                                                    \
      {                                                                                                                                      \
         static  sName = ->insert( #name );                                                                       \
          cbh( sName,  );                                                                                    \
         return returnType( cbh.call< returnType > argNames );                                                                               \
      }                                                                                                                                      \
      return returnType();                                                                                                                   \
   }                                                                                                                                         \
   namespace {                                                                                                                               \
       _ ## name ## header(                                                                                             \
         #returnType, #args, "" );                                                                                                           \
       _ ## name ## obj( , #name, usageString, &_ ## name ## header );                                                 \
   }

Used to define global callbacks not associated with any particular class or namespace.

IMPLEMENT_NEW_CALLBACK(class, name, returnType, args, argNames, usageString)    struct _ ## class ## name ## frame { typedef class ObjectType; };                                                                         \
   TORQUE_API < _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name;               \
   TORQUE_API  set_cb ## class ## _ ## name(                                                                                             \
      < _ ## class ## name ## frame, returnType args >::FunctionType fn )                                             \
      { cb ## class ## _ ## name = fn; }                                                                                                     \
   < _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name;                          \
   namespace {                                                                                                                               \
      :: _cb ## class ## name(                                                                                             \
         #name,                                                                                                                              \
         &::< class >()(),                                                                                                             \
         usageString,                                                                                                                        \
         "virtual " #returnType " " #name #args,                                                                                             \
         "cb" #class "_" #name,                                                                                                              \
         ::< < _ ## class ## name ## frame, returnType args >::FunctionType >(),                                  \
         ,                                                                                                                               \
         &cb ## class ## _ ## name,                                                                                                          \
                                                                                                                        \
      );                                                                                                                                     \
   }                                                                                                                                         \
   returnType class::name ## _callback args                                                                                                  \
   {                                                                                                                                         \
      ( cb ## class ## _ ## name ) {                                                                                                       \
          cbh( this, reinterpret_cast<  * >( cb ## class ## _ ## name ) );                                     \
         return returnType( cbh.call< returnType > argNames );                                                                               \
      }                                                                                                                                      \
      return returnType();                                                                                                                   \
   }

Public Functions

TYPE< const char *>()

   1
   2//-----------------------------------------------------------------------------
   3// Copyright (c) 2012 GarageGames, LLC
   4//
   5// Permission is hereby granted, free of charge, to any person obtaining a copy
   6// of this software and associated documentation files (the "Software"), to
   7// deal in the Software without restriction, including without limitation the
   8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   9// sell copies of the Software, and to permit persons to whom the Software is
  10// furnished to do so, subject to the following conditions:
  11//
  12// The above copyright notice and this permission notice shall be included in
  13// all copies or substantial portions of the Software.
  14//
  15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21// IN THE SOFTWARE.
  22//-----------------------------------------------------------------------------
  23
  24#ifndef _ENGINEAPI_H_
  25#define _ENGINEAPI_H_
  26
  27#ifndef _CONSOLETYPES_H_
  28#include "console/consoleTypes.h"
  29#endif
  30
  31#ifndef _CONSOLE_H_
  32#include "console/console.h"
  33#endif
  34
  35#ifndef _STRINGFUNCTIONS_H_
  36#include "core/strings/stringFunctions.h"
  37#endif
  38
  39#ifndef _SIMOBJECT_H_
  40#include "console/simObject.h"
  41#endif
  42
  43#ifndef _ENGINEFUNCTIONS_H_
  44#include "console/engineFunctions.h"
  45#endif
  46
  47// Whatever types are used in API definitions, their DECLAREs must be visible to the
  48// macros.  We include the basic primitive and struct types here.
  49
  50#ifndef _ENGINEPRIMITIVES_H_
  51   #include "console/enginePrimitives.h"
  52#endif
  53#ifndef _ENGINESTRUCTS_H_
  54   #include "console/engineStructs.h"
  55#endif
  56
  57// Needed for the executef macros. Blame GCC.
  58#ifndef _SIMEVENTS_H_
  59#include "console/simEvents.h"
  60#endif
  61
  62
  63/// @file
  64/// Definitions for exposing engine functionality to the control layer.
  65///
  66/// This file provides a convenience layer around the underlying engine interop system (which at
  67/// the moment still includes the legacy TorqueScript interop a.k.a. "console system").  The
  68/// macros exposed here will automatically take care of all marshalling, value type constraints,
  69/// reflection info instancing, etc. involved in defining engine API call-ins and call-outs.
  70///
  71/// @note At the moment, this file supplies both the legacy TorqueScript console system as well
  72///   as the new engine export system with the structures and information they need.  In the
  73///   near future, the console-based parts will get purged.  This will not result in visible
  74///   changes to users of the functionality here except for the string-based marshalling
  75///   functions currently exposed (which will also disappear).
  76
  77
  78
  79//TODO: Disable warning for extern "C" functions returning UDTs for now; need to take a closer look at this
  80#pragma warning( disable : 4190 )
  81
  82
  83
  84// Disable some VC warnings that are irrelevant to us.
  85#pragma warning( push )
  86#pragma warning( disable : 4510 ) // default constructor could not be generated; all the Args structures are never constructed by us
  87#pragma warning( disable : 4610 ) // can never be instantiated; again Args is never constructed by us
  88
  89
  90namespace engineAPI {
  91
  92   /// Flag for enabling legacy console behavior in the interop system while
  93   /// we still have it around.  Will disappear along with console.
  94   extern bool gUseConsoleInterop;
  95   
  96   /// Flag to allow engine functions to detect whether the engine had been
  97   /// initialized or shut down.
  98   extern bool gIsInitialized;
  99}
 100
 101
 102//FIXME: this allows const char* to be used as a struct field type
 103
 104// Temp support for allowing const char* to remain in the API functions as long as we
 105// still have the console system around.  When that is purged, these definitions should
 106// be deleted and all const char* uses be replaced with String.
 107template<> struct EngineTypeTraits< const char* > : public EngineTypeTraits< String> {};
 108template<> inline const EngineTypeInfo* TYPE< const char*>() { return TYPE< String >(); }
 109
 110
 111
 112
 113
 114
 115/// @name Marshalling
 116///
 117/// Functions for converting to/from string-based data representations.
 118///
 119/// @note This functionality is specific to the console interop.
 120/// @{
 121
 122/// Marshal a single piece of data from native into client form.
 123template< typename T >
 124inline const char* EngineMarshallData( const T& value )
 125{
 126   return castConsoleTypeToString( value );
 127}
 128inline const char* EngineMarshallData( bool value )
 129{
 130   if( value )
 131      return "1";
 132   else
 133      return "0";
 134}
 135inline const char* EngineMarshallData( const char* str )
 136{
 137   // The API assumes that if you pass a plain "const char*" through it, then you are referring
 138   // to string storage with non-local lifetime that can be safely passed to the control layer.
 139   return str;
 140}
 141template< typename T >
 142inline const char* EngineMarshallData( T* object )
 143{
 144   return ( object ? object->getIdString() : "0" );
 145}
 146template< typename T >
 147inline const char* EngineMarshallData( const T* object )
 148{
 149   return ( object ? object->getIdString() : "0" );
 150}
 151inline const char* EngineMarshallData( U32 value )
 152{
 153   return EngineMarshallData( S32( value ) );
 154}
 155
 156/// Marshal data from native into client form stored directly in
 157/// client function invocation vector.
 158template< typename T >
 159inline void EngineMarshallData( const T& arg, S32& argc, ConsoleValueRef *argv )
 160{
 161   argv[ argc ] = castConsoleTypeToString( arg );
 162   argc ++;
 163}
 164inline void EngineMarshallData( bool arg, S32& argc, ConsoleValueRef *argv )
 165{
 166   if( arg )
 167      argv[ argc ] = 1;
 168   else
 169      argv[ argc ] = 0;
 170   argc ++;
 171}
 172inline void EngineMarshallData( S32 arg, S32& argc, ConsoleValueRef *argv )
 173{
 174   argv[ argc ] = arg;
 175   argc ++;
 176}
 177inline void EngineMarshallData( U32 arg, S32& argc, ConsoleValueRef *argv )
 178{
 179   EngineMarshallData( S32( arg ), argc, argv );
 180}
 181inline void EngineMarshallData( F32 arg, S32& argc, ConsoleValueRef *argv )
 182{
 183   argv[ argc ] = arg;
 184   argc ++;
 185}
 186inline void EngineMarshallData( const char* arg, S32& argc, ConsoleValueRef *argv )
 187{
 188   argv[ argc ] = arg;
 189   argc ++;
 190}
 191inline void EngineMarshallData( char* arg, S32& argc, ConsoleValueRef *argv )
 192{
 193   argv[ argc ] = arg;
 194   argc ++;
 195}
 196
 197template< typename T >
 198inline void EngineMarshallData( T* object, S32& argc, ConsoleValueRef *argv )
 199{
 200   argv[ argc ] = object ? object->getId() : 0;
 201   argc ++;
 202}
 203template< typename T >
 204inline void EngineMarshallData( const T* object, S32& argc, ConsoleValueRef *argv )
 205{
 206   argv[ argc ] = object ? object->getId() : 0;
 207   argc ++;
 208}
 209
 210/// Unmarshal data from client form to engine form.
 211///
 212/// This is wrapped in an a struct as partial specializations on function
 213/// templates are not allowed in C++.
 214template< typename T >
 215struct EngineUnmarshallData
 216{
 217   T operator()( const char* str ) const
 218   {
 219      T value;
 220      castConsoleTypeFromString( value, str );
 221      return value;
 222   }
 223};
 224template<>
 225struct EngineUnmarshallData< S32 >
 226{
 227   S32 operator()( ConsoleValueRef &ref ) const
 228   {
 229      return (S32)ref;
 230   }
 231
 232   S32 operator()( const char* str ) const
 233   {
 234      return dAtoi( str );
 235   }
 236};
 237template<>
 238struct EngineUnmarshallData< U32 >
 239{
 240   U32 operator()( ConsoleValueRef &ref ) const
 241   {
 242      return (U32)((S32)ref);
 243   }
 244
 245   U32 operator()( const char* str ) const
 246   {
 247      return dAtoui( str );
 248   }
 249};
 250template<>
 251struct EngineUnmarshallData< F32 >
 252{
 253   F32 operator()( ConsoleValueRef &ref ) const
 254   {
 255      return (F32)ref;
 256   }
 257
 258   F32 operator()( const char* str ) const
 259   {
 260      return dAtof( str );
 261   }
 262};
 263template<>
 264struct EngineUnmarshallData< U8 >
 265{
 266   U8 operator()( ConsoleValueRef &ref ) const
 267   {
 268      return (U8)((S32)ref);
 269   }
 270
 271   U8 operator()( const char* str ) const
 272   {
 273      return dAtoui( str );
 274   }
 275};
 276template<>
 277struct EngineUnmarshallData< const char* >
 278{
 279   const char* operator()( ConsoleValueRef &ref ) const
 280   {
 281      return ref.getStringValue();
 282   }
 283
 284   const char* operator()( const char* str ) const
 285   {
 286      return str;
 287   }
 288};
 289template< typename T >
 290struct EngineUnmarshallData< T* >
 291{
 292   T* operator()( ConsoleValueRef &ref ) const
 293   {
 294      return dynamic_cast< T* >( Sim::findObject( ref.getStringValue() ) );
 295   }
 296
 297   T* operator()( const char* str ) const
 298   {
 299      return dynamic_cast< T* >( Sim::findObject( str ) );
 300   }
 301};
 302template<>
 303struct EngineUnmarshallData< void >
 304{
 305   void operator()( ConsoleValueRef& ) const {}
 306   void operator()( const char* ) const {}
 307};
 308
 309
 310template<>
 311struct EngineUnmarshallData< ConsoleValueRef >
 312{
 313   ConsoleValueRef operator()( ConsoleValueRef ref ) const
 314   {
 315      return ref;
 316   }
 317};
 318
 319/// @}
 320
 321
 322/// @name C to C++ Trampolines
 323///
 324/// The trampolines serve two purposes:
 325///
 326/// For one, they ensure that no matter what argument types are specified by users of the engine API macros, the correct
 327/// argument value types are enforced on the functions exported by the engine.  Let's say, for example, the user writes
 328/// a function that takes a "Point3F direction" argument, then the template machinery here will automatically expose an
 329/// API function that takes a "Point3F& direction" argument.
 330///
 331/// Secondly, the templates jump the incoming calls from extern "C" space into C++ space.  This is mostly relevant for
 332/// methods only as they will need an implicit object type argument.
 333///
 334/// @{
 335
 336// Helper type to factor out commonalities between function and method trampolines.
 337template< typename T >
 338struct _EngineTrampoline
 339{
 340   struct Args {};
 341};
 342
 343template< typename R, typename A >
 344struct _EngineTrampoline< R( A ) >
 345{
 346   struct Args
 347   {
 348      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ];
 349
 350      typename EngineTypeTraits< A >::ValueType a() const
 351      {
 352         return EngineTypeTraits< A >::ArgumentToValue(
 353            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 354               ( &data[ 0 ] ) ) );
 355      }
 356   };
 357};
 358
 359template< typename R, typename A, typename B >
 360struct _EngineTrampoline< R( A, B ) >
 361{
 362   struct Args
 363   {
 364      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 365                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ];
 366
 367      typename EngineTypeTraits< A >::ValueType a() const
 368      {
 369         return EngineTypeTraits< A >::ArgumentToValue(
 370            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 371               ( &data[ 0 ] ) ) );
 372      }
 373
 374      typename EngineTypeTraits< B >::ValueType b() const
 375      {
 376         return EngineTypeTraits< B >::ArgumentToValue(
 377            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 378               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 379      }
 380   };
 381};
 382
 383template< typename R, typename A, typename B, typename C >
 384struct _EngineTrampoline< R( A, B, C ) >
 385{
 386   struct Args
 387   {
 388      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 389                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 390                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ];
 391
 392      typename EngineTypeTraits< A >::ValueType a() const
 393      {
 394         return EngineTypeTraits< A >::ArgumentToValue(
 395            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 396               ( &data[ 0 ] ) ) );
 397      }
 398
 399      typename EngineTypeTraits< B >::ValueType b() const
 400      {
 401         return EngineTypeTraits< B >::ArgumentToValue(
 402            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 403               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 404      }
 405
 406      typename EngineTypeTraits< C >::ValueType c() const
 407      {
 408         return EngineTypeTraits< C >::ArgumentToValue(
 409            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
 410               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 411                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
 412      }
 413   };
 414};
 415
 416template< typename R, typename A, typename B, typename C, typename D >
 417struct _EngineTrampoline< R( A, B, C, D ) >
 418{
 419   struct Args
 420   {
 421      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 422                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 423                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 424                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ];
 425
 426      typename EngineTypeTraits< A >::ValueType a() const
 427      {
 428         return EngineTypeTraits< A >::ArgumentToValue(
 429            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 430               ( &data[ 0 ] ) ) );
 431      }
 432
 433      typename EngineTypeTraits< B >::ValueType b() const
 434      {
 435         return EngineTypeTraits< B >::ArgumentToValue(
 436            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 437               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 438      }
 439
 440      typename EngineTypeTraits< C >::ValueType c() const
 441      {
 442         return EngineTypeTraits< C >::ArgumentToValue(
 443            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
 444               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 445                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
 446      }
 447
 448      typename EngineTypeTraits< D >::ValueType d() const
 449      {
 450         return EngineTypeTraits< D >::ArgumentToValue(
 451            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
 452               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 453                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 454                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
 455      }
 456   };
 457};
 458
 459template< typename R, typename A, typename B, typename C, typename D, typename E >
 460struct _EngineTrampoline< R( A, B, C, D, E ) >
 461{
 462   struct Args
 463   {
 464      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 465                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 466                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 467                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 468                 sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ];
 469
 470      typename EngineTypeTraits< A >::ValueType a() const
 471      {
 472         return EngineTypeTraits< A >::ArgumentToValue(
 473            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 474               ( &data[ 0 ] ) ) );
 475      }
 476
 477      typename EngineTypeTraits< B >::ValueType b() const
 478      {
 479         return EngineTypeTraits< B >::ArgumentToValue(
 480            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 481               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 482      }
 483
 484      typename EngineTypeTraits< C >::ValueType c() const
 485      {
 486         return EngineTypeTraits< C >::ArgumentToValue(
 487            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
 488               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 489                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
 490      }
 491
 492      typename EngineTypeTraits< D >::ValueType d() const
 493      {
 494         return EngineTypeTraits< D >::ArgumentToValue(
 495            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
 496               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 497                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 498                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
 499      }
 500
 501      typename EngineTypeTraits< E >::ValueType e() const
 502      {
 503         return EngineTypeTraits< E >::ArgumentToValue(
 504            *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* >
 505               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 506                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 507                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 508                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) );
 509      }
 510   };
 511};
 512
 513template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
 514struct _EngineTrampoline< R( A, B, C, D, E, F ) >
 515{
 516   struct Args
 517   {
 518      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 519                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 520                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 521                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 522                 sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 523                 sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ];
 524
 525      typename EngineTypeTraits< A >::ValueType a() const
 526      {
 527         return EngineTypeTraits< A >::ArgumentToValue(
 528            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 529               ( &data[ 0 ] ) ) );
 530      }
 531
 532      typename EngineTypeTraits< B >::ValueType b() const
 533      {
 534         return EngineTypeTraits< B >::ArgumentToValue(
 535            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 536               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 537      }
 538
 539      typename EngineTypeTraits< C >::ValueType c() const
 540      {
 541         return EngineTypeTraits< C >::ArgumentToValue(
 542            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
 543               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 544                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
 545      }
 546
 547      typename EngineTypeTraits< D >::ValueType d() const
 548      {
 549         return EngineTypeTraits< D >::ArgumentToValue(
 550            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
 551               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 552                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 553                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
 554      }
 555
 556      typename EngineTypeTraits< E >::ValueType e() const
 557      {
 558         return EngineTypeTraits< E >::ArgumentToValue(
 559            *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* >
 560               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 561                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 562                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 563                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) );
 564      }
 565
 566      typename EngineTypeTraits< F >::ValueType f() const
 567      {
 568         return EngineTypeTraits< F >::ArgumentToValue(
 569            *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* >
 570               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 571                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 572                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 573                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 574                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) );
 575      }
 576   };
 577};
 578
 579template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
 580struct _EngineTrampoline< R( A, B, C, D, E, F, G ) >
 581{
 582   struct Args
 583   {
 584      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 585                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 586                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 587                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 588                 sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 589                 sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 590                 sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ];
 591
 592      typename EngineTypeTraits< A >::ValueType a() const
 593      {
 594         return EngineTypeTraits< A >::ArgumentToValue(
 595            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 596               ( &data[ 0 ] ) ) );
 597      }
 598
 599      typename EngineTypeTraits< B >::ValueType b() const
 600      {
 601         return EngineTypeTraits< B >::ArgumentToValue(
 602            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 603               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 604      }
 605
 606      typename EngineTypeTraits< C >::ValueType c() const
 607      {
 608         return EngineTypeTraits< C >::ArgumentToValue(
 609            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
 610               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 611                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
 612      }
 613
 614      typename EngineTypeTraits< D >::ValueType d() const
 615      {
 616         return EngineTypeTraits< D >::ArgumentToValue(
 617            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
 618               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 619                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 620                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
 621      }
 622
 623      typename EngineTypeTraits< E >::ValueType e() const
 624      {
 625         return EngineTypeTraits< E >::ArgumentToValue(
 626            *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* >
 627               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 628                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 629                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 630                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) );
 631      }
 632
 633      typename EngineTypeTraits< F >::ValueType f() const
 634      {
 635         return EngineTypeTraits< F >::ArgumentToValue(
 636            *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* >
 637               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 638                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 639                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 640                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 641                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) );
 642      }
 643
 644      typename EngineTypeTraits< G >::ValueType g() const
 645      {
 646         return EngineTypeTraits< G >::ArgumentToValue(
 647            *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* >
 648               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 649                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 650                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 651                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 652                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 653                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) );
 654      }
 655   };
 656};
 657
 658template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
 659struct _EngineTrampoline< R( A, B, C, D, E, F, G, H ) >
 660{
 661   struct Args
 662   {
 663      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 664                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 665                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 666                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 667                 sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 668                 sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 669                 sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
 670                 sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ];
 671
 672      typename EngineTypeTraits< A >::ValueType a() const
 673      {
 674         return EngineTypeTraits< A >::ArgumentToValue(
 675            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 676               ( &data[ 0 ] ) ) );
 677      }
 678
 679      typename EngineTypeTraits< B >::ValueType b() const
 680      {
 681         return EngineTypeTraits< B >::ArgumentToValue(
 682            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 683               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 684      }
 685
 686      typename EngineTypeTraits< C >::ValueType c() const
 687      {
 688         return EngineTypeTraits< C >::ArgumentToValue(
 689            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
 690               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 691                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
 692      }
 693
 694      typename EngineTypeTraits< D >::ValueType d() const
 695      {
 696         return EngineTypeTraits< D >::ArgumentToValue(
 697            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
 698               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 699                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 700                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
 701      }
 702
 703      typename EngineTypeTraits< E >::ValueType e() const
 704      {
 705         return EngineTypeTraits< E >::ArgumentToValue(
 706            *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* >
 707               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 708                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 709                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 710                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) );
 711      }
 712
 713      typename EngineTypeTraits< F >::ValueType f() const
 714      {
 715         return EngineTypeTraits< F >::ArgumentToValue(
 716            *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* >
 717               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 718                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 719                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 720                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 721                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) );
 722      }
 723
 724      typename EngineTypeTraits< G >::ValueType g() const
 725      {
 726         return EngineTypeTraits< G >::ArgumentToValue(
 727            *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* >
 728               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 729                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 730                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 731                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 732                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 733                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) );
 734      }
 735
 736      typename EngineTypeTraits< H >::ValueType h() const
 737      {
 738         return EngineTypeTraits< H >::ArgumentToValue(
 739            *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* >
 740               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 741                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 742                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 743                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 744                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 745                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 746                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) );
 747      }
 748   };
 749};
 750
 751template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
 752struct _EngineTrampoline< R( A, B, C, D, E, F, G, H, I ) >
 753{
 754   struct Args
 755   {
 756      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 757                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 758                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 759                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 760                 sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 761                 sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 762                 sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
 763                 sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
 764                 sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) ];
 765
 766      typename EngineTypeTraits< A >::ValueType a() const
 767      {
 768         return EngineTypeTraits< A >::ArgumentToValue(
 769            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 770               ( &data[ 0 ] ) ) );
 771      }
 772
 773      typename EngineTypeTraits< B >::ValueType b() const
 774      {
 775         return EngineTypeTraits< B >::ArgumentToValue(
 776            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 777               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 778      }
 779
 780      typename EngineTypeTraits< C >::ValueType c() const
 781      {
 782         return EngineTypeTraits< C >::ArgumentToValue(
 783            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
 784               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 785                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
 786      }
 787
 788      typename EngineTypeTraits< D >::ValueType d() const
 789      {
 790         return EngineTypeTraits< D >::ArgumentToValue(
 791            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
 792               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 793                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 794                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
 795      }
 796
 797      typename EngineTypeTraits< E >::ValueType e() const
 798      {
 799         return EngineTypeTraits< E >::ArgumentToValue(
 800            *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* >
 801               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 802                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 803                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 804                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) );
 805      }
 806
 807      typename EngineTypeTraits< F >::ValueType f() const
 808      {
 809         return EngineTypeTraits< F >::ArgumentToValue(
 810            *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* >
 811               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 812                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 813                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 814                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 815                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) );
 816      }
 817
 818      typename EngineTypeTraits< G >::ValueType g() const
 819      {
 820         return EngineTypeTraits< G >::ArgumentToValue(
 821            *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* >
 822               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 823                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 824                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 825                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 826                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 827                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) );
 828      }
 829
 830      typename EngineTypeTraits< H >::ValueType h() const
 831      {
 832         return EngineTypeTraits< H >::ArgumentToValue(
 833            *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* >
 834               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 835                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 836                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 837                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 838                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 839                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 840                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) );
 841      }
 842
 843      typename EngineTypeTraits< I >::ValueType i() const
 844      {
 845         return EngineTypeTraits< I >::ArgumentToValue(
 846            *( reinterpret_cast< const typename EngineTypeTraits< I >::ArgumentValueType* >
 847               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 848                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 849                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 850                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 851                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 852                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 853                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
 854                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ] ) ) );
 855      }
 856   };
 857};
 858
 859template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
 860struct _EngineTrampoline< R( A, B, C, D, E, F, G, H, I, J ) >
 861{
 862   struct Args
 863   {
 864      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 865                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 866                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 867                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 868                 sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 869                 sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 870                 sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
 871                 sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
 872                 sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) +
 873                 sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) ];
 874
 875      typename EngineTypeTraits< A >::ValueType a() const
 876      {
 877         return EngineTypeTraits< A >::ArgumentToValue(
 878            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
 879               ( &data[ 0 ] ) ) );
 880      }
 881
 882      typename EngineTypeTraits< B >::ValueType b() const
 883      {
 884         return EngineTypeTraits< B >::ArgumentToValue(
 885            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
 886               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
 887      }
 888
 889      typename EngineTypeTraits< C >::ValueType c() const
 890      {
 891         return EngineTypeTraits< C >::ArgumentToValue(
 892            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
 893               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 894                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
 895      }
 896
 897      typename EngineTypeTraits< D >::ValueType d() const
 898      {
 899         return EngineTypeTraits< D >::ArgumentToValue(
 900            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
 901               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 902                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 903                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
 904      }
 905
 906      typename EngineTypeTraits< E >::ValueType e() const
 907      {
 908         return EngineTypeTraits< E >::ArgumentToValue(
 909            *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* >
 910               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 911                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 912                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 913                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) );
 914      }
 915
 916      typename EngineTypeTraits< F >::ValueType f() const
 917      {
 918         return EngineTypeTraits< F >::ArgumentToValue(
 919            *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* >
 920               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 921                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 922                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 923                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 924                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) );
 925      }
 926
 927      typename EngineTypeTraits< G >::ValueType g() const
 928      {
 929         return EngineTypeTraits< G >::ArgumentToValue(
 930            *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* >
 931               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 932                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 933                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 934                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 935                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 936                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) );
 937      }
 938
 939      typename EngineTypeTraits< H >::ValueType h() const
 940      {
 941         return EngineTypeTraits< H >::ArgumentToValue(
 942            *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* >
 943               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 944                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 945                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 946                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 947                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 948                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 949                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) );
 950      }
 951
 952      typename EngineTypeTraits< I >::ValueType i() const
 953      {
 954         return EngineTypeTraits< I >::ArgumentToValue(
 955            *( reinterpret_cast< const typename EngineTypeTraits< I >::ArgumentValueType* >
 956               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 957                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 958                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 959                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 960                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 961                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 962                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
 963                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ] ) ) );
 964      }
 965
 966      typename EngineTypeTraits< J >::ValueType j() const
 967      {
 968         return EngineTypeTraits< J >::ArgumentToValue(
 969            *( reinterpret_cast< const typename EngineTypeTraits< J >::ArgumentValueType* >
 970               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 971                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 972                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 973                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 974                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 975                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 976                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
 977                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
 978                        sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) ] ) ) );
 979      }
 980   };
 981};
 982
 983template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
 984struct _EngineTrampoline< R( A, B, C, D, E, F, G, H, I, J, K ) >
 985{
 986   struct Args
 987   {
 988      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
 989                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
 990                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
 991                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
 992                 sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
 993                 sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
 994                 sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
 995                 sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
 996                 sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) +
 997                 sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) +
 998                 sizeof( typename EngineTypeTraits< K >::ArgumentValueType ) ];
 999
1000      typename EngineTypeTraits< A >::ValueType a() const
1001      {
1002         return EngineTypeTraits< A >::ArgumentToValue(
1003            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
1004               ( &data[ 0 ] ) ) );
1005      }
1006
1007      typename EngineTypeTraits< B >::ValueType b() const
1008      {
1009         return EngineTypeTraits< B >::ArgumentToValue(
1010            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
1011               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
1012      }
1013
1014      typename EngineTypeTraits< C >::ValueType c() const
1015      {
1016         return EngineTypeTraits< C >::ArgumentToValue(
1017            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
1018               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1019                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
1020      }
1021
1022      typename EngineTypeTraits< D >::ValueType d() const
1023      {
1024         return EngineTypeTraits< D >::ArgumentToValue(
1025            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
1026               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1027                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1028                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
1029      }
1030
1031      typename EngineTypeTraits< E >::ValueType e() const
1032      {
1033         return EngineTypeTraits< E >::ArgumentToValue(
1034            *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* >
1035               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1036                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1037                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1038                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) );
1039      }
1040
1041      typename EngineTypeTraits< F >::ValueType f() const
1042      {
1043         return EngineTypeTraits< F >::ArgumentToValue(
1044            *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* >
1045               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1046                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1047                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1048                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1049                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) );
1050      }
1051
1052      typename EngineTypeTraits< G >::ValueType g() const
1053      {
1054         return EngineTypeTraits< G >::ArgumentToValue(
1055            *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* >
1056               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1057                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1058                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1059                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1060                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1061                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) );
1062      }
1063
1064      typename EngineTypeTraits< H >::ValueType h() const
1065      {
1066         return EngineTypeTraits< H >::ArgumentToValue(
1067            *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* >
1068               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1069                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1070                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1071                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1072                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1073                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1074                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) );
1075      }
1076
1077      typename EngineTypeTraits< I >::ValueType i() const
1078      {
1079         return EngineTypeTraits< I >::ArgumentToValue(
1080            *( reinterpret_cast< const typename EngineTypeTraits< I >::ArgumentValueType* >
1081               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1082                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1083                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1084                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1085                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1086                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1087                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
1088                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ] ) ) );
1089      }
1090
1091      typename EngineTypeTraits< J >::ValueType j() const
1092      {
1093         return EngineTypeTraits< J >::ArgumentToValue(
1094            *( reinterpret_cast< const typename EngineTypeTraits< J >::ArgumentValueType* >
1095               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1096                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1097                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1098                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1099                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1100                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1101                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
1102                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
1103                        sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) ] ) ) );
1104      }
1105
1106      typename EngineTypeTraits< K >::ValueType k() const
1107      {
1108         return EngineTypeTraits< K >::ArgumentToValue(
1109            *( reinterpret_cast< const typename EngineTypeTraits< K >::ArgumentValueType* >
1110               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1111                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1112                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1113                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1114                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1115                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1116                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
1117                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
1118                        sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) +
1119                        sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) ] ) ) );
1120      }
1121   };
1122};
1123
1124template< 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 >
1125struct _EngineTrampoline< R( A, B, C, D, E, F, G, H, I, J, K, L ) >
1126{
1127   struct Args
1128   {
1129      char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1130                 sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1131                 sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1132                 sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1133                 sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1134                 sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1135                 sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
1136                 sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
1137                 sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) +
1138                 sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) +
1139                 sizeof( typename EngineTypeTraits< K >::ArgumentValueType ) +
1140                 sizeof( typename EngineTypeTraits< L >::ArgumentValueType ) ];
1141
1142      typename EngineTypeTraits< A >::ValueType a() const
1143      {
1144         return EngineTypeTraits< A >::ArgumentToValue(
1145            *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* >
1146               ( &data[ 0 ] ) ) );
1147      }
1148
1149      typename EngineTypeTraits< B >::ValueType b() const
1150      {
1151         return EngineTypeTraits< B >::ArgumentToValue(
1152            *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* >
1153               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) );
1154      }
1155
1156      typename EngineTypeTraits< C >::ValueType c() const
1157      {
1158         return EngineTypeTraits< C >::ArgumentToValue(
1159            *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* >
1160               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1161                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) );
1162      }
1163
1164      typename EngineTypeTraits< D >::ValueType d() const
1165      {
1166         return EngineTypeTraits< D >::ArgumentToValue(
1167            *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* >
1168               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1169                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1170                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) );
1171      }
1172
1173      typename EngineTypeTraits< E >::ValueType e() const
1174      {
1175         return EngineTypeTraits< E >::ArgumentToValue(
1176            *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* >
1177               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1178                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1179                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1180                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) );
1181      }
1182
1183      typename EngineTypeTraits< F >::ValueType f() const
1184      {
1185         return EngineTypeTraits< F >::ArgumentToValue(
1186            *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* >
1187               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1188                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1189                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1190                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1191                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) );
1192      }
1193
1194      typename EngineTypeTraits< G >::ValueType g() const
1195      {
1196         return EngineTypeTraits< G >::ArgumentToValue(
1197            *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* >
1198               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1199                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1200                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1201                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1202                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1203                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) );
1204      }
1205
1206      typename EngineTypeTraits< H >::ValueType h() const
1207      {
1208         return EngineTypeTraits< H >::ArgumentToValue(
1209            *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* >
1210               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1211                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1212                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1213                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1214                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1215                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1216                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) );
1217      }
1218
1219      typename EngineTypeTraits< I >::ValueType i() const
1220      {
1221         return EngineTypeTraits< I >::ArgumentToValue(
1222            *( reinterpret_cast< const typename EngineTypeTraits< I >::ArgumentValueType* >
1223               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1224                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1225                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1226                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1227                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1228                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1229                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
1230                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ] ) ) );
1231      }
1232
1233      typename EngineTypeTraits< J >::ValueType j() const
1234      {
1235         return EngineTypeTraits< J >::ArgumentToValue(
1236            *( reinterpret_cast< const typename EngineTypeTraits< J >::ArgumentValueType* >
1237               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1238                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1239                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1240                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1241                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1242                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1243                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
1244                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
1245                        sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) ] ) ) );
1246      }
1247
1248      typename EngineTypeTraits< K >::ValueType k() const
1249      {
1250         return EngineTypeTraits< K >::ArgumentToValue(
1251            *( reinterpret_cast< const typename EngineTypeTraits< K >::ArgumentValueType* >
1252               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1253                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1254                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1255                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1256                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1257                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1258                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
1259                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
1260                        sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) +
1261                        sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) ] ) ) );
1262      }
1263
1264      typename EngineTypeTraits< L >::ValueType l() const
1265      {
1266         return EngineTypeTraits< L >::ArgumentToValue(
1267            *( reinterpret_cast< const typename EngineTypeTraits< L >::ArgumentValueType* >
1268               ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) +
1269                        sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) +
1270                        sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) +
1271                        sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) +
1272                        sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) +
1273                        sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) +
1274                        sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) +
1275                        sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) +
1276                        sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) +
1277                        sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) +
1278                        sizeof( typename EngineTypeTraits< K >::ArgumentValueType ) ] ) ) );
1279      }
1280   };
1281};
1282
1283
1284template< typename T >
1285struct _EngineFunctionTrampolineBase : public _EngineTrampoline< T >
1286{
1287   typedef T FunctionType;
1288};
1289
1290// Trampolines for any call-ins that aren't methods.
1291template< typename T >
1292struct _EngineFunctionTrampoline {};
1293
1294template< typename R >
1295struct _EngineFunctionTrampoline< R() > : public _EngineFunctionTrampolineBase< R() >
1296{
1297   static R jmp( R ( *fn )(), const typename _EngineFunctionTrampolineBase< R() >::Args& args )
1298   {
1299      return R( fn() );
1300   }
1301};
1302
1303
1304template< typename R, typename A >
1305struct _EngineFunctionTrampoline< R( A ) > : public _EngineFunctionTrampolineBase< R( A ) >
1306{
1307   static R jmp( R ( *fn )( A ), const typename _EngineFunctionTrampolineBase< R( A ) >::Args& args )
1308   {
1309      return R( fn( args.a() ) );
1310   }
1311};
1312
1313template< typename R, typename A, typename B >
1314struct _EngineFunctionTrampoline< R( A, B ) > : public _EngineFunctionTrampolineBase< R( A, B ) >
1315{
1316   static R jmp( R ( *fn )( A, B ), const typename _EngineFunctionTrampolineBase< R( A, B ) >::Args& args )
1317   {
1318      return R( fn( args.a(), args.b() ) );
1319   }
1320};
1321
1322template< typename R, typename A, typename B, typename C >
1323struct _EngineFunctionTrampoline< R( A, B, C ) > : public _EngineFunctionTrampolineBase< R( A, B, C ) >
1324{
1325   static R jmp( R ( *fn )( A, B, C ), const typename _EngineFunctionTrampolineBase< R( A, B, C ) >::Args& args )
1326   {
1327      return R( fn( args.a(), args.b(), args.c() ) );
1328   }
1329};
1330
1331template< typename R, typename A, typename B, typename C, typename D >
1332struct _EngineFunctionTrampoline< R( A, B, C, D ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D ) >
1333{
1334   static R jmp( R ( *fn )( A, B, C, D ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D ) >::Args& args )
1335   {
1336      return R( fn( args.a(), args.b(), args.c(), args.d() ) );
1337   }
1338};
1339
1340template< typename R, typename A, typename B, typename C, typename D, typename E >
1341struct _EngineFunctionTrampoline< R( A, B, C, D, E ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E ) >
1342{
1343   static R jmp( R ( *fn )( A, B, C, D, E ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E ) >::Args& args )
1344   {
1345      return R( fn( args.a(), args.b(), args.c(), args.d(), args.e() ) );
1346   }
1347};
1348
1349template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
1350struct _EngineFunctionTrampoline< R( A, B, C, D, E, F ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F ) >
1351{
1352   static R jmp( R ( *fn )( A, B, C, D, E, F ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F ) >::Args& args )
1353   {
1354      return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f() ) );
1355   }
1356};
1357
1358template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
1359struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G ) >
1360{
1361   static R jmp( R ( *fn )( A, B, C, D, E, F, G ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G ) >::Args& args )
1362   {
1363      return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g() ) );
1364   }
1365};
1366
1367template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
1368struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H ) >
1369{
1370   static R jmp( R ( *fn )( A, B, C, D, E, F, G, H ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H ) >::Args& args )
1371   {
1372      return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h() ) );
1373   }
1374};
1375
1376template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
1377struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H, I ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I ) >
1378{
1379   static R jmp( R ( *fn )( A, B, C, D, E, F, G, H, I ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I ) >::Args& args )
1380   {
1381      return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i() ) );
1382   }
1383};
1384
1385template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
1386struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H, I, J ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J ) >
1387{
1388   static R jmp( R ( *fn )( A, B, C, D, E, F, G, H, I, J ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J ) >::Args& args )
1389   {
1390      return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j() ) );
1391   }
1392};
1393
1394template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
1395struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H, I, J, K ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K ) >
1396{
1397   static R jmp( R ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K ) >::Args& args )
1398   {
1399      return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j(), args.k() ) );
1400   }
1401};
1402
1403template< 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 >
1404struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H, I, J, K, L ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K, L ) >
1405{
1406   static R jmp( R ( *fn )( A, B, C, D, E, F, G, H, I, J, K, L ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K, L ) >::Args& args )
1407   {
1408      return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j(), args.k(), args.l() ) );
1409   }
1410};
1411
1412
1413// Trampolines for engine methods
1414
1415template< typename T >
1416struct _EngineMethodTrampolineBase : public _EngineTrampoline< T > {};
1417
1418template< typename Frame, typename T >
1419struct _EngineMethodTrampoline {};
1420
1421template< typename Frame, typename R >
1422struct _EngineMethodTrampoline< Frame, R() > : public _EngineMethodTrampolineBase< R() >
1423{
1424   typedef R( FunctionType )( typename Frame::ObjectType* );
1425   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R() >::Args& args )
1426   {
1427      Frame f;
1428      f.object = object;
1429      return R( f._exec() );
1430   }
1431};
1432
1433
1434template< typename Frame, typename R, typename A >
1435struct _EngineMethodTrampoline< Frame, R( A ) > : public _EngineMethodTrampolineBase< R( A ) >
1436{
1437   typedef R( FunctionType )( typename Frame::ObjectType*, A );
1438   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A ) >::Args& args )
1439   {
1440      Frame f;
1441      f.object = object;
1442      return R( f._exec( args.a() ) );
1443   }
1444};
1445
1446template< typename Frame, typename R, typename A, typename B >
1447struct _EngineMethodTrampoline< Frame, R( A, B ) > : public _EngineMethodTrampolineBase< R( A, B ) >
1448{
1449   typedef R( FunctionType )( typename Frame::ObjectType*, A, B );
1450   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B ) >::Args& args )
1451   {
1452      Frame f;
1453      f.object = object;
1454      return R( f._exec( args.a(), args.b() ) );
1455   }
1456};
1457
1458template< typename Frame, typename R, typename A, typename B, typename C >
1459struct _EngineMethodTrampoline< Frame, R( A, B, C ) > : public _EngineMethodTrampolineBase< R( A, B, C ) >
1460{
1461   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C );
1462   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C ) >::Args& args )
1463   {
1464      Frame f;
1465      f.object = object;
1466      return R( f._exec( args.a(), args.b(), args.c() ) );
1467   }
1468};
1469
1470template< typename Frame, typename R, typename A, typename B, typename C, typename D >
1471struct _EngineMethodTrampoline< Frame, R( A, B, C, D ) > : public _EngineMethodTrampolineBase< R( A, B, C, D ) >
1472{
1473   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D );
1474   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D ) >::Args& args )
1475   {
1476      Frame f;
1477      f.object = object;
1478      return R( f._exec( args.a(), args.b(), args.c(), args.d() ) );
1479   }
1480};
1481
1482template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E >
1483struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E ) >
1484{
1485   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E );
1486   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E ) >::Args& args )
1487   {
1488      Frame f;
1489      f.object = object;
1490      return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e() ) );
1491   }
1492};
1493
1494template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F >
1495struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F ) >
1496{
1497   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F );
1498   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F ) >::Args& args )
1499   {
1500      Frame f;
1501      f.object = object;
1502      return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f() ) );
1503   }
1504};
1505
1506template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
1507struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G ) >
1508{
1509   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G );
1510   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G ) >::Args& args )
1511   {
1512      Frame f;
1513      f.object = object;
1514      return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g() ) );
1515   }
1516};
1517
1518template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
1519struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H ) >
1520{
1521   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H );
1522   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H ) >::Args& args )
1523   {
1524      Frame f;
1525      f.object = object;
1526      return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h() ) );
1527   }
1528};
1529
1530template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
1531struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H, I ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H, I ) >
1532{
1533   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I );
1534   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I ) >::Args& args )
1535   {
1536      Frame f;
1537      f.object = object;
1538      return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i() ) );
1539   }
1540};
1541
1542template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
1543struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H, I, J ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H, I, J ) >
1544{
1545   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J );
1546   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J ) >::Args& args )
1547   {
1548      Frame f;
1549      f.object = object;
1550      return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j() ) );
1551   }
1552};
1553
1554template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
1555struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H, I, J, K ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K ) >
1556{
1557   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K );
1558   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K ) >::Args& args )
1559   {
1560      Frame f;
1561      f.object = object;
1562      return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j(), args.k() ) );
1563   }
1564};
1565
1566template< typename Frame, 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 >
1567struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H, I, J, K, L ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K, L ) >
1568{
1569   typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K, L );
1570   static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K, L ) >::Args& args )
1571   {
1572      Frame f;
1573      f.object = object;
1574      return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j(), args.k(), args.l() ) );
1575   }
1576};
1577
1578
1579
1580/// @}
1581
1582
1583/// @name Thunking
1584///
1585/// Internal functionality for thunks placed between TorqueScript calls of engine functions and their native
1586/// implementations.
1587///
1588/// @note The functionality in this group is specific to the console interop system.
1589/// @{
1590
1591
1592// Helper function to return data from a thunk.
1593template< typename T >
1594inline const char* _EngineConsoleThunkReturnValue( const T& value )
1595{
1596   return EngineMarshallData( value );
1597}
1598inline bool _EngineConsoleThunkReturnValue( bool value )
1599{
1600   return value;
1601}
1602inline S32 _EngineConsoleThunkReturnValue( S32 value )
1603{
1604   return value;
1605}
1606inline F32 _EngineConsoleThunkReturnValue( F32 value )
1607{
1608   return value;
1609}
1610inline const char* _EngineConsoleThunkReturnValue( const String& str )
1611{
1612   return Con::getReturnBuffer( str );
1613}
1614inline const char* _EngineConsoleThunkReturnValue( const char* value )
1615{
1616   return EngineMarshallData( value );
1617}
1618template< typename T >
1619inline const char* _EngineConsoleThunkReturnValue( T* value )
1620{
1621   return ( value ? value->getIdString() : "" );
1622}
1623template< typename T >
1624inline const char* _EngineConsoleThunkReturnValue( const T* value )
1625{
1626   return ( value ? value->getIdString() : "" );
1627}
1628
1629
1630
1631// Helper class to determine the type of callback registered with the console system.
1632template< typename R >
1633struct _EngineConsoleThunkType
1634{
1635   typedef const char* ReturnType;
1636   typedef StringCallback CallbackType;
1637};
1638template<>
1639struct _EngineConsoleThunkType< S32 >
1640{
1641   typedef S32 ReturnType;
1642   typedef IntCallback CallbackType;
1643};
1644template<>
1645struct _EngineConsoleThunkType< U32 >
1646{
1647   typedef U32 ReturnType;
1648   typedef IntCallback CallbackType;
1649};
1650template<>
1651struct _EngineConsoleThunkType< F32 >
1652{
1653   typedef F32 ReturnType;
1654   typedef FloatCallback CallbackType;
1655};
1656template<>
1657struct _EngineConsoleThunkType< bool >
1658{
1659   typedef bool ReturnType;
1660   typedef BoolCallback CallbackType;
1661};
1662template<>
1663struct _EngineConsoleThunkType< void >
1664{
1665   typedef void ReturnType;
1666   typedef VoidCallback CallbackType;
1667};
1668
1669
1670// Helper struct to count the number of parameters in a function list.
1671// The setup through operator () allows omitting the the argument list entirely.
1672struct _EngineConsoleThunkCountArgs
1673{
1674
1675   template< typename A >
1676   U32 operator ()( A a )
1677   {
1678      return 1;
1679   }
1680
1681   template< typename A, typename B >
1682   U32 operator ()( A a, B b )
1683   {
1684      return 2;
1685   }
1686
1687   template< typename A, typename B, typename C >
1688   U32 operator ()( A a, B b, C c )
1689   {
1690      return 3;
1691   }
1692
1693   template< typename A, typename B, typename C, typename D >
1694   U32 operator ()( A a, B b, C c, D d )
1695   {
1696      return 4;
1697   }
1698
1699   template< typename A, typename B, typename C, typename D, typename E >
1700   U32 operator ()( A a, B b, C c, D d, E e )
1701   {
1702      return 5;
1703   }
1704
1705   template< typename A, typename B, typename C, typename D, typename E, typename F >
1706   U32 operator ()( A a, B b, C c, D d, E e, F f )
1707   {
1708      return 6;
1709   }
1710
1711   template< typename A, typename B, typename C, typename D, typename E, typename F, typename G >
1712   U32 operator ()( A a, B b, C c, D d, E e, F f, G g )
1713   {
1714      return 7;
1715   }
1716
1717   template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
1718   U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h )
1719   {
1720      return 8;
1721   }
1722
1723   template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
1724   U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h, I i )
1725   {
1726      return 9;
1727   }
1728
1729   template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
1730   U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
1731   {
1732      return 10;
1733   }
1734
1735   template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
1736   U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
1737   {
1738      return 11;
1739   }
1740
1741   template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L >
1742   U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l )
1743   {
1744      return 12;
1745   }
1746
1747   
1748   operator U32() const
1749   {
1750      return 0;
1751   }
1752};
1753
1754
1755
1756
1757// Encapsulation of a legacy console function invocation.
1758
1759template< S32 startArgc, typename T >
1760struct _EngineConsoleThunk {};
1761
1762template< S32 startArgc, typename R >
1763struct _EngineConsoleThunk< startArgc, R() >
1764{
1765   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
1766   static const S32 NUM_ARGS = 0;
1767   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
1768   {
1769      return _EngineConsoleThunkReturnValue( fn() );
1770   }
1771   template< typename Frame >
1772   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
1773   {
1774      return _EngineConsoleThunkReturnValue( ( frame->*fn )() );
1775   }
1776};
1777
1778template< S32 startArgc >
1779struct _EngineConsoleThunk< startArgc, void() >
1780{
1781   typedef void ReturnType;
1782   static const S32 NUM_ARGS = 0;
1783   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )(), const _EngineFunctionDefaultArguments< void() >& )
1784   {
1785      fn();
1786   }
1787   template< typename Frame >
1788   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& )
1789   {
1790      return ( frame->*fn )();
1791   }
1792};
1793
1794
1795
1796template< S32 startArgc, typename R, typename A >
1797struct _EngineConsoleThunk< startArgc, R( A ) >
1798{
1799   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
1800   static const S32 NUM_ARGS = 1 + startArgc;
1801   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
1802   {
1803      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1804      
1805      return _EngineConsoleThunkReturnValue( fn( a ) );
1806   }
1807   template< typename Frame >
1808   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
1809   {
1810      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
1811      
1812      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a ) );
1813   }
1814};
1815
1816template< S32 startArgc, typename A >
1817struct _EngineConsoleThunk< startArgc, void( A ) >
1818{
1819   typedef void ReturnType;
1820   static const S32 NUM_ARGS = 1 + startArgc;
1821   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs )
1822   {
1823      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1824      
1825      fn( a );
1826   }
1827   template< typename Frame >
1828   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs )
1829   {
1830      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
1831      
1832      ( frame->*fn )( a );
1833   }
1834};
1835
1836
1837template< S32 startArgc, typename R, typename A, typename B >
1838struct _EngineConsoleThunk< startArgc, R( A, B ) >
1839{
1840   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
1841   static const S32 NUM_ARGS = 2 + startArgc;
1842   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
1843   {
1844      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1845      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
1846      
1847      return _EngineConsoleThunkReturnValue( fn( a, b ) );
1848   }
1849   template< typename Frame >
1850   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
1851   {
1852      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
1853      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
1854      
1855      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b ) );
1856   }
1857};
1858
1859template< S32 startArgc, typename A, typename B >
1860struct _EngineConsoleThunk< startArgc, void( A, B ) >
1861{
1862   typedef void ReturnType;
1863   static const S32 NUM_ARGS = 2 + startArgc;
1864   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs )
1865   {
1866      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1867      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
1868      
1869      fn( a, b );
1870   }
1871   template< typename Frame >
1872   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs )
1873   {
1874      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
1875      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
1876      
1877      ( frame->*fn )( a, b );
1878   }
1879};
1880
1881
1882template< S32 startArgc, typename R, typename A, typename B, typename C >
1883struct _EngineConsoleThunk< startArgc, R( A, B, C ) >
1884{
1885   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
1886   static const S32 NUM_ARGS = 3 + startArgc;
1887   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
1888   {
1889      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1890      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
1891      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
1892      
1893      return _EngineConsoleThunkReturnValue( fn( a, b, c ) );
1894   }
1895   template< typename Frame >
1896   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
1897   {
1898      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
1899      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
1900      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
1901      
1902      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c ) );
1903   }
1904};
1905
1906template< S32 startArgc, typename A, typename B, typename C >
1907struct _EngineConsoleThunk< startArgc, void( A, B, C ) >
1908{
1909   typedef void ReturnType;
1910   static const S32 NUM_ARGS = 3 + startArgc;
1911   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs )
1912   {
1913      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1914      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
1915      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
1916      
1917      fn( a, b, c );
1918   }
1919   template< typename Frame >
1920   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs )
1921   {
1922      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
1923      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
1924      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
1925      
1926      ( frame->*fn )( a, b, c );
1927   }
1928};
1929
1930
1931template< S32 startArgc, typename R, typename A, typename B, typename C, typename D >
1932struct _EngineConsoleThunk< startArgc, R( A, B, C, D ) >
1933{
1934   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
1935   static const S32 NUM_ARGS = 4 + startArgc;
1936   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
1937   {
1938      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1939      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
1940      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
1941      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
1942      
1943      return _EngineConsoleThunkReturnValue( fn( a, b, c, d ) );
1944   }
1945   template< typename Frame >
1946   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
1947   {
1948      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
1949      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
1950      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
1951      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
1952      
1953      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d ) );
1954   }
1955};
1956
1957template< S32 startArgc, typename A, typename B, typename C, typename D >
1958struct _EngineConsoleThunk< startArgc, void( A, B, C, D ) >
1959{
1960   typedef void ReturnType;
1961   static const S32 NUM_ARGS = 4 + startArgc;
1962   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs )
1963   {
1964      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1965      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
1966      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
1967      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
1968      
1969      fn( a, b, c, d );
1970   }
1971   template< typename Frame >
1972   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs )
1973   {
1974      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
1975      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
1976      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
1977      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
1978      
1979      ( frame->*fn )( a, b, c, d );
1980   }
1981};
1982
1983
1984template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E >
1985struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E ) >
1986{
1987   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
1988   static const S32 NUM_ARGS = 5 + startArgc;
1989   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
1990   {
1991      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
1992      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
1993      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
1994      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
1995      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
1996      
1997      return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e ) );
1998   }
1999   template< typename Frame >
2000   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
2001   {
2002      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2003      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2004      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2005      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2006      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2007      
2008      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e ) );
2009   }
2010};
2011
2012template< S32 startArgc, typename A, typename B, typename C, typename D, typename E >
2013struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E ) >
2014{
2015   typedef void ReturnType;
2016   static const S32 NUM_ARGS = 5 + startArgc;
2017   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs )
2018   {
2019      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2020      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2021      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2022      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2023      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2024      
2025      fn( a, b, c, d, e );
2026   }
2027   template< typename Frame >
2028   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs )
2029   {
2030      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2031      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2032      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2033      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2034      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2035      
2036      ( frame->*fn )( a, b, c, d, e );
2037   }
2038};
2039
2040
2041template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F >
2042struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F ) >
2043{
2044   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
2045   static const S32 NUM_ARGS = 6 + startArgc;
2046   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
2047   {
2048      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2049      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2050      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2051      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2052      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2053      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2054      
2055      return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f ) );
2056   }
2057   template< typename Frame >
2058   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
2059   {
2060      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2061      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2062      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2063      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2064      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2065      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2066      
2067      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f ) );
2068   }
2069};
2070
2071template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F >
2072struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F ) >
2073{
2074   typedef void ReturnType;
2075   static const S32 NUM_ARGS = 6 + startArgc;
2076   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs )
2077   {
2078      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2079      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2080      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2081      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2082      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2083      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2084      
2085      fn( a, b, c, d, e, f );
2086   }
2087   template< typename Frame >
2088   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs )
2089   {
2090      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2091      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2092      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2093      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2094      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2095      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2096      
2097      ( frame->*fn )( a, b, c, d, e, f );
2098   }
2099};
2100
2101
2102template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
2103struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G ) >
2104{
2105   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
2106   static const S32 NUM_ARGS = 7 + startArgc;
2107   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
2108   {
2109      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2110      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2111      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2112      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2113      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2114      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2115      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2116      
2117      return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g ) );
2118   }
2119   template< typename Frame >
2120   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
2121   {
2122      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2123      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2124      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2125      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2126      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2127      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2128      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2129      
2130      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g ) );
2131   }
2132};
2133
2134template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
2135struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G ) >
2136{
2137   typedef void ReturnType;
2138   static const S32 NUM_ARGS = 7 + startArgc;
2139   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs )
2140   {
2141      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2142      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2143      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2144      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2145      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2146      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2147      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2148      
2149      fn( a, b, c, d, e, f, g );
2150   }
2151   template< typename Frame >
2152   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs )
2153   {
2154      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2155      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2156      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2157      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2158      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2159      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2160      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2161      
2162      ( frame->*fn )( a, b, c, d, e, f, g );
2163   }
2164};
2165
2166
2167template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
2168struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H ) >
2169{
2170   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
2171   static const S32 NUM_ARGS = 8 + startArgc;
2172   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
2173   {
2174      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2175      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2176      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2177      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2178      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2179      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2180      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2181      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2182      
2183      return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h ) );
2184   }
2185   template< typename Frame >
2186   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
2187   {
2188      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2189      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2190      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2191      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2192      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2193      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2194      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2195      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2196      
2197      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h ) );
2198   }
2199};
2200
2201template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
2202struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H ) >
2203{
2204   typedef void ReturnType;
2205   static const S32 NUM_ARGS = 8 + startArgc;
2206   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs )
2207   {
2208      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2209      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2210      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2211      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2212      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2213      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2214      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2215      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2216      
2217      fn( a, b, c, d, e, f, g, h );
2218   }
2219   template< typename Frame >
2220   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs )
2221   {
2222      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2223      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2224      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2225      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2226      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2227      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2228      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2229      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2230      
2231      ( frame->*fn )( a, b, c, d, e, f, g, h );
2232   }
2233};
2234
2235
2236template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
2237struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I ) >
2238{
2239   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
2240   static const S32 NUM_ARGS = 9 + startArgc;
2241   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
2242   {
2243      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2244      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2245      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2246      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2247      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2248      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2249      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2250      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2251      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) );
2252      
2253      return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i ) );
2254   }
2255   template< typename Frame >
2256   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
2257   {
2258      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2259      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2260      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2261      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2262      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2263      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2264      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2265      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2266      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) );
2267      
2268      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h, i ) );
2269   }
2270};
2271
2272template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
2273struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I ) >
2274{
2275   typedef void ReturnType;
2276   static const S32 NUM_ARGS = 9 + startArgc;
2277   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs )
2278   {
2279      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2280      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2281      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2282      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2283      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2284      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2285      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2286      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2287      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) );
2288      
2289      fn( a, b, c, d, e, f, g, h, i );
2290   }
2291   template< typename Frame >
2292   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs )
2293   {
2294      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2295      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2296      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2297      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2298      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2299      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2300      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2301      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2302      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) );
2303      
2304      ( frame->*fn )( a, b, c, d, e, f, g, h, i );
2305   }
2306};
2307
2308
2309template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
2310struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J ) >
2311{
2312   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
2313   static const S32 NUM_ARGS = 10 + startArgc;
2314   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
2315   {
2316      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2317      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2318      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2319      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2320      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2321      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2322      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2323      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2324      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) );
2325      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) );
2326      
2327      return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j ) );
2328   }
2329   template< typename Frame >
2330   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
2331   {
2332      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2333      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2334      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2335      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2336      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2337      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2338      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2339      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2340      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) );
2341      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) );
2342      
2343      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h, i, j ) );
2344   }
2345};
2346
2347template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
2348struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J ) >
2349{
2350   typedef void ReturnType;
2351   static const S32 NUM_ARGS = 10 + startArgc;
2352   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
2353   {
2354      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2355      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2356      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2357      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2358      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2359      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2360      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2361      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2362      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) );
2363      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) );
2364      
2365      fn( a, b, c, d, e, f, g, h, i, j );
2366   }
2367   template< typename Frame >
2368   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs )
2369   {
2370      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2371      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2372      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2373      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2374      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2375      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2376      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2377      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2378      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) );
2379      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) );
2380      
2381      ( frame->*fn )( a, b, c, d, e, f, g, h, i, j );
2382   }
2383};
2384
2385
2386template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
2387struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K ) >
2388{
2389   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
2390   static const S32 NUM_ARGS = 11 + startArgc;
2391   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
2392   {
2393      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2394      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2395      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2396      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2397      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2398      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2399      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2400      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2401      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) );
2402      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) );
2403      K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K>()( argv[ startArgc + 10 ] ) : K( defaultArgs.k ) );
2404      
2405      return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j, k ) );
2406   }
2407   template< typename Frame >
2408   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
2409   {
2410      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2411      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2412      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2413      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2414      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2415      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2416      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2417      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2418      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) );
2419      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) );
2420      K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K>()( argv[ startArgc + 10 ] ) : K( defaultArgs.l ) );
2421      
2422      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h, i, j, k ) );
2423   }
2424};
2425
2426template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K >
2427struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) >
2428{
2429   typedef void ReturnType;
2430   static const S32 NUM_ARGS = 11 + startArgc;
2431   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
2432   {
2433      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2434      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2435      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2436      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2437      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2438      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2439      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2440      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2441      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) );
2442      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) );
2443      K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K>()( argv[ startArgc + 10 ] ) : K( defaultArgs.k ) );
2444      
2445      fn( a, b, c, d, e, f, g, h, i, j, k );
2446   }
2447   template< typename Frame >
2448   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs )
2449   {
2450      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2451      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2452      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2453      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2454      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2455      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2456      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2457      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2458      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) );
2459      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) );
2460      K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K>()( argv[ startArgc + 10 ] ) : K( defaultArgs.l ) );
2461      
2462      ( frame->*fn )( a, b, c, d, e, f, g, h, i, j, k );
2463   }
2464};
2465
2466
2467template< S32 startArgc, 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 >
2468struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K, L ) >
2469{
2470   typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType;
2471   static const S32 NUM_ARGS = 12 + startArgc;
2472   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J, K, L ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K, L ) >& defaultArgs )
2473   {
2474      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2475      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2476      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2477      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2478      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2479      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2480      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2481      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2482      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) );
2483      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) );
2484      K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K>()( argv[ startArgc + 10 ] ) : K( defaultArgs.k ) );
2485      L l = ( startArgc + 11 < argc ? EngineUnmarshallData< L>()( argv[ startArgc + 11 ] ) : L( defaultArgs.l ) );
2486      
2487      return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j, k, l ) );
2488   }
2489   template< typename Frame >
2490   static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K, L ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K, L ) >& defaultArgs )
2491   {
2492      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2493      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2494      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2495      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2496      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2497      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2498      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2499      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2500      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) );
2501      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) );
2502      K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K>()( argv[ startArgc + 10 ] ) : K( defaultArgs.l ) );
2503      L l = ( startArgc + 11 < argc ? EngineUnmarshallData< L>()( argv[ startArgc + 11 ] ) : L( defaultArgs.l ) );
2504      
2505      return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h, i, j, k, l ) );
2506   }
2507};
2508
2509template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L >
2510struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K, L ) >
2511{
2512   typedef void ReturnType;
2513   static const S32 NUM_ARGS = 12 + startArgc;
2514   static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J, K, L ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K, L ) >& defaultArgs )
2515   {
2516      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) );
2517      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) );
2518      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) );
2519      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) );
2520      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) );
2521      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) );
2522      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) );
2523      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) );
2524      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) );
2525      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) );
2526      K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K>()( argv[ startArgc + 10 ] ) : K( defaultArgs.k ) );
2527      L l = ( startArgc + 11 < argc ? EngineUnmarshallData< L>()( argv[ startArgc + 11 ] ) : L( defaultArgs.l ) );
2528      
2529      fn( a, b, c, d, e, f, g, h, i, j, k, l );
2530   }
2531   template< typename Frame >
2532   static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K, L ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K, L ) >& defaultArgs )
2533   {
2534      A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A>()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) );
2535      B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B>()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) );
2536      C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C>()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) );
2537      D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D>()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) );
2538      E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E>()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) );
2539      F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F>()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) );
2540      G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G>()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) );
2541      H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H>()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) );
2542      I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I>()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) );
2543      J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J>()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) );
2544      K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K>()( argv[ startArgc + 10 ] ) : K( defaultArgs.l ) );
2545      L l = ( startArgc + 11 < argc ? EngineUnmarshallData< L>()( argv[ startArgc + 11 ] ) : L( defaultArgs.l ) );
2546      
2547      ( frame->*fn )( a, b, c, d, e, f, g, h, i, j, k, l );
2548   }
2549};
2550
2551
2552
2553/// @}
2554
2555/// @name API Definition Macros
2556///
2557/// The macros in this group allow to create engine API functions that work both with the
2558/// legacy console system as well as with the new engine export system.  As such, they only
2559/// support those function features that are available in both systems.  This means that for
2560/// console-style variadic functions, the ConsoleXXX must be used and that for overloaded
2561/// and/or C-style variadic functions as well as for placing functions in export scopes,
2562/// DEFINE_CALLIN must be used directly.
2563///
2564/// When the console system is removed, the console thunking functionality will be removed
2565/// from these macros but otherwise they will remain unchanged and in place.
2566///
2567/// @{
2568
2569
2570// Helpers to implement initialization checks.  Pulled out into separate macros so this can be deactivated easily.
2571// Especially important for the initialize() function itself.
2572
2573#define _CHECK_ENGINE_INITIALIZED_IMPL( fnName, returnType )                                                                     \
2574      if( !engineAPI::gIsInitialized )                                                                                           \
2575      {                                                                                                                          \
2576         Con::errorf( "EngineAPI: Engine not initialized when calling " #fnName );                                               \
2577         return EngineTypeTraits< returnType >::ReturnValue( EngineTypeTraits< returnType >::ReturnValueType() );                \
2578      }
2579
2580#define _CHECK_ENGINE_INITIALIZED( fnName, returnType ) _CHECK_ENGINE_INITIALIZED_IMPL( fnName, returnType )
2581
2582
2583/// Define a call-in point for calling into the engine.
2584///
2585/// @param name The name of the function as it should be seen by the control layer.
2586/// @param returnType The value type returned to the control layer.
2587/// @param args The argument list as it would appear on the function definition
2588/// @param defaultArgs The list of default argument values.
2589/// @param usage The usage doc string for the engine API reference.
2590///
2591/// @code
2592/// DefineEngineFunction( myFunction, int, ( float f, const String& s ), ( "value for s" ), "This is my function." )
2593/// {
2594///    return int( f ) + dAtoi( s );
2595/// }
2596/// @endcode
2597#define DefineEngineFunction( name, returnType, args, defaultArgs, usage )                                                       \
2598   static inline returnType _fn ## name ## impl args;                                                                            \
2599   TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name                                                         \
2600      ( _EngineFunctionTrampoline< returnType args >::Args a )                                                                   \
2601   {                                                                                                                             \
2602      _CHECK_ENGINE_INITIALIZED( name, returnType );                                                                             \
2603      return EngineTypeTraits< returnType >::ReturnValue(                                                                        \
2604         _EngineFunctionTrampoline< returnType args >::jmp( _fn ## name ## impl, a )                                             \
2605      );                                                                                                                         \
2606   }                                                                                                                             \
2607   static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs;                                   \
2608   static EngineFunctionInfo _fn ## name ## FunctionInfo(                                                                        \
2609      #name,                                                                                                                     \
2610      &_SCOPE<>()(),                                                                                                             \
2611      usage,                                                                                                                     \
2612      #returnType " " #name #args,                                                                                               \
2613      "fn" #name,                                                                                                                \
2614      TYPE< returnType args >(),                                                                                                 \
2615      &_fn ## name ## DefaultArgs,                                                                                               \
2616      ( void* ) &fn ## name,                                                                                                     \
2617      0                                                                                                                          \
2618   );                                                                                                                            \
2619   static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )       \
2620   {                                                                                                                             \
2621      return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk(                \
2622         argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs                                                            \
2623      ) );                                                                                                                       \
2624   }                                                                                                                             \
2625   static ConsoleFunctionHeader _ ## name ## header                                                                              \
2626      ( #returnType, #args, #defaultArgs );                                                                                      \
2627   static ConsoleConstructor                                                                                                     \
2628      _ ## name ## obj( NULL, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## name ## caster ), usage,          \
2629         _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs,                       \
2630         _EngineConsoleThunk< 1, returnType args >::NUM_ARGS,                                                                    \
2631         false, &_ ## name ## header                                                                                             \
2632      );                                                                                                                         \
2633   static inline returnType _fn ## name ## impl args
2634   
2635   
2636// The next thing is a bit tricky.  DefineEngineMethod allows to make the 'object' (=this) argument to the function
2637// implicit which presents quite an obstacle for the macro internals as the engine export system requires the
2638// name of a DLL symbol that represents an extern "C" function with an explicit first object pointer argument.
2639//
2640// Even if we ignored the fact that we don't have a guarantee how the various C++ compilers implement implicit 'this' arguments,
2641// 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
2642// get to the function symbol name (let alone the fact that typing this method correctly would be tricky).
2643//
2644// So, the trick employed here is to package all but the implicit 'this' argument in a structure and then define an
2645// extern "C" function that takes the object pointer as a first argument and the struct type as the second argument.
2646// This will result in a function with an identical stack call frame layout to the function we want.
2647//
2648// Unfortunately, that still requires that function to chain on to the real user-defined function.  To do this
2649// cleanly and portably, _EngineMethodTrampoline is used to unpack and jump the call from extern "C" into C++ space.
2650// In optimized builds, the compiler should be smart enough to pretty much optimize all our trickery here away.
2651
2652#define _DefineMethodTrampoline( className, name, returnType, args ) \
2653   TORQUE_API EngineTypeTraits< returnType >::ReturnValueType \
2654      fn ## className ## _ ## name ( className* object, _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::Args a )   \
2655   {                                                                                                                                            \
2656      _CHECK_ENGINE_INITIALIZED( className::name, returnType );                                                                                 \
2657      return EngineTypeTraits< returnType >::ReturnValue(                                                                                       \
2658         _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::jmp( object, a )                                          \
2659      );                                                                                                                                        \
2660   }
2661
2662
2663/// Define a call-in point for calling a method on an engine object.
2664///
2665/// @param name The name of the C++ class.
2666/// @param name The name of the method as it should be seen by the control layer.
2667/// @param returnType The value type returned to the control layer.
2668/// @param args The argument list as it would appear on the function definition
2669/// @param defaultArgs The list of default argument values.
2670/// @param usage The usage doc string for the engine API reference.
2671///
2672/// @code
2673/// DefineEngineMethod( MyClass, myMethod, int, ( float f, const String& s ), ( "value for s" ), "This is my method." )
2674/// {
2675///    return object->someMethod( f, s );
2676/// }
2677/// @endcode
2678#define DefineEngineMethod( className, name, returnType, args, defaultArgs, usage )                                                             \
2679   struct _ ## className ## name ## frame                                                                                                       \
2680   {                                                                                                                                            \
2681      typedef className ObjectType;                                                                                                             \
2682      className* object;                                                                                                                        \
2683      inline returnType _exec args const;                                                                                                       \
2684   };                                                                                                                                           \
2685   _DefineMethodTrampoline( className, name, returnType, args );                                                                                \
2686   static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType >                \
2687      _fn ## className ## name ## DefaultArgs defaultArgs;                                                                                      \
2688   static EngineFunctionInfo _fn ## className ## name ## FunctionInfo(                                                                          \
2689      #name,                                                                                                                                    \
2690      &_SCOPE< className >()(),                                                                                                                 \
2691      usage,                                                                                                                                    \
2692      "virtual " #returnType " " #name #args,                                                                                                   \
2693      "fn" #className "_" #name,                                                                                                                \
2694      TYPE< _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::FunctionType >(),                                      \
2695      &_fn ## className ## name ## DefaultArgs,                                                                                                 \
2696      ( void* ) &fn ## className ## _ ## name,                                                                                                  \
2697      0                                                                                                                                         \
2698   );                                                                                                                                           \
2699   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv )  \
2700   {                                                                                                                                            \
2701      _ ## className ## name ## frame frame;                                                                                                    \
2702      frame.object = static_cast< className* >( object );                                                                                       \
2703      return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 2, returnType args >::thunk(                               \
2704         argc, argv, &_ ## className ## name ## frame::_exec, &frame, _fn ## className ## name ## DefaultArgs                                   \
2705      ) );                                                                                                                                      \
2706   }                                                                                                                                            \
2707   static ConsoleFunctionHeader _ ## className ## name ## header                                                                                \
2708      ( #returnType, #args, #defaultArgs );                                                                                                     \
2709   static ConsoleConstructor                                                                                                                    \
2710      className ## name ## obj( #className, #name,                                                                                              \
2711         _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage,                                        \
2712         _EngineConsoleThunk< 2, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs,                                      \
2713         _EngineConsoleThunk< 2, returnType args >::NUM_ARGS,                                                                                   \
2714         false, &_ ## className ## name ## header                                                                                               \
2715      );                                                                                                                                        \
2716   returnType _ ## className ## name ## frame::_exec args const
2717   
2718   
2719/// Define a call-in point for calling into the engine.  Unlike with DefineEngineFunction, the statically
2720/// callable function will be confined to the namespace of the given class.
2721///
2722/// @param name The name of the C++ class (or a registered export scope).
2723/// @param name The name of the method as it should be seen by the control layer.
2724/// @param returnType The value type returned to the control layer.
2725/// @param args The argument list as it would appear on the function definition
2726/// @param defaultArgs The list of default argument values.
2727/// @param usage The usage doc string for the engine API reference.
2728///
2729/// @code
2730/// DefineEngineStaticMethod( MyClass, myMethod, int, ( float f, string s ), ( "value for s" ), "This is my method." )
2731/// {
2732/// }
2733/// @endcode
2734#define DefineEngineStaticMethod( className, name, returnType, args, defaultArgs, usage )                                              \
2735   static inline returnType _fn ## className ## name ## impl args;                                                                     \
2736   TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name                                             \
2737      ( _EngineFunctionTrampoline< returnType args >::Args a )                                                                         \
2738   {                                                                                                                                   \
2739      _CHECK_ENGINE_INITIALIZED( className::name, returnType );                                                                        \
2740      return EngineTypeTraits< returnType >::ReturnValue(                                                                              \
2741         _EngineFunctionTrampoline< returnType args >::jmp( _fn ## className ## name ## impl, a )                                      \
2742      );                                                                                                                               \
2743   }                                                                                                                                   \
2744   static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs;                            \
2745   static EngineFunctionInfo _fn ## name ## FunctionInfo(                                                                              \
2746      #name,                                                                                                                           \
2747      &_SCOPE< className >()(),                                                                                                        \
2748      usage,                                                                                                                           \
2749      #returnType " " #name #args,                                                                                                     \
2750      "fn" #className "_" #name,                                                                                                       \
2751      TYPE< returnType args >(),                                                                                                       \
2752      &_fn ## className ## name ## DefaultArgs,                                                                                        \
2753      ( void* ) &fn ## className ## _ ## name,                                                                                         \
2754      0                                                                                                                                \
2755   );                                                                                                                                  \
2756   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
2757   {                                                                                                                                   \
2758      return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk(                      \
2759         argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs                                        \
2760      ) );                                                                                                                             \
2761   }                                                                                                                                   \
2762   static ConsoleFunctionHeader _ ## className ## name ## header                                                                       \
2763      ( #returnType, #args, #defaultArgs, true );                                                                                      \
2764   static ConsoleConstructor                                                                                                           \
2765      _ ## className ## name ## obj( #className, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
2766         _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs,                             \
2767         _EngineConsoleThunk< 1, returnType args >::NUM_ARGS,                                                                          \
2768         false, &_ ## className ## name ## header                                                                                      \
2769      );                                                                                                                               \
2770   static inline returnType _fn ## className ## name ## impl args
2771
2772
2773// Convenience macros to allow defining functions that use the new marshalling features
2774// while being only visible in the console interop.  When we drop the console system,
2775// these macros can be removed and all definitions that make use of them can be removed
2776// as well.
2777#define DefineConsoleFunction( name, returnType, args, defaultArgs, usage )                                                      \
2778   static inline returnType _fn ## name ## impl args;                                                                            \
2779   static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs;                                   \
2780   static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )       \
2781   {                                                                                                                             \
2782      return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk(                \
2783         argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs                                                            \
2784      ) );                                                                                                                       \
2785   }                                                                                                                             \
2786   static ConsoleFunctionHeader _ ## name ## header                                                                              \
2787      ( #returnType, #args, #defaultArgs );                                                                                      \
2788   static ConsoleConstructor                                                                                                     \
2789      _ ## name ## obj( NULL, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## name ## caster ), usage,          \
2790         _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs,                       \
2791         _EngineConsoleThunk< 1, returnType args >::NUM_ARGS,                                                                    \
2792         false, &_ ## name ## header                                                                                             \
2793      );                                                                                                                         \
2794   static inline returnType _fn ## name ## impl args
2795
2796#define DefineConsoleMethod( className, name, returnType, args, defaultArgs, usage )                                                            \
2797   struct _ ## className ## name ## frame                                                                                                       \
2798   {                                                                                                                                            \
2799      typedef className ObjectType;                                                                                                             \
2800      className* object;                                                                                                                        \
2801      inline returnType _exec args const;                                                                                                       \
2802   };                                                                                                                                           \
2803   static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType >                \
2804      _fn ## className ## name ## DefaultArgs defaultArgs;                                                                                      \
2805   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv )  \
2806   {                                                                                                                                            \
2807      _ ## className ## name ## frame frame;                                                                                                    \
2808      frame.object = static_cast< className* >( object );                                                                                       \
2809      return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 2, returnType args >::thunk(                               \
2810         argc, argv, &_ ## className ## name ## frame::_exec, &frame, _fn ## className ## name ## DefaultArgs                                   \
2811      ) );                                                                                                                                      \
2812   }                                                                                                                                            \
2813   static ConsoleFunctionHeader _ ## className ## name ## header                                                                                \
2814      ( #returnType, #args, #defaultArgs );                                                                                                     \
2815   static ConsoleConstructor                                                                                                                    \
2816      className ## name ## obj( #className, #name,                                                                                              \
2817         _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage,                                        \
2818         _EngineConsoleThunk< 2, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs,                                      \
2819         _EngineConsoleThunk< 2, returnType args >::NUM_ARGS,                                                                                   \
2820         false, &_ ## className ## name ## header                                                                                               \
2821      );                                                                                                                                        \
2822   returnType _ ## className ## name ## frame::_exec args const
2823
2824#define DefineConsoleStaticMethod( className, name, returnType, args, defaultArgs, usage )                                             \
2825   static inline returnType _fn ## className ## name ## impl args;                                                                     \
2826   static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs;                            \
2827   static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\
2828   {                                                                                                                                   \
2829      return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk(                      \
2830         argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs                                        \
2831      ) );                                                                                                                             \
2832   }                                                                                                                                   \
2833   static ConsoleFunctionHeader _ ## className ## name ## header                                                                       \
2834      ( #returnType, #args, #defaultArgs, true );                                                                                      \
2835   static ConsoleConstructor                                                                                                           \
2836      _ ## className ## name ## obj( #className, #name, _EngineConsoleThunkType< returnType >::CallbackType( _ ## className ## name ## caster ), usage, \
2837         _EngineConsoleThunk< 1, returnType args >::NUM_ARGS - _EngineConsoleThunkCountArgs() defaultArgs,                             \
2838         _EngineConsoleThunk< 1, returnType args >::NUM_ARGS,                                                                          \
2839         false, &_ ## className ## name ## header                                                                                      \
2840      );                                                                                                                               \
2841   static inline returnType _fn ## className ## name ## impl args
2842
2843
2844// The following three macros are only temporary.  They allow to define engineAPI functions using the framework
2845// here in this file while being visible only in the new API.  When the console interop is removed, these macros
2846// can be removed and all their uses be replaced with their corresponding versions that now still include support
2847// for the console (e.g. DefineNewEngineFunction should become DefineEngineFunction).
2848#define DefineNewEngineFunction( name, returnType, args, defaultArgs, usage )                                                    \
2849   static inline returnType _fn ## name ## impl args;                                                                            \
2850   TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name                                                         \
2851      ( _EngineFunctionTrampoline< returnType args >::Args a )                                                                   \
2852   {                                                                                                                             \
2853      _CHECK_ENGINE_INITIALIZED( name, returnType );                                                                             \
2854      return EngineTypeTraits< returnType >::ReturnValue(                                                                        \
2855         _EngineFunctionTrampoline< returnType args >::jmp( _fn ## name ## impl, a )                                             \
2856      );                                                                                                                         \
2857   }                                                                                                                             \
2858   static _EngineFunctionDefaultArguments< void args > _fn ## name ## DefaultArgs defaultArgs;                                   \
2859   static EngineFunctionInfo _fn ## name ## FunctionInfo(                                                                        \
2860      #name,                                                                                                                     \
2861      &_SCOPE<>()(),                                                                                                             \
2862      usage,                                                                                                                     \
2863      #returnType " " #name #args,                                                                                               \
2864      "fn" #name,                                                                                                                \
2865      TYPE< returnType args >(),                                                                                                 \
2866      &_fn ## name ## DefaultArgs,                                                                                               \
2867      ( void* ) &fn ## name,                                                                                                     \
2868      0                                                                                                                          \
2869   );                                                                                                                            \
2870   static inline returnType _fn ## name ## impl args
2871
2872#define DefineNewEngineMethod( className, name, returnType, args, defaultArgs, usage )                                                          \
2873   struct _ ## className ## name ## frame                                                                                                       \
2874   {                                                                                                                                            \
2875      typedef className ObjectType;                                                                                                             \
2876      className* object;                                                                                                                        \
2877      inline returnType _exec args const;                                                                                                       \
2878   };                                                                                                                                           \
2879   _DefineMethodTrampoline( className, name, returnType, args );                                                                                \
2880   static _EngineFunctionDefaultArguments< _EngineMethodTrampoline< _ ## className ## name ## frame, void args >::FunctionType >                \
2881      _fn ## className ## name ## DefaultArgs defaultArgs;                                                                                      \
2882   static EngineFunctionInfo _fn ## className ## name ## FunctionInfo(                                                                          \
2883      #name,                                                                                                                                    \
2884      &_SCOPE< className >()(),                                                                                                                 \
2885      usage,                                                                                                                                    \
2886      "virtual " #returnType " " #name #args,                                                                                                   \
2887      "fn" #className "_" #name,                                                                                                                \
2888      TYPE< _EngineMethodTrampoline< _ ## className ## name ## frame, returnType args >::FunctionType >(),                                      \
2889      &_fn ## className ## name ## DefaultArgs,                                                                                                 \
2890      ( void* ) &fn ## className ## _ ## name,                                                                                                  \
2891      0                                                                                                                                         \
2892   );                                                                                                                                           \
2893   returnType _ ## className ## name ## frame::_exec args const
2894
2895#define DefineNewEngineStaticMethod( className, name, returnType, args, defaultArgs, usage )                                           \
2896   static inline returnType _fn ## className ## name ## impl args;                                                                     \
2897   TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name                                             \
2898      ( _EngineFunctionTrampoline< returnType args >::Args a )                                                                         \
2899   {                                                                                                                                   \
2900      _CHECK_ENGINE_INITIALIZED( className::name, returnType );                                                                        \
2901      return EngineTypeTraits< returnType >::ReturnValue(                                                                              \
2902         _EngineFunctionTrampoline< returnType args >::jmp( _fn ## className ## name ## impl, a )                                      \
2903      );                                                                                                                               \
2904   }                                                                                                                                   \
2905   static _EngineFunctionDefaultArguments< void args > _fn ## className ## name ## DefaultArgs defaultArgs;                            \
2906   static EngineFunctionInfo _fn ## name ## FunctionInfo(                                                                              \
2907      #name,                                                                                                                           \
2908      &_SCOPE< className >()(),                                                                                                        \
2909      usage,                                                                                                                           \
2910      #returnType " " #name #args,                                                                                                     \
2911      "fn" #className "_" #name,                                                                                                       \
2912      TYPE< returnType args >(),                                                                                                       \
2913      &_fn ## className ## name ## DefaultArgs,                                                                                        \
2914      ( void* ) &fn ## className ## _ ## name,                                                                                         \
2915      0                                                                                                                                \
2916   );                                                                                                                                  \
2917   static inline returnType _fn ## className ## name ## impl args
2918
2919/// @}
2920
2921
2922//=============================================================================
2923//    Callbacks.
2924//=============================================================================
2925
2926/// Matching implement for DECLARE_CALLBACK.
2927///
2928///
2929/// @warn With the new interop system, method-style callbacks <em>must not</em> be triggered on object
2930///   that are being created!  This is because the control layer will likely not yet have a fully valid wrapper
2931///   object in place for the EngineObject under construction.
2932#define IMPLEMENT_CALLBACK( class, name, returnType, args, argNames, usageString )                                                           \
2933   struct _ ## class ## name ## frame { typedef class ObjectType; };                                                                         \
2934   TORQUE_API _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name;               \
2935   TORQUE_API void set_cb ## class ## _ ## name(                                                                                             \
2936      _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType fn )                                             \
2937      { cb ## class ## _ ## name = fn; }                                                                                                     \
2938   _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name;                          \
2939   namespace {                                                                                                                               \
2940      ::EngineFunctionInfo _cb ## class ## name(                                                                                             \
2941         #name,                                                                                                                              \
2942         &::_SCOPE< class >()(),                                                                                                             \
2943         usageString,                                                                                                                        \
2944         "virtual " #returnType " " #name #args,                                                                                             \
2945         "cb" #class "_" #name,                                                                                                              \
2946         ::TYPE< _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType >(),                                  \
2947         NULL,                                                                                                                               \
2948         ( void* ) &cb ## class ## _ ## name,                                                                                                \
2949         EngineFunctionCallout                                                                                                               \
2950      );                                                                                                                                     \
2951   }                                                                                                                                         \
2952   returnType class::name ## _callback args                                                                                                  \
2953   {                                                                                                                                         \
2954      if( cb ## class ## _ ## name ) {                                                                                                       \
2955         _EngineCallbackHelper cbh( this, reinterpret_cast< const void* >( cb ## class ## _ ## name ) );                                     \
2956         return returnType( cbh.call< returnType > argNames );                                                                               \
2957      }                                                                                                                                      \
2958      if( engineAPI::gUseConsoleInterop )                                                                                                    \
2959      {                                                                                                                                      \
2960         static StringTableEntry sName = StringTable->insert( #name );                                                                       \
2961         _EngineConsoleCallbackHelper cbh( sName, this );                                                                                    \
2962         return returnType( cbh.call< returnType > argNames );                                                                               \
2963      }                                                                                                                                      \
2964      return returnType();                                                                                                                   \
2965   }                                                                                                                                         \
2966   namespace {                                                                                                                               \
2967      ConsoleFunctionHeader _ ## class ## name ## header(                                                                                    \
2968         #returnType, #args, "" );                                                                                                           \
2969      ConsoleConstructor _ ## class ## name ## obj( #class, #name, usageString, &_ ## class ## name ## header );                             \
2970   }
2971
2972
2973/// Used to define global callbacks not associated with 
2974/// any particular class or namespace.
2975#define IMPLEMENT_GLOBAL_CALLBACK( name, returnType, args, argNames, usageString )                                                           \
2976   DEFINE_CALLOUT( cb ## name, name,, returnType, args, 0, usageString );                                                                    \
2977   returnType name ## _callback args                                                                                                         \
2978   {                                                                                                                                         \
2979      if( cb ## name )                                                                                                                       \
2980         return returnType( cb ## name argNames );                                                                                           \
2981      if( engineAPI::gUseConsoleInterop )                                                                                                    \
2982      {                                                                                                                                      \
2983         static StringTableEntry sName = StringTable->insert( #name );                                                                       \
2984         _EngineConsoleCallbackHelper cbh( sName, NULL );                                                                                    \
2985         return returnType( cbh.call< returnType > argNames );                                                                               \
2986      }                                                                                                                                      \
2987      return returnType();                                                                                                                   \
2988   }                                                                                                                                         \
2989   namespace {                                                                                                                               \
2990      ConsoleFunctionHeader _ ## name ## header(                                                                                             \
2991         #returnType, #args, "" );                                                                                                           \
2992      ConsoleConstructor _ ## name ## obj( NULL, #name, usageString, &_ ## name ## header );                                                 \
2993   }
2994   
2995   
2996// Again, temporary macros to allow splicing the API while we still have the console interop around.
2997
2998#define IMPLEMENT_CONSOLE_CALLBACK( class, name, returnType, args, argNames, usageString )                                                   \
2999   returnType class::name ## _callback args                                                                                                  \
3000   {                                                                                                                                         \
3001      if( engineAPI::gUseConsoleInterop )                                                                                                    \
3002      {                                                                                                                                      \
3003         static StringTableEntry sName = StringTable->insert( #name );                                                                       \
3004         _EngineConsoleCallbackHelper cbh( sName, this );                                                                                    \
3005         return returnType( cbh.call< returnType > argNames );                                                                               \
3006      }                                                                                                                                      \
3007      return returnType();                                                                                                                   \
3008   }                                                                                                                                         \
3009   namespace {                                                                                                                               \
3010      ConsoleFunctionHeader _ ## class ## name ## header(                                                                                    \
3011         #returnType, #args, "" );                                                                                                           \
3012      ConsoleConstructor _ ## class ## name ## obj( #class, #name, usageString, &_ ## class ## name ## header );                             \
3013   }
3014   
3015#define IMPLEMENT_NEW_CALLBACK( class, name, returnType, args, argNames, usageString )                                                       \
3016   struct _ ## class ## name ## frame { typedef class ObjectType; };                                                                         \
3017   TORQUE_API _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name;               \
3018   TORQUE_API void set_cb ## class ## _ ## name(                                                                                             \
3019      _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType fn )                                             \
3020      { cb ## class ## _ ## name = fn; }                                                                                                     \
3021   _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType* cb ## class ## _ ## name;                          \
3022   namespace {                                                                                                                               \
3023      ::EngineFunctionInfo _cb ## class ## name(                                                                                             \
3024         #name,                                                                                                                              \
3025         &::_SCOPE< class >()(),                                                                                                             \
3026         usageString,                                                                                                                        \
3027         "virtual " #returnType " " #name #args,                                                                                             \
3028         "cb" #class "_" #name,                                                                                                              \
3029         ::TYPE< _EngineMethodTrampoline< _ ## class ## name ## frame, returnType args >::FunctionType >(),                                  \
3030         NULL,                                                                                                                               \
3031         &cb ## class ## _ ## name,                                                                                                          \
3032         EngineFunctionCallout                                                                                                               \
3033      );                                                                                                                                     \
3034   }                                                                                                                                         \
3035   returnType class::name ## _callback args                                                                                                  \
3036   {                                                                                                                                         \
3037      if( cb ## class ## _ ## name ) {                                                                                                       \
3038         _EngineCallbackHelper cbh( this, reinterpret_cast< const void* >( cb ## class ## _ ## name ) );                                     \
3039         return returnType( cbh.call< returnType > argNames );                                                                               \
3040      }                                                                                                                                      \
3041      return returnType();                                                                                                                   \
3042   }
3043
3044
3045
3046
3047// Internal helper class for doing call-outs in the new interop.
3048struct _EngineCallbackHelper
3049{
3050   protected:
3051    
3052      EngineObject* mThis;
3053      const void* mFn;
3054            
3055   public:
3056
3057      _EngineCallbackHelper( EngineObject* pThis, const void* fn )
3058         : mThis( pThis ),
3059           mFn( fn ) {}
3060      
3061      template< typename R >
3062      R call() const
3063      {
3064         typedef R( FunctionType )( EngineObject* );
3065         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis ) );
3066      }
3067
3068      
3069      template< typename R, typename A >
3070      R call( A a ) const
3071      {
3072         typedef R( FunctionType )( EngineObject*, A );
3073         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a ) );
3074      }
3075      
3076      template< typename R, typename A, typename B >
3077      R call( A a, B b ) const
3078      {
3079         typedef R( FunctionType )( EngineObject*, A, B );
3080         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b ) );
3081      }
3082      
3083      template< typename R, typename A, typename B, typename C >
3084      R call( A a, B b, C c ) const
3085      {
3086         typedef R( FunctionType )( EngineObject*, A, B, C );
3087         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c ) );
3088      }
3089      
3090      template< typename R, typename A, typename B, typename C, typename D >
3091      R call( A a, B b, C c, D d ) const
3092      {
3093         typedef R( FunctionType )( EngineObject*, A, B, C, D );
3094         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d ) );
3095      }
3096      
3097      template< typename R, typename A, typename B, typename C, typename D, typename E >
3098      R call( A a, B b, C c, D d, E e ) const
3099      {
3100         typedef R( FunctionType )( EngineObject*, A, B, C, D, E );
3101         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e ) );
3102      }
3103      
3104      template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
3105      R call( A a, B b, C c, D d, E e, F f ) const
3106      {
3107         typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F );
3108         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f ) );
3109      }
3110      
3111      template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
3112      R call( A a, B b, C c, D d, E e, F f, G g ) const
3113      {
3114         typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G );
3115         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g ) );
3116      }
3117      
3118      template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
3119      R call( A a, B b, C c, D d, E e, F f, G g, H h ) const
3120      {
3121         typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H );
3122         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h ) );
3123      }
3124      
3125      template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
3126      R call( A a, B b, C c, D d, E e, F f, G g, H h, I i ) const
3127      {
3128         typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I );
3129         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h, i ) );
3130      }
3131      
3132      template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
3133      R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) const
3134      {
3135         typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J );
3136         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j ) );
3137      }
3138      
3139      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 >
3140      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
3141      {
3142         typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J, K );
3143         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j, k ) );
3144      }
3145      
3146      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 >
3147      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
3148      {
3149         typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J, K, L );
3150         return R( reinterpret_cast< FunctionType* >( const_cast<void*>(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j, k, l ) );
3151      }
3152      
3153};
3154
3155
3156#include "console/stringStack.h"
3157
3158// Internal helper for callback support in legacy console system.
3159struct _BaseEngineConsoleCallbackHelper
3160{
3161public:
3162
3163   /// Matches up to storeArgs.
3164   static const U32 MAX_ARGUMENTS = 11;
3165
3166   SimObject* mThis;
3167   S32 mInitialArgc;
3168   S32 mArgc;
3169   StringTableEntry mCallbackName;
3170   ConsoleValueRef mArgv[ MAX_ARGUMENTS + 2 ];
3171
3172   ConsoleValueRef _exec();
3173   ConsoleValueRef _execLater(SimConsoleThreadExecEvent *evt);
3174
3175   _BaseEngineConsoleCallbackHelper() {;}
3176};
3177
3178
3179
3180// Base helper for console callbacks
3181struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper
3182{
3183public:
3184
3185   _EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis )
3186   {
3187      mThis = pThis;
3188      mArgc = mInitialArgc = pThis ? 2 : 1 ;
3189      mCallbackName = callbackName;
3190   }
3191
3192   template< typename R >
3193   R call()
3194   {
3195      if (Con::isMainThread())
3196      {
3197         ConsoleStackFrameSaver sav; sav.save();
3198         CSTK.reserveValues(mArgc, mArgv);
3199         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3200         return R( EngineUnmarshallData< R>()( _exec() ) );
3201      }
3202      else
3203      {
3204         SimConsoleThreadExecCallback cb;
3205         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc, NULL, false, &cb);
3206         evt->populateArgs(mArgv);
3207         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3208         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3209
3210         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3211      }
3212   }
3213
3214
3215   
3216   template< typename R, typename A >
3217   R call( A a )
3218   {
3219      if (Con::isMainThread())
3220      {
3221         ConsoleStackFrameSaver sav; sav.save();
3222         CSTK.reserveValues(mArgc+1, mArgv);
3223         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3224
3225         EngineMarshallData( a, mArgc, mArgv );
3226
3227         return R( EngineUnmarshallData< R>()( _exec() ) );
3228      }
3229      else
3230      {
3231         SimConsoleThreadExecCallback cb;
3232         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, false, &cb);
3233         evt->populateArgs(mArgv);
3234         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3235
3236         EngineMarshallData( a, mArgc, mArgv );
3237
3238         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3239
3240         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3241      }
3242   }
3243   
3244   template< typename R, typename A, typename B >
3245   R call( A a, B b )
3246   {
3247      if (Con::isMainThread())
3248      {
3249         ConsoleStackFrameSaver sav; sav.save();
3250         CSTK.reserveValues(mArgc+2, mArgv);
3251         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3252
3253         EngineMarshallData( a, mArgc, mArgv );
3254         EngineMarshallData( b, mArgc, mArgv );
3255
3256         return R( EngineUnmarshallData< R>()( _exec() ) );
3257      }
3258      else
3259      {
3260         SimConsoleThreadExecCallback cb;
3261         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, false, &cb);
3262         evt->populateArgs(mArgv);
3263         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3264
3265         EngineMarshallData( a, mArgc, mArgv );
3266         EngineMarshallData( b, mArgc, mArgv );
3267
3268         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3269
3270         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3271      }
3272   }
3273   
3274   template< typename R, typename A, typename B, typename C >
3275   R call( A a, B b, C c )
3276   {
3277      if (Con::isMainThread())
3278      {
3279         ConsoleStackFrameSaver sav; sav.save();
3280         CSTK.reserveValues(mArgc+3, mArgv);
3281         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3282
3283         EngineMarshallData( a, mArgc, mArgv );
3284         EngineMarshallData( b, mArgc, mArgv );
3285         EngineMarshallData( c, mArgc, mArgv );
3286
3287         return R( EngineUnmarshallData< R>()( _exec() ) );
3288      }
3289      else
3290      {
3291         SimConsoleThreadExecCallback cb;
3292         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, false, &cb);
3293         evt->populateArgs(mArgv);
3294         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3295
3296         EngineMarshallData( a, mArgc, mArgv );
3297         EngineMarshallData( b, mArgc, mArgv );
3298         EngineMarshallData( c, mArgc, mArgv );
3299
3300         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3301
3302         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3303      }
3304   }
3305   
3306   template< typename R, typename A, typename B, typename C, typename D >
3307   R call( A a, B b, C c, D d )
3308   {
3309      if (Con::isMainThread())
3310      {
3311         ConsoleStackFrameSaver sav; sav.save();
3312         CSTK.reserveValues(mArgc+4, mArgv);
3313         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3314
3315         EngineMarshallData( a, mArgc, mArgv );
3316         EngineMarshallData( b, mArgc, mArgv );
3317         EngineMarshallData( c, mArgc, mArgv );
3318         EngineMarshallData( d, mArgc, mArgv );
3319
3320         return R( EngineUnmarshallData< R>()( _exec() ) );
3321      }
3322      else
3323      {
3324         SimConsoleThreadExecCallback cb;
3325         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, false, &cb);
3326         evt->populateArgs(mArgv);
3327         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3328
3329         EngineMarshallData( a, mArgc, mArgv );
3330         EngineMarshallData( b, mArgc, mArgv );
3331         EngineMarshallData( c, mArgc, mArgv );
3332         EngineMarshallData( d, mArgc, mArgv );
3333
3334         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3335
3336         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3337      }
3338   }
3339   
3340   template< typename R, typename A, typename B, typename C, typename D, typename E >
3341   R call( A a, B b, C c, D d, E e )
3342   {
3343      if (Con::isMainThread())
3344      {
3345         ConsoleStackFrameSaver sav; sav.save();
3346         CSTK.reserveValues(mArgc+5, mArgv);
3347         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3348
3349         EngineMarshallData( a, mArgc, mArgv );
3350         EngineMarshallData( b, mArgc, mArgv );
3351         EngineMarshallData( c, mArgc, mArgv );
3352         EngineMarshallData( d, mArgc, mArgv );
3353         EngineMarshallData( e, mArgc, mArgv );
3354
3355         return R( EngineUnmarshallData< R>()( _exec() ) );
3356      }
3357      else
3358      {
3359         SimConsoleThreadExecCallback cb;
3360         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, false, &cb);
3361         evt->populateArgs(mArgv);
3362         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3363
3364         EngineMarshallData( a, mArgc, mArgv );
3365         EngineMarshallData( b, mArgc, mArgv );
3366         EngineMarshallData( c, mArgc, mArgv );
3367         EngineMarshallData( d, mArgc, mArgv );
3368         EngineMarshallData( e, mArgc, mArgv );
3369
3370         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3371
3372         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3373      }
3374   }
3375   
3376   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
3377   R call( A a, B b, C c, D d, E e, F f )
3378   {
3379      if (Con::isMainThread())
3380      {
3381         ConsoleStackFrameSaver sav; sav.save();
3382         CSTK.reserveValues(mArgc+6, mArgv);
3383         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3384
3385         EngineMarshallData( a, mArgc, mArgv );
3386         EngineMarshallData( b, mArgc, mArgv );
3387         EngineMarshallData( c, mArgc, mArgv );
3388         EngineMarshallData( d, mArgc, mArgv );
3389         EngineMarshallData( e, mArgc, mArgv );
3390         EngineMarshallData( f, mArgc, mArgv );
3391
3392         return R( EngineUnmarshallData< R>()( _exec() ) );
3393      }
3394      else
3395      {
3396         SimConsoleThreadExecCallback cb;
3397         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, false, &cb);
3398         evt->populateArgs(mArgv);
3399         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3400
3401         EngineMarshallData( a, mArgc, mArgv );
3402         EngineMarshallData( b, mArgc, mArgv );
3403         EngineMarshallData( c, mArgc, mArgv );
3404         EngineMarshallData( d, mArgc, mArgv );
3405         EngineMarshallData( e, mArgc, mArgv );
3406         EngineMarshallData( f, mArgc, mArgv );
3407
3408         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3409
3410         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3411      }
3412   }
3413   
3414   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
3415   R call( A a, B b, C c, D d, E e, F f, G g )
3416   {
3417      if (Con::isMainThread())
3418      {
3419         ConsoleStackFrameSaver sav; sav.save();
3420         CSTK.reserveValues(mArgc+7, mArgv);
3421         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3422
3423         EngineMarshallData( a, mArgc, mArgv );
3424         EngineMarshallData( b, mArgc, mArgv );
3425         EngineMarshallData( c, mArgc, mArgv );
3426         EngineMarshallData( d, mArgc, mArgv );
3427         EngineMarshallData( e, mArgc, mArgv );
3428         EngineMarshallData( f, mArgc, mArgv );
3429         EngineMarshallData( g, mArgc, mArgv );
3430
3431         return R( EngineUnmarshallData< R>()( _exec() ) );
3432      }
3433      else
3434      {
3435         SimConsoleThreadExecCallback cb;
3436         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, false, &cb);
3437         evt->populateArgs(mArgv);
3438         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3439
3440         EngineMarshallData( a, mArgc, mArgv );
3441         EngineMarshallData( b, mArgc, mArgv );
3442         EngineMarshallData( c, mArgc, mArgv );
3443         EngineMarshallData( d, mArgc, mArgv );
3444         EngineMarshallData( e, mArgc, mArgv );
3445         EngineMarshallData( f, mArgc, mArgv );
3446         EngineMarshallData( g, mArgc, mArgv );
3447
3448         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3449
3450         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3451      }
3452   }
3453   
3454   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
3455   R call( A a, B b, C c, D d, E e, F f, G g, H h )
3456   {
3457      if (Con::isMainThread())
3458      {
3459         ConsoleStackFrameSaver sav; sav.save();
3460         CSTK.reserveValues(mArgc+8, mArgv);
3461         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3462
3463         EngineMarshallData( a, mArgc, mArgv );
3464         EngineMarshallData( b, mArgc, mArgv );
3465         EngineMarshallData( c, mArgc, mArgv );
3466         EngineMarshallData( d, mArgc, mArgv );
3467         EngineMarshallData( e, mArgc, mArgv );
3468         EngineMarshallData( f, mArgc, mArgv );
3469         EngineMarshallData( g, mArgc, mArgv );
3470         EngineMarshallData( h, mArgc, mArgv );
3471
3472         return R( EngineUnmarshallData< R>()( _exec() ) );
3473      }
3474      else
3475      {
3476         SimConsoleThreadExecCallback cb;
3477         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, false, &cb);
3478         evt->populateArgs(mArgv);
3479         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3480
3481         EngineMarshallData( a, mArgc, mArgv );
3482         EngineMarshallData( b, mArgc, mArgv );
3483         EngineMarshallData( c, mArgc, mArgv );
3484         EngineMarshallData( d, mArgc, mArgv );
3485         EngineMarshallData( e, mArgc, mArgv );
3486         EngineMarshallData( f, mArgc, mArgv );
3487         EngineMarshallData( g, mArgc, mArgv );
3488         EngineMarshallData( h, mArgc, mArgv );
3489
3490         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3491
3492         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3493      }
3494   }
3495   
3496   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
3497   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
3498   {
3499      if (Con::isMainThread())
3500      {
3501         ConsoleStackFrameSaver sav; sav.save();
3502         CSTK.reserveValues(mArgc+9, mArgv);
3503         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3504
3505         EngineMarshallData( a, mArgc, mArgv );
3506         EngineMarshallData( b, mArgc, mArgv );
3507         EngineMarshallData( c, mArgc, mArgv );
3508         EngineMarshallData( d, mArgc, mArgv );
3509         EngineMarshallData( e, mArgc, mArgv );
3510         EngineMarshallData( f, mArgc, mArgv );
3511         EngineMarshallData( g, mArgc, mArgv );
3512         EngineMarshallData( h, mArgc, mArgv );
3513         EngineMarshallData( i, mArgc, mArgv );
3514
3515         return R( EngineUnmarshallData< R>()( _exec() ) );
3516      }
3517      else
3518      {
3519         SimConsoleThreadExecCallback cb;
3520         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, false, &cb);
3521         evt->populateArgs(mArgv);
3522         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3523
3524         EngineMarshallData( a, mArgc, mArgv );
3525         EngineMarshallData( b, mArgc, mArgv );
3526         EngineMarshallData( c, mArgc, mArgv );
3527         EngineMarshallData( d, mArgc, mArgv );
3528         EngineMarshallData( e, mArgc, mArgv );
3529         EngineMarshallData( f, mArgc, mArgv );
3530         EngineMarshallData( g, mArgc, mArgv );
3531         EngineMarshallData( h, mArgc, mArgv );
3532         EngineMarshallData( i, mArgc, mArgv );
3533
3534         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3535
3536         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3537      }
3538   }
3539   
3540   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
3541   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
3542   {
3543      if (Con::isMainThread())
3544      {
3545         ConsoleStackFrameSaver sav; sav.save();
3546         CSTK.reserveValues(mArgc+10, mArgv);
3547         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3548
3549         EngineMarshallData( a, mArgc, mArgv );
3550         EngineMarshallData( b, mArgc, mArgv );
3551         EngineMarshallData( c, mArgc, mArgv );
3552         EngineMarshallData( d, mArgc, mArgv );
3553         EngineMarshallData( e, mArgc, mArgv );
3554         EngineMarshallData( f, mArgc, mArgv );
3555         EngineMarshallData( g, mArgc, mArgv );
3556         EngineMarshallData( h, mArgc, mArgv );
3557         EngineMarshallData( i, mArgc, mArgv );
3558         EngineMarshallData( j, mArgc, mArgv );
3559
3560         return R( EngineUnmarshallData< R>()( _exec() ) );
3561      }
3562      else
3563      {
3564         SimConsoleThreadExecCallback cb;
3565         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, false, &cb);
3566         evt->populateArgs(mArgv);
3567         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3568
3569         EngineMarshallData( a, mArgc, mArgv );
3570         EngineMarshallData( b, mArgc, mArgv );
3571         EngineMarshallData( c, mArgc, mArgv );
3572         EngineMarshallData( d, mArgc, mArgv );
3573         EngineMarshallData( e, mArgc, mArgv );
3574         EngineMarshallData( f, mArgc, mArgv );
3575         EngineMarshallData( g, mArgc, mArgv );
3576         EngineMarshallData( h, mArgc, mArgv );
3577         EngineMarshallData( i, mArgc, mArgv );
3578         EngineMarshallData( j, mArgc, mArgv );
3579
3580         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3581
3582         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3583      }
3584   }
3585   
3586   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 >
3587   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
3588   {
3589      if (Con::isMainThread())
3590      {
3591         ConsoleStackFrameSaver sav; sav.save();
3592         CSTK.reserveValues(mArgc+11, mArgv);
3593         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3594
3595         EngineMarshallData( a, mArgc, mArgv );
3596         EngineMarshallData( b, mArgc, mArgv );
3597         EngineMarshallData( c, mArgc, mArgv );
3598         EngineMarshallData( d, mArgc, mArgv );
3599         EngineMarshallData( e, mArgc, mArgv );
3600         EngineMarshallData( f, mArgc, mArgv );
3601         EngineMarshallData( g, mArgc, mArgv );
3602         EngineMarshallData( h, mArgc, mArgv );
3603         EngineMarshallData( i, mArgc, mArgv );
3604         EngineMarshallData( j, mArgc, mArgv );
3605         EngineMarshallData( k, mArgc, mArgv );
3606
3607         return R( EngineUnmarshallData< R>()( _exec() ) );
3608      }
3609      else
3610      {
3611         SimConsoleThreadExecCallback cb;
3612         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, false, &cb);
3613         evt->populateArgs(mArgv);
3614         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3615
3616         EngineMarshallData( a, mArgc, mArgv );
3617         EngineMarshallData( b, mArgc, mArgv );
3618         EngineMarshallData( c, mArgc, mArgv );
3619         EngineMarshallData( d, mArgc, mArgv );
3620         EngineMarshallData( e, mArgc, mArgv );
3621         EngineMarshallData( f, mArgc, mArgv );
3622         EngineMarshallData( g, mArgc, mArgv );
3623         EngineMarshallData( h, mArgc, mArgv );
3624         EngineMarshallData( i, mArgc, mArgv );
3625         EngineMarshallData( j, mArgc, mArgv );
3626         EngineMarshallData( k, mArgc, mArgv );
3627
3628         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3629
3630         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3631      }
3632   }
3633   
3634   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 >
3635   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 )
3636   {
3637      if (Con::isMainThread())
3638      {
3639         ConsoleStackFrameSaver sav; sav.save();
3640         CSTK.reserveValues(mArgc+12, mArgv);
3641         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3642
3643         EngineMarshallData( a, mArgc, mArgv );
3644         EngineMarshallData( b, mArgc, mArgv );
3645         EngineMarshallData( c, mArgc, mArgv );
3646         EngineMarshallData( d, mArgc, mArgv );
3647         EngineMarshallData( e, mArgc, mArgv );
3648         EngineMarshallData( f, mArgc, mArgv );
3649         EngineMarshallData( g, mArgc, mArgv );
3650         EngineMarshallData( h, mArgc, mArgv );
3651         EngineMarshallData( i, mArgc, mArgv );
3652         EngineMarshallData( j, mArgc, mArgv );
3653         EngineMarshallData( k, mArgc, mArgv );
3654         EngineMarshallData( l, mArgc, mArgv );
3655
3656         return R( EngineUnmarshallData< R>()( _exec() ) );
3657      }
3658      else
3659      {
3660         SimConsoleThreadExecCallback cb;
3661         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+12, NULL, false, &cb);
3662         evt->populateArgs(mArgv);
3663         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
3664
3665         EngineMarshallData( a, mArgc, mArgv );
3666         EngineMarshallData( b, mArgc, mArgv );
3667         EngineMarshallData( c, mArgc, mArgv );
3668         EngineMarshallData( d, mArgc, mArgv );
3669         EngineMarshallData( e, mArgc, mArgv );
3670         EngineMarshallData( f, mArgc, mArgv );
3671         EngineMarshallData( g, mArgc, mArgv );
3672         EngineMarshallData( h, mArgc, mArgv );
3673         EngineMarshallData( i, mArgc, mArgv );
3674         EngineMarshallData( j, mArgc, mArgv );
3675         EngineMarshallData( k, mArgc, mArgv );
3676         EngineMarshallData( l, mArgc, mArgv );
3677
3678         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
3679
3680         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3681      }
3682   }
3683   
3684};
3685
3686
3687// Override for when first parameter is presumably a SimObject*, in which case A will be absorbed as the callback
3688template<typename P1> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper
3689{
3690public:
3691
3692   _EngineConsoleExecCallbackHelper( SimObject* pThis )
3693   {
3694      mThis = pThis;
3695      mArgc = mInitialArgc = 2;
3696      mCallbackName = NULL;
3697   }
3698
3699   
3700   template< typename R, typename A >
3701   R call( A a )
3702   {
3703      if (Con::isMainThread())
3704      {
3705         ConsoleStackFrameSaver sav; sav.save();
3706         CSTK.reserveValues(mArgc+0, mArgv);
3707         mArgv[ 0 ].value->setStackStringValue(a);
3708
3709         
3710
3711         return R( EngineUnmarshallData< R>()( _exec() ) );
3712      }
3713      else
3714      {
3715         SimConsoleThreadExecCallback cb;
3716         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+0, NULL, true, &cb);
3717         evt->populateArgs(mArgv);
3718         mArgv[ 0 ].value->setStackStringValue(a);
3719
3720         
3721
3722         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
3723
3724         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3725      }
3726   }
3727   
3728   template< typename R, typename A, typename B >
3729   R call( A a, B b )
3730   {
3731      if (Con::isMainThread())
3732      {
3733         ConsoleStackFrameSaver sav; sav.save();
3734         CSTK.reserveValues(mArgc+1, mArgv);
3735         mArgv[ 0 ].value->setStackStringValue(a);
3736
3737         EngineMarshallData( b, mArgc, mArgv );
3738
3739         return R( EngineUnmarshallData< R>()( _exec() ) );
3740      }
3741      else
3742      {
3743         SimConsoleThreadExecCallback cb;
3744         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, true, &cb);
3745         evt->populateArgs(mArgv);
3746         mArgv[ 0 ].value->setStackStringValue(a);
3747
3748         EngineMarshallData( b, mArgc, mArgv );
3749
3750         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
3751
3752         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3753      }
3754   }
3755   
3756   template< typename R, typename A, typename B, typename C >
3757   R call( A a, B b, C c )
3758   {
3759      if (Con::isMainThread())
3760      {
3761         ConsoleStackFrameSaver sav; sav.save();
3762         CSTK.reserveValues(mArgc+2, mArgv);
3763         mArgv[ 0 ].value->setStackStringValue(a);
3764
3765         EngineMarshallData( b, mArgc, mArgv );
3766         EngineMarshallData( c, mArgc, mArgv );
3767
3768         return R( EngineUnmarshallData< R>()( _exec() ) );
3769      }
3770      else
3771      {
3772         SimConsoleThreadExecCallback cb;
3773         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, true, &cb);
3774         evt->populateArgs(mArgv);
3775         mArgv[ 0 ].value->setStackStringValue(a);
3776
3777         EngineMarshallData( b, mArgc, mArgv );
3778         EngineMarshallData( c, mArgc, mArgv );
3779
3780         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
3781
3782         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3783      }
3784   }
3785   
3786   template< typename R, typename A, typename B, typename C, typename D >
3787   R call( A a, B b, C c, D d )
3788   {
3789      if (Con::isMainThread())
3790      {
3791         ConsoleStackFrameSaver sav; sav.save();
3792         CSTK.reserveValues(mArgc+3, mArgv);
3793         mArgv[ 0 ].value->setStackStringValue(a);
3794
3795         EngineMarshallData( b, mArgc, mArgv );
3796         EngineMarshallData( c, mArgc, mArgv );
3797         EngineMarshallData( d, mArgc, mArgv );
3798
3799         return R( EngineUnmarshallData< R>()( _exec() ) );
3800      }
3801      else
3802      {
3803         SimConsoleThreadExecCallback cb;
3804         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, true, &cb);
3805         evt->populateArgs(mArgv);
3806         mArgv[ 0 ].value->setStackStringValue(a);
3807
3808         EngineMarshallData( b, mArgc, mArgv );
3809         EngineMarshallData( c, mArgc, mArgv );
3810         EngineMarshallData( d, mArgc, mArgv );
3811
3812         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
3813
3814         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3815      }
3816   }
3817   
3818   template< typename R, typename A, typename B, typename C, typename D, typename E >
3819   R call( A a, B b, C c, D d, E e )
3820   {
3821      if (Con::isMainThread())
3822      {
3823         ConsoleStackFrameSaver sav; sav.save();
3824         CSTK.reserveValues(mArgc+4, mArgv);
3825         mArgv[ 0 ].value->setStackStringValue(a);
3826
3827         EngineMarshallData( b, mArgc, mArgv );
3828         EngineMarshallData( c, mArgc, mArgv );
3829         EngineMarshallData( d, mArgc, mArgv );
3830         EngineMarshallData( e, mArgc, mArgv );
3831
3832         return R( EngineUnmarshallData< R>()( _exec() ) );
3833      }
3834      else
3835      {
3836         SimConsoleThreadExecCallback cb;
3837         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, true, &cb);
3838         evt->populateArgs(mArgv);
3839         mArgv[ 0 ].value->setStackStringValue(a);
3840
3841         EngineMarshallData( b, mArgc, mArgv );
3842         EngineMarshallData( c, mArgc, mArgv );
3843         EngineMarshallData( d, mArgc, mArgv );
3844         EngineMarshallData( e, mArgc, mArgv );
3845
3846         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
3847
3848         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3849      }
3850   }
3851   
3852   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
3853   R call( A a, B b, C c, D d, E e, F f )
3854   {
3855      if (Con::isMainThread())
3856      {
3857         ConsoleStackFrameSaver sav; sav.save();
3858         CSTK.reserveValues(mArgc+5, mArgv);
3859         mArgv[ 0 ].value->setStackStringValue(a);
3860
3861         EngineMarshallData( b, mArgc, mArgv );
3862         EngineMarshallData( c, mArgc, mArgv );
3863         EngineMarshallData( d, mArgc, mArgv );
3864         EngineMarshallData( e, mArgc, mArgv );
3865         EngineMarshallData( f, mArgc, mArgv );
3866
3867         return R( EngineUnmarshallData< R>()( _exec() ) );
3868      }
3869      else
3870      {
3871         SimConsoleThreadExecCallback cb;
3872         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, true, &cb);
3873         evt->populateArgs(mArgv);
3874         mArgv[ 0 ].value->setStackStringValue(a);
3875
3876         EngineMarshallData( b, mArgc, mArgv );
3877         EngineMarshallData( c, mArgc, mArgv );
3878         EngineMarshallData( d, mArgc, mArgv );
3879         EngineMarshallData( e, mArgc, mArgv );
3880         EngineMarshallData( f, mArgc, mArgv );
3881
3882         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
3883
3884         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3885      }
3886   }
3887   
3888   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
3889   R call( A a, B b, C c, D d, E e, F f, G g )
3890   {
3891      if (Con::isMainThread())
3892      {
3893         ConsoleStackFrameSaver sav; sav.save();
3894         CSTK.reserveValues(mArgc+6, mArgv);
3895         mArgv[ 0 ].value->setStackStringValue(a);
3896
3897         EngineMarshallData( b, mArgc, mArgv );
3898         EngineMarshallData( c, mArgc, mArgv );
3899         EngineMarshallData( d, mArgc, mArgv );
3900         EngineMarshallData( e, mArgc, mArgv );
3901         EngineMarshallData( f, mArgc, mArgv );
3902         EngineMarshallData( g, mArgc, mArgv );
3903
3904         return R( EngineUnmarshallData< R>()( _exec() ) );
3905      }
3906      else
3907      {
3908         SimConsoleThreadExecCallback cb;
3909         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, true, &cb);
3910         evt->populateArgs(mArgv);
3911         mArgv[ 0 ].value->setStackStringValue(a);
3912
3913         EngineMarshallData( b, mArgc, mArgv );
3914         EngineMarshallData( c, mArgc, mArgv );
3915         EngineMarshallData( d, mArgc, mArgv );
3916         EngineMarshallData( e, mArgc, mArgv );
3917         EngineMarshallData( f, mArgc, mArgv );
3918         EngineMarshallData( g, mArgc, mArgv );
3919
3920         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
3921
3922         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3923      }
3924   }
3925   
3926   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
3927   R call( A a, B b, C c, D d, E e, F f, G g, H h )
3928   {
3929      if (Con::isMainThread())
3930      {
3931         ConsoleStackFrameSaver sav; sav.save();
3932         CSTK.reserveValues(mArgc+7, mArgv);
3933         mArgv[ 0 ].value->setStackStringValue(a);
3934
3935         EngineMarshallData( b, mArgc, mArgv );
3936         EngineMarshallData( c, mArgc, mArgv );
3937         EngineMarshallData( d, mArgc, mArgv );
3938         EngineMarshallData( e, mArgc, mArgv );
3939         EngineMarshallData( f, mArgc, mArgv );
3940         EngineMarshallData( g, mArgc, mArgv );
3941         EngineMarshallData( h, mArgc, mArgv );
3942
3943         return R( EngineUnmarshallData< R>()( _exec() ) );
3944      }
3945      else
3946      {
3947         SimConsoleThreadExecCallback cb;
3948         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, true, &cb);
3949         evt->populateArgs(mArgv);
3950         mArgv[ 0 ].value->setStackStringValue(a);
3951
3952         EngineMarshallData( b, mArgc, mArgv );
3953         EngineMarshallData( c, mArgc, mArgv );
3954         EngineMarshallData( d, mArgc, mArgv );
3955         EngineMarshallData( e, mArgc, mArgv );
3956         EngineMarshallData( f, mArgc, mArgv );
3957         EngineMarshallData( g, mArgc, mArgv );
3958         EngineMarshallData( h, mArgc, mArgv );
3959
3960         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
3961
3962         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
3963      }
3964   }
3965   
3966   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
3967   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
3968   {
3969      if (Con::isMainThread())
3970      {
3971         ConsoleStackFrameSaver sav; sav.save();
3972         CSTK.reserveValues(mArgc+8, mArgv);
3973         mArgv[ 0 ].value->setStackStringValue(a);
3974
3975         EngineMarshallData( b, mArgc, mArgv );
3976         EngineMarshallData( c, mArgc, mArgv );
3977         EngineMarshallData( d, mArgc, mArgv );
3978         EngineMarshallData( e, mArgc, mArgv );
3979         EngineMarshallData( f, mArgc, mArgv );
3980         EngineMarshallData( g, mArgc, mArgv );
3981         EngineMarshallData( h, mArgc, mArgv );
3982         EngineMarshallData( i, mArgc, mArgv );
3983
3984         return R( EngineUnmarshallData< R>()( _exec() ) );
3985      }
3986      else
3987      {
3988         SimConsoleThreadExecCallback cb;
3989         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, true, &cb);
3990         evt->populateArgs(mArgv);
3991         mArgv[ 0 ].value->setStackStringValue(a);
3992
3993         EngineMarshallData( b, mArgc, mArgv );
3994         EngineMarshallData( c, mArgc, mArgv );
3995         EngineMarshallData( d, mArgc, mArgv );
3996         EngineMarshallData( e, mArgc, mArgv );
3997         EngineMarshallData( f, mArgc, mArgv );
3998         EngineMarshallData( g, mArgc, mArgv );
3999         EngineMarshallData( h, mArgc, mArgv );
4000         EngineMarshallData( i, mArgc, mArgv );
4001
4002         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
4003
4004         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4005      }
4006   }
4007   
4008   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
4009   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
4010   {
4011      if (Con::isMainThread())
4012      {
4013         ConsoleStackFrameSaver sav; sav.save();
4014         CSTK.reserveValues(mArgc+9, mArgv);
4015         mArgv[ 0 ].value->setStackStringValue(a);
4016
4017         EngineMarshallData( b, mArgc, mArgv );
4018         EngineMarshallData( c, mArgc, mArgv );
4019         EngineMarshallData( d, mArgc, mArgv );
4020         EngineMarshallData( e, mArgc, mArgv );
4021         EngineMarshallData( f, mArgc, mArgv );
4022         EngineMarshallData( g, mArgc, mArgv );
4023         EngineMarshallData( h, mArgc, mArgv );
4024         EngineMarshallData( i, mArgc, mArgv );
4025         EngineMarshallData( j, mArgc, mArgv );
4026
4027         return R( EngineUnmarshallData< R>()( _exec() ) );
4028      }
4029      else
4030      {
4031         SimConsoleThreadExecCallback cb;
4032         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, true, &cb);
4033         evt->populateArgs(mArgv);
4034         mArgv[ 0 ].value->setStackStringValue(a);
4035
4036         EngineMarshallData( b, mArgc, mArgv );
4037         EngineMarshallData( c, mArgc, mArgv );
4038         EngineMarshallData( d, mArgc, mArgv );
4039         EngineMarshallData( e, mArgc, mArgv );
4040         EngineMarshallData( f, mArgc, mArgv );
4041         EngineMarshallData( g, mArgc, mArgv );
4042         EngineMarshallData( h, mArgc, mArgv );
4043         EngineMarshallData( i, mArgc, mArgv );
4044         EngineMarshallData( j, mArgc, mArgv );
4045
4046         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
4047
4048         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4049      }
4050   }
4051   
4052   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 >
4053   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
4054   {
4055      if (Con::isMainThread())
4056      {
4057         ConsoleStackFrameSaver sav; sav.save();
4058         CSTK.reserveValues(mArgc+10, mArgv);
4059         mArgv[ 0 ].value->setStackStringValue(a);
4060
4061         EngineMarshallData( b, mArgc, mArgv );
4062         EngineMarshallData( c, mArgc, mArgv );
4063         EngineMarshallData( d, mArgc, mArgv );
4064         EngineMarshallData( e, mArgc, mArgv );
4065         EngineMarshallData( f, mArgc, mArgv );
4066         EngineMarshallData( g, mArgc, mArgv );
4067         EngineMarshallData( h, mArgc, mArgv );
4068         EngineMarshallData( i, mArgc, mArgv );
4069         EngineMarshallData( j, mArgc, mArgv );
4070         EngineMarshallData( k, mArgc, mArgv );
4071
4072         return R( EngineUnmarshallData< R>()( _exec() ) );
4073      }
4074      else
4075      {
4076         SimConsoleThreadExecCallback cb;
4077         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, true, &cb);
4078         evt->populateArgs(mArgv);
4079         mArgv[ 0 ].value->setStackStringValue(a);
4080
4081         EngineMarshallData( b, mArgc, mArgv );
4082         EngineMarshallData( c, mArgc, mArgv );
4083         EngineMarshallData( d, mArgc, mArgv );
4084         EngineMarshallData( e, mArgc, mArgv );
4085         EngineMarshallData( f, mArgc, mArgv );
4086         EngineMarshallData( g, mArgc, mArgv );
4087         EngineMarshallData( h, mArgc, mArgv );
4088         EngineMarshallData( i, mArgc, mArgv );
4089         EngineMarshallData( j, mArgc, mArgv );
4090         EngineMarshallData( k, mArgc, mArgv );
4091
4092         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
4093
4094         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4095      }
4096   }
4097   
4098   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 >
4099   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 )
4100   {
4101      if (Con::isMainThread())
4102      {
4103         ConsoleStackFrameSaver sav; sav.save();
4104         CSTK.reserveValues(mArgc+11, mArgv);
4105         mArgv[ 0 ].value->setStackStringValue(a);
4106
4107         EngineMarshallData( b, mArgc, mArgv );
4108         EngineMarshallData( c, mArgc, mArgv );
4109         EngineMarshallData( d, mArgc, mArgv );
4110         EngineMarshallData( e, mArgc, mArgv );
4111         EngineMarshallData( f, mArgc, mArgv );
4112         EngineMarshallData( g, mArgc, mArgv );
4113         EngineMarshallData( h, mArgc, mArgv );
4114         EngineMarshallData( i, mArgc, mArgv );
4115         EngineMarshallData( j, mArgc, mArgv );
4116         EngineMarshallData( k, mArgc, mArgv );
4117         EngineMarshallData( l, mArgc, mArgv );
4118
4119         return R( EngineUnmarshallData< R>()( _exec() ) );
4120      }
4121      else
4122      {
4123         SimConsoleThreadExecCallback cb;
4124         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, true, &cb);
4125         evt->populateArgs(mArgv);
4126         mArgv[ 0 ].value->setStackStringValue(a);
4127
4128         EngineMarshallData( b, mArgc, mArgv );
4129         EngineMarshallData( c, mArgc, mArgv );
4130         EngineMarshallData( d, mArgc, mArgv );
4131         EngineMarshallData( e, mArgc, mArgv );
4132         EngineMarshallData( f, mArgc, mArgv );
4133         EngineMarshallData( g, mArgc, mArgv );
4134         EngineMarshallData( h, mArgc, mArgv );
4135         EngineMarshallData( i, mArgc, mArgv );
4136         EngineMarshallData( j, mArgc, mArgv );
4137         EngineMarshallData( k, mArgc, mArgv );
4138         EngineMarshallData( l, mArgc, mArgv );
4139
4140         Sim::postEvent(mThis, evt, Sim::getCurrentTime());
4141
4142         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4143      }
4144   }
4145   
4146};
4147
4148// Override for when first parameter is const char*
4149template<> struct _EngineConsoleExecCallbackHelper<const char*> : public _BaseEngineConsoleCallbackHelper
4150{
4151   _EngineConsoleExecCallbackHelper( const char *callbackName )
4152   {
4153      mThis = NULL;
4154      mArgc = mInitialArgc = 1;
4155      mCallbackName = StringTable->insert(callbackName);
4156   }
4157
4158   template< typename R >
4159   R call()
4160   {
4161      if (Con::isMainThread())
4162      {
4163         ConsoleStackFrameSaver sav; sav.save();
4164         CSTK.reserveValues(mArgc, mArgv);
4165         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4166         return R( EngineUnmarshallData< R>()( _exec() ) );
4167      }
4168      else
4169      {
4170         SimConsoleThreadExecCallback cb;
4171         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc, NULL, false, &cb);
4172         evt->populateArgs(mArgv);
4173         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4174
4175         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4176         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4177      }
4178   }
4179
4180
4181   
4182   template< typename R, typename A >
4183   R call( A a )
4184   {
4185      if (Con::isMainThread())
4186      {
4187         ConsoleStackFrameSaver sav; sav.save();
4188         CSTK.reserveValues(mArgc+1, mArgv);
4189         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4190
4191         EngineMarshallData( a, mArgc, mArgv );
4192
4193         return R( EngineUnmarshallData< R>()( _exec() ) );
4194      }
4195      else
4196      {
4197         SimConsoleThreadExecCallback cb;
4198         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, false, &cb);
4199         evt->populateArgs(mArgv);
4200         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4201
4202         EngineMarshallData( a, mArgc, mArgv );
4203
4204         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4205
4206         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4207      }
4208   }
4209   
4210   template< typename R, typename A, typename B >
4211   R call( A a, B b )
4212   {
4213      if (Con::isMainThread())
4214      {
4215         ConsoleStackFrameSaver sav; sav.save();
4216         CSTK.reserveValues(mArgc+2, mArgv);
4217         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4218
4219         EngineMarshallData( a, mArgc, mArgv );
4220         EngineMarshallData( b, mArgc, mArgv );
4221
4222         return R( EngineUnmarshallData< R>()( _exec() ) );
4223      }
4224      else
4225      {
4226         SimConsoleThreadExecCallback cb;
4227         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, false, &cb);
4228         evt->populateArgs(mArgv);
4229         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4230
4231         EngineMarshallData( a, mArgc, mArgv );
4232         EngineMarshallData( b, mArgc, mArgv );
4233
4234         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4235
4236         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4237      }
4238   }
4239   
4240   template< typename R, typename A, typename B, typename C >
4241   R call( A a, B b, C c )
4242   {
4243      if (Con::isMainThread())
4244      {
4245         ConsoleStackFrameSaver sav; sav.save();
4246         CSTK.reserveValues(mArgc+3, mArgv);
4247         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4248
4249         EngineMarshallData( a, mArgc, mArgv );
4250         EngineMarshallData( b, mArgc, mArgv );
4251         EngineMarshallData( c, mArgc, mArgv );
4252
4253         return R( EngineUnmarshallData< R>()( _exec() ) );
4254      }
4255      else
4256      {
4257         SimConsoleThreadExecCallback cb;
4258         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, false, &cb);
4259         evt->populateArgs(mArgv);
4260         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4261
4262         EngineMarshallData( a, mArgc, mArgv );
4263         EngineMarshallData( b, mArgc, mArgv );
4264         EngineMarshallData( c, mArgc, mArgv );
4265
4266         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4267
4268         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4269      }
4270   }
4271   
4272   template< typename R, typename A, typename B, typename C, typename D >
4273   R call( A a, B b, C c, D d )
4274   {
4275      if (Con::isMainThread())
4276      {
4277         ConsoleStackFrameSaver sav; sav.save();
4278         CSTK.reserveValues(mArgc+4, mArgv);
4279         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4280
4281         EngineMarshallData( a, mArgc, mArgv );
4282         EngineMarshallData( b, mArgc, mArgv );
4283         EngineMarshallData( c, mArgc, mArgv );
4284         EngineMarshallData( d, mArgc, mArgv );
4285
4286         return R( EngineUnmarshallData< R>()( _exec() ) );
4287      }
4288      else
4289      {
4290         SimConsoleThreadExecCallback cb;
4291         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, false, &cb);
4292         evt->populateArgs(mArgv);
4293         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4294
4295         EngineMarshallData( a, mArgc, mArgv );
4296         EngineMarshallData( b, mArgc, mArgv );
4297         EngineMarshallData( c, mArgc, mArgv );
4298         EngineMarshallData( d, mArgc, mArgv );
4299
4300         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4301
4302         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4303      }
4304   }
4305   
4306   template< typename R, typename A, typename B, typename C, typename D, typename E >
4307   R call( A a, B b, C c, D d, E e )
4308   {
4309      if (Con::isMainThread())
4310      {
4311         ConsoleStackFrameSaver sav; sav.save();
4312         CSTK.reserveValues(mArgc+5, mArgv);
4313         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4314
4315         EngineMarshallData( a, mArgc, mArgv );
4316         EngineMarshallData( b, mArgc, mArgv );
4317         EngineMarshallData( c, mArgc, mArgv );
4318         EngineMarshallData( d, mArgc, mArgv );
4319         EngineMarshallData( e, mArgc, mArgv );
4320
4321         return R( EngineUnmarshallData< R>()( _exec() ) );
4322      }
4323      else
4324      {
4325         SimConsoleThreadExecCallback cb;
4326         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, false, &cb);
4327         evt->populateArgs(mArgv);
4328         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4329
4330         EngineMarshallData( a, mArgc, mArgv );
4331         EngineMarshallData( b, mArgc, mArgv );
4332         EngineMarshallData( c, mArgc, mArgv );
4333         EngineMarshallData( d, mArgc, mArgv );
4334         EngineMarshallData( e, mArgc, mArgv );
4335
4336         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4337
4338         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4339      }
4340   }
4341   
4342   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F >
4343   R call( A a, B b, C c, D d, E e, F f )
4344   {
4345      if (Con::isMainThread())
4346      {
4347         ConsoleStackFrameSaver sav; sav.save();
4348         CSTK.reserveValues(mArgc+6, mArgv);
4349         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4350
4351         EngineMarshallData( a, mArgc, mArgv );
4352         EngineMarshallData( b, mArgc, mArgv );
4353         EngineMarshallData( c, mArgc, mArgv );
4354         EngineMarshallData( d, mArgc, mArgv );
4355         EngineMarshallData( e, mArgc, mArgv );
4356         EngineMarshallData( f, mArgc, mArgv );
4357
4358         return R( EngineUnmarshallData< R>()( _exec() ) );
4359      }
4360      else
4361      {
4362         SimConsoleThreadExecCallback cb;
4363         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, false, &cb);
4364         evt->populateArgs(mArgv);
4365         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4366
4367         EngineMarshallData( a, mArgc, mArgv );
4368         EngineMarshallData( b, mArgc, mArgv );
4369         EngineMarshallData( c, mArgc, mArgv );
4370         EngineMarshallData( d, mArgc, mArgv );
4371         EngineMarshallData( e, mArgc, mArgv );
4372         EngineMarshallData( f, mArgc, mArgv );
4373
4374         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4375
4376         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4377      }
4378   }
4379   
4380   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G >
4381   R call( A a, B b, C c, D d, E e, F f, G g )
4382   {
4383      if (Con::isMainThread())
4384      {
4385         ConsoleStackFrameSaver sav; sav.save();
4386         CSTK.reserveValues(mArgc+7, mArgv);
4387         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4388
4389         EngineMarshallData( a, mArgc, mArgv );
4390         EngineMarshallData( b, mArgc, mArgv );
4391         EngineMarshallData( c, mArgc, mArgv );
4392         EngineMarshallData( d, mArgc, mArgv );
4393         EngineMarshallData( e, mArgc, mArgv );
4394         EngineMarshallData( f, mArgc, mArgv );
4395         EngineMarshallData( g, mArgc, mArgv );
4396
4397         return R( EngineUnmarshallData< R>()( _exec() ) );
4398      }
4399      else
4400      {
4401         SimConsoleThreadExecCallback cb;
4402         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, false, &cb);
4403         evt->populateArgs(mArgv);
4404         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4405
4406         EngineMarshallData( a, mArgc, mArgv );
4407         EngineMarshallData( b, mArgc, mArgv );
4408         EngineMarshallData( c, mArgc, mArgv );
4409         EngineMarshallData( d, mArgc, mArgv );
4410         EngineMarshallData( e, mArgc, mArgv );
4411         EngineMarshallData( f, mArgc, mArgv );
4412         EngineMarshallData( g, mArgc, mArgv );
4413
4414         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4415
4416         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4417      }
4418   }
4419   
4420   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
4421   R call( A a, B b, C c, D d, E e, F f, G g, H h )
4422   {
4423      if (Con::isMainThread())
4424      {
4425         ConsoleStackFrameSaver sav; sav.save();
4426         CSTK.reserveValues(mArgc+8, mArgv);
4427         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4428
4429         EngineMarshallData( a, mArgc, mArgv );
4430         EngineMarshallData( b, mArgc, mArgv );
4431         EngineMarshallData( c, mArgc, mArgv );
4432         EngineMarshallData( d, mArgc, mArgv );
4433         EngineMarshallData( e, mArgc, mArgv );
4434         EngineMarshallData( f, mArgc, mArgv );
4435         EngineMarshallData( g, mArgc, mArgv );
4436         EngineMarshallData( h, mArgc, mArgv );
4437
4438         return R( EngineUnmarshallData< R>()( _exec() ) );
4439      }
4440      else
4441      {
4442         SimConsoleThreadExecCallback cb;
4443         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, false, &cb);
4444         evt->populateArgs(mArgv);
4445         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4446
4447         EngineMarshallData( a, mArgc, mArgv );
4448         EngineMarshallData( b, mArgc, mArgv );
4449         EngineMarshallData( c, mArgc, mArgv );
4450         EngineMarshallData( d, mArgc, mArgv );
4451         EngineMarshallData( e, mArgc, mArgv );
4452         EngineMarshallData( f, mArgc, mArgv );
4453         EngineMarshallData( g, mArgc, mArgv );
4454         EngineMarshallData( h, mArgc, mArgv );
4455
4456         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4457
4458         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4459      }
4460   }
4461   
4462   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I >
4463   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i )
4464   {
4465      if (Con::isMainThread())
4466      {
4467         ConsoleStackFrameSaver sav; sav.save();
4468         CSTK.reserveValues(mArgc+9, mArgv);
4469         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4470
4471         EngineMarshallData( a, mArgc, mArgv );
4472         EngineMarshallData( b, mArgc, mArgv );
4473         EngineMarshallData( c, mArgc, mArgv );
4474         EngineMarshallData( d, mArgc, mArgv );
4475         EngineMarshallData( e, mArgc, mArgv );
4476         EngineMarshallData( f, mArgc, mArgv );
4477         EngineMarshallData( g, mArgc, mArgv );
4478         EngineMarshallData( h, mArgc, mArgv );
4479         EngineMarshallData( i, mArgc, mArgv );
4480
4481         return R( EngineUnmarshallData< R>()( _exec() ) );
4482      }
4483      else
4484      {
4485         SimConsoleThreadExecCallback cb;
4486         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, false, &cb);
4487         evt->populateArgs(mArgv);
4488         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4489
4490         EngineMarshallData( a, mArgc, mArgv );
4491         EngineMarshallData( b, mArgc, mArgv );
4492         EngineMarshallData( c, mArgc, mArgv );
4493         EngineMarshallData( d, mArgc, mArgv );
4494         EngineMarshallData( e, mArgc, mArgv );
4495         EngineMarshallData( f, mArgc, mArgv );
4496         EngineMarshallData( g, mArgc, mArgv );
4497         EngineMarshallData( h, mArgc, mArgv );
4498         EngineMarshallData( i, mArgc, mArgv );
4499
4500         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4501
4502         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4503      }
4504   }
4505   
4506   template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J >
4507   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j )
4508   {
4509      if (Con::isMainThread())
4510      {
4511         ConsoleStackFrameSaver sav; sav.save();
4512         CSTK.reserveValues(mArgc+10, mArgv);
4513         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4514
4515         EngineMarshallData( a, mArgc, mArgv );
4516         EngineMarshallData( b, mArgc, mArgv );
4517         EngineMarshallData( c, mArgc, mArgv );
4518         EngineMarshallData( d, mArgc, mArgv );
4519         EngineMarshallData( e, mArgc, mArgv );
4520         EngineMarshallData( f, mArgc, mArgv );
4521         EngineMarshallData( g, mArgc, mArgv );
4522         EngineMarshallData( h, mArgc, mArgv );
4523         EngineMarshallData( i, mArgc, mArgv );
4524         EngineMarshallData( j, mArgc, mArgv );
4525
4526         return R( EngineUnmarshallData< R>()( _exec() ) );
4527      }
4528      else
4529      {
4530         SimConsoleThreadExecCallback cb;
4531         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, false, &cb);
4532         evt->populateArgs(mArgv);
4533         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4534
4535         EngineMarshallData( a, mArgc, mArgv );
4536         EngineMarshallData( b, mArgc, mArgv );
4537         EngineMarshallData( c, mArgc, mArgv );
4538         EngineMarshallData( d, mArgc, mArgv );
4539         EngineMarshallData( e, mArgc, mArgv );
4540         EngineMarshallData( f, mArgc, mArgv );
4541         EngineMarshallData( g, mArgc, mArgv );
4542         EngineMarshallData( h, mArgc, mArgv );
4543         EngineMarshallData( i, mArgc, mArgv );
4544         EngineMarshallData( j, mArgc, mArgv );
4545
4546         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4547
4548         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4549      }
4550   }
4551   
4552   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 >
4553   R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k )
4554   {
4555      if (Con::isMainThread())
4556      {
4557         ConsoleStackFrameSaver sav; sav.save();
4558         CSTK.reserveValues(mArgc+11, mArgv);
4559         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4560
4561         EngineMarshallData( a, mArgc, mArgv );
4562         EngineMarshallData( b, mArgc, mArgv );
4563         EngineMarshallData( c, mArgc, mArgv );
4564         EngineMarshallData( d, mArgc, mArgv );
4565         EngineMarshallData( e, mArgc, mArgv );
4566         EngineMarshallData( f, mArgc, mArgv );
4567         EngineMarshallData( g, mArgc, mArgv );
4568         EngineMarshallData( h, mArgc, mArgv );
4569         EngineMarshallData( i, mArgc, mArgv );
4570         EngineMarshallData( j, mArgc, mArgv );
4571         EngineMarshallData( k, mArgc, mArgv );
4572
4573         return R( EngineUnmarshallData< R>()( _exec() ) );
4574      }
4575      else
4576      {
4577         SimConsoleThreadExecCallback cb;
4578         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, false, &cb);
4579         evt->populateArgs(mArgv);
4580         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4581
4582         EngineMarshallData( a, mArgc, mArgv );
4583         EngineMarshallData( b, mArgc, mArgv );
4584         EngineMarshallData( c, mArgc, mArgv );
4585         EngineMarshallData( d, mArgc, mArgv );
4586         EngineMarshallData( e, mArgc, mArgv );
4587         EngineMarshallData( f, mArgc, mArgv );
4588         EngineMarshallData( g, mArgc, mArgv );
4589         EngineMarshallData( h, mArgc, mArgv );
4590         EngineMarshallData( i, mArgc, mArgv );
4591         EngineMarshallData( j, mArgc, mArgv );
4592         EngineMarshallData( k, mArgc, mArgv );
4593
4594         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4595
4596         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4597      }
4598   }
4599   
4600   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 >
4601   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 )
4602   {
4603      if (Con::isMainThread())
4604      {
4605         ConsoleStackFrameSaver sav; sav.save();
4606         CSTK.reserveValues(mArgc+12, mArgv);
4607         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4608
4609         EngineMarshallData( a, mArgc, mArgv );
4610         EngineMarshallData( b, mArgc, mArgv );
4611         EngineMarshallData( c, mArgc, mArgv );
4612         EngineMarshallData( d, mArgc, mArgv );
4613         EngineMarshallData( e, mArgc, mArgv );
4614         EngineMarshallData( f, mArgc, mArgv );
4615         EngineMarshallData( g, mArgc, mArgv );
4616         EngineMarshallData( h, mArgc, mArgv );
4617         EngineMarshallData( i, mArgc, mArgv );
4618         EngineMarshallData( j, mArgc, mArgv );
4619         EngineMarshallData( k, mArgc, mArgv );
4620         EngineMarshallData( l, mArgc, mArgv );
4621
4622         return R( EngineUnmarshallData< R>()( _exec() ) );
4623      }
4624      else
4625      {
4626         SimConsoleThreadExecCallback cb;
4627         SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+12, NULL, false, &cb);
4628         evt->populateArgs(mArgv);
4629         mArgv[ 0 ].value->setStackStringValue(mCallbackName);
4630
4631         EngineMarshallData( a, mArgc, mArgv );
4632         EngineMarshallData( b, mArgc, mArgv );
4633         EngineMarshallData( c, mArgc, mArgv );
4634         EngineMarshallData( d, mArgc, mArgv );
4635         EngineMarshallData( e, mArgc, mArgv );
4636         EngineMarshallData( f, mArgc, mArgv );
4637         EngineMarshallData( g, mArgc, mArgv );
4638         EngineMarshallData( h, mArgc, mArgv );
4639         EngineMarshallData( i, mArgc, mArgv );
4640         EngineMarshallData( j, mArgc, mArgv );
4641         EngineMarshallData( k, mArgc, mArgv );
4642         EngineMarshallData( l, mArgc, mArgv );
4643
4644         Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
4645
4646         return R( EngineUnmarshallData< R>()( cb.waitForResult() ) );
4647      }
4648   }
4649   
4650};
4651
4652// Re-enable some VC warnings we disabled for this file.
4653#pragma warning( pop ) // 4510 and 4610
4654
4655#endif // !_ENGINEAPI_H_
4656