Alternative managed wrapper around flecs-cs bindings for using the ECS framework Flecs in modern .NET.
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.

77 lines
2.1 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using gaemstone.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;
public unsafe class Rule
: IDisposable
{
public World World { get; }
public ecs_rule_t* Handle { get; }
public Filter Filter { get; }
private VariableCollection? _variables;
public VariableCollection Variables => _variables ??= new(this);
public Iterator.Variable? ThisVar => Filter.ThisVar;
public Rule(World world, FilterDesc desc)
{
using var alloc = TempAllocator.Use();
var flecsDesc = desc.ToFlecs(alloc);
World = world;
Handle = ecs_rule_init(world, &flecsDesc);
Filter = new(World, ecs_rule_get_filter(Handle));
}
public void Dispose()
=> ecs_rule_fini(this);
public Iterator Iter()
=> new(World, IteratorType.Rule, ecs_rule_iter(World, this));
public override string ToString()
=> ecs_rule_str(Handle).FlecsToStringAndFree()!;
public static implicit operator ecs_rule_t*(Rule q) => q.Handle;
public unsafe class VariableCollection
: IReadOnlyCollection<Iterator.Variable>
{
private readonly List<Iterator.Variable> _variables = new();
public Rule Rule { get; }
public int Count => _variables.Count;
public Iterator.Variable? this[int index]
=> _variables.Find(v => v.Index == index);
public Iterator.Variable? this[string name]
=> _variables.Find(v => string.Equals(
v.Name, name, StringComparison.OrdinalIgnoreCase));
internal VariableCollection(Rule rule)
{
Rule = rule;
// Find the $This variable, if the rule has one.
var thisIndex = ecs_filter_find_this_var(ecs_rule_get_filter(Rule));
if (thisIndex >= 0) _variables.Add(new(thisIndex, "This"));
// Find all the other "accessible" variables.
var count = ecs_rule_var_count(Rule);
for (var i = 0; i < count; i++) {
if ((i == thisIndex) || !ecs_rule_var_is_entity(Rule, i)) continue;
var name = ecs_rule_var_name(Rule, i).FlecsToString()!;
_variables.Add(new(i, name));
}
}
// IEnumerable implementation
public IEnumerator<Iterator.Variable> GetEnumerator() => _variables.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _variables.GetEnumerator();
}
}