Ticket #3358: terraintexturemanager_file_loading.patch

File terraintexturemanager_file_loading.patch, 6.7 KB (added by leper, 9 years ago)
  • source/graphics/TerrainTextureManager.cpp

     
    8282    return 0;
    8383}
    8484
    85 CTerrainPropertiesPtr CTerrainTextureManager::GetPropertiesFromFile(const CTerrainPropertiesPtr& props, const VfsPath& pathname)
    86 {
    87     return CTerrainProperties::FromXML(props, pathname);
    88 }
    89 
    9085CTerrainTextureEntry* CTerrainTextureManager::AddTexture(const CTerrainPropertiesPtr& props, const VfsPath& path)
    9186{
    9287    CTerrainTextureEntry* entry = new CTerrainTextureEntry(props, path);
     
    10398    delete entry;
    10499}
    105100
    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)
     101struct AddTextureCallbackData
    113102{
    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};
    129106
    130 void CTerrainTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& parentProps, const VfsPath& path)
     107static Status AddTextureDirCallback(const VfsPath& pathname, const uintptr_t cbData)
    131108{
    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);
    135115
    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}
    147118
    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     }
     119static 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);
    156124
    157     LoadTextures(props, path);
     125    return INFO::OK;
    158126}
    159127
    160128int CTerrainTextureManager::LoadTerrainTextures()
    161129{
    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);
    164132    return 0;
    165133}
    166134
  • source/graphics/TerrainTextureManager.h

     
    103103
    104104    size_t m_LastGroupIndex;
    105105
    106     // Find+load all textures in directory; check if
    107     // 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 
    115106public:
    116107    // constructor, destructor
    117108    CTerrainTextureManager();
  • source/lib/file/vfs/vfs_util.cpp

     
    5656}
    5757
    5858
    59 Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags)
     59Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags, DirCallback dircb, uintptr_t dircbData)
    6060{
    6161    // (declare here to avoid reallocations)
    6262    CFileInfos files;
     
    7272
    7373        RETURN_STATUS_IF_ERR(fs->GetDirectoryEntries(path, &files, &subdirectoryNames));
    7474
     75        if(dircb)
     76            RETURN_STATUS_IF_ERR(dircb(path, dircbData));
     77
    7578        for(size_t i = 0; i < files.size(); i++)
    7679        {
    7780            const CFileInfo fileInfo = files[i];
  • source/lib/file/vfs/vfs_util.h

     
    4848 **/
    4949typedef Status (*FileCallback)(const VfsPath& pathname, const CFileInfo& fileInfo, const uintptr_t cbData);
    5050
     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 **/
     61typedef Status (*DirCallback)(const VfsPath& pathname, const uintptr_t cbData);
     62
    5163enum DirFlags
    5264{
    5365    DIR_RECURSIVE = 1
     
    6375 * @param pattern that file names must match. '*' and '&' wildcards
    6476 *        are allowed. 0 matches everything.
    6577 * @param flags @ref DirFlags
     78 * @param dircb @ref DirCallback
     79 * @param dircbData
    6680 * @return Status
    6781 **/
    68 extern Status ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const wchar_t* pattern = 0, size_t flags = 0);
     82extern 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);
    6983
    7084
    7185/**