execution_relation_linked_despawn.bend

bendvy-ecs-core@0.1.0.3 · 66 lines · 13 definitions

1import Base
2import bendvy-ecs-core@0.1.0.3/world.bend as W
3import bendvy-ecs-core@0.1.0.3/entity_allocator.bend as Allocator
4import bendvy-ecs-core@0.1.0.3/entity_key.bend as Key
5import bendvy-ecs-core@0.1.0.3/execution_composer_layout.bend as Layout
6import bendvy-ecs-core@0.1.0.3/execution_command_buffer.bend as Buffer
7import bendvy-ecs-core@0.1.0.3/execution_command_permission.bend as Permission
8import bendvy-ecs-core@0.1.0.3/execution_relation_context.bend as Context
9import bendvy-ecs-core@0.1.0.3/execution_relation_resource_snapshot.bend as Snapshot
10import bendvy-ecs-core@0.1.0.3/execution_lifetime_scope_coverage.bend as Coverage
11import bendvy-ecs-core@0.1.0.3/execution_lifetime_scope_cleanup.bend as Cleanup
12import bendvy-ecs-core@0.1.0.3/execution_lifetime_scope_world_access.bend as Access
13import bendvy-ecs-core@0.1.0.3/execution_lifetime_scope_store.bend as Store
14import bendvy-ecs-core@0.1.0.3/execution_lifetime_scope_resource_dispatch.bend as Dispatch
15import bendvy-ecs-core@0.1.0.3/relation_cleanup_engine.bend as Engine
16import bendvy-ecs-core@0.1.0.3/relation_types.bend as T
17import bendvy-ecs-core@0.1.0.3/change_tick.bend as Tick
18
19def denied(-S:Data,-C:Type,-R:Type,-E:Data,-P:Type,-D:Type,handle:W.Handle<S>,reason:Buffer.ScopeDenial,receipts:List<Buffer.Receipt<S,P,D>>,world:W.World<S,C,R,E>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
20  (world,Buffer.LinkedDespawn{handle,Buffer.LinkedDenied{reason},List.reverse(&1,Buffer.Receipt<S,P,D>,receipts),[]})
21def finished(-S:Data,-C:Type,-R:Type,-E:Data,-P:Type,-D:Type,handle:W.Handle<S>,result:Engine.Progress<S,Cleanup.State<S,C,R,E,P,D>>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
22  match result:
23    case Engine.Complete{Cleanup.State{world,receipts,_,_,_}}:(world,Buffer.LinkedDespawn{handle,Buffer.LinkedComplete{},List.reverse(&1,Buffer.Receipt<S,P,D>,receipts),[]})
24    case Engine.Incomplete{Cleanup.State{world,receipts,_,_,_},frames}:(world,Buffer.LinkedDespawn{handle,Buffer.LinkedPaused{},List.reverse(&1,Buffer.Receipt<S,P,D>,receipts),frames})
25def after(routes:List<&2,Layout.Route>) -> Cleanup.AfterDespawn:
26  match routes:
27    case []:Cleanup.KeepMembership{}
28    case routes:Cleanup.ForgetMembership{routes}
29def start(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~D:Type,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~selection:Permission.Selection<S,resources>,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),+handle:W.Handle<S>,+views:List<&2,Snapshot.GraphView<S>>,routes:List<&2,Layout.Route>,receipts:List<Buffer.Receipt<S,P,D>>,tick:Tick.Tick,world:W.World<S,C,R,E>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
30  match handle world:
31    case W.Handle{+namespace,+key} W.World{worldNamespace,Allocator.Allocator{next,+high,slots,capacity,depth,free,order},columns,resource,events,pending,registrations,nextSystem,clock,lifecycle}:finished(S,C,R,E,P,D,W.Handle{namespace,key},Engine.automatic(~S,~Cleanup.State<S,C,R,E,P,D>,~Cleanup.step_shared(~S,~C,~R,~E,~P,~D,~resources,~same,~selection,~dispose),Cleanup.State{W.World{worldNamespace,Allocator.Allocator{next,high,slots,capacity,depth,free,order},columns,resource,events,pending,registrations,nextSystem,clock,lifecycle},receipts,after(routes),tick,False{}},U32.to_nat(high),Cleanup.edges(S,views),namespace,key,Cleanup.descriptors(S,views)))
32def probe_namespace(-S:Data,-C:Type,-R:Type,-E:Data,-P:Type,-D:Type,allowed:Bool,handle:W.Handle<S>,receipts:List<Buffer.Receipt<S,P,D>>,next:List<Buffer.Receipt<S,P,D>> -> W.World<S,C,R,E> -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>,world:W.World<S,C,R,E>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
33  match allowed:
34    case True{}:next(receipts,world)
35    case False{}:denied(S,C,R,E,P,D,handle,Buffer.ForeignNamespace{},receipts,world)
36def probe_result(-S:Data,-C:Type,-R:Type,-E:Data,-P:Type,-D:Type,+namespace:U32,+handle:W.Handle<S>,+route:Layout.Route,receipts:List<Buffer.Receipt<S,P,D>>,next:List<Buffer.Receipt<S,P,D>> -> W.World<S,C,R,E> -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>,result:W.World<S,C,R,E> & Dispatch.Outcome<S>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
37  match result:
38    case (world,Dispatch.Completed{Store.Inspected{+stored}}):probe_namespace(S,C,R,E,P,D,U32.is_eq(namespace,stored),handle,Buffer.ScopeStoreApplied{route,Store.Inspect{},Dispatch.Completed{Store.Inspected{stored}}} <> receipts,next,world)
39    case (world,outcome):denied(S,C,R,E,P,D,handle,Buffer.ScopeStoreRefused{},Buffer.ScopeStoreApplied{route,Store.Inspect{},outcome} <> receipts,world)
40def probe(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~D:Type,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~selection:Permission.Selection<S,resources>,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),+context:Context.Context<S,R,resources,same>,+handle:W.Handle<S>,+namespace:U32,+views:List<&2,Snapshot.GraphView<S>>,+all:List<&2,Layout.Route>,routes:List<&2,Layout.Route>,receipts:List<Buffer.Receipt<S,P,D>>,+tick:Tick.Tick,world:W.World<S,C,R,E>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
41  match routes:
42    case []:start(~S,~C,~R,~E,~P,~D,~resources,~same,~selection,~dispose,handle,views,all,receipts,tick,world)
43    case +route <> rest:probe_result(S,C,R,E,P,D,namespace,handle,route,receipts,receipts => world => probe(~S,~C,~R,~E,~P,~D,~resources,~same,~selection,~dispose,context,handle,namespace,views,all,rest,receipts,tick,world),Access.apply(~S,~C,~R,~E,~resources,~same,~selection,context,route,Store.Inspect{},world,tick))
44def graphs_validated(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~D:Type,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~selection:Permission.Selection<S,resources>,~relations:Permission.Relations<S,resources>,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),valid:Bool,context:Context.Context<S,R,resources,same>,handle:W.Handle<S>,namespace:U32,views:List<&2,Snapshot.GraphView<S>>,tick:Tick.Tick,world:W.World<S,C,R,E>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
45  match valid:
46    case False{}:denied(S,C,R,E,P,D,handle,Buffer.ForeignNamespace{},[],world)
47    case True{}:probe(~S,~C,~R,~E,~P,~D,~resources,~same,~selection,~dispose,context,handle,namespace,views,Coverage.cleanup_scopes(S,resources,relations,Permission.cleanup_routes(S,resources,selection)),Coverage.cleanup_scopes(S,resources,relations,Permission.cleanup_routes(S,resources,selection)),[],tick,world)
48def observed(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~D:Type,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~selection:Permission.Selection<S,resources>,~relations:Permission.Relations<S,resources>,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),context:Context.Context<S,R,resources,same>,handle:W.Handle<S>,tick:Tick.Tick,result:W.World<S,C,R,E> & List<&2,Snapshot.GraphView<S>>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
49  match context result:
50    case Context.Context{+namespace}, (world,+views):graphs_validated(~S,~C,~R,~E,~P,~D,~resources,~same,~selection,~relations,~dispose,Coverage.namespaces(~S,namespace,views),Context.Context{namespace},handle,namespace,views,tick,world)
51def covered(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~D:Type,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~selection:Permission.Selection<S,resources>,~relations:Permission.Relations<S,resources>,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),complete:Bool,context:Context.Context<S,R,resources,same>,handle:W.Handle<S>,tick:Tick.Tick,world:W.World<S,C,R,E>) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
52  match complete:
53    case False{}:denied(S,C,R,E,P,D,handle,Buffer.MissingAuthority{},[],world)
54    case True{}:observed(~S,~C,~R,~E,~P,~D,~resources,~same,~selection,~relations,~dispose,context,handle,tick,Access.graphs(~S,~C,~R,~E,~resources,~same,~selection,world))
55def live_checked(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~D:Type,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~selection:Permission.Selection<S,resources>,~relations:Permission.Relations<S,resources>,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),context:Context.Context<S,R,resources,same>,handle:W.Handle<S>,tick:Tick.Tick,result:W.World<S,C,R,E> & Bool) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
56  match result:
57    case (world,False{}):(world,Buffer.DespawnRefused{handle})
58    case (world,True{}):covered(~S,~C,~R,~E,~P,~D,~resources,~same,~selection,~relations,~dispose,Coverage.cleanup_complete(~S,~resources,relations,Permission.cleanup_routes(S,resources,selection)),context,handle,tick,world)
59def context_checked(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~D:Type,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~selection:Permission.Selection<S,resources>,~relations:Permission.Relations<S,resources>,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),+context:Context.Context<S,R,resources,same>,+handle:W.Handle<S>,tick:Tick.Tick,result:W.World<S,C,R,E> & Bool) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
60  match result:
61    case (world,False{}):denied(S,C,R,E,P,D,handle,Buffer.ForeignNamespace{},[],world)
62    case (world,True{}):live_checked(~S,~C,~R,~E,~P,~D,~resources,~same,~selection,~relations,~dispose,context,handle,tick,Cleanup.live(S,C,R,E,world,handle))
63def apply(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~D:Type,~resources:Layout.Layout,~same:{R == Layout.resources(~S,resources) : Type},~selection:Permission.Selection<S,resources>,~relations:Permission.Relations<S,resources>,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),+context:Context.Context<S,R,resources,same>,permission:Permission.Permission,world:W.World<S,C,R,E>,+handle:W.Handle<S>,tick:Tick.Tick) -> W.World<S,C,R,E> & Buffer.Receipt<S,P,D>:
64  match permission:
65    case Permission.FamilyOnly{}:(world,Buffer.DespawnRefused{handle})
66    case Permission.EntityStructural{}:context_checked(~S,~C,~R,~E,~P,~D,~resources,~same,~Permission.cleanup_selection(S,resources,selection),~relations,~dispose,context,handle,tick,Context.matches(~S,~C,~R,~E,~resources,~same,context,world))