/// Recursive function for resolving a package request. /// /// @param[out] rspPackage Resolved package. /// @param[in] packagePath Package object path. void CachePackageLoader::ResolvePackage( AssetPtr& rspPackage, AssetPath packagePath ) { HELIUM_ASSERT( !packagePath.IsEmpty() ); rspPackage = Asset::FindObject( packagePath ); if( !rspPackage ) { AssetPtr spParent; AssetPath parentPath = packagePath.GetParent(); if( !parentPath.IsEmpty() ) { ResolvePackage( spParent, parentPath ); HELIUM_ASSERT( spParent ); } HELIUM_VERIFY( Asset::CreateObject( rspPackage, Package::GetStaticType(), packagePath.GetName(), spParent ) ); HELIUM_ASSERT( rspPackage ); HELIUM_ASSERT( rspPackage->IsA( Package::GetStaticType()->GetMetaClass() ) ); } rspPackage->SetFlags( Asset::FLAG_PRELOADED | Asset::FLAG_LINKED | Asset::FLAG_LOADED ); }
/// Test whether an object load request has completed, getting the result object if so. /// /// Note that after a load request has completed (this function returns true), the request ID should no longer be /// considered valid. /// /// @param[in] id Load request ID. /// @param[out] rspObject Smart pointer set to the loaded object if loading has completed. Note that this will be /// set to the object instance even if the object isn't finished loading (i.e. still being /// linked, etc.). /// /// @return True if the load request has completed, false if it is still being processed. /// /// @see FinishLoad(), BeginLoadObject() bool AssetLoader::TryFinishLoad( size_t id, AssetPtr& rspObject ) { HELIUM_ASSERT( IsValid( id ) ); // Retrieve the load request and test whether it has completed. LoadRequest* pRequest = m_loadRequestPool.GetObject( id ); HELIUM_ASSERT( pRequest ); if( ( pRequest->stateFlags & LOAD_FLAG_FULLY_LOADED ) != LOAD_FLAG_FULLY_LOADED ) { return false; } HELIUM_TRACE( TraceLevels::Debug, "AssetLoader::TryFinishLoad - Completed load for asset %s\n", *pRequest->path.ToString()); HELIUM_ASSERT( !pRequest->spObject.Get() || pRequest->spObject->IsFullyLoaded() || ( pRequest->spObject->GetFlags() & Asset::FLAG_BROKEN ) ); rspObject = pRequest->spObject; // Acquire an exclusive lock to the request entry. AssetPath objectPath = pRequest->path; ConcurrentHashMap< AssetPath, LoadRequest* >::Accessor requestAccessor; HELIUM_VERIFY( m_loadRequestMap.Find( requestAccessor, objectPath ) ); HELIUM_ASSERT( requestAccessor->Second() == pRequest ); // Decrement the reference count on the load request, releasing it if the reference count reaches zero. int32_t newRequestCount = AtomicDecrementRelease( pRequest->requestCount ); if( newRequestCount == 0 ) { pRequest->spObject.Release(); pRequest->resolver.Clear(); m_loadRequestMap.Remove( requestAccessor ); m_loadRequestPool.Release( pRequest ); } requestAccessor.Release(); #if HELIUM_TOOLS if (rspObject) { if ( !(rspObject->SetFlags(Asset::FLAG_LOAD_EVENT_FIRED) & Asset::FLAG_LOAD_EVENT_FIRED) ) { AssetTracker::GetStaticInstance()->NotifyAssetLoaded( rspObject.Get() ); } } #endif return true; }