backup of thread safe changes

This commit is contained in:
EricPlayZ
2025-01-07 07:45:32 +02:00
parent fdd82c56f1
commit 9e03a97d7f
2 changed files with 38 additions and 18 deletions

View File

@ -77,8 +77,8 @@ namespace EGSDK::GamePH {
PlayerVarVector& operator=(PlayerVarVector&&) noexcept = default;
std::unique_ptr<PlayerVariable>& emplace_back(std::unique_ptr<PlayerVariable> playerVar);
std::vector<std::unique_ptr<PlayerVariable>>::iterator begin();
std::vector<std::unique_ptr<PlayerVariable>>::iterator end();
std::vector<std::unique_ptr<PlayerVariable>>::iterator beginUnsafe();
std::vector<std::unique_ptr<PlayerVariable>>::iterator endUnsafe();
bool empty();
bool none_of(const std::string& name);
@ -86,7 +86,12 @@ namespace EGSDK::GamePH {
std::unique_ptr<PlayerVariable>* FindPtr(const std::string& name);
PlayerVariable* Find(const std::string& name);
std::vector<std::unique_ptr<PlayerVariable>>::iterator Erase(const std::string& name);
template <typename Callable, typename... Args>
void ForEach(Callable&& func, Args&&... args);
private:
std::vector<std::unique_ptr<PlayerVariable>>::iterator FindIterUnsafe(const std::string& name);
std::vector<std::unique_ptr<PlayerVariable>> _playerVars{};
mutable std::mutex _mutex{};
};

View File

@ -95,15 +95,16 @@ namespace EGSDK::GamePH {
_playerVars.emplace_back(std::move(playerVar));
return _playerVars.back();
}
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::begin() {
std::lock_guard<std::mutex> lock(_mutex);
// Unsafe function: Assumes the caller has locked _mutex
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::beginUnsafe() {
return _playerVars.begin();
}
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::end() {
std::lock_guard<std::mutex> lock(_mutex);
// Unsafe function: Assumes the caller has locked _mutex
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::endUnsafe() {
return _playerVars.end();
}
bool PlayerVarVector::empty() {
std::lock_guard<std::mutex> lock(_mutex);
return _playerVars.empty();
}
bool PlayerVarVector::none_of(const std::string& name) {
@ -113,31 +114,43 @@ namespace EGSDK::GamePH {
});
}
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::FindIter(const std::string& name) {
std::lock_guard<std::mutex> lock(_mutex);
auto playerVarIt = std::find_if(_playerVars.begin(), _playerVars.end(), [&name](const auto& playerVar) {
// Unsafe function: Assumes the caller has locked _mutex
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::FindIterUnsafe(const std::string& name) {
return std::find_if(_playerVars.begin(), _playerVars.end(), [&name](const auto& playerVar) {
return playerVar->GetName() == name;
});
}
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::FindIter(const std::string& name) {
std::lock_guard<std::mutex> lock(_mutex);
return std::find_if(_playerVars.begin(), _playerVars.end(), [&name](const auto& playerVar) {
return playerVar->GetName() == name;
});
return playerVarIt;
}
std::unique_ptr<PlayerVariable>* PlayerVarVector::FindPtr(const std::string& name) {
std::lock_guard<std::mutex> lock(_mutex);
auto playerVarIt = FindIter(name);
auto playerVarIt = FindIterUnsafe(name);
return playerVarIt == _playerVars.end() ? nullptr : &*playerVarIt;
}
PlayerVariable* PlayerVarVector::Find(const std::string& name) {
std::lock_guard<std::mutex> lock(_mutex);
auto playerVarPtr = FindPtr(name);
return !playerVarPtr ? nullptr : playerVarPtr->get();
auto playerVarIt = FindIterUnsafe(name);
return playerVarIt == _playerVars.end() ? nullptr : playerVarIt->get();
}
std::vector<std::unique_ptr<PlayerVariable>>::iterator PlayerVarVector::Erase(const std::string& name) {
std::lock_guard<std::mutex> lock(_mutex);
auto playerVarIt = FindIter(name);
auto playerVarIt = FindIterUnsafe(name);
if (playerVarIt != _playerVars.end())
return _playerVars.erase(playerVarIt);
return _playerVars.end();
}
template <typename Callable, typename... Args>
void PlayerVarVector::ForEach(Callable&& func, Args&&... args) {
std::lock_guard<std::mutex> lock(_mutex);
for (auto& playerVar : _playerVars)
func(playerVar, std::forward<Args>(args)...);
}
PlayerVarVector PlayerVariables::playerVars{};
PlayerVarVector PlayerVariables::customPlayerVars{};
PlayerVarVector PlayerVariables::defaultPlayerVars{};
@ -247,13 +260,17 @@ namespace EGSDK::GamePH {
}
}
}
static void processPlayerVarSafe(DWORD64*(*playerVarsGetter)(), std::unique_ptr<PlayerVariable>& playerVarPtr) {
static void processPlayerVarSafe(std::unique_ptr<PlayerVariable>& playerVarPtr, DWORD64*(*playerVarsGetter)()) {
__try {
processPlayerVar(playerVarsGetter, playerVarPtr);
} __except (EXCEPTION_EXECUTE_HANDLER) {
SPDLOG_ERROR("Failed to process player variable: {}", playerVarPtr->GetName());
}
}
template EGameSDK_API void PlayerVarVector::ForEach<decltype(processPlayerVarSafe)>(
void(*func)(std::unique_ptr<PlayerVariable>& playerVarPtr, DWORD64*(*playerVarsGetter)()),
DWORD64*(*playerVarsGetter)()
);
void PlayerVariables::GetPlayerVars() {
if (gotPlayerVars)
@ -263,9 +280,7 @@ namespace EGSDK::GamePH {
if (!Get())
return;
for (auto& playerVarPtr : playerVars)
processPlayerVarSafe(reinterpret_cast<DWORD64*(*)()>(&Get), playerVarPtr);
playerVars.ForEach(processPlayerVarSafe, reinterpret_cast<DWORD64*(*)()>(&Get));
gotPlayerVars = true;
}