aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/config-file.cpp240
-rw-r--r--common/config-file.h70
-rw-r--r--common/config-manager.cpp370
-rw-r--r--common/config-manager.h127
-rw-r--r--common/module.mk2
-rw-r--r--common/singleton.h57
6 files changed, 555 insertions, 311 deletions
diff --git a/common/config-file.cpp b/common/config-file.cpp
deleted file mode 100644
index 4b66e70981..0000000000
--- a/common/config-file.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2003 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * 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 General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#include "stdafx.h"
-#include "common/config-file.h"
-#include "base/engine.h" // for debug()
-
-#define MAXLINELEN 256
-
-static char *ltrim(char *t) {
- while (*t == ' ')
- t++;
- return t;
-}
-
-static char *rtrim(char *t) {
- int l = strlen(t) - 1;
- while (l >= 0 && t[l] == ' ')
- t[l--] = 0;
- return t;
-}
-
-// The config-class itself.
-
-Config::Config (const String &cfg, const String &d)
- : filename(cfg), defaultDomain(d), willwrite(false) {
- FILE *cfg_file;
- char t[MAXLINELEN];
-
- if (!(cfg_file = fopen(filename.c_str(), "r"))) {
- debug(1, "Unable to open configuration file: %s.\n", filename.c_str());
- } else {
- while (!feof(cfg_file)) {
- if (!fgets(t, MAXLINELEN, cfg_file))
- continue;
- if (t[0] != '#') {
- if (t[0] == '[') {
- // It's a new domain which begins here.
- char *p = strchr(t, ']');
- if (!p) {
- debug(1, "Config file buggy: no ] at the end of the domain name.\n");
- } else {
- *p = 0;
- set_domain(t + 1);
- }
- } else {
- // It's a new key in the domain.
- if (defaultDomain.isEmpty()) {
- debug(1, "Config file buggy: we have a key without a domain first.\n");
- }
- char *p = strchr(t, '\n');
- if (p)
- *p = 0;
- p = strchr(t, '\r');
- if (p)
- *p = 0;
-
- if (!(p = strchr(t, '='))) {
- if (strlen(t))
- debug(1, "Config file buggy: there is junk: %s\n", t);
- } else {
- char *key, *value;
- *p = 0;
- key = ltrim(rtrim(t));
- value = ltrim(p + 1);
- set(key, value);
- }
- }
- }
- }
- set_domain(d);
- fclose(cfg_file);
- }
-}
-
-const char *Config::get(const String &key, const String &d) const {
- String domain;
-
- if (d.isEmpty())
- domain = defaultDomain;
- else
- domain = d;
-
- domain.toLowercase();
- if (domains.contains(domain) && domains[domain].contains(key))
- return domains[domain][key].c_str();
-
- return 0;
-}
-
-const int Config::getInt(const String &key, int def, const String &d) const {
- const char *value = get(key, d);
-
- if (value)
- return atoi(value);
- return def;
-}
-
-const bool Config::getBool(const String &key, bool def, const String &d) const {
- const char *value = get(key, d);
-
- if (value)
- return !scumm_stricmp(value, "true");
- return def;
-}
-
-void Config::set(const String &key, const String &value, const String &d) {
- String domain(d);
-
- if (domain.isEmpty())
- domain = defaultDomain;
-
- domain.toLowercase();
- domains[domain][key] = value;
-}
-
-void Config::setInt(const String &key, int value_i, const String &d) {
- char value[MAXLINELEN];
- sprintf(value, "%i", value_i);
- set(key, String(value), d);
-}
-
-void Config::setBool(const String &key, bool value_b, const String &d) {
- String value(value_b ? "true" : "false");
- set(key, value, d);
-}
-
-void Config::set_domain(const String &d) {
- defaultDomain = d;
- defaultDomain.toLowercase();
-}
-
-bool Config::has_domain(const String &d) const {
- String temp(d);
- temp.toLowercase();
- return domains.contains(temp);
-}
-
-void Config::flush() const {
- FILE *cfg_file;
-
- if (!willwrite)
- return;
-
- if (!(cfg_file = fopen(filename.c_str(), "w"))) {
- debug(1, "Unable to write configuration file: %s.\n", filename.c_str());
- } else {
- DomainMap::ConstIterator d;
- for (d = domains.begin(); d != domains.end(); ++d) {
- fprintf(cfg_file, "[%s]\n", d->_key.c_str());
-
- const StringMap &data = d->_value;
- StringMap::ConstIterator x;
- for (x = data.begin(); x != data.end(); ++x) {
- const String &value = x->_value;
- if (!value.isEmpty())
- fprintf(cfg_file, "%s=%s\n", x->_key.c_str(), value.c_str());
- }
- fprintf(cfg_file, "\n");
- }
- fclose(cfg_file);
- }
-}
-
-void Config::rename_domain(const String &oldD, const String &newD) {
- String oldDomain(oldD);
- String newDomain(newD);
- oldDomain.toLowercase();
- newDomain.toLowercase();
-
- if (oldDomain == newDomain)
- return;
-
- StringMap &oldHash = domains[oldDomain];
- StringMap &newHash = domains[newDomain];
-
- newHash.merge(oldHash);
-
- domains.remove(oldDomain);
-}
-
-void Config::delete_domain(const String &d) {
- String domain(d);
- domain.toLowercase();
- domains.remove(d);
-}
-
-void Config::set_filename(const String &f) {
- filename = f;
-}
-
-void Config::merge_config(const Config &c) {
- DomainMap::ConstIterator d, end(c.domains.end());
- for (d = c.domains.begin(); d != end; ++d) {
- domains[d->_key].merge(d->_value);
- }
-}
-
-void Config::set_writing(bool w) {
- willwrite = w;
-}
-
-const int Config::count_domains() {
- int count = 0;
- DomainMap::ConstIterator d, end(domains.end());
- for (d = domains.begin(); d != end; ++d)
- count++;
-
- return count;
-}
-
-Common::StringList Config::get_domains() {
- StringList domainNames;
- DomainMap::ConstIterator d, end(domains.end());
- for (d = domains.begin(); d != end; ++d) {
- domainNames.push_back(d->_key);
- }
-
- return domainNames;
-}
-
diff --git a/common/config-file.h b/common/config-file.h
deleted file mode 100644
index bfec3e8465..0000000000
--- a/common/config-file.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2003 The ScummVM project
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * 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 General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- *
- */
-
-#ifndef CONFIG_FILE_H
-#define CONFIG_FILE_H
-
-#include "common/list.h"
-#include "common/map.h"
-#include "common/str.h"
-#include "common/util.h"
-
-class Config {
-public:
- typedef Common::String String;
- typedef Common::StringList StringList;
- typedef Common::StringMap StringMap;
- typedef Common::Map<String, StringMap> DomainMap;
-
- Config (const String & = String("config.cfg"), const String & = String("default"));
- const char *get(const String &key, const String &dom = String()) const;
- const int getInt(const String &key, int def = 0, const String &dom = String()) const;
- const bool getBool(const String &key, bool def = false, const String &dom = String()) const;
-
- void set(const String &key, const String &value, const String &dom = String());
- void setInt(const String &key, int value, const String &dom = String());
- void setBool(const String &key, bool value, const String &dom = String());
-
- void set_domain(const String &d);
- void flush() const;
- void rename_domain(const String &oldD, const String &newD);
- void delete_domain(const String &d);
- bool has_domain(const String &d) const;
- void set_filename(const String &);
- void merge_config(const Config &);
- void set_writing(bool);
-
- const int count_domains();
- StringList get_domains();
-
-protected:
- DomainMap domains;
- String filename;
- String defaultDomain;
-
- bool willwrite;
-};
-
-// The global config object
-extern Config *g_config;
-
-#endif
diff --git a/common/config-manager.cpp b/common/config-manager.cpp
new file mode 100644
index 0000000000..f90eefbbd3
--- /dev/null
+++ b/common/config-manager.cpp
@@ -0,0 +1,370 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2003 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#include "common/config-manager.h"
+
+#if defined(UNIX)
+#include <sys/param.h>
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 256
+#endif
+#ifdef MACOSX
+#define DEFAULT_CONFIG_FILE "Library/Preferences/ScummVM Preferences"
+#else
+#define DEFAULT_CONFIG_FILE ".scummvmrc"
+#endif
+#else
+#define DEFAULT_CONFIG_FILE "scummvm.ini"
+#endif
+
+#define MAXLINELEN 256
+
+static char *ltrim(char *t) {
+ while (*t == ' ')
+ t++;
+ return t;
+}
+
+static char *rtrim(char *t) {
+ int l = strlen(t) - 1;
+ while (l >= 0 && t[l] == ' ')
+ t[l--] = 0;
+ return t;
+}
+
+
+namespace Common {
+
+const String ConfigManager::kApplicationDomain("scummvm");
+
+const String trueStr("true");
+const String falseStr("false");
+
+
+#pragma mark -
+
+
+ConfigManager::ConfigManager() {
+
+#if defined(UNIX)
+ char configFile[MAXPATHLEN];
+ if(getenv("HOME") != NULL)
+ sprintf(configFile,"%s/%s", getenv("HOME"), DEFAULT_CONFIG_FILE);
+ else strcpy(configFile,DEFAULT_CONFIG_FILE);
+#else
+ char configFile[256];
+ #if defined (WIN32) && !defined(_WIN32_WCE)
+ GetWindowsDirectory(configFile, 256);
+ strcat(configFile, "\\");
+ strcat(configFile, DEFAULT_CONFIG_FILE);
+ #elif defined(__PALM_OS__)
+ strcpy(configFile,"/PALM/Programs/ScummVM/");
+ strcat(configFile, DEFAULT_CONFIG_FILE);
+ #else
+ strcpy(configFile, DEFAULT_CONFIG_FILE);
+ #endif
+#endif
+
+ // Ensure the global domain(s) are setup.
+ _globalDomains.addKey(kApplicationDomain);
+#ifdef _WIN32_WCE
+ // WinCE for some reasons uses additional global domains.
+ _globalDomains.addKey("wince");
+ _globalDomains.addKey("smartfon-keys");
+#endif
+
+ _filename = configFile;
+ loadFile(_filename);
+}
+
+void ConfigManager::loadFile(const String &filename) {
+ FILE *cfg_file;
+ char t[MAXLINELEN];
+ String domain;
+
+ if (!(cfg_file = fopen(filename.c_str(), "r"))) {
+ debug(1, "Unable to open configuration file: %s.\n", filename.c_str());
+ } else {
+ while (!feof(cfg_file)) {
+ if (!fgets(t, MAXLINELEN, cfg_file))
+ continue;
+ if (t[0] != '#') {
+ if (t[0] == '[') {
+ // It's a new domain which begins here.
+ char *p = strchr(t, ']');
+ if (!p) {
+ error("Config file buggy: no ] at the end of the domain name.\n");
+ } else {
+ *p = 0;
+ // TODO: Some kind of domain name verification might be nice.
+ // E.g. restrict to only a-zA-Z0-9 and maybe -_ or so...
+ domain = t + 1;
+ }
+ } else {
+ // It's a new key in the domain.
+ if (domain.isEmpty()) {
+ error("Config file buggy: we have a key without a domain first.\n");
+ }
+ char *p = strchr(t, '\n');
+ if (p)
+ *p = 0;
+ p = strchr(t, '\r');
+ if (p)
+ *p = 0;
+
+ if (!(p = strchr(t, '='))) {
+ if (strlen(t))
+ warning("Config file buggy: there is junk: %s\n", t);
+ } else {
+ *p = 0;
+ String key = ltrim(rtrim(t));
+ String value = ltrim(p + 1);
+ set(key, value, domain);
+ }
+ }
+ }
+ }
+ fclose(cfg_file);
+ }
+}
+
+void ConfigManager::flushToDisk() {
+ FILE *cfg_file;
+
+// TODO
+// if (!willwrite)
+// return;
+
+ if (!(cfg_file = fopen(_filename.c_str(), "w"))) {
+ warning("Unable to write configuration file: %s.\n", _filename.c_str());
+ } else {
+ DomainMap::ConstIterator d;
+
+ // First write the global domains
+ for (d = _globalDomains.begin(); d != _globalDomains.end(); ++d) {
+ writeDomain(cfg_file, d->_key, d->_value);
+ }
+
+ // Second, write the game domains
+ for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) {
+ writeDomain(cfg_file, d->_key, d->_value);
+ }
+
+ fclose(cfg_file);
+ }
+}
+
+void ConfigManager::writeDomain(FILE *file, const String &name, const Domain &domain) {
+ if (domain.isEmpty())
+ return; // Don't bother writing empty domains.
+
+ fprintf(file, "[%s]\n", name.c_str());
+
+ StringMap::ConstIterator x;
+ for (x = domain.begin(); x != domain.end(); ++x) {
+ const String &value = x->_value;
+ if (!value.isEmpty())
+ fprintf(file, "%s=%s\n", x->_key.c_str(), value.c_str());
+ }
+ fprintf(file, "\n");
+}
+
+#pragma mark -
+
+
+bool ConfigManager::hasKey(const String &key) const {
+ // Search the domains in the following order:
+ // 1) Run time domain
+ // 2) Active game domain (if any)
+ // 3) All global domains
+ // The defaults domain is explicitly *not* checked.
+
+// if (_runtimeDomain.contain(key))
+// return true;
+
+ if (!_activeDomain.isEmpty() && _gameDomains[_activeDomain].contains(key))
+ return true;
+
+ DomainMap::ConstIterator iter;
+ for (iter = _globalDomains.begin(); iter != _globalDomains.end(); ++iter) {
+ if (iter->_value.contains(key))
+ return true;
+ }
+
+ return false;
+}
+
+
+bool ConfigManager::hasKey(const String &key, const String &dom) const {
+ assert(!dom.isEmpty());
+
+ if (_gameDomains.contains(dom))
+ return _gameDomains[dom].contains(key);
+ if (_globalDomains.contains(dom))
+ return _globalDomains[dom].contains(key);
+
+ return false;
+}
+
+
+#pragma mark -
+
+
+const String & ConfigManager::get(const String &key) const {
+ // Search the domains in the following order:
+ // 1) Run time domain
+ // 2) Active game domain (if any)
+ // 3) All global domains
+ // 4) The defaults
+
+// if (_runtimeDomain.contain(key))
+// return true;
+
+ if (!_activeDomain.isEmpty() && _gameDomains[_activeDomain].contains(key))
+ return _gameDomains[_activeDomain][key];
+
+ DomainMap::ConstIterator iter;
+ for (iter = _globalDomains.begin(); iter != _globalDomains.end(); ++iter) {
+ if (iter->_value.contains(key))
+ return iter->_value[key];
+ }
+
+ return _defaultsDomain.get(key);
+}
+
+const String & ConfigManager::get(const String &key, const String &dom) const {
+ if (dom.isEmpty())
+ return get(key);
+
+ // TODO: How exactly should we handle the case were the domain 'dom'
+ // is not found, or were dom is found, but doesn't contain 'key' ?
+ // Right now we just return an empty string. But might want to print
+ // out a warning, or even error out?
+ if (_gameDomains.contains(dom))
+ return _gameDomains[dom].get(key);
+ if (_globalDomains.contains(dom))
+ return _globalDomains[dom].get(key);
+
+ return String::emptyString;
+}
+
+int ConfigManager::getInt(const String &key, const String &dom) const {
+ String value(get(key, dom));
+ // Convert the string to an integer.
+ // TODO: We should perform some error checking.
+ long v = strtol(value.c_str(), 0, 10);
+ return (int)v;
+}
+
+bool ConfigManager::getBool(const String &key, const String &dom) const {
+ String value(get(key, dom));
+ // '1', 'true' and 'yes' are accepted as true values; everything else
+ // maps to value 'false'.
+ return (value == "true") || (value == "yes") || (value == "1");
+}
+
+
+#pragma mark -
+
+
+void ConfigManager::set(const String &key, const String &value) {
+#if 0
+ // TODO ?!?
+// _runtimeDomain[key] = value;
+#else
+ if (_activeDomain.isEmpty())
+ _globalDomains[kApplicationDomain][key] = value;
+ else
+ _gameDomains[_activeDomain][key] = value;
+#endif
+}
+
+void ConfigManager::set(const String &key, const String &value, const String &dom) {
+ if (_globalDomains.contains(dom))
+ _globalDomains[dom][key] = value;
+ else
+ _gameDomains[dom][key] = value;
+}
+
+void ConfigManager::set(const String &key, const char *value, const String &dom) {
+ set(key, String(value), dom);
+}
+
+void ConfigManager::set(const String &key, int value, const String &dom) {
+ char tmp[128];
+ snprintf(tmp, sizeof(tmp), "%i", value);
+ set(key, String(tmp), dom);
+}
+
+void ConfigManager::set(const String &key, bool value, const String &dom) {
+ set(key, value ? trueStr : falseStr, dom);
+}
+
+
+#pragma mark -
+
+
+void ConfigManager::registerDefault(const String &key, const String &value) {
+ _defaultsDomain[key] = value;
+}
+
+void ConfigManager::registerDefault(const String &key, const char *value) {
+ registerDefault(key, String(value));
+}
+
+void ConfigManager::registerDefault(const String &key, int value) {
+ char tmp[128];
+ snprintf(tmp, sizeof(tmp), "%i", value);
+ registerDefault(key, tmp);
+}
+
+void ConfigManager::registerDefault(const String &key, bool value) {
+ registerDefault(key, value ? trueStr : falseStr);
+}
+
+
+#pragma mark -
+
+
+void ConfigManager::setActiveDomain(const String &domain) {
+ _activeDomain = domain;
+ _gameDomains.addKey(domain);
+}
+
+void ConfigManager::removeGameDomain(const String &name) {
+ _gameDomains.remove(name);
+}
+
+void ConfigManager::renameGameDomain(const String &oldName, const String &newName) {
+ if (oldName == newName)
+ return;
+
+ _gameDomains[newName].merge(_gameDomains[oldName]);
+
+ _gameDomains.remove(oldName);
+}
+
+bool ConfigManager::hasGameDomain(const String &domain) const {
+ return _gameDomains.contains(domain);
+}
+
+} // End of namespace Common
diff --git a/common/config-manager.h b/common/config-manager.h
new file mode 100644
index 0000000000..d4d368e761
--- /dev/null
+++ b/common/config-manager.h
@@ -0,0 +1,127 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2003 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef COMMON_CONFIG_H
+#define COMMON_CONFIG_H
+
+#include "common/list.h"
+#include "common/map.h"
+#include "common/singleton.h"
+#include "common/str.h"
+#include "common/util.h"
+
+namespace Common {
+
+class File;
+
+
+/**
+ * The (singleton) configuration manager, used to query & set configuration
+ * values using string keys.
+ *
+ * @todo Implement the callback based notification system (outline below)
+ * which sends out notifications to interested parties whenever the value
+ * of some specific (or any) configuration key changes.
+ */
+class ConfigManager : public Singleton<ConfigManager> {
+public:
+ class Domain : public StringMap {
+// friend class ConfigManager;
+ public:
+ const String &get(const String &key) const {
+ Node *node = findNode(_root, key);
+ return node ? node->_value : String::emptyString;
+ }
+/*
+ void set(const String &key, const String &value);
+ void set(const String &key, int value);
+ void set(const String &key, bool value);
+*/
+ };
+
+ typedef Map<String, Domain> DomainMap;
+
+ /** The name of the application domain (normally 'scummvm'). */
+ static const String kApplicationDomain;
+
+ bool hasKey(const String &key) const;
+ bool hasKey(const String &key, const String &dom) const;
+
+ const String & get(const String &key) const;
+ const String & get(const String &key, const String &dom) const;
+ int getInt(const String &key, const String &dom = String::emptyString) const;
+ bool getBool(const String &key, const String &dom = String::emptyString) const;
+
+ void set(const String &key, const String &value);
+ void set(const String &key, const String &value, const String &dom);
+ void set(const String &key, const char *value, const String &dom = String::emptyString);
+ void set(const String &key, int value, const String &dom = String::emptyString);
+ void set(const String &key, bool value, const String &dom = String::emptyString);
+
+ void registerDefault(const String &key, const String &value);
+ void registerDefault(const String &key, const char *value);
+ void registerDefault(const String &key, int value);
+ void registerDefault(const String &key, bool value);
+// ...
+
+ void flushToDisk();
+
+ void setActiveDomain(const String &domain);
+
+// void addDomain(const String &name);
+ void removeGameDomain(const String &name);
+ void renameGameDomain(const String &oldName, const String &newName);
+ bool hasGameDomain(const String &domain) const;
+ const DomainMap & getGameDomains() const { return _gameDomains; }
+
+/*
+ TODO: Callback/change notification system
+ typedef void (*ConfigCallback)(const ConstString &key, void *refCon);
+
+ void registerCallback(const ConstString &key, ConfigCallback cfgc, void *refCon)
+ void unregisterCallback(const ConstString &key, ConfigCallback cfgc)
+*/
+
+private:
+ friend class Singleton<ConfigManager>;
+ ConfigManager();
+
+ void loadFile(const String &filename);
+ void writeDomain(FILE *file, const String &name, const Domain &domain);
+
+// Domain _runtimeDomain;
+ DomainMap _gameDomains;
+ DomainMap _globalDomains;
+ Domain _defaultsDomain;
+
+ List<Domain *> _searchOrder;
+
+ String _activeDomain;
+ String _filename;
+};
+
+} // End of namespace Common
+
+/** Shortcut for accessing the configuration manager. */
+#define ConfMan Common::ConfigManager::instance()
+
+#endif
diff --git a/common/module.mk b/common/module.mk
index 4bb6e6e1e5..b55428edab 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -1,7 +1,7 @@
MODULE := common
MODULE_OBJS := \
- common/config-file.o \
+ common/config-manager.o \
common/file.o \
common/scaler.o \
common/str.o \
diff --git a/common/singleton.h b/common/singleton.h
new file mode 100644
index 0000000000..be40b45f42
--- /dev/null
+++ b/common/singleton.h
@@ -0,0 +1,57 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2003 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ *
+ */
+
+#ifndef COMMON_SINGLETON_H
+#define COMMON_SINGLETON_H
+
+namespace Common {
+
+/**
+ * Generic template base class for implementing the singleton design pattern.
+ */
+template <class T>
+class Singleton
+{
+public:
+ static T& instance() {
+ // TODO: We aren't thread safe. For now we ignore it since the
+ // only thing using this singleton template is the config manager,
+ // and that is first instantiated long before any threads.
+ // TODO: We don't leak, but the destruction order is nevertheless
+ // semi-random. If we use multiple singletons, the destruction
+ // order might become an issue. There are various approaches
+ // to solve that problem, but for now this is sufficient
+ static T singleton;
+ return singleton;
+ }
+protected:
+ Singleton<T>() { }
+ ~Singleton<T>() { }
+
+private:
+ Singleton(const Singleton&);
+ Singleton& operator= (const Singleton&);
+};
+
+} // End of namespace Common
+
+#endif