src/cfg.cpp

changeset 37
c82a86ea87be
parent 30
6b82f6a3ad53
child 39
2c368cf5cc19
equal deleted inserted replaced
36:b8fa9171be6e 37:c82a86ea87be
1 /* 1 /*
2 * ZCinema: Zandronum demo launcher 2 * ZCinema: Zandronum demo launcher
3 * Copyright (C) 2013 Santeri Piippo 3 * Copyright (C) 2013-2015 Teemu Piippo
4 * 4 *
5 * This program is free software: you can redistribute it and/or modify 5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or 7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version. 8 * (at your option) any later version.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include <cassert> 19 #include <assert.h>
20 #include <QDir> 20 #include <QDir>
21 #include <QTextStream> 21 #include <QTextStream>
22 #include <QSettings> 22 #include <QSettings>
23 #include "main.h" 23 #include "main.h"
24 #include "config.h" 24 #include "config.h"
25 25
26 #define MAX_CONFIG 512 26 typedef QMap<QString, QVariant> DefaultsMap;
27 27
28 // ============================================================================= 28 static QSettings* getSettingsObject()
29 // ----------------------------------------------------------------------------- 29 {
30 namespace cfg { 30 return new QSettings;
31 static struct { 31 }
32 void* ptr; 32
33 Type type; 33 static DefaultsMap& getDefaults()
34 const char* name; 34 {
35 QVariant def; 35 static DefaultsMap defaults;
36 } g_configData[MAX_CONFIG]; 36
37 37 if (defaults.isEmpty())
38 static int g_cfgDataCursor = 0; 38 {
39 39 // Initialize defaults here.
40 #define CASE(T) case T##Type: return QVariant (*(reinterpret_cast<T*> (ptr)));
41 static QVariant getConfigValue (void* ptr, Type type) {
42 switch (type) {
43 CASE (Int)
44 CASE (String)
45 CASE (Float)
46 CASE (Bool)
47 CASE (List)
48 CASE (Map)
49
50 case KeySeqType:
51 return QVariant (reinterpret_cast<KeySeq*> (ptr)->toString());
52 }
53
54 assert (false);
55 return QVariant();
56 }
57 #undef CASE
58
59 #define CASE(T, METHOD) case T##Type: (*(reinterpret_cast<T*> (ptr))) = val.METHOD(); return;
60 static void setConfigValue (void* ptr, Type type, const QVariant& val) {
61 switch (type) {
62 CASE (Int, toInt)
63 CASE (String, toString)
64 CASE (Float, toFloat)
65 CASE (Bool, toBool)
66 CASE (List, toList)
67 CASE (Map, toMap)
68
69 case KeySeqType:
70 reinterpret_cast<KeySeq*> (ptr)->fromString (val.toString());
71 break;
72 }
73 }
74
75 // =============================================================================
76 // Get the QSettings object.
77 // -----------------------------------------------------------------------------
78 static QSettings* getSettingsObject() {
79 return new QSettings;
80 }
81
82 // =============================================================================
83 // Load the configuration from file
84 // -----------------------------------------------------------------------------
85 bool load() {
86 QSettings* settings = getSettingsObject();
87 print ("config::load: Loading configuration file from %1\n", settings->fileName());
88
89 for (alias i : g_configData) {
90 if (i.name == null)
91 break;
92
93 setConfigValue (i.ptr, i.type, settings->value (i.name, i.def));
94 }
95
96 settings->deleteLater();
97 return true;
98 }
99
100 // =============================================================================
101 // Save the configuration to disk
102 // -----------------------------------------------------------------------------
103 bool save() {
104 QSettings* settings = getSettingsObject();
105 settings->clear();
106 print ("Saving configuration to %1...\n", settings->fileName());
107
108 for (alias i : g_configData) {
109 if (i.name == null)
110 break;
111
112 QVariant val = getConfigValue (i.ptr, i.type);
113
114 if (val == i.def)
115 continue;
116
117 settings->setValue (i.name, val);
118 }
119
120 settings->sync();
121 settings->deleteLater();
122 return true;
123 }
124
125 // =============================================================================
126 // Reset configuration defaults.
127 // -----------------------------------------------------------------------------
128 void reset() {
129 for (alias i : g_configData) {
130 if (i.name == null)
131 break;
132
133 setConfigValue (i.ptr, i.type, i.def);
134 }
135 } 40 }
136 41
137 // ============================================================================= 42 return defaults;
138 // We cannot just add config objects to a list or vector because that would rely
139 // on the vector's c-tor being called before the configs' c-tors. With global
140 // variables we cannot assume that!! Therefore we need to use a C-style array here.
141 // -----------------------------------------------------------------------------
142 ConfigAdder::ConfigAdder (void* ptr, Type type, const char* name, QVariant def) {
143 if (g_cfgDataCursor == 0)
144 memset (g_configData, 0, sizeof g_configData);
145
146 assert (g_cfgDataCursor < MAX_CONFIG);
147 alias i = g_configData[g_cfgDataCursor++];
148 i.ptr = ptr;
149 i.type = type;
150 i.name = name;
151 i.def = def;
152 }
153 } 43 }
44
45 void Config::reset()
46 {
47 DefaultsMap& defaults = getDefaults();
48
49 for (DefaultsMap::iterator it = defaults.begin(); it != defaults.end(); ++it)
50 set (it.key(), it.value());
51 }
52
53 QVariant Config::get (const QString& name)
54 {
55 QSettings* settings = getSettingsObject();
56 DefaultsMap& defaults = getDefaults();
57 DefaultsMap::iterator it = defaults.find (name);
58 QVariant def = it != defaults.end() ? *it : QVariant();
59 QVariant value = settings->value (name, def);
60 settings->deleteLater();
61 return value;
62 }
63
64 bool Config::set (const QString& name, const QVariant& value)
65 {
66 QSettings* settings = getSettingsObject();
67 settings->setValue (name, value);
68 settings->deleteLater();
69 return settings->status() == QSettings::NoError;
70 }

mercurial