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