execution_query.bend
bendvy-ecs-core@0.1.0.3 · 211 lines · 63 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/execution_effects.bend as Effects
3import bendvy-ecs-core@0.1.0.3/execution_query_identity.bend as Index
4import bendvy-ecs-core@0.1.0.3/execution_query_domain.bend as Domain
5import bendvy-ecs-core@0.1.0.3/execution_lifecycle_notices.bend as Notice
6import bendvy-ecs-core@0.1.0.3/chunk_column.bend as Col
7import bendvy-ecs-core@0.1.0.3/chunk_query.bend as Q
8import bendvy-ecs-core@0.1.0.3/execution_state.bend as State
9import bendvy-ecs-core@0.1.0.3/execution_declaration.bend as D
10import bendvy-ecs-core@0.1.0.3/execution_projection.bend as Projection
11import bendvy-ecs-core@0.1.0.3/ordinary_declaration.bend as Identity
12import bendvy-ecs-core@0.1.0.3/owner_product.bend as Product
13import bendvy-ecs-core@0.1.0.3/world.bend as W
14import bendvy-ecs-core@0.1.0.3/change_tick.bend as Tick
15import bendvy-ecs-core@0.1.0.3/lifecycle.bend as Life
16import bendvy-ecs-core@0.1.0.3/execution_composer_layout.bend as Layout
17import bendvy-ecs-core@0.1.0.3/execution_query_recipe.bend as Recipe
18
19type Mode is Data:
20 AllRows{}
21 Where{filter:Life.Filter}
22def selection(mode:Mode,indices:List<&2,U32>,prior:Maybe<&2,Tick.Tick>) -> Q.Selection:
23 match mode:
24 case AllRows{}:Q.Selected{indices}
25 case Where{filter}:Q.Filtered{indices,filter,prior}
26type Report<-E:Data> is Data:
27 Completed{errors:List<&2,Q.Error<E>>}
28 LayoutRefused{}
29type Each<-S:Data,-H:Type,-E:Data> is Type:
30 Each{run:H -> H & Report<E>}
31def Ops(~S:Data,~E:Data,H:Type) -> Type: Each<S,H,E>
32def logical_errors(~E:Data,errors:List<&2,Q.Error<E>>) -> List<&2,Q.Error<E>>:
33 match errors:
34 case []:[]
35 case Q.Error{index,value} <> rest:Q.Error{U32.add(index,1),value} <> logical_errors(~E,rest)
36def logical_body(~A:Type,~B:Type,~V:Data,~E:Data,~body:U32 -> V -> B -> B & Maybe<&2,E>,index:U32,view:V,owner:B) -> B & Maybe<&2,E>:
37 body(U32.add(index,1),view,owner)
38def view_namespace(~S:Data,view:Notice.View<S>) -> U32:
39 match view:
40 case Notice.View{namespace,_,_}:namespace
41def report(~E:Data,errors:List<&2,Q.Error<E>>,aligned:Bool) -> Report<E>:
42 match aligned:
43 case True{}: Completed{logical_errors(~E,errors)}
44 case False{}: LayoutRefused{}
45def returned(~S:Data,~C:Type,~R:Type,~A:Type,~B:Type,~Rest:Type,~E:Data,~lens:Product.Lens<C,Product.Owner<Col.Column<S,A>,Col.Column<S,B>>,Rest>,rest:Rest,resource:R,handles:List<&2,W.Handle<S>>,tick:Tick.Tick,prior:Maybe<&2,Tick.Tick>,result:Q.Run<S,A,B,E>,+lifecycleView:Notice.View<S>) -> State.Scope<S,C,R> & Report<E>:
46 match result:
47 case Q.Run{read,write,errors,aligned}: (State.Scope{Product.put_field(~C,~Product.Owner<Col.Column<S,A>,Col.Column<S,B>>,~Rest,lens)(rest,Product.Owner{read,write}),resource,handles,tick,prior,lifecycleView},report(~E,errors,aligned))
48def taken(~S:Data,~C:Type,~R:Type,~A:Type,~B:Type,~Rest:Type,~V:Data,~E:Data,~lens:Product.Lens<C,Product.Owner<Col.Column<S,A>,Col.Column<S,B>>,Rest>,~project:A -> A & V,~body:U32 -> V -> B -> B & Maybe<&2,E>,+mode:Mode,resource:R,+handles:List<&2,W.Handle<S>>,+tick:Tick.Tick,+prior:Maybe<&2,Tick.Tick>,+selected:List<&2,U32>,result:Rest & Product.Owner<Col.Column<S,A>,Col.Column<S,B>>,+lifecycleView:Notice.View<S>) -> State.Scope<S,C,R> & Report<E>:
49 match result:
50 case Tuple{rest,Product.Owner{read,write}}:returned(~S,~C,~R,~A,~B,~Rest,~E,~lens,rest,resource,handles,tick,prior,Q.selected(~S,~A,~B,~V,~E,~project,~logical_body(~A,~B,~V,~E,~body),read,write,0,tick,selection(mode,selected,prior)),lifecycleView)
51def invoke_targets(~S:Data,~C:Type,~R:Type,~A:Type,~B:Type,~Rest:Type,~V:Data,~E:Data,~lens:Product.Lens<C,Product.Owner<Col.Column<S,A>,Col.Column<S,B>>,Rest>,~project:A -> A & V,~body:U32 -> V -> B -> B & Maybe<&2,E>,mode:Mode,scope:State.Scope<S,C,R>,targets:Index.TargetCheck<S>) -> State.Scope<S,C,R> & Report<E>:
52 match scope targets:
53 case State.Scope{store,resource,handles,tick,prior,+lifecycleView} Index.Targets{_,Domain.Domain{selected}}: taken(~S,~C,~R,~A,~B,~Rest,~V,~E,~lens,~project,~body,mode,resource,handles,tick,prior,selected,Product.get_field(~C,~Product.Owner<Col.Column<S,A>,Col.Column<S,B>>,~Rest,lens)(store),lifecycleView)
54 case scope Index.Refused{_}:(scope,LayoutRefused{})
55def invoke(~S:Data,~C:Type,~R:Type,~A:Type,~B:Type,~Rest:Type,~V:Data,~E:Data,~lens:Product.Lens<C,Product.Owner<Col.Column<S,A>,Col.Column<S,B>>,Rest>,~project:A -> A & V,~body:U32 -> V -> B -> B & Maybe<&2,E>,mode:Mode,scope:State.Scope<S,C,R>) -> State.Scope<S,C,R> & Report<E>:
56 match scope:
57 case State.Scope{store,resource,+handles,tick,prior,+lifecycleView}:invoke_targets(~S,~C,~R,~A,~B,~Rest,~V,~E,~lens,~project,~body,mode,State.Scope{store,resource,handles,tick,prior,lifecycleView},Index.targets(~S,view_namespace(~S,lifecycleView),handles))
58def declaration(~S:Data,~C:Type,~R:Type,~A:Type,~B:Type,~Rest:Type,~V:Data,~E:Data,~lens:Product.Lens<C,Product.Owner<Col.Column<S,A>,Col.Column<S,B>>,Rest>,~project:A -> A & V,~body:U32 -> V -> B -> B & Maybe<&2,E>,_:Projection.Affine<A,V,project>,mode:Mode,read:Identity.Declaration<S,A>,write:Identity.Declaration<S,B>) -> D.Declaration<S,C,R,Ops(~S,~E)>:
59 D.Declaration{Each{invoke(~S,~C,~R,~A,~B,~Rest,~V,~E,~lens,~project,~body,mode)},[D.Access{Identity.key(~S,~A,read),D.ComponentAccess{},D.Exclusive{},D.ReadOnly{}},D.Access{Identity.key(~S,~B,write),D.ComponentAccess{},D.Exclusive{},D.Writable{}}]}
60def each(~S:Data,~H:Type,~E:Data,cap:Each<S,H,E>) -> H -> H & Report<E>:
61 match cap:
62 case Each{run}: run
63
64def layout_unwrapped(~S:Data,~layout:Layout.Layout,~route:Layout.Route,rest:Layout.subtree_rest(~S,layout,route),selected:Layout.query_pair(~S,~layout,~route)) -> Layout.subtree_rest(~S,layout,route) & Product.Owner<Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}})>,Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}})>>:
65 match selected:
66 case Product.Owner{Layout.ColumnSlot{read},Layout.ColumnSlot{write}}: (rest,Product.Owner{read,write})
67def layout_selected(~S:Data,~layout:Layout.Layout,~route:Layout.Route,~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},result:Layout.subtree_rest(~S,layout,route) & Layout.columns(~S,Layout.subtree(layout,route))) -> Layout.subtree_rest(~S,layout,route) & Product.Owner<Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}})>,Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}})>>:
68 match result:
69 case (rest,selected): layout_unwrapped(~S,~layout,~route,rest,Layout.checked_owner(Layout.columns(~S,Layout.subtree(layout,route)),Layout.query_pair(~S,~layout,~route),shape,selected))
70def layout_take(~S:Data,~C:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},owner:C) -> Layout.subtree_rest(~S,layout,route) & Product.Owner<Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}})>,Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}})>>:
71 layout_selected(~S,~layout,~route,~shape,Layout.subtree_take(~S,layout,route,Layout.checked_owner(C,Layout.columns(~S,layout),same,owner)))
72def layout_put(~S:Data,~C:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},rest:Layout.subtree_rest(~S,layout,route),selected:Product.Owner<Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}})>,Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}})>>) -> C:
73 match selected:
74 case Product.Owner{read,write}: Layout.checked_owner(Layout.columns(~S,layout),C,Equal.sym(Type,C,Layout.columns(~S,layout),same),Layout.subtree_put(~S,layout,route,rest,Layout.checked_owner(Layout.query_pair(~S,~layout,~route),Layout.columns(~S,Layout.subtree(layout,route)),Equal.sym(Type,Layout.columns(~S,Layout.subtree(layout,route)),Layout.query_pair(~S,~layout,~route),shape),Product.Owner{Layout.ColumnSlot{read},Layout.ColumnSlot{write}})))
75def layout_lens(~S:Data,~C:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type}) -> Product.Lens<C,Product.Owner<Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}})>,Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}})>>,Layout.subtree_rest(~S,layout,route)>:
76 Product.Lens{layout_take(~S,~C,~layout,~route,~same,~shape),layout_put(~S,~C,~layout,~route,~same,~shape)}
77def layout_body(~layout:Layout.Layout,~route:Layout.Route,~E:Data,~body:U32 -> Layout.query_view(layout,route) -> Layout.query_output(layout,route) -> Layout.query_output(layout,route) & Maybe<&2,E>,index:U32,view:Layout.query_view(layout,route),owner:Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}})) -> Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}) & Maybe<&2,E>:
78 Layout.rewrite(~Layout.subtree(layout,route),~Layout.InRight{Layout.AtLeaf{}},Maybe<&2,E>,body(index,view),owner)
79def layout_declaration(~S:Data,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~valid:{Layout.query_valid(~layout,~route) == True{} : Bool},~E:Data,~body:U32 -> Layout.query_view(layout,route) -> Layout.query_output(layout,route) -> Layout.query_output(layout,route) & Maybe<&2,E>,mode:Mode) -> D.Declaration<S,C,R,Ops(~S,~E)>:
80 declaration(~S,~C,~R,~Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}}),~Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),~Layout.subtree_rest(~S,layout,route),~Layout.query_view(layout,route),~E,~layout_lens(~S,~C,~layout,~route,~same,~shape),~Layout.read(~Layout.query_input(layout,route),~Layout.query_view(layout,route)),~layout_body(~layout,~route,~E,~body),Projection.trusted_affine(~Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}}),~Layout.query_view(layout,route),~Layout.read(~Layout.query_input(layout,route),~Layout.query_view(layout,route))),mode,Identity.component(~S,~Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}}),Layout.query_read_key(layout,route)),Identity.component(~S,~Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),Layout.query_write_key(layout,route)))
81
82
83
84def OutputBody(~S:Data,~layout:Layout.Layout,~route:Layout.Route,~O:Type,~E:Data) -> Type:
85 W.Handle<S> -> Layout.query_view(layout,route) -> Layout.query_output(layout,route) -> O -> Layout.query_output(layout,route) & (O & Maybe<&2,E>)
86type OutputEach<-S:Data,-H:Type,-O:Type,-E:Data> is Type:
87 OutputEach{run:H -> O -> H & (O & Report<E>)}
88def OutputOps(~S:Data,~O:Type,~E:Data,H:Type) -> Type:OutputEach<S,H,O,E>
89def handle_choice(~S:Data,handle:W.Handle<S>,rest:Maybe<&2,W.Handle<S>>,same:Bool) -> Maybe<&2,W.Handle<S>>:
90 match same:
91 case True{}:Some{handle}
92 case False{}:rest
93def selected_handle(~S:Data,+index:U32,handles:List<&2,W.Handle<S>>) -> Maybe<&2,W.Handle<S>>:
94 match handles:
95 case []:None{}
96 case +handle <> rest:handle_choice(~S,handle,selected_handle(~S,index,rest),U32.is_eq(U32.add(index,1),W.handle_index(~S,handle)))
97def output_body_found(~S:Data,~layout:Layout.Layout,~route:Layout.Route,~O:Type,~E:Data,~body:OutputBody(~S,~layout,~route,~O,~E),view:Layout.query_view(layout,route),owner:Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),output:O,found:Maybe<&2,W.Handle<S>>) -> Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}) & (O & Maybe<&2,E>):
98 match found:
99 case None{}:(owner,(output,None{}))
100 case Some{handle}:Layout.rewrite(~Layout.subtree(layout,route),~Layout.InRight{Layout.AtLeaf{}},O & Maybe<&2,E>,payload=>body(handle,view,payload,output),owner)
101def output_body(~S:Data,~layout:Layout.Layout,~route:Layout.Route,~O:Type,~E:Data,~body:OutputBody(~S,~layout,~route,~O,~E),handles:List<&2,W.Handle<S>>,index:U32,view:Layout.query_view(layout,route),owner:Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),output:O) -> Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}) & (O & Maybe<&2,E>):
102 output_body_found(~S,~layout,~route,~O,~E,~body,view,owner,output,selected_handle(~S,index,handles))
103def output_returned(~S:Data,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~O:Type,~E:Data,rest:Layout.subtree_rest(~S,layout,route),resource:R,handles:List<&2,W.Handle<S>>,tick:Tick.Tick,prior:Maybe<&2,Tick.Tick>,result:Q.OutputRun<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}}),Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),O,E>,+lifecycleView:Notice.View<S>) -> State.Scope<S,C,R> & (O & Report<E>):
104 match result:
105 case Q.OutputRun{read,write,output,errors,aligned}:(State.Scope{layout_put(~S,~C,~layout,~route,~same,~shape,rest,Product.Owner{read,write}),resource,handles,tick,prior,lifecycleView},(output,report(~E,errors,aligned)))
106def output_taken(~S:Data,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~O:Type,~E:Data,~body:OutputBody(~S,~layout,~route,~O,~E),output:O,resource:R,+handles:List<&2,W.Handle<S>>,+tick:Tick.Tick,+prior:Maybe<&2,Tick.Tick>,+mode:Mode,+selected:List<&2,U32>,result:Layout.subtree_rest(~S,layout,route) & Product.Owner<Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}})>,Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}})>>,+lifecycleView:Notice.View<S>) -> State.Scope<S,C,R> & (O & Report<E>):
107 match result:
108 case (rest,Product.Owner{read,write}):output_returned(~S,~C,~R,~layout,~route,~same,~shape,~O,~E,rest,resource,handles,tick,prior,Q.with_output(~S,~Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}}),~Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),~O,~Layout.query_view(layout,route),~List<&2,W.Handle<S>>,~E,~Layout.read(~Layout.query_input(layout,route),~Layout.query_view(layout,route)),~output_body(~S,~layout,~route,~O,~E,~body),handles,read,write,output,0,tick,selection(mode,selected,prior)),lifecycleView)
109def output_invoke_targets(~S:Data,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~O:Type,~E:Data,~body:OutputBody(~S,~layout,~route,~O,~E),mode:Mode,scope:State.Scope<S,C,R>,output:O,targets:Index.TargetCheck<S>) -> State.Scope<S,C,R> & (O & Report<E>):
110 match scope targets:
111 case State.Scope{store,resource,handles,tick,prior,+lifecycleView} Index.Targets{_,Domain.Domain{selected}}:output_taken(~S,~C,~R,~layout,~route,~same,~shape,~O,~E,~body,output,resource,handles,tick,prior,mode,selected,layout_take(~S,~C,~layout,~route,~same,~shape,store),lifecycleView)
112 case scope Index.Refused{_}:(scope,(output,LayoutRefused{}))
113def output_invoke(~S:Data,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~O:Type,~E:Data,~body:OutputBody(~S,~layout,~route,~O,~E),mode:Mode,scope:State.Scope<S,C,R>,output:O) -> State.Scope<S,C,R> & (O & Report<E>):
114 match scope:
115 case State.Scope{store,resource,+handles,tick,prior,+lifecycleView}:output_invoke_targets(~S,~C,~R,~layout,~route,~same,~shape,~O,~E,~body,mode,State.Scope{store,resource,handles,tick,prior,lifecycleView},output,Index.targets(~S,view_namespace(~S,lifecycleView),handles))
116def output_declaration(~S:Data,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~valid:{Layout.query_valid(~layout,~route) == True{} : Bool},~O:Type,~E:Data,~body:OutputBody(~S,~layout,~route,~O,~E),mode:Mode) -> D.Declaration<S,C,R,OutputOps(~S,~O,~E)>:
117 D.Declaration{OutputEach{output_invoke(~S,~C,~R,~layout,~route,~same,~shape,~O,~E,~body,mode)},[D.Access{Layout.query_read_key(layout,route),D.ComponentAccess{},D.Exclusive{},D.ReadOnly{}},D.Access{Layout.query_write_key(layout,route),D.ComponentAccess{},D.Exclusive{},D.Writable{}}]}
118def each_output(~S:Data,~H:Type,~O:Type,~E:Data,cap:OutputEach<S,H,O,E>) -> H -> O -> H & (O & Report<E>):
119 match cap:
120 case OutputEach{run}:run
121
122type GeneralRow<-S:Data,-V:Data> is Data:
123 GeneralRow{handle:W.Handle<S>,view:Maybe<&2,V>}
124type GeneralLookup<-V:Data> is Data:
125 MissingEntity{}
126 NotMatched{}
127 LookupRefused{}
128 Matched{view:Maybe<&2,V>}
129type GeneralReport<-S:Data,-V:Data> is Data:
130 SelectedRows{rows:List<&2,GeneralRow<S,V>>}
131 SelectionRefused{}
132type GeneralCount is Data:
133 CountSelectionRefused{}
134 SelectedCount{count:U32}
135type GeneralSingle<-S:Data,-V:Data> is Data:
136 SingleSelectionRefused{}
137 NoSelectedRow{}
138 OneSelectedRow{row:GeneralRow<S,V>}
139 MultipleSelectedRows{}
140def general_rows_count(~S:Data,~V:Data,rows:List<&2,GeneralRow<S,V>>) -> U32:
141 match rows:
142 case []:0
143 case _ <> rest:U32.add(1,general_rows_count(~S,~V,rest))
144def general_count(~S:Data,~V:Data,report:GeneralReport<S,V>) -> GeneralCount:
145 match report:
146 case SelectionRefused{}:CountSelectionRefused{}
147 case SelectedRows{rows}:SelectedCount{general_rows_count(~S,~V,rows)}
148def general_rows_single(~S:Data,~V:Data,rows:List<&2,GeneralRow<S,V>>) -> GeneralSingle<S,V>:
149 match rows:
150 case []:NoSelectedRow{}
151 case row <> []:OneSelectedRow{row}
152 case _ <> _ <> _:MultipleSelectedRows{}
153def general_single(~S:Data,~V:Data,report:GeneralReport<S,V>) -> GeneralSingle<S,V>:
154 match report:
155 case SelectionRefused{}:SingleSelectionRefused{}
156 case SelectedRows{rows}:general_rows_single(~S,~V,rows)
157type GeneralReader<-S:Data,-H:Type,-V:Data> is Type:
158 GeneralReader{query:H -> H & GeneralReport<S,V>,get:H -> W.Handle<S> -> H & GeneralLookup<V>}
159 UnsupportedReader{}
160type GeneralEdit<-P:Type,-Out:Type> is Type:
161 GeneralEdited{output:Out}
162 GeneralUnchanged{unused:P -> P & Out}
163type GeneralTargets<-S:Data> is Data:
164 AllMatched{}
165 ExplicitHandles{handles:List<&2,W.Handle<S>>}
166type GeneralWriter<-S:Data,-H:Type,-P:Type,-V:Data> is Type:
167 GeneralWriter{read:GeneralReader<S,H,V>,modify:@-Out:Type -> H -> W.Handle<S> -> (P -> P & Out) -> H & GeneralEdit<P,Out>}
168 UnsupportedWriter{}
169type GeneralOutputWriter<-S:Data,-H:Type,-P:Type,-V:Data,-O:Type,-E:Data> is Type:
170 GeneralOutputWriter{read:GeneralReader<S,H,V>,modify:@-Out:Type -> H -> W.Handle<S> -> (P -> P & Out) -> H & GeneralEdit<P,Out>,traverse:Mode -> H -> O -> GeneralTargets<S> -> H & (O & Report<E>)}
171 UnsupportedOutputWriter{}
172def GeneralOutputOps(~S:Data,~P:Type,~V:Data,~O:Type,~E:Data,H:Type) -> Type:
173 GeneralOutputWriter<S,H,P,V,O,E>
174def general_traverse(~S:Data,~H:Type,~P:Type,~V:Data,~O:Type,~E:Data,writer:GeneralOutputWriter<S,H,P,V,O,E>,mode:Mode,scope:H,output:O,targets:GeneralTargets<S>) -> H & (O & Report<E>):
175 match writer:
176 case GeneralOutputWriter{_,_,traverse}:traverse(mode,scope,output,targets)
177 case UnsupportedOutputWriter{}:(scope,(output,LayoutRefused{}))
178def GeneralOps(~S:Data,~P:Type,~V:Data,kind:Recipe.QueryKind,H:Type) -> Type:
179 match kind:
180 case Recipe.ReadRows{}:GeneralReader<S,H,V>
181 case Recipe.WriteRows{}:GeneralWriter<S,H,P,V>
182
183def SequentialOutputBody(~S:Data,~Permit:Data,~F:Type -> Type,~layout:Layout.Layout,~route:Layout.Route,~O:Type,~E:Data) -> Type:
184 W.Handle<S> -> Layout.query_view(layout,route) -> Layout.query_output(layout,route) -> O -> F(Layout.query_output(layout,route) & (O & Maybe<&2,E>))
185type SequentialOutputEach<-S:Data,-Permit:Data,-F:Type -> Type,-H:Type,-O:Type,-E:Data> is Type:
186 SequentialOutputEach{run:H -> O -> F(H & (O & Report<E>))}
187def SequentialOutputOps(~S:Data,~Permit:Data,~F:Type -> Type,~O:Type,~E:Data,H:Type) -> Type:SequentialOutputEach<S,Permit,F,H,O,E>
188def sequential_output_body_found(~S:Data,~Permit:Data,~F:Type -> Type,~effects:Effects.Effects<F>,~layout:Layout.Layout,~route:Layout.Route,~O:Type,~E:Data,~body:SequentialOutputBody(~S,~Permit,~F,~layout,~route,~O,~E),view:Layout.query_view(layout,route),owner:Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),output:O,found:Maybe<&2,W.Handle<S>>) -> F(Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}) & (O & Maybe<&2,E>)):
189 match owner found:
190 case owner None{}:Effects.pure(~F,(Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}) & (O & Maybe<&2,E>)),effects,(owner,(output,None{})))
191 case Layout.Viewed{payload,_} Some{handle}:Effects.map(~F,Layout.query_output(layout,route) & (O & Maybe<&2,E>),(Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}) & (O & Maybe<&2,E>)),effects,body(handle,view,payload,output),result=>Layout.rewritten(Layout.query_output(layout,route),Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),O & Maybe<&2,E>,Layout.initialize(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),result))
192def sequential_output_body(~S:Data,~Permit:Data,~F:Type -> Type,~effects:Effects.Effects<F>,~layout:Layout.Layout,~route:Layout.Route,~O:Type,~E:Data,~body:SequentialOutputBody(~S,~Permit,~F,~layout,~route,~O,~E),handles:List<&2,W.Handle<S>>,index:U32,view:Layout.query_view(layout,route),owner:Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),output:O) -> F(Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}) & (O & Maybe<&2,E>)):
193 sequential_output_body_found(~S,~Permit,~F,~effects,~layout,~route,~O,~E,~body,view,owner,output,selected_handle(~S,index,handles))
194def sequential_output_taken(~S:Data,~Permit:Data,~F:Type -> Type,~effects:Effects.Effects<F>,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~O:Type,~E:Data,~body:SequentialOutputBody(~S,~Permit,~F,~layout,~route,~O,~E),output:O,resource:R,+handles:List<&2,W.Handle<S>>,+tick:Tick.Tick,+prior:Maybe<&2,Tick.Tick>,+mode:Mode,+selected:List<&2,U32>,result:Layout.subtree_rest(~S,layout,route) & Product.Owner<Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}})>,Col.Column<S,Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}})>>,+lifecycleView:Notice.View<S>) -> F(State.Scope<S,C,R> & (O & Report<E>)):
195 match result:
196 case (rest,Product.Owner{read,write}):Effects.map(~F,Q.OutputRun<S,Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}}),Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),O,E>,(State.Scope<S,C,R> & (O & Report<E>)),effects,Q.effect_with_output(~S,~F,~effects,~Layout.stored(Layout.subtree(layout,route),Layout.InLeft{Layout.AtLeaf{}}),~Layout.stored(Layout.subtree(layout,route),Layout.InRight{Layout.AtLeaf{}}),~O,~Layout.query_view(layout,route),~List<&2,W.Handle<S>>,~E,~Layout.read(~Layout.query_input(layout,route),~Layout.query_view(layout,route)),~sequential_output_body(~S,~Permit,~F,~effects,~layout,~route,~O,~E,~body),handles,read,write,output,0,tick,selection(mode,selected,prior)),result=>output_returned(~S,~C,~R,~layout,~route,~same,~shape,~O,~E,rest,resource,handles,tick,prior,result,lifecycleView))
197def sequential_output_invoke_targets(~S:Data,~Permit:Data,~F:Type -> Type,~effects:Effects.Effects<F>,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~O:Type,~E:Data,~body:SequentialOutputBody(~S,~Permit,~F,~layout,~route,~O,~E),mode:Mode,scope:State.Scope<S,C,R>,output:O,targets:Index.TargetCheck<S>) -> F(State.Scope<S,C,R> & (O & Report<E>)):
198 match scope targets:
199 case State.Scope{store,resource,handles,tick,prior,+lifecycleView} Index.Targets{_,Domain.Domain{selected}}:sequential_output_taken(~S,~Permit,~F,~effects,~C,~R,~layout,~route,~same,~shape,~O,~E,~body,output,resource,handles,tick,prior,mode,selected,layout_take(~S,~C,~layout,~route,~same,~shape,store),lifecycleView)
200 case scope Index.Refused{_}:Effects.pure(~F,(State.Scope<S,C,R> & (O & Report<E>)),effects,(scope,(output,LayoutRefused{})))
201def sequential_output_invoke(~S:Data,~Permit:Data,~F:Type -> Type,~effects:Effects.Effects<F>,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~O:Type,~E:Data,~body:SequentialOutputBody(~S,~Permit,~F,~layout,~route,~O,~E),mode:Mode,scope:State.Scope<S,C,R>,output:O) -> F(State.Scope<S,C,R> & (O & Report<E>)):
202 match scope:
203 case State.Scope{store,resource,+handles,tick,prior,+lifecycleView}:sequential_output_invoke_targets(~S,~Permit,~F,~effects,~C,~R,~layout,~route,~same,~shape,~O,~E,~body,mode,State.Scope{store,resource,handles,tick,prior,lifecycleView},output,Index.targets(~S,view_namespace(~S,lifecycleView),handles))
204def sequential_output_declaration(~S:Data,~Permit:Data,~F:Type -> Type,~effects:Effects.Effects<F>,~C:Type,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{C == Layout.columns(~S,layout) : Type},~shape:{Layout.columns(~S,Layout.subtree(layout,route)) == Layout.query_pair(~S,~layout,~route) : Type},~valid:{Layout.query_valid(~layout,~route) == True{} : Bool},~O:Type,~E:Data,~body:SequentialOutputBody(~S,~Permit,~F,~layout,~route,~O,~E),mode:Mode) -> D.Declaration<S,C,R,SequentialOutputOps(~S,~Permit,~F,~O,~E)>:
205 D.Declaration{SequentialOutputEach{sequential_output_invoke(~S,~Permit,~F,~effects,~C,~R,~layout,~route,~same,~shape,~O,~E,~body,mode)},[D.Access{Layout.query_read_key(layout,route),D.ComponentAccess{},D.Exclusive{},D.ReadOnly{}},D.Access{Layout.query_write_key(layout,route),D.ComponentAccess{},D.Exclusive{},D.Writable{}}]}
206def each_sequential_output(~S:Data,~Permit:Data,~F:Type -> Type,~H:Type,~O:Type,~E:Data,cap:SequentialOutputEach<S,Permit,F,H,O,E>) -> H -> O -> F(H & (O & Report<E>)):
207 match cap:
208 case SequentialOutputEach{run}:run
209
210def SequentialGeneralBody(~S:Data,~Permit:Data,~F:Type -> Type,~P:Type,~V:Data,~O:Type,~E:Data) -> Type:
211 W.Handle<S> -> V -> P -> O -> F(P & (O & Maybe<&2,E>))