From 65cffba7f518c5c1fb32f62f99213f5d5d783679 Mon Sep 17 00:00:00 2001 From: Ersh <16157893+ersh1@users.noreply.github.com> Date: Tue, 28 May 2024 22:23:02 +0200 Subject: [PATCH] Version 2.3.3 --- CMakeLists.txt | 2 +- src/ActiveClip.cpp | 17 +++++- src/Variants.cpp | 137 ++++++++++++++++++++++++++++----------------- src/Variants.h | 4 ++ 4 files changed, 107 insertions(+), 53 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8952341..432de24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.22) project( OpenAnimationReplacer - VERSION 2.3.2 + VERSION 2.3.3 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/src/ActiveClip.cpp b/src/ActiveClip.cpp index f7b8255..3f99805 100644 --- a/src/ActiveClip.cpp +++ b/src/ActiveClip.cpp @@ -251,7 +251,10 @@ void ActiveClip::PreUpdate(RE::hkbClipGenerator* a_clipGenerator, const RE::hkbC // do not try to replace with other variants here Variant* dummy = nullptr; if (ShouldReplaceAnimation(newReplacementAnim, false, dummy)) { - const float blendTime = HasReplacementAnimation() ? GetReplacementAnimation()->GetCustomBlendTime(CustomBlendType::kInterrupt, false) : Settings::fDefaultBlendTimeOnInterrupt; + float blendTime = HasReplacementAnimation() ? GetReplacementAnimation()->GetCustomBlendTime(CustomBlendType::kInterrupt, false) : Settings::fDefaultBlendTimeOnInterrupt; + if (a_clipGenerator->animationControl->playbackSpeed > 0.f) { + blendTime /= a_clipGenerator->animationControl->playbackSpeed; + } QueueReplacementAnimation(newReplacementAnim, blendTime, QueuedReplacement::Type::kRestart, AnimationLogEntry::Event::kInterrupt); } } @@ -274,6 +277,10 @@ void ActiveClip::PreUpdate(RE::hkbClipGenerator* a_clipGenerator, const RE::hkbC blendTime = 0.f; } + if (a_clipGenerator->animationControl->playbackSpeed > 0.f) { + blendTime /= a_clipGenerator->animationControl->playbackSpeed; + } + bool bTryReplaceOnLoop = false; hkbClipGenerator_ComputeBeginAndEndLocalTime(a_clipGenerator, a_timestep + blendTime, &prevLocalTime, &newLocalTime, &numLoops, &newAtEnd); if (numLoops > 0) { @@ -492,7 +499,10 @@ bool ActiveClip::OnLoopOrEcho(RE::hkbClipGenerator* a_clipGenerator, bool a_bIsE // don't run the entire logic - we don't want to replace this with another animation, just replace with the next variant of the same animation Variant* variant = nullptr; [[maybe_unused]] const uint16_t newVariantIndex = _currentReplacementAnimation->GetIndex(this, variant); - const float blendTime = GetReplacementAnimation()->GetCustomBlendTime(a_bIsEcho ? CustomBlendType::kEcho : CustomBlendType::kLoop, true); + float blendTime = GetReplacementAnimation()->GetCustomBlendTime(a_bIsEcho ? CustomBlendType::kEcho : CustomBlendType::kLoop, true); + if (a_clipGenerator->animationControl->playbackSpeed > 0.f) { + blendTime /= a_clipGenerator->animationControl->playbackSpeed; + } QueueReplacementAnimation(_currentReplacementAnimation, blendTime, a_bIsEcho ? QueuedReplacement::Type::kRestart : QueuedReplacement::Type::kLoop, a_bIsEcho ? AnimationLogEntry::Event::kEchoReplace : AnimationLogEntry::Event::kLoopReplace, variant); return true; } @@ -507,6 +517,9 @@ bool ActiveClip::OnLoopOrEcho(RE::hkbClipGenerator* a_clipGenerator, bool a_bIsE if (ShouldReplaceAnimation(newReplacementAnim, bHasVariants, variant)) { const bool bBetweenVariants = newReplacementAnim == _currentReplacementAnimation; float blendTime = HasReplacementAnimation() ? GetReplacementAnimation()->GetCustomBlendTime(a_bIsEcho ? CustomBlendType::kEcho : CustomBlendType::kLoop, bBetweenVariants) : (a_bIsEcho ? a_echoDuration : Settings::fDefaultBlendTimeOnLoop); + if (a_clipGenerator->animationControl->playbackSpeed > 0.f) { + blendTime /= a_clipGenerator->animationControl->playbackSpeed; + } QueueReplacementAnimation(newReplacementAnim, blendTime, a_bIsEcho ? QueuedReplacement::Type::kRestart : QueuedReplacement::Type::kLoop, a_bIsEcho ? AnimationLogEntry::Event::kEchoReplace : AnimationLogEntry::Event::kLoopReplace, variant); return true; } diff --git a/src/Variants.cpp b/src/Variants.cpp index 2ab5968..360abf4 100644 --- a/src/Variants.cpp +++ b/src/Variants.cpp @@ -545,23 +545,29 @@ bool VariantStateDataContainer::UpdateData(float a_deltaTime) std::unordered_set activeKeys{}; - for (auto it = _localVariantStateData.begin(); it != _localVariantStateData.end();) { - auto& entry = it->second; - if (entry.UpdateData(a_deltaTime, activeKeys)) { - ++it; - bActive = true; - } else { - it = _localVariantStateData.erase(it); + { + WriteLocker locker(_localMapLock); + for (auto it = _localVariantStateData.begin(); it != _localVariantStateData.end();) { + auto& entry = it->second; + if (entry.UpdateData(a_deltaTime, activeKeys)) { + ++it; + bActive = true; + } else { + it = _localVariantStateData.erase(it); + } } } - for (auto it = _subModVariantStateData.begin(); it != _subModVariantStateData.end();) { - auto& entry = it->second; - if (entry.UpdateData(a_deltaTime, activeKeys)) { - ++it; - bActive = true; - } else { - it = _subModVariantStateData.erase(it); + { + WriteLocker locker(_subModMapLock); + for (auto it = _subModVariantStateData.begin(); it != _subModVariantStateData.end();) { + auto& entry = it->second; + if (entry.UpdateData(a_deltaTime, activeKeys)) { + ++it; + bActive = true; + } else { + it = _subModVariantStateData.erase(it); + } } } @@ -576,23 +582,29 @@ bool VariantStateDataContainer::OnLoopOrEcho(RE::ObjectRefHandle a_refHandle, Ac { bool bActive = false; - for (auto it = _localVariantStateData.begin(); it != _localVariantStateData.end();) { - auto& entry = it->second; - if (entry.OnLoopOrEcho(a_refHandle, a_activeClip, a_bIsEcho)) { - ++it; - bActive = true; - } else { - it = _localVariantStateData.erase(it); + { + WriteLocker locker(_localMapLock); + for (auto it = _localVariantStateData.begin(); it != _localVariantStateData.end();) { + auto& entry = it->second; + if (entry.OnLoopOrEcho(a_refHandle, a_activeClip, a_bIsEcho)) { + ++it; + bActive = true; + } else { + it = _localVariantStateData.erase(it); + } } } - for (auto it = _subModVariantStateData.begin(); it != _subModVariantStateData.end();) { - auto& entry = it->second; - if (entry.OnLoopOrEcho(a_refHandle, a_activeClip, a_bIsEcho)) { - ++it; - bActive = true; - } else { - it = _subModVariantStateData.erase(it); + { + WriteLocker locker(_subModMapLock); + for (auto it = _subModVariantStateData.begin(); it != _subModVariantStateData.end();) { + auto& entry = it->second; + if (entry.OnLoopOrEcho(a_refHandle, a_activeClip, a_bIsEcho)) { + ++it; + bActive = true; + } else { + it = _subModVariantStateData.erase(it); + } } } @@ -607,23 +619,29 @@ bool VariantStateDataContainer::ClearRefrData(RE::ObjectRefHandle a_refHandle) { bool bActive = false; - for (auto it = _localVariantStateData.begin(); it != _localVariantStateData.end();) { - auto& entry = it->second; - if (entry.ClearRefrData(a_refHandle)) { - ++it; - bActive = true; - } else { - it = _localVariantStateData.erase(it); + { + WriteLocker locker(_localMapLock); + for (auto it = _localVariantStateData.begin(); it != _localVariantStateData.end();) { + auto& entry = it->second; + if (entry.ClearRefrData(a_refHandle)) { + ++it; + bActive = true; + } else { + it = _localVariantStateData.erase(it); + } } } - for (auto it = _subModVariantStateData.begin(); it != _subModVariantStateData.end();) { - auto& entry = it->second; - if (entry.ClearRefrData(a_refHandle)) { - ++it; - bActive = true; - } else { - it = _subModVariantStateData.erase(it); + { + WriteLocker locker(_subModMapLock); + for (auto it = _subModVariantStateData.begin(); it != _subModVariantStateData.end();) { + auto& entry = it->second; + if (entry.ClearRefrData(a_refHandle)) { + ++it; + bActive = true; + } else { + it = _subModVariantStateData.erase(it); + } } } @@ -636,8 +654,15 @@ bool VariantStateDataContainer::ClearRefrData(RE::ObjectRefHandle a_refHandle) void VariantStateDataContainer::Clear() { - _localVariantStateData.clear(); - _subModVariantStateData.clear(); + { + WriteLocker locker(_localMapLock); + _localVariantStateData.clear(); + } + + { + WriteLocker locker(_subModMapLock); + _subModVariantStateData.clear(); + } _replacerModVariantStateData.Clear(); } @@ -645,13 +670,19 @@ Conditions::IStateData* VariantStateDataContainer::AccessStateData(RE::ObjectRef { switch (a_variants->GetVariantStateScope()) { case Conditions::StateDataScope::kLocal: - if (auto search = _localVariantStateData.find(a_clipGenerator); search != _localVariantStateData.end()) { - return search->second.AccessStateData(a_key, a_clipGenerator); + { + ReadLocker locker(_localMapLock); + if (auto search = _localVariantStateData.find(a_clipGenerator); search != _localVariantStateData.end()) { + return search->second.AccessStateData(a_key, a_clipGenerator); + } } break; case Conditions::StateDataScope::kSubMod: - if (auto search = _subModVariantStateData.find(a_variants->GetParentSubMod()); search != _subModVariantStateData.end()) { - return search->second.AccessStateData(a_key, a_clipGenerator); + { + ReadLocker locker(_subModMapLock); + if (auto search = _subModVariantStateData.find(a_variants->GetParentSubMod()); search != _subModVariantStateData.end()) { + return search->second.AccessStateData(a_key, a_clipGenerator); + } } break; case Conditions::StateDataScope::kReplacerMod: @@ -665,9 +696,15 @@ Conditions::IStateData* VariantStateDataContainer::AddStateData(RE::ObjectRefHan { switch (a_variants->GetVariantStateScope()) { case Conditions::StateDataScope::kLocal: - return _localVariantStateData[a_clipGenerator].AddStateData(a_key, a_stateData, a_clipGenerator); + { + WriteLocker locker(_localMapLock); + return _localVariantStateData[a_clipGenerator].AddStateData(a_key, a_stateData, a_clipGenerator); + } case Conditions::StateDataScope::kSubMod: - return _subModVariantStateData[a_variants->GetParentSubMod()].AddStateData(a_key, a_stateData, a_clipGenerator); + { + WriteLocker locker(_subModMapLock); + return _subModVariantStateData[a_variants->GetParentSubMod()].AddStateData(a_key, a_stateData, a_clipGenerator); + } case Conditions::StateDataScope::kReplacerMod: return _replacerModVariantStateData.AddStateData(a_key, a_stateData, a_clipGenerator); } diff --git a/src/Variants.h b/src/Variants.h index 3c5de01..30680a6 100644 --- a/src/Variants.h +++ b/src/Variants.h @@ -216,6 +216,10 @@ struct VariantStateDataContainer protected: StateDataContainer<> _replacerModVariantStateData{}; + + mutable SharedLock _subModMapLock; std::unordered_map> _subModVariantStateData{}; + + mutable SharedLock _localMapLock; std::unordered_map> _localVariantStateData{}; };