execution_machine_state.bend
bendvy-ecs-core@0.1.0.3 · 98 lines · 25 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/machine.bend as M
3import bendvy-ecs-core@0.1.0.3/machine_queue.bend as Queue
4import bendvy-ecs-core@0.1.0.3/execution_machine_stream.bend as Stream
5import bendvy-ecs-core@0.1.0.3/change_tick.bend as Tick
6
7
8type Cell<-S:Data,-K:Data,-V:Data> is Type:
9 Cell{slot:M.Slot<S,K,V>,stream:Stream.Store<V>,revision:Nat,stamp:Maybe<&2,Tick.Tick>,nextStamp:Maybe<&2,Tick.Tick>,sequence:Nat,initialPending:Bool,namespace:Maybe<&2,U32>,intent:Intent<V>}
10type Intent<-V:Data> is Data:
11 Idle{}
12 Initial{value:V}
13 Transition{from:V,to:V,runExitEnter:Bool}
14type View<-S:Data,-K:Data,-V:Data> is Data:
15 View{current:M.CurrentView<S,K,V>,next:M.NextView<S,K,V>,revision:Nat,stamp:Maybe<&2,Tick.Tick>,nextStamp:Maybe<&2,Tick.Tick>,intent:Intent<V>}
16def empty(~S:Data,~K:Data,~V:Data) -> Cell<S,K,V>:
17 Cell{M.Missing{},Stream.empty(~V),0n,None{},None{},0n,False{},None{},Idle{}}
18def projected(-S:Data,-K:Data,-V:Data,cell:Cell<S,K,V>) -> Cell<S,K,V> & View<S,K,V>:
19 match cell:
20 case Cell{+slot,stream,+revision,+stamp,+nextStamp,sequence,initialPending,namespace,+intent}:(Cell{slot,stream,revision,stamp,nextStamp,sequence,initialPending,namespace,intent},View{M.current_view_generic(S,K,V,slot),M.next_view_generic(S,K,V,slot),revision,stamp,nextStamp,intent})
21def queue_generic(-S:Data,-K:Data,-V:Data,same:V -> V -> Bool,cell:Cell<S,K,V>,request:M.QueueInput<V>) -> Cell<S,K,V>:
22 match cell request:
23 case Cell{slot,stream,revision,stamp,nextStamp,sequence,initialPending,namespace,intent} M.Set{value,skipSame}:Cell{Queue.queue_generic(S,K,V,same,slot,value,skipSame),stream,revision,stamp,nextStamp,sequence,initialPending,namespace,intent}
24 case Cell{slot,stream,revision,stamp,nextStamp,sequence,initialPending,namespace,intent} M.Reset{}:Cell{M.reset_generic(S,K,V,slot),stream,revision,stamp,nextStamp,sequence,initialPending,namespace,intent}
25
26
27def queue(~S:Data,~K:Data,~V:Data,~same:V -> V -> Bool,cell:Cell<S,K,V>,request:M.QueueInput<V>) -> Cell<S,K,V>:
28 queue_generic(S,K,V,same,cell,request)
29
30def request_stamped_generic(-S:Data,-K:Data,-V:Data,tick:Tick.Tick,cell:Cell<S,K,V>) -> Cell<S,K,V> & Unit:
31 match cell:
32 case Cell{M.Missing{},stream,revision,stamp,nextStamp,sequence,initialPending,namespace,intent}:(Cell{M.Missing{},stream,revision,stamp,nextStamp,sequence,initialPending,namespace,intent},Unit{})
33 case Cell{slot,stream,revision,stamp,_,sequence,initialPending,namespace,intent}:(Cell{slot,stream,revision,stamp,Some{tick},sequence,initialPending,namespace,intent},Unit{})
34def request_stamped(~S:Data,~K:Data,~V:Data,tick:Tick.Tick,cell:Cell<S,K,V>) -> Cell<S,K,V> & Unit:
35 request_stamped_generic(S,K,V,tick,cell)
36
37def queued_at_generic(-S:Data,-K:Data,-V:Data,same:V -> V -> Bool,request:M.QueueInput<V>,tick:Tick.Tick,cell:Cell<S,K,V>) -> Cell<S,K,V> & Unit:
38 request_stamped_generic(S,K,V,tick,queue_generic(S,K,V,same,cell,request))
39def queued_at(~S:Data,~K:Data,~V:Data,~same:V -> V -> Bool,request:M.QueueInput<V>,tick:Tick.Tick,cell:Cell<S,K,V>) -> Cell<S,K,V> & Unit:
40 queued_at_generic(S,K,V,same,request,tick,cell)
41
42def initialized(~S:Data,~K:Data,~V:Data,+value:V,+tick:Tick.Tick,stream:Stream.Store<V>,+sequence:Nat,namespace:Maybe<&2,U32>) -> Cell<S,K,V>:
43 Cell{M.Present{value,M.NoPending{},None{},True{}},Stream.publish(~V,stream,1n+sequence,M.Initial{value}),1n,Some{tick},Some{tick},1n+sequence,True{},namespace,Initial{value}}
44def initialize(~S:Data,~K:Data,~V:Data,cell:Cell<S,K,V>,value:V,tick:Tick.Tick) -> Cell<S,K,V>:
45 match cell:
46 case Cell{M.Missing{},stream,_,_,_,sequence,_,namespace,_}:initialized(~S,~K,~V,value,tick,stream,sequence,namespace)
47 case cell:cell
48def next_revision(same:Bool,revision:Nat) -> Nat:
49 match same:
50 case True{}:revision
51 case False{}:1n+revision
52def next_stamp(same:Bool,stamp:Maybe<&2,Tick.Tick>,tick:Tick.Tick) -> Maybe<&2,Tick.Tick>:
53 match same:
54 case True{}:stamp
55 case False{}:Some{tick}
56
57
58
59
60def retained(~V:Data,equal:Bool,from:V,to:V) -> V:
61 match equal:
62 case True{}:from
63 case False{}:to
64def exited(~V:Data,equal:Bool,from:V,to:V) -> V:
65 match equal:
66 case True{}:to
67 case False{}:from
68def committed(~S:Data,~K:Data,~V:Data,+from:V,+to:V,skipSame:Bool,stream:Stream.Store<V>,revision:Nat,stamp:Maybe<&2,Tick.Tick>,+sequence:Nat,+tick:Tick.Tick,+equal:Bool,namespace:Maybe<&2,U32>) -> Cell<S,K,V>:
69 Cell{M.Present{retained(~V,equal,from,to),M.NoPending{},Some{exited(~V,equal,from,to)},Bool.not(equal)},Stream.publish(~V,stream,1n+sequence,M.Transition{exited(~V,equal,from,to),to}),next_revision(equal,revision),next_stamp(equal,stamp,tick),Some{tick},1n+sequence,False{},namespace,Transition{exited(~V,equal,from,to),to,Bool.or(Bool.not(skipSame),Bool.not(equal))}}
70def apply(~S:Data,~K:Data,~V:Data,~same:V -> V -> Bool,cell:Cell<S,K,V>,tick:Tick.Tick) -> Cell<S,K,V>:
71 match cell:
72 case Cell{M.Present{+current,M.Queued{+value,skipSame},_,_},stream,revision,stamp,nextStamp,sequence,_,namespace,_}:committed(~S,~K,~V,current,value,skipSame,stream,revision,stamp,sequence,tick,same(current,value),namespace)
73 case Cell{slot,stream,revision,stamp,nextStamp,sequence,True{},namespace,intent}:Cell{slot,stream,revision,stamp,nextStamp,sequence,False{},namespace,intent}
74 case Cell{slot,stream,revision,stamp,nextStamp,sequence,False{},namespace,_}:Cell{M.clear_changed(~S,~K,~V,slot),stream,revision,stamp,nextStamp,sequence,False{},namespace,Idle{}}
75def run_exit(-V:Data,intent:Intent<V>) -> Bool:
76 match intent:
77 case Transition{_,_,allowed}:allowed
78 case _:False{}
79def run_transition(-V:Data,intent:Intent<V>) -> Bool:
80 match intent:
81 case Transition{_,_,_}:True{}
82 case _:False{}
83def run_enter(-V:Data,intent:Intent<V>) -> Bool:
84 match intent:
85 case Initial{_}:True{}
86 case Transition{_,_,allowed}:allowed
87 case _:False{}
88def matches(~S:Data,~K:Data,~V:Data,~same:V -> V -> Bool,value:V,view:View<S,K,V>) -> Bool:
89 match view:
90 case View{current,_,_,_,_,_}:M.is_current(~S,~K,~V,~same,current,value)
91
92def bind(~S:Data,~K:Data,~V:Data,namespace:U32,cell:Cell<S,K,V>) -> Cell<S,K,V>:
93 match cell:
94 case Cell{slot,stream,revision,stamp,nextStamp,sequence,initialPending,None{},intent}:Cell{slot,stream,revision,stamp,nextStamp,sequence,initialPending,Some{namespace},intent}
95 case cell:cell
96def maintain(~S:Data,~K:Data,~V:Data,tick:Tick.Tick,cell:Cell<S,K,V>) -> Cell<S,K,V>:
97 match cell:
98 case Cell{slot,stream,revision,stamp,nextStamp,+sequence,initialPending,namespace,intent}:Cell{slot,Stream.maintain(~V,sequence,tick,stream),revision,stamp,nextStamp,sequence,initialPending,namespace,intent}