Refactor ECS core, improve thread safety, add tests
- Switch Scene IDs to ushort, update invalid value logic - Add thread safety to SceneManager and ComponentRegistry - Add GHOST_ZERO_INIT_COMPONENT define for editor configs - Update mesh header counts to use int, not uint - Add Collect methods for archetype/component cleanup - Add With/Without/AsView to ComponentSet for easier use - Refactor World creation/destruction, version handling - Refactor ResourceStreamingContext to use init-only props - Add unit tests for entity queries and world lifecycle - Minor code cleanups and formatting fixes
This commit is contained in:
@@ -37,7 +37,7 @@ public class AssertRegistryTest
|
||||
{
|
||||
var sourcePath = "Assets/test.text";
|
||||
await File.WriteAllBytesAsync(sourcePath, [1, 2, 3], TestContext.CancellationToken);
|
||||
|
||||
|
||||
var metaPath = AssetMetaIO.GetMetaPath(sourcePath);
|
||||
|
||||
using var cts = new CancellationTokenSource(5000);
|
||||
@@ -47,7 +47,7 @@ public class AssertRegistryTest
|
||||
}
|
||||
|
||||
Assert.IsTrue(File.Exists(metaPath));
|
||||
|
||||
|
||||
var meta = await AssetMetaIO.ReadAsync(metaPath, TestContext.CancellationToken);
|
||||
Assert.IsNotNull(meta);
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ public class AssetManagerTest
|
||||
Assert.IsGreaterThanOrEqualTo((int)AssetState.Ready, entry.StateValue);
|
||||
|
||||
var (data, error) = _graphicsEngine.ResourceDatabase.GetResourceBarrierData(handle.AsResource());
|
||||
|
||||
|
||||
Assert.AreEqual(Error.None, error);
|
||||
Assert.AreEqual(BarrierAccess.ShaderResource, data.access);
|
||||
Assert.AreEqual(BarrierLayout.ShaderResource, data.layout);
|
||||
|
||||
71
src/Test/Ghost.UnitTest/ECS/EntityQueryTests.cs
Normal file
71
src/Test/Ghost.UnitTest/ECS/EntityQueryTests.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using Ghost.Engine.Components;
|
||||
using Ghost.Entities;
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
|
||||
namespace Ghost.UnitTest.ECS;
|
||||
|
||||
[TestClass]
|
||||
[DoNotParallelize]
|
||||
public class EntityQueryTests
|
||||
{
|
||||
private struct Enableable : IEnableableComponent
|
||||
{
|
||||
}
|
||||
|
||||
private World _world = null!;
|
||||
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
AllocationManager.Initialize();
|
||||
_world = World.Create(null, 64);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
_world.Dispose();
|
||||
AllocationManager.Dispose();
|
||||
}
|
||||
|
||||
private void CreateDefaultEntities(int count)
|
||||
{
|
||||
var set = new ComponentSetView([ComponentTypeID<MeshInstance>.Value, ComponentTypeID<LocalToWorld>.Value]);
|
||||
_world.EntityManager.CreateEntities(count, set);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ComponentSetCreation()
|
||||
{
|
||||
using var set1 = new ComponentSet(AllocationHandle.Persistent, ComponentTypeID<MeshInstance>.Value, ComponentTypeID<LocalToWorld>.Value);
|
||||
Assert.AreEqual(2, set1.Components.Length);
|
||||
|
||||
using var set2 = set1.With(AllocationHandle.Persistent, ComponentTypeID<Camera>.Value);
|
||||
Assert.AreEqual(3, set2.Components.Length);
|
||||
Assert.IsTrue(set2.Components.Contains(ComponentTypeID<Camera>.Value));
|
||||
|
||||
using var set3 = set2.Without(AllocationHandle.Persistent, ComponentTypeID<MeshInstance>.Value);
|
||||
Assert.AreEqual(2, set3.Components.Length);
|
||||
Assert.IsFalse(set3.Components.Contains(ComponentTypeID<MeshInstance>.Value));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SimpleQuery_EntityCountShouldEqual()
|
||||
{
|
||||
CreateDefaultEntities(100);
|
||||
|
||||
var queryID = QueryBuilder.New()
|
||||
.WithAll<LocalToWorld, MeshInstance>()
|
||||
.Build(_world);
|
||||
|
||||
ref readonly var query = ref _world.ComponentManager.GetEntityQueryReference(queryID);
|
||||
|
||||
var i = 0;
|
||||
foreach (var (entity, ltw, mesh) in query.GetEntityComponentIterator<LocalToWorld, MeshInstance>())
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
Assert.AreEqual(100, i);
|
||||
}
|
||||
}
|
||||
28
src/Test/Ghost.UnitTest/ECS/WorldTests.cs
Normal file
28
src/Test/Ghost.UnitTest/ECS/WorldTests.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Ghost.Entities;
|
||||
|
||||
namespace Ghost.UnitTest.ECS;
|
||||
|
||||
[TestClass]
|
||||
[DoNotParallelize]
|
||||
public class WorldTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void CreateWorld()
|
||||
{
|
||||
using var world = World.Create();
|
||||
Assert.IsNotNull(world);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AddEntityThenClearWorld()
|
||||
{
|
||||
using var world = World.Create();
|
||||
Assert.IsNotNull(world);
|
||||
|
||||
world.EntityManager.CreateEntity();
|
||||
Assert.AreEqual(1, world.EntityManager.EntityCount);
|
||||
|
||||
world.Clear(default);
|
||||
Assert.AreEqual(0, world.EntityManager.EntityCount);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
using Ghost.Core;
|
||||
using Ghost.Core.Utilities;
|
||||
using Ghost.Engine;
|
||||
using Ghost.Engine.Streaming;
|
||||
using Ghost.Graphics.Core;
|
||||
using Ghost.Graphics.RHI;
|
||||
using Misaki.HighPerformance.Mathematics;
|
||||
using Misaki.HighPerformance.Mathematics.Geometry;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ghost.UnitTest.MockingEnvironment;
|
||||
|
||||
@@ -130,14 +129,14 @@ internal class MockingContentProvider : IContentProvider
|
||||
{
|
||||
magic = MeshContentHeader.MAGIC,
|
||||
version = MeshContentHeader.VERSION,
|
||||
vertexCount = (uint)vertices.Length,
|
||||
indexCount = (uint)indices.Length,
|
||||
materialPartCount = (uint)materialParts.Length,
|
||||
meshletCount = (uint)meshlets.Length,
|
||||
meshletGroupCount = (uint)groups.Length,
|
||||
meshletHierarchyNodeCount = (uint)hierarchy.Length,
|
||||
meshletVertexCount = (uint)meshletVertices.Length,
|
||||
meshletTriangleCount = (uint)meshletTriangles.Length,
|
||||
vertexCount = vertices.Length,
|
||||
indexCount = indices.Length,
|
||||
materialPartCount = materialParts.Length,
|
||||
meshletCount = meshlets.Length,
|
||||
meshletGroupCount = groups.Length,
|
||||
meshletHierarchyNodeCount = hierarchy.Length,
|
||||
meshletVertexCount = meshletVertices.Length,
|
||||
meshletTriangleCount = meshletTriangles.Length,
|
||||
materialSlotCount = 1,
|
||||
lodLevelCount = 1,
|
||||
boundsMin = new float3(0, 0, 0),
|
||||
|
||||
Reference in New Issue
Block a user