Fix crash in animations system when assets gets loading/unloaded while async jobs are active

#2974
This commit is contained in:
Wojtek Figat
2025-02-18 22:30:49 +01:00
parent c81ddd09cc
commit 060bc0aaf8
7 changed files with 118 additions and 3 deletions

View File

@@ -6,6 +6,7 @@
#include "Engine/Content/Factories/BinaryAssetFactory.h"
#include "Engine/Animations/CurveSerialization.h"
#include "Engine/Animations/AnimEvent.h"
#include "Engine/Animations/Animations.h"
#include "Engine/Animations/SceneAnimations/SceneAnimation.h"
#include "Engine/Scripting/Scripting.h"
#include "Engine/Threading/Threading.h"
@@ -407,7 +408,6 @@ bool Animation::Save(const StringView& path)
LOG(Error, "Asset loading failed. Cannot save it.");
return true;
}
ScopeLock lock(Locker);
// Serialize animation data to the stream
@@ -552,6 +552,8 @@ void Animation::OnScriptingDispose()
Asset::LoadResult Animation::load()
{
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
// Get stream with animations data
const auto dataChunk = GetChunk(0);
if (dataChunk == nullptr)
@@ -682,6 +684,7 @@ Asset::LoadResult Animation::load()
void Animation::unload(bool isReloading)
{
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
#if USE_EDITOR
if (_registeredForScriptingReload)
{

View File

@@ -10,6 +10,7 @@
#include "Engine/Serialization/MemoryReadStream.h"
#include "Engine/Serialization/MemoryWriteStream.h"
#include "Engine/Content/Factories/BinaryAssetFactory.h"
#include "Engine/Animations/Animations.h"
#include "Engine/Threading/Threading.h"
#include "Engine/Debug/Exceptions/ArgumentNullException.h"
@@ -24,6 +25,8 @@ AnimationGraph::AnimationGraph(const SpawnParams& params, const AssetInfo* info)
Asset::LoadResult AnimationGraph::load()
{
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
// Get stream with graph data
const auto surfaceChunk = GetChunk(0);
if (surfaceChunk == nullptr)
@@ -48,6 +51,7 @@ Asset::LoadResult AnimationGraph::load()
void AnimationGraph::unload(bool isReloading)
{
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
Graph.Clear();
}
@@ -79,6 +83,7 @@ bool AnimationGraph::InitAsAnimation(SkinnedModel* baseModel, Animation* anim, b
Log::ArgumentNullException();
return true;
}
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
// Create Graph data
MemoryWriteStream writeStream(512);
@@ -172,7 +177,7 @@ bool AnimationGraph::SaveSurface(BytesContainer& data)
LOG(Error, "Asset loading failed. Cannot save it.");
return true;
}
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
ScopeLock lock(Locker);
if (IsVirtual())

View File

@@ -4,6 +4,7 @@
#include "Engine/Core/Log.h"
#include "Engine/Core/Types/DataContainer.h"
#include "Engine/Serialization/MemoryReadStream.h"
#include "Engine/Animations/Animations.h"
#include "Engine/Content/Factories/BinaryAssetFactory.h"
#include "Engine/Threading/Threading.h"
@@ -16,6 +17,8 @@ AnimationGraphFunction::AnimationGraphFunction(const SpawnParams& params, const
Asset::LoadResult AnimationGraphFunction::load()
{
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
// Get graph data from chunk
const auto surfaceChunk = GetChunk(0);
if (!surfaceChunk || !surfaceChunk->IsLoaded())
@@ -41,6 +44,7 @@ Asset::LoadResult AnimationGraphFunction::load()
void AnimationGraphFunction::unload(bool isReloading)
{
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
GraphData.Release();
Inputs.Clear();
Outputs.Clear();
@@ -65,6 +69,7 @@ BytesContainer AnimationGraphFunction::LoadSurface() const
void AnimationGraphFunction::GetSignature(Array<StringView, FixedAllocation<32>>& types, Array<StringView, FixedAllocation<32>>& names)
{
ScopeLock lock(Locker);
types.Resize(32);
names.Resize(32);
for (int32 i = 0, j = 0; i < Inputs.Count(); i++)
@@ -96,7 +101,7 @@ bool AnimationGraphFunction::SaveSurface(const BytesContainer& data)
LOG(Error, "Asset loading failed. Cannot save it.");
return true;
}
ConcurrentSystemLocker::WriteScope systemScope(Animations::SystemLocker);
ScopeLock lock(Locker);
// Set Visject Surface data
@@ -120,6 +125,7 @@ bool AnimationGraphFunction::SaveSurface(const BytesContainer& data)
void AnimationGraphFunction::ProcessGraphForSignature(AnimGraphBase* graph, bool canUseOutputs)
{
ScopeLock lock(Locker);
for (int32 i = 0; i < graph->Nodes.Count(); i++)
{
auto& node = graph->Nodes[i];