1 import Base 2 import ../../change_tick.bend as Tick 3 import ../../deferred_command.bend as Deferred 4 import domains.bend as D 5 import routing.bend as Route 6 import ../../world.bend as W 7 8 type BarrierState is Type: 9 BarrierState{world: W.World,domains: List<&2,D.Domain>,tick: Nat} 10 11 def collected(~S: Data,~C: Type,~R: Type,~E: Data,joined: W.World & List<&2,D.Domain>,tick: Nat) -> BarrierState: 12 (world,domains) = joined 13 BarrierState{world,domains,tick} 14 15 def command_collected(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe>,command: Deferred.Command>,state: BarrierState) -> BarrierState: 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,command,world),tick,domains),tick) 18 19 def closed(~S:Data,~C:Type,~R:Type,~E:Data,state:BarrierState) -> BarrierState: 20 match state: 21 case BarrierState{world,domains,tick}:BarrierState{W.leave_run(~S,~C,~R,~E,world),domains,tick} 22 def drain(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe>,commands: List>>,state: BarrierState) -> BarrierState: 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. 29 def opened(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe>,advanced: W.World & Tick.Tick,domains: List<&2,D.Domain>) -> BarrierState: 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>,pending),BarrierState{W.World{namespace,allocator,store,resource,events,[],registrations,nextSystemId,clock},domains,Tick.total(tick)}) 33 34 def barrier(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe>,world: W.World,domains: List<&2,D.Domain>) -> BarrierState: 35 opened(~S,~C,~R,~E,~classify,W.enter_run(~S,~C,~R,~E,world),domains)