component.bend
bendvy-ecs-core@0.1.0.3 · 244 lines · 45 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/execution_lifecycle_notices.bend as Notice
3import bendvy-ecs-core@0.1.0.3/change_tick.bend as Tick
4import bendvy-ecs-core@0.1.0.3/clock_state.bend as Clock
5import bendvy-ecs-core@0.1.0.3/deferred_command.bend as Deferred
6import lifecycle.bend as L
7import column.bend as Col
8import world.bend as W
9import entity_key.bend as K
10import entity_allocator.bend as A
11
12
13
14
15
16
17type Family<-S: Data,-Store: Type,-Rest: Type,-C: Type,-V: Data,-Token: Data,-take: Store -> Rest & Col.Column<S,C>,-put: Rest -> Col.Column<S,C> -> Store,-project: C -> C & V> is Data:
18 Family{name: String}
19
20
21type Access<V: Data> is Data:
22 Found{value: V}
23 ComponentAbsent{}
24 MissingEntity{}
25
26
27
28type Replacement<W: Type,C: Type> is Type:
29 Replaced{world: W,previous: Maybe<&1,C>}
30 ReplaceRejected{world: W,incoming: Maybe<&1,C>,error: W.WorldError}
31
32
33type Swap<C: Type> is Type:
34 Swapped{previous: Maybe<&1,C>}
35 SwapRejected{incoming: Maybe<&1,C>}
36
37
38
39type SetResult<Tx: Type,C: Type> is Type:
40 Written{tx: Tx}
41 WriteRejected{tx: Tx,incoming: C,error: W.WorldError}
42 WriteFailure{tx: Tx,error: W.WorldError}
43
44
45type RemoveResult<Tx: Type> is Type:
46 Removed{tx: Tx}
47 RemoveRejected{tx: Tx,error: W.WorldError}
48
49
50
51
52def define(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,name: String) -> Family<S,Store,Rest,C,V,Token,take,put,project>:
53 Family{name}
54
55def access(~V: Data,value: Maybe<&2,V>) -> Access<V>:
56 match value:
57 case None{}: ComponentAbsent{}
58 case Some{value}: Found{value}
59
60def get_projected(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,rest: Rest,observed: Col.Column<S,C> & Maybe<&2,V>) -> Store & Access<V>:
61 (column,value) = observed
62 (put(rest,column),access(~V,value))
63
64def get_store(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,split: Rest & Col.Column<S,C>) -> Store & Access<V>:
65 (rest,column) = split
66 get_projected(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,rest,Col.view(~S,~C,~V,~project,column,id))
67
68def get_world(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,world: W.World<S,Store,R,E>) -> W.World<S,Store,R,E> & Access<V>:
69 match world:
70 case W.World{+namespace,allocator,store,resource,+events,pending,+registrations,+nextSystemId,+clock,lifecycle}:
71 W.with_store_finish(~S,~Store,~R,~E,~Access<V>,get_store(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,take(store)),namespace,allocator,resource,events,pending,registrations,nextSystemId,clock,lifecycle)
72
73def get_allowed(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,checked: W.World<S,Store,R,E> & Bool,+handle: W.Handle<S>) -> W.World<S,Store,R,E> & Access<V>:
74 match checked handle:
75 case (world,False{}) _: (world,MissingEntity{})
76 case (world,True{}) W.Handle{_,K.EntityKey{+id,_}}:
77 get_world(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,world)
78
79def get_checked_fields(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,checked: A.Allocator & Bool,key: K.Key,namespace: U32,store: Store,resource: R,events: List<&2,E>,pending: List<Deferred.Command<W.World<S,Store,R,E>>>,registrations: List<&2,W.RegistrationMeta>,nextSystemId: U32,clock: Clock.State,lifecycle:Notice.Journal<S>) -> W.World<S,Store,R,E> & Access<V>:
80 match checked key:
81 case (allocator,False{}) _: (W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock,lifecycle},MissingEntity{})
82 case (allocator,True{}) K.EntityKey{+id,_}:
83 W.with_store_finish(~S,~Store,~R,~E,~Access<V>,get_store(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,take(store)),namespace,allocator,resource,events,pending,registrations,nextSystemId,clock,lifecycle)
84
85def get_namespace_fields(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,allowed: Bool,+key: K.Key,allocator: A.Allocator,namespace: U32,store: Store,resource: R,events: List<&2,E>,pending: List<Deferred.Command<W.World<S,Store,R,E>>>,registrations: List<&2,W.RegistrationMeta>,nextSystemId: U32,clock: Clock.State,lifecycle:Notice.Journal<S>) -> W.World<S,Store,R,E> & Access<V>:
86 match allowed:
87 case False{}: (W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock,lifecycle},MissingEntity{})
88 case True{}: get_checked_fields(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,A.checked(allocator,key,1),key,namespace,store,resource,events,pending,registrations,nextSystemId,clock,lifecycle)
89
90
91
92
93
94def get(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,family: Family<S,Store,Rest,C,V,Token,take,put,project>,world: W.World<S,Store,R,E>,+handle: W.Handle<S>) -> W.World<S,Store,R,E> & Access<V>:
95 match world handle:
96 case W.World{+namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock,lifecycle} W.Handle{ns,key}:
97 get_namespace_fields(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,U32.is_eq(namespace,ns),key,allocator,namespace,store,resource,events,pending,registrations,nextSystemId,clock,lifecycle)
98
99def has_access(~V: Data,value: Access<V>) -> Access<Bool>:
100 match value:
101 case MissingEntity{}: MissingEntity{}
102 case ComponentAbsent{}: Found{False{}}
103 case Found{_}: Found{True{}}
104
105def has_join(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,observed: W.World<S,Store,R,E> & Access<V>) -> W.World<S,Store,R,E> & Access<Bool>:
106 (world,value) = observed
107 (world,has_access(~V,value))
108
109
110
111
112def has(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,family: Family<S,Store,Rest,C,V,Token,take,put,project>,world: W.World<S,Store,R,E>,handle: W.Handle<S>) -> W.World<S,Store,R,E> & Access<Bool>:
113 has_join(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,get(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,family,world,handle))
114
115def owner_present(~C: Type,owner: Maybe<&1,C>) -> Maybe<&1,C> & Bool:
116 match owner:
117 case None{}: (None{},False{})
118 case Some{owner}: (Some{owner},True{})
119
120def mark_swapped(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,rest: Rest,column: Col.Column<S,C>,+id: U32,incoming: Bool,tick: Tick.Tick,observed: Maybe<&1,C> & Bool) -> Store & Swap<C>:
121 (previous,wasPresent) = observed
122 (put(rest,Col.mark(~S,~C,column,id,incoming,wasPresent,tick)),Swapped{previous})
123
124def swap_join(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,rest: Rest,+id: U32,incoming: Bool,tick: Tick.Tick,result: Col.SwapOutcome<S,C>) -> Store & Swap<C>:
125 match result:
126 case Col.Accepted{column,previous}: mark_swapped(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,rest,column,id,incoming,tick,owner_present(~C,previous))
127 case Col.Rejected{column,incoming}: (put(rest,column),SwapRejected{incoming})
128
129def swap_store(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,incoming: Maybe<&1,C>,incomingPresent: Bool,tick: Tick.Tick,split: Rest & Col.Column<S,C>) -> Store & Swap<C>:
130 (rest,column) = split
131 swap_join(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,rest,id,incomingPresent,tick,Col.swap(~S,~C,Col.ensure(~S,~C,column,id),id,incoming))
132
133def swap_world(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,incoming: Maybe<&1,C>,incomingPresent: Bool,tick: Tick.Tick,world: W.World<S,Store,R,E>) -> W.World<S,Store,R,E> & Swap<C>:
134 match world:
135 case W.World{+namespace,allocator,store,resource,+events,pending,+registrations,+nextSystemId,+clock,lifecycle}:
136 W.with_store_finish(~S,~Store,~R,~E,~Swap<C>,swap_store(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,incoming,incomingPresent,tick,take(store)),namespace,allocator,resource,events,pending,registrations,nextSystemId,clock,lifecycle)
137
138def replaced(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,result: W.World<S,Store,R,E> & Swap<C>) -> Replacement<W.World<S,Store,R,E>,C>:
139 match result:
140 case (world,Swapped{previous}): Replaced{world,previous}
141 case (world,SwapRejected{incoming}): ReplaceRejected{world,incoming,W.CapacityExceeded{}}
142
143def replace_clock_advanced(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,incomingPresent: Bool,incoming: Maybe<&1,C>,advanced: W.World<S,Store,R,E> & Tick.Tick) -> Replacement<W.World<S,Store,R,E>,C>:
144 (world,+tick) = advanced
145 replaced(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,swap_world(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,incoming,incomingPresent,tick,world))
146
147def replace_present(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~C:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,C>,~put:Rest -> Col.Column<S,C> -> Store,~project:C -> C & V,world:W.World<S,Store,R,E>,id:U32,observed:Maybe<&1,C> & Bool) -> Replacement<W.World<S,Store,R,E>,C>:
148 match observed:
149 case (incoming,present):replace_clock_advanced(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,present,incoming,W.write_clock(~S,~Store,~R,~E,world))
150
151def replace_allowed(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,checked: W.World<S,Store,R,E> & Bool,+handle: W.Handle<S>,incoming: Maybe<&1,C>) -> Replacement<W.World<S,Store,R,E>,C>:
152 match checked handle:
153 case (world,False{}) _: ReplaceRejected{world,incoming,W.MissingEntity{}}
154 case (world,True{}) W.Handle{_,K.EntityKey{+id,_}}:
155 replace_present(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,world,id,owner_present(~C,incoming))
156
157
158
159
160
161
162def replace(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,family: Family<S,Store,Rest,C,V,Token,take,put,project>,world: W.World<S,Store,R,E>,+handle: W.Handle<S>,incoming: Maybe<&1,C>) -> Replacement<W.World<S,Store,R,E>,C>:
163 replace_allowed(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,W.valid(~S,~Store,~R,~E,world,handle),handle,incoming)
164
165
166
167
168
169
170def structural_replace(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,family: Family<S,Store,Rest,C,V,Token,take,put,project>,world: W.World<S,Store,R,E>,+handle: W.Handle<S>,incoming: Maybe<&1,C>) -> Replacement<W.World<S,Store,R,E>,C>:
171 replace_allowed(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,W.metadata_valid(~S,~Store,~R,~E,world,handle),handle,incoming)
172
173def restore_done(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,result: Replacement<W.World<S,Store,R,E>,C>) -> W.World<S,Store,R,E>:
174 match result:
175 case Replaced{world,_}: world
176 case ReplaceRejected{world,_,_}: world
177
178
179
180def restore_swap(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,rest: Rest,result: Col.SwapOutcome<S,C>) -> Store & Unit:
181 match result:
182 case Col.Accepted{column,_}: (put(rest,column),Unit{})
183 case Col.Rejected{column,_}: (put(rest,column),Unit{})
184
185def restore_store(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,incoming: Maybe<&1,C>,split: Rest & Col.Column<S,C>) -> Store & Unit:
186 (rest,column) = split
187 restore_swap(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,rest,Col.swap(~S,~C,Col.ensure(~S,~C,column,id),id,incoming))
188
189def restore_world(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,incoming: Maybe<&1,C>,world: W.World<S,Store,R,E>) -> W.World<S,Store,R,E> & Unit:
190 match world:
191 case W.World{+namespace,allocator,store,resource,+events,pending,+registrations,+nextSystemId,+clock,lifecycle}:
192 W.with_store_finish(~S,~Store,~R,~E,~Unit,restore_store(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,incoming,take(store)),namespace,allocator,resource,events,pending,registrations,nextSystemId,clock,lifecycle)
193
194def restore_observed(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,observed: W.World<S,Store,R,E> & Unit) -> W.World<S,Store,R,E>:
195 (world,_) = observed
196 world
197
198def restore_allowed(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,checked: W.World<S,Store,R,E> & Bool,handle: W.Handle<S>,incoming: Maybe<&1,C>) -> W.World<S,Store,R,E>:
199 match checked handle:
200 case (world,False{}) _: world
201 case (world,True{}) W.Handle{_,K.EntityKey{+id,_}}: restore_observed(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,restore_world(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,incoming,world))
202
203def restore(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,family: Family<S,Store,Rest,C,V,Token,take,put,project>,+handle: W.Handle<S>,incoming: Maybe<&1,C>,world: W.World<S,Store,R,E>) -> W.World<S,Store,R,E>:
204 restore_allowed(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,W.metadata_valid(~S,~Store,~R,~E,world,handle),handle,incoming)
205
206def lifecycle_join(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,rest: Rest,observed: Col.Column<S,C> & L.Stamp) -> Store & L.Stamp:
207 (column,stamp) = observed
208 (put(rest,column),stamp)
209
210def lifecycle_store(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,split: Rest & Col.Column<S,C>) -> Store & L.Stamp:
211 (rest,column) = split
212 lifecycle_join(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,rest,Col.lifecycle(~S,~C,column,id))
213
214def lifecycle_world(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,world: W.World<S,Store,R,E>) -> W.World<S,Store,R,E> & L.Stamp:
215 match world:
216 case W.World{+namespace,allocator,store,resource,+events,pending,+registrations,+nextSystemId,+clock,lifecycle}:
217 W.with_store_finish(~S,~Store,~R,~E,~L.Stamp,lifecycle_store(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,take(store)),namespace,allocator,resource,events,pending,registrations,nextSystemId,clock,lifecycle)
218
219def lifecycle_allowed(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,checked: W.World<S,Store,R,E> & Bool,handle: W.Handle<S>) -> W.World<S,Store,R,E> & L.Stamp:
220 match checked handle:
221 case (world,False{}) _: (world,L.Stamp{None{},None{}})
222 case (world,True{}) W.Handle{_,K.EntityKey{+id,_}}: lifecycle_world(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,world)
223
224
225
226def lifecycle(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,family: Family<S,Store,Rest,C,V,Token,take,put,project>,world: W.World<S,Store,R,E>,+handle: W.Handle<S>) -> W.World<S,Store,R,E> & L.Stamp:
227 lifecycle_allowed(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,W.valid(~S,~Store,~R,~E,world,handle),handle)
228
229def restore_stamp_store(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,stamp: L.Stamp,split: Rest & Col.Column<S,C>) -> Store & Unit:
230 (rest,column) = split
231 (put(rest,Col.restore_stamp(~S,~C,column,id,stamp)),Unit{})
232
233def restore_stamp_world(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+id: U32,stamp: L.Stamp,world: W.World<S,Store,R,E>) -> W.World<S,Store,R,E> & Unit:
234 match world:
235 case W.World{+namespace,allocator,store,resource,+events,pending,+registrations,+nextSystemId,+clock,lifecycle}:
236 W.with_store_finish(~S,~Store,~R,~E,~Unit,restore_stamp_store(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,stamp,take(store)),namespace,allocator,resource,events,pending,registrations,nextSystemId,clock,lifecycle)
237
238def restore_stamp_done(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,observed: W.World<S,Store,R,E> & Unit) -> W.World<S,Store,R,E>:
239 (world,_) = observed
240 world
241
242def restore_stamp(~S: Data,~Store: Type,~R: Type,~E: Data,~Rest: Type,~C: Type,~V: Data,~Token: Data,~take: Store -> Rest & Col.Column<S,C>,~put: Rest -> Col.Column<S,C> -> Store,~project: C -> C & V,+handle: W.Handle<S>,stamp: L.Stamp,world: W.World<S,Store,R,E>) -> W.World<S,Store,R,E>:
243 match handle:
244 case W.Handle{_,K.EntityKey{+id,_}}: restore_stamp_done(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,restore_stamp_world(~S,~Store,~R,~E,~Rest,~C,~V,~Token,~take,~put,~project,id,stamp,world))