checked_condition_schedule.bend

bendvy-ecs-core@0.1.0.1 · 84 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.1/ordinary_checked_condition.bend as Cond
3import bendvy-ecs-core@0.1.0.1/ordinary_checked_bindings.bend as B
4import bendvy-ecs-core@0.1.0.1/check.bend as K
5import bendvy-ecs-core@0.1.0.1/world.bend as W
6import bendvy-ecs-core@0.1.0.1/system.bend as Sys
7import bendvy-ecs-core@0.1.0.1/schedule.bend as Sch
8import bendvy-ecs-core@0.1.0.1/schedule_provision.bend as SP
9# Same membership/duplicate/namespace, step and SP needs behavior as
10# ordinary-condition-composition. Only selected Check errors differ in transport.
11type Error<BodyError:Data> is Data:
12  SystemError{error:BodyError}
13  CheckError{error:K.Error}
14  ConditionUnavailable{}
15  ConditionRegistrationRejected{}
16
17type Attachment<S:Data,C:Type,R:Type,E:Data,H:Type,B:Type,-select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>> is Type:
18  Attached{schedule:Sch.Schedule<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>}
19  AttachmentRejected{schedule:Sch.Schedule<S,C,R,E,H>,bindings:B.Bindings<W.World<S,C,R,E>,B,select>}
20def attached(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,allowed:Bool,namespace:U32,name:String,+steps:List<&2,Sch.Step>,owners:H,bindings:B.Bindings<W.World<S,C,R,E>,B,select>,facts:List<&2,B.Description>) -> Attachment<S,C,R,E,H,B,select>:
21  match allowed:
22    case False{}:AttachmentRejected{Sch.Schedule{namespace,name,steps,owners},bindings}
23    case True{}:Attached{Sch.Schedule{namespace,name,steps,(owners,bindings)}}
24def attach(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,schedule:Sch.Schedule<S,C,R,E,H>,bindings:B.Bindings<W.World<S,C,R,E>,B,select>) -> Attachment<S,C,R,E,H,B,select>:
25  match schedule bindings:
26    case Sch.Schedule{namespace,name,+steps,owners} B.Bindings{state,+facts}:attached(~S,~C,~R,~E,~H,~B,~select,Bool.and(B.unique(facts,[]),B.targets(facts,steps)),namespace,name,steps,owners,B.Bindings{state,facts},facts)
27
28def body_outcome(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,bindings:B.Bindings<W.World<S,C,R,E>,B,select>,owners:H,outcome:Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>) -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & Sys.Outcome<W.World<S,C,R,E>,Error<BodyError>,Unit>:
29  match outcome:
30    case Sys.Succeeded{world,value}:((owners,bindings),Sys.Succeeded{world,value})
31    case Sys.Failed{world,error}:((owners,bindings),Sys.Failed{world,SystemError{error}})
32def body_returned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,bindings:B.Bindings<W.World<S,C,R,E>,B,select>,returned:H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>) -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & Sys.Outcome<W.World<S,C,R,E>,Error<BodyError>,Unit>:
33  match returned:
34    case (owners,outcome):body_outcome(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,bindings,owners,outcome)
35def body_dispatch(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,owners:H & B.Bindings<W.World<S,C,R,E>,B,select>,world:W.World<S,C,R,E>,id:U32) -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & Sys.Outcome<W.World<S,C,R,E>,Error<BodyError>,Unit>:
36  match owners:
37    case (gameplay,bindings):body_returned(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,bindings,dispatch(gameplay,world,id))
38def guard_decision_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,next:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> List<&2,Sch.Observation> -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>,value:Bool,owners:H,bindings:B.Bindings<W.World<S,C,R,E>,B,select>,world:W.World<S,C,R,E>,+namespace:U32,+name:String,+all:List<&2,Sch.Step>,+observations:List<&2,Sch.Observation>,+id:U32) -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
39  match value:
40    case False{}:next((owners,bindings),world,List.append(&2,Sch.Observation,observations,[Sch.Skipped{id}]))
41    case True{}:Sch.after_dispatch(~S,~C,~R,~E,~(H & B.Bindings<W.World<S,C,R,E>,B,select>),~Error<BodyError>,next,body_dispatch(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,(owners,bindings),world,id),namespace,name,all,observations,id)
42def guard_returned_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,next:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> List<&2,Sch.Observation> -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>,facts:List<&2,B.Description>,owners:H,result:B.Selection<W.World<S,C,R,E>,B>,namespace:U32,name:String,all:List<&2,Sch.Step>,observations:List<&2,Sch.Observation>,id:U32) -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
43  match result:
44    case B.Selected{world,state,Done{value}}:guard_decision_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,next,value,owners,B.Bindings{state,facts},world,namespace,name,all,observations,id)
45    case B.Unbound{world,state}:guard_decision_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,next,True{},owners,B.Bindings{state,facts},world,namespace,name,all,observations,id)
46    case B.Selected{world,state,Fail{Cond.CheckError{error}}}:Sch.Failed{Sch.Schedule{namespace,name,all,(owners,B.Bindings{state,facts})},world,CheckError{error},observations}
47    case B.Selected{world,state,Fail{Cond.NoValue{}}}:Sch.Failed{Sch.Schedule{namespace,name,all,(owners,B.Bindings{state,facts})},world,ConditionUnavailable{},observations}
48    case B.Selected{world,state,Fail{Cond.InvalidRegistration{}}}:Sch.Failed{Sch.Schedule{namespace,name,all,(owners,B.Bindings{state,facts})},world,ConditionRegistrationRejected{},observations}
49    case B.Selected{world,state,Fail{Cond.NoBinding{}}}:guard_decision_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,next,True{},owners,B.Bindings{state,facts},world,namespace,name,all,observations,id)
50def guard_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,next:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> List<&2,Sch.Observation> -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>,owners:H & B.Bindings<W.World<S,C,R,E>,B,select>,world:W.World<S,C,R,E>,namespace:U32,name:String,all:List<&2,Sch.Step>,observations:List<&2,Sch.Observation>,+id:U32) -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
51  match owners:
52    case (gameplay,B.Bindings{state,facts}):guard_returned_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,next,facts,gameplay,select(state,world,id),namespace,name,all,observations,id)
53def execute_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,steps:List<&2,Sch.Step>,owners:H & B.Bindings<W.World<S,C,R,E>,B,select>,world:W.World<S,C,R,E>,+namespace:U32,+name:String,+all:List<&2,Sch.Step>,observations:List<&2,Sch.Observation>) -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
54  match steps:
55    case []:Sch.Finished{Sch.Schedule{namespace,name,all,owners},world,observations}
56    case Sch.Phase{phase} <> rest:execute_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,rest,owners,world,namespace,name,all,List.append(&2,Sch.Observation,observations,[Sch.Entered{phase}]))
57    case Sch.Barrier{} <> rest:Sch.after_skip(~S,~C,~R,~E,~(H & B.Bindings<W.World<S,C,R,E>,B,select>),~Error<BodyError>,h => w => obs => execute_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,rest,h,w,namespace,name,all,obs),barrier(owners,world),List.append(&2,Sch.Observation,observations,[Sch.Applied{}]))
58    case Sch.System{id,_} <> rest:guard_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,h => w => obs => execute_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,rest,h,w,namespace,name,all,obs),owners,world,namespace,name,all,observations,id)
59def run_checked_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,allowed:Bool,schedule:Sch.Schedule<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>) -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
60  match allowed schedule:
61    case False{} schedule:Sch.Rejected{schedule,world}
62    case True{} Sch.Schedule{+namespace,+name,+steps,owners}:execute_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,steps,owners,world,namespace,name,steps,[])
63def run_namespaced_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,schedule:Sch.Schedule<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>,observed:W.World<S,C,R,E> & U32) -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
64  match schedule observed:
65    case Sch.Schedule{+namespace,name,+steps,(gameplay,B.Bindings{state,+facts})}, (world,actual):run_checked_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,Bool.and(U32.is_eq(namespace,actual),Bool.and(B.unique(facts,[]),B.targets(facts,steps))),Sch.Schedule{namespace,name,steps,(gameplay,B.Bindings{state,facts})},world)
66def run_schedule_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,schedule:Sch.Schedule<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>) -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
67  run_namespaced_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,schedule,W.namespace(~S,~C,~R,~E,world))
68
69def provision_checked_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,missing:List<&2,SP.Requirement<S>>,schedule:Sch.Schedule<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>,needs:List<&2,SP.Requirement<S>>) -> SP.ProvisionResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
70  match missing:
71    case first <> rest:SP.Missing{SP.Provisioned{schedule,needs},world,first <> rest}
72    case []:SP.Executed{run_schedule_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,schedule,world),needs}
73def provision_available_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,observed:W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,schedule:Sch.Schedule<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>,+needs:List<&2,SP.Requirement<S>>) -> SP.ProvisionResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
74  match observed:
75    case (world,available):provision_checked_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,SP.missing_requirements(~S,needs,available),schedule,world,needs)
76def run_provisioned_with_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~barrier:(H & B.Bindings<W.World<S,C,R,E>,B,select>) -> W.World<S,C,R,E> -> (H & B.Bindings<W.World<S,C,R,E>,B,select>) & W.World<S,C,R,E>,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,schedule:SP.Provisioned<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>) -> SP.ProvisionResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
77  match schedule:
78    case SP.Provisioned{schedule,needs}:provision_available_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~barrier,provision(world),schedule,needs)
79
80def run_schedule(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,schedule:Sch.Schedule<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>) -> Sch.RunResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
81  run_schedule_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~Sch.default_barrier(~S,~C,~R,~E,~(H & B.Bindings<W.World<S,C,R,E>,B,select>)),schedule,world)
82
83def run_provisioned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> B.Selection<W.World<S,C,R,E>,B>,~BodyError:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,BodyError,Unit>,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,schedule:SP.Provisioned<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>>,world:W.World<S,C,R,E>) -> SP.ProvisionResult<S,C,R,E,H & B.Bindings<W.World<S,C,R,E>,B,select>,Error<BodyError>>:
84  run_provisioned_with_barrier(~S,~C,~R,~E,~H,~B,~select,~BodyError,~dispatch,~Sch.default_barrier(~S,~C,~R,~E,~(H & B.Bindings<W.World<S,C,R,E>,B,select>)),~provision,schedule,world)