forked from Misaki/GhostEngine
Refactor ECS framework and improve performance
Refactored `ArcEntityTest` to use updated `Transform` and `Mesh` components, improving query logic with `GetChunkIterator` and introducing `ForEach` methods for better modularity. Enhanced `Chunk` and `Archetype` structs with `readonly` properties and memory optimizations. Fixed bugs in memory copy logic and entity relocation. Improved `EntityManager` with proper disposal handling, added a destructor, and fixed pointer usage in `AddComponent` and `SetComponentData`. Refactored `EntityQuery` to use `ChunkIterator` and `ChunkView` for better abstraction. Simplified `EntityQueryMask` logic for performance. Introduced templated `ForEach` methods and `ForEachWithEntity` methods, dynamically generated using T4 templates for scalability. Added disposal logic for archetypes and queries in `World`. Updated `Program.cs` to include memory debugging setup. Integrated T4 templates for dynamic code generation and added helper functions for template generation. Updated project file to include templates and generated outputs. General improvements include enforcing immutability, optimizing memory management, and adding debugging/logging for better traceability.
This commit is contained in:
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;
|
||||
}
|
||||
#>
|
||||
Reference in New Issue
Block a user