Skip to content

Commit 902b115

Browse files
committed
Fixed panicking on and added Observed signal.
1 parent c7e42fb commit 902b115

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

examples/ui.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn setup(mut commands: Commands) {
103103
))
104104
.spawn_task(move |entity| async move {
105105
let btn = fetch!(#btn_entity);
106-
let mut stream = btn.on::<Pointer<Click>>();
106+
let mut stream = btn.on::<Pointer<Click>>()?;
107107
while let Some(item) = stream.next().await {
108108
let s =
109109
format!("Clicked at {}", item.hit.position.unwrap_or_default().xz());
@@ -115,7 +115,7 @@ fn setup(mut commands: Commands) {
115115
})
116116
.spawn_task(move |entity| async move {
117117
let btn = fetch!(#btn_entity);
118-
let mut stream = btn.on::<Pointer<Pressed>>();
118+
let mut stream = btn.on::<Pointer<Pressed>>()?;
119119
while let Some(item) = stream.next().await {
120120
let s = format!(
121121
"Mouse down at {}",
@@ -129,7 +129,7 @@ fn setup(mut commands: Commands) {
129129
})
130130
.spawn_task(move |entity| async move {
131131
let btn = fetch!(#btn_entity);
132-
let mut stream = btn.on::<Pointer<Over>>();
132+
let mut stream = btn.on::<Pointer<Over>>()?;
133133
while let Some(item) = stream.next().await {
134134
let s = format!(
135135
"Hover entered at {}",
@@ -143,7 +143,7 @@ fn setup(mut commands: Commands) {
143143
})
144144
.spawn_task(move |entity| async move {
145145
let btn = fetch!(#btn_entity);
146-
let mut stream = btn.on::<Pointer<Out>>();
146+
let mut stream = btn.on::<Pointer<Out>>()?;
147147
while let Some(item) = stream.next().await {
148148
let s = format!(
149149
"Hover exited at {}",

src/entity_commands.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::access::AsyncWorld;
22
use crate::executor::{with_world_mut, with_world_ref};
3+
use crate::signals::Observed;
34
use crate::{access::AsyncEntityMut, AccessError, AccessResult};
45
use crate::{AsyncAccess, InspectEntity, OwnedQueryState};
56
use bevy::ecs::bundle::BundleFromComponents;
@@ -344,17 +345,37 @@ impl AsyncEntityMut {
344345
/// # Note
345346
///
346347
/// This function spawns an observer.
347-
pub fn on<T: Event + Clone>(&self) -> impl Stream<Item = T> + 'static {
348+
pub fn on<T: Event + Clone>(&self) -> AccessResult<impl Stream<Item = T> + 'static> {
348349
let entity = self.id();
349350
let (sender, receiver) = flume::unbounded();
351+
AsyncWorld.run(|world| {
352+
world
353+
.get_entity_mut(entity)
354+
.map(|mut entity| {
355+
entity.observe(move |trigger: Trigger<T>| {
356+
let _ = sender.send(trigger.event().clone());
357+
});
358+
})
359+
.map_err(|_| AccessError::EntityNotFound(entity))
360+
})?;
361+
Ok(receiver.into_stream())
362+
}
363+
364+
/// Initialize a signal receiver [`Observed<T>`] on this entity
365+
/// and spawn an observer that feeds into that signal receiver.
366+
///
367+
/// Call [`AsyncEntityMut::signal_receiver`] to read from that signal.
368+
pub fn signal_observe<T: Event + Clone>(&self) -> AccessResult {
369+
let entity = self.id();
370+
let signal = self.signal_receiver::<Observed<T>>()?;
350371
AsyncWorld.run(|world| {
351372
world
352373
.entity_mut(entity)
353374
.observe(move |trigger: Trigger<T>| {
354-
let _ = sender.send(trigger.event().clone());
375+
signal.write(trigger.event().clone());
355376
});
356377
});
357-
receiver.into_stream()
378+
Ok(())
358379
}
359380

360381
/// Returns a future that yields when the entity is despawned.

src/signals/signal_utils.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ impl<T: Clone + Default + Send + Sync + 'static> SignalId for Fac<T> {
4444
type Data = T;
4545
}
4646

47+
/// Standard [`SignalId`] for observed trigger events.
48+
pub struct Observed<T: Clone + Event>(PhantomData<T>, std::convert::Infallible);
49+
50+
impl<T: Clone + Event> SignalId for Observed<T> {
51+
type Data = T;
52+
}
53+
4754
mod sealed {
4855
use std::marker::PhantomData;
4956

@@ -135,4 +142,5 @@ mod sealed {
135142
}
136143
}
137144

145+
use bevy::ecs::event::Event;
138146
pub use sealed::{SignalReceiver, SignalSender};

0 commit comments

Comments
 (0)