예제 #1
0
/// @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 );
}
예제 #2
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;
}