1pub mod action;
2mod callback_collection;
3mod menu;
4pub(crate) mod ref_counts;
5#[cfg(any(test, feature = "test-support"))]
6pub mod test_app_context;
7pub(crate) mod window;
8mod window_input_handler;
9
10use std::{
11 any::{type_name, Any, TypeId},
12 cell::RefCell,
13 fmt::{self, Debug},
14 hash::{Hash, Hasher},
15 marker::PhantomData,
16 mem,
17 ops::{Deref, DerefMut, Range},
18 path::{Path, PathBuf},
19 pin::Pin,
20 rc::{self, Rc},
21 sync::{Arc, Weak},
22 time::Duration,
23};
24
25use anyhow::{anyhow, Context, Result};
26use parking_lot::Mutex;
27use postage::oneshot;
28use smol::prelude::*;
29use util::ResultExt;
30use uuid::Uuid;
31
32pub use action::*;
33use callback_collection::CallbackCollection;
34use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque};
35pub use menu::*;
36use platform::Event;
37#[cfg(any(test, feature = "test-support"))]
38use ref_counts::LeakDetector;
39#[cfg(any(test, feature = "test-support"))]
40pub use test_app_context::{ContextHandle, TestAppContext};
41use window_input_handler::WindowInputHandler;
42
43use crate::{
44 elements::{AnyElement, AnyRootElement, RootElement},
45 executor::{self, Task},
46 keymap_matcher::{self, Binding, KeymapContext, KeymapMatcher, Keystroke, MatchResult},
47 platform::{
48 self, FontSystem, KeyDownEvent, KeyUpEvent, ModifiersChangedEvent, MouseButton,
49 PathPromptOptions, Platform, PromptLevel, WindowBounds, WindowOptions,
50 },
51 util::post_inc,
52 window::{Window, WindowContext},
53 AssetCache, AssetSource, ClipboardItem, FontCache, MouseRegionId,
54};
55
56use self::ref_counts::RefCounts;
57
58pub trait Entity: 'static {
59 type Event;
60
61 fn release(&mut self, _: &mut AppContext) {}
62 fn app_will_quit(
63 &mut self,
64 _: &mut AppContext,
65 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
66 None
67 }
68}
69
70pub trait View: Entity + Sized {
71 fn ui_name() -> &'static str;
72 fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> AnyElement<Self>;
73 fn focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
74 fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
75 fn key_down(&mut self, _: &KeyDownEvent, _: &mut ViewContext<Self>) -> bool {
76 false
77 }
78 fn key_up(&mut self, _: &KeyUpEvent, _: &mut ViewContext<Self>) -> bool {
79 false
80 }
81 fn modifiers_changed(&mut self, _: &ModifiersChangedEvent, _: &mut ViewContext<Self>) -> bool {
82 false
83 }
84
85 fn keymap_context(&self, _: &AppContext) -> keymap_matcher::KeymapContext {
86 Self::default_keymap_context()
87 }
88 fn default_keymap_context() -> keymap_matcher::KeymapContext {
89 let mut cx = keymap_matcher::KeymapContext::default();
90 cx.add_identifier(Self::ui_name());
91 cx
92 }
93 fn debug_json(&self, _: &AppContext) -> serde_json::Value {
94 serde_json::Value::Null
95 }
96
97 fn text_for_range(&self, _: Range<usize>, _: &AppContext) -> Option<String> {
98 None
99 }
100 fn selected_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
101 None
102 }
103 fn marked_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
104 None
105 }
106 fn unmark_text(&mut self, _: &mut ViewContext<Self>) {}
107 fn replace_text_in_range(
108 &mut self,
109 _: Option<Range<usize>>,
110 _: &str,
111 _: &mut ViewContext<Self>,
112 ) {
113 }
114 fn replace_and_mark_text_in_range(
115 &mut self,
116 _: Option<Range<usize>>,
117 _: &str,
118 _: Option<Range<usize>>,
119 _: &mut ViewContext<Self>,
120 ) {
121 }
122}
123
124pub trait ReadModel {
125 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
126}
127
128pub trait ReadModelWith {
129 fn read_model_with<E: Entity, T>(
130 &self,
131 handle: &ModelHandle<E>,
132 read: &mut dyn FnMut(&E, &AppContext) -> T,
133 ) -> T;
134}
135
136pub trait UpdateModel {
137 fn update_model<T: Entity, O>(
138 &mut self,
139 handle: &ModelHandle<T>,
140 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
141 ) -> O;
142}
143
144pub trait UpgradeModelHandle {
145 fn upgrade_model_handle<T: Entity>(
146 &self,
147 handle: &WeakModelHandle<T>,
148 ) -> Option<ModelHandle<T>>;
149
150 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool;
151
152 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle>;
153}
154
155pub trait UpgradeViewHandle {
156 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>>;
157
158 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle>;
159}
160
161pub trait ReadView {
162 fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
163}
164
165pub trait ReadViewWith {
166 fn read_view_with<V, T>(
167 &self,
168 handle: &ViewHandle<V>,
169 read: &mut dyn FnMut(&V, &AppContext) -> T,
170 ) -> T
171 where
172 V: View;
173}
174
175pub trait UpdateView {
176 type Output<S>;
177
178 fn update_view<T, S>(
179 &mut self,
180 handle: &ViewHandle<T>,
181 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
182 ) -> Self::Output<S>
183 where
184 T: View;
185}
186
187#[derive(Clone)]
188pub struct App(Rc<RefCell<AppContext>>);
189
190#[derive(Clone)]
191pub struct AsyncAppContext(Rc<RefCell<AppContext>>);
192
193impl App {
194 pub fn new(asset_source: impl AssetSource) -> Result<Self> {
195 let platform = platform::current::platform();
196 let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
197 let foreground_platform = platform::current::foreground_platform(foreground.clone());
198 let app = Self(Rc::new(RefCell::new(AppContext::new(
199 foreground,
200 Arc::new(executor::Background::new()),
201 platform.clone(),
202 foreground_platform.clone(),
203 Arc::new(FontCache::new(platform.fonts())),
204 Default::default(),
205 asset_source,
206 ))));
207
208 foreground_platform.on_quit(Box::new({
209 let cx = app.0.clone();
210 move || {
211 cx.borrow_mut().quit();
212 }
213 }));
214 setup_menu_handlers(foreground_platform.as_ref(), &app);
215
216 app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
217 Ok(app)
218 }
219
220 pub fn background(&self) -> Arc<executor::Background> {
221 self.0.borrow().background().clone()
222 }
223
224 pub fn on_become_active<F>(self, mut callback: F) -> Self
225 where
226 F: 'static + FnMut(&mut AppContext),
227 {
228 let cx = self.0.clone();
229 self.0
230 .borrow_mut()
231 .foreground_platform
232 .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
233 self
234 }
235
236 pub fn on_resign_active<F>(self, mut callback: F) -> Self
237 where
238 F: 'static + FnMut(&mut AppContext),
239 {
240 let cx = self.0.clone();
241 self.0
242 .borrow_mut()
243 .foreground_platform
244 .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
245 self
246 }
247
248 pub fn on_quit<F>(&mut self, mut callback: F) -> &mut Self
249 where
250 F: 'static + FnMut(&mut AppContext),
251 {
252 let cx = self.0.clone();
253 self.0
254 .borrow_mut()
255 .foreground_platform
256 .on_quit(Box::new(move || callback(&mut *cx.borrow_mut())));
257 self
258 }
259
260 /// Handle the application being re-activated when no windows are open.
261 pub fn on_reopen<F>(&mut self, mut callback: F) -> &mut Self
262 where
263 F: 'static + FnMut(&mut AppContext),
264 {
265 let cx = self.0.clone();
266 self.0
267 .borrow_mut()
268 .foreground_platform
269 .on_reopen(Box::new(move || callback(&mut *cx.borrow_mut())));
270 self
271 }
272
273 pub fn on_event<F>(&mut self, mut callback: F) -> &mut Self
274 where
275 F: 'static + FnMut(Event, &mut AppContext) -> bool,
276 {
277 let cx = self.0.clone();
278 self.0
279 .borrow_mut()
280 .foreground_platform
281 .on_event(Box::new(move |event| {
282 callback(event, &mut *cx.borrow_mut())
283 }));
284 self
285 }
286
287 pub fn on_open_urls<F>(&mut self, mut callback: F) -> &mut Self
288 where
289 F: 'static + FnMut(Vec<String>, &mut AppContext),
290 {
291 let cx = self.0.clone();
292 self.0
293 .borrow_mut()
294 .foreground_platform
295 .on_open_urls(Box::new(move |urls| callback(urls, &mut *cx.borrow_mut())));
296 self
297 }
298
299 pub fn run<F>(self, on_finish_launching: F)
300 where
301 F: 'static + FnOnce(&mut AppContext),
302 {
303 let platform = self.0.borrow().foreground_platform.clone();
304 platform.run(Box::new(move || {
305 let mut cx = self.0.borrow_mut();
306 let cx = &mut *cx;
307 crate::views::init(cx);
308 on_finish_launching(cx);
309 }))
310 }
311
312 pub fn platform(&self) -> Arc<dyn Platform> {
313 self.0.borrow().platform.clone()
314 }
315
316 pub fn font_cache(&self) -> Arc<FontCache> {
317 self.0.borrow().font_cache.clone()
318 }
319
320 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, callback: F) -> T {
321 let mut state = self.0.borrow_mut();
322 let result = state.update(callback);
323 state.pending_notifications.clear();
324 result
325 }
326
327 fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
328 &mut self,
329 window_id: usize,
330 callback: F,
331 ) -> Option<T> {
332 let mut state = self.0.borrow_mut();
333 let result = state.update_window(window_id, callback);
334 state.pending_notifications.clear();
335 result
336 }
337}
338
339impl AsyncAppContext {
340 pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
341 where
342 F: FnOnce(AsyncAppContext) -> Fut,
343 Fut: 'static + Future<Output = T>,
344 T: 'static,
345 {
346 self.0.borrow().foreground.spawn(f(self.clone()))
347 }
348
349 pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
350 callback(&*self.0.borrow())
351 }
352
353 pub fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, callback: F) -> T {
354 self.0.borrow_mut().update(callback)
355 }
356
357 pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
358 &mut self,
359 window_id: usize,
360 callback: F,
361 ) -> Option<T> {
362 self.0.borrow_mut().update_window(window_id, callback)
363 }
364
365 pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
366 where
367 T: Entity,
368 F: FnOnce(&mut ModelContext<T>) -> T,
369 {
370 self.update(|cx| cx.add_model(build_model))
371 }
372
373 pub fn add_window<T, F>(
374 &mut self,
375 window_options: WindowOptions,
376 build_root_view: F,
377 ) -> (usize, ViewHandle<T>)
378 where
379 T: View,
380 F: FnOnce(&mut ViewContext<T>) -> T,
381 {
382 self.update(|cx| cx.add_window(window_options, build_root_view))
383 }
384
385 pub fn remove_window(&mut self, window_id: usize) {
386 self.update(|cx| cx.remove_window(window_id))
387 }
388
389 pub fn activate_window(&mut self, window_id: usize) {
390 self.update_window(window_id, |cx| cx.activate_window());
391 }
392
393 // TODO: Can we eliminate this method and move it to WindowContext then call it with update_window?s
394 pub fn prompt(
395 &mut self,
396 window_id: usize,
397 level: PromptLevel,
398 msg: &str,
399 answers: &[&str],
400 ) -> Option<oneshot::Receiver<usize>> {
401 self.update_window(window_id, |cx| cx.prompt(level, msg, answers))
402 }
403
404 pub fn platform(&self) -> Arc<dyn Platform> {
405 self.0.borrow().platform().clone()
406 }
407
408 pub fn foreground(&self) -> Rc<executor::Foreground> {
409 self.0.borrow().foreground.clone()
410 }
411
412 pub fn background(&self) -> Arc<executor::Background> {
413 self.0.borrow().background.clone()
414 }
415}
416
417impl UpdateModel for AsyncAppContext {
418 fn update_model<E: Entity, O>(
419 &mut self,
420 handle: &ModelHandle<E>,
421 update: &mut dyn FnMut(&mut E, &mut ModelContext<E>) -> O,
422 ) -> O {
423 self.0.borrow_mut().update_model(handle, update)
424 }
425}
426
427impl UpgradeModelHandle for AsyncAppContext {
428 fn upgrade_model_handle<T: Entity>(
429 &self,
430 handle: &WeakModelHandle<T>,
431 ) -> Option<ModelHandle<T>> {
432 self.0.borrow().upgrade_model_handle(handle)
433 }
434
435 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
436 self.0.borrow().model_handle_is_upgradable(handle)
437 }
438
439 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
440 self.0.borrow().upgrade_any_model_handle(handle)
441 }
442}
443
444impl UpgradeViewHandle for AsyncAppContext {
445 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
446 self.0.borrow_mut().upgrade_view_handle(handle)
447 }
448
449 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
450 self.0.borrow_mut().upgrade_any_view_handle(handle)
451 }
452}
453
454impl ReadModelWith for AsyncAppContext {
455 fn read_model_with<E: Entity, T>(
456 &self,
457 handle: &ModelHandle<E>,
458 read: &mut dyn FnMut(&E, &AppContext) -> T,
459 ) -> T {
460 let cx = self.0.borrow();
461 let cx = &*cx;
462 read(handle.read(cx), cx)
463 }
464}
465
466impl UpdateView for AsyncAppContext {
467 type Output<S> = Result<S>;
468
469 fn update_view<T, S>(
470 &mut self,
471 handle: &ViewHandle<T>,
472 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
473 ) -> Result<S>
474 where
475 T: View,
476 {
477 self.0
478 .borrow_mut()
479 .update_window(handle.window_id, |cx| cx.update_view(handle, update))
480 .ok_or_else(|| anyhow!("window was closed"))
481 }
482}
483
484impl ReadViewWith for AsyncAppContext {
485 fn read_view_with<V, T>(
486 &self,
487 handle: &ViewHandle<V>,
488 read: &mut dyn FnMut(&V, &AppContext) -> T,
489 ) -> T
490 where
491 V: View,
492 {
493 let cx = self.0.borrow();
494 let cx = &*cx;
495 read(handle.read(cx), cx)
496 }
497}
498
499type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut WindowContext, usize);
500type GlobalActionCallback = dyn FnMut(&dyn Action, &mut AppContext);
501
502type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut AppContext) -> bool>;
503type GlobalSubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut AppContext)>;
504type ObservationCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
505type GlobalObservationCallback = Box<dyn FnMut(&mut AppContext)>;
506type FocusObservationCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
507type ReleaseObservationCallback = Box<dyn FnMut(&dyn Any, &mut AppContext)>;
508type ActionObservationCallback = Box<dyn FnMut(TypeId, &mut AppContext)>;
509type WindowActivationCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
510type WindowFullscreenCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
511type WindowBoundsCallback = Box<dyn FnMut(WindowBounds, Uuid, &mut WindowContext) -> bool>;
512type KeystrokeCallback =
513 Box<dyn FnMut(&Keystroke, &MatchResult, Option<&Box<dyn Action>>, &mut WindowContext) -> bool>;
514type ActiveLabeledTasksCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
515type DeserializeActionCallback = fn(json: &str) -> anyhow::Result<Box<dyn Action>>;
516type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
517
518pub struct AppContext {
519 models: HashMap<usize, Box<dyn AnyModel>>,
520 views: HashMap<(usize, usize), Box<dyn AnyView>>,
521 pub(crate) parents: HashMap<(usize, usize), ParentId>,
522 windows: HashMap<usize, Window>,
523 globals: HashMap<TypeId, Box<dyn Any>>,
524 element_states: HashMap<ElementStateId, Box<dyn Any>>,
525 background: Arc<executor::Background>,
526 ref_counts: Arc<Mutex<RefCounts>>,
527
528 weak_self: Option<rc::Weak<RefCell<Self>>>,
529 platform: Arc<dyn Platform>,
530 foreground_platform: Rc<dyn platform::ForegroundPlatform>,
531 pub asset_cache: Arc<AssetCache>,
532 font_system: Arc<dyn FontSystem>,
533 pub font_cache: Arc<FontCache>,
534 action_deserializers: HashMap<&'static str, (TypeId, DeserializeActionCallback)>,
535 capture_actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
536 // Entity Types -> { Action Types -> Action Handlers }
537 actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
538 // Action Types -> Action Handlers
539 global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
540 keystroke_matcher: KeymapMatcher,
541 next_entity_id: usize,
542 next_window_id: usize,
543 next_subscription_id: usize,
544 frame_count: usize,
545
546 subscriptions: CallbackCollection<usize, SubscriptionCallback>,
547 global_subscriptions: CallbackCollection<TypeId, GlobalSubscriptionCallback>,
548 observations: CallbackCollection<usize, ObservationCallback>,
549 global_observations: CallbackCollection<TypeId, GlobalObservationCallback>,
550 focus_observations: CallbackCollection<usize, FocusObservationCallback>,
551 release_observations: CallbackCollection<usize, ReleaseObservationCallback>,
552 action_dispatch_observations: CallbackCollection<(), ActionObservationCallback>,
553 window_activation_observations: CallbackCollection<usize, WindowActivationCallback>,
554 window_fullscreen_observations: CallbackCollection<usize, WindowFullscreenCallback>,
555 window_bounds_observations: CallbackCollection<usize, WindowBoundsCallback>,
556 keystroke_observations: CallbackCollection<usize, KeystrokeCallback>,
557 active_labeled_task_observations: CallbackCollection<(), ActiveLabeledTasksCallback>,
558
559 foreground: Rc<executor::Foreground>,
560 pending_effects: VecDeque<Effect>,
561 pending_notifications: HashSet<usize>,
562 pending_global_notifications: HashSet<TypeId>,
563 pending_flushes: usize,
564 flushing_effects: bool,
565 halt_action_dispatch: bool,
566 next_labeled_task_id: usize,
567 active_labeled_tasks: BTreeMap<usize, &'static str>,
568}
569
570impl AppContext {
571 fn new(
572 foreground: Rc<executor::Foreground>,
573 background: Arc<executor::Background>,
574 platform: Arc<dyn platform::Platform>,
575 foreground_platform: Rc<dyn platform::ForegroundPlatform>,
576 font_cache: Arc<FontCache>,
577 ref_counts: RefCounts,
578 asset_source: impl AssetSource,
579 ) -> Self {
580 Self {
581 models: Default::default(),
582 views: Default::default(),
583 parents: Default::default(),
584 windows: Default::default(),
585 globals: Default::default(),
586 element_states: Default::default(),
587 ref_counts: Arc::new(Mutex::new(ref_counts)),
588 background,
589
590 weak_self: None,
591 font_system: platform.fonts(),
592 platform,
593 foreground_platform,
594 font_cache,
595 asset_cache: Arc::new(AssetCache::new(asset_source)),
596 action_deserializers: Default::default(),
597 capture_actions: Default::default(),
598 actions: Default::default(),
599 global_actions: Default::default(),
600 keystroke_matcher: KeymapMatcher::default(),
601 next_entity_id: 0,
602 next_window_id: 0,
603 next_subscription_id: 0,
604 frame_count: 0,
605 subscriptions: Default::default(),
606 global_subscriptions: Default::default(),
607 observations: Default::default(),
608 focus_observations: Default::default(),
609 release_observations: Default::default(),
610 global_observations: Default::default(),
611 window_activation_observations: Default::default(),
612 window_fullscreen_observations: Default::default(),
613 window_bounds_observations: Default::default(),
614 keystroke_observations: Default::default(),
615 action_dispatch_observations: Default::default(),
616 active_labeled_task_observations: Default::default(),
617 foreground,
618 pending_effects: VecDeque::new(),
619 pending_notifications: Default::default(),
620 pending_global_notifications: Default::default(),
621 pending_flushes: 0,
622 flushing_effects: false,
623 halt_action_dispatch: false,
624 next_labeled_task_id: 0,
625 active_labeled_tasks: Default::default(),
626 }
627 }
628
629 pub fn background(&self) -> &Arc<executor::Background> {
630 &self.background
631 }
632
633 pub fn font_cache(&self) -> &Arc<FontCache> {
634 &self.font_cache
635 }
636
637 pub fn platform(&self) -> &Arc<dyn Platform> {
638 &self.platform
639 }
640
641 pub fn has_global<T: 'static>(&self) -> bool {
642 self.globals.contains_key(&TypeId::of::<T>())
643 }
644
645 pub fn global<T: 'static>(&self) -> &T {
646 if let Some(global) = self.globals.get(&TypeId::of::<T>()) {
647 global.downcast_ref().unwrap()
648 } else {
649 panic!("no global has been added for {}", type_name::<T>());
650 }
651 }
652
653 pub fn upgrade(&self) -> App {
654 App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
655 }
656
657 pub fn quit(&mut self) {
658 let mut futures = Vec::new();
659
660 self.update(|cx| {
661 for model_id in cx.models.keys().copied().collect::<Vec<_>>() {
662 let mut model = cx.models.remove(&model_id).unwrap();
663 futures.extend(model.app_will_quit(cx));
664 cx.models.insert(model_id, model);
665 }
666
667 for view_id in cx.views.keys().copied().collect::<Vec<_>>() {
668 let mut view = cx.views.remove(&view_id).unwrap();
669 futures.extend(view.app_will_quit(cx));
670 cx.views.insert(view_id, view);
671 }
672 });
673
674 self.remove_all_windows();
675
676 let futures = futures::future::join_all(futures);
677 if self
678 .background
679 .block_with_timeout(Duration::from_millis(100), futures)
680 .is_err()
681 {
682 log::error!("timed out waiting on app_will_quit");
683 }
684 }
685
686 pub fn remove_all_windows(&mut self) {
687 self.windows.clear();
688 self.flush_effects();
689 }
690
691 pub fn foreground(&self) -> &Rc<executor::Foreground> {
692 &self.foreground
693 }
694
695 pub fn deserialize_action(
696 &self,
697 name: &str,
698 argument: Option<&str>,
699 ) -> Result<Box<dyn Action>> {
700 let callback = self
701 .action_deserializers
702 .get(name)
703 .ok_or_else(|| anyhow!("unknown action {}", name))?
704 .1;
705 callback(argument.unwrap_or("{}"))
706 .with_context(|| format!("invalid data for action {}", name))
707 }
708
709 pub fn add_action<A, V, F, R>(&mut self, handler: F)
710 where
711 A: Action,
712 V: View,
713 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> R,
714 {
715 self.add_action_internal(handler, false)
716 }
717
718 pub fn capture_action<A, V, F>(&mut self, handler: F)
719 where
720 A: Action,
721 V: View,
722 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
723 {
724 self.add_action_internal(handler, true)
725 }
726
727 fn add_action_internal<A, V, F, R>(&mut self, mut handler: F, capture: bool)
728 where
729 A: Action,
730 V: View,
731 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> R,
732 {
733 let handler = Box::new(
734 move |view: &mut dyn AnyView,
735 action: &dyn Action,
736 cx: &mut WindowContext,
737 view_id: usize| {
738 let action = action.as_any().downcast_ref().unwrap();
739 let mut cx = ViewContext::mutable(cx, view_id);
740 handler(
741 view.as_any_mut()
742 .downcast_mut()
743 .expect("downcast is type safe"),
744 action,
745 &mut cx,
746 );
747 },
748 );
749
750 self.action_deserializers
751 .entry(A::qualified_name())
752 .or_insert((TypeId::of::<A>(), A::from_json_str));
753
754 let actions = if capture {
755 &mut self.capture_actions
756 } else {
757 &mut self.actions
758 };
759
760 actions
761 .entry(TypeId::of::<V>())
762 .or_default()
763 .entry(TypeId::of::<A>())
764 .or_default()
765 .push(handler);
766 }
767
768 pub fn add_async_action<A, V, F>(&mut self, mut handler: F)
769 where
770 A: Action,
771 V: View,
772 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> Option<Task<Result<()>>>,
773 {
774 self.add_action(move |view, action, cx| {
775 if let Some(task) = handler(view, action, cx) {
776 task.detach_and_log_err(cx);
777 }
778 })
779 }
780
781 pub fn add_global_action<A, F>(&mut self, mut handler: F)
782 where
783 A: Action,
784 F: 'static + FnMut(&A, &mut AppContext),
785 {
786 let handler = Box::new(move |action: &dyn Action, cx: &mut AppContext| {
787 let action = action.as_any().downcast_ref().unwrap();
788 handler(action, cx);
789 });
790
791 self.action_deserializers
792 .entry(A::qualified_name())
793 .or_insert((TypeId::of::<A>(), A::from_json_str));
794
795 if self
796 .global_actions
797 .insert(TypeId::of::<A>(), handler)
798 .is_some()
799 {
800 panic!(
801 "registered multiple global handlers for {}",
802 type_name::<A>()
803 );
804 }
805 }
806
807 pub fn has_window(&self, window_id: usize) -> bool {
808 self.window_ids()
809 .find(|window| window == &window_id)
810 .is_some()
811 }
812
813 pub fn window_is_active(&self, window_id: usize) -> bool {
814 self.windows.get(&window_id).map_or(false, |w| w.is_active)
815 }
816
817 pub fn root_view(&self, window_id: usize) -> Option<&AnyViewHandle> {
818 self.windows.get(&window_id).map(|w| w.root_view())
819 }
820
821 pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
822 self.windows.keys().copied()
823 }
824
825 pub fn view_ui_name(&self, window_id: usize, view_id: usize) -> Option<&'static str> {
826 Some(self.views.get(&(window_id, view_id))?.ui_name())
827 }
828
829 pub fn view_type_id(&self, window_id: usize, view_id: usize) -> Option<TypeId> {
830 self.views
831 .get(&(window_id, view_id))
832 .map(|view| view.as_any().type_id())
833 }
834
835 pub fn active_labeled_tasks<'a>(
836 &'a self,
837 ) -> impl DoubleEndedIterator<Item = &'static str> + 'a {
838 self.active_labeled_tasks.values().cloned()
839 }
840
841 pub(crate) fn start_frame(&mut self) {
842 self.frame_count += 1;
843 }
844
845 pub fn update<T, F: FnOnce(&mut Self) -> T>(&mut self, callback: F) -> T {
846 self.pending_flushes += 1;
847 let result = callback(self);
848 self.flush_effects();
849 result
850 }
851
852 pub fn read_window<T, F: FnOnce(&WindowContext) -> T>(
853 &self,
854 window_id: usize,
855 callback: F,
856 ) -> Option<T> {
857 let window = self.windows.get(&window_id)?;
858 let window_context = WindowContext::immutable(self, &window, window_id);
859 Some(callback(&window_context))
860 }
861
862 pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
863 &mut self,
864 window_id: usize,
865 callback: F,
866 ) -> Option<T> {
867 self.update(|app_context| {
868 let mut window = app_context.windows.remove(&window_id)?;
869 let mut window_context = WindowContext::mutable(app_context, &mut window, window_id);
870 let result = callback(&mut window_context);
871 if !window_context.removed {
872 app_context.windows.insert(window_id, window);
873 }
874 Some(result)
875 })
876 }
877
878 pub fn update_active_window<T, F: FnOnce(&mut WindowContext) -> T>(
879 &mut self,
880 callback: F,
881 ) -> Option<T> {
882 self.platform
883 .main_window_id()
884 .and_then(|id| self.update_window(id, callback))
885 }
886
887 pub fn prompt_for_paths(
888 &self,
889 options: PathPromptOptions,
890 ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
891 self.foreground_platform.prompt_for_paths(options)
892 }
893
894 pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
895 self.foreground_platform.prompt_for_new_path(directory)
896 }
897
898 pub fn reveal_path(&self, path: &Path) {
899 self.foreground_platform.reveal_path(path)
900 }
901
902 pub fn emit_global<E: Any>(&mut self, payload: E) {
903 self.pending_effects.push_back(Effect::GlobalEvent {
904 payload: Box::new(payload),
905 });
906 }
907
908 pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
909 where
910 E: Entity,
911 E::Event: 'static,
912 H: Handle<E>,
913 F: 'static + FnMut(H, &E::Event, &mut Self),
914 {
915 self.subscribe_internal(handle, move |handle, event, cx| {
916 callback(handle, event, cx);
917 true
918 })
919 }
920
921 pub fn subscribe_global<E, F>(&mut self, mut callback: F) -> Subscription
922 where
923 E: Any,
924 F: 'static + FnMut(&E, &mut Self),
925 {
926 let subscription_id = post_inc(&mut self.next_subscription_id);
927 let type_id = TypeId::of::<E>();
928 self.pending_effects.push_back(Effect::GlobalSubscription {
929 type_id,
930 subscription_id,
931 callback: Box::new(move |payload, cx| {
932 let payload = payload.downcast_ref().expect("downcast is type safe");
933 callback(payload, cx)
934 }),
935 });
936 Subscription::GlobalSubscription(
937 self.global_subscriptions
938 .subscribe(type_id, subscription_id),
939 )
940 }
941
942 pub fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
943 where
944 E: Entity,
945 E::Event: 'static,
946 H: Handle<E>,
947 F: 'static + FnMut(H, &mut Self),
948 {
949 self.observe_internal(handle, move |handle, cx| {
950 callback(handle, cx);
951 true
952 })
953 }
954
955 fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
956 where
957 E: Entity,
958 E::Event: 'static,
959 H: Handle<E>,
960 F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
961 {
962 let subscription_id = post_inc(&mut self.next_subscription_id);
963 let emitter = handle.downgrade();
964 self.pending_effects.push_back(Effect::Subscription {
965 entity_id: handle.id(),
966 subscription_id,
967 callback: Box::new(move |payload, cx| {
968 if let Some(emitter) = H::upgrade_from(&emitter, cx) {
969 let payload = payload.downcast_ref().expect("downcast is type safe");
970 callback(emitter, payload, cx)
971 } else {
972 false
973 }
974 }),
975 });
976 Subscription::Subscription(self.subscriptions.subscribe(handle.id(), subscription_id))
977 }
978
979 fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
980 where
981 E: Entity,
982 E::Event: 'static,
983 H: Handle<E>,
984 F: 'static + FnMut(H, &mut Self) -> bool,
985 {
986 let subscription_id = post_inc(&mut self.next_subscription_id);
987 let observed = handle.downgrade();
988 let entity_id = handle.id();
989 self.pending_effects.push_back(Effect::Observation {
990 entity_id,
991 subscription_id,
992 callback: Box::new(move |cx| {
993 if let Some(observed) = H::upgrade_from(&observed, cx) {
994 callback(observed, cx)
995 } else {
996 false
997 }
998 }),
999 });
1000 Subscription::Observation(self.observations.subscribe(entity_id, subscription_id))
1001 }
1002
1003 fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
1004 where
1005 F: 'static + FnMut(ViewHandle<V>, bool, &mut WindowContext) -> bool,
1006 V: View,
1007 {
1008 let subscription_id = post_inc(&mut self.next_subscription_id);
1009 let observed = handle.downgrade();
1010 let view_id = handle.id();
1011
1012 self.pending_effects.push_back(Effect::FocusObservation {
1013 view_id,
1014 subscription_id,
1015 callback: Box::new(move |focused, cx| {
1016 if let Some(observed) = observed.upgrade(cx) {
1017 callback(observed, focused, cx)
1018 } else {
1019 false
1020 }
1021 }),
1022 });
1023 Subscription::FocusObservation(self.focus_observations.subscribe(view_id, subscription_id))
1024 }
1025
1026 pub fn observe_global<G, F>(&mut self, mut observe: F) -> Subscription
1027 where
1028 G: Any,
1029 F: 'static + FnMut(&mut AppContext),
1030 {
1031 let type_id = TypeId::of::<G>();
1032 let id = post_inc(&mut self.next_subscription_id);
1033
1034 self.global_observations.add_callback(
1035 type_id,
1036 id,
1037 Box::new(move |cx: &mut AppContext| observe(cx)),
1038 );
1039 Subscription::GlobalObservation(self.global_observations.subscribe(type_id, id))
1040 }
1041
1042 pub fn observe_default_global<G, F>(&mut self, observe: F) -> Subscription
1043 where
1044 G: Any + Default,
1045 F: 'static + FnMut(&mut AppContext),
1046 {
1047 if !self.has_global::<G>() {
1048 self.set_global(G::default());
1049 }
1050 self.observe_global::<G, F>(observe)
1051 }
1052
1053 pub fn observe_release<E, H, F>(&mut self, handle: &H, callback: F) -> Subscription
1054 where
1055 E: Entity,
1056 E::Event: 'static,
1057 H: Handle<E>,
1058 F: 'static + FnOnce(&E, &mut Self),
1059 {
1060 let id = post_inc(&mut self.next_subscription_id);
1061 let mut callback = Some(callback);
1062 self.release_observations.add_callback(
1063 handle.id(),
1064 id,
1065 Box::new(move |released, cx| {
1066 let released = released.downcast_ref().unwrap();
1067 if let Some(callback) = callback.take() {
1068 callback(released, cx)
1069 }
1070 }),
1071 );
1072 Subscription::ReleaseObservation(self.release_observations.subscribe(handle.id(), id))
1073 }
1074
1075 pub fn observe_actions<F>(&mut self, callback: F) -> Subscription
1076 where
1077 F: 'static + FnMut(TypeId, &mut AppContext),
1078 {
1079 let subscription_id = post_inc(&mut self.next_subscription_id);
1080 self.action_dispatch_observations
1081 .add_callback((), subscription_id, Box::new(callback));
1082 Subscription::ActionObservation(
1083 self.action_dispatch_observations
1084 .subscribe((), subscription_id),
1085 )
1086 }
1087
1088 fn observe_active_labeled_tasks<F>(&mut self, callback: F) -> Subscription
1089 where
1090 F: 'static + FnMut(&mut AppContext) -> bool,
1091 {
1092 let subscription_id = post_inc(&mut self.next_subscription_id);
1093 self.active_labeled_task_observations
1094 .add_callback((), subscription_id, Box::new(callback));
1095 Subscription::ActiveLabeledTasksObservation(
1096 self.active_labeled_task_observations
1097 .subscribe((), subscription_id),
1098 )
1099 }
1100
1101 pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut AppContext)) {
1102 self.pending_effects.push_back(Effect::Deferred {
1103 callback: Box::new(callback),
1104 after_window_update: false,
1105 })
1106 }
1107
1108 pub fn after_window_update(&mut self, callback: impl 'static + FnOnce(&mut AppContext)) {
1109 self.pending_effects.push_back(Effect::Deferred {
1110 callback: Box::new(callback),
1111 after_window_update: true,
1112 })
1113 }
1114
1115 fn notify_model(&mut self, model_id: usize) {
1116 if self.pending_notifications.insert(model_id) {
1117 self.pending_effects
1118 .push_back(Effect::ModelNotification { model_id });
1119 }
1120 }
1121
1122 fn notify_view(&mut self, window_id: usize, view_id: usize) {
1123 if self.pending_notifications.insert(view_id) {
1124 self.pending_effects
1125 .push_back(Effect::ViewNotification { window_id, view_id });
1126 }
1127 }
1128
1129 fn notify_global(&mut self, type_id: TypeId) {
1130 if self.pending_global_notifications.insert(type_id) {
1131 self.pending_effects
1132 .push_back(Effect::GlobalNotification { type_id });
1133 }
1134 }
1135
1136 pub fn all_action_names<'a>(&'a self) -> impl Iterator<Item = &'static str> + 'a {
1137 self.action_deserializers.keys().copied()
1138 }
1139
1140 pub fn is_action_available(&self, action: &dyn Action) -> bool {
1141 let mut available_in_window = false;
1142 let action_type = action.as_any().type_id();
1143 if let Some(window_id) = self.platform.main_window_id() {
1144 available_in_window = self
1145 .read_window(window_id, |cx| {
1146 if let Some(focused_view_id) = cx.focused_view_id() {
1147 for view_id in cx.ancestors(focused_view_id) {
1148 if let Some(view) = cx.views.get(&(window_id, view_id)) {
1149 let view_type = view.as_any().type_id();
1150 if let Some(actions) = cx.actions.get(&view_type) {
1151 if actions.contains_key(&action_type) {
1152 return true;
1153 }
1154 }
1155 }
1156 }
1157 }
1158 false
1159 })
1160 .unwrap_or(false);
1161 }
1162 available_in_window || self.global_actions.contains_key(&action_type)
1163 }
1164
1165 fn actions_mut(
1166 &mut self,
1167 capture_phase: bool,
1168 ) -> &mut HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>> {
1169 if capture_phase {
1170 &mut self.capture_actions
1171 } else {
1172 &mut self.actions
1173 }
1174 }
1175
1176 pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
1177 self.dispatch_global_action_any(&action);
1178 }
1179
1180 fn dispatch_global_action_any(&mut self, action: &dyn Action) -> bool {
1181 self.update(|this| {
1182 if let Some((name, mut handler)) = this.global_actions.remove_entry(&action.id()) {
1183 handler(action, this);
1184 this.global_actions.insert(name, handler);
1185 true
1186 } else {
1187 false
1188 }
1189 })
1190 }
1191
1192 pub fn add_bindings<T: IntoIterator<Item = Binding>>(&mut self, bindings: T) {
1193 self.keystroke_matcher.add_bindings(bindings);
1194 }
1195
1196 pub fn clear_bindings(&mut self) {
1197 self.keystroke_matcher.clear_bindings();
1198 }
1199
1200 pub fn default_global<T: 'static + Default>(&mut self) -> &T {
1201 let type_id = TypeId::of::<T>();
1202 self.update(|this| {
1203 if let Entry::Vacant(entry) = this.globals.entry(type_id) {
1204 entry.insert(Box::new(T::default()));
1205 this.notify_global(type_id);
1206 }
1207 });
1208 self.globals.get(&type_id).unwrap().downcast_ref().unwrap()
1209 }
1210
1211 pub fn set_global<T: 'static>(&mut self, state: T) {
1212 self.update(|this| {
1213 let type_id = TypeId::of::<T>();
1214 this.globals.insert(type_id, Box::new(state));
1215 this.notify_global(type_id);
1216 });
1217 }
1218
1219 pub fn update_default_global<T, F, U>(&mut self, update: F) -> U
1220 where
1221 T: 'static + Default,
1222 F: FnOnce(&mut T, &mut AppContext) -> U,
1223 {
1224 self.update(|mut this| {
1225 Self::update_default_global_internal(&mut this, |global, cx| update(global, cx))
1226 })
1227 }
1228
1229 fn update_default_global_internal<C, T, F, U>(this: &mut C, update: F) -> U
1230 where
1231 C: DerefMut<Target = AppContext>,
1232 T: 'static + Default,
1233 F: FnOnce(&mut T, &mut C) -> U,
1234 {
1235 let type_id = TypeId::of::<T>();
1236 let mut state = this
1237 .globals
1238 .remove(&type_id)
1239 .unwrap_or_else(|| Box::new(T::default()));
1240 let result = update(state.downcast_mut().unwrap(), this);
1241 this.globals.insert(type_id, state);
1242 this.notify_global(type_id);
1243 result
1244 }
1245
1246 pub fn update_global<T, F, U>(&mut self, update: F) -> U
1247 where
1248 T: 'static,
1249 F: FnOnce(&mut T, &mut AppContext) -> U,
1250 {
1251 self.update(|mut this| {
1252 Self::update_global_internal(&mut this, |global, cx| update(global, cx))
1253 })
1254 }
1255
1256 fn update_global_internal<C, T, F, U>(this: &mut C, update: F) -> U
1257 where
1258 C: DerefMut<Target = AppContext>,
1259 T: 'static,
1260 F: FnOnce(&mut T, &mut C) -> U,
1261 {
1262 let type_id = TypeId::of::<T>();
1263 if let Some(mut state) = this.globals.remove(&type_id) {
1264 let result = update(state.downcast_mut().unwrap(), this);
1265 this.globals.insert(type_id, state);
1266 this.notify_global(type_id);
1267 result
1268 } else {
1269 panic!("No global added for {}", std::any::type_name::<T>());
1270 }
1271 }
1272
1273 pub fn clear_globals(&mut self) {
1274 self.globals.clear();
1275 }
1276
1277 pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1278 where
1279 T: Entity,
1280 F: FnOnce(&mut ModelContext<T>) -> T,
1281 {
1282 self.update(|this| {
1283 let model_id = post_inc(&mut this.next_entity_id);
1284 let handle = ModelHandle::new(model_id, &this.ref_counts);
1285 let mut cx = ModelContext::new(this, model_id);
1286 let model = build_model(&mut cx);
1287 this.models.insert(model_id, Box::new(model));
1288 handle
1289 })
1290 }
1291
1292 pub fn add_window<V, F>(
1293 &mut self,
1294 window_options: WindowOptions,
1295 build_root_view: F,
1296 ) -> (usize, ViewHandle<V>)
1297 where
1298 V: View,
1299 F: FnOnce(&mut ViewContext<V>) -> V,
1300 {
1301 self.update(|this| {
1302 let window_id = post_inc(&mut this.next_window_id);
1303 let platform_window =
1304 this.platform
1305 .open_window(window_id, window_options, this.foreground.clone());
1306 let window = this.build_window(window_id, platform_window, build_root_view);
1307 let root_view = window.root_view().clone().downcast::<V>().unwrap();
1308 this.windows.insert(window_id, window);
1309 (window_id, root_view)
1310 })
1311 }
1312
1313 pub fn add_status_bar_item<V, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<V>)
1314 where
1315 V: View,
1316 F: FnOnce(&mut ViewContext<V>) -> V,
1317 {
1318 self.update(|this| {
1319 let window_id = post_inc(&mut this.next_window_id);
1320 let platform_window = this.platform.add_status_item(window_id);
1321 let window = this.build_window(window_id, platform_window, build_root_view);
1322 let root_view = window.root_view().clone().downcast::<V>().unwrap();
1323
1324 this.windows.insert(window_id, window);
1325 this.update_window(window_id, |cx| {
1326 root_view.update(cx, |view, cx| view.focus_in(cx.handle().into_any(), cx))
1327 });
1328
1329 (window_id, root_view)
1330 })
1331 }
1332
1333 pub fn remove_status_bar_item(&mut self, id: usize) {
1334 self.remove_window(id);
1335 }
1336
1337 pub fn remove_window(&mut self, window_id: usize) {
1338 self.windows.remove(&window_id);
1339 self.flush_effects();
1340 }
1341
1342 pub fn build_window<V, F>(
1343 &mut self,
1344 window_id: usize,
1345 mut platform_window: Box<dyn platform::Window>,
1346 build_root_view: F,
1347 ) -> Window
1348 where
1349 V: View,
1350 F: FnOnce(&mut ViewContext<V>) -> V,
1351 {
1352 {
1353 let mut app = self.upgrade();
1354
1355 platform_window.on_event(Box::new(move |event| {
1356 app.update_window(window_id, |cx| {
1357 if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event {
1358 if cx.dispatch_keystroke(keystroke) {
1359 return true;
1360 }
1361 }
1362
1363 cx.dispatch_event(event, false)
1364 })
1365 .unwrap_or(false)
1366 }));
1367 }
1368
1369 {
1370 let mut app = self.upgrade();
1371 platform_window.on_active_status_change(Box::new(move |is_active| {
1372 app.update(|cx| cx.window_changed_active_status(window_id, is_active))
1373 }));
1374 }
1375
1376 {
1377 let mut app = self.upgrade();
1378 platform_window.on_resize(Box::new(move || {
1379 app.update(|cx| cx.window_was_resized(window_id))
1380 }));
1381 }
1382
1383 {
1384 let mut app = self.upgrade();
1385 platform_window.on_moved(Box::new(move || {
1386 app.update(|cx| cx.window_was_moved(window_id))
1387 }));
1388 }
1389
1390 {
1391 let mut app = self.upgrade();
1392 platform_window.on_fullscreen(Box::new(move |is_fullscreen| {
1393 app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen))
1394 }));
1395 }
1396
1397 {
1398 let mut app = self.upgrade();
1399 platform_window.on_close(Box::new(move || {
1400 app.update(|cx| cx.remove_window(window_id));
1401 }));
1402 }
1403
1404 {
1405 let mut app = self.upgrade();
1406 platform_window
1407 .on_appearance_changed(Box::new(move || app.update(|cx| cx.refresh_windows())));
1408 }
1409
1410 platform_window.set_input_handler(Box::new(WindowInputHandler {
1411 app: self.upgrade().0,
1412 window_id,
1413 }));
1414
1415 let mut window = Window::new(window_id, platform_window, self, build_root_view);
1416 let scene = WindowContext::mutable(self, &mut window, window_id)
1417 .build_scene()
1418 .expect("initial scene should not error");
1419 window.platform_window.present_scene(scene);
1420 window
1421 }
1422
1423 pub fn replace_root_view<V, F>(
1424 &mut self,
1425 window_id: usize,
1426 build_root_view: F,
1427 ) -> Option<ViewHandle<V>>
1428 where
1429 V: View,
1430 F: FnOnce(&mut ViewContext<V>) -> V,
1431 {
1432 self.update_window(window_id, |cx| cx.replace_root_view(build_root_view))
1433 }
1434
1435 pub fn add_view<S, F>(&mut self, parent: &AnyViewHandle, build_view: F) -> ViewHandle<S>
1436 where
1437 S: View,
1438 F: FnOnce(&mut ViewContext<S>) -> S,
1439 {
1440 self.update_window(parent.window_id, |cx| {
1441 cx.build_and_insert_view(ParentId::View(parent.view_id), |cx| Some(build_view(cx)))
1442 .unwrap()
1443 })
1444 .unwrap()
1445 }
1446
1447 fn remove_dropped_entities(&mut self) {
1448 loop {
1449 let (dropped_models, dropped_views, dropped_element_states) =
1450 self.ref_counts.lock().take_dropped();
1451 if dropped_models.is_empty()
1452 && dropped_views.is_empty()
1453 && dropped_element_states.is_empty()
1454 {
1455 break;
1456 }
1457
1458 for model_id in dropped_models {
1459 self.subscriptions.remove(model_id);
1460 self.observations.remove(model_id);
1461 let mut model = self.models.remove(&model_id).unwrap();
1462 model.release(self);
1463 self.pending_effects
1464 .push_back(Effect::ModelRelease { model_id, model });
1465 }
1466
1467 for (window_id, view_id) in dropped_views {
1468 self.subscriptions.remove(view_id);
1469 self.observations.remove(view_id);
1470 let mut view = self.views.remove(&(window_id, view_id)).unwrap();
1471 view.release(self);
1472 let change_focus_to = self.windows.get_mut(&window_id).and_then(|window| {
1473 window
1474 .invalidation
1475 .get_or_insert_with(Default::default)
1476 .removed
1477 .push(view_id);
1478 if window.focused_view_id == Some(view_id) {
1479 Some(window.root_view().id())
1480 } else {
1481 None
1482 }
1483 });
1484 self.parents.remove(&(window_id, view_id));
1485
1486 if let Some(view_id) = change_focus_to {
1487 self.handle_focus_effect(window_id, Some(view_id));
1488 }
1489
1490 self.pending_effects
1491 .push_back(Effect::ViewRelease { view_id, view });
1492 }
1493
1494 for key in dropped_element_states {
1495 self.element_states.remove(&key);
1496 }
1497 }
1498 }
1499
1500 fn flush_effects(&mut self) {
1501 self.pending_flushes = self.pending_flushes.saturating_sub(1);
1502 let mut after_window_update_callbacks = Vec::new();
1503
1504 if !self.flushing_effects && self.pending_flushes == 0 {
1505 self.flushing_effects = true;
1506
1507 let mut refreshing = false;
1508 loop {
1509 if let Some(effect) = self.pending_effects.pop_front() {
1510 match effect {
1511 Effect::Subscription {
1512 entity_id,
1513 subscription_id,
1514 callback,
1515 } => self
1516 .subscriptions
1517 .add_callback(entity_id, subscription_id, callback),
1518
1519 Effect::Event { entity_id, payload } => {
1520 let mut subscriptions = self.subscriptions.clone();
1521 subscriptions
1522 .emit(entity_id, |callback| callback(payload.as_ref(), self))
1523 }
1524
1525 Effect::GlobalSubscription {
1526 type_id,
1527 subscription_id,
1528 callback,
1529 } => self.global_subscriptions.add_callback(
1530 type_id,
1531 subscription_id,
1532 callback,
1533 ),
1534
1535 Effect::GlobalEvent { payload } => self.emit_global_event(payload),
1536
1537 Effect::Observation {
1538 entity_id,
1539 subscription_id,
1540 callback,
1541 } => self
1542 .observations
1543 .add_callback(entity_id, subscription_id, callback),
1544
1545 Effect::ModelNotification { model_id } => {
1546 let mut observations = self.observations.clone();
1547 observations.emit(model_id, |callback| callback(self));
1548 }
1549
1550 Effect::ViewNotification { window_id, view_id } => {
1551 self.handle_view_notification_effect(window_id, view_id)
1552 }
1553
1554 Effect::GlobalNotification { type_id } => {
1555 let mut subscriptions = self.global_observations.clone();
1556 subscriptions.emit(type_id, |callback| {
1557 callback(self);
1558 true
1559 });
1560 }
1561
1562 Effect::Deferred {
1563 callback,
1564 after_window_update,
1565 } => {
1566 if after_window_update {
1567 after_window_update_callbacks.push(callback);
1568 } else {
1569 callback(self)
1570 }
1571 }
1572
1573 Effect::ModelRelease { model_id, model } => {
1574 self.handle_entity_release_effect(model_id, model.as_any())
1575 }
1576
1577 Effect::ViewRelease { view_id, view } => {
1578 self.handle_entity_release_effect(view_id, view.as_any())
1579 }
1580
1581 Effect::Focus { window_id, view_id } => {
1582 self.handle_focus_effect(window_id, view_id);
1583 }
1584
1585 Effect::FocusObservation {
1586 view_id,
1587 subscription_id,
1588 callback,
1589 } => {
1590 self.focus_observations.add_callback(
1591 view_id,
1592 subscription_id,
1593 callback,
1594 );
1595 }
1596
1597 Effect::ResizeWindow { window_id } => {
1598 if let Some(window) = self.windows.get_mut(&window_id) {
1599 window
1600 .invalidation
1601 .get_or_insert(WindowInvalidation::default());
1602 }
1603 self.handle_window_moved(window_id);
1604 }
1605
1606 Effect::MoveWindow { window_id } => {
1607 self.handle_window_moved(window_id);
1608 }
1609
1610 Effect::WindowActivationObservation {
1611 window_id,
1612 subscription_id,
1613 callback,
1614 } => self.window_activation_observations.add_callback(
1615 window_id,
1616 subscription_id,
1617 callback,
1618 ),
1619
1620 Effect::ActivateWindow {
1621 window_id,
1622 is_active,
1623 } => self.handle_window_activation_effect(window_id, is_active),
1624
1625 Effect::WindowFullscreenObservation {
1626 window_id,
1627 subscription_id,
1628 callback,
1629 } => self.window_fullscreen_observations.add_callback(
1630 window_id,
1631 subscription_id,
1632 callback,
1633 ),
1634
1635 Effect::FullscreenWindow {
1636 window_id,
1637 is_fullscreen,
1638 } => self.handle_fullscreen_effect(window_id, is_fullscreen),
1639
1640 Effect::WindowBoundsObservation {
1641 window_id,
1642 subscription_id,
1643 callback,
1644 } => self.window_bounds_observations.add_callback(
1645 window_id,
1646 subscription_id,
1647 callback,
1648 ),
1649
1650 Effect::RefreshWindows => {
1651 refreshing = true;
1652 }
1653 Effect::DispatchActionFrom {
1654 window_id,
1655 view_id,
1656 action,
1657 } => {
1658 self.handle_dispatch_action_from_effect(
1659 window_id,
1660 Some(view_id),
1661 action.as_ref(),
1662 );
1663 }
1664 Effect::ActionDispatchNotification { action_id } => {
1665 self.handle_action_dispatch_notification_effect(action_id)
1666 }
1667 Effect::WindowShouldCloseSubscription {
1668 window_id,
1669 callback,
1670 } => {
1671 self.handle_window_should_close_subscription_effect(window_id, callback)
1672 }
1673 Effect::Keystroke {
1674 window_id,
1675 keystroke,
1676 handled_by,
1677 result,
1678 } => self.handle_keystroke_effect(window_id, keystroke, handled_by, result),
1679 Effect::ActiveLabeledTasksChanged => {
1680 self.handle_active_labeled_tasks_changed_effect()
1681 }
1682 Effect::ActiveLabeledTasksObservation {
1683 subscription_id,
1684 callback,
1685 } => self.active_labeled_task_observations.add_callback(
1686 (),
1687 subscription_id,
1688 callback,
1689 ),
1690 }
1691 self.pending_notifications.clear();
1692 self.remove_dropped_entities();
1693 } else {
1694 self.remove_dropped_entities();
1695
1696 if refreshing {
1697 self.perform_window_refresh();
1698 } else {
1699 self.update_windows();
1700 }
1701
1702 if self.pending_effects.is_empty() {
1703 for callback in after_window_update_callbacks.drain(..) {
1704 callback(self);
1705 }
1706
1707 if self.pending_effects.is_empty() {
1708 self.flushing_effects = false;
1709 self.pending_notifications.clear();
1710 self.pending_global_notifications.clear();
1711 break;
1712 }
1713 }
1714
1715 refreshing = false;
1716 }
1717 }
1718 }
1719 }
1720
1721 fn update_windows(&mut self) {
1722 let window_ids = self.windows.keys().cloned().collect::<Vec<_>>();
1723 for window_id in window_ids {
1724 self.update_window(window_id, |cx| {
1725 if let Some(mut invalidation) = cx.window.invalidation.take() {
1726 let appearance = cx.window.platform_window.appearance();
1727 cx.invalidate(&mut invalidation, appearance);
1728 if let Some(scene) = cx.build_scene().log_err() {
1729 cx.window.platform_window.present_scene(scene);
1730 }
1731 }
1732 });
1733 }
1734 }
1735
1736 fn window_was_resized(&mut self, window_id: usize) {
1737 self.pending_effects
1738 .push_back(Effect::ResizeWindow { window_id });
1739 }
1740
1741 fn window_was_moved(&mut self, window_id: usize) {
1742 self.pending_effects
1743 .push_back(Effect::MoveWindow { window_id });
1744 }
1745
1746 fn window_was_fullscreen_changed(&mut self, window_id: usize, is_fullscreen: bool) {
1747 self.pending_effects.push_back(Effect::FullscreenWindow {
1748 window_id,
1749 is_fullscreen,
1750 });
1751 }
1752
1753 fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) {
1754 self.pending_effects.push_back(Effect::ActivateWindow {
1755 window_id,
1756 is_active,
1757 });
1758 }
1759
1760 fn keystroke(
1761 &mut self,
1762 window_id: usize,
1763 keystroke: Keystroke,
1764 handled_by: Option<Box<dyn Action>>,
1765 result: MatchResult,
1766 ) {
1767 self.pending_effects.push_back(Effect::Keystroke {
1768 window_id,
1769 keystroke,
1770 handled_by,
1771 result,
1772 });
1773 }
1774
1775 pub fn refresh_windows(&mut self) {
1776 self.pending_effects.push_back(Effect::RefreshWindows);
1777 }
1778
1779 pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: impl Action) {
1780 self.dispatch_any_action_at(window_id, view_id, Box::new(action));
1781 }
1782
1783 pub fn dispatch_any_action_at(
1784 &mut self,
1785 window_id: usize,
1786 view_id: usize,
1787 action: Box<dyn Action>,
1788 ) {
1789 self.pending_effects.push_back(Effect::DispatchActionFrom {
1790 window_id,
1791 view_id,
1792 action,
1793 });
1794 }
1795
1796 fn perform_window_refresh(&mut self) {
1797 let window_ids = self.windows.keys().cloned().collect::<Vec<_>>();
1798 for window_id in window_ids {
1799 self.update_window(window_id, |cx| {
1800 let mut invalidation = cx.window.invalidation.take().unwrap_or_default();
1801 invalidation
1802 .updated
1803 .extend(cx.window.rendered_views.keys().copied());
1804 cx.invalidate(&mut invalidation, cx.window.platform_window.appearance());
1805 cx.refreshing = true;
1806 if let Some(scene) = cx.build_scene().log_err() {
1807 cx.window.platform_window.present_scene(scene);
1808 }
1809 });
1810 }
1811 }
1812
1813 fn emit_global_event(&mut self, payload: Box<dyn Any>) {
1814 let type_id = (&*payload).type_id();
1815
1816 let mut subscriptions = self.global_subscriptions.clone();
1817 subscriptions.emit(type_id, |callback| {
1818 callback(payload.as_ref(), self);
1819 true //Always alive
1820 });
1821 }
1822
1823 fn handle_view_notification_effect(
1824 &mut self,
1825 observed_window_id: usize,
1826 observed_view_id: usize,
1827 ) {
1828 if self
1829 .views
1830 .contains_key(&(observed_window_id, observed_view_id))
1831 {
1832 if let Some(window) = self.windows.get_mut(&observed_window_id) {
1833 window
1834 .invalidation
1835 .get_or_insert_with(Default::default)
1836 .updated
1837 .insert(observed_view_id);
1838 }
1839
1840 let mut observations = self.observations.clone();
1841 observations.emit(observed_view_id, |callback| callback(self));
1842 }
1843 }
1844
1845 fn handle_entity_release_effect(&mut self, entity_id: usize, entity: &dyn Any) {
1846 self.release_observations
1847 .clone()
1848 .emit(entity_id, |callback| {
1849 callback(entity, self);
1850 // Release observations happen one time. So clear the callback by returning false
1851 false
1852 })
1853 }
1854
1855 fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) {
1856 self.update_window(window_id, |cx| {
1857 cx.window.is_fullscreen = is_fullscreen;
1858
1859 let mut fullscreen_observations = cx.window_fullscreen_observations.clone();
1860 fullscreen_observations.emit(window_id, |callback| callback(is_fullscreen, cx));
1861
1862 if let Some(uuid) = cx.window_display_uuid() {
1863 let bounds = cx.window_bounds();
1864 let mut bounds_observations = cx.window_bounds_observations.clone();
1865 bounds_observations.emit(window_id, |callback| callback(bounds, uuid, cx));
1866 }
1867
1868 Some(())
1869 });
1870 }
1871
1872 fn handle_keystroke_effect(
1873 &mut self,
1874 window_id: usize,
1875 keystroke: Keystroke,
1876 handled_by: Option<Box<dyn Action>>,
1877 result: MatchResult,
1878 ) {
1879 self.update_window(window_id, |cx| {
1880 let mut observations = cx.keystroke_observations.clone();
1881 observations.emit(window_id, move |callback| {
1882 callback(&keystroke, &result, handled_by.as_ref(), cx)
1883 });
1884 });
1885 }
1886
1887 fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) {
1888 self.update_window(window_id, |cx| {
1889 if cx.window.is_active == active {
1890 return;
1891 }
1892 cx.window.is_active = active;
1893
1894 if let Some(focused_id) = cx.window.focused_view_id {
1895 for view_id in cx.ancestors(focused_id).collect::<Vec<_>>() {
1896 cx.update_any_view(view_id, |view, cx| {
1897 if active {
1898 view.focus_in(focused_id, cx, view_id);
1899 } else {
1900 view.focus_out(focused_id, cx, view_id);
1901 }
1902 });
1903 }
1904 }
1905
1906 let mut observations = cx.window_activation_observations.clone();
1907 observations.emit(window_id, |callback| callback(active, cx));
1908 });
1909 }
1910
1911 fn handle_focus_effect(&mut self, window_id: usize, mut focused_id: Option<usize>) {
1912 let mut blurred_id = None;
1913 self.update_window(window_id, |cx| {
1914 if cx.window.focused_view_id == focused_id {
1915 focused_id = None;
1916 return;
1917 }
1918 blurred_id = cx.window.focused_view_id;
1919 cx.window.focused_view_id = focused_id;
1920
1921 let blurred_parents = blurred_id
1922 .map(|blurred_id| cx.ancestors(blurred_id).collect::<Vec<_>>())
1923 .unwrap_or_default();
1924 let focused_parents = focused_id
1925 .map(|focused_id| cx.ancestors(focused_id).collect::<Vec<_>>())
1926 .unwrap_or_default();
1927
1928 if let Some(blurred_id) = blurred_id {
1929 for view_id in blurred_parents.iter().copied() {
1930 if let Some(mut view) = cx.views.remove(&(window_id, view_id)) {
1931 view.focus_out(blurred_id, cx, view_id);
1932 cx.views.insert((window_id, view_id), view);
1933 }
1934 }
1935
1936 let mut subscriptions = cx.focus_observations.clone();
1937 subscriptions.emit(blurred_id, |callback| callback(false, cx));
1938 }
1939
1940 if let Some(focused_id) = focused_id {
1941 for view_id in focused_parents {
1942 if let Some(mut view) = cx.views.remove(&(window_id, view_id)) {
1943 view.focus_in(focused_id, cx, view_id);
1944 cx.views.insert((window_id, view_id), view);
1945 }
1946 }
1947
1948 let mut subscriptions = cx.focus_observations.clone();
1949 subscriptions.emit(focused_id, |callback| callback(true, cx));
1950 }
1951 });
1952 }
1953
1954 fn handle_dispatch_action_from_effect(
1955 &mut self,
1956 window_id: usize,
1957 view_id: Option<usize>,
1958 action: &dyn Action,
1959 ) {
1960 self.update_window(window_id, |cx| {
1961 cx.handle_dispatch_action_from_effect(view_id, action)
1962 });
1963 }
1964
1965 fn handle_action_dispatch_notification_effect(&mut self, action_id: TypeId) {
1966 self.action_dispatch_observations
1967 .clone()
1968 .emit((), |callback| {
1969 callback(action_id, self);
1970 true
1971 });
1972 }
1973
1974 fn handle_window_should_close_subscription_effect(
1975 &mut self,
1976 window_id: usize,
1977 mut callback: WindowShouldCloseSubscriptionCallback,
1978 ) {
1979 let mut app = self.upgrade();
1980 if let Some(window) = self.windows.get_mut(&window_id) {
1981 window
1982 .platform_window
1983 .on_should_close(Box::new(move || app.update(|cx| callback(cx))))
1984 }
1985 }
1986
1987 fn handle_window_moved(&mut self, window_id: usize) {
1988 self.update_window(window_id, |cx| {
1989 if let Some(display) = cx.window_display_uuid() {
1990 let bounds = cx.window_bounds();
1991 cx.window_bounds_observations
1992 .clone()
1993 .emit(window_id, move |callback| {
1994 callback(bounds, display, cx);
1995 true
1996 });
1997 }
1998 });
1999 }
2000
2001 fn handle_active_labeled_tasks_changed_effect(&mut self) {
2002 self.active_labeled_task_observations
2003 .clone()
2004 .emit((), move |callback| {
2005 callback(self);
2006 true
2007 });
2008 }
2009
2010 pub fn focus(&mut self, window_id: usize, view_id: Option<usize>) {
2011 self.pending_effects
2012 .push_back(Effect::Focus { window_id, view_id });
2013 }
2014
2015 fn spawn_internal<F, Fut, T>(&mut self, task_name: Option<&'static str>, f: F) -> Task<T>
2016 where
2017 F: FnOnce(AsyncAppContext) -> Fut,
2018 Fut: 'static + Future<Output = T>,
2019 T: 'static,
2020 {
2021 let label_id = task_name.map(|task_name| {
2022 let id = post_inc(&mut self.next_labeled_task_id);
2023 self.active_labeled_tasks.insert(id, task_name);
2024 self.pending_effects
2025 .push_back(Effect::ActiveLabeledTasksChanged);
2026 id
2027 });
2028
2029 let future = f(self.to_async());
2030 let cx = self.to_async();
2031 self.foreground.spawn(async move {
2032 let result = future.await;
2033 let mut cx = cx.0.borrow_mut();
2034
2035 if let Some(completed_label_id) = label_id {
2036 cx.active_labeled_tasks.remove(&completed_label_id);
2037 cx.pending_effects
2038 .push_back(Effect::ActiveLabeledTasksChanged);
2039 }
2040 cx.flush_effects();
2041 result
2042 })
2043 }
2044
2045 pub fn spawn_labeled<F, Fut, T>(&mut self, task_name: &'static str, f: F) -> Task<T>
2046 where
2047 F: FnOnce(AsyncAppContext) -> Fut,
2048 Fut: 'static + Future<Output = T>,
2049 T: 'static,
2050 {
2051 self.spawn_internal(Some(task_name), f)
2052 }
2053
2054 pub fn spawn<F, Fut, T>(&mut self, f: F) -> Task<T>
2055 where
2056 F: FnOnce(AsyncAppContext) -> Fut,
2057 Fut: 'static + Future<Output = T>,
2058 T: 'static,
2059 {
2060 self.spawn_internal(None, f)
2061 }
2062
2063 pub fn to_async(&self) -> AsyncAppContext {
2064 AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
2065 }
2066
2067 pub fn write_to_clipboard(&self, item: ClipboardItem) {
2068 self.platform.write_to_clipboard(item);
2069 }
2070
2071 pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
2072 self.platform.read_from_clipboard()
2073 }
2074
2075 #[cfg(any(test, feature = "test-support"))]
2076 pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
2077 self.ref_counts.lock().leak_detector.clone()
2078 }
2079}
2080
2081impl ReadModel for AppContext {
2082 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2083 if let Some(model) = self.models.get(&handle.model_id) {
2084 model
2085 .as_any()
2086 .downcast_ref()
2087 .expect("downcast is type safe")
2088 } else {
2089 panic!("circular model reference");
2090 }
2091 }
2092}
2093
2094impl UpdateModel for AppContext {
2095 fn update_model<T: Entity, V>(
2096 &mut self,
2097 handle: &ModelHandle<T>,
2098 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2099 ) -> V {
2100 if let Some(mut model) = self.models.remove(&handle.model_id) {
2101 self.update(|this| {
2102 let mut cx = ModelContext::new(this, handle.model_id);
2103 let result = update(
2104 model
2105 .as_any_mut()
2106 .downcast_mut()
2107 .expect("downcast is type safe"),
2108 &mut cx,
2109 );
2110 this.models.insert(handle.model_id, model);
2111 result
2112 })
2113 } else {
2114 panic!("circular model update");
2115 }
2116 }
2117}
2118
2119impl UpgradeModelHandle for AppContext {
2120 fn upgrade_model_handle<T: Entity>(
2121 &self,
2122 handle: &WeakModelHandle<T>,
2123 ) -> Option<ModelHandle<T>> {
2124 if self.ref_counts.lock().is_entity_alive(handle.model_id) {
2125 Some(ModelHandle::new(handle.model_id, &self.ref_counts))
2126 } else {
2127 None
2128 }
2129 }
2130
2131 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2132 self.ref_counts.lock().is_entity_alive(handle.model_id)
2133 }
2134
2135 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2136 if self.ref_counts.lock().is_entity_alive(handle.model_id) {
2137 Some(AnyModelHandle::new(
2138 handle.model_id,
2139 handle.model_type,
2140 self.ref_counts.clone(),
2141 ))
2142 } else {
2143 None
2144 }
2145 }
2146}
2147
2148impl UpgradeViewHandle for AppContext {
2149 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2150 if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2151 Some(ViewHandle::new(
2152 handle.window_id,
2153 handle.view_id,
2154 &self.ref_counts,
2155 ))
2156 } else {
2157 None
2158 }
2159 }
2160
2161 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2162 if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2163 Some(AnyViewHandle::new(
2164 handle.window_id,
2165 handle.view_id,
2166 handle.view_type,
2167 self.ref_counts.clone(),
2168 ))
2169 } else {
2170 None
2171 }
2172 }
2173}
2174
2175impl ReadView for AppContext {
2176 fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2177 if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
2178 view.as_any().downcast_ref().expect("downcast is type safe")
2179 } else {
2180 panic!("circular view reference for type {}", type_name::<T>());
2181 }
2182 }
2183}
2184
2185#[derive(Debug)]
2186pub enum ParentId {
2187 View(usize),
2188 Root,
2189}
2190
2191#[derive(Default, Clone)]
2192pub struct WindowInvalidation {
2193 pub updated: HashSet<usize>,
2194 pub removed: Vec<usize>,
2195}
2196
2197pub enum Effect {
2198 Subscription {
2199 entity_id: usize,
2200 subscription_id: usize,
2201 callback: SubscriptionCallback,
2202 },
2203 Event {
2204 entity_id: usize,
2205 payload: Box<dyn Any>,
2206 },
2207 GlobalSubscription {
2208 type_id: TypeId,
2209 subscription_id: usize,
2210 callback: GlobalSubscriptionCallback,
2211 },
2212 GlobalEvent {
2213 payload: Box<dyn Any>,
2214 },
2215 Observation {
2216 entity_id: usize,
2217 subscription_id: usize,
2218 callback: ObservationCallback,
2219 },
2220 ModelNotification {
2221 model_id: usize,
2222 },
2223 ViewNotification {
2224 window_id: usize,
2225 view_id: usize,
2226 },
2227 Deferred {
2228 callback: Box<dyn FnOnce(&mut AppContext)>,
2229 after_window_update: bool,
2230 },
2231 GlobalNotification {
2232 type_id: TypeId,
2233 },
2234 ModelRelease {
2235 model_id: usize,
2236 model: Box<dyn AnyModel>,
2237 },
2238 ViewRelease {
2239 view_id: usize,
2240 view: Box<dyn AnyView>,
2241 },
2242 Focus {
2243 window_id: usize,
2244 view_id: Option<usize>,
2245 },
2246 FocusObservation {
2247 view_id: usize,
2248 subscription_id: usize,
2249 callback: FocusObservationCallback,
2250 },
2251 ResizeWindow {
2252 window_id: usize,
2253 },
2254 MoveWindow {
2255 window_id: usize,
2256 },
2257 ActivateWindow {
2258 window_id: usize,
2259 is_active: bool,
2260 },
2261 WindowActivationObservation {
2262 window_id: usize,
2263 subscription_id: usize,
2264 callback: WindowActivationCallback,
2265 },
2266 FullscreenWindow {
2267 window_id: usize,
2268 is_fullscreen: bool,
2269 },
2270 WindowFullscreenObservation {
2271 window_id: usize,
2272 subscription_id: usize,
2273 callback: WindowFullscreenCallback,
2274 },
2275 WindowBoundsObservation {
2276 window_id: usize,
2277 subscription_id: usize,
2278 callback: WindowBoundsCallback,
2279 },
2280 Keystroke {
2281 window_id: usize,
2282 keystroke: Keystroke,
2283 handled_by: Option<Box<dyn Action>>,
2284 result: MatchResult,
2285 },
2286 RefreshWindows,
2287 DispatchActionFrom {
2288 window_id: usize,
2289 view_id: usize,
2290 action: Box<dyn Action>,
2291 },
2292 ActionDispatchNotification {
2293 action_id: TypeId,
2294 },
2295 WindowShouldCloseSubscription {
2296 window_id: usize,
2297 callback: WindowShouldCloseSubscriptionCallback,
2298 },
2299 ActiveLabeledTasksChanged,
2300 ActiveLabeledTasksObservation {
2301 subscription_id: usize,
2302 callback: ActiveLabeledTasksCallback,
2303 },
2304}
2305
2306impl Debug for Effect {
2307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2308 match self {
2309 Effect::Subscription {
2310 entity_id,
2311 subscription_id,
2312 ..
2313 } => f
2314 .debug_struct("Effect::Subscribe")
2315 .field("entity_id", entity_id)
2316 .field("subscription_id", subscription_id)
2317 .finish(),
2318 Effect::Event { entity_id, .. } => f
2319 .debug_struct("Effect::Event")
2320 .field("entity_id", entity_id)
2321 .finish(),
2322 Effect::GlobalSubscription {
2323 type_id,
2324 subscription_id,
2325 ..
2326 } => f
2327 .debug_struct("Effect::Subscribe")
2328 .field("type_id", type_id)
2329 .field("subscription_id", subscription_id)
2330 .finish(),
2331 Effect::GlobalEvent { payload, .. } => f
2332 .debug_struct("Effect::GlobalEvent")
2333 .field("type_id", &(&*payload).type_id())
2334 .finish(),
2335 Effect::Observation {
2336 entity_id,
2337 subscription_id,
2338 ..
2339 } => f
2340 .debug_struct("Effect::Observation")
2341 .field("entity_id", entity_id)
2342 .field("subscription_id", subscription_id)
2343 .finish(),
2344 Effect::ModelNotification { model_id } => f
2345 .debug_struct("Effect::ModelNotification")
2346 .field("model_id", model_id)
2347 .finish(),
2348 Effect::ViewNotification { window_id, view_id } => f
2349 .debug_struct("Effect::ViewNotification")
2350 .field("window_id", window_id)
2351 .field("view_id", view_id)
2352 .finish(),
2353 Effect::GlobalNotification { type_id } => f
2354 .debug_struct("Effect::GlobalNotification")
2355 .field("type_id", type_id)
2356 .finish(),
2357 Effect::Deferred { .. } => f.debug_struct("Effect::Deferred").finish(),
2358 Effect::ModelRelease { model_id, .. } => f
2359 .debug_struct("Effect::ModelRelease")
2360 .field("model_id", model_id)
2361 .finish(),
2362 Effect::ViewRelease { view_id, .. } => f
2363 .debug_struct("Effect::ViewRelease")
2364 .field("view_id", view_id)
2365 .finish(),
2366 Effect::Focus { window_id, view_id } => f
2367 .debug_struct("Effect::Focus")
2368 .field("window_id", window_id)
2369 .field("view_id", view_id)
2370 .finish(),
2371 Effect::FocusObservation {
2372 view_id,
2373 subscription_id,
2374 ..
2375 } => f
2376 .debug_struct("Effect::FocusObservation")
2377 .field("view_id", view_id)
2378 .field("subscription_id", subscription_id)
2379 .finish(),
2380 Effect::DispatchActionFrom {
2381 window_id, view_id, ..
2382 } => f
2383 .debug_struct("Effect::DispatchActionFrom")
2384 .field("window_id", window_id)
2385 .field("view_id", view_id)
2386 .finish(),
2387 Effect::ActionDispatchNotification { action_id, .. } => f
2388 .debug_struct("Effect::ActionDispatchNotification")
2389 .field("action_id", action_id)
2390 .finish(),
2391 Effect::ResizeWindow { window_id } => f
2392 .debug_struct("Effect::RefreshWindow")
2393 .field("window_id", window_id)
2394 .finish(),
2395 Effect::MoveWindow { window_id } => f
2396 .debug_struct("Effect::MoveWindow")
2397 .field("window_id", window_id)
2398 .finish(),
2399 Effect::WindowActivationObservation {
2400 window_id,
2401 subscription_id,
2402 ..
2403 } => f
2404 .debug_struct("Effect::WindowActivationObservation")
2405 .field("window_id", window_id)
2406 .field("subscription_id", subscription_id)
2407 .finish(),
2408 Effect::ActivateWindow {
2409 window_id,
2410 is_active,
2411 } => f
2412 .debug_struct("Effect::ActivateWindow")
2413 .field("window_id", window_id)
2414 .field("is_active", is_active)
2415 .finish(),
2416 Effect::FullscreenWindow {
2417 window_id,
2418 is_fullscreen,
2419 } => f
2420 .debug_struct("Effect::FullscreenWindow")
2421 .field("window_id", window_id)
2422 .field("is_fullscreen", is_fullscreen)
2423 .finish(),
2424 Effect::WindowFullscreenObservation {
2425 window_id,
2426 subscription_id,
2427 callback: _,
2428 } => f
2429 .debug_struct("Effect::WindowFullscreenObservation")
2430 .field("window_id", window_id)
2431 .field("subscription_id", subscription_id)
2432 .finish(),
2433
2434 Effect::WindowBoundsObservation {
2435 window_id,
2436 subscription_id,
2437 callback: _,
2438 } => f
2439 .debug_struct("Effect::WindowBoundsObservation")
2440 .field("window_id", window_id)
2441 .field("subscription_id", subscription_id)
2442 .finish(),
2443 Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
2444 Effect::WindowShouldCloseSubscription { window_id, .. } => f
2445 .debug_struct("Effect::WindowShouldCloseSubscription")
2446 .field("window_id", window_id)
2447 .finish(),
2448 Effect::Keystroke {
2449 window_id,
2450 keystroke,
2451 handled_by,
2452 result,
2453 } => f
2454 .debug_struct("Effect::Keystroke")
2455 .field("window_id", window_id)
2456 .field("keystroke", keystroke)
2457 .field(
2458 "keystroke",
2459 &handled_by.as_ref().map(|handled_by| handled_by.name()),
2460 )
2461 .field("result", result)
2462 .finish(),
2463 Effect::ActiveLabeledTasksChanged => {
2464 f.debug_struct("Effect::ActiveLabeledTasksChanged").finish()
2465 }
2466 Effect::ActiveLabeledTasksObservation {
2467 subscription_id,
2468 callback: _,
2469 } => f
2470 .debug_struct("Effect::ActiveLabeledTasksObservation")
2471 .field("subscription_id", subscription_id)
2472 .finish(),
2473 }
2474 }
2475}
2476
2477pub trait AnyModel {
2478 fn as_any(&self) -> &dyn Any;
2479 fn as_any_mut(&mut self) -> &mut dyn Any;
2480 fn release(&mut self, cx: &mut AppContext);
2481 fn app_will_quit(
2482 &mut self,
2483 cx: &mut AppContext,
2484 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2485}
2486
2487impl<T> AnyModel for T
2488where
2489 T: Entity,
2490{
2491 fn as_any(&self) -> &dyn Any {
2492 self
2493 }
2494
2495 fn as_any_mut(&mut self) -> &mut dyn Any {
2496 self
2497 }
2498
2499 fn release(&mut self, cx: &mut AppContext) {
2500 self.release(cx);
2501 }
2502
2503 fn app_will_quit(
2504 &mut self,
2505 cx: &mut AppContext,
2506 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2507 self.app_will_quit(cx)
2508 }
2509}
2510
2511pub trait AnyView {
2512 fn as_any(&self) -> &dyn Any;
2513 fn as_any_mut(&mut self) -> &mut dyn Any;
2514 fn release(&mut self, cx: &mut AppContext);
2515 fn app_will_quit(
2516 &mut self,
2517 cx: &mut AppContext,
2518 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2519 fn ui_name(&self) -> &'static str;
2520 fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement>;
2521 fn focus_in<'a, 'b>(&mut self, focused_id: usize, cx: &mut WindowContext<'a>, view_id: usize);
2522 fn focus_out(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize);
2523 fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool;
2524 fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool;
2525 fn modifiers_changed(
2526 &mut self,
2527 event: &ModifiersChangedEvent,
2528 cx: &mut WindowContext,
2529 view_id: usize,
2530 ) -> bool;
2531 fn keymap_context(&self, cx: &AppContext) -> KeymapContext;
2532 fn debug_json(&self, cx: &WindowContext) -> serde_json::Value;
2533
2534 fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String>;
2535 fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
2536 fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
2537 fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize);
2538 fn replace_text_in_range(
2539 &mut self,
2540 range: Option<Range<usize>>,
2541 text: &str,
2542 cx: &mut WindowContext,
2543 view_id: usize,
2544 );
2545 fn replace_and_mark_text_in_range(
2546 &mut self,
2547 range: Option<Range<usize>>,
2548 new_text: &str,
2549 new_selected_range: Option<Range<usize>>,
2550 cx: &mut WindowContext,
2551 view_id: usize,
2552 );
2553 fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle {
2554 AnyViewHandle::new(
2555 window_id,
2556 view_id,
2557 self.as_any().type_id(),
2558 cx.ref_counts.clone(),
2559 )
2560 }
2561}
2562
2563impl<V> AnyView for V
2564where
2565 V: View,
2566{
2567 fn as_any(&self) -> &dyn Any {
2568 self
2569 }
2570
2571 fn as_any_mut(&mut self) -> &mut dyn Any {
2572 self
2573 }
2574
2575 fn release(&mut self, cx: &mut AppContext) {
2576 self.release(cx);
2577 }
2578
2579 fn app_will_quit(
2580 &mut self,
2581 cx: &mut AppContext,
2582 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2583 self.app_will_quit(cx)
2584 }
2585
2586 fn ui_name(&self) -> &'static str {
2587 V::ui_name()
2588 }
2589
2590 fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement> {
2591 let mut view_context = ViewContext::mutable(cx, view_id);
2592 let element = V::render(self, &mut view_context);
2593 let view = WeakViewHandle::new(cx.window_id, view_id);
2594 Box::new(RootElement::new(element, view))
2595 }
2596
2597 fn focus_in(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize) {
2598 let mut cx = ViewContext::mutable(cx, view_id);
2599 let focused_view_handle: AnyViewHandle = if view_id == focused_id {
2600 cx.handle().into_any()
2601 } else {
2602 let focused_type = cx
2603 .views
2604 .get(&(cx.window_id, focused_id))
2605 .unwrap()
2606 .as_any()
2607 .type_id();
2608 AnyViewHandle::new(
2609 cx.window_id,
2610 focused_id,
2611 focused_type,
2612 cx.ref_counts.clone(),
2613 )
2614 };
2615 View::focus_in(self, focused_view_handle, &mut cx);
2616 }
2617
2618 fn focus_out(&mut self, blurred_id: usize, cx: &mut WindowContext, view_id: usize) {
2619 let mut cx = ViewContext::mutable(cx, view_id);
2620 let blurred_view_handle: AnyViewHandle = if view_id == blurred_id {
2621 cx.handle().into_any()
2622 } else {
2623 let blurred_type = cx
2624 .views
2625 .get(&(cx.window_id, blurred_id))
2626 .unwrap()
2627 .as_any()
2628 .type_id();
2629 AnyViewHandle::new(
2630 cx.window_id,
2631 blurred_id,
2632 blurred_type,
2633 cx.ref_counts.clone(),
2634 )
2635 };
2636 View::focus_out(self, blurred_view_handle, &mut cx);
2637 }
2638
2639 fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool {
2640 let mut cx = ViewContext::mutable(cx, view_id);
2641 View::key_down(self, event, &mut cx)
2642 }
2643
2644 fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool {
2645 let mut cx = ViewContext::mutable(cx, view_id);
2646 View::key_up(self, event, &mut cx)
2647 }
2648
2649 fn modifiers_changed(
2650 &mut self,
2651 event: &ModifiersChangedEvent,
2652 cx: &mut WindowContext,
2653 view_id: usize,
2654 ) -> bool {
2655 let mut cx = ViewContext::mutable(cx, view_id);
2656 View::modifiers_changed(self, event, &mut cx)
2657 }
2658
2659 fn keymap_context(&self, cx: &AppContext) -> KeymapContext {
2660 View::keymap_context(self, cx)
2661 }
2662
2663 fn debug_json(&self, cx: &WindowContext) -> serde_json::Value {
2664 View::debug_json(self, cx)
2665 }
2666
2667 fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String> {
2668 View::text_for_range(self, range, cx)
2669 }
2670
2671 fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
2672 View::selected_text_range(self, cx)
2673 }
2674
2675 fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
2676 View::marked_text_range(self, cx)
2677 }
2678
2679 fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize) {
2680 let mut cx = ViewContext::mutable(cx, view_id);
2681 View::unmark_text(self, &mut cx)
2682 }
2683
2684 fn replace_text_in_range(
2685 &mut self,
2686 range: Option<Range<usize>>,
2687 text: &str,
2688 cx: &mut WindowContext,
2689 view_id: usize,
2690 ) {
2691 let mut cx = ViewContext::mutable(cx, view_id);
2692 View::replace_text_in_range(self, range, text, &mut cx)
2693 }
2694
2695 fn replace_and_mark_text_in_range(
2696 &mut self,
2697 range: Option<Range<usize>>,
2698 new_text: &str,
2699 new_selected_range: Option<Range<usize>>,
2700 cx: &mut WindowContext,
2701 view_id: usize,
2702 ) {
2703 let mut cx = ViewContext::mutable(cx, view_id);
2704 View::replace_and_mark_text_in_range(self, range, new_text, new_selected_range, &mut cx)
2705 }
2706}
2707
2708pub struct ModelContext<'a, T: ?Sized> {
2709 app: &'a mut AppContext,
2710 model_id: usize,
2711 model_type: PhantomData<T>,
2712 halt_stream: bool,
2713}
2714
2715impl<'a, T: Entity> ModelContext<'a, T> {
2716 fn new(app: &'a mut AppContext, model_id: usize) -> Self {
2717 Self {
2718 app,
2719 model_id,
2720 model_type: PhantomData,
2721 halt_stream: false,
2722 }
2723 }
2724
2725 pub fn background(&self) -> &Arc<executor::Background> {
2726 &self.app.background
2727 }
2728
2729 pub fn halt_stream(&mut self) {
2730 self.halt_stream = true;
2731 }
2732
2733 pub fn model_id(&self) -> usize {
2734 self.model_id
2735 }
2736
2737 pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2738 where
2739 S: Entity,
2740 F: FnOnce(&mut ModelContext<S>) -> S,
2741 {
2742 self.app.add_model(build_model)
2743 }
2744
2745 pub fn emit(&mut self, payload: T::Event) {
2746 self.app.pending_effects.push_back(Effect::Event {
2747 entity_id: self.model_id,
2748 payload: Box::new(payload),
2749 });
2750 }
2751
2752 pub fn notify(&mut self) {
2753 self.app.notify_model(self.model_id);
2754 }
2755
2756 pub fn subscribe<S: Entity, F>(
2757 &mut self,
2758 handle: &ModelHandle<S>,
2759 mut callback: F,
2760 ) -> Subscription
2761 where
2762 S::Event: 'static,
2763 F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
2764 {
2765 let subscriber = self.weak_handle();
2766 self.app
2767 .subscribe_internal(handle, move |emitter, event, cx| {
2768 if let Some(subscriber) = subscriber.upgrade(cx) {
2769 subscriber.update(cx, |subscriber, cx| {
2770 callback(subscriber, emitter, event, cx);
2771 });
2772 true
2773 } else {
2774 false
2775 }
2776 })
2777 }
2778
2779 pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
2780 where
2781 S: Entity,
2782 F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
2783 {
2784 let observer = self.weak_handle();
2785 self.app.observe_internal(handle, move |observed, cx| {
2786 if let Some(observer) = observer.upgrade(cx) {
2787 observer.update(cx, |observer, cx| {
2788 callback(observer, observed, cx);
2789 });
2790 true
2791 } else {
2792 false
2793 }
2794 })
2795 }
2796
2797 pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
2798 where
2799 G: Any,
2800 F: 'static + FnMut(&mut T, &mut ModelContext<T>),
2801 {
2802 let observer = self.weak_handle();
2803 self.app.observe_global::<G, _>(move |cx| {
2804 if let Some(observer) = observer.upgrade(cx) {
2805 observer.update(cx, |observer, cx| callback(observer, cx));
2806 }
2807 })
2808 }
2809
2810 pub fn observe_release<S, F>(
2811 &mut self,
2812 handle: &ModelHandle<S>,
2813 mut callback: F,
2814 ) -> Subscription
2815 where
2816 S: Entity,
2817 F: 'static + FnMut(&mut T, &S, &mut ModelContext<T>),
2818 {
2819 let observer = self.weak_handle();
2820 self.app.observe_release(handle, move |released, cx| {
2821 if let Some(observer) = observer.upgrade(cx) {
2822 observer.update(cx, |observer, cx| {
2823 callback(observer, released, cx);
2824 });
2825 }
2826 })
2827 }
2828
2829 pub fn handle(&self) -> ModelHandle<T> {
2830 ModelHandle::new(self.model_id, &self.app.ref_counts)
2831 }
2832
2833 pub fn weak_handle(&self) -> WeakModelHandle<T> {
2834 WeakModelHandle::new(self.model_id)
2835 }
2836
2837 pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
2838 where
2839 F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
2840 Fut: 'static + Future<Output = S>,
2841 S: 'static,
2842 {
2843 let handle = self.handle();
2844 self.app.spawn(|cx| f(handle, cx))
2845 }
2846
2847 pub fn spawn_weak<F, Fut, S>(&mut self, f: F) -> Task<S>
2848 where
2849 F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
2850 Fut: 'static + Future<Output = S>,
2851 S: 'static,
2852 {
2853 let handle = self.weak_handle();
2854 self.app.spawn(|cx| f(handle, cx))
2855 }
2856}
2857
2858impl<M> AsRef<AppContext> for ModelContext<'_, M> {
2859 fn as_ref(&self) -> &AppContext {
2860 &self.app
2861 }
2862}
2863
2864impl<M> AsMut<AppContext> for ModelContext<'_, M> {
2865 fn as_mut(&mut self) -> &mut AppContext {
2866 self.app
2867 }
2868}
2869
2870impl<M> ReadModel for ModelContext<'_, M> {
2871 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2872 self.app.read_model(handle)
2873 }
2874}
2875
2876impl<M> UpdateModel for ModelContext<'_, M> {
2877 fn update_model<T: Entity, V>(
2878 &mut self,
2879 handle: &ModelHandle<T>,
2880 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2881 ) -> V {
2882 self.app.update_model(handle, update)
2883 }
2884}
2885
2886impl<M> UpgradeModelHandle for ModelContext<'_, M> {
2887 fn upgrade_model_handle<T: Entity>(
2888 &self,
2889 handle: &WeakModelHandle<T>,
2890 ) -> Option<ModelHandle<T>> {
2891 self.app.upgrade_model_handle(handle)
2892 }
2893
2894 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2895 self.app.model_handle_is_upgradable(handle)
2896 }
2897
2898 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2899 self.app.upgrade_any_model_handle(handle)
2900 }
2901}
2902
2903impl<M> Deref for ModelContext<'_, M> {
2904 type Target = AppContext;
2905
2906 fn deref(&self) -> &Self::Target {
2907 self.app
2908 }
2909}
2910
2911impl<M> DerefMut for ModelContext<'_, M> {
2912 fn deref_mut(&mut self) -> &mut Self::Target {
2913 &mut self.app
2914 }
2915}
2916
2917pub struct ViewContext<'a, 'b, T: ?Sized> {
2918 window_context: Reference<'b, WindowContext<'a>>,
2919 view_id: usize,
2920 view_type: PhantomData<T>,
2921}
2922
2923impl<'a, 'b, T: View> Deref for ViewContext<'a, 'b, T> {
2924 type Target = WindowContext<'a>;
2925
2926 fn deref(&self) -> &Self::Target {
2927 &self.window_context
2928 }
2929}
2930
2931impl<T: View> DerefMut for ViewContext<'_, '_, T> {
2932 fn deref_mut(&mut self) -> &mut Self::Target {
2933 &mut self.window_context
2934 }
2935}
2936
2937impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
2938 pub(crate) fn mutable(window_context: &'b mut WindowContext<'a>, view_id: usize) -> Self {
2939 Self {
2940 window_context: Reference::Mutable(window_context),
2941 view_id,
2942 view_type: PhantomData,
2943 }
2944 }
2945
2946 pub(crate) fn immutable(window_context: &'b WindowContext<'a>, view_id: usize) -> Self {
2947 Self {
2948 window_context: Reference::Immutable(window_context),
2949 view_id,
2950 view_type: PhantomData,
2951 }
2952 }
2953
2954 pub fn window_context(&mut self) -> &mut WindowContext<'a> {
2955 &mut self.window_context
2956 }
2957
2958 pub fn handle(&self) -> ViewHandle<V> {
2959 ViewHandle::new(
2960 self.window_id,
2961 self.view_id,
2962 &self.window_context.ref_counts,
2963 )
2964 }
2965
2966 pub fn weak_handle(&self) -> WeakViewHandle<V> {
2967 WeakViewHandle::new(self.window_id, self.view_id)
2968 }
2969
2970 pub fn parent(&self) -> Option<usize> {
2971 self.window_context.parent(self.view_id)
2972 }
2973
2974 pub fn window_id(&self) -> usize {
2975 self.window_id
2976 }
2977
2978 pub fn view_id(&self) -> usize {
2979 self.view_id
2980 }
2981
2982 pub fn foreground(&self) -> &Rc<executor::Foreground> {
2983 self.window_context.foreground()
2984 }
2985
2986 pub fn background_executor(&self) -> &Arc<executor::Background> {
2987 &self.window_context.background
2988 }
2989
2990 pub fn platform(&self) -> &Arc<dyn Platform> {
2991 self.window_context.platform()
2992 }
2993
2994 pub fn prompt_for_paths(
2995 &self,
2996 options: PathPromptOptions,
2997 ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
2998 self.window_context.prompt_for_paths(options)
2999 }
3000
3001 pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
3002 self.window_context.prompt_for_new_path(directory)
3003 }
3004
3005 pub fn reveal_path(&self, path: &Path) {
3006 self.window_context.reveal_path(path)
3007 }
3008
3009 pub fn focus(&mut self, handle: &AnyViewHandle) {
3010 self.window_context
3011 .focus(handle.window_id, Some(handle.view_id));
3012 }
3013
3014 pub fn focus_self(&mut self) {
3015 let window_id = self.window_id;
3016 let view_id = self.view_id;
3017 self.window_context.focus(window_id, Some(view_id));
3018 }
3019
3020 pub fn is_self_focused(&self) -> bool {
3021 self.window.focused_view_id == Some(self.view_id)
3022 }
3023
3024 pub fn is_parent_view_focused(&self) -> bool {
3025 if let Some(parent_view_id) = self.ancestors(self.view_id).next().clone() {
3026 self.focused_view_id() == Some(parent_view_id)
3027 } else {
3028 false
3029 }
3030 }
3031
3032 pub fn focus_parent_view(&mut self) {
3033 let next = self.ancestors(self.view_id).next().clone();
3034 if let Some(parent_view_id) = next {
3035 let window_id = self.window_id;
3036 self.window_context.focus(window_id, Some(parent_view_id));
3037 }
3038 }
3039
3040 pub fn is_child(&self, view: impl Into<AnyViewHandle>) -> bool {
3041 let view = view.into();
3042 if self.window_id != view.window_id {
3043 return false;
3044 }
3045 self.ancestors(view.view_id)
3046 .skip(1) // Skip self id
3047 .any(|parent| parent == self.view_id)
3048 }
3049
3050 pub fn blur(&mut self) {
3051 let window_id = self.window_id;
3052 self.window_context.focus(window_id, None);
3053 }
3054
3055 pub fn on_window_should_close<F>(&mut self, mut callback: F)
3056 where
3057 F: 'static + FnMut(&mut V, &mut ViewContext<V>) -> bool,
3058 {
3059 let window_id = self.window_id;
3060 let view = self.weak_handle();
3061 self.pending_effects
3062 .push_back(Effect::WindowShouldCloseSubscription {
3063 window_id,
3064 callback: Box::new(move |cx| {
3065 cx.update_window(window_id, |cx| {
3066 if let Some(view) = view.upgrade(cx) {
3067 view.update(cx, |view, cx| callback(view, cx))
3068 } else {
3069 true
3070 }
3071 })
3072 .unwrap_or(true)
3073 }),
3074 });
3075 }
3076
3077 pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
3078 where
3079 S: View,
3080 F: FnOnce(&mut ViewContext<S>) -> S,
3081 {
3082 self.window_context
3083 .build_and_insert_view(ParentId::View(self.view_id), |cx| Some(build_view(cx)))
3084 .unwrap()
3085 }
3086
3087 pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
3088 where
3089 S: View,
3090 F: FnOnce(&mut ViewContext<S>) -> Option<S>,
3091 {
3092 self.window_context
3093 .build_and_insert_view(ParentId::View(self.view_id), build_view)
3094 }
3095
3096 pub fn reparent(&mut self, view_handle: &AnyViewHandle) {
3097 if self.window_id != view_handle.window_id {
3098 panic!("Can't reparent view to a view from a different window");
3099 }
3100 self.parents
3101 .remove(&(view_handle.window_id, view_handle.view_id));
3102 let new_parent_id = self.view_id;
3103 self.parents.insert(
3104 (view_handle.window_id, view_handle.view_id),
3105 ParentId::View(new_parent_id),
3106 );
3107 }
3108
3109 pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3110 where
3111 E: Entity,
3112 E::Event: 'static,
3113 H: Handle<E>,
3114 F: 'static + FnMut(&mut V, H, &E::Event, &mut ViewContext<V>),
3115 {
3116 let subscriber = self.weak_handle();
3117 self.window_context
3118 .subscribe_internal(handle, move |emitter, event, cx| {
3119 if let Some(subscriber) = subscriber.upgrade(cx) {
3120 subscriber.update(cx, |subscriber, cx| {
3121 callback(subscriber, emitter, event, cx);
3122 });
3123 true
3124 } else {
3125 false
3126 }
3127 })
3128 }
3129
3130 pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3131 where
3132 E: Entity,
3133 H: Handle<E>,
3134 F: 'static + FnMut(&mut V, H, &mut ViewContext<V>),
3135 {
3136 let window_id = self.window_id;
3137 let observer = self.weak_handle();
3138 self.window_context
3139 .observe_internal(handle, move |observed, cx| {
3140 cx.update_window(window_id, |cx| {
3141 if let Some(observer) = observer.upgrade(cx) {
3142 observer.update(cx, |observer, cx| {
3143 callback(observer, observed, cx);
3144 });
3145 true
3146 } else {
3147 false
3148 }
3149 })
3150 .unwrap_or(false)
3151 })
3152 }
3153
3154 pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
3155 where
3156 G: Any,
3157 F: 'static + FnMut(&mut V, &mut ViewContext<V>),
3158 {
3159 let window_id = self.window_id;
3160 let observer = self.weak_handle();
3161 self.window_context.observe_global::<G, _>(move |cx| {
3162 cx.update_window(window_id, |cx| {
3163 if let Some(observer) = observer.upgrade(cx) {
3164 observer.update(cx, |observer, cx| callback(observer, cx));
3165 }
3166 });
3167 })
3168 }
3169
3170 pub fn observe_focus<F, W>(&mut self, handle: &ViewHandle<W>, mut callback: F) -> Subscription
3171 where
3172 F: 'static + FnMut(&mut V, ViewHandle<W>, bool, &mut ViewContext<V>),
3173 W: View,
3174 {
3175 let observer = self.weak_handle();
3176 self.window_context
3177 .observe_focus(handle, move |observed, focused, cx| {
3178 if let Some(observer) = observer.upgrade(cx) {
3179 observer.update(cx, |observer, cx| {
3180 callback(observer, observed, focused, cx);
3181 });
3182 true
3183 } else {
3184 false
3185 }
3186 })
3187 }
3188
3189 pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3190 where
3191 E: Entity,
3192 H: Handle<E>,
3193 F: 'static + FnMut(&mut V, &E, &mut ViewContext<V>),
3194 {
3195 let window_id = self.window_id;
3196 let observer = self.weak_handle();
3197 self.window_context
3198 .observe_release(handle, move |released, cx| {
3199 cx.update_window(window_id, |cx| {
3200 if let Some(observer) = observer.upgrade(cx) {
3201 observer.update(cx, |observer, cx| {
3202 callback(observer, released, cx);
3203 });
3204 }
3205 });
3206 })
3207 }
3208
3209 pub fn observe_actions<F>(&mut self, mut callback: F) -> Subscription
3210 where
3211 F: 'static + FnMut(&mut V, TypeId, &mut ViewContext<V>),
3212 {
3213 let window_id = self.window_id;
3214 let observer = self.weak_handle();
3215 self.window_context.observe_actions(move |action_id, cx| {
3216 cx.update_window(window_id, |cx| {
3217 if let Some(observer) = observer.upgrade(cx) {
3218 observer.update(cx, |observer, cx| {
3219 callback(observer, action_id, cx);
3220 });
3221 }
3222 });
3223 })
3224 }
3225
3226 pub fn observe_window_activation<F>(&mut self, mut callback: F) -> Subscription
3227 where
3228 F: 'static + FnMut(&mut V, bool, &mut ViewContext<V>),
3229 {
3230 let observer = self.weak_handle();
3231 self.window_context
3232 .observe_window_activation(move |active, cx| {
3233 if let Some(observer) = observer.upgrade(cx) {
3234 observer.update(cx, |observer, cx| {
3235 callback(observer, active, cx);
3236 });
3237 true
3238 } else {
3239 false
3240 }
3241 })
3242 }
3243
3244 pub fn observe_fullscreen<F>(&mut self, mut callback: F) -> Subscription
3245 where
3246 F: 'static + FnMut(&mut V, bool, &mut ViewContext<V>),
3247 {
3248 let observer = self.weak_handle();
3249 self.window_context.observe_fullscreen(move |active, cx| {
3250 if let Some(observer) = observer.upgrade(cx) {
3251 observer.update(cx, |observer, cx| {
3252 callback(observer, active, cx);
3253 });
3254 true
3255 } else {
3256 false
3257 }
3258 })
3259 }
3260
3261 pub fn observe_keystrokes<F>(&mut self, mut callback: F) -> Subscription
3262 where
3263 F: 'static
3264 + FnMut(
3265 &mut V,
3266 &Keystroke,
3267 Option<&Box<dyn Action>>,
3268 &MatchResult,
3269 &mut ViewContext<V>,
3270 ) -> bool,
3271 {
3272 let observer = self.weak_handle();
3273 self.window_context
3274 .observe_keystrokes(move |keystroke, result, handled_by, cx| {
3275 if let Some(observer) = observer.upgrade(cx) {
3276 observer.update(cx, |observer, cx| {
3277 callback(observer, keystroke, handled_by, result, cx);
3278 });
3279 true
3280 } else {
3281 false
3282 }
3283 })
3284 }
3285
3286 pub fn observe_window_bounds<F>(&mut self, mut callback: F) -> Subscription
3287 where
3288 F: 'static + FnMut(&mut V, WindowBounds, Uuid, &mut ViewContext<V>),
3289 {
3290 let observer = self.weak_handle();
3291 self.window_context
3292 .observe_window_bounds(move |bounds, display, cx| {
3293 if let Some(observer) = observer.upgrade(cx) {
3294 observer.update(cx, |observer, cx| {
3295 callback(observer, bounds, display, cx);
3296 });
3297 true
3298 } else {
3299 false
3300 }
3301 })
3302 }
3303
3304 pub fn observe_active_labeled_tasks<F>(&mut self, mut callback: F) -> Subscription
3305 where
3306 F: 'static + FnMut(&mut V, &mut ViewContext<V>),
3307 {
3308 let window_id = self.window_id;
3309 let observer = self.weak_handle();
3310 self.window_context.observe_active_labeled_tasks(move |cx| {
3311 cx.update_window(window_id, |cx| {
3312 if let Some(observer) = observer.upgrade(cx) {
3313 observer.update(cx, |observer, cx| {
3314 callback(observer, cx);
3315 });
3316 true
3317 } else {
3318 false
3319 }
3320 })
3321 .unwrap_or(false)
3322 })
3323 }
3324
3325 pub fn emit(&mut self, payload: V::Event) {
3326 self.window_context
3327 .pending_effects
3328 .push_back(Effect::Event {
3329 entity_id: self.view_id,
3330 payload: Box::new(payload),
3331 });
3332 }
3333
3334 pub fn notify(&mut self) {
3335 let window_id = self.window_id;
3336 let view_id = self.view_id;
3337 self.window_context.notify_view(window_id, view_id);
3338 }
3339
3340 pub fn dispatch_action(&mut self, action: impl Action) {
3341 let window_id = self.window_id;
3342 let view_id = self.view_id;
3343 self.window_context
3344 .dispatch_action_at(window_id, view_id, action)
3345 }
3346
3347 pub fn dispatch_any_action(&mut self, action: Box<dyn Action>) {
3348 let window_id = self.window_id;
3349 let view_id = self.view_id;
3350 self.window_context
3351 .dispatch_any_action_at(window_id, view_id, action)
3352 }
3353
3354 pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
3355 let handle = self.handle();
3356 self.window_context
3357 .defer(move |cx| handle.update(cx, |view, cx| callback(view, cx)))
3358 }
3359
3360 pub fn after_window_update(
3361 &mut self,
3362 callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>),
3363 ) {
3364 let window_id = self.window_id;
3365 let handle = self.handle();
3366 self.window_context.after_window_update(move |cx| {
3367 cx.update_window(window_id, |cx| {
3368 handle.update(cx, |view, cx| {
3369 callback(view, cx);
3370 })
3371 });
3372 })
3373 }
3374
3375 pub fn propagate_action(&mut self) {
3376 self.window_context.halt_action_dispatch = false;
3377 }
3378
3379 pub fn spawn_labeled<F, Fut, S>(&mut self, task_label: &'static str, f: F) -> Task<S>
3380 where
3381 F: FnOnce(ViewHandle<V>, AsyncAppContext) -> Fut,
3382 Fut: 'static + Future<Output = S>,
3383 S: 'static,
3384 {
3385 let handle = self.handle();
3386 self.window_context
3387 .spawn_labeled(task_label, |cx| f(handle, cx))
3388 }
3389
3390 pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
3391 where
3392 F: FnOnce(ViewHandle<V>, AsyncAppContext) -> Fut,
3393 Fut: 'static + Future<Output = S>,
3394 S: 'static,
3395 {
3396 let handle = self.handle();
3397 self.window_context.spawn(|cx| f(handle, cx))
3398 }
3399
3400 pub fn spawn_weak<F, Fut, S>(&mut self, f: F) -> Task<S>
3401 where
3402 F: FnOnce(WeakViewHandle<V>, AsyncAppContext) -> Fut,
3403 Fut: 'static + Future<Output = S>,
3404 S: 'static,
3405 {
3406 let handle = self.weak_handle();
3407 self.window_context.spawn(|cx| f(handle, cx))
3408 }
3409
3410 pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
3411 let region_id = MouseRegionId::new::<Tag>(self.view_id, region_id);
3412 MouseState {
3413 hovered: self.window.hovered_region_ids.contains(®ion_id),
3414 clicked: self
3415 .window
3416 .clicked_region_ids
3417 .get(®ion_id)
3418 .and_then(|_| self.window.clicked_button),
3419 accessed_hovered: false,
3420 accessed_clicked: false,
3421 }
3422 }
3423
3424 pub fn element_state<Tag: 'static, T: 'static>(
3425 &mut self,
3426 element_id: usize,
3427 initial: T,
3428 ) -> ElementStateHandle<T> {
3429 let id = ElementStateId {
3430 view_id: self.view_id(),
3431 element_id,
3432 tag: TypeId::of::<Tag>(),
3433 };
3434 self.element_states
3435 .entry(id)
3436 .or_insert_with(|| Box::new(initial));
3437 ElementStateHandle::new(id, self.frame_count, &self.ref_counts)
3438 }
3439
3440 pub fn default_element_state<Tag: 'static, T: 'static + Default>(
3441 &mut self,
3442 element_id: usize,
3443 ) -> ElementStateHandle<T> {
3444 self.element_state::<Tag, T>(element_id, T::default())
3445 }
3446}
3447
3448impl<V> UpgradeModelHandle for ViewContext<'_, '_, V> {
3449 fn upgrade_model_handle<T: Entity>(
3450 &self,
3451 handle: &WeakModelHandle<T>,
3452 ) -> Option<ModelHandle<T>> {
3453 self.window_context.upgrade_model_handle(handle)
3454 }
3455
3456 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3457 self.window_context.model_handle_is_upgradable(handle)
3458 }
3459
3460 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3461 self.window_context.upgrade_any_model_handle(handle)
3462 }
3463}
3464
3465impl<V> UpgradeViewHandle for ViewContext<'_, '_, V> {
3466 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3467 self.window_context.upgrade_view_handle(handle)
3468 }
3469
3470 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3471 self.window_context.upgrade_any_view_handle(handle)
3472 }
3473}
3474
3475impl<V: View> ReadModel for ViewContext<'_, '_, V> {
3476 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3477 self.window_context.read_model(handle)
3478 }
3479}
3480
3481impl<V: View> UpdateModel for ViewContext<'_, '_, V> {
3482 fn update_model<T: Entity, O>(
3483 &mut self,
3484 handle: &ModelHandle<T>,
3485 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3486 ) -> O {
3487 self.window_context.update_model(handle, update)
3488 }
3489}
3490
3491impl<V: View> ReadView for ViewContext<'_, '_, V> {
3492 fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3493 self.window_context.read_view(handle)
3494 }
3495}
3496
3497impl<V: View> UpdateView for ViewContext<'_, '_, V> {
3498 type Output<S> = S;
3499
3500 fn update_view<T, S>(
3501 &mut self,
3502 handle: &ViewHandle<T>,
3503 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3504 ) -> S
3505 where
3506 T: View,
3507 {
3508 self.window_context.update_view(handle, update)
3509 }
3510}
3511
3512pub struct EventContext<'a, 'b, 'c, V: View> {
3513 view_context: &'c mut ViewContext<'a, 'b, V>,
3514 pub(crate) handled: bool,
3515}
3516
3517impl<'a, 'b, 'c, V: View> EventContext<'a, 'b, 'c, V> {
3518 pub(crate) fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self {
3519 EventContext {
3520 view_context,
3521 handled: true,
3522 }
3523 }
3524
3525 pub fn propagate_event(&mut self) {
3526 self.handled = false;
3527 }
3528}
3529
3530impl<'a, 'b, 'c, V: View> Deref for EventContext<'a, 'b, 'c, V> {
3531 type Target = ViewContext<'a, 'b, V>;
3532
3533 fn deref(&self) -> &Self::Target {
3534 &self.view_context
3535 }
3536}
3537
3538impl<V: View> DerefMut for EventContext<'_, '_, '_, V> {
3539 fn deref_mut(&mut self) -> &mut Self::Target {
3540 &mut self.view_context
3541 }
3542}
3543
3544impl<V: View> UpdateModel for EventContext<'_, '_, '_, V> {
3545 fn update_model<T: Entity, O>(
3546 &mut self,
3547 handle: &ModelHandle<T>,
3548 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3549 ) -> O {
3550 self.view_context.update_model(handle, update)
3551 }
3552}
3553
3554impl<V: View> ReadView for EventContext<'_, '_, '_, V> {
3555 fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
3556 self.view_context.read_view(handle)
3557 }
3558}
3559
3560impl<V: View> UpdateView for EventContext<'_, '_, '_, V> {
3561 type Output<S> = S;
3562
3563 fn update_view<T, S>(
3564 &mut self,
3565 handle: &ViewHandle<T>,
3566 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3567 ) -> S
3568 where
3569 T: View,
3570 {
3571 self.view_context.update_view(handle, update)
3572 }
3573}
3574
3575impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, V> {
3576 fn upgrade_model_handle<T: Entity>(
3577 &self,
3578 handle: &WeakModelHandle<T>,
3579 ) -> Option<ModelHandle<T>> {
3580 self.view_context.upgrade_model_handle(handle)
3581 }
3582
3583 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3584 self.view_context.model_handle_is_upgradable(handle)
3585 }
3586
3587 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3588 self.view_context.upgrade_any_model_handle(handle)
3589 }
3590}
3591
3592impl<V: View> UpgradeViewHandle for EventContext<'_, '_, '_, V> {
3593 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3594 self.view_context.upgrade_view_handle(handle)
3595 }
3596
3597 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3598 self.view_context.upgrade_any_view_handle(handle)
3599 }
3600}
3601
3602pub(crate) enum Reference<'a, T> {
3603 Immutable(&'a T),
3604 Mutable(&'a mut T),
3605}
3606
3607impl<'a, T> Deref for Reference<'a, T> {
3608 type Target = T;
3609
3610 fn deref(&self) -> &Self::Target {
3611 match self {
3612 Reference::Immutable(target) => target,
3613 Reference::Mutable(target) => target,
3614 }
3615 }
3616}
3617
3618impl<'a, T> DerefMut for Reference<'a, T> {
3619 fn deref_mut(&mut self) -> &mut Self::Target {
3620 match self {
3621 Reference::Immutable(_) => {
3622 panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
3623 }
3624 Reference::Mutable(target) => target,
3625 }
3626 }
3627}
3628
3629#[derive(Debug, Clone, Default)]
3630pub struct MouseState {
3631 pub(crate) hovered: bool,
3632 pub(crate) clicked: Option<MouseButton>,
3633 pub(crate) accessed_hovered: bool,
3634 pub(crate) accessed_clicked: bool,
3635}
3636
3637impl MouseState {
3638 pub fn hovered(&mut self) -> bool {
3639 self.accessed_hovered = true;
3640 self.hovered
3641 }
3642
3643 pub fn clicked(&mut self) -> Option<MouseButton> {
3644 self.accessed_clicked = true;
3645 self.clicked
3646 }
3647
3648 pub fn accessed_hovered(&self) -> bool {
3649 self.accessed_hovered
3650 }
3651
3652 pub fn accessed_clicked(&self) -> bool {
3653 self.accessed_clicked
3654 }
3655}
3656
3657pub trait Handle<T> {
3658 type Weak: 'static;
3659 fn id(&self) -> usize;
3660 fn location(&self) -> EntityLocation;
3661 fn downgrade(&self) -> Self::Weak;
3662 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3663 where
3664 Self: Sized;
3665}
3666
3667pub trait WeakHandle {
3668 fn id(&self) -> usize;
3669}
3670
3671#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3672pub enum EntityLocation {
3673 Model(usize),
3674 View(usize, usize),
3675}
3676
3677pub struct ModelHandle<T: Entity> {
3678 any_handle: AnyModelHandle,
3679 model_type: PhantomData<T>,
3680}
3681
3682impl<T: Entity> Deref for ModelHandle<T> {
3683 type Target = AnyModelHandle;
3684
3685 fn deref(&self) -> &Self::Target {
3686 &self.any_handle
3687 }
3688}
3689
3690impl<T: Entity> ModelHandle<T> {
3691 fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3692 Self {
3693 any_handle: AnyModelHandle::new(model_id, TypeId::of::<T>(), ref_counts.clone()),
3694 model_type: PhantomData,
3695 }
3696 }
3697
3698 pub fn downgrade(&self) -> WeakModelHandle<T> {
3699 WeakModelHandle::new(self.model_id)
3700 }
3701
3702 pub fn id(&self) -> usize {
3703 self.model_id
3704 }
3705
3706 pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
3707 cx.read_model(self)
3708 }
3709
3710 pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3711 where
3712 C: ReadModelWith,
3713 F: FnOnce(&T, &AppContext) -> S,
3714 {
3715 let mut read = Some(read);
3716 cx.read_model_with(self, &mut |model, cx| {
3717 let read = read.take().unwrap();
3718 read(model, cx)
3719 })
3720 }
3721
3722 pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3723 where
3724 C: UpdateModel,
3725 F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
3726 {
3727 let mut update = Some(update);
3728 cx.update_model(self, &mut |model, cx| {
3729 let update = update.take().unwrap();
3730 update(model, cx)
3731 })
3732 }
3733}
3734
3735impl<T: Entity> Clone for ModelHandle<T> {
3736 fn clone(&self) -> Self {
3737 Self::new(self.model_id, &self.ref_counts)
3738 }
3739}
3740
3741impl<T: Entity> PartialEq for ModelHandle<T> {
3742 fn eq(&self, other: &Self) -> bool {
3743 self.model_id == other.model_id
3744 }
3745}
3746
3747impl<T: Entity> Eq for ModelHandle<T> {}
3748
3749impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
3750 fn eq(&self, other: &WeakModelHandle<T>) -> bool {
3751 self.model_id == other.model_id
3752 }
3753}
3754
3755impl<T: Entity> Hash for ModelHandle<T> {
3756 fn hash<H: Hasher>(&self, state: &mut H) {
3757 self.model_id.hash(state);
3758 }
3759}
3760
3761impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
3762 fn borrow(&self) -> &usize {
3763 &self.model_id
3764 }
3765}
3766
3767impl<T: Entity> Debug for ModelHandle<T> {
3768 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3769 f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
3770 .field(&self.model_id)
3771 .finish()
3772 }
3773}
3774
3775unsafe impl<T: Entity> Send for ModelHandle<T> {}
3776unsafe impl<T: Entity> Sync for ModelHandle<T> {}
3777
3778impl<T: Entity> Handle<T> for ModelHandle<T> {
3779 type Weak = WeakModelHandle<T>;
3780
3781 fn id(&self) -> usize {
3782 self.model_id
3783 }
3784
3785 fn location(&self) -> EntityLocation {
3786 EntityLocation::Model(self.model_id)
3787 }
3788
3789 fn downgrade(&self) -> Self::Weak {
3790 self.downgrade()
3791 }
3792
3793 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3794 where
3795 Self: Sized,
3796 {
3797 weak.upgrade(cx)
3798 }
3799}
3800
3801pub struct WeakModelHandle<T> {
3802 any_handle: AnyWeakModelHandle,
3803 model_type: PhantomData<T>,
3804}
3805
3806impl<T> WeakModelHandle<T> {
3807 pub fn into_any(self) -> AnyWeakModelHandle {
3808 self.any_handle
3809 }
3810}
3811
3812impl<T> Deref for WeakModelHandle<T> {
3813 type Target = AnyWeakModelHandle;
3814
3815 fn deref(&self) -> &Self::Target {
3816 &self.any_handle
3817 }
3818}
3819
3820impl<T> WeakHandle for WeakModelHandle<T> {
3821 fn id(&self) -> usize {
3822 self.model_id
3823 }
3824}
3825
3826unsafe impl<T> Send for WeakModelHandle<T> {}
3827unsafe impl<T> Sync for WeakModelHandle<T> {}
3828
3829impl<T: Entity> WeakModelHandle<T> {
3830 fn new(model_id: usize) -> Self {
3831 Self {
3832 any_handle: AnyWeakModelHandle {
3833 model_id,
3834 model_type: TypeId::of::<T>(),
3835 },
3836 model_type: PhantomData,
3837 }
3838 }
3839
3840 pub fn id(&self) -> usize {
3841 self.model_id
3842 }
3843
3844 pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
3845 cx.model_handle_is_upgradable(self)
3846 }
3847
3848 pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
3849 cx.upgrade_model_handle(self)
3850 }
3851}
3852
3853impl<T> Hash for WeakModelHandle<T> {
3854 fn hash<H: Hasher>(&self, state: &mut H) {
3855 self.model_id.hash(state)
3856 }
3857}
3858
3859impl<T> PartialEq for WeakModelHandle<T> {
3860 fn eq(&self, other: &Self) -> bool {
3861 self.model_id == other.model_id
3862 }
3863}
3864
3865impl<T> Eq for WeakModelHandle<T> {}
3866
3867impl<T: Entity> PartialEq<ModelHandle<T>> for WeakModelHandle<T> {
3868 fn eq(&self, other: &ModelHandle<T>) -> bool {
3869 self.model_id == other.model_id
3870 }
3871}
3872
3873impl<T> Clone for WeakModelHandle<T> {
3874 fn clone(&self) -> Self {
3875 Self {
3876 any_handle: self.any_handle.clone(),
3877 model_type: PhantomData,
3878 }
3879 }
3880}
3881
3882impl<T> Copy for WeakModelHandle<T> {}
3883
3884#[repr(transparent)]
3885pub struct ViewHandle<T> {
3886 any_handle: AnyViewHandle,
3887 view_type: PhantomData<T>,
3888}
3889
3890impl<T> Deref for ViewHandle<T> {
3891 type Target = AnyViewHandle;
3892
3893 fn deref(&self) -> &Self::Target {
3894 &self.any_handle
3895 }
3896}
3897
3898impl<T: View> ViewHandle<T> {
3899 fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3900 Self {
3901 any_handle: AnyViewHandle::new(
3902 window_id,
3903 view_id,
3904 TypeId::of::<T>(),
3905 ref_counts.clone(),
3906 ),
3907 view_type: PhantomData,
3908 }
3909 }
3910
3911 pub fn downgrade(&self) -> WeakViewHandle<T> {
3912 WeakViewHandle::new(self.window_id, self.view_id)
3913 }
3914
3915 pub fn into_any(self) -> AnyViewHandle {
3916 self.any_handle
3917 }
3918
3919 pub fn window_id(&self) -> usize {
3920 self.window_id
3921 }
3922
3923 pub fn id(&self) -> usize {
3924 self.view_id
3925 }
3926
3927 pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
3928 cx.read_view(self)
3929 }
3930
3931 pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3932 where
3933 C: ReadViewWith,
3934 F: FnOnce(&T, &AppContext) -> S,
3935 {
3936 let mut read = Some(read);
3937 cx.read_view_with(self, &mut |view, cx| {
3938 let read = read.take().unwrap();
3939 read(view, cx)
3940 })
3941 }
3942
3943 pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> C::Output<S>
3944 where
3945 C: UpdateView,
3946 F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
3947 {
3948 let mut update = Some(update);
3949 cx.update_view(self, &mut |view, cx| {
3950 let update = update.take().unwrap();
3951 update(view, cx)
3952 })
3953 }
3954
3955 pub fn is_focused(&self, cx: &WindowContext) -> bool {
3956 cx.focused_view_id() == Some(self.view_id)
3957 }
3958}
3959
3960impl<T: View> Clone for ViewHandle<T> {
3961 fn clone(&self) -> Self {
3962 ViewHandle::new(self.window_id, self.view_id, &self.ref_counts)
3963 }
3964}
3965
3966impl<T> PartialEq for ViewHandle<T> {
3967 fn eq(&self, other: &Self) -> bool {
3968 self.window_id == other.window_id && self.view_id == other.view_id
3969 }
3970}
3971
3972impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
3973 fn eq(&self, other: &WeakViewHandle<T>) -> bool {
3974 self.window_id == other.window_id && self.view_id == other.view_id
3975 }
3976}
3977
3978impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
3979 fn eq(&self, other: &ViewHandle<T>) -> bool {
3980 self.window_id == other.window_id && self.view_id == other.view_id
3981 }
3982}
3983
3984impl<T> Eq for ViewHandle<T> {}
3985
3986impl<T> Hash for ViewHandle<T> {
3987 fn hash<H: Hasher>(&self, state: &mut H) {
3988 self.window_id.hash(state);
3989 self.view_id.hash(state);
3990 }
3991}
3992
3993impl<T> Debug for ViewHandle<T> {
3994 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3995 f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
3996 .field("window_id", &self.window_id)
3997 .field("view_id", &self.view_id)
3998 .finish()
3999 }
4000}
4001
4002impl<T: View> Handle<T> for ViewHandle<T> {
4003 type Weak = WeakViewHandle<T>;
4004
4005 fn id(&self) -> usize {
4006 self.view_id
4007 }
4008
4009 fn location(&self) -> EntityLocation {
4010 EntityLocation::View(self.window_id, self.view_id)
4011 }
4012
4013 fn downgrade(&self) -> Self::Weak {
4014 self.downgrade()
4015 }
4016
4017 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4018 where
4019 Self: Sized,
4020 {
4021 weak.upgrade(cx)
4022 }
4023}
4024
4025pub struct AnyViewHandle {
4026 window_id: usize,
4027 view_id: usize,
4028 view_type: TypeId,
4029 ref_counts: Arc<Mutex<RefCounts>>,
4030
4031 #[cfg(any(test, feature = "test-support"))]
4032 handle_id: usize,
4033}
4034
4035impl AnyViewHandle {
4036 fn new(
4037 window_id: usize,
4038 view_id: usize,
4039 view_type: TypeId,
4040 ref_counts: Arc<Mutex<RefCounts>>,
4041 ) -> Self {
4042 ref_counts.lock().inc_view(window_id, view_id);
4043
4044 #[cfg(any(test, feature = "test-support"))]
4045 let handle_id = ref_counts
4046 .lock()
4047 .leak_detector
4048 .lock()
4049 .handle_created(None, view_id);
4050
4051 Self {
4052 window_id,
4053 view_id,
4054 view_type,
4055 ref_counts,
4056 #[cfg(any(test, feature = "test-support"))]
4057 handle_id,
4058 }
4059 }
4060
4061 pub fn window_id(&self) -> usize {
4062 self.window_id
4063 }
4064
4065 pub fn id(&self) -> usize {
4066 self.view_id
4067 }
4068
4069 pub fn is<T: 'static>(&self) -> bool {
4070 TypeId::of::<T>() == self.view_type
4071 }
4072
4073 pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4074 if self.is::<T>() {
4075 Some(ViewHandle {
4076 any_handle: self,
4077 view_type: PhantomData,
4078 })
4079 } else {
4080 None
4081 }
4082 }
4083
4084 pub fn downcast_ref<T: View>(&self) -> Option<&ViewHandle<T>> {
4085 if self.is::<T>() {
4086 Some(unsafe { mem::transmute(self) })
4087 } else {
4088 None
4089 }
4090 }
4091
4092 pub fn downgrade(&self) -> AnyWeakViewHandle {
4093 AnyWeakViewHandle {
4094 window_id: self.window_id,
4095 view_id: self.view_id,
4096 view_type: self.view_type,
4097 }
4098 }
4099
4100 pub fn view_type(&self) -> TypeId {
4101 self.view_type
4102 }
4103
4104 pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value {
4105 cx.views
4106 .get(&(self.window_id, self.view_id))
4107 .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4108 }
4109}
4110
4111impl Clone for AnyViewHandle {
4112 fn clone(&self) -> Self {
4113 Self::new(
4114 self.window_id,
4115 self.view_id,
4116 self.view_type,
4117 self.ref_counts.clone(),
4118 )
4119 }
4120}
4121
4122impl<T> PartialEq<ViewHandle<T>> for AnyViewHandle {
4123 fn eq(&self, other: &ViewHandle<T>) -> bool {
4124 self.window_id == other.window_id && self.view_id == other.view_id
4125 }
4126}
4127
4128impl Drop for AnyViewHandle {
4129 fn drop(&mut self) {
4130 self.ref_counts
4131 .lock()
4132 .dec_view(self.window_id, self.view_id);
4133 #[cfg(any(test, feature = "test-support"))]
4134 self.ref_counts
4135 .lock()
4136 .leak_detector
4137 .lock()
4138 .handle_dropped(self.view_id, self.handle_id);
4139 }
4140}
4141
4142pub struct AnyModelHandle {
4143 model_id: usize,
4144 model_type: TypeId,
4145 ref_counts: Arc<Mutex<RefCounts>>,
4146
4147 #[cfg(any(test, feature = "test-support"))]
4148 handle_id: usize,
4149}
4150
4151impl AnyModelHandle {
4152 fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4153 ref_counts.lock().inc_model(model_id);
4154
4155 #[cfg(any(test, feature = "test-support"))]
4156 let handle_id = ref_counts
4157 .lock()
4158 .leak_detector
4159 .lock()
4160 .handle_created(None, model_id);
4161
4162 Self {
4163 model_id,
4164 model_type,
4165 ref_counts,
4166
4167 #[cfg(any(test, feature = "test-support"))]
4168 handle_id,
4169 }
4170 }
4171
4172 pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4173 if self.is::<T>() {
4174 Some(ModelHandle {
4175 any_handle: self,
4176 model_type: PhantomData,
4177 })
4178 } else {
4179 None
4180 }
4181 }
4182
4183 pub fn downgrade(&self) -> AnyWeakModelHandle {
4184 AnyWeakModelHandle {
4185 model_id: self.model_id,
4186 model_type: self.model_type,
4187 }
4188 }
4189
4190 pub fn is<T: Entity>(&self) -> bool {
4191 self.model_type == TypeId::of::<T>()
4192 }
4193
4194 pub fn model_type(&self) -> TypeId {
4195 self.model_type
4196 }
4197}
4198
4199impl Clone for AnyModelHandle {
4200 fn clone(&self) -> Self {
4201 Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4202 }
4203}
4204
4205impl Drop for AnyModelHandle {
4206 fn drop(&mut self) {
4207 let mut ref_counts = self.ref_counts.lock();
4208 ref_counts.dec_model(self.model_id);
4209
4210 #[cfg(any(test, feature = "test-support"))]
4211 ref_counts
4212 .leak_detector
4213 .lock()
4214 .handle_dropped(self.model_id, self.handle_id);
4215 }
4216}
4217
4218#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
4219pub struct AnyWeakModelHandle {
4220 model_id: usize,
4221 model_type: TypeId,
4222}
4223
4224impl AnyWeakModelHandle {
4225 pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
4226 cx.upgrade_any_model_handle(self)
4227 }
4228 pub fn model_type(&self) -> TypeId {
4229 self.model_type
4230 }
4231
4232 fn is<T: 'static>(&self) -> bool {
4233 TypeId::of::<T>() == self.model_type
4234 }
4235
4236 pub fn downcast<T: Entity>(self) -> Option<WeakModelHandle<T>> {
4237 if self.is::<T>() {
4238 let result = Some(WeakModelHandle {
4239 any_handle: self,
4240 model_type: PhantomData,
4241 });
4242
4243 result
4244 } else {
4245 None
4246 }
4247 }
4248}
4249
4250#[derive(Debug, Copy)]
4251pub struct WeakViewHandle<T> {
4252 any_handle: AnyWeakViewHandle,
4253 view_type: PhantomData<T>,
4254}
4255
4256impl<T> WeakHandle for WeakViewHandle<T> {
4257 fn id(&self) -> usize {
4258 self.view_id
4259 }
4260}
4261
4262impl<T: View> WeakViewHandle<T> {
4263 fn new(window_id: usize, view_id: usize) -> Self {
4264 Self {
4265 any_handle: AnyWeakViewHandle {
4266 window_id,
4267 view_id,
4268 view_type: TypeId::of::<T>(),
4269 },
4270 view_type: PhantomData,
4271 }
4272 }
4273
4274 pub fn id(&self) -> usize {
4275 self.view_id
4276 }
4277
4278 pub fn window_id(&self) -> usize {
4279 self.window_id
4280 }
4281
4282 pub fn into_any(self) -> AnyWeakViewHandle {
4283 self.any_handle
4284 }
4285
4286 pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
4287 cx.upgrade_view_handle(self)
4288 }
4289}
4290
4291impl<T> Deref for WeakViewHandle<T> {
4292 type Target = AnyWeakViewHandle;
4293
4294 fn deref(&self) -> &Self::Target {
4295 &self.any_handle
4296 }
4297}
4298
4299impl<T> Clone for WeakViewHandle<T> {
4300 fn clone(&self) -> Self {
4301 Self {
4302 any_handle: self.any_handle.clone(),
4303 view_type: PhantomData,
4304 }
4305 }
4306}
4307
4308impl<T> PartialEq for WeakViewHandle<T> {
4309 fn eq(&self, other: &Self) -> bool {
4310 self.window_id == other.window_id && self.view_id == other.view_id
4311 }
4312}
4313
4314impl<T> Eq for WeakViewHandle<T> {}
4315
4316impl<T> Hash for WeakViewHandle<T> {
4317 fn hash<H: Hasher>(&self, state: &mut H) {
4318 self.any_handle.hash(state);
4319 }
4320}
4321
4322#[derive(Debug, Clone, Copy)]
4323pub struct AnyWeakViewHandle {
4324 window_id: usize,
4325 view_id: usize,
4326 view_type: TypeId,
4327}
4328
4329impl AnyWeakViewHandle {
4330 pub fn id(&self) -> usize {
4331 self.view_id
4332 }
4333
4334 pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
4335 cx.upgrade_any_view_handle(self)
4336 }
4337}
4338
4339impl Hash for AnyWeakViewHandle {
4340 fn hash<H: Hasher>(&self, state: &mut H) {
4341 self.window_id.hash(state);
4342 self.view_id.hash(state);
4343 self.view_type.hash(state);
4344 }
4345}
4346
4347#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4348pub struct ElementStateId {
4349 view_id: usize,
4350 element_id: usize,
4351 tag: TypeId,
4352}
4353
4354pub struct ElementStateHandle<T> {
4355 value_type: PhantomData<T>,
4356 id: ElementStateId,
4357 ref_counts: Weak<Mutex<RefCounts>>,
4358}
4359
4360impl<T: 'static> ElementStateHandle<T> {
4361 fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4362 ref_counts.lock().inc_element_state(id, frame_id);
4363 Self {
4364 value_type: PhantomData,
4365 id,
4366 ref_counts: Arc::downgrade(ref_counts),
4367 }
4368 }
4369
4370 pub fn id(&self) -> ElementStateId {
4371 self.id
4372 }
4373
4374 pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4375 cx.element_states
4376 .get(&self.id)
4377 .unwrap()
4378 .downcast_ref()
4379 .unwrap()
4380 }
4381
4382 pub fn update<C, D, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4383 where
4384 C: DerefMut<Target = D>,
4385 D: DerefMut<Target = AppContext>,
4386 {
4387 let mut element_state = cx.deref_mut().element_states.remove(&self.id).unwrap();
4388 let result = f(element_state.downcast_mut().unwrap(), cx);
4389 cx.deref_mut().element_states.insert(self.id, element_state);
4390 result
4391 }
4392}
4393
4394impl<T> Drop for ElementStateHandle<T> {
4395 fn drop(&mut self) {
4396 if let Some(ref_counts) = self.ref_counts.upgrade() {
4397 ref_counts.lock().dec_element_state(self.id);
4398 }
4399 }
4400}
4401
4402#[must_use]
4403pub enum Subscription {
4404 Subscription(callback_collection::Subscription<usize, SubscriptionCallback>),
4405 Observation(callback_collection::Subscription<usize, ObservationCallback>),
4406 GlobalSubscription(callback_collection::Subscription<TypeId, GlobalSubscriptionCallback>),
4407 GlobalObservation(callback_collection::Subscription<TypeId, GlobalObservationCallback>),
4408 FocusObservation(callback_collection::Subscription<usize, FocusObservationCallback>),
4409 WindowActivationObservation(callback_collection::Subscription<usize, WindowActivationCallback>),
4410 WindowFullscreenObservation(callback_collection::Subscription<usize, WindowFullscreenCallback>),
4411 WindowBoundsObservation(callback_collection::Subscription<usize, WindowBoundsCallback>),
4412 KeystrokeObservation(callback_collection::Subscription<usize, KeystrokeCallback>),
4413 ReleaseObservation(callback_collection::Subscription<usize, ReleaseObservationCallback>),
4414 ActionObservation(callback_collection::Subscription<(), ActionObservationCallback>),
4415 ActiveLabeledTasksObservation(
4416 callback_collection::Subscription<(), ActiveLabeledTasksCallback>,
4417 ),
4418}
4419
4420impl Subscription {
4421 pub fn id(&self) -> usize {
4422 match self {
4423 Subscription::Subscription(subscription) => subscription.id(),
4424 Subscription::Observation(subscription) => subscription.id(),
4425 Subscription::GlobalSubscription(subscription) => subscription.id(),
4426 Subscription::GlobalObservation(subscription) => subscription.id(),
4427 Subscription::FocusObservation(subscription) => subscription.id(),
4428 Subscription::WindowActivationObservation(subscription) => subscription.id(),
4429 Subscription::WindowFullscreenObservation(subscription) => subscription.id(),
4430 Subscription::WindowBoundsObservation(subscription) => subscription.id(),
4431 Subscription::KeystrokeObservation(subscription) => subscription.id(),
4432 Subscription::ReleaseObservation(subscription) => subscription.id(),
4433 Subscription::ActionObservation(subscription) => subscription.id(),
4434 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.id(),
4435 }
4436 }
4437
4438 pub fn detach(&mut self) {
4439 match self {
4440 Subscription::Subscription(subscription) => subscription.detach(),
4441 Subscription::GlobalSubscription(subscription) => subscription.detach(),
4442 Subscription::Observation(subscription) => subscription.detach(),
4443 Subscription::GlobalObservation(subscription) => subscription.detach(),
4444 Subscription::FocusObservation(subscription) => subscription.detach(),
4445 Subscription::KeystrokeObservation(subscription) => subscription.detach(),
4446 Subscription::WindowActivationObservation(subscription) => subscription.detach(),
4447 Subscription::WindowFullscreenObservation(subscription) => subscription.detach(),
4448 Subscription::WindowBoundsObservation(subscription) => subscription.detach(),
4449 Subscription::ReleaseObservation(subscription) => subscription.detach(),
4450 Subscription::ActionObservation(subscription) => subscription.detach(),
4451 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.detach(),
4452 }
4453 }
4454}
4455
4456#[cfg(test)]
4457mod tests {
4458 use super::*;
4459 use crate::{
4460 actions,
4461 elements::*,
4462 impl_actions,
4463 platform::{MouseButton, MouseButtonEvent},
4464 window::ChildView,
4465 };
4466 use itertools::Itertools;
4467 use postage::{sink::Sink, stream::Stream};
4468 use serde::Deserialize;
4469 use smol::future::poll_once;
4470 use std::{
4471 cell::Cell,
4472 sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
4473 };
4474
4475 #[crate::test(self)]
4476 fn test_model_handles(cx: &mut AppContext) {
4477 struct Model {
4478 other: Option<ModelHandle<Model>>,
4479 events: Vec<String>,
4480 }
4481
4482 impl Entity for Model {
4483 type Event = usize;
4484 }
4485
4486 impl Model {
4487 fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
4488 if let Some(other) = other.as_ref() {
4489 cx.observe(other, |me, _, _| {
4490 me.events.push("notified".into());
4491 })
4492 .detach();
4493 cx.subscribe(other, |me, _, event, _| {
4494 me.events.push(format!("observed event {}", event));
4495 })
4496 .detach();
4497 }
4498
4499 Self {
4500 other,
4501 events: Vec::new(),
4502 }
4503 }
4504 }
4505
4506 let handle_1 = cx.add_model(|cx| Model::new(None, cx));
4507 let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
4508 assert_eq!(cx.models.len(), 2);
4509
4510 handle_1.update(cx, |model, cx| {
4511 model.events.push("updated".into());
4512 cx.emit(1);
4513 cx.notify();
4514 cx.emit(2);
4515 });
4516 assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
4517 assert_eq!(
4518 handle_2.read(cx).events,
4519 vec![
4520 "observed event 1".to_string(),
4521 "notified".to_string(),
4522 "observed event 2".to_string(),
4523 ]
4524 );
4525
4526 handle_2.update(cx, |model, _| {
4527 drop(handle_1);
4528 model.other.take();
4529 });
4530
4531 assert_eq!(cx.models.len(), 1);
4532 assert!(cx.subscriptions.is_empty());
4533 assert!(cx.observations.is_empty());
4534 }
4535
4536 #[crate::test(self)]
4537 fn test_model_events(cx: &mut AppContext) {
4538 #[derive(Default)]
4539 struct Model {
4540 events: Vec<usize>,
4541 }
4542
4543 impl Entity for Model {
4544 type Event = usize;
4545 }
4546
4547 let handle_1 = cx.add_model(|_| Model::default());
4548 let handle_2 = cx.add_model(|_| Model::default());
4549
4550 handle_1.update(cx, |_, cx| {
4551 cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
4552 model.events.push(*event);
4553
4554 cx.subscribe(&emitter, |model, _, event, _| {
4555 model.events.push(*event * 2);
4556 })
4557 .detach();
4558 })
4559 .detach();
4560 });
4561
4562 handle_2.update(cx, |_, c| c.emit(7));
4563 assert_eq!(handle_1.read(cx).events, vec![7]);
4564
4565 handle_2.update(cx, |_, c| c.emit(5));
4566 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
4567 }
4568
4569 #[crate::test(self)]
4570 fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
4571 #[derive(Default)]
4572 struct Model;
4573
4574 impl Entity for Model {
4575 type Event = ();
4576 }
4577
4578 let events = Rc::new(RefCell::new(Vec::new()));
4579 cx.add_model(|cx| {
4580 drop(cx.subscribe(&cx.handle(), {
4581 let events = events.clone();
4582 move |_, _, _, _| events.borrow_mut().push("dropped before flush")
4583 }));
4584 cx.subscribe(&cx.handle(), {
4585 let events = events.clone();
4586 move |_, _, _, _| events.borrow_mut().push("before emit")
4587 })
4588 .detach();
4589 cx.emit(());
4590 cx.subscribe(&cx.handle(), {
4591 let events = events.clone();
4592 move |_, _, _, _| events.borrow_mut().push("after emit")
4593 })
4594 .detach();
4595 Model
4596 });
4597 assert_eq!(*events.borrow(), ["before emit"]);
4598 }
4599
4600 #[crate::test(self)]
4601 fn test_observe_and_notify_from_model(cx: &mut AppContext) {
4602 #[derive(Default)]
4603 struct Model {
4604 count: usize,
4605 events: Vec<usize>,
4606 }
4607
4608 impl Entity for Model {
4609 type Event = ();
4610 }
4611
4612 let handle_1 = cx.add_model(|_| Model::default());
4613 let handle_2 = cx.add_model(|_| Model::default());
4614
4615 handle_1.update(cx, |_, c| {
4616 c.observe(&handle_2, move |model, observed, c| {
4617 model.events.push(observed.read(c).count);
4618 c.observe(&observed, |model, observed, c| {
4619 model.events.push(observed.read(c).count * 2);
4620 })
4621 .detach();
4622 })
4623 .detach();
4624 });
4625
4626 handle_2.update(cx, |model, c| {
4627 model.count = 7;
4628 c.notify()
4629 });
4630 assert_eq!(handle_1.read(cx).events, vec![7]);
4631
4632 handle_2.update(cx, |model, c| {
4633 model.count = 5;
4634 c.notify()
4635 });
4636 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
4637 }
4638
4639 #[crate::test(self)]
4640 fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
4641 #[derive(Default)]
4642 struct Model;
4643
4644 impl Entity for Model {
4645 type Event = ();
4646 }
4647
4648 let events = Rc::new(RefCell::new(Vec::new()));
4649 cx.add_model(|cx| {
4650 drop(cx.observe(&cx.handle(), {
4651 let events = events.clone();
4652 move |_, _, _| events.borrow_mut().push("dropped before flush")
4653 }));
4654 cx.observe(&cx.handle(), {
4655 let events = events.clone();
4656 move |_, _, _| events.borrow_mut().push("before notify")
4657 })
4658 .detach();
4659 cx.notify();
4660 cx.observe(&cx.handle(), {
4661 let events = events.clone();
4662 move |_, _, _| events.borrow_mut().push("after notify")
4663 })
4664 .detach();
4665 Model
4666 });
4667 assert_eq!(*events.borrow(), ["before notify"]);
4668 }
4669
4670 #[crate::test(self)]
4671 fn test_defer_and_after_window_update(cx: &mut TestAppContext) {
4672 struct View {
4673 render_count: usize,
4674 }
4675
4676 impl Entity for View {
4677 type Event = usize;
4678 }
4679
4680 impl super::View for View {
4681 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
4682 post_inc(&mut self.render_count);
4683 Empty::new().into_any()
4684 }
4685
4686 fn ui_name() -> &'static str {
4687 "View"
4688 }
4689 }
4690
4691 let (_, view) = cx.add_window(|_| View { render_count: 0 });
4692 let called_defer = Rc::new(AtomicBool::new(false));
4693 let called_after_window_update = Rc::new(AtomicBool::new(false));
4694
4695 view.update(cx, |this, cx| {
4696 assert_eq!(this.render_count, 1);
4697 cx.defer({
4698 let called_defer = called_defer.clone();
4699 move |this, _| {
4700 assert_eq!(this.render_count, 1);
4701 called_defer.store(true, SeqCst);
4702 }
4703 });
4704 cx.after_window_update({
4705 let called_after_window_update = called_after_window_update.clone();
4706 move |this, cx| {
4707 assert_eq!(this.render_count, 2);
4708 called_after_window_update.store(true, SeqCst);
4709 cx.notify();
4710 }
4711 });
4712 assert!(!called_defer.load(SeqCst));
4713 assert!(!called_after_window_update.load(SeqCst));
4714 cx.notify();
4715 });
4716
4717 assert!(called_defer.load(SeqCst));
4718 assert!(called_after_window_update.load(SeqCst));
4719 assert_eq!(view.read_with(cx, |view, _| view.render_count), 3);
4720 }
4721
4722 #[crate::test(self)]
4723 fn test_view_handles(cx: &mut TestAppContext) {
4724 struct View {
4725 other: Option<ViewHandle<View>>,
4726 events: Vec<String>,
4727 }
4728
4729 impl Entity for View {
4730 type Event = usize;
4731 }
4732
4733 impl super::View for View {
4734 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
4735 Empty::new().into_any()
4736 }
4737
4738 fn ui_name() -> &'static str {
4739 "View"
4740 }
4741 }
4742
4743 impl View {
4744 fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
4745 if let Some(other) = other.as_ref() {
4746 cx.subscribe(other, |me, _, event, _| {
4747 me.events.push(format!("observed event {}", event));
4748 })
4749 .detach();
4750 }
4751 Self {
4752 other,
4753 events: Vec::new(),
4754 }
4755 }
4756 }
4757
4758 let (_, root_view) = cx.add_window(|cx| View::new(None, cx));
4759 let handle_1 = cx.add_view(&root_view, |cx| View::new(None, cx));
4760 let handle_2 = cx.add_view(&root_view, |cx| View::new(Some(handle_1.clone()), cx));
4761 assert_eq!(cx.read(|cx| cx.views.len()), 3);
4762
4763 handle_1.update(cx, |view, cx| {
4764 view.events.push("updated".into());
4765 cx.emit(1);
4766 cx.emit(2);
4767 });
4768 handle_1.read_with(cx, |view, _| {
4769 assert_eq!(view.events, vec!["updated".to_string()]);
4770 });
4771 handle_2.read_with(cx, |view, _| {
4772 assert_eq!(
4773 view.events,
4774 vec![
4775 "observed event 1".to_string(),
4776 "observed event 2".to_string(),
4777 ]
4778 );
4779 });
4780
4781 handle_2.update(cx, |view, _| {
4782 drop(handle_1);
4783 view.other.take();
4784 });
4785
4786 cx.read(|cx| {
4787 assert_eq!(cx.views.len(), 2);
4788 assert!(cx.subscriptions.is_empty());
4789 assert!(cx.observations.is_empty());
4790 });
4791 }
4792
4793 #[crate::test(self)]
4794 fn test_add_window(cx: &mut AppContext) {
4795 struct View {
4796 mouse_down_count: Arc<AtomicUsize>,
4797 }
4798
4799 impl Entity for View {
4800 type Event = ();
4801 }
4802
4803 impl super::View for View {
4804 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
4805 enum Handler {}
4806 let mouse_down_count = self.mouse_down_count.clone();
4807 MouseEventHandler::<Handler, _>::new(0, cx, |_, _| Empty::new())
4808 .on_down(MouseButton::Left, move |_, _, _| {
4809 mouse_down_count.fetch_add(1, SeqCst);
4810 })
4811 .into_any()
4812 }
4813
4814 fn ui_name() -> &'static str {
4815 "View"
4816 }
4817 }
4818
4819 let mouse_down_count = Arc::new(AtomicUsize::new(0));
4820 let (window_id, _) = cx.add_window(Default::default(), |_| View {
4821 mouse_down_count: mouse_down_count.clone(),
4822 });
4823
4824 cx.update_window(window_id, |cx| {
4825 // Ensure window's root element is in a valid lifecycle state.
4826 cx.dispatch_event(
4827 Event::MouseDown(MouseButtonEvent {
4828 position: Default::default(),
4829 button: MouseButton::Left,
4830 modifiers: Default::default(),
4831 click_count: 1,
4832 }),
4833 false,
4834 );
4835 assert_eq!(mouse_down_count.load(SeqCst), 1);
4836 });
4837 }
4838
4839 #[crate::test(self)]
4840 fn test_entity_release_hooks(cx: &mut AppContext) {
4841 struct Model {
4842 released: Rc<Cell<bool>>,
4843 }
4844
4845 struct View {
4846 released: Rc<Cell<bool>>,
4847 }
4848
4849 impl Entity for Model {
4850 type Event = ();
4851
4852 fn release(&mut self, _: &mut AppContext) {
4853 self.released.set(true);
4854 }
4855 }
4856
4857 impl Entity for View {
4858 type Event = ();
4859
4860 fn release(&mut self, _: &mut AppContext) {
4861 self.released.set(true);
4862 }
4863 }
4864
4865 impl super::View for View {
4866 fn ui_name() -> &'static str {
4867 "View"
4868 }
4869
4870 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
4871 Empty::new().into_any()
4872 }
4873 }
4874
4875 let model_released = Rc::new(Cell::new(false));
4876 let model_release_observed = Rc::new(Cell::new(false));
4877 let view_released = Rc::new(Cell::new(false));
4878 let view_release_observed = Rc::new(Cell::new(false));
4879
4880 let model = cx.add_model(|_| Model {
4881 released: model_released.clone(),
4882 });
4883 let (window_id, view) = cx.add_window(Default::default(), |_| View {
4884 released: view_released.clone(),
4885 });
4886 assert!(!model_released.get());
4887 assert!(!view_released.get());
4888
4889 cx.observe_release(&model, {
4890 let model_release_observed = model_release_observed.clone();
4891 move |_, _| model_release_observed.set(true)
4892 })
4893 .detach();
4894 cx.observe_release(&view, {
4895 let view_release_observed = view_release_observed.clone();
4896 move |_, _| view_release_observed.set(true)
4897 })
4898 .detach();
4899
4900 cx.update(move |_| {
4901 drop(model);
4902 });
4903 assert!(model_released.get());
4904 assert!(model_release_observed.get());
4905
4906 drop(view);
4907 cx.remove_window(window_id);
4908 assert!(view_released.get());
4909 assert!(view_release_observed.get());
4910 }
4911
4912 #[crate::test(self)]
4913 fn test_view_events(cx: &mut TestAppContext) {
4914 struct Model;
4915
4916 impl Entity for Model {
4917 type Event = String;
4918 }
4919
4920 let (_, handle_1) = cx.add_window(|_| TestView::default());
4921 let handle_2 = cx.add_view(&handle_1, |_| TestView::default());
4922 let handle_3 = cx.add_model(|_| Model);
4923
4924 handle_1.update(cx, |_, cx| {
4925 cx.subscribe(&handle_2, move |me, emitter, event, cx| {
4926 me.events.push(event.clone());
4927
4928 cx.subscribe(&emitter, |me, _, event, _| {
4929 me.events.push(format!("{event} from inner"));
4930 })
4931 .detach();
4932 })
4933 .detach();
4934
4935 cx.subscribe(&handle_3, |me, _, event, _| {
4936 me.events.push(event.clone());
4937 })
4938 .detach();
4939 });
4940
4941 handle_2.update(cx, |_, c| c.emit("7".into()));
4942 handle_1.read_with(cx, |view, _| assert_eq!(view.events, ["7"]));
4943
4944 handle_2.update(cx, |_, c| c.emit("5".into()));
4945 handle_1.read_with(cx, |view, _| {
4946 assert_eq!(view.events, ["7", "5", "5 from inner"])
4947 });
4948
4949 handle_3.update(cx, |_, c| c.emit("9".into()));
4950 handle_1.read_with(cx, |view, _| {
4951 assert_eq!(view.events, ["7", "5", "5 from inner", "9"])
4952 });
4953 }
4954
4955 #[crate::test(self)]
4956 fn test_global_events(cx: &mut AppContext) {
4957 #[derive(Clone, Debug, Eq, PartialEq)]
4958 struct GlobalEvent(u64);
4959
4960 let events = Rc::new(RefCell::new(Vec::new()));
4961 let first_subscription;
4962 let second_subscription;
4963
4964 {
4965 let events = events.clone();
4966 first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
4967 events.borrow_mut().push(("First", e.clone()));
4968 });
4969 }
4970
4971 {
4972 let events = events.clone();
4973 second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
4974 events.borrow_mut().push(("Second", e.clone()));
4975 });
4976 }
4977
4978 cx.update(|cx| {
4979 cx.emit_global(GlobalEvent(1));
4980 cx.emit_global(GlobalEvent(2));
4981 });
4982
4983 drop(first_subscription);
4984
4985 cx.update(|cx| {
4986 cx.emit_global(GlobalEvent(3));
4987 });
4988
4989 drop(second_subscription);
4990
4991 cx.update(|cx| {
4992 cx.emit_global(GlobalEvent(4));
4993 });
4994
4995 assert_eq!(
4996 &*events.borrow(),
4997 &[
4998 ("First", GlobalEvent(1)),
4999 ("Second", GlobalEvent(1)),
5000 ("First", GlobalEvent(2)),
5001 ("Second", GlobalEvent(2)),
5002 ("Second", GlobalEvent(3)),
5003 ]
5004 );
5005 }
5006
5007 #[crate::test(self)]
5008 fn test_global_events_emitted_before_subscription_in_same_update_cycle(cx: &mut AppContext) {
5009 let events = Rc::new(RefCell::new(Vec::new()));
5010 cx.update(|cx| {
5011 {
5012 let events = events.clone();
5013 drop(cx.subscribe_global(move |_: &(), _| {
5014 events.borrow_mut().push("dropped before emit");
5015 }));
5016 }
5017
5018 {
5019 let events = events.clone();
5020 cx.subscribe_global(move |_: &(), _| {
5021 events.borrow_mut().push("before emit");
5022 })
5023 .detach();
5024 }
5025
5026 cx.emit_global(());
5027
5028 {
5029 let events = events.clone();
5030 cx.subscribe_global(move |_: &(), _| {
5031 events.borrow_mut().push("after emit");
5032 })
5033 .detach();
5034 }
5035 });
5036
5037 assert_eq!(*events.borrow(), ["before emit"]);
5038 }
5039
5040 #[crate::test(self)]
5041 fn test_global_nested_events(cx: &mut AppContext) {
5042 #[derive(Clone, Debug, Eq, PartialEq)]
5043 struct GlobalEvent(u64);
5044
5045 let events = Rc::new(RefCell::new(Vec::new()));
5046
5047 {
5048 let events = events.clone();
5049 cx.subscribe_global(move |e: &GlobalEvent, cx| {
5050 events.borrow_mut().push(("Outer", e.clone()));
5051
5052 if e.0 == 1 {
5053 let events = events.clone();
5054 cx.subscribe_global(move |e: &GlobalEvent, _| {
5055 events.borrow_mut().push(("Inner", e.clone()));
5056 })
5057 .detach();
5058 }
5059 })
5060 .detach();
5061 }
5062
5063 cx.update(|cx| {
5064 cx.emit_global(GlobalEvent(1));
5065 cx.emit_global(GlobalEvent(2));
5066 cx.emit_global(GlobalEvent(3));
5067 });
5068 cx.update(|cx| {
5069 cx.emit_global(GlobalEvent(4));
5070 });
5071
5072 assert_eq!(
5073 &*events.borrow(),
5074 &[
5075 ("Outer", GlobalEvent(1)),
5076 ("Outer", GlobalEvent(2)),
5077 ("Outer", GlobalEvent(3)),
5078 ("Outer", GlobalEvent(4)),
5079 ("Inner", GlobalEvent(4)),
5080 ]
5081 );
5082 }
5083
5084 #[crate::test(self)]
5085 fn test_global(cx: &mut AppContext) {
5086 type Global = usize;
5087
5088 let observation_count = Rc::new(RefCell::new(0));
5089 let subscription = cx.observe_global::<Global, _>({
5090 let observation_count = observation_count.clone();
5091 move |_| {
5092 *observation_count.borrow_mut() += 1;
5093 }
5094 });
5095
5096 assert!(!cx.has_global::<Global>());
5097 assert_eq!(cx.default_global::<Global>(), &0);
5098 assert_eq!(*observation_count.borrow(), 1);
5099 assert!(cx.has_global::<Global>());
5100 assert_eq!(
5101 cx.update_global::<Global, _, _>(|global, _| {
5102 *global = 1;
5103 "Update Result"
5104 }),
5105 "Update Result"
5106 );
5107 assert_eq!(*observation_count.borrow(), 2);
5108 assert_eq!(cx.global::<Global>(), &1);
5109
5110 drop(subscription);
5111 cx.update_global::<Global, _, _>(|global, _| {
5112 *global = 2;
5113 });
5114 assert_eq!(*observation_count.borrow(), 2);
5115
5116 type OtherGlobal = f32;
5117
5118 let observation_count = Rc::new(RefCell::new(0));
5119 cx.observe_global::<OtherGlobal, _>({
5120 let observation_count = observation_count.clone();
5121 move |_| {
5122 *observation_count.borrow_mut() += 1;
5123 }
5124 })
5125 .detach();
5126
5127 assert_eq!(
5128 cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5129 assert_eq!(global, &0.0);
5130 *global = 2.0;
5131 "Default update result"
5132 }),
5133 "Default update result"
5134 );
5135 assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5136 assert_eq!(*observation_count.borrow(), 1);
5137 }
5138
5139 #[crate::test(self)]
5140 fn test_dropping_subscribers(cx: &mut TestAppContext) {
5141 struct Model;
5142
5143 impl Entity for Model {
5144 type Event = ();
5145 }
5146
5147 let (_, root_view) = cx.add_window(|_| TestView::default());
5148 let observing_view = cx.add_view(&root_view, |_| TestView::default());
5149 let emitting_view = cx.add_view(&root_view, |_| TestView::default());
5150 let observing_model = cx.add_model(|_| Model);
5151 let observed_model = cx.add_model(|_| Model);
5152
5153 observing_view.update(cx, |_, cx| {
5154 cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5155 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5156 });
5157 observing_model.update(cx, |_, cx| {
5158 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5159 });
5160
5161 cx.update(|_| {
5162 drop(observing_view);
5163 drop(observing_model);
5164 });
5165
5166 emitting_view.update(cx, |_, cx| cx.emit(Default::default()));
5167 observed_model.update(cx, |_, cx| cx.emit(()));
5168 }
5169
5170 #[crate::test(self)]
5171 fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
5172 let (_, view) = cx.add_window::<TestView, _>(Default::default(), |cx| {
5173 drop(cx.subscribe(&cx.handle(), {
5174 move |this, _, _, _| this.events.push("dropped before flush".into())
5175 }));
5176 cx.subscribe(&cx.handle(), {
5177 move |this, _, _, _| this.events.push("before emit".into())
5178 })
5179 .detach();
5180 cx.emit("the event".into());
5181 cx.subscribe(&cx.handle(), {
5182 move |this, _, _, _| this.events.push("after emit".into())
5183 })
5184 .detach();
5185 TestView { events: Vec::new() }
5186 });
5187
5188 assert_eq!(view.read(cx).events, ["before emit"]);
5189 }
5190
5191 #[crate::test(self)]
5192 fn test_observe_and_notify_from_view(cx: &mut TestAppContext) {
5193 #[derive(Default)]
5194 struct Model {
5195 state: String,
5196 }
5197
5198 impl Entity for Model {
5199 type Event = ();
5200 }
5201
5202 let (_, view) = cx.add_window(|_| TestView::default());
5203 let model = cx.add_model(|_| Model {
5204 state: "old-state".into(),
5205 });
5206
5207 view.update(cx, |_, c| {
5208 c.observe(&model, |me, observed, cx| {
5209 me.events.push(observed.read(cx).state.clone())
5210 })
5211 .detach();
5212 });
5213
5214 model.update(cx, |model, cx| {
5215 model.state = "new-state".into();
5216 cx.notify();
5217 });
5218 view.read_with(cx, |view, _| assert_eq!(view.events, ["new-state"]));
5219 }
5220
5221 #[crate::test(self)]
5222 fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
5223 let (_, view) = cx.add_window::<TestView, _>(Default::default(), |cx| {
5224 drop(cx.observe(&cx.handle(), {
5225 move |this, _, _| this.events.push("dropped before flush".into())
5226 }));
5227 cx.observe(&cx.handle(), {
5228 move |this, _, _| this.events.push("before notify".into())
5229 })
5230 .detach();
5231 cx.notify();
5232 cx.observe(&cx.handle(), {
5233 move |this, _, _| this.events.push("after notify".into())
5234 })
5235 .detach();
5236 TestView { events: Vec::new() }
5237 });
5238
5239 assert_eq!(view.read(cx).events, ["before notify"]);
5240 }
5241
5242 #[crate::test(self)]
5243 fn test_notify_and_drop_observe_subscription_in_same_update_cycle(cx: &mut TestAppContext) {
5244 struct Model;
5245 impl Entity for Model {
5246 type Event = ();
5247 }
5248
5249 let model = cx.add_model(|_| Model);
5250 let (_, view) = cx.add_window(|_| TestView::default());
5251
5252 view.update(cx, |_, cx| {
5253 model.update(cx, |_, cx| cx.notify());
5254 drop(cx.observe(&model, move |this, _, _| {
5255 this.events.push("model notified".into());
5256 }));
5257 model.update(cx, |_, cx| cx.notify());
5258 });
5259
5260 for _ in 0..3 {
5261 model.update(cx, |_, cx| cx.notify());
5262 }
5263 view.read_with(cx, |view, _| assert_eq!(view.events, Vec::<&str>::new()));
5264 }
5265
5266 #[crate::test(self)]
5267 fn test_dropping_observers(cx: &mut TestAppContext) {
5268 struct Model;
5269
5270 impl Entity for Model {
5271 type Event = ();
5272 }
5273
5274 let (_, root_view) = cx.add_window(|_| TestView::default());
5275 let observing_view = cx.add_view(&root_view, |_| TestView::default());
5276 let observing_model = cx.add_model(|_| Model);
5277 let observed_model = cx.add_model(|_| Model);
5278
5279 observing_view.update(cx, |_, cx| {
5280 cx.observe(&observed_model, |_, _, _| {}).detach();
5281 });
5282 observing_model.update(cx, |_, cx| {
5283 cx.observe(&observed_model, |_, _, _| {}).detach();
5284 });
5285
5286 cx.update(|_| {
5287 drop(observing_view);
5288 drop(observing_model);
5289 });
5290
5291 observed_model.update(cx, |_, cx| cx.notify());
5292 }
5293
5294 #[crate::test(self)]
5295 fn test_dropping_subscriptions_during_callback(cx: &mut TestAppContext) {
5296 struct Model;
5297
5298 impl Entity for Model {
5299 type Event = u64;
5300 }
5301
5302 // Events
5303 let observing_model = cx.add_model(|_| Model);
5304 let observed_model = cx.add_model(|_| Model);
5305
5306 let events = Rc::new(RefCell::new(Vec::new()));
5307
5308 observing_model.update(cx, |_, cx| {
5309 let events = events.clone();
5310 let subscription = Rc::new(RefCell::new(None));
5311 *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
5312 let subscription = subscription.clone();
5313 move |_, _, e, _| {
5314 subscription.borrow_mut().take();
5315 events.borrow_mut().push(*e);
5316 }
5317 }));
5318 });
5319
5320 observed_model.update(cx, |_, cx| {
5321 cx.emit(1);
5322 cx.emit(2);
5323 });
5324
5325 assert_eq!(*events.borrow(), [1]);
5326
5327 // Global Events
5328 #[derive(Clone, Debug, Eq, PartialEq)]
5329 struct GlobalEvent(u64);
5330
5331 let events = Rc::new(RefCell::new(Vec::new()));
5332
5333 {
5334 let events = events.clone();
5335 let subscription = Rc::new(RefCell::new(None));
5336 *subscription.borrow_mut() = Some(cx.subscribe_global({
5337 let subscription = subscription.clone();
5338 move |e: &GlobalEvent, _| {
5339 subscription.borrow_mut().take();
5340 events.borrow_mut().push(e.clone());
5341 }
5342 }));
5343 }
5344
5345 cx.update(|cx| {
5346 cx.emit_global(GlobalEvent(1));
5347 cx.emit_global(GlobalEvent(2));
5348 });
5349
5350 assert_eq!(*events.borrow(), [GlobalEvent(1)]);
5351
5352 // Model Observation
5353 let observing_model = cx.add_model(|_| Model);
5354 let observed_model = cx.add_model(|_| Model);
5355
5356 let observation_count = Rc::new(RefCell::new(0));
5357
5358 observing_model.update(cx, |_, cx| {
5359 let observation_count = observation_count.clone();
5360 let subscription = Rc::new(RefCell::new(None));
5361 *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
5362 let subscription = subscription.clone();
5363 move |_, _, _| {
5364 subscription.borrow_mut().take();
5365 *observation_count.borrow_mut() += 1;
5366 }
5367 }));
5368 });
5369
5370 observed_model.update(cx, |_, cx| {
5371 cx.notify();
5372 });
5373
5374 observed_model.update(cx, |_, cx| {
5375 cx.notify();
5376 });
5377
5378 assert_eq!(*observation_count.borrow(), 1);
5379
5380 // View Observation
5381 struct View;
5382
5383 impl Entity for View {
5384 type Event = ();
5385 }
5386
5387 impl super::View for View {
5388 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5389 Empty::new().into_any()
5390 }
5391
5392 fn ui_name() -> &'static str {
5393 "View"
5394 }
5395 }
5396
5397 let (_, root_view) = cx.add_window(|_| View);
5398 let observing_view = cx.add_view(&root_view, |_| View);
5399 let observed_view = cx.add_view(&root_view, |_| View);
5400
5401 let observation_count = Rc::new(RefCell::new(0));
5402 observing_view.update(cx, |_, cx| {
5403 let observation_count = observation_count.clone();
5404 let subscription = Rc::new(RefCell::new(None));
5405 *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
5406 let subscription = subscription.clone();
5407 move |_, _, _| {
5408 subscription.borrow_mut().take();
5409 *observation_count.borrow_mut() += 1;
5410 }
5411 }));
5412 });
5413
5414 observed_view.update(cx, |_, cx| {
5415 cx.notify();
5416 });
5417
5418 observed_view.update(cx, |_, cx| {
5419 cx.notify();
5420 });
5421
5422 assert_eq!(*observation_count.borrow(), 1);
5423
5424 // Global Observation
5425 let observation_count = Rc::new(RefCell::new(0));
5426 let subscription = Rc::new(RefCell::new(None));
5427 *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
5428 let observation_count = observation_count.clone();
5429 let subscription = subscription.clone();
5430 move |_| {
5431 subscription.borrow_mut().take();
5432 *observation_count.borrow_mut() += 1;
5433 }
5434 }));
5435
5436 cx.update(|cx| {
5437 cx.default_global::<()>();
5438 cx.set_global(());
5439 });
5440 assert_eq!(*observation_count.borrow(), 1);
5441 }
5442
5443 #[crate::test(self)]
5444 fn test_focus(cx: &mut TestAppContext) {
5445 struct View {
5446 name: String,
5447 events: Arc<Mutex<Vec<String>>>,
5448 }
5449
5450 impl Entity for View {
5451 type Event = ();
5452 }
5453
5454 impl super::View for View {
5455 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5456 Empty::new().into_any()
5457 }
5458
5459 fn ui_name() -> &'static str {
5460 "View"
5461 }
5462
5463 fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
5464 if cx.handle().id() == focused.id() {
5465 self.events.lock().push(format!("{} focused", &self.name));
5466 }
5467 }
5468
5469 fn focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
5470 if cx.handle().id() == blurred.id() {
5471 self.events.lock().push(format!("{} blurred", &self.name));
5472 }
5473 }
5474 }
5475
5476 let view_events: Arc<Mutex<Vec<String>>> = Default::default();
5477 let (window_id, view_1) = cx.add_window(|_| View {
5478 events: view_events.clone(),
5479 name: "view 1".to_string(),
5480 });
5481 let view_2 = cx.add_view(&view_1, |_| View {
5482 events: view_events.clone(),
5483 name: "view 2".to_string(),
5484 });
5485
5486 let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
5487 view_1.update(cx, |_, cx| {
5488 cx.observe_focus(&view_2, {
5489 let observed_events = observed_events.clone();
5490 move |this, view, focused, cx| {
5491 let label = if focused { "focus" } else { "blur" };
5492 observed_events.lock().push(format!(
5493 "{} observed {}'s {}",
5494 this.name,
5495 view.read(cx).name,
5496 label
5497 ))
5498 }
5499 })
5500 .detach();
5501 });
5502 view_2.update(cx, |_, cx| {
5503 cx.observe_focus(&view_1, {
5504 let observed_events = observed_events.clone();
5505 move |this, view, focused, cx| {
5506 let label = if focused { "focus" } else { "blur" };
5507 observed_events.lock().push(format!(
5508 "{} observed {}'s {}",
5509 this.name,
5510 view.read(cx).name,
5511 label
5512 ))
5513 }
5514 })
5515 .detach();
5516 });
5517 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5518 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5519
5520 view_1.update(cx, |_, cx| {
5521 // Ensure focus events are sent for all intermediate focuses
5522 cx.focus(&view_2);
5523 cx.focus(&view_1);
5524 cx.focus(&view_2);
5525 });
5526
5527 cx.read_window(window_id, |cx| {
5528 assert!(cx.is_child_focused(&view_1));
5529 assert!(!cx.is_child_focused(&view_2));
5530 });
5531 assert_eq!(
5532 mem::take(&mut *view_events.lock()),
5533 [
5534 "view 1 blurred",
5535 "view 2 focused",
5536 "view 2 blurred",
5537 "view 1 focused",
5538 "view 1 blurred",
5539 "view 2 focused"
5540 ],
5541 );
5542 assert_eq!(
5543 mem::take(&mut *observed_events.lock()),
5544 [
5545 "view 2 observed view 1's blur",
5546 "view 1 observed view 2's focus",
5547 "view 1 observed view 2's blur",
5548 "view 2 observed view 1's focus",
5549 "view 2 observed view 1's blur",
5550 "view 1 observed view 2's focus"
5551 ]
5552 );
5553
5554 view_1.update(cx, |_, cx| cx.focus(&view_1));
5555 cx.read_window(window_id, |cx| {
5556 assert!(!cx.is_child_focused(&view_1));
5557 assert!(!cx.is_child_focused(&view_2));
5558 });
5559 assert_eq!(
5560 mem::take(&mut *view_events.lock()),
5561 ["view 2 blurred", "view 1 focused"],
5562 );
5563 assert_eq!(
5564 mem::take(&mut *observed_events.lock()),
5565 [
5566 "view 1 observed view 2's blur",
5567 "view 2 observed view 1's focus"
5568 ]
5569 );
5570
5571 view_1.update(cx, |_, cx| cx.focus(&view_2));
5572 assert_eq!(
5573 mem::take(&mut *view_events.lock()),
5574 ["view 1 blurred", "view 2 focused"],
5575 );
5576 assert_eq!(
5577 mem::take(&mut *observed_events.lock()),
5578 [
5579 "view 2 observed view 1's blur",
5580 "view 1 observed view 2's focus"
5581 ]
5582 );
5583
5584 view_1.update(cx, |_, _| drop(view_2));
5585 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5586 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5587 }
5588
5589 #[crate::test(self)]
5590 fn test_deserialize_actions(cx: &mut AppContext) {
5591 #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
5592 pub struct ComplexAction {
5593 arg: String,
5594 count: usize,
5595 }
5596
5597 actions!(test::something, [SimpleAction]);
5598 impl_actions!(test::something, [ComplexAction]);
5599
5600 cx.add_global_action(move |_: &SimpleAction, _: &mut AppContext| {});
5601 cx.add_global_action(move |_: &ComplexAction, _: &mut AppContext| {});
5602
5603 let action1 = cx
5604 .deserialize_action(
5605 "test::something::ComplexAction",
5606 Some(r#"{"arg": "a", "count": 5}"#),
5607 )
5608 .unwrap();
5609 let action2 = cx
5610 .deserialize_action("test::something::SimpleAction", None)
5611 .unwrap();
5612 assert_eq!(
5613 action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
5614 &ComplexAction {
5615 arg: "a".to_string(),
5616 count: 5,
5617 }
5618 );
5619 assert_eq!(
5620 action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
5621 &SimpleAction
5622 );
5623 }
5624
5625 #[crate::test(self)]
5626 fn test_dispatch_action(cx: &mut AppContext) {
5627 struct ViewA {
5628 id: usize,
5629 }
5630
5631 impl Entity for ViewA {
5632 type Event = ();
5633 }
5634
5635 impl View for ViewA {
5636 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5637 Empty::new().into_any()
5638 }
5639
5640 fn ui_name() -> &'static str {
5641 "View"
5642 }
5643 }
5644
5645 struct ViewB {
5646 id: usize,
5647 }
5648
5649 impl Entity for ViewB {
5650 type Event = ();
5651 }
5652
5653 impl View for ViewB {
5654 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5655 Empty::new().into_any()
5656 }
5657
5658 fn ui_name() -> &'static str {
5659 "View"
5660 }
5661 }
5662
5663 #[derive(Clone, Default, Deserialize, PartialEq)]
5664 pub struct Action(pub String);
5665
5666 impl_actions!(test, [Action]);
5667
5668 let actions = Rc::new(RefCell::new(Vec::new()));
5669
5670 cx.add_global_action({
5671 let actions = actions.clone();
5672 move |_: &Action, _: &mut AppContext| {
5673 actions.borrow_mut().push("global".to_string());
5674 }
5675 });
5676
5677 cx.add_action({
5678 let actions = actions.clone();
5679 move |view: &mut ViewA, action: &Action, cx| {
5680 assert_eq!(action.0, "bar");
5681 cx.propagate_action();
5682 actions.borrow_mut().push(format!("{} a", view.id));
5683 }
5684 });
5685
5686 cx.add_action({
5687 let actions = actions.clone();
5688 move |view: &mut ViewA, _: &Action, cx| {
5689 if view.id != 1 {
5690 cx.add_view(|cx| {
5691 cx.propagate_action(); // Still works on a nested ViewContext
5692 ViewB { id: 5 }
5693 });
5694 }
5695 actions.borrow_mut().push(format!("{} b", view.id));
5696 }
5697 });
5698
5699 cx.add_action({
5700 let actions = actions.clone();
5701 move |view: &mut ViewB, _: &Action, cx| {
5702 cx.propagate_action();
5703 actions.borrow_mut().push(format!("{} c", view.id));
5704 }
5705 });
5706
5707 cx.add_action({
5708 let actions = actions.clone();
5709 move |view: &mut ViewB, _: &Action, cx| {
5710 cx.propagate_action();
5711 actions.borrow_mut().push(format!("{} d", view.id));
5712 }
5713 });
5714
5715 cx.capture_action({
5716 let actions = actions.clone();
5717 move |view: &mut ViewA, _: &Action, cx| {
5718 cx.propagate_action();
5719 actions.borrow_mut().push(format!("{} capture", view.id));
5720 }
5721 });
5722
5723 let observed_actions = Rc::new(RefCell::new(Vec::new()));
5724 cx.observe_actions({
5725 let observed_actions = observed_actions.clone();
5726 move |action_id, _| observed_actions.borrow_mut().push(action_id)
5727 })
5728 .detach();
5729
5730 let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
5731 let view_2 = cx.add_view(&view_1, |_| ViewB { id: 2 });
5732 let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
5733 let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
5734
5735 cx.update_window(window_id, |cx| {
5736 cx.handle_dispatch_action_from_effect(Some(view_4.id()), &Action("bar".to_string()))
5737 });
5738
5739 assert_eq!(
5740 *actions.borrow(),
5741 vec![
5742 "1 capture",
5743 "3 capture",
5744 "4 d",
5745 "4 c",
5746 "3 b",
5747 "3 a",
5748 "2 d",
5749 "2 c",
5750 "1 b"
5751 ]
5752 );
5753 assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
5754
5755 // Remove view_1, which doesn't propagate the action
5756
5757 let (window_id, view_2) = cx.add_window(Default::default(), |_| ViewB { id: 2 });
5758 let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
5759 let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
5760
5761 actions.borrow_mut().clear();
5762 cx.update_window(window_id, |cx| {
5763 cx.handle_dispatch_action_from_effect(Some(view_4.id()), &Action("bar".to_string()))
5764 });
5765
5766 assert_eq!(
5767 *actions.borrow(),
5768 vec![
5769 "3 capture",
5770 "4 d",
5771 "4 c",
5772 "3 b",
5773 "3 a",
5774 "2 d",
5775 "2 c",
5776 "global"
5777 ]
5778 );
5779 assert_eq!(
5780 *observed_actions.borrow(),
5781 [Action::default().id(), Action::default().id()]
5782 );
5783 }
5784
5785 #[crate::test(self)]
5786 fn test_dispatch_keystroke(cx: &mut AppContext) {
5787 #[derive(Clone, Deserialize, PartialEq)]
5788 pub struct Action(String);
5789
5790 impl_actions!(test, [Action]);
5791
5792 struct View {
5793 id: usize,
5794 keymap_context: KeymapContext,
5795 }
5796
5797 impl Entity for View {
5798 type Event = ();
5799 }
5800
5801 impl super::View for View {
5802 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5803 Empty::new().into_any()
5804 }
5805
5806 fn ui_name() -> &'static str {
5807 "View"
5808 }
5809
5810 fn keymap_context(&self, _: &AppContext) -> KeymapContext {
5811 self.keymap_context.clone()
5812 }
5813 }
5814
5815 impl View {
5816 fn new(id: usize) -> Self {
5817 View {
5818 id,
5819 keymap_context: KeymapContext::default(),
5820 }
5821 }
5822 }
5823
5824 let mut view_1 = View::new(1);
5825 let mut view_2 = View::new(2);
5826 let mut view_3 = View::new(3);
5827 view_1.keymap_context.add_identifier("a");
5828 view_2.keymap_context.add_identifier("a");
5829 view_2.keymap_context.add_identifier("b");
5830 view_3.keymap_context.add_identifier("a");
5831 view_3.keymap_context.add_identifier("b");
5832 view_3.keymap_context.add_identifier("c");
5833
5834 let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
5835 let view_2 = cx.add_view(&view_1, |_| view_2);
5836 let _view_3 = cx.add_view(&view_2, |cx| {
5837 cx.focus_self();
5838 view_3
5839 });
5840
5841 // This binding only dispatches an action on view 2 because that view will have
5842 // "a" and "b" in its context, but not "c".
5843 cx.add_bindings(vec![Binding::new(
5844 "a",
5845 Action("a".to_string()),
5846 Some("a && b && !c"),
5847 )]);
5848
5849 cx.add_bindings(vec![Binding::new("b", Action("b".to_string()), None)]);
5850
5851 // This binding only dispatches an action on views 2 and 3, because they have
5852 // a parent view with a in its context
5853 cx.add_bindings(vec![Binding::new(
5854 "c",
5855 Action("c".to_string()),
5856 Some("b > c"),
5857 )]);
5858
5859 // This binding only dispatches an action on view 2, because they have
5860 // a parent view with a in its context
5861 cx.add_bindings(vec![Binding::new(
5862 "d",
5863 Action("d".to_string()),
5864 Some("a && !b > b"),
5865 )]);
5866
5867 let actions = Rc::new(RefCell::new(Vec::new()));
5868 cx.add_action({
5869 let actions = actions.clone();
5870 move |view: &mut View, action: &Action, cx| {
5871 actions
5872 .borrow_mut()
5873 .push(format!("{} {}", view.id, action.0));
5874
5875 if action.0 == "b" {
5876 cx.propagate_action();
5877 }
5878 }
5879 });
5880
5881 cx.add_global_action({
5882 let actions = actions.clone();
5883 move |action: &Action, _| {
5884 actions.borrow_mut().push(format!("global {}", action.0));
5885 }
5886 });
5887
5888 cx.update_window(window_id, |cx| {
5889 cx.dispatch_keystroke(&Keystroke::parse("a").unwrap())
5890 });
5891 assert_eq!(&*actions.borrow(), &["2 a"]);
5892 actions.borrow_mut().clear();
5893
5894 cx.update_window(window_id, |cx| {
5895 cx.dispatch_keystroke(&Keystroke::parse("b").unwrap());
5896 });
5897
5898 assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
5899 actions.borrow_mut().clear();
5900
5901 cx.update_window(window_id, |cx| {
5902 cx.dispatch_keystroke(&Keystroke::parse("c").unwrap());
5903 });
5904 assert_eq!(&*actions.borrow(), &["3 c"]);
5905 actions.borrow_mut().clear();
5906
5907 cx.update_window(window_id, |cx| {
5908 cx.dispatch_keystroke(&Keystroke::parse("d").unwrap());
5909 });
5910 assert_eq!(&*actions.borrow(), &["2 d"]);
5911 actions.borrow_mut().clear();
5912 }
5913
5914 #[crate::test(self)]
5915 fn test_keystrokes_for_action(cx: &mut AppContext) {
5916 actions!(test, [Action1, Action2, GlobalAction]);
5917
5918 struct View1 {}
5919 struct View2 {}
5920
5921 impl Entity for View1 {
5922 type Event = ();
5923 }
5924 impl Entity for View2 {
5925 type Event = ();
5926 }
5927
5928 impl super::View for View1 {
5929 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5930 Empty::new().into_any()
5931 }
5932 fn ui_name() -> &'static str {
5933 "View1"
5934 }
5935 }
5936 impl super::View for View2 {
5937 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5938 Empty::new().into_any()
5939 }
5940 fn ui_name() -> &'static str {
5941 "View2"
5942 }
5943 }
5944
5945 let (window_id, view_1) = cx.add_window(Default::default(), |_| View1 {});
5946 let view_2 = cx.add_view(&view_1, |cx| {
5947 cx.focus_self();
5948 View2 {}
5949 });
5950
5951 cx.add_action(|_: &mut View1, _: &Action1, _cx| {});
5952 cx.add_action(|_: &mut View2, _: &Action2, _cx| {});
5953 cx.add_global_action(|_: &GlobalAction, _| {});
5954
5955 cx.add_bindings(vec![
5956 Binding::new("a", Action1, Some("View1")),
5957 Binding::new("b", Action2, Some("View1 > View2")),
5958 Binding::new("c", GlobalAction, Some("View3")), // View 3 does not exist
5959 ]);
5960
5961 cx.update_window(window_id, |cx| {
5962 // Sanity check
5963 assert_eq!(
5964 cx.keystrokes_for_action(view_1.id(), &Action1)
5965 .unwrap()
5966 .as_slice(),
5967 &[Keystroke::parse("a").unwrap()]
5968 );
5969 assert_eq!(
5970 cx.keystrokes_for_action(view_2.id(), &Action2)
5971 .unwrap()
5972 .as_slice(),
5973 &[Keystroke::parse("b").unwrap()]
5974 );
5975
5976 // The 'a' keystroke propagates up the view tree from view_2
5977 // to view_1. The action, Action1, is handled by view_1.
5978 assert_eq!(
5979 cx.keystrokes_for_action(view_2.id(), &Action1)
5980 .unwrap()
5981 .as_slice(),
5982 &[Keystroke::parse("a").unwrap()]
5983 );
5984
5985 // Actions that are handled below the current view don't have bindings
5986 assert_eq!(cx.keystrokes_for_action(view_1.id(), &Action2), None);
5987
5988 // Actions that are handled in other branches of the tree should not have a binding
5989 assert_eq!(cx.keystrokes_for_action(view_2.id(), &GlobalAction), None);
5990
5991 // Check that global actions do not have a binding, even if a binding does exist in another view
5992 assert_eq!(
5993 &available_actions(view_1.id(), cx),
5994 &[
5995 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
5996 ("test::GlobalAction", vec![])
5997 ],
5998 );
5999
6000 // Check that view 1 actions and bindings are available even when called from view 2
6001 assert_eq!(
6002 &available_actions(view_2.id(), cx),
6003 &[
6004 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
6005 ("test::Action2", vec![Keystroke::parse("b").unwrap()]),
6006 ("test::GlobalAction", vec![]),
6007 ],
6008 );
6009 });
6010
6011 // Produces a list of actions and key bindings
6012 fn available_actions(
6013 view_id: usize,
6014 cx: &WindowContext,
6015 ) -> Vec<(&'static str, Vec<Keystroke>)> {
6016 cx.available_actions(view_id)
6017 .map(|(action_name, _, bindings)| {
6018 (
6019 action_name,
6020 bindings
6021 .iter()
6022 .map(|binding| binding.keystrokes()[0].clone())
6023 .collect::<Vec<_>>(),
6024 )
6025 })
6026 .sorted_by(|(name1, _), (name2, _)| name1.cmp(name2))
6027 .collect()
6028 }
6029 }
6030
6031 #[crate::test(self)]
6032 async fn test_model_condition(cx: &mut TestAppContext) {
6033 struct Counter(usize);
6034
6035 impl super::Entity for Counter {
6036 type Event = ();
6037 }
6038
6039 impl Counter {
6040 fn inc(&mut self, cx: &mut ModelContext<Self>) {
6041 self.0 += 1;
6042 cx.notify();
6043 }
6044 }
6045
6046 let model = cx.add_model(|_| Counter(0));
6047
6048 let condition1 = model.condition(cx, |model, _| model.0 == 2);
6049 let condition2 = model.condition(cx, |model, _| model.0 == 3);
6050 smol::pin!(condition1, condition2);
6051
6052 model.update(cx, |model, cx| model.inc(cx));
6053 assert_eq!(poll_once(&mut condition1).await, None);
6054 assert_eq!(poll_once(&mut condition2).await, None);
6055
6056 model.update(cx, |model, cx| model.inc(cx));
6057 assert_eq!(poll_once(&mut condition1).await, Some(()));
6058 assert_eq!(poll_once(&mut condition2).await, None);
6059
6060 model.update(cx, |model, cx| model.inc(cx));
6061 assert_eq!(poll_once(&mut condition2).await, Some(()));
6062
6063 model.update(cx, |_, cx| cx.notify());
6064 }
6065
6066 #[crate::test(self)]
6067 #[should_panic]
6068 async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6069 struct Model;
6070
6071 impl super::Entity for Model {
6072 type Event = ();
6073 }
6074
6075 let model = cx.add_model(|_| Model);
6076 model.condition(cx, |_, _| false).await;
6077 }
6078
6079 #[crate::test(self)]
6080 #[should_panic(expected = "model dropped with pending condition")]
6081 async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6082 struct Model;
6083
6084 impl super::Entity for Model {
6085 type Event = ();
6086 }
6087
6088 let model = cx.add_model(|_| Model);
6089 let condition = model.condition(cx, |_, _| false);
6090 cx.update(|_| drop(model));
6091 condition.await;
6092 }
6093
6094 #[crate::test(self)]
6095 async fn test_view_condition(cx: &mut TestAppContext) {
6096 struct Counter(usize);
6097
6098 impl super::Entity for Counter {
6099 type Event = ();
6100 }
6101
6102 impl super::View for Counter {
6103 fn ui_name() -> &'static str {
6104 "test view"
6105 }
6106
6107 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6108 Empty::new().into_any()
6109 }
6110 }
6111
6112 impl Counter {
6113 fn inc(&mut self, cx: &mut ViewContext<Self>) {
6114 self.0 += 1;
6115 cx.notify();
6116 }
6117 }
6118
6119 let (_, view) = cx.add_window(|_| Counter(0));
6120
6121 let condition1 = view.condition(cx, |view, _| view.0 == 2);
6122 let condition2 = view.condition(cx, |view, _| view.0 == 3);
6123 smol::pin!(condition1, condition2);
6124
6125 view.update(cx, |view, cx| view.inc(cx));
6126 assert_eq!(poll_once(&mut condition1).await, None);
6127 assert_eq!(poll_once(&mut condition2).await, None);
6128
6129 view.update(cx, |view, cx| view.inc(cx));
6130 assert_eq!(poll_once(&mut condition1).await, Some(()));
6131 assert_eq!(poll_once(&mut condition2).await, None);
6132
6133 view.update(cx, |view, cx| view.inc(cx));
6134 assert_eq!(poll_once(&mut condition2).await, Some(()));
6135 view.update(cx, |_, cx| cx.notify());
6136 }
6137
6138 #[crate::test(self)]
6139 #[should_panic]
6140 async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6141 let (_, view) = cx.add_window(|_| TestView::default());
6142 view.condition(cx, |_, _| false).await;
6143 }
6144
6145 #[crate::test(self)]
6146 #[should_panic(expected = "view dropped with pending condition")]
6147 async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6148 let (_, root_view) = cx.add_window(|_| TestView::default());
6149 let view = cx.add_view(&root_view, |_| TestView::default());
6150
6151 let condition = view.condition(cx, |_, _| false);
6152 cx.update(|_| drop(view));
6153 condition.await;
6154 }
6155
6156 #[crate::test(self)]
6157 fn test_refresh_windows(cx: &mut AppContext) {
6158 struct View(usize);
6159
6160 impl super::Entity for View {
6161 type Event = ();
6162 }
6163
6164 impl super::View for View {
6165 fn ui_name() -> &'static str {
6166 "test view"
6167 }
6168
6169 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6170 Empty::new().into_any_named(format!("render count: {}", post_inc(&mut self.0)))
6171 }
6172 }
6173
6174 let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
6175 cx.update_window(window_id, |cx| {
6176 assert_eq!(
6177 cx.window.rendered_views[&root_view.id()].name(),
6178 Some("render count: 0")
6179 );
6180 });
6181
6182 let view = cx.add_view(&root_view, |cx| {
6183 cx.refresh_windows();
6184 View(0)
6185 });
6186
6187 cx.update_window(window_id, |cx| {
6188 assert_eq!(
6189 cx.window.rendered_views[&root_view.id()].name(),
6190 Some("render count: 1")
6191 );
6192 assert_eq!(
6193 cx.window.rendered_views[&view.id()].name(),
6194 Some("render count: 0")
6195 );
6196 });
6197
6198 cx.update(|cx| cx.refresh_windows());
6199
6200 cx.update_window(window_id, |cx| {
6201 assert_eq!(
6202 cx.window.rendered_views[&root_view.id()].name(),
6203 Some("render count: 2")
6204 );
6205 assert_eq!(
6206 cx.window.rendered_views[&view.id()].name(),
6207 Some("render count: 1")
6208 );
6209 });
6210
6211 cx.update(|cx| {
6212 cx.refresh_windows();
6213 drop(view);
6214 });
6215
6216 cx.update_window(window_id, |cx| {
6217 assert_eq!(
6218 cx.window.rendered_views[&root_view.id()].name(),
6219 Some("render count: 3")
6220 );
6221 assert_eq!(cx.window.rendered_views.len(), 1);
6222 });
6223 }
6224
6225 #[crate::test(self)]
6226 async fn test_labeled_tasks(cx: &mut TestAppContext) {
6227 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6228 let (mut sender, mut reciever) = postage::oneshot::channel::<()>();
6229 let task = cx
6230 .update(|cx| cx.spawn_labeled("Test Label", |_| async move { reciever.recv().await }));
6231
6232 assert_eq!(
6233 Some("Test Label"),
6234 cx.update(|cx| cx.active_labeled_tasks().next())
6235 );
6236 sender
6237 .send(())
6238 .await
6239 .expect("Could not send message to complete task");
6240 task.await;
6241
6242 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6243 }
6244
6245 #[crate::test(self)]
6246 async fn test_window_activation(cx: &mut TestAppContext) {
6247 struct View(&'static str);
6248
6249 impl super::Entity for View {
6250 type Event = ();
6251 }
6252
6253 impl super::View for View {
6254 fn ui_name() -> &'static str {
6255 "test view"
6256 }
6257
6258 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6259 Empty::new().into_any()
6260 }
6261 }
6262
6263 let events = Rc::new(RefCell::new(Vec::new()));
6264 let (window_1, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6265 cx.observe_window_activation({
6266 let events = events.clone();
6267 move |this, active, _| events.borrow_mut().push((this.0, active))
6268 })
6269 .detach();
6270 View("window 1")
6271 });
6272 assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]);
6273
6274 let (window_2, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6275 cx.observe_window_activation({
6276 let events = events.clone();
6277 move |this, active, _| events.borrow_mut().push((this.0, active))
6278 })
6279 .detach();
6280 View("window 2")
6281 });
6282 assert_eq!(
6283 mem::take(&mut *events.borrow_mut()),
6284 [("window 1", false), ("window 2", true)]
6285 );
6286
6287 let (window_3, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6288 cx.observe_window_activation({
6289 let events = events.clone();
6290 move |this, active, _| events.borrow_mut().push((this.0, active))
6291 })
6292 .detach();
6293 View("window 3")
6294 });
6295 assert_eq!(
6296 mem::take(&mut *events.borrow_mut()),
6297 [("window 2", false), ("window 3", true)]
6298 );
6299
6300 cx.simulate_window_activation(Some(window_2));
6301 assert_eq!(
6302 mem::take(&mut *events.borrow_mut()),
6303 [("window 3", false), ("window 2", true)]
6304 );
6305
6306 cx.simulate_window_activation(Some(window_1));
6307 assert_eq!(
6308 mem::take(&mut *events.borrow_mut()),
6309 [("window 2", false), ("window 1", true)]
6310 );
6311
6312 cx.simulate_window_activation(Some(window_3));
6313 assert_eq!(
6314 mem::take(&mut *events.borrow_mut()),
6315 [("window 1", false), ("window 3", true)]
6316 );
6317
6318 cx.simulate_window_activation(Some(window_3));
6319 assert_eq!(mem::take(&mut *events.borrow_mut()), []);
6320 }
6321
6322 #[crate::test(self)]
6323 fn test_child_view(cx: &mut TestAppContext) {
6324 struct Child {
6325 rendered: Rc<Cell<bool>>,
6326 dropped: Rc<Cell<bool>>,
6327 }
6328
6329 impl super::Entity for Child {
6330 type Event = ();
6331 }
6332
6333 impl super::View for Child {
6334 fn ui_name() -> &'static str {
6335 "child view"
6336 }
6337
6338 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6339 self.rendered.set(true);
6340 Empty::new().into_any()
6341 }
6342 }
6343
6344 impl Drop for Child {
6345 fn drop(&mut self) {
6346 self.dropped.set(true);
6347 }
6348 }
6349
6350 struct Parent {
6351 child: Option<ViewHandle<Child>>,
6352 }
6353
6354 impl super::Entity for Parent {
6355 type Event = ();
6356 }
6357
6358 impl super::View for Parent {
6359 fn ui_name() -> &'static str {
6360 "parent view"
6361 }
6362
6363 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
6364 if let Some(child) = self.child.as_ref() {
6365 ChildView::new(child, cx).into_any()
6366 } else {
6367 Empty::new().into_any()
6368 }
6369 }
6370 }
6371
6372 let child_rendered = Rc::new(Cell::new(false));
6373 let child_dropped = Rc::new(Cell::new(false));
6374 let (_, root_view) = cx.add_window(|cx| Parent {
6375 child: Some(cx.add_view(|_| Child {
6376 rendered: child_rendered.clone(),
6377 dropped: child_dropped.clone(),
6378 })),
6379 });
6380 assert!(child_rendered.take());
6381 assert!(!child_dropped.take());
6382
6383 root_view.update(cx, |view, cx| {
6384 view.child.take();
6385 cx.notify();
6386 });
6387 assert!(!child_rendered.take());
6388 assert!(child_dropped.take());
6389 }
6390
6391 #[derive(Default)]
6392 struct TestView {
6393 events: Vec<String>,
6394 }
6395
6396 impl Entity for TestView {
6397 type Event = String;
6398 }
6399
6400 impl View for TestView {
6401 fn ui_name() -> &'static str {
6402 "TestView"
6403 }
6404
6405 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6406 Empty::new().into_any()
6407 }
6408 }
6409}