You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
2.3 KiB

using System;
using Unity.Collections;
using Unity.Mathematics;
namespace GameCore.TinyECS
{
public struct EntityGenerator<TEnum> : IDisposable where TEnum : unmanaged
{
private NativeList<int> 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<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;
}
}
}