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 @@ +