/// Initialize this package loader. /// /// @param[in] packagePath Asset path of the package to load. /// /// @return True if this loader was initialized successfully, false if not. /// /// @see Shutdown() bool LoosePackageLoader::Initialize( AssetPath packagePath ) { Shutdown(); // Make sure the path represents a package. if( packagePath.IsEmpty() ) { HELIUM_TRACE( TraceLevels::Error, TXT( "LoosePackageLoader::Initialize(): Empty package path specified.\n" ) ); return false; } HELIUM_TRACE( TraceLevels::Debug, TXT( "LoosePackageLoader::Initialize(): Initializing loader for package \"%s\".\n" ), *packagePath.ToString() ); if( !packagePath.IsPackage() ) { HELIUM_TRACE( TraceLevels::Error, TXT( "LoosePackageLoader::Initialize(): \"%s\" does not represent a package path.\n" ), *packagePath.ToString() ); return false; } // Store the package path. m_packagePath = packagePath; // Attempt to locate the specified package if it already happens to exist. m_spPackage = Asset::Find< Package >( packagePath ); Package* pPackage = m_spPackage; if( pPackage ) { if( pPackage->GetLoader() ) { HELIUM_TRACE( TraceLevels::Error, TXT( "LoosePackageLoader::Initialize(): Package \"%s\" already has a loader.\n" ), *packagePath.ToString() ); m_spPackage.Release(); return false; } pPackage->SetLoader( this ); } else { // Make sure we don't have a name clash with a non-package object. AssetPtr spObject( Asset::FindObject( packagePath ) ); if( spObject ) { HELIUM_ASSERT( !spObject->IsPackage() ); HELIUM_TRACE( TraceLevels::Error, ( TXT( "PackageLoader::Initialize(): Package loader cannot be initialized for \"%s\", as an " ) TXT( "object with the same name exists that is not a package.\n" ) ), *packagePath.ToString() ); return false; } } // Build the package file path. If the package is a user configuration package, use the user data directory, // otherwise use the global data directory. Config& rConfig = Config::GetStaticInstance(); FilePath dataDirectory; if ( !FileLocations::GetDataDirectory( dataDirectory ) ) { HELIUM_TRACE( TraceLevels::Error, TXT( "PackageLoader::Initialize(): Could not obtain user data directory." ) ); return false; } // Set up to read the TOC (which may not exist) //SetInvalid( m_packageTocFileSize ); // First do this check without a trailing "/" so that FilePath has to actually look at the file system FilePath package_dir = dataDirectory + packagePath.ToFilePathString().GetData(); if (!package_dir.Exists()) { // Some packages like types or uninitialized user config packages may not exist on file system m_packageDirPath = package_dir + TXT("/"); return true; } if (!package_dir.IsDirectory()) { // Packages should not be files return false; } // But internally we will store this m_packageDirPath = package_dir + TXT("/"); return true; }
/// @copydoc AssetLoader::CacheObject() bool LooseAssetLoader::CacheObject( Asset* pAsset, bool bEvictPlatformPreprocessedResourceData ) { HELIUM_ASSERT( pAsset ); HELIUM_TRACE( TraceLevels::Info, TXT( "LooseAssetLoader::CacheObject(): Caching asset %s.\n" ), *pAsset->GetPath().ToString() ); // Don't cache broken objects or packages. if( pAsset->GetAnyFlagSet( Asset::FLAG_BROKEN ) || pAsset->IsPackage() ) { return false; } // Make sure we have an object preprocessor instance with which to cache the object. AssetPreprocessor* pAssetPreprocessor = AssetPreprocessor::GetStaticInstance(); if( !pAssetPreprocessor ) { HELIUM_TRACE( TraceLevels::Warning, TXT( "LooseAssetLoader::CacheObject(): Missing AssetPreprocessor to use for caching.\n" ) ); return false; } // User configuration objects should not be cached. AssetPath objectPath = pAsset->GetPath(); Config& rConfig = Config::GetStaticInstance(); // Only cache the files we care about if ( rConfig.IsAssetPathInUserConfigPackage(objectPath) ) { return false; } int64_t objectTimestamp = pAsset->GetAssetFileTimeStamp(); if( !pAsset->IsDefaultTemplate() ) { Resource* pResource = Reflect::SafeCast< Resource >( pAsset ); if( pResource ) { AssetPath baseResourcePath = pResource->GetPath(); HELIUM_ASSERT( !baseResourcePath.IsPackage() ); for( ; ; ) { AssetPath parentPath = baseResourcePath.GetParent(); if( parentPath.IsEmpty() || parentPath.IsPackage() ) { break; } baseResourcePath = parentPath; } FilePath sourceFilePath; if ( !FileLocations::GetDataDirectory( sourceFilePath ) ) { HELIUM_TRACE( TraceLevels::Warning, TXT( "LooseAssetLoader::CacheObject(): Could not obtain data directory.\n" ) ); return false; } sourceFilePath += baseResourcePath.ToFilePathString().GetData(); Status stat; stat.Read( sourceFilePath.Get().c_str() ); int64_t sourceFileTimestamp = stat.m_ModifiedTime; if( sourceFileTimestamp > objectTimestamp ) { objectTimestamp = sourceFileTimestamp; } } } // Cache the object. bool bSuccess = pAssetPreprocessor->CacheObject( pAsset, objectTimestamp, bEvictPlatformPreprocessedResourceData ); if( !bSuccess ) { HELIUM_TRACE( TraceLevels::Error, TXT( "LooseAssetLoader: Failed to cache object \"%s\".\n" ), *objectPath.ToString() ); } return bSuccess; }