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{}))