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