engineTypes.h

Engine/source/console/engineTypes.h

This file forms the basis for Torque's engine API type system.

More...

Classes:

Namespaces:

namespace

Engine Type Traits

Type traits allow to access the static properties of a type at compile-time.

This is primarily useful for templating in order to make decisions based on static typing.

TYPE()

Return the type info for the given engine type.

TYPE(const T & )

Return the type info for the static type of the given variable.

define
T(x) typename < x >::ValueType

Public Defines

define
_DECLARE_BITFIELD(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
define
_DECLARE_BITFIELD_R(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
define
_DECLARE_ENUM(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
define
_DECLARE_ENUM_R(type)    ( type )                                                                   \
   template<>                                                                                \
   struct < type > : public < type > {};
define
_DECLARE_PRIMITIVE(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
define
_DECLARE_PRIMITIVE_R(type)    ( type )                                                                   \
   template<>                                                                                \
   struct < type > : public < type > {};
define
_DECLARE_STRUCT(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
define
_DECLARE_STRUCT_R(type)    ( type )                                                                   \
   template<>                                                                                \
   struct < type > : public < type > {};
define
_DECLARE_TYPE(type)    template<>  * < type >();                                          \
   template<> struct < type > {                                                        \
      & operator()()  {                                                \
         return *static_cast< * >(                                          \
            const_cast< * >( ( < type >() ) )                              \
         );                                                                                  \
      }                                                                                      \
   };
define
_DECLARE_TYPE_R(type)    template<>  * < type >();                                          \
   template<> struct < type > {                                                        \
      & operator()()  {                                                \
         return *reinterpret_cast< * >(                                     \
            const_cast< * >( ( < type >() ) )                              \
         );                                                                                  \
      }                                                                                      \
   };
define
_END_IMPLEMENT_BITFIELD()       };                                                                                                                               \
      static  _sEnumTable( sizeof( _sEnums ) / sizeof( _sEnums[ 0 ] ), _sEnums );                                       \
      < BitfieldType > gsTypeInfo( _sBitfieldName, &_sScope, , _sDoc, &_sEnumTable );        \
   } }
define
_END_IMPLEMENT_ENUM()       };                                                                                                                               \
      static  _sEnumTable( sizeof( _sEnums ) / sizeof( _sEnums[ 0 ] ), _sEnums );                                       \
      < EnumType > gsTypeInfo( _sEnumName, &_sScope, , _sDoc, &_sEnumTable );                    \
   } }
define
_END_IMPLEMENT_STRUCT()          {  }                                                                                                                      \
      };                                                                                                                               \
      static  _sFieldTable( sizeof( _sFields ) / sizeof( _sFields[ 0 ] ) - 1, _sFields );                              \
      < StructType > gsTypeInfo( _sStructName, &_sScope, _sDoc, &_sFieldTable );                                   \
   } }
define
_FIELD(fieldName, exportName, numElements, doc)    { #exportName, doc, numElements, ( ( ( ThisType* ) 16 )->fieldName ), ()( fieldName ) }
define
_FIELD_AS(type, fieldName, exportName, numElements, doc)    { #exportName, doc, numElements, ( *( ( type* ) &( ( ThisType* ) 16 )->fieldName ) ), ()( fieldName ) }
define
_IMPLEMENT_BITFIELD(type, exportName, scope, doc)    namespace { namespace _ ## exportName {                                                                                             \
      extern < type > gsTypeInfo;                                                                                  \
   } }                                                                                                                                 \
   ( type, exportName );                                                                                                \
   namespace { namespace _ ## exportName {                                                                                             \
      typedef type BitfieldType;                                                                                                       \
      static  char*  _sBitfieldName = #exportName;                                                                           \
      static  char*  _sDoc = doc;                                                                                            \
      static & _sScope = < scope >()();                                                                         \
      static  _sEnums[] = {
define
_IMPLEMENT_ENUM(type, exportName, scope, doc)    namespace { namespace _ ## exportName {                                                                                             \
      typedef type EnumType;                                                                                                           \
      extern < EnumType > gsTypeInfo;                                                                              \
   } }                                                                                                                                 \
   ( type, exportName );                                                                                                \
   namespace { namespace _ ## exportName {                                                                                             \
      static  char*  _sEnumName = #exportName;                                                                               \
      static  char*  _sDoc = doc;                                                                                            \
      static & _sScope = < scope >()();                                                                         \
      static  _sEnums[] = {
define
_IMPLEMENT_PRIMITIVE(type, exportName, scope, doc)    namespace { namespace _ ## exportName {                                                                                             \
      static < type > gsTypeInfo( #exportName, &< scope >()(), , doc );               \
   } }                                                                                                                                 \
   ( type, exportName )
define
_IMPLEMENT_STRUCT(type, exportName, scope, doc)    namespace { namespace _ ## exportName {                                                                                             \
      extern < type > gsTypeInfo;                                                                                  \
   } }                                                                                                                                 \
   ( type, exportName );                                                                                                \
   namespace { namespace _ ## exportName {                                                                                             \
      typedef type StructType;                                                                                                         \
      typedef StructType ThisType;                                                                                                     \
      static  char*  _sStructName = #exportName;                                                                             \
      static  char*  _sDoc = doc;                                                                                            \
      static & _sScope = < scope >()();                                                                         \
      static  _sFields[] = {
define
_IMPLEMENT_TYPE(type, exportName)    template<>                                      \
    * < type >()            \
   {                                               \
      return &_ ## exportName::gsTypeInfo;         \
   }
define
ConsoleDocClass(className, doc)    template<>  char* < className, className::_ClassBase >::smDocString = doc;
define
DECLARE_BITFIELD(type)    ( type )
define
DECLARE_BITFIELD_R(type)    ( type )
define
DECLARE_ENUM(type)    ( type )
define
DECLARE_ENUM_R(type)    ( type )
define
DECLARE_PRIMITIVE(type)    ( type )
define
DECLARE_PRIMITIVE_R(type)    ( type )
define
DECLARE_SCOPE(name)    struct name {                                                                             \
      static  __engineExportScopeInst;                                      \
      static & __engineExportScope() { return __engineExportScopeInst; }    \
   };
define
DECLARE_STRUCT(type)    ( type )
define
DECLARE_STRUCT_R(type)    ( type )
define
FIELD(fieldName, exportName, numElements, doc)    (fieldName, exportName, numElements, doc),
define
FIELD_AS(type, fieldName, exportName, numElements, doc)    (type, fieldName, exportName, numElements, doc),
define
FIELDOFFSET(fieldName)    ( ( (  char* ) &( ( ( ThisType* ) 16 )->fieldName ) ) - 16 )
define
IMPLEMENT_BITFIELD(type, exportName, scope, doc)    ( type, exportName, scope, doc )
define
IMPLEMENT_ENUM(type, exportName, scope, doc)    ( type, exportName, scope, doc )
define
IMPLEMENT_PRIMITIVE(type, exportName, scope, doc)    ( type, exportName, scope, doc )
define
IMPLEMENT_SCOPE(name, exportName, scope, doc)     name::__engineExportScopeInst( #exportName, &< scope >()(), doc );
define
IMPLEMENT_STRUCT(type, exportName, scope, doc)    ( type, exportName, scope, doc )

Detailed Description

This file forms the basis for Torque's engine API type system.

The type system is geared towards use in a control layer in a .NET-like environment and is intended to allow for all-native data exchange between the engine and its control layer.

Engine Type Traits

Type traits allow to access the static properties of a type at compile-time.

This is primarily useful for templating in order to make decisions based on static typing.

TYPE()

Return the type info for the given engine type.

TYPE(const T & )

Return the type info for the static type of the given variable.

T(x) typename < x >::ValueType

Public Defines

_DECLARE_BITFIELD(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
_DECLARE_BITFIELD_R(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
_DECLARE_ENUM(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
_DECLARE_ENUM_R(type)    ( type )                                                                   \
   template<>                                                                                \
   struct < type > : public < type > {};
_DECLARE_PRIMITIVE(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
_DECLARE_PRIMITIVE_R(type)    ( type )                                                                   \
   template<>                                                                                \
   struct < type > : public < type > {};
_DECLARE_STRUCT(type)    ( type )                                                                     \
   template<>                                                                                \
   struct < type > : public < type > {};
_DECLARE_STRUCT_R(type)    ( type )                                                                   \
   template<>                                                                                \
   struct < type > : public < type > {};
_DECLARE_TYPE(type)    template<>  * < type >();                                          \
   template<> struct < type > {                                                        \
      & operator()()  {                                                \
         return *static_cast< * >(                                          \
            const_cast< * >( ( < type >() ) )                              \
         );                                                                                  \
      }                                                                                      \
   };
_DECLARE_TYPE_R(type)    template<>  * < type >();                                          \
   template<> struct < type > {                                                        \
      & operator()()  {                                                \
         return *reinterpret_cast< * >(                                     \
            const_cast< * >( ( < type >() ) )                              \
         );                                                                                  \
      }                                                                                      \
   };
_END_IMPLEMENT_BITFIELD()       };                                                                                                                               \
      static  _sEnumTable( sizeof( _sEnums ) / sizeof( _sEnums[ 0 ] ), _sEnums );                                       \
      < BitfieldType > gsTypeInfo( _sBitfieldName, &_sScope, , _sDoc, &_sEnumTable );        \
   } }
_END_IMPLEMENT_ENUM()       };                                                                                                                               \
      static  _sEnumTable( sizeof( _sEnums ) / sizeof( _sEnums[ 0 ] ), _sEnums );                                       \
      < EnumType > gsTypeInfo( _sEnumName, &_sScope, , _sDoc, &_sEnumTable );                    \
   } }
_END_IMPLEMENT_STRUCT()          {  }                                                                                                                      \
      };                                                                                                                               \
      static  _sFieldTable( sizeof( _sFields ) / sizeof( _sFields[ 0 ] ) - 1, _sFields );                              \
      < StructType > gsTypeInfo( _sStructName, &_sScope, _sDoc, &_sFieldTable );                                   \
   } }
_FIELD(fieldName, exportName, numElements, doc)    { #exportName, doc, numElements, ( ( ( ThisType* ) 16 )->fieldName ), ()( fieldName ) }
_FIELD_AS(type, fieldName, exportName, numElements, doc)    { #exportName, doc, numElements, ( *( ( type* ) &( ( ThisType* ) 16 )->fieldName ) ), ()( fieldName ) }
_IMPLEMENT_BITFIELD(type, exportName, scope, doc)    namespace { namespace _ ## exportName {                                                                                             \
      extern < type > gsTypeInfo;                                                                                  \
   } }                                                                                                                                 \
   ( type, exportName );                                                                                                \
   namespace { namespace _ ## exportName {                                                                                             \
      typedef type BitfieldType;                                                                                                       \
      static  char*  _sBitfieldName = #exportName;                                                                           \
      static  char*  _sDoc = doc;                                                                                            \
      static & _sScope = < scope >()();                                                                         \
      static  _sEnums[] = {
_IMPLEMENT_ENUM(type, exportName, scope, doc)    namespace { namespace _ ## exportName {                                                                                             \
      typedef type EnumType;                                                                                                           \
      extern < EnumType > gsTypeInfo;                                                                              \
   } }                                                                                                                                 \
   ( type, exportName );                                                                                                \
   namespace { namespace _ ## exportName {                                                                                             \
      static  char*  _sEnumName = #exportName;                                                                               \
      static  char*  _sDoc = doc;                                                                                            \
      static & _sScope = < scope >()();                                                                         \
      static  _sEnums[] = {
_IMPLEMENT_PRIMITIVE(type, exportName, scope, doc)    namespace { namespace _ ## exportName {                                                                                             \
      static < type > gsTypeInfo( #exportName, &< scope >()(), , doc );               \
   } }                                                                                                                                 \
   ( type, exportName )
_IMPLEMENT_STRUCT(type, exportName, scope, doc)    namespace { namespace _ ## exportName {                                                                                             \
      extern < type > gsTypeInfo;                                                                                  \
   } }                                                                                                                                 \
   ( type, exportName );                                                                                                \
   namespace { namespace _ ## exportName {                                                                                             \
      typedef type StructType;                                                                                                         \
      typedef StructType ThisType;                                                                                                     \
      static  char*  _sStructName = #exportName;                                                                             \
      static  char*  _sDoc = doc;                                                                                            \
      static & _sScope = < scope >()();                                                                         \
      static  _sFields[] = {
_IMPLEMENT_TYPE(type, exportName)    template<>                                      \
    * < type >()            \
   {                                               \
      return &_ ## exportName::gsTypeInfo;         \
   }
ConsoleDocClass(className, doc)    template<>  char* < className, className::_ClassBase >::smDocString = doc;
DECLARE_BITFIELD(type)    ( type )
DECLARE_BITFIELD_R(type)    ( type )
DECLARE_ENUM(type)    ( type )
DECLARE_ENUM_R(type)    ( type )
DECLARE_PRIMITIVE(type)    ( type )
DECLARE_PRIMITIVE_R(type)    ( type )
DECLARE_SCOPE(name)    struct name {                                                                             \
      static  __engineExportScopeInst;                                      \
      static & __engineExportScope() { return __engineExportScopeInst; }    \
   };
DECLARE_STRUCT(type)    ( type )
DECLARE_STRUCT_R(type)    ( type )
END_IMPLEMENT_BITFIELD()    
END_IMPLEMENT_ENUM()    
END_IMPLEMENT_STRUCT()    
FIELD(fieldName, exportName, numElements, doc)    (fieldName, exportName, numElements, doc),
FIELD_AS(type, fieldName, exportName, numElements, doc)    (type, fieldName, exportName, numElements, doc),
FIELDOFFSET(fieldName)    ( ( (  char* ) &( ( ( ThisType* ) 16 )->fieldName ) ) - 16 )
IMPLEMENT_BITFIELD(type, exportName, scope, doc)    ( type, exportName, scope, doc )
IMPLEMENT_ENUM(type, exportName, scope, doc)    ( type, exportName, scope, doc )
IMPLEMENT_PRIMITIVE(type, exportName, scope, doc)    ( type, exportName, scope, doc )
IMPLEMENT_SCOPE(name, exportName, scope, doc)     name::__engineExportScopeInst( #exportName, &< scope >()(), doc );
IMPLEMENT_STRUCT(type, exportName, scope, doc)    ( type, exportName, scope, doc )
  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 _ENGINETYPES_H_
 25#define _ENGINETYPES_H_
 26
 27#ifndef _TYPETRAITS_H_
 28   #include "platform/typetraits.h"
 29#endif
 30#ifndef _BITSET_H_
 31   #include "core/bitSet.h"
 32#endif
 33
 34
 35//TODO: documentation
 36
 37
 38/// @file
 39/// This file forms the basis for Torque's engine API type system.
 40///
 41/// The type system is geared towards use in a control layer in a .NET-like environment
 42/// and is intended to allow for all-native data exchange between the engine and its
 43/// control layer.
 44
 45
 46/// @defgroup engineAPI_types Engine Type System
 47///
 48///
 49/// Akin to C++ RTTI (though more thorough in depth), the engine type system provides a reflection layer
 50/// that can be used to query type properties at run-time.
 51///
 52/// @section engineAPI_kinds Type Kinds
 53///
 54/// Engine types are segregated into kinds.  A kind is to a type what a type is to a value, i.e. a value
 55/// is an instance of a type whereas a type is an instance of a kind.
 56///
 57/// Just as values share behavior through types, types share behavior through kinds.
 58///
 59/// The following kinds are defined:
 60///
 61/// <dl>
 62///    <dt>Primitive</dt>
 63///    <dd>An atomic piece of data like an int, float, etc.</dt>
 64///    <dt>Enums</dt>
 65///    <dd></dd>
 66///    <dt>Bitfields</dt>
 67///    <dd>A bitwise combination of enumeration values.</dd>
 68///    <dt>Functions</dt>
 69///    <dd></dd>
 70///    <dt>Structs</dt>
 71///    <dd>A structured piece of data like a Point3F or MatrixF.  Unlike class instances, structs are directly stored
 72///      in the memory of their owner.  Also, structs don't allow inheritance.</dd>
 73///    <dt>Classes</dt>
 74///    <dd></dd>
 75/// </dl>
 76///
 77/// @section engineAPI_subtyping Subtyping of Engine Types
 78///
 79///
 80/// At the moment, the type system is not unified such that all types are implicitly subtypes to a single root type.
 81/// This may change in the future.
 82///
 83/// @section engineAPI_defaultConstruction Default Construction
 84///
 85/// All engine types must be default-constructible, i.e. a parameter-less construction of a value of any type
 86/// in the engine must be successful.  Class and struct types are affected the most by this.  Classes and structs
 87/// @b may provide non-default constructors but they @b must provide a default construction routine that always
 88/// succeeds.
 89///
 90/// @section engineAPI_networking Engine Type Networking
 91///
 92/// @{
 93
 94
 95class EngineExportScope;
 96class EngineTypeInfo;
 97class EnginePropertyTable;
 98
 99template< typename T, typename Base > class EngineClassTypeInfo;
100template< typename T > class EngineFunctionTypeInfo;
101
102
103//--------------------------------------------------------------------------
104//    Type Traits.
105//--------------------------------------------------------------------------
106
107/// @name Engine Type Traits
108///
109/// Type traits allow to access the static properties of a type at compile-time.  This
110/// is primarily useful for templating in order to make decisions based on static
111/// typing.
112///
113/// @{
114
115
116template< typename T >
117struct _EngineTypeTraits
118{
119   // Default type traits corresponding to the semantics of class types.
120   
121   typedef T Type;
122   typedef T* ValueType;
123   typedef typename Type::SuperType SuperType;
124   
125   typedef T* ArgumentValueType;
126   typedef T* ReturnValueType;
127   typedef T* DefaultArgumentValueStoreType;
128   
129   typedef ReturnValueType ReturnValue;
130   static ValueType ArgumentToValue( ArgumentValueType val ) { return val; }
131
132   static const EngineTypeInfo* const TYPEINFO;
133};
134template< typename T > const EngineTypeInfo* const _EngineTypeTraits< T >::TYPEINFO = &T::_smTypeInfo;
135
136template<>
137struct _EngineTypeTraits< void >
138{
139   typedef void Type;
140   typedef void ValueType;
141   typedef void ReturnValueType;   
142   typedef ReturnValueType ReturnValue;
143   
144   static const EngineTypeInfo* const TYPEINFO;
145};
146
147
148template< typename T >
149struct EngineTypeTraits : public _EngineTypeTraits< T > {};
150
151// Strip off native type modifiers.  Doing it like this allows to query type traits on types
152// that are not true engine types or value types thereof (like e.g. a reference to a primitive type)
153// but it simplifies matters for us.
154template< typename T >
155struct EngineTypeTraits< T* > : public EngineTypeTraits< T> {};
156template< typename T >
157struct EngineTypeTraits< const T* > : public EngineTypeTraits< T> {};
158template< typename T >
159struct EngineTypeTraits< T& > : public EngineTypeTraits< T> {};
160template< typename T >
161struct EngineTypeTraits< const T& > : public EngineTypeTraits< T> {};
162template< typename T >
163struct EngineTypeTraits< const T > : public EngineTypeTraits< T > {};
164
165
166
167/// Return the type info for the given engine type.
168template< typename T >
169inline const EngineTypeInfo* TYPE() { return EngineTypeTraits< T >::TYPEINFO; }
170
171
172/// Return the type info for the @b static type of the given variable.
173template< typename T >
174inline const EngineTypeInfo* TYPE( const T& )
175{
176   return TYPE< T >();
177}
178
179
180// Base type trait definitions for different type kinds.
181
182template< typename T >
183struct _EnginePrimitiveTypeTraits
184{
185   typedef T Type;
186   typedef T ValueType;
187   typedef void SuperType;
188   
189   typedef ValueType ArgumentValueType;
190   typedef ValueType ReturnValueType;
191   typedef ValueType DefaultArgumentValueStoreType;
192   
193   typedef ReturnValueType ReturnValue;   
194   static ValueType ArgumentToValue( ArgumentValueType val ) { return val; }
195
196   static const EngineTypeInfo* const TYPEINFO;
197};
198template< typename T > const EngineTypeInfo* const _EnginePrimitiveTypeTraits< T >::TYPEINFO = TYPE< T >();
199
200template< typename T >
201struct _EngineEnumTypeTraits
202{
203   typedef T Type;
204   typedef T ValueType;
205   typedef void SuperType;
206
207   typedef ValueType ArgumentValueType;
208   typedef ValueType ReturnValueType;
209   typedef ValueType DefaultArgumentValueStoreType;
210   
211   typedef ReturnValueType ReturnValue;
212   static ValueType ArgumentToValue( ArgumentValueType val ) { return val; }
213
214   static const EngineTypeInfo* const TYPEINFO;
215};
216template< typename T > const EngineTypeInfo* const _EngineEnumTypeTraits< T >::TYPEINFO = TYPE< T >();
217
218template< typename T >
219struct _EngineBitfieldTypeTraits
220{
221   typedef T Type;
222   typedef T ValueType;
223   typedef void SuperType;
224
225   typedef ValueType ArgumentValueType;
226   typedef ValueType ReturnValueType;
227   typedef ValueType DefaultArgumentValueStoreType;
228   
229   typedef ReturnValueType ReturnValue;
230   static ValueType ArgumentToValue( ArgumentValueType val ) { return val; }
231
232   static const EngineTypeInfo* const TYPEINFO;
233};
234template< typename T > const EngineTypeInfo* const _EngineBitfieldTypeTraits< T >::TYPEINFO = TYPE< T >();
235
236template< typename T >
237struct _EngineStructTypeTraits
238{
239   typedef T Type;
240   typedef const T ValueType;
241   typedef void SuperType;
242   
243   // Structs get passed in as pointers and passed out as full copies.
244   typedef T* ArgumentValueType;
245   typedef T ReturnValueType;
246   typedef T DefaultArgumentValueStoreType;
247
248   typedef ReturnValueType ReturnValue;
249   static ValueType ArgumentToValue( ArgumentValueType val ) { return *val; }
250
251   static const EngineTypeInfo* const TYPEINFO;
252};
253template< typename T > const EngineTypeInfo* const _EngineStructTypeTraits< T >::TYPEINFO = TYPE< T >();
254
255
256template< typename T > struct _EngineArgumentTypeTable {};
257
258template< typename T >
259struct _EngineFunctionTypeTraits
260{
261      typedef T Type;
262      typedef T* ValueType;
263
264      typedef T* ArgumentValueType;
265      typedef T* ReturnValueType;
266      typedef T* DefaultArgumentValueStoreType;
267      
268      static const bool IS_VARIADIC = _EngineArgumentTypeTable< T >::VARIADIC;
269      static const U32 NUM_ARGUMENTS  = _EngineArgumentTypeTable< T >::NUM_ARGUMENTS;
270
271      static const EngineTypeInfo* const TYPEINFO;
272   
273   private:
274      static const EngineFunctionTypeInfo< T> smTYPEINFO;
275};
276template< typename T > const EngineTypeInfo* const _EngineFunctionTypeTraits< T >::TYPEINFO = &smTYPEINFO;
277
278
279// Temporary helper.  Used to strip the return or argument types supplied in a function type
280// down to the value type and thus account for the discrepancy between (argument/return) value
281// types and engine types.  Don't go for the base type as VC will not allow us to use abstract
282// types even in return or argument positions of abstract function types (GCC allows it; not
283// sure what the stance of the ANSI C++ standard towards this is).  Also, while it may be tempting
284// to go for the real return and argument value types here, this would lead to errors as these
285// are not guaranteed to be any meaningful value or base types to the engine type system.
286#define T( x ) typename EngineTypeTraits< x >::ValueType
287
288template<typename R, typename ...ArgTs>
289struct _EngineTypeTraits< R(ArgTs ...) > : public _EngineFunctionTypeTraits<T(R)(T(ArgTs)...)> {};
290template<typename R, typename ...ArgTs>
291struct _EngineTypeTraits< R(ArgTs ..., ...) > : public _EngineFunctionTypeTraits<T(R)(T(ArgTs)..., ...)> {};
292
293#undef T
294
295/// @}
296
297//--------------------------------------------------------------------------
298//    Helpers.
299//--------------------------------------------------------------------------
300
301namespace _Private {
302   template< typename T >
303   struct _InstantiableConcreteClass
304   {
305      static bool _construct( void* ptr )
306      {
307         T* p = reinterpret_cast< T* >( ptr );
308         constructInPlace( p );
309         return true;
310      }
311   
312      static void _destruct( void* ptr )
313      {
314         T* p = reinterpret_cast< T* >( ptr );
315         destructInPlace( p );
316      }
317   };
318   template< typename T >
319   struct _NonInstantiableConcreteClass
320   {
321      static bool _construct( void* ptr )
322      {
323         AssertFatal( false, "EngineClassTypeInfo - constructInstance called on non-instantiable class" );
324         return false;
325      }
326   
327      static void _destruct( void* ptr )
328      {
329         AssertFatal( false, "EngineClassTypeInfo - destructInstance called on non-instantiable class" );
330      }
331   };
332   template< typename T >
333   struct _ConcreteClassBase : public IfTrueType< typename T::__IsInstantiableType, _InstantiableConcreteClass< T >, _NonInstantiableConcreteClass< T > >
334   {
335      typedef ::FalseType IsAbstractType;
336   };
337   template< typename T >
338   struct _AbstractClassBase
339   {
340      typedef ::TrueType IsAbstractType;
341      static bool _construct( void* ptr )
342      {
343         AssertFatal( false, "EngineClassTypeInfo - constructInstance called on abstract class" );
344         return false;
345      }
346   
347      static void _destruct( void* ptr )
348      {
349         AssertFatal( false, "EngineClassTypeInfo - destructInstance called on abstract class" );
350      }
351   };
352}
353
354//--------------------------------------------------------------------------
355//    Macros.
356//--------------------------------------------------------------------------
357
358///
359///
360#define DECLARE_SCOPE( name )                                                                \
361   struct name {                                                                             \
362      static EngineExportScope __engineExportScopeInst;                                      \
363      static EngineExportScope& __engineExportScope() { return __engineExportScopeInst; }    \
364   };
365   
366///
367#define IMPLEMENT_SCOPE( name, exportName, scope, doc )                                      \
368   EngineExportScope name::__engineExportScopeInst( #exportName, &_SCOPE< scope >()(), doc );
369
370
371#define _DECLARE_TYPE( type )                                                                \
372   template<> const EngineTypeInfo* TYPE< type >();                                          \
373   template<> struct _SCOPE< type > {                                                        \
374      EngineExportScope& operator()() const {                                                \
375         return *static_cast< EngineExportScope* >(                                          \
376            const_cast< EngineTypeInfo* >( ( TYPE< type >() ) )                              \
377         );                                                                                  \
378      }                                                                                      \
379   };
380
381#define _DECLARE_TYPE_R( type )                                                              \
382   template<> const EngineTypeInfo* TYPE< type >();                                          \
383   template<> struct _SCOPE< type > {                                                        \
384      EngineExportScope& operator()() const {                                                \
385         return *reinterpret_cast< EngineExportScope* >(                                     \
386            const_cast< EngineTypeInfo* >( ( TYPE< type >() ) )                              \
387         );                                                                                  \
388      }                                                                                      \
389   };
390
391// Unlike the other types, primitives directly specialize on EngineTypeTraits instead
392// of _EngineTypeTraits so as to prevent any stripping from taking place.  Otherwise,
393// pointers could not be primitive types.
394#define _DECLARE_PRIMITIVE( type )                                                           \
395   _DECLARE_TYPE( type )                                                                     \
396   template<>                                                                                \
397   struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
398
399#define _DECLARE_PRIMITIVE_R( type )                                                         \
400   _DECLARE_TYPE_R( type )                                                                   \
401   template<>                                                                                \
402   struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {};
403   
404#define _DECLARE_ENUM( type )                                                                \
405   _DECLARE_TYPE( type )                                                                     \
406   template<>                                                                                \
407   struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
408
409#define _DECLARE_ENUM_R( type )                                                              \
410   _DECLARE_TYPE_R( type )                                                                   \
411   template<>                                                                                \
412   struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {};
413
414#define _DECLARE_BITFIELD( type )                                                            \
415   _DECLARE_TYPE( type )                                                                     \
416   template<>                                                                                \
417   struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
418
419#define _DECLARE_BITFIELD_R( type )                                                            \
420   _DECLARE_TYPE_R( type )                                                                     \
421   template<>                                                                                \
422   struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {};
423
424
425#define _DECLARE_STRUCT( type )                                                              \
426   _DECLARE_TYPE( type )                                                                     \
427   template<>                                                                                \
428   struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
429
430#define _DECLARE_STRUCT_R( type )                                                            \
431   _DECLARE_TYPE_R( type )                                                                   \
432   template<>                                                                                \
433   struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {};
434
435#define _IMPLEMENT_TYPE( type, exportName )        \
436   template<>                                      \
437   const EngineTypeInfo* TYPE< type >()            \
438   {                                               \
439      return &_ ## exportName::gsTypeInfo;         \
440   }
441
442
443#define _IMPLEMENT_PRIMITIVE( type, exportName, scope, doc )                                                                           \
444   namespace { namespace _ ## exportName {                                                                                             \
445      static EngineSimpleTypeInfo< type > gsTypeInfo( #exportName, &_SCOPE< scope >()(), EngineTypeKindPrimitive, doc );               \
446   } }                                                                                                                                 \
447   _IMPLEMENT_TYPE( type, exportName )
448   
449#define _IMPLEMENT_ENUM( type, exportName, scope, doc )                                                                                \
450   namespace { namespace _ ## exportName {                                                                                             \
451      typedef type EnumType;                                                                                                           \
452      extern EngineSimpleTypeInfo< EnumType > gsTypeInfo;                                                                              \
453   } }                                                                                                                                 \
454   _IMPLEMENT_TYPE( type, exportName );                                                                                                \
455   namespace { namespace _ ## exportName {                                                                                             \
456      static const char* const _sEnumName = #exportName;                                                                               \
457      static const char* const _sDoc = doc;                                                                                            \
458      static EngineExportScope& _sScope = _SCOPE< scope >()();                                                                         \
459      static EngineEnumTable::Value _sEnums[] = {
460   
461#define _END_IMPLEMENT_ENUM                                                                                                            \
462      };                                                                                                                               \
463      static EngineEnumTable _sEnumTable( sizeof( _sEnums ) / sizeof( _sEnums[ 0 ] ), _sEnums );                                       \
464      EngineSimpleTypeInfo< EnumType > gsTypeInfo( _sEnumName, &_sScope, EngineTypeKindEnum, _sDoc, &_sEnumTable );                    \
465   } }
466
467#define _IMPLEMENT_BITFIELD( type, exportName, scope, doc )                                                                            \
468   namespace { namespace _ ## exportName {                                                                                             \
469      extern EngineSimpleTypeInfo< type > gsTypeInfo;                                                                                  \
470   } }                                                                                                                                 \
471   _IMPLEMENT_TYPE( type, exportName );                                                                                                \
472   namespace { namespace _ ## exportName {                                                                                             \
473      typedef type BitfieldType;                                                                                                       \
474      static const char* const _sBitfieldName = #exportName;                                                                           \
475      static const char* const _sDoc = doc;                                                                                            \
476      static EngineExportScope& _sScope = _SCOPE< scope >()();                                                                         \
477      static EngineEnumTable::Value _sEnums[] = {
478   
479#define _END_IMPLEMENT_BITFIELD                                                                                                        \
480      };                                                                                                                               \
481      static EngineEnumTable _sEnumTable( sizeof( _sEnums ) / sizeof( _sEnums[ 0 ] ), _sEnums );                                       \
482      EngineSimpleTypeInfo< BitfieldType > gsTypeInfo( _sBitfieldName, &_sScope, EngineTypeKindBitfield, _sDoc, &_sEnumTable );        \
483   } }
484   
485#define _IMPLEMENT_STRUCT( type, exportName, scope, doc )                                                                              \
486   namespace { namespace _ ## exportName {                                                                                             \
487      extern EngineStructTypeInfo< type > gsTypeInfo;                                                                                  \
488   } }                                                                                                                                 \
489   _IMPLEMENT_TYPE( type, exportName );                                                                                                \
490   namespace { namespace _ ## exportName {                                                                                             \
491      typedef type StructType;                                                                                                         \
492      typedef StructType ThisType;                                                                                                     \
493      static const char* const _sStructName = #exportName;                                                                             \
494      static const char* const _sDoc = doc;                                                                                            \
495      static EngineExportScope& _sScope = _SCOPE< scope >()();                                                                         \
496      static EngineFieldTable::Field _sFields[] = {
497
498#define _END_IMPLEMENT_STRUCT                                                                                                          \
499         { NULL }                                                                                                                      \
500      };                                                                                                                               \
501      static EngineFieldTable _sFieldTable( sizeof( _sFields ) / sizeof( _sFields[ 0 ] ) - 1, _sFields );                              \
502      EngineStructTypeInfo< StructType > gsTypeInfo( _sStructName, &_sScope, _sDoc, &_sFieldTable );                                   \
503   } }
504
505
506///
507#define DECLARE_PRIMITIVE( type ) \
508   _DECLARE_PRIMITIVE( type )
509
510///
511#define DECLARE_PRIMITIVE_R( type ) \
512   _DECLARE_PRIMITIVE_R( type )
513
514///
515#define IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \
516   _IMPLEMENT_PRIMITIVE( type, exportName, scope, doc )
517
518///
519#define DECLARE_ENUM( type ) \
520   _DECLARE_ENUM( type )
521
522///
523#define DECLARE_ENUM_R( type ) \
524   _DECLARE_ENUM_R( type )
525   
526///
527#define DECLARE_BITFIELD( type ) \
528   _DECLARE_BITFIELD( type )
529
530///
531#define DECLARE_BITFIELD_R( type ) \
532   _DECLARE_BITFIELD_R( type )
533
534///
535#define IMPLEMENT_ENUM( type, exportName, scope, doc ) \
536   _IMPLEMENT_ENUM( type, exportName, scope, doc )
537   
538///
539#define IMPLEMENT_BITFIELD( type, exportName, scope, doc ) \
540   _IMPLEMENT_BITFIELD( type, exportName, scope, doc )
541
542///
543#define END_IMPLEMENT_ENUM \
544   _END_IMPLEMENT_ENUM
545   
546///
547#define END_IMPLEMENT_BITFIELD \
548   _END_IMPLEMENT_BITFIELD
549
550///
551#define DECLARE_STRUCT( type ) \
552   _DECLARE_STRUCT( type )
553
554///
555#define DECLARE_STRUCT_R( type ) \
556   _DECLARE_STRUCT_R( type )
557
558///
559#define IMPLEMENT_STRUCT( type, exportName, scope, doc ) \
560   _IMPLEMENT_STRUCT( type, exportName, scope, doc )
561
562///
563#define END_IMPLEMENT_STRUCT \
564   _END_IMPLEMENT_STRUCT
565
566
567///
568#define _FIELD( fieldName, exportName, numElements, doc ) \
569   { #exportName, doc, numElements, TYPE( ( ( ThisType* ) 16 )->fieldName ), (U32)FIELDOFFSET( fieldName ) } // Artificial offset to avoid compiler warnings.
570
571#define FIELD( fieldName, exportName, numElements, doc ) \
572   _FIELD(fieldName, exportName, numElements, doc),
573
574///
575#define _FIELD_AS( type, fieldName, exportName, numElements, doc ) \
576   { #exportName, doc, numElements, TYPE( *( ( type* ) &( ( ThisType* ) 16 )->fieldName ) ), (U32)FIELDOFFSET( fieldName ) } // Artificial offset to avoid compiler warnings.
577
578#define FIELD_AS( type, fieldName, exportName, numElements, doc ) \
579   _FIELD_AS(type, fieldName, exportName, numElements, doc),
580   
581///
582#define FIELDOFFSET( fieldName ) \
583   uintptr_t( ( ( const char* ) &( ( ( ThisType* ) 16 )->fieldName ) ) - 16 ) // Artificial offset to avoid compiler warnings.
584   
585///
586#define ConsoleDocClass( className, doc ) \
587   template<> const char* EngineClassTypeInfo< className, className::_ClassBase >::smDocString = doc;
588   
589
590/// @}
591
592
593struct _GLOBALSCOPE
594{
595   static EngineExportScope& __engineExportScope();
596};
597
598// Helper to retrieve a scope instance through a C++ type.  The setup here is a little
599// contrived to allow the scope parameters to the various macros to be empty.  What makes
600// this difficult is that T need not necessarily be a structured type.
601template< typename T = _GLOBALSCOPE >
602struct _SCOPE
603{
604   EngineExportScope& operator()() const { return T::__engineExportScope(); }
605};
606
607#endif // !_ENGINETYPES_H_
608