mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-12 19:31:41 +00:00
Initial Implementation of the Taml, Asset and Modules systems.
Only has example and shape assets currently.
This commit is contained in:
parent
2044b2691e
commit
7a3b40a86d
123 changed files with 30435 additions and 181 deletions
|
|
@ -1566,6 +1566,494 @@ void popInstantGroup()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
typedef HashMap<StringTableEntry, StringTableEntry> typePathExpandoMap;
|
||||
static typePathExpandoMap PathExpandos;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void addPathExpando(const char* pExpandoName, const char* pPath)
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal(pExpandoName != NULL, "Expando name cannot be NULL.");
|
||||
AssertFatal(pPath != NULL, "Expando path cannot be NULL.");
|
||||
|
||||
// Fetch expando name.
|
||||
StringTableEntry expandoName = StringTable->insert(pExpandoName);
|
||||
|
||||
// Fetch the length of the path.
|
||||
S32 pathLength = dStrlen(pPath);
|
||||
|
||||
char pathBuffer[1024];
|
||||
|
||||
// Sanity!
|
||||
if (pathLength == 0 || pathLength >= sizeof(pathBuffer))
|
||||
{
|
||||
Con::warnf("Cannot add path expando '%s' with path '%s' as the path is an invalid length.", pExpandoName, pPath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Strip repeat slashes.
|
||||
if (!Con::stripRepeatSlashes(pathBuffer, pPath, sizeof(pathBuffer)))
|
||||
{
|
||||
Con::warnf("Cannot add path expando '%s' with path '%s' as the path is an invalid length.", pExpandoName, pPath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch new path length.
|
||||
pathLength = dStrlen(pathBuffer);
|
||||
|
||||
// Sanity!
|
||||
if (pathLength == 0)
|
||||
{
|
||||
Con::warnf("Cannot add path expando '%s' with path '%s' as the path is an invalid length.", pExpandoName, pPath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove any terminating slash.
|
||||
if (pathBuffer[pathLength - 1] == '/')
|
||||
pathBuffer[pathLength - 1] = 0;
|
||||
|
||||
// Fetch expanded path.
|
||||
StringTableEntry expandedPath = StringTable->insert(pathBuffer);
|
||||
|
||||
// Info.
|
||||
#if defined(TORQUE_DEBUG)
|
||||
Con::printf("Adding path expando of '%s' as '%s'.", expandoName, expandedPath);
|
||||
#endif
|
||||
|
||||
// Find any existing path expando.
|
||||
typePathExpandoMap::iterator expandoItr = PathExpandos.find(pExpandoName);
|
||||
|
||||
// Does the expando exist?
|
||||
if (expandoItr != PathExpandos.end())
|
||||
{
|
||||
// Yes, so modify the path.
|
||||
expandoItr->value = expandedPath;
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert expando.
|
||||
PathExpandos.insert(expandoName, expandedPath);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry getPathExpando(const char* pExpandoName)
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal(pExpandoName != NULL, "Expando name cannot be NULL.");
|
||||
|
||||
// Fetch expando name.
|
||||
StringTableEntry expandoName = StringTable->insert(pExpandoName);
|
||||
|
||||
// Find any existing path expando.
|
||||
typePathExpandoMap::iterator expandoItr = PathExpandos.find(expandoName);
|
||||
|
||||
// Does the expando exist?
|
||||
if (expandoItr != PathExpandos.end())
|
||||
{
|
||||
// Yes, so return it.
|
||||
return expandoItr->value;
|
||||
}
|
||||
|
||||
// Not found.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void removePathExpando(const char* pExpandoName)
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal(pExpandoName != NULL, "Expando name cannot be NULL.");
|
||||
|
||||
// Fetch expando name.
|
||||
StringTableEntry expandoName = StringTable->insert(pExpandoName);
|
||||
|
||||
// Find any existing path expando.
|
||||
typePathExpandoMap::iterator expandoItr = PathExpandos.find(expandoName);
|
||||
|
||||
// Does the expando exist?
|
||||
if (expandoItr == PathExpandos.end())
|
||||
{
|
||||
// No, so warn.
|
||||
#if defined(TORQUE_DEBUG)
|
||||
Con::warnf("Removing path expando of '%s' but it does not exist.", expandoName);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Info.
|
||||
#if defined(TORQUE_DEBUG)
|
||||
Con::printf("Removing path expando of '%s' as '%s'.", expandoName, expandoItr->value);
|
||||
#endif
|
||||
// Remove expando.
|
||||
PathExpandos.erase(expandoItr);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool isPathExpando(const char* pExpandoName)
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal(pExpandoName != NULL, "Expando name cannot be NULL.");
|
||||
|
||||
// Fetch expando name.
|
||||
StringTableEntry expandoName = StringTable->insert(pExpandoName);
|
||||
|
||||
return PathExpandos.contains(expandoName);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
U32 getPathExpandoCount(void)
|
||||
{
|
||||
return PathExpandos.size();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry getPathExpandoKey(U32 expandoIndex)
|
||||
{
|
||||
// Finish if index is out of range.
|
||||
if (expandoIndex >= PathExpandos.size())
|
||||
return NULL;
|
||||
|
||||
// Find indexed iterator.
|
||||
typePathExpandoMap::iterator expandoItr = PathExpandos.begin();
|
||||
while (expandoIndex > 0) { ++expandoItr; --expandoIndex; }
|
||||
|
||||
return expandoItr->key;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry getPathExpandoValue(U32 expandoIndex)
|
||||
{
|
||||
// Finish if index is out of range.
|
||||
if (expandoIndex >= PathExpandos.size())
|
||||
return NULL;
|
||||
|
||||
// Find indexed iterator.
|
||||
typePathExpandoMap::iterator expandoItr = PathExpandos.begin();
|
||||
while (expandoIndex > 0) { ++expandoItr; --expandoIndex; }
|
||||
|
||||
return expandoItr->value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool expandPath(char* pDstPath, U32 size, const char* pSrcPath, const char* pWorkingDirectoryHint, const bool ensureTrailingSlash)
|
||||
{
|
||||
char pathBuffer[2048];
|
||||
const char* pSrc = pSrcPath;
|
||||
char* pSlash;
|
||||
|
||||
// Fetch leading character.
|
||||
const char leadingToken = *pSrc;
|
||||
|
||||
// Fetch following token.
|
||||
const char followingToken = leadingToken != 0 ? pSrc[1] : 0;
|
||||
|
||||
// Expando.
|
||||
if (leadingToken == '^')
|
||||
{
|
||||
// Initial prefix search.
|
||||
const char* pPrefixSrc = pSrc + 1;
|
||||
char* pPrefixDst = pathBuffer;
|
||||
|
||||
// Search for end of expando.
|
||||
while (*pPrefixSrc != '/' && *pPrefixSrc != 0)
|
||||
{
|
||||
// Copy prefix character.
|
||||
*pPrefixDst++ = *pPrefixSrc++;
|
||||
}
|
||||
|
||||
// Yes, so terminate the expando string.
|
||||
*pPrefixDst = 0;
|
||||
|
||||
// Fetch the expando path.
|
||||
StringTableEntry expandoPath = getPathExpando(pathBuffer);
|
||||
|
||||
// Does the expando exist?
|
||||
if (expandoPath == NULL)
|
||||
{
|
||||
// No, so error.
|
||||
Con::errorf("expandPath() : Could not find path expando '%s' for path '%s'.", pathBuffer, pSrcPath);
|
||||
|
||||
// Are we ensuring the trailing slash?
|
||||
if (ensureTrailingSlash)
|
||||
{
|
||||
// Yes, so ensure it.
|
||||
Con::ensureTrailingSlash(pDstPath, pSrcPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, so just use the source path.
|
||||
dStrcpy(pDstPath, pSrcPath);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip the expando and the following slash.
|
||||
pSrc += dStrlen(pathBuffer) + 1;
|
||||
|
||||
// Format the output path.
|
||||
dSprintf(pathBuffer, sizeof(pathBuffer), "%s/%s", expandoPath, pSrc);
|
||||
|
||||
// Are we ensuring the trailing slash?
|
||||
if (ensureTrailingSlash)
|
||||
{
|
||||
// Yes, so ensure it.
|
||||
Con::ensureTrailingSlash(pathBuffer, pathBuffer);
|
||||
}
|
||||
|
||||
// Strip repeat slashes.
|
||||
Con::stripRepeatSlashes(pDstPath, pathBuffer, size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Script-Relative.
|
||||
if (leadingToken == '.')
|
||||
{
|
||||
// Fetch the code-block file-path.
|
||||
const StringTableEntry codeblockFullPath = CodeBlock::getCurrentCodeBlockFullPath();
|
||||
|
||||
// Do we have a code block full path?
|
||||
if (codeblockFullPath == NULL)
|
||||
{
|
||||
// No, so error.
|
||||
Con::errorf("expandPath() : Could not find relative path from code-block for path '%s'.", pSrcPath);
|
||||
|
||||
// Are we ensuring the trailing slash?
|
||||
if (ensureTrailingSlash)
|
||||
{
|
||||
// Yes, so ensure it.
|
||||
Con::ensureTrailingSlash(pDstPath, pSrcPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, so just use the source path.
|
||||
dStrcpy(pDstPath, pSrcPath);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Yes, so use it as the prefix.
|
||||
dStrncpy(pathBuffer, codeblockFullPath, sizeof(pathBuffer) - 1);
|
||||
|
||||
// Find the final slash in the code-block.
|
||||
pSlash = dStrrchr(pathBuffer, '/');
|
||||
|
||||
// Is this a parent directory token?
|
||||
if (followingToken == '.')
|
||||
{
|
||||
// Yes, so terminate after the slash so we include it.
|
||||
pSlash[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No, it's a current directory token so terminate at the slash so we don't include it.
|
||||
pSlash[0] = 0;
|
||||
|
||||
// Skip the current directory token.
|
||||
pSrc++;
|
||||
}
|
||||
|
||||
// Format the output path.
|
||||
dStrncat(pathBuffer, "/", sizeof(pathBuffer) - 1 - strlen(pathBuffer));
|
||||
dStrncat(pathBuffer, pSrc, sizeof(pathBuffer) - 1 - strlen(pathBuffer));
|
||||
|
||||
// Are we ensuring the trailing slash?
|
||||
if (ensureTrailingSlash)
|
||||
{
|
||||
// Yes, so ensure it.
|
||||
Con::ensureTrailingSlash(pathBuffer, pathBuffer);
|
||||
}
|
||||
|
||||
// Strip repeat slashes.
|
||||
Con::stripRepeatSlashes(pDstPath, pathBuffer, size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// All else.
|
||||
|
||||
//Using a special case here because the code below barfs on trying to build a full path for apk reading
|
||||
#ifdef TORQUE_OS_ANDROID
|
||||
if (leadingToken == '/' || strstr(pSrcPath, "/") == NULL)
|
||||
Platform::makeFullPathName(pSrcPath, pathBuffer, sizeof(pathBuffer), pWorkingDirectoryHint);
|
||||
else
|
||||
dSprintf(pathBuffer, sizeof(pathBuffer), "/%s", pSrcPath);
|
||||
#else
|
||||
Platform::makeFullPathName(pSrcPath, pathBuffer, sizeof(pathBuffer), pWorkingDirectoryHint);
|
||||
#endif
|
||||
|
||||
// Are we ensuring the trailing slash?
|
||||
if (ensureTrailingSlash)
|
||||
{
|
||||
// Yes, so ensure it.
|
||||
Con::ensureTrailingSlash(pathBuffer, pathBuffer);
|
||||
}
|
||||
|
||||
// Strip repeat slashes.
|
||||
Con::stripRepeatSlashes(pDstPath, pathBuffer, size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool isBasePath(const char* SrcPath, const char* pBasePath)
|
||||
{
|
||||
char expandBuffer[1024];
|
||||
Con::expandPath(expandBuffer, sizeof(expandBuffer), SrcPath);
|
||||
return dStrnicmp(pBasePath, expandBuffer, dStrlen(pBasePath)) == 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void collapsePath(char* pDstPath, U32 size, const char* pSrcPath, const char* pWorkingDirectoryHint)
|
||||
{
|
||||
// Check path against expandos. If there are multiple matches, choose the
|
||||
// expando that produces the shortest relative path.
|
||||
|
||||
char pathBuffer[2048];
|
||||
|
||||
// Fetch expando count.
|
||||
const U32 expandoCount = getPathExpandoCount();
|
||||
|
||||
// Iterate expandos.
|
||||
U32 expandoRelativePathLength = U32_MAX;
|
||||
for (U32 expandoIndex = 0; expandoIndex < expandoCount; ++expandoIndex)
|
||||
{
|
||||
// Fetch expando value (path).
|
||||
StringTableEntry expandoValue = getPathExpandoValue(expandoIndex);
|
||||
|
||||
// Skip if not the base path.
|
||||
if (!isBasePath(pSrcPath, expandoValue))
|
||||
continue;
|
||||
|
||||
// Fetch path relative to expando path.
|
||||
StringTableEntry relativePath = Platform::makeRelativePathName(pSrcPath, expandoValue);
|
||||
|
||||
// If the relative path is simply a period
|
||||
if (relativePath[0] == '.')
|
||||
relativePath++;
|
||||
|
||||
if (dStrlen(relativePath) > expandoRelativePathLength)
|
||||
{
|
||||
// This expando covers less of the path than any previous one found.
|
||||
// We will keep the previous one.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Keep track of the relative path length
|
||||
expandoRelativePathLength = dStrlen(relativePath);
|
||||
|
||||
// Fetch expando key (name).
|
||||
StringTableEntry expandoName = getPathExpandoKey(expandoIndex);
|
||||
|
||||
// Format against expando.
|
||||
dSprintf(pathBuffer, sizeof(pathBuffer), "^%s/%s", expandoName, relativePath);
|
||||
}
|
||||
|
||||
// Check if we've found a suitable expando
|
||||
if (expandoRelativePathLength != U32_MAX)
|
||||
{
|
||||
// Strip repeat slashes.
|
||||
Con::stripRepeatSlashes(pDstPath, pathBuffer, size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the working directory.
|
||||
StringTableEntry workingDirectory = pWorkingDirectoryHint != NULL ? pWorkingDirectoryHint : Platform::getCurrentDirectory();
|
||||
|
||||
// Fetch path relative to current directory.
|
||||
StringTableEntry relativePath = Platform::makeRelativePathName(pSrcPath, workingDirectory);
|
||||
|
||||
// If the relative path is simply a period
|
||||
if (relativePath[0] == '.' && relativePath[1] != '.')
|
||||
relativePath++;
|
||||
|
||||
// Format against expando.
|
||||
dSprintf(pathBuffer, sizeof(pathBuffer), "%s/%s", workingDirectory, relativePath);
|
||||
|
||||
// Strip repeat slashes.
|
||||
Con::stripRepeatSlashes(pDstPath, pathBuffer, size);
|
||||
}
|
||||
|
||||
|
||||
void ensureTrailingSlash(char* pDstPath, const char* pSrcPath)
|
||||
{
|
||||
// Copy to target.
|
||||
dStrcpy(pDstPath, pSrcPath);
|
||||
|
||||
// Find trailing character index.
|
||||
S32 trailIndex = dStrlen(pDstPath);
|
||||
|
||||
// Ignore if empty string.
|
||||
if (trailIndex == 0)
|
||||
return;
|
||||
|
||||
// Finish if the trailing slash already exists.
|
||||
if (pDstPath[trailIndex - 1] == '/')
|
||||
return;
|
||||
|
||||
// Add trailing slash.
|
||||
pDstPath[trailIndex++] = '/';
|
||||
pDstPath[trailIndex] = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool stripRepeatSlashes(char* pDstPath, const char* pSrcPath, S32 dstSize)
|
||||
{
|
||||
// Note original destination.
|
||||
char* pOriginalDst = pDstPath;
|
||||
|
||||
// Reset last source character.
|
||||
char lastSrcChar = 0;
|
||||
|
||||
// Search source...
|
||||
while (dstSize > 0)
|
||||
{
|
||||
// Fetch characters.
|
||||
const char srcChar = *pSrcPath++;
|
||||
|
||||
// Do we have a repeat slash?
|
||||
if (srcChar == '/' && lastSrcChar == '/')
|
||||
{
|
||||
// Yes, so skip it.
|
||||
continue;
|
||||
}
|
||||
|
||||
// No, so copy character.
|
||||
*pDstPath++ = srcChar;
|
||||
|
||||
// Finish if end of source.
|
||||
if (srcChar == 0)
|
||||
return true;
|
||||
|
||||
// Reduce room left in destination.
|
||||
dstSize--;
|
||||
|
||||
// Set last character.
|
||||
lastSrcChar = srcChar;
|
||||
}
|
||||
|
||||
// Terminate the destination string as we ran out of room.
|
||||
*pOriginalDst = 0;
|
||||
|
||||
// Fail!
|
||||
return false;
|
||||
}
|
||||
|
||||
} // end of Console namespace
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue