MoonTools.ECS/src/Filter.cs

95 lines
2.0 KiB
C#
Raw Normal View History

2023-11-08 01:46:44 +00:00
using MoonTools.ECS.Collections;
2022-03-06 06:12:27 +00:00
2023-11-03 19:40:26 +00:00
namespace MoonTools.ECS;
// TODO: do we want to get fancy with queries beyond Include and Exclude?
public class Filter
2022-03-06 06:12:27 +00:00
{
2023-11-08 01:46:44 +00:00
private World World;
internal FilterSignature Signature;
2023-11-03 19:40:26 +00:00
2023-11-08 01:46:44 +00:00
internal IndexableSet<Entity> EntitySet = new IndexableSet<Entity>();
2023-11-03 19:40:26 +00:00
2023-11-08 01:46:44 +00:00
public ReverseSpanEnumerator<Entity> Entities => EntitySet.GetEnumerator();
2023-11-03 19:40:26 +00:00
2023-11-08 01:46:44 +00:00
public bool Empty => EntitySet.Count == 0;
public int Count => EntitySet.Count;
2023-11-03 19:40:26 +00:00
2023-11-08 01:46:44 +00:00
// WARNING: this WILL crash if the index is out of range!
public Entity NthEntity(int index) => EntitySet[index];
2023-11-03 19:40:26 +00:00
2023-11-08 01:46:44 +00:00
// WARNING: this WILL crash if the filter is empty!
public Entity RandomEntity => EntitySet[RandomManager.Next(EntitySet.Count)];
public RandomEntityEnumerator EntitiesInRandomOrder => new RandomEntityEnumerator(this);
2023-11-03 19:40:26 +00:00
2023-11-08 01:46:44 +00:00
internal Filter(World world, FilterSignature signature)
{
World = world;
Signature = signature;
2023-11-03 19:40:26 +00:00
}
2023-11-08 01:46:44 +00:00
public void DestroyAllEntities()
2023-11-03 19:40:26 +00:00
{
2023-11-08 01:46:44 +00:00
foreach (var entity in EntitySet)
2023-11-03 19:40:26 +00:00
{
2023-11-08 01:46:44 +00:00
World.Destroy(entity);
2023-11-03 19:40:26 +00:00
}
}
2022-04-08 05:52:03 +00:00
2023-11-08 01:46:44 +00:00
internal void Check(Entity entity)
2023-11-03 19:40:26 +00:00
{
2023-11-08 01:46:44 +00:00
foreach (var type in Signature.Included)
2023-11-03 19:40:26 +00:00
{
2023-11-08 01:46:44 +00:00
if (!World.Has(entity, type))
2023-11-03 19:40:26 +00:00
{
2023-11-08 01:46:44 +00:00
EntitySet.Remove(entity);
return;
2023-11-03 19:40:26 +00:00
}
}
2022-08-17 22:29:38 +00:00
2023-11-08 01:46:44 +00:00
foreach (var type in Signature.Excluded)
2023-01-27 00:34:15 +00:00
{
2023-11-08 01:46:44 +00:00
if (World.Has(entity, type))
{
EntitySet.Remove(entity);
return;
}
2023-01-27 00:34:15 +00:00
}
2023-11-08 01:46:44 +00:00
EntitySet.Add(entity);
2023-11-03 19:40:26 +00:00
}
2023-11-08 01:46:44 +00:00
internal void AddEntity(in Entity entity)
2023-11-03 19:40:26 +00:00
{
2023-11-08 01:46:44 +00:00
EntitySet.Add(entity);
2023-11-03 19:40:26 +00:00
}
2023-11-08 01:46:44 +00:00
internal void RemoveEntity(in Entity entity)
2023-11-03 19:40:26 +00:00
{
2023-11-08 01:46:44 +00:00
EntitySet.Remove(entity);
2023-11-03 19:40:26 +00:00
}
2023-11-08 01:46:44 +00:00
internal void Clear()
2023-11-03 19:40:26 +00:00
{
2023-11-08 01:46:44 +00:00
EntitySet.Clear();
2023-11-03 19:40:26 +00:00
}
public ref struct RandomEntityEnumerator
{
private Filter Filter;
private LinearCongruentialEnumerator LinearCongruentialEnumerator;
public RandomEntityEnumerator GetEnumerator() => this;
internal RandomEntityEnumerator(Filter filter)
{
Filter = filter;
LinearCongruentialEnumerator =
RandomManager.LinearCongruentialSequence(filter.Count);
}
public bool MoveNext() => LinearCongruentialEnumerator.MoveNext();
public Entity Current => Filter.NthEntity(LinearCongruentialEnumerator.Current);
2022-04-08 05:52:03 +00:00
}
2022-03-06 06:12:27 +00:00
}