|
|
|
|
using System;
|
|
|
|
|
using Unity.Collections;
|
|
|
|
|
using Unity.Mathematics;
|
|
|
|
|
|
|
|
|
|
namespace GameCore.TinyECS
|
|
|
|
|
{
|
|
|
|
|
public struct EntityGenerator<TEnum> : IDisposable
|
|
|
|
|
where TEnum : unmanaged, IConvertible
|
|
|
|
|
{
|
|
|
|
|
public readonly TEnum entityType;
|
|
|
|
|
private NativeList<int> indexToGeneration;
|
|
|
|
|
private int beginSearchIndex;
|
|
|
|
|
private int freeCount;
|
|
|
|
|
|
|
|
|
|
public EntityGenerator(TEnum type, int capacity, AllocatorManager.AllocatorHandle allocator)
|
|
|
|
|
{
|
|
|
|
|
indexToGeneration = new(capacity, allocator) { 0 };
|
|
|
|
|
beginSearchIndex = 1;
|
|
|
|
|
freeCount = 0;
|
|
|
|
|
entityType = type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
indexToGeneration.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Entity<TEnum> 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<TEnum> 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<TEnum> entity)
|
|
|
|
|
{
|
|
|
|
|
var generation = indexToGeneration[entity.index];
|
|
|
|
|
return generation == entity.generation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear()
|
|
|
|
|
{
|
|
|
|
|
indexToGeneration.Resize(1, NativeArrayOptions.UninitializedMemory);
|
|
|
|
|
beginSearchIndex = 1;
|
|
|
|
|
freeCount = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|