Skip to content

Commit

Permalink
Refactor|libcore|FS: Added a Node base class for files
Browse files Browse the repository at this point in the history
filesys::Node is the base class for File. It stores the most basic
members: name and parent. It also has overridable logic for following
a path from a node.

This is only a minimal file system node class; at some point in the
future, the management of child nodes could be moved here from Folder.
  • Loading branch information
skyjake committed Jun 30, 2014
1 parent faf8173 commit 4634beb
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 124 deletions.
1 change: 1 addition & 0 deletions doomsday/libcore/include/de/filesys/Node
@@ -0,0 +1 @@
#include "node.h"
28 changes: 5 additions & 23 deletions doomsday/libcore/include/de/filesys/file.h
@@ -1,7 +1,7 @@
/*
* The Doomsday Engine Project -- libcore
*
* Copyright © 2009-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* Copyright © 2009-2014 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* LGPL: http://www.gnu.org/licenses/lgpl.html
Expand All @@ -26,7 +26,7 @@
#include "../Record"
#include "../AccessorValue"
#include "../Audience"
#include "../Lockable"
#include "../filesys/Node"

#include <QFlags>

Expand Down Expand Up @@ -77,7 +77,7 @@ class Feed;
* lock themselves as appropriate. A user may lock the file manually if long-term
* exclusive access is required.
*/
class DENG2_PUBLIC File : public Lockable, public IIOStream
class DENG2_PUBLIC File : public filesys::Node, public IIOStream
{
public:
// Mode flags.
Expand Down Expand Up @@ -201,8 +201,8 @@ class DENG2_PUBLIC File : public Lockable, public IIOStream
/// Returns a reference to the application's file system.
static FileSystem &fileSystem();

/// Returns the name of the file.
String name() const;
/// Returns the parent folder.
Folder *parent() const;

/**
* Returns a textual description of the file, intended only for humans.
Expand All @@ -222,16 +222,6 @@ class DENG2_PUBLIC File : public Lockable, public IIOStream
*/
virtual String describe() const;

/**
* Sets the parent folder of this file.
*/
void setParent(Folder *parent);

/**
* Returns the parent folder. May be NULL.
*/
Folder *parent() const;

/**
* Sets the origin Feed of the File. The origin feed is the feed that is able
* to singlehandedly decide whether the File needs to be pruned. Typically
Expand Down Expand Up @@ -298,14 +288,6 @@ class DENG2_PUBLIC File : public Lockable, public IIOStream
*/
dsize size() const;

/**
* Forms the complete path of this file object.
*
* @return Path of the object. This is not a native path, but instead
* intended for de::FileSystem.
*/
String const path() const;

/**
* Returns the mode of the file.
*/
Expand Down
14 changes: 5 additions & 9 deletions doomsday/libcore/include/de/filesys/folder.h
Expand Up @@ -230,15 +230,7 @@ class DENG2_PUBLIC Folder : public File
*/
virtual File *remove(File &file);

/**
* Locates a file in this folder or in one of its subfolders. Looks recursively
* through subfolders.
*
* @param path Path to look for. Relative to this folder.
*
* @return The located file, or @c NULL if the path was not found.
*/
virtual File *tryLocateFile(String const &path) const;
File *tryLocateFile(String const &path) const;

template <typename Type>
Type *tryLocate(String const &path) const {
Expand Down Expand Up @@ -305,6 +297,10 @@ class DENG2_PUBLIC Folder : public File

String contentsAsText() const;

// filesys::Node overrides:
Node const *tryFollowPath(PathRef const &path) const;
Node const *tryGetChild(String const &name) const;

private:
DENG2_PRIVATE(d)
};
Expand Down
105 changes: 105 additions & 0 deletions doomsday/libcore/include/de/filesys/node.h
@@ -0,0 +1,105 @@
/** @file filesys/node.h File system node.
*
* @authors Copyright (c) 2014 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* LGPL: http://www.gnu.org/licenses/lgpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef LIBDENG2_FILESYS_NODE_H
#define LIBDENG2_FILESYS_NODE_H

#include "../String"
#include "../Path"
#include "../Lockable"

namespace de {
namespace filesys {

/**
* File system node. Base class for a file.
* @ingroup fs
*
* @par Thread-safety
*
* All nodes are Lockable so that multiple threads can use them simultaneously. As a
* general rule, the user of a node does not need to lock the file manually; nodes will
* lock themselves as appropriate. A user may lock the node manually if long-term
* exclusive access is required.
*/
class Node : public Lockable
{
public:
virtual ~Node();

/// Returns the name of the file.
String name() const;

/**
* Sets the parent node of this file.
*/
void setParent(Node *parent);

/**
* Returns the parent node. May be NULL.
*/
Node *parent() const;

/**
* Forms the complete path of this node.
*
* @return Absolute path of the node.
*/
String const path() const;

/**
* Locates another node starting with a path from this node. The basic logic
* of interpreting the segments of a path in sequence is implemented here. Also,
* the special segments "." and ".." are handled by this method.
*
* @param path Relative path to look for. The path is followed starting from
* this node. Absolute paths are not supported.
*
* @return The located node, or @c NULL if the path was not found.
*/
virtual Node const *tryFollowPath(PathRef const &path) const;

/**
* Gets a child node with a specific name. The default implementation does nothing,
* because Node does not keep track of children, just the parent. Subclasses should
* override this if they have children.
*
* @param name Name of a node.
*
* @return The child node, or @c NULL if there is no child named @a name.
*/
virtual Node const *tryGetChild(String const &name) const;

DENG2_AS_IS_METHODS()

protected:
/**
* Constructs a new node.
*
* @param name Name of the node.
*/
explicit Node(String const &name = "");

private:
DENG2_PRIVATE(d)
};

} // namespace filesys
} // namespace de

