From 8972e607fd6f0dc3d3b1540ea9d1d149a9be801a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Wed, 5 Jun 2024 13:54:46 +0200 Subject: [PATCH] Asset Placeholders --- .../resources/Textures/ErrorTexture2D.png | Bin 0 -> 125 bytes .../resources/Textures/ErrorTexture2D.png.ass | 37 +++++ .../Textures/PlaceholderTexture2D.png | Bin 0 -> 119 bytes .../Textures/PlaceholderTexture2D.png.ass | 37 +++++ GlitchyEditor/src/EditorContentManager.bf | 143 +++++++++++++++--- 5 files changed, 192 insertions(+), 25 deletions(-) create mode 100644 GlitchyEditor/resources/Textures/ErrorTexture2D.png create mode 100644 GlitchyEditor/resources/Textures/ErrorTexture2D.png.ass create mode 100644 GlitchyEditor/resources/Textures/PlaceholderTexture2D.png create mode 100644 GlitchyEditor/resources/Textures/PlaceholderTexture2D.png.ass diff --git a/GlitchyEditor/resources/Textures/ErrorTexture2D.png b/GlitchyEditor/resources/Textures/ErrorTexture2D.png new file mode 100644 index 0000000000000000000000000000000000000000..ff77dc3083b7eaf9a3374d13c3a8e28db6eba423 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^Od!kwBL7~QRScvUi-X*q7}lMWc?smOq&xaLGB9lH z=l+w(3gmMZctipf@f`+X#^d=bQhFVdQ I&MBb@0LP6S=>Px# literal 0 HcmV?d00001 diff --git a/GlitchyEditor/resources/Textures/PlaceholderTexture2D.png.ass b/GlitchyEditor/resources/Textures/PlaceholderTexture2D.png.ass new file mode 100644 index 0000000..f6bf7e4 --- /dev/null +++ b/GlitchyEditor/resources/Textures/PlaceholderTexture2D.png.ass @@ -0,0 +1,37 @@ +{ + AssetLoader = null, + Config = null, + Importer = "TextureImporter", + ImporterConfig = (GlitchyEditor.Assets.Importers.TextureImporterConfig){ + _isSrgb = false + }, + Processor = "TextureProcessor", + ProcessorConfig = (GlitchyEditor.Assets.Importers.TextureProcessorConfig){ + _generateMipMaps = .No, + _samplerStateDescription = { + MinFilter = .Linear, + MagFilter = .Linear, + MipFilter = .Linear, + FilterMode = .Default, + ComparisonFunction = .Never, + AddressModeU = .Clamp, + AddressModeV = .Clamp, + AddressModeW = .Clamp, + MipLODBias = 0, + MipMinLOD = -3.40282347e+38, + MipMaxLOD = 3.40282347e+38, + MaxAnisotropy = 1, + BorderColor = { + R = 1, + G = 1, + B = 1, + A = 1 + } + } + }, + Exporter = "TextureExporter", + ExporterConfig = { + _compression = .None + }, + AssetHandle = 7647313657967374590 +} \ No newline at end of file diff --git a/GlitchyEditor/src/EditorContentManager.bf b/GlitchyEditor/src/EditorContentManager.bf index 536c63a..855c031 100644 --- a/GlitchyEditor/src/EditorContentManager.bf +++ b/GlitchyEditor/src/EditorContentManager.bf @@ -125,11 +125,12 @@ class EditorContentManager : IContentManager private void SwapInLoadedAssets() { // Don't take the lock if we have nothing to do. - if (_finishedEntries.Count == 0) + if (_finishedEntries.Count == 0 && _newFinishedEntries.Count == 0) return; using (_finishedEntriesLock.Enter()) { + // TODO: Get rid of old queue while (_finishedEntries.Count > 0) { let (placeholder, asset) = _finishedEntries[0]; @@ -152,6 +153,36 @@ class EditorContentManager : IContentManager _finishedEntries.RemoveAtFast(0); } + + for (let (placeholder, loadedAsset) in _newFinishedEntries) + { + delete placeholder.LoadingTask; + placeholder.LoadingTask = null; + + if (loadedAsset == null) + placeholder.PlaceholderType = .Error; + else + { + Result> assetNodeResult = _assetHierarchy.GetNodeFromAssetHandle(placeholder.Handle); + + if (assetNodeResult case .Ok(let assetNode)) + { + assetNode->AssetFile.[Friend]_loadedAsset = loadedAsset; + + SwapAsset(placeholder, loadedAsset); + } + else + { + Log.EngineLogger.Error($"Could not find asset node for asset with handle \"{placeholder.AssetHandle}\" while swapping in asset."); + placeholder.PlaceholderType = .Error; + } + + // SwapAsset increases RefCount, but this scope also holds a reference. + loadedAsset.ReleaseRef(); + } + } + + _newFinishedEntries.Clear(); } } @@ -355,6 +386,11 @@ class EditorContentManager : IContentManager else if (placeholder.PlaceholderType == .Error) return placeholder.AssetLoader.GetErrorAsset(assetType); } + + if (var placeholder = asset as NewPlaceholderAsset) + { + return GetPlaceholderAsset(assetType, placeholder.PlaceholderType); + } if (assetType == null) { @@ -372,6 +408,26 @@ class EditorContentManager : IContentManager } } + private Asset GetPlaceholderAsset(Type assetType, PlaceholderType placeholderType) + { + switch (assetType) + { + case typeof(Texture2D): + if (placeholderType == .Loading) + { + AssetHandle handle = LoadAsset("Resources/Textures/PlaceholderTexture2D.png", true); + return GetAsset(null, handle); + } + else if (placeholderType == .Error) + { + AssetHandle handle = LoadAsset("Resources/Textures/ErrorTexture2D.png", true); + return GetAsset(null, handle); + } + } + + return null; + } + private void ReloadAsset(AssetHandle handle) { Debug.Profiler.ProfileResourceFunction!(); @@ -470,8 +526,22 @@ class EditorContentManager : IContentManager } } + private class NewPlaceholderAsset : Asset + { + public AssetHandle AssetHandle {get; private set;} + public Task LoadingTask {get;set;} + public PlaceholderType PlaceholderType {get; set;} + + public this(AssetHandle assetHandle, PlaceholderType placeholderType) + { + AssetHandle = assetHandle; + PlaceholderType = placeholderType; + } + } + private append Monitor _finishedEntriesLock = .(); private append List<(PlaceholderAsset placeholder, Asset newAsset)> _finishedEntries = .(); + private append List<(NewPlaceholderAsset placeholder, Asset newAsset)> _newFinishedEntries = .(); private class MissingAsset : Asset {} @@ -952,13 +1022,10 @@ class EditorContentManager : IContentManager if (asset == null) { - Result> assetNodeResult = AssetHierarchy.GetNodeFromAssetHandle(handle); + TreeNode assetNode = TrySilent!(AssetHierarchy.GetNodeFromAssetHandle(handle)); - if (assetNodeResult case .Ok(let assetNode)) - { - _assetConverter.QueueForProcessing(assetNode->AssetFile, isBlocking); - } - + _assetConverter.QueueForProcessing(assetNode->AssetFile, isBlocking); + if (isBlocking) { asset = _assetCache.GetCacheEntry(handle); @@ -967,32 +1034,58 @@ class EditorContentManager : IContentManager } else { - // TODO: Return placeholder! - return null; + return new NewPlaceholderAsset(asset.Handle, .Loading); } } - Result streamResult = _assetCache.OpenStream(asset); - - if (streamResult case .Err) + Asset InternalLoad(CachedAsset cachedAsset) { - // Return error - return null; + Result streamResult = _assetCache.OpenStream(cachedAsset); + + if (streamResult case .Ok(Stream dataStream)) + { + defer { delete dataStream; } + + IProcessedAssetLoader loader = GetLoader(cachedAsset.AssetType); + + if (loader.Load(dataStream) case .Ok(let loadedAsset)) + { + return loadedAsset; + } + else + { + TreeNode assetNode = TrySilent!(AssetHierarchy.GetNodeFromAssetHandle(handle)); + Log.EngineLogger.Error($"Failed to load asset \"{assetNode->Identifier}\" ({cachedAsset.Handle}): Loading of cached file failed."); + } + } + else + { + TreeNode assetNode = TrySilent!(AssetHierarchy.GetNodeFromAssetHandle(handle)); + Log.EngineLogger.Error($"Failed to load asset \"{assetNode->Identifier}\" ({cachedAsset.Handle}): Could not open stream to cached file."); + } + + NewPlaceholderAsset placeholder = new NewPlaceholderAsset(asset.Handle, .Error); + + return placeholder; } - Stream dataStream = streamResult.Value; - defer { delete dataStream; } - - IProcessedAssetLoader loader = GetLoader(asset.AssetType); - - if (loader.Load(dataStream) case .Ok(let loadedAsset)) - { - return loadedAsset; - } + if (isBlocking) + return InternalLoad(asset); else { - // Return error - return null; + NewPlaceholderAsset placeholder = new NewPlaceholderAsset(asset.Handle, .Loading); + placeholder.LoadingTask = new Task(new () => { + Asset loadedAsset = InternalLoad(asset); + + using (_finishedEntriesLock.Enter()) + { + _newFinishedEntries.Add((placeholder, loadedAsset)); + } + }); + + ThreadPool.QueueUserWorkItem(placeholder.LoadingTask); + + return placeholder; } } } \ No newline at end of file