mirror of
https://github.com/EricPlayZ/EGameTools.git
synced 2025-07-18 17:37:53 +08:00
working VarManagerBase with VarRef
This commit is contained in:
@ -1,56 +1,41 @@
|
||||
#include <EGSDK\Engine\VarManagerBase.h>
|
||||
#include <EGSDK\Engine\CVars.h>
|
||||
#include <EGSDK\GamePH\PlayerVariables.h>
|
||||
#include <EGSDK\Vec4.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
template <typename VarMapType, typename VarType>
|
||||
VarMapType VarManagerBase<VarMapType, VarType>::vars{};
|
||||
template <typename VarMapType, typename VarType>
|
||||
VarMapType VarManagerBase<VarMapType, VarType>::customVars{};
|
||||
template <typename VarMapType, typename VarType>
|
||||
VarMapType VarManagerBase<VarMapType, VarType>::defaultVars{};
|
||||
template <typename VarMapT, typename VarT>
|
||||
VarMapT VarManagerBase<VarMapT, VarT>::vars{};
|
||||
template <typename VarMapT, typename VarT>
|
||||
VarMapT VarManagerBase<VarMapT, VarT>::customVars{};
|
||||
template <typename VarMapT, typename VarT>
|
||||
VarMapT VarManagerBase<VarMapT, VarT>::defaultVars{};
|
||||
template <typename VarMapT, typename VarT>
|
||||
VarMapT VarManagerBase<VarMapT, VarT>::defaultCustomVars{};
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
std::recursive_mutex VarManagerBase<VarMapType, VarType>::mutex{};
|
||||
template <typename VarMapT, typename VarT>
|
||||
std::recursive_mutex VarManagerBase<VarMapT, VarT>::mutex{};
|
||||
|
||||
#ifdef EGameSDK_EXPORTS
|
||||
template <typename VarMapType, typename VarType>
|
||||
std::unordered_map<std::string, std::any> VarManagerBase<VarMapType, VarType>::prevVarValueMap{};
|
||||
template <typename VarMapType, typename VarType>
|
||||
std::unordered_map<std::string, bool> VarManagerBase<VarMapType, VarType>::prevBoolValueMap{};
|
||||
template <typename VarMapType, typename VarType>
|
||||
std::unordered_map<std::string, uint64_t> VarManagerBase<VarMapType, VarType>::varOwnerMap{};
|
||||
#endif
|
||||
template <typename VarMapT, typename VarT>
|
||||
std::unordered_map<std::string, std::any> VarManagerBase<VarMapT, VarT>::prevVarValueMap{};
|
||||
template <typename VarMapT, typename VarT>
|
||||
std::unordered_map<std::string, bool> VarManagerBase<VarMapT, VarT>::prevBoolValueMap{};
|
||||
template <typename VarMapT, typename VarT>
|
||||
std::unordered_map<std::string, uint64_t> VarManagerBase<VarMapT, VarT>::varOwnerMap{};
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
VarType* VarManagerBase<VarMapType, VarType>::GetVar(const std::string& name) {
|
||||
return vars.Find(name);
|
||||
}
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
bool VarManagerBase<VarMapType, VarType>::IsVarManagedByBool(const std::string& name) {
|
||||
std::lock_guard lock(mutex);
|
||||
return prevBoolValueMap.find(name) != prevBoolValueMap.end() && prevBoolValueMap[name];
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
bool VarManagerBase<VarMapType, VarType>::DoesVarHaveCustomValue(const std::string& name) {
|
||||
return !customVars.none_of(name);
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
bool VarManagerBase<VarMapType, VarType>::AreAnyVarsPresent() {
|
||||
template <typename VarMapT, typename VarT>
|
||||
bool VarManagerBase<VarMapT, VarT>::AreAnyVarsPresent() {
|
||||
return !vars.empty();
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
bool VarManagerBase<VarMapType, VarType>::AreAnyCustomVarsPresent() {
|
||||
template <typename VarMapT, typename VarT>
|
||||
bool VarManagerBase<VarMapT, VarT>::AreAnyCustomVarsPresent() {
|
||||
return !customVars.empty();
|
||||
}
|
||||
template <typename VarMapType, typename VarType>
|
||||
bool VarManagerBase<VarMapType, VarType>::AreAllCustomVarsManagedByBool() {
|
||||
template <typename VarMapT, typename VarT>
|
||||
bool VarManagerBase<VarMapT, VarT>::AreAllCustomVarsManagedByBool() {
|
||||
bool allManagedByBool = true;
|
||||
|
||||
customVars.ForEach([&allManagedByBool](const std::unique_ptr<VarType>& varPtr) {
|
||||
if (!IsVarManagedByBool(varPtr->GetName())) {
|
||||
customVars.ForEach([&allManagedByBool](const std::unique_ptr<VarT>& varPtr) {
|
||||
if (!_IsManagedByBool(varPtr->GetName())) {
|
||||
allManagedByBool = false;
|
||||
return;
|
||||
}
|
||||
@ -59,6 +44,20 @@ namespace EGSDK::Engine {
|
||||
return allManagedByBool;
|
||||
}
|
||||
|
||||
template <typename VarMapT, typename VarT>
|
||||
bool VarManagerBase<VarMapT, VarT>::_IsManagedByBool(const char* name) {
|
||||
std::lock_guard lock(mutex);
|
||||
return prevBoolValueMap.find(name) != prevBoolValueMap.end() && prevBoolValueMap[name];
|
||||
}
|
||||
template <typename VarMapT, typename VarT>
|
||||
bool VarManagerBase<VarMapT, VarT>::_IsManagedByBool(VarRef<VarMapT, VarT>* var) {
|
||||
return _IsManagedByBool(var->GetName());
|
||||
}
|
||||
template <typename VarMapT, typename VarT>
|
||||
bool VarManagerBase<VarMapT, VarT>::_HasCustomValue(VarRef<VarMapT, VarT>* var) {
|
||||
return !customVars.none_of(var->GetName());
|
||||
}
|
||||
|
||||
template EGameSDK_API class VarManagerBase<CVarMap, CVar>;
|
||||
template EGameSDK_API class VarManagerBase<GamePH::PlayerVarMap, GamePH::PlayerVar>;
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
#include <EGSDK\GamePH\PlayerVariables.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
template <typename VarType>
|
||||
std::unique_ptr<VarType>& VarMapBase<VarType>::try_emplace(std::unique_ptr<VarType> var) {
|
||||
template <typename VarT>
|
||||
std::unique_ptr<VarT>& VarMapBase<VarT>::try_emplace(std::unique_ptr<VarT> var) {
|
||||
std::lock_guard lock(mutex);
|
||||
const std::string& name = var->GetName();
|
||||
auto [it, inserted] = vars.try_emplace(name, std::move(var));
|
||||
@ -12,36 +12,36 @@ namespace EGSDK::Engine {
|
||||
varsOrdered.emplace_back(name);
|
||||
return it->second;
|
||||
}
|
||||
template <typename VarType>
|
||||
bool VarMapBase<VarType>::empty() const {
|
||||
template <typename VarT>
|
||||
bool VarMapBase<VarT>::empty() const {
|
||||
std::lock_guard lock(mutex);
|
||||
return vars.empty();
|
||||
}
|
||||
template <typename VarType>
|
||||
bool VarMapBase<VarType>::none_of(const std::string& name) const {
|
||||
template <typename VarT>
|
||||
bool VarMapBase<VarT>::none_of(const std::string& name) const {
|
||||
std::lock_guard lock(mutex);
|
||||
return vars.find(name) == vars.end();
|
||||
}
|
||||
template <typename VarType>
|
||||
void VarMapBase<VarType>::reserve(size_t count) {
|
||||
template <typename VarT>
|
||||
void VarMapBase<VarT>::reserve(size_t count) {
|
||||
std::lock_guard lock(mutex);
|
||||
vars.reserve(count);
|
||||
}
|
||||
template <typename VarType>
|
||||
size_t VarMapBase<VarType>::size() {
|
||||
template <typename VarT>
|
||||
size_t VarMapBase<VarT>::size() {
|
||||
std::lock_guard lock(mutex);
|
||||
return vars.size();
|
||||
}
|
||||
|
||||
template <typename VarType>
|
||||
VarType* VarMapBase<VarType>::Find(const std::string& name) const {
|
||||
template <typename VarT>
|
||||
VarT* VarMapBase<VarT>::Find(const std::string& name) const {
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = vars.find(name);
|
||||
return (it != vars.end()) ? it->second.get() : nullptr;
|
||||
}
|
||||
|
||||
template <typename VarType>
|
||||
void VarMapBase<VarType>::Erase(const std::string& name) {
|
||||
template <typename VarT>
|
||||
void VarMapBase<VarT>::Erase(const std::string& name) {
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = vars.find(name);
|
||||
if (it == vars.end())
|
||||
|
@ -15,136 +15,188 @@
|
||||
#pragma intrinsic(_ReturnAddress)
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
#define StaticAssertValueType static_assert(std::is_same_v<T, std::string> || std::is_same_v<T, float> || std::is_same_v<T, int> || std::is_same_v<T, Vec3> || std::is_same_v<T, Vec4> || std::is_same_v<T, bool>, "Invalid type: value must be string, float, int, Vec3, Vec4 or bool")
|
||||
template <typename T>
|
||||
concept AllowedVarTypes = std::is_same_v<T, std::string> || std::is_same_v<T, float> || std::is_same_v<T, int> || std::is_same_v<T, Vec3> || std::is_same_v<T, Vec4> || std::is_same_v<T, bool>;
|
||||
|
||||
template <typename VarMapType, typename VarType>
|
||||
class EGameSDK_API VarManagerBase {
|
||||
template <typename VarMapT, typename VarT>
|
||||
class VarManagerBase;
|
||||
|
||||
template <typename VarMapT, typename VarT>
|
||||
class VarRef {
|
||||
public:
|
||||
static VarMapType vars;
|
||||
static VarMapType customVars;
|
||||
static VarMapType defaultVars;
|
||||
VarRef(VarT* var) : ptr(var) {
|
||||
name = var->GetName();
|
||||
}
|
||||
VarRef(const char* name, VarMapT& map) : name(name), ptr(map.Find(name)) {}
|
||||
|
||||
template <typename T>
|
||||
static std::optional<T> GetVarValue(const std::string& name) {
|
||||
StaticAssertValueType;
|
||||
auto var = vars.Find(name);
|
||||
if (!var)
|
||||
const char* GetName() const {
|
||||
return name;
|
||||
}
|
||||
VarType GetType() const {
|
||||
return ptr ? ptr->GetType() : VarType::NONE;
|
||||
}
|
||||
VarT* GetPtr() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <AllowedVarTypes T>
|
||||
std::optional<T> GetValue() {
|
||||
if (!ptr)
|
||||
return std::nullopt;
|
||||
auto value = var->GetValue();
|
||||
|
||||
auto value = ptr->GetValue();
|
||||
auto variantValue = std::get_if<T>(&value);
|
||||
return variantValue ? std::optional<T>(*variantValue) : std::nullopt;
|
||||
}
|
||||
template <typename T>
|
||||
static std::optional<T> GetVarValue(VarType* var) {
|
||||
StaticAssertValueType;
|
||||
if (!var)
|
||||
return std::nullopt;
|
||||
auto value = var->GetValue();
|
||||
auto variantValue = std::get_if<T>(&value);
|
||||
return variantValue ? std::optional<T>(*variantValue) : std::nullopt;
|
||||
}
|
||||
template <typename T>
|
||||
static std::optional<T> GetVarValueFromMap(const std::string& name, const VarMapType& map) {
|
||||
StaticAssertValueType;
|
||||
auto var = map.Find(name);
|
||||
return GetVarValue<T>(var);
|
||||
}
|
||||
|
||||
static VarType* GetVar(const std::string& name);
|
||||
|
||||
template <typename T>
|
||||
static void ChangeVar(const std::string& name, T value) {
|
||||
StaticAssertValueType;
|
||||
auto var = vars.Find(name);
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
ChangeVar<T>(var, value);
|
||||
}
|
||||
template <typename T>
|
||||
static void ChangeVar(VarType* var, T value) {
|
||||
StaticAssertValueType;
|
||||
|
||||
if (!var)
|
||||
template <AllowedVarTypes T>
|
||||
void SetValue(T value) {
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
switch (var->GetType()) {
|
||||
case Engine::VarType::Float:
|
||||
ChangeVar<float>(var, std::stof(Utils::Values::to_string(value)));
|
||||
switch (ptr->GetType()) {
|
||||
case VarType::Float:
|
||||
SetValue<float>(std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
case Engine::VarType::Int:
|
||||
ChangeVar<int>(var, std::stof(Utils::Values::to_string(value)));
|
||||
case VarType::Int:
|
||||
SetValue<int>(std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
case Engine::VarType::Bool:
|
||||
ChangeVar<bool>(var, std::stof(Utils::Values::to_string(value)));
|
||||
case VarType::Bool:
|
||||
SetValue<bool>(std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
var->SetValue(value);
|
||||
ptr->SetValue(value);
|
||||
}
|
||||
template <typename T>
|
||||
static void ChangeVarFromMap(const std::string& name, T value, const VarMapType& map) {
|
||||
StaticAssertValueType;
|
||||
auto var = map.Find(name);
|
||||
ChangeVar<T>(var, value);
|
||||
template <AllowedVarTypes T>
|
||||
void SetValueFromList(T value) {
|
||||
VarManagerBase<VarMapT, VarT>::template _SetValueFromList<T>(this, value);
|
||||
}
|
||||
template <typename T>
|
||||
static void ChangeVarFromList(const std::string& name, T value) {
|
||||
StaticAssertValueType;
|
||||
|
||||
auto var = vars.Find(name);
|
||||
bool IsManagedByBool() {
|
||||
return VarManagerBase<VarMapT, VarT>::_IsManagedByBool(this);
|
||||
}
|
||||
bool HasCustomValue() {
|
||||
return VarManagerBase<VarMapT, VarT>::_HasCustomValue(this);
|
||||
}
|
||||
|
||||
template <AllowedVarTypes T>
|
||||
void ManageByBool(T valueIfTrue, T valueIfFalse, bool boolVal, bool usePreviousVal = true) {
|
||||
VarManagerBase<VarMapT, VarT>::template _ManageByBool<T>(this, valueIfTrue, valueIfFalse, boolVal, usePreviousVal);
|
||||
}
|
||||
template <AllowedVarTypes T>
|
||||
void SaveVariableAsDefault() {
|
||||
VarManagerBase<VarMapT, VarT>::template _SaveVariableAsDefault<T>(this);
|
||||
}
|
||||
template <AllowedVarTypes T>
|
||||
void RestoreVarToDefault(bool restoreToSavedVars = false) {
|
||||
VarManagerBase<VarMapT, VarT>::template _RestoreVarToDefault<T>(this, restoreToSavedVars);
|
||||
}
|
||||
private:
|
||||
const char* name = nullptr;
|
||||
VarT* ptr = nullptr;
|
||||
};
|
||||
|
||||
template <typename VarMapT, typename VarT>
|
||||
class EGameSDK_API VarManagerBase {
|
||||
template <typename, typename>
|
||||
friend class VarRef;
|
||||
|
||||
public:
|
||||
static VarMapT vars;
|
||||
static VarMapT customVars;
|
||||
static VarMapT defaultVars;
|
||||
static VarMapT defaultCustomVars;
|
||||
|
||||
static std::optional<VarRef<VarMapT, VarT>> GetVarRef(VarT* var) {
|
||||
return std::optional<VarRef<VarMapT, VarT>>(VarRef<VarMapT, VarT>(var));
|
||||
}
|
||||
static std::optional<VarRef<VarMapT, VarT>> GetVarRef(const char* name) {
|
||||
VarRef<VarMapT, VarT> varRef(name, vars);
|
||||
return varRef.GetPtr() ? std::optional<VarRef<VarMapT, VarT>>(varRef) : std::nullopt;
|
||||
}
|
||||
static std::optional<VarRef<VarMapT, VarT>> GetCustomVarRef(const char* name) {
|
||||
VarRef<VarMapT, VarT> varRef(name, customVars);
|
||||
return varRef.GetPtr() ? std::optional<VarRef<VarMapT, VarT>>(varRef) : std::nullopt;
|
||||
}
|
||||
static std::optional<VarRef<VarMapT, VarT>> GetDefaultVarRef(const char* name) {
|
||||
VarRef<VarMapT, VarT> varRef(name, defaultVars);
|
||||
return varRef.GetPtr() ? std::optional<VarRef<VarMapT, VarT>>(varRef) : std::nullopt;
|
||||
}
|
||||
static std::optional<VarRef<VarMapT, VarT>> GetCustomDefaultVarRef(const char* name) {
|
||||
VarRef<VarMapT, VarT> varRef(name, defaultCustomVars);
|
||||
return varRef.GetPtr() ? std::optional<VarRef<VarMapT, VarT>>(varRef) : std::nullopt;
|
||||
}
|
||||
|
||||
static bool AreAnyVarsPresent();
|
||||
static bool AreAnyCustomVarsPresent();
|
||||
static bool AreAllCustomVarsManagedByBool();
|
||||
|
||||
template <AllowedVarTypes T>
|
||||
static void ManageVarByBool(const char* name, T valueIfTrue, T valueIfFalse, bool boolVal, bool usePreviousVal = true) {
|
||||
auto playerVar = GetVarRef(name);
|
||||
if (playerVar)
|
||||
_ManageByBool(&*playerVar, valueIfTrue, valueIfFalse, boolVal, usePreviousVal);
|
||||
}
|
||||
private:
|
||||
static std::unordered_map<std::string, std::any> prevVarValueMap;
|
||||
static std::unordered_map<std::string, bool> prevBoolValueMap;
|
||||
static std::unordered_map<std::string, uint64_t> varOwnerMap;
|
||||
static std::recursive_mutex mutex;
|
||||
|
||||
static bool _IsManagedByBool(const char* name);
|
||||
static bool _IsManagedByBool(VarRef<VarMapT, VarT>* var);
|
||||
static bool _HasCustomValue(VarRef<VarMapT, VarT>* var);
|
||||
|
||||
template <AllowedVarTypes T>
|
||||
static void _SetValueFromList(VarRef<VarMapT, VarT>* var, T value) {
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
ChangeVarFromList<T>(var, value);
|
||||
}
|
||||
template <typename T>
|
||||
static void ChangeVarFromList(VarType* var, T value) {
|
||||
StaticAssertValueType;
|
||||
auto name = var->GetName();
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
auto customVar = customVars.Find(var->GetName());
|
||||
auto defVar = defaultVars.Find(var->GetName());
|
||||
auto customVar = GetCustomVarRef(name);
|
||||
auto defVar = GetDefaultVarRef(name);
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
switch (var->GetType()) {
|
||||
case Engine::VarType::Float:
|
||||
ChangeVarFromList<float>(var, std::stof(Utils::Values::to_string(value)));
|
||||
case VarType::Float:
|
||||
_SetValueFromList<float>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
case Engine::VarType::Int:
|
||||
ChangeVarFromList<int>(var, std::stof(Utils::Values::to_string(value)));
|
||||
case VarType::Int:
|
||||
_SetValueFromList<int>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
case Engine::VarType::Bool:
|
||||
ChangeVarFromList<bool>(var, std::stof(Utils::Values::to_string(value)));
|
||||
case VarType::Bool:
|
||||
_SetValueFromList<bool>(var, std::stof(Utils::Values::to_string(value)));
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!customVar)
|
||||
customVar = customVars.try_emplace(std::make_unique<VarType>(var->GetName(), var->GetType())).get();
|
||||
customVar = customVars.try_emplace(std::make_unique<VarT>(name, var->GetType())).get();
|
||||
if (!defVar) {
|
||||
defVar = defaultVars.try_emplace(std::make_unique<VarType>(var->GetName(), var->GetType())).get();
|
||||
if (auto varValue = GetVarValue<T>(var); defVar && varValue)
|
||||
defVar->SetValue(*varValue);
|
||||
defVar = defaultVars.try_emplace(std::make_unique<VarT>(name, var->GetType())).get();
|
||||
if (auto varValue = var->GetValue<T>(); defVar && varValue)
|
||||
defVar->SetValue<T>(*varValue);
|
||||
}
|
||||
|
||||
if (customVar)
|
||||
customVar->SetValue(value);
|
||||
var->SetValue(value);
|
||||
}
|
||||
template <AllowedVarTypes T>
|
||||
static void _ManageByBool(VarRef<VarMapT, VarT>* var, T valueIfTrue, T valueIfFalse, bool boolVal, bool usePreviousVal = true) {
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
template <typename T>
|
||||
static void ManageVarByBool(const std::string& name, T valueIfTrue, T valueIfFalse, bool boolVal, bool usePreviousVal = true) {
|
||||
uint64_t caller = reinterpret_cast<uint64_t>(_ReturnAddress());
|
||||
|
||||
std::lock_guard lock(mutex);
|
||||
|
||||
const char* name = var->GetName();
|
||||
|
||||
auto ownerIt = varOwnerMap.find(name);
|
||||
if (ownerIt != varOwnerMap.end() && ownerIt->second != caller)
|
||||
return;
|
||||
@ -156,15 +208,15 @@ namespace EGSDK::Engine {
|
||||
|
||||
if (boolVal) {
|
||||
if (!prevBoolValue) {
|
||||
auto varValue = GetVarValue<T>(name);
|
||||
auto varValue = var->GetValue<T>();
|
||||
prevVarValueMap[name] = varValue ? *varValue : T{};
|
||||
}
|
||||
|
||||
ChangeVarFromList(name, valueIfTrue);
|
||||
_SetValueFromList<T>(var, valueIfTrue);
|
||||
prevBoolValue = true;
|
||||
varOwnerMap[name] = caller;
|
||||
} else if (prevBoolValue) {
|
||||
ChangeVarFromList(name, usePreviousVal ? std::any_cast<T>(prevValueAny) : valueIfFalse);
|
||||
_SetValueFromList<T>(var, usePreviousVal ? std::any_cast<T>(prevValueAny) : valueIfFalse);
|
||||
defaultVars.Erase(name);
|
||||
customVars.Erase(name);
|
||||
prevVarValueMap.erase(name);
|
||||
@ -172,50 +224,40 @@ namespace EGSDK::Engine {
|
||||
varOwnerMap.erase(name);
|
||||
}
|
||||
}
|
||||
static bool IsVarManagedByBool(const std::string& name);
|
||||
static bool DoesVarHaveCustomValue(const std::string& name);
|
||||
static bool AreAnyVarsPresent();
|
||||
static bool AreAnyCustomVarsPresent();
|
||||
static bool AreAllCustomVarsManagedByBool();
|
||||
|
||||
template <typename T>
|
||||
static void RestoreVariableToDefault(VarType* var, bool eraseFromMaps = true) {
|
||||
if (IsVarManagedByBool(var->GetName()))
|
||||
template <AllowedVarTypes T>
|
||||
static void _SaveVariableAsDefault(VarRef<VarMapT, VarT>* var) {
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
auto defValue = GetVarValueFromMap<T>(var->GetName(), defaultVars);
|
||||
auto customDefaultVar = GetCustomDefaultVarRef(var->GetName());
|
||||
|
||||
auto varValue = var->GetValue<T>();
|
||||
if (!varValue)
|
||||
return;
|
||||
customDefaultVar->SetValue(*varValue);
|
||||
}
|
||||
template <AllowedVarTypes T>
|
||||
static void _RestoreVarToDefault(VarRef<VarMapT, VarT>* var, bool restoreToSavedVars = false) {
|
||||
if (!var)
|
||||
return;
|
||||
if (_IsManagedByBool(var))
|
||||
return;
|
||||
|
||||
const char* name = var->GetName();
|
||||
|
||||
auto defVar = !restoreToSavedVars ? GetDefaultVarRef(name) : GetCustomDefaultVarRef(name);
|
||||
if (!defVar)
|
||||
return;
|
||||
auto defValue = defVar->GetValue<T>();
|
||||
if (!defValue)
|
||||
return;
|
||||
|
||||
ChangeVar(var->GetName(), *defValue);
|
||||
var->SetValue<T>(*defValue);
|
||||
|
||||
if (eraseFromMaps) {
|
||||
defaultVars.Erase(var->GetName());
|
||||
customVars.Erase(var->GetName());
|
||||
if (!restoreToSavedVars) {
|
||||
defaultVars.Erase(name);
|
||||
customVars.Erase(name);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
static void RestoreVariableToDefaultFromMap(VarType* var, VarMapType& map, bool eraseFromMaps = true) {
|
||||
if (IsVarManagedByBool(var->GetName()))
|
||||
return;
|
||||
|
||||
auto defValue = GetVarValueFromMap<T>(var->GetName(), map);
|
||||
if (!defValue)
|
||||
return;
|
||||
|
||||
ChangeVar(var->GetName(), *defValue);
|
||||
|
||||
if (eraseFromMaps) {
|
||||
map.Erase(var->GetName());
|
||||
customVars.Erase(var->GetName());
|
||||
}
|
||||
}
|
||||
private:
|
||||
static std::unordered_map<std::string, std::any> prevVarValueMap;
|
||||
static std::unordered_map<std::string, bool> prevBoolValueMap;
|
||||
static std::unordered_map<std::string, uint64_t> varOwnerMap;
|
||||
static std::recursive_mutex mutex;
|
||||
};
|
||||
|
||||
#undef StaticAssertValueType
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
#include <EGSDK\Exports.h>
|
||||
|
||||
namespace EGSDK::Engine {
|
||||
template <typename VarType>
|
||||
template <typename VarT>
|
||||
class EGameSDK_API VarMapBase {
|
||||
public:
|
||||
VarMapBase() = default;
|
||||
@ -19,13 +19,13 @@ namespace EGSDK::Engine {
|
||||
|
||||
virtual ~VarMapBase() = default;
|
||||
|
||||
virtual std::unique_ptr<VarType>& try_emplace(std::unique_ptr<VarType> var);
|
||||
virtual std::unique_ptr<VarT>& try_emplace(std::unique_ptr<VarT> var);
|
||||
bool empty() const;
|
||||
bool none_of(const std::string& name) const;
|
||||
void reserve(size_t count);
|
||||
size_t size();
|
||||
|
||||
VarType* Find(const std::string& name) const;
|
||||
VarT* Find(const std::string& name) const;
|
||||
|
||||
virtual void Erase(const std::string& name);
|
||||
|
||||
@ -36,7 +36,7 @@ namespace EGSDK::Engine {
|
||||
func(vars.at(name), std::forward<Args>(args)...);
|
||||
}
|
||||
protected:
|
||||
std::unordered_map<std::string, std::unique_ptr<VarType>> vars{};
|
||||
std::unordered_map<std::string, std::unique_ptr<VarT>> vars{};
|
||||
std::vector<std::string> varsOrdered{};
|
||||
mutable std::recursive_mutex mutex{};
|
||||
};
|
||||
|
@ -46,7 +46,6 @@ namespace EGSDK::GamePH {
|
||||
|
||||
class EGameSDK_API PlayerVariables : public Engine::VarManagerBase<PlayerVarMap, PlayerVar> {
|
||||
public:
|
||||
static PlayerVarMap customDefaultVars;
|
||||
static std::atomic<bool> gotPlayerVars;
|
||||
|
||||
#ifdef EGameSDK_EXPORTS
|
||||
|
@ -72,7 +72,6 @@ namespace EGSDK::GamePH {
|
||||
SetType(Engine::VarType::Bool);
|
||||
}
|
||||
|
||||
PlayerVarMap PlayerVariables::customDefaultVars{};
|
||||
std::atomic<bool> PlayerVariables::gotPlayerVars = false;
|
||||
static bool sortedPlayerVars = false;
|
||||
|
||||
@ -149,7 +148,7 @@ namespace EGSDK::GamePH {
|
||||
playerVarPtr.reset(floatPlayerVar);
|
||||
playerVarPtr->SetName(varName);
|
||||
playerVarPtr->SetType(varType);
|
||||
updateDefaultVar(PlayerVariables::customDefaultVars, varName, floatPlayerVar->floatValue.data, floatPlayerVar->defaultFloatValue.data);
|
||||
updateDefaultVar(PlayerVariables::defaultCustomVars, varName, floatPlayerVar->floatValue.data, floatPlayerVar->defaultFloatValue.data);
|
||||
|
||||
offset += FLOAT_SIZE_OFFSET;
|
||||
return;
|
||||
@ -163,7 +162,7 @@ namespace EGSDK::GamePH {
|
||||
playerVarPtr.reset(boolPlayerVar);
|
||||
playerVarPtr->SetName(varName);
|
||||
playerVarPtr->SetType(varType);
|
||||
updateDefaultVar(PlayerVariables::customDefaultVars, varName, boolPlayerVar->boolValue.data, boolPlayerVar->defaultBoolValue.data);
|
||||
updateDefaultVar(PlayerVariables::defaultCustomVars, varName, boolPlayerVar->boolValue.data, boolPlayerVar->defaultBoolValue.data);
|
||||
|
||||
offset += BOOL_SIZE_OFFSET;
|
||||
return;
|
||||
@ -192,7 +191,7 @@ namespace EGSDK::GamePH {
|
||||
|
||||
customVars.reserve(vars.size());
|
||||
defaultVars.reserve(vars.size());
|
||||
customDefaultVars.reserve(vars.size());
|
||||
defaultCustomVars.reserve(vars.size());
|
||||
|
||||
vars.ForEach(processPlayerVarSafe, reinterpret_cast<uint64_t*(*)()>(&Get));
|
||||
gotPlayerVars = true;
|
||||
|
@ -36,21 +36,21 @@ namespace EGT::Menu {
|
||||
return lowerKey.find(lowerFilter) != std::string::npos;
|
||||
}
|
||||
static void RestoreVariableToDefault(const std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
auto cVar = cVarPtr.get();
|
||||
auto cVar = EGSDK::Engine::CVars::GetVarRef(cVarPtr.get());
|
||||
|
||||
ImGui_impl::DeferredActions::Add([cVar]() {
|
||||
ImGui_impl::DeferredActions::Add([cVar]() mutable {
|
||||
switch (cVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
EGSDK::Engine::CVars::RestoreVariableToDefault<float>(cVar);
|
||||
cVar->RestoreVarToDefault<float>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
EGSDK::Engine::CVars::RestoreVariableToDefault<int>(cVar);
|
||||
cVar->RestoreVarToDefault<int>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Vec3:
|
||||
EGSDK::Engine::CVars::RestoreVariableToDefault<EGSDK::Vec3>(cVar);
|
||||
cVar->RestoreVarToDefault<EGSDK::Vec3>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Vec4:
|
||||
EGSDK::Engine::CVars::RestoreVariableToDefault<EGSDK::Vec4>(cVar);
|
||||
cVar->RestoreVarToDefault<EGSDK::Vec4>();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -63,48 +63,48 @@ namespace EGT::Menu {
|
||||
});
|
||||
}
|
||||
static void RenderRendererCVar(const std::unique_ptr<EGSDK::Engine::CVar>& cVarPtr) {
|
||||
auto cVar = cVarPtr.get();
|
||||
auto cVar = EGSDK::Engine::CVars::GetVarRef(cVarPtr.get());
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::Engine::CVars::IsVarManagedByBool(cVar->GetName()));
|
||||
ImGui::BeginDisabled(cVar->IsManagedByBool());
|
||||
switch (cVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto value = EGSDK::Engine::CVars::GetVarValue<float>(cVar);
|
||||
auto value = cVar->GetValue<float>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat(cVar->GetName(), &newValue))
|
||||
EGSDK::Engine::CVars::ChangeVarFromList(cVar, newValue);
|
||||
cVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Int:
|
||||
{
|
||||
auto value = EGSDK::Engine::CVars::GetVarValue<int>(cVar);
|
||||
auto value = cVar->GetValue<int>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputInt(cVar->GetName(), &newValue))
|
||||
EGSDK::Engine::CVars::ChangeVarFromList(cVar, newValue);
|
||||
cVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Vec3:
|
||||
{
|
||||
auto value = EGSDK::Engine::CVars::GetVarValue<EGSDK::Vec3>(cVar);
|
||||
auto value = cVar->GetValue<EGSDK::Vec3>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat3(cVar->GetName(), reinterpret_cast<float*>(&newValue)))
|
||||
EGSDK::Engine::CVars::ChangeVarFromList(cVar, newValue);
|
||||
cVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Vec4:
|
||||
{
|
||||
auto value = EGSDK::Engine::CVars::GetVarValue<EGSDK::Vec4>(cVar);
|
||||
auto value = cVar->GetValue<EGSDK::Vec4>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat4(cVar->GetName(), reinterpret_cast<float*>(&newValue)))
|
||||
EGSDK::Engine::CVars::ChangeVarFromList(cVar, newValue);
|
||||
cVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -115,13 +115,13 @@ namespace EGT::Menu {
|
||||
ImGui::SameLine();
|
||||
std::string restoreBtnName = "Restore##" + std::string(cVar->GetName());
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::Engine::CVars::DoesVarHaveCustomValue(cVar->GetName()) || EGSDK::Engine::CVars::IsVarManagedByBool(cVar->GetName()));
|
||||
ImGui::BeginDisabled(!cVar->HasCustomValue() || cVar->IsManagedByBool());
|
||||
if (ImGui::Button(restoreBtnName.c_str(), "Restores renderer cvar to default"))
|
||||
RestoreVariableToDefault(cVarPtr);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
static void HandleRendererCVarsList() {
|
||||
ImGui::BeginDisabled(EGSDK::Engine::CVars::AreAnyVarsPresent());
|
||||
ImGui::BeginDisabled(!EGSDK::Engine::CVars::AreAnyVarsPresent());
|
||||
if (ImGui::CollapsingHeader("Renderer CVars list", ImGuiTreeNodeFlags_None)) {
|
||||
ImGui::Indent();
|
||||
|
||||
|
@ -91,8 +91,8 @@ namespace EGT::Menu {
|
||||
return;
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::customVars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& customPlayerVarPtr) {
|
||||
auto customPlayerVar = customPlayerVarPtr.get();
|
||||
if (EGSDK::GamePH::PlayerVariables::IsVarManagedByBool(customPlayerVar->GetName()))
|
||||
auto customPlayerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(customPlayerVarPtr.get());
|
||||
if (customPlayerVar->IsManagedByBool())
|
||||
return;
|
||||
|
||||
switch (customPlayerVar->GetType()) {
|
||||
@ -100,18 +100,22 @@ namespace EGT::Menu {
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto customVarValue = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(customPlayerVar);
|
||||
auto customVarValue = customPlayerVar->GetValue<float>();
|
||||
if (!customVarValue)
|
||||
return;
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVar(customPlayerVar->GetName(), *customVarValue);
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(customPlayerVar->GetName());
|
||||
if (!playerVar)
|
||||
playerVar->SetValue(*customVarValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto customVarValue = EGSDK::GamePH::PlayerVariables::GetVarValue<bool>(customPlayerVar);
|
||||
auto customVarValue = customPlayerVar->GetValue<bool>();
|
||||
if (!customVarValue)
|
||||
return;
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVar(customPlayerVar->GetName(), *customVarValue);
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(customPlayerVar->GetName());
|
||||
if (!playerVar)
|
||||
playerVar->SetValue(*customVarValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -150,7 +154,7 @@ namespace EGT::Menu {
|
||||
if (name.empty())
|
||||
continue;
|
||||
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVar(name);
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(name.c_str());
|
||||
if (!playerVar)
|
||||
continue;
|
||||
|
||||
@ -159,7 +163,7 @@ namespace EGT::Menu {
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto varValue = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(playerVar);
|
||||
auto varValue = playerVar->GetValue<float>();
|
||||
if (!varValue)
|
||||
return;
|
||||
replaceParamValue(line, std::to_string(*varValue));
|
||||
@ -167,7 +171,7 @@ namespace EGT::Menu {
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto varValue = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(playerVar);
|
||||
auto varValue = playerVar->GetValue<bool>();
|
||||
if (!varValue)
|
||||
return;
|
||||
replaceParamValue(line, *varValue ? "true" : "false");
|
||||
@ -209,25 +213,26 @@ namespace EGT::Menu {
|
||||
if (value.empty())
|
||||
continue;
|
||||
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVar(name, value);
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(name.c_str());
|
||||
if (playerVar)
|
||||
playerVar->SetValue(value);
|
||||
}
|
||||
file.close();
|
||||
ImGui::OpenPopup("Loaded player variables!");
|
||||
}
|
||||
|
||||
static void RestoreVariableToDefault(const std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
auto playerVar = playerVarPtr.get();
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(playerVarPtr.get());
|
||||
|
||||
ImGui_impl::DeferredActions::Add([playerVar]() {
|
||||
auto& defVars = restoreVarsToSavedVarsEnabled ? EGSDK::GamePH::PlayerVariables::customDefaultVars : EGSDK::GamePH::PlayerVariables::defaultVars;
|
||||
ImGui_impl::DeferredActions::Add([playerVar]() mutable {
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
EGSDK::GamePH::PlayerVariables::RestoreVariableToDefaultFromMap<float>(playerVar, defVars, !restoreVarsToSavedVarsEnabled);
|
||||
playerVar->RestoreVarToDefault<float>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
EGSDK::GamePH::PlayerVariables::RestoreVariableToDefaultFromMap<bool>(playerVar, defVars, !restoreVarsToSavedVarsEnabled);
|
||||
playerVar->RestoreVarToDefault<bool>(restoreVarsToSavedVarsEnabled);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -241,32 +246,24 @@ namespace EGT::Menu {
|
||||
|
||||
ImGui::OpenPopup("Restored player variables!");
|
||||
}
|
||||
static void SaveVariableAsDefault(const std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(playerVarPtr.get());
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
playerVar->SaveVariableAsDefault<float>();
|
||||
break;
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
playerVar->SaveVariableAsDefault<bool>();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void SaveVariablesAsDefault() {
|
||||
EGSDK::GamePH::PlayerVariables::vars.ForEach([](std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
auto playerVar = playerVarPtr.get();
|
||||
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto varValue = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(playerVar);
|
||||
if (!varValue)
|
||||
return;
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVarFromMap(playerVar->GetName(), *varValue, EGSDK::GamePH::PlayerVariables::customDefaultVars);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto varValue = EGSDK::GamePH::PlayerVariables::GetVarValue<bool>(playerVar);
|
||||
if (!varValue)
|
||||
return;
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVarFromMap(playerVar->GetName(), *varValue, EGSDK::GamePH::PlayerVariables::customDefaultVars);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SaveVariableAsDefault(playerVarPtr);
|
||||
});
|
||||
ImGui::OpenPopup("Saved current player variables!");
|
||||
}
|
||||
@ -302,30 +299,30 @@ namespace EGT::Menu {
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
static void RenderPlayerVariable(const std::unique_ptr<EGSDK::GamePH::PlayerVar>& playerVarPtr) {
|
||||
auto playerVar = playerVarPtr.get();
|
||||
auto playerVar = EGSDK::GamePH::PlayerVariables::GetVarRef(playerVarPtr.get());
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::GamePH::PlayerVariables::IsVarManagedByBool(playerVar->GetName()));
|
||||
ImGui::BeginDisabled(playerVar->IsManagedByBool());
|
||||
switch (playerVar->GetType()) {
|
||||
case EGSDK::Engine::VarType::String:
|
||||
break; // TO IMPLEMENT
|
||||
case EGSDK::Engine::VarType::Float:
|
||||
{
|
||||
auto value = EGSDK::GamePH::PlayerVariables::GetVarValue<float>(playerVar);
|
||||
auto value = playerVar->GetValue<float>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::InputFloat(playerVar->GetName(), &newValue))
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVarFromList(playerVar, newValue);
|
||||
playerVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
case EGSDK::Engine::VarType::Bool:
|
||||
{
|
||||
auto value = EGSDK::GamePH::PlayerVariables::GetVarValue<bool>(playerVar);
|
||||
auto value = playerVar->GetValue<bool>();
|
||||
if (!value)
|
||||
return;
|
||||
auto newValue = *value;
|
||||
if (ImGui::Checkbox(playerVar->GetName(), &newValue))
|
||||
EGSDK::GamePH::PlayerVariables::ChangeVarFromList(playerVar, newValue);
|
||||
playerVar->SetValueFromList(newValue);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -336,7 +333,7 @@ namespace EGT::Menu {
|
||||
ImGui::SameLine();
|
||||
std::string restoreBtnName = "Restore##" + std::string(playerVarPtr->GetName());
|
||||
|
||||
ImGui::BeginDisabled(EGSDK::GamePH::PlayerVariables::DoesVarHaveCustomValue(playerVar->GetName()) || EGSDK::GamePH::PlayerVariables::IsVarManagedByBool(playerVar->GetName()));
|
||||
ImGui::BeginDisabled(!playerVar->HasCustomValue() || playerVar->IsManagedByBool());
|
||||
if (ImGui::Button(restoreBtnName.c_str(), "Restores player variable to default"))
|
||||
RestoreVariableToDefault(playerVarPtr);
|
||||
ImGui::EndDisabled();
|
||||
|
Reference in New Issue
Block a user