X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fsettings.h;h=b5e859ee0521111151812b4f62066c54138798f5;hb=0f74c7a977c412a81890926548e2a5c8dae5f6eb;hp=7241877bdb1093456eeb1637ed8522136c898b30;hpb=f2c18511a4a3c3cfdda3671d02f1b7468cb56405;p=dragonfireclient.git diff --git a/src/settings.h b/src/settings.h index 7241877bd..b5e859ee0 100644 --- a/src/settings.h +++ b/src/settings.h @@ -17,22 +17,33 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef SETTINGS_HEADER -#define SETTINGS_HEADER +#pragma once #include "irrlichttypes_bloated.h" #include "util/string.h" -#include "jthread/jmutex.h" #include -#include #include #include +#include class Settings; struct NoiseParams; -/** function type to register a changed callback */ -typedef void (*setting_changed_callback)(const std::string); +// Global objects +extern Settings *g_settings; // Same as Settings::getLayer(SL_GLOBAL); +extern std::string g_settings_path; + +// Type for a settings changed callback function +typedef void (*SettingsChangedCallback)(const std::string &name, void *data); + +typedef std::vector< + std::pair< + SettingsChangedCallback, + void * + > +> SettingsCallbackList; + +typedef std::unordered_map SettingsCallbackMap; enum ValueType { VALUETYPE_STRING, @@ -49,44 +60,53 @@ enum SettingsParseEvent { SPE_MULTILINE, }; +enum SettingsLayer { + SL_DEFAULTS, + SL_GAME, + SL_GLOBAL, + SL_MAP, + SL_TOTAL_COUNT +}; + struct ValueSpec { ValueSpec(ValueType a_type, const char *a_help=NULL) { type = a_type; help = a_help; } + ValueType type; const char *help; }; struct SettingsEntry { - SettingsEntry() - { - group = NULL; - is_group = false; - } + SettingsEntry() = default; - SettingsEntry(const std::string &value_) - { - value = value_; - group = NULL; - is_group = false; - } + SettingsEntry(const std::string &value_) : + value(value_) + {} - SettingsEntry(Settings *group_) - { - group = group_; - is_group = true; - } + SettingsEntry(Settings *group_) : + group(group_), + is_group(true) + {} - std::string value; - Settings *group; - bool is_group; + std::string value = ""; + Settings *group = nullptr; + bool is_group = false; }; +typedef std::unordered_map SettingEntries; + class Settings { public: - Settings() {} + static Settings *createLayer(SettingsLayer sl, const std::string &end_tag = ""); + static Settings *getLayer(SettingsLayer sl); + SettingsLayer getLayerType() const { return m_settingslayer; } + + Settings(const std::string &end_tag = "") : + m_end_tag(end_tag) + {} ~Settings(); Settings & operator += (const Settings &other); @@ -103,29 +123,19 @@ class Settings { // NOTE: Types of allowed_options are ignored. Returns success. bool parseCommandLine(int argc, char *argv[], std::map &allowed_options); - bool parseConfigLines(std::istream &is, const std::string &end = ""); + bool parseConfigLines(std::istream &is); void writeLines(std::ostream &os, u32 tab_depth=0) const; - SettingsParseEvent parseConfigObject(const std::string &line, - const std::string &end, std::string &name, std::string &value); - bool updateConfigObject(std::istream &is, std::ostream &os, - const std::string &end, u32 tab_depth=0); - - static std::string getMultiline(std::istream &is, size_t *num_lines=NULL); - static std::string sanitizeString(const std::string &value); - static void printEntry(std::ostream &os, const std::string &name, - const SettingsEntry &entry, u32 tab_depth=0); - /*********** * Getters * ***********/ - const SettingsEntry &getEntry(const std::string &name) const; Settings *getGroup(const std::string &name) const; - std::string get(const std::string &name) const; + const std::string &get(const std::string &name) const; bool getBool(const std::string &name) const; u16 getU16(const std::string &name) const; s16 getS16(const std::string &name) const; + u32 getU32(const std::string &name) const; s32 getS32(const std::string &name) const; u64 getU64(const std::string &name) const; float getFloat(const std::string &name) const; @@ -133,10 +143,6 @@ class Settings { v3f getV3F(const std::string &name) const; u32 getFlagStr(const std::string &name, const FlagDesc *flagdesc, u32 *flagmask) const; - // N.B. if getStruct() is used to read a non-POD aggregate type, - // the behavior is undefined. - bool getStruct(const std::string &name, const std::string &format, - void *out, size_t olen) const; bool getNoiseParams(const std::string &name, NoiseParams &np) const; bool getNoiseParamsFromValue(const std::string &name, NoiseParams &np) const; bool getNoiseParamsFromGroup(const std::string &name, NoiseParams &np) const; @@ -150,7 +156,6 @@ class Settings { * Getters that don't throw exceptions * ***************************************/ - bool getEntryNoEx(const std::string &name, SettingsEntry &val) const; bool getGroupNoEx(const std::string &name, Settings *&val) const; bool getNoEx(const std::string &name, std::string &val) const; bool getFlag(const std::string &name) const; @@ -161,10 +166,12 @@ class Settings { bool getFloatNoEx(const std::string &name, float &val) const; bool getV2FNoEx(const std::string &name, v2f &val) const; bool getV3FNoEx(const std::string &name, v3f &val) const; - // N.B. getFlagStrNoEx() does not set val, but merely modifies it. Thus, - // val must be initialized before using getFlagStrNoEx(). The intention of - // this is to simplify modifying a flags field from a default value. - bool getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const; + + // Like other getters, but handling each flag individualy: + // 1) Read default flags (or 0) + // 2) Override using user-defined flags + bool getFlagStrNoEx(const std::string &name, u32 &val, + const FlagDesc *flagdesc) const; /*********** @@ -173,48 +180,82 @@ class Settings { // N.B. Groups not allocated with new must be set to NULL in the settings // tree before object destruction. - void setEntry(const std::string &name, const void *entry, - bool set_group, bool set_default); - void set(const std::string &name, const std::string &value); - void setDefault(const std::string &name, const std::string &value); - void setGroup(const std::string &name, Settings *group); - void setGroupDefault(const std::string &name, Settings *group); - void setBool(const std::string &name, bool value); - void setS16(const std::string &name, s16 value); - void setU16(const std::string &name, u16 value); - void setS32(const std::string &name, s32 value); - void setU64(const std::string &name, u64 value); - void setFloat(const std::string &name, float value); - void setV2F(const std::string &name, v2f value); - void setV3F(const std::string &name, v3f value); - void setFlagStr(const std::string &name, u32 flags, - const FlagDesc *flagdesc, u32 flagmask); - void setNoiseParams(const std::string &name, const NoiseParams &np, - bool set_default=false); - // N.B. if setStruct() is used to write a non-POD aggregate type, - // the behavior is undefined. - bool setStruct(const std::string &name, const std::string &format, void *value); + bool setEntry(const std::string &name, const void *entry, + bool set_group); + bool set(const std::string &name, const std::string &value); + bool setDefault(const std::string &name, const std::string &value); + bool setGroup(const std::string &name, const Settings &group); + bool setBool(const std::string &name, bool value); + bool setS16(const std::string &name, s16 value); + bool setU16(const std::string &name, u16 value); + bool setS32(const std::string &name, s32 value); + bool setU64(const std::string &name, u64 value); + bool setFloat(const std::string &name, float value); + bool setV2F(const std::string &name, v2f value); + bool setV3F(const std::string &name, v3f value); + bool setFlagStr(const std::string &name, u32 flags, + const FlagDesc *flagdesc = nullptr, u32 flagmask = U32_MAX); + bool setNoiseParams(const std::string &name, const NoiseParams &np); // remove a setting bool remove(const std::string &name); - void clear(); - void updateValue(const Settings &other, const std::string &name); - void update(const Settings &other); - void registerChangedCallback(std::string name, setting_changed_callback cbf); + + /************** + * Miscellany * + **************/ + + void setDefault(const std::string &name, const FlagDesc *flagdesc, u32 flags); + const FlagDesc *getFlagDescFallback(const std::string &name) const; + + void registerChangedCallback(const std::string &name, + SettingsChangedCallback cbf, void *userdata = NULL); + void deregisterChangedCallback(const std::string &name, + SettingsChangedCallback cbf, void *userdata = NULL); + + void removeSecureSettings(); private: + /*********************** + * Reading and writing * + ***********************/ + + SettingsParseEvent parseConfigObject(const std::string &line, + std::string &name, std::string &value); + bool updateConfigObject(std::istream &is, std::ostream &os, + u32 tab_depth=0); + + static bool checkNameValid(const std::string &name); + static bool checkValueValid(const std::string &value); + static std::string getMultiline(std::istream &is, size_t *num_lines=NULL); + static void printEntry(std::ostream &os, const std::string &name, + const SettingsEntry &entry, u32 tab_depth=0); + + /*********** + * Getters * + ***********/ + Settings *getParent() const; + + const SettingsEntry &getEntry(const std::string &name) const; + + // Allow TestSettings to run sanity checks using private functions. + friend class TestSettings; void updateNoLock(const Settings &other); void clearNoLock(); + void clearDefaultsNoLock(); - void doCallbacks(std::string name); + void doCallbacks(const std::string &name) const; - std::map m_settings; - std::map m_defaults; - std::map > m_callbacks; - // All methods that access m_settings/m_defaults directly should lock this. - mutable JMutex m_mutex; -}; + SettingEntries m_settings; + SettingsCallbackMap m_callbacks; + std::string m_end_tag; -#endif + mutable std::mutex m_callback_mutex; + // All methods that access m_settings/m_defaults directly should lock this. + mutable std::mutex m_mutex; + + static Settings *s_layers[SL_TOTAL_COUNT]; + SettingsLayer m_settingslayer = SL_TOTAL_COUNT; + static std::unordered_map s_flags; +};