From a81d7adee422ec027cea169e2055996435f22c2a Mon Sep 17 00:00:00 2001 From: janwas Date: Wed, 19 Oct 2005 22:39:54 +0000 Subject: [PATCH] restructure terrain texture loading to first get a filelist, then do work for each file. this is slightly more efficient than iterating over dir and doing work for each (due to less seeks) but intended to fix an issue where files are created while iterating over the directory (this confuses VFS). the problem had come up after adding terrain XML files. also restructured a few calls to avoid passing CStr by value down multiple call levels (ugh) This was SVN commit r2977. --- source/graphics/TerrainProperties.cpp | 6 +- source/graphics/TerrainProperties.h | 2 +- source/graphics/TextureManager.cpp | 94 +++++++++++++-------------- source/graphics/TextureManager.h | 6 +- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/source/graphics/TerrainProperties.cpp b/source/graphics/TerrainProperties.cpp index a2ecccb2c2..5a58e56fcf 100644 --- a/source/graphics/TerrainProperties.cpp +++ b/source/graphics/TerrainProperties.cpp @@ -24,7 +24,7 @@ CTerrainProperties::CTerrainProperties(CTerrainProperties *parent): m_Groups = m_pParent->m_Groups; } -CTerrainProperties *CTerrainProperties::FromXML(CTerrainProperties *parent, CStr path) +CTerrainProperties *CTerrainProperties::FromXML(CTerrainProperties *parent, const char* path) { CXeromyces XeroFile; if (XeroFile.Load(path) != PSRETURN_OK) @@ -39,7 +39,7 @@ CTerrainProperties *CTerrainProperties::FromXML(CTerrainProperties *parent, CStr LOG(ERROR, LOG_CATEGORY, "TextureManager: Loading %s: Root node is not terrains (found \"%s\")", - path.c_str(), + path, rootName.c_str()); return NULL; } @@ -70,7 +70,7 @@ CTerrainProperties *CTerrainProperties::FromXML(CTerrainProperties *parent, CStr { LOG(WARNING, LOG_CATEGORY, "TerrainProperties: Loading %s: Unexpected node %s\n", - path.c_str(), + path, XeroFile.getElementString(child.getNodeName()).c_str()); // Keep reading - typos shouldn't be showstoppers } diff --git a/source/graphics/TerrainProperties.h b/source/graphics/TerrainProperties.h index d680964037..3e668d0407 100644 --- a/source/graphics/TerrainProperties.h +++ b/source/graphics/TerrainProperties.h @@ -43,7 +43,7 @@ public: // Create a new object and load the XML file specified. Returns NULL upon // failure // The parent pointer may be NULL, for the "root" terrainproperties object. - static CTerrainProperties *FromXML(CTerrainProperties *parent, CStr path); + static CTerrainProperties *FromXML(CTerrainProperties *parent, const char* path); // Save the object to an XML file. Implement when needed! ;-) // bool WriteXML(CStr path); diff --git a/source/graphics/TextureManager.cpp b/source/graphics/TextureManager.cpp index d3b9f73d0e..beec82f289 100755 --- a/source/graphics/TextureManager.cpp +++ b/source/graphics/TextureManager.cpp @@ -63,7 +63,7 @@ CTextureEntry* CTextureManager::FindTexture(Handle handle) return CTextureEntry::GetByHandle(handle); } -CTerrainProperties *CTextureManager::GetPropertiesFromFile(CTerrainProperties *props, CStr path) +CTerrainProperties *CTextureManager::GetPropertiesFromFile(CTerrainProperties *props, const char* path) { return CTerrainProperties::FromXML(props, path); } @@ -91,73 +91,73 @@ void CTextureManager::DeleteTexture(CTextureEntry* entry) // jw: indeed this is inefficient and RecurseDirectory should be implemented // via VFSUtil::EnumFiles, but it works fine and "only" takes 25ms for // typical maps. therefore, we'll leave it for now. -void CTextureManager::LoadTextures(CTerrainProperties *props, CStr path, const char* fileext_filter) +void CTextureManager::LoadTextures(CTerrainProperties *props, const char* dir, const char* fileext_filter) { - Handle dir=vfs_dir_open(path.c_str()); - DirEnt dent; - - path += '/'; - - if (dir > 0) - { - while (vfs_dir_next_ent(dir, &dent, fileext_filter) == 0) - { - // Strip extension off of dent.name, add .xml, check if the file - // exists - CStr xmlname=path+dent.name; - xmlname=xmlname.GetSubstring(0, xmlname.size() - (strlen(fileext_filter) - 1)); - xmlname += ".xml"; - - CTerrainProperties *myprops = NULL; - // Has XML file -> attempt to load properties - if (vfs_exists(xmlname.c_str())) - myprops=GetPropertiesFromFile(props, xmlname); - - if (myprops) - LOG(NORMAL, LOG_CATEGORY, "CTextureManager: Successfully loaded override xml %s for texture %s\n", xmlname.c_str(), dent.name); - - // Error or non-existant xml file -> use parent props - if (!myprops) - myprops = props; - - AddTexture(myprops, path+dent.name); - } + VFSUtil::FileList files; + if(!VFSUtil::FindFiles(dir, fileext_filter, files)) + // FindFiles has already logged the failure + return; - vfs_dir_close(dir); - } + for(VFSUtil::FileList::iterator it = files.begin(); it != files.end(); ++it) + { + const char* texture_name = it->c_str(); + + // build name of associated xml file (i.e. replace extension) + char xml_name[PATH_MAX+5]; // add room for .XML + strcpy_s(xml_name, PATH_MAX, texture_name); + char* ext = strrchr(xml_name, '.'); + if(ext) + strcpy(ext, ".xml"); // safe + + CTerrainProperties *myprops = NULL; + // Has XML file -> attempt to load properties + if (vfs_exists(xml_name)) + { + myprops=GetPropertiesFromFile(props, xml_name); + if (myprops) + LOG(NORMAL, LOG_CATEGORY, "CTextureManager: Successfully loaded override xml %s for texture %s\n", xml_name, texture_name); + } + + // Error or non-existant xml file -> use parent props + if (!myprops) + myprops = props; + + AddTexture(myprops, texture_name); + } } -void CTextureManager::RecurseDirectory(CTerrainProperties *parentProps, CStr path) +void CTextureManager::RecurseDirectory(CTerrainProperties *parentProps, const char* cur_dir_path) { //LOG(NORMAL, LOG_CATEGORY, "CTextureManager::RecurseDirectory(%s)", path.c_str()); - - // Load terrains.xml first, if it exists + CTerrainProperties *props=NULL; - CStr xmlpath=path+"terrains.xml"; - if (vfs_exists(xmlpath.c_str())) - props=GetPropertiesFromFile(parentProps, xmlpath); + + // Load terrains.xml first, if it exists + char fn[PATH_MAX]; + snprintf(fn, PATH_MAX, "%s/%s", cur_dir_path, "terrains.xml"); + if (vfs_exists(fn)) + props=GetPropertiesFromFile(parentProps, fn); // No terrains.xml, or read failures -> use parent props (i.e. if (!props) { LOG(NORMAL, LOG_CATEGORY, - "CTextureManager::RecurseDirectory(%s): no terrains.xml (or errors while loading) - using parent properties", path.c_str()); + "CTextureManager::RecurseDirectory(%s): no terrains.xml (or errors while loading) - using parent properties", cur_dir_path); props = parentProps; } // Recurse once for each subdirectory - - vector folders; - VFSUtil::FindFiles(path.c_str(), "/", folders); - - for (uint i=0;i