Commit c430ed66 authored by Phillip Stephens's avatar Phillip Stephens

Various fixes and improvements to CVars

parent 9854cce1
......@@ -10,10 +10,10 @@
namespace hecl {
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 {
None = -1,
enum class EFlags {
None = 0,
System = (1 << 0),
Game = (1 << 1),
Editor = (1 << 2),
......@@ -24,7 +24,10 @@ enum EFlags {
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 */
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)
......@@ -55,40 +58,61 @@ public:
using EType = DNACVAR::EType;
using EFlags = DNACVAR::EFlags;
CVar(std::string_view name, std::string_view value, std::string_view help, EType type, EFlags flags,
CVarManager& parent);
CVar(std::string_view name, std::string_view value, std::string_view help, EFlags flags, CVarManager& parent);
CVar(std::string_view name, float value, std::string_view help, EFlags flags, CVarManager& parent);
CVar(std::string_view name, bool value, std::string_view help, EFlags flags, CVarManager& parent);
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, CVarManager& parent);
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; }
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;
float toFloat(bool* isValid = nullptr) const;
atVec4d toVec4d(bool* isValie = nullptr) const;
double toReal(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::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 fromFloat(float val);
bool fromVec4d(const atVec4d& val);
bool fromReal(double 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::wstring_view val);
bool fromLiteralToType(std::string_view val, bool setDefault = false);
bool fromLiteralToType(std::wstring_view val, bool setDefault = false);
bool fromLiteralToType(std::string_view val);
bool fromLiteralToType(std::wstring_view val);
bool isFloat() const { return m_type == EType::Float; }
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::Integer; }
bool isInteger() const { return m_type == EType::Signed || m_type == EType::Unsigned; }
bool isLiteral() const { return m_type == EType::Literal; }
bool isVec4f() const { return m_type == EType::Vec4f; }
bool isModified() const;
bool modificationRequiresRestart() const;
bool isReadOnly() const;
......@@ -96,6 +120,8 @@ public:
bool isHidden() const;
bool isArchive() const;
bool isInternalArchivable() const;
bool isNoDeveloper() const;
bool isColor() const;
bool wasDeserialized() const;
bool hasDefaultValue() const;
void clearModified();
......@@ -121,19 +147,22 @@ public:
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();
EType m_type;
std::string m_help;
EType m_type;
std::string m_defaultValue;
EFlags m_flags;
EFlags m_oldFlags;
EFlags m_flags = EFlags::None;
EFlags m_oldFlags = EFlags::None;
bool m_unlocked = false;
bool m_wasDeserialized = false;
CVarManager& m_mgr;
std::vector<ListenerFunc> m_listeners;
bool safeToModify(EType type) const;
void init(EFlags flags, bool removeColor=true);
};
class CVarUnlocker {
......
......@@ -18,7 +18,7 @@ using namespace std::literals;
#elif defined(__APPLE__)
#define DEFAULT_GRAPHICS_API "Metal"sv
#else
#define DEFAULT_GRAPHICS_API "OpenGL"sv
#define DEFAULT_GRAPHICS_API "Vulkan"sv
#endif
struct CVarCommons {
......@@ -47,13 +47,13 @@ struct CVarCommons {
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)); }
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(); }
......
......@@ -20,7 +20,7 @@ class CVarManager final {
using CVarContainer = DNACVAR::CVarContainer;
template <typename T>
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);
return ret;
}
......@@ -39,20 +39,44 @@ public:
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<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) {
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) {
return _newCVar<std::string_view>(name, help, value, flags);
}
CVar* newCVar(std::string_view name, std::string_view help, bool value, CVar::EFlags 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) {
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) {
return _newCVar<int>(name, help, value, flags);
CVar* newCVar(std::string_view name, std::string_view help, double value, CVar::EFlags 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);
......@@ -66,13 +90,15 @@ public:
}
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 serialize();
static CVarManager* instance();
void proc();
void list(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);
......
This diff is collapsed.
......@@ -25,7 +25,9 @@ static logvisor::Module CVarLog("CVarManager");
CVarManager::CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary)
: m_store(store), m_useBinary(useBinary) {
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,
(CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::InternalArchivable));
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*> ret;
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());
return ret;
}
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;
/* 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 */
if (!cvar->isArchive() && !cvar->isInternalArchivable())
return;
#if _WIN32
hecl::SystemString filename =
hecl::SystemString(m_store.getStoreRoot()) + _SYS_STR('/') + com_configfile->toWideLiteral();
......@@ -122,10 +122,9 @@ void CVarManager::deserialize(CVar* cvar) {
DNACVAR::CVar& tmp = *serialized;
if (cvar->m_value != tmp.m_value) {
cvar->unlock();
cvar->fromLiteralToType(tmp.m_value, true);
CVarUnlocker lc(cvar);
cvar->fromLiteralToType(tmp.m_value);
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;
if (cvar->m_value != tmp->m_scalarString) {
cvar->unlock();
cvar->fromLiteralToType(tmp->m_scalarString, true);
CVarUnlocker lc(cvar);
cvar->fromLiteralToType(tmp->m_scalarString);
cvar->m_wasDeserialized = true;
cvar->lock();
}
}
}
......@@ -329,5 +327,12 @@ void CVarManager::restoreDeveloper(bool oldDeveloper) {
CVarUnlocker unlock(com_developer);
com_developer->fromBoolean(oldDeveloper);
}
void CVarManager::proc() {
for (const auto& [name, cvar] : m_cvars) {
if (cvar->isModified() && !cvar->modificationRequiresRestart()) {
cvar->dispatch();
}
}
}
} // namespace hecl
......@@ -174,12 +174,12 @@ void Console::init(boo::IWindow* window) {
void Console::proc() {
if (m_conHeight->isModified()) {
m_cachedConHeight = m_conHeight->toFloat();
m_cachedConHeight = m_conHeight->toReal();
m_conHeight->clearModified();
}
if (m_conSpeed->isModified()) {
m_cachedConSpeed = m_conSpeed->toFloat();
m_cachedConSpeed = m_conSpeed->toReal();
m_conSpeed->clearModified();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment