restore_lifecycle.bend
bendvy-ecs-core@0.1.0.0 · 39 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/world.bend as W
3import bendvy-ecs-core@0.1.0.0/restore_world.bend as Adapter
4import bendvy-ecs-core@0.1.0.0/restore_data.bend as R
5import bendvy-ecs-core@0.1.0.0/transaction.bend as T
6import bendvy-ecs-core@0.1.0.0/commands.bend as Cmd
7
8def changes(~S:Data,~E:Data,~emit:R.Change<S> -> E,values:List<&2,R.Change<S>>) -> List<&2,E>:
9 match values:
10 case []:[]
11 case value <> rest:emit(value) <> changes(~S,~E,~emit,rest)
12def clear_join(~S:Data,~C:Type,~E:Data,~emit:R.Change<S> -> E,observed:C & List<&2,R.Change<S>>) -> C & List<&2,E>:
13 match observed:
14 case (store,events):(store,changes(~S,~E,~emit,events))
15def clear_store(~S:Data,~C:Type,~E:Data,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~emit:R.Change<S> -> E,store:C,handle:W.Handle<S>) -> C & List<&2,E>:
16 clear_join(~S,~C,~E,~emit,clear(store,handle))
17def despawned(~S:Data,~E:Data,~emit:R.Change<S> -> E,handle:W.Handle<S>) -> E:emit(R.Despawned{handle})
18def queued(~S:Data,~C:Type,~Resources:Type,~E:Data,next:T.Tx<W.World<S,C,Resources,E>,E> -> T.Tx<W.World<S,C,Resources,E>,E>,observed:T.Tx<W.World<S,C,Resources,E>,E> & W.Status) -> T.Tx<W.World<S,C,Resources,E>,E>:
19 match observed:
20 case (tx,_):next(tx)
21def queue(~S:Data,~C:Type,~Resources:Type,~E:Data,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~emit:R.Change<S> -> E,handles:List<&2,W.Handle<S>>,tx:T.Tx<W.World<S,C,Resources,E>,E>) -> T.Tx<W.World<S,C,Resources,E>,E>:
22 match handles:
23 case []:tx
24 case handle <> rest:queued(~S,~C,~Resources,~E,next => queue(~S,~C,~Resources,~E,~clear,~emit,rest,next),Cmd.tx_despawn_observed(~S,~C,~Resources,~E,~clear_store(~S,~C,~E,~clear,~emit),~despawned(~S,~E,~emit),tx,handle))
25def committed(~S:Data,~C:Type,~Resources:Type,~E:Data,observed:T.Returned<W.World<S,C,Resources,E>,Unit>) -> W.World<S,C,Resources,E>:
26 match observed:
27 case T.Returned{world,_}:W.barrier(~S,~C,~Resources,~E,world)
28def clean(~S:Data,~C:Type,~Resources:Type,~E:Data,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~emit:R.Change<S> -> E,handles:List<&2,W.Handle<S>>,world:W.World<S,C,Resources,E>) -> W.World<S,C,Resources,E>:
29 committed(~S,~C,~Resources,~E,Cmd.tx_finish(~S,~C,~Resources,~E,~Unit,queue(~S,~C,~Resources,~E,~clear,~emit,handles,T.begin(~W.World<S,C,Resources,E>,~E,Adapter.cancel_pending(~S,~C,~Resources,~E,world))),T.Success{}))
30def populate(~S:Data,~C:Type,~Resources:Type,~E:Data,world:W.World<S,C,Resources,E>,handle:W.Handle<S>,unit:Unit) -> W.World<S,C,Resources,E>:
31 world
32def spawn_committed(~S:Data,~C:Type,~Resources:Type,~E:Data,reservation:W.Reservation<S>,observed:T.Returned<W.World<S,C,Resources,E>,Unit>) -> W.World<S,C,Resources,E> & W.Reservation<S>:
33 match observed:
34 case T.Returned{world,_}:(W.barrier(~S,~C,~Resources,~E,world),reservation)
35def spawn_staged(~S:Data,~C:Type,~Resources:Type,~E:Data,observed:T.Tx<W.World<S,C,Resources,E>,E> & W.Reservation<S>) -> W.World<S,C,Resources,E> & W.Reservation<S>:
36 match observed:
37 case (tx,reservation):spawn_committed(~S,~C,~Resources,~E,reservation,Cmd.tx_finish(~S,~C,~Resources,~E,~Unit,tx,T.Success{}))
38def spawn(~S:Data,~C:Type,~Resources:Type,~E:Data,world:W.World<S,C,Resources,E>) -> W.World<S,C,Resources,E> & W.Reservation<S>:
39 spawn_staged(~S,~C,~Resources,~E,Cmd.tx_spawn(~S,~C,~Resources,~E,~Unit,~populate(~S,~C,~Resources,~E),T.begin(~W.World<S,C,Resources,E>,~E,world),Unit{}))