Skip to content

Commit

Permalink
libdeng2|FileSystem: Creating subfolder when parent has multiple feeds
Browse files Browse the repository at this point in the history
When inheriting feeds, find the first one that actually returns a
valid sub-feed (i.e., the subfolder must exist in the context of
the parent folder's feed).

Also added a flag that disables the automatic population of new folders,
useful internally for folders created during the population process.
  • Loading branch information
skyjake committed May 4, 2013
1 parent 96ad320 commit 00a8734
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 16 deletions.
20 changes: 15 additions & 5 deletions doomsday/libdeng2/include/de/filesys/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "../Folder"
#include "../System"

#include <QFlags>
#include <map>

/**
Expand Down Expand Up @@ -127,18 +128,25 @@ class DENG2_PUBLIC FileSystem : public System
void refresh();

enum FolderCreationBehavior {
DontInheritFeeds, ///< Subfolder will not have any feeds created for them.
InheritPrimaryFeed, ///< Subfolder will inherit the primary (first) feed of its parent.
InheritAllFeeds ///< Subfolder will inherit all feeds of its parent.
DontInheritFeeds = 0, ///< Subfolder will not have any feeds created for them.
InheritPrimaryFeed = 0x1, ///< Subfolder will inherit the primary (first) feed of its parent.
InheritAllFeeds = 0x2, ///< Subfolder will inherit all feeds of its parent.
PopulateNewFolder = 0x4, ///< Populate new folder automatically.

InheritPrimaryFeedAndPopulate = InheritPrimaryFeed | PopulateNewFolder
};
Q_DECLARE_FLAGS(FolderCreationBehaviors, FolderCreationBehavior)

/**
* Retrieves a folder in the file system. The folder gets created if it
* does not exist. Any missing parent folders will also be created.
*
* @param path Path of the folder. Relative to the root folder.
* @param path Path of the folder. Relative to the root folder.
* @param behavior What to do with the new folder: automatically attach feeds and
* maybe also populate it automatically.
*/
Folder &makeFolder(String const &path, FolderCreationBehavior behavior = InheritPrimaryFeed);
Folder &makeFolder(String const &path,
FolderCreationBehaviors behavior = InheritPrimaryFeedAndPopulate);

/**
* Finds all files matching a full or partial path. The search is done
Expand Down Expand Up @@ -249,6 +257,8 @@ class DENG2_PUBLIC FileSystem : public System
DENG2_PRIVATE(d)
};

Q_DECLARE_OPERATORS_FOR_FLAGS(FileSystem::FolderCreationBehaviors)

// Alias.
typedef FileSystem FS;

Expand Down
10 changes: 9 additions & 1 deletion doomsday/libdeng2/include/de/filesys/folder.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,18 @@ class DENG2_PUBLIC Folder : public File
*
* @param feed Feed to detach from the folder.
*
* @return The Feed object. Ownership is returned to the caller.
* @return Feed instance. Ownership is returned to the caller.
*/
Feed *detach(Feed &feed);

/**
* Makes the specified feed the primary one.
*
* @param feed Feed instance to make the primary feed. Must already be
* attached to the Folder.
*/
void setPrimaryFeed(Feed &feed);

/**
* Provides access to the list of Feeds for this folder. The feeds are responsible
* for creating File and Folder instances in the folder.
Expand Down
2 changes: 2 additions & 0 deletions doomsday/libdeng2/include/de/filesys/nativepath.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ class DENG2_PUBLIC NativePath : public Path

bool exists() const;

bool isReadable() const;

/**
* Returns the current native working path.
*/
Expand Down
2 changes: 1 addition & 1 deletion doomsday/libdeng2/src/filesys/archivefeed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ DENG2_PIMPL(ArchiveFeed)

for(Archive::Names::iterator i = names.begin(); i != names.end(); ++i)
{
folder.fileSystem().makeFolder(folder.path() / *i);
folder.fileSystem().makeFolder(folder.path() / *i, FS::InheritPrimaryFeed);
}
}
};
Expand Down
10 changes: 8 additions & 2 deletions doomsday/libdeng2/src/filesys/directoryfeed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ void DirectoryFeed::populateSubFolder(Folder &folder, String const &entryName)

