restore_public.bend

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

1import Base
2import bendvy-ecs-core@0.1.0.1/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.1/restore_data.bend as R
4import bendvy-ecs-core@0.1.0.1/restore_schema.bend as Schema
5import bendvy-ecs-core@0.1.0.1/restore_prepare.bend as Prepare
6import bendvy-ecs-core@0.1.0.1/restore_apply.bend as Apply
7import bendvy-ecs-core@0.1.0.1/world.bend as W
8import bendvy-ecs-core@0.1.0.1/snapshot_data.bend as Snapshot
9import bendvy-ecs-core@0.1.0.1/decode_data.bend as D
10
11# Validate and stage a typed snapshot using the retained schema, without a World
12# argument or live-world mutation. Check version, nextEntity bounds, duplicate saved
13# keys, and schema field dispatch/construction before returning Ready or Refused.
14# Refusal retains the input and staging State; staged owners are released through
15# the schema adapter where preparation stops. This is typed input, not Raw parsing.
16# Use schema-derived codecs/factories; arbitrary adapter behavior is trusted setup.
17def prepare(~S:Data,~C:Type,~Resources:Type,~E:Data,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,~Recovery:Type,~commit:State -> State,~takeRecovery:State -> State & Recovery,schema:Schema.Schema<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>,state:State,input:Snapshot.Snapshot) -> R.Prepared<State,Custom>:
18  Prepare.prepare(~State,~Custom,~stage,~release,state,input)
19# Apply a prepared restore to the supplied World, returning Applied or Refused
20# with the World and staging State. A preparation refusal returns World untouched;
21# capacity admission precedes cleanup. Successful application cleans current live
22# entities, allocates fresh target handles and inserts staged fields, returning
23# saved-key-to-handle bindings rather than reusing saved keys as live identities.
24# The emit adapter maps ordinary cleanup/spawn changes into E. This basic wrapper
25# does not reset a complete App Runtime or reconstruct omitted runtime owners;
26# use the runtime restore adapter when its stream/pending-work boundary is needed.
27def apply(~S:Data,~C:Type,~Resources:Type,~E:Data,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,~Recovery:Type,~commit:State -> State,~takeRecovery:State -> State & Recovery,~emit:R.Change<S> -> E,schema:Schema.Schema<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>,world:W.World<S,C,Resources,E>,prepared:R.Prepared<State,Custom>) -> Apply.ApplyResult<S,C,Resources,E,State,Custom>:
28  Apply.apply(~S,~C,~Resources,~E,~State,~Custom,~release,~clear,~insert,~emit,world,prepared)
29# Convenience prepare-then-apply on the same schema and staging State. Complete
30# input preparation precedes application; returned State remains an owned result.
31# For persistent constructor context and explicit recovery, use owned then run.
32# See docs/parity/restore-basic.md and its ordinary Restore.restore consumer.
33def restore(~S:Data,~C:Type,~Resources:Type,~E:Data,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,~Recovery:Type,~commit:State -> State,~takeRecovery:State -> State & Recovery,~emit:R.Change<S> -> E,+schema:Schema.Schema<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>,world:W.World<S,C,Resources,E>,state:State,input:Snapshot.Snapshot) -> Apply.ApplyResult<S,C,Resources,E,State,Custom>:
34  apply(~S,~C,~Resources,~E,~State,~Custom,~stage,~release,~clear,~insert,~Recovery,~commit,~takeRecovery,~emit,schema,world,prepare(~S,~C,~Resources,~E,~State,~Custom,~stage,~release,~clear,~insert,~Recovery,~commit,~takeRecovery,schema,state,input))
35# Detached owned-run result. Restored carries full saved-key/actual-handle bindings;
36# RestoreRejected carries the rejected typed input and its structured error.
37# Actual affine recovery is returned separately, never hidden in this Data result.
38type Outcome<S:Data,Custom:Data> is Data:
39  Restored{bindings:List<&2,R.Binding<S>>}
40  RestoreRejected{input:Snapshot.Snapshot,error:R.Error<Custom>}
41# Affine restore context retaining the schema and actual constructor State across
42# calls. Its stage/release/clear/insert/commit/recovery functions are schema-bound
43# advanced adapters, not gameplay access to an arbitrary World or cloned payloads.
44type Owner<-S:Data,-C:Type,-Resources:Type,-State:Type,-Custom:Data,-stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,-release:State -> State,-clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,-insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,-Recovery:Type,-commit:State -> State,-takeRecovery:State -> State & Recovery> is Type:
45  Owner{schema:Schema.Schema<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>,state:State}
46# Retain the supplied schema and actual staging context in a restore Owner.
47# This setup step neither validates a snapshot nor changes a World.
48def owned(~S:Data,~C:Type,~Resources:Type,~E:Data,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,~Recovery:Type,~commit:State -> State,~takeRecovery:State -> State & Recovery,schema:Schema.Schema<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>,state:State) -> Owner<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>:
49  Owner{schema,state}
50def recovered(~S:Data,~C:Type,~Resources:Type,~E:Data,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,~Recovery:Type,~commit:State -> State,~takeRecovery:State -> State & Recovery,schema:Schema.Schema<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>,world:W.World<S,C,Resources,E>,outcome:Outcome<S,Custom>,observed:State & Recovery) -> W.World<S,C,Resources,E> & (Owner<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery> & (Outcome<S,Custom> & Recovery)):
51  match observed:
52    case (state,recovery):(world,(Owner{schema,state},(outcome,recovery)))
53def run_returned(~S:Data,~C:Type,~Resources:Type,~E:Data,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,~Recovery:Type,~commit:State -> State,~takeRecovery:State -> State & Recovery,schema:Schema.Schema<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>,result:Apply.ApplyResult<S,C,Resources,E,State,Custom>) -> W.World<S,C,Resources,E> & (Owner<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery> & (Outcome<S,Custom> & Recovery)):
54  match result:
55    case Apply.Applied{world,state,bindings}:recovered(~S,~C,~Resources,~E,~State,~Custom,~stage,~release,~clear,~insert,~Recovery,~commit,~takeRecovery,schema,world,Restored{bindings},takeRecovery(commit(state)))
56    case Apply.Refused{world,state,input,error}:recovered(~S,~C,~Resources,~E,~State,~Custom,~stage,~release,~clear,~insert,~Recovery,~commit,~takeRecovery,schema,world,RestoreRejected{input,error},takeRecovery(release(state)))
57# Consume and return the restore Owner with the World, detached Outcome and actual
58# Recovery owner. Success commits staging before taking recovery; refusal releases
59# staging before taking recovery. Follow the concrete schema recovery type: returned
60# inputs are not duplicate copies of payloads installed into the World. No implicit
61# destructor or full Runtime reset is supplied by this operation.
62def run(~S:Data,~C:Type,~Resources:Type,~E:Data,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,~Recovery:Type,~commit:State -> State,~takeRecovery:State -> State & Recovery,~emit:R.Change<S> -> E,owner:Owner<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>,world:W.World<S,C,Resources,E>,input:Snapshot.Snapshot) -> W.World<S,C,Resources,E> & (Owner<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery> & (Outcome<S,Custom> & Recovery)):
63  match owner:
64    case Owner{+schema,state}:run_returned(~S,~C,~Resources,~E,~State,~Custom,~stage,~release,~clear,~insert,~Recovery,~commit,~takeRecovery,schema,restore(~S,~C,~Resources,~E,~State,~Custom,~stage,~release,~clear,~insert,~Recovery,~commit,~takeRecovery,~emit,schema,world,state,input))
65# Explicit affine receipt disposal; no implicit destructor callback is invented.
66# Consume an unwanted recovery receipt explicitly and return Unit. This drops the
67# owned value; it invokes no user destructor callback and restores nothing into
68# World. Callers needing recovery contents must handle them before disposal.
69def dispose_recovery(~Recovery:Type,recovery:Recovery) -> Unit:
70  Unit{}