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}