bevyengine / bevyengine/bevy

`IntoObserverSystem` is implemented for any `IntoSystem`, but observers actually only work with non-exclusive systems

Open
#14,925 5 comments 0 reactions 0 assignees View on GitHub
A-ECS C-Bug D-Modest S-Needs-Design
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version

0.14.1

## What you did

```rs
use bevy_ecs::event::Event;
use bevy_ecs::observer::Trigger;
use bevy_ecs::system::In;
use bevy_ecs::world::World;

#[derive(Event)]
struct E;

fn observer(_: In>, _: &mut World) {}

fn main() {
let mut world = World::new();
world.observe(observer);
world.flush();
world.trigger(E);
}
```

## What went wrong

When `world.trigger(E)` calls the observer system it ends up panicking with:

```
thread 'main' panicked at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.1\src\system\exclusive_function_system.rs:99:9:
Cannot run exclusive systems with a shared World reference
stack backtrace:
0: std::panicking::begin_panic_handler
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\std\src\panicking.rs:652
1: core::panicking::panic_fmt
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library\core\src\panicking.rs:72
2: bevy_ecs::system::exclusive_function_system::impl$1::run_unsafe > >),void (*)(bevy_ecs::system::In > >,ref_mut$ >
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.1\src\observer\runner.rs:409
4: bevy_ecs::observer::impl$2::invoke::closure$0 >
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.1\src\observer\mod.rs:192
5: core::ops::function::impls::impl$3::call_mut,ref$)> > >,bevy_ecs::observer::impl$2:
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\ops\function.rs:294
6: core::iter::traits::iterator::Iterator::for_each::call::closure$0,ref$)> >,ref_mut$),tuple$<>,core::iter::traits::iterator::Iterator::for_each::ca
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\hashbrown-0.14.5\src\map.rs:4749
8: hashbrown::raw::inner::RawIterRange)> >::fold_impl)>,tuple$<>,hashbrown::map::impl$63::fold::closure_env$0),tuple$<>,core::iter::traits::iterator::Iterator::for_each::call::closure
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\hashbrown-0.14.5\src\map.rs:4747
11: core::iter::traits::iterator::Iterator::for_each)>,ref_mut$ >
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.1\src\observer\mod.rs:204
13: bevy_ecs::world::deferred_world::DeferredWorld::trigger_observers_with_data >
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.1\src\world\deferred_world.rs:368
14: bevy_ecs::observer::trigger_event::trigger_event >
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.1\src\observer\trigger_event.rs:61
15: bevy_ecs::observer::trigger_event::impl$0::apply >
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.1\src\observer\trigger_event.rs:20
16: bevy_ecs::world::World::trigger
at E:\Programmi\Rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bevy_ecs-0.14.1\src\observer\mod.rs:275
17: rust_bevy_snake::main
at .\src\main.rs:15
18: core::ops::function::FnOnce::call_once >
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\ops\function.rs:250
19: core::hint::black_box
at /rustc/051478957371ee0084a7c0913941d2a8c4757bb9\library\core\src\hint.rs:338
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

I can see why observers should not be allowed exclusive world access, but the API does nothing to prevent you from actually creating one and getting a panic only when it gets called.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.