1 import Base 2 import ./schedule.bend as Sch 3 import ./world.bend as W 4 import ./system.bend as Sys 5 # Declaration lowering owns fixed group order; closed callbacks retain failure outcomes. 6 # Detached ordinary marker schedule name; phase lowering is fixed by the library. 7 type Declaration<-S:Data> is Data: Declaration{name:String} 8 # Declare the marker schedule label without building or executing handlers. 9 def declare(~S:Data,name:String) -> Declaration:Declaration{name} 10 def phase_name(id:U32) -> String: 11 match id: 12 case 1:"apply" 13 case 2:"exit" 14 case 3:"transition" 15 case _:"enter" 16 # Fixed sequence: structural barrier, then apply, exit, transition and enter 17 # system groups with their phase labels and condition slot zero. 18 def steps() -> List<&2,Sch.Step>:[Sch.Barrier{},Sch.Phase{phase_name(1)},Sch.System{1,0},Sch.Phase{phase_name(2)},Sch.System{2,0},Sch.Phase{phase_name(3)},Sch.System{3,0},Sch.Phase{phase_name(4)},Sch.System{4,0}] 19 # Build the fixed four-group schedule retaining actual H owners. Group ids 1..4 20 # are internal dispatch slots, not newly registered gameplay system identities. 21 def install(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,declaration:Declaration,namespace:U32,owners:H) -> Sch.Build: 22 match declaration: 23 case Declaration{name}:Sch.build(~S,~C,~R,~E,~H,namespace,name,steps(),[1,2,3,4],owners) 24 # Advanced fixed-group router: ids 1/2/3 call apply/exit/transition; the remaining 25 # case calls enter. Use with steps(), not arbitrary ids assumed validated here. 26 # Closed callbacks must return actual owners/World and their failure outcome. 27 def dispatch(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,~apply:H -> W.World -> H & Sys.Outcome,Error,Unit>,~exit:H -> W.World -> H & Sys.Outcome,Error,Unit>,~transition:H -> W.World -> H & Sys.Outcome,Error,Unit>,~enter:H -> W.World -> H & Sys.Outcome,Error,Unit>,owners:H,world:W.World,id:U32) -> H & Sys.Outcome,Error,Unit>: 28 match id: 29 case 1:apply(owners,world) 30 case 2:exit(owners,world) 31 case 3:transition(owners,world) 32 case _:enter(owners,world) 33 # Fixed marker group condition returns World unchanged and True. 34 def condition(~S:Data,~C:Type,~R:Type,~E:Data,world:W.World,_:U32) -> W.World & Bool:(world,True{}) 35 # Run the fixed schedule after namespace admission, preserving H and World in 36 # all results. Stop on first failed callback; earlier successful transactions are 37 # not one marker-wide rollback. Explicit initial barrier precedes group dispatch. 38 # See docs/parity/handlers.md for the higher-level transition-marker contract. 39 def run(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,~apply:H -> W.World -> H & Sys.Outcome,Error,Unit>,~exit:H -> W.World -> H & Sys.Outcome,Error,Unit>,~transition:H -> W.World -> H & Sys.Outcome,Error,Unit>,~enter:H -> W.World -> H & Sys.Outcome,Error,Unit>,schedule:Sch.Schedule,world:W.World) -> Sch.RunResult:Sch.run(~S,~C,~R,~E,~H,~Error,~dispatch(~S,~C,~R,~E,~H,~Error,~apply,~exit,~transition,~enter),~condition(~S,~C,~R,~E),schedule,world)