use std::marker::PhantomData; use std::ops::Deref; /// Contains handles of modified objects. /// /// This is a wrapper over a `Vec` to ensure we don’t forget to set the object’s /// MODIFIED flag when adding it to this set. /// It is possible to bypass the wrapper with `.as_mut_internal`. But this should only /// be done for internal engine usage (like the physics pipeline). #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[derive(Clone, Debug)] pub(crate) struct ModifiedObjects(Vec, PhantomData); impl Default for ModifiedObjects { fn default() -> Self { Self(Vec::new(), PhantomData) } } pub(crate) trait HasModifiedFlag { fn has_modified_flag(&self) -> bool; fn set_modified_flag(&mut self); } impl Deref for ModifiedObjects { type Target = Vec; fn deref(&self) -> &Self::Target { &self.0 } } impl ModifiedObjects { pub fn with_capacity(capacity: usize) -> Self { Self(Vec::with_capacity(capacity), PhantomData) } /// Remove every handle from this set. /// /// Note that the corresponding object MODIFIED flags won’t be reset automatically by this function. pub fn clear(&mut self) { self.0.clear() } /// Pushes a object handle to this set after checking that it doesn’t have the MODIFIED /// flag set. /// /// This will also set the object’s MODIFIED flag. pub fn push_once(&mut self, handle: Handle, object: &mut Object) { if !object.has_modified_flag() { self.push_unchecked(handle, object); } } /// Pushes an object handle to this set without checking if the object already has the MODIFIED /// flags. /// /// Only use in situation where you are certain (due to other contextual information) that /// the object isn’t already in the set. /// /// This will also set the object’s MODIFIED flag. pub fn push_unchecked(&mut self, handle: Handle, object: &mut Object) { object.set_modified_flag(); self.0.push(handle); } }