cranpose_core/snapshot_v2/
nested.rs1use super::*;
2
3pub struct NestedReadonlySnapshot {
13 state: SnapshotState,
14 parent: Weak<NestedReadonlySnapshot>,
15}
16
17impl NestedReadonlySnapshot {
18 pub fn new(
19 id: SnapshotId,
20 invalid: SnapshotIdSet,
21 read_observer: Option<ReadObserver>,
22 parent: Weak<NestedReadonlySnapshot>,
23 ) -> Arc<Self> {
24 Arc::new(Self {
25 state: SnapshotState::new(id, invalid, read_observer, None, false),
26 parent,
27 })
28 }
29
30 pub fn snapshot_id(&self) -> SnapshotId {
31 self.state.id.get()
32 }
33
34 pub fn invalid(&self) -> SnapshotIdSet {
35 self.state.invalid.borrow().clone()
36 }
37
38 pub fn read_only(&self) -> bool {
39 true
40 }
41
42 pub fn root_nested_readonly(&self) -> Arc<NestedReadonlySnapshot> {
43 if let Some(parent) = self.parent.upgrade() {
44 parent.root_nested_readonly()
45 } else {
46 NestedReadonlySnapshot::new(
47 self.state.id.get(),
48 self.state.invalid.borrow().clone(),
49 self.state.read_observer.borrow().clone(),
50 Weak::new(),
51 )
52 }
53 }
54
55 pub fn enter<T>(self: &Arc<Self>, f: impl FnOnce() -> T) -> T {
56 enter_snapshot_scope(AnySnapshot::NestedReadonly(self.clone()), f)
57 }
58
59 pub fn take_nested_snapshot(
60 &self,
61 read_observer: Option<ReadObserver>,
62 ) -> Arc<NestedReadonlySnapshot> {
63 let merged_observer =
64 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
65
66 NestedReadonlySnapshot::new(
67 self.state.id.get(),
68 self.state.invalid.borrow().clone(),
69 merged_observer,
70 self.parent.clone(),
71 )
72 }
73
74 pub fn has_pending_changes(&self) -> bool {
75 false
76 }
77
78 pub fn dispose(&self) {
79 if !self.state.disposed.get() {
80 self.state.dispose();
81 }
82 }
83
84 pub fn record_read(&self, state: &dyn StateObject) {
85 self.state.record_read(state);
86 }
87
88 pub fn record_write(&self, _state: Arc<dyn StateObject>) {
89 panic!("Cannot write to a read-only snapshot");
90 }
91
92 pub fn close(&self) {
93 self.state.disposed.set(true);
94 }
95
96 pub fn is_disposed(&self) -> bool {
97 self.state.disposed.get()
98 }
99}
100
101pub struct NestedMutableSnapshot {
112 state: SnapshotState,
113 parent: Weak<MutableSnapshot>,
114 nested_count: Cell<usize>,
115 applied: Cell<bool>,
116 base_parent_id: SnapshotId,
117}
118
119impl NestedMutableSnapshot {
120 pub fn new(
121 id: SnapshotId,
122 invalid: SnapshotIdSet,
123 read_observer: Option<ReadObserver>,
124 write_observer: Option<WriteObserver>,
125 parent: Weak<MutableSnapshot>,
126 base_parent_id: SnapshotId,
127 ) -> Arc<Self> {
128 Arc::new(Self {
129 state: SnapshotState::new(id, invalid, read_observer, write_observer, true),
130 parent,
131 nested_count: Cell::new(0),
132 applied: Cell::new(false),
133 base_parent_id,
134 })
135 }
136
137 pub fn snapshot_id(&self) -> SnapshotId {
138 self.state.id.get()
139 }
140
141 pub fn invalid(&self) -> SnapshotIdSet {
142 self.state.invalid.borrow().clone()
143 }
144
145 pub fn read_only(&self) -> bool {
146 false
147 }
148
149 pub(crate) fn set_on_dispose<F>(&self, f: F)
150 where
151 F: FnOnce() + 'static,
152 {
153 self.state.set_on_dispose(f);
154 }
155
156 pub fn root_mutable(&self) -> Arc<MutableSnapshot> {
157 if let Some(parent) = self.parent.upgrade() {
158 parent.root_mutable()
159 } else {
160 MutableSnapshot::new(
161 self.state.id.get(),
162 self.state.invalid.borrow().clone(),
163 self.state.read_observer.borrow().clone(),
164 self.state.write_observer.borrow().clone(),
165 self.base_parent_id,
166 )
167 }
168 }
169
170 pub fn enter<T>(self: &Arc<Self>, f: impl FnOnce() -> T) -> T {
171 enter_snapshot_scope(AnySnapshot::NestedMutable(self.clone()), f)
172 }
173
174 pub fn take_nested_snapshot(
175 &self,
176 read_observer: Option<ReadObserver>,
177 ) -> Arc<ReadonlySnapshot> {
178 let merged_observer =
179 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
180
181 ReadonlySnapshot::new(
182 self.state.id.get(),
183 self.state.invalid.borrow().clone(),
184 merged_observer,
185 )
186 }
187
188 pub fn has_pending_changes(&self) -> bool {
189 !self.state.modified.borrow().is_empty()
190 }
191
192 pub fn pending_children(&self) -> Vec<SnapshotId> {
193 self.state.pending_children()
194 }
195
196 pub fn has_pending_children(&self) -> bool {
197 self.state.has_pending_children()
198 }
199
200 pub fn dispose(&self) {
201 if !self.state.disposed.get() && self.nested_count.get() == 0 {
202 self.state.dispose();
203 }
204 }
205
206 pub fn record_read(&self, state: &dyn StateObject) {
207 self.state.record_read(state);
208 }
209
210 pub fn record_write(&self, state: Arc<dyn StateObject>) {
211 assert!(!self.applied.get(), "Cannot write to an applied snapshot");
212 assert!(
213 !self.state.disposed.get(),
214 "Cannot write to a disposed snapshot"
215 );
216 self.state.record_write(state, self.state.id.get());
217 }
218
219 pub fn close(&self) {
220 self.state.disposed.set(true);
221 }
222
223 pub fn is_disposed(&self) -> bool {
224 self.state.disposed.get()
225 }
226
227 pub fn apply(&self) -> SnapshotApplyResult {
228 if self.state.disposed.get() {
229 return SnapshotApplyResult::Failure;
230 }
231
232 if self.applied.get() {
233 return SnapshotApplyResult::Failure;
234 }
235
236 if let Some(parent) = self.parent.upgrade() {
237 let child_modified = self.state.modified.borrow();
238 if child_modified.is_empty() {
239 self.applied.set(true);
240 self.state.dispose();
241 return SnapshotApplyResult::Success;
242 }
243 if parent.merge_child_modifications(&child_modified).is_err() {
244 return SnapshotApplyResult::Failure;
245 }
246
247 self.applied.set(true);
248 self.state.dispose();
249 SnapshotApplyResult::Success
250 } else {
251 SnapshotApplyResult::Failure
252 }
253 }
254
255 pub fn take_nested_mutable_snapshot(
256 self: &Arc<Self>,
257 read_observer: Option<ReadObserver>,
258 write_observer: Option<WriteObserver>,
259 ) -> Arc<NestedMutableSnapshot> {
260 let root = Arc::downgrade(&self.root_mutable());
261 allocate_nested_mutable_snapshot(self, root, read_observer, write_observer)
262 }
263}
264
265impl NestedMutableHost for NestedMutableSnapshot {
266 fn snapshot_state(&self) -> &SnapshotState {
267 &self.state
268 }
269
270 fn nested_count(&self) -> &Cell<usize> {
271 &self.nested_count
272 }
273}
274
275#[cfg(test)]
276#[path = "tests/nested_tests.rs"]
277mod tests;