Refactor ECS framework and improve performance
Refactored `ArcEntityTest` to use updated `Transform` and `Mesh` components, improving query logic with `GetChunkIterator` and introducing `ForEach` methods for better modularity. Enhanced `Chunk` and `Archetype` structs with `readonly` properties and memory optimizations. Fixed bugs in memory copy logic and entity relocation. Improved `EntityManager` with proper disposal handling, added a destructor, and fixed pointer usage in `AddComponent` and `SetComponentData`. Refactored `EntityQuery` to use `ChunkIterator` and `ChunkView` for better abstraction. Simplified `EntityQueryMask` logic for performance. Introduced templated `ForEach` methods and `ForEachWithEntity` methods, dynamically generated using T4 templates for scalability. Added disposal logic for archetypes and queries in `World`. Updated `Program.cs` to include memory debugging setup. Integrated T4 templates for dynamic code generation and added helper functions for template generation. Updated project file to include templates and generated outputs. General improvements include enforcing immutability, optimizing memory management, and adding debugging/logging for better traceability.
This commit is contained in:
@@ -15,13 +15,19 @@ public unsafe class EntityManager : IDisposable
|
||||
public int rowIndex;
|
||||
}
|
||||
|
||||
private World _world;
|
||||
private readonly World _world;
|
||||
private UnsafeSlotMap<EntityLocation> _entityLocations;
|
||||
private bool _disposed;
|
||||
|
||||
internal EntityManager(World world, int initialCapacity)
|
||||
{
|
||||
_world = world;
|
||||
_entityLocations = new UnsafeSlotMap<EntityLocation>(initialCapacity, Allocator.Persistent);
|
||||
_entityLocations = new UnsafeSlotMap<EntityLocation>(initialCapacity, Allocator.Persistent, AllocationOption.Clear);
|
||||
}
|
||||
|
||||
~EntityManager()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
internal ResultStatus UpdateEntityLocation(Entity entity, Identifier<Archetype> newArchetypeID, int newChunkIndex, int newRowIndex)
|
||||
@@ -115,8 +121,8 @@ public unsafe class EntityManager : IDisposable
|
||||
var layout = oldArch._layouts[i];
|
||||
|
||||
var src = oldArch._chunks[oldChunk].GetUnsafePtr() + layout.offset + (layout.size * oldRow);
|
||||
var newOffset = newArch.GetOffset(layout.componentID); // O(1) Lookup
|
||||
var dst = oldArch._chunks[oldChunk].GetUnsafePtr() + newOffset + (layout.size * newRow);
|
||||
var newOffset = newArch.GetOffset(layout.componentID); // O(1) Looku
|
||||
var dst = newArch._chunks[newChunk].GetUnsafePtr() + newOffset + (layout.size * newRow);
|
||||
|
||||
MemoryUtility.MemCpy(src, dst, (nuint)layout.size);
|
||||
}
|
||||
@@ -217,10 +223,10 @@ public unsafe class EntityManager : IDisposable
|
||||
return ResultStatus.Success;
|
||||
}
|
||||
|
||||
public ResultStatus AddComponent<T>(Entity entity, ref T component)
|
||||
public ResultStatus AddComponent<T>(Entity entity, T component)
|
||||
where T : unmanaged, IComponent
|
||||
{
|
||||
return AddComponent(entity, ComponentTypeID<T>.value, UnsafeUtility.AddressOf(ref component));
|
||||
return AddComponent(entity, ComponentTypeID<T>.value, &component);
|
||||
}
|
||||
|
||||
public ResultStatus SetComponentData(Entity entity, Identifier<IComponent> componentID, void* pComponent)
|
||||
@@ -236,10 +242,10 @@ public unsafe class EntityManager : IDisposable
|
||||
return ResultStatus.Success;
|
||||
}
|
||||
|
||||
public ResultStatus SetComponentData<T>(Entity entity, ref T component)
|
||||
public ResultStatus SetComponentData<T>(Entity entity, T component)
|
||||
where T : unmanaged, IComponent
|
||||
{
|
||||
return SetComponentData(entity, ComponentTypeID<T>.value, UnsafeUtility.AddressOf(ref component));
|
||||
return SetComponentData(entity, ComponentTypeID<T>.value, &component);
|
||||
}
|
||||
|
||||
public bool HasComponent(Entity entity, Identifier<IComponent> componentID)
|
||||
@@ -261,6 +267,14 @@ public unsafe class EntityManager : IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_entityLocations.Dispose();
|
||||
_disposed = true;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user