Refactor: variant-aware shader/material pipeline overhaul

Major architectural update to graphics/material/shader system:
- Introduced strongly-typed key structs (Key64/Key128) for passes, variants, and pipelines; removed legacy key types.
- Implemented robust hashing and key generation utilities for efficient variant and pipeline lookup/caching.
- Shader compiler now compiles/caches all keyword variants using new key system; includes handled as lists.
- Switched to push constant root signature for per-draw data; updated HLSL and C# codegen accordingly.
- Refactored Material, Shader, and Pass data structures for cache efficiency and variant support.
- Pipeline library and PSO management now use 128-bit keys and variant-specific caching.
- Replaced WorldNode with SceneNode in editor/scene graph; introduced ComponentManager for archetype/query management.
- Migrated math utilities to Misaki.HighPerformance.Mathematics; updated editor controls.
- Updated all HLSL and codegen for new buffer/push constant layouts and macros.
- Misc: project reference cleanup, D3D12 Work Graph support, doc updates, and code modernization.
This commit is contained in:
2026-01-09 22:25:37 +09:00
parent c9be05fc60
commit 6a041f75ba
93 changed files with 1926 additions and 1390 deletions

View File

@@ -70,7 +70,7 @@ internal unsafe sealed class ChunkDebugView
return [];
}
ref var archetype = ref r.Value.GetArchetypeReference(archetypeID);
ref var archetype = ref r.Value.ComponentManager.GetArchetypeReference(archetypeID);
var it = archetype._signature.GetIterator();
while (it.Next(out var index))
{

View File

@@ -21,65 +21,7 @@ internal struct ComponentInfo
public int size;
public int alignment;
public bool isEnableable;
}
/// <summary>
/// Represents an immutable set of component identifiers used to define a group of components within an entity or system.
/// </summary>
public struct ComponentSet : IDisposable, IEquatable<ComponentSet>
{
private UnsafeArray<Identifier<IComponent>> _components;
private int _hashCode;
public readonly ReadOnlySpan<Identifier<IComponent>> Components => _components.AsSpan();
public ComponentSet(AllocationHandle allocationHandle, params ReadOnlySpan<Identifier<IComponent>> components)
{
_components = new UnsafeArray<Identifier<IComponent>>(components.Length, allocationHandle);
components.CopyTo(_components.AsSpan());
_hashCode = -1;
}
public ComponentSet(Allocator allocator, params ReadOnlySpan<Identifier<IComponent>> components)
: this(AllocationManager.GetAllocationHandle(allocator), components)
{
}
public readonly bool Equals(ComponentSet other)
{
return _hashCode == other._hashCode;
}
public override int GetHashCode()
{
if (_hashCode == -1)
{
_hashCode = ComponentRegistry.GetHashCode(_components.AsSpan());
}
return _hashCode;
}
public override bool Equals(object? obj)
{
return obj is ComponentSet set && Equals(set);
}
public static bool operator ==(ComponentSet left, ComponentSet right)
{
return left.Equals(right);
}
public static bool operator !=(ComponentSet left, ComponentSet right)
{
return !(left == right);
}
public void Dispose()
{
_components.Dispose();
}
public bool isShared;
}
/// <summary>
@@ -122,7 +64,7 @@ internal static class ComponentRegistry
size = sizeof(T),
alignment = (int)MemoryUtility.AlignOf<T>(),
isEnableable = typeof(IEnableableComponent).IsAssignableFrom(type),
// isManaged = typeof(IManagedWrapper).IsAssignableFrom(space),
// isShared = typeof(ISharedComponent).IsAssignableFrom(type),
};
s_registeredComponents.Add(info);
@@ -198,3 +140,191 @@ internal static class ComponentRegistry
return bitSet.GetHashCode();
}
}
public class ComponentManager : IDisposable
{
private readonly World _world;
private UnsafeList<Archetype> _archetypes;
private UnsafeList<EntityQuery> _entityQueries;
private UnsafeHashMap<int, Identifier<Archetype>> _archetypeLookup; // Signature Hash to Archetype ID
private UnsafeHashMap<int, Identifier<EntityQuery>> _querieLookup; // Query Mask Hash to Query ID
private bool _isDisposed;
public int ArchetypeCount => _archetypes.Count;
internal ComponentManager(World world)
{
_world = world;
_archetypes = new UnsafeList<Archetype>(16, Allocator.Persistent);
_entityQueries = new UnsafeList<EntityQuery>(16, Allocator.Persistent);
_archetypeLookup = new UnsafeHashMap<int, Identifier<Archetype>>(16, Allocator.Persistent);
_querieLookup = new UnsafeHashMap<int, Identifier<EntityQuery>>(16, Allocator.Persistent);
// Create the empty archetype
CreateArchetype(ReadOnlySpan<Identifier<IComponent>>.Empty, 0);
}
~ComponentManager()
{
Dispose();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Identifier<Archetype> CreateArchetype(ReadOnlySpan<Identifier<IComponent>> componentTypeIDs, int signatureHash)
{
var arcID = new Identifier<Archetype>(_archetypes.Count);
_archetypes.Add(new Archetype(arcID, _world.ID, componentTypeIDs));
_archetypeLookup.Add(signatureHash, arcID);
for (int i = 0; i < _entityQueries.Count; i++)
{
ref var query = ref _entityQueries[i];
query.AddArchetypeIfMatch(in _archetypes[arcID.Value]);
}
return arcID;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Identifier<Archetype> GetArchetypeIDBySignatureHash(int signatureHash)
{
if (_archetypeLookup.TryGetValue(signatureHash, out var arcID))
{
return arcID;
}
return Identifier<Archetype>.Invalid;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal ref Archetype GetArchetypeReference(Identifier<Archetype> id)
{
return ref _archetypes[id.Value];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Identifier<EntityQuery> CreateEntityQuery(EntityQueryMask mask, int maskHash)
{
var queryID = new Identifier<EntityQuery>(_entityQueries.Count);
_entityQueries.Add(new EntityQuery(queryID, _world.ID, mask));
_querieLookup.Add(maskHash, queryID);
ref var query = ref _entityQueries[queryID.Value];
for (var i = 0; i < _archetypes.Count; i++)
{
query.AddArchetypeIfMatch(in _archetypes[i]);
}
return queryID;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Identifier<EntityQuery> GetEntityQueryIDByMaskHash(int maskHash)
{
if (_querieLookup.TryGetValue(maskHash, out var queryID))
{
return queryID;
}
return Identifier<EntityQuery>.Invalid;
}
/// <summary>
/// Gets a reference to the entity query with the specified identifier.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityQuery GetEntityQueryReference(Identifier<EntityQuery> id)
{
return ref _entityQueries[id.Value];
}
public void Dispose()
{
if (_isDisposed)
{
return;
}
foreach (ref var archetype in _archetypes)
{
archetype.Dispose();
}
foreach (ref var query in _entityQueries)
{
query.Dispose();
}
_archetypes.Dispose();
_entityQueries.Dispose();
_archetypeLookup.Dispose();
_querieLookup.Dispose();
_isDisposed = true;
GC.SuppressFinalize(this);
}
}
/// <summary>
/// Represents an immutable set of component identifiers used to define a group of components within an entity or system.
/// </summary>
public struct ComponentSet : IDisposable, IEquatable<ComponentSet>
{
private UnsafeArray<Identifier<IComponent>> _components;
private int _hashCode;
public readonly ReadOnlySpan<Identifier<IComponent>> Components => _components.AsSpan();
public ComponentSet(AllocationHandle allocationHandle, params ReadOnlySpan<Identifier<IComponent>> components)
{
_components = new UnsafeArray<Identifier<IComponent>>(components.Length, allocationHandle);
components.CopyTo(_components.AsSpan());
_hashCode = -1;
}
public ComponentSet(Allocator allocator, params ReadOnlySpan<Identifier<IComponent>> components)
: this(AllocationManager.GetAllocationHandle(allocator), components)
{
}
public readonly bool Equals(ComponentSet other)
{
return _hashCode == other._hashCode;
}
public override int GetHashCode()
{
if (_hashCode == -1)
{
_hashCode = ComponentRegistry.GetHashCode(_components.AsSpan());
}
return _hashCode;
}
public override readonly bool Equals(object? obj)
{
return obj is ComponentSet set && Equals(set);
}
public static bool operator ==(ComponentSet left, ComponentSet right)
{
return left.Equals(right);
}
public static bool operator !=(ComponentSet left, ComponentSet right)
{
return !(left == right);
}
public void Dispose()
{
_components.Dispose();
}
}

View File

@@ -108,7 +108,7 @@ public partial class EntityManager
where T : ScriptComponent, new()
{
var location = _entityLocations.GetElementAt(entity.ID, entity.Generation);
ref var archetype = ref _world.GetArchetypeReference(location.archetypeID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
var pManagedEntityRef = (ManagedEntityRef*)archetype.GetComponentData(location.chunkIndex, location.rowIndex, ComponentTypeID<ManagedEntityRef>.Value);
if (pManagedEntityRef == null)

View File

@@ -116,7 +116,7 @@ public unsafe partial class EntityManager : IDisposable
/// <param name="entities">The span to store the created entities.</param>
public void CreateEntities(Span<Entity> entities)
{
ref var emptyArchetype = ref _world.GetArchetypeReference(World.EmptyArchetypeID);
ref var emptyArchetype = ref _world.ComponentManager.GetArchetypeReference(World.EmptyArchetypeID);
emptyArchetype.AllocateEntity(out var chunkIndex, out var rowIndex);
for (var i = 0; i < entities.Length; i++)
@@ -141,7 +141,7 @@ public unsafe partial class EntityManager : IDisposable
/// <param name="count">The number of entities to create.</param>
public void CreateEntities(int count)
{
ref var emptyArchetype = ref _world.GetArchetypeReference(World.EmptyArchetypeID);
ref var emptyArchetype = ref _world.ComponentManager.GetArchetypeReference(World.EmptyArchetypeID);
emptyArchetype.AllocateEntity(out var chunkIndex, out var rowIndex);
for (var i = 0; i < count; i++)
@@ -167,14 +167,14 @@ public unsafe partial class EntityManager : IDisposable
public void CreateEntities(Span<Entity> entities, ComponentSet set)
{
var hash = set.GetHashCode();
var arcID = _world.GetArchetypeIDBySignatureHash(hash);
var arcID = _world.ComponentManager.GetArchetypeIDBySignatureHash(hash);
if (arcID.IsInvalid)
{
arcID = _world.CreateArchetype(set.Components, hash);
arcID = _world.ComponentManager.CreateArchetype(set.Components, hash);
}
ref var archetype = ref _world.GetArchetypeReference(arcID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(arcID);
for (var i = 0; i < entities.Length; i++)
{
@@ -202,14 +202,14 @@ public unsafe partial class EntityManager : IDisposable
public void CreateEntities(int count, ComponentSet set)
{
var hash = set.GetHashCode();
var arcID = _world.GetArchetypeIDBySignatureHash(hash);
var arcID = _world.ComponentManager.GetArchetypeIDBySignatureHash(hash);
if (arcID.IsInvalid)
{
arcID = _world.CreateArchetype(set.Components, hash);
arcID = _world.ComponentManager.CreateArchetype(set.Components, hash);
}
ref var archetype = ref _world.GetArchetypeReference(arcID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(arcID);
for (var i = 0; i < count; i++)
{
@@ -247,7 +247,7 @@ public unsafe partial class EntityManager : IDisposable
return ErrorStatus.NotFound;
}
ref var archetype = ref _world.GetArchetypeReference(location.archetypeID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
DestoryManagedEntityIfExists(in archetype, location);
var r = archetype.RemoveEntity(location.chunkIndex, location.rowIndex);
@@ -332,7 +332,7 @@ public unsafe partial class EntityManager : IDisposable
{
// FLUSH PREVIOUS BATCH
// We must retrieve the Archetype of the *Previous* batch, not the current 'loc'
ref var prevArchetype = ref _world.GetArchetypeReference(prevArchetypeID);
ref var prevArchetype = ref _world.ComponentManager.GetArchetypeReference(prevArchetypeID);
// Remove Managed Entities first
RemoveManagedEntity(rowIndicesCache.AsSpan(), in prevArchetype, prevChunkIndex);
@@ -353,7 +353,7 @@ public unsafe partial class EntityManager : IDisposable
// Process the stragglers remaining in the cache
if (rowIndicesCache.Count > 0)
{
ref var lastArchetype = ref _world.GetArchetypeReference(prevArchetypeID);
ref var lastArchetype = ref _world.ComponentManager.GetArchetypeReference(prevArchetypeID);
RemoveManagedEntity(rowIndicesCache.AsSpan(), in lastArchetype, prevChunkIndex);
lastArchetype.RemoveEntities(prevChunkIndex, rowIndicesCache.AsSpan());
@@ -392,16 +392,16 @@ public unsafe partial class EntityManager : IDisposable
// Check if singleton already exists
var signatureHash = ComponentRegistry.GetHashCode(componentID);
var arcID = _world.GetArchetypeIDBySignatureHash(signatureHash);
var arcID = _world.ComponentManager.GetArchetypeIDBySignatureHash(signatureHash);
if (arcID.IsValid)
{
return ErrorStatus.InvalidArgument;
}
arcID = _world.CreateArchetype([componentID], signatureHash);
arcID = _world.ComponentManager.CreateArchetype([componentID], signatureHash);
ref var archetype = ref _world.GetArchetypeReference(arcID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(arcID);
archetype.AllocateEntity(out var chunkIndex, out var rowIndex);
var id = _entityLocations.Add(new EntityLocation
@@ -438,14 +438,14 @@ public unsafe partial class EntityManager : IDisposable
public void* GetSingleton(Identifier<IComponent> componentID)
{
var signatureHash = ComponentRegistry.GetHashCode(componentID);
var arcID = _world.GetArchetypeIDBySignatureHash(signatureHash);
var arcID = _world.ComponentManager.GetArchetypeIDBySignatureHash(signatureHash);
if (arcID.IsInvalid)
{
return null;
}
ref var archetype = ref _world.GetArchetypeReference(arcID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(arcID);
var layoutResult = archetype.GetLayout(componentID);
if (layoutResult.Error != ErrorStatus.None)
{
@@ -510,7 +510,7 @@ public unsafe partial class EntityManager : IDisposable
}
// Build new archetype signature
ref var oldArchetype = ref _world.GetArchetypeReference(location.archetypeID);
ref var oldArchetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
var oldSignature = oldArchetype._signature;
if (oldSignature.IsSet(componentID))
@@ -543,7 +543,7 @@ public unsafe partial class EntityManager : IDisposable
// Find or create new archetype
var newSignatureHash = newSignature.GetHashCode();
newArcID = _world.GetArchetypeIDBySignatureHash(newSignatureHash);
newArcID = _world.ComponentManager.GetArchetypeIDBySignatureHash(newSignatureHash);
if (newArcID.IsInvalid)
{
// Create new archetype
@@ -556,14 +556,14 @@ public unsafe partial class EntityManager : IDisposable
componentTypeIDs[i++] = index;
}
newArcID = _world.CreateArchetype(componentTypeIDs, newSignatureHash);
newArcID = _world.ComponentManager.CreateArchetype(componentTypeIDs, newSignatureHash);
}
oldArchetype.AddEdgeAdd(componentID, newArcID);
}
// Move entity data
ref var newArchetype = ref _world.GetArchetypeReference(newArcID);
ref var newArchetype = ref _world.ComponentManager.GetArchetypeReference(newArcID);
newArchetype.AllocateEntity(out var newChunkIndex, out var newRowIndex);
CopyData(ref oldArchetype, location.chunkIndex, location.rowIndex,
ref newArchetype, newChunkIndex, newRowIndex);
@@ -615,7 +615,7 @@ public unsafe partial class EntityManager : IDisposable
}
// Build new archetype signature
ref var oldArchetype = ref _world.GetArchetypeReference(location.archetypeID);
ref var oldArchetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
var oldSignature = oldArchetype._signature;
var newArcID = oldArchetype.GetEdgeRemove(componentID);
@@ -642,7 +642,7 @@ public unsafe partial class EntityManager : IDisposable
// Find or create new archetype
var newSignatureHash = newSignature.GetHashCode();
newArcID = _world.GetArchetypeIDBySignatureHash(newSignatureHash);
newArcID = _world.ComponentManager.GetArchetypeIDBySignatureHash(newSignatureHash);
if (newArcID.IsInvalid)
{
// Create new archetype
@@ -655,14 +655,14 @@ public unsafe partial class EntityManager : IDisposable
componentTypeIDs[i++] = index;
}
newArcID = _world.CreateArchetype(componentTypeIDs, newSignatureHash);
newArcID = _world.ComponentManager.CreateArchetype(componentTypeIDs, newSignatureHash);
}
oldArchetype.AddEdgeRemove(componentID, newArcID);
}
// Move entity data
ref var newArchetype = ref _world.GetArchetypeReference(newArcID);
ref var newArchetype = ref _world.ComponentManager.GetArchetypeReference(newArcID);
newArchetype.AllocateEntity(out var newChunkIndex, out var newRowIndex);
CopyData(ref oldArchetype, location.chunkIndex, location.rowIndex,
ref newArchetype, newChunkIndex, newRowIndex);
@@ -716,7 +716,7 @@ public unsafe partial class EntityManager : IDisposable
return ErrorStatus.NotFound;
}
ref var archetype = ref _world.GetArchetypeReference(location.archetypeID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
archetype.SetComponentData(location.chunkIndex, location.rowIndex, componentID, pComponent);
return ErrorStatus.None;
@@ -747,7 +747,7 @@ public unsafe partial class EntityManager : IDisposable
return null;
}
ref var archetype = ref _world.GetArchetypeReference(location.archetypeID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
return archetype.GetComponentData(location.chunkIndex, location.rowIndex, componentID);
}
@@ -777,7 +777,7 @@ public unsafe partial class EntityManager : IDisposable
return false;
}
ref var archetype = ref _world.GetArchetypeReference(location.archetypeID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
return archetype.HasComponent(componentID);
}
@@ -807,7 +807,7 @@ public unsafe partial class EntityManager : IDisposable
return ErrorStatus.NotFound;
}
ref var archetype = ref _world.GetArchetypeReference(location.archetypeID);
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
var chunkIndex = location.chunkIndex;
var rowIndex = location.rowIndex;

View File

@@ -57,7 +57,7 @@ public unsafe partial struct EntityQuery
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
for (int i = 0; i < arch.ChunkCount; i++)
{

View File

@@ -285,7 +285,7 @@ public unsafe partial struct EntityQuery : IDisposable
{
get
{
ref var archetype = ref _iterator._world.GetArchetypeReference(_iterator._matchingArchetypes[_archetypeIndex]);
ref var archetype = ref _iterator._world.ComponentManager.GetArchetypeReference(_iterator._matchingArchetypes[_archetypeIndex]);
ref var chunk = ref archetype.GetChunkReference(_chunkIndex);
return new ChunkView(in archetype, in chunk);
}
@@ -297,7 +297,7 @@ public unsafe partial struct EntityQuery : IDisposable
while (_archetypeIndex < _iterator._matchingArchetypes.Count)
{
ref var archetype = ref _iterator._world.GetArchetypeReference(_iterator._matchingArchetypes[_archetypeIndex]);
ref var archetype = ref _iterator._world.ComponentManager.GetArchetypeReference(_iterator._matchingArchetypes[_archetypeIndex]);
if (_chunkIndex < archetype.ChunkCount)
{
return true;
@@ -452,7 +452,7 @@ public unsafe partial struct EntityQuery : IDisposable
for(var i = 0; i < _matchingArchetypes.Count; i++)
{
var archetypeID = _matchingArchetypes[i];
ref var archetype = ref world.GetArchetypeReference(archetypeID);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(archetypeID);
for (var j = 0; j < archetype.ChunkCount; j++)
{
ref var chunk = ref archetype.GetChunkReference(j);
@@ -577,12 +577,12 @@ public ref partial struct QueryBuilder
// 4. Ask World for the Query (Cached)
var maskHash = mask.GetHashCode();
var queryID = world.GetEntityQueryIDByMaskHash(maskHash);
var queryID = world.ComponentManager.GetEntityQueryIDByMaskHash(maskHash);
if (queryID.IsValid)
{
// Check if the masks are actually equal (Hash collision?).
// Really worth it? It's unlikely to have collisions here.
if (world.GetEntityQueryReference(queryID)._mask.Equals(mask))
if (world.ComponentManager.GetEntityQueryReference(queryID)._mask.Equals(mask))
{
mask.Dispose();
goto Return;
@@ -590,7 +590,7 @@ public ref partial struct QueryBuilder
}
// NOTE: We do not dispose the mask here, as it is now owned by the EntityQuery.
queryID = world.CreateEntityQuery(mask, maskHash);
queryID = world.ComponentManager.CreateEntityQuery(mask, maskHash);
Return:
Dispose();

View File

@@ -0,0 +1,176 @@
#if false // FIX: API update in Misaki.HighPerformance.LowLevel.Collections require me to disable this for now.
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using Misaki.HighPerformance.LowLevel.Utilities;
namespace Ghost.Entities;
public interface ISharedComponent
{
}
internal unsafe sealed class SharedComponentStore : IDisposable
{
private struct EntryInfo
{
public int RefCount;
public int HashCode;
public int Version;
public int NextFree; // free-list linkage (index)
}
private struct TypeStore : IDisposable
{
public int TypeSize;
public UnsafeList<byte> Data; // raw bytes, stride = TypeSize
public UnsafeList<EntryInfo> Infos; // parallel to Data entries (Entry 0 reserved)
public UnsafeHashMap<long, int> HashLookup; // (hashKey) -> entryIndex
public int FreeListHead; // head index, 0 means none (we'll use Infos[0].NextFree too if you prefer)
public int VersionCounter;
public void Dispose()
{
Data.Dispose();
Infos.Dispose();
HashLookup.Dispose();
}
}
private readonly UnsafeHashMap<int, TypeStore> _perType; // componentTypeId -> TypeStore
public SharedComponentStore(int initialCapacity = 16)
{
_perType = new UnsafeHashMap<int, TypeStore>(initialCapacity, Allocator.Persistent);
}
public void Dispose()
{
foreach (var kvp in _perType)
{
kvp.Value.Dispose();
}
_perType.Dispose();
}
public int InsertOrGet(int componentTypeId, int typeSize, void* data, int hashCode)
{
// Reserve index 0 for "default"
if (data == null)
{
return 0;
}
ref var store = ref GetOrCreateTypeStore(componentTypeId, typeSize);
// Combine (typeId, hash) into a single key; collisions handled by memcmp below.
var key = ((long)componentTypeId << 32) ^ (uint)hashCode;
if (store.HashLookup.TryGetValue(key, out var existingIndex))
{
var existingPtr = (byte*)store.Data.GetUnsafePtr() + (existingIndex * store.TypeSize);
if (new Span<byte>(existingPtr, store.TypeSize).SequenceEqual(new Span<byte>(data, store.TypeSize)))
{
((EntryInfo*)store.Infos.GetUnsafePtr())[existingIndex].RefCount++;
return existingIndex;
}
// If collision: fall through to insert (you may want a secondary structure).
}
int index = AllocateEntry(ref store);
var dst = (byte*)store.Data.GetUnsafePtr() + (index * store.TypeSize);
MemoryUtility.MemCpy(dst, data, (nuint)store.TypeSize);
store.Infos[index] = new EntryInfo
{
RefCount = 1,
HashCode = hashCode,
Version = ++store.VersionCounter,
NextFree = -1
};
store.HashLookup[key] = index;
return index;
}
public void AddRef(int componentTypeId, int index)
{
if (index == 0) return;
ref var store = ref _perType[componentTypeId];
store.Infos[index].RefCount++;
}
public void Release(int componentTypeId, int index)
{
if (index == 0) return;
ref var store = ref _perType.GetValueByKey(componentTypeId);
ref var info = ref store.Infos.Ptr[index];
info.RefCount--;
if (info.RefCount > 0) return;
// Remove from hash lookup (best-effort; collisions require more robust handling)
long key = ((long)componentTypeId << 32) ^ (uint)info.HashCode;
store.HashLookup.Remove(key);
// Push to free-list
info.NextFree = store.FreeListHead;
store.FreeListHead = index;
}
public void* GetDataPtr(int componentTypeId, int index)
{
if (index == 0) return null;
ref var store = ref _perType.GetValueByKey(componentTypeId);
return (byte*)store.Data.Ptr + (index * store.TypeSize);
}
private ref TypeStore GetOrCreateTypeStore(int componentTypeId, int typeSize)
{
if (_perType.TryGetValue(componentTypeId, out var existing))
{
// UnsafeHashMap returns by value in some implementations; you may need a different pattern here.
// Adjust to your container API (e.g., TryGetValueRef).
}
var store = new TypeStore
{
TypeSize = typeSize,
Data = new UnsafeList<byte>(typeSize * 16, Allocator.Persistent),
Infos = new UnsafeList<EntryInfo>(16, Allocator.Persistent),
HashLookup = new UnsafeHashMap<long, int>(16, Allocator.Persistent),
FreeListHead = 0,
VersionCounter = 0
};
// Create reserved default entry at index 0
store.Data.Resize(typeSize); // one element worth of bytes
store.Infos.Add(new EntryInfo { RefCount = int.MaxValue, HashCode = 0, Version = 0, NextFree = -1 });
_perType.Add(componentTypeId, store);
// NOTE: returning a ref requires a "get ref" API; adjust to your UnsafeHashMap capabilities.
return ref _perType.GetValueByKey(componentTypeId);
}
private static int AllocateEntry(ref TypeStore store)
{
if (store.FreeListHead != 0)
{
int idx = store.FreeListHead;
store.FreeListHead = store.Infos[idx].NextFree;
store.Infos[idx].NextFree = -1;
return idx;
}
int newIndex = store.Infos.Count;
store.Infos.Add(default);
int newByteCount = (newIndex + 1) * store.TypeSize;
store.Data.Resize(newByteCount);
return newIndex;
}
}
#endif

View File

@@ -45,7 +45,7 @@ public abstract class SystemBase : ISystem
foreach (var queryID in _requiredQueries)
{
ref var query = ref World.GetEntityQueryReference(new Identifier<EntityQuery>(queryID));
ref var query = ref World.ComponentManager.GetEntityQueryReference(new Identifier<EntityQuery>(queryID));
if (query.GetEntityCount() == 0)
{
return false;
@@ -197,7 +197,7 @@ public abstract class SystemGroup : ISystem
private static List<ISystem> Sort(List<ISystem> systems)
{
// 1. Build the Graph
// Key: The System, Value: Systems that MUST run before the Key
// Key64: The System, Value: Systems that MUST run before the Key64
var dependencies = new Dictionary<Type, HashSet<Type>>();
var systemMap = systems.ToDictionary(s => s.GetType(), s => s);

View File

@@ -113,7 +113,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -142,7 +142,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -309,7 +309,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -338,7 +338,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -515,7 +515,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -544,7 +544,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -731,7 +731,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -760,7 +760,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -957,7 +957,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -986,7 +986,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -1193,7 +1193,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -1222,7 +1222,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -1439,7 +1439,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -1468,7 +1468,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -1695,7 +1695,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -1724,7 +1724,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);

View File

@@ -158,7 +158,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -187,7 +187,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);

View File

@@ -136,7 +136,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -165,7 +165,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -339,7 +339,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -368,7 +368,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -552,7 +552,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -581,7 +581,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -775,7 +775,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -804,7 +804,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -1008,7 +1008,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -1037,7 +1037,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -1251,7 +1251,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -1280,7 +1280,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -1504,7 +1504,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -1533,7 +1533,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);
@@ -1767,7 +1767,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -1796,7 +1796,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);

View File

@@ -159,7 +159,7 @@ public unsafe partial struct EntityQuery
_currentArchetypeIndex++;
if (_currentArchetypeIndex < _matchingArchetypes.Count)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[_currentArchetypeIndex]);
_currentChunkIndex = 0;
if (_currentArchetype.ChunkCount > 0)
@@ -188,7 +188,7 @@ public unsafe partial struct EntityQuery
if (_matchingArchetypes.Count > 0)
{
_currentArchetype = ref _world.GetArchetypeReference(_matchingArchetypes[0]);
_currentArchetype = ref _world.ComponentManager.GetArchetypeReference(_matchingArchetypes[0]);
if (_currentArchetype.ChunkCount > 0)
{
SetChunk(0);

View File

@@ -37,7 +37,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 1; index++)
{
@@ -124,7 +124,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 2; index++)
{
@@ -215,7 +215,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 3; index++)
{
@@ -310,7 +310,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 4; index++)
{
@@ -409,7 +409,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 5; index++)
{
@@ -512,7 +512,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 6; index++)
{
@@ -619,7 +619,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 7; index++)
{
@@ -730,7 +730,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 8; index++)
{
@@ -821,7 +821,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 1; index++)
{
@@ -909,7 +909,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 2; index++)
{
@@ -1001,7 +1001,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 3; index++)
{
@@ -1097,7 +1097,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 4; index++)
{
@@ -1197,7 +1197,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 5; index++)
{
@@ -1301,7 +1301,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 6; index++)
{
@@ -1409,7 +1409,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 7; index++)
{
@@ -1521,7 +1521,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < 8; index++)
{

View File

@@ -58,7 +58,7 @@ public unsafe partial struct EntityQuery
for (var i = 0; i < _matchingArchetypes.Count; i++)
{
ref var archetype = ref world.GetArchetypeReference(_matchingArchetypes[i]);
ref var archetype = ref world.ComponentManager.GetArchetypeReference(_matchingArchetypes[i]);
var hasAllComponents = true;
for (var index = 0; index < <#= i #>; index++)
{

View File

@@ -1114,7 +1114,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{
@@ -1255,7 +1255,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{
@@ -1423,7 +1423,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{
@@ -1618,7 +1618,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{
@@ -1840,7 +1840,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{
@@ -2089,7 +2089,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{
@@ -2365,7 +2365,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{
@@ -2668,7 +2668,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{

View File

@@ -146,7 +146,7 @@ public unsafe partial struct EntityQuery
// Iterate the Query's matching archetypes
foreach (var archID in _matchingArchetypes)
{
ref var arch = ref world.GetArchetypeReference(archID);
ref var arch = ref world.ComponentManager.GetArchetypeReference(archID);
if (arch.ChunkCount == 0)
{

View File

@@ -1,3 +1,4 @@
namespace Ghost.Entities;
public delegate void ForEach<T0>(ref T0 component0)

View File

@@ -6,7 +6,7 @@ namespace Ghost.Entities;
public ref partial struct QueryBuilder
{
/// <summary>
/// Adds the specified component space(s) to the 'All' filter of the query.
/// 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.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -19,7 +19,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'All' filter of the query and requires read-write access.
/// 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)]
@@ -33,7 +33,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Any' filter of the query.
/// 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.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -46,7 +46,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Absent' filter of the query.
/// Adds the specified component type(s) to the 'Absent' filter of the query.
/// Targets entities that do not have any of the specified component types.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -59,7 +59,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'None' filter of the query.
/// Adds the specified component type(s) to the 'None' filter of the query.
/// Targets entities that do not have any of the specified component types, or those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -72,7 +72,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Disabled' filter of the query.
/// Adds the specified component type(s) to the 'Disabled' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -85,7 +85,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Present' filter of the query.
/// Adds the specified component type(s) to the 'Present' filter of the query.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -98,7 +98,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Present' filter of the query and requires read-write access.
/// 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)]
@@ -112,7 +112,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'All' filter of the query.
/// 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.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -127,7 +127,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'All' filter of the query and requires read-write access.
/// 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)]
@@ -144,7 +144,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Any' filter of the query.
/// 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.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -159,7 +159,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Absent' filter of the query.
/// Adds the specified component type(s) to the 'Absent' filter of the query.
/// Targets entities that do not have any of the specified component types.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -174,7 +174,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'None' filter of the query.
/// Adds the specified component type(s) to the 'None' filter of the query.
/// Targets entities that do not have any of the specified component types, or those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -189,7 +189,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Disabled' filter of the query.
/// Adds the specified component type(s) to the 'Disabled' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -204,7 +204,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Present' filter of the query.
/// Adds the specified component type(s) to the 'Present' filter of the query.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -219,7 +219,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Present' filter of the query and requires read-write access.
/// 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)]
@@ -236,7 +236,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'All' filter of the query.
/// 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.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -253,7 +253,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'All' filter of the query and requires read-write access.
/// 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)]
@@ -273,7 +273,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Any' filter of the query.
/// 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.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -290,7 +290,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Absent' filter of the query.
/// Adds the specified component type(s) to the 'Absent' filter of the query.
/// Targets entities that do not have any of the specified component types.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -307,7 +307,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'None' filter of the query.
/// Adds the specified component type(s) to the 'None' filter of the query.
/// Targets entities that do not have any of the specified component types, or those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -324,7 +324,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Disabled' filter of the query.
/// Adds the specified component type(s) to the 'Disabled' filter of the query.
/// Targets entities that have all of the specified component types and those component(s) are disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -341,7 +341,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Present' filter of the query.
/// Adds the specified component type(s) to the 'Present' filter of the query.
/// Targets entities that have all of the specified component types, regardless of whether those component(s) are enabled or disabled.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -358,7 +358,7 @@ public ref partial struct QueryBuilder
}
/// <summary>
/// Adds the specified component space(s) to the 'Present' filter of the query and requires read-write access.
/// 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)]

View File

@@ -1,7 +1,5 @@
using Ghost.Core;
using Misaki.HighPerformance.Jobs;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
namespace Ghost.Entities;
@@ -85,19 +83,12 @@ public partial class World : IDisposable, IEquatable<World>
private readonly EntityCommandBuffer _entityCommandBuffer;
private readonly EntityCommandBuffer[]? _threadLocalECBs;
private readonly ComponentManager _componentManager;
private readonly SystemManager _systemManager;
private UnsafeList<Archetype> _archetypes;
private UnsafeList<EntityQuery> _entityQueries;
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;
/// <summary>
/// Gets the unique identifier of this world.
/// </summary>
@@ -113,6 +104,11 @@ public partial class World : IDisposable, IEquatable<World>
/// </summary>
public EntityManager EntityManager => _entityManager;
/// <summary>
/// Gets the component manager for this world.
/// </summary>
public ComponentManager ComponentManager => _componentManager;
/// <summary>
/// Gets the system manager for this world.
/// </summary>
@@ -139,14 +135,9 @@ public partial class World : IDisposable, IEquatable<World>
_entityManager = new EntityManager(this, entityCapacity);
_entityCommandBuffer = new EntityCommandBuffer(_entityManager);
_componentManager = new ComponentManager(this);
_systemManager = new SystemManager(this);
_archetypes = new UnsafeList<Archetype>(16, Allocator.Persistent);
_entityQueries = new UnsafeList<EntityQuery>(16, Allocator.Persistent);
_archetypeLookup = new UnsafeHashMap<int, Identifier<Archetype>>(16, Allocator.Persistent);
_querieLookup = new UnsafeHashMap<int, Identifier<EntityQuery>>(16, Allocator.Persistent);
if (jobScheduler != null)
{
_threadLocalECBs = new EntityCommandBuffer[jobScheduler.WorkerCount];
@@ -155,9 +146,6 @@ public partial class World : IDisposable, IEquatable<World>
_threadLocalECBs[i] = new EntityCommandBuffer(_entityManager);
}
}
// Create the empty archetype
CreateArchetype(ReadOnlySpan<Identifier<IComponent>>.Empty, 0);
}
~World()
@@ -165,66 +153,6 @@ public partial class World : IDisposable, IEquatable<World>
Dispose();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Identifier<Archetype> CreateArchetype(ReadOnlySpan<Identifier<IComponent>> componentTypeIDs, int signatureHash)
{
var arcID = new Identifier<Archetype>(_archetypes.Count);
_archetypes.Add(new Archetype(arcID, _id, componentTypeIDs));
_archetypeLookup.Add(signatureHash, arcID);
for (int i = 0; i < _entityQueries.Count; i++)
{
ref var query = ref _entityQueries[i];
query.AddArchetypeIfMatch(in _archetypes[arcID.Value]);
}
return arcID;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Identifier<Archetype> GetArchetypeIDBySignatureHash(int signatureHash)
{
if (_archetypeLookup.TryGetValue(signatureHash, out var arcID))
{
return arcID;
}
return Identifier<Archetype>.Invalid;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal ref Archetype GetArchetypeReference(Identifier<Archetype> id)
{
return ref _archetypes[id.Value];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Identifier<EntityQuery> CreateEntityQuery(EntityQueryMask mask, int maskHash)
{
var queryID = new Identifier<EntityQuery>(_entityQueries.Count);
_entityQueries.Add(new EntityQuery(queryID, _id, mask));
_querieLookup.Add(maskHash, queryID);
ref var query = ref _entityQueries[queryID.Value];
for (var i = 0; i < _archetypes.Count; i++)
{
query.AddArchetypeIfMatch(in _archetypes[i]);
}
return queryID;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Identifier<EntityQuery> GetEntityQueryIDByMaskHash(int maskHash)
{
if (_querieLookup.TryGetValue(maskHash, out var queryID))
{
return queryID;
}
return Identifier<EntityQuery>.Invalid;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void PlaybackEntityCommandBuffers()
{
@@ -245,15 +173,6 @@ public partial class World : IDisposable, IEquatable<World>
return Interlocked.Increment(ref _version);
}
/// <summary>
/// Gets a reference to the entity query with the specified identifier.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityQuery GetEntityQueryReference(Identifier<EntityQuery> id)
{
return ref _entityQueries[id.Value];
}
/// <summary>
/// Gets the thread-local entity command buffer for the specified thread index.
/// </summary>
@@ -300,16 +219,6 @@ public partial class World : IDisposable, IEquatable<World>
return;
}
foreach (ref var archetype in _archetypes)
{
archetype.Dispose();
}
foreach (ref var query in _entityQueries)
{
query.Dispose();
}
_entityManager.Dispose();
_entityCommandBuffer.Dispose();
@@ -321,11 +230,6 @@ public partial class World : IDisposable, IEquatable<World>
}
}
_archetypes.Dispose();
_entityQueries.Dispose();
_archetypeLookup.Dispose();
_querieLookup.Dispose();
s_freeWorldSlots.Enqueue(_id);
s_worlds[_id] = null;