execution_relation_interpreter.bend
bendvy-ecs-core@0.1.0.3 · 57 lines · 12 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/entity_allocator.bend as A
3import bendvy-ecs-core@0.1.0.3/entity_key.bend as K
4import bendvy-ecs-core@0.1.0.3/world.bend as W
5import bendvy-ecs-core@0.1.0.3/relation_types.bend as T
6import bendvy-ecs-core@0.1.0.3/relation_graph.bend as Graph
7import bendvy-ecs-core@0.1.0.3/relation_reorder_core.bend as Reorder
8import bendvy-ecs-core@0.1.0.3/execution_relation_operation.bend as O
9
10
11
12def live_namespace(~S:Data,same:Bool,allocator:A.Allocator,handle:W.Handle<S>) -> A.Allocator & Bool:
13 match same:
14 case False{}:(allocator,False{})
15 case True{}:A.checked(allocator,W.handle_key(~S,handle),1)
16def live(~S:Data,+namespace:U32,allocator:A.Allocator,+handle:W.Handle<S>) -> A.Allocator & Bool:
17 match handle:
18 case W.Handle{ns,key}:live_namespace(~S,U32.is_eq(namespace,ns),allocator,W.Handle{ns,key})
19def result(~S:Data,operation:O.Operation<S>,checked:T.CoreResult<S>) -> O.Outcome<S>:
20 match checked:
21 case T.CoreResult{graph,None{}}:O.Applied{graph,operation}
22 case T.CoreResult{graph,Some{error}}:O.Refused{graph,operation,O.RelationError{error}}
23def relate_target(~S:Data,graph:T.Graph<S>,descriptor:T.Descriptor<S>,+source:W.Handle<S>,+target:W.Handle<S>,sourceLive:Bool,checked:A.Allocator & Bool) -> A.Allocator & O.Outcome<S>:
24 match checked:
25 case (allocator,targetLive):(allocator,result(~S,O.Relate{source,target},Graph.relate(~S,graph,descriptor,W.handle_key(~S,source),W.handle_key(~S,target),sourceLive,targetLive)))
26def relate_source(~S:Data,+namespace:U32,graph:T.Graph<S>,descriptor:T.Descriptor<S>,source:W.Handle<S>,+target:W.Handle<S>,checked:A.Allocator & Bool) -> A.Allocator & O.Outcome<S>:
27 match checked:
28 case (allocator,sourceLive):relate_target(~S,graph,descriptor,source,target,sourceLive,live(~S,namespace,allocator,target))
29def unrelate_checked(~S:Data,graph:T.Graph<S>,descriptor:T.Descriptor<S>,+source:W.Handle<S>,checked:A.Allocator & Bool) -> A.Allocator & O.Outcome<S>:
30 match checked:
31 case (allocator,False{}):(allocator,O.Refused{graph,O.Unrelate{source},O.RelationError{T.MissingEntity{W.handle_key(~S,source)}}})
32 case (allocator,True{}):(allocator,O.Applied{Graph.unrelate(~S,graph,descriptor,W.handle_key(~S,source)),O.Unrelate{source}})
33def child_next(key:K.Key,reversed:List<&2,T.ChildStatus>,next:A.Allocator -> List<&2,T.ChildStatus> -> A.Allocator & List<&2,T.ChildStatus>,checked:A.Allocator & Bool) -> A.Allocator & List<&2,T.ChildStatus>:
34 match checked:
35 case (allocator,isLive):next(allocator,T.ChildStatus{key,isLive} <> reversed)
36def children_checked(~S:Data,+namespace:U32,children:List<&2,W.Handle<S>>,allocator:A.Allocator,reversed:List<&2,T.ChildStatus>) -> A.Allocator & List<&2,T.ChildStatus>:
37 match children:
38 case []:(allocator,List.reverse(&2,T.ChildStatus,reversed))
39 case +child <> rest:child_next(W.handle_key(~S,child),reversed,allocator => reversed => children_checked(~S,namespace,rest,allocator,reversed),live(~S,namespace,allocator,child))
40def reorder_children(~S:Data,graph:T.Graph<S>,descriptor:T.Descriptor<S>,+parent:W.Handle<S>,+children:List<&2,W.Handle<S>>,parentLive:Bool,checked:A.Allocator & List<&2,T.ChildStatus>) -> A.Allocator & O.Outcome<S>:
41 match checked:
42 case (allocator,statuses):(allocator,result(~S,O.Reorder{parent,children},Reorder.reorder(~S,graph,descriptor,W.handle_key(~S,parent),statuses,parentLive)))
43def reorder_parent(~S:Data,namespace:U32,graph:T.Graph<S>,descriptor:T.Descriptor<S>,parent:W.Handle<S>,+children:List<&2,W.Handle<S>>,checked:A.Allocator & Bool) -> A.Allocator & O.Outcome<S>:
44 match checked:
45 case (allocator,parentLive):reorder_children(~S,graph,descriptor,parent,children,parentLive,children_checked(~S,namespace,children,allocator,[]))
46def reorder(~S:Data,+namespace:U32,allocator:A.Allocator,graph:T.Graph<S>,descriptor:T.Descriptor<S>,+parent:W.Handle<S>,children:List<&2,W.Handle<S>>) -> A.Allocator & O.Outcome<S>:
47 match descriptor:
48 case T.Descriptor{key,name,inverse,T.Ordinary{}}:(allocator,O.Refused{graph,O.Reorder{parent,children},O.HierarchyRequired{}})
49 case T.Descriptor{key,name,inverse,T.Hierarchy{}}:reorder_parent(~S,namespace,graph,T.Descriptor{key,name,inverse,T.Hierarchy{}},parent,children,live(~S,namespace,allocator,parent))
50
51
52
53def apply(~S:Data,~descriptor:T.Descriptor<S>,+namespace:U32,allocator:A.Allocator,graph:T.Graph<S>,operation:O.Operation<S>) -> A.Allocator & O.Outcome<S>:
54 match operation:
55 case O.Relate{+source,target}:relate_source(~S,namespace,graph,descriptor,source,target,live(~S,namespace,allocator,source))
56 case O.Unrelate{+source}:unrelate_checked(~S,graph,descriptor,source,live(~S,namespace,allocator,source))
57 case O.Reorder{parent,children}:reorder(~S,namespace,allocator,graph,descriptor,parent,children)