check.bend
bendvy-ecs-core@0.1.0.3 · 96 lines · 20 definitions
1import Base
2import inspector.bend as I
3import inspector_query_projection.bend as Q
4import world.bend as W
5import component.bend as C
6import column.bend as Col
7import capabilities.bend as Cap
8
9
10
11
12
13
14
15type Frame<-S:Data,-Store:Type,-R:Type,-E:Data> is Type:
16 Frame{world:W.World<S,Store,R,E>}
17
18
19type PlainSelection is Data:
20 Required{}
21 Optional{}
22
23
24type Row<S:Data,V:Data> is Data:
25 Row{entity:W.Handle<S>,value:C.Access<V>}
26
27
28type Error is Data:
29 MissingRuntimeRequirements{resources:List<&2,String>}
30
31
32
33type Plan<-S:Data,-Store:Type,-R:Type,-E:Data,-Ops:Type -> Type> is Type:
34 Plan{required:W.World<S,Store,R,E> -> W.World<S,Store,R,E> & List<&2,String>,caps:Ops(Frame<S,Store,R,E>)}
35
36
37type Checked<S:Data,Store:Type,R:Type,E:Data> is Type:
38 Checked{world:W.World<S,Store,R,E>,result:Result<&2,&2,Error,Bool>}
39
40def selection(value:PlainSelection) -> Q.Selection:
41 match value:
42 case Required{}:Q.Required{}
43 case Optional{}:Q.Optional{}
44def plain_row(~S:Data,~V:Data,value:Q.Row<S,V>) -> Row<S,V>:
45 match value:
46 case Q.Row{entity,I.Value{access,_,_}}:Row{entity,access}
47def plain_rows(~S:Data,~V:Data,values:List<&2,Q.Row<S,V>>) -> List<&2,Row<S,V>>:
48 match values:
49 case []:[]
50 case value <> rest:plain_row(~S,~V,value) <> plain_rows(~S,~V,rest)
51def query_done(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,result:I.Frame<S,Store,R,E> & List<&2,Q.Row<S,V>>) -> Frame<S,Store,R,E> & List<&2,Row<S,V>>:
52 match result:
53 case (I.Frame{world,_},rows):(Frame{world},plain_rows(~S,~V,rows))
54def query_read(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~project:Payload -> Payload & V,~family:C.Family<S,Store,Rest,Payload,V,Token,take,put,project>,~mode:PlainSelection,frame:Frame<S,Store,R,E>) -> Frame<S,Store,R,E> & List<&2,Row<S,V>>:
55 match frame:
56 case Frame{world}:query_done(~S,~Store,~R,~E,~V,Q.scan(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~project,~family,~selection(mode),I.Frame{world,None{}}))
57
58
59
60
61def query_grant(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~project:Payload -> Payload & V,~family:C.Family<S,Store,Rest,Payload,V,Token,take,put,project>,~mode:PlainSelection) -> Cap.ValueRead<Frame<S,Store,R,E>,List<&2,Row<S,V>>>:
62 Cap.ValueRead{frame => query_read(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~project,~family,~mode,frame)}
63def resource_done(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,result:W.World<S,Store,R,E> & V) -> Frame<S,Store,R,E> & V:
64 (world,value)=result
65 (Frame{world},value)
66def resource_read(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,~project:R -> R & V,frame:Frame<S,Store,R,E>) -> Frame<S,Store,R,E> & V:
67 match frame:
68 case Frame{world}:resource_done(~S,~Store,~R,~E,~V,W.observe_resource(~S,~Store,~R,~E,~V,~project,world))
69
70
71
72def resource_grant(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,~project:R -> R & V) -> Cap.ValueRead<Frame<S,Store,R,E>,V>:
73 Cap.ValueRead{frame => resource_read(~S,~Store,~R,~E,~V,~project,frame)}
74
75def completed(~S:Data,~Store:Type,~R:Type,~E:Data,result:Frame<S,Store,R,E> & Bool) -> Checked<S,Store,R,E>:
76 match result:
77 case (Frame{world},value):Checked{world,Done{value}}
78def ready(~S:Data,~Store:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & Bool,~caps:Ops(Frame<S,Store,R,E>),args:A,result:W.World<S,Store,R,E> & List<&2,String>) -> Checked<S,Store,R,E>:
79 match result:
80 case (world,[]):completed(~S,~Store,~R,~E,Cap.invoke(~Ops,~A,~Bool,~body,~Frame<S,Store,R,E>,~caps,args,Frame{world}))
81 case (world,name <> rest):Checked{world,Fail{MissingRuntimeRequirements{name <> rest}}}
82def required_field(~S:Data,~Store:Type,~R:Type,~E:Data,~Ops:Type -> Type,plan:Plan<S,Store,R,E,Ops>) -> W.World<S,Store,R,E> -> W.World<S,Store,R,E> & List<&2,String>:
83 match plan:
84 case Plan{required,_}:required
85def caps_field(~S:Data,~Store:Type,~R:Type,~E:Data,~Ops:Type -> Type,plan:Plan<S,Store,R,E,Ops>) -> Ops(Frame<S,Store,R,E>):
86 match plan:
87 case Plan{_,caps}:caps
88
89
90
91
92
93
94
95def run(~S:Data,~Store:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & Bool,~plan:Plan<S,Store,R,E,Ops>,args:A,world:W.World<S,Store,R,E>) -> Checked<S,Store,R,E>:
96 ready(~S,~Store,~R,~E,~Ops,~A,~body,~caps_field(~S,~Store,~R,~E,~Ops,plan),args,required_field(~S,~Store,~R,~E,~Ops,plan)(world))