/// 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 );
}
Example #2
0
/// 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;
}