diff --git a/Ghost.Core/Ghost.Core.csproj b/Ghost.Core/Ghost.Core.csproj index b2696fc..ccfba5b 100644 --- a/Ghost.Core/Ghost.Core.csproj +++ b/Ghost.Core/Ghost.Core.csproj @@ -20,9 +20,9 @@ - + - + diff --git a/Ghost.Entities.Test/EntityTest.cs b/Ghost.Entities.Test/EntityTest.cs index f6c6368..6804904 100644 --- a/Ghost.Entities.Test/EntityTest.cs +++ b/Ghost.Entities.Test/EntityTest.cs @@ -1,7 +1,7 @@ using Ghost.Test.Core; using Misaki.HighPerformance.Jobs; +using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.Mathematics; -using System.Diagnostics; namespace Ghost.Entities.Test; @@ -9,17 +9,19 @@ internal struct TestChunkQueryJob : IJobChunk { public readonly void Execute(ChunkView view, int threadIndex) { + var random = new random((uint)threadIndex + 1u); + var transforms = view.GetComponentDataRW(); for (var i = 0; i < view.Count; i++) { - transforms[i].position += new float3(10, 10, 10); + transforms[i].position += random.NextFloat3(-1f, 1f); } } } internal struct TestEntityQueryJob : IJobEntity { - public readonly void Execute(Entity entity, ref Transform transform, int index) + public readonly void Execute(Entity entity, ref Transform transform, int threadIndex) { transform.position += new float3(5, 5, 5); } @@ -38,23 +40,16 @@ public partial class EntityTest : ITest public void Run() { - var entity1 = _world.EntityManager.CreateEntity(ComponentTypeID.value, ComponentTypeID.value); - _world.EntityManager.AddComponent(entity1, new Mesh { index = 1 }); - _world.EntityManager.SetComponent(entity1, new ManagedEntityRef - { - entity = _world.EntityManager.CreateManagedEntity() - }); + var entities = (Span)stackalloc Entity[1000]; + _world.EntityManager.CreateEntities(entities, ComponentTypeID.value); - var entity2 = _world.EntityManager.CreateEntity(ComponentTypeID.value); - _world.EntityManager.SetComponent(entity2, new Transform { position = new float3(1, 2, 3) }); - - var queryID = new QueryBuilder().WithAllRW().WithAbsent().Build(_world); + var queryID = new QueryBuilder().WithAllRW().Build(_world); ref var query = ref _world.GetEntityQueryReference(queryID); _world.AdvanceVersion(); - var testJob = new TestEntityQueryJob(); - var handle = query.ScheduleEntityParallel(testJob, 64, JobHandle.Invalid); + var testJob = new TestChunkQueryJob(); + var handle = query.ScheduleChunkParallel(testJob, 64, JobHandle.Invalid); _jobScheduler.WaitComplete(handle); // _world.EntityManager.AddScriptComponent(entity1); @@ -73,22 +68,22 @@ public partial class EntityTest : ITest foreach (var chunk in query.GetChunkIterator()) { var transforms = chunk.GetComponentData(); - var entities = chunk.GetEntities(); + var chunkEntities = chunk.GetEntities(); - if (chunk.HasChanged(0)) + // if (chunk.HasChanged(0)) { - var bits = chunk.GetEnableBits(); + // var bits = chunk.GetEnableBits(); - var it = bits.GetIterator(); - while (it.Next(out var index) && index < chunk.Count) + // var it = bits.GetIterator(); + // while (it.Next(out var index) && index < chunk.Count) + for (var index = 0; index < chunk.Count; index++) { - Console.WriteLine($"Entity {entities[index]} Updated Position: {transforms[index].position}"); + Console.WriteLine($"Entity {chunkEntities[index]} Updated Position: {transforms[index].position}"); } } } - Debug.Assert(_world.EntityManager.DestroyEntity(entity1) == Core.ErrorStatus.None); - Debug.Assert(_world.EntityManager.DestroyEntity(entity2) == Core.ErrorStatus.None); + _world.EntityManager.DestroyEntities(entities); } public void Cleanup() diff --git a/Ghost.Entities/Archetype.cs b/Ghost.Entities/Archetype.cs index 7807bc4..455ce20 100644 --- a/Ghost.Entities/Archetype.cs +++ b/Ghost.Entities/Archetype.cs @@ -157,7 +157,9 @@ internal unsafe struct Chunk : IDisposable public void Dispose() { _data.Dispose(); + Console.WriteLine($"Disposing chunk data"); _versions.Dispose(); + Console.WriteLine($"Disposing chunk versions"); } } @@ -587,9 +589,12 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable { if (_chunks.IsCreated) { + var i= 0; foreach (ref var chunk in _chunks) { + Console.WriteLine($"Disposing chunk {i} of archetype {_id}"); chunk.Dispose(); + i++; } } diff --git a/Ghost.Entities/EntityManager.Managed.cs b/Ghost.Entities/EntityManager.Managed.cs index c9fc5cc..22f59d8 100644 --- a/Ghost.Entities/EntityManager.Managed.cs +++ b/Ghost.Entities/EntityManager.Managed.cs @@ -68,7 +68,7 @@ public partial class EntityManager /// True if the ManagedEntity exists, false otherwise. public bool Exists(ManagedEntity managedEntity) { - return _scriptComponents.Contain(managedEntity.id, managedEntity.generation); + return _scriptComponents.Contains(managedEntity.id, managedEntity.generation); } /// diff --git a/Ghost.Entities/EntityManager.cs b/Ghost.Entities/EntityManager.cs index 7aaa512..09c060a 100644 --- a/Ghost.Entities/EntityManager.cs +++ b/Ghost.Entities/EntityManager.cs @@ -60,7 +60,7 @@ public unsafe partial class EntityManager : IDisposable public Entity CreateEntity() { var entities = (Span)stackalloc Entity[1]; - CreateEntities(1, entities); + CreateEntities(entities); return entities[0]; } @@ -73,7 +73,7 @@ public unsafe partial class EntityManager : IDisposable public Entity CreateEntity(params ReadOnlySpan> componentTypeIDs) { var entities = (Span)stackalloc Entity[1]; - CreateEntities(1, entities, componentTypeIDs); + CreateEntities(entities, componentTypeIDs); return entities[0]; } @@ -81,14 +81,13 @@ public unsafe partial class EntityManager : IDisposable /// /// Create multiple entities with no components. /// - /// The number of entities to create. /// The span to store the created entities. - public void CreateEntities(int count, Span entities) + public void CreateEntities(Span entities) { ref var emptyArchetype = ref _world.GetArchetypeReference(World.EmptyArchetypeID); emptyArchetype.AllocateEntity(out var chunkIndex, out var rowIndex); - for (var i = 0; i < count; i++) + for (var i = 0; i < entities.Length; i++) { var id = _entityLocations.Add(new EntityLocation { @@ -130,11 +129,10 @@ public unsafe partial class EntityManager : IDisposable /// /// Create multiple entities with specified components. /// - /// The number of entities to create. /// The allocator to use for the returned array. /// The component type IDs to add to the entities. /// An array of the created entities. - public void CreateEntities(int count, Span entities, params ReadOnlySpan> componentTypeIDs) + public void CreateEntities(Span entities, params ReadOnlySpan> componentTypeIDs) { var signatureHash = ComponentRegister.GetHashCode(componentTypeIDs); var arcID = _world.GetArchetypeIDBySignatureHash(signatureHash); @@ -146,7 +144,7 @@ public unsafe partial class EntityManager : IDisposable ref var archetype = ref _world.GetArchetypeReference(arcID); - for (var i = 0; i < count; i++) + for (var i = 0; i < entities.Length; i++) { archetype.AllocateEntity(out var chunkIndex, out var rowIndex); @@ -230,6 +228,18 @@ public unsafe partial class EntityManager : IDisposable return ErrorStatus.None; } + /// + /// Destroy the specified entities. + /// + /// The entities to destroy. + public void DestroyEntities(ReadOnlySpan entities) + { + for (var i = 0; i < entities.Length; i++) + { + DestroyEntity(entities[i]); + } + } + /// /// Check if the specified entity exists. /// @@ -714,9 +724,6 @@ public unsafe partial class EntityManager : IDisposable return; } - Debug.Assert(_entityLocations.Count == 0, "There are still entities alive when disposing EntityManager."); - Debug.Assert(_scriptComponents.Count == 0, "There are still managed entities alive when disposing EntityManager."); - _entityLocations.Dispose(); _disposed = true;