feature/archetype-ecs #1
@@ -14,24 +14,29 @@ public partial class ArcEntityTest : ITest
|
|||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
var entity1 = _world.EntityManager.CreateEntity(ComponentTypeID<TransformData>.value);
|
var entity1 = _world.EntityManager.CreateEntity(ComponentTypeID<Transform>.value);
|
||||||
var mesh = new MeshData { index = 1 };
|
Console.WriteLine(entity1);
|
||||||
_world.EntityManager.AddComponent<MeshData>(entity1, ref mesh);
|
_world.EntityManager.AddComponent<Mesh>(entity1, new Mesh { index = 1 });
|
||||||
|
|
||||||
var queryID = new QueryBuilder().WithAll<TransformData>().Build(_world);
|
var queryID = new QueryBuilder().WithAll<Transform>().Build(_world);
|
||||||
ref var query = ref _world.GetEntityQueryReference(queryID);
|
ref var query = ref _world.GetEntityQueryReference(queryID);
|
||||||
|
|
||||||
foreach (var item in query)
|
foreach (var chunk in query.GetChunkIterator())
|
||||||
{
|
{
|
||||||
var transforms = item.GetComponentData<TransformData>();
|
var transforms = chunk.GetComponentData<Transform>();
|
||||||
Console.WriteLine($"Item Count: {item.Count}");
|
var entities = chunk.GetEntities();
|
||||||
for (var i = 0; i < item.Count; i++)
|
|
||||||
|
for (var i = 0; i < chunk.Count; i++)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Entity Position: {transforms[i].position}");
|
Console.WriteLine($"Entity {entities[i]} Position: {transforms[i].position}");
|
||||||
transforms[i].position = new float3(1, 2, 3);
|
transforms[i].position = new float3(1, 2, 3);
|
||||||
Console.WriteLine($"Updated Entity Position: {transforms[i].position}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query.ForEach<Transform>((e, ref t) =>
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Entity {e} Updated Position: {t.position}");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cleanup()
|
public void Cleanup()
|
||||||
@@ -40,12 +45,12 @@ public partial class ArcEntityTest : ITest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct TransformData : IComponent
|
public struct Transform : IComponent
|
||||||
{
|
{
|
||||||
public float3 position;
|
public float3 position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MeshData : IComponent
|
public struct Mesh : IComponent
|
||||||
{
|
{
|
||||||
public int index;
|
public int index;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
using Ghost.Entities.Test;
|
using Ghost.Entities.Test;
|
||||||
using Ghost.Test.Core;
|
using Ghost.Test.Core;
|
||||||
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
|
|
||||||
TestRunner.Run<ArcEntityTest>();
|
AllocationManager.EnableDebugLayer();
|
||||||
|
TestRunner.Run<ArcEntityTest>();
|
||||||
|
AllocationManager.Dispose();
|
||||||
@@ -16,21 +16,21 @@ internal unsafe struct Chunk : IDisposable
|
|||||||
|
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
get => _count;
|
readonly get => _count;
|
||||||
set => _count = value;
|
set => _count = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Capacity => _capacity;
|
public readonly int Capacity => _capacity;
|
||||||
|
|
||||||
public Chunk(int size, int capacity)
|
public Chunk(int size, int capacity)
|
||||||
{
|
{
|
||||||
_data = new UnsafeArray<byte>(size, Allocator.Persistent);
|
_data = new UnsafeArray<byte>(size, Allocator.Persistent, AllocationOption.Clear);
|
||||||
_capacity = capacity;
|
_capacity = capacity;
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public byte* GetUnsafePtr()
|
public readonly byte* GetUnsafePtr()
|
||||||
{
|
{
|
||||||
return (byte*)_data.GetUnsafePtr();
|
return (byte*)_data.GetUnsafePtr();
|
||||||
}
|
}
|
||||||
@@ -68,15 +68,16 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
private UnsafeList<Edge> _edgesAdd;
|
private UnsafeList<Edge> _edgesAdd;
|
||||||
private UnsafeList<Edge> _edgesRemove;
|
private UnsafeList<Edge> _edgesRemove;
|
||||||
|
|
||||||
private int _hash;
|
private readonly int _hash;
|
||||||
private int _entityCapacity;
|
private int _entityCapacity;
|
||||||
private int _maxComponentID;
|
private int _maxComponentID;
|
||||||
private int _entityIdsOffset;
|
private int _entityIdsOffset;
|
||||||
|
|
||||||
public Identifier<Archetype> ID => _id;
|
public readonly Identifier<Archetype> ID => _id;
|
||||||
|
|
||||||
public int EntityCapacity => _entityCapacity;
|
public readonly int EntityCapacity => _entityCapacity;
|
||||||
public int ChunkCount => _chunks.Count;
|
public readonly int ChunkCount => _chunks.Count;
|
||||||
|
public readonly int EntityIDsOffset => _entityIdsOffset;
|
||||||
|
|
||||||
public Archetype(Identifier<Archetype> id, Identifier<World> worldID, ReadOnlySpan<Identifier<IComponent>> componentIds)
|
public Archetype(Identifier<Archetype> id, Identifier<World> worldID, ReadOnlySpan<Identifier<IComponent>> componentIds)
|
||||||
{
|
{
|
||||||
@@ -204,7 +205,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < _chunks.Count; i++)
|
for (var i = 0; i < _chunks.Count; i++)
|
||||||
{
|
{
|
||||||
var chunk = _chunks[i];
|
ref var chunk = ref _chunks[i];
|
||||||
if (chunk.Count < _entityCapacity)
|
if (chunk.Count < _entityCapacity)
|
||||||
{
|
{
|
||||||
rowIndex = chunk.Count;
|
rowIndex = chunk.Count;
|
||||||
@@ -226,7 +227,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SetEntity(int chunkIndex, int rowIndex, Entity entity)
|
public readonly void SetEntity(int chunkIndex, int rowIndex, Entity entity)
|
||||||
{
|
{
|
||||||
var chunk = _chunks[chunkIndex];
|
var chunk = _chunks[chunkIndex];
|
||||||
var chunkBase = chunk.GetUnsafePtr();
|
var chunkBase = chunk.GetUnsafePtr();
|
||||||
@@ -236,7 +237,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SetComponentData(int chunkIndex, int rowIndex, Identifier<IComponent> componentID, void* pComponent)
|
public readonly void SetComponentData(int chunkIndex, int rowIndex, Identifier<IComponent> componentID, void* pComponent)
|
||||||
{
|
{
|
||||||
var offset = _componentIDToOffset[componentID];
|
var offset = _componentIDToOffset[componentID];
|
||||||
var chunk = _chunks[chunkIndex];
|
var chunk = _chunks[chunkIndex];
|
||||||
@@ -249,7 +250,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void* GetComponentDataPtr(int chunkIndex, int rowIndex, Identifier<IComponent> componentID)
|
public readonly void* GetComponentDataPtr(int chunkIndex, int rowIndex, Identifier<IComponent> componentID)
|
||||||
{
|
{
|
||||||
var offset = _componentIDToOffset[componentID];
|
var offset = _componentIDToOffset[componentID];
|
||||||
var chunk = _chunks[chunkIndex];
|
var chunk = _chunks[chunkIndex];
|
||||||
@@ -268,7 +269,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int GetOffset(int componentId)
|
public readonly int GetOffset(int componentId)
|
||||||
{
|
{
|
||||||
if (componentId >= _componentIDToOffset.Count)
|
if (componentId >= _componentIDToOffset.Count)
|
||||||
{
|
{
|
||||||
@@ -326,7 +327,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool HasComponent(Identifier<IComponent> componentID)
|
public readonly bool HasComponent(Identifier<IComponent> componentID)
|
||||||
{
|
{
|
||||||
return _signature.IsSet(componentID);
|
return _signature.IsSet(componentID);
|
||||||
}
|
}
|
||||||
@@ -342,7 +343,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Identifier<Archetype> GetEdgeAdd(Identifier<IComponent> componentID)
|
public readonly Identifier<Archetype> GetEdgeAdd(Identifier<IComponent> componentID)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < _edgesAdd.Count; i++)
|
for (var i = 0; i < _edgesAdd.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -367,7 +368,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Identifier<Archetype> GetEdgeRemove(Identifier<IComponent> componentID)
|
public readonly Identifier<Archetype> GetEdgeRemove(Identifier<IComponent> componentID)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < _edgesRemove.Count; i++)
|
for (var i = 0; i < _edgesRemove.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -382,7 +383,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Span<T> GetComponentArray<T>(int chunkIndex)
|
public readonly Span<T> GetComponentArray<T>(int chunkIndex)
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
var id = ComponentTypeID<T>.value;
|
var id = ComponentTypeID<T>.value;
|
||||||
@@ -401,7 +402,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
|||||||
return new Span<T>((T*)((byte*)chunk.GetUnsafePtr() + offset), chunk.Count);
|
return new Span<T>((T*)((byte*)chunk.GetUnsafePtr() + offset), chunk.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override readonly int GetHashCode()
|
||||||
{
|
{
|
||||||
return _hash;
|
return _hash;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public struct ComponentInfo
|
|||||||
public Identifier<IComponent> id;
|
public Identifier<IComponent> id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static unsafe class ComponentTypeID<T>
|
public static class ComponentTypeID<T>
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
public static readonly Identifier<IComponent> value = ComponentRegister.GetOrRegisterComponent<T>();
|
public static readonly Identifier<IComponent> value = ComponentRegister.GetOrRegisterComponent<T>();
|
||||||
|
|||||||
@@ -15,13 +15,19 @@ public unsafe class EntityManager : IDisposable
|
|||||||
public int rowIndex;
|
public int rowIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private World _world;
|
private readonly World _world;
|
||||||
private UnsafeSlotMap<EntityLocation> _entityLocations;
|
private UnsafeSlotMap<EntityLocation> _entityLocations;
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
internal EntityManager(World world, int initialCapacity)
|
internal EntityManager(World world, int initialCapacity)
|
||||||
{
|
{
|
||||||
_world = world;
|
_world = world;
|
||||||
_entityLocations = new UnsafeSlotMap<EntityLocation>(initialCapacity, Allocator.Persistent);
|
_entityLocations = new UnsafeSlotMap<EntityLocation>(initialCapacity, Allocator.Persistent, AllocationOption.Clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
~EntityManager()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ResultStatus UpdateEntityLocation(Entity entity, Identifier<Archetype> newArchetypeID, int newChunkIndex, int newRowIndex)
|
internal ResultStatus UpdateEntityLocation(Entity entity, Identifier<Archetype> newArchetypeID, int newChunkIndex, int newRowIndex)
|
||||||
@@ -115,8 +121,8 @@ public unsafe class EntityManager : IDisposable
|
|||||||
var layout = oldArch._layouts[i];
|
var layout = oldArch._layouts[i];
|
||||||
|
|
||||||
var src = oldArch._chunks[oldChunk].GetUnsafePtr() + layout.offset + (layout.size * oldRow);
|
var src = oldArch._chunks[oldChunk].GetUnsafePtr() + layout.offset + (layout.size * oldRow);
|
||||||
var newOffset = newArch.GetOffset(layout.componentID); // O(1) Lookup
|
var newOffset = newArch.GetOffset(layout.componentID); // O(1) Looku
|
||||||
var dst = oldArch._chunks[oldChunk].GetUnsafePtr() + newOffset + (layout.size * newRow);
|
var dst = newArch._chunks[newChunk].GetUnsafePtr() + newOffset + (layout.size * newRow);
|
||||||
|
|
||||||
MemoryUtility.MemCpy(src, dst, (nuint)layout.size);
|
MemoryUtility.MemCpy(src, dst, (nuint)layout.size);
|
||||||
}
|
}
|
||||||
@@ -217,10 +223,10 @@ public unsafe class EntityManager : IDisposable
|
|||||||
return ResultStatus.Success;
|
return ResultStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultStatus AddComponent<T>(Entity entity, ref T component)
|
public ResultStatus AddComponent<T>(Entity entity, T component)
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
return AddComponent(entity, ComponentTypeID<T>.value, UnsafeUtility.AddressOf(ref component));
|
return AddComponent(entity, ComponentTypeID<T>.value, &component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultStatus SetComponentData(Entity entity, Identifier<IComponent> componentID, void* pComponent)
|
public ResultStatus SetComponentData(Entity entity, Identifier<IComponent> componentID, void* pComponent)
|
||||||
@@ -236,10 +242,10 @@ public unsafe class EntityManager : IDisposable
|
|||||||
return ResultStatus.Success;
|
return ResultStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultStatus SetComponentData<T>(Entity entity, ref T component)
|
public ResultStatus SetComponentData<T>(Entity entity, T component)
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
return SetComponentData(entity, ComponentTypeID<T>.value, UnsafeUtility.AddressOf(ref component));
|
return SetComponentData(entity, ComponentTypeID<T>.value, &component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasComponent(Entity entity, Identifier<IComponent> componentID)
|
public bool HasComponent(Entity entity, Identifier<IComponent> componentID)
|
||||||
@@ -261,6 +267,14 @@ public unsafe class EntityManager : IDisposable
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_entityLocations.Dispose();
|
_entityLocations.Dispose();
|
||||||
|
_disposed = true;
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public unsafe class EntityQueryy<T1, T2>
|
|||||||
struct ArchetypeCache
|
struct ArchetypeCache
|
||||||
{
|
{
|
||||||
public Archetype Archetype;
|
public Archetype Archetype;
|
||||||
public int Offset1; // Offset for T1
|
public int Offset1; // Offset for T0
|
||||||
public int Offset2; // Offset for T2
|
public int Offset2; // Offset for T2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,53 @@
|
|||||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Templates\ForEach.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Templates\EntityQuery.ForEach.gen.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>EntityQuery.ForEach.tt</DependentUpon>
|
||||||
|
</None>
|
||||||
|
<None Include="Templates\ForEach.gen.cs">
|
||||||
|
<DependentUpon>ForEach.tt</DependentUpon>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ghost.Core\Ghost.Core.csproj" />
|
<ProjectReference Include="..\Ghost.Core\Ghost.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Templates\EntityQuery.ForEach.tt">
|
||||||
|
<Generator>TextTemplatingFileGenerator</Generator>
|
||||||
|
<LastGenOutput>EntityQuery.ForEach.gen.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<None Update="Templates\ForEach.tt">
|
||||||
|
<LastGenOutput>ForEach.gen.cs</LastGenOutput>
|
||||||
|
<Generator>TextTemplatingFileGenerator</Generator>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="Templates\EntityQuery.ForEach.gen.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>EntityQuery.ForEach.tt</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="Templates\ForEach.gen.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>ForEach.tt</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ghost.Entities;
|
namespace Ghost.Entities;
|
||||||
|
|
||||||
@@ -10,30 +11,15 @@ public struct EntityQueryMask : IDisposable
|
|||||||
public UnsafeBitSet any;
|
public UnsafeBitSet any;
|
||||||
public UnsafeBitSet absent;
|
public UnsafeBitSet absent;
|
||||||
|
|
||||||
public bool Matches(UnsafeBitSet archetypeSignature)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public readonly bool Matches(UnsafeBitSet archetypeSignature)
|
||||||
{
|
{
|
||||||
// 1. Check All: Archetype must have ALL bits set
|
return (!all.IsCreated || all.All(archetypeSignature))
|
||||||
if (all.IsCreated && !archetypeSignature.All(all))
|
&& (!absent.IsCreated || absent.None(archetypeSignature))
|
||||||
{
|
&& (!any.IsCreated || any.Count == 0 || any.Any(archetypeSignature));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Check None: Archetype must have NONE of these bits set
|
|
||||||
if (absent.IsCreated && archetypeSignature.Any(absent))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Check Any: Archetype must have AT LEAST ONE of these bits (if Any is defined)
|
|
||||||
if (any.IsCreated && any.Count != 0 && !archetypeSignature.Any(any))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public readonly override int GetHashCode()
|
||||||
{
|
{
|
||||||
var hash = 17;
|
var hash = 17;
|
||||||
if (all.IsCreated) hash = hash * 23 + all.GetHashCode();
|
if (all.IsCreated) hash = hash * 23 + all.GetHashCode();
|
||||||
@@ -51,90 +37,114 @@ public struct EntityQueryMask : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe struct EntityQuery : IIdentifierType, IDisposable
|
public unsafe partial struct EntityQuery : IIdentifierType, IDisposable
|
||||||
{
|
{
|
||||||
public readonly ref struct QueryItem
|
public readonly ref struct ChunkIterator
|
||||||
{
|
{
|
||||||
private readonly ref Archetype _archetype;
|
public readonly ref struct ChunkView
|
||||||
private readonly ref Chunk _chunk;
|
|
||||||
|
|
||||||
public readonly int Count => _chunk.Count;
|
|
||||||
|
|
||||||
internal QueryItem(ref Archetype archetype, int chunkIndex)
|
|
||||||
{
|
{
|
||||||
_archetype = ref archetype;
|
private readonly ref Archetype _archetype;
|
||||||
_chunk = ref archetype.GetChunkReference(chunkIndex);
|
private readonly ref Chunk _chunk;
|
||||||
}
|
|
||||||
|
|
||||||
public readonly Span<T> GetComponentData<T>()
|
public readonly int Count => _chunk.Count;
|
||||||
where T : unmanaged, IComponent
|
|
||||||
{
|
internal ChunkView(ref Archetype archetype, int chunkIndex)
|
||||||
var offset = _archetype.GetOffset(ComponentTypeID<T>.value);
|
|
||||||
if (offset < 0)
|
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Archetype does not contain component of type {typeof(T)}");
|
_archetype = ref archetype;
|
||||||
|
_chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
var ptr = (byte*)_chunk.GetUnsafePtr() + offset;
|
public readonly ReadOnlySpan<Entity> GetEntities()
|
||||||
return new Span<T>(ptr, _chunk.Count);
|
{
|
||||||
|
var ptr = _chunk.GetUnsafePtr();
|
||||||
|
var pEntity = (Entity*)(ptr + _archetype.EntityIDsOffset);
|
||||||
|
return new ReadOnlySpan<Entity>(pEntity, _chunk.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly Span<T> GetComponentData<T>()
|
||||||
|
where T : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var offset = _archetype.GetOffset(ComponentTypeID<T>.value);
|
||||||
|
if (offset < 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Archetype does not contain component of type {typeof(T)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var ptr = (byte*)_chunk.GetUnsafePtr() + offset;
|
||||||
|
return new Span<T>(ptr, _chunk.Count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public ref struct ChunkEnumerator
|
public ref struct Enumerator
|
||||||
{
|
{
|
||||||
private ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
|
private readonly ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
|
||||||
private World _world;
|
private readonly World _world;
|
||||||
private int _archetypeIndex;
|
private int _archetypeIndex;
|
||||||
private int _chunkIndex;
|
private int _chunkIndex;
|
||||||
|
|
||||||
internal ChunkEnumerator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, World world)
|
internal Enumerator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, World world)
|
||||||
|
{
|
||||||
|
_matchingArchetypes = matchingArchetypes;
|
||||||
|
_world = world;
|
||||||
|
_archetypeIndex = 0;
|
||||||
|
_chunkIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly ChunkView Current
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
ref var archetype = ref _world.GetArchetypeReference(_matchingArchetypes[_archetypeIndex]);
|
||||||
|
return new ChunkView(ref archetype, _chunkIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
_chunkIndex++;
|
||||||
|
|
||||||
|
while (_archetypeIndex < _matchingArchetypes.Count)
|
||||||
|
{
|
||||||
|
ref var archetype = ref _world.GetArchetypeReference(_matchingArchetypes[_archetypeIndex]);
|
||||||
|
if (_chunkIndex < archetype.ChunkCount)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_chunkIndex = 0;
|
||||||
|
_archetypeIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_archetypeIndex = 0;
|
||||||
|
_chunkIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
|
||||||
|
private readonly World _world;
|
||||||
|
|
||||||
|
internal ChunkIterator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, World world)
|
||||||
{
|
{
|
||||||
_matchingArchetypes = matchingArchetypes;
|
_matchingArchetypes = matchingArchetypes;
|
||||||
_world = world;
|
_world = world;
|
||||||
_archetypeIndex = 0;
|
|
||||||
_chunkIndex = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryItem Current
|
public readonly Enumerator GetEnumerator()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
ref var archetype = ref _world.GetArchetypeReference(_matchingArchetypes[_archetypeIndex]);
|
|
||||||
return new QueryItem(ref archetype, _chunkIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
_chunkIndex++;
|
|
||||||
|
|
||||||
while (_archetypeIndex < _matchingArchetypes.Count)
|
|
||||||
{
|
|
||||||
ref var archetype = ref _world.GetArchetypeReference(_matchingArchetypes[_archetypeIndex]);
|
|
||||||
if (_chunkIndex < archetype.ChunkCount)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_chunkIndex = 0;
|
|
||||||
_archetypeIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
|
||||||
{
|
|
||||||
_archetypeIndex = 0;
|
|
||||||
_chunkIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
{
|
||||||
|
return new Enumerator(_matchingArchetypes, _world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Identifier<World> _worldID;
|
private readonly Identifier<World> _worldID;
|
||||||
private EntityQueryMask _mask;
|
private EntityQueryMask _mask;
|
||||||
private UnsafeList<Identifier<Archetype>> _matchingArchetypes;
|
private UnsafeList<Identifier<Archetype>> _matchingArchetypes;
|
||||||
|
|
||||||
@@ -145,7 +155,6 @@ public unsafe struct EntityQuery : IIdentifierType, IDisposable
|
|||||||
_matchingArchetypes = new UnsafeList<Identifier<Archetype>>(8, Allocator.Persistent);
|
_matchingArchetypes = new UnsafeList<Identifier<Archetype>>(8, Allocator.Persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by World when a new archetype is created
|
|
||||||
internal void AddArchetypeIfMatch(Archetype archetype)
|
internal void AddArchetypeIfMatch(Archetype archetype)
|
||||||
{
|
{
|
||||||
if (_mask.Matches(archetype._signature))
|
if (_mask.Matches(archetype._signature))
|
||||||
@@ -154,10 +163,10 @@ public unsafe struct EntityQuery : IIdentifierType, IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChunkEnumerator GetEnumerator()
|
public readonly ChunkIterator GetChunkIterator()
|
||||||
{
|
{
|
||||||
var world = World.GetWorld(_worldID).Value;
|
var world = World.GetWorld(_worldID).Value;
|
||||||
return new ChunkEnumerator(_matchingArchetypes.AsReadOnly(), world);
|
return new ChunkIterator(_matchingArchetypes.AsReadOnly(), world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -169,7 +178,7 @@ public unsafe struct EntityQuery : IIdentifierType, IDisposable
|
|||||||
|
|
||||||
public ref struct QueryBuilder
|
public ref struct QueryBuilder
|
||||||
{
|
{
|
||||||
private Stack.Scope _scope;
|
private readonly Stack.Scope _scope;
|
||||||
|
|
||||||
private UnsafeList<Identifier<IComponent>> _all;
|
private UnsafeList<Identifier<IComponent>> _all;
|
||||||
private UnsafeList<Identifier<IComponent>> _any;
|
private UnsafeList<Identifier<IComponent>> _any;
|
||||||
@@ -244,7 +253,7 @@ public ref struct QueryBuilder
|
|||||||
return queryID;
|
return queryID;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FindMax(UnsafeList<Identifier<IComponent>> list, ref int max)
|
private static void FindMax(UnsafeList<Identifier<IComponent>> list, ref int max)
|
||||||
{
|
{
|
||||||
foreach (var id in list)
|
foreach (var id in list)
|
||||||
{
|
{
|
||||||
|
|||||||
881
Ghost.Entities/Templates/EntityQuery.ForEach.gen.cs
Normal file
881
Ghost.Entities/Templates/EntityQuery.ForEach.gen.cs
Normal file
@@ -0,0 +1,881 @@
|
|||||||
|
|
||||||
|
using Ghost.Core;
|
||||||
|
|
||||||
|
namespace Ghost.Entities;
|
||||||
|
|
||||||
|
public unsafe partial struct EntityQuery
|
||||||
|
{
|
||||||
|
public readonly void ForEach<T0>(ForEach<T0> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value };
|
||||||
|
var offsets = stackalloc int[1];
|
||||||
|
var basePtrs = stackalloc byte*[1];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 1; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 1; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
|
||||||
|
action(ref *pComp0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1>(ForEach<T0, T1> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value };
|
||||||
|
var offsets = stackalloc int[2];
|
||||||
|
var basePtrs = stackalloc byte*[2];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 2; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 2; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
|
||||||
|
action(ref *pComp0,ref *pComp1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2>(ForEach<T0, T1, T2> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value };
|
||||||
|
var offsets = stackalloc int[3];
|
||||||
|
var basePtrs = stackalloc byte*[3];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 3; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 3; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
|
||||||
|
action(ref *pComp0,ref *pComp1,ref *pComp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3>(ForEach<T0, T1, T2, T3> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value };
|
||||||
|
var offsets = stackalloc int[4];
|
||||||
|
var basePtrs = stackalloc byte*[4];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 4; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 4; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
|
||||||
|
action(ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3, T4>(ForEach<T0, T1, T2, T3, T4> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
where T4 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value };
|
||||||
|
var offsets = stackalloc int[5];
|
||||||
|
var basePtrs = stackalloc byte*[5];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 5; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 5; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
var pComp4 = (T4*)(basePtrs[4] + (sizeof(T4) * entityIndex));
|
||||||
|
|
||||||
|
action(ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3,ref *pComp4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3, T4, T5>(ForEach<T0, T1, T2, T3, T4, T5> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
where T4 : unmanaged, IComponent
|
||||||
|
where T5 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value, ComponentTypeID<T5>.value };
|
||||||
|
var offsets = stackalloc int[6];
|
||||||
|
var basePtrs = stackalloc byte*[6];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 6; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 6; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
var pComp4 = (T4*)(basePtrs[4] + (sizeof(T4) * entityIndex));
|
||||||
|
var pComp5 = (T5*)(basePtrs[5] + (sizeof(T5) * entityIndex));
|
||||||
|
|
||||||
|
action(ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3,ref *pComp4,ref *pComp5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3, T4, T5, T6>(ForEach<T0, T1, T2, T3, T4, T5, T6> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
where T4 : unmanaged, IComponent
|
||||||
|
where T5 : unmanaged, IComponent
|
||||||
|
where T6 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value, ComponentTypeID<T5>.value, ComponentTypeID<T6>.value };
|
||||||
|
var offsets = stackalloc int[7];
|
||||||
|
var basePtrs = stackalloc byte*[7];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 7; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 7; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
var pComp4 = (T4*)(basePtrs[4] + (sizeof(T4) * entityIndex));
|
||||||
|
var pComp5 = (T5*)(basePtrs[5] + (sizeof(T5) * entityIndex));
|
||||||
|
var pComp6 = (T6*)(basePtrs[6] + (sizeof(T6) * entityIndex));
|
||||||
|
|
||||||
|
action(ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3,ref *pComp4,ref *pComp5,ref *pComp6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3, T4, T5, T6, T7>(ForEach<T0, T1, T2, T3, T4, T5, T6, T7> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
where T4 : unmanaged, IComponent
|
||||||
|
where T5 : unmanaged, IComponent
|
||||||
|
where T6 : unmanaged, IComponent
|
||||||
|
where T7 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value, ComponentTypeID<T5>.value, ComponentTypeID<T6>.value, ComponentTypeID<T7>.value };
|
||||||
|
var offsets = stackalloc int[8];
|
||||||
|
var basePtrs = stackalloc byte*[8];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 8; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 8; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
var pComp4 = (T4*)(basePtrs[4] + (sizeof(T4) * entityIndex));
|
||||||
|
var pComp5 = (T5*)(basePtrs[5] + (sizeof(T5) * entityIndex));
|
||||||
|
var pComp6 = (T6*)(basePtrs[6] + (sizeof(T6) * entityIndex));
|
||||||
|
var pComp7 = (T7*)(basePtrs[7] + (sizeof(T7) * entityIndex));
|
||||||
|
|
||||||
|
action(ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3,ref *pComp4,ref *pComp5,ref *pComp6,ref *pComp7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public readonly void ForEach<T0>(ForEachWithEntity<T0> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value };
|
||||||
|
var offsets = stackalloc int[1];
|
||||||
|
var basePtrs = stackalloc byte*[1];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 1; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 1; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
|
||||||
|
action(*pEntity, ref *pComp0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1>(ForEachWithEntity<T0, T1> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value };
|
||||||
|
var offsets = stackalloc int[2];
|
||||||
|
var basePtrs = stackalloc byte*[2];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 2; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 2; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
|
||||||
|
action(*pEntity, ref *pComp0,ref *pComp1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2>(ForEachWithEntity<T0, T1, T2> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value };
|
||||||
|
var offsets = stackalloc int[3];
|
||||||
|
var basePtrs = stackalloc byte*[3];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 3; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 3; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
|
||||||
|
action(*pEntity, ref *pComp0,ref *pComp1,ref *pComp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3>(ForEachWithEntity<T0, T1, T2, T3> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value };
|
||||||
|
var offsets = stackalloc int[4];
|
||||||
|
var basePtrs = stackalloc byte*[4];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 4; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 4; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
|
||||||
|
action(*pEntity, ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3, T4>(ForEachWithEntity<T0, T1, T2, T3, T4> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
where T4 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value };
|
||||||
|
var offsets = stackalloc int[5];
|
||||||
|
var basePtrs = stackalloc byte*[5];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 5; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 5; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
var pComp4 = (T4*)(basePtrs[4] + (sizeof(T4) * entityIndex));
|
||||||
|
|
||||||
|
action(*pEntity, ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3,ref *pComp4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3, T4, T5>(ForEachWithEntity<T0, T1, T2, T3, T4, T5> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
where T4 : unmanaged, IComponent
|
||||||
|
where T5 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value, ComponentTypeID<T5>.value };
|
||||||
|
var offsets = stackalloc int[6];
|
||||||
|
var basePtrs = stackalloc byte*[6];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 6; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 6; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
var pComp4 = (T4*)(basePtrs[4] + (sizeof(T4) * entityIndex));
|
||||||
|
var pComp5 = (T5*)(basePtrs[5] + (sizeof(T5) * entityIndex));
|
||||||
|
|
||||||
|
action(*pEntity, ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3,ref *pComp4,ref *pComp5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3, T4, T5, T6>(ForEachWithEntity<T0, T1, T2, T3, T4, T5, T6> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
where T4 : unmanaged, IComponent
|
||||||
|
where T5 : unmanaged, IComponent
|
||||||
|
where T6 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value, ComponentTypeID<T5>.value, ComponentTypeID<T6>.value };
|
||||||
|
var offsets = stackalloc int[7];
|
||||||
|
var basePtrs = stackalloc byte*[7];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 7; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 7; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
var pComp4 = (T4*)(basePtrs[4] + (sizeof(T4) * entityIndex));
|
||||||
|
var pComp5 = (T5*)(basePtrs[5] + (sizeof(T5) * entityIndex));
|
||||||
|
var pComp6 = (T6*)(basePtrs[6] + (sizeof(T6) * entityIndex));
|
||||||
|
|
||||||
|
action(*pEntity, ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3,ref *pComp4,ref *pComp5,ref *pComp6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly void ForEach<T0, T1, T2, T3, T4, T5, T6, T7>(ForEachWithEntity<T0, T1, T2, T3, T4, T5, T6, T7> action)
|
||||||
|
where T0 : unmanaged, IComponent
|
||||||
|
where T1 : unmanaged, IComponent
|
||||||
|
where T2 : unmanaged, IComponent
|
||||||
|
where T3 : unmanaged, IComponent
|
||||||
|
where T4 : unmanaged, IComponent
|
||||||
|
where T5 : unmanaged, IComponent
|
||||||
|
where T6 : unmanaged, IComponent
|
||||||
|
where T7 : unmanaged, IComponent
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value, ComponentTypeID<T5>.value, ComponentTypeID<T6>.value, ComponentTypeID<T7>.value };
|
||||||
|
var offsets = stackalloc int[8];
|
||||||
|
var basePtrs = stackalloc byte*[8];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < 8; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < 8; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
var pComp0 = (T0*)(basePtrs[0] + (sizeof(T0) * entityIndex));
|
||||||
|
var pComp1 = (T1*)(basePtrs[1] + (sizeof(T1) * entityIndex));
|
||||||
|
var pComp2 = (T2*)(basePtrs[2] + (sizeof(T2) * entityIndex));
|
||||||
|
var pComp3 = (T3*)(basePtrs[3] + (sizeof(T3) * entityIndex));
|
||||||
|
var pComp4 = (T4*)(basePtrs[4] + (sizeof(T4) * entityIndex));
|
||||||
|
var pComp5 = (T5*)(basePtrs[5] + (sizeof(T5) * entityIndex));
|
||||||
|
var pComp6 = (T6*)(basePtrs[6] + (sizeof(T6) * entityIndex));
|
||||||
|
var pComp7 = (T7*)(basePtrs[7] + (sizeof(T7) * entityIndex));
|
||||||
|
|
||||||
|
action(*pEntity, ref *pComp0,ref *pComp1,ref *pComp2,ref *pComp3,ref *pComp4,ref *pComp5,ref *pComp6,ref *pComp7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
127
Ghost.Entities/Templates/EntityQuery.ForEach.tt
Normal file
127
Ghost.Entities/Templates/EntityQuery.ForEach.tt
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<#@ template language="C#" #>
|
||||||
|
<#@ output extension="gen.cs" #>
|
||||||
|
<#@ assembly name="System.Core" #>
|
||||||
|
<#@ import namespace="System.Linq" #>
|
||||||
|
<#@ import namespace="System.Text" #>
|
||||||
|
<#@ include file="Helpers.ttinclude" #>
|
||||||
|
using Ghost.Core;
|
||||||
|
|
||||||
|
namespace Ghost.Entities;
|
||||||
|
|
||||||
|
public unsafe partial struct EntityQuery
|
||||||
|
{
|
||||||
|
<# for (var i = 1; i <= Amount; i++)
|
||||||
|
{
|
||||||
|
var generics = AppendGenerics(i);
|
||||||
|
var compGenerics = AppendGenericRefParameters(i);
|
||||||
|
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2);
|
||||||
|
#>
|
||||||
|
public readonly void ForEach<<#= generics #>>(ForEach<<#= generics #>> action)
|
||||||
|
<#= restrictions #>
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { <#= AppendGenerics(i, "ComponentTypeID<T{0}>.value") #> };
|
||||||
|
var offsets = stackalloc int[<#= i #>];
|
||||||
|
var basePtrs = stackalloc byte*[<#= i #>];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < <#= i #>; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < <#= i #>; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
<# for (var localIndex = 0; localIndex < i; localIndex++) { #>
|
||||||
|
var pComp<#= localIndex #> = (T<#= localIndex #>*)(basePtrs[<#= localIndex #>] + (sizeof(T<#= localIndex #>) * entityIndex));
|
||||||
|
<# } #>
|
||||||
|
|
||||||
|
action(<#= AppendRefParameters(i, "*pComp{0}") #>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<# } #>
|
||||||
|
|
||||||
|
<# for (var i = 1; i <= Amount; i++)
|
||||||
|
{
|
||||||
|
var generics = AppendGenerics(i);
|
||||||
|
var compGenerics = AppendGenericRefParameters(i);
|
||||||
|
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2);
|
||||||
|
#>
|
||||||
|
public readonly void ForEach<<#= generics #>>(ForEachWithEntity<<#= generics #>> action)
|
||||||
|
<#= restrictions #>
|
||||||
|
{
|
||||||
|
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
|
||||||
|
|
||||||
|
var compTypeIDs = stackalloc int[] { <#= AppendGenerics(i, "ComponentTypeID<T{0}>.value") #> };
|
||||||
|
var offsets = stackalloc int[<#= i #>];
|
||||||
|
var basePtrs = stackalloc byte*[<#= i #>];
|
||||||
|
|
||||||
|
foreach (var archetypeID in _matchingArchetypes)
|
||||||
|
{
|
||||||
|
ref var archetype = ref world.GetArchetypeReference(archetypeID);
|
||||||
|
var hasAllComponents = true;
|
||||||
|
for (var index = 0; index < <#= i #>; index++)
|
||||||
|
{
|
||||||
|
offsets[index] = archetype.GetOffset(compTypeIDs[index]);
|
||||||
|
if (offsets[index] == -1)
|
||||||
|
{
|
||||||
|
hasAllComponents = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasAllComponents)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var chunkIndex = 0; chunkIndex < archetype.ChunkCount; chunkIndex++)
|
||||||
|
{
|
||||||
|
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||||
|
var count = chunk.Count;
|
||||||
|
for (var index = 0; index < <#= i #>; index++)
|
||||||
|
{
|
||||||
|
basePtrs[index] = chunk.GetUnsafePtr() + offsets[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entityIndex = 0; entityIndex < count; entityIndex++)
|
||||||
|
{
|
||||||
|
var pEntity = (Entity*)(chunk.GetUnsafePtr() + archetype.EntityIDsOffset + (sizeof(Entity) * entityIndex));
|
||||||
|
<# for (var localIndex = 0; localIndex < i; localIndex++) { #>
|
||||||
|
var pComp<#= localIndex #> = (T<#= localIndex #>*)(basePtrs[<#= localIndex #>] + (sizeof(T<#= localIndex #>) * entityIndex));
|
||||||
|
<# } #>
|
||||||
|
|
||||||
|
action(*pEntity, <#= AppendRefParameters(i, "*pComp{0}") #>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<# } #>
|
||||||
|
}
|
||||||
21
Ghost.Entities/Templates/ForEach.gen.cs
Normal file
21
Ghost.Entities/Templates/ForEach.gen.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
namespace Ghost.Entities;
|
||||||
|
|
||||||
|
public delegate void ForEach<T0>(ref T0 t0Component);
|
||||||
|
public delegate void ForEach<T0, T1>(ref T0 t0Component,ref T1 t1Component);
|
||||||
|
public delegate void ForEach<T0, T1, T2>(ref T0 t0Component,ref T1 t1Component,ref T2 t2Component);
|
||||||
|
public delegate void ForEach<T0, T1, T2, T3>(ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component);
|
||||||
|
public delegate void ForEach<T0, T1, T2, T3, T4>(ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component);
|
||||||
|
public delegate void ForEach<T0, T1, T2, T3, T4, T5>(ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component);
|
||||||
|
public delegate void ForEach<T0, T1, T2, T3, T4, T5, T6>(ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component);
|
||||||
|
public delegate void ForEach<T0, T1, T2, T3, T4, T5, T6, T7>(ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component);
|
||||||
|
|
||||||
|
public delegate void ForEachWithEntity<T0>(Entity entity, ref T0 t0Component);
|
||||||
|
public delegate void ForEachWithEntity<T0, T1>(Entity entity, ref T0 t0Component,ref T1 t1Component);
|
||||||
|
public delegate void ForEachWithEntity<T0, T1, T2>(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component);
|
||||||
|
public delegate void ForEachWithEntity<T0, T1, T2, T3>(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component);
|
||||||
|
public delegate void ForEachWithEntity<T0, T1, T2, T3, T4>(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component);
|
||||||
|
public delegate void ForEachWithEntity<T0, T1, T2, T3, T4, T5>(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component);
|
||||||
|
public delegate void ForEachWithEntity<T0, T1, T2, T3, T4, T5, T6>(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component);
|
||||||
|
public delegate void ForEachWithEntity<T0, T1, T2, T3, T4, T5, T6, T7>(Entity entity, ref T0 t0Component,ref T1 t1Component,ref T2 t2Component,ref T3 t3Component,ref T4 t4Component,ref T5 t5Component,ref T6 t6Component,ref T7 t7Component);
|
||||||
24
Ghost.Entities/Templates/ForEach.tt
Normal file
24
Ghost.Entities/Templates/ForEach.tt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<#@ template language="C#" #>
|
||||||
|
<#@ output extension="gen.cs" #>
|
||||||
|
<#@ assembly name="System.Core" #>
|
||||||
|
<#@ import namespace="System.Linq" #>
|
||||||
|
<#@ import namespace="System.Text" #>
|
||||||
|
<#@ include file="Helpers.ttinclude" #>
|
||||||
|
|
||||||
|
namespace Ghost.Entities;
|
||||||
|
|
||||||
|
<# for (var i = 1; i <= Amount; i++)
|
||||||
|
{
|
||||||
|
var generics = AppendGenerics(i);
|
||||||
|
var compGenerics = AppendGenericRefParameters(i);
|
||||||
|
#>
|
||||||
|
public delegate void ForEach<<#= generics #>>(<#= compGenerics #>);
|
||||||
|
<# } #>
|
||||||
|
|
||||||
|
<# for (var i = 1; i <= Amount; i++)
|
||||||
|
{
|
||||||
|
var generics = AppendGenerics(i);
|
||||||
|
var compGenerics = AppendGenericRefParameters(i);
|
||||||
|
#>
|
||||||
|
public delegate void ForEachWithEntity<<#= generics #>>(Entity entity, <#= compGenerics #>);
|
||||||
|
<# } #>
|
||||||
149
Ghost.Entities/Templates/Helpers.ttinclude
Normal file
149
Ghost.Entities/Templates/Helpers.ttinclude
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
<#@ import namespace="System.Text" #>
|
||||||
|
<#@ import namespace="System.Collections.Generic" #>
|
||||||
|
<#+
|
||||||
|
|
||||||
|
public int Amount = 8;
|
||||||
|
public int ExtensionAmount = 3;
|
||||||
|
|
||||||
|
public string Indent(StringBuilder sb, int spaces)
|
||||||
|
{
|
||||||
|
var indent = new string(' ', spaces);
|
||||||
|
return sb.ToString().Replace("\n", "\n" + indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
string AppendGenerics(int amount, string template)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (var i = 0; i < amount; i++)
|
||||||
|
{
|
||||||
|
if (i > 0) sb.Append(", ");
|
||||||
|
sb.Append(string.Format(template, i));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
string AppendGenerics(int amount)
|
||||||
|
{
|
||||||
|
return AppendGenerics(amount, "T{0}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder AppendGenericRefParameters(int amount)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (var localIndex = 0; localIndex < amount; localIndex++)
|
||||||
|
{
|
||||||
|
sb.Append($"ref T{localIndex} t{localIndex}Component,");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Length--;
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder AppendRefParameters(int amount, string template)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (var localIndex = 0; localIndex < amount; localIndex++)
|
||||||
|
{
|
||||||
|
sb.Append($"ref {string.Format(template, localIndex)},");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Length--;
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder AppendGenericRestrictions(int amount, string Ttemplate, string template)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (var localIndex = 0; localIndex < amount; localIndex++)
|
||||||
|
{
|
||||||
|
sb.Append($"where {Ttemplate}{localIndex} : {template}");
|
||||||
|
if (localIndex < amount - 1)
|
||||||
|
{
|
||||||
|
sb.Append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder AppendGenericRestrictions(int amount, string template)
|
||||||
|
{
|
||||||
|
return AppendGenericRestrictions(amount, "T", template);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder AppendGenericRestrictionsMultiline(int amount, string Ttemplate, string template, int indentation)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var spaces = new string(' ', indentation * 4);
|
||||||
|
|
||||||
|
for (var localIndex = 0; localIndex < amount; localIndex++)
|
||||||
|
{
|
||||||
|
sb.Append($"{spaces}where {Ttemplate}{localIndex} : {template}");
|
||||||
|
if (localIndex < amount - 1)
|
||||||
|
{
|
||||||
|
sb.AppendLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder AppendGenericRestrictionsMultiline(int amount, string template, int indentation)
|
||||||
|
{
|
||||||
|
return AppendGenericRestrictionsMultiline(amount, "T", template, indentation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder TryGetComponentPools(int amount)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (var localIndex = 0; localIndex < amount; localIndex++)
|
||||||
|
{
|
||||||
|
sb.Append($"_componentStorage.TryGetPool<T{localIndex}>(out var pool{localIndex})");
|
||||||
|
if (localIndex < amount - 1)
|
||||||
|
{
|
||||||
|
sb.Append(" && ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder HasEntity(int amount)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (var localIndex = 1; localIndex < amount; localIndex++)
|
||||||
|
{
|
||||||
|
sb.Append($"pool{localIndex}.Has(entity)");
|
||||||
|
if (localIndex < amount - 1)
|
||||||
|
{
|
||||||
|
sb.Append(" && ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder GetComponent(int amount)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (var localIndex = 0; localIndex < amount; localIndex++)
|
||||||
|
{
|
||||||
|
sb.Append($"pool{localIndex}.GetRef(entity)");
|
||||||
|
if (localIndex < amount - 1)
|
||||||
|
{
|
||||||
|
sb.Append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder GetComponentRef(int amount)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (var localIndex = 0; localIndex < amount; localIndex++)
|
||||||
|
{
|
||||||
|
sb.Append($"ref pool{localIndex}.GetRef(entity)");
|
||||||
|
if (localIndex < amount - 1)
|
||||||
|
{
|
||||||
|
sb.Append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
#>
|
||||||
@@ -196,6 +196,16 @@ public partial class World : IIdentifierType, IDisposable, IEquatable<World>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var archetype in _archetypes)
|
||||||
|
{
|
||||||
|
archetype.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var query in _entityQueries)
|
||||||
|
{
|
||||||
|
query.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
_entityManager.Dispose();
|
_entityManager.Dispose();
|
||||||
_entityCommandBuffer.Dispose();
|
_entityCommandBuffer.Dispose();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<#@ import namespace="System.Text" #>
|
<#@ import namespace="System.Text" #>
|
||||||
<#@ import namespace="System.Collections.Generic" #>
|
<#@ import namespace="System.Collections.Generic" #>
|
||||||
<#+
|
<#+
|
||||||
|
|
||||||
@@ -17,14 +17,14 @@
|
|||||||
for (var i = 0; i < amount; i++)
|
for (var i = 0; i < amount; i++)
|
||||||
{
|
{
|
||||||
if (i > 0) sb.Append(", ");
|
if (i > 0) sb.Append(", ");
|
||||||
sb.Append($"{template}{i}");
|
sb.Append(string.Format(template, i));
|
||||||
}
|
}
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
string AppendGenerics(int amount)
|
string AppendGenerics(int amount)
|
||||||
{
|
{
|
||||||
return AppendGenerics(amount, "T");
|
return AppendGenerics(amount, "T{0}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBuilder AppendGenericRefParameters(int amount)
|
public StringBuilder AppendGenericRefParameters(int amount)
|
||||||
|
|||||||
Reference in New Issue
Block a user