forked from Misaki/GhostEngine
Per-component versioning and change tracking for ECS
Introduce per-component versioning in chunks and world for efficient change detection. - Add version arrays to chunks and global version to world. - Update queries and ForEach to mark written components as changed. - Extend QueryBuilder with WithAllRW/WithPresentRW for write access. - Expose change tracking API in ChunkView. - Improve thread safety and debug code. - Update tests and examples to demonstrate new features.
This commit is contained in:
@@ -39,7 +39,7 @@ public partial class EntityTest : ITest
|
||||
var entity2 = _world.EntityManager.CreateEntity(ComponentTypeID<Transform>.value);
|
||||
_world.EntityManager.SetComponent(entity2, new Transform { position = new float3(1, 2, 3) });
|
||||
|
||||
var queryID = new QueryBuilder().WithAll<Transform>().Build(_world);
|
||||
var queryID = new QueryBuilder().WithAllRW<Transform>().WithAbsent<Mesh>().Build(_world);
|
||||
ref var query = ref _world.GetEntityQueryReference(queryID);
|
||||
|
||||
// var testJob = new TestEntityQueryJob();
|
||||
@@ -49,28 +49,32 @@ public partial class EntityTest : ITest
|
||||
_world.EntityManager.AddScriptComponent<TestScriptComponent>(entity1);
|
||||
_world.EntityManager.RemoveComponent<ManagedEntityRef>(entity1); // This should destory the managed entity and call OnDestroy
|
||||
|
||||
_world.AdvanceVersion();
|
||||
|
||||
query.ForEach<Transform>((e, ref t) =>
|
||||
{
|
||||
Console.WriteLine($"Entity {e} Has Position: {t.position}");
|
||||
});
|
||||
|
||||
// foreach (var (entity, transform) in query.GetEntityComponentIterator<Transform>())
|
||||
// {
|
||||
//foreach (var (entity, transform) in query.GetEntityComponentIterator<Transform>())
|
||||
//{
|
||||
// Console.WriteLine($"Entity {entity} Updated Position: {transform.Get().position}");
|
||||
// }
|
||||
//
|
||||
// foreach (var chunk in query.GetChunkIterator())
|
||||
// {
|
||||
// var transforms = chunk.GetComponentData<Transform>();
|
||||
// var entities = chunk.GetEntities();
|
||||
// var bits = chunk.GetEnableBits<Transform>();
|
||||
//
|
||||
// var it = bits.GetIterator();
|
||||
// while (it.Next(out var index) && index < chunk.Count)
|
||||
// {
|
||||
// Console.WriteLine($"Entity {entities[index]} Updated Position: {transforms[index].position}");
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
foreach (var chunk in query.GetChunkIterator())
|
||||
{
|
||||
var transforms = chunk.GetComponentData<Transform>();
|
||||
var entities = chunk.GetEntities();
|
||||
var bits = chunk.GetEnableBits<Transform>();
|
||||
|
||||
var changed = chunk.HasChanged<Transform>(0);
|
||||
|
||||
var it = bits.GetIterator();
|
||||
while (it.Next(out var index) && index < chunk.Count)
|
||||
{
|
||||
Console.WriteLine($"Entity {entities[index]} Updated Position: {transforms[index].position}");
|
||||
}
|
||||
}
|
||||
|
||||
_world.EntityManager.DestroyEntity(entity1);
|
||||
_world.EntityManager.DestroyEntity(entity2);
|
||||
|
||||
@@ -48,7 +48,7 @@ internal unsafe sealed class ChunkDebugView
|
||||
{
|
||||
get
|
||||
{
|
||||
#if DEBUG || GHOST_EDITOR
|
||||
#if !(DEBUG || GHOST_EDITOR)
|
||||
#else
|
||||
if (count == 0)
|
||||
#endif
|
||||
@@ -56,9 +56,7 @@ internal unsafe sealed class ChunkDebugView
|
||||
return [];
|
||||
}
|
||||
|
||||
#pragma warning disable CS0162 // Unreachable code detected
|
||||
var views = new List<object>();
|
||||
#pragma warning restore CS0162 // Unreachable code detected
|
||||
ref var archetype = ref World.GetWorld(worldID).GetValueOrThrow()
|
||||
.GetArchetypeReference(archetypeID);
|
||||
|
||||
@@ -108,8 +106,8 @@ internal unsafe struct Chunk : IDisposable
|
||||
public const int BIT_ALIGNMENT_MINUS_ONE = BIT_ALIGNMENT - 1;
|
||||
|
||||
private UnsafeArray<byte> _data;
|
||||
private UnsafeArray<int> _versions;
|
||||
|
||||
internal int _version;
|
||||
internal int _count;
|
||||
internal readonly int _capacity;
|
||||
|
||||
@@ -119,11 +117,26 @@ internal unsafe struct Chunk : IDisposable
|
||||
internal int _archetypeID;
|
||||
#endif
|
||||
|
||||
public Chunk(int bufferSize, int capacity)
|
||||
public Chunk(int bufferSize, int capacity, int componentCount, int globalVersion)
|
||||
{
|
||||
_data = new UnsafeArray<byte>(bufferSize, Allocator.Persistent, AllocationOption.Clear);
|
||||
_versions = new UnsafeArray<int>(componentCount, Allocator.Persistent);
|
||||
_capacity = capacity;
|
||||
_count = 0;
|
||||
|
||||
_versions.AsSpan().Fill(globalVersion);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void MarkChanged(int componentTypeId, int globalVersion)
|
||||
{
|
||||
_versions[componentTypeId] = globalVersion;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly int GetVersion(int componentTypeId)
|
||||
{
|
||||
return _versions[componentTypeId];
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -132,9 +145,16 @@ internal unsafe struct Chunk : IDisposable
|
||||
return (byte*)_data.GetUnsafePtr();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly int* GetVersionUnsafePtr()
|
||||
{
|
||||
return (int*)_versions.GetUnsafePtr();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_data.Dispose();
|
||||
_versions.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,8 +344,10 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
|
||||
// Need to allocate a new chunk
|
||||
var newChunk = new Chunk(Chunk.CHUNK_BUFFER_SIZE, _entityCapacity);
|
||||
var newChunk = new Chunk(Chunk.CHUNK_BUFFER_SIZE, _entityCapacity, _layouts.Count, world.Version);
|
||||
#if DEBUG || GHOST_EDITOR
|
||||
newChunk._worldID = _worldID;
|
||||
newChunk._archetypeID = _id;
|
||||
@@ -370,7 +392,7 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
||||
}
|
||||
|
||||
var offset = r.Value.offset;
|
||||
var chunk = _chunks[chunkIndex];
|
||||
ref var chunk = ref _chunks[chunkIndex];
|
||||
|
||||
var chunkBase = chunk.GetUnsafePtr();
|
||||
var size = ComponentRegister.GetComponentInfo(componentID).size;
|
||||
@@ -378,6 +400,9 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
||||
|
||||
MemoryUtility.MemCpy(dst, pComponent, (nuint)size);
|
||||
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
chunk.MarkChanged(componentID, world.Version);
|
||||
|
||||
return ErrorStatus.None;
|
||||
}
|
||||
|
||||
@@ -438,13 +463,8 @@ internal unsafe struct Archetype : IIdentifierType, IDisposable
|
||||
var pLastEntity = chunkBase + _entityIdsOffset + (sizeof(Entity) * lastIndex);
|
||||
var pRowEntity = chunkBase + _entityIdsOffset + (sizeof(Entity) * rowIndex);
|
||||
|
||||
var wroldResult = World.GetWorld(_worldID);
|
||||
if (wroldResult.Error != ErrorStatus.None)
|
||||
{
|
||||
return wroldResult.Error;
|
||||
}
|
||||
|
||||
var result = wroldResult.Value.EntityManager.UpdateEntityLocation(*(Entity*)pLastEntity, _id, chunkIndex, rowIndex);
|
||||
var wrold = World.GetWorldUncheck(_worldID);
|
||||
var result = wrold.EntityManager.UpdateEntityLocation(*(Entity*)pLastEntity, _id, chunkIndex, rowIndex);
|
||||
if (result != ErrorStatus.None)
|
||||
{
|
||||
return result;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Ghost.Core;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ghost.Entities;
|
||||
|
||||
@@ -18,6 +19,7 @@ public struct ComponentInfo
|
||||
public Identifier<IComponent> id;
|
||||
public int size;
|
||||
public int alignment;
|
||||
public int lastWriteVersion;
|
||||
public bool isEnableable;
|
||||
}
|
||||
|
||||
@@ -77,6 +79,7 @@ internal static class ComponentRegister
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Identifier<IComponent> GetComponentID(Type type)
|
||||
{
|
||||
var typeHandle = type.TypeHandle.Value;
|
||||
@@ -91,10 +94,25 @@ internal static class ComponentRegister
|
||||
throw new KeyNotFoundException($"Component type {type} is not registered.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ComponentInfo GetComponentInfo(Identifier<IComponent> typeId)
|
||||
{
|
||||
lock (s_registeredComponents)
|
||||
{
|
||||
return s_registeredComponents[typeId];
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void SetComponentLastWrite(Identifier<IComponent> typeId, int version)
|
||||
{
|
||||
lock (s_registeredComponents)
|
||||
{
|
||||
var info = s_registeredComponents[typeId];
|
||||
info.lastWriteVersion = version;
|
||||
s_registeredComponents[typeId] = info;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetHashCode(params ReadOnlySpan<Identifier<IComponent>> componentTypeIDs)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ghost.Entities;
|
||||
|
||||
public struct EntityQueryMask : IDisposable, IEquatable<EntityQueryMask>
|
||||
internal struct EntityQueryMask : IDisposable, IEquatable<EntityQueryMask>
|
||||
{
|
||||
public UnsafeBitSet structuralAll;
|
||||
public UnsafeBitSet structuralAny;
|
||||
@@ -15,6 +15,8 @@ public struct EntityQueryMask : IDisposable, IEquatable<EntityQueryMask>
|
||||
public UnsafeBitSet requireDisabled;
|
||||
public UnsafeBitSet rejectIfEnabled;
|
||||
|
||||
public UnsafeBitSet writeAccess;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly bool Matches(ref readonly UnsafeBitSet archetypeSignature)
|
||||
{
|
||||
@@ -33,6 +35,7 @@ public struct EntityQueryMask : IDisposable, IEquatable<EntityQueryMask>
|
||||
if (requireEnabled.IsCreated) hash = hash * 23 + requireEnabled.GetHashCode();
|
||||
if (requireDisabled.IsCreated) hash = hash * 23 + requireDisabled.GetHashCode();
|
||||
if (rejectIfEnabled.IsCreated) hash = hash * 23 + rejectIfEnabled.GetHashCode();
|
||||
if (writeAccess.IsCreated) hash = hash * 23 + writeAccess.GetHashCode();
|
||||
|
||||
return hash;
|
||||
}
|
||||
@@ -44,7 +47,8 @@ public struct EntityQueryMask : IDisposable, IEquatable<EntityQueryMask>
|
||||
&& structuralAbsent.Equals(other.structuralAbsent)
|
||||
&& requireEnabled.Equals(other.requireEnabled)
|
||||
&& requireDisabled.Equals(other.requireDisabled)
|
||||
&& rejectIfEnabled.Equals(other.rejectIfEnabled);
|
||||
&& rejectIfEnabled.Equals(other.rejectIfEnabled)
|
||||
&& writeAccess.Equals(other.writeAccess);
|
||||
}
|
||||
|
||||
public override readonly bool Equals(object? obj)
|
||||
@@ -71,6 +75,8 @@ public struct EntityQueryMask : IDisposable, IEquatable<EntityQueryMask>
|
||||
requireEnabled.Dispose();
|
||||
requireDisabled.Dispose();
|
||||
rejectIfEnabled.Dispose();
|
||||
|
||||
writeAccess.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,21 +88,11 @@ public readonly unsafe ref struct ChunkView
|
||||
{
|
||||
private readonly ReadOnlyUnsafeCollection<Archetype.ComponentMemoryLayout> _layouts;
|
||||
private readonly byte* _pChunkData;
|
||||
private readonly int* _pVersion;
|
||||
private readonly int _entityOffset;
|
||||
private readonly int _entityCount;
|
||||
private readonly int _version;
|
||||
|
||||
public readonly int Count => _entityCount;
|
||||
public readonly int Version => _version;
|
||||
|
||||
internal ChunkView(ReadOnlyUnsafeCollection<Archetype.ComponentMemoryLayout> layouts, byte* pChunkData, int entityOffset, int entityCount, int version)
|
||||
{
|
||||
_layouts = layouts;
|
||||
_pChunkData = pChunkData;
|
||||
_entityOffset = entityOffset;
|
||||
_entityCount = entityCount;
|
||||
_version = version;
|
||||
}
|
||||
|
||||
internal ChunkView(ref readonly Archetype archetype, ref readonly Chunk chunk)
|
||||
{
|
||||
@@ -104,19 +100,63 @@ public readonly unsafe ref struct ChunkView
|
||||
_pChunkData = chunk.GetUnsafePtr();
|
||||
_entityOffset = archetype.EntityIDsOffset;
|
||||
_entityCount = chunk._count;
|
||||
_version = chunk._version;
|
||||
_pVersion = chunk.GetVersionUnsafePtr();
|
||||
}
|
||||
|
||||
// TODO: We do not have a proper versioning system yet.
|
||||
public bool HasChanged(int version)
|
||||
/// <summary>
|
||||
/// Determines whether the specified component has changed since the given version.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the component to check for changes.</param>
|
||||
/// <param name="version">The version number to compare against the component's current version. Must be greater than or equal to zero.</param>
|
||||
/// <returns>true if the component's current version is less than or equal to the specified version; otherwise, false.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool HasChanged(Identifier<IComponent> id, int version)
|
||||
{
|
||||
return _version != version;
|
||||
return version < _pVersion[id];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified version indicates that the component of type <typeparamref name="T"/> has
|
||||
/// changed since the last recorded version.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of component to check for changes. Must be an unmanaged type that implements <see cref="IComponent"/>.</typeparam>
|
||||
/// <param name="version">The version number to compare against the current version of the component.</param>
|
||||
/// <returns>true if the component of type T has changed since the specified version; otherwise, false.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly bool HasChanged<T>(int version)
|
||||
where T : unmanaged, IComponent
|
||||
{
|
||||
return version < _pVersion[ComponentTypeID<T>.value];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version number associated with the specified component identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the component for which to retrieve the version number. Must reference a valid component.</param>
|
||||
/// <returns>The version number of the specified component.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly int GetComponentVersion(Identifier<IComponent> id)
|
||||
{
|
||||
return _pVersion[id];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version number associated with the specified component type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The component type for which to retrieve the version. Must be an unmanaged type that implements <see cref="IComponent"/>.</typeparam>
|
||||
/// <returns>The version number of the component type <typeparamref name="T"/>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly int GetComponentVersion<T>()
|
||||
where T : unmanaged, IComponent
|
||||
{
|
||||
return _pVersion[ComponentTypeID<T>.value];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a read-only span containing structuralAll entities stored in the current chunk.
|
||||
/// </summary>
|
||||
/// <returns>A read-only span of <see cref="Entity"/> values representing the entities in the chunk.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlySpan<Entity> GetEntities()
|
||||
{
|
||||
var pEntity = (Entity*)(_pChunkData + _entityOffset);
|
||||
@@ -129,6 +169,7 @@ public readonly unsafe ref struct ChunkView
|
||||
/// <typeparam name="T">The type of component to access. Must be an unmanaged type that implements <see cref="Component"/>.</typeparam>
|
||||
/// <returns>A span of type <see cref="{T}"/> containing the component data for each entity in the chunk.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the specified component type is not present in the archetype.</exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Span<T> GetComponentData<T>()
|
||||
where T : unmanaged, IComponent
|
||||
{
|
||||
@@ -144,6 +185,7 @@ public readonly unsafe ref struct ChunkView
|
||||
/// <typeparam name="T">The component type for which to retrieve enablement bits. Must be unmanaged and implement <see cref="IEnableableComponent"/>.</typeparam>
|
||||
/// <returns>A <see cref="SpanBitSet"/> that provides access to the enablement bits for all instances of the specified component type in the chunk.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the specified component type does not support enablement.</exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public SpanBitSet GetEnableBits<T>()
|
||||
where T : unmanaged, IEnableableComponent
|
||||
{
|
||||
@@ -164,6 +206,7 @@ public readonly unsafe ref struct ChunkView
|
||||
/// <param name="index">The zero-based index of the component instance to check within the chunk.</param>
|
||||
/// <returns>true if the component at the specified index is enabled; otherwise, false.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown if the specified component type <typeparamref name="T"/> does not support enable/disable functionality.</exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsComponentEnabled<T>(int index)
|
||||
where T : unmanaged, IEnableableComponent
|
||||
{
|
||||
@@ -373,6 +416,8 @@ public ref partial struct QueryBuilder
|
||||
private UnsafeList<Identifier<IComponent>> _disabled;
|
||||
private UnsafeList<Identifier<IComponent>> _present;
|
||||
|
||||
private UnsafeList<Identifier<IComponent>> _rw;
|
||||
|
||||
public QueryBuilder()
|
||||
{
|
||||
_scope = AllocationManager.CreateStackScope();
|
||||
@@ -383,6 +428,8 @@ public ref partial struct QueryBuilder
|
||||
_none = new UnsafeList<Identifier<IComponent>>(4, _scope.AllocationHandle);
|
||||
_disabled = new UnsafeList<Identifier<IComponent>>(4, _scope.AllocationHandle);
|
||||
_present = new UnsafeList<Identifier<IComponent>>(4, _scope.AllocationHandle);
|
||||
|
||||
_rw = new UnsafeList<Identifier<IComponent>>(4, _scope.AllocationHandle);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -394,7 +441,7 @@ public ref partial struct QueryBuilder
|
||||
}
|
||||
}
|
||||
|
||||
public Identifier<EntityQuery> Build(World world)
|
||||
public Identifier<EntityQuery> Build(World world, Allocator allocator = Allocator.Persistent)
|
||||
{
|
||||
// 1. Calculate max component ID to size the BitSets
|
||||
var maxID = 0;
|
||||
@@ -408,12 +455,14 @@ public ref partial struct QueryBuilder
|
||||
// 2. Create the Mask
|
||||
var mask = new EntityQueryMask
|
||||
{
|
||||
structuralAll = new UnsafeBitSet(maxID + 1, Allocator.Persistent, AllocationOption.Clear),
|
||||
structuralAny = new UnsafeBitSet(maxID + 1, Allocator.Persistent, AllocationOption.Clear),
|
||||
structuralAbsent = new UnsafeBitSet(maxID + 1, Allocator.Persistent, AllocationOption.Clear),
|
||||
requireEnabled = new UnsafeBitSet(maxID + 1, Allocator.Persistent, AllocationOption.Clear),
|
||||
requireDisabled = new UnsafeBitSet(maxID + 1, Allocator.Persistent, AllocationOption.Clear),
|
||||
rejectIfEnabled = new UnsafeBitSet(maxID + 1, Allocator.Persistent, AllocationOption.Clear),
|
||||
structuralAll = new UnsafeBitSet(maxID + 1, allocator, AllocationOption.Clear),
|
||||
structuralAny = new UnsafeBitSet(maxID + 1, allocator, AllocationOption.Clear),
|
||||
structuralAbsent = new UnsafeBitSet(maxID + 1, allocator, AllocationOption.Clear),
|
||||
requireEnabled = new UnsafeBitSet(maxID + 1, allocator, AllocationOption.Clear),
|
||||
requireDisabled = new UnsafeBitSet(maxID + 1, allocator, AllocationOption.Clear),
|
||||
rejectIfEnabled = new UnsafeBitSet(maxID + 1, allocator, AllocationOption.Clear),
|
||||
|
||||
writeAccess = new UnsafeBitSet(maxID + 1, allocator, AllocationOption.Clear),
|
||||
};
|
||||
|
||||
// 3. Fill BitSets
|
||||
@@ -456,6 +505,11 @@ public ref partial struct QueryBuilder
|
||||
mask.structuralAny.SetBit(id);
|
||||
}
|
||||
|
||||
foreach (var id in _rw)
|
||||
{
|
||||
mask.writeAccess.SetBit(id);
|
||||
}
|
||||
|
||||
// 4. Ask World for the Query (Cached)
|
||||
var maskHash = mask.GetHashCode();
|
||||
var queryID = world.GetEntityQueryIDByMaskHash(maskHash);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
using Ghost.Core;
|
||||
|
||||
namespace Ghost.Entities;
|
||||
@@ -7,12 +8,37 @@ public unsafe partial struct EntityQuery
|
||||
public readonly void ForEach<T0>(ForEach<T0> action)
|
||||
where T0 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[1];
|
||||
var offsets = stackalloc int[1];
|
||||
var basePtrs = stackalloc byte*[1];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 1; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -39,6 +65,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 1; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -63,12 +94,39 @@ public unsafe partial struct EntityQuery
|
||||
where T0 : unmanaged, IComponent
|
||||
where T1 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[2];
|
||||
var offsets = stackalloc int[2];
|
||||
var basePtrs = stackalloc byte*[2];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 2; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -95,6 +153,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 2; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -121,12 +184,41 @@ public unsafe partial struct EntityQuery
|
||||
where T1 : unmanaged, IComponent
|
||||
where T2 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[3];
|
||||
var offsets = stackalloc int[3];
|
||||
var basePtrs = stackalloc byte*[3];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 3; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -153,6 +245,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 3; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -181,12 +278,43 @@ public unsafe partial struct EntityQuery
|
||||
where T2 : unmanaged, IComponent
|
||||
where T3 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[4];
|
||||
var offsets = stackalloc int[4];
|
||||
var basePtrs = stackalloc byte*[4];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 4; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -213,6 +341,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 4; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -243,12 +376,45 @@ public unsafe partial struct EntityQuery
|
||||
where T3 : unmanaged, IComponent
|
||||
where T4 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
var comp4TypeID = ComponentTypeID<T4>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
comp4TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[5];
|
||||
var offsets = stackalloc int[5];
|
||||
var basePtrs = stackalloc byte*[5];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 5; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -275,6 +441,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 5; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -307,12 +478,47 @@ public unsafe partial struct EntityQuery
|
||||
where T4 : unmanaged, IComponent
|
||||
where T5 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value, ComponentTypeID<T5>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
var comp4TypeID = ComponentTypeID<T4>.value;
|
||||
var comp5TypeID = ComponentTypeID<T5>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
comp4TypeID.value,
|
||||
comp5TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[6];
|
||||
var offsets = stackalloc int[6];
|
||||
var basePtrs = stackalloc byte*[6];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 6; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -339,6 +545,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 6; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -373,12 +584,49 @@ public unsafe partial struct EntityQuery
|
||||
where T5 : unmanaged, IComponent
|
||||
where T6 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
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 comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
var comp4TypeID = ComponentTypeID<T4>.value;
|
||||
var comp5TypeID = ComponentTypeID<T5>.value;
|
||||
var comp6TypeID = ComponentTypeID<T6>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
comp4TypeID.value,
|
||||
comp5TypeID.value,
|
||||
comp6TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[7];
|
||||
var offsets = stackalloc int[7];
|
||||
var basePtrs = stackalloc byte*[7];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 7; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -405,6 +653,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 7; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -441,12 +694,51 @@ public unsafe partial struct EntityQuery
|
||||
where T6 : unmanaged, IComponent
|
||||
where T7 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
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 comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
var comp4TypeID = ComponentTypeID<T4>.value;
|
||||
var comp5TypeID = ComponentTypeID<T5>.value;
|
||||
var comp6TypeID = ComponentTypeID<T6>.value;
|
||||
var comp7TypeID = ComponentTypeID<T7>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
comp4TypeID.value,
|
||||
comp5TypeID.value,
|
||||
comp6TypeID.value,
|
||||
comp7TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[8];
|
||||
var offsets = stackalloc int[8];
|
||||
var basePtrs = stackalloc byte*[8];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 8; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -473,6 +765,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 8; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -503,12 +800,37 @@ public unsafe partial struct EntityQuery
|
||||
public readonly void ForEach<T0>(ForEachWithEntity<T0> action)
|
||||
where T0 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[1];
|
||||
var offsets = stackalloc int[1];
|
||||
var basePtrs = stackalloc byte*[1];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 1; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -535,6 +857,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 1; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -560,12 +887,39 @@ public unsafe partial struct EntityQuery
|
||||
where T0 : unmanaged, IComponent
|
||||
where T1 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[2];
|
||||
var offsets = stackalloc int[2];
|
||||
var basePtrs = stackalloc byte*[2];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 2; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -592,6 +946,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 2; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -619,12 +978,41 @@ public unsafe partial struct EntityQuery
|
||||
where T1 : unmanaged, IComponent
|
||||
where T2 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[3];
|
||||
var offsets = stackalloc int[3];
|
||||
var basePtrs = stackalloc byte*[3];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 3; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -651,6 +1039,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 3; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -680,12 +1073,43 @@ public unsafe partial struct EntityQuery
|
||||
where T2 : unmanaged, IComponent
|
||||
where T3 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[4];
|
||||
var offsets = stackalloc int[4];
|
||||
var basePtrs = stackalloc byte*[4];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 4; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -712,6 +1136,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 4; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -743,12 +1172,45 @@ public unsafe partial struct EntityQuery
|
||||
where T3 : unmanaged, IComponent
|
||||
where T4 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
var comp4TypeID = ComponentTypeID<T4>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
comp4TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[5];
|
||||
var offsets = stackalloc int[5];
|
||||
var basePtrs = stackalloc byte*[5];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 5; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -775,6 +1237,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 5; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -808,12 +1275,47 @@ public unsafe partial struct EntityQuery
|
||||
where T4 : unmanaged, IComponent
|
||||
where T5 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { ComponentTypeID<T0>.value, ComponentTypeID<T1>.value, ComponentTypeID<T2>.value, ComponentTypeID<T3>.value, ComponentTypeID<T4>.value, ComponentTypeID<T5>.value };
|
||||
var comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
var comp4TypeID = ComponentTypeID<T4>.value;
|
||||
var comp5TypeID = ComponentTypeID<T5>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
comp4TypeID.value,
|
||||
comp5TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[6];
|
||||
var offsets = stackalloc int[6];
|
||||
var basePtrs = stackalloc byte*[6];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 6; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -840,6 +1342,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 6; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -875,12 +1382,49 @@ public unsafe partial struct EntityQuery
|
||||
where T5 : unmanaged, IComponent
|
||||
where T6 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
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 comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
var comp4TypeID = ComponentTypeID<T4>.value;
|
||||
var comp5TypeID = ComponentTypeID<T5>.value;
|
||||
var comp6TypeID = ComponentTypeID<T6>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
comp4TypeID.value,
|
||||
comp5TypeID.value,
|
||||
comp6TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[7];
|
||||
var offsets = stackalloc int[7];
|
||||
var basePtrs = stackalloc byte*[7];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 7; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -907,6 +1451,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 7; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
@@ -944,12 +1493,51 @@ public unsafe partial struct EntityQuery
|
||||
where T6 : unmanaged, IComponent
|
||||
where T7 : unmanaged, IComponent
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
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 comp0TypeID = ComponentTypeID<T0>.value;
|
||||
var comp1TypeID = ComponentTypeID<T1>.value;
|
||||
var comp2TypeID = ComponentTypeID<T2>.value;
|
||||
var comp3TypeID = ComponentTypeID<T3>.value;
|
||||
var comp4TypeID = ComponentTypeID<T4>.value;
|
||||
var comp5TypeID = ComponentTypeID<T5>.value;
|
||||
var comp6TypeID = ComponentTypeID<T6>.value;
|
||||
var comp7TypeID = ComponentTypeID<T7>.value;
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
comp0TypeID.value,
|
||||
comp1TypeID.value,
|
||||
comp2TypeID.value,
|
||||
comp3TypeID.value,
|
||||
comp4TypeID.value,
|
||||
comp5TypeID.value,
|
||||
comp6TypeID.value,
|
||||
comp7TypeID.value,
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[8];
|
||||
var offsets = stackalloc int[8];
|
||||
var basePtrs = stackalloc byte*[8];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < 8; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -976,6 +1564,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < 8; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
|
||||
@@ -24,12 +24,41 @@ public unsafe partial struct EntityQuery
|
||||
public readonly void ForEach<<#= generics #>>(<#= delegateTupe #><<#= generics #>> action)
|
||||
<#= restrictions #>
|
||||
{
|
||||
var world = World.GetWorld(_worldID).GetValueOrThrow();
|
||||
var world = World.GetWorldUncheck(_worldID);
|
||||
var globalVersion = world.Version;
|
||||
|
||||
var compTypeIDs = stackalloc int[] { <#= AppendGenerics(i, "ComponentTypeID<T{0}>.value") #> };
|
||||
<# for (var localIndex = 0; localIndex < i; localIndex++) { #>
|
||||
var comp<#= localIndex #>TypeID = ComponentTypeID<T<#= localIndex #>>.value;
|
||||
<# } #>
|
||||
|
||||
var compTypeIDs = stackalloc int[]
|
||||
{
|
||||
<# for (var localIndex = 0; localIndex < i; localIndex++) { #>
|
||||
comp<#= localIndex #>TypeID.value,
|
||||
<# } #>
|
||||
};
|
||||
|
||||
var changedCompIDs = stackalloc int[<#= i #>];
|
||||
var offsets = stackalloc int[<#= i #>];
|
||||
var basePtrs = stackalloc byte*[<#= i #>];
|
||||
|
||||
var changedCompCount = 0;
|
||||
|
||||
var it = _mask.writeAccess.GetIterator();
|
||||
while (it.Next(out var id))
|
||||
{
|
||||
for (var i =0; i < <#= i #>; i++)
|
||||
{
|
||||
if (id == compTypeIDs[i])
|
||||
{
|
||||
ComponentRegister.SetComponentLastWrite(id, globalVersion);
|
||||
changedCompIDs[changedCompCount] = id;
|
||||
changedCompCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < _matchingArchetypes.Count; i++)
|
||||
{
|
||||
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
|
||||
@@ -56,6 +85,11 @@ public unsafe partial struct EntityQuery
|
||||
ref var chunk = ref archetype.GetChunkReference(chunkIndex);
|
||||
var pChunkData = chunk.GetUnsafePtr();
|
||||
|
||||
for (var j = 0; j < changedCompCount; j++)
|
||||
{
|
||||
chunk.MarkChanged(changedCompIDs[i], globalVersion);
|
||||
}
|
||||
|
||||
for (var index = 0; index < <#= i #>; index++)
|
||||
{
|
||||
basePtrs[index] = pChunkData + offsets[index];
|
||||
|
||||
@@ -18,6 +18,20 @@ public ref partial struct QueryBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'All' filter of the query and requires read-write access.
|
||||
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public QueryBuilder WithAllRW<T0>()
|
||||
where T0 : unmanaged, IComponent
|
||||
{
|
||||
_all.Add(ComponentTypeID<T0>.value);
|
||||
_rw.Add(ComponentTypeID<T0>.value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'Any' filter of the query.
|
||||
/// Targets entities that have at least one of the specified component types and those component(s) must be enabled.
|
||||
@@ -83,6 +97,20 @@ public ref partial struct QueryBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'Present' filter of the query and requires read-write access.
|
||||
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public QueryBuilder WithPresentRW<T0>()
|
||||
where T0 : unmanaged, IComponent
|
||||
{
|
||||
_present.Add(ComponentTypeID<T0>.value);
|
||||
_rw.Add(ComponentTypeID<T0>.value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'All' filter of the query.
|
||||
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
|
||||
@@ -98,6 +126,23 @@ public ref partial struct QueryBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'All' filter of the query and requires read-write access.
|
||||
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public QueryBuilder WithAllRW<T0, T1>()
|
||||
where T0 : unmanaged, IComponent
|
||||
where T1 : unmanaged, IComponent
|
||||
{
|
||||
_all.Add(ComponentTypeID<T0>.value);
|
||||
_rw.Add(ComponentTypeID<T0>.value);
|
||||
_all.Add(ComponentTypeID<T1>.value);
|
||||
_rw.Add(ComponentTypeID<T1>.value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'Any' filter of the query.
|
||||
/// Targets entities that have at least one of the specified component types and those component(s) must be enabled.
|
||||
@@ -173,6 +218,23 @@ public ref partial struct QueryBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'Present' filter of the query and requires read-write access.
|
||||
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public QueryBuilder WithPresentRW<T0, T1>()
|
||||
where T0 : unmanaged, IComponent
|
||||
where T1 : unmanaged, IComponent
|
||||
{
|
||||
_present.Add(ComponentTypeID<T0>.value);
|
||||
_rw.Add(ComponentTypeID<T0>.value);
|
||||
_present.Add(ComponentTypeID<T1>.value);
|
||||
_rw.Add(ComponentTypeID<T1>.value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'All' filter of the query.
|
||||
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
|
||||
@@ -190,6 +252,26 @@ public ref partial struct QueryBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'All' filter of the query and requires read-write access.
|
||||
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public QueryBuilder WithAllRW<T0, T1, T2>()
|
||||
where T0 : unmanaged, IComponent
|
||||
where T1 : unmanaged, IComponent
|
||||
where T2 : unmanaged, IComponent
|
||||
{
|
||||
_all.Add(ComponentTypeID<T0>.value);
|
||||
_rw.Add(ComponentTypeID<T0>.value);
|
||||
_all.Add(ComponentTypeID<T1>.value);
|
||||
_rw.Add(ComponentTypeID<T1>.value);
|
||||
_all.Add(ComponentTypeID<T2>.value);
|
||||
_rw.Add(ComponentTypeID<T2>.value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'Any' filter of the query.
|
||||
/// Targets entities that have at least one of the specified component types and those component(s) must be enabled.
|
||||
@@ -275,4 +357,24 @@ public ref partial struct QueryBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'Present' filter of the query and requires read-write access.
|
||||
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public QueryBuilder WithPresentRW<T0, T1, T2>()
|
||||
where T0 : unmanaged, IComponent
|
||||
where T1 : unmanaged, IComponent
|
||||
where T2 : unmanaged, IComponent
|
||||
{
|
||||
_present.Add(ComponentTypeID<T0>.value);
|
||||
_rw.Add(ComponentTypeID<T0>.value);
|
||||
_present.Add(ComponentTypeID<T1>.value);
|
||||
_rw.Add(ComponentTypeID<T1>.value);
|
||||
_present.Add(ComponentTypeID<T2>.value);
|
||||
_rw.Add(ComponentTypeID<T2>.value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,22 @@ public ref partial struct QueryBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'All' filter of the query and requires read-write access.
|
||||
/// Targets entities that have all of the specified component types and those component(s) must be enabled.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public QueryBuilder WithAllRW<<#= generics #>>()
|
||||
<#= restrictions #>
|
||||
{
|
||||
<# for (var j = 0; j < i; j++) { #>
|
||||
_all.Add(ComponentTypeID<T<#= j #>>.value);
|
||||
_rw.Add(ComponentTypeID<T<#= j #>>.value);
|
||||
<# } #>
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'Any' filter of the query.
|
||||
/// Targets entities that have at least one of the specified component types and those component(s) must be enabled.
|
||||
@@ -106,5 +122,21 @@ public ref partial struct QueryBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified component type(s) to the 'Present' filter of the query and requires read-write access.
|
||||
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public QueryBuilder WithPresentRW<<#= generics #>>()
|
||||
<#= restrictions #>
|
||||
{
|
||||
<# for (var j = 0; j < i; j++) { #>
|
||||
_present.Add(ComponentTypeID<T<#= j #>>.value);
|
||||
_rw.Add(ComponentTypeID<T<#= j #>>.value);
|
||||
<# } #>
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
@@ -47,6 +47,12 @@ public partial class World
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static World GetWorldUncheck(Identifier<World> id)
|
||||
{
|
||||
return s_worlds[id.value]!;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Result<World, ErrorStatus> GetWorld(Identifier<World> id)
|
||||
{
|
||||
@@ -80,6 +86,7 @@ public partial class World : IIdentifierType, IDisposable, IEquatable<World>
|
||||
private UnsafeHashMap<int, Identifier<Archetype>> _archetypeLookup; // Signature Hash to Archetype ID
|
||||
private UnsafeHashMap<int, Identifier<EntityQuery>> _querieLookup; // Query Mask Hash to Query ID
|
||||
|
||||
private int _version;
|
||||
private bool _disposed = false;
|
||||
|
||||
internal int ArchetypeCount => _archetypes.Count;
|
||||
@@ -99,6 +106,11 @@ public partial class World : IIdentifierType, IDisposable, IEquatable<World>
|
||||
/// </summary>
|
||||
public EntityManager EntityManager => _entityManager;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version number of the world.
|
||||
/// </summary>
|
||||
public int Version => Interlocked.CompareExchange(ref _version, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the main entity command buffer for this world.
|
||||
/// </summary>
|
||||
@@ -196,6 +208,7 @@ public partial class World : IIdentifierType, IDisposable, IEquatable<World>
|
||||
return Identifier<EntityQuery>.Invalid;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void PlaybackEntityCommandBuffers()
|
||||
{
|
||||
_entityCommandBuffer.Playback();
|
||||
@@ -206,6 +219,12 @@ public partial class World : IIdentifierType, IDisposable, IEquatable<World>
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal int AdvanceVersion()
|
||||
{
|
||||
return Interlocked.Increment(ref _version);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a reference to the entity query with the specified identifier.
|
||||
/// </summary>
|
||||
|
||||
@@ -231,7 +231,7 @@ public unsafe static class MeshBuilder
|
||||
public static void ComputeTangents(UnsafeList<Vertex> vertices, UnsafeList<uint> indices)
|
||||
{
|
||||
using var scope = AllocationManager.CreateStackScope();
|
||||
using var bitangents = new UnsafeArray<float4>(vertices.Count, Allocator.Stack);
|
||||
var bitangents = new UnsafeArray<float4>(vertices.Count, scope.AllocationHandle);
|
||||
|
||||
for (var i = 0; i < indices.Count; i += 3)
|
||||
{
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<Project Path="Ghost.Zeux.MeshOptimizer/Ghost.Zeux.MeshOptimizer.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Runtime/">
|
||||
<Project Path="Ghost.ArcEntities/Ghost.ArcEntities.csproj" />
|
||||
<Project Path="Ghost.Core/Ghost.Core.csproj" />
|
||||
<Project Path="Ghost.Engine/Ghost.Engine.csproj" />
|
||||
<Project Path="Ghost.Entities/Ghost.Entities.csproj" />
|
||||
|
||||
Reference in New Issue
Block a user