From 884611181a9d248a1d03279d642e2b54852c1b51 Mon Sep 17 00:00:00 2001 From: Misaki Date: Wed, 22 Apr 2026 15:36:49 +0900 Subject: [PATCH] Refactor instance update flow, asset registry, and texture IO - Renamed AddInstanceRequest to UpdateInstanceRequest; unified add/update logic for GPU instances - Introduced UpdateGPUInstanceSystem to handle changed MeshInstance components - Replaced QueryBuilder.Create() with QueryBuilder.New() for consistency - Switched versioning in ChunkView HasChanged/HasStructuralChanged to uint - Added extension-to-AssetType mapping in AssetHandlerRegistry - Changed TextureAssetHandler/Processor to use nint for image data - Enhanced DDS cache: read mipmap count, handle invalid files - Updated ProjectBrowserViewModel to use IAssetRegistry - Upgraded Misaki.HighPerformance and System.IO.Hashing packages - Set DependencyChainCapacity in JobSchedulerDesc - Fixed instance buffer logic in GhostRenderPipeline - Miscellaneous cleanups and namespace improvements --- .../.github}/commit-instructions.md | 0 .../AssetHandler/AssetHandlerRegistry.cs | 14 +++++ .../AssetHandler/TextureAssetHandler.cs | 6 +- .../AssetHandler/TextureProcessor.cs | 49 ++++++++++------ .../Services/AssetCatalog.cs | 1 - .../Services/AssetRegistry.cs | 2 +- .../Controls/ProjectBrowserViewModel.cs | 8 +-- .../Views/Windows/EngineEditorWindow.xaml | 3 + src/Runtime/Ghost.Core/Ghost.Core.csproj | 6 +- src/Runtime/Ghost.Engine/EngineCore.cs | 1 + .../GhostRenderPipeline.UpdateGPUScene.cs | 10 ++-- .../GhostRenderPipelineSettings.cs | 19 ++++--- .../Systems/AddGPUInstanceSystem.cs | 4 +- .../Systems/RemoveGPUInstanceSystem.cs | 5 +- .../Systems/UpdateGPUInstanceSystem.cs | 56 +++++++++++++++++++ src/Runtime/Ghost.Entities/Query.cs | 8 +-- src/Runtime/Ghost.Entities/System.cs | 6 ++ .../IResourceStreamingProcessor.cs | 5 -- .../Systems/CameraMovingSystem.cs | 2 +- 19 files changed, 150 insertions(+), 55 deletions(-) rename {.github => src/.github}/commit-instructions.md (100%) create mode 100644 src/Runtime/Ghost.Engine/Systems/UpdateGPUInstanceSystem.cs diff --git a/.github/commit-instructions.md b/src/.github/commit-instructions.md similarity index 100% rename from .github/commit-instructions.md rename to src/.github/commit-instructions.md diff --git a/src/Editor/Ghost.Editor.Core/AssetHandler/AssetHandlerRegistry.cs b/src/Editor/Ghost.Editor.Core/AssetHandler/AssetHandlerRegistry.cs index 47d93db..24c03f8 100644 --- a/src/Editor/Ghost.Editor.Core/AssetHandler/AssetHandlerRegistry.cs +++ b/src/Editor/Ghost.Editor.Core/AssetHandler/AssetHandlerRegistry.cs @@ -9,12 +9,14 @@ namespace Ghost.Editor.Core.AssetHandler; public static class AssetHandlerRegistry { private static readonly Dictionary s_byExtension; + private static readonly Dictionary s_typeByExtension; private static readonly Dictionary s_byTypeId; private static readonly Dictionary s_versionByTypeId; static AssetHandlerRegistry() { s_byExtension = new Dictionary(StringComparer.OrdinalIgnoreCase); + s_typeByExtension = new Dictionary(StringComparer.OrdinalIgnoreCase); s_byTypeId = new Dictionary(); s_versionByTypeId = new Dictionary(); } @@ -28,6 +30,7 @@ public static class AssetHandlerRegistry { var normalizedExt = ext.StartsWith('.') ? ext : "." + ext; s_byExtension[normalizedExt] = handler; + s_typeByExtension[normalizedExt] = handler.TargetAssetType; } } @@ -59,4 +62,15 @@ public static class AssetHandlerRegistry { return s_byExtension.Keys; } + + public static AssetType GetAssetTypeByExtension(string extension) + { + if (string.IsNullOrEmpty(extension)) + { + return AssetType.Unknown; + } + + var normalized = extension.StartsWith('.') ? extension : "." + extension; + return s_typeByExtension.GetValueOrDefault(normalized, AssetType.Unknown); + } } diff --git a/src/Editor/Ghost.Editor.Core/AssetHandler/TextureAssetHandler.cs b/src/Editor/Ghost.Editor.Core/AssetHandler/TextureAssetHandler.cs index 738788b..34d5292 100644 --- a/src/Editor/Ghost.Editor.Core/AssetHandler/TextureAssetHandler.cs +++ b/src/Editor/Ghost.Editor.Core/AssetHandler/TextureAssetHandler.cs @@ -1,10 +1,8 @@ using Ghost.Core; using Ghost.Engine; -using Ghost.Engine.AssetLoader; using Ghost.Graphics.RHI; using ImageMagick; using Misaki.HighPerformance.LowLevel; -using Misaki.HighPerformance.LowLevel.Buffer; using System.Runtime.InteropServices; namespace Ghost.Editor.Core.AssetHandler; @@ -339,8 +337,8 @@ internal class TextureAssetHandler : IAssetHandler try { using var image = new MagickImage(sourceStream); - var pixels = image.GetPixels().GetValues(); - if (pixels == null) + var pixels = image.GetPixelsUnsafe().GetAreaPointer(0, 0, image.Width, image.Height); + if (pixels == 0) { return Result.Failure("Failed to retrieve pixel data from the source image."); } diff --git a/src/Editor/Ghost.Editor.Core/AssetHandler/TextureProcessor.cs b/src/Editor/Ghost.Editor.Core/AssetHandler/TextureProcessor.cs index 482eb33..e03a859 100644 --- a/src/Editor/Ghost.Editor.Core/AssetHandler/TextureProcessor.cs +++ b/src/Editor/Ghost.Editor.Core/AssetHandler/TextureProcessor.cs @@ -1,6 +1,4 @@ -using Ghost.Graphics.RHI; using Ghost.Nvtt; -using ImageMagick; using Misaki.HighPerformance.LowLevel; using System.IO.Hashing; using System.Runtime.CompilerServices; @@ -26,7 +24,7 @@ internal static class TextureProcessor { private readonly string _outputPath; - private readonly float[] _image; + private readonly nint _image; private readonly uint _depth; private readonly uint _width; private readonly uint _height; @@ -38,7 +36,7 @@ internal static class TextureProcessor public Task Task => _completionSource.Task; - public NvttPipelineTask(string outputPath, float[] image, uint width, uint height, uint depth, TextureAssetSettings settings) + public NvttPipelineTask(string outputPath, nint image, uint width, uint height, uint depth, TextureAssetSettings settings) { _outputPath = outputPath; _image = image; @@ -60,10 +58,7 @@ internal static class TextureProcessor ? NvttInputFormat.NVTT_InputFormat_RGBA_32F : NvttInputFormat.NVTT_InputFormat_BGRA_8UB; // we'll swizzle RB below - fixed (void* pData = _image) - { - pSurface.Get()->SetImageData(inputFormat, (int)_width, (int)_height, 1, pData, NvttBoolean.NVTT_True, null); - } + pSurface.Get()->SetImageData(inputFormat, (int)_width, (int)_height, 1, (void*)_image, NvttBoolean.NVTT_True, null); // stb gives us RGBA byte order; NVTT BGRA_8UB reads it as BGRA, // so channels R and B are swapped — fix with swizzle(2,1,0,3). @@ -164,7 +159,7 @@ internal static class TextureProcessor } } - public static async ValueTask<(string cachePath, int mipmapCount)> CompressToCacheAsync(string cachesFolderPath, Guid assetId, float[] image, uint width, uint height, uint depth, TextureAssetSettings settings, CancellationToken cancellationToken) + public static async ValueTask<(string cachePath, int mipmapCount)> CompressToCacheAsync(string cachesFolderPath, Guid assetId, nint image, uint width, uint height, uint depth, TextureAssetSettings settings, CancellationToken cancellationToken) { var settingsHash = ComputeSettingsHash(settings); var cacheFileName = $"texturecache_{assetId:N}_{settingsHash:X16}.dds"; @@ -176,15 +171,37 @@ internal static class TextureProcessor if (File.Exists(cachePath)) { - // TODO: Implement mipmap count retrieval from existing cache file - return (cachePath, 0); - } - - foreach (var stale in Directory.EnumerateFiles(cachesFolderPath, $"texturecache_{assetId:N}_*.dds")) - { - File.Delete(stale); + using var fs = new FileStream(cachePath, FileMode.Open, FileAccess.Read); + using var reader = new BinaryReader(fs); + if (reader.ReadUInt32() != 0x20534444) + { + File.Delete(cachePath); + goto ScheduleWork; + } + + // Read dwFlags (Offset 8) + // Skip dwSize (4 bytes), then read dwFlags (4 bytes) + reader.BaseStream.Seek(4, SeekOrigin.Current); + var flags = reader.ReadUInt32(); + + // The DDSD_MIPMAPCOUNT flag is 0x00020000 + var hasMipMapFlag = (flags & 0x00020000) != 0; + + // Read dwMipMapCount (Offset 28) + reader.BaseStream.Seek(28, SeekOrigin.Begin); + var mipMapCount = reader.ReadUInt32(); + + // Return the correct count + // If the flag is missing, or the count says 0, there is still 1 main image. + if (!hasMipMapFlag || mipMapCount == 0) + { + return (cachePath, 1); + } + + return (cachePath, (int)mipMapCount); } + ScheduleWork: var workItem = new NvttPipelineTask(cachePath, image, width, height, depth, settings); ThreadPool.UnsafeQueueUserWorkItem(workItem, true); await workItem.Task.WaitAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Editor/Ghost.Editor.Core/Services/AssetCatalog.cs b/src/Editor/Ghost.Editor.Core/Services/AssetCatalog.cs index 6d93efb..6bc6c71 100644 --- a/src/Editor/Ghost.Editor.Core/Services/AssetCatalog.cs +++ b/src/Editor/Ghost.Editor.Core/Services/AssetCatalog.cs @@ -1,5 +1,4 @@ using Ghost.Editor.Core.AssetHandler; -using Ghost.Engine; using Microsoft.Data.Sqlite; namespace Ghost.Editor.Core.Services; diff --git a/src/Editor/Ghost.Editor.Core/Services/AssetRegistry.cs b/src/Editor/Ghost.Editor.Core/Services/AssetRegistry.cs index f7b9eec..23aca97 100644 --- a/src/Editor/Ghost.Editor.Core/Services/AssetRegistry.cs +++ b/src/Editor/Ghost.Editor.Core/Services/AssetRegistry.cs @@ -341,7 +341,7 @@ internal sealed class AssetRegistry : IAssetRegistry, IDisposable } var tasks = new Task[_dirtyAssets.Count]; - + var i = 0; foreach (var id in _dirtyAssets) { diff --git a/src/Editor/Ghost.Editor/ViewModels/Controls/ProjectBrowserViewModel.cs b/src/Editor/Ghost.Editor/ViewModels/Controls/ProjectBrowserViewModel.cs index e8e79aa..8049b49 100644 --- a/src/Editor/Ghost.Editor/ViewModels/Controls/ProjectBrowserViewModel.cs +++ b/src/Editor/Ghost.Editor/ViewModels/Controls/ProjectBrowserViewModel.cs @@ -10,7 +10,7 @@ namespace Ghost.Editor.ViewModels.Controls; internal partial class ProjectBrowserViewModel : ObservableObject { private readonly IInspectorService _inspectorService; - // private readonly IAssetService _assetService; + private readonly IAssetRegistry _assetRegistry; private readonly Dictionary _pathToDirectoryItemMap = new(); private ExplorerItem? _selectedItem; @@ -40,10 +40,10 @@ internal partial class ProjectBrowserViewModel : ObservableObject get; set; } = string.Empty; - public ProjectBrowserViewModel(IInspectorService inspectorService) // , IAssetService assetService) + public ProjectBrowserViewModel(IInspectorService inspectorService, IAssetRegistry assetRegistry) { _inspectorService = inspectorService; - // _assetService = assetService; + _assetRegistry = assetRegistry; var assetsRootItem = new ExplorerItem(EditorApplication.ASSETS_FOLDER_NAME, Path.Combine(EditorApplication.ProjectPath, EditorApplication.ASSETS_FOLDER_NAME), true); LoadSubFolderRecursive(assetsRootItem); @@ -109,7 +109,7 @@ internal partial class ProjectBrowserViewModel : ObservableObject } else { - // _assetService.OpenAsset(SelectedItem.FullName); + // _assetRegistry.OpenAsset(SelectedItem.FullName); return (null, 1); } } diff --git a/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml index a9b88f6..b925cb4 100644 --- a/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml +++ b/src/Editor/Ghost.Editor/Views/Windows/EngineEditorWindow.xaml @@ -70,6 +70,7 @@ x:Name="ContentFrame" Grid.Row="2" IsNavigationStackEnabled="False" />--> + @@ -390,6 +391,7 @@ Margin="8,0" PlaceholderText="Search components..." /> + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/src/Runtime/Ghost.Engine/EngineCore.cs b/src/Runtime/Ghost.Engine/EngineCore.cs index 1c6a8c4..684e5f7 100644 --- a/src/Runtime/Ghost.Engine/EngineCore.cs +++ b/src/Runtime/Ghost.Engine/EngineCore.cs @@ -21,6 +21,7 @@ public sealed partial class EngineCore : IDisposable { ThreadCount = Environment.ProcessorCount - 2, // We -2 here, one for main thread, one for render thread ThreadPriority = ThreadPriority.Normal, + DependencyChainCapacity = 8192, }; _jobScheduler = new JobScheduler(in desc); diff --git a/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipeline.UpdateGPUScene.cs b/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipeline.UpdateGPUScene.cs index eb439e1..be1feb4 100644 --- a/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipeline.UpdateGPUScene.cs +++ b/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipeline.UpdateGPUScene.cs @@ -41,13 +41,13 @@ internal partial class GhostRenderPipeline private static unsafe Handle CreateUpdateInstanceBuffer(GhostRenderPayload ghostPayload, ResourceManager resourceManager, IResourceDatabase resourceDatabase, out int count) { // TODO: This should also include update requests like transform update, material update, etc. - var totalUpdateCount = ghostPayload.AddRequest.Count; // + ghostPayload.UpdateRequest.Count; + var totalUpdateCount = ghostPayload.UpdateRequest.Count; // + ghostPayload.UpdateRequest.Count; - if (!ghostPayload.AddRequest.IsEmpty) + if (!ghostPayload.UpdateRequest.IsEmpty) { var addDesc = new BufferDesc { - Size = (nuint)ghostPayload.AddRequest.Count * MemoryUtility.SizeOf(), + Size = (nuint)ghostPayload.UpdateRequest.Count * MemoryUtility.SizeOf(), Stride = (uint)MemoryUtility.SizeOf(), Usage = BufferUsage.Structured | BufferUsage.ShaderResource, HeapType = HeapType.Upload @@ -57,7 +57,7 @@ internal partial class GhostRenderPipeline var pAddData = (UpdateInstanceData*)resourceDatabase.MapResource(addBuffer.AsResource(), 0, null); var i = 0; - while (ghostPayload.AddRequest.TryDequeue(out var addRequest)) + while (ghostPayload.UpdateRequest.TryDequeue(out var addRequest)) { var (mesh, error) = resourceManager.GetMeshReference(addRequest.meshInstance.mesh); if (error.IsFailure) @@ -95,7 +95,7 @@ internal partial class GhostRenderPipeline { var addDesc = new BufferDesc { - Size = (nuint)ghostPayload.AddRequest.Count * MemoryUtility.SizeOf(), + Size = (nuint)ghostPayload.UpdateRequest.Count * MemoryUtility.SizeOf(), Stride = (uint)MemoryUtility.SizeOf(), Usage = BufferUsage.Structured | BufferUsage.ShaderResource, HeapType = HeapType.Upload diff --git a/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipelineSettings.cs b/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipelineSettings.cs index ab12bdd..22c1fd0 100644 --- a/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipelineSettings.cs +++ b/src/Runtime/Ghost.Engine/RenderPipeline/GhostRenderPipelineSettings.cs @@ -10,7 +10,7 @@ namespace Ghost.Engine.RenderPipeline; internal sealed class GhostRenderPayload : IRenderPayload { - public struct AddInstanceRequest + public struct UpdateInstanceRequest { public MeshInstance meshInstance; public float4x4 localToWorld; @@ -27,7 +27,7 @@ internal sealed class GhostRenderPayload : IRenderPayload private UnsafeList _renderRequests; - private readonly ConcurrentQueue _addRequest; + private readonly ConcurrentQueue _updateRequest; private readonly ConcurrentQueue _removeRequest; private uint _instanceCountBefore; @@ -35,7 +35,7 @@ internal sealed class GhostRenderPayload : IRenderPayload public ReadOnlySpan RenderRequests => _renderRequests; - public ConcurrentQueue AddRequest => _addRequest; + public ConcurrentQueue UpdateRequest => _updateRequest; public ConcurrentQueue RemoveRequest => _removeRequest; public uint InstanceCountBefore => _instanceCountBefore; public uint InstanceCount => _instanceCount; @@ -45,7 +45,7 @@ internal sealed class GhostRenderPayload : IRenderPayload _renderPipeline = renderPipeline; _renderRequests = new UnsafeList(4, Misaki.HighPerformance.LowLevel.Buffer.AllocationHandle.Persistent); - _addRequest = new ConcurrentQueue(); + _updateRequest = new ConcurrentQueue(); _removeRequest = new ConcurrentQueue(); } @@ -59,10 +59,15 @@ internal sealed class GhostRenderPayload : IRenderPayload { var index = _renderPipeline.GPUScene.AddInstance(); - _addRequest.Enqueue(new AddInstanceRequest { instanceId = index, localToWorld = ltw, meshInstance = meshInstance }); + _updateRequest.Enqueue(new UpdateInstanceRequest { instanceId = index, localToWorld = ltw, meshInstance = meshInstance }); return index; } + public void UpdateInstance(uint instanceId, float4x4 ltw, ref readonly MeshInstance meshInstance) + { + _updateRequest.Enqueue(new UpdateInstanceRequest { instanceId = instanceId, localToWorld = ltw, meshInstance = meshInstance }); + } + public void RemoveInstance(uint instanceId) { var swapWithInstanceId = _renderPipeline.GPUScene.RemoveInstance(instanceId); @@ -81,13 +86,13 @@ internal sealed class GhostRenderPayload : IRenderPayload { // We capture the count here to prevent that main thread continues to add more requests for next frame while the render thread is still processing current frame's requests. _instanceCount = _renderPipeline.GPUScene.InstanceCount; - Logger.DebugAssert(_instanceCount == _instanceCountBefore + (uint)_addRequest.Count - (uint)_removeRequest.Count); + Logger.DebugAssert(_instanceCount == _instanceCountBefore + (uint)_updateRequest.Count - (uint)_removeRequest.Count); } public void Reset() { _renderRequests.Clear(); - _addRequest.Clear(); + _updateRequest.Clear(); _removeRequest.Clear(); } diff --git a/src/Runtime/Ghost.Engine/Systems/AddGPUInstanceSystem.cs b/src/Runtime/Ghost.Engine/Systems/AddGPUInstanceSystem.cs index a548d35..4a8cdb2 100644 --- a/src/Runtime/Ghost.Engine/Systems/AddGPUInstanceSystem.cs +++ b/src/Runtime/Ghost.Engine/Systems/AddGPUInstanceSystem.cs @@ -7,8 +7,8 @@ using Misaki.HighPerformance.Utilities; namespace Ghost.Engine.Systems; -[UpdateAfter] [RenderPipelineSystem] +[UpdateAfter] internal class AddGPUInstanceSystem : SystemBase { private RenderSystem _renderSystem = null!; @@ -19,7 +19,7 @@ internal class AddGPUInstanceSystem : SystemBase { _renderSystem = systemAPI.World.GetService(); - _meshInstanceQueryID = QueryBuilder.Create() + _meshInstanceQueryID = QueryBuilder.New() .WithAll() .WithAbsent() .Build(systemAPI.World, true); diff --git a/src/Runtime/Ghost.Engine/Systems/RemoveGPUInstanceSystem.cs b/src/Runtime/Ghost.Engine/Systems/RemoveGPUInstanceSystem.cs index b31a2ac..57b21e4 100644 --- a/src/Runtime/Ghost.Engine/Systems/RemoveGPUInstanceSystem.cs +++ b/src/Runtime/Ghost.Engine/Systems/RemoveGPUInstanceSystem.cs @@ -18,7 +18,7 @@ internal class RemoveGPUInstanceSystem : SystemBase { _renderSystem = systemAPI.World.GetService(); - _gpuInstanceQueryID = QueryBuilder.Create() + _gpuInstanceQueryID = QueryBuilder.New() .WithAll() .WithAbsent() .Build(systemAPI.World, true); @@ -29,6 +29,7 @@ internal class RemoveGPUInstanceSystem : SystemBase protected override void OnUpdate(ref readonly SystemAPI systemAPI) { var payload = (GhostRenderPayload)_renderSystem.GetCurrentFramePayload(); + payload.BeginRecord(); ref var gpuInstanceQuery = ref systemAPI.World.ComponentManager.GetEntityQueryReference(_gpuInstanceQueryID); @@ -47,4 +48,4 @@ internal class RemoveGPUInstanceSystem : SystemBase } } } -} \ No newline at end of file +} diff --git a/src/Runtime/Ghost.Engine/Systems/UpdateGPUInstanceSystem.cs b/src/Runtime/Ghost.Engine/Systems/UpdateGPUInstanceSystem.cs new file mode 100644 index 0000000..cbf57fe --- /dev/null +++ b/src/Runtime/Ghost.Engine/Systems/UpdateGPUInstanceSystem.cs @@ -0,0 +1,56 @@ +using Ghost.Core; +using Ghost.Engine.Components; +using Ghost.Engine.RenderPipeline; +using Ghost.Entities; +using Ghost.Graphics; +using Misaki.HighPerformance.Utilities; + +namespace Ghost.Engine.Systems; + +[RenderPipelineSystem] +[UpdateAfter] +[UpdateBefore] +internal class UpdateGPUInstanceSystem : SystemBase +{ + private RenderSystem _renderSystem = null!; + private Identifier _gpuInstanceQueryID; + + protected override void OnInitialize(ref readonly SystemAPI systemAPI) + { + _renderSystem = systemAPI.World.GetService(); + + _gpuInstanceQueryID = QueryBuilder.New() + .WithAll() + .Build(systemAPI.World, true); + + RequireQueryForUpdate(_gpuInstanceQueryID); + } + + protected override void OnUpdate(ref readonly SystemAPI systemAPI) + { + var playload = (GhostRenderPayload)_renderSystem.GetCurrentFramePayload(); + + ref var instanceQuery = ref systemAPI.World.ComponentManager.GetEntityQueryReference(_gpuInstanceQueryID); + + foreach (var chunk in instanceQuery.GetChunkIterator()) + { + if (!chunk.HasChanged(LastSystemVersion)) + { + continue; + } + + var ltws = chunk.GetComponentData(); + var meshs = chunk.GetComponentData(); + var gpuInstances = chunk.GetComponentData(); + + for (var i = 0; i < chunk.EntityCount; i++) + { + ref readonly var ltw = ref ltws.GetElementUnsafe(i); + ref readonly var mesh = ref meshs.GetElementUnsafe(i); + ref readonly var instance = ref gpuInstances.GetElementUnsafe(i); + + playload.UpdateInstance(instance.gpuSceneIndex, ltw.matrix, in mesh); + } + } + } +} diff --git a/src/Runtime/Ghost.Entities/Query.cs b/src/Runtime/Ghost.Entities/Query.cs index 5b5e8a5..3dce1e9 100644 --- a/src/Runtime/Ghost.Entities/Query.cs +++ b/src/Runtime/Ghost.Entities/Query.cs @@ -130,7 +130,7 @@ public readonly unsafe ref struct ChunkView /// The version number to compare against the component's current version. Must be greater than or equal to zero. /// true if the component's current version is less than or equal to the specified version; otherwise, false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool HasChanged(Identifier id, int version) + public bool HasChanged(Identifier id, uint version) { var layout = GetLayout(id); return version < _pVersion[layout.versionIndex]; @@ -144,7 +144,7 @@ public readonly unsafe ref struct ChunkView /// The version number to compare against the current version of the component. /// true if the component of space T has changed since the specified version; otherwise, false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly bool HasChanged(int version) + public readonly bool HasChanged(uint version) where T : unmanaged, IComponent { var layout = GetLayout(ComponentTypeID.Value); @@ -157,7 +157,7 @@ public readonly unsafe ref struct ChunkView /// The version number to compare against the chunk's structural version. /// true if the chunk's structure has changed since the specified version; otherwise, false. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly bool HasStructuralChanged(int version) + public readonly bool HasStructuralChanged(uint version) { return version < _structuralVersion; } @@ -502,7 +502,7 @@ public ref partial struct QueryBuilder : IDisposable _rw = new UnsafeList>(4, _scope.AllocationHandle); } - public static QueryBuilder Create() + public static QueryBuilder New() { return new QueryBuilder(); } diff --git a/src/Runtime/Ghost.Entities/System.cs b/src/Runtime/Ghost.Entities/System.cs index d1bfcb5..c46740c 100644 --- a/src/Runtime/Ghost.Entities/System.cs +++ b/src/Runtime/Ghost.Entities/System.cs @@ -28,11 +28,17 @@ public abstract class SystemBase : ISystem { private UnsafeList _requiredQueries; + /// + /// Gets the world that the system is running on currently. + /// public World World { get; init; } = null!; + /// + /// Gets the last version that the system update. + /// public uint LastSystemVersion { get; internal set; diff --git a/src/Runtime/Ghost.Graphics/IResourceStreamingProcessor.cs b/src/Runtime/Ghost.Graphics/IResourceStreamingProcessor.cs index 41fb693..292a220 100644 --- a/src/Runtime/Ghost.Graphics/IResourceStreamingProcessor.cs +++ b/src/Runtime/Ghost.Graphics/IResourceStreamingProcessor.cs @@ -1,10 +1,5 @@ -using Ghost.Core; using Ghost.Graphics.RHI; using Ghost.Graphics.Services; -using Misaki.HighPerformance.LowLevel.Buffer; -using Misaki.HighPerformance.LowLevel.Collections; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; namespace Ghost.Graphics; diff --git a/src/Test/Ghost.Graphics.Test/Systems/CameraMovingSystem.cs b/src/Test/Ghost.Graphics.Test/Systems/CameraMovingSystem.cs index 1536aeb..2e18e7c 100644 --- a/src/Test/Ghost.Graphics.Test/Systems/CameraMovingSystem.cs +++ b/src/Test/Ghost.Graphics.Test/Systems/CameraMovingSystem.cs @@ -15,7 +15,7 @@ internal class CameraMovingSystem : ISystem public void Initialize(ref readonly SystemAPI systemAPI) { - _cameraQueryID = QueryBuilder.Create() + _cameraQueryID = QueryBuilder.New() .WithAll() .Build(systemAPI.World, true);