diff -r c9b6dd9dd4cd -r a5457405cc9b src/cfg.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cfg.cpp Sun Sep 08 16:14:58 2013 +0300
@@ -0,0 +1,153 @@
+/*
+ * ZanDemo: Zandronum demo launcher
+ * Copyright (C) 2013 Santeri 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
+ * the Free Software Foundation, either version 3 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, see .
+ */
+
+#include
+#include
+#include
+#include
+#include "main.h"
+#include "config.h"
+
+#define MAX_CONFIG 512
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+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 (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 (ptr)->toString());
+ }
+
+ assert (false);
+ return QVariant();
+ }
+#undef CASE
+
+#define CASE(T, METHOD) case T##Type: (*(reinterpret_cast (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 (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);
+ }
+ }
+
+ // =============================================================================
+ // 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;
+ }
+}
\ No newline at end of file