1 import Base 2 import ./machine_handler_engine.bend as Engine 3 4 import world.bend as W 5 6 import system.bend as Sys 7 8 import machine.bend as M 9 10 11 12 type Phase is Data: 13 Exit{} 14 Transition{} 15 Enter{} 16 17 type Invocation is Data: 18 Invocation{phase:Phase,ordinal:U32,from:V,to:V} 19 InitialEnter{ordinal:U32,to:V} 20 21 type Entry -> Invocation -> Sys.Outcome,String,Unit>> is Type: 22 Entry{ordinal:U32,registry:Sys.Registry,String,Unit,runner>} 23 24 type PhaseResult -> Invocation -> Sys.Outcome,String,Unit>> is Type: 25 Complete{entries:List<&1,Entry>,world:W.World} 26 Failed{entries:List<&1,Entry>,world:W.World,error:String} 27 28 type Owners -> Invocation -> Sys.Outcome,String,Unit>> is Type: 29 Owners{exit:List<&1,Entry>,transition:List<&1,Entry>,enter:List<&1,Entry>} 30 31 type HandlerResult -> Invocation -> Sys.Outcome,String,Unit>> is Type: 32 Completed{owners:Owners,world:W.World} 33 Stopped{owners:Owners,world:W.World,phase:Phase,error:String} 34 35 type Prepared is Data: 36 Idle{slot:M.Slot} 37 Ready{slot:M.Slot,transition:M.Transition,skipSame:Bool} 38 39 def invoked(~S:Data,~C:Type,~R:Type,~E:Data,~V:Data,~runner:W.World -> Invocation -> Sys.Outcome,String,Unit>,ordinal:U32,result:Sys.RunResult,String,Unit,runner>) -> Entry & Sys.Outcome,String,Unit>: 40 match result: 41 case Sys.Completed{registry,outcome}:(Entry{ordinal,registry},outcome) 42 case Sys.RegistrationRejected{registry,world,_}:(Entry{ordinal,registry},Sys.Failed{world,"HandlerRegistrationRejected"}) 43 def invoke_phase(~S:Data,~C:Type,~R:Type,~E:Data,~V:Data,~runner:W.World -> Invocation -> Sys.Outcome,String,Unit>,entry:Entry,world:W.World,phase:Phase,from:V,to:V) -> Entry & Sys.Outcome,String,Unit>: 44 match entry: 45 case Entry{+ordinal,registry}:invoked(~S,~C,~R,~E,~V,~runner,ordinal,Sys.run(~S,~C,~R,~E,~Invocation,~String,~Unit,~runner,registry,world,Invocation{phase,ordinal,from,to})) 46 def invoke_initial(~S:Data,~C:Type,~R:Type,~E:Data,~V:Data,~runner:W.World -> Invocation -> Sys.Outcome,String,Unit>,entry:Entry,world:W.World,to:V) -> Entry & Sys.Outcome,String,Unit>: 47 match entry: 48 case Entry{+ordinal,registry}:invoked(~S,~C,~R,~E,~V,~runner,ordinal,Sys.run(~S,~C,~R,~E,~Invocation,~String,~Unit,~runner,registry,world,InitialEnter{ordinal,to})) 49 def phase_result(~S:Data,~C:Type,~R:Type,~E:Data,~V:Data,~runner:W.World -> Invocation -> Sys.Outcome,String,Unit>,result:Engine.PhaseResult,Entry>) -> PhaseResult: 50 match result: 51 case Engine.Complete{entries,world}:Complete{entries,world} 52 case Engine.Failed{entries,world,error}:Failed{entries,world,error} 53 def handler_result(~S:Data,~C:Type,~R:Type,~E:Data,~V:Data,~runner:W.World -> Invocation -> Sys.Outcome,String,Unit>,result:Engine.HandlerResult,Entry,Phase>) -> HandlerResult: 54 match result: 55 case Engine.Completed{Engine.Owners{exit,transition,enter},world}:Completed{Owners{exit,transition,enter},world} 56 case Engine.Stopped{Engine.Owners{exit,transition,enter},world,phase,error}:Stopped{Owners{exit,transition,enter},world,phase,error} 57 def prepared_result(~S:Data,~K:Data,~V:Data,result:Engine.Prepared) -> Prepared: 58 match result: 59 case Engine.Idle{slot}:Idle{slot} 60 case Engine.Ready{slot,transition,skipSame}:Ready{slot,transition,skipSame} 61 def run_phase(~S:Data,~C:Type,~R:Type,~E:Data,~V:Data,~runner:W.World -> Invocation -> Sys.Outcome,String,Unit>,entries:List<&1,Entry>,world:W.World,+phase:Phase,+from:V,+to:V,error:Maybe<&2,String>) -> PhaseResult: 62 phase_result(~S,~C,~R,~E,~V,~runner,Engine.run_phase(~S,~W.World,~Entry,~Phase,~V,~invoke_phase(~S,~C,~R,~E,~V,~runner),~invoke_initial(~S,~C,~R,~E,~V,~runner),~Exit{},~Transition{},~Enter{},entries,world,phase,from,to,error)) 63 def run_initial(~S:Data,~C:Type,~R:Type,~E:Data,~V:Data,~runner:W.World -> Invocation -> Sys.Outcome,String,Unit>,entries:List<&1,Entry>,world:W.World,+to:V,error:Maybe<&2,String>) -> PhaseResult: 64 phase_result(~S,~C,~R,~E,~V,~runner,Engine.run_initial(~S,~W.World,~Entry,~Phase,~V,~invoke_phase(~S,~C,~R,~E,~V,~runner),~invoke_initial(~S,~C,~R,~E,~V,~runner),~Exit{},~Transition{},~Enter{},entries,world,to,error)) 65 def choose(~S:Data,~K:Data,~V:Data,skip:Bool,+current:V,+value:V,previous:Maybe<&2,V>,+skipSame:Bool) -> Prepared: 66 prepared_result(~S,~K,~V,Engine.choose(~S,~K,~V,skip,current,value,previous,skipSame)) 67 def prepare(~S:Data,~K:Data,~V:Data,~same:V -> V -> Bool,slot:M.Slot,captured:M.Snapshot) -> Prepared: 68 prepared_result(~S,~K,~V,Engine.prepare(~S,~K,~V,~same,slot,captured)) 69 def committed(~S:Data,~K:Data,~V:Data,slot:M.Slot,from:V,to:V) -> M.Slot: 70 Engine.committed(~S,~K,~V,slot,from,to) 71 def run(~S:Data,~C:Type,~R:Type,~E:Data,~V:Data,~runner:W.World -> Invocation -> Sys.Outcome,String,Unit>,~K:Data,~take:W.World -> W.World & M.Slot,~put:W.World -> M.Slot -> W.World,~publish:W.World -> M.Transition -> W.World,~same:V -> V -> Bool,owners:Owners,world:W.World,captured:M.Snapshot) -> HandlerResult: 72 match owners: 73 case Owners{exit,transition,enter}:handler_result(~S,~C,~R,~E,~V,~runner,Engine.run(~S,~W.World,~Entry,~Phase,~V,~invoke_phase(~S,~C,~R,~E,~V,~runner),~invoke_initial(~S,~C,~R,~E,~V,~runner),~Exit{},~Transition{},~Enter{},~K,~take,~put,~publish,~same,Engine.Owners{exit,transition,enter},world,captured))