#endif // LIBDENG2_FILESYS_NODE_H
45 changes: 7 additions & 38 deletions doomsday/libcore/src/filesys/file.cpp
@@ -1,7 +1,7 @@
/*
* The Doomsday Engine Project -- libcore
*
* Copyright © 2009-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* Copyright © 2009-2014 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* LGPL: http://www.gnu.org/licenses/lgpl.html
Expand Down Expand Up @@ -31,19 +31,13 @@ namespace de {

DENG2_PIMPL_NOREF(File)
{
/// The parent folder.
Folder *parent;

/// The source file (NULL for non-interpreted files).
File *source;

/// Feed that generated the file. This feed is called upon when the file needs
/// to be pruned. May also be NULL.
Feed *originFeed;

/// Name of the file.
String name;

/// Status of the file.
Status status;

Expand All @@ -53,17 +47,14 @@ DENG2_PIMPL_NOREF(File)
/// File information.
Record info;

Instance(String const &fileName)
: parent(0)
, originFeed(0)
, name(fileName) {}
Instance() : source(0), originFeed(0) {}

DENG2_PIMPL_AUDIENCE(Deletion)
};

DENG2_AUDIENCE_METHOD(File, Deletion)

File::File(String const &fileName) : d(new Instance(fileName))
File::File(String const &fileName) : Node(fileName), d(new Instance(this))
{
d->source = this;

Expand All @@ -88,10 +79,10 @@ File::~File()
delete d->source;
d->source = 0;
}
if(d->parent)
if(Folder *parentFolder = parent())
{
// Remove from parent folder.
d->parent->remove(this);
parentFolder->remove(this);
}
deindex();
}
Expand All @@ -114,9 +105,9 @@ FileSystem &File::fileSystem()
return DENG2_APP->fileSystem();
}

String File::name() const
Folder *File::parent() const
{
return d->name;
return Node::parent()->maybeAs<Folder>();
}

String File::description() const
Expand Down Expand Up @@ -178,16 +169,6 @@ String File::describe() const
return "abstract File";
}

void File::setParent(Folder *parent)
{
d->parent = parent;
}

Folder *File::parent() const
{
return d->parent;
}

void File::setOriginFeed(Feed *feed)
{
DENG2_GUARD(this);
Expand All @@ -199,18 +180,6 @@ Feed *File::originFeed() const
{
return d->originFeed;
}

String const File::path() const
{
DENG2_GUARD(this);

String thePath = name();
for(Folder *i = d->parent; i; i = i->File::d->parent)
{
thePath = i->name() / thePath;
}
return "/" + thePath;
}

void File::setSource(File *source)
{
Expand Down

0 comments on commit 4634beb

Please sign in to comment.