Add support for iterator variables

- Add Iterator.Variable
- Add Iterator.GetVar and .SetVar methods
- Add ThisVar to Filter, Query and Rule
- Add Rule.Variables, shows all its variables
- Remove Iterator.SetThis
wip/bindgen
copygirl 1 year ago
parent 1fa1fa4a3c
commit f9fa808d68
  1. 8
      src/gaemstone.ECS/Filter.cs
  2. 29
      src/gaemstone.ECS/Iterator.cs
  3. 4
      src/gaemstone.ECS/Query.cs
  4. 45
      src/gaemstone.ECS/Rule.cs

@ -12,6 +12,14 @@ public unsafe class Filter
public World World { get; }
public ecs_filter_t* Handle { get; }
public Iterator.Variable? ThisVar { get {
var index = ecs_filter_find_this_var(this);
return (index >= 0) ? new(index, "This") : null;
} }
internal Filter(World world, ecs_filter_t* handle)
{ World = world; Handle = handle; }
public Filter(World world, FilterDesc desc)
{
using var alloc = TempAllocator.Use();

@ -31,13 +31,6 @@ public unsafe class Iterator
return new(world, IteratorType.Term, flecsIter);
}
public Iterator SetThis(Entity entity)
{
fixed (ecs_iter_t* ptr = &Value)
ecs_iter_set_var(ptr, 0, entity);
return this;
}
public void Dispose()
{
// When an iterator is iterated until completion,
@ -47,6 +40,19 @@ public unsafe class Iterator
ecs_iter_fini(ptr);
}
public EntityRef GetVar(Variable var)
{
fixed (ecs_iter_t* ptr = &Value)
return new(World, new(ecs_iter_get_var(ptr, var.Index)));
}
public Iterator SetVar(Variable var, Entity entity)
{
fixed (ecs_iter_t* ptr = &Value)
ecs_iter_set_var(ptr, var.Index, entity);
return this;
}
public bool Next()
{
fixed (ecs_iter_t* ptr = &Value) {
@ -113,6 +119,15 @@ public unsafe class Iterator
// IEnumerable implementation
public IEnumerator<Iterator> GetEnumerator() { while (Next()) yield return this; }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public class Variable
{
public int Index { get; }
public string Name { get; }
public Variable(int index, string name)
{ Index = index; Name = name; }
}
}
public enum IteratorType

@ -9,6 +9,9 @@ public unsafe class Query
{
public World World { get; }
public ecs_query_t* Handle { get; }
public Filter Filter { get; }
public Iterator.Variable? ThisVar => Filter.ThisVar;
public Query(World world, QueryDesc desc)
{
@ -16,6 +19,7 @@ public unsafe class Query
var flecsDesc = desc.ToFlecs(alloc);
World = world;
Handle = ecs_query_init(world, &flecsDesc);
Filter = new(world, ecs_query_get_filter(Handle));
}
public void Dispose()

@ -1,4 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using gaemstone.Utility;
using static flecs_hub.flecs;
@ -9,6 +11,11 @@ public unsafe class Rule
{
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)
{
@ -16,6 +23,7 @@ public unsafe class Rule
var flecsDesc = desc.ToFlecs(alloc);
World = world;
Handle = ecs_rule_init(world, &flecsDesc);
Filter = new(World, ecs_rule_get_filter(Handle));
}
public void Dispose()
@ -28,4 +36,41 @@ public unsafe class Rule
=> 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();
}
}

Loading…
Cancel
Save