diff --git a/hecl/include/hecl/CVar.hpp b/hecl/include/hecl/CVar.hpp index 05474f938..989c7ea6b 100644 --- a/hecl/include/hecl/CVar.hpp +++ b/hecl/include/hecl/CVar.hpp @@ -1,320 +1,320 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include - -namespace hecl { -namespace DNACVAR { -enum class EType : atUint8 { Boolean, Signed, Unsigned, Real, Literal, Vec2f, Vec2d, Vec3f, Vec3d, Vec4f, Vec4d }; - -enum class EFlags { - None = 0, - System = (1 << 0), - Game = (1 << 1), - Editor = (1 << 2), - Gui = (1 << 3), - Cheat = (1 << 4), - Hidden = (1 << 5), - ReadOnly = (1 << 6), - Archive = (1 << 7), - InternalArchivable = (1 << 8), - Modified = (1 << 9), - ModifyRestart = (1 << 10), //!< If this bit is set, any modification will inform the user that a restart is required - Color = (1 << 11), //!< If this bit is set, Vec3f and Vec4f will be displayed in the console with a colored square - NoDeveloper = (1 << 12), //!< Not even developer mode can modify this - Any = -1 -}; -ENABLE_BITWISE_ENUM(EFlags) - -class CVar : public athena::io::DNA { -public: - AT_DECL_DNA - String<-1> m_name; - String<-1> m_value; -}; - -struct CVarContainer : public athena::io::DNA { - AT_DECL_DNA - Value magic = 'CVAR'; - Value cvarCount; - Vector cvars; -}; - -} // namespace DNACVAR - -class CVarManager; -class CVar : protected DNACVAR::CVar { - friend class CVarManager; - Delete _d; - -public: - typedef std::function ListenerFunc; - - using EType = DNACVAR::EType; - using EFlags = DNACVAR::EFlags; - - CVar(std::string_view name, std::string_view value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec2f& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec2d& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec3f& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec3d& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec4d& value, std::string_view help, EFlags flags); - CVar(std::string_view name, double value, std::string_view help, EFlags flags); - CVar(std::string_view name, bool value, std::string_view help, EFlags flags); - CVar(std::string_view name, int32_t value, std::string_view help, EFlags flags); - CVar(std::string_view name, uint32_t value, std::string_view help, EFlags flags); - - std::string_view name() const { return m_name; } - std::string_view rawHelp() const { return m_help; } - std::string help() const; - std::string value() const { return m_value; } - - template - inline bool toValue(T& value) const; - atVec2f toVec2f(bool* isValid = nullptr) const; - atVec2d toVec2d(bool* isValid = nullptr) const; - atVec3f toVec3f(bool* isValid = nullptr) const; - atVec3d toVec3d(bool* isValid = nullptr) const; - atVec4f toVec4f(bool* isValid = nullptr) const; - atVec4d toVec4d(bool* isValid = nullptr) const; - double toReal(bool* isValid = nullptr) const; - bool toBoolean(bool* isValid = nullptr) const; - int32_t toSigned(bool* isValid = nullptr) const; - uint32_t toUnsigned(bool* isValid = nullptr) const; - std::wstring toWideLiteral(bool* isValid = nullptr) const; - std::string toLiteral(bool* isValid = nullptr) const; - - template - inline bool fromValue(T value) { - return false; - } - bool fromVec2f(const atVec2f& val); - bool fromVec2d(const atVec2d& val); - bool fromVec3f(const atVec3f& val); - bool fromVec3d(const atVec3d& val); - bool fromVec4f(const atVec4f& val); - bool fromVec4d(const atVec4d& val); - bool fromReal(double val); - bool fromBoolean(bool val); - bool fromInteger(int32_t val); - bool fromInteger(uint32_t val); - bool fromLiteral(std::string_view val); - bool fromLiteral(std::wstring_view val); - bool fromLiteralToType(std::string_view val); - bool fromLiteralToType(std::wstring_view val); - - bool isVec2f() const { return m_type == EType::Vec2f; } - bool isVec2d() const { return m_type == EType::Vec2d; } - bool isVec3f() const { return m_type == EType::Vec3f; } - bool isVec3d() const { return m_type == EType::Vec3d; } - bool isVec4f() const { return m_type == EType::Vec4f; } - bool isVec4d() const { return m_type == EType::Vec4d; } - bool isFloat() const { return m_type == EType::Real; } - bool isBoolean() const { return m_type == EType::Boolean; } - bool isInteger() const { return m_type == EType::Signed || m_type == EType::Unsigned; } - bool isLiteral() const { return m_type == EType::Literal; } - bool isModified() const; - bool modificationRequiresRestart() const; - bool isReadOnly() const; - bool isCheat() const; - bool isHidden() const; - bool isArchive() const; - bool isInternalArchivable() const; - bool isNoDeveloper() const; - bool isColor() const; - bool wasDeserialized() const; - bool hasDefaultValue() const; - - EType type() const { return m_type; } - EFlags flags() const { return (m_unlocked ? m_oldFlags : m_flags); } - - /*! - * \brief Unlocks the CVar for writing if it is ReadOnly. - * Handle with care!!! if you use unlock(), make sure - * you lock the cvar using lock() - * \see lock - */ - void unlock(); - - /*! - * \brief Locks the CVar to prevent writing if it is ReadOnly. - * Unlike its partner function unlock, lock is harmless - * \see unlock - */ - void lock(); - - void addListener(ListenerFunc func) { m_listeners.push_back(std::move(func)); } - - bool isValidInput(std::string_view input) const; - bool isValidInput(std::wstring_view input) const; - -private: - CVar(std::string_view name, std::string_view help, EType type) : m_help(help), m_type(type) { m_name = name; } - void dispatch(); - void clearModified(); - void setModified(); - std::string m_help; - EType m_type; - std::string m_defaultValue; - EFlags m_flags = EFlags::None; - EFlags m_oldFlags = EFlags::None; - bool m_unlocked = false; - bool m_wasDeserialized = false; - std::vector m_listeners; - bool safeToModify(EType type) const; - void init(EFlags flags, bool removeColor = true); -}; - -template <> -inline bool CVar::toValue(atVec2f& value) const { - bool isValid = false; - value = toVec2f(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(atVec2d& value) const { - bool isValid = false; - value = toVec2d(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(atVec3f& value) const { - bool isValid = false; - value = toVec3f(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(atVec3d& value) const { - bool isValid = false; - value = toVec3d(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(atVec4f& value) const { - bool isValid = false; - value = toVec4f(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(atVec4d& value) const { - bool isValid = false; - value = toVec4d(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(double& value) const { - bool isValid = false; - value = toReal(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(float& value) const { - bool isValid = false; - value = static_cast(toReal(&isValid)); - return isValid; -} -template <> -inline bool CVar::toValue(bool& value) const { - bool isValid = false; - value = toBoolean(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(int32_t& value) const { - bool isValid = false; - value = toSigned(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(uint32_t& value) const { - bool isValid = false; - value = toUnsigned(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(std::wstring& value) const { - bool isValid = false; - value = toWideLiteral(&isValid); - return isValid; -} -template <> -inline bool CVar::toValue(std::string& value) const { - bool isValid = false; - value = toLiteral(&isValid); - return isValid; -} - -template <> -inline bool CVar::fromValue(const atVec2f& val) { - return fromVec2f(val); -} -template <> -inline bool CVar::fromValue(const atVec2d& val) { - return fromVec2d(val); -} -template <> -inline bool CVar::fromValue(const atVec3f& val) { - return fromVec3f(val); -} -template <> -inline bool CVar::fromValue(const atVec3d& val) { - return fromVec3d(val); -} -template <> -inline bool CVar::fromValue(const atVec4f& val) { - return fromVec4f(val); -} -template <> -inline bool CVar::fromValue(const atVec4d& val) { - return fromVec4d(val); -} -template <> -inline bool CVar::fromValue(float val) { - return fromReal(val); -} -template <> -inline bool CVar::fromValue(double val) { - return fromReal(val); -} -template <> -inline bool CVar::fromValue(bool val) { - return fromBoolean(val); -} -template <> -inline bool CVar::fromValue(int32_t val) { - return fromInteger(val); -} -template <> -inline bool CVar::fromValue(uint32_t val) { - return fromInteger(val); -} -template <> -inline bool CVar::fromValue(std::string_view val) { - return fromLiteral(val); -} -template <> -inline bool CVar::fromValue(std::wstring_view val) { - return fromLiteral(val); -} - -class CVarUnlocker { - CVar* m_cvar; - -public: - CVarUnlocker(CVar* cvar) : m_cvar(cvar) { - if (m_cvar) - m_cvar->unlock(); - } - ~CVarUnlocker() { - if (m_cvar) - m_cvar->lock(); - } -}; - -} // namespace hecl +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace hecl { +namespace DNACVAR { +enum class EType : atUint8 { Boolean, Signed, Unsigned, Real, Literal, Vec2f, Vec2d, Vec3f, Vec3d, Vec4f, Vec4d }; + +enum class EFlags { + None = 0, + System = (1 << 0), + Game = (1 << 1), + Editor = (1 << 2), + Gui = (1 << 3), + Cheat = (1 << 4), + Hidden = (1 << 5), + ReadOnly = (1 << 6), + Archive = (1 << 7), + InternalArchivable = (1 << 8), + Modified = (1 << 9), + ModifyRestart = (1 << 10), //!< If this bit is set, any modification will inform the user that a restart is required + Color = (1 << 11), //!< If this bit is set, Vec3f and Vec4f will be displayed in the console with a colored square + NoDeveloper = (1 << 12), //!< Not even developer mode can modify this + Any = -1 +}; +ENABLE_BITWISE_ENUM(EFlags) + +class CVar : public athena::io::DNA { +public: + AT_DECL_DNA + String<-1> m_name; + String<-1> m_value; +}; + +struct CVarContainer : public athena::io::DNA { + AT_DECL_DNA + Value magic = 'CVAR'; + Value cvarCount; + Vector cvars; +}; + +} // namespace DNACVAR + +class CVarManager; +class CVar : protected DNACVAR::CVar { + friend class CVarManager; + Delete _d; + +public: + typedef std::function ListenerFunc; + + using EType = DNACVAR::EType; + using EFlags = DNACVAR::EFlags; + + CVar(std::string_view name, std::string_view value, std::string_view help, EFlags flags); + CVar(std::string_view name, const atVec2f& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const atVec2d& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const atVec3f& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const atVec3d& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const atVec4d& value, std::string_view help, EFlags flags); + CVar(std::string_view name, double value, std::string_view help, EFlags flags); + CVar(std::string_view name, bool value, std::string_view help, EFlags flags); + CVar(std::string_view name, int32_t value, std::string_view help, EFlags flags); + CVar(std::string_view name, uint32_t value, std::string_view help, EFlags flags); + + std::string_view name() const { return m_name; } + std::string_view rawHelp() const { return m_help; } + std::string help() const; + std::string value() const { return m_value; } + + template + inline bool toValue(T& value) const; + atVec2f toVec2f(bool* isValid = nullptr) const; + atVec2d toVec2d(bool* isValid = nullptr) const; + atVec3f toVec3f(bool* isValid = nullptr) const; + atVec3d toVec3d(bool* isValid = nullptr) const; + atVec4f toVec4f(bool* isValid = nullptr) const; + atVec4d toVec4d(bool* isValid = nullptr) const; + double toReal(bool* isValid = nullptr) const; + bool toBoolean(bool* isValid = nullptr) const; + int32_t toSigned(bool* isValid = nullptr) const; + uint32_t toUnsigned(bool* isValid = nullptr) const; + std::wstring toWideLiteral(bool* isValid = nullptr) const; + std::string toLiteral(bool* isValid = nullptr) const; + + template + inline bool fromValue(T value) { + return false; + } + bool fromVec2f(const atVec2f& val); + bool fromVec2d(const atVec2d& val); + bool fromVec3f(const atVec3f& val); + bool fromVec3d(const atVec3d& val); + bool fromVec4f(const atVec4f& val); + bool fromVec4d(const atVec4d& val); + bool fromReal(double val); + bool fromBoolean(bool val); + bool fromInteger(int32_t val); + bool fromInteger(uint32_t val); + bool fromLiteral(std::string_view val); + bool fromLiteral(std::wstring_view val); + bool fromLiteralToType(std::string_view val); + bool fromLiteralToType(std::wstring_view val); + + bool isVec2f() const { return m_type == EType::Vec2f; } + bool isVec2d() const { return m_type == EType::Vec2d; } + bool isVec3f() const { return m_type == EType::Vec3f; } + bool isVec3d() const { return m_type == EType::Vec3d; } + bool isVec4f() const { return m_type == EType::Vec4f; } + bool isVec4d() const { return m_type == EType::Vec4d; } + bool isFloat() const { return m_type == EType::Real; } + bool isBoolean() const { return m_type == EType::Boolean; } + bool isInteger() const { return m_type == EType::Signed || m_type == EType::Unsigned; } + bool isLiteral() const { return m_type == EType::Literal; } + bool isModified() const; + bool modificationRequiresRestart() const; + bool isReadOnly() const; + bool isCheat() const; + bool isHidden() const; + bool isArchive() const; + bool isInternalArchivable() const; + bool isNoDeveloper() const; + bool isColor() const; + bool wasDeserialized() const; + bool hasDefaultValue() const; + + EType type() const { return m_type; } + EFlags flags() const { return (m_unlocked ? m_oldFlags : m_flags); } + + /*! + * \brief Unlocks the CVar for writing if it is ReadOnly. + * Handle with care!!! if you use unlock(), make sure + * you lock the cvar using lock() + * \see lock + */ + void unlock(); + + /*! + * \brief Locks the CVar to prevent writing if it is ReadOnly. + * Unlike its partner function unlock, lock is harmless + * \see unlock + */ + void lock(); + + void addListener(ListenerFunc func) { m_listeners.push_back(std::move(func)); } + + bool isValidInput(std::string_view input) const; + bool isValidInput(std::wstring_view input) const; + +private: + CVar(std::string_view name, std::string_view help, EType type) : m_help(help), m_type(type) { m_name = name; } + void dispatch(); + void clearModified(); + void setModified(); + std::string m_help; + EType m_type; + std::string m_defaultValue; + EFlags m_flags = EFlags::None; + EFlags m_oldFlags = EFlags::None; + bool m_unlocked = false; + bool m_wasDeserialized = false; + std::vector m_listeners; + bool safeToModify(EType type) const; + void init(EFlags flags, bool removeColor = true); +}; + +template <> +inline bool CVar::toValue(atVec2f& value) const { + bool isValid = false; + value = toVec2f(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(atVec2d& value) const { + bool isValid = false; + value = toVec2d(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(atVec3f& value) const { + bool isValid = false; + value = toVec3f(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(atVec3d& value) const { + bool isValid = false; + value = toVec3d(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(atVec4f& value) const { + bool isValid = false; + value = toVec4f(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(atVec4d& value) const { + bool isValid = false; + value = toVec4d(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(double& value) const { + bool isValid = false; + value = toReal(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(float& value) const { + bool isValid = false; + value = static_cast(toReal(&isValid)); + return isValid; +} +template <> +inline bool CVar::toValue(bool& value) const { + bool isValid = false; + value = toBoolean(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(int32_t& value) const { + bool isValid = false; + value = toSigned(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(uint32_t& value) const { + bool isValid = false; + value = toUnsigned(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(std::wstring& value) const { + bool isValid = false; + value = toWideLiteral(&isValid); + return isValid; +} +template <> +inline bool CVar::toValue(std::string& value) const { + bool isValid = false; + value = toLiteral(&isValid); + return isValid; +} + +template <> +inline bool CVar::fromValue(const atVec2f& val) { + return fromVec2f(val); +} +template <> +inline bool CVar::fromValue(const atVec2d& val) { + return fromVec2d(val); +} +template <> +inline bool CVar::fromValue(const atVec3f& val) { + return fromVec3f(val); +} +template <> +inline bool CVar::fromValue(const atVec3d& val) { + return fromVec3d(val); +} +template <> +inline bool CVar::fromValue(const atVec4f& val) { + return fromVec4f(val); +} +template <> +inline bool CVar::fromValue(const atVec4d& val) { + return fromVec4d(val); +} +template <> +inline bool CVar::fromValue(float val) { + return fromReal(val); +} +template <> +inline bool CVar::fromValue(double val) { + return fromReal(val); +} +template <> +inline bool CVar::fromValue(bool val) { + return fromBoolean(val); +} +template <> +inline bool CVar::fromValue(int32_t val) { + return fromInteger(val); +} +template <> +inline bool CVar::fromValue(uint32_t val) { + return fromInteger(val); +} +template <> +inline bool CVar::fromValue(std::string_view val) { + return fromLiteral(val); +} +template <> +inline bool CVar::fromValue(std::wstring_view val) { + return fromLiteral(val); +} + +class CVarUnlocker { + CVar* m_cvar; + +public: + CVarUnlocker(CVar* cvar) : m_cvar(cvar) { + if (m_cvar) + m_cvar->unlock(); + } + ~CVarUnlocker() { + if (m_cvar) + m_cvar->lock(); + } +}; + +} // namespace hecl diff --git a/hecl/include/hecl/CVarManager.hpp b/hecl/include/hecl/CVarManager.hpp index 292ef3179..64b333841 100644 --- a/hecl/include/hecl/CVarManager.hpp +++ b/hecl/include/hecl/CVarManager.hpp @@ -1,120 +1,120 @@ -#pragma once - -#include -#include -#include -#include - -#include "hecl/CVar.hpp" -#include "hecl/SystemChar.hpp" - -namespace hecl { -namespace Runtime { -class FileStoreManager; -} -extern CVar* com_developer; -extern CVar* com_configfile; -extern CVar* com_enableCheats; -extern CVar* com_cubemaps; -class CVarManager final { - using CVarContainer = DNACVAR::CVarContainer; - template - CVar* _newCVar(std::string_view name, std::string_view help, const T& value, CVar::EFlags flags) { - if (CVar* ret = registerCVar(std::make_unique(name, value, help, flags))) { - deserialize(ret); - return ret; - } - return nullptr; - } - - hecl::Runtime::FileStoreManager& m_store; - bool m_useBinary; - static CVarManager* m_instance; - -public: - CVarManager() = delete; - CVarManager(const CVarManager&) = delete; - CVarManager& operator=(const CVarManager&) = delete; - CVarManager& operator=(const CVarManager&&) = delete; - CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary = false); - ~CVarManager(); - - CVar* newCVar(std::string_view name, std::string_view help, const atVec2f& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - CVar* newCVar(std::string_view name, std::string_view help, const atVec2d& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - CVar* newCVar(std::string_view name, std::string_view help, const atVec3f& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - CVar* newCVar(std::string_view name, std::string_view help, const atVec3d& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - CVar* newCVar(std::string_view name, std::string_view help, const atVec4f& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - CVar* newCVar(std::string_view name, std::string_view help, const atVec4d& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - CVar* newCVar(std::string_view name, std::string_view help, std::string_view value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - CVar* newCVar(std::string_view name, std::string_view help, bool value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - // Float and double are internally identical, all floating point values are stored as `double` - CVar* newCVar(std::string_view name, std::string_view help, float value, CVar::EFlags flags) { - return _newCVar(name, help, static_cast(value), flags); - } - CVar* newCVar(std::string_view name, std::string_view help, double value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - // Integer CVars can be seamlessly converted between either type, the distinction is to make usage absolutely clear - CVar* newCVar(std::string_view name, std::string_view help, int32_t value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - - CVar* newCVar(std::string_view name, std::string_view help, uint32_t value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); - } - - CVar* registerCVar(std::unique_ptr&& cvar); - - CVar* findCVar(std::string_view name); - template - CVar* findOrMakeCVar(std::string_view name, _Args&&... args) { - if (CVar* cv = findCVar(name)) - return cv; - return newCVar(name, std::forward<_Args>(args)...); - } - - std::vector archivedCVars() const; - std::vector cvars(CVar::EFlags filter = CVar::EFlags::Any) const; - - void deserialize(CVar* cvar); - void serialize(); - - static CVarManager* instance(); - - void proc(); - - void list(class Console* con, const std::vector& args); - void setCVar(class Console* con, const std::vector& args); - void getCVar(class Console* con, const std::vector& args); - - void setDeveloperMode(bool v, bool setDeserialized = false); - void setCheatsEnabled(bool v, bool setDeserialized = false); - bool restartRequired() const; - - void parseCommandLine(const std::vector& args); - -private: - bool suppressDeveloper(); - void restoreDeveloper(bool oldDeveloper); - - std::unordered_map> m_cvars; - std::unordered_map m_deferedCVars; -}; - -} // namespace hecl +#pragma once + +#include +#include +#include +#include + +#include "hecl/CVar.hpp" +#include "hecl/SystemChar.hpp" + +namespace hecl { +namespace Runtime { +class FileStoreManager; +} +extern CVar* com_developer; +extern CVar* com_configfile; +extern CVar* com_enableCheats; +extern CVar* com_cubemaps; +class CVarManager final { + using CVarContainer = DNACVAR::CVarContainer; + template + CVar* _newCVar(std::string_view name, std::string_view help, const T& value, CVar::EFlags flags) { + if (CVar* ret = registerCVar(std::make_unique(name, value, help, flags))) { + deserialize(ret); + return ret; + } + return nullptr; + } + + hecl::Runtime::FileStoreManager& m_store; + bool m_useBinary; + static CVarManager* m_instance; + +public: + CVarManager() = delete; + CVarManager(const CVarManager&) = delete; + CVarManager& operator=(const CVarManager&) = delete; + CVarManager& operator=(const CVarManager&&) = delete; + CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary = false); + ~CVarManager(); + + CVar* newCVar(std::string_view name, std::string_view help, const atVec2f& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + CVar* newCVar(std::string_view name, std::string_view help, const atVec2d& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + CVar* newCVar(std::string_view name, std::string_view help, const atVec3f& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + CVar* newCVar(std::string_view name, std::string_view help, const atVec3d& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + CVar* newCVar(std::string_view name, std::string_view help, const atVec4f& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + CVar* newCVar(std::string_view name, std::string_view help, const atVec4d& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + CVar* newCVar(std::string_view name, std::string_view help, std::string_view value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + CVar* newCVar(std::string_view name, std::string_view help, bool value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + // Float and double are internally identical, all floating point values are stored as `double` + CVar* newCVar(std::string_view name, std::string_view help, float value, CVar::EFlags flags) { + return _newCVar(name, help, static_cast(value), flags); + } + CVar* newCVar(std::string_view name, std::string_view help, double value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + // Integer CVars can be seamlessly converted between either type, the distinction is to make usage absolutely clear + CVar* newCVar(std::string_view name, std::string_view help, int32_t value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + + CVar* newCVar(std::string_view name, std::string_view help, uint32_t value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + + CVar* registerCVar(std::unique_ptr&& cvar); + + CVar* findCVar(std::string_view name); + template + CVar* findOrMakeCVar(std::string_view name, _Args&&... args) { + if (CVar* cv = findCVar(name)) + return cv; + return newCVar(name, std::forward<_Args>(args)...); + } + + std::vector archivedCVars() const; + std::vector cvars(CVar::EFlags filter = CVar::EFlags::Any) const; + + void deserialize(CVar* cvar); + void serialize(); + + static CVarManager* instance(); + + void proc(); + + void list(class Console* con, const std::vector& args); + void setCVar(class Console* con, const std::vector& args); + void getCVar(class Console* con, const std::vector& args); + + void setDeveloperMode(bool v, bool setDeserialized = false); + void setCheatsEnabled(bool v, bool setDeserialized = false); + bool restartRequired() const; + + void parseCommandLine(const std::vector& args); + +private: + bool suppressDeveloper(); + void restoreDeveloper(bool oldDeveloper); + + std::unordered_map> m_cvars; + std::unordered_map m_deferedCVars; +}; + +} // namespace hecl