Skip to content

Commit

Permalink
remove old workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobhellermann committed Nov 30, 2024
1 parent ccbe7b5 commit 97d23b3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 43 deletions.
33 changes: 20 additions & 13 deletions crates/bevy-inspector-egui/src/bevy_inspector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ pub(crate) fn ui_for_entity_components(
queue: queue.as_deref_mut(),
};

let (value, is_changed, set_changed) = match component_view.get_entity_component_reflect(
let mut value = match component_view.get_entity_component_reflect(
entity,
component_type_id,
type_registry,
Expand All @@ -518,7 +518,7 @@ pub(crate) fn ui_for_entity_components(
}
};

if is_changed {
if value.is_changed() {
#[cfg(feature = "highlight_changes")]
set_highlight_style(ui);
}
Expand All @@ -528,14 +528,14 @@ pub(crate) fn ui_for_entity_components(

let inspector_changed = InspectorUi::for_bevy(type_registry, &mut cx)
.ui_for_reflect_with_options(
value.as_partial_reflect_mut(),
value.bypass_change_detection().as_partial_reflect_mut(),
ui,
id.with(component_id),
&(),
);

if inspector_changed {
set_changed();
value.set_changed();
}
});
ui.reset_style();
Expand Down Expand Up @@ -633,7 +633,6 @@ pub fn ui_for_entities_shared_components(
};

let mut values = Vec::with_capacity(entities.len());
let mut mark_changeds = Vec::with_capacity(entities.len());

for (i, &entity) in entities.iter().enumerate() {
// skip duplicate entities
Expand All @@ -649,9 +648,8 @@ pub fn ui_for_entities_shared_components(
&type_registry,
)
} {
Ok((value, mark_changed)) => {
values.push(value.as_partial_reflect_mut());
mark_changeds.push(mark_changed);
Ok(value) => {
values.push(value);
}
Err(error) => {
errors::show_error(error, ui, &name);
Expand All @@ -660,17 +658,23 @@ pub fn ui_for_entities_shared_components(
}
}

let mut values_reflect: Vec<_> = values
.iter_mut()
.map(|value| value.bypass_change_detection().as_partial_reflect_mut())
.collect();
let changed = env.ui_for_reflect_many_with_options(
component_type_id,
&name,
ui,
id.with(component_id),
&(),
values.as_mut_slice(),
values_reflect.as_mut_slice(),
&|a| a,
);
if changed {
mark_changeds.into_iter().for_each(|f| f());
for value in values.iter_mut() {
value.set_changed();
}
}
});
}
Expand Down Expand Up @@ -715,16 +719,19 @@ pub mod by_type_id {
};
let mut env = InspectorUi::for_bevy(type_registry, &mut cx);

let (resource, set_changed) = match resource_view
let mut resource = match resource_view
.get_resource_reflect_mut_by_id(resource_type_id, type_registry)
{
Ok(resource) => resource,
Err(err) => return errors::show_error(err, ui, name_of_type),
};

let changed = env.ui_for_reflect(resource.as_partial_reflect_mut(), ui);
let changed = env.ui_for_reflect(
resource.bypass_change_detection().as_partial_reflect_mut(),
ui,
);
if changed {
set_changed();
resource.set_changed();
}
}

Expand Down
34 changes: 17 additions & 17 deletions crates/bevy-inspector-egui/src/restricted_world_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ impl<'w> RestrictedWorldView<'w> {
&mut self,
type_id: TypeId,
type_registry: &TypeRegistry,
) -> Result<(&'_ mut dyn Reflect, impl FnOnce() + '_), Error> {
) -> Result<Mut<'_, dyn Reflect>, Error> {
if !self.allows_access_to_resource(type_id) {
return Err(Error::NoAccessToResource(type_id));
}
Expand Down Expand Up @@ -350,7 +350,7 @@ impl<'w> RestrictedWorldView<'w> {
entity: Entity,
component: TypeId,
type_registry: &TypeRegistry,
) -> Result<(&'_ mut dyn Reflect, bool, impl FnOnce() + '_), Error> {
) -> Result<Mut<'_, dyn Reflect>, Error> {
if !self.allows_access_to_component((entity, component)) {
return Err(Error::NoAccessToComponent((entity, component)));
}
Expand All @@ -370,12 +370,10 @@ impl<'w> RestrictedWorldView<'w> {
.get_mut_by_id(component_id)
.ok_or(Error::ComponentDoesNotExist((entity, component)))?
};
let changed = value.is_changed();

