36 # define EXTENSION ".ini" |
36 # define EXTENSION ".ini" |
37 #else |
37 #else |
38 # define EXTENSION ".cfg" |
38 # define EXTENSION ".cfg" |
39 #endif // _WIN32 |
39 #endif // _WIN32 |
40 |
40 |
41 Config* g_configPointers[MAX_CONFIG]; |
41 #define MAX_CONFIG 512 |
42 static int g_cfgPointerCursor = 0; |
|
43 static QMap<String, Config*> g_configsByName; |
|
44 static QList<Config*> g_configs; |
|
45 |
42 |
46 // ============================================================================= |
43 ConfigEntry* g_configPointers[MAX_CONFIG]; |
|
44 static int g_cfgPointerCursor = 0; |
|
45 static QMap<String, ConfigEntry*> g_configsByName; |
|
46 static QList<ConfigEntry*> g_configs; |
|
47 |
|
48 // |
47 // Get the QSettings object. |
49 // Get the QSettings object. |
48 // ============================================================================= |
50 // |
49 static QSettings* getSettingsObject() |
51 static QSettings* getSettingsObject() |
50 { |
52 { |
51 String path = qApp->applicationDirPath() + "/" UNIXNAME EXTENSION; |
53 String path = qApp->applicationDirPath() + "/" UNIXNAME EXTENSION; |
52 return new QSettings (path, QSettings::IniFormat); |
54 return new QSettings (path, QSettings::IniFormat); |
53 } |
55 } |
54 |
56 |
55 Config::Config (String name) : |
57 ConfigEntry::ConfigEntry (String name) : |
56 m_name (name) {} |
58 m_name (name) {} |
57 |
59 |
58 // ============================================================================= |
60 // |
59 // Load the configuration from file |
61 // Load the configuration from file |
60 // ============================================================================= |
62 // |
61 bool Config::load() |
63 bool Config::load() |
62 { |
64 { |
63 QSettings* settings = getSettingsObject(); |
65 QSettings* settings = getSettingsObject(); |
64 print ("config::load: Loading configuration file from %1\n", settings->fileName()); |
66 print ("config::load: Loading configuration file from %1\n", settings->fileName()); |
65 |
67 |
66 for (Config* cfg : g_configPointers) |
68 for (ConfigEntry* cfg : g_configPointers) |
67 { |
69 { |
68 if (not cfg) |
70 if (not cfg) |
69 break; |
71 break; |
70 |
72 |
71 QVariant val = settings->value (cfg->name(), cfg->getDefaultAsVariant()); |
73 QVariant val = settings->value (cfg->name(), cfg->getDefaultAsVariant()); |
98 print ("Configuration saved to %1.\n", settings->fileName()); |
99 print ("Configuration saved to %1.\n", settings->fileName()); |
99 settings->deleteLater(); |
100 settings->deleteLater(); |
100 return true; |
101 return true; |
101 } |
102 } |
102 |
103 |
103 // ============================================================================= |
104 // |
104 // Reset configuration to defaults. |
105 // Reset configuration to defaults. |
105 // ============================================================================= |
106 // |
106 void Config::reset() |
107 void Config::reset() |
107 { |
108 { |
108 for (Config* cfg : g_configs) |
109 for (ConfigEntry* cfg : g_configs) |
109 cfg->resetValue(); |
110 cfg->resetValue(); |
110 } |
111 } |
111 |
112 |
112 // ============================================================================= |
113 // |
113 // Where is the configuration file located at? |
114 // Where is the configuration file located at? |
114 // ============================================================================= |
115 // |
115 String Config::filepath (String file) |
116 String Config::filepath (String file) |
116 { |
117 { |
117 return Config::dirpath() + DIRSLASH + file; |
118 return Config::dirpath() + DIRSLASH + file; |
118 } |
119 } |
119 |
120 |
120 // ============================================================================= |
121 // |
121 // Directory of the configuration file. |
122 // Directory of the configuration file. |
122 // ============================================================================= |
123 // |
123 String Config::dirpath() |
124 String Config::dirpath() |
124 { |
125 { |
125 QSettings* cfg = getSettingsObject(); |
126 QSettings* cfg = getSettingsObject(); |
126 return dirname (cfg->fileName()); |
127 return dirname (cfg->fileName()); |
127 } |
128 } |
128 |
129 |
129 // ============================================================================= |
130 // |
130 // We cannot just add config objects to a list or vector because that would rely |
131 // We cannot just add config objects to a list or vector because that would rely |
131 // on the vector's c-tor being called before the configs' c-tors. With global |
132 // on the vector's c-tor being called before the configs' c-tors. With global |
132 // variables we cannot assume that, therefore we need to use a C-style array here. |
133 // variables we cannot assume that, therefore we need to use a C-style array here. |
133 // ============================================================================= |
134 // |
134 void Config::addToArray (Config* ptr) |
135 void ConfigEntry::addToArray (ConfigEntry* ptr) |
135 { |
136 { |
136 if (g_cfgPointerCursor == 0) |
137 if (g_cfgPointerCursor == 0) |
137 memset (g_configPointers, 0, sizeof g_configPointers); |
138 memset (g_configPointers, 0, sizeof g_configPointers); |
138 |
139 |
139 assert (g_cfgPointerCursor < MAX_CONFIG); |
140 assert (g_cfgPointerCursor < MAX_CONFIG); |
140 g_configPointers[g_cfgPointerCursor++] = ptr; |
141 g_configPointers[g_cfgPointerCursor++] = ptr; |
141 } |
142 } |
142 |
143 |
143 // ============================================================================= |
144 template<typename T> |
144 // ============================================================================= |
145 T* getConfigByName (String name, ConfigEntry::Type type) |
145 template<class T> T* getConfigByName (String name, Config::Type type) |
|
146 { |
146 { |
147 auto it = g_configsByName.find (name); |
147 auto it = g_configsByName.find (name); |
148 |
148 |
149 if (it == g_configsByName.end()) |
149 if (it == g_configsByName.end()) |
150 return null; |
150 return null; |
151 |
151 |
152 Config* cfg = it.value(); |
152 ConfigEntry* cfg = it.value(); |
153 |
153 |
154 if (cfg->getType() != type) |
154 if (cfg->getType() != type) |
155 { |
155 { |
156 fprint (stderr, "type of %1 is %2, not %3\n", name, cfg->getType(), type); |
156 fprint (stderr, "type of %1 is %2, not %3\n", name, cfg->getType(), type); |
157 abort(); |
157 abort(); |
158 } |
158 } |
159 |
159 |
160 return reinterpret_cast<T*> (cfg); |
160 return reinterpret_cast<T*> (cfg); |
161 } |
161 } |
162 |
162 |
163 // ============================================================================= |
|
164 // ============================================================================= |
|
165 #undef IMPLEMENT_CONFIG |
163 #undef IMPLEMENT_CONFIG |
166 |
164 |
167 #define IMPLEMENT_CONFIG(NAME) \ |
165 #define IMPLEMENT_CONFIG(NAME) \ |
168 NAME##Config* NAME##Config::getByName (String name) \ |
166 NAME##ConfigEntry* NAME##ConfigEntry::getByName (String name) \ |
169 { \ |
167 { \ |
170 return getConfigByName<NAME##Config> (name, E##NAME##Type); \ |
168 return getConfigByName<NAME##ConfigEntry> (name, E##NAME##Type); \ |
171 } |
169 } |
172 |
170 |
173 IMPLEMENT_CONFIG (Int) |
171 IMPLEMENT_CONFIG (Int) |
174 IMPLEMENT_CONFIG (String) |
172 IMPLEMENT_CONFIG (String) |
175 IMPLEMENT_CONFIG (Bool) |
173 IMPLEMENT_CONFIG (Bool) |