internal/relation_failures/barrier.bend
bendvy-ecs-core@0.1.0.1 · 35 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.1/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.1/deferred_command.bend as Deferred
4import domains.bend as D
5import routing.bend as Route
6import bendvy-ecs-core@0.1.0.1/world.bend as W
7
8type BarrierState<S: Data,C: Type,R: Type,E: Data> is Type:
9 BarrierState{world: W.World<S,C,R,E>,domains: List<&2,D.Domain<S,E>>,tick: Nat}
10
11def collected(~S: Data,~C: Type,~R: Type,~E: Data,joined: W.World<S,C,R,E> & List<&2,D.Domain<S,E>>,tick: Nat) -> BarrierState<S,C,R,E>:
12 (world,domains) = joined
13 BarrierState{world,domains,tick}
14
15def command_collected(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe<D.DescriptorKey<S>>,command: Deferred.Command<W.World<S,C,R,E>>,state: BarrierState<S,C,R,E>) -> BarrierState<S,C,R,E>:
16 match state:
17 case BarrierState{world,domains,+tick}: collected(~S,~C,~R,~E,Route.collect(~S,~C,~R,~E,~classify,Deferred.run_disabled(~W.World<S,C,R,E>,command,world),tick,domains),tick)
18
19def closed(~S:Data,~C:Type,~R:Type,~E:Data,state:BarrierState<S,C,R,E>) -> BarrierState<S,C,R,E>:
20 match state:
21 case BarrierState{world,domains,tick}:BarrierState{W.leave_run(~S,~C,~R,~E,world),domains,tick}
22def drain(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe<D.DescriptorKey<S>>,commands: List<Deferred.Command<W.World<S,C,R,E>>>,state: BarrierState<S,C,R,E>) -> BarrierState<S,C,R,E>:
23 match commands:
24 case []: closed(~S,~C,~R,~E,state)
25 case command <> rest: drain(~S,~C,~R,~E,~classify,rest,command_collected(~S,~C,~R,~E,~classify,command,state))
26
27# The deferred barrier advances the actual World clock once. Every command
28# publishes a distinct batch stamped with that same barrier tick.
29def opened(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe<D.DescriptorKey<S>>,advanced: W.World<S,C,R,E> & Tick.Tick,domains: List<&2,D.Domain<S,E>>) -> BarrierState<S,C,R,E>:
30 (world,+tick) = advanced
31 match world:
32 case W.World{+namespace,allocator,store,resource,+events,pending,+registrations,+nextSystemId,+clock}: drain(~S,~C,~R,~E,~classify,List.reverse(&1,Deferred.Command<W.World<S,C,R,E>>,pending),BarrierState{W.World{namespace,allocator,store,resource,events,[],registrations,nextSystemId,clock},domains,Tick.total(tick)})
33
34def barrier(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe<D.DescriptorKey<S>>,world: W.World<S,C,R,E>,domains: List<&2,D.Domain<S,E>>) -> BarrierState<S,C,R,E>:
35 opened(~S,~C,~R,~E,~classify,W.enter_run(~S,~C,~R,~E,world),domains)