From c54454d125d1547e611b34db351c40427b9acfca Mon Sep 17 00:00:00 2001 From: pursche Date: Sat, 6 Apr 2024 21:54:55 +0200 Subject: [PATCH] CVar improvements --- Source/Base/Base/CVarSystem/CVarSystem.h | 74 ++- .../Base/CVarSystem/CVarSystemPrivate.cpp | 338 +++++++++++--- .../Base/Base/CVarSystem/CVarSystemPrivate.h | 50 ++- Source/Base/Base/Util/JsonUtils.cpp | 424 +++++++++++++----- Source/Base/Base/Util/JsonUtils.h | 11 +- Source/Renderer/Renderer/RenderGraph.cpp | 2 +- 6 files changed, 709 insertions(+), 190 deletions(-) diff --git a/Source/Base/Base/CVarSystem/CVarSystem.h b/Source/Base/Base/CVarSystem/CVarSystem.h index c3d2ea6c..eb3027dc 100644 --- a/Source/Base/Base/CVarSystem/CVarSystem.h +++ b/Source/Base/Base/CVarSystem/CVarSystem.h @@ -5,13 +5,17 @@ enum class CVarFlags : u32 { None = 0, - Noedit = 1 << 1, + Hidden = 1 << 1, EditReadOnly = 1 << 2, Advanced = 1 << 3, EditCheckbox = 1 << 8, EditFloatDrag = 1 << 9, + + RuntimeCreated = 1 << 20, + DoNotSave = 1 << 21, }; +DECLARE_GENERIC_BITWISE_OPERATORS(CVarFlags); enum class ShowFlag : bool { @@ -19,35 +23,79 @@ enum class ShowFlag : bool DISABLED }; +enum class CVarCategory : u8 +{ + Server = 1 << 0, + Client = 1 << 1, + Rendering = 1 << 2, + Physics = 1 << 3, + Network = 1 << 4, + + COUNT = 5, // Keep this updated! +}; +DECLARE_GENERIC_BITWISE_OPERATORS(CVarCategory); + +constexpr char* CVarCategoryToString[u8(CVarCategory::COUNT)] = +{ + "Server", + "Client", + "Rendering", + "Physics", + "Network", +}; + +constexpr char* CVarCategoryToPrefix[u8(CVarCategory::COUNT)] = +{ + "sv_", + "cl_", + "r_", + "phys_", + "net_", +}; + class CVarParameter; class CVarSystem { public: static CVarSystem* Get(); + static std::string GetQualifiedName(CVarCategory category, const char* name); //pimpl virtual CVarParameter* GetCVar(StringUtils::StringHash hash) = 0; + virtual CVarParameter* GetCVar(CVarCategory category, StringUtils::StringHash hash) = 0; virtual f64* GetFloatCVar(StringUtils::StringHash hash) = 0; + virtual f64* GetFloatCVar(CVarCategory category, StringUtils::StringHash hash) = 0; virtual i32* GetIntCVar(StringUtils::StringHash hash) = 0; + virtual i32* GetIntCVar(CVarCategory category, StringUtils::StringHash hash) = 0; virtual const char* GetStringCVar(StringUtils::StringHash hash) = 0; + virtual const char* GetStringCVar(CVarCategory category, StringUtils::StringHash hash) = 0; virtual vec4* GetVecFloatCVar(StringUtils::StringHash hash) = 0; + virtual vec4* GetVecFloatCVar(CVarCategory category, StringUtils::StringHash hash) = 0; virtual ivec4* GetVecIntCVar(StringUtils::StringHash hash) = 0; + virtual ivec4* GetVecIntCVar(CVarCategory category, StringUtils::StringHash hash) = 0; virtual ShowFlag* GetShowFlagCVar(StringUtils::StringHash hash) = 0; + virtual ShowFlag* GetShowFlagCVar(CVarCategory category, StringUtils::StringHash hash) = 0; virtual void SetFloatCVar(StringUtils::StringHash hash, f64 value) = 0; + virtual void SetFloatCVar(CVarCategory category, StringUtils::StringHash hash, f64 value) = 0; virtual void SetIntCVar(StringUtils::StringHash hash, i32 value) = 0; + virtual void SetIntCVar(CVarCategory category, StringUtils::StringHash hash, i32 value) = 0; virtual void SetStringCVar(StringUtils::StringHash hash, const char* value) = 0; + virtual void SetStringCVar(CVarCategory category, StringUtils::StringHash hash, const char* value) = 0; virtual void SetVecFloatCVar(StringUtils::StringHash hash, const vec4& value) = 0; + virtual void SetVecFloatCVar(CVarCategory category, StringUtils::StringHash hash, const vec4& value) = 0; virtual void SetVecIntCVar(StringUtils::StringHash hash, const ivec4& value) = 0; + virtual void SetVecIntCVar(CVarCategory category, StringUtils::StringHash hash, const ivec4& value) = 0; virtual void SetShowFlagCVar(StringUtils::StringHash hash, const ShowFlag& value) = 0; + virtual void SetShowFlagCVar(CVarCategory category, StringUtils::StringHash hash, const ShowFlag& value) = 0; - virtual CVarParameter* CreateFloatCVar(const char* name, const char* description, f64 defaultValue, f64 currentValue) = 0; - virtual CVarParameter* CreateIntCVar(const char* name, const char* description, i32 defaultValue, i32 currentValue) = 0; - virtual CVarParameter* CreateStringCVar(const char* name, const char* description, const char* defaultValue, const char* currentValue) = 0; - virtual CVarParameter* CreateVecFloatCVar(const char* name, const char* description, const vec4& defaultValue, const vec4& currentValue) = 0; - virtual CVarParameter* CreateVecIntCVar(const char* name, const char* description, const ivec4& defaultValue, const ivec4& currentValue) = 0; - virtual CVarParameter* CreateShowFlagCVar(const char* name, const char* description, const ShowFlag& defaultValue, const ShowFlag& currentValue) = 0; + virtual CVarParameter* CreateFloatCVar(CVarCategory category, const char* name, const char* description, f64 defaultValue, f64 currentValue, CVarFlags flags = CVarFlags::None) = 0; + virtual CVarParameter* CreateIntCVar(CVarCategory category, const char* name, const char* description, i32 defaultValue, i32 currentValue, CVarFlags flags = CVarFlags::None) = 0; + virtual CVarParameter* CreateStringCVar(CVarCategory category, const char* name, const char* description, const char* defaultValue, const char* currentValue, CVarFlags flags = CVarFlags::None) = 0; + virtual CVarParameter* CreateVecFloatCVar(CVarCategory category, const char* name, const char* description, const vec4& defaultValue, const vec4& currentValue, CVarFlags flags = CVarFlags::None) = 0; + virtual CVarParameter* CreateVecIntCVar(CVarCategory category, const char* name, const char* description, const ivec4& defaultValue, const ivec4& currentValue, CVarFlags flags = CVarFlags::None) = 0; + virtual CVarParameter* CreateShowFlagCVar(CVarCategory category, const char* name, const char* description, const ShowFlag& defaultValue, const ShowFlag& currentValue, CVarFlags flags = CVarFlags::None) = 0; void MarkDirty() { _isDirty = true; } void ClearDirty() { _isDirty = false; } @@ -66,7 +114,7 @@ struct AutoCVar struct AutoCVar_Float : AutoCVar { public: - AutoCVar_Float(const char* name, const char* description, f64 defaultValue, CVarFlags flags = CVarFlags::None); + AutoCVar_Float(CVarCategory category, const char* name, const char* description, f64 defaultValue, CVarFlags flags = CVarFlags::None); f64 Get(); f64* GetPtr(); @@ -78,7 +126,7 @@ struct AutoCVar_Float : AutoCVar struct AutoCVar_Int : AutoCVar { public: - AutoCVar_Int(const char* name, const char* description, i32 defaultValue, CVarFlags flags = CVarFlags::None); + AutoCVar_Int(CVarCategory category, const char* name, const char* description, i32 defaultValue, CVarFlags flags = CVarFlags::None); i32 Get(); i32* GetPtr(); void Set(i32 val); @@ -89,7 +137,7 @@ struct AutoCVar_Int : AutoCVar struct AutoCVar_String : AutoCVar { public: - AutoCVar_String(const char* name, const char* description, const char* defaultValue, CVarFlags flags = CVarFlags::None); + AutoCVar_String(CVarCategory category, const char* name, const char* description, const char* defaultValue, CVarFlags flags = CVarFlags::None); const char* Get(); void Set(std::string&& val); @@ -98,7 +146,7 @@ struct AutoCVar_String : AutoCVar struct AutoCVar_VecFloat : AutoCVar { public: - AutoCVar_VecFloat(const char* name, const char* description, const vec4& defaultValue, CVarFlags flags = CVarFlags::None); + AutoCVar_VecFloat(CVarCategory category, const char* name, const char* description, const vec4& defaultValue, CVarFlags flags = CVarFlags::None); vec4 Get(); void Set(const vec4& val); @@ -107,7 +155,7 @@ struct AutoCVar_VecFloat : AutoCVar struct AutoCVar_VecInt : AutoCVar { public: - AutoCVar_VecInt(const char* name, const char* description, const ivec4& defaultValue, CVarFlags flags = CVarFlags::None); + AutoCVar_VecInt(CVarCategory category, const char* name, const char* description, const ivec4& defaultValue, CVarFlags flags = CVarFlags::None); ivec4 Get(); void Set(const ivec4& val); @@ -116,7 +164,7 @@ struct AutoCVar_VecInt : AutoCVar struct AutoCVar_ShowFlag : AutoCVar { public: - AutoCVar_ShowFlag(const char* name, const char* description, const ShowFlag& defaultValue); + AutoCVar_ShowFlag(CVarCategory category, const char* name, const char* description, const ShowFlag& defaultValue, CVarFlags flags = CVarFlags::None); ShowFlag Get(); void Set(const ShowFlag& val); diff --git a/Source/Base/Base/CVarSystem/CVarSystemPrivate.cpp b/Source/Base/Base/CVarSystem/CVarSystemPrivate.cpp index 6b59f292..121cd30b 100644 --- a/Source/Base/Base/CVarSystem/CVarSystemPrivate.cpp +++ b/Source/Base/Base/CVarSystem/CVarSystemPrivate.cpp @@ -4,14 +4,19 @@ #include -u32 Hash(const char* str) +f64* CVarSystemImpl::GetFloatCVar(StringUtils::StringHash hash) { - return StringUtils::fnv1a_32(str, strlen(str)); + return GetCVarCurrent(hash); } -f64* CVarSystemImpl::GetFloatCVar(StringUtils::StringHash hash) +f64* CVarSystemImpl::GetFloatCVar(CVarCategory category, StringUtils::StringHash hash) { - return GetCVarCurrent(hash); + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return nullptr; + } + return GetFloatCVar(qualifiedNameHash); } i32* CVarSystemImpl::GetIntCVar(StringUtils::StringHash hash) @@ -19,32 +24,102 @@ i32* CVarSystemImpl::GetIntCVar(StringUtils::StringHash hash) return GetCVarCurrent(hash); } +i32* CVarSystemImpl::GetIntCVar(CVarCategory category, StringUtils::StringHash hash) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return nullptr; + } + return GetIntCVar(qualifiedNameHash); +} + const char* CVarSystemImpl::GetStringCVar(StringUtils::StringHash hash) { return GetCVarCurrent(hash)->c_str(); } +const char* CVarSystemImpl::GetStringCVar(CVarCategory category, StringUtils::StringHash hash) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return nullptr; + } + return GetStringCVar(qualifiedNameHash); +} + vec4* CVarSystemImpl::GetVecFloatCVar(StringUtils::StringHash hash) { return GetCVarCurrent(hash); } +vec4* CVarSystemImpl::GetVecFloatCVar(CVarCategory category, StringUtils::StringHash hash) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return nullptr; + } + return GetVecFloatCVar(qualifiedNameHash); +} + ivec4* CVarSystemImpl::GetVecIntCVar(StringUtils::StringHash hash) { return GetCVarCurrent(hash); } +ivec4* CVarSystemImpl::GetVecIntCVar(CVarCategory category, StringUtils::StringHash hash) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return nullptr; + } + return GetVecIntCVar(qualifiedNameHash); +} + ShowFlag* CVarSystemImpl::GetShowFlagCVar(StringUtils::StringHash hash) { return GetCVarCurrent(hash); } +ShowFlag* CVarSystemImpl::GetShowFlagCVar(CVarCategory category, StringUtils::StringHash hash) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return nullptr; + } + return GetShowFlagCVar(qualifiedNameHash); +} + CVarSystem* CVarSystem::Get() { static CVarSystemImpl cvarSys{}; return &cvarSys; } +std::string CVarSystem::GetQualifiedName(CVarCategory category, const char* name) +{ + // Construct the qualified name + std::string qualifiedName; + + // Add all prefixes + for (u32 i = 0; i < static_cast(CVarCategory::COUNT); i++) + { + u32 mask = 1 << i; + if (static_cast(category) & mask) + { + qualifiedName += CVarCategoryToPrefix[i]; + } + } + + qualifiedName += name; + + return qualifiedName; +} + CVarParameter* CVarSystemImpl::GetCVar(StringUtils::StringHash hash) { std::shared_lock lock(mutex_); @@ -58,133 +133,296 @@ CVarParameter* CVarSystemImpl::GetCVar(StringUtils::StringHash hash) return nullptr; } +CVarParameter* CVarSystemImpl::GetCVar(CVarCategory category, StringUtils::StringHash hash) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return nullptr; + } + + return GetCVar(qualifiedNameHash); +} + void CVarSystemImpl::SetFloatCVar(StringUtils::StringHash hash, f64 value) { SetCVarCurrent(hash, value); } +void CVarSystemImpl::SetFloatCVar(CVarCategory category, StringUtils::StringHash hash, f64 value) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return; + } + + SetFloatCVar(qualifiedNameHash, value); +} + void CVarSystemImpl::SetIntCVar(StringUtils::StringHash hash, i32 value) { SetCVarCurrent(hash, value); } +void CVarSystemImpl::SetIntCVar(CVarCategory category, StringUtils::StringHash hash, i32 value) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return; + } + + SetIntCVar(qualifiedNameHash, value); +} + void CVarSystemImpl::SetStringCVar(StringUtils::StringHash hash, const char* value) { SetCVarCurrent(hash, value); } +void CVarSystemImpl::SetStringCVar(CVarCategory category, StringUtils::StringHash hash, const char* value) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return; + } + + SetStringCVar(qualifiedNameHash, value); +} + void CVarSystemImpl::SetVecFloatCVar(StringUtils::StringHash hash, const vec4& value) { SetCVarCurrent(hash, value); } +void CVarSystemImpl::SetVecFloatCVar(CVarCategory category, StringUtils::StringHash hash, const vec4& value) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return; + } + + SetVecFloatCVar(qualifiedNameHash, value); +} + void CVarSystemImpl::SetVecIntCVar(StringUtils::StringHash hash, const ivec4& value) { SetCVarCurrent(hash, value); } +void CVarSystemImpl::SetVecIntCVar(CVarCategory category, StringUtils::StringHash hash, const ivec4& value) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return; + } + + SetVecIntCVar(qualifiedNameHash, value); +} + void CVarSystemImpl::SetShowFlagCVar(StringUtils::StringHash hash, const ShowFlag& value) { SetCVarCurrent(hash, value); } -CVarParameter* CVarSystemImpl::CreateFloatCVar(const char* name, const char* description, f64 defaultValue, f64 currentValue) +void CVarSystemImpl::SetShowFlagCVar(CVarCategory category, StringUtils::StringHash hash, const ShowFlag& value) +{ + u32 qualifiedNameHash = 0; + if (!LookupCVar(category, hash, qualifiedNameHash)) + { + return; + } + + SetShowFlagCVar(qualifiedNameHash, value); +} + +CVarParameter* CVarSystemImpl::CreateFloatCVar(CVarCategory category, const char* name, const char* description, f64 defaultValue, f64 currentValue, CVarFlags flags) { - CVarParameter* param = InitCVar(name, description); - if (!param) return nullptr; + CVarParameter* param = nullptr; + bool wasCreated = InitCVar(category, name, description, param); + bool typeChanged = param->type != CVarType::FLOAT; std::unique_lock lock(mutex_); param->type = CVarType::FLOAT; + param->flags = flags; - GetCVarArray()->Add(defaultValue, currentValue, param); + CVarArray* cvarArray = GetCVarArray(); + if (wasCreated || typeChanged) + { + cvarArray->Add(defaultValue, currentValue, param); + } return param; } -CVarParameter* CVarSystemImpl::CreateIntCVar(const char* name, const char* description, i32 defaultValue, i32 currentValue) +CVarParameter* CVarSystemImpl::CreateIntCVar(CVarCategory category, const char* name, const char* description, i32 defaultValue, i32 currentValue, CVarFlags flags) { - CVarParameter* param = InitCVar(name, description); - if (!param) return nullptr; + CVarParameter* param = nullptr; + bool wasCreated = InitCVar(category, name, description, param); + bool typeChanged = param->type != CVarType::INT; + std::unique_lock lock(mutex_); param->type = CVarType::INT; + param->flags = flags; - GetCVarArray()->Add(defaultValue, currentValue, param); + CVarArray* cvarArray = GetCVarArray(); + if (wasCreated || typeChanged) + { + cvarArray->Add(defaultValue, currentValue, param); + } return param; } -CVarParameter* CVarSystemImpl::CreateStringCVar(const char* name, const char* description, const char* defaultValue, const char* currentValue) +CVarParameter* CVarSystemImpl::CreateStringCVar(CVarCategory category, const char* name, const char* description, const char* defaultValue, const char* currentValue, CVarFlags flags) { - CVarParameter* param = InitCVar(name, description); - if (!param) return nullptr; + CVarParameter* param = nullptr; + bool wasCreated = InitCVar(category, name, description, param); + bool typeChanged = param->type != CVarType::STRING; std::unique_lock lock(mutex_); param->type = CVarType::STRING; + param->flags = flags; - GetCVarArray()->Add(defaultValue, currentValue, param); + CVarArray* cvarArray = GetCVarArray(); + if (wasCreated || typeChanged) + { + cvarArray->Add(defaultValue, currentValue, param); + } return param; } -CVarParameter* CVarSystemImpl::CreateVecFloatCVar(const char* name, const char* description, const vec4& defaultValue, const vec4& currentValue) +CVarParameter* CVarSystemImpl::CreateVecFloatCVar(CVarCategory category, const char* name, const char* description, const vec4& defaultValue, const vec4& currentValue, CVarFlags flags) { - CVarParameter* param = InitCVar(name, description); - if (!param) return nullptr; + CVarParameter* param = nullptr; + bool wasCreated = InitCVar(category, name, description, param); + bool typeChanged = param->type != CVarType::FLOATVEC; std::unique_lock lock(mutex_); param->type = CVarType::FLOATVEC; + param->flags = flags; - GetCVarArray()->Add(defaultValue, currentValue, param); + CVarArray* cvarArray = GetCVarArray(); + if (wasCreated || typeChanged) + { + cvarArray->Add(defaultValue, currentValue, param); + } return param; } -CVarParameter* CVarSystemImpl::CreateVecIntCVar(const char* name, const char* description, const ivec4& defaultValue, const ivec4& currentValue) +CVarParameter* CVarSystemImpl::CreateVecIntCVar(CVarCategory category, const char* name, const char* description, const ivec4& defaultValue, const ivec4& currentValue, CVarFlags flags) { - CVarParameter* param = InitCVar(name, description); - if (!param) return nullptr; + CVarParameter* param = nullptr; + bool wasCreated = InitCVar(category, name, description, param); + bool typeChanged = param->type != CVarType::INTVEC; std::unique_lock lock(mutex_); param->type = CVarType::INTVEC; + param->flags = flags; - GetCVarArray()->Add(defaultValue, currentValue, param); + CVarArray* cvarArray = GetCVarArray(); + if (wasCreated || typeChanged) + { + cvarArray->Add(defaultValue, currentValue, param); + } return param; } -CVarParameter* CVarSystemImpl::CreateShowFlagCVar(const char* name, const char* description, const ShowFlag& defaultValue, const ShowFlag& currentValue) +CVarParameter* CVarSystemImpl::CreateShowFlagCVar(CVarCategory category, const char* name, const char* description, const ShowFlag& defaultValue, const ShowFlag& currentValue, CVarFlags flags) { - CVarParameter* param = InitCVar(name, description); - if (!param) return nullptr; + CVarParameter* param = nullptr; + bool wasCreated = InitCVar(category, name, description, param); + bool typeChanged = param->type != CVarType::SHOWFLAG; std::unique_lock lock(mutex_); param->type = CVarType::SHOWFLAG; + param->flags = flags; - GetCVarArray()->Add(defaultValue, currentValue, param); + CVarArray* cvarArray = GetCVarArray(); + if (wasCreated || typeChanged) + { + cvarArray->Add(defaultValue, currentValue, param); + } return param; } -CVarParameter* CVarSystemImpl::InitCVar(const char* name, const char* description) +bool CVarSystemImpl::InitCVar(CVarCategory category, const char* name, const char* description, CVarParameter*& outParam) { - if (GetCVar(name)) return nullptr; //return null if the cvar already exists - + std::string qualifiedName = GetQualifiedName(category, name); + u32 qualifiedNameHash = StringUtils::StringHash{ qualifiedName }; + u32 nameHash = StringUtils::StringHash{ name }; + + outParam = GetCVar(qualifiedName.c_str()); std::unique_lock lock(mutex_); - u32 namehash = StringUtils::StringHash{ name }; - savedCVars[namehash] = CVarParameter{}; + if (outParam) + { + CVarCategory existingCategory = outParam->category; + if (category != existingCategory) + { + // Remove old category lookup + cvarCategoryLookupTable[existingCategory].erase(nameHash); + + // Add new category lookup + if (!cvarCategoryLookupTable.contains(category)) + { + cvarCategoryLookupTable[category] = CVarLookupTable(); + } + + cvarCategoryLookupTable[category][nameHash] = qualifiedNameHash; + } + + outParam->category = category; + outParam->description = description; + return false; + } - CVarParameter& newParam = savedCVars[namehash]; + savedCVars[qualifiedNameHash] = CVarParameter{}; + CVarParameter& newParam = savedCVars[qualifiedNameHash]; + newParam.category = category; newParam.name = name; newParam.description = description; - return &newParam; + if (!cvarCategoryLookupTable.contains(category)) + { + cvarCategoryLookupTable[category] = CVarLookupTable(); + } + + cvarCategoryLookupTable[category][nameHash] = qualifiedNameHash; + + outParam = &newParam; + return true; +} + +bool CVarSystemImpl::LookupCVar(CVarCategory category, StringUtils::StringHash nameHash, u32& outHash) +{ + outHash = 0; + if (!cvarCategoryLookupTable.contains(category)) + { + return false; + } + + CVarLookupTable& table = cvarCategoryLookupTable[category]; + if (!table.contains(nameHash)) + { + return false; + } + + outHash = table[nameHash]; + return true; } -AutoCVar_Float::AutoCVar_Float(const char* name, const char* description, f64 defaultValue, CVarFlags flags) +AutoCVar_Float::AutoCVar_Float(CVarCategory category, const char* name, const char* description, f64 defaultValue, CVarFlags flags) { - CVarParameter* cvar = CVarSystem::Get()->CreateFloatCVar(name, description, defaultValue, defaultValue); - cvar->flags = flags; + CVarParameter* cvar = CVarSystem::Get()->CreateFloatCVar(category, name, description, defaultValue, defaultValue, flags); index = cvar->arrayIndex; } @@ -214,10 +452,9 @@ void AutoCVar_Float::Set(f64 f) CVarSystemImpl::Get()->GetCVarArray()->SetCurrent(f, index); } -AutoCVar_Int::AutoCVar_Int(const char* name, const char* description, i32 defaultValue, CVarFlags flags) +AutoCVar_Int::AutoCVar_Int(CVarCategory category, const char* name, const char* description, i32 defaultValue, CVarFlags flags) { - CVarParameter* cvar = CVarSystem::Get()->CreateIntCVar(name, description, defaultValue, defaultValue); - cvar->flags = flags; + CVarParameter* cvar = CVarSystem::Get()->CreateIntCVar(category, name, description, defaultValue, defaultValue, flags); index = cvar->arrayIndex; } @@ -243,10 +480,9 @@ void AutoCVar_Int::Toggle() Set(enabled ? 0 : 1); } -AutoCVar_String::AutoCVar_String(const char* name, const char* description, const char* defaultValue, CVarFlags flags) +AutoCVar_String::AutoCVar_String(CVarCategory category, const char* name, const char* description, const char* defaultValue, CVarFlags flags) { - CVarParameter* cvar = CVarSystem::Get()->CreateStringCVar(name, description, defaultValue, defaultValue); - cvar->flags = flags; + CVarParameter* cvar = CVarSystem::Get()->CreateStringCVar(category, name, description, defaultValue, defaultValue, flags); index = cvar->arrayIndex; } @@ -260,10 +496,9 @@ void AutoCVar_String::Set(std::string&& val) CVarSystemImpl::Get()->GetCVarArray()->SetCurrent(val, index); } -AutoCVar_VecFloat::AutoCVar_VecFloat(const char* name, const char* description, const vec4& defaultValue, CVarFlags flags /*= CVarFlags::None*/) +AutoCVar_VecFloat::AutoCVar_VecFloat(CVarCategory category, const char* name, const char* description, const vec4& defaultValue, CVarFlags flags /*= CVarFlags::None*/) { - CVarParameter* cvar = CVarSystem::Get()->CreateVecFloatCVar(name, description, defaultValue, defaultValue); - cvar->flags = flags; + CVarParameter* cvar = CVarSystem::Get()->CreateVecFloatCVar(category, name, description, defaultValue, defaultValue, flags); index = cvar->arrayIndex; } @@ -277,10 +512,9 @@ void AutoCVar_VecFloat::Set(const vec4& val) CVarSystemImpl::Get()->GetCVarArray()->SetCurrent(val, index); } -AutoCVar_VecInt::AutoCVar_VecInt(const char* name, const char* description, const ivec4& defaultValue, CVarFlags flags) +AutoCVar_VecInt::AutoCVar_VecInt(CVarCategory category, const char* name, const char* description, const ivec4& defaultValue, CVarFlags flags) { - CVarParameter* cvar = CVarSystem::Get()->CreateVecIntCVar(name, description, defaultValue, defaultValue); - cvar->flags = flags; + CVarParameter* cvar = CVarSystem::Get()->CreateVecIntCVar(category, name, description, defaultValue, defaultValue, flags); index = cvar->arrayIndex; } @@ -294,9 +528,9 @@ void AutoCVar_VecInt::Set(const ivec4& val) CVarSystemImpl::Get()->GetCVarArray()->SetCurrent(val, index); } -AutoCVar_ShowFlag::AutoCVar_ShowFlag(const char* name, const char* description, const ShowFlag& defaultValue) +AutoCVar_ShowFlag::AutoCVar_ShowFlag(CVarCategory category, const char* name, const char* description, const ShowFlag& defaultValue, CVarFlags flags) { - CVarParameter* cvar = CVarSystem::Get()->CreateShowFlagCVar(name, description, defaultValue, defaultValue); + CVarParameter* cvar = CVarSystem::Get()->CreateShowFlagCVar(category, name, description, defaultValue, defaultValue, flags); index = cvar->arrayIndex; } diff --git a/Source/Base/Base/CVarSystem/CVarSystemPrivate.h b/Source/Base/Base/CVarSystem/CVarSystemPrivate.h index e380e814..d4e3da99 100644 --- a/Source/Base/Base/CVarSystem/CVarSystemPrivate.h +++ b/Source/Base/Base/CVarSystem/CVarSystemPrivate.h @@ -1,12 +1,11 @@ #pragma once #include "CVarSystem.h" -#include "Base/Types.h" -#include "Base/Util/StringUtils.h" -//#include "Base/Util/JsonConfig.h" +#include +#include #include -#include +#include #include enum class CVarType : u8 @@ -26,6 +25,7 @@ class CVarParameter i32 arrayIndex; + CVarCategory category; CVarType type; CVarFlags flags; std::string name; @@ -79,27 +79,40 @@ class CVarSystemImpl : public CVarSystem { public: CVarParameter* GetCVar(StringUtils::StringHash hash) override final; + CVarParameter* GetCVar(CVarCategory category, StringUtils::StringHash hash) override final; - CVarParameter* CreateFloatCVar(const char* name, const char* description, f64 defaultValue, f64 currentValue) override final; - CVarParameter* CreateIntCVar(const char* name, const char* description, i32 defaultValue, i32 currentValue) override final; - CVarParameter* CreateStringCVar(const char* name, const char* description, const char* defaultValue, const char* currentValue) override final; - CVarParameter* CreateVecFloatCVar(const char* name, const char* description, const vec4& defaultValue, const vec4& currentValue) override final; - CVarParameter* CreateVecIntCVar(const char* name, const char* description, const ivec4& defaultValue, const ivec4& currentValue) override final; - CVarParameter* CreateShowFlagCVar(const char* name, const char* description, const ShowFlag& defaultValue, const ShowFlag& currentValue) override final; + CVarParameter* CreateFloatCVar(CVarCategory category, const char* name, const char* description, f64 defaultValue, f64 currentValue, CVarFlags flags = CVarFlags::None) override final; + CVarParameter* CreateIntCVar(CVarCategory category, const char* name, const char* description, i32 defaultValue, i32 currentValue, CVarFlags flags = CVarFlags::None) override final; + CVarParameter* CreateStringCVar(CVarCategory category, const char* name, const char* description, const char* defaultValue, const char* currentValue, CVarFlags flags = CVarFlags::None) override final; + CVarParameter* CreateVecFloatCVar(CVarCategory category, const char* name, const char* description, const vec4& defaultValue, const vec4& currentValue, CVarFlags flags = CVarFlags::None) override final; + CVarParameter* CreateVecIntCVar(CVarCategory category, const char* name, const char* description, const ivec4& defaultValue, const ivec4& currentValue, CVarFlags flags = CVarFlags::None) override final; + CVarParameter* CreateShowFlagCVar(CVarCategory category, const char* name, const char* description, const ShowFlag& defaultValue, const ShowFlag& currentValue, CVarFlags flags = CVarFlags::None) override final; f64* GetFloatCVar(StringUtils::StringHash hash) override final; + f64* GetFloatCVar(CVarCategory category, StringUtils::StringHash hash) override final; i32* GetIntCVar(StringUtils::StringHash hash) override final; + i32* GetIntCVar(CVarCategory category, StringUtils::StringHash hash) override final; const char* GetStringCVar(StringUtils::StringHash hash) override final; + const char* GetStringCVar(CVarCategory category, StringUtils::StringHash hash) override final; vec4* GetVecFloatCVar(StringUtils::StringHash hash) override final; + vec4* GetVecFloatCVar(CVarCategory category, StringUtils::StringHash hash) override final; ivec4* GetVecIntCVar(StringUtils::StringHash hash) override final; + ivec4* GetVecIntCVar(CVarCategory category, StringUtils::StringHash hash) override final; ShowFlag* GetShowFlagCVar(StringUtils::StringHash hash) override final; + ShowFlag* GetShowFlagCVar(CVarCategory category, StringUtils::StringHash hash) override final; void SetFloatCVar(StringUtils::StringHash hash, f64 value) override final; + void SetFloatCVar(CVarCategory category, StringUtils::StringHash hash, f64 value) override final; void SetIntCVar(StringUtils::StringHash hash, i32 value) override final; + void SetIntCVar(CVarCategory category, StringUtils::StringHash hash, i32 value) override final; void SetStringCVar(StringUtils::StringHash hash, const char* value) override final; + void SetStringCVar(CVarCategory category, StringUtils::StringHash hash, const char* value) override final; void SetVecFloatCVar(StringUtils::StringHash hash, const vec4& value) override final; + void SetVecFloatCVar(CVarCategory category, StringUtils::StringHash hash, const vec4& value) override final; void SetVecIntCVar(StringUtils::StringHash hash, const ivec4& value) override final; + void SetVecIntCVar(CVarCategory category, StringUtils::StringHash hash, const ivec4& value) override final; void SetShowFlagCVar(StringUtils::StringHash hash, const ShowFlag& value) override final; + void SetShowFlagCVar(CVarCategory category, StringUtils::StringHash hash, const ShowFlag& value) override final; constexpr static int MAX_INT_CVARS = 1000; @@ -144,9 +157,15 @@ class CVarSystemImpl : public CVarSystem private: std::shared_mutex mutex_; - CVarParameter* InitCVar(const char* name, const char* description); + // Returns true if the CVar was created, false if it already existed + bool InitCVar(CVarCategory category, const char* name, const char* description, CVarParameter*& outParam); - std::unordered_map savedCVars; + bool LookupCVar(CVarCategory category, StringUtils::StringHash nameHash, u32& outHash); + + robin_hood::unordered_map savedCVars; + + using CVarLookupTable = robin_hood::unordered_map; // Keyed by nameHash, gives qualifiedNameHash into savedCVars + robin_hood::unordered_map cvarCategoryLookupTable; // Keyed by category }; template @@ -154,12 +173,7 @@ void CVarArray::SetCurrent(const T &val, i32 index) { cvars[index].current = val; - bool noEdit = ((u32) cvars[index].parameter->flags & (u32) CVarFlags::Noedit) != 0; - bool readOnly = ((u32) cvars[index].parameter->flags & (u32) CVarFlags::EditReadOnly) != 0; - - if (!noEdit && !readOnly) { - CVarSystemImpl::Get()->MarkDirty(); - } + CVarSystemImpl::Get()->MarkDirty(); } template diff --git a/Source/Base/Base/Util/JsonUtils.cpp b/Source/Base/Base/Util/JsonUtils.cpp index 065886ff..ddf3190f 100644 --- a/Source/Base/Base/Util/JsonUtils.cpp +++ b/Source/Base/Base/Util/JsonUtils.cpp @@ -70,6 +70,7 @@ namespace JsonUtils return true; } + bool LoadFromPathOrCreate(nlohmann::json& json, const nlohmann::json& fallback, const std::filesystem::path& path) { if (std::filesystem::exists(path)) @@ -81,6 +82,7 @@ namespace JsonUtils json = fallback; return true; } + bool SaveToPath(const nlohmann::json& json, const std::filesystem::path& path) { std::ofstream fileStream(path); @@ -103,6 +105,7 @@ namespace JsonUtils return true; } + bool LoadFromPathOrCreate(nlohmann::ordered_json& json, const nlohmann::ordered_json& fallback, const std::filesystem::path& path) { if (std::filesystem::exists(path)) @@ -114,6 +117,7 @@ namespace JsonUtils json = fallback; return true; } + bool SaveToPath(const nlohmann::ordered_json& json, const std::filesystem::path& path) { std::ofstream fileStream(path); @@ -125,11 +129,27 @@ namespace JsonUtils return true; } - void LoadCVarsIntoJson(nlohmann::json& json) + void VerifyCVarsOrFallback(nlohmann::json& json, const nlohmann::json& fallback) + { + // First implementation of CVARs didn't have a version field + if (json.find("version") == json.end()) + { + json = fallback; + return; + } + + u32 version = json["version"].get(); + if (version != CVAR_VERSION) + { + json = fallback; + } + } + + void SaveCVarsToJson(nlohmann::json& json) { CVarSystemImpl* cvarSystem = CVarSystemImpl::Get(); - // Load Integers + // Save Integers { nlohmann::json& config = json["integer"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -137,8 +157,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -146,11 +171,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load Doubles + // Save Doubles { nlohmann::json& config = json["double"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -158,8 +184,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -167,11 +198,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load Strings + // Save Strings { nlohmann::json& config = json["string"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -179,8 +211,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -188,11 +225,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load Vec4s + // Save Vec4s { nlohmann::json& config = json["vec4"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -200,8 +238,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -209,11 +252,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load IVec4s + // Save IVec4s { nlohmann::json& config = json["ivec4"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -221,8 +265,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -230,11 +279,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load ShowFlags + // Save ShowFlags { nlohmann::json& config = json["showflag"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -242,8 +292,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -251,15 +306,17 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } } - void LoadJsonIntoCVars(nlohmann::json& json) + + void LoadCVarsFromJson(nlohmann::json& json) { CVarSystemImpl* cvarSystem = CVarSystemImpl::Get(); - // Write Integers + // Load Integers { nlohmann::json& config = json["integer"]; @@ -268,15 +325,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); i32 initial = value["initial"].get(); i32 current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateIntCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateIntCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -285,14 +349,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = flags; } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write Doubles + // Load Doubles { nlohmann::json& config = json["double"]; @@ -301,15 +364,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); f64 initial = value["initial"].get(); f64 current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateFloatCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateFloatCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -318,14 +388,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write Strings + // Load Strings { nlohmann::json& config = json["string"]; @@ -334,15 +403,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); std::string& initial = value["initial"].get_ref(); std::string& current = value["current"].get_ref(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateStringCVar(key.c_str(), description.c_str(), initial.c_str(), current.c_str()); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateStringCVar(category, name.c_str(),description.c_str(), initial.c_str(), current.c_str(), flags); + } } else { @@ -351,14 +427,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write Vec4s + // Load Vec4s { nlohmann::json& config = json["vec4"]; @@ -367,15 +442,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); vec4 initial = value["initial"].get(); vec4 current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateVecFloatCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateVecFloatCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -384,14 +466,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write Vec4s + // Load IVec4s { nlohmann::json& config = json["ivec4"]; @@ -400,15 +481,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); ivec4 initial = value["initial"].get(); ivec4 current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateVecFloatCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateVecFloatCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -417,14 +505,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write ShowFlags + // Load ShowFlags { nlohmann::json& config = json["showflag"]; @@ -433,15 +520,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); ShowFlag initial = value["initial"].get(); ShowFlag current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateShowFlagCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateShowFlagCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -450,19 +544,18 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } } - void LoadCVarsIntoJson(nlohmann::ordered_json& json) + void SaveCVarsToJson(nlohmann::ordered_json& json) { CVarSystemImpl* cvarSystem = CVarSystemImpl::Get(); - // Load Integers + // Save Integers { nlohmann::ordered_json& config = json["integer"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -470,8 +563,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -479,11 +577,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load Doubles + // Save Doubles { nlohmann::ordered_json& config = json["double"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -491,8 +590,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -500,11 +604,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load Strings + // Save Strings { nlohmann::ordered_json& config = json["string"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -512,8 +617,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -521,11 +631,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load Vec4s + // Save Vec4s { nlohmann::ordered_json& config = json["vec4"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -533,8 +644,13 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -542,11 +658,12 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } - // Load IVec4s + // Save IVec4s { nlohmann::ordered_json& config = json["ivec4"]; for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) @@ -554,8 +671,40 @@ namespace JsonUtils CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; CVarParameter* parameter = cvar.parameter; + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + + nlohmann::json object = nlohmann::json::object(); + { + object["category"] = parameter->category; + object["name"] = parameter->name; + object["initial"] = cvar.initial; + object["current"] = cvar.current; + object["type"] = parameter->type; + object["flags"] = parameter->flags; + object["description"] = parameter->description; + } + + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; + } + } + + // Save ShowFlags + { + nlohmann::ordered_json& config = json["showflag"]; + for (i32 i = 0; i < cvarSystem->GetCVarArray()->lastCVar; i++) + { + CVarStorage& cvar = cvarSystem->GetCVarArray()->cvars[i]; + CVarParameter* parameter = cvar.parameter; + + if ((parameter->flags & CVarFlags::DoNotSave) != CVarFlags::None) + continue; + nlohmann::json object = nlohmann::json::object(); { + object["category"] = parameter->category; + object["name"] = parameter->name; object["initial"] = cvar.initial; object["current"] = cvar.current; object["type"] = parameter->type; @@ -563,15 +712,17 @@ namespace JsonUtils object["description"] = parameter->description; } - config[parameter->name] = object; + std::string qualifiedName = CVarSystemImpl::GetQualifiedName(parameter->category, parameter->name.c_str()); + config[qualifiedName] = object; } } } - void LoadJsonIntoCVars(nlohmann::ordered_json& json) + + void LoadCVarsFromJson(nlohmann::ordered_json& json) { CVarSystemImpl* cvarSystem = CVarSystemImpl::Get(); - // Write Integers + // Load Integers { nlohmann::ordered_json& config = json["integer"]; @@ -580,15 +731,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::ordered_json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); i32 initial = value["initial"].get(); i32 current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateIntCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateIntCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -597,14 +755,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = flags; } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write Doubles + // Load Doubles { nlohmann::ordered_json& config = json["double"]; @@ -613,15 +770,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::ordered_json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); f64 initial = value["initial"].get(); f64 current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateFloatCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateFloatCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -630,14 +794,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write Strings + // Load Strings { nlohmann::ordered_json& config = json["string"]; @@ -646,15 +809,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::ordered_json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); std::string& initial = value["initial"].get_ref(); std::string& current = value["current"].get_ref(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateStringCVar(key.c_str(), description.c_str(), initial.c_str(), current.c_str()); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateStringCVar(category, name.c_str(), description.c_str(), initial.c_str(), current.c_str(), flags); + } } else { @@ -663,14 +833,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write Vec4s + // Load Vec4s { nlohmann::ordered_json& config = json["vec4"]; @@ -679,15 +848,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::ordered_json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); vec4 initial = value["initial"].get(); vec4 current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateVecFloatCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateVecFloatCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -696,14 +872,13 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); } - - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); } } - // Write IVec4s + // Load IVec4s { nlohmann::ordered_json& config = json["ivec4"]; @@ -712,15 +887,22 @@ namespace JsonUtils const std::string& key = it.key(); nlohmann::ordered_json& value = it.value(); - u32 cvarNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); ivec4 initial = value["initial"].get(); ivec4 current = value["current"].get(); std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); - CVarParameter* parameter = cvarSystem->GetCVar(cvarNameHash); + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); if (!parameter) { - parameter = cvarSystem->CreateVecFloatCVar(key.c_str(), description.c_str(), initial, current); + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateVecFloatCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } else { @@ -729,10 +911,48 @@ namespace JsonUtils storage->initial = initial; storage->current = current; parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); + } + } + } + + // Load ShowFlags + { + nlohmann::ordered_json& config = json["showflag"]; + + for (auto it = config.begin(); it != config.end(); it++) + { + const std::string& key = it.key(); + nlohmann::ordered_json& value = it.value(); + + CVarCategory category = value["category"].get(); + std::string& name = value["name"].get_ref(); + + u32 cvarQualifiedNameHash = StringUtils::fnv1a_32(key.c_str(), key.length()); + ShowFlag initial = value["initial"].get(); + ShowFlag current = value["current"].get(); + std::string& description = value["description"].get_ref(); + CVarFlags flags = value["flags"].get(); + + CVarParameter* parameter = cvarSystem->GetCVar(cvarQualifiedNameHash); + if (!parameter) + { + if ((flags & CVarFlags::RuntimeCreated) != CVarFlags::None) + { + parameter = cvarSystem->CreateShowFlagCVar(category, name.c_str(), description.c_str(), initial, current, flags); + } } + else + { + CVarStorage* storage = cvarSystem->GetCVarArray()->GetCurrentStorage(parameter->arrayIndex); - parameter->type = value["type"].get(); - parameter->flags = value["flags"].get(); + storage->initial = initial; + storage->current = current; + parameter->description = description; + parameter->type = value["type"].get(); + parameter->flags = value["flags"].get(); + } } } } diff --git a/Source/Base/Base/Util/JsonUtils.h b/Source/Base/Base/Util/JsonUtils.h index 0585b540..1db82cbd 100644 --- a/Source/Base/Base/Util/JsonUtils.h +++ b/Source/Base/Base/Util/JsonUtils.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include @@ -14,9 +15,11 @@ namespace JsonUtils bool LoadFromPathOrCreate(nlohmann::ordered_json& json, const nlohmann::ordered_json& fallback, const std::filesystem::path& path); bool SaveToPath(const nlohmann::ordered_json& json, const std::filesystem::path& path); - void LoadCVarsIntoJson(nlohmann::json& json); - void LoadJsonIntoCVars(nlohmann::json& json); + constexpr u32 CVAR_VERSION = 1u; + void VerifyCVarsOrFallback(nlohmann::json& json, const nlohmann::json& fallback); + void SaveCVarsToJson(nlohmann::json& json); + void LoadCVarsFromJson(nlohmann::json& json); - void LoadCVarsIntoJson(nlohmann::ordered_json& json); - void LoadJsonIntoCVars(nlohmann::ordered_json& json); + void SaveCVarsToJson(nlohmann::ordered_json& json); + void LoadCVarsFromJson(nlohmann::ordered_json& json); } \ No newline at end of file diff --git a/Source/Renderer/Renderer/RenderGraph.cpp b/Source/Renderer/Renderer/RenderGraph.cpp index 561a0206..9bdb9d97 100644 --- a/Source/Renderer/Renderer/RenderGraph.cpp +++ b/Source/Renderer/Renderer/RenderGraph.cpp @@ -9,7 +9,7 @@ namespace Renderer { - AutoCVar_Int CVAR_RenderGraphPrintNumBarriers("renderGraph.printNumBarriers", "Print number of barriers automatically placed by the Rendergraph", 0, CVarFlags::EditCheckbox); + AutoCVar_Int CVAR_RenderGraphPrintNumBarriers(CVarCategory::Client | CVarCategory::Rendering, "renderGraphPrintNumBarriers", "Print number of barriers automatically placed by the Rendergraph", 0, CVarFlags::EditCheckbox); struct RenderGraphData : IRenderGraphData {