engineTypes.h
Engine/source/console/engineTypes.h
This file forms the basis for Torque's engine API type system.
Classes:
Namespaces:
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.
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 ); \ } }
_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; \ }
CLASSDOC(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 )
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 ) },
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 )
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 ); \ } }
_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; \ }
CLASSDOC(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) { #exportName, doc, numElements, ( ( ( ThisType* ) 16 )->fieldName ), ()( fieldName ) },
FIELD_AS(type, fieldName, exportName, numElements, doc) { #exportName, doc, numElements, ( *( ( type* ) &( ( ThisType* ) 16 )->fieldName ) ), ()( fieldName ) },
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 > 289struct _EngineTypeTraits< R() > : public _EngineFunctionTypeTraits< T( R )() > {}; 290template< typename R > 291struct _EngineTypeTraits< R( ... ) > : public _EngineFunctionTypeTraits< T( R )( ... ) > {}; 292template< typename R, typename A > 293struct _EngineTypeTraits< R( A ) > : public _EngineFunctionTypeTraits< T( R )( T( A ) ) > {}; 294template< typename R, typename A > 295struct _EngineTypeTraits< R( A, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), ... ) > {}; 296template< typename R, typename A, typename B > 297struct _EngineTypeTraits< R( A, B ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ) ) > {}; 298template< typename R, typename A, typename B > 299struct _EngineTypeTraits< R( A, B, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), ... ) > {}; 300template< typename R, typename A, typename B, typename C > 301struct _EngineTypeTraits< R( A, B, C ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ) ) > {}; 302template< typename R, typename A, typename B, typename C > 303struct _EngineTypeTraits< R( A, B, C, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), ... ) > {}; 304template< typename R, typename A, typename B, typename C, typename D > 305struct _EngineTypeTraits< R( A, B, C, D ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ) ) > {}; 306template< typename R, typename A, typename B, typename C, typename D > 307struct _EngineTypeTraits< R( A, B, C, D, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), ... ) > {}; 308template< typename R, typename A, typename B, typename C, typename D, typename E > 309struct _EngineTypeTraits< R( A, B, C, D, E ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ) ) > {}; 310template< typename R, typename A, typename B, typename C, typename D, typename E > 311struct _EngineTypeTraits< R( A, B, C, D, E, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), ... ) > {}; 312template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > 313struct _EngineTypeTraits< R( A, B, C, D, E, F ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ) ) > {}; 314template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > 315struct _EngineTypeTraits< R( A, B, C, D, E, F, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), ... ) > {}; 316template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > 317struct _EngineTypeTraits< R( A, B, C, D, E, F, G ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ) ) > {}; 318template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > 319struct _EngineTypeTraits< R( A, B, C, D, E, F, G, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), ... ) > {}; 320template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > 321struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ) ) > {}; 322template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > 323struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), ... ) > {}; 324template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > 325struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ) ) > {}; 326template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > 327struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), ... ) > {}; 328template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > 329struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ) ) > {}; 330template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > 331struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), ... ) > {}; 332template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > 333struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, K ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), T( K ) ) > {}; 334template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > 335struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, K, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), T( K ), ... ) > {}; 336template< 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 > 337struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, K, L ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), T( K ), T( L ) ) > {}; 338template< 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 > 339struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, K, L, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), T( K ), T( L ), ... ) > {}; 340 341#undef T 342 343/// @} 344 345//-------------------------------------------------------------------------- 346// Helpers. 347//-------------------------------------------------------------------------- 348 349namespace _Private { 350 template< typename T > 351 struct _InstantiableConcreteClass 352 { 353 static bool _construct( void* ptr ) 354 { 355 T* p = reinterpret_cast< T* >( ptr ); 356 constructInPlace( p ); 357 return true; 358 } 359 360 static void _destruct( void* ptr ) 361 { 362 T* p = reinterpret_cast< T* >( ptr ); 363 destructInPlace( p ); 364 } 365 }; 366 template< typename T > 367 struct _NonInstantiableConcreteClass 368 { 369 static bool _construct( void* ptr ) 370 { 371 AssertFatal( false, "EngineClassTypeInfo - constructInstance called on non-instantiable class" ); 372 return false; 373 } 374 375 static void _destruct( void* ptr ) 376 { 377 AssertFatal( false, "EngineClassTypeInfo - destructInstance called on non-instantiable class" ); 378 } 379 }; 380 template< typename T > 381 struct _ConcreteClassBase : public IfTrueType< typename T::__IsInstantiableType, _InstantiableConcreteClass< T >, _NonInstantiableConcreteClass< T > > 382 { 383 typedef ::FalseType IsAbstractType; 384 }; 385 template< typename T > 386 struct _AbstractClassBase 387 { 388 typedef ::TrueType IsAbstractType; 389 static bool _construct( void* ptr ) 390 { 391 AssertFatal( false, "EngineClassTypeInfo - constructInstance called on abstract class" ); 392 return false; 393 } 394 395 static void _destruct( void* ptr ) 396 { 397 AssertFatal( false, "EngineClassTypeInfo - destructInstance called on abstract class" ); 398 } 399 }; 400} 401 402//-------------------------------------------------------------------------- 403// Macros. 404//-------------------------------------------------------------------------- 405 406/// 407/// 408#define DECLARE_SCOPE( name ) \ 409 struct name { \ 410 static EngineExportScope __engineExportScopeInst; \ 411 static EngineExportScope& __engineExportScope() { return __engineExportScopeInst; } \ 412 }; 413 414/// 415#define IMPLEMENT_SCOPE( name, exportName, scope, doc ) \ 416 EngineExportScope name::__engineExportScopeInst( #exportName, &_SCOPE< scope >()(), doc ); 417 418 419#define _DECLARE_TYPE( type ) \ 420 template<> const EngineTypeInfo* TYPE< type >(); \ 421 template<> struct _SCOPE< type > { \ 422 EngineExportScope& operator()() const { \ 423 return *static_cast< EngineExportScope* >( \ 424 const_cast< EngineTypeInfo* >( ( TYPE< type >() ) ) \ 425 ); \ 426 } \ 427 }; 428 429#define _DECLARE_TYPE_R( type ) \ 430 template<> const EngineTypeInfo* TYPE< type >(); \ 431 template<> struct _SCOPE< type > { \ 432 EngineExportScope& operator()() const { \ 433 return *reinterpret_cast< EngineExportScope* >( \ 434 const_cast< EngineTypeInfo* >( ( TYPE< type >() ) ) \ 435 ); \ 436 } \ 437 }; 438 439// Unlike the other types, primitives directly specialize on EngineTypeTraits instead 440// of _EngineTypeTraits so as to prevent any stripping from taking place. Otherwise, 441// pointers could not be primitive types. 442#define _DECLARE_PRIMITIVE( type ) \ 443 _DECLARE_TYPE( type ) \ 444 template<> \ 445 struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {}; 446 447#define _DECLARE_PRIMITIVE_R( type ) \ 448 _DECLARE_TYPE_R( type ) \ 449 template<> \ 450 struct EngineTypeTraits< type > : public _EnginePrimitiveTypeTraits< type > {}; 451 452#define _DECLARE_ENUM( type ) \ 453 _DECLARE_TYPE( type ) \ 454 template<> \ 455 struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {}; 456 457#define _DECLARE_ENUM_R( type ) \ 458 _DECLARE_TYPE_R( type ) \ 459 template<> \ 460 struct _EngineTypeTraits< type > : public _EngineEnumTypeTraits< type > {}; 461 462#define _DECLARE_BITFIELD( type ) \ 463 _DECLARE_TYPE( type ) \ 464 template<> \ 465 struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {}; 466 467#define _DECLARE_BITFIELD_R( type ) \ 468 _DECLARE_TYPE_R( type ) \ 469 template<> \ 470 struct _EngineTypeTraits< type > : public _EngineBitfieldTypeTraits< type > {}; 471 472 473#define _DECLARE_STRUCT( type ) \ 474 _DECLARE_TYPE( type ) \ 475 template<> \ 476 struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {}; 477 478#define _DECLARE_STRUCT_R( type ) \ 479 _DECLARE_TYPE_R( type ) \ 480 template<> \ 481 struct _EngineTypeTraits< type > : public _EngineStructTypeTraits< type > {}; 482 483#define _IMPLEMENT_TYPE( type, exportName ) \ 484 template<> \ 485 const EngineTypeInfo* TYPE< type >() \ 486 { \ 487 return &_ ## exportName::gsTypeInfo; \ 488 } 489 490 491#define _IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \ 492 namespace { namespace _ ## exportName { \ 493 static EngineSimpleTypeInfo< type > gsTypeInfo( #exportName, &_SCOPE< scope >()(), EngineTypeKindPrimitive, doc ); \ 494 } } \ 495 _IMPLEMENT_TYPE( type, exportName ) 496 497#define _IMPLEMENT_ENUM( type, exportName, scope, doc ) \ 498 namespace { namespace _ ## exportName { \ 499 typedef type EnumType; \ 500 extern EngineSimpleTypeInfo< EnumType > gsTypeInfo; \ 501 } } \ 502 _IMPLEMENT_TYPE( type, exportName ); \ 503 namespace { namespace _ ## exportName { \ 504 static const char* const _sEnumName = #exportName; \ 505 static const char* const _sDoc = doc; \ 506 static EngineExportScope& _sScope = _SCOPE< scope >()(); \ 507 static EngineEnumTable::Value _sEnums[] = { 508 509#define _END_IMPLEMENT_ENUM \ 510 }; \ 511 static EngineEnumTable _sEnumTable( sizeof( _sEnums ) / sizeof( _sEnums[ 0 ] ), _sEnums ); \ 512 EngineSimpleTypeInfo< EnumType > gsTypeInfo( _sEnumName, &_sScope, EngineTypeKindEnum, _sDoc, &_sEnumTable ); \ 513 } } 514 515#define _IMPLEMENT_BITFIELD( type, exportName, scope, doc ) \ 516 namespace { namespace _ ## exportName { \ 517 extern EngineSimpleTypeInfo< type > gsTypeInfo; \ 518 } } \ 519 _IMPLEMENT_TYPE( type, exportName ); \ 520 namespace { namespace _ ## exportName { \ 521 typedef type BitfieldType; \ 522 static const char* const _sBitfieldName = #exportName; \ 523 static const char* const _sDoc = doc; \ 524 static EngineExportScope& _sScope = _SCOPE< scope >()(); \ 525 static EngineEnumTable::Value _sEnums[] = { 526 527#define _END_IMPLEMENT_BITFIELD \ 528 }; \ 529 static EngineEnumTable _sEnumTable( sizeof( _sEnums ) / sizeof( _sEnums[ 0 ] ), _sEnums ); \ 530 EngineSimpleTypeInfo< BitfieldType > gsTypeInfo( _sBitfieldName, &_sScope, EngineTypeKindBitfield, _sDoc, &_sEnumTable ); \ 531 } } 532 533#define _IMPLEMENT_STRUCT( type, exportName, scope, doc ) \ 534 namespace { namespace _ ## exportName { \ 535 extern EngineStructTypeInfo< type > gsTypeInfo; \ 536 } } \ 537 _IMPLEMENT_TYPE( type, exportName ); \ 538 namespace { namespace _ ## exportName { \ 539 typedef type StructType; \ 540 typedef StructType ThisType; \ 541 static const char* const _sStructName = #exportName; \ 542 static const char* const _sDoc = doc; \ 543 static EngineExportScope& _sScope = _SCOPE< scope >()(); \ 544 static EngineFieldTable::Field _sFields[] = { 545 546#define _END_IMPLEMENT_STRUCT \ 547 { NULL } \ 548 }; \ 549 static EngineFieldTable _sFieldTable( sizeof( _sFields ) / sizeof( _sFields[ 0 ] ) - 1, _sFields ); \ 550 EngineStructTypeInfo< StructType > gsTypeInfo( _sStructName, &_sScope, _sDoc, &_sFieldTable ); \ 551 } } 552 553 554/// 555#define DECLARE_PRIMITIVE( type ) \ 556 _DECLARE_PRIMITIVE( type ) 557 558/// 559#define DECLARE_PRIMITIVE_R( type ) \ 560 _DECLARE_PRIMITIVE_R( type ) 561 562/// 563#define IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) \ 564 _IMPLEMENT_PRIMITIVE( type, exportName, scope, doc ) 565 566/// 567#define DECLARE_ENUM( type ) \ 568 _DECLARE_ENUM( type ) 569 570/// 571#define DECLARE_ENUM_R( type ) \ 572 _DECLARE_ENUM_R( type ) 573 574/// 575#define DECLARE_BITFIELD( type ) \ 576 _DECLARE_BITFIELD( type ) 577 578/// 579#define DECLARE_BITFIELD_R( type ) \ 580 _DECLARE_BITFIELD_R( type ) 581 582/// 583#define IMPLEMENT_ENUM( type, exportName, scope, doc ) \ 584 _IMPLEMENT_ENUM( type, exportName, scope, doc ) 585 586/// 587#define IMPLEMENT_BITFIELD( type, exportName, scope, doc ) \ 588 _IMPLEMENT_BITFIELD( type, exportName, scope, doc ) 589 590/// 591#define END_IMPLEMENT_ENUM \ 592 _END_IMPLEMENT_ENUM 593 594/// 595#define END_IMPLEMENT_BITFIELD \ 596 _END_IMPLEMENT_BITFIELD 597 598/// 599#define DECLARE_STRUCT( type ) \ 600 _DECLARE_STRUCT( type ) 601 602/// 603#define DECLARE_STRUCT_R( type ) \ 604 _DECLARE_STRUCT_R( type ) 605 606/// 607#define IMPLEMENT_STRUCT( type, exportName, scope, doc ) \ 608 _IMPLEMENT_STRUCT( type, exportName, scope, doc ) 609 610/// 611#define END_IMPLEMENT_STRUCT \ 612 _END_IMPLEMENT_STRUCT 613 614 615/// 616#define FIELD( fieldName, exportName, numElements, doc ) \ 617 { #exportName, doc, numElements, TYPE( ( ( ThisType* ) 16 )->fieldName ), (U32)FIELDOFFSET( fieldName ) }, // Artificial offset to avoid compiler warnings. 618 619/// 620#define FIELD_AS( type, fieldName, exportName, numElements, doc ) \ 621 { #exportName, doc, numElements, TYPE( *( ( type* ) &( ( ThisType* ) 16 )->fieldName ) ), (U32)FIELDOFFSET( fieldName ) }, // Artificial offset to avoid compiler warnings. 622 623/// 624#define FIELDOFFSET( fieldName ) \ 625 uintptr_t( ( ( const char* ) &( ( ( ThisType* ) 16 )->fieldName ) ) - 16 ) // Artificial offset to avoid compiler warnings. 626 627/// 628#define CLASSDOC( className, doc ) \ 629 template<> const char* EngineClassTypeInfo< className, className::_ClassBase >::smDocString = doc; 630 631 632/// @} 633 634 635struct _GLOBALSCOPE 636{ 637 static EngineExportScope& __engineExportScope(); 638}; 639 640// Helper to retrieve a scope instance through a C++ type. The setup here is a little 641// contrived to allow the scope parameters to the various macros to be empty. What makes 642// this difficult is that T need not necessarily be a structured type. 643template< typename T = _GLOBALSCOPE > 644struct _SCOPE 645{ 646 EngineExportScope& operator()() const { return T::__engineExportScope(); } 647}; 648 649#endif // !_ENGINETYPES_H_ 650
