From c249a389e3a76cf790a4b6622fe7b25f489f6a5f Mon Sep 17 00:00:00 2001 From: Misaki Date: Mon, 20 Apr 2026 16:54:49 +0900 Subject: [PATCH] Refactor AssetHandlerRegistry, modernize editor window UI Refactored AssetHandlerRegistry to a static class and updated all usages. Replaced the docking-based EngineEditorWindow with a new grid/panel layout, adding modern toolbar, menu bar, and status bar. Introduced new divider styles and improved UI details. Removed obsolete and unused files, updated project references, and made minor code and UI/UX improvements. --- .../AssetHandler/AssetHandlerRegistry.cs | 41 +- .../Services/AssetRegistry.cs | 13 +- .../Services/ImportCoordinator.cs | 12 +- .../Utilities/AssetHandlerUtility.cs | 53 -- src/Editor/Ghost.Editor/ActivationHandler.cs | 2 + src/Editor/Ghost.Editor/App.xaml | 2 +- src/Editor/Ghost.Editor/Ghost.Editor.csproj | 6 +- src/Editor/Ghost.Editor/Themes/Generic.xaml | 13 + .../Pages/EngineEditor/ConsoleViewModel.cs | 2 +- .../Views/Windows/BlankWindow1.xaml | 17 - .../Views/Windows/BlankWindow1.xaml.cs | 29 - .../Views/Windows/EngineEditorWindow.xaml | 575 +++++++++++++----- .../Views/Windows/EngineEditorWindow.xaml.cs | 79 +-- .../Views/Windows/EngineEditorWindowOld.xaml | 246 ++++++++ .../Windows/EngineEditorWindowOld.xaml.cs | 88 +++ .../RenderPipeline/GhostRenderPipeline.cs | 2 +- src/Test/Ghost.UnitTest/Ghost.UnitTest.csproj | 1 + 17 files changed, 806 insertions(+), 375 deletions(-) delete mode 100644 src/Editor/Ghost.Editor.Core/Utilities/AssetHandlerUtility.cs delete mode 100644 src/Editor/Ghost.Editor/Views/Windows/BlankWindow1.xaml delete mode 100644 src/Editor/Ghost.Editor/Views/Windows/BlankWindow1.xaml.cs create mode 100644 src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindowOld.xaml create mode 100644 src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindowOld.xaml.cs diff --git a/src/Editor/Ghost.Editor.Core/AssetHandler/AssetHandlerRegistry.cs b/src/Editor/Ghost.Editor.Core/AssetHandler/AssetHandlerRegistry.cs index ee0909e..0f41285 100644 --- a/src/Editor/Ghost.Editor.Core/AssetHandler/AssetHandlerRegistry.cs +++ b/src/Editor/Ghost.Editor.Core/AssetHandler/AssetHandlerRegistry.cs @@ -4,32 +4,32 @@ namespace Ghost.Editor.Core.AssetHandler; /// One-time scan at editor startup → two dictionaries. /// All lookups are O(1) after construction. /// -public sealed class AssetHandlerRegistry +public static class AssetHandlerRegistry { - private readonly Dictionary _byExtension; - private readonly Dictionary _byTypeId; - private readonly Dictionary _versionByTypeId; + private static readonly Dictionary s_byExtension; + private static readonly Dictionary s_byTypeId; + private static readonly Dictionary s_versionByTypeId; - public AssetHandlerRegistry() + static AssetHandlerRegistry() { - _byExtension = new Dictionary(StringComparer.OrdinalIgnoreCase); - _byTypeId = new Dictionary(); - _versionByTypeId = new Dictionary(); + s_byExtension = new Dictionary(StringComparer.OrdinalIgnoreCase); + s_byTypeId = new Dictionary(); + s_versionByTypeId = new Dictionary(); } - public void RegisterHandler(IAssetHandler handler, Guid typeId, ReadOnlySpan extensions, int version) + public static void RegisterHandler(IAssetHandler handler, Guid typeId, ReadOnlySpan extensions, int version) { - _byTypeId[typeId] = handler; - _versionByTypeId[typeId] = version; + s_byTypeId[typeId] = handler; + s_versionByTypeId[typeId] = version; foreach (var ext in extensions) { var normalizedExt = ext.StartsWith('.') ? ext : "." + ext; - _byExtension[normalizedExt] = handler; + s_byExtension[normalizedExt] = handler; } } - public IAssetHandler? GetByExtension(string extension) + public static IAssetHandler? GetByExtension(string extension) { if (string.IsNullOrEmpty(extension)) { @@ -37,21 +37,24 @@ public sealed class AssetHandlerRegistry } var normalized = extension.StartsWith('.') ? extension : "." + extension; - _byExtension.TryGetValue(normalized, out var handler); + s_byExtension.TryGetValue(normalized, out var handler); return handler; } - public IAssetHandler? GetByTypeId(Guid typeId) + public static IAssetHandler? GetByTypeId(Guid typeId) { - _byTypeId.TryGetValue(typeId, out var handler); + s_byTypeId.TryGetValue(typeId, out var handler); return handler; } - public int GetVersionByTypeId(Guid typeId) + public static int GetVersionByTypeId(Guid typeId) { - _versionByTypeId.TryGetValue(typeId, out var version); + s_versionByTypeId.TryGetValue(typeId, out var version); return version; } - public IEnumerable GetSupportedExtensions() => _byExtension.Keys; + public static IEnumerable GetSupportedExtensions() + { + return s_byExtension.Keys; + } } diff --git a/src/Editor/Ghost.Editor.Core/Services/AssetRegistry.cs b/src/Editor/Ghost.Editor.Core/Services/AssetRegistry.cs index d1eda5e..20d38ad 100644 --- a/src/Editor/Ghost.Editor.Core/Services/AssetRegistry.cs +++ b/src/Editor/Ghost.Editor.Core/Services/AssetRegistry.cs @@ -14,7 +14,6 @@ internal sealed class AssetRegistry : IAssetRegistry, IDisposable private readonly string _assetsRoot; private readonly string _libraryRoot; private readonly AssetCatalog _catalog; - private readonly AssetHandlerRegistry _handlerRegistry; private readonly ImportCoordinator _importCoordinator; private readonly FileSystemWatcher _watcher; @@ -36,8 +35,7 @@ internal sealed class AssetRegistry : IAssetRegistry, IDisposable var dbPath = Path.Combine(_libraryRoot, "AssetDB.sqlite"); _catalog = new AssetCatalog(dbPath); - _handlerRegistry = new AssetHandlerRegistry(); - _importCoordinator = new ImportCoordinator(_catalog, _handlerRegistry, _assetsRoot, _libraryRoot); + _importCoordinator = new ImportCoordinator(_catalog, _assetsRoot, _libraryRoot); _loadedAssets = new ConcurrentDictionary>(); @@ -156,8 +154,11 @@ internal sealed class AssetRegistry : IAssetRegistry, IDisposable { var ext = Path.GetExtension(relativePath); - var handler = _handlerRegistry.GetByExtension(ext); - var importable = handler as IAssetHandler; + var handler = AssetHandlerRegistry.GetByExtension(ext); + if (handler is null) + { + return; + } var metaPath = AssetMetaIO.GetMetaPath(fullPath); if (File.Exists(metaPath)) @@ -171,7 +172,7 @@ internal sealed class AssetRegistry : IAssetRegistry, IDisposable Guid = Guid.NewGuid(), HandlerTypeId = handlerTypeId is string str ? Guid.Parse(str) : null, HandlerVersion = 1, - Settings = importable?.CreateDefaultSettings() + Settings = handler?.CreateDefaultSettings() }; _ignoreMetaWrites[metaPath] = true; diff --git a/src/Editor/Ghost.Editor.Core/Services/ImportCoordinator.cs b/src/Editor/Ghost.Editor.Core/Services/ImportCoordinator.cs index 00d95a3..e79fcb2 100644 --- a/src/Editor/Ghost.Editor.Core/Services/ImportCoordinator.cs +++ b/src/Editor/Ghost.Editor.Core/Services/ImportCoordinator.cs @@ -27,7 +27,6 @@ internal sealed class ImportCoordinator : IDisposable { private readonly Channel _importChannel; private readonly AssetCatalog _catalog; - private readonly AssetHandlerRegistry _handlers; private readonly string _assetsRoot; private readonly string _libraryRoot; private readonly CancellationTokenSource _cts; @@ -37,10 +36,9 @@ internal sealed class ImportCoordinator : IDisposable // For now we just focus on the core logic // public event EventHandler? OnAssetChanged; - public ImportCoordinator(AssetCatalog catalog, AssetHandlerRegistry handlers, string assetsRoot, string libraryRoot, int workerCount = 2) + public ImportCoordinator(AssetCatalog catalog, string assetsRoot, string libraryRoot, int workerCount = 2) { _catalog = catalog; - _handlers = handlers; _assetsRoot = assetsRoot; _libraryRoot = libraryRoot; _cts = new CancellationTokenSource(); @@ -98,8 +96,8 @@ internal sealed class ImportCoordinator : IDisposable } var handler = meta.HandlerTypeId.HasValue - ? _handlers.GetByTypeId(meta.HandlerTypeId.Value) - : _handlers.GetByExtension(Path.GetExtension(job.SourcePath)); + ? AssetHandlerRegistry.GetByTypeId(meta.HandlerTypeId.Value) + : AssetHandlerRegistry.GetByExtension(Path.GetExtension(job.SourcePath)); var contentHash = await ComputeFileHashAsync(fullSourcePath, token); var settingsHash = ComputeSettingsHash(meta.Settings); @@ -108,7 +106,7 @@ internal sealed class ImportCoordinator : IDisposable if (job.Reason != ImportReason.ManualReimport && meta.ContentHash == contentHash && meta.SettingsHash == settingsHash && - meta.HandlerVersion == _handlers.GetVersionByTypeId(meta.HandlerTypeId ?? Guid.Empty)) + meta.HandlerVersion == AssetHandlerRegistry.GetVersionByTypeId(meta.HandlerTypeId ?? Guid.Empty)) { _catalog.MarkImported(job.AssetGuid, contentHash, settingsHash); return; @@ -132,7 +130,7 @@ internal sealed class ImportCoordinator : IDisposable { meta.ContentHash = contentHash; meta.SettingsHash = settingsHash; - meta.HandlerVersion = _handlers.GetVersionByTypeId(meta.HandlerTypeId ?? Guid.Empty); + meta.HandlerVersion = AssetHandlerRegistry.GetVersionByTypeId(meta.HandlerTypeId ?? Guid.Empty); meta.LastImportedUtc = DateTime.UtcNow; await AssetMetaIO.WriteAsync(job.MetaPath, meta, token); diff --git a/src/Editor/Ghost.Editor.Core/Utilities/AssetHandlerUtility.cs b/src/Editor/Ghost.Editor.Core/Utilities/AssetHandlerUtility.cs deleted file mode 100644 index c1ecec5..0000000 --- a/src/Editor/Ghost.Editor.Core/Utilities/AssetHandlerUtility.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Ghost.Editor.Core.AssetHandler; -using System.Buffers; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ghost.Editor.Core.Utilities; - -public static class AssetHandlerUtility -{ - public static async ValueTask SerializeAssetAsync(Stream stream, Guid id, Guid typeID, int handlerVersion, ReadOnlyMemory dependencies, IAssetSettings? settings, ReadOnlyMemory contents, CancellationToken token = default) - where TSetting : IAssetSettings - { - var header = new AssetMetadata(id, TextureAsset.s_typeGuid) - { - HandlerVersion = handlerVersion, - DependenciesOffset = AssetMetadata.SIZE, - DependencyCount = dependencies.Length, - }; - - var tempArray = ArrayPool.Shared.Rent(4096); - - if (dependencies.Length > 0) - { - stream.Seek(header.DependenciesOffset, SeekOrigin.Begin); - for (var i = 0; i < dependencies.Length; i++) - { - Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(tempArray.AsSpan(0, 16)), dependencies.Span[i]); - await stream.WriteAsync(tempArray.AsMemory(0, 16), token); - } - } - - header.SettingsOffset = stream.Position; - - // TODO: We can use source generator to generate optimized serializer for settings. - // For now, we just use reflection for simplicity. - - if (settings is not null) - { - var properties = typeof(TSetting).GetProperties(); - - if (properties.Length > 0) - { - using var bw = new BinaryWriter(stream); - - for (var i = 0; (i < properties.Length); i++) - { - var property = properties[i]; - var value = property.GetValue(settings); - } - } - } - } -} diff --git a/src/Editor/Ghost.Editor/ActivationHandler.cs b/src/Editor/Ghost.Editor/ActivationHandler.cs index 3371810..4f86848 100644 --- a/src/Editor/Ghost.Editor/ActivationHandler.cs +++ b/src/Editor/Ghost.Editor/ActivationHandler.cs @@ -58,6 +58,8 @@ internal static class ActivationHandler { ArenaCapacity = 1024 * 1024 * 1024, // 1 GB. Arena using virtual memory, so this is just a reservation and won't actually consume physical memory until used. StackCapacity = 1024 * 1024 * 32, // 32 MB. Stack using virtual memory, so this is just a reservation and won't actually consume physical memory until used. + FreeListChunkSize = 64 * 1024 * 1024, + FreeListDefaultAlignment = 8, FreeListConcurrencyLevel = Environment.ProcessorCount }; diff --git a/src/Editor/Ghost.Editor/App.xaml b/src/Editor/Ghost.Editor/App.xaml index 3df924f..d5c7231 100644 --- a/src/Editor/Ghost.Editor/App.xaml +++ b/src/Editor/Ghost.Editor/App.xaml @@ -10,7 +10,7 @@ - + diff --git a/src/Editor/Ghost.Editor/Ghost.Editor.csproj b/src/Editor/Ghost.Editor/Ghost.Editor.csproj index b81341c..66c1f17 100644 --- a/src/Editor/Ghost.Editor/Ghost.Editor.csproj +++ b/src/Editor/Ghost.Editor/Ghost.Editor.csproj @@ -12,8 +12,7 @@ preview - - + @@ -142,6 +141,9 @@ PreserveNewest + + MSBuild:Compile + MSBuild:Compile diff --git a/src/Editor/Ghost.Editor/Themes/Generic.xaml b/src/Editor/Ghost.Editor/Themes/Generic.xaml index cd64256..fbc361b 100644 --- a/src/Editor/Ghost.Editor/Themes/Generic.xaml +++ b/src/Editor/Ghost.Editor/Themes/Generic.xaml @@ -22,6 +22,7 @@ 12 12 + 14 24 2,2,6,1 32 @@ -54,6 +55,18 @@ BasedOn="{StaticResource SubtleButtonStyle}" TargetType="Button" /> + + + + 12 diff --git a/src/Editor/Ghost.Editor/ViewModels/Pages/EngineEditor/ConsoleViewModel.cs b/src/Editor/Ghost.Editor/ViewModels/Pages/EngineEditor/ConsoleViewModel.cs index 5ddd4d6..95c657e 100644 --- a/src/Editor/Ghost.Editor/ViewModels/Pages/EngineEditor/ConsoleViewModel.cs +++ b/src/Editor/Ghost.Editor/ViewModels/Pages/EngineEditor/ConsoleViewModel.cs @@ -7,7 +7,7 @@ namespace Ghost.Editor.ViewModels.Pages.EngineEditor; internal partial class ConsoleViewModel : ObservableObject { - public ReadOnlyObservableCollection Logs => Logger.Logs; + public ReadOnlyObservableCollection Logs; [ObservableProperty] public partial bool ShowInfo diff --git a/src/Editor/Ghost.Editor/Views/Windows/BlankWindow1.xaml b/src/Editor/Ghost.Editor/Views/Windows/BlankWindow1.xaml deleted file mode 100644 index b6646a8..0000000 --- a/src/Editor/Ghost.Editor/Views/Windows/BlankWindow1.xaml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - diff --git a/src/Editor/Ghost.Editor/Views/Windows/BlankWindow1.xaml.cs b/src/Editor/Ghost.Editor/Views/Windows/BlankWindow1.xaml.cs deleted file mode 100644 index 9ed9574..0000000 --- a/src/Editor/Ghost.Editor/Views/Windows/BlankWindow1.xaml.cs +++ /dev/null @@ -1,29 +0,0 @@ -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.Windows; -/// -/// An empty window that can be used on its own or navigated to within a Frame. -/// -public sealed partial class BlankWindow1 : Window -{ - public BlankWindow1() - { - InitializeComponent(); - } -} diff --git a/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml index 4916528..a9b88f6 100644 --- a/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml +++ b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml @@ -3,244 +3,491 @@ x:Class="Ghost.Editor.Views.Windows.EngineEditorWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors" - xmlns:controls="using:Ghost.Editor.Views.Controls" xmlns:ctc="using:CommunityToolkit.WinUI.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:ee="using:Ghost.Editor.Views.Pages.EngineEditor" - xmlns:ghost="using:Ghost.Editor.Controls" - xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:local="using:Ghost.Editor.Views.Windows" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:winex="using:WinUIEx" + Title="EditorWindow" mc:Ignorable="d"> - + - + - + - - - + - - - - + Padding="8,0,200,0" + BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}" + BorderThickness="0,0,0,1" + Orientation="Horizontal"> + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - + + + + + + - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - - - - - - - - + BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}" + BorderThickness="0,0,1,0"> + + + + - - - - - - - - - + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}" + BorderThickness="1,0,0,0"> + + + + - - - - - - - - - - - - - - - - - --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Grid.Row="2" + Padding="8,4" + Background="{ThemeResource SolidBackgroundFillColorSecondaryBrush}" + BorderBrush="{ThemeResource DividerStrokeColorDefaultBrush}" + BorderThickness="0,1,0,0"> - + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - + - \ No newline at end of file + diff --git a/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml.cs b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml.cs index a81d4ee..9da6d6b 100644 --- a/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml.cs +++ b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml.cs @@ -1,88 +1,17 @@ -using Ghost.Editor.Core; -using Ghost.Editor.Core.Contracts; -using Ghost.Editor.Core.Services; -using Ghost.Editor.ViewModels.Windows; -using Windows.ApplicationModel; using WinUIEx; namespace Ghost.Editor.Views.Windows; -/// -/// An empty window that can be used on its own or navigated to within a Frame. -/// + internal sealed partial class EngineEditorWindow : WindowEx { - private readonly NotificationService _notificationService; - private readonly ProgressService _progressService; - - public EngineEditorViewModel ViewModel - { - get; - } - public EngineEditorWindow() { - ViewModel = App.GetService(); - - _notificationService = (NotificationService)App.GetService(); - _progressService = (ProgressService)App.GetService(); - InitializeComponent(); AppWindow.SetIcon(Path.Combine(AppContext.BaseDirectory, "Assets/icon.ico")); - Title = "Ghost Engine"; ExtendsContentIntoTitleBar = true; + Title = "Ghost Engine"; - SetTitleBar(PART_TitleBar); - this.CenterOnScreen(); + SetTitleBar(TitleBar); } - - private void MainGrid_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) - { - PART_TitleBar.Title = EditorApplication.ProjectName; - PART_TitleBar.Subtitle = $"Ghost Engine {Package.Current.Id.Version.Major}.{Package.Current.Id.Version.Minor}.{Package.Current.Id.Version.Build}"; - - _notificationService.SetReference(InfoBar, NotificationQueue); - _progressService.SetReference(ProgressBarContainer); - - InitializeDockingLayout(); - } - - private void InitializeDockingLayout() - { - var sceneDoc = new Controls.Docking.DockDocument { Title = "Scene", Content = new Pages.EngineEditor.ScenePage() }; - var hierarchyDoc = new Controls.Docking.DockDocument { Title = "Hierarchy", Content = new Controls.Hierarchy() }; - var inspectorDoc = new Controls.Docking.DockDocument { Title = "Inspector", Content = new Pages.EngineEditor.InspectorPage() }; - var projectDoc = new Controls.Docking.DockDocument { Title = "Project", Content = new Controls.ProjectBrowser() }; - var consoleDoc = new Controls.Docking.DockDocument { Title = "Console", Content = new Pages.EngineEditor.ConsolePage() }; - - var leftGroup = new Controls.Docking.DockGroup(); - leftGroup.AddChild(hierarchyDoc); - - var centerGroup = new Controls.Docking.DockGroup(); - centerGroup.AddChild(sceneDoc); - - var rightGroup = new Controls.Docking.DockGroup(); - rightGroup.AddChild(inspectorDoc); - - var bottomGroup = new Controls.Docking.DockGroup(); - bottomGroup.AddChild(projectDoc); - bottomGroup.AddChild(consoleDoc); - - var topPanel = new Controls.Docking.DockPanel { Orientation = Microsoft.UI.Xaml.Controls.Orientation.Horizontal }; - topPanel.AddChild(leftGroup); - topPanel.AddChild(centerGroup); - topPanel.AddChild(rightGroup); - - var rootPanel = new Controls.Docking.DockPanel { Orientation = Microsoft.UI.Xaml.Controls.Orientation.Vertical }; - rootPanel.AddChild(topPanel); - rootPanel.AddChild(bottomGroup); - - MainDockingLayout.RootModule = rootPanel; - } - - private void MainGrid_Unloaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) - { - _notificationService.ClearReference(); - _progressService.ClearReference(); - } -} \ No newline at end of file +} diff --git a/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindowOld.xaml b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindowOld.xaml new file mode 100644 index 0000000..fdcf948 --- /dev/null +++ b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindowOld.xaml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindowOld.xaml.cs b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindowOld.xaml.cs new file mode 100644 index 0000000..3e31ecc --- /dev/null +++ b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindowOld.xaml.cs @@ -0,0 +1,88 @@ +using Ghost.Editor.Core; +using Ghost.Editor.Core.Contracts; +using Ghost.Editor.Core.Services; +using Ghost.Editor.ViewModels.Windows; +using Windows.ApplicationModel; +using WinUIEx; + +namespace Ghost.Editor.Views.Windows; +/// +/// An empty window that can be used on its own or navigated to within a Frame. +/// +internal sealed partial class EngineEditorWindowOld : WindowEx +{ + private readonly NotificationService _notificationService; + private readonly ProgressService _progressService; + + public EngineEditorViewModel ViewModel + { + get; + } + + public EngineEditorWindowOld() + { + ViewModel = App.GetService(); + + _notificationService = (NotificationService)App.GetService(); + _progressService = (ProgressService)App.GetService(); + + InitializeComponent(); + + AppWindow.SetIcon(Path.Combine(AppContext.BaseDirectory, "Assets/icon.ico")); + Title = "Ghost Engine"; + ExtendsContentIntoTitleBar = true; + + SetTitleBar(PART_TitleBar); + this.CenterOnScreen(); + } + + private void MainGrid_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) + { + PART_TitleBar.Title = EditorApplication.ProjectName; + PART_TitleBar.Subtitle = $"Ghost Engine {Package.Current.Id.Version.Major}.{Package.Current.Id.Version.Minor}.{Package.Current.Id.Version.Build}"; + + _notificationService.SetReference(InfoBar, NotificationQueue); + _progressService.SetReference(ProgressBarContainer); + + InitializeDockingLayout(); + } + + private void InitializeDockingLayout() + { + var sceneDoc = new Controls.Docking.DockDocument { Title = "Scene", Content = new Pages.EngineEditor.ScenePage() }; + var hierarchyDoc = new Controls.Docking.DockDocument { Title = "Hierarchy", Content = new Controls.Hierarchy() }; + var inspectorDoc = new Controls.Docking.DockDocument { Title = "Inspector", Content = new Pages.EngineEditor.InspectorPage() }; + var projectDoc = new Controls.Docking.DockDocument { Title = "Project", Content = new Controls.ProjectBrowser() }; + var consoleDoc = new Controls.Docking.DockDocument { Title = "Console", Content = new Pages.EngineEditor.ConsolePage() }; + + var leftGroup = new Controls.Docking.DockGroup(); + leftGroup.AddChild(hierarchyDoc); + + var centerGroup = new Controls.Docking.DockGroup(); + centerGroup.AddChild(sceneDoc); + + var rightGroup = new Controls.Docking.DockGroup(); + rightGroup.AddChild(inspectorDoc); + + var bottomGroup = new Controls.Docking.DockGroup(); + bottomGroup.AddChild(projectDoc); + bottomGroup.AddChild(consoleDoc); + + var topPanel = new Controls.Docking.DockPanel { Orientation = Microsoft.UI.Xaml.Controls.Orientation.Horizontal }; + topPanel.AddChild(leftGroup); + topPanel.AddChild(centerGroup); + topPanel.AddChild(rightGroup); + + var rootPanel = new Controls.Docking.DockPanel { Orientation = Microsoft.UI.Xaml.Controls.Orientation.Vertical }; + rootPanel.AddChild(topPanel); + rootPanel.AddChild(bottomGroup); + + MainDockingLayout.RootModule = rootPanel; + } + + private void MainGrid_Unloaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) + { + _notificationService.ClearReference(); + _progressService.ClearReference(); + } +} \ No newline at end of file diff --git a/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipeline.cs b/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipeline.cs index 7722dc3..47a51f4 100644 --- a/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipeline.cs +++ b/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipeline.cs @@ -22,7 +22,7 @@ internal partial class GhostRenderPipeline : IRenderPipeline _gpuScene = new GPUScene(renderSystem.GraphicsEngine.ResourceAllocator, renderSystem.GraphicsEngine.ResourceDatabase, 102_400u); // 102.4k objects should be enough for now } - public void Render(RenderContext ctx, int frameIndex, IRenderPayload payload, ReadOnlySpan resourceUpdateCommands) + public void Render(RenderContext ctx, int frameIndex, IRenderPayload payload) { var ghostPayload = (GhostRenderPayload)payload; diff --git a/src/Test/Ghost.UnitTest/Ghost.UnitTest.csproj b/src/Test/Ghost.UnitTest/Ghost.UnitTest.csproj index bf5f2ed..1a6cf36 100644 --- a/src/Test/Ghost.UnitTest/Ghost.UnitTest.csproj +++ b/src/Test/Ghost.UnitTest/Ghost.UnitTest.csproj @@ -16,6 +16,7 @@ +