diff options
Diffstat (limited to 'src/filesystem')
-rw-r--r-- | src/filesystem/diskfile.cc | 44 | ||||
-rw-r--r-- | src/filesystem/filesystem.cc | 145 | ||||
-rw-r--r-- | src/filesystem/filesystem.h | 26 |
3 files changed, 139 insertions, 76 deletions
diff --git a/src/filesystem/diskfile.cc b/src/filesystem/diskfile.cc index a01a327..56e2727 100644 --- a/src/filesystem/diskfile.cc +++ b/src/filesystem/diskfile.cc @@ -4,6 +4,7 @@ the terms of the GNU General Public License version 2 */ +#include "filesystem/filesystem.h" #include "filesystem/diskfile.h" namespace filesystem { @@ -27,46 +28,19 @@ bool DiskFile::open(const char *filename) } file_name.assign(filename); - std::string fn; - - // if moddir is set, try the mods subdir first - if (moddir.size()) { - // try homedir + moddir - file_path = homedir; - file_path.append(moddir); - fn = file_path; - fn.append(filename); - diskfile_handle = fopen(fn.c_str(), "rb"); - if (diskfile_handle) - return true; + file_path.clear(); - // try datadir + moddir - file_path = datadir; - file_path.append(moddir); - fn = file_path; + for (SearchPath::iterator path = searchpath().begin(); path != searchpath().end(); path++) { + std::string fn((*path)); fn.append(filename); + diskfile_handle = fopen(fn.c_str(), "rb"); - if (diskfile_handle) + if (diskfile_handle) { + file_path.assign((*path)); return true; - } - // try homedir + basedir - file_path = homedir; - file_path.append(basedir); - fn = file_path; - fn.append(filename); - diskfile_handle = fopen(fn.c_str(), "rb"); - if (diskfile_handle) - return true; + } + } - // try datadir + basedir - file_path = datadir; - file_path.append(basedir); - fn = file_path; - fn.append(filename); - diskfile_handle = fopen(fn.c_str(), "rb"); - if (diskfile_handle) - return true; - //con_error << "Could not open " << filename << std::endl; return false; } diff --git a/src/filesystem/filesystem.cc b/src/filesystem/filesystem.cc index dd694ee..1cb13e9 100644 --- a/src/filesystem/filesystem.cc +++ b/src/filesystem/filesystem.cc @@ -5,6 +5,7 @@ */ // project headers +#include <list> #include "filesystem/filesystem.h" #include "filesystem/diskfile.h" @@ -14,49 +15,139 @@ namespace filesystem { -std::string datadir = ""; -std::string homedir = ""; -std::string basedir = ""; -std::string moddir = ""; -std::string writedir = ""; +SearchPath filesystem_searchpath; +std::string filesystem_basename; +std::string filesystem_modname; -void init() +std::string filesystem_homedir; +std::string filesystem_writedir; +std::string filesystem_datadir; + +std::string const & writedir() { - con_print << "^BInitializing filesystem..." << std::endl; + return filesystem_writedir; +} - // initialize game data locations - // FIXME datadir should by set by ./configure and read from config.h - datadir = "./data/"; +std::string const & homedir() +{ + return filesystem_homedir; +} - // FIXME a local or remote game module must be able to set these - basedir = "base/"; - moddir = ""; +SearchPath & searchpath() +{ + return filesystem_searchpath; +} +void init(std::string const & basename, std::string const & modname) +{ + con_print << "^BInitializing filesystem..." << std::endl; + + // clear everything + filesystem_searchpath.clear(); + filesystem_basename.assign(basename); + if (!filesystem_basename.size()) + filesystem_basename.assign("base"); + + filesystem_modname.assign(modname); #ifndef _WIN32 - homedir = getenv("HOME"); - homedir = homedir + "/.osirion/"; + filesystem_homedir.assign(getenv("HOME")); + filesystem_homedir.append("/.osirion/"); #else // FIXME win32 - homedir = "./home/"; + filesystem_homedir.assign("./home/"); #endif - - sys::mkdir(homedir); - sys::mkdir(homedir+basedir); - - writedir = homedir; - if (moddir.size()) { - writedir.append(moddir); - } else - writedir.append(basedir); - sys::mkdir(writedir); + std::string current_datadir("data/"); + std::string package_datadir(PACKAGE_DATADIR); + std::string dir; - con_print << " files are created in " << writedir << std::endl; + // set writedir depending on modname and add home paths to the searchpath + filesystem_writedir.assign(filesystem_homedir); + if (filesystem_modname.size()) { + // append modname to writedir + filesystem_writedir.append(filesystem_modname); + filesystem_writedir += '/'; + } else { + // append basename to writedir + filesystem_writedir.append(filesystem_basename); + filesystem_writedir += '/'; + } + + sys::mkdir(filesystem_homedir); + sys::mkdir(filesystem_writedir); + + + // modname search path + if (filesystem_modname.size()) { + // HOME/modname + dir.assign(filesystem_homedir + filesystem_modname); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + } + + // CURRENT/data/modname + dir.assign(current_datadir + filesystem_modname); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + } + + // PACKAGE_DATADIR/modname + std::string dir(package_datadir + '/' + filesystem_modname); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + } + } + + // basename search path + // HOME/basename + dir.assign(filesystem_homedir + filesystem_basename); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + } + + // PACKAGE_DATADIR/basename + dir.assign(package_datadir + '/' + filesystem_basename); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + filesystem_datadir.assign(dir); + } else { + // CURRENT/data/basename + dir.assign(current_datadir + filesystem_basename); + if (sys::isdirectory(dir)) { + dir += '/'; + filesystem_searchpath.push_back(dir); + filesystem_datadir.assign(dir); + } else { + con_warn << "data/" << basename << " not found!" << std::endl; + } + } + + // print search path + for (SearchPath::iterator path = filesystem_searchpath.begin(); path != filesystem_searchpath.end(); ++path) { + con_print << " " << (*path) << std::endl; + } + con_print << " " << filesystem_searchpath.size() << " directories added to searchpath" << std::endl; + + // create writedir + con_print << " files are created in " << filesystem_writedir << std::endl; } void shutdown() { con_print << "^BShutting down filesystem..." << std::endl; + + filesystem_searchpath.clear(); + filesystem_basename.clear(); + + filesystem_modname.clear(); + filesystem_homedir.clear(); + + filesystem_writedir.clear(); } File *open(const char *filename) diff --git a/src/filesystem/filesystem.h b/src/filesystem/filesystem.h index 83e93c0..f8740d1 100644 --- a/src/filesystem/filesystem.h +++ b/src/filesystem/filesystem.h @@ -11,37 +11,35 @@ #include "filesystem/diskfile.h" #include <string> +#include <list> /// The filesystem namespace contains classes and functions for common file operations. /** filesystem is a core subsystem */ namespace filesystem { -/// location of the main data files, includes trailing / -extern std::string datadir; +typedef std::list<std::string> SearchPath; -/// location of the personal data files, includes trailing / -extern std::string homedir; - -/// writeable location -extern std::string writedir; - -/// subdirectory with the base data files, includes trailing / -extern std::string basedir; - -/// subdirectory for the current mod, includes trailing / -extern std::string moddir; +SearchPath & searchpath(); /// initialize the filesystem subsystem -void init(); +void init(std::string const & basename, std::string const & modname); /// shutdown the filesystem subsystem void shutdown(); +/// current home directory e.g. ~/.osirion/ +std::string const & homedir(); + +/// current write directory e.g. ~/.osirion/base/ +std::string const & writedir(); + /// open a file and return a pointer to a File instance File *open(const char *filename); + /// open a file and return a pointer to a File instance File *open(const std::string &filename); + /// close and delete a file instance void close(File *file); |