MoonTools.ECS/src/Filter.cs

124 lines
2.6 KiB
C#
Raw Normal View History

2022-04-08 05:52:03 +00:00
using System;
using MoonTools.ECS.Collections;
2022-03-06 06:12:27 +00:00
namespace MoonTools.ECS;
public class Filter
2022-03-06 06:12:27 +00:00
{
private World World;
internal FilterSignature Signature;
internal IndexableSet<Entity> EntitySet = new IndexableSet<Entity>();
private bool IsDisposed;
public ReverseSpanEnumerator<Entity> Entities => EntitySet.GetEnumerator();
public bool Empty => EntitySet.Count == 0;
public int Count => EntitySet.Count;
// WARNING: this WILL crash if the index is out of range!
public Entity NthEntity(int index) => EntitySet[index];
// WARNING: this WILL crash if the filter is empty!
public Entity RandomEntity => EntitySet[RandomManager.Next(EntitySet.Count)];
public RandomEntityEnumerator EntitiesInRandomOrder => new RandomEntityEnumerator(this);
internal Filter(World world, FilterSignature signature)
2022-03-06 06:12:27 +00:00
{
World = world;
Signature = signature;
}
2022-03-06 06:12:27 +00:00
public void DestroyAllEntities()
{
foreach (var entity in EntitySet)
2022-04-08 05:52:03 +00:00
{
World.Destroy(entity);
2022-04-08 05:52:03 +00:00
}
}
internal void Check(Entity entity)
{
foreach (var type in Signature.Included)
{
if (!World.Has(entity, type))
{
EntitySet.Remove(entity);
return;
}
}
2022-04-08 05:52:03 +00:00
foreach (var type in Signature.Excluded)
{
if (World.Has(entity, type))
{
EntitySet.Remove(entity);
return;
}
}
2022-08-17 22:29:38 +00:00
EntitySet.Add(entity);
}
2023-01-27 00:34:15 +00:00
internal void AddEntity(in Entity entity)
{
EntitySet.Add(entity);
}
internal void RemoveEntity(in Entity entity)
{
EntitySet.Remove(entity);
}
internal void Clear()
{
EntitySet.Clear();
}
public ref struct RandomEntityEnumerator
{
private Filter Filter;
private LinearCongruentialEnumerator LinearCongruentialEnumerator;
public RandomEntityEnumerator GetEnumerator() => this;
internal RandomEntityEnumerator(Filter filter)
2023-01-27 00:34:15 +00:00
{
Filter = filter;
LinearCongruentialEnumerator =
RandomManager.LinearCongruentialSequence(filter.Count);
2023-01-27 00:34:15 +00:00
}
public bool MoveNext() => LinearCongruentialEnumerator.MoveNext();
public Entity Current => Filter.NthEntity(LinearCongruentialEnumerator.Current);
}
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed)
2023-01-27 00:34:15 +00:00
{
if (disposing)
{
EntitySet.Dispose();
}
IsDisposed = true;
2023-01-27 00:34:15 +00:00
}
2022-04-08 05:52:03 +00:00
}
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
// ~Filter()
// {
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
// Dispose(disposing: false);
// }
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
2022-03-06 06:12:27 +00:00
}