From 21e85e0c02fe4b1f27f8e3b52f93097b92de04e8 Mon Sep 17 00:00:00 2001 From: Misaki Date: Wed, 10 Dec 2025 16:12:56 +0900 Subject: [PATCH] Add managed entity and script component. Added ManagedEntity and related methods in EntityManager; Added ScriptComponent to write game play logic in oop; --- Ghost.Core/Handle.cs | 3 - Ghost.Entities.Test/EntityTest.cs | 65 ++++-- Ghost.Entities/Archetype.cs | 150 ++++++++++--- Ghost.Entities/Component.cs | 10 +- Ghost.Entities/Entity.cs | 32 +-- Ghost.Entities/EntityManager.Managed.cs | 197 ++++++++++++++++++ Ghost.Entities/EntityManager.cs | 24 ++- Ghost.Entities/ManagedEntity.cs | 74 +++++++ Ghost.Entities/Query.cs | 22 +- .../EntityQuery.ComponentIterator.gen.cs | 32 +-- .../EntityQuery.ComponentIterator.tt | 4 +- ...EntityQuery.EntityComponentIterator.gen.cs | 32 +-- .../EntityQuery.EntityComponentIterator.tt | 4 +- .../Templates/EntityQuery.ForEach.gen.cs | 32 +-- .../Templates/EntityQuery.ForEach.tt | 2 +- .../Templates/EntityQuery.JobEntity.gen.cs | 16 +- .../Templates/EntityQuery.JobEntity.tt | 2 +- 17 files changed, 549 insertions(+), 152 deletions(-) create mode 100644 Ghost.Entities/EntityManager.Managed.cs create mode 100644 Ghost.Entities/ManagedEntity.cs diff --git a/Ghost.Core/Handle.cs b/Ghost.Core/Handle.cs index ddd0071..1f61d3e 100644 --- a/Ghost.Core/Handle.cs +++ b/Ghost.Core/Handle.cs @@ -5,7 +5,6 @@ public interface IIdentifierType; public interface IKeyType; public readonly struct Handle : IEquatable> - where T : IHandleType { public readonly int id; public readonly int generation; @@ -58,7 +57,6 @@ public readonly struct Handle : IEquatable> } public readonly struct Identifier : IEquatable> - where T : IIdentifierType { public readonly int value; @@ -132,7 +130,6 @@ public readonly struct Identifier : IEquatable> } public readonly struct Key - where T : IKeyType { public readonly ulong value; diff --git a/Ghost.Entities.Test/EntityTest.cs b/Ghost.Entities.Test/EntityTest.cs index 5e9ae0d..a8815ed 100644 --- a/Ghost.Entities.Test/EntityTest.cs +++ b/Ghost.Entities.Test/EntityTest.cs @@ -29,8 +29,12 @@ public partial class EntityTest : ITest public void Run() { - var entity1 = _world.EntityManager.CreateEntity(ComponentTypeID.value); + 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 entity2 = _world.EntityManager.CreateEntity(ComponentTypeID.value); _world.EntityManager.SetComponent(entity2, new Transform { position = new float3(1, 2, 3) }); @@ -38,32 +42,38 @@ public partial class EntityTest : ITest var queryID = new QueryBuilder().WithAll().Build(_world); ref var query = ref _world.GetEntityQueryReference(queryID); - var testJob = new TestEntityQueryJob(); - var handle = query.ScheduleChunkParallel(testJob, 64, JobHandle.Invalid); - _jobScheduler.WaitComplete(handle); + // var testJob = new TestEntityQueryJob(); + // var handle = query.ScheduleChunkParallel(testJob, 64, JobHandle.Invalid); + // _jobScheduler.WaitComplete(handle); + + _world.EntityManager.AddScriptComponent(entity1); + _world.EntityManager.RemoveComponent(entity1); // This should destory the managed entity and call OnDestroy query.ForEach((e, ref t) => { Console.WriteLine($"Entity {e} Has Position: {t.position}"); }); - foreach (var (entity, transform) in query.GetEntityComponentIterator()) - { - Console.WriteLine($"Entity {entity} Updated Position: {transform.Get().position}"); - } + // foreach (var (entity, transform) in query.GetEntityComponentIterator()) + // { + // Console.WriteLine($"Entity {entity} Updated Position: {transform.Get().position}"); + // } + // + // foreach (var chunk in query.GetChunkIterator()) + // { + // var transforms = chunk.GetComponentData(); + // var entities = chunk.GetEntities(); + // var bits = chunk.GetEnableBits(); + // + // var it = bits.GetIterator(); + // while (it.Next(out var index) && index < chunk.Count) + // { + // Console.WriteLine($"Entity {entities[index]} Updated Position: {transforms[index].position}"); + // } + // } - foreach (var chunk in query.GetChunkIterator()) - { - var transforms = chunk.GetComponentData(); - var entities = chunk.GetEntities(); - var bits = chunk.GetEnableBits(); - - var it = bits.GetIterator(); - while (it.Next(out var index) && index < chunk.Count) - { - Console.WriteLine($"Entity {entities[index]} Updated Position: {transforms[index].position}"); - } - } + _world.EntityManager.DestroyEntity(entity1); + _world.EntityManager.DestroyEntity(entity2); } public void Cleanup() @@ -83,3 +93,18 @@ public struct Mesh : IComponent { public int index; } + +public class TestScriptComponent : ScriptComponent +{ + public override void OnCreate() + { + Console.WriteLine($"TestScriptComponent OnCreate called for Entity {Entity}"); + ref var transform = ref GetComponent(); + transform.position += new float3(0, 1, 0); + } + + public override void OnDestroy() + { + Console.WriteLine($"TestScriptComponent OnDestroy called for Entity {Entity}"); + } +} diff --git a/Ghost.Entities/Archetype.cs b/Ghost.Entities/Archetype.cs index 7b48d50..18fdcb6 100644 --- a/Ghost.Entities/Archetype.cs +++ b/Ghost.Entities/Archetype.cs @@ -2,32 +2,126 @@ using Ghost.Core; using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Collections; using Misaki.HighPerformance.LowLevel.Utilities; +using System.Diagnostics; using System.Runtime.CompilerServices; namespace Ghost.Entities; +internal unsafe sealed class ChunkDebugView +{ + [DebuggerDisplay("{Name,nq}: {Data}")] + internal class ComponentArrayView + { + public string Name { get; } + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public object Data { get; } + + public ComponentArrayView(string name, object data) + { + Name = name; + Data = data; + } + } + + public byte* pData; + public int count; + public int capacity; + public int worldID; + public int archetypeID; + + public ChunkDebugView(Chunk chunk) + { + pData = chunk.GetUnsafePtr(); + count = chunk._count; + capacity = chunk._capacity; +#if DEBUG || GHOST_EDITOR + worldID = chunk._worldID; + archetypeID = chunk._archetypeID; +#else + worldID = -1; + archetypeID = -1; +#endif + } + + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public object[] Items + { + get + { +#if DEBUG || GHOST_EDITOR +#else + if (count == 0) +#endif + { + return []; + } + +#pragma warning disable CS0162 // Unreachable code detected + var views = new List(); +#pragma warning restore CS0162 // Unreachable code detected + ref var archetype = ref World.GetWorld(worldID).GetValueOrThrow() + .GetArchetypeReference(archetypeID); + + foreach (var layout in archetype._layouts) + { + var type = Type.GetTypeFromHandle(RuntimeTypeHandle.FromIntPtr(ComponentRegister.s_runtimeIDToTypeHandle[layout.componentID])); + var readMethod = typeof(ChunkDebugView) + .GetMethod(nameof(ReadComponentArray), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) + .MakeGenericMethod(type); + + // 3. Invoke it to get a Position[] or Velocity[] + var array = readMethod.Invoke(this, [layout.offset]); + + // 4. Wrap it in a nice label so the debugger shows "Position[]" + views.Add(new ComponentArrayView(type.Name, array)); + } + + return [.. views]; + } + } + + private T[] ReadComponentArray(int offsetInChunk) + where T : unmanaged + { + var result = new T[count]; + unsafe + { + var basePtr = pData + offsetInChunk; + + var sizeOfT = sizeof(T); + for (int i = 0; i < count; i++) + { + // Read directly from raw memory + result[i] = Unsafe.Read(basePtr + (i * sizeOfT)); + } + } + return result; + } +} + +[DebuggerTypeProxy(typeof(ChunkDebugView))] internal unsafe struct Chunk : IDisposable { - public const int CHUNK_SIZE = 16384; // 16 KB + public const int CHUNK_BUFFER_SIZE = 16384; // 16 KB public const int BIT_ALIGNMENT = 8; public const int BIT_SHIFT = 3; // log2(BIT_ALIGNMENT) public const int BIT_ALIGNMENT_MINUS_ONE = BIT_ALIGNMENT - 1; private UnsafeArray _data; - private int _count; - private readonly int _capacity; - public int Count + internal int _version; + internal int _count; + internal readonly int _capacity; + +#if DEBUG || GHOST_EDITOR + // For debugging purpose + internal int _worldID; + internal int _archetypeID; +#endif + + public Chunk(int bufferSize, int capacity) { - readonly get => _count; - set => _count = value; - } - - public readonly int Capacity => _capacity; - - public Chunk(int size, int capacity) - { - _data = new UnsafeArray(size, Allocator.Persistent, AllocationOption.Clear); + _data = new UnsafeArray(bufferSize, Allocator.Persistent, AllocationOption.Clear); _capacity = capacity; _count = 0; } @@ -60,9 +154,6 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable public int targetArchetype; // can't use Identifier because cycle causer } - private readonly Identifier _id; - private readonly Identifier _worldID; - internal UnsafeBitSet _signature; internal UnsafeList _chunks; internal UnsafeArray _layouts; @@ -72,6 +163,9 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable private UnsafeList _edgesAdd; private UnsafeList _edgesRemove; + private readonly Identifier _id; + private readonly Identifier _worldID; + private readonly int _hash; private int _entityCapacity; private int _maxComponentID; @@ -98,7 +192,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable _hash = 0; _signature.ClearAll(); - _entityCapacity = Chunk.CHUNK_SIZE / sizeof(Entity); + _entityCapacity = Chunk.CHUNK_BUFFER_SIZE / sizeof(Entity); return; } @@ -144,7 +238,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable } _maxComponentID = maxComponentID; - _entityCapacity = Chunk.CHUNK_SIZE / bytesPerEntity; + _entityCapacity = Chunk.CHUNK_BUFFER_SIZE / bytesPerEntity; _layouts = new UnsafeArray(components.Length, Allocator.Persistent); _componentIDToLayoutIndex = new UnsafeArray(_maxComponentID + 1, Allocator.Persistent); @@ -186,7 +280,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable tempBitmaskOffsets[i] = bitmaskOffset; - if (currentOffset > Chunk.CHUNK_SIZE) + if (currentOffset > Chunk.CHUNK_BUFFER_SIZE) { fits = false; break; @@ -220,10 +314,10 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable for (var i = 0; i < _chunks.Count; i++) { ref var chunk = ref _chunks[i]; - if (chunk.Count < _entityCapacity) + if (chunk._count < _entityCapacity) { - rowIndex = chunk.Count; - chunk.Count++; + rowIndex = chunk._count; + chunk._count++; chunkIndex = i; return; @@ -231,7 +325,11 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable } // Need to allocate a new chunk - var newChunk = new Chunk(Chunk.CHUNK_SIZE, _entityCapacity); + var newChunk = new Chunk(Chunk.CHUNK_BUFFER_SIZE, _entityCapacity); +#if DEBUG || GHOST_EDITOR + newChunk._worldID = _worldID; + newChunk._archetypeID = _id; +#endif // Set all enable to true by default for enableable components for (var i = 0; i < _layouts.Count; i++) @@ -246,7 +344,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable } rowIndex = 0; - newChunk.Count++; + newChunk._count++; chunkIndex = _chunks.Count; _chunks.Add(newChunk); @@ -331,7 +429,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable } ref var chunk = ref _chunks[chunkIndex]; - var lastIndex = chunk.Count - 1; + var lastIndex = chunk._count - 1; // If we are NOT removing the very last entity, we must swap. if (rowIndex != lastIndex) @@ -366,7 +464,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable } } - chunk.Count--; + chunk._count--; return ErrorStatus.None; } diff --git a/Ghost.Entities/Component.cs b/Ghost.Entities/Component.cs index cead545..c589e28 100644 --- a/Ghost.Entities/Component.cs +++ b/Ghost.Entities/Component.cs @@ -32,8 +32,11 @@ internal static class ComponentRegister private static int s_nextComponentTypeID = 0; private static readonly List s_registeredComponents = new(); - private static readonly Dictionary> s_typeHandleToID = new(); - private static readonly Dictionary> s_nameToRuntimeID = new(); + private static readonly Dictionary s_typeHandleToID = new(); + private static readonly Dictionary s_nameToRuntimeID = new(); +#if DEBUG || GHOST_EDITOR + internal static readonly Dictionary s_runtimeIDToTypeHandle = new(); +#endif public static unsafe Identifier GetOrRegisterComponent() where T : unmanaged, IComponent @@ -66,6 +69,9 @@ internal static class ComponentRegister s_typeHandleToID[typeHandle] = newID; s_nameToRuntimeID[stableName] = newID; +#if DEBUG || GHOST_EDITOR + s_runtimeIDToTypeHandle[newID.value] = typeHandle; +#endif return newID; } diff --git a/Ghost.Entities/Entity.cs b/Ghost.Entities/Entity.cs index ae99fd2..dbbc183 100644 --- a/Ghost.Entities/Entity.cs +++ b/Ghost.Entities/Entity.cs @@ -4,7 +4,7 @@ using System.Runtime.InteropServices; namespace Ghost.Entities; [StructLayout(LayoutKind.Sequential, Size = 8)] -public readonly struct Entity : IEquatable, IComparable +public readonly record struct Entity { public const EntityID INVALID_ID = -1; @@ -41,36 +41,6 @@ public readonly struct Entity : IEquatable, IComparable _generation = generation; } - public bool Equals(Entity other) - { - return _id == other._id && _generation == other._generation; - } - - public int CompareTo(Entity other) - { - return _id.CompareTo(other._id); - } - - public override bool Equals(object? obj) - { - return obj is Entity other && Equals(other); - } - - public override int GetHashCode() - { - return _id ^ _generation << 16; - } - - public static bool operator ==(Entity left, Entity right) - { - return left.Equals(right); - } - - public static bool operator !=(Entity left, Entity right) - { - return !(left == right); - } - public override string ToString() { return $"Entity {{ Index: {ID}, Generation: {Generation} }}"; diff --git a/Ghost.Entities/EntityManager.Managed.cs b/Ghost.Entities/EntityManager.Managed.cs new file mode 100644 index 0000000..c9fc5cc --- /dev/null +++ b/Ghost.Entities/EntityManager.Managed.cs @@ -0,0 +1,197 @@ +using Misaki.HighPerformance.Collections; + +namespace Ghost.Entities; + +public partial class EntityManager +{ + private readonly SlotMap> _scriptComponents = []; + + internal SlotMap> ScriptComponents => _scriptComponents; + + /// + /// Creates a new ManagedEntity and associates it with the given Entity. + /// + /// The Entity to associate with the ManagedEntity. + /// The created ManagedEntity. + public ManagedEntity CreateManagedEntity(Entity entity) + { + var managedEntity = CreateManagedEntity(); + AddComponent(entity, new ManagedEntityRef + { + entity = managedEntity + }); + + return managedEntity; + } + + /// + /// Creates a new ManagedEntity. + /// + /// + /// You must call this if you add manually to an entity. + /// Otherwise, use . + /// + /// The created ManagedEntity. + public ManagedEntity CreateManagedEntity() + { + var id = _scriptComponents.Add(new(8), out var generation); + var managedEntity = new ManagedEntity + { + id = id, + generation = generation + }; + + return managedEntity; + } + + /// + /// Destroys the given ManagedEntity and calls OnDestroy on all associated ScriptComponents. + /// + /// The ManagedEntity to destroy. + public void DestroyManagedEntity(ManagedEntity managedEntity) + { + if (_scriptComponents.TryGetElement(managedEntity.id, managedEntity.generation, out var scripts)) + { + foreach (var script in scripts) + { + script.OnDestroy(); + } + + _scriptComponents.Remove(managedEntity.id, managedEntity.generation); + } + } + + /// + /// Checks if the given ManagedEntity exists. + /// + /// The ManagedEntity to check. + /// True if the ManagedEntity exists, false otherwise. + public bool Exists(ManagedEntity managedEntity) + { + return _scriptComponents.Contain(managedEntity.id, managedEntity.generation); + } + + /// + /// Adds a ScriptComponent of type T to the given ManagedEntity and Entity. + /// + /// The type of ScriptComponent to add. + /// The ManagedEntity to add the ScriptComponent to.The Entity associated with the ManagedEntity. + public void AddScriptComponent(ManagedEntity managedEntity, Entity entity) + where T : ScriptComponent, new() + { + if (_scriptComponents.TryGetElement(managedEntity.id, managedEntity.generation, out var scripts)) + { + var script = new T + { + _world = _world, + _entity = entity, + _managedEntity = managedEntity + }; + + scripts.Add(script); + script.OnCreate(); + + return; + } + + throw new InvalidOperationException($"ManagedEntity {managedEntity} does not exist."); + } + + /// + /// Adds a ScriptComponent of type T to the given Entity. + /// + /// The type of ScriptComponent to add. + /// The Entity to add the ScriptComponent to. + public unsafe void AddScriptComponent(Entity entity) + where T : ScriptComponent, new() + { + var location = _entityLocations.GetElementAt(entity.ID, entity.Generation); + ref var archetype = ref _world.GetArchetypeReference(location.archetypeID); + + var pManagedEntityRef = (ManagedEntityRef*)archetype.GetComponentData(location.chunkIndex, location.rowIndex, ComponentTypeID.value); + if (pManagedEntityRef == null) + { + throw new InvalidOperationException($"Entity {entity} does not have ManagedEntityRef component."); + } + + AddScriptComponent(pManagedEntityRef->entity, entity); + } + + /// + /// Destroys the ScriptComponent of type T associated with the given ManagedEntity. + /// + /// The type of ScriptComponent to destroy. + /// The ManagedEntity whose ScriptComponent is to be destroyed + /// True if the ScriptComponent was found and destroyed, false otherwise.(ManagedEntity managedEntity) + where T : ScriptComponent + { + if (_scriptComponents.TryGetElement(managedEntity.id, managedEntity.generation, out var scripts)) + { + for (var i = 0; i < scripts.Count; i++) + { + if (scripts[i] is T script) + { + script.OnDestroy(); + scripts.RemoveAt(i); + return true; + } + } + + return false; + } + + throw new InvalidOperationException($"ManagedEntity {managedEntity} does not exist."); + } + + /// + /// Checks if the given ManagedEntity has a ScriptComponent of type T. + /// + /// The type of ScriptComponent to check for. + /// The ManagedEntity to check. + /// True if the ManagedEntity has a ScriptComponent of type T, false + public bool HasScriptComponent(ManagedEntity managedEntity) + where T : ScriptComponent + { + if (_scriptComponents.TryGetElement(managedEntity.id, managedEntity.generation, out var scripts)) + { + foreach (var script in scripts) + { + if (script is T) + { + return true; + } + } + + return false; + } + + throw new InvalidOperationException($"ManagedEntity {managedEntity} does not exist."); + } + + /// + /// Gets the ScriptComponent of type T associated with the given ManagedEntity. + /// + /// The type of ScriptComponent to get. + /// The ManagedEntity whose ScriptComponent is to be retrieved + /// The ScriptComponent of type T. + public T GetScriptComponent(ManagedEntity managedEntity) + where T : ScriptComponent + { + if (_scriptComponents.TryGetElement(managedEntity.id, managedEntity.generation, out var scripts)) + { + foreach (var script in scripts) + { + if (script is T typedScript) + { + return typedScript; + } + } + + throw new InvalidOperationException($"ManagedEntity {managedEntity} does not have script component of type {typeof(T)}."); + } + + throw new InvalidOperationException($"ManagedEntity {managedEntity} does not exist."); + } +} diff --git a/Ghost.Entities/EntityManager.cs b/Ghost.Entities/EntityManager.cs index 4353de3..7aaa512 100644 --- a/Ghost.Entities/EntityManager.cs +++ b/Ghost.Entities/EntityManager.cs @@ -18,7 +18,7 @@ public unsafe partial class EntityManager : IDisposable { private struct EntityLocation { - public Identifier archetypeID; + public int archetypeID; public int chunkIndex; public int rowIndex; } @@ -209,6 +209,13 @@ public unsafe partial class EntityManager : IDisposable } ref var archetype = ref _world.GetArchetypeReference(location.archetypeID); + + var pManagedRef = archetype.GetComponentData(location.chunkIndex, location.rowIndex, ComponentTypeID.value); + if (pManagedRef != null) + { + DestroyManagedEntity(((ManagedEntityRef*)pManagedRef)->entity); + } + var r = archetype.RemoveEntity(location.chunkIndex, location.rowIndex); if (r != ErrorStatus.None) { @@ -336,9 +343,10 @@ public unsafe partial class EntityManager : IDisposable var src = oldArch._chunks[oldChunk].GetUnsafePtr() + layout.offset + (layout.size * oldRow); var r = newArch.GetLayout(layout.componentID); - Debug.Assert(r.Error == ErrorStatus.None); // This should always be true if the system is consistent. if (r.Error != ErrorStatus.None) { + // New archetype does not have this component, skip it. + // This can happen when removing components. continue; } @@ -514,6 +522,9 @@ public unsafe partial class EntityManager : IDisposable // Move entity data ref var newArchetype = ref _world.GetArchetypeReference(newArcID); newArchetype.AllocateEntity(out var newChunkIndex, out var newRowIndex); + CopyData(ref oldArchetype, location.chunkIndex, location.rowIndex, + ref newArchetype, newChunkIndex, newRowIndex); + newArchetype.SetEntity(newChunkIndex, newRowIndex, entity); var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex); @@ -523,6 +534,12 @@ public unsafe partial class EntityManager : IDisposable return r; } + var pManagedRef = oldArchetype.GetComponentData(location.chunkIndex, location.rowIndex, ComponentTypeID.value); + if (pManagedRef != null) + { + DestroyManagedEntity(((ManagedEntityRef*)pManagedRef)->entity); + } + // Update location location.archetypeID = newArcID; location.chunkIndex = newChunkIndex; @@ -697,6 +714,9 @@ 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; diff --git a/Ghost.Entities/ManagedEntity.cs b/Ghost.Entities/ManagedEntity.cs new file mode 100644 index 0000000..72cb2f5 --- /dev/null +++ b/Ghost.Entities/ManagedEntity.cs @@ -0,0 +1,74 @@ +using System.Runtime.CompilerServices; + +namespace Ghost.Entities; + +public record struct ManagedEntity +{ + public int id; + public int generation; + + public override readonly string ToString() + { + return $"ManagedEntity({id}, {generation})"; + } +} + +public struct ManagedEntityRef : IComponent +{ + public ManagedEntity entity; +} + +public abstract class ScriptComponent : IComponent +{ + internal World _world = null!; + internal Entity _entity; + internal ManagedEntity _managedEntity; + + public World World => _world; + public Entity Entity => _entity; + public ManagedEntity ManagedEntity => _managedEntity; + + protected ref T GetComponent() + where T : unmanaged, IComponent + { + ref var value = ref _world.EntityManager.GetComponent(_entity); + if (Unsafe.IsNullRef(ref value)) + { + throw new InvalidOperationException($"Entity {_entity} does not have component of type {typeof(T)}"); + } + + return ref value; + } + + public virtual void OnCreate() + { + } + + public virtual void OnDestroy() + { + } + + public virtual void OnEnable() + { + } + + public virtual void OnDisable() + { + } + + public virtual void Start() + { + } + + public virtual void Update() + { + } + + public virtual void FixedUpdate() + { + } + + public virtual void LateUpdate() + { + } +} diff --git a/Ghost.Entities/Query.cs b/Ghost.Entities/Query.cs index 2f36726..6fad2bd 100644 --- a/Ghost.Entities/Query.cs +++ b/Ghost.Entities/Query.cs @@ -84,15 +84,18 @@ public readonly unsafe ref struct ChunkView private readonly byte* _pChunkData; private readonly int _entityOffset; private readonly int _entityCount; + private readonly int _version; public readonly int Count => _entityCount; + public readonly int Version => _version; - internal ChunkView(ReadOnlyUnsafeCollection layouts, byte* pChunkData, int entityOffset, int entityCount) + internal ChunkView(ReadOnlyUnsafeCollection layouts, byte* pChunkData, int entityOffset, int entityCount, int version) { _layouts = layouts; _pChunkData = pChunkData; _entityOffset = entityOffset; _entityCount = entityCount; + _version = version; } internal ChunkView(ref readonly Archetype archetype, ref readonly Chunk chunk) @@ -100,14 +103,21 @@ public readonly unsafe ref struct ChunkView _layouts = archetype._layouts.AsReadOnly(); _pChunkData = chunk.GetUnsafePtr(); _entityOffset = archetype.EntityIDsOffset; - _entityCount = chunk.Count; + _entityCount = chunk._count; + _version = chunk._version; + } + + // TODO: We do not have a proper versioning system yet. + public bool HasChanged(int version) + { + return _version != version; } /// /// Returns a read-only span containing structuralAll entities stored in the current chunk. /// /// A read-only span of values representing the entities in the chunk. - public readonly ReadOnlySpan GetEntities() + public ReadOnlySpan GetEntities() { var pEntity = (Entity*)(_pChunkData + _entityOffset); return new ReadOnlySpan(pEntity, _entityCount); @@ -119,7 +129,7 @@ public readonly unsafe ref struct ChunkView /// The type of component to access. Must be an unmanaged type that implements . /// A span of type containing the component data for each entity in the chunk. /// Thrown if the specified component type is not present in the archetype. - public readonly Span GetComponentData() + public Span GetComponentData() where T : unmanaged, IComponent { var layout = _layouts[ComponentTypeID.value]; @@ -134,7 +144,7 @@ public readonly unsafe ref struct ChunkView /// The component type for which to retrieve enablement bits. Must be unmanaged and implement . /// A that provides access to the enablement bits for all instances of the specified component type in the chunk. /// Thrown if the specified component type does not support enablement. - public readonly SpanBitSet GetEnableBits() + public SpanBitSet GetEnableBits() where T : unmanaged, IEnableableComponent { var layout = _layouts[ComponentTypeID.value]; @@ -154,7 +164,7 @@ public readonly unsafe ref struct ChunkView /// The zero-based index of the component instance to check within the chunk. /// true if the component at the specified index is enabled; otherwise, false. /// Thrown if the specified component type does not support enable/disable functionality. - public readonly bool IsComponentEnabled(int index) + public bool IsComponentEnabled(int index) where T : unmanaged, IEnableableComponent { var layout = _layouts[ComponentTypeID.value]; diff --git a/Ghost.Entities/Templates/EntityQuery.ComponentIterator.gen.cs b/Ghost.Entities/Templates/EntityQuery.ComponentIterator.gen.cs index f2aa5ff..416517f 100644 --- a/Ghost.Entities/Templates/EntityQuery.ComponentIterator.gen.cs +++ b/Ghost.Entities/Templates/EntityQuery.ComponentIterator.gen.cs @@ -49,7 +49,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 1; index++) { @@ -65,7 +65,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -216,7 +216,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 2; index++) { @@ -232,7 +232,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -393,7 +393,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 3; index++) { @@ -409,7 +409,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -580,7 +580,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 4; index++) { @@ -596,7 +596,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -777,7 +777,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 5; index++) { @@ -793,7 +793,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -984,7 +984,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 6; index++) { @@ -1000,7 +1000,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -1201,7 +1201,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 7; index++) { @@ -1217,7 +1217,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -1428,7 +1428,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 8; index++) { @@ -1444,7 +1444,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) diff --git a/Ghost.Entities/Templates/EntityQuery.ComponentIterator.tt b/Ghost.Entities/Templates/EntityQuery.ComponentIterator.tt index 6a4eb8a..a4b7b8f 100644 --- a/Ghost.Entities/Templates/EntityQuery.ComponentIterator.tt +++ b/Ghost.Entities/Templates/EntityQuery.ComponentIterator.tt @@ -94,7 +94,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < <#= i #>; index++) { @@ -110,7 +110,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) diff --git a/Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.gen.cs b/Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.gen.cs index 0c66003..55e6534 100644 --- a/Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.gen.cs +++ b/Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.gen.cs @@ -72,7 +72,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 1; index++) { @@ -88,7 +88,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -246,7 +246,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 2; index++) { @@ -262,7 +262,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -430,7 +430,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 3; index++) { @@ -446,7 +446,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -624,7 +624,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 4; index++) { @@ -640,7 +640,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -828,7 +828,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 5; index++) { @@ -844,7 +844,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -1042,7 +1042,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 6; index++) { @@ -1058,7 +1058,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -1266,7 +1266,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 7; index++) { @@ -1282,7 +1282,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) @@ -1500,7 +1500,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < 8; index++) { @@ -1516,7 +1516,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) diff --git a/Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.tt b/Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.tt index 1bfe419..08d2aea 100644 --- a/Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.tt +++ b/Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.tt @@ -95,7 +95,7 @@ public unsafe partial struct EntityQuery { _currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex); _chunkBasePtr = _currentChunk.GetUnsafePtr(); - _currentChunkEntityCount = _currentChunk.Count; + _currentChunkEntityCount = _currentChunk._count; for (var index = 0; index < <#= i #>; index++) { @@ -111,7 +111,7 @@ public unsafe partial struct EntityQuery while (true) { _currentEntityIndex++; - if (_currentEntityIndex < _currentChunk.Count) + if (_currentEntityIndex < _currentChunk._count) { var pChunkData = _currentChunk.GetUnsafePtr(); if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask)) diff --git a/Ghost.Entities/Templates/EntityQuery.ForEach.gen.cs b/Ghost.Entities/Templates/EntityQuery.ForEach.gen.cs index f111921..d4e5437 100644 --- a/Ghost.Entities/Templates/EntityQuery.ForEach.gen.cs +++ b/Ghost.Entities/Templates/EntityQuery.ForEach.gen.cs @@ -44,7 +44,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -100,7 +100,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -158,7 +158,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -218,7 +218,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -280,7 +280,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -344,7 +344,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -410,7 +410,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -478,7 +478,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -540,7 +540,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -597,7 +597,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -656,7 +656,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -717,7 +717,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -780,7 +780,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -845,7 +845,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -912,7 +912,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { @@ -981,7 +981,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { diff --git a/Ghost.Entities/Templates/EntityQuery.ForEach.tt b/Ghost.Entities/Templates/EntityQuery.ForEach.tt index 1dbc780..c2527aa 100644 --- a/Ghost.Entities/Templates/EntityQuery.ForEach.tt +++ b/Ghost.Entities/Templates/EntityQuery.ForEach.tt @@ -61,7 +61,7 @@ public unsafe partial struct EntityQuery basePtrs[index] = pChunkData + offsets[index]; } - for (var entityIndex = 0; entityIndex < chunk.Count; entityIndex++) + for (var entityIndex = 0; entityIndex < chunk._count; entityIndex++) { if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask)) { diff --git a/Ghost.Entities/Templates/EntityQuery.JobEntity.gen.cs b/Ghost.Entities/Templates/EntityQuery.JobEntity.gen.cs index 8a369ba..3ab41ff 100644 --- a/Ghost.Entities/Templates/EntityQuery.JobEntity.gen.cs +++ b/Ghost.Entities/Templates/EntityQuery.JobEntity.gen.cs @@ -798,7 +798,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); offsets0.Add(layout0.offset); @@ -906,7 +906,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); offsets0.Add(layout0.offset); @@ -1035,7 +1035,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); offsets0.Add(layout0.offset); @@ -1185,7 +1185,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); offsets0.Add(layout0.offset); @@ -1356,7 +1356,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); offsets0.Add(layout0.offset); @@ -1548,7 +1548,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); offsets0.Add(layout0.offset); @@ -1761,7 +1761,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); offsets0.Add(layout0.offset); @@ -1995,7 +1995,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); offsets0.Add(layout0.offset); diff --git a/Ghost.Entities/Templates/EntityQuery.JobEntity.tt b/Ghost.Entities/Templates/EntityQuery.JobEntity.tt index 9b1c228..88070b9 100644 --- a/Ghost.Entities/Templates/EntityQuery.JobEntity.tt +++ b/Ghost.Entities/Templates/EntityQuery.JobEntity.tt @@ -138,7 +138,7 @@ public unsafe partial struct EntityQuery ref var chunkRef = ref arch.GetChunkReference(i); chunkList.Add((IntPtr)chunkRef.GetUnsafePtr()); - chunkEntityCounts.Add(chunkRef.Count); + chunkEntityCounts.Add(chunkRef._count); entityOffsets.Add(arch.EntityIDsOffset); <# for (var j = 0; j < i; j++){ #>