forked from Misaki/GhostEngine
Add managed entity and script component.
Added ManagedEntity and related methods in EntityManager; Added ScriptComponent to write game play logic in oop;
This commit is contained in:
@@ -5,7 +5,6 @@ public interface IIdentifierType;
|
|||||||
public interface IKeyType;
|
public interface IKeyType;
|
||||||
|
|
||||||
public readonly struct Handle<T> : IEquatable<Handle<T>>
|
public readonly struct Handle<T> : IEquatable<Handle<T>>
|
||||||
where T : IHandleType
|
|
||||||
{
|
{
|
||||||
public readonly int id;
|
public readonly int id;
|
||||||
public readonly int generation;
|
public readonly int generation;
|
||||||
@@ -58,7 +57,6 @@ public readonly struct Handle<T> : IEquatable<Handle<T>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public readonly struct Identifier<T> : IEquatable<Identifier<T>>
|
public readonly struct Identifier<T> : IEquatable<Identifier<T>>
|
||||||
where T : IIdentifierType
|
|
||||||
{
|
{
|
||||||
public readonly int value;
|
public readonly int value;
|
||||||
|
|
||||||
@@ -132,7 +130,6 @@ public readonly struct Identifier<T> : IEquatable<Identifier<T>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public readonly struct Key<T>
|
public readonly struct Key<T>
|
||||||
where T : IKeyType
|
|
||||||
{
|
{
|
||||||
public readonly ulong value;
|
public readonly ulong value;
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,12 @@ public partial class EntityTest : ITest
|
|||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
var entity1 = _world.EntityManager.CreateEntity(ComponentTypeID<Transform>.value);
|
var entity1 = _world.EntityManager.CreateEntity(ComponentTypeID<Transform>.value, ComponentTypeID<ManagedEntityRef>.value);
|
||||||
_world.EntityManager.AddComponent(entity1, new Mesh { index = 1 });
|
_world.EntityManager.AddComponent(entity1, new Mesh { index = 1 });
|
||||||
|
_world.EntityManager.SetComponent(entity1, new ManagedEntityRef
|
||||||
|
{
|
||||||
|
entity = _world.EntityManager.CreateManagedEntity()
|
||||||
|
});
|
||||||
|
|
||||||
var entity2 = _world.EntityManager.CreateEntity(ComponentTypeID<Transform>.value);
|
var entity2 = _world.EntityManager.CreateEntity(ComponentTypeID<Transform>.value);
|
||||||
_world.EntityManager.SetComponent(entity2, new Transform { position = new float3(1, 2, 3) });
|
_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<Transform>().Build(_world);
|
var queryID = new QueryBuilder().WithAll<Transform>().Build(_world);
|
||||||
ref var query = ref _world.GetEntityQueryReference(queryID);
|
ref var query = ref _world.GetEntityQueryReference(queryID);
|
||||||
|
|
||||||
var testJob = new TestEntityQueryJob();
|
// var testJob = new TestEntityQueryJob();
|
||||||
var handle = query.ScheduleChunkParallel(testJob, 64, JobHandle.Invalid);
|
// var handle = query.ScheduleChunkParallel(testJob, 64, JobHandle.Invalid);
|
||||||
_jobScheduler.WaitComplete(handle);
|
// _jobScheduler.WaitComplete(handle);
|
||||||
|
|
||||||
|
_world.EntityManager.AddScriptComponent<TestScriptComponent>(entity1);
|
||||||
|
_world.EntityManager.RemoveComponent<ManagedEntityRef>(entity1); // This should destory the managed entity and call OnDestroy
|
||||||
|
|
||||||
query.ForEach<Transform>((e, ref t) =>
|
query.ForEach<Transform>((e, ref t) =>
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Entity {e} Has Position: {t.position}");
|
Console.WriteLine($"Entity {e} Has Position: {t.position}");
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var (entity, transform) in query.GetEntityComponentIterator<Transform>())
|
// foreach (var (entity, transform) in query.GetEntityComponentIterator<Transform>())
|
||||||
{
|
// {
|
||||||
Console.WriteLine($"Entity {entity} Updated Position: {transform.Get().position}");
|
// Console.WriteLine($"Entity {entity} Updated Position: {transform.Get().position}");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// foreach (var chunk in query.GetChunkIterator())
|
||||||
|
// {
|
||||||
|
// var transforms = chunk.GetComponentData<Transform>();
|
||||||
|
// var entities = chunk.GetEntities();
|
||||||
|
// var bits = chunk.GetEnableBits<Transform>();
|
||||||
|
//
|
||||||
|
// 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())
|
_world.EntityManager.DestroyEntity(entity1);
|
||||||
{
|
_world.EntityManager.DestroyEntity(entity2);
|
||||||
var transforms = chunk.GetComponentData<Transform>();
|
|
||||||
var entities = chunk.GetEntities();
|
|
||||||
var bits = chunk.GetEnableBits<Transform>();
|
|
||||||
|
|
||||||
var it = bits.GetIterator();
|
|
||||||
while (it.Next(out var index) && index < chunk.Count)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Entity {entities[index]} Updated Position: {transforms[index].position}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cleanup()
|
public void Cleanup()
|
||||||
@@ -83,3 +93,18 @@ public struct Mesh : IComponent
|
|||||||
{
|
{
|
||||||
public int index;
|
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>();
|
||||||
|
transform.position += new float3(0, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnDestroy()
|
||||||
|
{
|
||||||
|
Console.WriteLine($"TestScriptComponent OnDestroy called for Entity {Entity}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,32 +2,126 @@ using Ghost.Core;
|
|||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ghost.Entities;
|
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<object>();
|
||||||
|
#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<T>(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<T>(basePtr + (i * sizeOfT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DebuggerTypeProxy(typeof(ChunkDebugView))]
|
||||||
internal unsafe struct Chunk : IDisposable
|
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_ALIGNMENT = 8;
|
||||||
public const int BIT_SHIFT = 3; // log2(BIT_ALIGNMENT)
|
public const int BIT_SHIFT = 3; // log2(BIT_ALIGNMENT)
|
||||||
public const int BIT_ALIGNMENT_MINUS_ONE = BIT_ALIGNMENT - 1;
|
public const int BIT_ALIGNMENT_MINUS_ONE = BIT_ALIGNMENT - 1;
|
||||||
|
|
||||||
private UnsafeArray<byte> _data;
|
private UnsafeArray<byte> _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;
|
_data = new UnsafeArray<byte>(bufferSize, Allocator.Persistent, AllocationOption.Clear);
|
||||||
set => _count = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly int Capacity => _capacity;
|
|
||||||
|
|
||||||
public Chunk(int size, int capacity)
|
|
||||||
{
|
|
||||||
_data = new UnsafeArray<byte>(size, Allocator.Persistent, AllocationOption.Clear);
|
|
||||||
_capacity = capacity;
|
_capacity = capacity;
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
@@ -60,9 +154,6 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
public int targetArchetype; // can't use Identifier<Archetype> because cycle causer
|
public int targetArchetype; // can't use Identifier<Archetype> because cycle causer
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Identifier<Archetype> _id;
|
|
||||||
private readonly Identifier<World> _worldID;
|
|
||||||
|
|
||||||
internal UnsafeBitSet _signature;
|
internal UnsafeBitSet _signature;
|
||||||
internal UnsafeList<Chunk> _chunks;
|
internal UnsafeList<Chunk> _chunks;
|
||||||
internal UnsafeArray<ComponentMemoryLayout> _layouts;
|
internal UnsafeArray<ComponentMemoryLayout> _layouts;
|
||||||
@@ -72,6 +163,9 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
private UnsafeList<Edge> _edgesAdd;
|
private UnsafeList<Edge> _edgesAdd;
|
||||||
private UnsafeList<Edge> _edgesRemove;
|
private UnsafeList<Edge> _edgesRemove;
|
||||||
|
|
||||||
|
private readonly Identifier<Archetype> _id;
|
||||||
|
private readonly Identifier<World> _worldID;
|
||||||
|
|
||||||
private readonly int _hash;
|
private readonly int _hash;
|
||||||
private int _entityCapacity;
|
private int _entityCapacity;
|
||||||
private int _maxComponentID;
|
private int _maxComponentID;
|
||||||
@@ -98,7 +192,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
_hash = 0;
|
_hash = 0;
|
||||||
|
|
||||||
_signature.ClearAll();
|
_signature.ClearAll();
|
||||||
_entityCapacity = Chunk.CHUNK_SIZE / sizeof(Entity);
|
_entityCapacity = Chunk.CHUNK_BUFFER_SIZE / sizeof(Entity);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -144,7 +238,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
_maxComponentID = maxComponentID;
|
_maxComponentID = maxComponentID;
|
||||||
_entityCapacity = Chunk.CHUNK_SIZE / bytesPerEntity;
|
_entityCapacity = Chunk.CHUNK_BUFFER_SIZE / bytesPerEntity;
|
||||||
_layouts = new UnsafeArray<ComponentMemoryLayout>(components.Length, Allocator.Persistent);
|
_layouts = new UnsafeArray<ComponentMemoryLayout>(components.Length, Allocator.Persistent);
|
||||||
_componentIDToLayoutIndex = new UnsafeArray<int>(_maxComponentID + 1, Allocator.Persistent);
|
_componentIDToLayoutIndex = new UnsafeArray<int>(_maxComponentID + 1, Allocator.Persistent);
|
||||||
|
|
||||||
@@ -186,7 +280,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
|
|
||||||
tempBitmaskOffsets[i] = bitmaskOffset;
|
tempBitmaskOffsets[i] = bitmaskOffset;
|
||||||
|
|
||||||
if (currentOffset > Chunk.CHUNK_SIZE)
|
if (currentOffset > Chunk.CHUNK_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
fits = false;
|
fits = false;
|
||||||
break;
|
break;
|
||||||
@@ -220,10 +314,10 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
for (var i = 0; i < _chunks.Count; i++)
|
for (var i = 0; i < _chunks.Count; i++)
|
||||||
{
|
{
|
||||||
ref var chunk = ref _chunks[i];
|
ref var chunk = ref _chunks[i];
|
||||||
if (chunk.Count < _entityCapacity)
|
if (chunk._count < _entityCapacity)
|
||||||
{
|
{
|
||||||
rowIndex = chunk.Count;
|
rowIndex = chunk._count;
|
||||||
chunk.Count++;
|
chunk._count++;
|
||||||
chunkIndex = i;
|
chunkIndex = i;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -231,7 +325,11 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Need to allocate a new chunk
|
// 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
|
// Set all enable to true by default for enableable components
|
||||||
for (var i = 0; i < _layouts.Count; i++)
|
for (var i = 0; i < _layouts.Count; i++)
|
||||||
@@ -246,7 +344,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
rowIndex = 0;
|
rowIndex = 0;
|
||||||
newChunk.Count++;
|
newChunk._count++;
|
||||||
chunkIndex = _chunks.Count;
|
chunkIndex = _chunks.Count;
|
||||||
|
|
||||||
_chunks.Add(newChunk);
|
_chunks.Add(newChunk);
|
||||||
@@ -331,7 +429,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
ref var chunk = ref _chunks[chunkIndex];
|
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 we are NOT removing the very last entity, we must swap.
|
||||||
if (rowIndex != lastIndex)
|
if (rowIndex != lastIndex)
|
||||||
@@ -366,7 +464,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chunk.Count--;
|
chunk._count--;
|
||||||
return ErrorStatus.None;
|
return ErrorStatus.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,11 @@ internal static class ComponentRegister
|
|||||||
private static int s_nextComponentTypeID = 0;
|
private static int s_nextComponentTypeID = 0;
|
||||||
|
|
||||||
private static readonly List<ComponentInfo> s_registeredComponents = new();
|
private static readonly List<ComponentInfo> s_registeredComponents = new();
|
||||||
private static readonly Dictionary<IntPtr, Identifier<IComponent>> s_typeHandleToID = new();
|
private static readonly Dictionary<IntPtr, int> s_typeHandleToID = new();
|
||||||
private static readonly Dictionary<string, Identifier<IComponent>> s_nameToRuntimeID = new();
|
private static readonly Dictionary<string, int> s_nameToRuntimeID = new();
|
||||||
|
#if DEBUG || GHOST_EDITOR
|
||||||
|
internal static readonly Dictionary<int, IntPtr> s_runtimeIDToTypeHandle = new();
|
||||||
|
#endif
|
||||||
|
|
||||||
public static unsafe Identifier<IComponent> GetOrRegisterComponent<T>()
|
public static unsafe Identifier<IComponent> GetOrRegisterComponent<T>()
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
@@ -66,6 +69,9 @@ internal static class ComponentRegister
|
|||||||
|
|
||||||
s_typeHandleToID[typeHandle] = newID;
|
s_typeHandleToID[typeHandle] = newID;
|
||||||
s_nameToRuntimeID[stableName] = newID;
|
s_nameToRuntimeID[stableName] = newID;
|
||||||
|
#if DEBUG || GHOST_EDITOR
|
||||||
|
s_runtimeIDToTypeHandle[newID.value] = typeHandle;
|
||||||
|
#endif
|
||||||
|
|
||||||
return newID;
|
return newID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
|
|||||||
namespace Ghost.Entities;
|
namespace Ghost.Entities;
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 8)]
|
[StructLayout(LayoutKind.Sequential, Size = 8)]
|
||||||
public readonly struct Entity : IEquatable<Entity>, IComparable<Entity>
|
public readonly record struct Entity
|
||||||
{
|
{
|
||||||
public const EntityID INVALID_ID = -1;
|
public const EntityID INVALID_ID = -1;
|
||||||
|
|
||||||
@@ -41,36 +41,6 @@ public readonly struct Entity : IEquatable<Entity>, IComparable<Entity>
|
|||||||
_generation = generation;
|
_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()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"Entity {{ Index: {ID}, Generation: {Generation} }}";
|
return $"Entity {{ Index: {ID}, Generation: {Generation} }}";
|
||||||
|
|||||||
197
Ghost.Entities/EntityManager.Managed.cs
Normal file
197
Ghost.Entities/EntityManager.Managed.cs
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
using Misaki.HighPerformance.Collections;
|
||||||
|
|
||||||
|
namespace Ghost.Entities;
|
||||||
|
|
||||||
|
public partial class EntityManager
|
||||||
|
{
|
||||||
|
private readonly SlotMap<List<ScriptComponent>> _scriptComponents = [];
|
||||||
|
|
||||||
|
internal SlotMap<List<ScriptComponent>> ScriptComponents => _scriptComponents;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new ManagedEntity and associates it with the given Entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">The Entity to associate with the ManagedEntity.</param>
|
||||||
|
/// <returns>The created ManagedEntity.</returns>
|
||||||
|
public ManagedEntity CreateManagedEntity(Entity entity)
|
||||||
|
{
|
||||||
|
var managedEntity = CreateManagedEntity();
|
||||||
|
AddComponent(entity, new ManagedEntityRef
|
||||||
|
{
|
||||||
|
entity = managedEntity
|
||||||
|
});
|
||||||
|
|
||||||
|
return managedEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new ManagedEntity.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// You must call this if you add <see cref="ManagedEntityRef"/> manually to an entity.
|
||||||
|
/// Otherwise, use <see cref="CreateManagedEntity(Entity)"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>The created ManagedEntity.</returns>
|
||||||
|
public ManagedEntity CreateManagedEntity()
|
||||||
|
{
|
||||||
|
var id = _scriptComponents.Add(new(8), out var generation);
|
||||||
|
var managedEntity = new ManagedEntity
|
||||||
|
{
|
||||||
|
id = id,
|
||||||
|
generation = generation
|
||||||
|
};
|
||||||
|
|
||||||
|
return managedEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Destroys the given ManagedEntity and calls OnDestroy on all associated ScriptComponents.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="managedEntity">The ManagedEntity to destroy.</param>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the given ManagedEntity exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="managedEntity">The ManagedEntity to check.</param>
|
||||||
|
/// <returns>True if the ManagedEntity exists, false otherwise.</returns>
|
||||||
|
public bool Exists(ManagedEntity managedEntity)
|
||||||
|
{
|
||||||
|
return _scriptComponents.Contain(managedEntity.id, managedEntity.generation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a ScriptComponent of type T to the given ManagedEntity and Entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of ScriptComponent to add.</typeparam>
|
||||||
|
/// <param name="managedEntity">The ManagedEntity to add the ScriptComponent to.</
|
||||||
|
/// <param name="entity">The Entity associated with the ManagedEntity.</param>
|
||||||
|
public void AddScriptComponent<T>(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.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a ScriptComponent of type T to the given Entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of ScriptComponent to add.</typeparam>
|
||||||
|
/// <param name="entity">The Entity to add the ScriptComponent to.</param>
|
||||||
|
public unsafe void AddScriptComponent<T>(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<ManagedEntityRef>.value);
|
||||||
|
if (pManagedEntityRef == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Entity {entity} does not have ManagedEntityRef component.");
|
||||||
|
}
|
||||||
|
|
||||||
|
AddScriptComponent<T>(pManagedEntityRef->entity, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Destroys the ScriptComponent of type T associated with the given ManagedEntity.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of ScriptComponent to destroy.</typeparam>
|
||||||
|
/// <param name="managedEntity">The ManagedEntity whose ScriptComponent is to be destroyed </param>
|
||||||
|
/// <returns>True if the ScriptComponent was found and destroyed, false otherwise.</returns
|
||||||
|
public bool DestroyScriptComponent<T>(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.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the given ManagedEntity has a ScriptComponent of type T.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of ScriptComponent to check for.</typeparam>
|
||||||
|
/// <param name="managedEntity">The ManagedEntity to check.</param>
|
||||||
|
/// <returns>True if the ManagedEntity has a ScriptComponent of type T, false </returns>
|
||||||
|
public bool HasScriptComponent<T>(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.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ScriptComponent of type T associated with the given ManagedEntity.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of ScriptComponent to get.</typeparam>
|
||||||
|
/// <param name="managedEntity">The ManagedEntity whose ScriptComponent is to be retrieved
|
||||||
|
/// <returns>The ScriptComponent of type T.</returns>
|
||||||
|
public T GetScriptComponent<T>(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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
{
|
{
|
||||||
private struct EntityLocation
|
private struct EntityLocation
|
||||||
{
|
{
|
||||||
public Identifier<Archetype> archetypeID;
|
public int archetypeID;
|
||||||
public int chunkIndex;
|
public int chunkIndex;
|
||||||
public int rowIndex;
|
public int rowIndex;
|
||||||
}
|
}
|
||||||
@@ -209,6 +209,13 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
ref var archetype = ref _world.GetArchetypeReference(location.archetypeID);
|
ref var archetype = ref _world.GetArchetypeReference(location.archetypeID);
|
||||||
|
|
||||||
|
var pManagedRef = archetype.GetComponentData(location.chunkIndex, location.rowIndex, ComponentTypeID<ManagedEntityRef>.value);
|
||||||
|
if (pManagedRef != null)
|
||||||
|
{
|
||||||
|
DestroyManagedEntity(((ManagedEntityRef*)pManagedRef)->entity);
|
||||||
|
}
|
||||||
|
|
||||||
var r = archetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
var r = archetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
||||||
if (r != ErrorStatus.None)
|
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 src = oldArch._chunks[oldChunk].GetUnsafePtr() + layout.offset + (layout.size * oldRow);
|
||||||
var r = newArch.GetLayout(layout.componentID);
|
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)
|
if (r.Error != ErrorStatus.None)
|
||||||
{
|
{
|
||||||
|
// New archetype does not have this component, skip it.
|
||||||
|
// This can happen when removing components.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,6 +522,9 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
// Move entity data
|
// Move entity data
|
||||||
ref var newArchetype = ref _world.GetArchetypeReference(newArcID);
|
ref var newArchetype = ref _world.GetArchetypeReference(newArcID);
|
||||||
newArchetype.AllocateEntity(out var newChunkIndex, out var newRowIndex);
|
newArchetype.AllocateEntity(out var newChunkIndex, out var newRowIndex);
|
||||||
|
CopyData(ref oldArchetype, location.chunkIndex, location.rowIndex,
|
||||||
|
ref newArchetype, newChunkIndex, newRowIndex);
|
||||||
|
|
||||||
newArchetype.SetEntity(newChunkIndex, newRowIndex, entity);
|
newArchetype.SetEntity(newChunkIndex, newRowIndex, entity);
|
||||||
|
|
||||||
var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
||||||
@@ -523,6 +534,12 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pManagedRef = oldArchetype.GetComponentData(location.chunkIndex, location.rowIndex, ComponentTypeID<ManagedEntityRef>.value);
|
||||||
|
if (pManagedRef != null)
|
||||||
|
{
|
||||||
|
DestroyManagedEntity(((ManagedEntityRef*)pManagedRef)->entity);
|
||||||
|
}
|
||||||
|
|
||||||
// Update location
|
// Update location
|
||||||
location.archetypeID = newArcID;
|
location.archetypeID = newArcID;
|
||||||
location.chunkIndex = newChunkIndex;
|
location.chunkIndex = newChunkIndex;
|
||||||
@@ -697,6 +714,9 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
return;
|
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();
|
_entityLocations.Dispose();
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
|
||||||
|
|||||||
74
Ghost.Entities/ManagedEntity.cs
Normal file
74
Ghost.Entities/ManagedEntity.cs
Normal file
@@ -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<T>()
|
||||||
|
where T : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
ref var value = ref _world.EntityManager.GetComponent<T>(_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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -84,15 +84,18 @@ public readonly unsafe ref struct ChunkView
|
|||||||
private readonly byte* _pChunkData;
|
private readonly byte* _pChunkData;
|
||||||
private readonly int _entityOffset;
|
private readonly int _entityOffset;
|
||||||
private readonly int _entityCount;
|
private readonly int _entityCount;
|
||||||
|
private readonly int _version;
|
||||||
|
|
||||||
public readonly int Count => _entityCount;
|
public readonly int Count => _entityCount;
|
||||||
|
public readonly int Version => _version;
|
||||||
|
|
||||||
internal ChunkView(ReadOnlyUnsafeCollection<Archetype.ComponentMemoryLayout> layouts, byte* pChunkData, int entityOffset, int entityCount)
|
internal ChunkView(ReadOnlyUnsafeCollection<Archetype.ComponentMemoryLayout> layouts, byte* pChunkData, int entityOffset, int entityCount, int version)
|
||||||
{
|
{
|
||||||
_layouts = layouts;
|
_layouts = layouts;
|
||||||
_pChunkData = pChunkData;
|
_pChunkData = pChunkData;
|
||||||
_entityOffset = entityOffset;
|
_entityOffset = entityOffset;
|
||||||
_entityCount = entityCount;
|
_entityCount = entityCount;
|
||||||
|
_version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ChunkView(ref readonly Archetype archetype, ref readonly Chunk chunk)
|
internal ChunkView(ref readonly Archetype archetype, ref readonly Chunk chunk)
|
||||||
@@ -100,14 +103,21 @@ public readonly unsafe ref struct ChunkView
|
|||||||
_layouts = archetype._layouts.AsReadOnly();
|
_layouts = archetype._layouts.AsReadOnly();
|
||||||
_pChunkData = chunk.GetUnsafePtr();
|
_pChunkData = chunk.GetUnsafePtr();
|
||||||
_entityOffset = archetype.EntityIDsOffset;
|
_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a read-only span containing structuralAll entities stored in the current chunk.
|
/// Returns a read-only span containing structuralAll entities stored in the current chunk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A read-only span of <see cref="Entity"/> values representing the entities in the chunk.</returns>
|
/// <returns>A read-only span of <see cref="Entity"/> values representing the entities in the chunk.</returns>
|
||||||
public readonly ReadOnlySpan<Entity> GetEntities()
|
public ReadOnlySpan<Entity> GetEntities()
|
||||||
{
|
{
|
||||||
var pEntity = (Entity*)(_pChunkData + _entityOffset);
|
var pEntity = (Entity*)(_pChunkData + _entityOffset);
|
||||||
return new ReadOnlySpan<Entity>(pEntity, _entityCount);
|
return new ReadOnlySpan<Entity>(pEntity, _entityCount);
|
||||||
@@ -119,7 +129,7 @@ public readonly unsafe ref struct ChunkView
|
|||||||
/// <typeparam name="T">The type of component to access. Must be an unmanaged type that implements <see cref="Component"/>.</typeparam>
|
/// <typeparam name="T">The type of component to access. Must be an unmanaged type that implements <see cref="Component"/>.</typeparam>
|
||||||
/// <returns>A span of type <see cref="{T}"/> containing the component data for each entity in the chunk.</returns>
|
/// <returns>A span of type <see cref="{T}"/> containing the component data for each entity in the chunk.</returns>
|
||||||
/// <exception cref="InvalidOperationException">Thrown if the specified component type is not present in the archetype.</exception>
|
/// <exception cref="InvalidOperationException">Thrown if the specified component type is not present in the archetype.</exception>
|
||||||
public readonly Span<T> GetComponentData<T>()
|
public Span<T> GetComponentData<T>()
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
var layout = _layouts[ComponentTypeID<T>.value];
|
var layout = _layouts[ComponentTypeID<T>.value];
|
||||||
@@ -134,7 +144,7 @@ public readonly unsafe ref struct ChunkView
|
|||||||
/// <typeparam name="T">The component type for which to retrieve enablement bits. Must be unmanaged and implement <see cref="IEnableableComponent"/>.</typeparam>
|
/// <typeparam name="T">The component type for which to retrieve enablement bits. Must be unmanaged and implement <see cref="IEnableableComponent"/>.</typeparam>
|
||||||
/// <returns>A <see cref="SpanBitSet"/> that provides access to the enablement bits for all instances of the specified component type in the chunk.</returns>
|
/// <returns>A <see cref="SpanBitSet"/> that provides access to the enablement bits for all instances of the specified component type in the chunk.</returns>
|
||||||
/// <exception cref="InvalidOperationException">Thrown if the specified component type does not support enablement.</exception>
|
/// <exception cref="InvalidOperationException">Thrown if the specified component type does not support enablement.</exception>
|
||||||
public readonly SpanBitSet GetEnableBits<T>()
|
public SpanBitSet GetEnableBits<T>()
|
||||||
where T : unmanaged, IEnableableComponent
|
where T : unmanaged, IEnableableComponent
|
||||||
{
|
{
|
||||||
var layout = _layouts[ComponentTypeID<T>.value];
|
var layout = _layouts[ComponentTypeID<T>.value];
|
||||||
@@ -154,7 +164,7 @@ public readonly unsafe ref struct ChunkView
|
|||||||
/// <param name="index">The zero-based index of the component instance to check within the chunk.</param>
|
/// <param name="index">The zero-based index of the component instance to check within the chunk.</param>
|
||||||
/// <returns>true if the component at the specified index is enabled; otherwise, false.</returns>
|
/// <returns>true if the component at the specified index is enabled; otherwise, false.</returns>
|
||||||
/// <exception cref="InvalidOperationException">Thrown if the specified component type <typeparamref name="T"/> does not support enable/disable functionality.</exception>
|
/// <exception cref="InvalidOperationException">Thrown if the specified component type <typeparamref name="T"/> does not support enable/disable functionality.</exception>
|
||||||
public readonly bool IsComponentEnabled<T>(int index)
|
public bool IsComponentEnabled<T>(int index)
|
||||||
where T : unmanaged, IEnableableComponent
|
where T : unmanaged, IEnableableComponent
|
||||||
{
|
{
|
||||||
var layout = _layouts[ComponentTypeID<T>.value];
|
var layout = _layouts[ComponentTypeID<T>.value];
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 1; index++)
|
for (var index = 0; index < 1; index++)
|
||||||
{
|
{
|
||||||
@@ -65,7 +65,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -216,7 +216,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 2; index++)
|
for (var index = 0; index < 2; index++)
|
||||||
{
|
{
|
||||||
@@ -232,7 +232,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -393,7 +393,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 3; index++)
|
for (var index = 0; index < 3; index++)
|
||||||
{
|
{
|
||||||
@@ -409,7 +409,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -580,7 +580,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 4; index++)
|
for (var index = 0; index < 4; index++)
|
||||||
{
|
{
|
||||||
@@ -596,7 +596,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -777,7 +777,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 5; index++)
|
for (var index = 0; index < 5; index++)
|
||||||
{
|
{
|
||||||
@@ -793,7 +793,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -984,7 +984,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 6; index++)
|
for (var index = 0; index < 6; index++)
|
||||||
{
|
{
|
||||||
@@ -1000,7 +1000,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -1201,7 +1201,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 7; index++)
|
for (var index = 0; index < 7; index++)
|
||||||
{
|
{
|
||||||
@@ -1217,7 +1217,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -1428,7 +1428,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 8; index++)
|
for (var index = 0; index < 8; index++)
|
||||||
{
|
{
|
||||||
@@ -1444,7 +1444,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < <#= i #>; index++)
|
for (var index = 0; index < <#= i #>; index++)
|
||||||
{
|
{
|
||||||
@@ -110,7 +110,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 1; index++)
|
for (var index = 0; index < 1; index++)
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -246,7 +246,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 2; index++)
|
for (var index = 0; index < 2; index++)
|
||||||
{
|
{
|
||||||
@@ -262,7 +262,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -430,7 +430,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 3; index++)
|
for (var index = 0; index < 3; index++)
|
||||||
{
|
{
|
||||||
@@ -446,7 +446,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -624,7 +624,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 4; index++)
|
for (var index = 0; index < 4; index++)
|
||||||
{
|
{
|
||||||
@@ -640,7 +640,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -828,7 +828,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 5; index++)
|
for (var index = 0; index < 5; index++)
|
||||||
{
|
{
|
||||||
@@ -844,7 +844,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -1042,7 +1042,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 6; index++)
|
for (var index = 0; index < 6; index++)
|
||||||
{
|
{
|
||||||
@@ -1058,7 +1058,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -1266,7 +1266,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 7; index++)
|
for (var index = 0; index < 7; index++)
|
||||||
{
|
{
|
||||||
@@ -1282,7 +1282,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
@@ -1500,7 +1500,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < 8; index++)
|
for (var index = 0; index < 8; index++)
|
||||||
{
|
{
|
||||||
@@ -1516,7 +1516,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public unsafe partial struct EntityQuery
|
|||||||
{
|
{
|
||||||
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
|
||||||
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
_chunkBasePtr = _currentChunk.GetUnsafePtr();
|
||||||
_currentChunkEntityCount = _currentChunk.Count;
|
_currentChunkEntityCount = _currentChunk._count;
|
||||||
|
|
||||||
for (var index = 0; index < <#= i #>; index++)
|
for (var index = 0; index < <#= i #>; index++)
|
||||||
{
|
{
|
||||||
@@ -111,7 +111,7 @@ public unsafe partial struct EntityQuery
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
_currentEntityIndex++;
|
_currentEntityIndex++;
|
||||||
if (_currentEntityIndex < _currentChunk.Count)
|
if (_currentEntityIndex < _currentChunk._count)
|
||||||
{
|
{
|
||||||
var pChunkData = _currentChunk.GetUnsafePtr();
|
var pChunkData = _currentChunk.GetUnsafePtr();
|
||||||
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -100,7 +100,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -158,7 +158,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -218,7 +218,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -280,7 +280,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -344,7 +344,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -410,7 +410,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -478,7 +478,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -540,7 +540,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -597,7 +597,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -656,7 +656,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -717,7 +717,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -780,7 +780,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -845,7 +845,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -912,7 +912,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
@@ -981,7 +981,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public unsafe partial struct EntityQuery
|
|||||||
basePtrs[index] = pChunkData + offsets[index];
|
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))
|
if (!IsEntityValid(pChunkData, entityIndex, in archetype, in _mask))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -798,7 +798,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
offsets0.Add(layout0.offset);
|
offsets0.Add(layout0.offset);
|
||||||
@@ -906,7 +906,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
offsets0.Add(layout0.offset);
|
offsets0.Add(layout0.offset);
|
||||||
@@ -1035,7 +1035,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
offsets0.Add(layout0.offset);
|
offsets0.Add(layout0.offset);
|
||||||
@@ -1185,7 +1185,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
offsets0.Add(layout0.offset);
|
offsets0.Add(layout0.offset);
|
||||||
@@ -1356,7 +1356,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
offsets0.Add(layout0.offset);
|
offsets0.Add(layout0.offset);
|
||||||
@@ -1548,7 +1548,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
offsets0.Add(layout0.offset);
|
offsets0.Add(layout0.offset);
|
||||||
@@ -1761,7 +1761,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
offsets0.Add(layout0.offset);
|
offsets0.Add(layout0.offset);
|
||||||
@@ -1995,7 +1995,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
offsets0.Add(layout0.offset);
|
offsets0.Add(layout0.offset);
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public unsafe partial struct EntityQuery
|
|||||||
ref var chunkRef = ref arch.GetChunkReference(i);
|
ref var chunkRef = ref arch.GetChunkReference(i);
|
||||||
|
|
||||||
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
chunkList.Add((IntPtr)chunkRef.GetUnsafePtr());
|
||||||
chunkEntityCounts.Add(chunkRef.Count);
|
chunkEntityCounts.Add(chunkRef._count);
|
||||||
entityOffsets.Add(arch.EntityIDsOffset);
|
entityOffsets.Add(arch.EntityIDsOffset);
|
||||||
|
|
||||||
<# for (var j = 0; j < i; j++){ #>
|
<# for (var j = 0; j < i; j++){ #>
|
||||||
|
|||||||
Reference in New Issue
Block a user