]> git.lizzy.rs Git - minetest.git/blob - src/settings.h
Add keybind to swap items between hands
[minetest.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 "util/basic_macros.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; // Same as Settings::getLayer(SL_GLOBAL);
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 // Describes the global setting layers, SL_GLOBAL is where settings are read from
65 enum SettingsLayer {
66         SL_DEFAULTS,
67         SL_GAME,
68         SL_GLOBAL,
69         SL_TOTAL_COUNT
70 };
71
72 // Implements the hierarchy a settings object may be part of
73 class SettingsHierarchy {
74 public:
75         /*
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.
78          */
79         SettingsHierarchy(Settings *fallback = nullptr);
80
81         DISABLE_CLASS_COPY(SettingsHierarchy)
82
83         Settings *getLayer(int layer) const;
84
85 private:
86         friend class Settings;
87         Settings *getParent(int layer) const;
88         void onLayerCreated(int layer, Settings *obj);
89         void onLayerRemoved(int layer);
90
91         std::vector<Settings*> layers;
92 };
93
94 struct ValueSpec {
95         ValueSpec(ValueType a_type, const char *a_help=NULL)
96         {
97                 type = a_type;
98                 help = a_help;
99         }
100
101         ValueType type;
102         const char *help;
103 };
104
105 struct SettingsEntry {
106         SettingsEntry() = default;
107
108         SettingsEntry(const std::string &value_) :
109                 value(value_)
110         {}
111
112         SettingsEntry(Settings *group_) :
113                 group(group_),
114                 is_group(true)
115         {}
116
117         std::string value = "";
118         Settings *group = nullptr;
119         bool is_group = false;
120 };
121
122 typedef std::unordered_map<std::string, SettingsEntry> SettingEntries;
123
124 class Settings {
125 public:
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);
129         /**/
130
131         Settings(const std::string &end_tag = "") :
132                 m_end_tag(end_tag)
133         {}
134         Settings(const std::string &end_tag, SettingsHierarchy *h, int settings_layer);
135         ~Settings();
136
137         Settings & operator += (const Settings &other);
138         Settings & operator = (const Settings &other);
139
140         /***********************
141          * Reading and writing *
142          ***********************/
143
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;
153
154         /***********
155          * Getters *
156          ***********/
157
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;
175
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;
182
183
184         /***************************************
185          * Getters that don't throw exceptions *
186          ***************************************/
187
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;
199
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;
205
206
207         /***********
208          * Setters *
209          ***********/
210
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,
214                 bool set_group);
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);
229
230         // remove a setting
231         bool remove(const std::string &name);
232
233         /*****************
234          * Miscellaneous *
235          *****************/
236
237         void setDefault(const std::string &name, const FlagDesc *flagdesc, u32 flags);
238         const FlagDesc *getFlagDescFallback(const std::string &name) const;
239
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);
244
245         void removeSecureSettings();
246
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; }
250
251 private:
252         /***********************
253          * Reading and writing *
254          ***********************/
255
256         SettingsParseEvent parseConfigObject(const std::string &line,
257                 std::string &name, std::string &value);
258         bool updateConfigObject(std::istream &is, std::ostream &os,
259                 u32 tab_depth=0);
260
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);
266
267         /***********
268          * Getters *
269          ***********/
270         Settings *getParent() const;
271
272         const SettingsEntry &getEntry(const std::string &name) const;
273
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;
278
279         void updateNoLock(const Settings &other);
280         void clearNoLock();
281         void clearDefaultsNoLock();
282
283         void doCallbacks(const std::string &name) const;
284
285         SettingEntries m_settings;
286         SettingsCallbackMap m_callbacks;
287         std::string m_end_tag;
288
289         mutable std::mutex m_callback_mutex;
290
291         // All methods that access m_settings/m_defaults directly should lock this.
292         mutable std::mutex m_mutex;
293
294         SettingsHierarchy *m_hierarchy = nullptr;
295         int m_settingslayer = -1;
296
297         static std::unordered_map<std::string, const FlagDesc *> s_flags;
298 };