cranpose_core/snapshot_v2/
transparent.rs1use super::*;
2
3pub struct TransparentObserverMutableSnapshot {
13 pub(super) state: SnapshotState,
14 parent: Option<Weak<TransparentObserverMutableSnapshot>>,
15 nested_count: Cell<usize>,
16 applied: Cell<bool>,
17 reusable: Cell<bool>,
18}
19
20impl TransparentObserverMutableSnapshot {
21 pub fn new(
25 id: SnapshotId,
26 invalid: SnapshotIdSet,
27 read_observer: Option<ReadObserver>,
28 write_observer: Option<WriteObserver>,
29 parent: Option<Weak<TransparentObserverMutableSnapshot>>,
30 ) -> Rc<Self> {
31 Self::new_reusing(None, id, invalid, read_observer, write_observer, parent)
32 }
33
34 pub(crate) fn new_reusing(
35 recycled: Option<Rc<Self>>,
36 id: SnapshotId,
37 invalid: SnapshotIdSet,
38 read_observer: Option<ReadObserver>,
39 write_observer: Option<WriteObserver>,
40 parent: Option<Weak<Self>>,
41 ) -> Rc<Self> {
42 let fresh = Self {
43 state: SnapshotState::new_with_pinning(
44 id,
45 invalid,
46 read_observer,
47 write_observer,
48 false,
49 false,
50 ),
51 parent,
52 nested_count: Cell::new(0),
53 applied: Cell::new(false),
54 reusable: Cell::new(true),
55 };
56 if let Some(mut recycled) = recycled
57 && let Some(target) = Rc::get_mut(&mut recycled)
58 {
59 *target = fresh;
60 recycled
61 } else {
62 Rc::new(fresh)
63 }
64 }
65
66 pub fn can_reuse(&self) -> bool {
68 self.reusable.get()
69 }
70
71 pub(crate) fn observers(&self) -> (Option<ReadObserver>, Option<WriteObserver>) {
72 (
73 self.state.read_observer.borrow().clone(),
74 self.state.write_observer.borrow().clone(),
75 )
76 }
77
78 pub(crate) fn reads_into(&self, observer: &ReadObserver) -> bool {
79 self.state
80 .read_observer
81 .borrow()
82 .as_ref()
83 .is_some_and(|installed| Rc::ptr_eq(installed, observer))
84 }
85
86 pub fn set_read_observer(&self, observer: Option<ReadObserver>) {
88 assert!(
89 self.can_reuse(),
90 "Cannot change observers on non-reusable snapshot"
91 );
92 *self.state.read_observer.borrow_mut() = observer;
93 }
94
95 pub fn set_write_observer(&self, observer: Option<WriteObserver>) {
97 assert!(
98 self.can_reuse(),
99 "Cannot change observers on non-reusable snapshot"
100 );
101 *self.state.write_observer.borrow_mut() = observer;
102 }
103
104 pub fn snapshot_id(&self) -> SnapshotId {
106 self.state.id.get()
107 }
108
109 pub fn invalid(&self) -> SnapshotIdSet {
111 self.state.invalid.borrow().clone()
112 }
113
114 pub fn read_only(&self) -> bool {
116 false
117 }
118
119 pub fn root_transparent_mutable(self: &Rc<Self>) -> Rc<Self> {
121 match &self.parent {
122 Some(weak) => weak
123 .upgrade()
124 .map_or_else(|| self.clone(), |parent| parent.root_transparent_mutable()),
125 None => self.clone(),
126 }
127 }
128
129 pub fn enter<T>(self: &Rc<Self>, f: impl FnOnce() -> T) -> T {
133 let prev = current_snapshot();
134
135 if let Some(ref snapshot) = prev
136 && snapshot.is_same_transparent(self)
137 {
138 return f();
139 }
140
141 enter_snapshot_scope(AnySnapshot::TransparentMutable(self.clone()), f)
142 }
143
144 pub fn take_nested_snapshot(
147 &self,
148 read_observer: Option<ReadObserver>,
149 ) -> Rc<ReadonlySnapshot> {
150 let merged_observer =
151 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
152 ReadonlySnapshot::new(
153 self.state.id.get(),
154 self.state.invalid.borrow().clone(),
155 merged_observer,
156 )
157 }
158
159 pub fn has_pending_changes(&self) -> bool {
161 !self.state.modified.borrow().is_empty()
162 }
163
164 pub fn dispose(&self) {
167 if !self.state.disposed.get() && self.nested_count.get() == 0 {
168 self.state.dispose();
169 }
170 }
171
172 pub fn record_read(&self, state: &dyn StateObject) {
174 self.state.record_read(state);
175 }
176
177 pub fn record_write(&self, state: Rc<dyn StateObject>) {
180 assert!(!self.applied.get(), "Cannot write to an applied snapshot");
181 self.state.record_write(state, self.state.id.get());
182 }
183
184 pub fn is_disposed(&self) -> bool {
186 self.state.disposed.get()
187 }
188
189 pub fn apply(&self) -> SnapshotApplyResult {
191 if self.state.disposed.get() || self.applied.get() {
192 return SnapshotApplyResult::Failure;
193 }
194
195 self.applied.set(true);
196 SnapshotApplyResult::Success
197 }
198
199 pub fn take_nested_mutable_snapshot(
202 &self,
203 read_observer: Option<ReadObserver>,
204 write_observer: Option<WriteObserver>,
205 ) -> Rc<TransparentObserverMutableSnapshot> {
206 let merged_read =
207 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
208 let merged_write =
209 merge_write_observers(write_observer, self.state.write_observer.borrow().clone());
210
211 let mut invalid = self.state.invalid.borrow().clone();
212 let new_id = self.state.id.get() + 1;
213 invalid = invalid.set(new_id);
214
215 TransparentObserverMutableSnapshot::new(
216 new_id,
217 invalid,
218 merged_read,
219 merged_write,
220 self.parent.clone(),
221 )
222 }
223}
224
225pub struct TransparentObserverSnapshot {
234 pub(super) state: SnapshotState,
235 parent: Option<Weak<TransparentObserverSnapshot>>,
236 reusable: Cell<bool>,
237}
238
239impl TransparentObserverSnapshot {
240 pub fn new(
244 id: SnapshotId,
245 invalid: SnapshotIdSet,
246 read_observer: Option<ReadObserver>,
247 parent: Option<Weak<TransparentObserverSnapshot>>,
248 ) -> Rc<Self> {
249 Rc::new(Self {
250 state: SnapshotState::new_with_pinning(id, invalid, read_observer, None, false, false),
251 parent,
252 reusable: Cell::new(true),
253 })
254 }
255
256 pub fn can_reuse(&self) -> bool {
258 self.reusable.get()
259 }
260
261 pub fn set_read_observer(&self, observer: Option<ReadObserver>) {
263 assert!(
264 self.can_reuse(),
265 "Cannot change observers on non-reusable snapshot"
266 );
267 *self.state.read_observer.borrow_mut() = observer;
268 }
269
270 pub fn snapshot_id(&self) -> SnapshotId {
272 self.state.id.get()
273 }
274
275 pub fn invalid(&self) -> SnapshotIdSet {
277 self.state.invalid.borrow().clone()
278 }
279
280 pub fn read_only(&self) -> bool {
282 true
283 }
284
285 pub fn root_transparent_readonly(self: &Rc<Self>) -> Rc<Self> {
287 match &self.parent {
288 Some(weak) => weak
289 .upgrade()
290 .map_or_else(|| self.clone(), |parent| parent.root_transparent_readonly()),
291 None => self.clone(),
292 }
293 }
294
295 pub fn enter<T>(self: &Rc<Self>, f: impl FnOnce() -> T) -> T {
299 let previous = current_snapshot();
300
301 if let Some(ref prev_snapshot) = previous
302 && prev_snapshot.is_same_transparent_readonly(self)
303 {
304 return f();
305 }
306
307 enter_snapshot_scope(AnySnapshot::TransparentReadonly(self.clone()), f)
308 }
309
310 pub fn take_nested_snapshot(
313 &self,
314 read_observer: Option<ReadObserver>,
315 ) -> Rc<TransparentObserverSnapshot> {
316 let merged_observer =
317 merge_read_observers(read_observer, self.state.read_observer.borrow().clone());
318 TransparentObserverSnapshot::new(
319 self.state.id.get(),
320 self.state.invalid.borrow().clone(),
321 merged_observer,
322 self.parent.clone(),
323 )
324 }
325
326 pub fn has_pending_changes(&self) -> bool {
328 false
329 }
330
331 pub fn dispose(&self) {
333 self.state.dispose();
334 }
335
336 pub fn record_read(&self, state: &dyn StateObject) {
338 self.state.record_read(state);
339 }
340
341 pub fn record_write(&self, _state: Rc<dyn StateObject>) {
343 panic!("Cannot write to a read-only snapshot");
344 }
345
346 pub fn is_disposed(&self) -> bool {
348 self.state.disposed.get()
349 }
350}
351
352#[cfg(test)]
353#[path = "tests/transparent_tests.rs"]
354mod tests;