mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Optimize observer unregistration (#15150)
# Objective
Fixes #14980
## Solution
Only iterate over archetypes containing the component.
## Alternatives
Additionally, for each archetype, cache how many observers are watching
one of its components & use this to speed up the check for each affected
archetype ([implemented
here](55c89aa033
)).
Benchmarking showed this to lead only to a minor speedup.
## Testing
There's both already a test checking that observers don't run after
being despawned as well as a regression test for the bug that
necessitates the check this PR optimizes.
This commit is contained in:
parent
c454db88a3
commit
f570f52aa2
2 changed files with 11 additions and 8 deletions
|
@ -766,7 +766,7 @@ pub struct Archetypes {
|
|||
/// find the archetype id by the archetype's components
|
||||
by_components: HashMap<ArchetypeComponents, ArchetypeId>,
|
||||
/// find all the archetypes that contain a component
|
||||
by_component: ComponentIndex,
|
||||
pub(crate) by_component: ComponentIndex,
|
||||
}
|
||||
|
||||
/// Metadata about how a component is stored in an [`Archetype`].
|
||||
|
|
|
@ -456,14 +456,17 @@ impl World {
|
|||
if observers.map.is_empty() && observers.entity_map.is_empty() {
|
||||
cache.component_observers.remove(component);
|
||||
if let Some(flag) = Observers::is_archetype_cached(event_type) {
|
||||
for archetype in &mut archetypes.archetypes {
|
||||
if archetype.contains(*component) {
|
||||
let no_longer_observed = archetype
|
||||
.components()
|
||||
.all(|id| !cache.component_observers.contains_key(&id));
|
||||
if let Some(by_component) = archetypes.by_component.get(component) {
|
||||
for archetype in by_component.keys() {
|
||||
let archetype = &mut archetypes.archetypes[archetype.index()];
|
||||
if archetype.contains(*component) {
|
||||
let no_longer_observed = archetype
|
||||
.components()
|
||||
.all(|id| !cache.component_observers.contains_key(&id));
|
||||
|
||||
if no_longer_observed {
|
||||
archetype.flags.set(flag, false);
|
||||
if no_longer_observed {
|
||||
archetype.flags.set(flag, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue