[Scummvm-cvs-logs] CVS: scummvm/common config-manager.cpp,NONE,1.1 config-manager.h,NONE,1.1 singleton.h,NONE,1.1 module.mk,1.10,1.11 config-file.cpp,1.18,NONE config-file.h,1.10,NONE
Max Horn
fingolfin at users.sourceforge.net
Wed Oct 8 15:00:14 CEST 2003
- Previous message: [Scummvm-cvs-logs] CVS: scummvm/base engine.cpp,1.3,1.4 gameDetector.cpp,1.13,1.14 gameDetector.h,1.7,1.8 main.cpp,1.12,1.13
- Next message: [Scummvm-cvs-logs] CVS: scummvm/queen queen.cpp,1.5,1.6 queen.h,1.4,1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/scummvm/scummvm/common
In directory sc8-pr-cvs1:/tmp/cvs-serv6106/common
Modified Files:
module.mk
Added Files:
config-manager.cpp config-manager.h singleton.h
Removed Files:
config-file.cpp config-file.h
Log Message:
new config manager. not everything is completed, and some things will still be changed, but it seems to work well enough to put it into CVS
--- NEW FILE: config-manager.cpp ---
/* 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: /cvsroot/scummvm/scummvm/common/config-manager.cpp,v 1.1 2003/10/08 21:59:22 fingolfin Exp $
*
*/
#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
--- NEW FILE: config-manager.h ---
/* 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: /cvsroot/scummvm/scummvm/common/config-manager.h,v 1.1 2003/10/08 21:59:22 fingolfin Exp $
*
*/
#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
--- NEW FILE: singleton.h ---
/* 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: /cvsroot/scummvm/scummvm/common/singleton.h,v 1.1 2003/10/08 21:59:22 fingolfin Exp $
*
*/
#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
Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/common/module.mk,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- module.mk 29 Sep 2003 21:58:40 -0000 1.10
+++ module.mk 8 Oct 2003 21:59:22 -0000 1.11
@@ -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 \
--- config-file.cpp DELETED ---
--- config-file.h DELETED ---
- Previous message: [Scummvm-cvs-logs] CVS: scummvm/base engine.cpp,1.3,1.4 gameDetector.cpp,1.13,1.14 gameDetector.h,1.7,1.8 main.cpp,1.12,1.13
- Next message: [Scummvm-cvs-logs] CVS: scummvm/queen queen.cpp,1.5,1.6 queen.h,1.4,1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Scummvm-git-logs
mailing list