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 ); \ } }
_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 )
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 )
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