--- a/src/cfg.cpp Mon Jun 01 17:06:13 2015 +0300 +++ b/src/cfg.cpp Fri Jun 05 18:33:51 2015 +0300 @@ -1,6 +1,6 @@ /* * ZCinema: Zandronum demo launcher - * Copyright (C) 2013 Santeri Piippo + * Copyright (C) 2013-2015 Teemu Piippo * * 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 @@ -16,138 +16,55 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <cassert> +#include <assert.h> #include <QDir> #include <QTextStream> #include <QSettings> #include "main.h" #include "config.h" -#define MAX_CONFIG 512 +typedef QMap<QString, QVariant> DefaultsMap; + +static QSettings* getSettingsObject() +{ + return new QSettings; +} -// ============================================================================= -// ----------------------------------------------------------------------------- -namespace cfg { - static struct { - void* ptr; - Type type; - const char* name; - QVariant def; - } g_configData[MAX_CONFIG]; - - static int g_cfgDataCursor = 0; - -#define CASE(T) case T##Type: return QVariant (*(reinterpret_cast<T*> (ptr))); - static QVariant getConfigValue (void* ptr, Type type) { - switch (type) { - CASE (Int) - CASE (String) - CASE (Float) - CASE (Bool) - CASE (List) - CASE (Map) - - case KeySeqType: - return QVariant (reinterpret_cast<KeySeq*> (ptr)->toString()); - } - - assert (false); - return QVariant(); - } -#undef CASE - -#define CASE(T, METHOD) case T##Type: (*(reinterpret_cast<T*> (ptr))) = val.METHOD(); return; - static void setConfigValue (void* ptr, Type type, const QVariant& val) { - switch (type) { - CASE (Int, toInt) - CASE (String, toString) - CASE (Float, toFloat) - CASE (Bool, toBool) - CASE (List, toList) - CASE (Map, toMap) - - case KeySeqType: - reinterpret_cast<KeySeq*> (ptr)->fromString (val.toString()); - break; - } - } - - // ============================================================================= - // Get the QSettings object. - // ----------------------------------------------------------------------------- - static QSettings* getSettingsObject() { - return new QSettings; - } - - // ============================================================================= - // Load the configuration from file - // ----------------------------------------------------------------------------- - bool load() { - QSettings* settings = getSettingsObject(); - print ("config::load: Loading configuration file from %1\n", settings->fileName()); - - for (alias i : g_configData) { - if (i.name == null) - break; - - setConfigValue (i.ptr, i.type, settings->value (i.name, i.def)); - } - - settings->deleteLater(); - return true; - } - - // ============================================================================= - // Save the configuration to disk - // ----------------------------------------------------------------------------- - bool save() { - QSettings* settings = getSettingsObject(); - settings->clear(); - print ("Saving configuration to %1...\n", settings->fileName()); - - for (alias i : g_configData) { - if (i.name == null) - break; - - QVariant val = getConfigValue (i.ptr, i.type); - - if (val == i.def) - continue; - - settings->setValue (i.name, val); - } - - settings->sync(); - settings->deleteLater(); - return true; - } - - // ============================================================================= - // Reset configuration defaults. - // ----------------------------------------------------------------------------- - void reset() { - for (alias i : g_configData) { - if (i.name == null) - break; - - setConfigValue (i.ptr, i.type, i.def); - } +static DefaultsMap& getDefaults() +{ + static DefaultsMap defaults; + + if (defaults.isEmpty()) + { + // Initialize defaults here. } - // ============================================================================= - // We cannot just add config objects to a list or vector because that would rely - // on the vector's c-tor being called before the configs' c-tors. With global - // variables we cannot assume that!! Therefore we need to use a C-style array here. - // ----------------------------------------------------------------------------- - ConfigAdder::ConfigAdder (void* ptr, Type type, const char* name, QVariant def) { - if (g_cfgDataCursor == 0) - memset (g_configData, 0, sizeof g_configData); - - assert (g_cfgDataCursor < MAX_CONFIG); - alias i = g_configData[g_cfgDataCursor++]; - i.ptr = ptr; - i.type = type; - i.name = name; - i.def = def; - } + return defaults; +} + +void Config::reset() +{ + DefaultsMap& defaults = getDefaults(); + + for (DefaultsMap::iterator it = defaults.begin(); it != defaults.end(); ++it) + set (it.key(), it.value()); +} + +QVariant Config::get (const QString& name) +{ + QSettings* settings = getSettingsObject(); + DefaultsMap& defaults = getDefaults(); + DefaultsMap::iterator it = defaults.find (name); + QVariant def = it != defaults.end() ? *it : QVariant(); + QVariant value = settings->value (name, def); + settings->deleteLater(); + return value; +} + +bool Config::set (const QString& name, const QVariant& value) +{ + QSettings* settings = getSettingsObject(); + settings->setValue (name, value); + settings->deleteLater(); + return settings->status() == QSettings::NoError; } \ No newline at end of file