if(entryName != "." && entryName != "..")
{
Folder &subFolder = folder.fileSystem().makeFolder(folder.path() / entryName);
Folder &subFolder = folder.fileSystem()
.makeFolder(folder.path() / entryName, FS::InheritPrimaryFeed);

if(_mode & AllowWrite)
{
Expand Down Expand Up @@ -201,7 +202,12 @@ void DirectoryFeed::removeFile(String const &name)

Feed *DirectoryFeed::newSubFeed(String const &name)
{
return new DirectoryFeed(_nativePath / name, _mode);
NativePath subPath = _nativePath / name;
if(subPath.exists() && subPath.isReadable())
{
return new DirectoryFeed(subPath, _mode);
}
return 0;
}

void DirectoryFeed::changeWorkingDir(NativePath const &nativePath)
Expand Down
21 changes: 14 additions & 7 deletions doomsday/libdeng2/src/filesys/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ void FileSystem::refresh()
printIndex();
}

Folder &FileSystem::makeFolder(String const &path, FolderCreationBehavior behavior)
Folder &FileSystem::makeFolder(String const &path, FolderCreationBehaviors behavior)
{
LOG_AS("FS::makeFolder");

Folder *subFolder = d->root.tryLocate<Folder>(path);
if(!subFolder)
{
// This folder does not exist yet. Let's create it.
Folder &parentFolder = makeFolder(path.fileNamePath());
Folder &parentFolder = makeFolder(path.fileNamePath(), behavior);
subFolder = new Folder(path.fileName());

// If parent folder is writable, this will be too.
Expand All @@ -80,24 +80,31 @@ Folder &FileSystem::makeFolder(String const &path, FolderCreationBehavior behavi
}

// Inherit parent's feeds?
if(behavior != DontInheritFeeds)
if(behavior & (InheritPrimaryFeed | InheritAllFeeds))
{
DENG2_GUARD(parentFolder);
DENG2_FOR_EACH_CONST(Folder::Feeds, i, parentFolder.feeds())
{
LOG_DEV_TRACE("Creating subfeed \"%s\" from %s",
subFolder->name() << (*i)->description());

subFolder->attach((*i)->newSubFeed(subFolder->name()));
if(behavior == InheritPrimaryFeed) break;
Feed *feed = (*i)->newSubFeed(subFolder->name());
if(!feed) continue; // Check next one instead.

subFolder->attach(feed);

if(!behavior.testFlag(InheritAllFeeds)) break;
}
}

parentFolder.add(subFolder);
index(*subFolder);

// Populate the new folder.
subFolder->populate();
if(behavior.testFlag(PopulateNewFolder))
{
// Populate the new folder.
subFolder->populate();
}
}
return *subFolder;
}
Expand Down
8 changes: 8 additions & 0 deletions doomsday/libdeng2/src/filesys/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,14 @@ Feed *Folder::detach(Feed &feed)
return &feed;
}

void Folder::setPrimaryFeed(Feed &feed)
{
DENG2_GUARD(this);

_feeds.remove(&feed);
_feeds.push_front(&feed);
}

Folder::Accessor::Accessor(Folder &owner, Property prop) : _owner(owner), _prop(prop)
{}

Expand Down
5 changes: 5 additions & 0 deletions doomsday/libdeng2/src/filesys/nativepath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ bool NativePath::exists() const
return QFile::exists(toString());
}

bool NativePath::isReadable() const
{
return QFileInfo(toString()).isReadable();
}

static NativePath currentNativeWorkPath;

NativePath NativePath::workPath()
Expand Down

0 comments on commit 00a8734

Please sign in to comment.