/// Create a type object. /// /// @param[in] name Type name. /// @param[in] pTypePackage Package in which the template object should be stored. /// @param[in] pParent Parent type. /// @param[in] pTemplate Template object. /// @param[in] flags Type flags. /// /// @return Pointer to the type object if created successfully, null if not. /// /// @see Unregister() const GameObjectType* GameObjectType::Create( Name name, Package* pTypePackage, const GameObjectType* pParent, GameObject* pTemplate, RELEASE_STATIC_TYPE_CALLBACK* pReleaseStaticTypeCallback, uint32_t flags ) { HELIUM_ASSERT( !name.IsEmpty() ); HELIUM_ASSERT( pTypePackage ); HELIUM_ASSERT( pTemplate ); HELIUM_ASSERT( pReleaseStaticTypeCallback ); // Register the template object with the object system. if( !GameObject::RegisterObject( pTemplate ) ) { HELIUM_TRACE( TRACE_ERROR, TXT( "GameObjectType::Initialize(): Failed to register type \"%s\" template object.\n" ), *name ); return false; } // Set up the template object name, and set this object as its parent. GameObject::RenameParameters nameParameters; nameParameters.name = name; nameParameters.spOwner = pTypePackage; if( !pTemplate->Rename( nameParameters ) ) { HELIUM_TRACE( TRACE_ERROR, TXT( "GameObjectType::Initialize(): Failed to set type \"%s\" template object name and owner.\n" ), *name ); GameObject::UnregisterObject( pTemplate ); return false; } // Flag the object as the default template object for the type being created. pTemplate->SetFlags( GameObject::FLAG_DEFAULT_TEMPLATE ); // If the parent type is null, default to Reflect::Object, as the type should be deriving from it directly. const Reflect::Class* pBaseClass = pParent; if( !pBaseClass ) { pBaseClass = Reflect::Object::s_Class; HELIUM_ASSERT( pBaseClass ); } // Create the type object and store its parameters. GameObjectType* pType = new GameObjectType; HELIUM_ASSERT( pType ); pType->m_Name = *name; pType->m_Size = static_cast< uint32_t >( pTemplate->GetInstanceSize() ); pType->m_Base = pBaseClass; pType->Composite::m_Default = pType->m_Default = pTemplate; pType->m_cachedName = name; pType->m_pReleaseStaticTypeCallback = pReleaseStaticTypeCallback; pType->m_flags = flags; if( pParent ) { pParent->AddDerived( pType ); } // Lazily initialize the lookup map. Note that this is not inherently thread-safe, but there should always be // at least one type registered before any sub-threads are spawned. if( !sm_pLookupMap ) { sm_pLookupMap = new LookupMap; HELIUM_ASSERT( sm_pLookupMap ); } // Register the type (note that a type with the same name should not already exist in the lookup map). LookupMap::Iterator typeIterator; HELIUM_VERIFY( sm_pLookupMap->Insert( typeIterator, KeyValue< Name, GameObjectTypePtr >( pType->GetName(), pType ) ) ); Reflect::Registry* pRegistry = Reflect::Registry::GetInstance(); HELIUM_ASSERT( pRegistry ); pRegistry->RegisterType( pType ); return pType; }