]> git.lizzy.rs Git - dragonfireclient.git/blob - src/settings.h
Merge branch 'master' into master
[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 #pragma once
21
22 #include "irrlichttypes_bloated.h"
23 #include "util/string.h"
24 #include <string>
25 #include <list>
26 #include <set>
27 #include <mutex>
28
29 class Settings;
30 struct NoiseParams;
31
32 // Global objects
33 extern Settings *g_settings;
34 extern std::string g_settings_path;
35
36 // Type for a settings changed callback function
37 typedef void (*SettingsChangedCallback)(const std::string &name, void *data);
38
39 typedef std::vector<std::pair<SettingsChangedCallback, void *>> SettingsCallbackList;
40
41 typedef std::unordered_map<std::string, SettingsCallbackList> SettingsCallbackMap;
42
43 enum ValueType
44 {
45         VALUETYPE_STRING,
46         VALUETYPE_FLAG // Doesn't take any arguments
47 };
48
49 enum SettingsParseEvent
50 {
51         SPE_NONE,
52         SPE_INVALID,
53         SPE_COMMENT,
54         SPE_KVPAIR,
55         SPE_END,
56         SPE_GROUP,
57         SPE_MULTILINE,
58 };
59
60 struct ValueSpec
61 {
62         ValueSpec(ValueType a_type, const char *a_help = NULL)
63         {
64                 type = a_type;
65                 help = a_help;
66         }
67
68         ValueType type;
69         const char *help;
70 };
71
72 struct SettingsEntry
73 {
74         SettingsEntry() = default;
75
76         SettingsEntry(const std::string &value_) : value(value_) {}
77
78         SettingsEntry(Settings *group_) : group(group_), is_group(true) {}
79
80         std::string value = "";
81         Settings *group = nullptr;
82         bool is_group = false;
83 };
84
85 typedef std::unordered_map<std::string, SettingsEntry> SettingEntries;
86
87 class Settings
88 {
89 public:
90         Settings() = default;
91
92         ~Settings();
93
94         Settings &operator+=(const Settings &other);
95         Settings &operator=(const Settings &other);
96
97         /***********************
98          * Reading and writing *
99          ***********************/
100
101         // Read configuration file.  Returns success.
102         bool readConfigFile(const char *filename);
103         // Updates configuration file.  Returns success.
104         bool updateConfigFile(const char *filename);
105         // NOTE: Types of allowed_options are ignored.  Returns success.
106         bool parseCommandLine(int argc, char *argv[],
107                         std::map<std::string, ValueSpec> &allowed_options);
108         bool parseConfigLines(std::istream &is, const std::string &end = "");
109         void writeLines(std::ostream &os, u32 tab_depth = 0) const;
110
111         SettingsParseEvent parseConfigObject(const std::string &line,
112                         const std::string &end, std::string &name, std::string &value);
113         bool updateConfigObject(std::istream &is, std::ostream &os,
114                         const std::string &end, u32 tab_depth = 0);
115
116         static bool checkNameValid(const std::string &name);
117         static bool checkValueValid(const std::string &value);
118         static std::string getMultiline(std::istream &is, size_t *num_lines = NULL);
119         static void printEntry(std::ostream &os, const std::string &name,
120                         const SettingsEntry &entry, u32 tab_depth = 0);
121
122         /***********
123          * Getters *
124          ***********/
125
126         const SettingsEntry &getEntry(const std::string &name) const;
127         const SettingsEntry &getEntryDefault(const std::string &name) const;
128         Settings *getGroup(const std::string &name) const;
129         const std::string &get(const std::string &name) const;
130         const std::string &getDefault(const std::string &name) const;
131         bool getBool(const std::string &name) const;
132         u16 getU16(const std::string &name) const;
133         s16 getS16(const std::string &name) const;
134         u32 getU32(const std::string &name) const;
135         s32 getS32(const std::string &name) const;
136         u64 getU64(const std::string &name) const;
137         float getFloat(const std::string &name) const;
138         v2f getV2F(const std::string &name) const;
139         v3f getV3F(const std::string &name) const;
140         u32 getFlagStr(const std::string &name, const FlagDesc *flagdesc,
141                         u32 *flagmask) const;
142         // N.B. if getStruct() is used to read a non-POD aggregate type,
143         // the behavior is undefined.
144         bool getStruct(const std::string &name, const std::string &format, void *out,
145                         size_t olen) const;
146         bool getNoiseParams(const std::string &name, NoiseParams &np) const;
147         bool getNoiseParamsFromValue(const std::string &name, NoiseParams &np) const;
148         bool getNoiseParamsFromGroup(const std::string &name, NoiseParams &np) const;
149
150         // return all keys used
151         std::vector<std::string> getNames() const;
152         bool exists(const std::string &name) const;
153
154         /***************************************
155          * Getters that don't throw exceptions *
156          ***************************************/
157
158         bool getEntryNoEx(const std::string &name, SettingsEntry &val) const;
159         bool getEntryDefaultNoEx(const std::string &name, SettingsEntry &val) const;
160         bool getGroupNoEx(const std::string &name, Settings *&val) const;
161         bool getNoEx(const std::string &name, std::string &val) const;
162         bool getDefaultNoEx(const std::string &name, std::string &val) const;
163         bool getFlag(const std::string &name) const;
164         bool getU16NoEx(const std::string &name, u16 &val) const;
165         bool getS16NoEx(const std::string &name, s16 &val) const;
166         bool getS32NoEx(const std::string &name, s32 &val) const;
167         bool getU64NoEx(const std::string &name, u64 &val) const;
168         bool getFloatNoEx(const std::string &name, float &val) const;
169         bool getV2FNoEx(const std::string &name, v2f &val) const;
170         bool getV3FNoEx(const std::string &name, v3f &val) const;
171
172         // Like other getters, but handling each flag individualy:
173         // 1) Read default flags (or 0)
174         // 2) Override using user-defined flags
175         bool getFlagStrNoEx(const std::string &name, u32 &val,
176                         const FlagDesc *flagdesc) const;
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, bool set_group,
185                         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 = nullptr, u32 flagmask = U32_MAX);
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         /**************
214          * Miscellany *
215          **************/
216
217         void setDefault(const std::string &name, const FlagDesc *flagdesc, u32 flags);
218         // Takes the provided setting values and uses them as new defaults
219         void overrideDefaults(Settings *other);
220         const FlagDesc *getFlagDescFallback(const std::string &name) const;
221
222         void registerChangedCallback(const std::string &name, SettingsChangedCallback cbf,
223                         void *userdata = NULL);
224         void deregisterChangedCallback(const std::string &name,
225                         SettingsChangedCallback cbf, void *userdata = NULL);
226
227 private:
228         void updateNoLock(const Settings &other);
229         void clearNoLock();
230         void clearDefaultsNoLock();
231
232         void doCallbacks(const std::string &name) const;
233
234         SettingEntries m_settings;
235         SettingEntries m_defaults;
236         std::unordered_map<std::string, const FlagDesc *> m_flags;
237
238         SettingsCallbackMap m_callbacks;
239
240         mutable std::mutex m_callback_mutex;
241
242         // All methods that access m_settings/m_defaults directly should lock this.
243         mutable std::mutex m_mutex;
244 };