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.
81 lines
2.3 KiB
81 lines
2.3 KiB
using System; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
using gaemstone.ECS.Utility; |
|
using static flecs_hub.flecs; |
|
|
|
namespace gaemstone.ECS; |
|
|
|
public unsafe class Rule<TContext> |
|
: IDisposable |
|
{ |
|
public World<TContext> World { get; } |
|
public ecs_rule_t* Handle { get; } |
|
public Filter<TContext> Filter { get; } |
|
|
|
private VariableCollection? _variables; |
|
public VariableCollection Variables => _variables ??= new(this); |
|
public Variable? ThisVar => Filter.ThisVar; |
|
|
|
public Rule(World<TContext> 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 RuleIterator<TContext> Iter() |
|
=> new(ecs_rule_iter(World, this)); |
|
|
|
public override string ToString() |
|
=> ecs_rule_str(Handle).FlecsToStringAndFree()!; |
|
|
|
public static implicit operator ecs_rule_t*(Rule<TContext> rule) => rule.Handle; |
|
|
|
|
|
public unsafe class VariableCollection |
|
: IReadOnlyCollection<Variable> |
|
{ |
|
private readonly List<Variable> _variables = new(); |
|
|
|
public int Count => _variables.Count; |
|
public Variable? this[int index] |
|
=> _variables.Find(v => v.Index == index); |
|
public Variable? this[string name] |
|
=> _variables.Find(v => string.Equals( |
|
v.Name, name, StringComparison.OrdinalIgnoreCase)); |
|
|
|
internal VariableCollection(ecs_rule_t* handle) |
|
{ |
|
// Find the $this variable, if the rule has one. |
|
var thisIndex = ecs_filter_find_this_var(ecs_rule_get_filter(handle)); |
|
if (thisIndex >= 0) _variables.Add(new(thisIndex, "this")); |
|
|
|
// Find all the other "accessible" variables. |
|
var count = ecs_rule_var_count(handle); |
|
for (var i = 0; i < count; i++) { |
|
if ((i == thisIndex) || !ecs_rule_var_is_entity(handle, i)) continue; |
|
var name = ecs_rule_var_name(handle, i).FlecsToString()!; |
|
_variables.Add(new(i, name)); |
|
} |
|
} |
|
|
|
// IEnumerable implementation |
|
public IEnumerator<Variable> GetEnumerator() => _variables.GetEnumerator(); |
|
IEnumerator IEnumerable.GetEnumerator() => _variables.GetEnumerator(); |
|
} |
|
} |
|
|
|
public unsafe class RuleIterator<TContext> |
|
: Iterator<TContext> |
|
{ |
|
internal RuleIterator(ecs_iter_t value) |
|
: base(value) { } |
|
public override bool Next() |
|
=> ecs_rule_next(Handle); |
|
}
|
|
|