1
0
forked from 0ad/0ad

add VirtualPath API to VFS in preparation for moving hotload logic out of library code and into the game. also rename GetRealPath -> RealPath + some cleanup/documentation

This was SVN commit r7169.
This commit is contained in:
janwas 2009-11-06 01:30:16 +00:00
parent 8fefedb5ae
commit 25717ef768
4 changed files with 68 additions and 23 deletions

View File

@ -239,7 +239,7 @@ VfsPath CColladaManager::GetLoadableFilename(const VfsPath& pathnameNoExtension,
// realDaePath_ is "[..]/mods/whatever/art/meshes/whatever.dae"
fs::wpath realDaePath_;
LibError ret = g_VFS->GetRealPath(dae, realDaePath_);
LibError ret = g_VFS->RealPath(dae, realDaePath_);
debug_assert(ret == INFO::OK);
wchar_t realDaeBuf[PATH_MAX];
wcscpy_s(realDaeBuf, ARRAY_SIZE(realDaeBuf), realDaePath_.string().c_str());

View File

@ -45,7 +45,7 @@ public:
virtual LibError Mount(const VfsPath& mountPoint, const fs::wpath& path, size_t flags /* = 0 */, size_t priority /* = 0 */)
{
CreateDirectories(path, 0700);
RETURN_ERR(CreateDirectories(path, 0700));
VfsDirectory* directory;
CHECK_ERR(vfs_Lookup(mountPoint, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_CREATE));
@ -103,13 +103,13 @@ public:
const std::wstring& name = pathname.leaf();
RETURN_ERR(realDirectory->Store(name, fileContents, size));
const VfsFile file(name, size, time(0), realDirectory->Priority(), realDirectory);
directory->AddFile(file);
// wipe out any cached blocks. this is necessary to cover the (rare) case
// of file cache contents predating the file write.
m_fileCache.Remove(pathname);
const VfsFile file(name, size, time(0), realDirectory->Priority(), realDirectory);
directory->AddFile(file);
m_trace->NotifyStore(pathname.string().c_str(), size);
return INFO::OK;
}
@ -146,11 +146,6 @@ public:
return INFO::OK;
}
virtual void Clear()
{
m_rootDirectory.Clear();
}
virtual std::wstring TextRepresentation() const
{
std::wstring textRepresentation;
@ -159,12 +154,20 @@ public:
return textRepresentation;
}
virtual LibError GetRealPath(const VfsPath& pathname, fs::wpath& realPathname)
virtual LibError RealPath(const VfsPath& pathname, fs::wpath& realPathname)
{
VfsDirectory* directory;
CHECK_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0));
const PRealDirectory& realDirectory = directory->AssociatedDirectory();
realPathname = realDirectory->Path() / pathname.leaf();
realPathname = directory->AssociatedDirectory()->Path() / pathname.leaf();
return INFO::OK;
}
virtual LibError VirtualPath(const fs::wpath& realPathname, VfsPath& pathname)
{
const fs::wpath realPath = AddSlash(realPathname.branch_path());
VfsPath path;
RETURN_ERR(FindRealPathR(realPathname, m_rootDirectory, L"", path));
pathname = path / realPathname.leaf();
return INFO::OK;
}
@ -181,6 +184,11 @@ public:
return INFO::OK;
}
virtual void Clear()
{
m_rootDirectory.Clear();
}
private:
// try to skip unnecessary work by ignoring uninteresting notifications.
static bool CanIgnore(const DirWatchNotification& notification)
@ -203,6 +211,29 @@ private:
return false;
}
LibError FindRealPathR(const fs::wpath& realPath, const VfsDirectory& directory, const VfsPath& curPath, VfsPath& path)
{
PRealDirectory realDirectory = directory.AssociatedDirectory();
if(realDirectory && realDirectory->Path() == realPath)
{
path = curPath;
return INFO::OK;
}
const VfsDirectory::VfsSubdirectories& subdirectories = directory.Subdirectories();
for(VfsDirectory::VfsSubdirectories::const_iterator it = subdirectories.begin(); it != subdirectories.end(); ++it)
{
const std::wstring& subdirectoryName = it->first;
const VfsDirectory& subdirectory = it->second;
LibError ret = FindRealPathR(realPath, subdirectory, AddSlash(path/subdirectoryName), path);
if(ret == INFO::OK)
return INFO::OK;
}
return ERR::PATH_NOT_FOUND; // NOWARN
}
LibError NotifyChangedR(VfsDirectory& directory, const VfsPath& path, const fs::wpath& realPathname)
{
const fs::wpath realPath = AddSlash(realPathname.branch_path());

View File

@ -70,6 +70,9 @@ struct IVFS
/**
* retrieve information about a file (similar to POSIX stat)
*
* @param pfileInfo receives information about the file. passing NULL
* suppresses warnings if the file doesn't exist.
*
* @return LibError.
**/
@ -113,24 +116,27 @@ struct IVFS
virtual LibError LoadFile(const VfsPath& pathname, shared_ptr<u8>& fileContents, size_t& size) = 0;
/**
* @return a text representation of all files and directories.
* @return a string representation of all files and directories.
**/
virtual std::wstring TextRepresentation() const = 0;
/**
* empty the contents of the filesystem.
* this is typically only necessary when changing the set of
* mounted directories, e.g. when switching mods.
* NB: open files are not affected.
* retrieve the real (POSIX) pathname underlying a VFS file.
*
* this is useful for passing paths to external libraries.
**/
virtual void Clear() = 0;
virtual LibError RealPath(const VfsPath& pathname, fs::wpath& realPathname) = 0;
/**
* retrieve the real (POSIX) path underlying a VFS file.
* retrieve the VFS pathname that corresponds to a real file.
*
* this is useful when passing paths to external libraries.
* this is useful for reacting to file change notifications.
*
* the current implementation requires time proportional to the
* number of directories; this could be accelerated by only checking
* directories below a mount point with a matching real path.
**/
virtual LibError GetRealPath(const VfsPath& pathname, fs::wpath& path) = 0;
virtual LibError VirtualPath(const fs::wpath& realPathname, VfsPath& pathname) = 0;
/**
* poll for directory change notifications and reload all affected files.
@ -139,6 +145,14 @@ struct IVFS
* note: polling is much simpler than asynchronous notifications.
**/
virtual LibError ReloadChangedFiles() = 0;
/**
* empty the contents of the filesystem.
* this is typically only necessary when changing the set of
* mounted directories, e.g. when switching mods.
* NB: open files are not affected.
**/
virtual void Clear() = 0;
};
typedef shared_ptr<IVFS> PIVFS;

View File

@ -75,7 +75,7 @@ void CXeromyces::GetXMBPath(const PIVFS& vfs, const VfsPath& xmlFilename, const
// get real path of XML file (e.g. mods/official/entities/...)
fs::wpath XMBRealPath_;
vfs->GetRealPath(xmlFilename, XMBRealPath_);
vfs->RealPath(xmlFilename, XMBRealPath_);
wchar_t XMBRealPath[PATH_MAX];
wcscpy_s(XMBRealPath, ARRAY_SIZE(XMBRealPath), XMBRealPath_.string().c_str());