Remove old project and continue improving ecs.

Updated packages version;
Removed Ghost.SparseEntities;
Added new EntityQuery.EntityComponentIterator;
Added new thread local command buffer in World;
Changed commands in EntityCommandBuffer from UnsafeList<Command> to UnsafeList<byte> for better performance;
Changed the name of IJobEntityParallel to IJobEntity;
This commit is contained in:
2025-12-09 15:10:10 +09:00
parent 5e276b289d
commit 97d1118caa
38 changed files with 2093 additions and 5165 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,199 @@
<#@ 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;
using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
namespace Ghost.Entities;
public unsafe partial struct EntityQuery
{
<# for (var i = 1; i <= Amount; i++)
{
var generics = AppendParameters(i, "T{0}");
var compGenerics = AppendParameters(i, "ref T{0} component{0}");
var deconstrictOutPrams = AppendParameters(i, "out Ref<T{0}> component{0}");
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 2);
#>
public readonly ref struct EntityComponentIterator<<#= generics #>>
<#= restrictions #>
{
public ref struct QueryItem
{
public Entity entity;
<# for (var j = 0; j < i; j++) { #>
public ref T<#= j #> component<#= j #>;
<# } #>
internal QueryItem(Entity entity, <#= compGenerics #>)
{
this.entity = entity;
<# for (var j = 0; j < i; j++) { #>
this.component<#= j #> = ref component<#= j #>;
<# } #>
}
public void Deconstruct(out Entity entity, <#= deconstrictOutPrams #>)
{
entity = this.entity;
<# for (var j = 0; j < i; j++) { #>
component<#= j #> = new Ref<T<#= j #>>(ref this.component<#= j #>);
<# } #>
}
}
public ref struct Enumerator
{
private fixed int _compTypeIDs[<#= i #>];
private fixed int _offsets[<#= i #>];
private fixed long _compBasePtrs[<#= i #>];
private readonly ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
private readonly EntityQueryMask _mask;
private readonly World _world;
private ref Archetype _currentArchetype;
private ref Chunk _currentChunk;
private byte* _chunkBasePtr;
private int _currentChunkEntityCount;
private int _currentArchetypeIndex;
private int _currentChunkIndex;
private int _currentEntityIndex;
internal Enumerator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, EntityQueryMask mask, World world)
{
<# for (var j = 0; j < i; j++) { #>
_compTypeIDs[<#= j #>] = ComponentTypeID<T<#= j #>>.value;
_offsets[<#= j #>] = 0;
_compBasePtrs[<#= j #>] = 0;
<# } #>
_matchingArchetypes = matchingArchetypes;
_mask = mask;
_world = world;
Reset();
}
public QueryItem Current => new(
*(Entity*)(_chunkBasePtr + _currentArchetype.EntityIDsOffset + _currentEntityIndex * sizeof(Entity)),
<# for (var j = 0; j < i; j++) { #>
ref *(T<#= j #>*)(_compBasePtrs[<#= j #>] + _currentEntityIndex * sizeof(T<#= j #>))<#= j < i - 1 ? "," : "" #>
<# } #>
);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetChunk(int chunkIndex)
{
_currentChunk = ref _currentArchetype.GetChunkReference(chunkIndex);
_chunkBasePtr = _currentChunk.GetUnsafePtr();
_currentChunkEntityCount = _currentChunk.Count;
for (var index = 0; index < <#= i #>; index++)
{
var layout = _currentArchetype.GetLayout(_compTypeIDs[index])
.GetValueOrThrow(ResultStatus.Success);
_offsets[index] = layout.offset;
_compBasePtrs[index] = (long)(_chunkBasePtr + _offsets[index]);
}
}
public bool MoveNext()
{
while (true)
{
_currentEntityIndex++;
if (_currentEntityIndex < _currentChunk.Count)
{
var pChunkData = _currentChunk.GetUnsafePtr();
if (IsEntityValid(pChunkData, _currentEntityIndex, in _currentArchetype, in _mask))
{
return true;
}
continue;
}
_currentChunkIndex++;
if (!Unsafe.IsNullRef(ref _currentArchetype) && _currentChunkIndex < _currentArchetype.ChunkCount)
{
SetChunk(_currentChunkIndex);
_currentEntityIndex = -1; // Reset for new chunk
continue;
}
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
_currentEntityIndex = -1;
continue;
}
// If archetype has no chunks, loop will try next archetype
}
else
{
return false; // End of all data
}
}
}
public void Reset()
{
_currentArchetype = ref Unsafe.NullRef<Archetype>();
_currentChunk = ref Unsafe.NullRef<Chunk>();
_currentArchetypeIndex = 0;
_currentChunkIndex = 0;
_currentEntityIndex = -1;
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
}
}
}
}
private readonly ReadOnlyUnsafeCollection<Identifier<Archetype>> _matchingArchetypes;
private readonly EntityQueryMask _mask;
private readonly World _world;
internal EntityComponentIterator(ReadOnlyUnsafeCollection<Identifier<Archetype>> matchingArchetypes, EntityQueryMask mask, World world)
{
_matchingArchetypes = matchingArchetypes;
_mask = mask;
_world = world;
}
public Enumerator GetEnumerator()
{
return new Enumerator(_matchingArchetypes, _mask, _world);
}
}
public readonly EntityComponentIterator<<#= generics#>> GetEntityComponentIterator<<#= generics#>>()
<#= restrictions #>
{
return new EntityComponentIterator<<#= generics#>>(_matchingArchetypes.AsReadOnly(), _mask, World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success));
}
<# } #>
}

View File

@@ -5,14 +5,14 @@ using Misaki.HighPerformance.LowLevel.Collections;
namespace Ghost.Entities;
public interface IJobEntityParallel<T0>
public interface IJobEntity<T0>
where T0 : unmanaged, IComponent
{
void Execute(Entity entity, ref T0 component0);
}
internal unsafe struct JobEntityBatch<TJob, T0> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<T0>
where TJob : unmanaged, IJobEntity<T0>
where T0 : unmanaged, IComponent
{
public TJob userJob;
@@ -48,7 +48,7 @@ internal unsafe struct JobEntityBatch<TJob, T0> : IJobParallelFor
}
}
public interface IJobEntityParallel<T0, T1>
public interface IJobEntity<T0, T1>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
@@ -56,7 +56,7 @@ public interface IJobEntityParallel<T0, T1>
}
internal unsafe struct JobEntityBatch<TJob, T0, T1> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<T0, T1>
where TJob : unmanaged, IJobEntity<T0, T1>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
@@ -105,7 +105,7 @@ internal unsafe struct JobEntityBatch<TJob, T0, T1> : IJobParallelFor
}
}
public interface IJobEntityParallel<T0, T1, T2>
public interface IJobEntity<T0, T1, T2>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -114,7 +114,7 @@ public interface IJobEntityParallel<T0, T1, T2>
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2>
where TJob : unmanaged, IJobEntity<T0, T1, T2>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -176,7 +176,7 @@ internal unsafe struct JobEntityBatch<TJob, T0, T1, T2> : IJobParallelFor
}
}
public interface IJobEntityParallel<T0, T1, T2, T3>
public interface IJobEntity<T0, T1, T2, T3>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -186,7 +186,7 @@ public interface IJobEntityParallel<T0, T1, T2, T3>
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -261,7 +261,7 @@ internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3> : IJobParallelFor
}
}
public interface IJobEntityParallel<T0, T1, T2, T3, T4>
public interface IJobEntity<T0, T1, T2, T3, T4>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -272,7 +272,7 @@ public interface IJobEntityParallel<T0, T1, T2, T3, T4>
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3, T4>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -360,7 +360,7 @@ internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4> : IJobParallelFo
}
}
public interface IJobEntityParallel<T0, T1, T2, T3, T4, T5>
public interface IJobEntity<T0, T1, T2, T3, T4, T5>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -372,7 +372,7 @@ public interface IJobEntityParallel<T0, T1, T2, T3, T4, T5>
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3, T4, T5>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -473,7 +473,7 @@ internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5> : IJobParall
}
}
public interface IJobEntityParallel<T0, T1, T2, T3, T4, T5, T6>
public interface IJobEntity<T0, T1, T2, T3, T4, T5, T6>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -486,7 +486,7 @@ public interface IJobEntityParallel<T0, T1, T2, T3, T4, T5, T6>
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5, T6> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3, T4, T5, T6>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5, T6>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -600,7 +600,7 @@ internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5, T6> : IJobPa
}
}
public interface IJobEntityParallel<T0, T1, T2, T3, T4, T5, T6, T7>
public interface IJobEntity<T0, T1, T2, T3, T4, T5, T6, T7>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -614,7 +614,7 @@ public interface IJobEntityParallel<T0, T1, T2, T3, T4, T5, T6, T7>
}
internal unsafe struct JobEntityBatch<TJob, T0, T1, T2, T3, T4, T5, T6, T7> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3, T4, T5, T6, T7>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5, T6, T7>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -765,7 +765,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, T0>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<T0>
where TJob : unmanaged, IJobEntity<T0>
where T0 : unmanaged, IComponent
{
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);
@@ -867,7 +867,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<T0, T1>
where TJob : unmanaged, IJobEntity<T0, T1>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
{
@@ -990,7 +990,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2>
where TJob : unmanaged, IJobEntity<T0, T1, T2>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -1134,7 +1134,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -1299,7 +1299,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3, T4>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3, T4>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -1485,7 +1485,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3, T4, T5>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3, T4, T5>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -1692,7 +1692,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3, T4, T5, T6>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3, T4, T5, T6>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5, T6>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent
@@ -1920,7 +1920,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, T0, T1, T2, T3, T4, T5, T6, T7>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<T0, T1, T2, T3, T4, T5, T6, T7>
where TJob : unmanaged, IJobEntity<T0, T1, T2, T3, T4, T5, T6, T7>
where T0 : unmanaged, IComponent
where T1 : unmanaged, IComponent
where T2 : unmanaged, IComponent

View File

@@ -16,14 +16,14 @@ namespace Ghost.Entities;
var generics = AppendGenerics(i);
var restrictions = AppendGenericRestrictionsMultiline(i, "unmanaged, IComponent", 1);
#>
public interface IJobEntityParallel<<#= generics #>>
public interface IJobEntity<<#= generics #>>
<#= restrictions #>
{
void Execute(Entity entity, <#= AppendParameters(i, "ref T{0} component{0}") #>);
}
internal unsafe struct JobEntityBatch<TJob, <#= generics #>> : IJobParallelFor
where TJob : unmanaged, IJobEntityParallel<<#= generics #>>
where TJob : unmanaged, IJobEntity<<#= generics #>>
<#= restrictions #>
{
public TJob userJob;
@@ -101,7 +101,7 @@ public unsafe partial struct EntityQuery
}
public JobHandle ScheduleEntityParallel<TJob, <#= generics #>>(TJob jobData, Allocator allocator, int batchSize, JobHandle dependency)
where TJob : unmanaged, IJobEntityParallel<<#= generics #>>
where TJob : unmanaged, IJobEntity<<#= generics #>>
<#= restrictions #>
{
var world = World.GetWorld(_worldID).GetValueOrThrow(ResultStatus.Success);