let (value, set_changed) =
// SAFETY: value is of type component
unsafe { mut_untyped_to_reflect(value, type_registry, component) }?;
Ok((value, changed, set_changed))
// SAFETY: value is of type component
let value = unsafe { mut_untyped_to_reflect(value, type_registry, component) }?;
Ok(value)
}

// SAFETY: must ensure distinct access
Expand All @@ -384,7 +382,7 @@ impl<'w> RestrictedWorldView<'w> {
entity: Entity,
component: TypeId,
type_registry: &TypeRegistry,
) -> Result<(&'_ mut dyn Reflect, impl FnOnce() + '_), Error> {
) -> Result<Mut<'_, dyn Reflect>, Error> {
if !self.allows_access_to_component((entity, component)) {
return Err(Error::NoAccessToComponent((entity, component)));
}
Expand Down Expand Up @@ -415,20 +413,22 @@ unsafe fn mut_untyped_to_reflect<'a>(
value: MutUntyped<'a>,
type_registry: &TypeRegistry,
type_id: TypeId,
) -> Result<(&'a mut dyn Reflect, impl FnOnce() + 'a), Error> {
) -> Result<Mut<'a, dyn Reflect>, Error> {
let registration = type_registry
.get(type_id)
.ok_or(Error::NoTypeRegistration(type_id))?;
let reflect_from_ptr = registration
.data::<ReflectFromPtr>()
.ok_or(Error::NoTypeData(type_id, "ReflectFromPtr"))?;

let (ptr, set_changed) = crate::utils::mut_untyped_split(value);
assert_eq!(reflect_from_ptr.type_id(), type_id);
// SAFETY: ptr is of type type_id as required in safety contract, type_id was checked above
let value = unsafe { reflect_from_ptr.as_reflect_mut(ptr) };

Ok((value, set_changed))
let value = value.map_unchanged(|ptr| {
// SAFETY: ptr is of type type_id as required in safety contract, type_id was checked above
unsafe { reflect_from_ptr.as_reflect_mut(ptr) }
});

Ok(value)
}

#[cfg(test)]
Expand Down Expand Up @@ -476,12 +476,12 @@ mod tests {

let mut type_registry = TypeRegistry::empty();
type_registry.register::<B>();
let b = world
let mut b = world
.get_resource_reflect_mut_by_id(TypeId::of::<B>(), &type_registry)
.unwrap();

a.0.clear();
b.0.downcast_mut::<B>().unwrap().0.clear();
b.downcast_mut::<B>().unwrap().0.clear();
}

#[test]
Expand Down Expand Up @@ -531,12 +531,12 @@ mod tests {

let (mut component_view, mut world) =
world.split_off_component((entity, TypeId::of::<ComponentA>()));
let component = component_view
let mut component = component_view
.get_entity_component_reflect(entity, TypeId::of::<ComponentA>(), &type_registry)
.unwrap();
let mut resource = world.get_resource_mut::<A>().unwrap();

component.0.downcast_mut::<ComponentA>().unwrap().0.clear();
component.downcast_mut::<ComponentA>().unwrap().0.clear();
resource.0.clear();
}
}
13 changes: 0 additions & 13 deletions crates/bevy-inspector-egui/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
use bevy_ecs::change_detection::{DetectChangesMut, MutUntyped};
use bevy_ecs::ptr::PtrMut;

// workaround for https://github.com/bevyengine/bevy/pull/6430
pub fn mut_untyped_split<'a>(mut mut_untyped: MutUntyped<'a>) -> (PtrMut<'a>, impl FnOnce() + 'a) {
// bypass_change_detection returns a `&mut PtrMut` which is basically useless, because all its methods take `self`
let ptr = mut_untyped.bypass_change_detection();
// SAFETY: this is exactly the same PtrMut, just not in a `&mut`. The old one is no longer accessible
let ptr = unsafe { PtrMut::new(std::ptr::NonNull::new_unchecked(ptr.as_ptr())) };

(ptr, move || mut_untyped.set_changed())
}

pub mod guess_entity_name {
use bevy_core::Name;
use bevy_ecs::{archetype::Archetype, prelude::*, world::unsafe_world_cell::UnsafeWorldCell};
Expand Down

0 comments on commit 97d23b3

Please sign in to comment.