Skip to content

Commit

Permalink
Refactor CustomArchiveVisitor class a bit.
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Sep 12, 2017
1 parent 344d1a3 commit 08fa7cc
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 38 deletions.
71 changes: 41 additions & 30 deletions include/iarchive.h
Expand Up @@ -122,42 +122,53 @@ class Archive
/// Name comparisons are case-insensitive.
virtual bool containsFile(const std::string& name) = 0;

/// \brief Performs a depth-first traversal of the archive tree starting at \p root.
/// Traverses the entire tree if \p root is "".
/// When a file is encountered, calls \c visitor.file passing the file name.
/// When a directory is encountered, calls \c visitor.directory passing the directory name.
/// Skips the directory if \c visitor.directory returned true.
/// Root comparisons are case-insensitive.
/// Names are mixed-case.
virtual void forEachFile(VisitorFunc visitor, const std::string& root) = 0;
/// \brief Performs a depth-first traversal of the archive tree starting at \p root.
/// Traverses the entire tree if \p root is "".
/// When a file is encountered, calls \c visitor.file passing the file name.
/// When a directory is encountered, calls \c visitor.directory passing the directory name.
/// Skips the directory if \c visitor.directory returned true.
/// Root comparisons are case-insensitive.
/// Names are mixed-case.
virtual void forEachFile(VisitorFunc visitor, const std::string& root) = 0;
};
typedef std::shared_ptr<Archive> ArchivePtr;

class CustomArchiveVisitor
{
Archive::Visitor* m_visitor;
Archive::EMode m_mode;
std::size_t m_depth;
private:
std::function<void(const std::string&)> _visitorFunc;
Archive::EMode _mode;
std::size_t _depth;

public:
CustomArchiveVisitor(Archive::Visitor& visitor, Archive::EMode mode, std::size_t depth)
: m_visitor(&visitor), m_mode(mode), m_depth(depth)
{
}
void file(const std::string& name)
{
if((m_mode & Archive::eFiles) != 0)
m_visitor->visit(name);
}
bool directory(const std::string& name, std::size_t depth)
{
if ((m_mode & Archive::eDirectories) != 0) {
m_visitor->visit(name);
}
if (depth == m_depth) {
return true;
}
return false;
}
CustomArchiveVisitor(const std::function<void(const std::string&)>& func, Archive::EMode mode, std::size_t depth) :
_visitorFunc(func),
_mode(mode),
_depth(depth)
{}

void visitFile(const std::string& name)
{
if ((_mode & Archive::eFiles) != 0)
{
_visitorFunc(name);
}
}

bool visitDirectory(const std::string& name, std::size_t depth)
{
if ((_mode & Archive::eDirectories) != 0)
{
_visitorFunc(name);
}

if (depth == _depth)
{
return true;
}

return false;
}
};

const std::string MODULE_ARCHIVE("Archive");
Expand Down
4 changes: 2 additions & 2 deletions plugins/archivezip/GenericFileSystem.h
Expand Up @@ -180,9 +180,9 @@ class GenericFileSystem
{
if (!i->second.isDirectory())
{
visitor.file(i->first.string());
visitor.visitFile(i->first.string());
}
else if (visitor.directory(i->first.string(), i->first.depth() - start_depth))
else if (visitor.visitDirectory(i->first.string(), i->first.depth() - start_depth))
{
skip_depth = i->first.depth();
}
Expand Down
4 changes: 2 additions & 2 deletions plugins/vfspk3/DirectoryArchive.cpp
Expand Up @@ -77,7 +77,7 @@ void DirectoryArchive::forEachFile(VisitorFunc visitor, const std::string& root)
if (fs::is_directory(candidate))
{
// Check if we should traverse further
if (visitor.directory(candidateStr.substr(rootLen), os::getDepth(it)+1))
if (visitor.visitDirectory(candidateStr.substr(rootLen), os::getDepth(it)+1))
{
// Visitor returned true, prevent going deeper into it
os::disableRecursionPending(it);
Expand All @@ -86,7 +86,7 @@ void DirectoryArchive::forEachFile(VisitorFunc visitor, const std::string& root)
else
{
// File
visitor.file(candidateStr.substr(rootLen));
visitor.visitFile(candidateStr.substr(rootLen));
}
}
}
10 changes: 6 additions & 4 deletions plugins/vfspk3/Doom3FileSystem.cpp
Expand Up @@ -233,13 +233,14 @@ void Doom3FileSystem::forEachFile(const std::string& basedir,
std::set<std::string> visitedFiles;

// Wrap around the passed visitor
FileVisitor visitor2(visitorFunc, basedir, extension, visitedFiles);
FileVisitor fileVisitor(visitorFunc, basedir, extension, visitedFiles);
Archive::VisitorFunc functor(std::bind(&FileVisitor::visit, fileVisitor, std::placeholders::_1), Archive::eFiles, depth);

// Visit each Archive, applying the FileVisitor to each one (which in
// turn calls the callback for each matching file.
for (const ArchiveDescriptor& descriptor : _archives)
{
descriptor.archive->forEachFile(Archive::VisitorFunc(visitor2, Archive::eFiles, depth), basedir);
descriptor.archive->forEachFile(functor, basedir);
}
}

Expand All @@ -254,9 +255,10 @@ void Doom3FileSystem::forEachFileInAbsolutePath(const std::string& path,
DirectoryArchive tempArchive(os::standardPathWithSlash(path));

// Wrap around the passed visitor
FileVisitor visitor2(visitorFunc, "", extension, visitedFiles);
FileVisitor fileVisitor(visitorFunc, "", extension, visitedFiles);
Archive::VisitorFunc functor(std::bind(&FileVisitor::visit, fileVisitor, std::placeholders::_1), Archive::eFiles, depth);

tempArchive.forEachFile(Archive::VisitorFunc(visitor2, Archive::eFiles, depth), "/");
tempArchive.forEachFile(functor, "/");
}

std::string Doom3FileSystem::findFile(const std::string& name)
Expand Down

0 comments on commit 08fa7cc

Please sign in to comment.