1use crate::{
2 AnyView, AnyWindowHandle, AppContext, AsyncApp, DispatchPhase, Effect, EntityId, EventEmitter,
3 FocusHandle, FocusOutEvent, Focusable, Global, Priority, Reservation, Subscription, Task,
4 WeakEntity, WeakFocusHandle, Window, WindowHandle, WindowVisibility,
5};
6use anyhow::Result;
7use futures::FutureExt;
8use gpui_util::Deferred;
9use std::{
10 any::{Any, TypeId},
11 borrow::{Borrow, BorrowMut},
12 future::Future,
13 ops,
14 sync::Arc,
15};
16
17use super::{App, AsyncWindowContext, Entity, KeystrokeEvent};
18
19pub struct Context<'a, T> {
21 app: &'a mut App,
22 entity_state: WeakEntity<T>,
23}
24
25impl<'a, T> ops::Deref for Context<'a, T> {
26 type Target = App;
27
28 fn deref(&self) -> &Self::Target {
29 self.app
30 }
31}
32
33impl<'a, T> ops::DerefMut for Context<'a, T> {
34 fn deref_mut(&mut self) -> &mut Self::Target {
35 self.app
36 }
37}
38
39impl<'a, T: 'static> Context<'a, T> {
40 pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self {
41 Self { app, entity_state }
42 }
43
44 pub fn entity_id(&self) -> EntityId {
46 self.entity_state.entity_id
47 }
48
49 pub fn entity(&self) -> Entity<T> {
51 self.weak_entity()
52 .upgrade()
53 .expect("The entity must be alive if we have a entity context")
54 }
55
56 pub fn weak_entity(&self) -> WeakEntity<T> {
58 self.entity_state.clone()
59 }
60
61 pub fn observe<W>(
64 &mut self,
65 entity: &Entity<W>,
66 mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<T>) + 'static,
67 ) -> Subscription
68 where
69 T: 'static,
70 W: 'static,
71 {
72 let observer = self.weak_entity();
73 self.app.observe_internal(entity, move |entity, cx| {
74 invoke_observer(&observer, entity, cx, &mut on_notify)
75 })
76 }
77
78 pub fn observe_self(
80 &mut self,
81 mut on_event: impl FnMut(&mut T, &mut Context<T>) + 'static,
82 ) -> Subscription
83 where
84 T: 'static,
85 {
86 let this = self.entity();
87 self.app.observe(&this, move |this, cx| {
88 this.update(cx, |this, cx| on_event(this, cx))
89 })
90 }
91
92 pub fn subscribe<T2, Evt>(
94 &mut self,
95 entity: &Entity<T2>,
96 mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<T>) + 'static,
97 ) -> Subscription
98 where
99 T: 'static,
100 T2: 'static + EventEmitter<Evt>,
101 Evt: 'static,
102 {
103 let subscriber = self.weak_entity();
104 self.app
105 .subscribe_internal(entity, move |entity, event, cx| {
106 invoke_subscriber(&subscriber, entity, event, cx, &mut on_event)
107 })
108 }
109
110 pub fn subscribe_self<Evt>(
112 &mut self,
113 mut on_event: impl FnMut(&mut T, &Evt, &mut Context<T>) + 'static,
114 ) -> Subscription
115 where
116 T: 'static + EventEmitter<Evt>,
117 Evt: 'static,
118 {
119 let this = self.entity();
120 self.app.subscribe(&this, move |this, evt, cx| {
121 this.update(cx, |this, cx| on_event(this, evt, cx))
122 })
123 }
124
125 pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription
127 where
128 T: 'static,
129 {
130 self.app.release_listeners.insert(
131 self.entity_state.entity_id,
132 Box::new(move |this, cx| {
133 let this = this.downcast_mut().expect("invalid entity type");
134 on_release(this, cx);
135 }),
136 )
137 }
138
139 pub fn observe_release<T2>(
141 &self,
142 entity: &Entity<T2>,
143 on_release: impl FnOnce(&mut T, &mut T2, &mut Context<T>) + 'static,
144 ) -> Subscription
145 where
146 T: Any,
147 T2: 'static,
148 {
149 let entity_id = entity.entity_id();
150 let this = self.weak_entity();
151 self.app.release_listeners.insert(
152 entity_id,
153 Box::new(move |entity, cx| {
154 let entity = entity.downcast_mut().expect("invalid entity type");
155 if let Some(this) = this.upgrade() {
156 this.update(cx, |this, cx| on_release(this, entity, cx));
157 }
158 }),
159 )
160 }
161
162 pub fn observe_global<G: 'static>(
164 &mut self,
165 mut f: impl FnMut(&mut T, &mut Context<T>) + 'static,
166 ) -> Subscription
167 where
168 T: 'static,
169 {
170 let handle = self.weak_entity();
171 let (subscription, activate) = self.global_observers.insert_pending(
172 TypeId::of::<G>(),
173 Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()),
174 );
175 self.defer(move |_| activate());
176 subscription
177 }
178
179 pub fn on_app_restart(
181 &self,
182 mut on_restart: impl FnMut(&mut T, &mut App) + 'static,
183 ) -> Subscription
184 where
185 T: 'static,
186 {
187 let handle = self.weak_entity();
188 self.app.on_app_restart(move |cx| {
189 handle.update(cx, |entity, cx| on_restart(entity, cx)).ok();
190 })
191 }
192
193 pub fn on_app_quit<Fut>(
196 &self,
197 mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static,
198 ) -> Subscription
199 where
200 Fut: 'static + Future<Output = ()>,
201 T: 'static,
202 {
203 let handle = self.weak_entity();
204 self.app.on_app_quit(move |cx| {
205 let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok();
206 async move {
207 if let Some(future) = future {
208 future.await;
209 }
210 }
211 .boxed_local()
212 })
213 }
214
215 pub fn notify(&mut self) {
217 self.app.notify(self.entity_state.entity_id);
218 }
219
220 #[track_caller]
224 #[inline(always)]
225 pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
226 where
227 T: 'static,
228 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncApp) -> R + 'static,
229 R: 'static,
230 {
231 let this = self.weak_entity();
232 self.app.spawn(async move |cx| f(this, cx).await)
233 }
234
235 #[inline(always)]
241 pub fn listener<E: ?Sized>(
242 &self,
243 listener: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static,
244 ) -> impl Fn(&E, &mut Window, &mut App) + 'static {
245 let view = self.entity().downgrade();
246 move |event: &E, window: &mut Window, cx: &mut App| {
247 invoke_listener(&view, window, cx, &|view, window, cx| {
248 listener(view, event, window, cx);
249 });
250 }
251 }
252
253 pub fn processor<E, R>(
256 &self,
257 f: impl Fn(&mut T, E, &mut Window, &mut Context<T>) -> R + 'static,
258 ) -> impl Fn(E, &mut Window, &mut App) -> R + 'static {
259 let view = self.entity();
260 move |e: E, window: &mut Window, cx: &mut App| {
261 view.update(cx, |view, cx| f(view, e, window, cx))
262 }
263 }
264
265 pub fn on_drop(
267 &self,
268 f: impl FnOnce(&mut T, &mut Context<T>) + 'static,
269 ) -> Deferred<impl FnOnce()> {
270 let this = self.weak_entity();
271 let mut cx = self.to_async();
272 gpui_util::defer(move || {
273 this.update(&mut cx, f).ok();
274 })
275 }
276
277 pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) {
279 window.focus(&view.focus_handle(self), self);
280 }
281
282 pub fn on_next_frame(
284 &self,
285 window: &mut Window,
286 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
287 ) where
288 T: 'static,
289 {
290 let view = self.entity();
291 window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx)));
292 }
293
294 pub fn defer_in(
297 &mut self,
298 window: &Window,
299 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
300 ) {
301 let view = self.weak_entity();
302 let entity_id = self.entity_id();
303 self.ensure_window(entity_id, window.handle.id);
304 self.app.defer(move |cx| {
305 cx.with_window(entity_id, |window, cx| {
306 view.update(cx, |view, cx| f(view, window, cx)).ok();
307 });
308 });
309 }
310
311 pub fn observe_in<V2>(
313 &mut self,
314 observed: &Entity<V2>,
315 window: &mut Window,
316 mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<T>) + 'static,
317 ) -> Subscription
318 where
319 V2: 'static,
320 T: 'static,
321 {
322 let observed_id = observed.entity_id();
323 let observed = observed.downgrade();
324 let observer = self.weak_entity();
325 let observer_id = self.entity_id();
326 self.ensure_window(observer_id, window.handle.id);
327 self.new_observer(
328 observed_id,
329 Box::new(move |cx| invoke_observer_in(&observer, &observed, cx, &mut on_notify)),
330 )
331 }
332
333 pub fn subscribe_in<Emitter, Evt>(
337 &mut self,
338 emitter: &Entity<Emitter>,
339 window: &Window,
340 mut on_event: impl FnMut(&mut T, &Entity<Emitter>, &Evt, &mut Window, &mut Context<T>) + 'static,
341 ) -> Subscription
342 where
343 Emitter: EventEmitter<Evt>,
344 Evt: 'static,
345 {
346 let emitter = emitter.downgrade();
347 let subscriber = self.weak_entity();
348 let subscriber_id = self.entity_id();
349 self.ensure_window(subscriber_id, window.handle.id);
350 self.new_subscription(
351 emitter.entity_id(),
352 (
353 TypeId::of::<Evt>(),
354 Box::new(move |event, cx| {
355 invoke_subscriber_in(&subscriber, &emitter, event, cx, &mut on_event)
356 }),
357 ),
358 )
359 }
360
361 pub fn on_release_in(
366 &mut self,
367 window: &Window,
368 on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
369 ) -> Subscription {
370 let entity = self.entity();
371 self.app.observe_release_in(&entity, window, on_release)
372 }
373
374 pub fn observe_release_in<T2>(
376 &self,
377 observed: &Entity<T2>,
378 window: &Window,
379 mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static,
380 ) -> Subscription
381 where
382 T: 'static,
383 T2: 'static,
384 {
385 let observer = self.weak_entity();
386 self.app
387 .observe_release_in(observed, window, move |observed, window, cx| {
388 observer
389 .update(cx, |observer, cx| {
390 on_release(observer, observed, window, cx)
391 })
392 .ok();
393 })
394 }
395
396 pub fn observe_window_bounds(
398 &self,
399 window: &mut Window,
400 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
401 ) -> Subscription {
402 let view = self.weak_entity();
403 window.bounds_observers.insert(Box::new(move |window, cx| {
404 view.update(cx, |view, cx| callback(view, window, cx))
405 .is_ok()
406 }))
407 }
408
409 pub fn observe_window_activation(
411 &self,
412 window: &mut Window,
413 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
414 ) -> Subscription {
415 let view = self.weak_entity();
416 window
417 .activation_observers
418 .insert(Box::new(move |window, cx| {
419 view.update(cx, |view, cx| callback(view, window, cx))
420 .is_ok()
421 }))
422 }
423
424 pub fn observe_window_visibility(
427 &self,
428 window: &mut Window,
429 mut callback: impl FnMut(&mut T, WindowVisibility, &mut Window, &mut Context<T>) + 'static,
430 ) -> Subscription {
431 let view = self.weak_entity();
432 window
433 .visibility_observers
434 .insert(Box::new(move |visibility, window, cx| {
435 view.update(cx, |view, cx| callback(view, visibility, window, cx))
436 .is_ok()
437 }))
438 }
439
440 pub fn observe_window_appearance(
442 &self,
443 window: &mut Window,
444 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
445 ) -> Subscription {
446 let view = self.weak_entity();
447 window
448 .appearance_observers
449 .insert(Box::new(move |window, cx| {
450 view.update(cx, |view, cx| callback(view, window, cx))
451 .is_ok()
452 }))
453 }
454
455 pub fn observe_window_display(
459 &self,
460 window: &mut Window,
461 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
462 ) -> Subscription {
463 let view = self.weak_entity();
464 window.display_observers.insert(Box::new(move |window, cx| {
465 view.update(cx, |view, cx| callback(view, window, cx))
466 .is_ok()
467 }))
468 }
469
470 pub fn observe_button_layout_changed(
472 &self,
473 window: &mut Window,
474 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
475 ) -> Subscription {
476 let view = self.weak_entity();
477 window
478 .button_layout_observers
479 .insert(Box::new(move |window, cx| {
480 view.update(cx, |view, cx| callback(view, window, cx))
481 .is_ok()
482 }))
483 }
484
485 pub fn observe_keystrokes(
487 &mut self,
488 mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static,
489 ) -> Subscription {
490 let view = self.weak_entity();
491 self.keystroke_observers
492 .insert(Box::new(move |event, window, cx| {
493 if let Some(view) = view.upgrade() {
494 view.update(cx, |view, cx| f(view, event, window, cx));
495 true
496 } else {
497 false
498 }
499 }))
500 }
501
502 pub fn observe_pending_input(
504 &self,
505 window: &mut Window,
506 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
507 ) -> Subscription {
508 let view = self.weak_entity();
509 window
510 .pending_input_observers
511 .insert(Box::new(move |window, cx| {
512 view.update(cx, |view, cx| callback(view, window, cx))
513 .is_ok()
514 }))
515 }
516
517 pub fn on_focus(
520 &mut self,
521 handle: &FocusHandle,
522 window: &mut Window,
523 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
524 ) -> Subscription {
525 let view = self.weak_entity();
526 let focus_id = handle.id;
527 let (subscription, activate) =
528 window.new_focus_listener(Box::new(move |event, window, cx| {
529 view.update(cx, |view, cx| {
530 if event.previous_focus_path.last() != Some(&focus_id)
531 && event.current_focus_path.last() == Some(&focus_id)
532 {
533 listener(view, window, cx)
534 }
535 })
536 .is_ok()
537 }));
538 self.defer(|_| activate());
539 subscription
540 }
541
542 pub fn on_focus_in(
546 &mut self,
547 handle: &FocusHandle,
548 window: &mut Window,
549 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
550 ) -> Subscription {
551 let view = self.weak_entity();
552 let focus_id = handle.id;
553 let (subscription, activate) =
554 window.new_focus_listener(Box::new(move |event, window, cx| {
555 view.update(cx, |view, cx| {
556 if event.is_focus_in(focus_id) {
557 listener(view, window, cx)
558 }
559 })
560 .is_ok()
561 }));
562 self.defer(|_| activate());
563 subscription
564 }
565
566 pub fn on_blur(
569 &mut self,
570 handle: &FocusHandle,
571 window: &mut Window,
572 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
573 ) -> Subscription {
574 let view = self.weak_entity();
575 let focus_id = handle.id;
576 let (subscription, activate) =
577 window.new_focus_listener(Box::new(move |event, window, cx| {
578 view.update(cx, |view, cx| {
579 if event.previous_focus_path.last() == Some(&focus_id)
580 && event.current_focus_path.last() != Some(&focus_id)
581 {
582 listener(view, window, cx)
583 }
584 })
585 .is_ok()
586 }));
587 self.defer(|_| activate());
588 subscription
589 }
590
591 pub fn on_focus_lost(
596 &mut self,
597 window: &mut Window,
598 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
599 ) -> Subscription {
600 let view = self.weak_entity();
601 let (subscription, activate) =
602 window
603 .focus_lost_listeners
604 .insert_pending(Box::new(move |window, cx| {
605 view.update(cx, |view, cx| listener(view, window, cx))
606 .is_ok()
607 }));
608 self.defer(|_| activate());
609 subscription
610 }
611
612 pub fn on_focus_out(
615 &mut self,
616 handle: &FocusHandle,
617 window: &mut Window,
618 mut listener: impl FnMut(&mut T, FocusOutEvent, &mut Window, &mut Context<T>) + 'static,
619 ) -> Subscription {
620 let view = self.weak_entity();
621 let focus_id = handle.id;
622 let (subscription, activate) =
623 window.new_focus_listener(Box::new(move |event, window, cx| {
624 view.update(cx, |view, cx| {
625 if let Some(blurred_id) = event.previous_focus_path.last().copied()
626 && event.is_focus_out(focus_id)
627 {
628 let event = FocusOutEvent {
629 blurred: WeakFocusHandle {
630 id: blurred_id,
631 handles: Arc::downgrade(&cx.focus_handles),
632 },
633 };
634 listener(view, event, window, cx)
635 }
636 })
637 .is_ok()
638 }));
639 self.defer(|_| activate());
640 subscription
641 }
642
643 #[track_caller]
648 #[inline(always)]
649 pub fn spawn_in<AsyncFn, R>(&self, window: &Window, f: AsyncFn) -> Task<R>
650 where
651 R: 'static,
652 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
653 {
654 let view = self.weak_entity();
655 window.spawn(self, async move |cx| f(view, cx).await)
656 }
657
658 #[track_caller]
663 #[inline(always)]
664 pub fn spawn_in_with_priority<AsyncFn, R>(
665 &self,
666 priority: Priority,
667 window: &Window,
668 f: AsyncFn,
669 ) -> Task<R>
670 where
671 R: 'static,
672 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
673 {
674 let view = self.weak_entity();
675 window.spawn_with_priority(priority, self, async move |cx| f(view, cx).await)
676 }
677
678 pub fn observe_global_in<G: Global>(
680 &mut self,
681 window: &Window,
682 mut f: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
683 ) -> Subscription {
684 let window_handle = window.handle;
685 let view = self.weak_entity();
686 let (subscription, activate) = self.global_observers.insert_pending(
687 TypeId::of::<G>(),
688 Box::new(move |cx| {
689 if view.upgrade().is_none() {
691 return false;
692 }
693 let Ok(entity_alive) = window_handle.update(cx, |_, window, cx| {
697 view.update(cx, |view, cx| f(view, window, cx)).is_ok()
698 }) else {
699 return true;
700 };
701 entity_alive
702 }),
703 );
704 self.defer(move |_| activate());
705 subscription
706 }
707
708 pub fn on_action(
710 &mut self,
711 action_type: TypeId,
712 window: &mut Window,
713 listener: impl Fn(&mut T, &dyn Any, DispatchPhase, &mut Window, &mut Context<T>) + 'static,
714 ) {
715 let handle = self.weak_entity();
716 window.on_action(action_type, move |action, phase, window, cx| {
717 handle
718 .update(cx, |view, cx| {
719 listener(view, action, phase, window, cx);
720 })
721 .ok();
722 });
723 }
724
725 pub fn focus_self(&mut self, window: &mut Window)
727 where
728 T: Focusable,
729 {
730 let view = self.entity();
731 window.defer(self, move |window, cx| {
732 view.read(cx).focus_handle(cx).focus(window, cx)
733 })
734 }
735}
736
737impl<T> Context<'_, T> {
738 pub fn emit<Evt>(&mut self, event: Evt)
740 where
741 T: EventEmitter<Evt>,
742 Evt: 'static,
743 {
744 let event = self
745 .event_arena
746 .alloc(|| event)
747 .map(|it| it as &mut dyn Any);
748 self.app.pending_effects.push_back(Effect::Emit {
749 emitter: self.entity_state.entity_id,
750 event_type: TypeId::of::<Evt>(),
751 event,
752 });
753 }
754}
755
756impl<T> AppContext for Context<'_, T> {
757 #[inline]
758 fn new<U: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<U>) -> U) -> Entity<U> {
759 self.app.new(build_entity)
760 }
761
762 #[inline]
763 fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
764 self.app.reserve_entity()
765 }
766
767 #[inline]
768 fn insert_entity<U: 'static>(
769 &mut self,
770 reservation: Reservation<U>,
771 build_entity: impl FnOnce(&mut Context<U>) -> U,
772 ) -> Entity<U> {
773 self.app.insert_entity(reservation, build_entity)
774 }
775
776 #[inline]
777 fn update_entity<U: 'static, R>(
778 &mut self,
779 handle: &Entity<U>,
780 update: impl FnOnce(&mut U, &mut Context<U>) -> R,
781 ) -> R {
782 self.app.update_entity(handle, update)
783 }
784
785 #[inline]
786 fn as_mut<'a, E>(&'a mut self, handle: &Entity<E>) -> super::GpuiBorrow<'a, E>
787 where
788 E: 'static,
789 {
790 self.app.as_mut(handle)
791 }
792
793 #[inline]
794 fn read_entity<U, R>(&self, handle: &Entity<U>, read: impl FnOnce(&U, &App) -> R) -> R
795 where
796 U: 'static,
797 {
798 self.app.read_entity(handle, read)
799 }
800
801 #[inline]
802 fn update_window<R, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<R>
803 where
804 F: FnOnce(AnyView, &mut Window, &mut App) -> R,
805 {
806 self.app.update_window(window, update)
807 }
808
809 #[inline]
810 fn with_window<R>(
811 &mut self,
812 entity_id: EntityId,
813 f: impl FnOnce(&mut Window, &mut App) -> R,
814 ) -> Option<R> {
815 self.app.with_window(entity_id, f)
816 }
817
818 #[inline]
819 fn read_window<U, R>(
820 &self,
821 window: &WindowHandle<U>,
822 read: impl FnOnce(Entity<U>, &App) -> R,
823 ) -> Result<R>
824 where
825 U: 'static,
826 {
827 self.app.read_window(window, read)
828 }
829
830 #[inline]
831 fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
832 where
833 R: Send + 'static,
834 {
835 self.app.background_executor.spawn(future)
836 }
837
838 #[inline]
839 fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> R
840 where
841 G: Global,
842 {
843 self.app.read_global(callback)
844 }
845}
846
847impl<T> Borrow<App> for Context<'_, T> {
848 fn borrow(&self) -> &App {
849 self.app
850 }
851}
852
853impl<T> BorrowMut<App> for Context<'_, T> {
854 fn borrow_mut(&mut self) -> &mut App {
855 self.app
856 }
857}
858
859#[inline(never)]
860fn invoke_observer<T: 'static, W: 'static>(
861 observer: &WeakEntity<T>,
862 observed: Entity<W>,
863 cx: &mut App,
864 on_notify: &mut dyn FnMut(&mut T, Entity<W>, &mut Context<T>),
865) -> bool {
866 if let Some(observer) = observer.upgrade() {
867 observer.update(cx, |observer, cx| on_notify(observer, observed, cx));
868 true
869 } else {
870 false
871 }
872}
873
874#[inline(never)]
875fn invoke_subscriber<T: 'static, Emitter: 'static, Event: 'static>(
876 subscriber: &WeakEntity<T>,
877 emitter: Entity<Emitter>,
878 event: &Event,
879 cx: &mut App,
880 on_event: &mut dyn FnMut(&mut T, Entity<Emitter>, &Event, &mut Context<T>),
881) -> bool {
882 if let Some(subscriber) = subscriber.upgrade() {
883 subscriber.update(cx, |subscriber, cx| {
884 on_event(subscriber, emitter, event, cx)
885 });
886 true
887 } else {
888 false
889 }
890}
891
892#[inline(never)]
893fn invoke_observer_in<T: 'static, W: 'static>(
894 observer: &WeakEntity<T>,
895 observed: &WeakEntity<W>,
896 cx: &mut App,
897 on_notify: &mut dyn FnMut(&mut T, Entity<W>, &mut Window, &mut Context<T>),
898) -> bool {
899 let Some((observer, observed)) = observer.upgrade().zip(observed.upgrade()) else {
900 return false;
901 };
902 cx.with_window(observer.entity_id(), |window, cx| {
903 observer.update(cx, |observer, cx| {
904 on_notify(observer, observed, window, cx);
905 });
906 });
907 true
908}
909
910#[inline(never)]
911fn invoke_subscriber_in<T: 'static, Emitter: 'static, Event: 'static>(
912 subscriber: &WeakEntity<T>,
913 emitter: &WeakEntity<Emitter>,
914 event: &dyn Any,
915 cx: &mut App,
916 on_event: &mut dyn FnMut(&mut T, &Entity<Emitter>, &Event, &mut Window, &mut Context<T>),
917) -> bool {
918 let Some((subscriber, emitter)) = subscriber.upgrade().zip(emitter.upgrade()) else {
919 return false;
920 };
921 let event = event.downcast_ref().expect("invalid event type");
922 cx.with_window(subscriber.entity_id(), |window, cx| {
923 subscriber.update(cx, |subscriber, cx| {
924 on_event(subscriber, &emitter, event, window, cx);
925 });
926 });
927 true
928}
929
930#[inline(never)]
931fn invoke_listener<T: 'static>(
932 view: &WeakEntity<T>,
933 window: &mut Window,
934 cx: &mut App,
935 listener: &dyn Fn(&mut T, &mut Window, &mut Context<T>),
936) {
937 view.update(cx, |view, cx| listener(view, window, cx)).ok();
938}