forked from Misaki/GhostEngine
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:
1610
Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.gen.cs
Normal file
1610
Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.gen.cs
Normal file
File diff suppressed because it is too large
Load Diff
199
Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.tt
Normal file
199
Ghost.Entities/Templates/EntityQuery.EntityComponentIterator.tt
Normal 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));
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user