bundle_component_install.bend

bendvy-ecs-core@0.1.0.0 · 37 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.0/change_tick.bend as Tick
3import entity_key.bend as Key
4import world.bend as W
5import component.bend as C
6import column.bend as Col
7import lifecycle.bend as L
8import bundle_install.bend as F
9
10type Entry<S:Data,Owner:Type> is Type:
11  Entry{handle:W.Handle<S>,owner:Maybe<&1,Owner>}
12type Recovery<S:Data,Owner:Type> is Type:
13  Recovery{previous:Entry<S,Owner>,stamp:L.Stamp}
14def undone(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,+handle:W.Handle<S>,+stamp:L.Stamp,observed:W.World<S,Store,R,E> & C.Swap<C>) -> F.Restore<W.World<S,Store,R,E>,Entry<S,C>,Recovery<S,C>>:
15  match observed:
16    case (world,C.Swapped{incoming}): F.Restored{C.restore_stamp(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,handle,stamp,world),Entry{handle,incoming}}
17    case (world,C.SwapRejected{old}): F.Pending{world,Recovery{Entry{handle,old},stamp},W.CapacityExceeded{}}
18def undo_present(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,+handle:W.Handle<S>,+id:U32,stamp:L.Stamp,world:W.World<S,Store,R,E>,observed:Maybe<&1,C> & Bool) -> F.Restore<W.World<S,Store,R,E>,Entry<S,C>,Recovery<S,C>>:
19  (previous,present)=observed
20  undone(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,handle,stamp,C.swap_world(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,previous,present,Tick.zero(),world))
21def undo_checked(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,+handle:W.Handle<S>,+id:U32,stamp:L.Stamp,previous:Maybe<&1,C>,observed:W.World<S,Store,R,E> & Bool) -> F.Restore<W.World<S,Store,R,E>,Entry<S,C>,Recovery<S,C>>:
22  match observed:
23    case (world,False{}): F.Pending{world,Recovery{Entry{handle,previous},stamp},W.MissingEntity{}}
24    case (world,True{}): undo_present(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,handle,id,stamp,world,C.owner_present(~C,previous))
25def undo(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,recovery:Recovery<S,C>,world:W.World<S,Store,R,E>) -> F.Restore<W.World<S,Store,R,E>,Entry<S,C>,Recovery<S,C>>:
26  match recovery:
27    case Recovery{Entry{W.Handle{+ns,+id},previous},stamp}: undo_checked(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,W.Handle{ns,id},Key.index(id),stamp,previous,W.valid(~S,~Store,~R,~E,world,W.Handle{ns,id}))
28def replaced(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,+handle:W.Handle<S>,+stamp:L.Stamp,result:C.Replacement<W.World<S,Store,R,E>,C>) -> F.Attempt<W.World<S,Store,R,E>,Entry<S,C>,Recovery<S,C>>:
29  match result:
30    case C.ReplaceRejected{world,incoming,error}: F.Refused{world,Entry{handle,incoming},error}
31    case C.Replaced{world,previous}: F.Installed{world,w => undo(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,Recovery{Entry{handle,previous},stamp},w)}
32def stamped(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,+family:C.Family<S,Store,Rest,C,V,Token,take,put,project>,+handle:W.Handle<S>,incoming:Maybe<&1,C>,observed:W.World<S,Store,R,E> & L.Stamp) -> F.Attempt<W.World<S,Store,R,E>,Entry<S,C>,Recovery<S,C>>:
33  (world,stamp)=observed
34  replaced(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,handle,stamp,C.replace(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,family,world,handle,incoming))
35def install(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,+family:C.Family<S,Store,Rest,C,V,Token,take,put,project>,world:W.World<S,Store,R,E>,entry:Entry<S,C>) -> F.Attempt<W.World<S,Store,R,E>,Entry<S,C>,Recovery<S,C>>:
36  match entry:
37    case Entry{+handle,incoming}: stamped(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,family,handle,incoming,C.lifecycle(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,family,world,handle))