forked from 0ad/0ad
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.
This commit is contained in:
parent
bed9363bfe
commit
a81d7adee4
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
VFSUtil::FileList files;
|
||||
if(!VFSUtil::FindFiles(dir, fileext_filter, files))
|
||||
// FindFiles has already logged the failure
|
||||
return;
|
||||
|
||||
path += '/';
|
||||
for(VFSUtil::FileList::iterator it = files.begin(); it != files.end(); ++it)
|
||||
{
|
||||
const char* texture_name = it->c_str();
|
||||
|
||||
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";
|
||||
// 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(xmlname.c_str()))
|
||||
myprops=GetPropertiesFromFile(props, xmlname);
|
||||
|
||||
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", xmlname.c_str(), dent.name);
|
||||
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, path+dent.name);
|
||||
}
|
||||
|
||||
vfs_dir_close(dir);
|
||||
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<CStr> folders;
|
||||
VFSUtil::FindFiles(path.c_str(), "/", folders);
|
||||
|
||||
for (uint i=0;i<folders.size();i++)
|
||||
VFSUtil::FileList subdirs;
|
||||
VFSUtil::FindFiles(cur_dir_path, "/", subdirs);
|
||||
for (uint i=0;i<subdirs.size();i++)
|
||||
{
|
||||
RecurseDirectory(props, folders[i]);
|
||||
RecurseDirectory(props, subdirs[i].c_str());
|
||||
}
|
||||
|
||||
// TODO: just iterate over all files and check if its extension is supported
|
||||
for (int i=0;i<ARRAY_SIZE(SupportedTextureFormats);i++)
|
||||
{
|
||||
LoadTextures(props, path, SupportedTextureFormats[i]);
|
||||
LoadTextures(props, cur_dir_path, SupportedTextureFormats[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,12 +65,12 @@ private:
|
||||
|
||||
// Find all textures in directory matching the file extension, check if
|
||||
// there's an override XML with the same basename (if there is, load it)
|
||||
void LoadTextures(CTerrainProperties *props, CStr path, const char* ext);
|
||||
void LoadTextures(CTerrainProperties *props, const char* dir, const char* ext);
|
||||
|
||||
// Load all terrains below path, using props as the parent property sheet.
|
||||
void RecurseDirectory(CTerrainProperties *props, CStr path);
|
||||
void RecurseDirectory(CTerrainProperties *props, const char* dir);
|
||||
|
||||
CTerrainProperties *GetPropertiesFromFile(CTerrainProperties *props, CStr path);
|
||||
CTerrainProperties *GetPropertiesFromFile(CTerrainProperties *props, const char* path);
|
||||
|
||||
public:
|
||||
// constructor, destructor
|
||||
|
Loading…
Reference in New Issue
Block a user