3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "irrlichttypes_bloated.h"
23 #include "util/string.h"
24 #include "util/basic_macros.h"
34 extern Settings *g_settings; // Same as Settings::getLayer(SL_GLOBAL);
35 extern std::string g_settings_path;
37 // Type for a settings changed callback function
38 typedef void (*SettingsChangedCallback)(const std::string &name, void *data);
42 SettingsChangedCallback,
45 > SettingsCallbackList;
47 typedef std::unordered_map<std::string, SettingsCallbackList> SettingsCallbackMap;
51 VALUETYPE_FLAG // Doesn't take any arguments
54 enum SettingsParseEvent {
64 // Describes the global setting layers, SL_GLOBAL is where settings are read from
72 // Implements the hierarchy a settings object may be part of
73 class SettingsHierarchy {
76 * A settings object that may be part of another hierarchy can
77 * occupy the index 0 as a fallback. If not set you can use 0 on your own.
79 SettingsHierarchy(Settings *fallback = nullptr);
81 DISABLE_CLASS_COPY(SettingsHierarchy)
83 Settings *getLayer(int layer) const;
86 friend class Settings;
87 Settings *getParent(int layer) const;
88 void onLayerCreated(int layer, Settings *obj);
89 void onLayerRemoved(int layer);
91 std::vector<Settings*> layers;
95 ValueSpec(ValueType a_type, const char *a_help=NULL)
105 struct SettingsEntry {
106 SettingsEntry() = default;
108 SettingsEntry(const std::string &value_) :
112 SettingsEntry(Settings *group_) :
117 std::string value = "";
118 Settings *group = nullptr;
119 bool is_group = false;
122 typedef std::unordered_map<std::string, SettingsEntry> SettingEntries;
126 /* These functions operate on the global hierarchy! */
127 static Settings *createLayer(SettingsLayer sl, const std::string &end_tag = "");
128 static Settings *getLayer(SettingsLayer sl);
131 Settings(const std::string &end_tag = "") :
134 Settings(const std::string &end_tag, SettingsHierarchy *h, int settings_layer);
137 Settings & operator += (const Settings &other);
138 Settings & operator = (const Settings &other);
140 /***********************
141 * Reading and writing *
142 ***********************/
144 // Read configuration file. Returns success.
145 bool readConfigFile(const char *filename);
146 //Updates configuration file. Returns success.
147 bool updateConfigFile(const char *filename);
148 // NOTE: Types of allowed_options are ignored. Returns success.
149 bool parseCommandLine(int argc, char *argv[],
150 std::map<std::string, ValueSpec> &allowed_options);
151 bool parseConfigLines(std::istream &is);
152 void writeLines(std::ostream &os, u32 tab_depth=0) const;
158 Settings *getGroup(const std::string &name) const;
159 const std::string &get(const std::string &name) const;
160 bool getBool(const std::string &name) const;
161 u16 getU16(const std::string &name) const;
162 s16 getS16(const std::string &name) const;
163 u32 getU32(const std::string &name) const;
164 s32 getS32(const std::string &name) const;
165 u64 getU64(const std::string &name) const;
166 float getFloat(const std::string &name) const;
167 float getFloat(const std::string &name, float min, float max) const;
168 v2f getV2F(const std::string &name) const;
169 v3f getV3F(const std::string &name) const;
170 u32 getFlagStr(const std::string &name, const FlagDesc *flagdesc,
171 u32 *flagmask) const;
172 bool getNoiseParams(const std::string &name, NoiseParams &np) const;
173 bool getNoiseParamsFromValue(const std::string &name, NoiseParams &np) const;
174 bool getNoiseParamsFromGroup(const std::string &name, NoiseParams &np) const;
176 // return all keys used in this object
177 std::vector<std::string> getNames() const;
178 // check if setting exists anywhere in the hierarchy
179 bool exists(const std::string &name) const;
180 // check if setting exists in this object ("locally")
181 bool existsLocal(const std::string &name) const;
184 /***************************************
185 * Getters that don't throw exceptions *
186 ***************************************/
188 bool getGroupNoEx(const std::string &name, Settings *&val) const;
189 bool getNoEx(const std::string &name, std::string &val) const;
190 bool getFlag(const std::string &name) const;
191 bool getU16NoEx(const std::string &name, u16 &val) const;
192 bool getS16NoEx(const std::string &name, s16 &val) const;
193 bool getU32NoEx(const std::string &name, u32 &val) const;
194 bool getS32NoEx(const std::string &name, s32 &val) const;
195 bool getU64NoEx(const std::string &name, u64 &val) const;
196 bool getFloatNoEx(const std::string &name, float &val) const;
197 bool getV2FNoEx(const std::string &name, v2f &val) const;
198 bool getV3FNoEx(const std::string &name, v3f &val) const;
200 // Like other getters, but handling each flag individualy:
201 // 1) Read default flags (or 0)
202 // 2) Override using user-defined flags
203 bool getFlagStrNoEx(const std::string &name, u32 &val,
204 const FlagDesc *flagdesc) const;
211 // N.B. Groups not allocated with new must be set to NULL in the settings
212 // tree before object destruction.
213 bool setEntry(const std::string &name, const void *entry,
215 bool set(const std::string &name, const std::string &value);
216 bool setDefault(const std::string &name, const std::string &value);
217 bool setGroup(const std::string &name, const Settings &group);
218 bool setBool(const std::string &name, bool value);
219 bool setS16(const std::string &name, s16 value);
220 bool setU16(const std::string &name, u16 value);
221 bool setS32(const std::string &name, s32 value);
222 bool setU64(const std::string &name, u64 value);
223 bool setFloat(const std::string &name, float value);
224 bool setV2F(const std::string &name, v2f value);
225 bool setV3F(const std::string &name, v3f value);
226 bool setFlagStr(const std::string &name, u32 flags,
227 const FlagDesc *flagdesc = nullptr, u32 flagmask = U32_MAX);
228 bool setNoiseParams(const std::string &name, const NoiseParams &np);
231 bool remove(const std::string &name);
237 void setDefault(const std::string &name, const FlagDesc *flagdesc, u32 flags);
238 const FlagDesc *getFlagDescFallback(const std::string &name) const;
240 void registerChangedCallback(const std::string &name,
241 SettingsChangedCallback cbf, void *userdata = NULL);
242 void deregisterChangedCallback(const std::string &name,
243 SettingsChangedCallback cbf, void *userdata = NULL);
245 void removeSecureSettings();
247 // Returns the settings layer this object is.
248 // If within the global hierarchy you can cast this to enum SettingsLayer
249 inline int getLayer() const { return m_settingslayer; }
252 /***********************
253 * Reading and writing *
254 ***********************/
256 SettingsParseEvent parseConfigObject(const std::string &line,
257 std::string &name, std::string &value);
258 bool updateConfigObject(std::istream &is, std::ostream &os,
261 static bool checkNameValid(const std::string &name);
262 static bool checkValueValid(const std::string &value);
263 static std::string getMultiline(std::istream &is, size_t *num_lines=NULL);
264 static void printEntry(std::ostream &os, const std::string &name,
265 const SettingsEntry &entry, u32 tab_depth=0);
270 Settings *getParent() const;
272 const SettingsEntry &getEntry(const std::string &name) const;
274 // Allow TestSettings to run sanity checks using private functions.
275 friend class TestSettings;
276 // For sane mutex locking when iterating
277 friend class LuaSettings;
279 void updateNoLock(const Settings &other);
281 void clearDefaultsNoLock();
283 void doCallbacks(const std::string &name) const;
285 SettingEntries m_settings;
286 SettingsCallbackMap m_callbacks;
287 std::string m_end_tag;
289 mutable std::mutex m_callback_mutex;
291 // All methods that access m_settings/m_defaults directly should lock this.
292 mutable std::mutex m_mutex;
294 SettingsHierarchy *m_hierarchy = nullptr;
295 int m_settingslayer = -1;
297 static std::unordered_map<std::string, const FlagDesc *> s_flags;