duat_core/
data.rs

1//! Duat's way of sharing and updating state
2//!
3//! This module consists primarily of the [`RwData`] struct, which
4//! holds state that can be [read] or [written to]. When it is
5//! modified, other holders of a clone of [`RwData`] will know that
6//! the data within has been modified.
7//!
8//! This is used in many places, for example, [`Widget`]s can read
9//! from [`File`]s, and Duat can know when a [`File`] has been
10//! altered, so these [`Widget`]s may be [updated] automatically.
11//!
12//! Another struct from this module is [`DataMap`]. This is
13//! essentially a mapping for a [`RwData`]. It is created via
14//! [`RwData::map`], and both it and [`RwData`] can be very useful in,
15//! for example, a [`StatusLine`], since it will be updated
16//! automatically whenever the [`RwData`] is altered.
17//!
18//! One thing to note is that these structs are only meant to exist
19//! and be used in the main thread of execution in Duat. In fact, it
20//! should be impossible to acquire them outside of this main thread
21//! without use of unsafe code. If it is still possible, report that
22//! as a bug.
23//!
24//! The reason why these structs should only be valid in the main
25//! thread is because, internally, they use non [`Send`]/[`Sync`]
26//! structs, specifically [`Rc`] and [`RefCell`]. These are often
27//! considered "crutches" by a lot of the Rust community, but in an
28//! environment where most of the code is supposed to be able to
29//! access most of the state, it is impossible to go without using
30//! them.
31//!
32//! As well as not having the problem of deadlocks that [`Mutex`]es
33//! would have, [`Rc<RefCell>`] is way faster to clone and lock than
34//! its [`Sync`] equivalents [`Arc<Mutex>`] or [`Arc<RwLock>`].
35//!
36//! [read]: RwData::read
37//! [written to]: RwData::write
38//! [`Widget`]: crate::ui::Widget
39//! [`File`]: crate::file::File
40//! [updated]: crate::ui::Widget::update
41//! [`Text`]: crate::text::Text
42//! [`StatusLine`]: https://docs.rs/duat-utils/latest/duat_utils/widgets/struct.StatusLine.html
43//! [`context`]: crate::context
44//! [`Mutex`]: std::sync::Mutex
45//! [`Arc<Mutex>`]: std::sync::Arc
46//! [`Arc<RwLock>`]: std::sync::Arc
47use std::{
48    self,
49    any::TypeId,
50    cell::{Cell, RefCell},
51    marker::PhantomData,
52    rc::Rc,
53    sync::{
54        Arc,
55        atomic::{AtomicBool, Ordering},
56    },
57    time::Duration,
58};
59
60use crate::{
61    cfg::PrintCfg,
62    text::Text,
63    ui::{Ui, Widget},
64};
65
66/// A container for shared read/write state
67///
68/// This is the struct used internally (and externally) to allow for
69/// massively shareable state in duat's API. Its main purpose is to
70/// hold all of the [`Widget`]s in Duat, making them available for
71/// usage from any function with access to a [`Pass`].
72///
73/// # [`Pass`]es
74///
75/// The [`Pass`] is a sort of "key" for accessing the value within an
76/// [`RwData`], it's purpose is to maintain Rust's number one rule,
77/// i.e. one exclusive reference or multiple shared references, and
78/// that is done by borrowing the [`Pass`] mutably or non mutably.
79/// That comes with some limitations, of course, mainly that you can't
80/// really mutate two [`RwData`]s at the same time, even if it is
81/// known that they don't point to the same data.
82///
83/// There are some common exceptions to this, where Duat provides some
84/// safe way to do that when it is known that the two types are not
85/// the same.
86///
87/// # Not [`Send`]/[`Sync`]
88///
89/// Internally, the [`RwData`] makes use of an [`Rc<RefCell>`]. The
90/// usage of an [`Rc<RefCell>`] over an [`Arc<Mutex>`] is, i've
91/// assumed, a necessary evil in order to preserve the aforementioned
92/// rule. But the lack of [`Send`]/[`Sync`] does confer the [`RwData`]
93/// some advantages:
94///
95/// * Deadlocks are impossible, being replaced by much easier to debug
96///   panics.
97/// * The order in which data is accessed doesn't matter, unlike with
98///   [`Mutex`]es.
99/// * Performance of unlocking and cloning should generally be better,
100///   since no atomic operations are done (I actually managed to
101///   observe this, where in my rudimentary benchmarks against neovim,
102///   the [`Arc<Mutex>`] version was very frequently losing to a
103///   comparable neovim build.
104///
105/// However, I admit that there are also some drawbacks, the most
106/// notable being the difficulty of reading or writing to [`Text`]
107/// from outside of the main thread. But for the most common usecase
108/// where that will be needed ([`Reader`]s), a [`Send`]/[`Sync`]
109/// solution will be provided soon.
110///
111/// [`Arc<Mutex>`]: std::sync::Arc
112/// [`Mutex`]: std::sync::Mutex
113/// [`Reader`]: crate::file::Reader
114#[derive(Debug)]
115pub struct RwData<T: ?Sized> {
116    value: Rc<RefCell<T>>,
117    cur_state: Rc<Cell<usize>>,
118    read_state: Rc<Cell<usize>>,
119    ty: TypeId,
120}
121
122impl<T: 'static> RwData<T> {
123    /// Returns a new [`RwData<T>`]
124    ///
125    /// Note that this is only for sized types. For unsized types, the
126    /// process is a little more convoluted, and you need to use
127    /// [`RwData::new_unsized`].
128    pub fn new(value: T) -> Self {
129        Self {
130            value: Rc::new(RefCell::new(value)),
131            ty: TypeId::of::<T>(),
132            cur_state: Rc::new(Cell::new(1)),
133            read_state: Rc::new(Cell::new(0)),
134        }
135    }
136
137    /// Replaces the value within using a [`Pass`]
138    ///
139    /// The consistent use of a [`Pass`] for the purposes of
140    /// reading/writing to the values of [`RwData`]s ensures that no
141    /// panic or invalid borrow happens at runtime, even while working
142    /// with untrusted code. More importantly, Duat uses these
143    /// guarantees in order to give the end user a ridiculous amount
144    /// of freedom in where they can do things, whilst keeping Rust's
145    /// number one rule and ensuring thread safety, even with a
146    /// relatively large amount of shareable state.
147    ///
148    /// # Panics
149    ///
150    /// Panics if there is any type of borrow of this struct
151    /// somewhere, which could happen if you use [`read_unsafe`]
152    /// or [`write_unsafe`], for example.
153    ///
154    /// [`read_unsafe`]: Self::read_unsafe
155    /// [`write_unsafe`]: Self::write_unsafe
156    pub fn replace(&self, pa: &mut Pass, new: T) -> T {
157        self.write(pa, |value| std::mem::replace(value, new))
158    }
159
160    /// Gets the value within using a [`Pass`]
161    ///
162    /// The consistent use of a [`Pass`] for the purposes of
163    /// reading/writing to the values of [`RwData`]s ensures that no
164    /// panic or invalid borrow happens at runtime, even while working
165    /// with untrusted code. More importantly, Duat uses these
166    /// guarantees in order to give the end user a ridiculous amount
167    /// of freedom in where they can do things, whilst keeping Rust's
168    /// number one rule and ensuring thread safety, even with a
169    /// relatively large amount of shareable state.
170    ///
171    /// # Panics
172    ///
173    /// Panics if there is a mutable borrow of this struct somewhere,
174    /// which could happen if you use [`write_unsafe`] or
175    /// [`write_unsafe_as`]
176    ///
177    /// [`write_unsafe`]: Self::write_unsafe
178    /// [`write_unsafe_as`]: Self::write_unsafe_as
179    pub fn get(&self, pa: &Pass) -> T
180    where
181        T: Clone,
182    {
183        self.read(pa, |value| value.clone())
184    }
185}
186
187impl<T: ?Sized> RwData<T> {
188    /// Returns an unsized [`RwData`], such as [`RwData<dyn Trait>`]
189    ///
190    /// # Safety
191    ///
192    /// There is a type argument `SizedT` which _must_ be the exact
193    /// type you are passing to this constructor, i.e., if you are
194    /// creating an [`RwData<dyn Display>`] from a [`String`], you'd
195    /// do this:
196    ///
197    /// ```rust
198    /// use std::{cell::RefCell, fmt::Display, rc::Rc};
199    ///
200    /// use duat_core::{data::RwData, prelude::*};
201    /// let rw_data: RwData<dyn Display> =
202    ///     unsafe { RwData::new_unsized::<String>(Rc::new(RefCell::new("testing".to_string()))) };
203    /// ```
204    ///
205    /// This ensures that methods such as [`read_as`] and [`write_as`]
206    /// will correctly identify such [`RwData<dyn Display>`] as a
207    /// [`String`].
208    ///
209    /// [`read_as`]: Self::read_as
210    /// [`write_as`]: Self::write_as
211    pub unsafe fn new_unsized<SizedT: 'static>(value: Rc<RefCell<T>>) -> Self {
212        Self {
213            value,
214            ty: TypeId::of::<SizedT>(),
215            cur_state: Rc::new(Cell::new(1)),
216            read_state: Rc::new(Cell::new(0)),
217        }
218    }
219
220    ////////// Reading functions
221
222    /// Reads the value within using a [`Pass`]
223    ///
224    /// The consistent use of a [`Pass`] for the purposes of
225    /// reading/writing to the values of [`RwData`]s ensures that no
226    /// panic or invalid borrow happens at runtime, even while working
227    /// with untrusted code. More importantly, Duat uses these
228    /// guarantees in order to give the end user a ridiculous amount
229    /// of freedom in where they can do things, whilst keeping Rust's
230    /// number one rule and ensuring thread safety, even with a
231    /// relatively large amount of shareable state.
232    ///
233    /// # Panics
234    ///
235    /// Panics if there is a mutable borrow of this struct somewhere,
236    /// which could happen if you use [`write_unsafe`] or
237    /// [`write_unsafe_as`]
238    ///
239    /// [`write_unsafe`]: Self::write_unsafe
240    /// [`write_unsafe_as`]: Self::write_unsafe_as
241    pub fn read<Ret>(&self, _: &Pass, f: impl FnOnce(&T) -> Ret) -> Ret {
242        update_read_state(&self.read_state, &self.cur_state);
243        f(&*self.value.borrow())
244    }
245
246    /// Reads the value within as `U` using a [`Pass`]
247    ///
248    /// The consistent use of a [`Pass`] for the purposes of
249    /// reading/writing to the values of [`RwData`]s ensures that no
250    /// panic or invalid borrow happens at runtime, even while working
251    /// with untrusted code. More importantly, Duat uses these
252    /// guarantees in order to give the end user a ridiculous amount
253    /// of freedom in where they can do things, whilst keeping Rust's
254    /// number one rule and ensuring thread safety, even with a
255    /// relatively large amount of shareable state.
256    ///
257    /// # Panics
258    ///
259    /// Panics if there is a mutable borrow of this struct somewhere,
260    /// which could happen if you use [`write_unsafe`] or
261    /// [`write_unsafe_as`]
262    ///
263    /// [`write_unsafe`]: Self::write_unsafe
264    /// [`write_unsafe_as`]: Self::write_unsafe_as
265    pub fn read_as<Ret, U: 'static>(&self, _: &Pass, f: impl FnOnce(&U) -> Ret) -> Option<Ret> {
266        fn prepare<T: ?Sized, U: 'static>(data: &RwData<T>) -> Option<std::cell::Ref<U>> {
267            if TypeId::of::<U>() != data.ty {
268                return None;
269            }
270
271            data.read_state.set(data.cur_state.get());
272            let ptr = Rc::as_ptr(&data.value);
273            Some(unsafe { (ptr as *const RefCell<U>).as_ref().unwrap().borrow() })
274        }
275
276        prepare(self).map(|mapped| f(&*mapped))
277    }
278
279    /// Reads the value within, without a [`Pass`]
280    ///
281    /// While a lack of [`Pass`]es grants you more freedom, it may
282    /// also cause panics if not handled carefully, since you could be
283    /// breaking the number one rule of Rust.
284    ///
285    /// # Panics
286    ///
287    /// Panics if there is a mutable borrow of this struct somewhere
288    ///
289    /// # Safety
290    ///
291    /// In order to safely use this function without panicking, there
292    /// are some useful guidelines that you should follow:
293    ///
294    /// - The value being read does not have any [`RwData`] within;
295    /// - You know that this value is not being shared anywhere else;
296    ///
297    /// Essentially, in order to use this safely, you should treat it
298    /// like a glorified [`RefCell`]
299    pub unsafe fn read_unsafe<Ret>(&self, f: impl FnOnce(&T) -> Ret) -> Ret {
300        update_read_state(&self.read_state, &self.cur_state);
301        f(&*self.value.borrow())
302    }
303
304    /// Reads the value within as `U`, without a [`Pass`]
305    ///
306    /// While a lack of [`Pass`]es grants you more freedom, it may
307    /// also cause panics if not handled carefully, since you could be
308    /// breaking the number one rule of Rust.
309    ///
310    /// # Panics
311    ///
312    /// Panics if there is a mutable borrow of this struct somewhere
313    ///
314    /// # Safety
315    ///
316    /// In order to safely use this function without panicking, there
317    /// are some useful guidelines that you should follow:
318    ///
319    /// - The value being read does not have any [`RwData`] within;
320    /// - You know that this value is not being shared anywhere else;
321    ///
322    /// Essentially, in order to use this safely, you should treat it
323    /// like a glorified [`RefCell`]
324    pub unsafe fn read_unsafe_as<Ret, U: 'static>(&self, f: impl FnOnce(&U) -> Ret) -> Option<Ret> {
325        if TypeId::of::<U>() != self.ty {
326            return None;
327        }
328
329        self.read_state.set(self.cur_state.get());
330        let ptr = Rc::as_ptr(&self.value);
331        let value = unsafe { (ptr as *const RefCell<U>).as_ref().unwrap() };
332        Some(f(&*value.borrow()))
333    }
334
335    /// Simulates a [`read`] without actually reading
336    ///
337    /// This is useful if you want to tell Duat that you don't want
338    /// [`has_changed`] to return `true`, but you don't have a
339    /// [`Pass`] available to [`read`] the value.
340    ///
341    /// [`read`]: Self::read
342    /// [`has_changed`]: Self::has_changed
343    pub fn declare_as_read(&self) {
344        self.read_state.set(self.cur_state.get());
345    }
346
347    /// Reads the data without updating its read state, might be
348    /// removed, idk
349    pub(crate) fn read_raw<Ret>(&self, f: impl FnOnce(&T) -> Ret) -> Ret {
350        f(&*self.value.borrow())
351    }
352
353    /// Acquires the value within, meant for improving compile times
354    /// internally.
355    pub(crate) fn acquire(&self, _: &Pass) -> std::cell::RefMut<'_, T> {
356        update_read_state(&self.read_state, &self.cur_state);
357        self.value.borrow_mut()
358    }
359
360    ////////// Writing functions
361
362    /// Writes to the value within using a [`Pass`]
363    ///
364    /// The consistent use of a [`Pass`] for the purposes of
365    /// reading/writing to the values of [`RwData`]s ensures that no
366    /// panic or invalid borrow happens at runtime, even while working
367    /// with untrusted code. More importantly, Duat uses these
368    /// guarantees in order to give the end user a ridiculous amount
369    /// of freedom in where they can do things, whilst keeping Rust's
370    /// number one rule and ensuring thread safety, even with a
371    /// relatively large amount of shareable state.
372    ///
373    /// # Panics
374    ///
375    /// Panics if there is any type of borrow of this struct
376    /// somewhere, which could happen if you use [`read_unsafe`]
377    /// or [`write_unsafe`], for example.
378    ///
379    /// [`read_unsafe`]: Self::read_unsafe
380    /// [`write_unsafe`]: Self::write_unsafe
381    #[track_caller]
382    pub fn write<Ret>(&self, _: &mut Pass, f: impl FnOnce(&mut T) -> Ret) -> Ret {
383        update_cur_state(&self.read_state, &self.cur_state);
384        f(&mut *self.value.borrow_mut())
385    }
386
387    /// Writes to the value within as `U` using a [`Pass`]
388    ///
389    /// The consistent use of a [`Pass`] for the purposes of
390    /// reading/writing to the values of [`RwData`]s ensures that no
391    /// panic or invalid borrow happens at runtime, even while working
392    /// with untrusted code. More importantly, Duat uses these
393    /// guarantees in order to give the end user a ridiculous amount
394    /// of freedom in where they can do things, whilst keeping Rust's
395    /// number one rule and ensuring thread safety, even with a
396    /// relatively large amount of shareable state.
397    ///
398    /// # Panics
399    ///
400    /// Panics if there is any type of borrow of this struct
401    /// somewhere, which could happen if you use [`read_unsafe`]
402    /// or [`write_unsafe`], for example.
403    ///
404    /// [`read_unsafe`]: Self::read_unsafe
405    /// [`write_unsafe`]: Self::write_unsafe
406    pub fn write_as<Ret, U: 'static>(
407        &self,
408        _: &mut Pass,
409        f: impl FnOnce(&mut U) -> Ret,
410    ) -> Option<Ret> {
411        fn prepare<T: ?Sized, U: 'static>(data: &RwData<T>) -> Option<std::cell::RefMut<U>> {
412            if TypeId::of::<U>() != data.ty {
413                return None;
414            }
415
416            data.cur_state.set(data.cur_state.get() + 1);
417            data.read_state.set(data.cur_state.get());
418            let ptr = Rc::as_ptr(&data.value);
419            Some(unsafe { (ptr as *const RefCell<U>).as_ref().unwrap().borrow_mut() })
420        }
421
422        prepare(self).map(|mut mapped| f(&mut *mapped))
423    }
424
425    /// Writes to the value within as `U`, without a [`Pass`]
426    ///
427    /// While a lack of [`Pass`]es grants you more freedom, it may
428    /// also cause panics if not handled carefully, since you could be
429    /// breaking the number one rule of Rust.
430    ///
431    /// # Panics
432    ///
433    /// Will panic if there are any types of borrows of the value
434    /// within somewhere else.
435    ///
436    /// # Safety
437    ///
438    /// In order to safely use this function without panicking, there
439    /// are some useful guidelines that you should follow:
440    ///
441    /// - The value being read does not have any [`RwData`] within;
442    /// - You know that this value is not being shared anywhere else;
443    ///
444    /// Essentially, in order to use this safely, you should treat it
445    /// like a glorified [`RefCell`]
446    pub unsafe fn write_unsafe<Ret>(&self, f: impl FnOnce(&mut T) -> Ret) -> Ret {
447        update_cur_state(&self.read_state, &self.cur_state);
448        f(&mut *self.value.borrow_mut())
449    }
450
451    /// Writes to the value within, without a [`Pass`]
452    ///
453    /// While a lack of [`Pass`]es grants you more freedom, it may
454    /// also cause panics if not handled carefully, since you could be
455    /// breaking the number one rule of Rust.
456    ///
457    /// # Panics
458    ///
459    /// Will panic if there are any types of borrows of the value
460    /// within somewhere else.
461    ///
462    /// # Safety
463    ///
464    /// In order to safely use this function without panicking, there
465    /// are some useful guidelines that you should follow:
466    ///
467    /// - The value being read does not have any [`RwData`] within;
468    /// - You know that this value is not being shared anywhere else;
469    ///
470    /// Essentially, in order to use this safely, you should treat it
471    /// like a glorified [`RefCell`]
472    pub unsafe fn write_unsafe_as<Ret, U: 'static>(
473        &self,
474        f: impl FnOnce(&mut U) -> Ret,
475    ) -> Option<Ret> {
476        fn prepare<T: ?Sized, U: 'static>(data: &RwData<T>) -> Option<std::cell::RefMut<U>> {
477            if TypeId::of::<U>() != data.ty {
478                return None;
479            }
480
481            data.cur_state.set(data.cur_state.get() + 1);
482            data.read_state.set(data.cur_state.get());
483            let ptr = Rc::as_ptr(&data.value);
484            Some(unsafe { (ptr as *const RefCell<U>).as_ref().unwrap().borrow_mut() })
485        }
486
487        prepare(self).map(|mut mapped| f(&mut *mapped))
488    }
489
490    /// Simulates a [`write`] without actually reading
491    ///
492    /// This is useful if you want to tell Duat that you want
493    /// [`has_changed`] to return `true`, but you don't have a
494    /// [`Pass`] available to [`write`] the value with.
495    ///
496    /// [`write`]: Self::write
497    /// [`has_changed`]: Self::has_changed
498    pub fn declare_written(&self) {
499        update_cur_state(&self.read_state, &self.cur_state);
500    }
501
502    /// Acquires a mutable reference to the value within, for
503    /// compilation time improvements inside Duat
504    pub(crate) fn acquire_mut(&self, _: &mut Pass) -> std::cell::RefMut<'_, T> {
505        update_cur_state(&self.read_state, &self.cur_state);
506        self.value.borrow_mut()
507    }
508
509    ////////// Mapping of the inner value
510
511    /// Maps the value to another value with a function
512    ///
513    /// This function will return a struct that acts like a "read
514    /// only" version of [`RwData`], which also maps the value to
515    /// a return type.
516    pub fn map<Ret: 'static>(&self, map: impl FnMut(&T) -> Ret + 'static) -> DataMap<T, Ret> {
517        let RwData { value, cur_state, read_state, .. } = self.clone();
518        let data = RwData {
519            value,
520            cur_state,
521            read_state,
522            ty: TypeId::of::<T>(),
523        };
524
525        DataMap { data, map: Rc::new(RefCell::new(map)) }
526    }
527
528    /// Attempts to downcast an [`RwData`] to a concrete type
529    ///
530    /// Returns [`Some(RwData<U>)`] if the value within was of type
531    /// `U`, i.e., for unsized types, `U` was the type parameter
532    /// passed when calling [`RwData::new_unsized`].
533    ///
534    /// [`Some(RwData<U>)`]: Some
535    pub fn try_downcast<U: 'static>(&self) -> Option<RwData<U>> {
536        if TypeId::of::<U>() != self.ty {
537            return None;
538        }
539
540        let ptr = Rc::into_raw(self.value.clone());
541        let value = unsafe { Rc::from_raw(ptr as *const RefCell<U>) };
542        Some(RwData {
543            value,
544            cur_state: self.cur_state.clone(),
545            read_state: Rc::new(Cell::new(self.cur_state.get())),
546            ty: TypeId::of::<U>(),
547        })
548    }
549
550    ////////// Querying functions
551
552    /// Wether this [`RwData`] and another point to the same value
553    pub fn ptr_eq<U: ?Sized>(&self, other: &RwData<U>) -> bool {
554        self.value.as_ptr().addr() == other.value.as_ptr().addr()
555    }
556
557    /// The [`TypeId`] of the concrete type within
558    pub fn type_id(&self) -> TypeId {
559        self.ty
560    }
561
562    /// Wether the concrete [`TypeId`] matches that of `U`
563    pub fn data_is<U: 'static>(&self) -> bool {
564        self.ty == TypeId::of::<U>()
565    }
566
567    /// Wether someone else called [`write`] or [`write_as`] since the
568    /// last [`read`] or [`write`]
569    ///
570    /// Do note that this *DOES NOT* mean that the value inside has
571    /// actually been changed, it just means a mutable reference was
572    /// acquired after the last call to [`has_changed`].
573    ///
574    /// Some types like [`Text`], and traits like [`Widget`] offer
575    /// [`has_changed`](crate::ui::Widget::needs_update) methods,
576    /// you should try to determine what parts to look for changes.
577    ///
578    /// Generally though, you can use this method to gauge that.
579    ///
580    /// [`write`]: Self::write
581    /// [`write_as`]: Self::write_as
582    /// [`read`]: Self::read
583    /// [`has_changed`]: Self::has_changed
584    /// [`Text`]: crate::text::Text
585    /// [`Widget`]: crate::ui::Widget
586    pub fn has_changed(&self) -> bool {
587        self.read_state.get() < self.cur_state.get()
588    }
589
590    /// A function that checks if the data has been updated
591    ///
592    /// Do note that this function will check for the specific
593    /// [`RwData`] that was used in its creation, so if you call
594    /// [`read`] on that specific [`RwData`] for example, this
595    /// function will start returning `false`.
596    ///
597    /// [`read`]: Self::read
598    pub fn checker(&self) -> impl Fn() -> bool + 'static {
599        let (cur, read) = (self.cur_state.clone(), self.read_state.clone());
600        move || read.get() < cur.get()
601    }
602
603    ////////// Widget Functions
604
605    /// Clones the [`Text`] of the [`Widget`]
606    pub fn clone_text<U>(&self, pa: &Pass) -> Text
607    where
608        T: Widget<U>,
609        U: Ui,
610    {
611        self.acquire(pa).text().clone()
612    }
613
614    /// Takes the [`Text`] from the [`Widget`], replacing it with the
615    /// [`Default`]
616    pub fn take_text<U>(&self, pa: &mut Pass) -> Text
617    where
618        T: Widget<U>,
619        U: Ui,
620    {
621        std::mem::take(self.acquire_mut(pa).text_mut())
622    }
623
624    /// Replaces the [`Text`] of the [`Widget`], returning the
625    /// previous value
626    pub fn replace_text<U>(&self, pa: &mut Pass, text: impl Into<Text>) -> Text
627    where
628        T: Widget<U>,
629        U: Ui,
630    {
631        std::mem::replace(self.acquire_mut(pa).text_mut(), text.into())
632    }
633
634    /// The [`PrintCfg`] of the [`Widget`]
635    pub fn print_cfg<U>(&self, pa: &Pass) -> PrintCfg
636    where
637        T: Widget<U>,
638        U: Ui,
639    {
640        self.acquire(pa).print_cfg()
641    }
642
643    /// Whether the [`Widget`] needs to be updated
644    pub fn needs_update<U>(&self, pa: &Pass) -> bool
645    where
646        T: Widget<U>,
647        U: Ui,
648    {
649        self.acquire(pa).needs_update()
650    }
651}
652
653impl<T: ?Sized + 'static> RwData<T> {}
654
655impl<T: ?Sized> Clone for RwData<T> {
656    fn clone(&self) -> Self {
657        Self {
658            value: self.value.clone(),
659            ty: self.ty,
660            cur_state: self.cur_state.clone(),
661            read_state: Rc::new(Cell::new(self.cur_state.get())),
662        }
663    }
664}
665
666impl<T: Default + 'static> Default for RwData<T> {
667    fn default() -> Self {
668        Self {
669            value: Rc::default(),
670            cur_state: Rc::new(Cell::new(1)),
671            read_state: Rc::default(),
672            ty: TypeId::of::<T>(),
673        }
674    }
675}
676
677/// A mapping of an [`RwData`]
678pub struct DataMap<I: ?Sized + 'static, O: 'static> {
679    data: RwData<I>,
680    map: Rc<RefCell<dyn FnMut(&I) -> O>>,
681}
682
683impl<I: ?Sized, O> DataMap<I, O> {
684    /// Maps the value within, works just like [`RwData::map`]
685    pub fn map<O2>(&self, mut f: impl FnMut(O) -> O2 + 'static) -> DataMap<I, O2> {
686        let data_map = self.clone();
687        data_map
688            .data
689            .clone()
690            .map(move |input| f(data_map.map.borrow_mut()(input)))
691    }
692
693    /// Wether someone else called [`write`] or [`write_as`] since the
694    /// last [`read`] or [`write`]
695    ///
696    /// Do note that this *DOES NOT* mean that the value inside has
697    /// actually been changed, it just means a mutable reference was
698    /// acquired after the last call to [`has_changed`].
699    ///
700    /// Some types like [`Text`], and traits like [`Widget`] offer
701    /// [`needs_update`] methods, you should try to determine what
702    /// parts to look for changes.
703    ///
704    /// Generally though, you can use this method to gauge that.
705    ///
706    /// [`write`]: RwData::write
707    /// [`write_as`]: RwData::write_as
708    /// [`read`]: RwData::read
709    /// [`has_changed`]: RwData::has_changed
710    /// [`Text`]: crate::text::Text
711    /// [`Widget`]: crate::ui::Widget
712    /// [`needs_update`]: crate::ui::Widget::needs_update
713    pub fn has_changed(&self) -> bool {
714        self.data.has_changed()
715    }
716
717    /// A function that checks if the data has been updated
718    ///
719    /// Do note that this function will check for the specific
720    /// [`RwData`] that was used in its creation, so if you call
721    /// [`read`] on that specific [`RwData`] for example, this
722    /// function will start returning `false`.
723    ///
724    /// [`read`]: RwData::read
725    pub fn checker(&self) -> impl Fn() -> bool + 'static {
726        self.data.checker()
727    }
728}
729
730impl<I: ?Sized + 'static, O> Clone for DataMap<I, O> {
731    fn clone(&self) -> Self {
732        Self {
733            data: self.data.clone(),
734            map: self.map.clone(),
735        }
736    }
737}
738
739impl<I: ?Sized + 'static, O: 'static> DataMap<I, O> {}
740
741impl<I: ?Sized + 'static, O: 'static> FnOnce<(&Pass<'_>,)> for DataMap<I, O> {
742    type Output = O;
743
744    extern "rust-call" fn call_once(self, (key,): (&Pass,)) -> Self::Output {
745        self.data.read(key, |input| self.map.borrow_mut()(input))
746    }
747}
748
749impl<I: ?Sized + 'static, O: 'static> FnMut<(&Pass<'_>,)> for DataMap<I, O> {
750    extern "rust-call" fn call_mut(&mut self, (key,): (&Pass,)) -> Self::Output {
751        self.data.read(key, |input| self.map.borrow_mut()(input))
752    }
753}
754
755impl<I: ?Sized + 'static, O: 'static> Fn<(&Pass<'_>,)> for DataMap<I, O> {
756    extern "rust-call" fn call(&self, (key,): (&Pass,)) -> Self::Output {
757        self.data.read(key, |input| self.map.borrow_mut()(input))
758    }
759}
760
761/// A checking struct that periodically returns `true`
762pub struct PeriodicChecker(Arc<AtomicBool>);
763
764impl PeriodicChecker {
765    /// Returns a new [`PeriodicChecker`]
766    pub fn new(duration: Duration) -> Self {
767        let has_elapsed = Arc::new(AtomicBool::new(false));
768        std::thread::spawn({
769            let has_elapsed = has_elapsed.clone();
770            move || {
771                while !crate::context::will_reload_or_quit() {
772                    std::thread::sleep(duration);
773                    has_elapsed.store(true, Ordering::Relaxed);
774                }
775            }
776        });
777
778        Self(has_elapsed)
779    }
780
781    /// Checks if the requested [`Duration`] has elapsed
782    pub fn check(&self) -> bool {
783        self.0.fetch_and(false, Ordering::Relaxed)
784    }
785}
786
787/// A key for reading/writing to [`RwData`]
788///
789/// This key is necessary in order to prevent breakage of the number
790/// one rule of Rust: any number of shared references, or one
791/// exclusive reference.
792///
793/// When you call [`RwData::read`], any call to [`RwData::write`] may
794/// end up breaking this rule, and vice-versa, which is why this
795/// struct is necessary.
796///
797/// One downside of this approach is that it is even more restrictive
798/// than Rust's rule of thumb, since that one is enforced on
799/// individual instances, while this one is enforced on all
800/// [`RwData`]s. This (as far as i know) cannot be circumvented, as a
801/// more advanced compile time checker (that distinguishes
802/// [`RwData<T>`]s of different `T`s, for example) does not seem
803/// feasible without the use of unfinished features, which I am not
804/// willing to use.
805///
806/// Do note that you can still ignore this if you want, by use of
807/// [`read_unsafe`] and [`write_unsafe`], but this might cause a panic
808/// in Duat because of the [`RefCell`]s under the hood.
809///
810/// [`read_unsafe`]: RwData::read_unsafe
811/// [`write_unsafe`]: RwData::write_unsafe
812pub struct Pass<'a>(PhantomData<&'a Rc<RefCell<()>>>);
813
814impl Pass<'_> {
815    /// Returns a new instance of [`Pass`]
816    ///
817    /// Be careful when using this!
818    pub(crate) unsafe fn new() -> Self {
819        Pass(PhantomData)
820    }
821}
822
823fn update_read_state(read_state: &Rc<Cell<usize>>, cur_state: &Rc<Cell<usize>>) {
824    read_state.set(cur_state.get());
825}
826
827fn update_cur_state(read_state: &Rc<Cell<usize>>, cur_state: &Rc<Cell<usize>>) {
828    cur_state.set(cur_state.get() + 1);
829    read_state.set(cur_state.get());
830}