Skip to content

Commit

Permalink
don't error when sending HierarchyEvents when Event type not register…
Browse files Browse the repository at this point in the history
…ed (#7031)

# Objective

- Loading a gltf files prints many errors
```
ERROR bevy_ecs::world: Unable to send event `bevy_hierarchy::events::HierarchyEvent`
	Event must be added to the app with `add_event()`
	https://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event
```
- Loading a gltf file create a world for a scene where events are not registered. Executing hierarchy commands on that world should not print error

## Solution

- Revert part of #6921 
- don't use `world.send_event` / `world.send_event_batch` from commands
  • Loading branch information
mockersf committed Dec 26, 2022
1 parent 7763b5e commit f1a21db
Showing 1 changed file with 35 additions and 17 deletions.
52 changes: 35 additions & 17 deletions crates/bevy_hierarchy/src/child_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@ use crate::{Children, HierarchyEvent, Parent};
use bevy_ecs::{
bundle::Bundle,
entity::Entity,
prelude::Events,
system::{Command, Commands, EntityCommands},
world::{EntityMut, World},
};
use smallvec::SmallVec;

// Do not use `world.send_event_batch` as it prints error message when the Events are not available in the world,
// even though it's a valid use case to execute commands on a world without events. Loading a GLTF file for example
fn push_events(world: &mut World, events: impl IntoIterator<Item = HierarchyEvent>) {
if let Some(mut moved) = world.get_resource_mut::<Events<HierarchyEvent>>() {
moved.extend(events);
}
}

fn push_child_unchecked(world: &mut World, parent: Entity, child: Entity) {
let mut parent = world.entity_mut(parent);
if let Some(mut children) = parent.get_mut::<Children>() {
Expand Down Expand Up @@ -58,13 +67,16 @@ fn update_old_parent(world: &mut World, child: Entity, parent: Entity) {
}
remove_from_children(world, previous_parent, child);

world.send_event(HierarchyEvent::ChildMoved {
child,
previous_parent,
new_parent: parent,
});
push_events(
world,
[HierarchyEvent::ChildMoved {
child,
previous_parent,
new_parent: parent,
}],
);
} else {
world.send_event(HierarchyEvent::ChildAdded { child, parent });
push_events(world, [HierarchyEvent::ChildAdded { child, parent }]);
}
}

Expand Down Expand Up @@ -95,7 +107,7 @@ fn update_old_parents(world: &mut World, parent: Entity, children: &[Entity]) {
events.push(HierarchyEvent::ChildAdded { child, parent });
}
}
world.send_event_batch(events);
push_events(world, events);
}

fn remove_children(parent: Entity, children: &[Entity], world: &mut World) {
Expand All @@ -114,7 +126,7 @@ fn remove_children(parent: Entity, children: &[Entity], world: &mut World) {
world.entity_mut(child).remove::<Parent>();
}
}
world.send_event_batch(events);
push_events(world, events);

let mut parent = world.entity_mut(parent);
if let Some(mut parent_children) = parent.get_mut::<Children>() {
Expand Down Expand Up @@ -337,21 +349,27 @@ impl<'w> WorldChildBuilder<'w> {
pub fn spawn(&mut self, bundle: impl Bundle + Send + Sync + 'static) -> EntityMut<'_> {
let entity = self.world.spawn((bundle, Parent(self.parent))).id();
push_child_unchecked(self.world, self.parent, entity);
self.world.send_event(HierarchyEvent::ChildAdded {
child: entity,
parent: self.parent,
});
push_events(
self.world,
[HierarchyEvent::ChildAdded {
child: entity,
parent: self.parent,
}],
);
self.world.entity_mut(entity)
}

/// Spawns an [`Entity`] with no components and inserts it into the children defined by the [`WorldChildBuilder`] which adds the [`Parent`] component to it.
pub fn spawn_empty(&mut self) -> EntityMut<'_> {
let entity = self.world.spawn(Parent(self.parent)).id();
push_child_unchecked(self.world, self.parent, entity);
self.world.send_event(HierarchyEvent::ChildAdded {
child: entity,
parent: self.parent,
});
push_events(
self.world,
[HierarchyEvent::ChildAdded {
child: entity,
parent: self.parent,
}],
);
self.world.entity_mut(entity)
}

Expand Down Expand Up @@ -465,7 +483,7 @@ impl<'w> BuildWorldChildren for EntityMut<'w> {
if let Some(parent) = self.remove::<Parent>().map(|p| p.get()) {
self.world_scope(|world| {
remove_from_children(world, parent, child);
world.send_event(HierarchyEvent::ChildRemoved { child, parent });
push_events(world, [HierarchyEvent::ChildRemoved { child, parent }]);
});
}
self
Expand Down

0 comments on commit f1a21db

Please sign in to comment.