inspector_query_projection.bend
bendvy-ecs-core@0.1.0.3 · 148 lines · 38 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/change_tick.bend as Tick
3import inspector.bend as I
4import world.bend as W
5import component.bend as C
6import column.bend as Col
7import capabilities.bend as Cap
8
9
10
11type Row<S:Data,V:Data> is Data:
12 Row{entity:W.Handle<S>,value:I.Value<V>}
13
14
15type Selection is Data:
16 Required{}
17 Optional{}
18 Added{}
19 Changed{}
20
21def present(~V:Data,value:C.Access<V>) -> Bool:
22 match value:
23 case C.Found{_}:True{}
24 case _:False{}
25def accepts(~V:Data,selection:Selection,value:I.Value<V>) -> Bool:
26 match selection value:
27 case Optional{} _:True{}
28 case Required{} I.Value{access,_,_}:present(~V,access)
29 case Added{} I.Value{access,added,_}:Bool.and(present(~V,access),added)
30 case Changed{} I.Value{access,_,changed}:Bool.and(present(~V,access),changed)
31def included(~S:Data,~V:Data,include:Bool,row:Row<S,V>,rows:List<&2,Row<S,V>>) -> List<&2,Row<S,V>>:
32 match include:
33 case True{}:row <> rows
34 case False{}:rows
35
36def read_row(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,~selection:Selection,target:W.Handle<S>,rows:List<&2,Row<S,V>>,continue:I.Frame<S,Store,R,E> -> List<&2,Row<S,V>> -> I.Frame<S,Store,R,E> & List<&2,Row<S,V>>,observed:I.Frame<S,Store,R,E> & I.Value<V>) -> I.Frame<S,Store,R,E> & List<&2,Row<S,V>>:
37 (frame,+value)=observed
38 continue(frame,included(~S,~V,accepts(~V,selection,value),Row{target,value},rows))
39
40def read_rows(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,~family:C.Family<S,Store,Rest,C,V,Token,take,put,project>,~selection:Selection,handles:List<&2,W.Handle<S>>,frame:I.Frame<S,Store,R,E>,rows:List<&2,Row<S,V>>) -> I.Frame<S,Store,R,E> & List<&2,Row<S,V>>:
41 match handles:
42 case []:(frame,List.reverse(&2,Row<S,V>,rows))
43 case +target <> rest:read_row(~S,~Store,~R,~E,~V,~selection,target,rows,(frame => rows => read_rows(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,~family,~selection,rest,frame,rows)),I.family_get(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,~family,frame,target))
44
45def scanned(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,~family:C.Family<S,Store,Rest,C,V,Token,take,put,project>,~selection:Selection,cursor:Maybe<&2,Tick.Tick>,observed:W.World<S,Store,R,E> & List<&2,W.Handle<S>>) -> I.Frame<S,Store,R,E> & List<&2,Row<S,V>>:
46 (world,handles)=observed
47 read_rows(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,~family,~selection,handles,I.Frame{world,cursor},[])
48def scan(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,~family:C.Family<S,Store,Rest,C,V,Token,take,put,project>,~selection:Selection,frame:I.Frame<S,Store,R,E>) -> I.Frame<S,Store,R,E> & List<&2,Row<S,V>>:
49 match frame:
50 case I.Frame{world,cursor}:scanned(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,~family,~selection,cursor,W.handles(~S,~Store,~R,~E,world))
51
52
53
54def read_query(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,~family:C.Family<S,Store,Rest,C,V,Token,take,put,project>,~selection:Selection) -> Cap.ValueRead<I.Frame<S,Store,R,E>,List<&2,Row<S,V>>>:
55 Cap.ValueRead{frame => scan(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,~family,~selection,frame)}
56
57
58
59
60
61
62type DeclaredSelection<-H:Type,-S:Data,-V:Data> is Type:
63 DeclaredSelection{matches:H -> W.Handle<S> -> H & Bool,project:H -> W.Handle<S> -> H & V}
64
65
66type Product<A:Data,B:Data> is Data:
67 Product{left:A,right:B}
68
69
70type Predicate<-H:Type,-S:Data> is Type:
71 Predicate{matches:H -> W.Handle<S> -> H & Bool}
72
73
74def predicate_field(~H:Type,~S:Data,value:Predicate<H,S>) -> H -> W.Handle<S> -> H & Bool:
75 match value:
76 case Predicate{matches}:matches
77
78
79def matches_field(~H:Type,~S:Data,~V:Data,value:DeclaredSelection<H,S,V>) -> H -> W.Handle<S> -> H & Bool:
80 match value:
81 case DeclaredSelection{matches,_}:matches
82
83
84def project_field(~H:Type,~S:Data,~V:Data,value:DeclaredSelection<H,S,V>) -> H -> W.Handle<S> -> H & V:
85 match value:
86 case DeclaredSelection{_,project}:project
87def yes(~H:Type,~S:Data,owner:H,target:W.Handle<S>) -> H & Bool:
88 (owner,True{})
89def empty_value(~H:Type,~S:Data,owner:H,target:W.Handle<S>) -> H & Unit:
90 (owner,Unit{})
91
92
93def empty(~H:Type,~S:Data) -> DeclaredSelection<H,S,Unit>:
94 DeclaredSelection{yes(~H,~S),empty_value(~H,~S)}
95def matched_right(~H:Type,~S:Data,~right:H -> W.Handle<S> -> H & Bool,target:W.Handle<S>,observed:H & Bool) -> H & Bool:
96 match observed:
97 case (owner,False{}):(owner,False{})
98 case (owner,True{}):right(owner,target)
99def pair_matches_target(~H:Type,~S:Data,~left:H -> W.Handle<S> -> H & Bool,~right:H -> W.Handle<S> -> H & Bool,owner:H,+target:W.Handle<S>) -> H & Bool:
100 matched_right(~H,~S,~right,target,left(owner,target))
101def pair_matches(~H:Type,~S:Data,~left:H -> W.Handle<S> -> H & Bool,~right:H -> W.Handle<S> -> H & Bool,owner:H,target:W.Handle<S>) -> H & Bool:
102 pair_matches_target(~H,~S,~left,~right,owner,target)
103def projected_right(~H:Type,~A:Data,~B:Data,left:A,observed:H & B) -> H & Product<A,B>:
104 (owner,right)=observed
105 (owner,Product{left,right})
106def projected_left(~H:Type,~S:Data,~A:Data,~B:Data,~right:H -> W.Handle<S> -> H & B,target:W.Handle<S>,observed:H & A) -> H & Product<A,B>:
107 (owner,left)=observed
108 projected_right(~H,~A,~B,left,right(owner,target))
109def pair_project_target(~H:Type,~S:Data,~A:Data,~B:Data,~left:H -> W.Handle<S> -> H & A,~right:H -> W.Handle<S> -> H & B,owner:H,+target:W.Handle<S>) -> H & Product<A,B>:
110 projected_left(~H,~S,~A,~B,~right,target,left(owner,target))
111def pair_project(~H:Type,~S:Data,~A:Data,~B:Data,~left:H -> W.Handle<S> -> H & A,~right:H -> W.Handle<S> -> H & B,owner:H,target:W.Handle<S>) -> H & Product<A,B>:
112 pair_project_target(~H,~S,~A,~B,~left,~right,owner,target)
113
114
115
116def pair(~H:Type,~S:Data,~A:Data,~B:Data,~left:DeclaredSelection<H,S,A>,~right:DeclaredSelection<H,S,B>) -> DeclaredSelection<H,S,Product<A,B>>:
117 DeclaredSelection{pair_matches(~H,~S,~matches_field(~H,~S,~A,left),~matches_field(~H,~S,~B,right)),pair_project(~H,~S,~A,~B,~project_field(~H,~S,~A,left),~project_field(~H,~S,~B,right))}
118def true_predicate(~H:Type,~S:Data) -> Predicate<H,S>:
119 Predicate{yes(~H,~S)}
120def predicate_right(~H:Type,~S:Data,right:H -> W.Handle<S> -> H & Bool,target:W.Handle<S>,observed:H & Bool) -> H & Bool:
121 match observed:
122 case (owner,False{}):(owner,False{})
123 case (owner,True{}):right(owner,target)
124def predicate_both_target(~H:Type,~S:Data,left:H -> W.Handle<S> -> H & Bool,right:H -> W.Handle<S> -> H & Bool,owner:H,+target:W.Handle<S>) -> H & Bool:
125 predicate_right(~H,~S,right,target,left(owner,target))
126def predicate_both(~H:Type,~S:Data,left:H -> W.Handle<S> -> H & Bool,right:H -> W.Handle<S> -> H & Bool,owner:H,target:W.Handle<S>) -> H & Bool:
127 predicate_both_target(~H,~S,left,right,owner,target)
128
129
130def both(~H:Type,~S:Data,~left:Predicate<H,S>,~right:Predicate<H,S>) -> Predicate<H,S>:
131 Predicate{predicate_both(~H,~S,predicate_field(~H,~S,left),predicate_field(~H,~S,right))}
132def constrained_target(~H:Type,~S:Data,source:H -> W.Handle<S> -> H & Bool,predicate:H -> W.Handle<S> -> H & Bool,owner:H,+target:W.Handle<S>) -> H & Bool:
133 predicate_right(~H,~S,predicate,target,source(owner,target))
134def constrained(~H:Type,~S:Data,source:H -> W.Handle<S> -> H & Bool,predicate:H -> W.Handle<S> -> H & Bool,owner:H,target:W.Handle<S>) -> H & Bool:
135 constrained_target(~H,~S,source,predicate,owner,target)
136
137
138def constrain(~H:Type,~S:Data,~V:Data,~source:DeclaredSelection<H,S,V>,~predicate:Predicate<H,S>) -> DeclaredSelection<H,S,V>:
139 DeclaredSelection{constrained(~H,~S,matches_field(~H,~S,~V,source),predicate_field(~H,~S,predicate)),project_field(~H,~S,~V,source)}
140def mapped(~H:Type,~A:Data,~B:Data,name:A -> B,observed:H & A) -> H & B:
141 (owner,value)=observed
142 (owner,name(value))
143def map_project(~H:Type,~S:Data,~A:Data,~B:Data,project:H -> W.Handle<S> -> H & A,name:A -> B,owner:H,target:W.Handle<S>) -> H & B:
144 mapped(~H,~A,~B,name,project(owner,target))
145
146
147def map(~H:Type,~S:Data,~A:Data,~B:Data,~source:DeclaredSelection<H,S,A>,~name:A -> B) -> DeclaredSelection<H,S,B>:
148 DeclaredSelection{matches_field(~H,~S,~A,source),map_project(~H,~S,~A,~B,project_field(~H,~S,~A,source),name)}