Config Database, initial commit
This was SVN commit r443.
This commit is contained in:
parent
ca523e9f3c
commit
8b617e732b
130
source/ps/ConfigDB.cpp
Executable file
130
source/ps/ConfigDB.cpp
Executable file
@ -0,0 +1,130 @@
|
||||
#include "Prometheus.h"
|
||||
#include "Parser.h"
|
||||
#include "ConfigDB.h"
|
||||
#include "CLogger.h"
|
||||
#include "res/vfs.h"
|
||||
#include "res/file.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef map <CStr, CConfigValue> TConfigMap;
|
||||
TConfigMap CConfigDB::m_Map[CFG_LAST];
|
||||
CStr CConfigDB::m_ConfigFile[CFG_LAST];
|
||||
bool CConfigDB::m_UseVFS[CFG_LAST];
|
||||
|
||||
CConfigValue *CConfigDB::GetValue(EConfigNamespace ns, CStr name)
|
||||
{
|
||||
assert(ns < CFG_LAST && ns >= 0);
|
||||
|
||||
TConfigMap::iterator it=m_Map[ns].find(name);
|
||||
if (it == m_Map[ns].end())
|
||||
return NULL;
|
||||
else
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
CConfigValue *CConfigDB::CreateValue(EConfigNamespace ns, CStr name)
|
||||
{
|
||||
assert(ns < CFG_LAST && ns >= 0);
|
||||
|
||||
CConfigValue *ret=GetValue(ns, name);
|
||||
if (ret) return ret;
|
||||
|
||||
TConfigMap::iterator it=m_Map[ns].insert(m_Map[ns].begin(), make_pair(name, CConfigValue()));
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
void CConfigDB::SetConfigFile(EConfigNamespace ns, bool useVFS, CStr path)
|
||||
{
|
||||
assert(ns < CFG_LAST && ns >= 0);
|
||||
|
||||
m_ConfigFile[ns]=path;
|
||||
m_UseVFS[ns]=useVFS;
|
||||
}
|
||||
|
||||
bool CConfigDB::Reload(EConfigNamespace ns)
|
||||
{
|
||||
// Set up CParser
|
||||
CParser parser;
|
||||
CParserLine parserLine;
|
||||
parser.InputTaskType("Assignment", "_$ident_=_[-$arg(_minus)]_$value_[;$rest]");
|
||||
parser.InputTaskType("Comment", "_;$rest");
|
||||
|
||||
void *buffer;
|
||||
uint buflen;
|
||||
File f;
|
||||
Handle fh;
|
||||
if (m_UseVFS[ns])
|
||||
{
|
||||
// Open file with VFS
|
||||
fh=vfs_load(m_ConfigFile[ns], buffer, buflen);
|
||||
if (fh <= 0)
|
||||
{
|
||||
LOG(ERROR, "vfs_load for \"%s\" failed: return was %lld", m_ConfigFile[ns].c_str(), fh);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (file_open(m_ConfigFile[ns].c_str(), 0, &f)!=0)
|
||||
{
|
||||
LOG(ERROR, "file_open for \"%s\" failed", m_ConfigFile[ns].c_str());
|
||||
return false;
|
||||
}
|
||||
if (file_map(&f, buffer, buflen) != 0)
|
||||
{
|
||||
LOG(ERROR, "file_map for \"%s\" failed", m_ConfigFile[ns].c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TConfigMap newMap;
|
||||
|
||||
char *filebuf=(char *)malloc(buflen+1);
|
||||
memcpy(filebuf, buffer, buflen);
|
||||
filebuf[buflen]=0;
|
||||
|
||||
// Read file line by line
|
||||
char *ctxt=NULL;
|
||||
// strtok is defined to skip empty tokens, so this neatly takes care of
|
||||
// unix/windows file endings
|
||||
const char *delim="\r\n";
|
||||
char *line=strtok_r((char *)filebuf, delim, &ctxt);
|
||||
do
|
||||
{
|
||||
// Send line to parser
|
||||
parserLine.ParseString(parser, line);
|
||||
// Get name and value from parser
|
||||
string name;
|
||||
string value;
|
||||
|
||||
if (parserLine.GetArgCount()>=2 &&
|
||||
parserLine.GetArgString(0, name) &&
|
||||
parserLine.GetArgString(1, value))
|
||||
{
|
||||
// Add name and value to the map
|
||||
newMap[name].m_String=value;
|
||||
LOG(NORMAL, "Loaded config string \"%s\" = \"%s\"", name.c_str(), value.c_str());
|
||||
}
|
||||
}
|
||||
while (line = strtok_r(NULL, delim, &ctxt));
|
||||
|
||||
m_Map[ns].swap(newMap);
|
||||
|
||||
free(filebuf);
|
||||
// Close the correct file handle
|
||||
if (m_UseVFS[ns])
|
||||
{
|
||||
vfs_close(fh);
|
||||
}
|
||||
else
|
||||
{
|
||||
file_unmap(&f);
|
||||
file_close(&f);
|
||||
}
|
||||
}
|
||||
|
||||
void CConfigDB::WriteFile(EConfigNamespace ns, bool useVFS, CStr path)
|
||||
{
|
||||
// TODO Implement this function
|
||||
}
|
80
source/ps/ConfigDB.h
Executable file
80
source/ps/ConfigDB.h
Executable file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
CConfigDB - Load, access and store configuration variables
|
||||
|
||||
TDD : http://forums.wildfiregames.com/0ad/index.php?showtopic=1125
|
||||
AUTHOR : Simon Brenner <simon@wildfiregames.com>, <simon.brenner@home.se>
|
||||
OVERVIEW:
|
||||
*/
|
||||
|
||||
#ifndef _ps_ConfigDB_H
|
||||
#define _ps_ConfigDB_H
|
||||
|
||||
#include "Prometheus.h"
|
||||
#include "Parser.h"
|
||||
#include "CStr.h"
|
||||
#include "Singleton.h"
|
||||
|
||||
enum EConfigNamespace
|
||||
{
|
||||
CFG_SYSTEM,
|
||||
CFG_MOD,
|
||||
CFG_USER,
|
||||
CFG_LAST
|
||||
};
|
||||
|
||||
typedef CParserValue CConfigValue;
|
||||
#define g_ConfigDB CConfigDB::GetSingleton()
|
||||
|
||||
class CConfigDB: public Singleton<CConfigDB>
|
||||
{
|
||||
static std::map <CStr, CConfigValue> m_Map[];
|
||||
static CStr m_ConfigFile[];
|
||||
static bool m_UseVFS[];
|
||||
|
||||
public:
|
||||
// GetValue()
|
||||
// Attempt to find a config variable with the given name in the specified
|
||||
// namespace.
|
||||
//
|
||||
// Returns a pointer to the config value structure for the variable, or
|
||||
// NULL if such a variable could not be found
|
||||
CConfigValue *GetValue(EConfigNamespace ns, CStr name);
|
||||
|
||||
// CreateValue()
|
||||
// Create a new config value in the specified namespace. If such a
|
||||
// variable already exists, the old value is returned and the effect is
|
||||
// exactly the same as that of GetValue()
|
||||
//
|
||||
// Returns a pointer to the value of the newly created config variable, or
|
||||
// that of the already existing config variable.
|
||||
CConfigValue *CreateValue(EConfigNamespace ns, CStr name);
|
||||
|
||||
// SetConfigFile()
|
||||
// Set the path to the config file used to populate the specified namespace
|
||||
// Note that this function does not actually load the config file. Use
|
||||
// the Reload() method if you want to read the config file at the same time.
|
||||
//
|
||||
// 'path': The path to the config file.
|
||||
// VFS: relative to VFS root
|
||||
// non-VFS: relative to current working directory (binaries/data/)
|
||||
// 'useVFS': true if the path is a VFS path, false if it is a real path
|
||||
void SetConfigFile(EConfigNamespace ns, bool useVFS, CStr path);
|
||||
|
||||
// Reload()
|
||||
// Reload the config file associated with the specified config namespace
|
||||
// (the last config file path set with SetConfigFile)
|
||||
//
|
||||
// Returns:
|
||||
// true: if the reload succeeded,
|
||||
// false: if the reload failed
|
||||
bool Reload(EConfigNamespace);
|
||||
|
||||
// WriteFile()
|
||||
// Write the current state of the specified config namespace to the file
|
||||
// specified by 'path'
|
||||
//
|
||||
// This function can also
|
||||
void WriteFile(EConfigNamespace ns, bool useVFS, CStr path);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user