using Misaki.HighPerformance.LowLevel.Collections; using Misaki.HighPerformance.LowLevel.Utilities; namespace Ghost.Entities; public unsafe class EntityCommandBuffer : IDisposable { private enum CommandType { CreateEntity, DestroyEntity, AddComponent, RemoveComponent, SetComponent, } private struct Command { public UnsafeArray data; public CommandType type; public Entity entity; public int componentTypeID; } private readonly EntityManager _entityManager; private UnsafeList _commands; // TODO: Maybe use UnsafeArray directly? public EntityCommandBuffer(EntityManager entityManager) { _entityManager = entityManager; _commands = new UnsafeList(32, Misaki.HighPerformance.LowLevel.Buffer.Allocator.Persistent); } public void CreateEntity() { var command = new Command { type = CommandType.CreateEntity, data = default, entity = default, componentTypeID = -1 }; _commands.Add(command); } public void DestroyEntity(Entity entity) { var command = new Command { type = CommandType.DestroyEntity, data = default, entity = entity, componentTypeID = -1 }; _commands.Add(command); } public void AddComponent(Entity entity, T component) where T : unmanaged, IComponent { var data = new UnsafeArray(sizeof(T), Misaki.HighPerformance.LowLevel.Buffer.Allocator.Persistent); MemoryUtility.MemCpy(&component, data.GetUnsafePtr(), (nuint)sizeof(T)); var command = new Command { type = CommandType.AddComponent, data = data, entity = entity, componentTypeID = ComponentTypeID.value }; _commands.Add(command); } public void RemoveComponent(Entity entity) where T : unmanaged, IComponent { var command = new Command { type = CommandType.RemoveComponent, data = default, entity = entity, componentTypeID = ComponentTypeID.value }; _commands.Add(command); } public void Reset() { foreach (ref var command in _commands) { command.data.Dispose(); } _commands.Clear(); } public void Dispose() { foreach (ref var command in _commands) { command.data.Dispose(); } _commands.Dispose(); } }