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.

112 lines
3.4 KiB

using System;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;
public class Term
{
public Id Id { get; set; }
public TermId? Source { get; set; }
public TermId? Relation { get; set; }
public TermId? Target { get; set; }
public TermInOutKind InOutKind { get; set; }
public TermOperKind OperKind { get; set; }
public IdFlags Flags { get; set; }
public Term() { }
public Term(Id id) => Id = id;
public Term(TermId relation, TermId target)
{ Relation = relation; Target = target; }
public Term None { get { InOutKind = TermInOutKind.None; return this; } }
public Term In { get { InOutKind = TermInOutKind.In; return this; } }
public Term Out { get { InOutKind = TermInOutKind.Out; return this; } }
public Term InOut { get { InOutKind = TermInOutKind.InOut; return this; } }
public Term Or { get { OperKind = TermOperKind.Or; return this; } }
public Term Not { get { OperKind = TermOperKind.Not; return this; } }
public Term Optional { get { OperKind = TermOperKind.Optional; return this; } }
public ecs_term_t ToFlecs(IAllocator allocator) => new() {
id = Id,
src = Source ?.ToFlecs(allocator) ?? default,
first = Relation?.ToFlecs(allocator) ?? default,
second = Target ?.ToFlecs(allocator) ?? default,
inout = (ecs_inout_kind_t)InOutKind,
oper = (ecs_oper_kind_t)OperKind,
id_flags = (ecs_id_t)(ulong)Flags,
};
}
public enum TermInOutKind
{
Default = ecs_inout_kind_t.EcsInOutDefault,
None = ecs_inout_kind_t.EcsInOutNone,
InOut = ecs_inout_kind_t.EcsInOut,
In = ecs_inout_kind_t.EcsIn,
Out = ecs_inout_kind_t.EcsOut,
}
public enum TermOperKind
{
And = ecs_oper_kind_t.EcsAnd,
Or = ecs_oper_kind_t.EcsOr,
Not = ecs_oper_kind_t.EcsNot,
Optional = ecs_oper_kind_t.EcsOptional,
AndFrom = ecs_oper_kind_t.EcsAndFrom,
OrFrom = ecs_oper_kind_t.EcsOrFrom,
NotFrom = ecs_oper_kind_t.EcsNotFrom,
}
public class TermId
{
public static TermId This { get; } = new("$this");
public Entity Id { get; }
public string? Name { get; }
public Entity Traverse { get; set; }
public TermTraversalFlags Flags { get; set; }
public TermId(Entity id)
=> Id = id;
public TermId(string name)
{
if (name[0] == '$') {
Name = name[1..];
Flags = TermTraversalFlags.IsVariable;
} else Name = name;
}
public ecs_term_id_t ToFlecs(IAllocator allocator) => new() {
id = Id,
_name = allocator.AllocateCString(Name),
trav = Traverse,
flags = (ecs_flags32_t)(uint)Flags
};
}
[Flags]
public enum TermTraversalFlags : uint
{
/// <summary> Match on self. </summary>
Self = EcsSelf,
/// <summary> Match by traversing upwards. </summary>
Up = EcsUp,
/// <summary> Match by traversing downwards (derived, cannot be set). </summary>
Down = EcsDown,
/// <summary> Match all entities encountered through traversal. </summary>
TraverseAll = EcsTraverseAll,
/// <summary> Sort results breadth first. </summary>
Cascade = EcsCascade,
/// <summary> Short for up(ChildOf). </summary>
Parent = EcsParent,
/// <summary> Term id is a variable. </summary>
IsVariable = EcsIsVariable,
/// <summary> Term id is an entity. </summary>
IsEntity = EcsIsEntity,
/// <summary> Term id is a name (don't attempt to lookup as entity). </summary>
IsName = EcsIsName,
/// <summary> revent observer from triggering on term. </summary>
Filter = EcsFilter,
}