]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/settings.h
upright_sprite: Fix walk animation in first person (#12194)
[dragonfireclient.git] / src / settings.h
index 0c9a155db4f0ac258259166a13f8a3311490db65..767d057f9c1b77eb4b11e7fe4095121a32eb0aa3 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "irrlichttypes_bloated.h"
 #include "util/string.h"
+#include "util/basic_macros.h"
 #include <string>
 #include <list>
 #include <set>
@@ -30,7 +31,7 @@ class Settings;
 struct NoiseParams;
 
 // Global objects
-extern Settings *g_settings;
+extern Settings *g_settings; // Same as Settings::getLayer(SL_GLOBAL);
 extern std::string g_settings_path;
 
 // Type for a settings changed callback function
@@ -60,6 +61,36 @@ enum SettingsParseEvent {
        SPE_MULTILINE,
 };
 
+// Describes the global setting layers, SL_GLOBAL is where settings are read from
+enum SettingsLayer {
+       SL_DEFAULTS,
+       SL_GAME,
+       SL_GLOBAL,
+       SL_TOTAL_COUNT
+};
+
+// Implements the hierarchy a settings object may be part of
+class SettingsHierarchy {
+public:
+       /*
+        * A settings object that may be part of another hierarchy can
+        * occupy the index 0 as a fallback. If not set you can use 0 on your own.
+        */
+       SettingsHierarchy(Settings *fallback = nullptr);
+
+       DISABLE_CLASS_COPY(SettingsHierarchy)
+
+       Settings *getLayer(int layer) const;
+
+private:
+       friend class Settings;
+       Settings *getParent(int layer) const;
+       void onLayerCreated(int layer, Settings *obj);
+       void onLayerRemoved(int layer);
+
+       std::vector<Settings*> layers;
+};
+
 struct ValueSpec {
        ValueSpec(ValueType a_type, const char *a_help=NULL)
        {
@@ -92,8 +123,15 @@ typedef std::unordered_map<std::string, SettingsEntry> SettingEntries;
 
 class Settings {
 public:
-       Settings() = default;
+       /* These functions operate on the global hierarchy! */
+       static Settings *createLayer(SettingsLayer sl, const std::string &end_tag = "");
+       static Settings *getLayer(SettingsLayer sl);
+       /**/
 
+       Settings(const std::string &end_tag = "") :
+               m_end_tag(end_tag)
+       {}
+       Settings(const std::string &end_tag, SettingsHierarchy *h, int settings_layer);
        ~Settings();
 
        Settings & operator += (const Settings &other);
@@ -110,29 +148,15 @@ class Settings {
        // NOTE: Types of allowed_options are ignored.  Returns success.
        bool parseCommandLine(int argc, char *argv[],
                        std::map<std::string, ValueSpec> &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 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 *
         ***********/
 
-       const SettingsEntry &getEntry(const std::string &name) const;
-       const SettingsEntry &getEntryDefault(const std::string &name) const;
        Settings *getGroup(const std::string &name) const;
        const std::string &get(const std::string &name) const;
-       const std::string &getDefault(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;
@@ -144,31 +168,28 @@ 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;
 
-       // return all keys used
+       // return all keys used in this object
        std::vector<std::string> getNames() const;
+       // check if setting exists anywhere in the hierarchy
        bool exists(const std::string &name) const;
+       // check if setting exists in this object ("locally")
+       bool existsLocal(const std::string &name) const;
 
 
        /***************************************
         * Getters that don't throw exceptions *
         ***************************************/
 
-       bool getEntryNoEx(const std::string &name, SettingsEntry &val) const;
-       bool getEntryDefaultNoEx(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 getDefaultNoEx(const std::string &name, std::string &val) const;
        bool getFlag(const std::string &name) const;
        bool getU16NoEx(const std::string &name, u16 &val) const;
        bool getS16NoEx(const std::string &name, s16 &val) const;
+       bool getU32NoEx(const std::string &name, u32 &val) const;
        bool getS32NoEx(const std::string &name, s32 &val) const;
        bool getU64NoEx(const std::string &name, u64 &val) const;
        bool getFloatNoEx(const std::string &name, float &val) const;
@@ -189,11 +210,10 @@ class Settings {
        // N.B. Groups not allocated with new must be set to NULL in the settings
        // tree before object destruction.
        bool setEntry(const std::string &name, const void *entry,
-               bool set_group, bool set_default);
+               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, Settings *group);
-       bool setGroupDefault(const std::string &name, Settings *group);
+       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);
@@ -204,26 +224,16 @@ class Settings {
        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,
-               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 setNoiseParams(const std::string &name, const NoiseParams &np);
 
        // remove a setting
        bool remove(const std::string &name);
-       void clear();
-       void clearDefaults();
-       void updateValue(const Settings &other, const std::string &name);
-       void update(const Settings &other);
 
-       /**************
-        * Miscellany *
-        **************/
+       /*****************
+        * Miscellaneous *
+        *****************/
 
        void setDefault(const std::string &name, const FlagDesc *flagdesc, u32 flags);
-       // Takes the provided setting values and uses them as new defaults
-       void overrideDefaults(Settings *other);
        const FlagDesc *getFlagDescFallback(const std::string &name) const;
 
        void registerChangedCallback(const std::string &name,
@@ -231,7 +241,40 @@ class Settings {
        void deregisterChangedCallback(const std::string &name,
                SettingsChangedCallback cbf, void *userdata = NULL);
 
+       void removeSecureSettings();
+
+       // Returns the settings layer this object is.
+       // If within the global hierarchy you can cast this to enum SettingsLayer
+       inline int getLayer() const { return m_settingslayer; }
+
 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;
+       // For sane mutex locking when iterating
+       friend class LuaSettings;
+
        void updateNoLock(const Settings &other);
        void clearNoLock();
        void clearDefaultsNoLock();
@@ -239,14 +282,16 @@ class Settings {
        void doCallbacks(const std::string &name) const;
 
        SettingEntries m_settings;
-       SettingEntries m_defaults;
-       std::unordered_map<std::string, const FlagDesc *> m_flags;
-
        SettingsCallbackMap m_callbacks;
+       std::string m_end_tag;
 
        mutable std::mutex m_callback_mutex;
 
        // All methods that access m_settings/m_defaults directly should lock this.
        mutable std::mutex m_mutex;
 
+       SettingsHierarchy *m_hierarchy = nullptr;
+       int m_settingslayer = -1;
+
+       static std::unordered_map<std::string, const FlagDesc *> s_flags;
 };