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)