execution_relation_failure_retention.bend
bendvy-ecs-core@0.1.0.3 · 114 lines · 26 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/execution_composer_layout.bend as Layout
3import bendvy-ecs-core@0.1.0.3/execution_resource_policy.bend as Policy
4import bendvy-ecs-core@0.1.0.3/execution_relation_store.bend as Store
5import bendvy-ecs-core@0.1.0.3/world.bend as W
6import bendvy-ecs-core@0.1.0.3/lifecycle.bend as Life
7import bendvy-ecs-core@0.1.0.3/dependency_application.bend as App
8import bendvy-ecs-core@0.1.0.3/dependency_executor.bend as Exec
9import bendvy-ecs-core@0.1.0.3/relation_types.bend as T
10import bendvy-ecs-core@0.1.0.3/change_tick.bend as Tick
11
12
13
14
15
16
17def payload(~S:Data,~descriptor:T.Descriptor<S>,~P:Type,~shape:{P == Store.Store<S,descriptor> : Type},tick:Tick.Tick,owner:P) -> P & Unit:
18 (Layout.checked_owner(Store.Store<S,descriptor>,P,Equal.sym(Type,P,Store.Store<S,descriptor>,shape),Store.maintained(~S,~descriptor,tick,Layout.checked_owner(P,Store.Store<S,descriptor>,shape,owner))),Unit{})
19def restored(~S:Data,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{R == Layout.resources(~S,layout) : Type},stamp:Life.Stamp,rest:Layout.resource_rest(~S,layout,route),result:Layout.stored(layout,route) & Unit) -> R:
20 match result:
21 case (stored,_):Layout.checked_owner(Layout.resources(~S,layout),R,Equal.sym(Type,R,Layout.resources(~S,layout),same),Layout.resource_put(~S,layout,route,rest,Layout.ResourceSlot{stored,stamp}))
22def selected(~S:Data,~descriptor:T.Descriptor<S>,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{R == Layout.resources(~S,layout) : Type},~shape:{Layout.payload(layout,route) == Store.Store<S,descriptor> : Type},tick:Tick.Tick,result:Layout.resource_rest(~S,layout,route) & Layout.ResourceSlot<S,Layout.stored(layout,route),Layout.key(layout,route),Layout.origin(layout,route)>) -> R:
23 match result:
24 case (rest,Layout.ResourceSlot{stored,stamp}):restored(~S,~R,~layout,~route,~same,stamp,rest,Layout.rewrite(~layout,~route,Unit,payload(~S,~descriptor,~Layout.payload(layout,route),~shape,tick),stored))
25def maintain_resources(~S:Data,~descriptor:T.Descriptor<S>,~R:Type,~layout:Layout.Layout,~route:Layout.Route,~same:{R == Layout.resources(~S,layout) : Type},~shape:{Layout.payload(layout,route) == Store.Store<S,descriptor> : Type},tick:Tick.Tick,owner:R) -> R:
26 selected(~S,~descriptor,~R,~layout,~route,~same,~shape,tick,Layout.resource_take(~S,layout,route,Layout.checked_owner(R,Layout.resources(~S,layout),same,owner)))
27def clocked(~S:Data,~descriptor:T.Descriptor<S>,~C:Type,~R:Type,~E:Data,~layout:Layout.Layout,~route:Layout.Route,~same:{R == Layout.resources(~S,layout) : Type},~shape:{Layout.payload(layout,route) == Store.Store<S,descriptor> : Type},result:W.World<S,C,R,E> & Tick.Tick) -> W.World<S,C,R,E>:
28 match result:
29 case (W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock,lifecycle},tick):W.World{namespace,allocator,store,maintain_resources(~S,~descriptor,~R,~layout,~route,~same,~shape,tick,resource),events,pending,registrations,nextSystemId,clock,lifecycle}
30def world(~S:Data,~descriptor:T.Descriptor<S>,~C:Type,~R:Type,~E:Data,~layout:Layout.Layout,~route:Layout.Route,~same:{R == Layout.resources(~S,layout) : Type},~shape:{Layout.payload(layout,route) == Store.Store<S,descriptor> : Type},value:W.World<S,C,R,E>) -> W.World<S,C,R,E>:
31 clocked(~S,~descriptor,~C,~R,~E,~layout,~route,~same,~shape,W.clock(~S,~C,~R,~E,value))
32
33
34def Program(~S:Data,~resources:Layout.Layout) -> Type:
35 Tick.Tick -> Layout.resources(~S,resources) -> Layout.resources(~S,resources)
36def empty(~S:Data,~resources:Layout.Layout,tick:Tick.Tick,owners:Layout.resources(~S,resources)) -> Layout.resources(~S,resources):owners
37
38def extend(~S:Data,~resources:Layout.Layout,~route:Layout.Route,~valid:{Layout.grant_valid(~resources,~route) == True{} : Bool},~descriptor:T.Descriptor<S>,~payload:{Layout.payload(resources,route) == Store.Store<S,descriptor> : Type},~view:{Layout.view(resources,route) == Store.View<S,descriptor> : Data},~protected:{Layout.policy(resources,route) == Policy.ProtectedRelation{S,descriptor} : Policy.Policy},previous:Program(~S,~resources)) -> Program(~S,~resources):
39 +tick => owners => maintain_resources(~S,~descriptor,~Layout.resources(~S,resources),~resources,~route,~{==},~payload,tick,previous(tick,owners))
40
41type Catalogue<-S:Data,-resources:Layout.Layout> is Type:
42 Catalogue{routes:List<&2,Layout.Route>,program:Program(~S,~resources)}
43def none(~S:Data,~resources:Layout.Layout) -> Catalogue<S,resources>:
44 Catalogue{[],empty(~S,~resources)}
45def route_equal(left:Layout.Route,right:Layout.Route) -> Bool:
46 match left right:
47 case Layout.AtLeaf{} Layout.AtLeaf{}:True{}
48 case Layout.InLeft{left} Layout.InLeft{right}:route_equal(left,right)
49 case Layout.InRight{left} Layout.InRight{right}:route_equal(left,right)
50 case _ _:False{}
51def contains(+route:Layout.Route,routes:List<&2,Layout.Route>) -> Bool:
52 match routes:
53 case []:False{}
54 case selected <> rest:Bool.or(route_equal(route,selected),contains(route,rest))
55def admitted(~S:Data,~resources:Layout.Layout,~route:Layout.Route,~valid:{Layout.grant_valid(~resources,~route) == True{} : Bool},~descriptor:T.Descriptor<S>,~payload:{Layout.payload(resources,route) == Store.Store<S,descriptor> : Type},~view:{Layout.view(resources,route) == Store.View<S,descriptor> : Data},~protected:{Layout.policy(resources,route) == Policy.ProtectedRelation{S,descriptor} : Policy.Policy},duplicate:Bool,routes:List<&2,Layout.Route>,previous:Program(~S,~resources)) -> Catalogue<S,resources>:
56 match duplicate:
57 case True{}:Catalogue{routes,previous}
58 case False{}:Catalogue{route <> routes,extend(~S,~resources,~route,~valid,~descriptor,~payload,~view,~protected,previous)}
59def add(~S:Data,~resources:Layout.Layout,~route:Layout.Route,~valid:{Layout.grant_valid(~resources,~route) == True{} : Bool},~descriptor:T.Descriptor<S>,~payload:{Layout.payload(resources,route) == Store.Store<S,descriptor> : Type},~view:{Layout.view(resources,route) == Store.View<S,descriptor> : Data},~protected:{Layout.policy(resources,route) == Policy.ProtectedRelation{S,descriptor} : Policy.Policy},previous:Catalogue<S,resources>) -> Catalogue<S,resources>:
60 match previous:
61 case Catalogue{+routes,program}:admitted(~S,~resources,~route,~valid,~descriptor,~payload,~view,~protected,contains(route,routes),routes,program)
62def append(prefix:Layout.Route,+suffix:Layout.Route) -> Layout.Route:
63 match prefix:
64 case Layout.AtLeaf{}:suffix
65 case Layout.InLeft{rest}:Layout.InLeft{append(rest,suffix)}
66 case Layout.InRight{rest}:Layout.InRight{append(rest,suffix)}
67def leaf(policy:Policy.Policy,route:Layout.Route,routes:List<&2,Layout.Route>) -> Bool:
68 match policy:
69 case Policy.ProtectedRelation{_,_}:contains(route,routes)
70 case Policy.Ordinary{}:True{}
71 case Policy.ProtectedLifetimeScope{_}:True{}
72def covers(current:Layout.Layout,+prefix:Layout.Route,+routes:List<&2,Layout.Route>) -> Bool:
73 match current:
74 case Layout.EmptyLayout{}:True{}
75 case Layout.LayoutLeaf{_,_,_,_,policy}:leaf(policy,prefix,routes)
76 case Layout.ClassifiedLayoutLeaf{_,_,_,_,_,policy}:leaf(policy,prefix,routes)
77 case Layout.LayoutPair{left,right}:Bool.and(covers(left,append(prefix,Layout.InLeft{Layout.AtLeaf{}}),routes),covers(right,append(prefix,Layout.InRight{Layout.AtLeaf{}}),routes))
78
79type MaintenanceResult<-S:Data,-resources:Layout.Layout> is Type:
80 Maintained{owners:Layout.resources(~S,resources)}
81 IncompleteCatalogue{owners:Layout.resources(~S,resources)}
82def checked(~S:Data,~resources:Layout.Layout,complete:Bool,tick:Tick.Tick,program:Program(~S,~resources),owners:Layout.resources(~S,resources)) -> MaintenanceResult<S,resources>:
83 match complete:
84 case False{}:IncompleteCatalogue{owners}
85 case True{}:Maintained{program(tick,owners)}
86def apply(~S:Data,~resources:Layout.Layout,tick:Tick.Tick,catalogue:Catalogue<S,resources>,owners:Layout.resources(~S,resources)) -> MaintenanceResult<S,resources>:
87 match catalogue:
88 case Catalogue{routes,program}:checked(~S,~resources,covers(resources,Layout.AtLeaf{},routes),tick,program,owners)
89
90
91
92
93type Admission<-S:Data,-resources:Layout.Layout> is Type:
94 Accepted{program:Program(~S,~resources)}
95 Refused{catalogue:Catalogue<S,resources>}
96def preparation(~S:Data,~resources:Layout.Layout,complete:Bool,routes:List<&2,Layout.Route>,program:Program(~S,~resources)) -> Admission<S,resources>:
97 match complete:
98 case False{}:Refused{Catalogue{routes,program}}
99 case True{}:Accepted{program}
100def prepare(~S:Data,~resources:Layout.Layout,catalogue:Catalogue<S,resources>) -> Admission<S,resources>:
101 match catalogue:
102 case Catalogue{+routes,program}:preparation(~S,~resources,covers(resources,Layout.AtLeaf{},routes),routes,program)
103
104def retained_world(~S:Data,~C:Type,~R:Type,~E:Data,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},program:Program(~S,~resources),result:W.World<S,C,R,E> & Tick.Tick) -> W.World<S,C,R,E>:
105 match result:
106 case (W.World{namespace,allocator,columns,resource,events,pending,registrations,nextSystemId,clock,lifecycle},tick):W.World{namespace,allocator,columns,Layout.checked_owner(Layout.resources(~S,resources),R,Equal.sym(Type,R,Layout.resources(~S,resources),same),program(tick,Layout.checked_owner(R,Layout.resources(~S,resources),same,resource))),events,pending,registrations,nextSystemId,clock,lifecycle}
107
108
109
110def completed(~S:Data,~C:Type,~R:Type,~E:Data,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~Owners:Type,~Guards:Type,~Handler:Type,~Error:Data,~Out:Data,program:Program(~S,~resources),result:Exec.ExecutionResult<App.State<W.World<S,C,R,E>,Owners,Guards,Handler>,String,Error,Out>) -> Exec.ExecutionResult<App.State<W.World<S,C,R,E>,Owners,Guards,Handler>,String,Error,Out>:
111 match result:
112 case Exec.Finished{App.State{world,owners,guards,handler,bindings},events}:Exec.Finished{App.State{retained_world(~S,~C,~R,~E,~resources,~same,program,W.clock(~S,~C,~R,~E,world)),owners,guards,handler,bindings},events}
113 case Exec.Stopped{state,error,events}:Exec.Stopped{state,error,events}
114 case Exec.Invalid{state,reason}:Exec.Invalid{state,reason}