Ticket #3358: terraintexturemanager_file_loading.patch
File terraintexturemanager_file_loading.patch, 6.7 KB (added by , 9 years ago) |
---|
-
source/graphics/TerrainTextureManager.cpp
82 82 return 0; 83 83 } 84 84 85 CTerrainPropertiesPtr CTerrainTextureManager::GetPropertiesFromFile(const CTerrainPropertiesPtr& props, const VfsPath& pathname)86 {87 return CTerrainProperties::FromXML(props, pathname);88 }89 90 85 CTerrainTextureEntry* CTerrainTextureManager::AddTexture(const CTerrainPropertiesPtr& props, const VfsPath& path) 91 86 { 92 87 CTerrainTextureEntry* entry = new CTerrainTextureEntry(props, path); … … 103 98 delete entry; 104 99 } 105 100 106 // FIXME This could be effectivized by surveying the xml files in the directory 107 // instead of trial-and-error checking for existence of the xml file through 108 // the VFS. 109 // jw: indeed this is inefficient and RecurseDirectory should be implemented 110 // via VFSUtil::EnumFiles, but it works fine and "only" takes 25ms for 111 // typical maps. therefore, we'll leave it for now. 112 void CTerrainTextureManager::LoadTextures(const CTerrainPropertiesPtr& props, const VfsPath& path) 101 struct AddTextureCallbackData 113 102 { 114 VfsPaths pathnames; 115 if(vfs::GetPathnames(g_VFS, path, 0, pathnames) < 0) 116 return; 117 118 for(size_t i = 0; i < pathnames.size(); i++) 119 { 120 if (pathnames[i].Extension() != L".xml") 121 continue; 122 123 if (pathnames[i].Basename() == L"terrains") 124 continue; 125 126 AddTexture(props, pathnames[i]); 127 } 128 } 103 CTerrainTextureManager* self; 104 CTerrainPropertiesPtr props; 105 }; 129 106 130 void CTerrainTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& parentProps, const VfsPath& path)107 static Status AddTextureDirCallback(const VfsPath& pathname, const uintptr_t cbData) 131 108 { 132 //LOGMESSAGE("CTextureManager::RecurseDirectory(%s)", path.string8()); 133 134 CTerrainPropertiesPtr props; 109 AddTextureCallbackData& data = *(AddTextureCallbackData*)cbData; 110 VfsPath path = pathname / L"terrains.xml"; 111 if (!VfsFileExists(path)) 112 LOGMESSAGE("'%s' does not exist. Using previous properties.", path.string8()); 113 else 114 data.props = CTerrainProperties::FromXML(data.props, path); 135 115 136 // Load terrains.xml first, if it exists 137 VfsPath pathname = path / "terrains.xml"; 138 if (VfsFileExists(pathname)) 139 props = GetPropertiesFromFile(parentProps, pathname); 140 141 // No terrains.xml, or read failures -> use parent props (i.e. 142 if (!props) 143 { 144 LOGMESSAGE("CTerrainTextureManager::RecurseDirectory(%s): no terrains.xml (or errors while loading) - using parent properties", path.string8()); 145 props = parentProps; 146 } 116 return INFO::OK; 117 } 147 118 148 // Recurse once for each subdirectory 149 DirectoryNames subdirectoryNames; 150 (void)g_VFS->GetDirectoryEntries(path, 0, &subdirectoryNames); 151 for (size_t i=0;i<subdirectoryNames.size();i++) 152 { 153 VfsPath subdirectoryPath = path / subdirectoryNames[i] / ""; 154 RecurseDirectory(props, subdirectoryPath); 155 } 119 static Status AddTextureCallback(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData) 120 { 121 AddTextureCallbackData& data = *(AddTextureCallbackData*)cbData; 122 if (pathname.Basename() != L"terrains") 123 data.self->AddTexture(data.props, pathname); 156 124 157 LoadTextures(props, path);125 return INFO::OK; 158 126 } 159 127 160 128 int CTerrainTextureManager::LoadTerrainTextures() 161 129 { 162 CTerrainPropertiesPtr rootProps(new CTerrainProperties(CTerrainPropertiesPtr()));163 RecurseDirectory(rootProps, L"art/terrains/");130 AddTextureCallbackData data = {this, CTerrainPropertiesPtr(new CTerrainProperties(CTerrainPropertiesPtr()))}; 131 vfs::ForEachFile(g_VFS, L"art/terrains/", AddTextureCallback, (uintptr_t)&data, L"*.xml", vfs::DIR_RECURSIVE, AddTextureDirCallback, (uintptr_t)&data); 164 132 return 0; 165 133 } 166 134 -
source/graphics/TerrainTextureManager.h
103 103 104 104 size_t m_LastGroupIndex; 105 105 106 // Find+load all textures in directory; check if107 // there's an override XML with the same basename (if there is, load it)108 void LoadTextures(const CTerrainPropertiesPtr& props, const VfsPath& path);109 110 // Load all terrains below path, using props as the parent property sheet.111 void RecurseDirectory(const CTerrainPropertiesPtr& props, const VfsPath& path);112 113 CTerrainPropertiesPtr GetPropertiesFromFile(const CTerrainPropertiesPtr& props, const VfsPath& pathname);114 115 106 public: 116 107 // constructor, destructor 117 108 CTerrainTextureManager(); -
source/lib/file/vfs/vfs_util.cpp
56 56 } 57 57 58 58 59 Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags )59 Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags, DirCallback dircb, uintptr_t dircbData) 60 60 { 61 61 // (declare here to avoid reallocations) 62 62 CFileInfos files; … … 72 72 73 73 RETURN_STATUS_IF_ERR(fs->GetDirectoryEntries(path, &files, &subdirectoryNames)); 74 74 75 if(dircb) 76 RETURN_STATUS_IF_ERR(dircb(path, dircbData)); 77 75 78 for(size_t i = 0; i < files.size(); i++) 76 79 { 77 80 const CFileInfo fileInfo = files[i]; -
source/lib/file/vfs/vfs_util.h
48 48 **/ 49 49 typedef Status (*FileCallback)(const VfsPath& pathname, const CFileInfo& fileInfo, const uintptr_t cbData); 50 50 51 /** 52 * called for directories in a directory. 53 * 54 * @param pathname full pathname 55 * @param cbData user-specified context 56 * @return INFO::OK on success; any other value will immediately 57 * be returned to the caller (no more calls will be forthcoming). 58 * 59 * CAVEAT: pathname only valid until the function returns! 60 **/ 61 typedef Status (*DirCallback)(const VfsPath& pathname, const uintptr_t cbData); 62 51 63 enum DirFlags 52 64 { 53 65 DIR_RECURSIVE = 1 … … 63 75 * @param pattern that file names must match. '*' and '&' wildcards 64 76 * are allowed. 0 matches everything. 65 77 * @param flags @ref DirFlags 78 * @param dircb @ref DirCallback 79 * @param dircbData 66 80 * @return Status 67 81 **/ 68 extern Status ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const wchar_t* pattern = 0, size_t flags = 0 );82 extern Status ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const wchar_t* pattern = 0, size_t flags = 0, DirCallback dircb = NULL, uintptr_t dircbData = 0); 69 83 70 84 71 85 /**