shipyard/views/
unique_view.rs

1use crate::atomic_refcell::SharedBorrow;
2use crate::component::Unique;
3use crate::tracking::TrackingTimestamp;
4use crate::unique::UniqueStorage;
5use core::fmt;
6use core::ops::Deref;
7
8/// Shared view over a unique component storage.
9pub struct UniqueView<'a, T: Unique> {
10    pub(crate) unique: &'a UniqueStorage<T>,
11    pub(crate) borrow: Option<SharedBorrow<'a>>,
12    pub(crate) all_borrow: Option<SharedBorrow<'a>>,
13    pub(crate) last_insertion: TrackingTimestamp,
14    pub(crate) last_modification: TrackingTimestamp,
15    pub(crate) current: TrackingTimestamp,
16}
17
18impl<T: Unique> UniqueView<'_, T> {
19    /// Duplicates the [`UniqueView`].
20    ///
21    /// [`Clone`] is not implemented to not conflict with `T::clone`.
22    #[allow(clippy::should_implement_trait)]
23    #[inline]
24    pub fn clone(unique: &Self) -> Self {
25        UniqueView {
26            unique: unique.unique,
27            borrow: unique.borrow.clone(),
28            all_borrow: unique.all_borrow.clone(),
29            last_insertion: unique.last_insertion,
30            last_modification: unique.last_modification,
31            current: unique.current,
32        }
33    }
34
35    /// Replaces the timestamp starting the tracking time window for insertions.
36    ///
37    /// Tracking works based on a time window. From the last time the system ran (in workloads)
38    /// or since the last clear.
39    ///
40    /// Sometimes this automatic time window isn't what you need.
41    /// This can happen when you want to keep the same tracking information for multiple runs
42    /// of the same system.
43    ///
44    /// For example if you interpolate movement between frames, you might run an interpolation workload
45    /// multiple times but not change the [`World`](crate::World) during its execution.\
46    /// In this case you want the same tracking information for all runs of this workload
47    /// which would have disappeared using the automatic window.
48    pub fn override_last_insertion(
49        &mut self,
50        new_timestamp: TrackingTimestamp,
51    ) -> TrackingTimestamp {
52        core::mem::replace(&mut self.last_insertion, new_timestamp)
53    }
54
55    /// Replaces the timestamp starting the tracking time window for modifications.
56    ///
57    /// Tracking works based on a time window. From the last time the system ran (in workloads)
58    /// or since the last clear.
59    ///
60    /// Sometimes this automatic time window isn't what you need.
61    /// This can happen when you want to keep the same tracking information for multiple runs
62    /// of the same system.
63    ///
64    /// For example if you interpolate movement between frames, you might run an interpolation workload
65    /// multiple times but not change the [`World`](crate::World) during its execution.\
66    /// In this case you want the same tracking information for all runs of this workload
67    /// which would have disappeared using the automatic window.
68    pub fn override_last_modification(
69        &mut self,
70        new_timestamp: TrackingTimestamp,
71    ) -> TrackingTimestamp {
72        core::mem::replace(&mut self.last_modification, new_timestamp)
73    }
74}
75
76impl<T: Unique> UniqueView<'_, T> {
77    /// Returns `true` if the component was inserted before the last [`clear_inserted`] call.  
78    ///
79    /// [`clear_inserted`]: crate::UniqueViewMut::clear_inserted
80    #[inline]
81    pub fn is_inserted(&self) -> bool {
82        self.unique
83            .insert
84            .is_within(self.last_insertion, self.current)
85    }
86    /// Returns `true` is the component was modified since the last [`clear_modified`] call.
87    ///
88    /// [`clear_modified`]: crate::UniqueViewMut::clear_modified
89    #[inline]
90    pub fn is_modified(&self) -> bool {
91        self.unique
92            .modification
93            .is_within(self.last_modification, self.current)
94    }
95    /// Returns `true` if the component was inserted or modified since the last [`clear_inserted`] or [`clear_modified`] call.  
96    ///
97    /// [`clear_inserted`]: crate::UniqueViewMut::clear_inserted
98    /// [`clear_modified`]: crate::UniqueViewMut::clear_modified
99    #[inline]
100    pub fn is_inserted_or_modified(&self) -> bool {
101        self.is_inserted() || self.is_modified()
102    }
103}
104
105impl<T: Unique> Deref for UniqueView<'_, T> {
106    type Target = T;
107
108    #[inline]
109    fn deref(&self) -> &Self::Target {
110        &self.unique.value
111    }
112}
113
114impl<T: Unique> AsRef<T> for UniqueView<'_, T> {
115    #[inline]
116    fn as_ref(&self) -> &T {
117        &self.unique.value
118    }
119}
120
121impl<T: fmt::Debug + Unique> fmt::Debug for UniqueView<'_, T> {
122    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123        self.unique.value.fmt(f)
124    }
125}