recoverable_component_family.bend

bendvy-ecs-core@0.1.0.1 · 41 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.1/clock_state.bend as Clock
3import bendvy-ecs-core@0.1.0.1/deferred_command.bend as Deferred
4import entity_allocator.bend as Alloc
5import bendvy-ecs-core@0.1.0.1/world.bend as W
6import bendvy-ecs-core@0.1.0.1/column.bend as Col
7import bendvy-ecs-core@0.1.0.1/component.bend as C
8import bendvy-ecs-core@0.1.0.1/lifecycle.bend as Life
9import bendvy-ecs-core@0.1.0.1/recoverable_component.bend as RC
10# Existing Family lenses remain trusted schema provisioning, not gameplay grants.
11# No caller-authored inverse or recovery pack callback is introduced.
12def replaced(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,handle:W.Handle<S>,stamp:Life.Stamp,result:C.Replacement<W.World<S,Store,R,E>,P>) -> RC.Replacement<W.World<S,Store,R,E>,S,P>:
13  match result:
14    case C.Replaced{world,previous}:RC.Applied{world,RC.Record{handle,stamp,previous}}
15    case C.ReplaceRejected{world,incoming,error}:RC.Refused{world,incoming,error}
16def stamped(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,family:C.Family<S,Store,Rest,P,V,Token,take,put,view>,+handle:W.Handle<S>,incoming:Maybe<P>,observed:W.World<S,Store,R,E> & Life.Stamp) -> RC.Replacement<W.World<S,Store,R,E>,S,P>:
17  match observed:
18    case (world,stamp):replaced(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,handle,stamp,C.replace(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,family,world,handle,incoming))
19def replace(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,+family:C.Family<S,Store,Rest,P,V,Token,take,put,view>,world:W.World<S,Store,R,E>,+handle:W.Handle<S>,incoming:Maybe<P>) -> RC.Replacement<W.World<S,Store,R,E>,S,P>:
20  stamped(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,family,handle,incoming,C.lifecycle(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,family,world,handle))
21def column_returned(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,rest:Rest,result:Col.Column<S,P> & RC.Record<S,P>) -> Store & RC.Record<S,P>:
22  match result:
23    case (column,released):(put(rest,column),released)
24def column_taken(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,record:RC.Record<S,P>,taken:Rest & Col.Column<S,P>) -> Store & RC.Record<S,P>:
25  match record taken:
26    case RC.Record{handle,stamp,payload}, (rest,column):column_returned(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,rest,RC.undo_column(~S,~P,handle,stamp,payload,column))
27def undone(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,ns:U32,allocator:Alloc.Allocator,resource:R,events:List<&2,E>,pending:List<Deferred.Command<W.World<S,Store,R,E>>>,regs:List<&2,W.RegistrationMeta>,sid:U32,clock:Clock.State,result:Store & RC.Record<S,P>) -> W.World<S,Store,R,E> & RC.Record<S,P>:
28  match result:
29    case (store,released):(W.World{ns,allocator,store,resource,events,pending,regs,sid,clock},released)
30# Canonical undo_column restores the saved stamp and returns the displaced
31# payload with its pre-undo stamp. Neither clocks nor unrelated owners rewind.
32def undo_valid(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,record:RC.Record<S,P>,world:W.World<S,Store,R,E>) -> W.World<S,Store,R,E> & RC.Record<S,P>:
33  match world:
34    case W.World{ns,allocator,store,resource,events,pending,regs,sid,clock}:undone(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,ns,allocator,resource,events,pending,regs,sid,clock,column_taken(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,record,take(store)))
35def undo_checked(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,record:RC.Record<S,P>,checked:W.World<S,Store,R,E> & Bool) -> W.World<S,Store,R,E> & RC.Record<S,P>:
36  match checked:
37    case (world,False{}):(world,record)
38    case (world,True{}):undo_valid(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,record,world)
39def undo(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,~family:C.Family<S,Store,Rest,P,V,Token,take,put,view>,record:RC.Record<S,P>,world:W.World<S,Store,R,E>) -> W.World<S,Store,R,E> & RC.Record<S,P>:
40  match record:
41    case RC.Record{+handle,stamp,payload}:undo_checked(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,RC.Record{handle,stamp,payload},W.valid(~S,~Store,~R,~E,world,handle))