123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768 |
- /*
- * Settings.h
- * ----------
- * Purpose: Header file for application setting handling framework.
- * Notes : (currently none)
- * Authors: Joern Heusipp
- * OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "../common/misc_util.h"
- #include "mpt/mutex/mutex.hpp"
- #include <map>
- #include <set>
- #include <variant>
- OPENMPT_NAMESPACE_BEGIN
- enum SettingType
- {
- SettingTypeNone,
- SettingTypeBool,
- SettingTypeInt,
- SettingTypeFloat,
- SettingTypeString,
- SettingTypeBinary,
- };
- // SettingValue is a variant type that stores any type that can natively be represented in a config backend.
- // Any other type that should be stored must provide a matching ToSettingValue and FromSettingValue.
- // Other types can optionally also set a type tag which would get checked in debug builds.
- class SettingValue
- {
- private:
- std::variant<std::monostate, bool, int32, double, mpt::ustring, std::vector<std::byte>> value;
- std::string typeTag;
- public:
- bool operator == (const SettingValue &other) const
- {
- return value == other.value && typeTag == other.typeTag;
- }
- bool operator != (const SettingValue &other) const
- {
- return !(*this == other);
- }
- SettingValue()
- {
- }
- SettingValue(const SettingValue &other)
- {
- *this = other;
- }
- SettingValue & operator = (const SettingValue &other)
- {
- if(this == &other)
- {
- return *this;
- }
- MPT_ASSERT(value.index() == 0 || (value.index() == other.value.index() && typeTag == other.typeTag));
- value = other.value;
- typeTag = other.typeTag;
- return *this;
- }
- SettingValue(bool val)
- : value(val)
- {
- }
- SettingValue(int32 val)
- : value(val)
- {
- }
- SettingValue(double val)
- : value(val)
- {
- }
- SettingValue(const mpt::ustring &val)
- : value(val)
- {
- }
- SettingValue(const std::vector<std::byte> &val)
- : value(val)
- {
- }
- SettingValue(bool val, const std::string &typeTag_)
- : value(val)
- , typeTag(typeTag_)
- {
- }
- SettingValue(int32 val, const std::string &typeTag_)
- : value(val)
- , typeTag(typeTag_)
- {
- }
- SettingValue(double val, const std::string &typeTag_)
- : value(val)
- , typeTag(typeTag_)
- {
- }
- SettingValue(const mpt::ustring &val, const std::string &typeTag_)
- : value(val)
- , typeTag(typeTag_)
- {
- }
- SettingValue(const std::vector<std::byte> &val, const std::string &typeTag_)
- : value(val)
- , typeTag(typeTag_)
- {
- }
- // these need to be explicitly deleted because otherwise the bool overload will catch the pointers
- SettingValue(const char *val) = delete;
- SettingValue(const wchar_t *val) = delete;
- SettingValue(const char *val, const std::string &typeTag_) = delete;
- SettingValue(const wchar_t *val, const std::string &typeTag_) = delete;
- SettingType GetType() const
- {
- SettingType result = SettingTypeNone;
- if(std::holds_alternative<bool>(value))
- {
- result = SettingTypeBool;
- }
- if(std::holds_alternative<int32>(value))
- {
- result = SettingTypeInt;
- }
- if(std::holds_alternative<double>(value))
- {
- result = SettingTypeFloat;
- }
- if(std::holds_alternative<mpt::ustring>(value))
- {
- result = SettingTypeString;
- }
- if(std::holds_alternative<std::vector<std::byte>>(value))
- {
- result = SettingTypeBinary;
- }
- return result;
- }
- bool HasTypeTag() const
- {
- return !typeTag.empty();
- }
- std::string GetTypeTag() const
- {
- return typeTag;
- }
- template <typename T>
- T as() const
- {
- return *this;
- }
- operator bool () const
- {
- MPT_ASSERT(std::holds_alternative<bool>(value));
- return std::get<bool>(value);
- }
- operator int32 () const
- {
- MPT_ASSERT(std::holds_alternative<int32>(value));
- return std::get<int32>(value);
- }
- operator double () const
- {
- MPT_ASSERT(std::holds_alternative<double>(value));
- return std::get<double>(value);
- }
- operator mpt::ustring () const
- {
- MPT_ASSERT(std::holds_alternative<mpt::ustring>(value));
- return std::get<mpt::ustring>(value);
- }
- operator std::vector<std::byte> () const
- {
- MPT_ASSERT(std::holds_alternative<std::vector<std::byte>>(value));
- return std::get<std::vector<std::byte>>(value);
- }
- mpt::ustring FormatTypeAsString() const;
- mpt::ustring FormatValueAsString() const;
- void SetFromString(const AnyStringLocale &newVal);
- };
- template<typename T>
- std::vector<std::byte> EncodeBinarySetting(const T &val)
- {
- std::vector<std::byte> result(sizeof(T));
- std::memcpy(result.data(), &val, sizeof(T));
- return result;
- }
- template<typename T>
- T DecodeBinarySetting(const std::vector<std::byte> &val)
- {
- T result = T();
- if(val.size() >= sizeof(T))
- {
- std::memcpy(&result, val.data(), sizeof(T));
- }
- return result;
- }
- template<typename T>
- inline SettingValue ToSettingValue(const T &val)
- {
- return SettingValue(val);
- }
- template<typename T>
- inline T FromSettingValue(const SettingValue &val)
- {
- return val.as<T>();
- }
- // To support settings.Read<Tcustom> and settings.Write<Tcustom>,
- // just provide specializations of ToSettingsValue<Tcustom> and FromSettingValue<Tcustom>.
- // You may use the SettingValue(value, typeTag) constructor in ToSettingValue
- // and check the typeTag FromSettingsValue to implement runtime type-checking for custom types.
- template<> inline SettingValue ToSettingValue(const std::string &val) { return SettingValue(mpt::ToUnicode(mpt::Charset::Locale, val)); }
- template<> inline std::string FromSettingValue(const SettingValue &val) { return mpt::ToCharset(mpt::Charset::Locale, val.as<mpt::ustring>()); }
- template<> inline SettingValue ToSettingValue(const mpt::lstring &val) { return SettingValue(mpt::ToUnicode(val)); }
- template<> inline mpt::lstring FromSettingValue(const SettingValue &val) { return mpt::ToLocale(val.as<mpt::ustring>()); }
- #if !MPT_USTRING_MODE_WIDE
- template<> inline SettingValue ToSettingValue(const std::wstring &val) { return SettingValue(mpt::ToUnicode(val)); }
- template<> inline std::wstring FromSettingValue(const SettingValue &val) { return mpt::ToWide(val.as<mpt::ustring>()); }
- #endif
- template<> inline SettingValue ToSettingValue(const CString &val) { return SettingValue(mpt::ToUnicode(val)); }
- template<> inline CString FromSettingValue(const SettingValue &val) { return mpt::ToCString(val.as<mpt::ustring>()); }
- template<> inline SettingValue ToSettingValue(const mpt::PathString &val) { return SettingValue(val.ToUnicode()); }
- template<> inline mpt::PathString FromSettingValue(const SettingValue &val) { return mpt::PathString::FromUnicode(val); }
- template<> inline SettingValue ToSettingValue(const float &val) { return SettingValue(double(val)); }
- template<> inline float FromSettingValue(const SettingValue &val) { return float(val.as<double>()); }
- template<> inline SettingValue ToSettingValue(const int64 &val) { return SettingValue(mpt::ufmt::dec(val), "int64"); }
- template<> inline int64 FromSettingValue(const SettingValue &val) { return ConvertStrTo<int64>(val.as<mpt::ustring>()); }
- template<> inline SettingValue ToSettingValue(const uint64 &val) { return SettingValue(mpt::ufmt::dec(val), "uint64"); }
- template<> inline uint64 FromSettingValue(const SettingValue &val) { return ConvertStrTo<uint64>(val.as<mpt::ustring>()); }
- template<> inline SettingValue ToSettingValue(const uint32 &val) { return SettingValue(int32(val)); }
- template<> inline uint32 FromSettingValue(const SettingValue &val) { return uint32(val.as<int32>()); }
- template<> inline SettingValue ToSettingValue(const uint16 &val) { return SettingValue(int32(val)); }
- template<> inline uint16 FromSettingValue(const SettingValue &val) { return uint16(val.as<int32>()); }
- template<> inline SettingValue ToSettingValue(const uint8 &val) { return SettingValue(int32(val)); }
- template<> inline uint8 FromSettingValue(const SettingValue &val) { return uint8(val.as<int32>()); }
- template<> inline SettingValue ToSettingValue(const LONG &val) { return SettingValue(int32(val)); }
- template<> inline LONG FromSettingValue(const SettingValue &val) { return LONG(val.as<int32>()); }
- // An instance of SetttingState represents the cached on-disk state of a certain SettingPath.
- // The mapping is stored externally in SettingsContainer::map.
- class SettingState
- {
- private:
- SettingValue value;
- const SettingValue defaultValue;
- bool dirty;
- public:
- SettingState()
- : dirty(false)
- {
- return;
- }
- SettingState(const SettingValue &def)
- : value(def)
- , defaultValue(def)
- , dirty(false)
- {
- return;
- }
- SettingState & assign(const SettingValue &other, bool setDirty = true)
- {
- MPT_ASSERT(defaultValue.GetType() == SettingTypeNone || (defaultValue.GetType() == other.GetType() && defaultValue.GetTypeTag() == other.GetTypeTag()));
- if(setDirty)
- {
- if(value != other)
- {
- value = other;
- dirty = true;
- }
- } else
- {
- value = other;
- }
- return *this;
- }
- SettingState & operator = (const SettingValue &val)
- {
- assign(val);
- return *this;
- }
- SettingValue GetDefault() const
- {
- return defaultValue;
- }
- const SettingValue &GetRefDefault() const
- {
- return defaultValue;
- }
- bool IsDefault() const
- {
- return value == defaultValue;
- }
- bool IsDirty() const
- {
- return dirty;
- }
- void Clean()
- {
- dirty = false;
- }
- SettingValue GetValue() const
- {
- return value;
- }
- const SettingValue &GetRefValue() const
- {
- return value;
- }
- operator SettingValue () const
- {
- return value;
- }
- };
- // SettingPath represents the path in a config backend to a certain setting.
- class SettingPath
- {
- private:
- mpt::ustring section;
- mpt::ustring key;
- public:
- SettingPath()
- {
- return;
- }
- SettingPath(mpt::ustring section_, mpt::ustring key_)
- : section(std::move(section_))
- , key(std::move(key_))
- {
- return;
- }
- mpt::ustring GetSection() const
- {
- return section;
- }
- mpt::ustring GetKey() const
- {
- return key;
- }
- const mpt::ustring &GetRefSection() const
- {
- return section;
- }
- const mpt::ustring &GetRefKey() const
- {
- return key;
- }
- int compare(const SettingPath &other) const
- {
- int cmp_section = section.compare(other.section);
- if(cmp_section)
- {
- return cmp_section;
- }
- int cmp_key = key.compare(other.key);
- return cmp_key;
- }
- mpt::ustring FormatAsString() const
- {
- return section + U_(".") + key;
- }
- };
- inline bool operator < (const SettingPath &left, const SettingPath &right) { return left.compare(right) < 0; }
- inline bool operator <= (const SettingPath &left, const SettingPath &right) { return left.compare(right) <= 0; }
- inline bool operator > (const SettingPath &left, const SettingPath &right) { return left.compare(right) > 0; }
- inline bool operator >= (const SettingPath &left, const SettingPath &right) { return left.compare(right) >= 0; }
- inline bool operator == (const SettingPath &left, const SettingPath &right) { return left.compare(right) == 0; }
- inline bool operator != (const SettingPath &left, const SettingPath &right) { return left.compare(right) != 0; }
- class ISettingsBackend
- {
- public:
- virtual SettingValue ReadSetting(const SettingPath &path, const SettingValue &def) const = 0;
- virtual void WriteSetting(const SettingPath &path, const SettingValue &val) = 0;
- virtual void RemoveSetting(const SettingPath &path) = 0;
- virtual void RemoveSection(const mpt::ustring §ion) = 0;
- protected:
- virtual ~ISettingsBackend() = default;
- };
- class ISettingChanged
- {
- public:
- virtual void SettingChanged(const SettingPath &changedPath) = 0;
- protected:
- virtual ~ISettingChanged() = default;
- };
- enum SettingFlushMode
- {
- SettingWriteBack = 0,
- SettingWriteThrough = 1,
- };
- // SettingContainer basically represents a frontend to 1 or 2 backends (e.g. ini files or registry subtrees) for a collection of configuration settings.
- // SettingContainer provides basic read/write access to individual setting. The values are cached and only flushed on destruction or explicit flushs.
- class SettingsContainer
- {
- public:
- using SettingsMap = std::map<SettingPath,SettingState>;
- using SettingsListenerMap = std::map<SettingPath,std::set<ISettingChanged*>>;
- void WriteSettings();
- private:
- mutable SettingsMap map;
- mutable SettingsListenerMap mapListeners;
- private:
- ISettingsBackend *backend;
- private:
- bool immediateFlush = false;
- SettingValue BackendsReadSetting(const SettingPath &path, const SettingValue &def) const;
- void BackendsWriteSetting(const SettingPath &path, const SettingValue &val);
- void BackendsRemoveSetting(const SettingPath &path);
- void BackendsRemoveSection(const mpt::ustring §ion);
- void NotifyListeners(const SettingPath &path);
- SettingValue ReadSetting(const SettingPath &path, const SettingValue &def) const;
- bool IsDefaultSetting(const SettingPath &path) const;
- void WriteSetting(const SettingPath &path, const SettingValue &val, SettingFlushMode flushMode);
- void ForgetSetting(const SettingPath &path);
- void RemoveSetting(const SettingPath &path);
- void RemoveSection(const mpt::ustring §ion);
- private:
- SettingsContainer(const SettingsContainer &other); // disable
- SettingsContainer& operator = (const SettingsContainer &other); // disable
- public:
- SettingsContainer(ISettingsBackend *backend);
- void SetImmediateFlush(bool newImmediateFlush);
- template <typename T>
- T Read(const SettingPath &path, const T &def = T()) const
- {
- return FromSettingValue<T>(ReadSetting(path, ToSettingValue<T>(def)));
- }
- template <typename T>
- T Read(mpt::ustring section, mpt::ustring key, const T &def = T()) const
- {
- return FromSettingValue<T>(ReadSetting(SettingPath(std::move(section), std::move(key)), ToSettingValue<T>(def)));
- }
- bool IsDefault(const SettingPath &path) const
- {
- return IsDefaultSetting(path);
- }
- bool IsDefault(mpt::ustring section, mpt::ustring key) const
- {
- return IsDefaultSetting(SettingPath(std::move(section), std::move(key)));
- }
- template <typename T>
- void Write(const SettingPath &path, const T &val, SettingFlushMode flushMode = SettingWriteBack)
- {
- WriteSetting(path, ToSettingValue<T>(val), flushMode);
- }
- template <typename T>
- void Write(mpt::ustring section, mpt::ustring key, const T &val, SettingFlushMode flushMode = SettingWriteBack)
- {
- WriteSetting(SettingPath(std::move(section), std::move(key)), ToSettingValue<T>(val), flushMode);
- }
- void Forget(const SettingPath &path)
- {
- ForgetSetting(path);
- }
- void Forget(mpt::ustring section, mpt::ustring key)
- {
- ForgetSetting(SettingPath(std::move(section), std::move(key)));
- }
- void ForgetAll();
- void Remove(const SettingPath &path)
- {
- RemoveSetting(path);
- }
- void Remove(mpt::ustring section, mpt::ustring key)
- {
- RemoveSetting(SettingPath(std::move(section), std::move(key)));
- }
- void Remove(const mpt::ustring §ion)
- {
- RemoveSection(section);
- }
- void Flush();
- ~SettingsContainer();
- public:
- void Register(ISettingChanged *listener, const SettingPath &path);
- void UnRegister(ISettingChanged *listener, const SettingPath &path);
- SettingsMap::const_iterator begin() const { return map.begin(); }
- SettingsMap::const_iterator end() const { return map.end(); }
- SettingsMap::size_type size() const { return map.size(); }
- bool empty() const { return map.empty(); }
- const SettingsMap &GetMap() const { return map; }
- };
- // Setting<T> and CachedSetting<T> are references to a SettingPath below a SettingConainer (both provided to the constructor).
- // They should mostly behave like normal non-reference variables of type T. I.e., they can be assigned to and read from.
- // As they have actual reference semantics, all Setting<T> or CachedSetting<T> that access the same path consistently have the same value.
- // The difference between the 2 lies in the way this consistency is achieved:
- // Setting<T>: The actual value is not stored in an instance of Setting<T>.
- // Instead, it is read/written and converted on every access from the SettingContainer.
- // In the SettingContainer, each SettingPath is mapped to a single instance of SettingValue, so there cannot be any incoherence.
- // CachedSetting<T>: The value, readily converted to T, is stored directly in each instance of CachedSetting<T>.
- // A callback for its SettingPath is registered with SettingContainer, and on every change to this SettingPath, the value gets re-read and updated.
- // Setting<T> implies some overhead on every access but is generally simpler to understand.
- // CachedSetting<T> implies overhead in stored (the copy of T and the callback pointers).
- // Except for the difference in runtime/space characteristics, Setting<T> and CachedSetting<T> behave exactly the same way.
- // It is recommended to only use CachedSetting<T> for settings that get read frequently, i.e. during GUI updates (like in the pattern view).
- template <typename T>
- class Setting
- {
- private:
- SettingsContainer &conf;
- const SettingPath path;
- public:
- Setting(const Setting &other) = delete;
- Setting & operator = (const Setting &other) = delete;
- public:
- Setting(SettingsContainer &conf_, mpt::ustring section, mpt::ustring key, const T&def)
- : conf(conf_)
- , path(std::move(section), std::move(key))
- {
- conf.Read(path, def); // set default value
- }
- Setting(SettingsContainer &conf_, const SettingPath &path_, const T&def)
- : conf(conf_)
- , path(path_)
- {
- conf.Read(path, def); // set default value
- }
- SettingPath GetPath() const
- {
- return path;
- }
- Setting & operator = (const T &val)
- {
- conf.Write(path, val);
- return *this;
- }
- operator T () const
- {
- return conf.Read<T>(path);
- }
- T Get() const
- {
- return conf.Read<T>(path);
- }
- bool IsDefault() const
- {
- return conf.IsDefault(path);
- }
- template<typename Trhs> Setting & operator += (const Trhs &rhs) { T tmp = *this; tmp += rhs; *this = tmp; return *this; }
- template<typename Trhs> Setting & operator -= (const Trhs &rhs) { T tmp = *this; tmp -= rhs; *this = tmp; return *this; }
- template<typename Trhs> Setting & operator *= (const Trhs &rhs) { T tmp = *this; tmp *= rhs; *this = tmp; return *this; }
- template<typename Trhs> Setting & operator /= (const Trhs &rhs) { T tmp = *this; tmp /= rhs; *this = tmp; return *this; }
- template<typename Trhs> Setting & operator %= (const Trhs &rhs) { T tmp = *this; tmp %= rhs; *this = tmp; return *this; }
- template<typename Trhs> Setting & operator |= (const Trhs &rhs) { T tmp = *this; tmp |= rhs; *this = tmp; return *this; }
- template<typename Trhs> Setting & operator &= (const Trhs &rhs) { T tmp = *this; tmp &= rhs; *this = tmp; return *this; }
- template<typename Trhs> Setting & operator ^= (const Trhs &rhs) { T tmp = *this; tmp ^= rhs; *this = tmp; return *this; }
- };
- template <typename T>
- class CachedSetting
- : public ISettingChanged
- {
- private:
- mutable mpt::mutex valueMutex;
- T value;
- SettingsContainer &conf;
- const SettingPath path;
- public:
- CachedSetting(const CachedSetting &other) = delete;
- CachedSetting & operator = (const CachedSetting &other) = delete;
- public:
- CachedSetting(SettingsContainer &conf_, mpt::ustring section, mpt::ustring key, const T&def)
- : value(def)
- , conf(conf_)
- , path(std::move(section), std::move(key))
- {
- {
- mpt::lock_guard<mpt::mutex> l(valueMutex);
- value = conf.Read(path, def);
- }
- conf.Register(this, path);
- }
- CachedSetting(SettingsContainer &conf_, const SettingPath &path_, const T&def)
- : value(def)
- , conf(conf_)
- , path(path_)
- {
- {
- mpt::lock_guard<mpt::mutex> l(valueMutex);
- value = conf.Read(path, def);
- }
- conf.Register(this, path);
- }
- ~CachedSetting()
- {
- conf.UnRegister(this, path);
- }
- SettingPath GetPath() const
- {
- return path;
- }
- CachedSetting & operator = (const T &val)
- {
- {
- mpt::lock_guard<mpt::mutex> l(valueMutex);
- value = val;
- }
- conf.Write(path, val);
- return *this;
- }
- operator T () const
- {
- mpt::lock_guard<mpt::mutex> l(valueMutex);
- return value;
- }
- T Get() const
- {
- mpt::lock_guard<mpt::mutex> l(valueMutex);
- return value;
- }
- bool IsDefault() const
- {
- return conf.IsDefault(path);
- }
- CachedSetting & Update()
- {
- {
- mpt::lock_guard<mpt::mutex> l(valueMutex);
- value = conf.Read<T>(path);
- }
- return *this;
- }
- void SettingChanged(const SettingPath &changedPath)
- {
- MPT_UNREFERENCED_PARAMETER(changedPath);
- Update();
- }
- template<typename Trhs> CachedSetting & operator += (const Trhs &rhs) { T tmp = *this; tmp += rhs; *this = tmp; return *this; }
- template<typename Trhs> CachedSetting & operator -= (const Trhs &rhs) { T tmp = *this; tmp -= rhs; *this = tmp; return *this; }
- template<typename Trhs> CachedSetting & operator *= (const Trhs &rhs) { T tmp = *this; tmp *= rhs; *this = tmp; return *this; }
- template<typename Trhs> CachedSetting & operator /= (const Trhs &rhs) { T tmp = *this; tmp /= rhs; *this = tmp; return *this; }
- template<typename Trhs> CachedSetting & operator %= (const Trhs &rhs) { T tmp = *this; tmp %= rhs; *this = tmp; return *this; }
- template<typename Trhs> CachedSetting & operator |= (const Trhs &rhs) { T tmp = *this; tmp |= rhs; *this = tmp; return *this; }
- template<typename Trhs> CachedSetting & operator &= (const Trhs &rhs) { T tmp = *this; tmp &= rhs; *this = tmp; return *this; }
- template<typename Trhs> CachedSetting & operator ^= (const Trhs &rhs) { T tmp = *this; tmp ^= rhs; *this = tmp; return *this; }
- };
- class IniFileSettingsBackend : public ISettingsBackend
- {
- private:
- const mpt::PathString filename;
- private:
- std::vector<std::byte> ReadSettingRaw(const SettingPath &path, const std::vector<std::byte> &def) const;
- mpt::ustring ReadSettingRaw(const SettingPath &path, const mpt::ustring &def) const;
- double ReadSettingRaw(const SettingPath &path, double def) const;
- int32 ReadSettingRaw(const SettingPath &path, int32 def) const;
- bool ReadSettingRaw(const SettingPath &path, bool def) const;
- void WriteSettingRaw(const SettingPath &path, const std::vector<std::byte> &val);
- void WriteSettingRaw(const SettingPath &path, const mpt::ustring &val);
- void WriteSettingRaw(const SettingPath &path, double val);
- void WriteSettingRaw(const SettingPath &path, int32 val);
- void WriteSettingRaw(const SettingPath &path, bool val);
- void RemoveSettingRaw(const SettingPath &path);
- void RemoveSectionRaw(const mpt::ustring §ion);
- static mpt::winstring GetSection(const SettingPath &path);
- static mpt::winstring GetKey(const SettingPath &path);
- public:
- IniFileSettingsBackend(const mpt::PathString &filename);
- ~IniFileSettingsBackend() override;
- void ConvertToUnicode(const mpt::ustring &backupTag = mpt::ustring());
- virtual SettingValue ReadSetting(const SettingPath &path, const SettingValue &def) const override;
- virtual void WriteSetting(const SettingPath &path, const SettingValue &val) override;
- virtual void RemoveSetting(const SettingPath &path) override;
- virtual void RemoveSection(const mpt::ustring §ion) override;
- const mpt::PathString& GetFilename() const { return filename; }
- };
- class IniFileSettingsContainer : private IniFileSettingsBackend, public SettingsContainer
- {
- public:
- IniFileSettingsContainer(const mpt::PathString &filename);
- ~IniFileSettingsContainer() override;
- };
- class DefaultSettingsContainer : public IniFileSettingsContainer
- {
- public:
- DefaultSettingsContainer();
- ~DefaultSettingsContainer() override;
- };
- class SettingChangedNotifyGuard
- {
- private:
- SettingsContainer &conf;
- SettingPath m_Path;
- bool m_Registered;
- ISettingChanged *m_Handler;
- public:
- SettingChangedNotifyGuard(SettingsContainer &conf, const SettingPath &path)
- : conf(conf)
- , m_Path(path)
- , m_Registered(false)
- , m_Handler(nullptr)
- {
- return;
- }
- void Register(ISettingChanged *handler)
- {
- if(m_Registered)
- {
- return;
- }
- m_Handler = handler;
- conf.Register(m_Handler, m_Path);
- m_Registered = true;
- }
- ~SettingChangedNotifyGuard()
- {
- if(m_Registered)
- {
- conf.UnRegister(m_Handler, m_Path);
- m_Registered = false;
- }
- }
- };
- OPENMPT_NAMESPACE_END
|