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.

98 lines
2.5 KiB

2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using gaemstone.Utility;
2 years ago
using static flecs_hub.flecs;
namespace gaemstone.ECS;
public unsafe partial class Iterator
2 years ago
: IEnumerable<Iterator>
{
public Universe Universe { get; }
public IteratorType? Type { get; }
public ecs_iter_t Value;
public int Count => Value.count;
public TimeSpan DeltaTime => TimeSpan.FromSeconds(Value.delta_time);
public TimeSpan DeltaSystemTime => TimeSpan.FromSeconds(Value.delta_system_time);
public Iterator(Universe universe, IteratorType? type, ecs_iter_t value)
{ Universe = universe; Type = type; Value = value; }
// TODO: ecs_iter_set_var(world, 0, ent) to run a query for a known entity.
public static Iterator FromTerm(Universe universe, Term term)
2 years ago
{
using var alloc = TempAllocator.Lock();
var flecsTerm = term.ToFlecs(alloc);
var flecsIter = ecs_term_iter(universe, &flecsTerm);
return new(universe, IteratorType.Term, flecsIter);
2 years ago
}
public bool Next()
{
fixed (ecs_iter_t* ptr = &Value)
return Type switch {
IteratorType.Term => ecs_term_next(ptr),
IteratorType.Filter => ecs_filter_next(ptr),
IteratorType.Query => ecs_query_next(ptr),
IteratorType.Rule => ecs_rule_next(ptr),
_ => ecs_iter_next(ptr),
};
}
public EntityRef Entity(int index)
=> new(Universe, new(Value.entities[index]));
2 years ago
public Span<T> Field<T>(int index)
where T : unmanaged
{
fixed (ecs_iter_t* ptr = &Value) {
var size = (ulong)Unsafe.SizeOf<T>();
var pointer = ecs_field_w_size(ptr, size, index);
return new Span<T>(pointer, Count);
}
}
public Span<T> MaybeField<T>(int index)
where T : unmanaged => FieldIsSet(index) ? Field<T>(index) : default;
2 years ago
public SpanToRef<T> FieldRef<T>(int index)
where T : class => new(Field<nint>(index));
public bool FieldIsSet(int index)
{
fixed (ecs_iter_t* ptr = &Value)
return ecs_field_is_set(ptr, index);
}
public bool FieldIs<T>(int index)
{
fixed (ecs_iter_t* ptr = &Value) {
var id = ecs_field_id(ptr, index);
var comp = Universe.LookupOrThrow<T>();
return id == comp.Entity.Value.Data;
2 years ago
}
}
public override string ToString()
2 years ago
{
fixed (ecs_iter_t* ptr = &Value)
return ecs_iter_str(ptr).FlecsToStringAndFree()!;
2 years ago
}
// IEnumerable implementation
public IEnumerator<Iterator> GetEnumerator() { while (Next()) yield return this; }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public enum IteratorType
{
Term,
Filter,
Query,
Rule,
}