Пример #1
0
const FilePath *Helium::Asset::GetAssetFileSystemPath()
{
	HELIUM_ASSERT( !m_path.IsEmpty() );

	FilePath filePath;

	Asset *pSourceAsset = GetSourceAsset();
	if (pSourceAsset)
	{
		Package *pPackage = Reflect::SafeCast<Package>( pSourceAsset->GetOwner() );

		if ( pPackage )
		{
			PackageLoader *pLoader = pPackage->GetLoader();
			HELIUM_ASSERT( pLoader->HasAssetFileState() );

			if ( pLoader )
			{
				return &pLoader->GetAssetFileSystemPath( pSourceAsset->GetPath() );
			}
		}
	}

	return NULL;
}
Пример #2
0
int64_t AssetLoader::GetAssetFileTimestamp( const AssetPath &path )
{
	Package *pPackage = Asset::Find<Package>( path.GetParent() );
	HELIUM_ASSERT( pPackage );

	PackageLoader *pLoader = pPackage->GetLoader();
	HELIUM_ASSERT( pLoader );

	return pLoader->GetAssetFileSystemTimestamp( path );
}
Пример #3
0
bool Helium::Asset::SaveAsset()
{
	Package *pPackage = GetOwningPackage();
	if ( pPackage )
	{
		PackageLoader *pLoader = pPackage->GetLoader();
		if ( pLoader )
		{
			pLoader->SaveAsset( this );
			return true;
		}
	}

	return false;
}
Пример #4
0
void ProjectPanel::OnSave( wxCommandEvent& event )
{
    wxDataViewItemArray selection;
    int numSelected = m_DataViewCtrl->GetSelections( selection );

    for (int i = 0; i < numSelected; ++i)
    {
        Asset *pAsset = static_cast<Asset *>( selection[i].GetID() );
        Package *pPackage = pAsset->GetOwningPackage();
        HELIUM_ASSERT( pPackage );

        PackageLoader *pPackageLoader = pPackage->GetLoader();
        HELIUM_ASSERT( pPackageLoader );

        pPackageLoader->SaveAsset( pAsset );
    }
}
Пример #5
0
int lua::DefaultPackageLoaderCallback(lua_State* L)
{
	const char* name = lua_tostring(L, 1);
	PackageLoader* loader = (PackageLoader*)lua_topointer(L, lua_upvalueindex(1));
	LoadedPackage data;
	if( !loader || !loader->pfn )
	{
		lua_pushstring(L, "package loader initialization error");
		return 1;
	}
	else
	{
		data = loader->pfn(loader->userdata, name);
		if( data.bytes != NULL )
		{
			eiASSERT( data.numBytes && data.filename );
			eiDEBUG( int ok = ) luaL_loadbuffer(L, data.bytes, data.numBytes, data.filename);
			eiASSERT( ok == 0 );
			lua_pushstring(L, data.filename);
			return 2;
		}
	}
Пример #6
0
uint64_t Helium::Asset::GetAssetFileTimeStamp()
{
	HELIUM_ASSERT( !m_path.IsEmpty() );
	uint64_t timestamp = 0;

	Asset *pSourceAsset = GetSourceAsset();
	if (pSourceAsset)
	{
		Package *pPackage = Reflect::SafeCast<Package>( pSourceAsset->GetOwner() );

		if ( pPackage )
		{
			PackageLoader *pLoader = pPackage->GetLoader();
			HELIUM_ASSERT( pLoader->HasAssetFileState() );

			if ( pLoader )
			{
				pLoader->GetAssetFileSystemTimestamp( pSourceAsset->GetPath() );
			}
		}
	}

	return timestamp;
}
Пример #7
0
/// Update property preloading for the given object load request.
///
/// @param[in] pRequest  Load request to update.
///
/// @return  True if preloading still needs processing, false if it is complete.
bool GameObjectLoader::TickPreload( LoadRequest* pRequest )
{
    HELIUM_ASSERT( pRequest );
    HELIUM_ASSERT( !( pRequest->stateFlags & ( LOAD_FLAG_LINKED | LOAD_FLAG_PRECACHED | LOAD_FLAG_LOADED ) ) );

    PackageLoader* pPackageLoader = pRequest->pPackageLoader;
    HELIUM_ASSERT( pPackageLoader );

    if( IsInvalid( pRequest->packageLoadRequestId ) )
    {
        if( !pPackageLoader->TryFinishPreload() )
        {
            // Still waiting for package loader preload.
            return false;
        }

        // Add an object load request.
        GameObjectPath path = pRequest->path;
        pRequest->packageLoadRequestId = pPackageLoader->BeginLoadObject( path );
        if( IsInvalid( pRequest->packageLoadRequestId ) )
        {
            pRequest->spObject = GameObject::FindObject( path );
            GameObject* pObject = pRequest->spObject;
            if( pObject )
            {
                HELIUM_TRACE(
                    TRACE_WARNING,
                    TXT( "GameObjectLoader: GameObject \"%s\" is not serialized, but was found in memory.\n" ),
                    *path.ToString() );

                // Make sure the object is preloaded and linked, but still perform resource caching and load
                // finalization if necessary.
                pObject->SetFlags( GameObject::FLAG_PRELOADED | GameObject::FLAG_LINKED );

                AtomicOrRelease( pRequest->stateFlags, LOAD_FLAG_PRELOADED | LOAD_FLAG_LINKED );

                return true;
            }

            HELIUM_TRACE(
                TRACE_ERROR,
                TXT( "GameObjectLoader: GameObject \"%s\" is not serialized and does not exist in memory.\n" ),
                *path.ToString() );

            AtomicOrRelease( pRequest->stateFlags, LOAD_FLAG_FULLY_LOADED | LOAD_FLAG_ERROR );

            return true;
        }
    }

    HELIUM_ASSERT( IsValid( pRequest->packageLoadRequestId ) );

    bool bFinished = pPackageLoader->TryFinishLoadObject(
        pRequest->packageLoadRequestId,
        pRequest->spObject,
        pRequest->linkTable );
    if( !bFinished )
    {
        // Still waiting for object to load.
        return false;
    }

    // Preload complete.
    SetInvalid( pRequest->packageLoadRequestId );

    AtomicOrRelease( pRequest->stateFlags, LOAD_FLAG_PRELOADED );

    return true;
}
Пример #8
0
void ForciblyFullyLoadedPackageManager::Tick()
{
	AssetLoader *pAssetLoader = AssetLoader::GetStaticInstance();

	// For each editable package
	for ( DynamicArray< ForciblyFullyLoadedPackage >::Iterator packageIter = m_ForciblyFullyLoadedPackages.Begin();
		packageIter != m_ForciblyFullyLoadedPackages.End(); ++packageIter)
	{
		ForciblyFullyLoadedPackage &package = *packageIter;

		// Load the package if we need to
		if ( Helium::IsValid< size_t >( package.m_PackageLoadId ) )
		{
			HELIUM_ASSERT( package.m_Assets.IsEmpty() );
			HELIUM_ASSERT( package.m_AssetLoadIds.IsEmpty() );
			HELIUM_ASSERT( package.m_AssetPaths.IsEmpty() );
			HELIUM_ASSERT( !package.m_Package );

			AssetPtr packagePtr;
			if ( pAssetLoader->TryFinishLoad( package.m_PackageLoadId, packagePtr ) )
			{
				// Load request is finished.
				package.m_PackageLoadId = Helium::Invalid< size_t >();
				package.m_Package = Reflect::AssertCast<Package>(packagePtr);

				if ( package.m_Package )
				{
					if ( !package.m_Package->GetAllFlagsSet( Asset::FLAG_EDITOR_FORCIBLY_LOADED ) )
					{
						// Package loaded successfully, queue load requests for all children
						package.m_Package->SetFlags( Asset::FLAG_EDITOR_FORCIBLY_LOADED );
						e_AssetForciblyLoadedEvent.Raise( AssetEventArgs( package.m_Package ) );
					}

					PackageLoader *pLoader = package.m_Package->GetLoader();
					pLoader->EnumerateChildren( package.m_AssetPaths );

					package.m_Assets.Resize( package.m_AssetPaths.GetSize() );
					package.m_AssetLoadIds.Resize( package.m_AssetPaths.GetSize() );

					DynamicArray< AssetPath >::Iterator assetPathIter = package.m_AssetPaths.Begin();
					DynamicArray< size_t >::Iterator assetLoadIdIter = package.m_AssetLoadIds.Begin();

					int i = 0;
					for ( ; assetPathIter != package.m_AssetPaths.End(); ++assetPathIter, ++assetLoadIdIter )
					{
						*assetLoadIdIter = pAssetLoader->BeginLoadObject( *assetPathIter );
						HELIUM_ASSERT( !package.m_Assets[i++] );
					}
				}
				else
				{
					HELIUM_TRACE(
						TraceLevels::Warning,
						"Failed to load package '%s' for editor.",
						*package.m_PackagePath.ToString());
				}
			}
		}
	}

	// For each editable package
	for ( DynamicArray< ForciblyFullyLoadedPackage >::Iterator packageIter = m_ForciblyFullyLoadedPackages.Begin();
		packageIter != m_ForciblyFullyLoadedPackages.End(); ++packageIter)
	{
		ForciblyFullyLoadedPackage &package = *packageIter;

		// If the package is loaded
		if ( package.m_Package )
		{
			// Load the child assets if we need to
			for ( int i = 0; i < package.m_AssetPaths.GetSize(); ++i )
			{
				if ( Helium::IsValid<size_t>( package.m_AssetLoadIds[i] ) )
				{
					HELIUM_ASSERT( !package.m_Assets[i] );
					if ( pAssetLoader->TryFinishLoad( package.m_AssetLoadIds[i], package.m_Assets[i] ) )
					{
						package.m_AssetLoadIds[i] = Invalid< size_t >();

						if ( package.m_Assets[i] )
						{
							// Asset loaded successfully
							if ( !package.m_Assets[i]->IsPackage() && !package.m_Assets[i]->GetAllFlagsSet( Asset::FLAG_EDITOR_FORCIBLY_LOADED ) )
							{
								package.m_Assets[i]->SetFlags( Asset::FLAG_EDITOR_FORCIBLY_LOADED );
								e_AssetForciblyLoadedEvent.Raise( AssetEventArgs( package.m_Assets[i] ) );
							}
						}
						else
						{
							HELIUM_TRACE(
								TraceLevels::Warning,
								"Failed to asset '%s' for editor.",
								*package.m_PackagePath.ToString());
						}
					}
					else
					{
						HELIUM_ASSERT( !package.m_Assets[i] );
					}

					if ( Helium::IsValid<size_t>( package.m_AssetLoadIds[i] ) )
					{
						HELIUM_ASSERT( !package.m_Assets[i] );
					}
				}
			}
		}
	}
}
Пример #9
0
/// 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;
}
Пример #10
0
/// @copydoc GameObjectLoader::CacheObject()
bool EditorObjectLoader::CacheObject( GameObject* pObject, bool bEvictPlatformPreprocessedResourceData )
{
    HELIUM_ASSERT( pObject );

    // Don't cache broken objects or packages.
    if( pObject->GetAnyFlagSet( GameObject::FLAG_BROKEN ) || pObject->IsPackage() )
    {
        return false;
    }

    // Make sure we have an object preprocessor instance with which to cache the object.
    ObjectPreprocessor* pObjectPreprocessor = ObjectPreprocessor::GetStaticInstance();
    if( !pObjectPreprocessor )
    {
        HELIUM_TRACE(
            TRACE_WARNING,
            TXT( "EditorObjectLoader::CacheObject(): Missing ObjectPreprocessor to use for caching.\n" ) );

        return false;
    }

    // Configuration objects should not be cached.
    GameObjectPath objectPath = pObject->GetPath();

    Config& rConfig = Config::GetStaticInstance();
    GameObjectPath configPackagePath = rConfig.GetConfigContainerPackagePath();
    HELIUM_ASSERT( !configPackagePath.IsEmpty() );

    for( GameObjectPath testPath = objectPath; !testPath.IsEmpty(); testPath = testPath.GetParent() )
    {
        if( testPath == configPackagePath )
        {
            return false;
        }
    }

    // Get the timestamp for the object based on the timestamp of its source package file and, if it's a resource,
    // the timestamp of the source resource file.
    GameObject* pPackageObject;
    for( pPackageObject = pObject;
        pPackageObject && !pPackageObject->IsPackage();
        pPackageObject = pPackageObject->GetOwner() )
    {
    }

    HELIUM_ASSERT( pPackageObject );

    PackageLoader* pPackageLoader = Reflect::AssertCast< Package >( pPackageObject )->GetLoader();
    HELIUM_ASSERT( pPackageLoader );
    HELIUM_ASSERT( pPackageLoader->IsSourcePackageFile() );

    int64_t objectTimestamp = pPackageLoader->GetFileTimestamp();

    if( !pObject->IsDefaultTemplate() )
    {
        Resource* pResource = Reflect::SafeCast< Resource >( pObject );
        if( pResource )
        {
            GameObjectPath baseResourcePath = pResource->GetPath();
            HELIUM_ASSERT( !baseResourcePath.IsPackage() );
            for( ; ; )
            {
                GameObjectPath parentPath = baseResourcePath.GetParent();
                if( parentPath.IsEmpty() || parentPath.IsPackage() )
                {
                    break;
                }

                baseResourcePath = parentPath;
            }

            Path sourceFilePath;
            if ( !File::GetDataDirectory( sourceFilePath ) )
            {
                HELIUM_TRACE(
                    TRACE_WARNING,
                    TXT( "EditorObjectLoader::CacheObject(): Could not obtain data directory.\n" ) );

                return false;
            }

            sourceFilePath += baseResourcePath.ToFilePathString().GetData();

            int64_t sourceFileTimestamp = sourceFilePath.ModifiedTime();
            if( sourceFileTimestamp > objectTimestamp )
            {
                objectTimestamp = sourceFileTimestamp;
            }
        }
    }

    // Cache the object.
    bool bSuccess = pObjectPreprocessor->CacheObject(
        pObject,
        objectTimestamp,
        bEvictPlatformPreprocessedResourceData );
    if( !bSuccess )
    {
        HELIUM_TRACE(
            TRACE_ERROR,
            TXT( "EditorObjectLoader: Failed to cache object \"%s\".\n" ),
            *objectPath.ToString() );
    }

    return bSuccess;
}