restore_prepare.bend
bendvy-ecs-core@0.1.0.1 · 55 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.1/restore_data.bend as R
3import bendvy-ecs-core@0.1.0.1/snapshot_data.bend as Snapshot
4import bendvy-ecs-core@0.1.0.1/decode_data.bend as D
5import bendvy-ecs-core@0.1.0.1/entity_key.bend as Key
6import bendvy-ecs-core@0.1.0.1/decode_construction.bend as Constructor
7
8type Walk<State:Type,Custom:Data> is Type:
9 Working{state:State}
10 Stopped{state:State,error:R.Error<Custom>}
11def unknown(~Custom:Data,position:R.Position,name:String) -> R.Error<Custom>:
12 match position:
13 case R.Component{key}:R.UnknownComponent{key,name}
14 case R.Resource{}:R.UnknownResource{name}
15def invalid(~Custom:Data,position:R.Position,name:String,error:Constructor.Error<Custom>) -> R.Error<Custom>:
16 match position:
17 case R.Component{key}:R.InvalidComponent{key,name,error}
18 case R.Resource{}:R.InvalidResource{name,error}
19def dispatched(~State:Type,~Custom:Data,+position:R.Position,+name:String,next:State -> Walk<State,Custom>,observed:State & R.Dispatch<Custom>) -> Walk<State,Custom>:
20 match observed:
21 case (state,R.Unhandled{}):Stopped{state,unknown(~Custom,position,name)}
22 case (state,R.Rejected{error}):Stopped{state,invalid(~Custom,position,name,error)}
23 case (state,R.Staged{}):next(state)
24def fields(~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,+position:R.Position,values:List<&2,D.Field>,state:State) -> Walk<State,Custom>:
25 match values:
26 case []:Working{state}
27 case D.Field{+name,value} <> rest:dispatched(~State,~Custom,position,name,next => fields(~State,~Custom,~stage,position,rest,next),stage(state,position,D.Field{name,value}))
28def seen(+key:Key.Key,keys:List<&2,Key.Key>) -> Bool:
29 match keys:
30 case []:False{}
31 case other <> rest:Bool.or(Key.equal(key,other),seen(key,rest))
32def continued(~State:Type,~Custom:Data,next:State -> Walk<State,Custom>,result:Walk<State,Custom>) -> Walk<State,Custom>:
33 match result:
34 case Working{state}:next(state)
35 case Stopped{state,error}:Stopped{state,error}
36def entity_checked(~State:Type,~Custom:Data,duplicate:Bool,+key:Key.Key,fields:List<&2,D.Field>,state:State,next:State -> Walk<State,Custom>,stage:State -> List<&2,D.Field> -> Walk<State,Custom>) -> Walk<State,Custom>:
37 match duplicate:
38 case True{}:Stopped{state,R.DuplicateEntity{key}}
39 case False{}:continued(~State,~Custom,next,stage(state,fields))
40def entities(~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,values:List<&2,Snapshot.Entity>,+previous:List<&2,Key.Key>,state:State) -> Walk<State,Custom>:
41 match values:
42 case []:Working{state}
43 case Snapshot.Entity{+key,components} <> rest:entity_checked(~State,~Custom,seen(key,previous),key,components,state,next => entities(~State,~Custom,~stage,rest,key <> previous,next),(next => values => fields(~State,~Custom,~stage,R.Component{key},values,next)))
44def finished(~State:Type,~Custom:Data,~release:State -> State,+input:Snapshot.Snapshot,result:Walk<State,Custom>) -> R.Prepared<State,Custom>:
45 match result:
46 case Working{state}:R.BendvyReady{state,input}
47 case Stopped{state,error}:R.Refused{release(state),input,error}
48def header(~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,version:Bool,progress:Bool,state:State,+input:Snapshot.Snapshot) -> R.Prepared<State,Custom>:
49 match version progress input:
50 case False{} _ Snapshot.Snapshot{value,next,entities,resources}:R.Refused{state,Snapshot.Snapshot{value,next,entities,resources},R.UnsupportedVersion{D.Number{value}}}
51 case True{} False{} Snapshot.Snapshot{version,next,entities,resources}:R.Refused{state,Snapshot.Snapshot{version,next,entities,resources},R.InvalidSnapshot{"$.nextEntity"}}
52 case True{} True{} Snapshot.Snapshot{version,next,+values,+resources}:finished(~State,~Custom,~release,Snapshot.Snapshot{version,next,values,resources},continued(~State,~Custom,state => fields(~State,~Custom,~stage,R.Resource{},resources,state),entities(~State,~Custom,~stage,values,[],state)))
53def prepare(~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,state:State,+input:Snapshot.Snapshot) -> R.Prepared<State,Custom>:
54 match input:
55 case Snapshot.Snapshot{+version,+next,+entities,+resources}:header(~State,~Custom,~stage,~release,U32.is_eq(version,1),Bool.and(U32.is_lt(0,next),U32.is_le(next,131073)),state,Snapshot.Snapshot{version,next,entities,resources})