1 import Base 2 import ./world.bend as W 3 import ./entity_allocator.bend as Allocator 4 import ./entity_key.bend as Key 5 import ./execution_composer_layout.bend as Layout 6 import ./execution_command_buffer.bend as Buffer 7 import ./execution_command_permission.bend as Permission 8 import ./execution_relation_context.bend as Context 9 import ./execution_relation_resource_snapshot.bend as Snapshot 10 import ./execution_lifetime_scope_coverage.bend as Coverage 11 import ./execution_lifetime_scope_cleanup.bend as Cleanup 12 import ./execution_lifetime_scope_world_access.bend as Access 13 import ./execution_lifetime_scope_store.bend as Store 14 import ./execution_lifetime_scope_resource_dispatch.bend as Dispatch 15 import ./relation_cleanup_engine.bend as Engine 16 import ./relation_types.bend as T 17 import ./change_tick.bend as Tick 18 19 def denied(-S:Data,-C:Type,-R:Type,-E:Data,-P:Type,-D:Type,handle:W.Handle,reason:Buffer.ScopeDenial,receipts:List>,world:W.World) -> W.World & Buffer.Receipt: 20 (world,Buffer.LinkedDespawn{handle,Buffer.LinkedDenied{reason},List.reverse(&1,Buffer.Receipt,receipts),[]}) 21 def finished(-S:Data,-C:Type,-R:Type,-E:Data,-P:Type,-D:Type,handle:W.Handle,result:Engine.Progress>) -> W.World & Buffer.Receipt: 22 match result: 23 case Engine.Complete{Cleanup.State{world,receipts,_,_,_}}:(world,Buffer.LinkedDespawn{handle,Buffer.LinkedComplete{},List.reverse(&1,Buffer.Receipt,receipts),[]}) 24 case Engine.Incomplete{Cleanup.State{world,receipts,_,_,_},frames}:(world,Buffer.LinkedDespawn{handle,Buffer.LinkedPaused{},List.reverse(&1,Buffer.Receipt,receipts),frames}) 25 def after(routes:List<&2,Layout.Route>) -> Cleanup.AfterDespawn: 26 match routes: 27 case []:Cleanup.KeepMembership{} 28 case routes:Cleanup.ForgetMembership{routes} 29 def 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,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),+handle:W.Handle,+views:List<&2,Snapshot.GraphView>,routes:List<&2,Layout.Route>,receipts:List>,tick:Tick.Tick,world:W.World) -> W.World & Buffer.Receipt: 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,~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))) 32 def probe_namespace(-S:Data,-C:Type,-R:Type,-E:Data,-P:Type,-D:Type,allowed:Bool,handle:W.Handle,receipts:List>,next:List> -> W.World -> W.World & Buffer.Receipt,world:W.World) -> W.World & Buffer.Receipt: 33 match allowed: 34 case True{}:next(receipts,world) 35 case False{}:denied(S,C,R,E,P,D,handle,Buffer.ForeignNamespace{},receipts,world) 36 def probe_result(-S:Data,-C:Type,-R:Type,-E:Data,-P:Type,-D:Type,+namespace:U32,+handle:W.Handle,+route:Layout.Route,receipts:List>,next:List> -> W.World -> W.World & Buffer.Receipt,result:W.World & Dispatch.Outcome) -> W.World & Buffer.Receipt: 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) 40 def 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,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),+context:Context.Context,+handle:W.Handle,+namespace:U32,+views:List<&2,Snapshot.GraphView>,+all:List<&2,Layout.Route>,routes:List<&2,Layout.Route>,receipts:List>,+tick:Tick.Tick,world:W.World) -> W.World & Buffer.Receipt: 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)) 44 def 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,~relations:Permission.Relations,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),valid:Bool,context:Context.Context,handle:W.Handle,namespace:U32,views:List<&2,Snapshot.GraphView>,tick:Tick.Tick,world:W.World) -> W.World & Buffer.Receipt: 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) 48 def 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,~relations:Permission.Relations,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),context:Context.Context,handle:W.Handle,tick:Tick.Tick,result:W.World & List<&2,Snapshot.GraphView>) -> W.World & Buffer.Receipt: 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) 51 def 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,~relations:Permission.Relations,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),complete:Bool,context:Context.Context,handle:W.Handle,tick:Tick.Tick,world:W.World) -> W.World & Buffer.Receipt: 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)) 55 def 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,~relations:Permission.Relations,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),context:Context.Context,handle:W.Handle,tick:Tick.Tick,result:W.World & Bool) -> W.World & Buffer.Receipt: 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) 59 def 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,~relations:Permission.Relations,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),+context:Context.Context,+handle:W.Handle,tick:Tick.Tick,result:W.World & Bool) -> W.World & Buffer.Receipt: 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)) 63 def 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,~relations:Permission.Relations,~dispose:Cleanup.Dispose(~S,~C,~R,~E,~P,~D),+context:Context.Context,permission:Permission.Permission,world:W.World,+handle:W.Handle,tick:Tick.Tick) -> W.World & Buffer.Receipt: 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))