hierarchy_provider.bend

bendvy-ecs-core@0.1.0.0 · 47 lines · 0 definitions

1import Base
2import entity_key.bend as Key
3import bendvy-ecs-core@0.1.0.0/relation_types.bend as G
4import bendvy-ecs-core@0.1.0.0/relation_graph.bend as Graph
5import bendvy-ecs-core@0.1.0.0/relation_commands.bend as A
6import bendvy-ecs-core@0.1.0.0/relation_reorder.bend as Reorder
7import bendvy-ecs-core@0.1.0.0/relation_providers.bend as Relations
8import bendvy-ecs-core@0.1.0.0/world.bend as W
9import bendvy-ecs-core@0.1.0.0/capabilities.bend as Cap
10import bendvy-ecs-core@0.1.0.0/hierarchy_traversal.bend as T
11
12type Path<S:Data> is Data:
13  Complete{handles:List<&2,W.Handle<S>>}
14  Incomplete{handles:List<&2,W.Handle<S>>,pending:List<&2,W.Handle<S>>}
15type Frame<S:Data> is Data:
16  Frame{entity:W.Handle<S>,parent:Maybe<&2,W.Handle<S>>,children:List<&2,W.Handle<S>>,ancestors:Path<S>,root:Maybe<&2,W.Handle<S>>,depth:Path<S>,breadth:Path<S>}
17type Read<H:Type,S:Data> is Type:
18  Read{lookup:Cap.Request<H,W.Handle<S>,Maybe<&2,Frame<S>>>}
19def path(~S:Data,walk:T.Walk,+namespace:U32) -> Path<S>:
20  match walk:
21    case T.Complete{ids}: Complete{Relations.handle_ids(~S,ids,namespace)}
22    case T.Incomplete{ids,pending}: Incomplete{Relations.handle_ids(~S,ids,namespace),Relations.handle_ids(~S,pending,namespace)}
23def handle(~S:Data,id:Maybe<&2,Key.Key>,namespace:U32) -> Maybe<&2,W.Handle<S>>:
24  match id:
25    case None{}: None{}
26    case Some{id}: Some{W.Handle{namespace,id}}
27def snapshot(~S:Data,+graph:G.Graph<S>,+descriptor:G.Descriptor<S>,target:W.Handle<S>) -> Frame<S>:
28  match target:
29    case W.Handle{+namespace,+id}: Frame{W.Handle{namespace,id},handle(~S,Graph.target(~S,graph,descriptor,id),namespace),Relations.handle_ids(~S,Graph.inverse(~S,graph,descriptor,id),namespace),path(~S,T.ancestors(~S,graph,descriptor,id),namespace),handle(~S,T.root(T.ancestors(~S,graph,descriptor,id),id),namespace),path(~S,T.descendants(~S,graph,descriptor,id,T.Depth{}),namespace),path(~S,T.descendants(~S,graph,descriptor,id,T.Breadth{}),namespace)}
30def store_snapshot(~S:Data,~C:Type,store:A.Store<S,C>,descriptor:G.Descriptor<S>,target:W.Handle<S>) -> A.Store<S,C> & Frame<S>:
31  match store:
32    case A.Store{components,+graph}: (A.Store{components,graph},snapshot(~S,graph,descriptor,target))
33def present(~S:Data,~C:Type,~R:Type,~E:Data,result:W.World<S,A.Store<S,C>,R,A.Notice<S,E>> & Frame<S>) -> W.World<S,A.Store<S,C>,R,A.Notice<S,E>> & Maybe<&2,Frame<S>>:
34  (world,frame) = result
35  (world,Some{frame})
36def checked(~S:Data,~C:Type,~R:Type,~E:Data,~descriptor:G.HierarchyDescriptor<S>,observed:W.World<S,A.Store<S,C>,R,A.Notice<S,E>> & Bool,target:W.Handle<S>) -> W.World<S,A.Store<S,C>,R,A.Notice<S,E>> & Maybe<&2,Frame<S>>:
37  match observed:
38    case (world,False{}): (world,None{})
39    case (world,True{}): present(~S,~C,~R,~E,W.with_store(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,~Frame<S>,store => store_snapshot(~S,~C,store,Reorder.descriptor(~S,descriptor),target),world))
40def lookup(~S:Data,~C:Type,~R:Type,~E:Data,~descriptor:G.HierarchyDescriptor<S>,world:W.World<S,A.Store<S,C>,R,A.Notice<S,E>>,target:W.Handle<S>) -> W.World<S,A.Store<S,C>,R,A.Notice<S,E>> & Maybe<&2,Frame<S>>:
41  match target:
42    case W.Handle{+ns,+id}: checked(~S,~C,~R,~E,~descriptor,W.valid(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,world,W.Handle{ns,id}),W.Handle{ns,id})
43def read(-H:Type,-S:Data,caps:Read<H,S>,owner:H,target:W.Handle<S>) -> H & Maybe<&2,Frame<S>>:
44  match caps:
45    case Read{Cap.Request{get}}: get(owner,target)
46def grant(~S:Data,~C:Type,~R:Type,~E:Data,~descriptor:G.HierarchyDescriptor<S>,~Out:Type,~body:@-H:Type -> Read<H,S> -> W.Handle<S> -> H -> H & Out,target:W.Handle<S>,world:W.World<S,A.Store<S,C>,R,A.Notice<S,E>>) -> W.World<S,A.Store<S,C>,R,A.Notice<S,E>> & Out:
47  body(W.World<S,A.Store<S,C>,R,A.Notice<S,E>>,Read{Cap.Request{lookup(~S,~C,~R,~E,~descriptor)}},target,world)