restore_leaf.bend
bendvy-ecs-core@0.1.0.0 · 62 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/persistence_declaration.bend as Persistence
3import bendvy-ecs-core@0.1.0.0/restore_data.bend as R
4import bendvy-ecs-core@0.1.0.0/decode_data.bend as D
5import bendvy-ecs-core@0.1.0.0/decode_construction.bend as Constructor
6import bendvy-ecs-core@0.1.0.0/bundle_construction.bend as Build
7import bendvy-ecs-core@0.1.0.0/ordinary_declaration.bend as Identity
8
9type Record<I:Type,P:Type> is Type:
10 Record{position:R.Position,owner:P,undo:P -> I}
11type Applied<I:Type,P:Type> is Type:
12 Applied{position:R.Position,undo:P -> I}
13type State<Context:Type,I:Type,P:Type> is Type:
14 State{context:Context,records:List<Record<I,P>>,returned:List<I>,removed:List<P>,applied:List<Applied<I,P>>}
15type FamilyKind is Data:Component{} Resource{}
16def same_kind(kind:FamilyKind,position:R.Position) -> Bool:
17 match kind position:
18 case Component{} R.Component{_}:True{}
19 case Resource{} R.Resource{}:True{}
20 case _ _:False{}
21def constructed(~Context:Type,~I:Type,~P:Type,~Custom:Data,position:R.Position,records:List<Record<I,P>>,returned:List<I>,removed:List<P>,applied:List<Applied<I,P>>,context:Context,result:Build.Construction<I,P,Constructor.Error<Custom>>) -> State<Context,I,P> & R.Dispatch<Custom>:
22 match result:
23 case Build.Invalid{owner,error}:(State{context,records,List.append(&1,I,returned,[owner]),removed,applied},R.Rejected{error})
24 case Build.Constructed{owner,undo}:(State{context,Record{position,owner,undo} <> records,returned,removed,applied},R.Staged{})
25def stored(~I:Type,~P:Type,~Custom:Data,undo:P -> I,receipt:D.Receipt<P>) -> Build.Construction<I,P,Constructor.Error<Custom>>:
26 match receipt:
27 case D.Receipt{owner,D.Accepted{_}}:Build.Constructed{owner,undo}
28 case D.Receipt{owner,D.Rejected{error}}:Build.Invalid{undo(owner),Constructor.Validation{error}}
29def admitted(~S:Data,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,declaration:Persistence.Constructed<S,P,identity,project>,result:Build.Construction<I,P,Constructor.Error<Custom>>) -> Build.Construction<I,P,Constructor.Error<Custom>>:
30 match result:
31 case Build.Invalid{owner,error}:Build.Invalid{owner,error}
32 case Build.Constructed{owner,undo}:stored(~I,~P,~Custom,undo,Persistence.validate(~S,~P,~identity,~project,declaration,owner))
33def declaration(~S:Data,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction<I,P,Custom>,factory:Constructor.FallibleFactory<S,I,P,Custom,identity,project,incoming,build>) -> Persistence.Constructed<S,P,identity,project>:
34 match factory:
35 case Constructor.FallibleFactory{declaration,_}:declaration
36def supplied(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction<I,P,Custom>,~factory:Constructor.FallibleFactory<S,I,P,Custom,identity,project,incoming,build>,position:R.Position,records:List<Record<I,P>>,returned:List<I>,removed:List<P>,applied:List<Applied<I,P>>,observed:Context & I) -> State<Context,I,P> & R.Dispatch<Custom>:
37 match observed:
38 case (context,input):constructed(~Context,~I,~P,~Custom,position,records,returned,removed,applied,context,admitted(~S,~I,~P,~Custom,~identity,~project,declaration(~S,~I,~P,~Custom,~identity,~project,~incoming,~build,factory),Constructor.fallible_construct(~S,~I,~P,~Custom,~identity,~project,~incoming,~build,factory,input)))
39def selected(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction<I,P,Custom>,~factory:Constructor.FallibleFactory<S,I,P,Custom,identity,project,incoming,build>,~supply:Context -> D.Raw -> Context & I,matches:Bool,state:State<Context,I,P>,position:R.Position,field:D.Field) -> State<Context,I,P> & R.Dispatch<Custom>:
40 match matches state field:
41 case False{} state _:(state,R.Unhandled{})
42 case True{} State{context,records,returned,removed,applied} D.Field{_,raw}:supplied(~S,~Context,~I,~P,~Custom,~identity,~project,~incoming,~build,~factory,position,records,returned,removed,applied,supply(context,raw))
43def stage(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction<I,P,Custom>,~factory:Constructor.FallibleFactory<S,I,P,Custom,identity,project,incoming,build>,~supply:Context -> D.Raw -> Context & I,~kind:FamilyKind,state:State<Context,I,P>,+position:R.Position,+field:D.Field) -> State<Context,I,P> & R.Dispatch<Custom>:
44 match field:
45 case D.Field{+name,+raw}:selected(~S,~Context,~I,~P,~Custom,~identity,~project,~incoming,~build,~factory,~supply,Bool.and(same_kind(kind,position),String.eq(name,Identity.key(~S,~P,identity))),state,position,D.Field{name,raw})
46def released(~I:Type,~P:Type,head:I,rest:List<I>) -> List<I>:
47 List.append(&1,I,rest,[head])
48def release_records(~I:Type,~P:Type,records:List<Record<I,P>>,returned:List<I>) -> List<I>:
49 match records:
50 case []:returned
51 case Record{_,owner,undo} <> rest:release_records(~I,~P,rest,undo(owner) <> returned)
52def release(~Context:Type,~I:Type,~P:Type,state:State<Context,I,P>) -> State<Context,I,P>:
53 match state:
54 case State{context,records,returned,removed,applied}:State{context,[],release_records(~I,~P,records,returned),removed,applied}
55def empty(~Context:Type,~I:Type,~P:Type,context:Context) -> State<Context,I,P>:
56 State{context,[],[],[],[]}
57def commit(~Context:Type,~I:Type,~P:Type,state:State<Context,I,P>) -> State<Context,I,P>:
58 match state:
59 case State{context,_,_,_,_}:State{context,[],[],[],[]}
60def take_recovery(~Context:Type,~I:Type,~P:Type,state:State<Context,I,P>) -> State<Context,I,P> & List<I>:
61 match state:
62 case State{context,records,returned,removed,applied}:(State{context,records,[],removed,applied},returned)