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.
80 lines
2.3 KiB
80 lines
2.3 KiB
2 years ago
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|