Esempio n. 1
0
/// Find an object based on its path name.
///
/// @param[in] path  FilePath of the object to locate.
///
/// @return  Pointer to the object if found, null pointer if not found.
Asset* Asset::FindObject( AssetPath path )
{
	// Make sure the path isn't empty.
	if( path.IsEmpty() )
	{
		return NULL;
	}

	// Assemble a list of object names and instance indices, from the top level on down.
	size_t pathDepth = 0;
	size_t packageDepth = 0;
	for( AssetPath testPath = path; !testPath.IsEmpty(); testPath = testPath.GetParent() )
	{
		++pathDepth;

		if( testPath.IsPackage() )
		{
			++packageDepth;
		}
	}

	StackMemoryHeap<>& rStackHeap = ThreadLocalStackAllocator::GetMemoryHeap();
	StackMemoryHeap<>::Marker stackMarker( rStackHeap );

	Name* pPathNames = static_cast< Name* >( rStackHeap.Allocate( sizeof( Name ) * pathDepth ) );
	HELIUM_ASSERT( pPathNames );

	uint32_t* pInstanceIndices = static_cast< uint32_t* >( rStackHeap.Allocate( sizeof( uint32_t ) * pathDepth ) );
	HELIUM_ASSERT( pInstanceIndices );

	size_t pathIndex = pathDepth;
	for( AssetPath testPath = path; !testPath.IsEmpty(); testPath = testPath.GetParent() )
	{
		HELIUM_ASSERT( pathIndex != 0 );
		--pathIndex;

		pPathNames[ pathIndex ] = testPath.GetName();
		pInstanceIndices[ pathIndex ] = testPath.GetInstanceIndex();
	}

	HELIUM_ASSERT( pathIndex == 0 );

	// Search from the root.
	return FindChildOf( NULL, pPathNames, pInstanceIndices, pathDepth, packageDepth );
}
Esempio n. 2
0
/// Set this path to the combination of two paths.
///
/// @param[in] pRootPath  Root portion of the path.
/// @param[in] subPath    Sub-path component.
///
/// @return  True if the paths could be joined into a valid path (to which this path was set), false if joining was
///          invalid.
bool AssetPath::Join( const char* pRootPath, AssetPath subPath )
{
	if( !pRootPath || pRootPath[ 0 ] == TXT( '\0' ) )
	{
		m_pEntry = subPath.m_pEntry;

		return true;
	}

	// Parse the root path into a series of names.
	StackMemoryHeap<>& rStackHeap = ThreadLocalStackAllocator::GetMemoryHeap();
	StackMemoryHeap<>::Marker stackMarker( rStackHeap );

	Name* pRootPathNames;
	uint32_t* pRootPathIndices;
	size_t rootPathNameCount;
	size_t rootPathPackageCount;
	if( !Parse( pRootPath, rStackHeap, pRootPathNames, pRootPathIndices, rootPathNameCount, rootPathPackageCount ) )
	{
		return false;
	}

	if( rootPathNameCount != rootPathPackageCount )
	{
		AssetPath testSubPathComponent = subPath.GetParent();
		AssetPath subPathComponent;
		do
		{
			subPathComponent = testSubPathComponent;
			testSubPathComponent = testSubPathComponent.GetParent();

			if( subPathComponent.IsPackage() )
			{
				HELIUM_TRACE(
					TraceLevels::Error,
					( TXT( "AssetPath::Join(): Cannot combine \"%s\" and \"%s\" (second path is rooted in a " )
					TXT( "package, while the first path ends in an object).\n" ) ),
					pRootPath,
					*subPath.ToString() );

				return false;
			}
		} while( !testSubPathComponent.IsEmpty() );
	}

	// Assemble the list of path names in reverse order for performing the object path lookup/add.
	size_t nameCount = rootPathNameCount;
	size_t packageCount = rootPathPackageCount;

	AssetPath testPath;

	for( testPath = subPath; !testPath.IsEmpty(); testPath = testPath.GetParent() )
	{
		++nameCount;
		if( testPath.IsPackage() )
		{
			++packageCount;
		}
	}

	Name* pEntryNames = static_cast< Name* >( rStackHeap.Allocate( sizeof( Name ) * nameCount ) );
	HELIUM_ASSERT( pEntryNames );

	uint32_t* pInstanceIndices = static_cast< uint32_t* >( rStackHeap.Allocate( sizeof( uint32_t ) * nameCount ) );
	HELIUM_ASSERT( pInstanceIndices );

	Name* pCurrentName = pEntryNames;
	uint32_t* pCurrentIndex = pInstanceIndices;

	for( testPath = subPath; !testPath.IsEmpty(); testPath = testPath.GetParent() )
	{
		*pCurrentName = testPath.GetName();
		*pCurrentIndex = testPath.GetInstanceIndex();
		++pCurrentName;
		++pCurrentIndex;
	}

	ArrayCopy( pCurrentName, pRootPathNames, rootPathNameCount );
	ArrayCopy( pCurrentIndex, pRootPathIndices, rootPathNameCount );

	// Set the path.
	Set( pEntryNames, pInstanceIndices, nameCount, packageCount );

	return true;
}