/// @copydoc GameObjectLoader::OnPrecacheReady() void EditorObjectLoader::OnPrecacheReady( GameObject* pObject, PackageLoader* pPackageLoader ) { HELIUM_ASSERT( pObject ); HELIUM_ASSERT( pPackageLoader ); // The default template object for a given type never has its resource data preprocessed, so there's no need to // precache default template objects. if( pObject->IsDefaultTemplate() ) { return; } // Retrieve the object preprocessor if it exists. ObjectPreprocessor* pObjectPreprocessor = ObjectPreprocessor::GetStaticInstance(); if( !pObjectPreprocessor ) { HELIUM_TRACE( TRACE_WARNING, ( TXT( "EditorObjectLoader::OnPrecacheReady(): Missing ObjectPreprocessor to use for resource " ) TXT( "preprocessing.\n" ) ) ); return; } // We only need to do precache handling for resources, so skip non-resource types. Resource* pResource = Reflect::SafeCast< Resource >( pObject ); if( !pResource ) { return; } // Grab the package timestamp. HELIUM_ASSERT( pPackageLoader->IsSourcePackageFile() ); int64_t objectTimestamp = pPackageLoader->GetFileTimestamp(); // Attempt to load the resource data. pObjectPreprocessor->LoadResourceData( pResource, objectTimestamp ); }
/// Begin asynchronous loading of a shader variant. /// /// @param[in] pShader Parent shader resource. /// @param[in] shaderType Shader type. /// @param[in] userOptionIndex Index associated with the user option combination for the shader variant. /// /// @return ID associated with the load procedure, or an invalid index if the load could not be started. /// /// @see TryFinishLoadVariant() size_t ShaderVariantResourceHandler::BeginLoadVariant( Shader* pShader, RShader::EType shaderType, uint32_t userOptionIndex ) { HELIUM_ASSERT( pShader ); HELIUM_ASSERT( static_cast< size_t >( shaderType ) < static_cast< size_t >( RShader::TYPE_MAX ) ); // Attempt to locate an existing load request for the specified shader variant. LoadRequest* pLoadRequest = m_loadRequestPool.Allocate(); HELIUM_ASSERT( pLoadRequest ); pLoadRequest->shaderType = shaderType; pLoadRequest->userOptionIndex = userOptionIndex; HELIUM_ASSERT( !pLoadRequest->spVariant ); pLoadRequest->requestCount = 1; LoadRequestSetType::ConstAccessor loadRequestConstAccessor; if( !m_loadRequestSet.Insert( loadRequestConstAccessor, pLoadRequest ) ) { // Request exists, so increment its reference count. m_loadRequestPool.Release( pLoadRequest ); pLoadRequest = *loadRequestConstAccessor; HELIUM_ASSERT( pLoadRequest ); AtomicIncrementAcquire( pLoadRequest->requestCount ); size_t loadId = m_loadRequestPool.GetIndex( pLoadRequest ); HELIUM_ASSERT( IsValid( loadId ) ); return loadId; } // Adding a new request, so create the variant object if it does not yet exist. tchar_t shaderTypeCharacter; if( shaderType == RShader::TYPE_VERTEX ) { shaderTypeCharacter = TXT( 'v' ); } else { HELIUM_ASSERT( shaderType == RShader::TYPE_PIXEL ); shaderTypeCharacter = TXT( 'p' ); } String variantNameString; variantNameString.Format( TXT( "%c%" ) TPRIu32, shaderTypeCharacter, userOptionIndex ); Name variantName( variantNameString ); variantNameString.Clear(); pLoadRequest->spVariant.Set( Reflect::AssertCast< ShaderVariant >( pShader->FindChild( variantName ) ) ); if( !pLoadRequest->spVariant ) { if( !GameObject::Create< ShaderVariant >( pLoadRequest->spVariant, variantName, pShader ) ) { HELIUM_TRACE( TRACE_ERROR, ( TXT( "ShaderVariantResourceHandler::BeginLoadVariant(): Failed to create shader variant object " ) TXT( "\"%s:%s\".\n" ) ), *pShader->GetPath().ToString(), *variantName ); } else { HELIUM_ASSERT( pLoadRequest->spVariant ); } } // If we have an object for the shader variant, attempt to load its resource data. ShaderVariant* pVariant = pLoadRequest->spVariant; if( pVariant && !pVariant->GetAnyFlagSet( GameObject::FLAG_PRECACHED ) ) { GameObject* pPackageObject; for( pPackageObject = pShader->GetOwner(); pPackageObject != NULL && !pPackageObject->IsPackage(); pPackageObject = pPackageObject->GetOwner() ) { // This space intentionally left blank... } HELIUM_ASSERT( pPackageObject ); PackageLoader* pPackageLoader = Reflect::AssertCast< Package >( pPackageObject )->GetLoader(); HELIUM_ASSERT( pPackageLoader ); HELIUM_ASSERT( pPackageLoader->IsSourcePackageFile() ); ObjectPreprocessor* pObjectPreprocessor = ObjectPreprocessor::GetStaticInstance(); HELIUM_ASSERT( pObjectPreprocessor ); pObjectPreprocessor->LoadResourceData( pVariant, pPackageLoader->GetFileTimestamp() ); // Resource data loaded, so deserialize the persistent data for the current platform and begin precaching. CacheManager& rCacheManager = CacheManager::GetStaticInstance(); const Resource::PreprocessedData& rPreprocessedData = pVariant->GetPreprocessedData( rCacheManager.GetCurrentPlatform() ); const DynArray< uint8_t >& rPersistentDataBuffer = rPreprocessedData.persistentDataBuffer; //PMDTODO: Implmenet this // BinaryDeserializer deserializer; // deserializer.Prepare( rPersistentDataBuffer.GetData(), rPersistentDataBuffer.GetSize() ); // deserializer.BeginSerialize(); // pVariant->SerializePersistentResourceData( deserializer ); // deserializer.EndSerialize(); Reflect::ObjectPtr persistent_resource_data = Cache::ReadCacheObjectFromBuffer(rPersistentDataBuffer); pVariant->LoadPersistentResourceObject(persistent_resource_data); pVariant->BeginPrecacheResourceData(); } size_t loadId = m_loadRequestPool.GetIndex( pLoadRequest ); HELIUM_ASSERT( IsValid( loadId ) ); return loadId; }