ordinary_app_hierarchy_query.bend

bendvy-ecs-core@0.1.0.1 · 58 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.1/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.1/ordinary_app_hierarchy.bend as App
4import bendvy-ecs-core@0.1.0.1/ordinary_app_relation.bend as Relation
5import bendvy-ecs-core@0.1.0.1/ordinary_app_composer.bend as Build
6import bendvy-ecs-core@0.1.0.1/ordinary_app_observation_data.bend as DTO
7import bendvy-ecs-core@0.1.0.1/ordinary_app_registration_fields.bend as Fields
8import bendvy-ecs-core@0.1.0.1/relation_types.bend as G
9import bendvy-ecs-core@0.1.0.1/relation_commands.bend as A
10import bendvy-ecs-core@0.1.0.1/hierarchy_traversal_provider.bend as H
11import bendvy-ecs-core@0.1.0.1/hierarchy_provider.bend as Path
12import bendvy-ecs-core@0.1.0.1/hierarchy_traversal.bend as Traversal
13import bendvy-ecs-core@0.1.0.1/ordinary_query_declaration.bend as Query
14import bendvy-ecs-core@0.1.0.1/ordinary_system.bend as System
15import bendvy-ecs-core@0.1.0.1/compose.bend as Q
16import bendvy-ecs-core@0.1.0.1/transaction.bend as Tx
17import bendvy-ecs-core@0.1.0.1/world.bend as W
18
19# Query membership requires a live handle independently of its declaration.
20# Preserve the raw traversal path; this only chooses the query invocation list.
21def live_prepend(~S:Data,~C:Type,~R:Type,~E:Data,selected:Bool,handle:W.Handle<S>,observed:Relation.World(~S,~C,~R,~E) & List<&2,W.Handle<S>>) -> Relation.World(~S,~C,~R,~E) & List<&2,W.Handle<S>>:
22  match selected observed:
23    case True{} Tuple{world,handles}:(world,handle <> handles)
24    case False{} Tuple{world,handles}:(world,handles)
25def live_checked(~S:Data,~C:Type,~R:Type,~E:Data,handle:W.Handle<S>,observed:Relation.World(~S,~C,~R,~E) & Bool,next:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & List<&2,W.Handle<S>>) -> Relation.World(~S,~C,~R,~E) & List<&2,W.Handle<S>>:
26  match observed:
27    case (world,selected):live_prepend(~S,~C,~R,~E,selected,handle,next(world))
28def live_handles(~S:Data,~C:Type,~R:Type,~E:Data,handles:List<&2,W.Handle<S>>,world:Relation.World(~S,~C,~R,~E)) -> Relation.World(~S,~C,~R,~E) & List<&2,W.Handle<S>>:
29  match handles:
30    case []:(world,[])
31    case +handle <> rest:live_checked(~S,~C,~R,~E,handle,W.valid(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,world,handle),world => live_handles(~S,~C,~R,~E,rest,world))
32
33# Keep the hierarchy diagnostic and existing composition result separately.
34# The gameplay callback receives only the retained declaration's opaque owner.
35def executed(~S:Data,~C:Type,~R:Type,~E:Data,~U:Data,~Out:Data,path:Maybe<&2,Path.Path<S>>,result:Q.Executed<Relation.World(~S,~C,~R,~E),Q.Error<U>,Out>) -> Relation.World(~S,~C,~R,~E) & DTO.Product<Maybe<&2,Path.Path<S>>,Maybe<&2,DTO.Product<Tx.Outcome<Q.Error<U>>,List<&2,Out>>>>:
36  match result:
37    case Q.Executed{world,outcome,values}:(world,DTO.Product{path,Some{DTO.Product{outcome,values}}})
38def complete_live(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Arg:Data,~U:Data,~Out:Data,~query:Query.Declaration<S,Q.Frame<S,A.Store<S,C>,R,A.Notice<S,E>>,Ops(Q.Frame<S,A.Store<S,C>,R,A.Notice<S,E>>)>,~body:@-H:Type -> @-caps:Ops(H) -> Arg -> H -> H & (Tx.Outcome<U> & Out),path:Maybe<&2,Path.Path<S>>,args:Arg,cursor:Maybe<&2,Tick.Tick>,observed:Relation.World(~S,~C,~R,~E) & List<&2,W.Handle<S>>) -> Relation.World(~S,~C,~R,~E) & DTO.Product<Maybe<&2,Path.Path<S>>,Maybe<&2,DTO.Product<Tx.Outcome<Q.Error<U>>,List<&2,Out>>>>:
39  executed(~S,~C,~R,~E,~U,~Out,path,Q.reserved(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,~Ops,~Arg,~U,~Out,~System.plan(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,~Ops,~Arg,~U,~Out,~query,~body),~body,args,cursor,observed))
40def selected_path(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Arg:Data,~U:Data,~Out:Data,~query:Query.Declaration<S,Q.Frame<S,A.Store<S,C>,R,A.Notice<S,E>>,Ops(Q.Frame<S,A.Store<S,C>,R,A.Notice<S,E>>)>,~body:@-H:Type -> @-caps:Ops(H) -> Arg -> H -> H & (Tx.Outcome<U> & Out),args:Arg,cursor:Maybe<&2,Tick.Tick>,observed:Relation.World(~S,~C,~R,~E) & Maybe<&2,Path.Path<S>>) -> Relation.World(~S,~C,~R,~E) & DTO.Product<Maybe<&2,Path.Path<S>>,Maybe<&2,DTO.Product<Tx.Outcome<Q.Error<U>>,List<&2,Out>>>>:
41  match observed:
42    case (world,None{}):(world,DTO.Product{None{},None{}})
43    case (world,Some{Path.Incomplete{handles,pending}}):(world,DTO.Product{Some{Path.Incomplete{handles,pending}},None{}})
44    case (world,Some{Path.Complete{+handles}}):complete_live(~S,~C,~R,~E,~Ops,~Arg,~U,~Out,~query,~body,Some{Path.Complete{handles}},args,cursor,live_handles(~S,~C,~R,~E,handles,world))
45# Run a declared query over a complete descendant traversal and return the App.
46# Invalid target yields (None, None); incomplete traversal retains its diagnostic
47# but returns no execution result and invokes no partial gameplay callbacks.
48# For a complete path, revalidate each handle, retain live members in traversal
49# order, then apply the declaration's selectors and opaque-owner body. Preserve
50# the original raw path separately from the execution outcome and output list.
51# Transaction failure rolls back through ordinary query semantics and clears row
52# outputs. args and cursor are supplied for this invocation; this does not register
53# or advance an App reader. Structural commands still require an explicit barrier.
54# Uses only declared capabilities; it does not widen authority to arbitrary graph
55# access. See docs/parity/hierarchy.md, ordinary App descendant-query scenarios.
56def visit_descendants_app(~S:Data,~C:Type,~R:Type,~E:Data,~hierarchy:G.HierarchyDescriptor<S>,~Owners:Type,~Rows:Data,~prior:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,~Ops:Type -> Type,~Arg:Data,~U:Data,~Out:Data,~query:Query.Declaration<S,Q.Frame<S,A.Store<S,C>,R,A.Notice<S,E>>,Ops(Q.Frame<S,A.Store<S,C>,R,A.Notice<S,E>>)>,~body:@-H:Type -> @-caps:Ops(H) -> Arg -> H -> H & (Tx.Outcome<U> & Out),app:App.Application(~S,~C,~R,~E,~hierarchy,~Owners,~Rows,~prior,~fold),target:W.Handle<S>,order:Traversal.Order,args:Arg,cursor:Maybe<&2,Tick.Tick>) -> App.Application(~S,~C,~R,~E,~hierarchy,~Owners,~Rows,~prior,~fold) & DTO.Product<Maybe<&2,Path.Path<S>>,Maybe<&2,DTO.Product<Tx.Outcome<Q.Error<U>>,List<&2,Out>>>>:
57  match app:
58    case Build.Registered{world,owners,recipe,debug}:App.returned(~S,~C,~R,~E,~hierarchy,~Owners,~Rows,~prior,~fold,~DTO.Product<Maybe<&2,Path.Path<S>>,Maybe<&2,DTO.Product<Tx.Outcome<Q.Error<U>>,List<&2,Out>>>>,owners,recipe,debug,selected_path(~S,~C,~R,~E,~Ops,~Arg,~U,~Out,~query,~body,args,cursor,H.lookup_descendants(~S,~C,~R,~E,~hierarchy,world,H.Descendants{target,order})))