lifetime_scope_world_spawn.bend
bendvy-ecs-core@0.1.0.0 · 37 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/deferred_command.bend as Deferred
3import bendvy-ecs-core@0.1.0.0/trace_facts.bend as TraceFacts
4import bendvy-ecs-core@0.1.0.0/commands.bend as Cmd
5import bendvy-ecs-core@0.1.0.0/lifetime_scope.bend as Sc
6import bendvy-ecs-core@0.1.0.0/world.bend as W
7import bendvy-ecs-core@0.1.0.0/transaction.bend as T
8import bendvy-ecs-core@0.1.0.0/relation_commands.bend as A
9
10# Ordinary population receives the same full World context as Cmd.tx_spawn.
11# Membership is assigned only after successful activation and population.
12def assigned(~S:Data,~C:Type,~R:Type,~E:Data,seen:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> & Unit) -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>:
13 match seen:
14 case (world,_):world
15def assign(~S:Data,~C:Type,~R:Type,~E:Data,world:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,handle:W.Handle<S>,name:String) -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>:
16 match handle:
17 case W.Handle{_,id}:assigned(~S,~C,~R,~E,W.with_store(~S,~A.Store<S,Sc.Store<S,C>>,~R,~A.Notice<S,E>,~Unit,store => Sc.assigned(~S,~C,store,name,id),world))
18def activated(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~populate:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.Handle<S> -> P -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,seen:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> & W.Status,+handle:W.Handle<S>,payload:P,name:String) -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>:
19 match seen:
20 case (world,W.Accepted{}):assign(~S,~C,~R,~E,populate(world,handle,payload),handle,name)
21 case (world,W.Rejected{_}):world
22def apply(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~populate:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.Handle<S> -> P -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,world:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,+handle:W.Handle<S>,payload:P,name:String) -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>:
23 activated(~S,~C,~R,~E,~P,~populate,W.activate(~S,~A.Store<S,Sc.Store<S,C>>,~R,~A.Notice<S,E>,world,handle),handle,payload,name)
24def reserved(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~populate:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.Handle<S> -> P -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,seen:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> & W.Reservation<S>,undo:List<(W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>)>,commands:List<Deferred.Command<W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>>>,events:List<&2,A.Notice<S,E>>,trace:TraceFacts.State,payload:P,name:String) -> T.Tx<W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,A.Notice<S,E>> & Sc.SpawnResult<S,P>:
25 match seen:
26 case (world,W.ReservationRejected{error}):(T.Tx{world,undo,commands,events,trace},Sc.SpawnRejected{payload,error})
27 case (world,W.Reserved{+handle}):(Cmd.track_pending(~S,~A.Store<S,Sc.Store<S,C>>,~R,~A.Notice<S,E>,T.Tx{world,undo,Deferred.Raw{(world => apply(~S,~C,~R,~E,~P,~populate,world,handle,payload,name))} <> commands,events,trace},handle),Sc.Spawned{handle})
28def checked(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~populate:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.Handle<S> -> P -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,same:Bool,world:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,undo:List<(W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>)>,commands:List<Deferred.Command<W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>>>,events:List<&2,A.Notice<S,E>>,trace:TraceFacts.State,payload:P,name:String) -> T.Tx<W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,A.Notice<S,E>> & Sc.SpawnResult<S,P>:
29 match same:
30 case False{}:(T.Tx{world,undo,commands,events,trace},Sc.SpawnRejected{payload,W.MissingEntity{}})
31 case True{}:reserved(~S,~C,~R,~E,~P,~populate,W.reserve_id(~S,~A.Store<S,Sc.Store<S,C>>,~R,~A.Notice<S,E>,world),undo,commands,events,trace,payload,name)
32def namespaced(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~populate:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.Handle<S> -> P -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,seen:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> & U32,scope:Sc.Scope<S>,undo:List<(W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>)>,commands:List<Deferred.Command<W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>>>,events:List<&2,A.Notice<S,E>>,trace:TraceFacts.State,payload:P) -> T.Tx<W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,A.Notice<S,E>> & Sc.SpawnResult<S,P>:
33 match seen scope:
34 case (world,current) Sc.Scope{namespace,name}:checked(~S,~C,~R,~E,~P,~populate,U32.is_eq(current,namespace),world,undo,commands,events,trace,payload,name)
35def tx_spawn_in(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~populate:W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>> -> W.Handle<S> -> P -> W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,tx:T.Tx<W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,A.Notice<S,E>>,scope:Sc.Scope<S>,payload:P) -> T.Tx<W.World<S,A.Store<S,Sc.Store<S,C>>,R,A.Notice<S,E>>,A.Notice<S,E>> & Sc.SpawnResult<S,P>:
36 match tx:
37 case T.Tx{world,undo,commands,events,trace}:namespaced(~S,~C,~R,~E,~P,~populate,W.namespace(~S,~A.Store<S,Sc.Store<S,C>>,~R,~A.Notice<S,E>,world),scope,undo,commands,events,trace,payload)