Fix user changes handling (#803)
* add failing test from @Johannes0021 * apply fix on update_positions * apply fix on ColliderSet::iter_mut * fix clippy.. * more complete test * feat: refactor modified sets into a wrapper to avoid future mistakes * chore: fix typos --------- Co-authored-by: Sébastien Crozet <sebcrozet@dimforge.com>
This commit is contained in:
65
src/data/modified_objects.rs
Normal file
65
src/data/modified_objects.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
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<Handle, Object>(Vec<Handle>, PhantomData<Object>);
|
||||
|
||||
impl<Handle, Object> Default for ModifiedObjects<Handle, Object> {
|
||||
fn default() -> Self {
|
||||
Self(Vec::new(), PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait HasModifiedFlag {
|
||||
fn has_modified_flag(&self) -> bool;
|
||||
fn set_modified_flag(&mut self);
|
||||
}
|
||||
|
||||
impl<Handle, Object> Deref for ModifiedObjects<Handle, Object> {
|
||||
type Target = Vec<Handle>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<Handle, Object: HasModifiedFlag> ModifiedObjects<Handle, Object> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user