Added the new AbstractFilesystemNode::getCurrentDirectory() method. Also changed the semantics of the FilesystemNode constructors (see also the relevant doxygen comments for explanations). This also fixes bug #1485941.

svn-id: r22424
This commit is contained in:
Max Horn 2006-05-12 21:41:54 +00:00
parent ed339aa771
commit 3623a94927
14 changed files with 111 additions and 43 deletions

View File

@ -70,6 +70,15 @@ protected:
*/
static AbstractFilesystemNode *getRoot();
/**
* Returns a node representing the "current directory". If your system does
* not support this concept, you can either try to emulate it or
* simply return some "sensible" default directory node, e.g. the same
* value as getRoot() returns.
*/
static AbstractFilesystemNode *getCurrentDirectory();
/**
* Construct a node based on a path; the path is in the same format as it
* would be for calls to fopen().
@ -92,6 +101,11 @@ public:
virtual String displayName() const = 0;
virtual bool isDirectory() const = 0;
/**
* Return the 'path' of the current node, usable in fopen(). See also
* the static getNodeForPath() method.
*/
virtual String path() const = 0;
virtual bool listDir(AbstractFSList &list, ListMode mode) const = 0;

View File

@ -70,11 +70,15 @@ class AmigaOSFilesystemNode : public AbstractFilesystemNode {
virtual String path() const { return _sPath; };
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
virtual AbstractFSList listVolumes(void) const;
virtual AbstractFSList listVolumes() const;
virtual AbstractFilesystemNode *parent() const;
virtual AbstractFilesystemNode *child(const String &name) const;
};
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
return new AmigaOSFilesystemNode();
}
@ -333,7 +337,7 @@ AbstractFilesystemNode *AmigaOSFilesystemNode::child(const String &name) const {
return new AmigaOSFilesystemNode(newPath);
}
AbstractFSList AmigaOSFilesystemNode::listVolumes(void) const {
AbstractFSList AmigaOSFilesystemNode::listVolumes() const {
ENTER();
AbstractFSList myList;

View File

@ -26,33 +26,28 @@
#include "common/util.h"
static AbstractFilesystemNode *_rootNode = 0;
static int *_rootRefCount = 0;
FilesystemNode::FilesystemNode(AbstractFilesystemNode *realNode) {
_realNode = realNode;
_refCount = new int(1);
}
FilesystemNode::FilesystemNode() {
if (_rootNode == 0) {
_rootNode = AbstractFilesystemNode::getRoot();
assert(_rootNode);
_rootRefCount = new int(1);
}
_realNode = _rootNode;
_refCount = _rootRefCount;
++(*_refCount);
_realNode = 0;
_refCount = 0;
}
FilesystemNode::FilesystemNode(const FilesystemNode &node) {
_realNode = node._realNode;
_refCount = node._refCount;
++(*_refCount);
if (_refCount)
++(*_refCount);
}
FilesystemNode::FilesystemNode(const Common::String &p) {
_realNode = AbstractFilesystemNode::getNodeForPath(p);
if (p.empty() || p == ".")
_realNode = AbstractFilesystemNode::getCurrentDirectory();
else
_realNode = AbstractFilesystemNode::getNodeForPath(p);
_refCount = new int(1);
}
@ -61,16 +56,19 @@ FilesystemNode::~FilesystemNode() {
}
void FilesystemNode::decRefCount() {
assert(*_refCount > 0);
--(*_refCount);
if (*_refCount == 0) {
delete _refCount;
delete _realNode;
if (_refCount) {
assert(*_refCount > 0);
--(*_refCount);
if (*_refCount == 0) {
delete _refCount;
delete _realNode;
}
}
}
FilesystemNode &FilesystemNode::operator =(const FilesystemNode &node) {
++(*node._refCount);
if (node._refCount)
++(*node._refCount);
decRefCount();

View File

@ -78,18 +78,37 @@ public:
kListAll = 3
};
/**
* Create a new invalid FilesystemNode. In other words, isValid() for that
* node returns false, and if you try to get it's path, an assert is
* triggered.
*/
FilesystemNode();
/**
* Create a new FilesystemNode referring to the specified path. This is
* the counterpart to the path() method.
*
* If path is empty or equals ".", then a node representing the "current
* directory" will be created. If that is not possible (since e.g. the
* operating system doesn't support the concept), some other directory is
* used (usually the root directory).
*/
FilesystemNode(const String &path);
FilesystemNode();
/**
* Copy constructor.
*/
FilesystemNode(const FilesystemNode &node);
/**
* Destructor.
*/
virtual ~FilesystemNode();
/**
* Copy operator.
*/
FilesystemNode &operator =(const FilesystemNode &node);
/**

View File

@ -58,6 +58,10 @@ class ABoxFilesystemNode : public AbstractFilesystemNode {
};
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot()
{
return new ABoxFilesystemNode();

View File

@ -78,6 +78,10 @@ void PalmOSFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const ch
list.push_back(new PalmOSFilesystemNode(entry));
}
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
return new PalmOSFilesystemNode();
}

View File

@ -50,7 +50,7 @@ protected:
public:
POSIXFilesystemNode();
POSIXFilesystemNode(const String &path, bool verify = false);
POSIXFilesystemNode(const String &path, bool verify);
virtual String displayName() const { return _displayName; }
virtual bool isValid() const { return _isValid; }
@ -74,6 +74,12 @@ static const char *lastPathComponent(const Common::String &str) {
return cur + 1;
}
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
char buf[MAXPATHLEN];
getcwd(buf, MAXPATHLEN);
return new POSIXFilesystemNode(buf, true);
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
return new POSIXFilesystemNode();
}
@ -156,7 +162,7 @@ bool POSIXFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const {
newPath += '/';
newPath += dp->d_name;
POSIXFilesystemNode entry(newPath);
POSIXFilesystemNode entry(newPath, false);
#ifdef __DC__
entry._isDirectory = dp->d_size < 0;
@ -212,7 +218,7 @@ AbstractFilesystemNode *POSIXFilesystemNode::parent() const {
const char *start = _path.c_str();
const char *end = lastPathComponent(_path);
POSIXFilesystemNode *p = new POSIXFilesystemNode(String(start, end - start));
POSIXFilesystemNode *p = new POSIXFilesystemNode(String(start, end - start), false);
return p;
}

View File

@ -37,7 +37,7 @@ protected:
String _path;
public:
Ps2FilesystemNode(void);
Ps2FilesystemNode();
Ps2FilesystemNode(const String &path);
virtual String displayName() const { return _displayName; }
@ -52,7 +52,11 @@ public:
virtual AbstractFilesystemNode *clone() const { return new Ps2FilesystemNode(this); }
};
AbstractFilesystemNode *AbstractFilesystemNode::getRoot(void) {
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
return new Ps2FilesystemNode();
}
@ -60,7 +64,7 @@ AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &pat
return new Ps2FilesystemNode(path);
}
Ps2FilesystemNode::Ps2FilesystemNode(void) {
Ps2FilesystemNode::Ps2FilesystemNode() {
_isDirectory = true;
_isRoot = true;
_displayName = "CD Root";

View File

@ -69,6 +69,10 @@ static const char *lastPathComponent(const Common::String &str) {
return cur + 1;
}
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
return new SymbianFilesystemNode(true);
}

View File

@ -120,6 +120,10 @@ void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const c
list.push_back(new WindowsFilesystemNode(entry));
}
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
return new WindowsFilesystemNode();
}

View File

@ -36,7 +36,7 @@ protected:
String _path;
public:
GP32FilesystemNode(void);
GP32FilesystemNode();
GP32FilesystemNode(const String &path);
virtual String displayName() const { return _displayName; }
@ -48,15 +48,19 @@ public:
virtual AbstractFilesystemNode *parent() const;
};
AbstractFilesystemNode *FilesystemNode::getRoot(void) {
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
return new GP32FilesystemNode();
}
AbstractFilesystemNode *FilesystemNode::getNodeForPath(const String &path) {
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
return new GP32FilesystemNode(path);
}
GP32FilesystemNode::GP32FilesystemNode(void) {
GP32FilesystemNode::GP32FilesystemNode() {
_isDirectory = true;
_isRoot = true;
_displayName = "GP32 Root";

View File

@ -55,7 +55,11 @@ public:
virtual AbstractFilesystemNode *parent() const;
};
AbstractFilesystemNode *FilesystemNode::getRoot() {
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() {
return new PSPFilesystemNode();
}
@ -76,7 +80,7 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p)
}
AbstractFilesystemNode *FilesystemNode::getNodeForPath(const String &path)
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path)
{
return new PSPFilesystemNode(path);
}

View File

@ -164,11 +164,15 @@ static const Plugin *detectMain() {
return 0;
}
// FIXME: Do we really need this one?
printf("Trying to start game '%s'\n", game.description.c_str());
return plugin;
}
static int runGame(const Plugin *plugin, OSystem &system, const Common::String &edebuglevels) {
Common::String gameDataPath(ConfMan.get("path"));
if (gameDataPath.empty()) {
warning("No path was provided. Assuming the data files are in the current directory");
} else if (gameDataPath.lastChar() != '/'
#if defined(__MORPHOS__) || defined(__amigaos4__)
&& gameDataPath.lastChar() != ':'
@ -178,10 +182,6 @@ static const Plugin *detectMain() {
ConfMan.set("path", gameDataPath, Common::ConfigManager::kTransientDomain);
}
return plugin;
}
static int runGame(const Plugin *plugin, OSystem &system, const Common::String &edebuglevels) {
// We add it here, so MD5-based detection will be able to
// read mixed case files
if (ConfMan.hasKey("path")) {
@ -193,6 +193,7 @@ static int runGame(const Plugin *plugin, OSystem &system, const Common::String &
}
Common::File::addDefaultDirectory(path);
} else {
warning("No path was provided. Assuming the data files are in the current directory");
Common::File::addDefaultDirectory(".");
}

View File

@ -1330,9 +1330,7 @@ PluginError Engine_SCUMM_create(OSystem *syst, Engine **engine) {
FSList fslist;
FilesystemNode dir;
if (ConfMan.hasKey("path") )
dir = FilesystemNode(ConfMan.get("path"));
FilesystemNode dir(ConfMan.get("path"));
if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) {
warning("ScummEngine: invalid game path '%s'", dir.path().c_str());
return kInvalidPathError;