]> git.lizzy.rs Git - dragonfireclient.git/blob - src/settings.h
c4b94d67dcb82811c3c5c2d5d7cc81de82778b1f
[dragonfireclient.git] / src / settings.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #ifndef SETTINGS_HEADER
21 #define SETTINGS_HEADER
22
23 #include "irrlichttypes_bloated.h"
24 #include "util/string.h"
25 #include <string>
26 #include <list>
27 #include <set>
28 #include <mutex>
29
30 class Settings;
31 struct NoiseParams;
32
33 // Global objects
34 extern Settings *g_settings;
35 extern std::string g_settings_path;
36
37 // Type for a settings changed callback function
38 typedef void (*SettingsChangedCallback)(const std::string &name, void *data);
39
40 typedef std::vector<
41         std::pair<
42                 SettingsChangedCallback,
43                 void *
44         >
45 > SettingsCallbackList;
46
47 typedef std::unordered_map<std::string, SettingsCallbackList> SettingsCallbackMap;
48
49 enum ValueType {
50         VALUETYPE_STRING,
51         VALUETYPE_FLAG // Doesn't take any arguments
52 };
53
54 enum SettingsParseEvent {
55         SPE_NONE,
56         SPE_INVALID,
57         SPE_COMMENT,
58         SPE_KVPAIR,
59         SPE_END,
60         SPE_GROUP,
61         SPE_MULTILINE,
62 };
63
64 struct ValueSpec {
65         ValueSpec(ValueType a_type, const char *a_help=NULL)
66         {
67                 type = a_type;
68                 help = a_help;
69         }
70
71         ValueType type;
72         const char *help;
73 };
74
75 struct SettingsEntry {
76         SettingsEntry() {}
77
78         SettingsEntry(const std::string &value_) :
79                 value(value_)
80         {}
81
82         SettingsEntry(Settings *group_) :
83                 group(group_),
84                 is_group(true)
85         {}
86
87         std::string value = "";
88         Settings *group = nullptr;
89         bool is_group = false;
90 };
91
92 typedef std::unordered_map<std::string, SettingsEntry> SettingEntries;
93
94 class Settings {
95 public:
96         Settings() {}
97         ~Settings();
98
99         Settings & operator += (const Settings &other);
100         Settings & operator = (const Settings &other);
101
102         /***********************
103          * Reading and writing *
104          ***********************/
105
106         // Read configuration file.  Returns success.
107         bool readConfigFile(const char *filename);
108         //Updates configuration file.  Returns success.
109         bool updateConfigFile(const char *filename);
110         // NOTE: Types of allowed_options are ignored.  Returns success.
111         bool parseCommandLine(int argc, char *argv[],
112                         std::map<std::string, ValueSpec> &allowed_options);
113         bool parseConfigLines(std::istream &is, const std::string &end = "");
114         void writeLines(std::ostream &os, u32 tab_depth=0) const;
115
116         SettingsParseEvent parseConfigObject(const std::string &line,
117                 const std::string &end, std::string &name, std::string &value);
118         bool updateConfigObject(std::istream &is, std::ostream &os,
119                 const std::string &end, u32 tab_depth=0);
120
121         static bool checkNameValid(const std::string &name);
122         static bool checkValueValid(const std::string &value);
123         static std::string getMultiline(std::istream &is, size_t *num_lines=NULL);
124         static void printEntry(std::ostream &os, const std::string &name,
125                 const SettingsEntry &entry, u32 tab_depth=0);
126
127         /***********
128          * Getters *
129          ***********/
130
131         const SettingsEntry &getEntry(const std::string &name) const;
132         Settings *getGroup(const std::string &name) const;
133         const std::string &get(const std::string &name) const;
134         bool getBool(const std::string &name) const;
135         u16 getU16(const std::string &name) const;
136         s16 getS16(const std::string &name) const;
137         s32 getS32(const std::string &name) const;
138         u64 getU64(const std::string &name) const;
139         float getFloat(const std::string &name) const;
140         v2f getV2F(const std::string &name) const;
141         v3f getV3F(const std::string &name) const;
142         u32 getFlagStr(const std::string &name, const FlagDesc *flagdesc,
143                         u32 *flagmask) const;
144         // N.B. if getStruct() is used to read a non-POD aggregate type,
145         // the behavior is undefined.
146         bool getStruct(const std::string &name, const std::string &format,
147                         void *out, size_t olen) const;
148         bool getNoiseParams(const std::string &name, NoiseParams &np) const;
149         bool getNoiseParamsFromValue(const std::string &name, NoiseParams &np) const;
150         bool getNoiseParamsFromGroup(const std::string &name, NoiseParams &np) const;
151
152         // return all keys used
153         std::vector<std::string> getNames() const;
154         bool exists(const std::string &name) const;
155
156
157         /***************************************
158          * Getters that don't throw exceptions *
159          ***************************************/
160
161         bool getEntryNoEx(const std::string &name, SettingsEntry &val) const;
162         bool getGroupNoEx(const std::string &name, Settings *&val) const;
163         bool getNoEx(const std::string &name, std::string &val) const;
164         bool getFlag(const std::string &name) const;
165         bool getU16NoEx(const std::string &name, u16 &val) const;
166         bool getS16NoEx(const std::string &name, s16 &val) const;
167         bool getS32NoEx(const std::string &name, s32 &val) const;
168         bool getU64NoEx(const std::string &name, u64 &val) const;
169         bool getFloatNoEx(const std::string &name, float &val) const;
170         bool getV2FNoEx(const std::string &name, v2f &val) const;
171         bool getV3FNoEx(const std::string &name, v3f &val) const;
172         // N.B. getFlagStrNoEx() does not set val, but merely modifies it.  Thus,
173         // val must be initialized before using getFlagStrNoEx().  The intention of
174         // this is to simplify modifying a flags field from a default value.
175         bool getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const;
176
177
178         /***********
179          * Setters *
180          ***********/
181
182         // N.B. Groups not allocated with new must be set to NULL in the settings
183         // tree before object destruction.
184         bool setEntry(const std::string &name, const void *entry,
185                 bool set_group, bool set_default);
186         bool set(const std::string &name, const std::string &value);
187         bool setDefault(const std::string &name, const std::string &value);
188         bool setGroup(const std::string &name, Settings *group);
189         bool setGroupDefault(const std::string &name, Settings *group);
190         bool setBool(const std::string &name, bool value);
191         bool setS16(const std::string &name, s16 value);
192         bool setU16(const std::string &name, u16 value);
193         bool setS32(const std::string &name, s32 value);
194         bool setU64(const std::string &name, u64 value);
195         bool setFloat(const std::string &name, float value);
196         bool setV2F(const std::string &name, v2f value);
197         bool setV3F(const std::string &name, v3f value);
198         bool setFlagStr(const std::string &name, u32 flags,
199                 const FlagDesc *flagdesc, u32 flagmask);
200         bool setNoiseParams(const std::string &name, const NoiseParams &np,
201                 bool set_default=false);
202         // N.B. if setStruct() is used to write a non-POD aggregate type,
203         // the behavior is undefined.
204         bool setStruct(const std::string &name, const std::string &format, void *value);
205
206         // remove a setting
207         bool remove(const std::string &name);
208         void clear();
209         void clearDefaults();
210         void updateValue(const Settings &other, const std::string &name);
211         void update(const Settings &other);
212
213         void registerChangedCallback(const std::string &name,
214                 SettingsChangedCallback cbf, void *userdata = NULL);
215         void deregisterChangedCallback(const std::string &name,
216                 SettingsChangedCallback cbf, void *userdata = NULL);
217
218 private:
219         void updateNoLock(const Settings &other);
220         void clearNoLock();
221         void clearDefaultsNoLock();
222
223         void doCallbacks(const std::string &name) const;
224
225         SettingEntries m_settings;
226         SettingEntries m_defaults;
227
228         SettingsCallbackMap m_callbacks;
229
230         mutable std::mutex m_callback_mutex;
231
232         // All methods that access m_settings/m_defaults directly should lock this.
233         mutable std::mutex m_mutex;
234
235 };
236
237 #endif
238