mirror of https://github.com/AxioDL/metaforce.git
Various fixes and improvements to CVars
This commit is contained in:
parent
e80d0319fa
commit
7fd54effc9
|
@ -10,10 +10,10 @@
|
||||||
|
|
||||||
namespace hecl {
|
namespace hecl {
|
||||||
namespace DNACVAR {
|
namespace DNACVAR {
|
||||||
enum class EType : atUint8 { Boolean, Integer, Float, Literal, Vec4f };
|
enum class EType : atUint8 { Boolean, Signed, Unsigned, Real, Literal, Vec2f, Vec2d, Vec3f, Vec3d, Vec4f, Vec4d };
|
||||||
|
|
||||||
enum EFlags {
|
enum class EFlags {
|
||||||
None = -1,
|
None = 0,
|
||||||
System = (1 << 0),
|
System = (1 << 0),
|
||||||
Game = (1 << 1),
|
Game = (1 << 1),
|
||||||
Editor = (1 << 2),
|
Editor = (1 << 2),
|
||||||
|
@ -24,7 +24,10 @@ enum EFlags {
|
||||||
Archive = (1 << 7),
|
Archive = (1 << 7),
|
||||||
InternalArchivable = (1 << 8),
|
InternalArchivable = (1 << 8),
|
||||||
Modified = (1 << 9),
|
Modified = (1 << 9),
|
||||||
ModifyRestart = (1 << 10) /*!< If this bit is set, any modification will inform the user that a restart is required */
|
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)
|
ENABLE_BITWISE_ENUM(EFlags)
|
||||||
|
|
||||||
|
@ -55,40 +58,61 @@ public:
|
||||||
using EType = DNACVAR::EType;
|
using EType = DNACVAR::EType;
|
||||||
using EFlags = DNACVAR::EFlags;
|
using EFlags = DNACVAR::EFlags;
|
||||||
|
|
||||||
CVar(std::string_view name, std::string_view value, std::string_view help, EType type, EFlags flags,
|
CVar(std::string_view name, std::string_view value, std::string_view help, EFlags flags);
|
||||||
CVarManager& parent);
|
CVar(std::string_view name, const atVec2f& value, std::string_view help, EFlags flags);
|
||||||
CVar(std::string_view name, std::string_view value, std::string_view help, EFlags flags, CVarManager& parent);
|
CVar(std::string_view name, const atVec2d& value, std::string_view help, EFlags flags);
|
||||||
CVar(std::string_view name, float value, std::string_view help, EFlags flags, CVarManager& parent);
|
CVar(std::string_view name, const atVec3f& value, std::string_view help, EFlags flags);
|
||||||
CVar(std::string_view name, bool value, std::string_view help, EFlags flags, CVarManager& parent);
|
CVar(std::string_view name, const atVec3d& value, std::string_view help, EFlags flags);
|
||||||
CVar(std::string_view name, int value, std::string_view help, EFlags flags, CVarManager& parent);
|
CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags);
|
||||||
CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags, CVarManager& parent);
|
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 name() const { return m_name; }
|
||||||
std::string_view rawHelp() const { return m_help; }
|
std::string_view rawHelp() const { return m_help; }
|
||||||
std::string help() const;
|
std::string help() const;
|
||||||
std::string value() const { return m_value; }
|
std::string value() const { return m_value; }
|
||||||
|
|
||||||
|
atVec2f toVec2f(bool* isValid = nullptr) const;
|
||||||
|
atVec2d toVec2d(bool* isValie = nullptr) const;
|
||||||
|
atVec3f toVec3f(bool* isValid = nullptr) const;
|
||||||
|
atVec3d toVec3d(bool* isValie = nullptr) const;
|
||||||
atVec4f toVec4f(bool* isValid = nullptr) const;
|
atVec4f toVec4f(bool* isValid = nullptr) const;
|
||||||
float toFloat(bool* isValid = nullptr) const;
|
atVec4d toVec4d(bool* isValie = nullptr) const;
|
||||||
|
double toReal(bool* isValid = nullptr) const;
|
||||||
bool toBoolean(bool* isValid = nullptr) const;
|
bool toBoolean(bool* isValid = nullptr) const;
|
||||||
int toInteger(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::wstring toWideLiteral(bool* isValid = nullptr) const;
|
||||||
std::string toLiteral(bool* isValid = nullptr) const;
|
std::string toLiteral(bool* isValid = nullptr) const;
|
||||||
|
|
||||||
|
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 fromVec4f(const atVec4f& val);
|
||||||
bool fromFloat(float val);
|
bool fromVec4d(const atVec4d& val);
|
||||||
|
bool fromReal(double val);
|
||||||
bool fromBoolean(bool val);
|
bool fromBoolean(bool val);
|
||||||
bool fromInteger(int val);
|
bool fromInteger(int32_t val);
|
||||||
|
bool fromInteger(uint32_t val);
|
||||||
bool fromLiteral(std::string_view val);
|
bool fromLiteral(std::string_view val);
|
||||||
bool fromLiteral(std::wstring_view val);
|
bool fromLiteral(std::wstring_view val);
|
||||||
bool fromLiteralToType(std::string_view val, bool setDefault = false);
|
bool fromLiteralToType(std::string_view val);
|
||||||
bool fromLiteralToType(std::wstring_view val, bool setDefault = false);
|
bool fromLiteralToType(std::wstring_view val);
|
||||||
|
|
||||||
bool isFloat() const { return m_type == EType::Float; }
|
bool isVec2f() const { return m_type == EType::Vec2f; }
|
||||||
bool isBoolean() const { return m_type == EType::Boolean; }
|
bool isVec2d() const { return m_type == EType::Vec2d; }
|
||||||
bool isInteger() const { return m_type == EType::Integer; }
|
bool isVec3f() const { return m_type == EType::Vec3f; }
|
||||||
bool isLiteral() const { return m_type == EType::Literal; }
|
bool isVec3d() const { return m_type == EType::Vec3d; }
|
||||||
bool isVec4f() const { return m_type == EType::Vec4f; }
|
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 isModified() const;
|
||||||
bool modificationRequiresRestart() const;
|
bool modificationRequiresRestart() const;
|
||||||
bool isReadOnly() const;
|
bool isReadOnly() const;
|
||||||
|
@ -96,6 +120,8 @@ public:
|
||||||
bool isHidden() const;
|
bool isHidden() const;
|
||||||
bool isArchive() const;
|
bool isArchive() const;
|
||||||
bool isInternalArchivable() const;
|
bool isInternalArchivable() const;
|
||||||
|
bool isNoDeveloper() const;
|
||||||
|
bool isColor() const;
|
||||||
bool wasDeserialized() const;
|
bool wasDeserialized() const;
|
||||||
bool hasDefaultValue() const;
|
bool hasDefaultValue() const;
|
||||||
void clearModified();
|
void clearModified();
|
||||||
|
@ -121,19 +147,22 @@ public:
|
||||||
|
|
||||||
void addListener(ListenerFunc func) { m_listeners.push_back(std::move(func)); }
|
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:
|
private:
|
||||||
|
CVar(std::string_view name, std::string_view help, EType type) : m_help(help), m_type(type) { m_name = name; }
|
||||||
void dispatch();
|
void dispatch();
|
||||||
EType m_type;
|
|
||||||
std::string m_help;
|
std::string m_help;
|
||||||
|
EType m_type;
|
||||||
std::string m_defaultValue;
|
std::string m_defaultValue;
|
||||||
EFlags m_flags;
|
EFlags m_flags = EFlags::None;
|
||||||
EFlags m_oldFlags;
|
EFlags m_oldFlags = EFlags::None;
|
||||||
bool m_unlocked = false;
|
bool m_unlocked = false;
|
||||||
bool m_wasDeserialized = false;
|
bool m_wasDeserialized = false;
|
||||||
|
|
||||||
CVarManager& m_mgr;
|
|
||||||
|
|
||||||
std::vector<ListenerFunc> m_listeners;
|
std::vector<ListenerFunc> m_listeners;
|
||||||
|
bool safeToModify(EType type) const;
|
||||||
|
void init(EFlags flags, bool removeColor=true);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CVarUnlocker {
|
class CVarUnlocker {
|
||||||
|
|
|
@ -18,7 +18,7 @@ using namespace std::literals;
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#define DEFAULT_GRAPHICS_API "Metal"sv
|
#define DEFAULT_GRAPHICS_API "Metal"sv
|
||||||
#else
|
#else
|
||||||
#define DEFAULT_GRAPHICS_API "OpenGL"sv
|
#define DEFAULT_GRAPHICS_API "Vulkan"sv
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct CVarCommons {
|
struct CVarCommons {
|
||||||
|
@ -47,13 +47,13 @@ struct CVarCommons {
|
||||||
|
|
||||||
void setGraphicsApi(std::string_view api) { m_graphicsApi->fromLiteral(api); }
|
void setGraphicsApi(std::string_view api) { m_graphicsApi->fromLiteral(api); }
|
||||||
|
|
||||||
uint32_t getSamples() const { return std::max(uint32_t(1), uint32_t(m_drawSamples->toInteger())); }
|
uint32_t getSamples() const { return std::max(1u, m_drawSamples->toUnsigned()); }
|
||||||
|
|
||||||
void setSamples(uint32_t v) { m_drawSamples->fromInteger(std::max(uint32_t(1), v)); }
|
void setSamples(uint32_t v) { m_drawSamples->fromInteger(std::max(uint32_t(1), v)); }
|
||||||
|
|
||||||
uint32_t getAnisotropy() const { return std::max(uint32_t(1), uint32_t(m_texAnisotropy->toInteger())); }
|
uint32_t getAnisotropy() const { return std::max(1u, uint32_t(m_texAnisotropy->toUnsigned())); }
|
||||||
|
|
||||||
void setAnisotropy(uint32_t v) { m_texAnisotropy->fromInteger(std::max(uint32_t(1), v)); }
|
void setAnisotropy(uint32_t v) { m_texAnisotropy->fromInteger(std::max(1u, v)); }
|
||||||
|
|
||||||
bool getDeepColor() const { return m_deepColor->toBoolean(); }
|
bool getDeepColor() const { return m_deepColor->toBoolean(); }
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class CVarManager final {
|
||||||
using CVarContainer = DNACVAR::CVarContainer;
|
using CVarContainer = DNACVAR::CVarContainer;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
CVar* _newCVar(std::string_view name, std::string_view help, const T& value, CVar::EFlags flags) {
|
CVar* _newCVar(std::string_view name, std::string_view help, const T& value, CVar::EFlags flags) {
|
||||||
if (CVar* ret = registerCVar(std::make_unique<CVar>(name, value, help, flags, *this))) {
|
if (CVar* ret = registerCVar(std::make_unique<CVar>(name, value, help, flags))) {
|
||||||
deserialize(ret);
|
deserialize(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -39,20 +39,44 @@ public:
|
||||||
CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary = false);
|
CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary = false);
|
||||||
~CVarManager();
|
~CVarManager();
|
||||||
|
|
||||||
|
CVar* newCVar(std::string_view name, std::string_view help, const atVec2f& value, CVar::EFlags flags) {
|
||||||
|
return _newCVar<atVec2f>(name, help, value, flags);
|
||||||
|
}
|
||||||
|
CVar* newCVar(std::string_view name, std::string_view help, const atVec2d& value, CVar::EFlags flags) {
|
||||||
|
return _newCVar<atVec2d>(name, help, value, flags);
|
||||||
|
}
|
||||||
|
CVar* newCVar(std::string_view name, std::string_view help, const atVec3f& value, CVar::EFlags flags) {
|
||||||
|
return _newCVar<atVec3f>(name, help, value, flags);
|
||||||
|
}
|
||||||
|
CVar* newCVar(std::string_view name, std::string_view help, const atVec3d& value, CVar::EFlags flags) {
|
||||||
|
return _newCVar<atVec3d>(name, help, value, flags);
|
||||||
|
}
|
||||||
CVar* newCVar(std::string_view name, std::string_view help, const atVec4f& value, CVar::EFlags flags) {
|
CVar* newCVar(std::string_view name, std::string_view help, const atVec4f& value, CVar::EFlags flags) {
|
||||||
return _newCVar<atVec4f>(name, help, value, flags);
|
return _newCVar<atVec4f>(name, help, value, flags);
|
||||||
}
|
}
|
||||||
|
CVar* newCVar(std::string_view name, std::string_view help, const atVec4d& value, CVar::EFlags flags) {
|
||||||
|
return _newCVar<atVec4d>(name, help, value, flags);
|
||||||
|
}
|
||||||
CVar* newCVar(std::string_view name, std::string_view help, std::string_view value, CVar::EFlags flags) {
|
CVar* newCVar(std::string_view name, std::string_view help, std::string_view value, CVar::EFlags flags) {
|
||||||
return _newCVar<std::string_view>(name, help, value, flags);
|
return _newCVar<std::string_view>(name, help, value, flags);
|
||||||
}
|
}
|
||||||
CVar* newCVar(std::string_view name, std::string_view help, bool value, CVar::EFlags flags) {
|
CVar* newCVar(std::string_view name, std::string_view help, bool value, CVar::EFlags flags) {
|
||||||
return _newCVar<bool>(name, help, value, flags);
|
return _newCVar<bool>(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) {
|
CVar* newCVar(std::string_view name, std::string_view help, float value, CVar::EFlags flags) {
|
||||||
return _newCVar<float>(name, help, value, flags);
|
return _newCVar<double>(name, help, static_cast<double>(value), flags);
|
||||||
}
|
}
|
||||||
CVar* newCVar(std::string_view name, std::string_view help, int value, CVar::EFlags flags) {
|
CVar* newCVar(std::string_view name, std::string_view help, double value, CVar::EFlags flags) {
|
||||||
return _newCVar<int>(name, help, value, flags);
|
return _newCVar<double>(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<int32_t>(name, help, value, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
CVar* newCVar(std::string_view name, std::string_view help, uint32_t value, CVar::EFlags flags) {
|
||||||
|
return _newCVar<uint32_t>(name, help, value, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
CVar* registerCVar(std::unique_ptr<CVar>&& cvar);
|
CVar* registerCVar(std::unique_ptr<CVar>&& cvar);
|
||||||
|
@ -66,13 +90,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CVar*> archivedCVars() const;
|
std::vector<CVar*> archivedCVars() const;
|
||||||
std::vector<CVar*> cvars(CVar::EFlags filter = CVar::EFlags::None) const;
|
std::vector<CVar*> cvars(CVar::EFlags filter = CVar::EFlags::Any) const;
|
||||||
|
|
||||||
void deserialize(CVar* cvar);
|
void deserialize(CVar* cvar);
|
||||||
void serialize();
|
void serialize();
|
||||||
|
|
||||||
static CVarManager* instance();
|
static CVarManager* instance();
|
||||||
|
|
||||||
|
void proc();
|
||||||
|
|
||||||
void list(class Console* con, const std::vector<std::string>& args);
|
void list(class Console* con, const std::vector<std::string>& args);
|
||||||
void setCVar(class Console* con, const std::vector<std::string>& args);
|
void setCVar(class Console* con, const std::vector<std::string>& args);
|
||||||
void getCVar(class Console* con, const std::vector<std::string>& args);
|
void getCVar(class Console* con, const std::vector<std::string>& args);
|
||||||
|
|
|
@ -13,111 +13,70 @@ extern CVar* com_enableCheats;
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
|
||||||
CVar::CVar(std::string_view name, std::string_view value, std::string_view help, EType type, EFlags flags,
|
CVar::CVar(std::string_view name, std::string_view value, std::string_view help, CVar::EFlags flags)
|
||||||
CVarManager& parent)
|
: CVar(name, help, EType::Literal) {
|
||||||
: m_mgr(parent) {
|
|
||||||
m_name = std::string(name);
|
|
||||||
m_value = std::string(value);
|
|
||||||
m_defaultValue = std::string(value);
|
|
||||||
m_help = help;
|
|
||||||
m_type = type;
|
|
||||||
m_flags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
CVar::CVar(std::string_view name, std::string_view value, std::string_view help, CVar::EFlags flags,
|
|
||||||
CVarManager& parent)
|
|
||||||
: m_mgr(parent) {
|
|
||||||
m_flags = flags;
|
|
||||||
m_name = std::string(name);
|
|
||||||
m_help = help;
|
|
||||||
m_type = EType::Literal;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
|
||||||
unlock();
|
|
||||||
|
|
||||||
fromLiteral(value);
|
fromLiteral(value);
|
||||||
m_defaultValue = m_value;
|
init(flags);
|
||||||
|
|
||||||
// Lock the cvar
|
|
||||||
lock();
|
|
||||||
// Clear the modified flag, just incase lock didn't do it.
|
|
||||||
m_flags = flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CVar::CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags, CVarManager& parent)
|
CVar::CVar(std::string_view name, const atVec2f& value, std::string_view help, EFlags flags)
|
||||||
: m_mgr(parent) {
|
: CVar(name, help, EType::Vec2f) {
|
||||||
m_name = std::string(name);
|
fromVec2f(value);
|
||||||
m_help = help;
|
init(flags);
|
||||||
m_type = EType::Vec4f;
|
}
|
||||||
m_flags = flags;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
CVar::CVar(std::string_view name, const atVec2d& value, std::string_view help, EFlags flags)
|
||||||
unlock();
|
: CVar(name, help, EType::Vec2d) {
|
||||||
|
fromVec2d(value);
|
||||||
|
|
||||||
|
init(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
CVar::CVar(std::string_view name, const atVec3f& value, std::string_view help, EFlags flags)
|
||||||
|
: CVar(name, help, EType::Vec3f) {
|
||||||
|
fromVec3f(value);
|
||||||
|
init(flags, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CVar::CVar(std::string_view name, const atVec3d& value, std::string_view help, EFlags flags)
|
||||||
|
: CVar(name, help, EType::Vec3d) {
|
||||||
|
fromVec3d(value);
|
||||||
|
init(flags, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CVar::CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags)
|
||||||
|
: CVar(name, help, EType::Vec4f) {
|
||||||
fromVec4f(value);
|
fromVec4f(value);
|
||||||
m_defaultValue = m_value;
|
init(flags, false);
|
||||||
|
|
||||||
// Lock the cvar
|
|
||||||
lock();
|
|
||||||
// Clear the modified flag, just incase lock didn't do it.
|
|
||||||
m_flags = flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CVar::CVar(std::string_view name, float value, std::string_view help, EFlags flags, CVarManager& parent)
|
CVar::CVar(std::string_view name, const atVec4d& value, std::string_view help, EFlags flags)
|
||||||
: m_mgr(parent) {
|
: CVar(name, help, EType::Vec4d) {
|
||||||
m_name = std::string(name);
|
fromVec4d(value);
|
||||||
m_help = help;
|
init(flags, false);
|
||||||
m_type = EType::Float;
|
|
||||||
m_flags = flags;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
|
||||||
unlock();
|
|
||||||
|
|
||||||
fromFloat(value);
|
|
||||||
m_defaultValue = m_value;
|
|
||||||
|
|
||||||
// Lock the cvar
|
|
||||||
lock();
|
|
||||||
// Clear the modified flag, just incase lock didn't do it.
|
|
||||||
m_flags = flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CVar::CVar(std::string_view name, bool value, std::string_view help, CVar::EFlags flags, CVarManager& parent)
|
CVar::CVar(std::string_view name, double value, std::string_view help, EFlags flags) : CVar(name, help, EType::Real) {
|
||||||
: m_mgr(parent) {
|
fromReal(value);
|
||||||
m_name = std::string(name);
|
init(flags);
|
||||||
m_help = help;
|
}
|
||||||
m_type = EType::Boolean;
|
|
||||||
m_flags = flags;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
|
||||||
unlock();
|
|
||||||
|
|
||||||
|
CVar::CVar(std::string_view name, bool value, std::string_view help, CVar::EFlags flags)
|
||||||
|
: CVar(name, help, EType::Boolean) {
|
||||||
fromBoolean(value);
|
fromBoolean(value);
|
||||||
m_defaultValue = m_value;
|
init(flags);
|
||||||
|
|
||||||
// Lock the cvar
|
|
||||||
lock();
|
|
||||||
// Clear the modified flag, just incase lock didn't do it.
|
|
||||||
m_flags = flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CVar::CVar(std::string_view name, int value, std::string_view help, CVar::EFlags flags, CVarManager& parent)
|
CVar::CVar(std::string_view name, int32_t value, std::string_view help, CVar::EFlags flags)
|
||||||
: m_mgr(parent) {
|
: CVar(name, help, EType::Signed) {
|
||||||
m_name = std::string(name);
|
|
||||||
m_help = help;
|
|
||||||
m_type = EType::Integer;
|
|
||||||
m_flags = flags;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
|
||||||
unlock();
|
|
||||||
|
|
||||||
fromInteger(value);
|
fromInteger(value);
|
||||||
m_defaultValue = m_value;
|
init(flags);
|
||||||
|
}
|
||||||
|
|
||||||
// Lock the cvar
|
CVar::CVar(std::string_view name, uint32_t value, std::string_view help, CVar::EFlags flags)
|
||||||
lock();
|
: CVar(name, help, EType::Unsigned) {
|
||||||
// Clear the modified flag, just incase lock didn't do it.
|
fromInteger(value);
|
||||||
m_flags = flags;
|
init(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CVar::help() const {
|
std::string CVar::help() const {
|
||||||
|
@ -125,6 +84,82 @@ std::string CVar::help() const {
|
||||||
(isReadOnly() ? " [ReadOnly]" : ""));
|
(isReadOnly() ? " [ReadOnly]" : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
atVec2f CVar::toVec2f(bool* isValid) const {
|
||||||
|
if (m_type != EType::Vec2f) {
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = false;
|
||||||
|
|
||||||
|
return atVec2f{};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = true;
|
||||||
|
|
||||||
|
atVec2f vec{};
|
||||||
|
athena::simd_floats f;
|
||||||
|
std::sscanf(m_value.c_str(), "%g %g", &f[0], &f[1]);
|
||||||
|
vec.simd.copy_from(f);
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
atVec2d CVar::toVec2d(bool* isValid) const {
|
||||||
|
if (m_type != EType::Vec2d) {
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = false;
|
||||||
|
|
||||||
|
return atVec2d{};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = true;
|
||||||
|
|
||||||
|
atVec2d vec{};
|
||||||
|
athena::simd_doubles f;
|
||||||
|
std::sscanf(m_value.c_str(), "%lg %lg", &f[0], &f[1]);
|
||||||
|
vec.simd.copy_from(f);
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
atVec3f CVar::toVec3f(bool* isValid) const {
|
||||||
|
if (m_type != EType::Vec3f) {
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = false;
|
||||||
|
|
||||||
|
return atVec3f{};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = true;
|
||||||
|
|
||||||
|
atVec3f vec{};
|
||||||
|
athena::simd_floats f;
|
||||||
|
std::sscanf(m_value.c_str(), "%g %g %g", &f[0], &f[1], &f[2]);
|
||||||
|
vec.simd.copy_from(f);
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
atVec3d CVar::toVec3d(bool* isValid) const {
|
||||||
|
if (m_type != EType::Vec3d) {
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = false;
|
||||||
|
|
||||||
|
return atVec3d{};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = true;
|
||||||
|
|
||||||
|
atVec3d vec{};
|
||||||
|
athena::simd_doubles f;
|
||||||
|
std::sscanf(m_value.c_str(), "%lg %lg %lg", &f[0], &f[1], &f[2]);
|
||||||
|
vec.simd.copy_from(f);
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
atVec4f CVar::toVec4f(bool* isValid) const {
|
atVec4f CVar::toVec4f(bool* isValid) const {
|
||||||
if (m_type != EType::Vec4f) {
|
if (m_type != EType::Vec4f) {
|
||||||
if (isValid != nullptr)
|
if (isValid != nullptr)
|
||||||
|
@ -136,22 +171,44 @@ atVec4f CVar::toVec4f(bool* isValid) const {
|
||||||
if (isValid != nullptr)
|
if (isValid != nullptr)
|
||||||
*isValid = true;
|
*isValid = true;
|
||||||
|
|
||||||
atVec4f vec;
|
atVec4f vec{};
|
||||||
athena::simd_floats f;
|
athena::simd_floats f;
|
||||||
std::sscanf(m_value.c_str(), "%f %f %f %f", &f[0], &f[1], &f[2], &f[3]);
|
std::sscanf(m_value.c_str(), "%g %g %g %g", &f[0], &f[1], &f[2], &f[3]);
|
||||||
vec.simd.copy_from(f);
|
vec.simd.copy_from(f);
|
||||||
|
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CVar::toFloat(bool* isValid) const {
|
atVec4d CVar::toVec4d(bool* isValid) const {
|
||||||
if (m_type != EType::Float) {
|
if (m_type != EType::Vec4d) {
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = false;
|
||||||
|
|
||||||
|
return atVec4d{};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = true;
|
||||||
|
|
||||||
|
atVec4d vec{};
|
||||||
|
athena::simd_doubles f;
|
||||||
|
std::sscanf(m_value.c_str(), "%lg %lg %lg %lg", &f[0], &f[1], &f[2], &f[3]);
|
||||||
|
vec.simd.copy_from(f);
|
||||||
|
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
double CVar::toReal(bool* isValid) const {
|
||||||
|
if (m_type != EType::Real) {
|
||||||
if (isValid)
|
if (isValid)
|
||||||
*isValid = false;
|
*isValid = false;
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return strtof(m_value.c_str(), nullptr);
|
if (isValid != nullptr)
|
||||||
|
*isValid = true;
|
||||||
|
|
||||||
|
return strtod(m_value.c_str(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::toBoolean(bool* isValid) const {
|
bool CVar::toBoolean(bool* isValid) const {
|
||||||
|
@ -162,36 +219,38 @@ bool CVar::toBoolean(bool* isValid) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't want to modify the original value;
|
if (isValid != nullptr)
|
||||||
std::string tmp = m_value;
|
*isValid = true;
|
||||||
athena::utility::tolower(tmp);
|
|
||||||
|
|
||||||
if (!tmp.compare("yes") || !tmp.compare("true") || !tmp.compare("1")) {
|
return athena::utility::parseBool(m_value);
|
||||||
if (isValid)
|
|
||||||
*isValid = true;
|
|
||||||
return true;
|
|
||||||
} else if (!tmp.compare("no") || !tmp.compare("false") || !tmp.compare("0")) {
|
|
||||||
if (isValid)
|
|
||||||
*isValid = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValid)
|
|
||||||
*isValid = false;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CVar::toInteger(bool* isValid) const {
|
int32_t CVar::toSigned(bool* isValid) const {
|
||||||
if (m_type != EType::Integer) {
|
if (m_type != EType::Signed && m_type != EType::Unsigned) {
|
||||||
if (isValid)
|
if (isValid)
|
||||||
*isValid = false;
|
*isValid = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = true;
|
||||||
|
|
||||||
return strtol(m_value.c_str(), nullptr, 0);
|
return strtol(m_value.c_str(), nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t CVar::toUnsigned(bool* isValid) const {
|
||||||
|
if (m_type != EType::Signed && m_type != EType::Unsigned) {
|
||||||
|
if (isValid)
|
||||||
|
*isValid = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid != nullptr)
|
||||||
|
*isValid = true;
|
||||||
|
|
||||||
|
return strtoul(m_value.c_str(), nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
std::string CVar::toLiteral(bool* isValid) const {
|
std::string CVar::toLiteral(bool* isValid) const {
|
||||||
if (m_type != EType::Literal && (com_developer && com_developer->toBoolean())) {
|
if (m_type != EType::Literal && (com_developer && com_developer->toBoolean())) {
|
||||||
if (isValid != nullptr)
|
if (isValid != nullptr)
|
||||||
|
@ -216,16 +275,48 @@ std::wstring CVar::toWideLiteral(bool* isValid) const {
|
||||||
return hecl::UTF8ToWide(m_value);
|
return hecl::UTF8ToWide(m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CVar::fromVec2f(const atVec2f& val) {
|
||||||
|
if (!safeToModify(EType::Vec2f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
athena::simd_floats f(val.simd);
|
||||||
|
m_value.assign(fmt::format(fmt("{} {}"), f[0], f[1]));
|
||||||
|
m_flags |= EFlags::Modified;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::fromVec2d(const atVec2d& val) {
|
||||||
|
if (!safeToModify(EType::Vec2d))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
athena::simd_doubles f(val.simd);
|
||||||
|
m_value.assign(fmt::format(fmt("{} {}"), f[0], f[1]));
|
||||||
|
m_flags |= EFlags::Modified;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::fromVec3f(const atVec3f& val) {
|
||||||
|
if (!safeToModify(EType::Vec3f))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
athena::simd_floats f(val.simd);
|
||||||
|
m_value.assign(fmt::format(fmt("{} {} {}"), f[0], f[1], f[2]));
|
||||||
|
m_flags |= EFlags::Modified;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::fromVec3d(const atVec3d& val) {
|
||||||
|
if (!safeToModify(EType::Vec3d))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
athena::simd_doubles f(val.simd);
|
||||||
|
m_value.assign(fmt::format(fmt("{} {} {}"), f[0], f[1], f[2]));
|
||||||
|
m_flags |= EFlags::Modified;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CVar::fromVec4f(const atVec4f& val) {
|
bool CVar::fromVec4f(const atVec4f& val) {
|
||||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
if (!safeToModify(EType::Vec4f))
|
||||||
return false;
|
|
||||||
else if (isCheat())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_type != EType::Vec4f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
athena::simd_floats f(val.simd);
|
athena::simd_floats f(val.simd);
|
||||||
|
@ -234,16 +325,18 @@ bool CVar::fromVec4f(const atVec4f& val) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::fromFloat(float val) {
|
bool CVar::fromVec4d(const atVec4d& val) {
|
||||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
if (!safeToModify(EType::Vec4d))
|
||||||
return false;
|
|
||||||
else if (isCheat())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_type != EType::Float)
|
athena::simd_doubles f(val.simd);
|
||||||
return false;
|
m_value.assign(fmt::format(fmt("{} {} {} {}"), f[0], f[1], f[2], f[3]));
|
||||||
|
m_flags |= EFlags::Modified;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
bool CVar::fromReal(double val) {
|
||||||
|
if (!safeToModify(EType::Real))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_value.assign(fmt::format(fmt("{}"), val));
|
m_value.assign(fmt::format(fmt("{}"), val));
|
||||||
|
@ -252,15 +345,7 @@ bool CVar::fromFloat(float val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::fromBoolean(bool val) {
|
bool CVar::fromBoolean(bool val) {
|
||||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
if (!safeToModify(EType::Boolean))
|
||||||
return false;
|
|
||||||
else if (isCheat())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_type != EType::Boolean)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
|
@ -272,33 +357,44 @@ bool CVar::fromBoolean(bool val) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::fromInteger(int val) {
|
bool CVar::fromInteger(int32_t val) {
|
||||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
if ((com_developer && com_enableCheats) && (!com_developer->toBoolean() || !com_enableCheats->toBoolean()) &&
|
||||||
return false;
|
isCheat())
|
||||||
else if (isCheat())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_type != EType::Integer)
|
// We'll accept both signed an unsigned input
|
||||||
|
if (m_type != EType::Signed && m_type != EType::Unsigned)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_value = fmt::format(fmt("{}"), val);
|
// Properly format based on signedness
|
||||||
|
m_value = fmt::format(fmt("{}"), (m_type == EType::Signed ? val : static_cast<uint32_t>(val)));
|
||||||
|
setModified();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::fromInteger(uint32_t val) {
|
||||||
|
if ((com_developer && com_enableCheats) && (!com_developer->toBoolean() || !com_enableCheats->toBoolean()) &&
|
||||||
|
isCheat())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We'll accept both signed an unsigned input
|
||||||
|
if (m_type != EType::Signed && m_type != EType::Unsigned)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Properly format based on signedness
|
||||||
|
m_value = fmt::format(fmt("{}"), (m_type == EType::Unsigned ? val : static_cast<int32_t>(val)));
|
||||||
setModified();
|
setModified();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::fromLiteral(std::string_view val) {
|
bool CVar::fromLiteral(std::string_view val) {
|
||||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
if (!safeToModify(EType::Literal))
|
||||||
return false;
|
|
||||||
else if (isCheat())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_type != EType::Literal)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_value.assign(val);
|
m_value.assign(val);
|
||||||
|
@ -307,15 +403,7 @@ bool CVar::fromLiteral(std::string_view val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::fromLiteral(std::wstring_view val) {
|
bool CVar::fromLiteral(std::wstring_view val) {
|
||||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
if (!safeToModify(EType::Literal))
|
||||||
return false;
|
|
||||||
else if (isCheat())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_type != EType::Literal)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_value.assign(hecl::WideToUTF8(val));
|
m_value.assign(hecl::WideToUTF8(val));
|
||||||
|
@ -323,94 +411,36 @@ bool CVar::fromLiteral(std::wstring_view val) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::fromLiteralToType(std::string_view val, bool setDefault) {
|
bool CVar::fromLiteralToType(std::string_view val) {
|
||||||
switch (m_type) {
|
if (!safeToModify(m_type) || !isValidInput(val))
|
||||||
case EType::Literal:
|
return false;
|
||||||
return fromLiteral(val);
|
m_value = val;
|
||||||
case EType::Boolean: {
|
return true;
|
||||||
std::stringstream ss;
|
|
||||||
ss << std::boolalpha << val;
|
|
||||||
bool v;
|
|
||||||
ss >> v;
|
|
||||||
return fromBoolean(v);
|
|
||||||
}
|
|
||||||
case EType::Float: {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << val;
|
|
||||||
float v;
|
|
||||||
ss >> v;
|
|
||||||
return fromFloat(v);
|
|
||||||
}
|
|
||||||
case EType::Integer: {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << val;
|
|
||||||
int v;
|
|
||||||
ss >> v;
|
|
||||||
return fromInteger(v);
|
|
||||||
}
|
|
||||||
case EType::Vec4f: {
|
|
||||||
atVec4f vec;
|
|
||||||
athena::simd_floats f;
|
|
||||||
std::sscanf(val.data(), "%f %f %f %f", &f[0], &f[1], &f[2], &f[3]);
|
|
||||||
vec.simd.copy_from(f);
|
|
||||||
return fromVec4f(vec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (setDefault)
|
|
||||||
m_value = m_defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::fromLiteralToType(std::wstring_view val, bool setDefault) {
|
bool CVar::fromLiteralToType(std::wstring_view val) {
|
||||||
switch (m_type) {
|
return fromLiteralToType(hecl::WideToUTF8(val));
|
||||||
case EType::Literal:
|
|
||||||
return fromLiteral(val);
|
|
||||||
case EType::Boolean: {
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << std::boolalpha << val;
|
|
||||||
bool v;
|
|
||||||
ss >> v;
|
|
||||||
return fromBoolean(v);
|
|
||||||
}
|
|
||||||
case EType::Float: {
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << val;
|
|
||||||
float v;
|
|
||||||
ss >> v;
|
|
||||||
return fromFloat(v);
|
|
||||||
}
|
|
||||||
case EType::Integer: {
|
|
||||||
std::wstringstream ss;
|
|
||||||
ss << val;
|
|
||||||
int v;
|
|
||||||
ss >> v;
|
|
||||||
return fromInteger(v);
|
|
||||||
}
|
|
||||||
case EType::Vec4f: {
|
|
||||||
atVec4f vec;
|
|
||||||
athena::simd_floats f;
|
|
||||||
std::swscanf(val.data(), L"%f %f %f %f", &f[0], &f[1], &f[2], &f[3]);
|
|
||||||
vec.simd.copy_from(f);
|
|
||||||
return fromVec4f(vec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (setDefault)
|
|
||||||
m_value = m_defaultValue;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVar::isModified() const { return int(m_flags & EFlags::Modified) != 0; }
|
bool CVar::isModified() const { return True(m_flags & EFlags::Modified); }
|
||||||
bool CVar::modificationRequiresRestart() const { return int(m_flags & EFlags::ModifyRestart) != 0; }
|
bool CVar::modificationRequiresRestart() const { return True(m_flags & EFlags::ModifyRestart); }
|
||||||
|
|
||||||
bool CVar::isReadOnly() const { return int(m_flags & EFlags::ReadOnly) != 0; }
|
bool CVar::isReadOnly() const { return True(m_flags & EFlags::ReadOnly); }
|
||||||
|
|
||||||
bool CVar::isCheat() const { return int(m_flags & EFlags::Cheat) != 0; }
|
bool CVar::isCheat() const { return True(m_flags & EFlags::Cheat); }
|
||||||
|
|
||||||
bool CVar::isHidden() const { return int(m_flags & EFlags::Hidden) != 0; }
|
bool CVar::isHidden() const { return True(m_flags & EFlags::Hidden); }
|
||||||
|
|
||||||
bool CVar::isArchive() const { return int(m_flags & EFlags::Archive) != 0; }
|
bool CVar::isArchive() const { return True(m_flags & EFlags::Archive); }
|
||||||
|
|
||||||
bool CVar::isInternalArchivable() const { return int(m_flags & EFlags::InternalArchivable) != 0; }
|
bool CVar::isInternalArchivable() const { return True(m_flags & EFlags::InternalArchivable); }
|
||||||
|
|
||||||
|
bool CVar::isColor() const {
|
||||||
|
return True(m_flags & EFlags::Color) &&
|
||||||
|
(m_type == EType::Vec3f || m_type == EType::Vec3d || m_type == EType::Vec3f || m_type == EType::Vec4d);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::isNoDeveloper() const { return True(m_flags & EFlags::NoDeveloper); }
|
||||||
|
|
||||||
bool CVar::wasDeserialized() const { return m_wasDeserialized; }
|
bool CVar::wasDeserialized() const { return m_wasDeserialized; }
|
||||||
|
|
||||||
|
@ -442,4 +472,85 @@ void CVar::dispatch() {
|
||||||
for (const ListenerFunc& listen : m_listeners)
|
for (const ListenerFunc& listen : m_listeners)
|
||||||
listen(this);
|
listen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isReal(std::string_view v) {
|
||||||
|
char* p;
|
||||||
|
std::strtod(v.data(), &p);
|
||||||
|
return *p == 0;
|
||||||
|
}
|
||||||
|
bool isReal(const std::vector<std::string>& v) {
|
||||||
|
for (auto& s : v) {
|
||||||
|
if (!isReal(s))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::isValidInput(std::string_view input) const {
|
||||||
|
std::vector<std::string> parts = athena::utility::split(input, ' ');
|
||||||
|
char* p;
|
||||||
|
switch(m_type) {
|
||||||
|
case EType::Boolean: {
|
||||||
|
bool valid = false;
|
||||||
|
athena::utility::parseBool(input, &valid);
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
case EType::Signed:
|
||||||
|
std::strtol(input.data(), &p, 0);
|
||||||
|
return p == nullptr;
|
||||||
|
case EType::Unsigned:
|
||||||
|
std::strtoul(input.data(), &p, 0);
|
||||||
|
return p == nullptr;
|
||||||
|
case EType::Real: {
|
||||||
|
bool size = parts.size() == 1;
|
||||||
|
bool ret = isReal(input);
|
||||||
|
return ret && size;
|
||||||
|
}
|
||||||
|
case EType::Literal:
|
||||||
|
return true;
|
||||||
|
case EType::Vec2f:
|
||||||
|
case EType::Vec2d:
|
||||||
|
return parts.size() == 2 && isReal(parts);
|
||||||
|
case EType::Vec3f:
|
||||||
|
case EType::Vec3d:
|
||||||
|
return parts.size() == 3 && isReal(parts);
|
||||||
|
case EType::Vec4f:
|
||||||
|
case EType::Vec4d:
|
||||||
|
return parts.size() == 4 && isReal(parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::isValidInput(std::wstring_view input) const {
|
||||||
|
return isValidInput(hecl::WideToUTF8(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::safeToModify(EType type) const {
|
||||||
|
// Are we NoDevelper?
|
||||||
|
if (isNoDeveloper())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Are we a cheat?
|
||||||
|
if (isCheat() && (com_developer && com_enableCheats) &&
|
||||||
|
(!com_developer->toBoolean() || !com_enableCheats->toBoolean()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Are we read only?
|
||||||
|
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return m_type == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVar::init(EFlags flags, bool removeColor) {
|
||||||
|
m_defaultValue = m_value;
|
||||||
|
m_flags = flags;
|
||||||
|
if (removeColor) {
|
||||||
|
// If the user specifies color, we don't want it
|
||||||
|
m_flags &= ~EFlags::Color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace hecl
|
} // namespace hecl
|
||||||
|
|
|
@ -25,7 +25,9 @@ static logvisor::Module CVarLog("CVarManager");
|
||||||
CVarManager::CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary)
|
CVarManager::CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary)
|
||||||
: m_store(store), m_useBinary(useBinary) {
|
: m_store(store), m_useBinary(useBinary) {
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
com_configfile = newCVar("config", "File to store configuration", std::string("config"), CVar::EFlags::System);
|
com_configfile =
|
||||||
|
newCVar("config", "File to store configuration", std::string("config"),
|
||||||
|
CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::NoDeveloper | CVar::EFlags::Hidden);
|
||||||
com_developer = newCVar("developer", "Enables developer mode", false,
|
com_developer = newCVar("developer", "Enables developer mode", false,
|
||||||
(CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::InternalArchivable));
|
(CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::InternalArchivable));
|
||||||
com_enableCheats = newCVar(
|
com_enableCheats = newCVar(
|
||||||
|
@ -72,14 +74,15 @@ std::vector<CVar*> CVarManager::archivedCVars() const {
|
||||||
std::vector<CVar*> CVarManager::cvars(CVar::EFlags filter) const {
|
std::vector<CVar*> CVarManager::cvars(CVar::EFlags filter) const {
|
||||||
std::vector<CVar*> ret;
|
std::vector<CVar*> ret;
|
||||||
for (const auto& pair : m_cvars)
|
for (const auto& pair : m_cvars)
|
||||||
if (filter == CVar::EFlags::None || (pair.second->flags() & filter) != 0)
|
if (filter == CVar::EFlags::Any || True(pair.second->flags() & filter))
|
||||||
ret.push_back(pair.second.get());
|
ret.push_back(pair.second.get());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVarManager::deserialize(CVar* cvar) {
|
void CVarManager::deserialize(CVar* cvar) {
|
||||||
if (!cvar)
|
/* Make sure we're not trying to deserialize a CVar that is invalid or not exposed */
|
||||||
|
if (!cvar || (!cvar->isArchive() && !cvar->isInternalArchivable()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* First let's check for a deferred value */
|
/* First let's check for a deferred value */
|
||||||
|
@ -93,9 +96,6 @@ void CVarManager::deserialize(CVar* cvar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We were either unable to find a deferred value or got an invalid value */
|
/* We were either unable to find a deferred value or got an invalid value */
|
||||||
if (!cvar->isArchive() && !cvar->isInternalArchivable())
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
hecl::SystemString filename =
|
hecl::SystemString filename =
|
||||||
hecl::SystemString(m_store.getStoreRoot()) + _SYS_STR('/') + com_configfile->toWideLiteral();
|
hecl::SystemString(m_store.getStoreRoot()) + _SYS_STR('/') + com_configfile->toWideLiteral();
|
||||||
|
@ -122,10 +122,9 @@ void CVarManager::deserialize(CVar* cvar) {
|
||||||
DNACVAR::CVar& tmp = *serialized;
|
DNACVAR::CVar& tmp = *serialized;
|
||||||
|
|
||||||
if (cvar->m_value != tmp.m_value) {
|
if (cvar->m_value != tmp.m_value) {
|
||||||
cvar->unlock();
|
CVarUnlocker lc(cvar);
|
||||||
cvar->fromLiteralToType(tmp.m_value, true);
|
cvar->fromLiteralToType(tmp.m_value);
|
||||||
cvar->m_wasDeserialized = true;
|
cvar->m_wasDeserialized = true;
|
||||||
cvar->lock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,10 +144,9 @@ void CVarManager::deserialize(CVar* cvar) {
|
||||||
const std::unique_ptr<athena::io::YAMLNode>& tmp = serialized->second;
|
const std::unique_ptr<athena::io::YAMLNode>& tmp = serialized->second;
|
||||||
|
|
||||||
if (cvar->m_value != tmp->m_scalarString) {
|
if (cvar->m_value != tmp->m_scalarString) {
|
||||||
cvar->unlock();
|
CVarUnlocker lc(cvar);
|
||||||
cvar->fromLiteralToType(tmp->m_scalarString, true);
|
cvar->fromLiteralToType(tmp->m_scalarString);
|
||||||
cvar->m_wasDeserialized = true;
|
cvar->m_wasDeserialized = true;
|
||||||
cvar->lock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,5 +327,12 @@ void CVarManager::restoreDeveloper(bool oldDeveloper) {
|
||||||
CVarUnlocker unlock(com_developer);
|
CVarUnlocker unlock(com_developer);
|
||||||
com_developer->fromBoolean(oldDeveloper);
|
com_developer->fromBoolean(oldDeveloper);
|
||||||
}
|
}
|
||||||
|
void CVarManager::proc() {
|
||||||
|
for (const auto& [name, cvar] : m_cvars) {
|
||||||
|
if (cvar->isModified() && !cvar->modificationRequiresRestart()) {
|
||||||
|
cvar->dispatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace hecl
|
} // namespace hecl
|
||||||
|
|
|
@ -174,12 +174,12 @@ void Console::init(boo::IWindow* window) {
|
||||||
|
|
||||||
void Console::proc() {
|
void Console::proc() {
|
||||||
if (m_conHeight->isModified()) {
|
if (m_conHeight->isModified()) {
|
||||||
m_cachedConHeight = m_conHeight->toFloat();
|
m_cachedConHeight = m_conHeight->toReal();
|
||||||
m_conHeight->clearModified();
|
m_conHeight->clearModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_conSpeed->isModified()) {
|
if (m_conSpeed->isModified()) {
|
||||||
m_cachedConSpeed = m_conSpeed->toFloat();
|
m_cachedConSpeed = m_conSpeed->toReal();
|
||||||
m_conSpeed->clearModified();
|
m_conSpeed->clearModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue