using System; using Unity.Collections; using Unity.Mathematics; namespace GameCore.TinyECS { public struct EntityGenerator : IDisposable where TEnum : unmanaged { private NativeList indexToGeneration; private int beginSearchIndex; private int freeCount; private TEnum entityType; public EntityGenerator(TEnum type, int capacity, Allocator allocator) { indexToGeneration = new(capacity, allocator) { 0 }; beginSearchIndex = 1; freeCount = 0; entityType = type; } public void Dispose() { indexToGeneration.Dispose(); } public Entity Create() { if (freeCount == 0) { var index = indexToGeneration.Length; indexToGeneration.Add(1); return new(entityType, index, 1); } var count = indexToGeneration.Length; for (var i = beginSearchIndex; i < count; ++i) { var oldGeneration = indexToGeneration[i]; if (oldGeneration >= 0) continue; beginSearchIndex = i + 1; freeCount--; var generation = 1 - oldGeneration; indexToGeneration[i] = generation; return new(entityType, i, generation); } throw new Exception("Impossible"); } public void Delete(Entity entity) { var generation = indexToGeneration[entity.index]; if (generation != entity.generation) { throw new Exception($"Invalid entity: {entity}"); } indexToGeneration[entity.index] = -generation; freeCount++; beginSearchIndex = math.min(beginSearchIndex, entity.index); } public bool IsValid(Entity entity) { var generation = indexToGeneration[entity.index]; return generation == entity.generation; } public void Clear() { indexToGeneration.Resize(1, NativeArrayOptions.UninitializedMemory); beginSearchIndex = 1; freeCount = 0; } } }