Line data Source code
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 "jthread/jmutex.h"
26 : #include <string>
27 : #include <map>
28 : #include <list>
29 : #include <set>
30 :
31 : class Settings;
32 : struct NoiseParams;
33 :
34 : // Global objects
35 : extern Settings *g_settings;
36 : extern std::string g_settings_path;
37 :
38 : /** function type to register a changed callback */
39 : typedef void (*setting_changed_callback)(const std::string, void*);
40 :
41 : enum ValueType {
42 : VALUETYPE_STRING,
43 : VALUETYPE_FLAG // Doesn't take any arguments
44 : };
45 :
46 : enum SettingsParseEvent {
47 : SPE_NONE,
48 : SPE_INVALID,
49 : SPE_COMMENT,
50 : SPE_KVPAIR,
51 : SPE_END,
52 : SPE_GROUP,
53 : SPE_MULTILINE,
54 : };
55 :
56 : struct ValueSpec {
57 23 : ValueSpec(ValueType a_type, const char *a_help=NULL)
58 : {
59 23 : type = a_type;
60 23 : help = a_help;
61 23 : }
62 :
63 : ValueType type;
64 : const char *help;
65 : };
66 :
67 3128 : struct SettingsEntry {
68 514 : SettingsEntry()
69 514 : {
70 514 : group = NULL;
71 514 : is_group = false;
72 514 : }
73 :
74 279 : SettingsEntry(const std::string &value_)
75 279 : {
76 279 : value = value_;
77 279 : group = NULL;
78 279 : is_group = false;
79 279 : }
80 :
81 0 : SettingsEntry(Settings *group_)
82 0 : {
83 0 : group = group_;
84 0 : is_group = true;
85 0 : }
86 :
87 : std::string value;
88 : Settings *group;
89 : bool is_group;
90 : };
91 :
92 : class Settings {
93 : public:
94 13 : Settings() {}
95 : ~Settings();
96 :
97 : Settings & operator += (const Settings &other);
98 : Settings & operator = (const Settings &other);
99 :
100 : /***********************
101 : * Reading and writing *
102 : ***********************/
103 :
104 : // Read configuration file. Returns success.
105 : bool readConfigFile(const char *filename);
106 : //Updates configuration file. Returns success.
107 : bool updateConfigFile(const char *filename);
108 : // NOTE: Types of allowed_options are ignored. Returns success.
109 : bool parseCommandLine(int argc, char *argv[],
110 : std::map<std::string, ValueSpec> &allowed_options);
111 : bool parseConfigLines(std::istream &is, const std::string &end = "");
112 : void writeLines(std::ostream &os, u32 tab_depth=0) const;
113 :
114 : SettingsParseEvent parseConfigObject(const std::string &line,
115 : const std::string &end, std::string &name, std::string &value);
116 : bool updateConfigObject(std::istream &is, std::ostream &os,
117 : const std::string &end, u32 tab_depth=0);
118 :
119 : static bool checkNameValid(const std::string &name);
120 : static bool checkValueValid(const std::string &value);
121 : static std::string sanitizeName(const std::string &name);
122 : static std::string sanitizeValue(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 : 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 : void registerChangedCallback(std::string name, setting_changed_callback cbf, void *userdata = NULL);
213 : void deregisterChangedCallback(std::string name, setting_changed_callback cbf, void *userdata = NULL);
214 :
215 : private:
216 :
217 : void updateNoLock(const Settings &other);
218 : void clearNoLock();
219 : void clearDefaultsNoLock();
220 :
221 : void doCallbacks(std::string name);
222 :
223 : std::map<std::string, SettingsEntry> m_settings;
224 : std::map<std::string, SettingsEntry> m_defaults;
225 :
226 : std::map<std::string, std::vector<std::pair<setting_changed_callback,void*> > > m_callbacks;
227 :
228 : mutable JMutex m_callbackMutex;
229 : mutable JMutex m_mutex; // All methods that access m_settings/m_defaults directly should lock this.
230 :
231 : };
232 :
233 : #endif
234 :
|