From e2bc68d35958b0d85a714280cf93f329de097b7e Mon Sep 17 00:00:00 2001 From: Misaki Date: Sat, 9 May 2026 15:20:22 +0900 Subject: [PATCH] Refactor UI panels, shader logic, and project settings Refactored Hierarchy and Inspector panels into separate controls with improved styling and modularity. Cached EngineCore in EditorShaderCompilerBridge and updated shader cache logic for correctness. Renamed static field in PropertyField for consistency. Enhanced test coverage and fixed IDisposable implementation. Added XAML debugging properties for Debug_Editor and cleaned up obsolete scripts. --- .../Controls/BasicInput/PropertyField.cs | 4 +- .../Services/EditorShaderCompilerBridge.cs | 23 ++- src/Editor/Ghost.Editor/Ghost.Editor.csproj | 9 + .../Views/Controls/Hierarchy.xaml | 86 +++++----- .../Views/Controls/Inspector.xaml | 107 ++++++++++++ .../Views/Controls/Inspector.xaml.cs | 27 +++ .../Ghost.Editor/Views/Pages/EditPage.xaml | 161 +----------------- .../ShaderPropertiesGenerator.cs | 7 +- .../Ghost.Graphics/Services/ShaderLibrary.cs | 13 +- .../Graphics/ShaderLibraryTest.cs | 9 +- src/test_generator.cs | 34 ---- 11 files changed, 219 insertions(+), 261 deletions(-) create mode 100644 src/Editor/Ghost.Editor/Views/Controls/Inspector.xaml create mode 100644 src/Editor/Ghost.Editor/Views/Controls/Inspector.xaml.cs delete mode 100644 src/test_generator.cs diff --git a/src/Editor/Ghost.Editor.Core/Controls/BasicInput/PropertyField.cs b/src/Editor/Ghost.Editor.Core/Controls/BasicInput/PropertyField.cs index 3f0c93f..b9a06d3 100644 --- a/src/Editor/Ghost.Editor.Core/Controls/BasicInput/PropertyField.cs +++ b/src/Editor/Ghost.Editor.Core/Controls/BasicInput/PropertyField.cs @@ -9,7 +9,7 @@ namespace Ghost.Editor.Core.Controls; public sealed partial class PropertyField : ContentControl { - private static readonly Dictionary _valueProperties = new() + private static readonly Dictionary s_valueProperties = new() { { typeof(TextBox), TextBox.TextProperty }, { typeof(NumberBox), NumberBox.ValueProperty }, @@ -48,7 +48,7 @@ public sealed partial class PropertyField : ContentControl { while (fieldType != null) { - if (_valueProperties.TryGetValue(fieldType, out var dp)) + if (s_valueProperties.TryGetValue(fieldType, out var dp)) { return dp; } diff --git a/src/Editor/Ghost.Editor.Core/Services/EditorShaderCompilerBridge.cs b/src/Editor/Ghost.Editor.Core/Services/EditorShaderCompilerBridge.cs index d25427c..fc90851 100644 --- a/src/Editor/Ghost.Editor.Core/Services/EditorShaderCompilerBridge.cs +++ b/src/Editor/Ghost.Editor.Core/Services/EditorShaderCompilerBridge.cs @@ -19,6 +19,7 @@ internal sealed class EditorShaderCompilerBridge : IShaderCompilationBridge private readonly IAssetRegistry _assetRegistry; private readonly IServiceProvider _serviceProvider; private readonly IShaderCompiler _compiler; + private EngineCore? _engineCore; private readonly ConcurrentDictionary _shaderIdToAssetId = new(); private readonly ConcurrentDictionary[]> _assetKeywordMappings = new(); @@ -49,11 +50,11 @@ internal sealed class EditorShaderCompilerBridge : IShaderCompilationBridge _shaderIdToAssetId[nameHash] = guid; BuildKeywordMappings(result.Value, guid); - var engineCore = _serviceProvider.GetService(); - if (engineCore != null) + _engineCore ??= _serviceProvider.GetService(); + if (_engineCore != null) { - var shaderLibrary = engineCore.RenderSystem.ShaderLibrary; - var pipelineLibrary = engineCore.RenderSystem.GraphicsEngine.PipelineLibrary; + var shaderLibrary = _engineCore.RenderSystem.ShaderLibrary; + var pipelineLibrary = _engineCore.RenderSystem.GraphicsEngine.PipelineLibrary; shaderLibrary.InvalidateShaderCache(nameHash, pipelineLibrary); } } @@ -264,12 +265,11 @@ internal sealed class EditorShaderCompilerBridge : IShaderCompilationBridge var compileResult = _compiler.CompileShaderPass(ref descriptor, ref additionalConfig, AllocationHandle.Persistent); if (compileResult.IsFailure) { - Ghost.Core.Logger.Error($"Failed to compile graphics shader {shaderId}: {compileResult.Message}"); + Logger.Error($"Failed to compile graphics shader {shaderId}: {compileResult.Message}"); return Task.CompletedTask; } - var engineCore = _serviceProvider.GetService(); - if (engineCore == null) + if (_engineCore == null) { return Task.CompletedTask; } @@ -298,7 +298,7 @@ internal sealed class EditorShaderCompilerBridge : IShaderCompilationBridge byteCodes[idx++] = new ShaderByteCode { pCode = (byte*)compiled.psResult.GetUnsafePtr(), size = (ulong)compiled.psResult.Length }; } - var shaderLibrary = engineCore.RenderSystem.ShaderLibrary; + var shaderLibrary = _engineCore.RenderSystem.ShaderLibrary; shaderLibrary.CacheCompiledResult(shaderId, passIndex, variantKey, new ReadOnlySpan(byteCodes, stageCount)); var (compiledHash, _) = shaderLibrary.GetCompiledHash(shaderId, passIndex, variantKey); @@ -327,12 +327,11 @@ internal sealed class EditorShaderCompilerBridge : IShaderCompilationBridge var compileResult = _compiler.Compile(ref config, AllocationHandle.Persistent); if (compileResult.IsFailure) { - Ghost.Core.Logger.Error($"Failed to compile compute shader {shaderId}: {compileResult.Message}"); + Logger.Error($"Failed to compile compute shader {shaderId}: {compileResult.Message}"); return Task.CompletedTask; } - var engineCore = _serviceProvider.GetService(); - if (engineCore == null) + if (_engineCore == null) { return Task.CompletedTask; } @@ -345,7 +344,7 @@ internal sealed class EditorShaderCompilerBridge : IShaderCompilationBridge size = (ulong)bytecodeArray.Length }; - var shaderLibrary = engineCore.RenderSystem.ShaderLibrary; + var shaderLibrary = _engineCore.RenderSystem.ShaderLibrary; shaderLibrary.CacheCompiledResult(shaderId, passIndex, variantKey, new ReadOnlySpan(ref byteCode)); var (compiledHash, _) = shaderLibrary.GetCompiledHash(shaderId, passIndex, variantKey); diff --git a/src/Editor/Ghost.Editor/Ghost.Editor.csproj b/src/Editor/Ghost.Editor/Ghost.Editor.csproj index 2be0766..f345500 100644 --- a/src/Editor/Ghost.Editor/Ghost.Editor.csproj +++ b/src/Editor/Ghost.Editor/Ghost.Editor.csproj @@ -12,6 +12,7 @@ + @@ -140,6 +141,9 @@ PreserveNewest + + MSBuild:Compile + Designer @@ -214,6 +218,11 @@ true + + True + False + + False diff --git a/src/Editor/Ghost.Editor/Views/Controls/Hierarchy.xaml b/src/Editor/Ghost.Editor/Views/Controls/Hierarchy.xaml index 4694d1c..56ed149 100644 --- a/src/Editor/Ghost.Editor/Views/Controls/Hierarchy.xaml +++ b/src/Editor/Ghost.Editor/Views/Controls/Hierarchy.xaml @@ -14,49 +14,55 @@ - - - - - + Padding="8,2,4,4" + Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"> + + + + + - - - - - - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Editor/Ghost.Editor/Views/Controls/Inspector.xaml b/src/Editor/Ghost.Editor/Views/Controls/Inspector.xaml new file mode 100644 index 0000000..08c7626 --- /dev/null +++ b/src/Editor/Ghost.Editor/Views/Controls/Inspector.xaml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Editor/Ghost.Editor/Views/Controls/Inspector.xaml.cs b/src/Editor/Ghost.Editor/Views/Controls/Inspector.xaml.cs new file mode 100644 index 0000000..214f817 --- /dev/null +++ b/src/Editor/Ghost.Editor/Views/Controls/Inspector.xaml.cs @@ -0,0 +1,27 @@ +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace Ghost.Editor.Views.Controls; + +public sealed partial class Inspector : UserControl +{ + public Inspector() + { + InitializeComponent(); + } +} diff --git a/src/Editor/Ghost.Editor/Views/Pages/EditPage.xaml b/src/Editor/Ghost.Editor/Views/Pages/EditPage.xaml index 6a45c46..6c4f924 100644 --- a/src/Editor/Ghost.Editor/Views/Pages/EditPage.xaml +++ b/src/Editor/Ghost.Editor/Views/Pages/EditPage.xaml @@ -95,67 +95,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -195,7 +140,6 @@ Stretch="UniformToFill" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/src/Runtime/Ghost.Generator/ShaderPropertiesGenerator.cs b/src/Runtime/Ghost.Generator/ShaderPropertiesGenerator.cs index c2dbead..b70edbf 100644 --- a/src/Runtime/Ghost.Generator/ShaderPropertiesGenerator.cs +++ b/src/Runtime/Ghost.Generator/ShaderPropertiesGenerator.cs @@ -91,8 +91,6 @@ namespace Ghost.Generator continue; } - var definedSymbol = $"__{info.Name.ToUpper()}_G_HLSL"; - var fieldsBuilder = new StringBuilder(); fieldsBuilder.AppendLine($" public static readonly global::Ghost.Core.Graphics.ShaderPropertyFieldInfo[] ReflectionData = new global::Ghost.Core.Graphics.ShaderPropertyFieldInfo[]"); fieldsBuilder.AppendLine(" {"); @@ -204,13 +202,10 @@ namespace {info.TypeSymbol.ContainingNamespace.ToDisplayString()} {{ #if GHOST_EDITOR public const string HLSL_SOURCE = @"" -# ifndef {definedSymbol} -# define {definedSymbol} struct {info.Name} {{ {codeBuilder} -}}; -# endif // {definedSymbol}""; +}};""; {fieldsBuilder} #endif diff --git a/src/Runtime/Ghost.Graphics/Services/ShaderLibrary.cs b/src/Runtime/Ghost.Graphics/Services/ShaderLibrary.cs index 248214d..030971c 100644 --- a/src/Runtime/Ghost.Graphics/Services/ShaderLibrary.cs +++ b/src/Runtime/Ghost.Graphics/Services/ShaderLibrary.cs @@ -128,7 +128,8 @@ internal unsafe class ShaderLibrary : IDisposable }; var offsets = stackalloc ulong[byteCodes.Length]; - var offset = (nuint)(sizeof(CacheHeader) + (sizeof(ulong) * byteCodes.Length)); + var headerSize = (nuint)(sizeof(CacheHeader) + (sizeof(ulong) * byteCodes.Length)); + var offset = headerSize; for (var i = 0; i < byteCodes.Length; i++) { offsets[i] = offset; @@ -136,9 +137,9 @@ internal unsafe class ShaderLibrary : IDisposable } var alignment = Math.Max(Math.Max(MemoryUtility.AlignOf(), MemoryUtility.AlignOf()), 8); - offset = MemoryUtility.AlignUp(offset, alignment); + var alignedOffset = MemoryUtility.AlignUp(offset, alignment); - var data = new MemoryBlock(offset, alignment, AllocationHandle.Persistent); + var data = new MemoryBlock(alignedOffset, alignment, AllocationHandle.Persistent); var writer = new SpanWriter(data.AsSpan()); writer.Write(header); @@ -159,11 +160,7 @@ internal unsafe class ShaderLibrary : IDisposable var codeHash = 0UL; if (byteCodes.Length > 0) { - ulong totalBytecodeSize = 0; - for (int i = 0; i < byteCodes.Length; i++) totalBytecodeSize += byteCodes[i].size; - - // We skip the header and offsets at the beginning of the MemoryBlock - var bytecodeSpan = data.AsSpan().Slice((int)(sizeof(CacheHeader) + (sizeof(ulong) * byteCodes.Length)), (int)totalBytecodeSize); + var bytecodeSpan = data.AsSpan().Slice((int)headerSize, (int)(offset - headerSize)); codeHash = XxHash64.HashToUInt64(bytecodeSpan); } diff --git a/src/Test/Ghost.UnitTest/Graphics/ShaderLibraryTest.cs b/src/Test/Ghost.UnitTest/Graphics/ShaderLibraryTest.cs index 9e5ecb0..361826a 100644 --- a/src/Test/Ghost.UnitTest/Graphics/ShaderLibraryTest.cs +++ b/src/Test/Ghost.UnitTest/Graphics/ShaderLibraryTest.cs @@ -42,6 +42,10 @@ public class ShaderLibraryTest { OnShaderVariantCompiled?.Invoke(variantKey, newHash); } + + public void Dispose() + { + } } [TestInitialize] @@ -151,8 +155,7 @@ public class ShaderLibraryTest { // Arrange using var shaderLibrary = new ShaderLibrary(null, "TestShaderCache"); - ulong testShaderId = 111; - var scope = AllocationManager.CreateStackScope(); + var testShaderId = 111UL; // Act var result = shaderLibrary.GetCompiledCache(testShaderId, 99); @@ -160,7 +163,5 @@ public class ShaderLibraryTest // Assert Assert.IsFalse(result.IsSuccess); Assert.AreEqual(Error.NotFound, result.Error); - - scope.Dispose(); } } diff --git a/src/test_generator.cs b/src/test_generator.cs deleted file mode 100644 index 7f5fb57..0000000 --- a/src/test_generator.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; - -class Program { - static void Main() { - string definedSymbol = "__FOO_HLSL__"; - string infoName = "Foo"; - string codeBuilder = " float4 myColor;\n"; - string fieldsBuilder = " // fields"; - var code = $$""" -// - -namespace MyNamespace -{ - [global::System.Runtime.InteropServices.StructLayout(global::System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 4)] - public partial struct {{infoName}} - { -#if GHOST_EDITOR - public const string HLSL_SOURCE = @" -#ifndef {{definedSymbol}} -#define {{definedSymbol}} -struct {{infoName}} -{ -{{codeBuilder}} -}; -#endif // {{definedSymbol}}"; - -{{fieldsBuilder}} -#endif - } -} -"""; - Console.WriteLine(code); - } -}