event_stream.bend
bendvy-ecs-core@0.1.0.4 · 84 lines · 18 definitions
1import Base
2import bendvy-ecs-core@0.1.0.4/event_runtime.bend as Ev
3import bendvy-ecs-core@0.1.0.4/ordinary_event_declaration.bend as Event
4
5
6
7
8
9type Stream<S:Data,E:Data> is Data:
10 Stream{domain:Event.Domain<S,E>,batches:List<&2,Ev.Batch<E>>,positions:List<&2,Ev.Position>,nextReader:U32,frameStart:Nat,boundary:Nat,capacity:Nat,dropped:Nat}
11
12def provision(~S:Data,~E:Data,domain:Event.Domain<S,E>,capacity:Nat) -> Stream<S,E>:
13 Stream{domain,[],[],1,0n,0n,capacity,0n}
14
15def can_register(~S:Data,~E:Data,stream:Stream<S,E>) -> Bool:
16 match stream:
17 case Stream{_,_,_,nextReader,_,_,_,_}:U32.is_lt(nextReader,4294967295)
18def increment_reader(~S:Data,~E:Data,stream:Stream<S,E>,+tick:Nat) -> Stream<S,E> & U32:
19 match stream:
20 case Stream{domain,batches,positions,+nextReader,frameStart,boundary,capacity,dropped}:(Stream{domain,batches,positions,(nextReader+1:U32),frameStart,boundary,capacity,dropped},nextReader)
21def registered_checked(~S:Data,~E:Data,available:Bool,stream:Stream<S,E>,+tick:Nat) -> Stream<S,E> & U32:
22 match available:
23 case False{}:(stream,0)
24 case True{}:increment_reader(~S,~E,stream,tick)
25
26
27def append(~S:Data,~E:Data,stream:Stream<S,E>,tick:Nat,+values:List<&2,E>) -> Stream<S,E>:
28 match stream:
29 case Stream{domain,+batches,positions,nextReader,frameStart,boundary,capacity,dropped}:Stream{domain,Ev.sync_checked(~E,Nat.is_lt(0n,Ev.count(~E,values)),batches,tick,values),positions,nextReader,frameStart,boundary,capacity,dropped}
30
31
32
33def registered(~S:Data,~E:Data,+stream:Stream<S,E>,+tick:Nat) -> Stream<S,E> & U32:
34 registered_checked(~S,~E,can_register(~S,~E,stream),stream,tick)
35def read_position(~S:Data,~E:Data,stream:Stream<S,E>,+id:U32,+tick:Nat,position:Maybe<Ev.Position>) -> Stream<S,E> & Ev.Reading<E>:
36 match stream position:
37 case Stream{domain,+batches,positions,nextReader,frameStart,boundary,capacity,+dropped} Some{position}:(Stream{domain,batches,positions,nextReader,frameStart,boundary,capacity,dropped},Ev.reading(~E,position,batches,dropped))
38 case Stream{domain,+batches,positions,nextReader,frameStart,boundary,capacity,+dropped} None{}:(Stream{domain,batches,positions,nextReader,frameStart,boundary,capacity,dropped},Ev.reading(~E,Ev.Position{id,0n,tick},batches,dropped))
39
40
41
42def reading(~S:Data,~E:Data,+stream:Stream<S,E>,+id:U32,+tick:Nat) -> Stream<S,E> & Ev.Reading<E>:
43 match stream:
44 case Stream{+domain,+batches,+positions,+nextReader,+frameStart,+boundary,+capacity,+dropped}:read_position(~S,~E,Stream{domain,batches,positions,nextReader,frameStart,boundary,capacity,dropped},id,tick,Ev.lookup(positions,id))
45
46
47def advance(~S:Data,~E:Data,stream:Stream<S,E>,+id:U32,+tick:Nat) -> Stream<S,E>:
48 match stream:
49 case Stream{domain,batches,positions,nextReader,frameStart,boundary,capacity,dropped}:Stream{domain,batches,Ev.update(Ev.activate(positions,id,Nat.sub(tick,1n)),id,tick,False{}),nextReader,frameStart,boundary,capacity,dropped}
50def trimmed(~S:Data,~E:Data,domain:Event.Domain<S,E>,positions:List<&2,Ev.Position>,nextReader:U32,frameStart:Nat,boundary:Nat,capacity:Nat,trimmed:Ev.Trimmed<E>) -> Stream<S,E>:
51 match trimmed:
52 case Ev.Trimmed{batches,dropped}:Stream{domain,batches,positions,nextReader,frameStart,boundary,capacity,dropped}
53
54
55
56def frame(~S:Data,~E:Data,stream:Stream<S,E>,+tick:Nat) -> Stream<S,E>:
57 match stream:
58 case Stream{domain,batches,+positions,nextReader,+frameStart,_,+capacity,dropped}:trimmed(~S,~E,domain,positions,nextReader,tick,frameStart,capacity,Ev.trim_capacity(~E,Ev.past_window(~E,batches,Ev.hold_boundary(positions,frameStart),dropped),capacity))
59
60def inventory(~S:Data,~E:Data,stream:Stream<S,E>) -> String:
61 match stream:
62 case Stream{Event.Domain{key},_,_,_,_,_,_,_}:key
63
64def dropped(~S:Data,~E:Data,stream:Stream<S,E>) -> Nat:
65 match stream:
66 case Stream{_,_,_,_,_,_,_,value}:value
67def completed_positions(success:Bool,+positions:List<&2,Ev.Position>,+id:U32,+tick:Nat) -> List<&2,Ev.Position>:
68 match success:
69 case False{}:Ev.activate(positions,id,Nat.sub(tick,1n))
70 case True{}:Ev.update(Ev.activate(positions,id,Nat.sub(tick,1n)),id,tick,False{})
71
72
73
74def completed(~S:Data,~E:Data,stream:Stream<S,E>,id:U32,tick:Nat,success:Bool) -> Stream<S,E>:
75 match stream:
76 case Stream{domain,batches,positions,nextReader,frameStart,boundary,capacity,dropped}:Stream{domain,batches,completed_positions(success,positions,id,tick),nextReader,frameStart,boundary,capacity,dropped}
77
78def read_declaration(~S:Data,~E:Data,stream:Stream<S,E>) -> Event.Declaration<S,E>:
79 match stream:
80 case Stream{domain,_,_,_,_,_,_,_}:Event.read(~S,~E,domain)
81
82def domain(~S:Data,~E:Data,stream:Stream<S,E>) -> Event.Domain<S,E>:
83 match stream:
84 case Stream{domain,_,_,_,_,_,_,_}:domain