From 78d6fe6b50db1f86e9baeaa5007c30f314624cc2 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 6 May 2022 18:30:49 +0200 Subject: [PATCH] Fix error when loading surface from not yet loaded asset --- Source/Engine/Content/Asset.cpp | 6 +++--- Source/Engine/Content/Asset.h | 2 +- Source/Engine/Content/Assets/AnimationGraph.cpp | 2 ++ Source/Engine/Content/Assets/AnimationGraphFunction.cpp | 2 ++ Source/Engine/Content/Assets/Material.cpp | 4 +++- Source/Engine/Content/Assets/MaterialFunction.cpp | 4 ++++ Source/Engine/Content/Assets/VisualScript.cpp | 3 ++- Source/Engine/Particles/ParticleEmitter.cpp | 2 ++ Source/Engine/Particles/ParticleEmitterFunction.cpp | 6 ++++++ 9 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Source/Engine/Content/Asset.cpp b/Source/Engine/Content/Asset.cpp index 8d520a62d..05498460a 100644 --- a/Source/Engine/Content/Asset.cpp +++ b/Source/Engine/Content/Asset.cpp @@ -350,7 +350,7 @@ namespace ContentLoadingManagerImpl extern ConcurrentTaskQueue Tasks; }; -bool Asset::WaitForLoaded(double timeoutInMilliseconds) +bool Asset::WaitForLoaded(double timeoutInMilliseconds) const { // This function is used many time when some parts of the engine need to wait for asset loading end (it may fail but has to end). // But it cannot be just a simple active-wait loop. @@ -376,7 +376,7 @@ bool Asset::WaitForLoaded(double timeoutInMilliseconds) // If running on a main thread we can flush asset `Loaded` event if (IsInMainThread()) { - Content::tryCallOnLoaded(this); + Content::tryCallOnLoaded((Asset*)this); } return false; @@ -467,7 +467,7 @@ bool Asset::WaitForLoaded(double timeoutInMilliseconds) // If running on a main thread we can flush asset `Loaded` event if (IsInMainThread() && IsLoaded()) { - Content::tryCallOnLoaded(this); + Content::tryCallOnLoaded((Asset*)this); } return _isLoaded == 0; diff --git a/Source/Engine/Content/Asset.h b/Source/Engine/Content/Asset.h index 4635d7e96..32a3dcf25 100644 --- a/Source/Engine/Content/Asset.h +++ b/Source/Engine/Content/Asset.h @@ -154,7 +154,7 @@ public: /// /// Custom timeout value in milliseconds. /// True if cannot load that asset (failed or has been cancelled), otherwise false. - API_FUNCTION() bool WaitForLoaded(double timeoutInMilliseconds = 30000.0); + API_FUNCTION() bool WaitForLoaded(double timeoutInMilliseconds = 30000.0) const; /// /// Initializes asset data as virtual asset. diff --git a/Source/Engine/Content/Assets/AnimationGraph.cpp b/Source/Engine/Content/Assets/AnimationGraph.cpp index 5b795fe5c..e5a40e8cf 100644 --- a/Source/Engine/Content/Assets/AnimationGraph.cpp +++ b/Source/Engine/Content/Assets/AnimationGraph.cpp @@ -129,6 +129,8 @@ bool AnimationGraph::InitAsAnimation(SkinnedModel* baseModel, Animation* anim, b BytesContainer AnimationGraph::LoadSurface() { + if (!IsVirtual() && WaitForLoaded()) + return BytesContainer(); ScopeLock lock(Locker); if (IsVirtual()) diff --git a/Source/Engine/Content/Assets/AnimationGraphFunction.cpp b/Source/Engine/Content/Assets/AnimationGraphFunction.cpp index d79836dea..013ea693d 100644 --- a/Source/Engine/Content/Assets/AnimationGraphFunction.cpp +++ b/Source/Engine/Content/Assets/AnimationGraphFunction.cpp @@ -54,6 +54,8 @@ AssetChunksFlag AnimationGraphFunction::getChunksToPreload() const BytesContainer AnimationGraphFunction::LoadSurface() const { BytesContainer result; + if (WaitForLoaded()) + return result; ScopeLock lock(Locker); result.Link(GraphData); return result; diff --git a/Source/Engine/Content/Assets/Material.cpp b/Source/Engine/Content/Assets/Material.cpp index 2b715da0c..fb6f9dcc7 100644 --- a/Source/Engine/Content/Assets/Material.cpp +++ b/Source/Engine/Content/Assets/Material.cpp @@ -431,7 +431,7 @@ void Material::InitCompilationOptions(ShaderCompilationOptions& options) options.Macros.Add({ "USE_GBUFFER_CUSTOM_DATA", Numbers[useCustomData ? 1 : 0] }); options.Macros.Add({ "USE_REFLECTIONS", Numbers[info.FeaturesFlags & MaterialFeaturesFlags::DisableReflections ? 0 : 1] }); if (!(info.FeaturesFlags & MaterialFeaturesFlags::DisableReflections) && info.FeaturesFlags & MaterialFeaturesFlags::ScreenSpaceReflections) - options.Macros.Add({ "MATERIAL_REFLECTIONS", Numbers[1]}); + options.Macros.Add({ "MATERIAL_REFLECTIONS", Numbers[1] }); options.Macros.Add({ "USE_FOG", Numbers[info.FeaturesFlags & MaterialFeaturesFlags::DisableFog ? 0 : 1] }); if (useForward) options.Macros.Add({ "USE_PIXEL_NORMAL_OFFSET_REFRACTION", Numbers[info.FeaturesFlags & MaterialFeaturesFlags::PixelNormalOffsetRefraction ? 1 : 0] }); @@ -476,6 +476,8 @@ void Material::InitCompilationOptions(ShaderCompilationOptions& options) BytesContainer Material::LoadSurface(bool createDefaultIfMissing) { BytesContainer result; + if (WaitForLoaded()) + return result; ScopeLock lock(Locker); // Check if has that chunk diff --git a/Source/Engine/Content/Assets/MaterialFunction.cpp b/Source/Engine/Content/Assets/MaterialFunction.cpp index fd6420124..caa909b01 100644 --- a/Source/Engine/Content/Assets/MaterialFunction.cpp +++ b/Source/Engine/Content/Assets/MaterialFunction.cpp @@ -75,6 +75,8 @@ AssetChunksFlag MaterialFunction::getChunksToPreload() const BytesContainer MaterialFunction::LoadSurface() { BytesContainer result; + if (WaitForLoaded()) + return result; ScopeLock lock(Locker); if (HasChunk(0)) { @@ -89,6 +91,8 @@ BytesContainer MaterialFunction::LoadSurface() bool MaterialFunction::LoadSurface(MaterialGraph& graph) { + if (WaitForLoaded()) + return true; ScopeLock lock(Locker); if (HasChunk(0)) { diff --git a/Source/Engine/Content/Assets/VisualScript.cpp b/Source/Engine/Content/Assets/VisualScript.cpp index d23eb2674..d710e7b64 100644 --- a/Source/Engine/Content/Assets/VisualScript.cpp +++ b/Source/Engine/Content/Assets/VisualScript.cpp @@ -2116,6 +2116,8 @@ const VisualScript::Field* VisualScript::FindField(const StringAnsiView& name) c BytesContainer VisualScript::LoadSurface() { + if (WaitForLoaded()) + return BytesContainer(); ScopeLock lock(Locker); if (!LoadChunks(GET_CHUNK_FLAG(0))) { @@ -2124,7 +2126,6 @@ BytesContainer VisualScript::LoadSurface() result.Copy(data->Data); return result; } - LOG(Warning, "\'{0}\' surface data is missing.", ToString()); return BytesContainer(); } diff --git a/Source/Engine/Particles/ParticleEmitter.cpp b/Source/Engine/Particles/ParticleEmitter.cpp index 51aab255b..d24e5b341 100644 --- a/Source/Engine/Particles/ParticleEmitter.cpp +++ b/Source/Engine/Particles/ParticleEmitter.cpp @@ -335,6 +335,8 @@ void ParticleEmitter::InitCompilationOptions(ShaderCompilationOptions& options) BytesContainer ParticleEmitter::LoadSurface(bool createDefaultIfMissing) { BytesContainer result; + if (WaitForLoaded()) + return result; ScopeLock lock(Locker); // Check if has that chunk diff --git a/Source/Engine/Particles/ParticleEmitterFunction.cpp b/Source/Engine/Particles/ParticleEmitterFunction.cpp index af7c6f1c6..935877b60 100644 --- a/Source/Engine/Particles/ParticleEmitterFunction.cpp +++ b/Source/Engine/Particles/ParticleEmitterFunction.cpp @@ -84,6 +84,8 @@ AssetChunksFlag ParticleEmitterFunction::getChunksToPreload() const bool ParticleEmitterFunction::LoadSurface(ParticleEmitterGraphCPU& graph) { + if (WaitForLoaded()) + return true; ScopeLock lock(Locker); if (HasChunk(0)) { @@ -102,6 +104,8 @@ bool ParticleEmitterFunction::LoadSurface(ParticleEmitterGraphCPU& graph) BytesContainer ParticleEmitterFunction::LoadSurface() { BytesContainer result; + if (WaitForLoaded()) + return result; ScopeLock lock(Locker); if (HasChunk(0)) { @@ -118,6 +122,8 @@ BytesContainer ParticleEmitterFunction::LoadSurface() bool ParticleEmitterFunction::LoadSurface(ParticleEmitterGraphGPU& graph) { + if (WaitForLoaded()) + return true; ScopeLock lock(Locker); if (HasChunk(0)) {