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::{AnyRootElement, Element, 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>) -> Element<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>(
2522 &mut self,
2523 focused_id: usize,
2524 cx: &mut WindowContext<'a, 'b>,
2525 view_id: usize,
2526 );
2527 fn focus_out(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize);
2528 fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool;
2529 fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool;
2530 fn modifiers_changed(
2531 &mut self,
2532 event: &ModifiersChangedEvent,
2533 cx: &mut WindowContext,
2534 view_id: usize,
2535 ) -> bool;
2536 fn keymap_context(&self, cx: &AppContext) -> KeymapContext;
2537 fn debug_json(&self, cx: &WindowContext) -> serde_json::Value;
2538
2539 fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String>;
2540 fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
2541 fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
2542 fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize);
2543 fn replace_text_in_range(
2544 &mut self,
2545 range: Option<Range<usize>>,
2546 text: &str,
2547 cx: &mut WindowContext,
2548 view_id: usize,
2549 );
2550 fn replace_and_mark_text_in_range(
2551 &mut self,
2552 range: Option<Range<usize>>,
2553 new_text: &str,
2554 new_selected_range: Option<Range<usize>>,
2555 cx: &mut WindowContext,
2556 view_id: usize,
2557 );
2558 fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle {
2559 AnyViewHandle::new(
2560 window_id,
2561 view_id,
2562 self.as_any().type_id(),
2563 cx.ref_counts.clone(),
2564 )
2565 }
2566}
2567
2568impl<V> AnyView for V
2569where
2570 V: View,
2571{
2572 fn as_any(&self) -> &dyn Any {
2573 self
2574 }
2575
2576 fn as_any_mut(&mut self) -> &mut dyn Any {
2577 self
2578 }
2579
2580 fn release(&mut self, cx: &mut AppContext) {
2581 self.release(cx);
2582 }
2583
2584 fn app_will_quit(
2585 &mut self,
2586 cx: &mut AppContext,
2587 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2588 self.app_will_quit(cx)
2589 }
2590
2591 fn ui_name(&self) -> &'static str {
2592 V::ui_name()
2593 }
2594
2595 fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement> {
2596 let mut view_context = ViewContext::mutable(cx, view_id);
2597 let element = V::render(self, &mut view_context);
2598 let view = WeakViewHandle::new(cx.window_id, view_id);
2599 Box::new(RootElement::new(element, view))
2600 }
2601
2602 fn focus_in(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize) {
2603 let mut cx = ViewContext::mutable(cx, view_id);
2604 let focused_view_handle: AnyViewHandle = if view_id == focused_id {
2605 cx.handle().into_any()
2606 } else {
2607 let focused_type = cx
2608 .views
2609 .get(&(cx.window_id, focused_id))
2610 .unwrap()
2611 .as_any()
2612 .type_id();
2613 AnyViewHandle::new(
2614 cx.window_id,
2615 focused_id,
2616 focused_type,
2617 cx.ref_counts.clone(),
2618 )
2619 };
2620 View::focus_in(self, focused_view_handle, &mut cx);
2621 }
2622
2623 fn focus_out(&mut self, blurred_id: usize, cx: &mut WindowContext, view_id: usize) {
2624 let mut cx = ViewContext::mutable(cx, view_id);
2625 let blurred_view_handle: AnyViewHandle = if view_id == blurred_id {
2626 cx.handle().into_any()
2627 } else {
2628 let blurred_type = cx
2629 .views
2630 .get(&(cx.window_id, blurred_id))
2631 .unwrap()
2632 .as_any()
2633 .type_id();
2634 AnyViewHandle::new(
2635 cx.window_id,
2636 blurred_id,
2637 blurred_type,
2638 cx.ref_counts.clone(),
2639 )
2640 };
2641 View::focus_out(self, blurred_view_handle, &mut cx);
2642 }
2643
2644 fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool {
2645 let mut cx = ViewContext::mutable(cx, view_id);
2646 View::key_down(self, event, &mut cx)
2647 }
2648
2649 fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool {
2650 let mut cx = ViewContext::mutable(cx, view_id);
2651 View::key_up(self, event, &mut cx)
2652 }
2653
2654 fn modifiers_changed(
2655 &mut self,
2656 event: &ModifiersChangedEvent,
2657 cx: &mut WindowContext,
2658 view_id: usize,
2659 ) -> bool {
2660 let mut cx = ViewContext::mutable(cx, view_id);
2661 View::modifiers_changed(self, event, &mut cx)
2662 }
2663
2664 fn keymap_context(&self, cx: &AppContext) -> KeymapContext {
2665 View::keymap_context(self, cx)
2666 }
2667
2668 fn debug_json(&self, cx: &WindowContext) -> serde_json::Value {
2669 View::debug_json(self, cx)
2670 }
2671
2672 fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String> {
2673 View::text_for_range(self, range, cx)
2674 }
2675
2676 fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
2677 View::selected_text_range(self, cx)
2678 }
2679
2680 fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
2681 View::marked_text_range(self, cx)
2682 }
2683
2684 fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize) {
2685 let mut cx = ViewContext::mutable(cx, view_id);
2686 View::unmark_text(self, &mut cx)
2687 }
2688
2689 fn replace_text_in_range(
2690 &mut self,
2691 range: Option<Range<usize>>,
2692 text: &str,
2693 cx: &mut WindowContext,
2694 view_id: usize,
2695 ) {
2696 let mut cx = ViewContext::mutable(cx, view_id);
2697 View::replace_text_in_range(self, range, text, &mut cx)
2698 }
2699
2700 fn replace_and_mark_text_in_range(
2701 &mut self,
2702 range: Option<Range<usize>>,
2703 new_text: &str,
2704 new_selected_range: Option<Range<usize>>,
2705 cx: &mut WindowContext,
2706 view_id: usize,
2707 ) {
2708 let mut cx = ViewContext::mutable(cx, view_id);
2709 View::replace_and_mark_text_in_range(self, range, new_text, new_selected_range, &mut cx)
2710 }
2711}
2712
2713pub struct ModelContext<'a, T: ?Sized> {
2714 app: &'a mut AppContext,
2715 model_id: usize,
2716 model_type: PhantomData<T>,
2717 halt_stream: bool,
2718}
2719
2720impl<'a, T: Entity> ModelContext<'a, T> {
2721 fn new(app: &'a mut AppContext, model_id: usize) -> Self {
2722 Self {
2723 app,
2724 model_id,
2725 model_type: PhantomData,
2726 halt_stream: false,
2727 }
2728 }
2729
2730 pub fn background(&self) -> &Arc<executor::Background> {
2731 &self.app.background
2732 }
2733
2734 pub fn halt_stream(&mut self) {
2735 self.halt_stream = true;
2736 }
2737
2738 pub fn model_id(&self) -> usize {
2739 self.model_id
2740 }
2741
2742 pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2743 where
2744 S: Entity,
2745 F: FnOnce(&mut ModelContext<S>) -> S,
2746 {
2747 self.app.add_model(build_model)
2748 }
2749
2750 pub fn emit(&mut self, payload: T::Event) {
2751 self.app.pending_effects.push_back(Effect::Event {
2752 entity_id: self.model_id,
2753 payload: Box::new(payload),
2754 });
2755 }
2756
2757 pub fn notify(&mut self) {
2758 self.app.notify_model(self.model_id);
2759 }
2760
2761 pub fn subscribe<S: Entity, F>(
2762 &mut self,
2763 handle: &ModelHandle<S>,
2764 mut callback: F,
2765 ) -> Subscription
2766 where
2767 S::Event: 'static,
2768 F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
2769 {
2770 let subscriber = self.weak_handle();
2771 self.app
2772 .subscribe_internal(handle, move |emitter, event, cx| {
2773 if let Some(subscriber) = subscriber.upgrade(cx) {
2774 subscriber.update(cx, |subscriber, cx| {
2775 callback(subscriber, emitter, event, cx);
2776 });
2777 true
2778 } else {
2779 false
2780 }
2781 })
2782 }
2783
2784 pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
2785 where
2786 S: Entity,
2787 F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
2788 {
2789 let observer = self.weak_handle();
2790 self.app.observe_internal(handle, move |observed, cx| {
2791 if let Some(observer) = observer.upgrade(cx) {
2792 observer.update(cx, |observer, cx| {
2793 callback(observer, observed, cx);
2794 });
2795 true
2796 } else {
2797 false
2798 }
2799 })
2800 }
2801
2802 pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
2803 where
2804 G: Any,
2805 F: 'static + FnMut(&mut T, &mut ModelContext<T>),
2806 {
2807 let observer = self.weak_handle();
2808 self.app.observe_global::<G, _>(move |cx| {
2809 if let Some(observer) = observer.upgrade(cx) {
2810 observer.update(cx, |observer, cx| callback(observer, cx));
2811 }
2812 })
2813 }
2814
2815 pub fn observe_release<S, F>(
2816 &mut self,
2817 handle: &ModelHandle<S>,
2818 mut callback: F,
2819 ) -> Subscription
2820 where
2821 S: Entity,
2822 F: 'static + FnMut(&mut T, &S, &mut ModelContext<T>),
2823 {
2824 let observer = self.weak_handle();
2825 self.app.observe_release(handle, move |released, cx| {
2826 if let Some(observer) = observer.upgrade(cx) {
2827 observer.update(cx, |observer, cx| {
2828 callback(observer, released, cx);
2829 });
2830 }
2831 })
2832 }
2833
2834 pub fn handle(&self) -> ModelHandle<T> {
2835 ModelHandle::new(self.model_id, &self.app.ref_counts)
2836 }
2837
2838 pub fn weak_handle(&self) -> WeakModelHandle<T> {
2839 WeakModelHandle::new(self.model_id)
2840 }
2841
2842 pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
2843 where
2844 F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
2845 Fut: 'static + Future<Output = S>,
2846 S: 'static,
2847 {
2848 let handle = self.handle();
2849 self.app.spawn(|cx| f(handle, cx))
2850 }
2851
2852 pub fn spawn_weak<F, Fut, S>(&mut self, f: F) -> Task<S>
2853 where
2854 F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
2855 Fut: 'static + Future<Output = S>,
2856 S: 'static,
2857 {
2858 let handle = self.weak_handle();
2859 self.app.spawn(|cx| f(handle, cx))
2860 }
2861}
2862
2863impl<M> AsRef<AppContext> for ModelContext<'_, M> {
2864 fn as_ref(&self) -> &AppContext {
2865 &self.app
2866 }
2867}
2868
2869impl<M> AsMut<AppContext> for ModelContext<'_, M> {
2870 fn as_mut(&mut self) -> &mut AppContext {
2871 self.app
2872 }
2873}
2874
2875impl<M> ReadModel for ModelContext<'_, M> {
2876 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2877 self.app.read_model(handle)
2878 }
2879}
2880
2881impl<M> UpdateModel for ModelContext<'_, M> {
2882 fn update_model<T: Entity, V>(
2883 &mut self,
2884 handle: &ModelHandle<T>,
2885 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2886 ) -> V {
2887 self.app.update_model(handle, update)
2888 }
2889}
2890
2891impl<M> UpgradeModelHandle for ModelContext<'_, M> {
2892 fn upgrade_model_handle<T: Entity>(
2893 &self,
2894 handle: &WeakModelHandle<T>,
2895 ) -> Option<ModelHandle<T>> {
2896 self.app.upgrade_model_handle(handle)
2897 }
2898
2899 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2900 self.app.model_handle_is_upgradable(handle)
2901 }
2902
2903 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2904 self.app.upgrade_any_model_handle(handle)
2905 }
2906}
2907
2908impl<M> Deref for ModelContext<'_, M> {
2909 type Target = AppContext;
2910
2911 fn deref(&self) -> &Self::Target {
2912 self.app
2913 }
2914}
2915
2916impl<M> DerefMut for ModelContext<'_, M> {
2917 fn deref_mut(&mut self) -> &mut Self::Target {
2918 &mut self.app
2919 }
2920}
2921
2922pub struct ViewContext<'a, 'b, 'c, T: ?Sized> {
2923 window_context: Reference<'c, WindowContext<'a, 'b>>,
2924 view_id: usize,
2925 view_type: PhantomData<T>,
2926}
2927
2928impl<'a, 'b, 'c, T: View> Deref for ViewContext<'a, 'b, 'c, T> {
2929 type Target = WindowContext<'a, 'b>;
2930
2931 fn deref(&self) -> &Self::Target {
2932 &self.window_context
2933 }
2934}
2935
2936impl<T: View> DerefMut for ViewContext<'_, '_, '_, T> {
2937 fn deref_mut(&mut self) -> &mut Self::Target {
2938 &mut self.window_context
2939 }
2940}
2941
2942impl<'a, 'b, 'c, V: View> ViewContext<'a, 'b, 'c, V> {
2943 pub(crate) fn mutable(window_context: &'c mut WindowContext<'a, 'b>, view_id: usize) -> Self {
2944 Self {
2945 window_context: Reference::Mutable(window_context),
2946 view_id,
2947 view_type: PhantomData,
2948 }
2949 }
2950
2951 pub(crate) fn immutable(window_context: &'c WindowContext<'a, 'b>, view_id: usize) -> Self {
2952 Self {
2953 window_context: Reference::Immutable(window_context),
2954 view_id,
2955 view_type: PhantomData,
2956 }
2957 }
2958
2959 pub fn window_context(&mut self) -> &mut WindowContext<'a, 'b> {
2960 &mut self.window_context
2961 }
2962
2963 pub fn handle(&self) -> ViewHandle<V> {
2964 ViewHandle::new(
2965 self.window_id,
2966 self.view_id,
2967 &self.window_context.ref_counts,
2968 )
2969 }
2970
2971 pub fn weak_handle(&self) -> WeakViewHandle<V> {
2972 WeakViewHandle::new(self.window_id, self.view_id)
2973 }
2974
2975 pub fn parent(&self) -> Option<usize> {
2976 self.window_context.parent(self.view_id)
2977 }
2978
2979 pub fn window_id(&self) -> usize {
2980 self.window_id
2981 }
2982
2983 pub fn view_id(&self) -> usize {
2984 self.view_id
2985 }
2986
2987 pub fn foreground(&self) -> &Rc<executor::Foreground> {
2988 self.window_context.foreground()
2989 }
2990
2991 pub fn background_executor(&self) -> &Arc<executor::Background> {
2992 &self.window_context.background
2993 }
2994
2995 pub fn platform(&self) -> &Arc<dyn Platform> {
2996 self.window_context.platform()
2997 }
2998
2999 pub fn prompt_for_paths(
3000 &self,
3001 options: PathPromptOptions,
3002 ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
3003 self.window_context.prompt_for_paths(options)
3004 }
3005
3006 pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
3007 self.window_context.prompt_for_new_path(directory)
3008 }
3009
3010 pub fn reveal_path(&self, path: &Path) {
3011 self.window_context.reveal_path(path)
3012 }
3013
3014 pub fn focus(&mut self, handle: &AnyViewHandle) {
3015 self.window_context
3016 .focus(handle.window_id, Some(handle.view_id));
3017 }
3018
3019 pub fn focus_self(&mut self) {
3020 let window_id = self.window_id;
3021 let view_id = self.view_id;
3022 self.window_context.focus(window_id, Some(view_id));
3023 }
3024
3025 pub fn is_self_focused(&self) -> bool {
3026 self.window.focused_view_id == Some(self.view_id)
3027 }
3028
3029 pub fn is_parent_view_focused(&self) -> bool {
3030 if let Some(parent_view_id) = self.ancestors(self.view_id).next().clone() {
3031 self.focused_view_id() == Some(parent_view_id)
3032 } else {
3033 false
3034 }
3035 }
3036
3037 pub fn focus_parent_view(&mut self) {
3038 let next = self.ancestors(self.view_id).next().clone();
3039 if let Some(parent_view_id) = next {
3040 let window_id = self.window_id;
3041 self.window_context.focus(window_id, Some(parent_view_id));
3042 }
3043 }
3044
3045 pub fn is_child(&self, view: impl Into<AnyViewHandle>) -> bool {
3046 let view = view.into();
3047 if self.window_id != view.window_id {
3048 return false;
3049 }
3050 self.ancestors(view.view_id)
3051 .skip(1) // Skip self id
3052 .any(|parent| parent == self.view_id)
3053 }
3054
3055 pub fn blur(&mut self) {
3056 let window_id = self.window_id;
3057 self.window_context.focus(window_id, None);
3058 }
3059
3060 pub fn on_window_should_close<F>(&mut self, mut callback: F)
3061 where
3062 F: 'static + FnMut(&mut V, &mut ViewContext<V>) -> bool,
3063 {
3064 let window_id = self.window_id;
3065 let view = self.weak_handle();
3066 self.pending_effects
3067 .push_back(Effect::WindowShouldCloseSubscription {
3068 window_id,
3069 callback: Box::new(move |cx| {
3070 cx.update_window(window_id, |cx| {
3071 if let Some(view) = view.upgrade(cx) {
3072 view.update(cx, |view, cx| callback(view, cx))
3073 } else {
3074 true
3075 }
3076 })
3077 .unwrap_or(true)
3078 }),
3079 });
3080 }
3081
3082 pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
3083 where
3084 S: View,
3085 F: FnOnce(&mut ViewContext<S>) -> S,
3086 {
3087 self.window_context
3088 .build_and_insert_view(ParentId::View(self.view_id), |cx| Some(build_view(cx)))
3089 .unwrap()
3090 }
3091
3092 pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
3093 where
3094 S: View,
3095 F: FnOnce(&mut ViewContext<S>) -> Option<S>,
3096 {
3097 self.window_context
3098 .build_and_insert_view(ParentId::View(self.view_id), build_view)
3099 }
3100
3101 pub fn reparent(&mut self, view_handle: &AnyViewHandle) {
3102 if self.window_id != view_handle.window_id {
3103 panic!("Can't reparent view to a view from a different window");
3104 }
3105 self.parents
3106 .remove(&(view_handle.window_id, view_handle.view_id));
3107 let new_parent_id = self.view_id;
3108 self.parents.insert(
3109 (view_handle.window_id, view_handle.view_id),
3110 ParentId::View(new_parent_id),
3111 );
3112 }
3113
3114 pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3115 where
3116 E: Entity,
3117 E::Event: 'static,
3118 H: Handle<E>,
3119 F: 'static + FnMut(&mut V, H, &E::Event, &mut ViewContext<V>),
3120 {
3121 let subscriber = self.weak_handle();
3122 self.window_context
3123 .subscribe_internal(handle, move |emitter, event, cx| {
3124 if let Some(subscriber) = subscriber.upgrade(cx) {
3125 subscriber.update(cx, |subscriber, cx| {
3126 callback(subscriber, emitter, event, cx);
3127 });
3128 true
3129 } else {
3130 false
3131 }
3132 })
3133 }
3134
3135 pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3136 where
3137 E: Entity,
3138 H: Handle<E>,
3139 F: 'static + FnMut(&mut V, H, &mut ViewContext<V>),
3140 {
3141 let window_id = self.window_id;
3142 let observer = self.weak_handle();
3143 self.window_context
3144 .observe_internal(handle, move |observed, cx| {
3145 cx.update_window(window_id, |cx| {
3146 if let Some(observer) = observer.upgrade(cx) {
3147 observer.update(cx, |observer, cx| {
3148 callback(observer, observed, cx);
3149 });
3150 true
3151 } else {
3152 false
3153 }
3154 })
3155 .unwrap_or(false)
3156 })
3157 }
3158
3159 pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
3160 where
3161 G: Any,
3162 F: 'static + FnMut(&mut V, &mut ViewContext<V>),
3163 {
3164 let window_id = self.window_id;
3165 let observer = self.weak_handle();
3166 self.window_context.observe_global::<G, _>(move |cx| {
3167 cx.update_window(window_id, |cx| {
3168 if let Some(observer) = observer.upgrade(cx) {
3169 observer.update(cx, |observer, cx| callback(observer, cx));
3170 }
3171 });
3172 })
3173 }
3174
3175 pub fn observe_focus<F, W>(&mut self, handle: &ViewHandle<W>, mut callback: F) -> Subscription
3176 where
3177 F: 'static + FnMut(&mut V, ViewHandle<W>, bool, &mut ViewContext<V>),
3178 W: View,
3179 {
3180 let observer = self.weak_handle();
3181 self.window_context
3182 .observe_focus(handle, move |observed, focused, cx| {
3183 if let Some(observer) = observer.upgrade(cx) {
3184 observer.update(cx, |observer, cx| {
3185 callback(observer, observed, focused, cx);
3186 });
3187 true
3188 } else {
3189 false
3190 }
3191 })
3192 }
3193
3194 pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3195 where
3196 E: Entity,
3197 H: Handle<E>,
3198 F: 'static + FnMut(&mut V, &E, &mut ViewContext<V>),
3199 {
3200 let window_id = self.window_id;
3201 let observer = self.weak_handle();
3202 self.window_context
3203 .observe_release(handle, move |released, cx| {
3204 cx.update_window(window_id, |cx| {
3205 if let Some(observer) = observer.upgrade(cx) {
3206 observer.update(cx, |observer, cx| {
3207 callback(observer, released, cx);
3208 });
3209 }
3210 });
3211 })
3212 }
3213
3214 pub fn observe_actions<F>(&mut self, mut callback: F) -> Subscription
3215 where
3216 F: 'static + FnMut(&mut V, TypeId, &mut ViewContext<V>),
3217 {
3218 let window_id = self.window_id;
3219 let observer = self.weak_handle();
3220 self.window_context.observe_actions(move |action_id, cx| {
3221 cx.update_window(window_id, |cx| {
3222 if let Some(observer) = observer.upgrade(cx) {
3223 observer.update(cx, |observer, cx| {
3224 callback(observer, action_id, cx);
3225 });
3226 }
3227 });
3228 })
3229 }
3230
3231 pub fn observe_window_activation<F>(&mut self, mut callback: F) -> Subscription
3232 where
3233 F: 'static + FnMut(&mut V, bool, &mut ViewContext<V>),
3234 {
3235 let observer = self.weak_handle();
3236 self.window_context
3237 .observe_window_activation(move |active, cx| {
3238 if let Some(observer) = observer.upgrade(cx) {
3239 observer.update(cx, |observer, cx| {
3240 callback(observer, active, cx);
3241 });
3242 true
3243 } else {
3244 false
3245 }
3246 })
3247 }
3248
3249 pub fn observe_fullscreen<F>(&mut self, mut callback: F) -> Subscription
3250 where
3251 F: 'static + FnMut(&mut V, bool, &mut ViewContext<V>),
3252 {
3253 let observer = self.weak_handle();
3254 self.window_context.observe_fullscreen(move |active, cx| {
3255 if let Some(observer) = observer.upgrade(cx) {
3256 observer.update(cx, |observer, cx| {
3257 callback(observer, active, cx);
3258 });
3259 true
3260 } else {
3261 false
3262 }
3263 })
3264 }
3265
3266 pub fn observe_keystrokes<F>(&mut self, mut callback: F) -> Subscription
3267 where
3268 F: 'static
3269 + FnMut(
3270 &mut V,
3271 &Keystroke,
3272 Option<&Box<dyn Action>>,
3273 &MatchResult,
3274 &mut ViewContext<V>,
3275 ) -> bool,
3276 {
3277 let observer = self.weak_handle();
3278 self.window_context
3279 .observe_keystrokes(move |keystroke, result, handled_by, cx| {
3280 if let Some(observer) = observer.upgrade(cx) {
3281 observer.update(cx, |observer, cx| {
3282 callback(observer, keystroke, handled_by, result, cx);
3283 });
3284 true
3285 } else {
3286 false
3287 }
3288 })
3289 }
3290
3291 pub fn observe_window_bounds<F>(&mut self, mut callback: F) -> Subscription
3292 where
3293 F: 'static + FnMut(&mut V, WindowBounds, Uuid, &mut ViewContext<V>),
3294 {
3295 let observer = self.weak_handle();
3296 self.window_context
3297 .observe_window_bounds(move |bounds, display, cx| {
3298 if let Some(observer) = observer.upgrade(cx) {
3299 observer.update(cx, |observer, cx| {
3300 callback(observer, bounds, display, cx);
3301 });
3302 true
3303 } else {
3304 false
3305 }
3306 })
3307 }
3308
3309 pub fn observe_active_labeled_tasks<F>(&mut self, mut callback: F) -> Subscription
3310 where
3311 F: 'static + FnMut(&mut V, &mut ViewContext<V>),
3312 {
3313 let window_id = self.window_id;
3314 let observer = self.weak_handle();
3315 self.window_context.observe_active_labeled_tasks(move |cx| {
3316 cx.update_window(window_id, |cx| {
3317 if let Some(observer) = observer.upgrade(cx) {
3318 observer.update(cx, |observer, cx| {
3319 callback(observer, cx);
3320 });
3321 true
3322 } else {
3323 false
3324 }
3325 })
3326 .unwrap_or(false)
3327 })
3328 }
3329
3330 pub fn emit(&mut self, payload: V::Event) {
3331 self.window_context
3332 .pending_effects
3333 .push_back(Effect::Event {
3334 entity_id: self.view_id,
3335 payload: Box::new(payload),
3336 });
3337 }
3338
3339 pub fn notify(&mut self) {
3340 let window_id = self.window_id;
3341 let view_id = self.view_id;
3342 self.window_context.notify_view(window_id, view_id);
3343 }
3344
3345 pub fn dispatch_action(&mut self, action: impl Action) {
3346 let window_id = self.window_id;
3347 let view_id = self.view_id;
3348 self.window_context
3349 .dispatch_action_at(window_id, view_id, action)
3350 }
3351
3352 pub fn dispatch_any_action(&mut self, action: Box<dyn Action>) {
3353 let window_id = self.window_id;
3354 let view_id = self.view_id;
3355 self.window_context
3356 .dispatch_any_action_at(window_id, view_id, action)
3357 }
3358
3359 pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
3360 let handle = self.handle();
3361 self.window_context
3362 .defer(move |cx| handle.update(cx, |view, cx| callback(view, cx)))
3363 }
3364
3365 pub fn after_window_update(
3366 &mut self,
3367 callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>),
3368 ) {
3369 let window_id = self.window_id;
3370 let handle = self.handle();
3371 self.window_context.after_window_update(move |cx| {
3372 cx.update_window(window_id, |cx| {
3373 handle.update(cx, |view, cx| {
3374 callback(view, cx);
3375 })
3376 });
3377 })
3378 }
3379
3380 pub fn propagate_action(&mut self) {
3381 self.window_context.halt_action_dispatch = false;
3382 }
3383
3384 pub fn spawn_labeled<F, Fut, S>(&mut self, task_label: &'static str, f: F) -> Task<S>
3385 where
3386 F: FnOnce(ViewHandle<V>, AsyncAppContext) -> Fut,
3387 Fut: 'static + Future<Output = S>,
3388 S: 'static,
3389 {
3390 let handle = self.handle();
3391 self.window_context
3392 .spawn_labeled(task_label, |cx| f(handle, cx))
3393 }
3394
3395 pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
3396 where
3397 F: FnOnce(ViewHandle<V>, AsyncAppContext) -> Fut,
3398 Fut: 'static + Future<Output = S>,
3399 S: 'static,
3400 {
3401 let handle = self.handle();
3402 self.window_context.spawn(|cx| f(handle, cx))
3403 }
3404
3405 pub fn spawn_weak<F, Fut, S>(&mut self, f: F) -> Task<S>
3406 where
3407 F: FnOnce(WeakViewHandle<V>, AsyncAppContext) -> Fut,
3408 Fut: 'static + Future<Output = S>,
3409 S: 'static,
3410 {
3411 let handle = self.weak_handle();
3412 self.window_context.spawn(|cx| f(handle, cx))
3413 }
3414
3415 pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
3416 let region_id = MouseRegionId::new::<Tag>(self.view_id, region_id);
3417 MouseState {
3418 hovered: self.window.hovered_region_ids.contains(®ion_id),
3419 clicked: self
3420 .window
3421 .clicked_region_ids
3422 .get(®ion_id)
3423 .and_then(|_| self.window.clicked_button),
3424 accessed_hovered: false,
3425 accessed_clicked: false,
3426 }
3427 }
3428
3429 pub fn element_state<Tag: 'static, T: 'static>(
3430 &mut self,
3431 element_id: usize,
3432 initial: T,
3433 ) -> ElementStateHandle<T> {
3434 let id = ElementStateId {
3435 view_id: self.view_id(),
3436 element_id,
3437 tag: TypeId::of::<Tag>(),
3438 };
3439 self.element_states
3440 .entry(id)
3441 .or_insert_with(|| Box::new(initial));
3442 ElementStateHandle::new(id, self.frame_count, &self.ref_counts)
3443 }
3444
3445 pub fn default_element_state<Tag: 'static, T: 'static + Default>(
3446 &mut self,
3447 element_id: usize,
3448 ) -> ElementStateHandle<T> {
3449 self.element_state::<Tag, T>(element_id, T::default())
3450 }
3451}
3452
3453impl<V> UpgradeModelHandle for ViewContext<'_, '_, '_, V> {
3454 fn upgrade_model_handle<T: Entity>(
3455 &self,
3456 handle: &WeakModelHandle<T>,
3457 ) -> Option<ModelHandle<T>> {
3458 self.window_context.upgrade_model_handle(handle)
3459 }
3460
3461 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3462 self.window_context.model_handle_is_upgradable(handle)
3463 }
3464
3465 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3466 self.window_context.upgrade_any_model_handle(handle)
3467 }
3468}
3469
3470impl<V> UpgradeViewHandle for ViewContext<'_, '_, '_, V> {
3471 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3472 self.window_context.upgrade_view_handle(handle)
3473 }
3474
3475 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3476 self.window_context.upgrade_any_view_handle(handle)
3477 }
3478}
3479
3480impl<V: View> ReadModel for ViewContext<'_, '_, '_, V> {
3481 fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3482 self.window_context.read_model(handle)
3483 }
3484}
3485
3486impl<V: View> UpdateModel for ViewContext<'_, '_, '_, V> {
3487 fn update_model<T: Entity, O>(
3488 &mut self,
3489 handle: &ModelHandle<T>,
3490 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3491 ) -> O {
3492 self.window_context.update_model(handle, update)
3493 }
3494}
3495
3496impl<V: View> ReadView for ViewContext<'_, '_, '_, V> {
3497 fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3498 self.window_context.read_view(handle)
3499 }
3500}
3501
3502impl<V: View> UpdateView for ViewContext<'_, '_, '_, V> {
3503 type Output<S> = S;
3504
3505 fn update_view<T, S>(
3506 &mut self,
3507 handle: &ViewHandle<T>,
3508 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3509 ) -> S
3510 where
3511 T: View,
3512 {
3513 self.window_context.update_view(handle, update)
3514 }
3515}
3516
3517pub struct EventContext<'a, 'b, 'c, 'd, V: View> {
3518 view_context: &'d mut ViewContext<'a, 'b, 'c, V>,
3519 pub(crate) handled: bool,
3520}
3521
3522impl<'a, 'b, 'c, 'd, V: View> EventContext<'a, 'b, 'c, 'd, V> {
3523 pub(crate) fn new(view_context: &'d mut ViewContext<'a, 'b, 'c, V>) -> Self {
3524 EventContext {
3525 view_context,
3526 handled: true,
3527 }
3528 }
3529
3530 pub fn propagate_event(&mut self) {
3531 self.handled = false;
3532 }
3533}
3534
3535impl<'a, 'b, 'c, 'd, V: View> Deref for EventContext<'a, 'b, 'c, 'd, V> {
3536 type Target = ViewContext<'a, 'b, 'c, V>;
3537
3538 fn deref(&self) -> &Self::Target {
3539 &self.view_context
3540 }
3541}
3542
3543impl<V: View> DerefMut for EventContext<'_, '_, '_, '_, V> {
3544 fn deref_mut(&mut self) -> &mut Self::Target {
3545 &mut self.view_context
3546 }
3547}
3548
3549impl<V: View> UpdateModel for EventContext<'_, '_, '_, '_, V> {
3550 fn update_model<T: Entity, O>(
3551 &mut self,
3552 handle: &ModelHandle<T>,
3553 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3554 ) -> O {
3555 self.view_context.update_model(handle, update)
3556 }
3557}
3558
3559impl<V: View> ReadView for EventContext<'_, '_, '_, '_, V> {
3560 fn read_view<W: View>(&self, handle: &crate::ViewHandle<W>) -> &W {
3561 self.view_context.read_view(handle)
3562 }
3563}
3564
3565impl<V: View> UpdateView for EventContext<'_, '_, '_, '_, V> {
3566 type Output<S> = S;
3567
3568 fn update_view<T, S>(
3569 &mut self,
3570 handle: &ViewHandle<T>,
3571 update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3572 ) -> S
3573 where
3574 T: View,
3575 {
3576 self.view_context.update_view(handle, update)
3577 }
3578}
3579
3580impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, '_, V> {
3581 fn upgrade_model_handle<T: Entity>(
3582 &self,
3583 handle: &WeakModelHandle<T>,
3584 ) -> Option<ModelHandle<T>> {
3585 self.view_context.upgrade_model_handle(handle)
3586 }
3587
3588 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3589 self.view_context.model_handle_is_upgradable(handle)
3590 }
3591
3592 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3593 self.view_context.upgrade_any_model_handle(handle)
3594 }
3595}
3596
3597impl<V: View> UpgradeViewHandle for EventContext<'_, '_, '_, '_, V> {
3598 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3599 self.view_context.upgrade_view_handle(handle)
3600 }
3601
3602 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3603 self.view_context.upgrade_any_view_handle(handle)
3604 }
3605}
3606
3607pub(crate) enum Reference<'a, T> {
3608 Immutable(&'a T),
3609 Mutable(&'a mut T),
3610}
3611
3612impl<'a, T> Deref for Reference<'a, T> {
3613 type Target = T;
3614
3615 fn deref(&self) -> &Self::Target {
3616 match self {
3617 Reference::Immutable(target) => target,
3618 Reference::Mutable(target) => target,
3619 }
3620 }
3621}
3622
3623impl<'a, T> DerefMut for Reference<'a, T> {
3624 fn deref_mut(&mut self) -> &mut Self::Target {
3625 match self {
3626 Reference::Immutable(_) => {
3627 panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
3628 }
3629 Reference::Mutable(target) => target,
3630 }
3631 }
3632}
3633
3634#[derive(Debug, Clone, Default)]
3635pub struct MouseState {
3636 pub(crate) hovered: bool,
3637 pub(crate) clicked: Option<MouseButton>,
3638 pub(crate) accessed_hovered: bool,
3639 pub(crate) accessed_clicked: bool,
3640}
3641
3642impl MouseState {
3643 pub fn hovered(&mut self) -> bool {
3644 self.accessed_hovered = true;
3645 self.hovered
3646 }
3647
3648 pub fn clicked(&mut self) -> Option<MouseButton> {
3649 self.accessed_clicked = true;
3650 self.clicked
3651 }
3652
3653 pub fn accessed_hovered(&self) -> bool {
3654 self.accessed_hovered
3655 }
3656
3657 pub fn accessed_clicked(&self) -> bool {
3658 self.accessed_clicked
3659 }
3660}
3661
3662pub trait Handle<T> {
3663 type Weak: 'static;
3664 fn id(&self) -> usize;
3665 fn location(&self) -> EntityLocation;
3666 fn downgrade(&self) -> Self::Weak;
3667 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3668 where
3669 Self: Sized;
3670}
3671
3672pub trait WeakHandle {
3673 fn id(&self) -> usize;
3674}
3675
3676#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3677pub enum EntityLocation {
3678 Model(usize),
3679 View(usize, usize),
3680}
3681
3682pub struct ModelHandle<T: Entity> {
3683 any_handle: AnyModelHandle,
3684 model_type: PhantomData<T>,
3685}
3686
3687impl<T: Entity> Deref for ModelHandle<T> {
3688 type Target = AnyModelHandle;
3689
3690 fn deref(&self) -> &Self::Target {
3691 &self.any_handle
3692 }
3693}
3694
3695impl<T: Entity> ModelHandle<T> {
3696 fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3697 Self {
3698 any_handle: AnyModelHandle::new(model_id, TypeId::of::<T>(), ref_counts.clone()),
3699 model_type: PhantomData,
3700 }
3701 }
3702
3703 pub fn downgrade(&self) -> WeakModelHandle<T> {
3704 WeakModelHandle::new(self.model_id)
3705 }
3706
3707 pub fn id(&self) -> usize {
3708 self.model_id
3709 }
3710
3711 pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
3712 cx.read_model(self)
3713 }
3714
3715 pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3716 where
3717 C: ReadModelWith,
3718 F: FnOnce(&T, &AppContext) -> S,
3719 {
3720 let mut read = Some(read);
3721 cx.read_model_with(self, &mut |model, cx| {
3722 let read = read.take().unwrap();
3723 read(model, cx)
3724 })
3725 }
3726
3727 pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3728 where
3729 C: UpdateModel,
3730 F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
3731 {
3732 let mut update = Some(update);
3733 cx.update_model(self, &mut |model, cx| {
3734 let update = update.take().unwrap();
3735 update(model, cx)
3736 })
3737 }
3738}
3739
3740impl<T: Entity> Clone for ModelHandle<T> {
3741 fn clone(&self) -> Self {
3742 Self::new(self.model_id, &self.ref_counts)
3743 }
3744}
3745
3746impl<T: Entity> PartialEq for ModelHandle<T> {
3747 fn eq(&self, other: &Self) -> bool {
3748 self.model_id == other.model_id
3749 }
3750}
3751
3752impl<T: Entity> Eq for ModelHandle<T> {}
3753
3754impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
3755 fn eq(&self, other: &WeakModelHandle<T>) -> bool {
3756 self.model_id == other.model_id
3757 }
3758}
3759
3760impl<T: Entity> Hash for ModelHandle<T> {
3761 fn hash<H: Hasher>(&self, state: &mut H) {
3762 self.model_id.hash(state);
3763 }
3764}
3765
3766impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
3767 fn borrow(&self) -> &usize {
3768 &self.model_id
3769 }
3770}
3771
3772impl<T: Entity> Debug for ModelHandle<T> {
3773 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3774 f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
3775 .field(&self.model_id)
3776 .finish()
3777 }
3778}
3779
3780unsafe impl<T: Entity> Send for ModelHandle<T> {}
3781unsafe impl<T: Entity> Sync for ModelHandle<T> {}
3782
3783impl<T: Entity> Handle<T> for ModelHandle<T> {
3784 type Weak = WeakModelHandle<T>;
3785
3786 fn id(&self) -> usize {
3787 self.model_id
3788 }
3789
3790 fn location(&self) -> EntityLocation {
3791 EntityLocation::Model(self.model_id)
3792 }
3793
3794 fn downgrade(&self) -> Self::Weak {
3795 self.downgrade()
3796 }
3797
3798 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3799 where
3800 Self: Sized,
3801 {
3802 weak.upgrade(cx)
3803 }
3804}
3805
3806pub struct WeakModelHandle<T> {
3807 any_handle: AnyWeakModelHandle,
3808 model_type: PhantomData<T>,
3809}
3810
3811impl<T> WeakModelHandle<T> {
3812 pub fn into_any(self) -> AnyWeakModelHandle {
3813 self.any_handle
3814 }
3815}
3816
3817impl<T> Deref for WeakModelHandle<T> {
3818 type Target = AnyWeakModelHandle;
3819
3820 fn deref(&self) -> &Self::Target {
3821 &self.any_handle
3822 }
3823}
3824
3825impl<T> WeakHandle for WeakModelHandle<T> {
3826 fn id(&self) -> usize {
3827 self.model_id
3828 }
3829}
3830
3831unsafe impl<T> Send for WeakModelHandle<T> {}
3832unsafe impl<T> Sync for WeakModelHandle<T> {}
3833
3834impl<T: Entity> WeakModelHandle<T> {
3835 fn new(model_id: usize) -> Self {
3836 Self {
3837 any_handle: AnyWeakModelHandle {
3838 model_id,
3839 model_type: TypeId::of::<T>(),
3840 },
3841 model_type: PhantomData,
3842 }
3843 }
3844
3845 pub fn id(&self) -> usize {
3846 self.model_id
3847 }
3848
3849 pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
3850 cx.model_handle_is_upgradable(self)
3851 }
3852
3853 pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
3854 cx.upgrade_model_handle(self)
3855 }
3856}
3857
3858impl<T> Hash for WeakModelHandle<T> {
3859 fn hash<H: Hasher>(&self, state: &mut H) {
3860 self.model_id.hash(state)
3861 }
3862}
3863
3864impl<T> PartialEq for WeakModelHandle<T> {
3865 fn eq(&self, other: &Self) -> bool {
3866 self.model_id == other.model_id
3867 }
3868}
3869
3870impl<T> Eq for WeakModelHandle<T> {}
3871
3872impl<T: Entity> PartialEq<ModelHandle<T>> for WeakModelHandle<T> {
3873 fn eq(&self, other: &ModelHandle<T>) -> bool {
3874 self.model_id == other.model_id
3875 }
3876}
3877
3878impl<T> Clone for WeakModelHandle<T> {
3879 fn clone(&self) -> Self {
3880 Self {
3881 any_handle: self.any_handle.clone(),
3882 model_type: PhantomData,
3883 }
3884 }
3885}
3886
3887impl<T> Copy for WeakModelHandle<T> {}
3888
3889#[repr(transparent)]
3890pub struct ViewHandle<T> {
3891 any_handle: AnyViewHandle,
3892 view_type: PhantomData<T>,
3893}
3894
3895impl<T> Deref for ViewHandle<T> {
3896 type Target = AnyViewHandle;
3897
3898 fn deref(&self) -> &Self::Target {
3899 &self.any_handle
3900 }
3901}
3902
3903impl<T: View> ViewHandle<T> {
3904 fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3905 Self {
3906 any_handle: AnyViewHandle::new(
3907 window_id,
3908 view_id,
3909 TypeId::of::<T>(),
3910 ref_counts.clone(),
3911 ),
3912 view_type: PhantomData,
3913 }
3914 }
3915
3916 pub fn downgrade(&self) -> WeakViewHandle<T> {
3917 WeakViewHandle::new(self.window_id, self.view_id)
3918 }
3919
3920 pub fn into_any(self) -> AnyViewHandle {
3921 self.any_handle
3922 }
3923
3924 pub fn window_id(&self) -> usize {
3925 self.window_id
3926 }
3927
3928 pub fn id(&self) -> usize {
3929 self.view_id
3930 }
3931
3932 pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
3933 cx.read_view(self)
3934 }
3935
3936 pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3937 where
3938 C: ReadViewWith,
3939 F: FnOnce(&T, &AppContext) -> S,
3940 {
3941 let mut read = Some(read);
3942 cx.read_view_with(self, &mut |view, cx| {
3943 let read = read.take().unwrap();
3944 read(view, cx)
3945 })
3946 }
3947
3948 pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> C::Output<S>
3949 where
3950 C: UpdateView,
3951 F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
3952 {
3953 let mut update = Some(update);
3954 cx.update_view(self, &mut |view, cx| {
3955 let update = update.take().unwrap();
3956 update(view, cx)
3957 })
3958 }
3959
3960 pub fn is_focused(&self, cx: &WindowContext) -> bool {
3961 cx.focused_view_id() == Some(self.view_id)
3962 }
3963}
3964
3965impl<T: View> Clone for ViewHandle<T> {
3966 fn clone(&self) -> Self {
3967 ViewHandle::new(self.window_id, self.view_id, &self.ref_counts)
3968 }
3969}
3970
3971impl<T> PartialEq for ViewHandle<T> {
3972 fn eq(&self, other: &Self) -> bool {
3973 self.window_id == other.window_id && self.view_id == other.view_id
3974 }
3975}
3976
3977impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
3978 fn eq(&self, other: &WeakViewHandle<T>) -> bool {
3979 self.window_id == other.window_id && self.view_id == other.view_id
3980 }
3981}
3982
3983impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
3984 fn eq(&self, other: &ViewHandle<T>) -> bool {
3985 self.window_id == other.window_id && self.view_id == other.view_id
3986 }
3987}
3988
3989impl<T> Eq for ViewHandle<T> {}
3990
3991impl<T> Hash for ViewHandle<T> {
3992 fn hash<H: Hasher>(&self, state: &mut H) {
3993 self.window_id.hash(state);
3994 self.view_id.hash(state);
3995 }
3996}
3997
3998impl<T> Debug for ViewHandle<T> {
3999 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4000 f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
4001 .field("window_id", &self.window_id)
4002 .field("view_id", &self.view_id)
4003 .finish()
4004 }
4005}
4006
4007impl<T: View> Handle<T> for ViewHandle<T> {
4008 type Weak = WeakViewHandle<T>;
4009
4010 fn id(&self) -> usize {
4011 self.view_id
4012 }
4013
4014 fn location(&self) -> EntityLocation {
4015 EntityLocation::View(self.window_id, self.view_id)
4016 }
4017
4018 fn downgrade(&self) -> Self::Weak {
4019 self.downgrade()
4020 }
4021
4022 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4023 where
4024 Self: Sized,
4025 {
4026 weak.upgrade(cx)
4027 }
4028}
4029
4030pub struct AnyViewHandle {
4031 window_id: usize,
4032 view_id: usize,
4033 view_type: TypeId,
4034 ref_counts: Arc<Mutex<RefCounts>>,
4035
4036 #[cfg(any(test, feature = "test-support"))]
4037 handle_id: usize,
4038}
4039
4040impl AnyViewHandle {
4041 fn new(
4042 window_id: usize,
4043 view_id: usize,
4044 view_type: TypeId,
4045 ref_counts: Arc<Mutex<RefCounts>>,
4046 ) -> Self {
4047 ref_counts.lock().inc_view(window_id, view_id);
4048
4049 #[cfg(any(test, feature = "test-support"))]
4050 let handle_id = ref_counts
4051 .lock()
4052 .leak_detector
4053 .lock()
4054 .handle_created(None, view_id);
4055
4056 Self {
4057 window_id,
4058 view_id,
4059 view_type,
4060 ref_counts,
4061 #[cfg(any(test, feature = "test-support"))]
4062 handle_id,
4063 }
4064 }
4065
4066 pub fn window_id(&self) -> usize {
4067 self.window_id
4068 }
4069
4070 pub fn id(&self) -> usize {
4071 self.view_id
4072 }
4073
4074 pub fn is<T: 'static>(&self) -> bool {
4075 TypeId::of::<T>() == self.view_type
4076 }
4077
4078 pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4079 if self.is::<T>() {
4080 Some(ViewHandle {
4081 any_handle: self,
4082 view_type: PhantomData,
4083 })
4084 } else {
4085 None
4086 }
4087 }
4088
4089 pub fn downcast_ref<T: View>(&self) -> Option<&ViewHandle<T>> {
4090 if self.is::<T>() {
4091 Some(unsafe { mem::transmute(self) })
4092 } else {
4093 None
4094 }
4095 }
4096
4097 pub fn downgrade(&self) -> AnyWeakViewHandle {
4098 AnyWeakViewHandle {
4099 window_id: self.window_id,
4100 view_id: self.view_id,
4101 view_type: self.view_type,
4102 }
4103 }
4104
4105 pub fn view_type(&self) -> TypeId {
4106 self.view_type
4107 }
4108
4109 pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a, 'b>) -> serde_json::Value {
4110 cx.views
4111 .get(&(self.window_id, self.view_id))
4112 .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4113 }
4114}
4115
4116impl Clone for AnyViewHandle {
4117 fn clone(&self) -> Self {
4118 Self::new(
4119 self.window_id,
4120 self.view_id,
4121 self.view_type,
4122 self.ref_counts.clone(),
4123 )
4124 }
4125}
4126
4127impl<T> PartialEq<ViewHandle<T>> for AnyViewHandle {
4128 fn eq(&self, other: &ViewHandle<T>) -> bool {
4129 self.window_id == other.window_id && self.view_id == other.view_id
4130 }
4131}
4132
4133impl Drop for AnyViewHandle {
4134 fn drop(&mut self) {
4135 self.ref_counts
4136 .lock()
4137 .dec_view(self.window_id, self.view_id);
4138 #[cfg(any(test, feature = "test-support"))]
4139 self.ref_counts
4140 .lock()
4141 .leak_detector
4142 .lock()
4143 .handle_dropped(self.view_id, self.handle_id);
4144 }
4145}
4146
4147pub struct AnyModelHandle {
4148 model_id: usize,
4149 model_type: TypeId,
4150 ref_counts: Arc<Mutex<RefCounts>>,
4151
4152 #[cfg(any(test, feature = "test-support"))]
4153 handle_id: usize,
4154}
4155
4156impl AnyModelHandle {
4157 fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4158 ref_counts.lock().inc_model(model_id);
4159
4160 #[cfg(any(test, feature = "test-support"))]
4161 let handle_id = ref_counts
4162 .lock()
4163 .leak_detector
4164 .lock()
4165 .handle_created(None, model_id);
4166
4167 Self {
4168 model_id,
4169 model_type,
4170 ref_counts,
4171
4172 #[cfg(any(test, feature = "test-support"))]
4173 handle_id,
4174 }
4175 }
4176
4177 pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4178 if self.is::<T>() {
4179 Some(ModelHandle {
4180 any_handle: self,
4181 model_type: PhantomData,
4182 })
4183 } else {
4184 None
4185 }
4186 }
4187
4188 pub fn downgrade(&self) -> AnyWeakModelHandle {
4189 AnyWeakModelHandle {
4190 model_id: self.model_id,
4191 model_type: self.model_type,
4192 }
4193 }
4194
4195 pub fn is<T: Entity>(&self) -> bool {
4196 self.model_type == TypeId::of::<T>()
4197 }
4198
4199 pub fn model_type(&self) -> TypeId {
4200 self.model_type
4201 }
4202}
4203
4204impl Clone for AnyModelHandle {
4205 fn clone(&self) -> Self {
4206 Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4207 }
4208}
4209
4210impl Drop for AnyModelHandle {
4211 fn drop(&mut self) {
4212 let mut ref_counts = self.ref_counts.lock();
4213 ref_counts.dec_model(self.model_id);
4214
4215 #[cfg(any(test, feature = "test-support"))]
4216 ref_counts
4217 .leak_detector
4218 .lock()
4219 .handle_dropped(self.model_id, self.handle_id);
4220 }
4221}
4222
4223#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
4224pub struct AnyWeakModelHandle {
4225 model_id: usize,
4226 model_type: TypeId,
4227}
4228
4229impl AnyWeakModelHandle {
4230 pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
4231 cx.upgrade_any_model_handle(self)
4232 }
4233 pub fn model_type(&self) -> TypeId {
4234 self.model_type
4235 }
4236
4237 fn is<T: 'static>(&self) -> bool {
4238 TypeId::of::<T>() == self.model_type
4239 }
4240
4241 pub fn downcast<T: Entity>(self) -> Option<WeakModelHandle<T>> {
4242 if self.is::<T>() {
4243 let result = Some(WeakModelHandle {
4244 any_handle: self,
4245 model_type: PhantomData,
4246 });
4247
4248 result
4249 } else {
4250 None
4251 }
4252 }
4253}
4254
4255#[derive(Debug, Copy)]
4256pub struct WeakViewHandle<T> {
4257 any_handle: AnyWeakViewHandle,
4258 view_type: PhantomData<T>,
4259}
4260
4261impl<T> WeakHandle for WeakViewHandle<T> {
4262 fn id(&self) -> usize {
4263 self.view_id
4264 }
4265}
4266
4267impl<T: View> WeakViewHandle<T> {
4268 fn new(window_id: usize, view_id: usize) -> Self {
4269 Self {
4270 any_handle: AnyWeakViewHandle {
4271 window_id,
4272 view_id,
4273 view_type: TypeId::of::<T>(),
4274 },
4275 view_type: PhantomData,
4276 }
4277 }
4278
4279 pub fn id(&self) -> usize {
4280 self.view_id
4281 }
4282
4283 pub fn window_id(&self) -> usize {
4284 self.window_id
4285 }
4286
4287 pub fn into_any(self) -> AnyWeakViewHandle {
4288 self.any_handle
4289 }
4290
4291 pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
4292 cx.upgrade_view_handle(self)
4293 }
4294}
4295
4296impl<T> Deref for WeakViewHandle<T> {
4297 type Target = AnyWeakViewHandle;
4298
4299 fn deref(&self) -> &Self::Target {
4300 &self.any_handle
4301 }
4302}
4303
4304impl<T> Clone for WeakViewHandle<T> {
4305 fn clone(&self) -> Self {
4306 Self {
4307 any_handle: self.any_handle.clone(),
4308 view_type: PhantomData,
4309 }
4310 }
4311}
4312
4313impl<T> PartialEq for WeakViewHandle<T> {
4314 fn eq(&self, other: &Self) -> bool {
4315 self.window_id == other.window_id && self.view_id == other.view_id
4316 }
4317}
4318
4319impl<T> Eq for WeakViewHandle<T> {}
4320
4321impl<T> Hash for WeakViewHandle<T> {
4322 fn hash<H: Hasher>(&self, state: &mut H) {
4323 self.any_handle.hash(state);
4324 }
4325}
4326
4327#[derive(Debug, Clone, Copy)]
4328pub struct AnyWeakViewHandle {
4329 window_id: usize,
4330 view_id: usize,
4331 view_type: TypeId,
4332}
4333
4334impl AnyWeakViewHandle {
4335 pub fn id(&self) -> usize {
4336 self.view_id
4337 }
4338
4339 pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
4340 cx.upgrade_any_view_handle(self)
4341 }
4342}
4343
4344impl Hash for AnyWeakViewHandle {
4345 fn hash<H: Hasher>(&self, state: &mut H) {
4346 self.window_id.hash(state);
4347 self.view_id.hash(state);
4348 self.view_type.hash(state);
4349 }
4350}
4351
4352#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4353pub struct ElementStateId {
4354 view_id: usize,
4355 element_id: usize,
4356 tag: TypeId,
4357}
4358
4359pub struct ElementStateHandle<T> {
4360 value_type: PhantomData<T>,
4361 id: ElementStateId,
4362 ref_counts: Weak<Mutex<RefCounts>>,
4363}
4364
4365impl<T: 'static> ElementStateHandle<T> {
4366 fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4367 ref_counts.lock().inc_element_state(id, frame_id);
4368 Self {
4369 value_type: PhantomData,
4370 id,
4371 ref_counts: Arc::downgrade(ref_counts),
4372 }
4373 }
4374
4375 pub fn id(&self) -> ElementStateId {
4376 self.id
4377 }
4378
4379 pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4380 cx.element_states
4381 .get(&self.id)
4382 .unwrap()
4383 .downcast_ref()
4384 .unwrap()
4385 }
4386
4387 pub fn update<C, D, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4388 where
4389 C: DerefMut<Target = D>,
4390 D: DerefMut<Target = AppContext>,
4391 {
4392 let mut element_state = cx.deref_mut().element_states.remove(&self.id).unwrap();
4393 let result = f(element_state.downcast_mut().unwrap(), cx);
4394 cx.deref_mut().element_states.insert(self.id, element_state);
4395 result
4396 }
4397}
4398
4399impl<T> Drop for ElementStateHandle<T> {
4400 fn drop(&mut self) {
4401 if let Some(ref_counts) = self.ref_counts.upgrade() {
4402 ref_counts.lock().dec_element_state(self.id);
4403 }
4404 }
4405}
4406
4407#[must_use]
4408pub enum Subscription {
4409 Subscription(callback_collection::Subscription<usize, SubscriptionCallback>),
4410 Observation(callback_collection::Subscription<usize, ObservationCallback>),
4411 GlobalSubscription(callback_collection::Subscription<TypeId, GlobalSubscriptionCallback>),
4412 GlobalObservation(callback_collection::Subscription<TypeId, GlobalObservationCallback>),
4413 FocusObservation(callback_collection::Subscription<usize, FocusObservationCallback>),
4414 WindowActivationObservation(callback_collection::Subscription<usize, WindowActivationCallback>),
4415 WindowFullscreenObservation(callback_collection::Subscription<usize, WindowFullscreenCallback>),
4416 WindowBoundsObservation(callback_collection::Subscription<usize, WindowBoundsCallback>),
4417 KeystrokeObservation(callback_collection::Subscription<usize, KeystrokeCallback>),
4418 ReleaseObservation(callback_collection::Subscription<usize, ReleaseObservationCallback>),
4419 ActionObservation(callback_collection::Subscription<(), ActionObservationCallback>),
4420 ActiveLabeledTasksObservation(
4421 callback_collection::Subscription<(), ActiveLabeledTasksCallback>,
4422 ),
4423}
4424
4425impl Subscription {
4426 pub fn id(&self) -> usize {
4427 match self {
4428 Subscription::Subscription(subscription) => subscription.id(),
4429 Subscription::Observation(subscription) => subscription.id(),
4430 Subscription::GlobalSubscription(subscription) => subscription.id(),
4431 Subscription::GlobalObservation(subscription) => subscription.id(),
4432 Subscription::FocusObservation(subscription) => subscription.id(),
4433 Subscription::WindowActivationObservation(subscription) => subscription.id(),
4434 Subscription::WindowFullscreenObservation(subscription) => subscription.id(),
4435 Subscription::WindowBoundsObservation(subscription) => subscription.id(),
4436 Subscription::KeystrokeObservation(subscription) => subscription.id(),
4437 Subscription::ReleaseObservation(subscription) => subscription.id(),
4438 Subscription::ActionObservation(subscription) => subscription.id(),
4439 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.id(),
4440 }
4441 }
4442
4443 pub fn detach(&mut self) {
4444 match self {
4445 Subscription::Subscription(subscription) => subscription.detach(),
4446 Subscription::GlobalSubscription(subscription) => subscription.detach(),
4447 Subscription::Observation(subscription) => subscription.detach(),
4448 Subscription::GlobalObservation(subscription) => subscription.detach(),
4449 Subscription::FocusObservation(subscription) => subscription.detach(),
4450 Subscription::KeystrokeObservation(subscription) => subscription.detach(),
4451 Subscription::WindowActivationObservation(subscription) => subscription.detach(),
4452 Subscription::WindowFullscreenObservation(subscription) => subscription.detach(),
4453 Subscription::WindowBoundsObservation(subscription) => subscription.detach(),
4454 Subscription::ReleaseObservation(subscription) => subscription.detach(),
4455 Subscription::ActionObservation(subscription) => subscription.detach(),
4456 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.detach(),
4457 }
4458 }
4459}
4460
4461#[cfg(test)]
4462mod tests {
4463 use super::*;
4464 use crate::{
4465 actions,
4466 elements::*,
4467 impl_actions,
4468 platform::{MouseButton, MouseButtonEvent},
4469 window::ChildView,
4470 };
4471 use itertools::Itertools;
4472 use postage::{sink::Sink, stream::Stream};
4473 use serde::Deserialize;
4474 use smol::future::poll_once;
4475 use std::{
4476 cell::Cell,
4477 sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
4478 };
4479
4480 #[crate::test(self)]
4481 fn test_model_handles(cx: &mut AppContext) {
4482 struct Model {
4483 other: Option<ModelHandle<Model>>,
4484 events: Vec<String>,
4485 }
4486
4487 impl Entity for Model {
4488 type Event = usize;
4489 }
4490
4491 impl Model {
4492 fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
4493 if let Some(other) = other.as_ref() {
4494 cx.observe(other, |me, _, _| {
4495 me.events.push("notified".into());
4496 })
4497 .detach();
4498 cx.subscribe(other, |me, _, event, _| {
4499 me.events.push(format!("observed event {}", event));
4500 })
4501 .detach();
4502 }
4503
4504 Self {
4505 other,
4506 events: Vec::new(),
4507 }
4508 }
4509 }
4510
4511 let handle_1 = cx.add_model(|cx| Model::new(None, cx));
4512 let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
4513 assert_eq!(cx.models.len(), 2);
4514
4515 handle_1.update(cx, |model, cx| {
4516 model.events.push("updated".into());
4517 cx.emit(1);
4518 cx.notify();
4519 cx.emit(2);
4520 });
4521 assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
4522 assert_eq!(
4523 handle_2.read(cx).events,
4524 vec![
4525 "observed event 1".to_string(),
4526 "notified".to_string(),
4527 "observed event 2".to_string(),
4528 ]
4529 );
4530
4531 handle_2.update(cx, |model, _| {
4532 drop(handle_1);
4533 model.other.take();
4534 });
4535
4536 assert_eq!(cx.models.len(), 1);
4537 assert!(cx.subscriptions.is_empty());
4538 assert!(cx.observations.is_empty());
4539 }
4540
4541 #[crate::test(self)]
4542 fn test_model_events(cx: &mut AppContext) {
4543 #[derive(Default)]
4544 struct Model {
4545 events: Vec<usize>,
4546 }
4547
4548 impl Entity for Model {
4549 type Event = usize;
4550 }
4551
4552 let handle_1 = cx.add_model(|_| Model::default());
4553 let handle_2 = cx.add_model(|_| Model::default());
4554
4555 handle_1.update(cx, |_, cx| {
4556 cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
4557 model.events.push(*event);
4558
4559 cx.subscribe(&emitter, |model, _, event, _| {
4560 model.events.push(*event * 2);
4561 })
4562 .detach();
4563 })
4564 .detach();
4565 });
4566
4567 handle_2.update(cx, |_, c| c.emit(7));
4568 assert_eq!(handle_1.read(cx).events, vec![7]);
4569
4570 handle_2.update(cx, |_, c| c.emit(5));
4571 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
4572 }
4573
4574 #[crate::test(self)]
4575 fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
4576 #[derive(Default)]
4577 struct Model;
4578
4579 impl Entity for Model {
4580 type Event = ();
4581 }
4582
4583 let events = Rc::new(RefCell::new(Vec::new()));
4584 cx.add_model(|cx| {
4585 drop(cx.subscribe(&cx.handle(), {
4586 let events = events.clone();
4587 move |_, _, _, _| events.borrow_mut().push("dropped before flush")
4588 }));
4589 cx.subscribe(&cx.handle(), {
4590 let events = events.clone();
4591 move |_, _, _, _| events.borrow_mut().push("before emit")
4592 })
4593 .detach();
4594 cx.emit(());
4595 cx.subscribe(&cx.handle(), {
4596 let events = events.clone();
4597 move |_, _, _, _| events.borrow_mut().push("after emit")
4598 })
4599 .detach();
4600 Model
4601 });
4602 assert_eq!(*events.borrow(), ["before emit"]);
4603 }
4604
4605 #[crate::test(self)]
4606 fn test_observe_and_notify_from_model(cx: &mut AppContext) {
4607 #[derive(Default)]
4608 struct Model {
4609 count: usize,
4610 events: Vec<usize>,
4611 }
4612
4613 impl Entity for Model {
4614 type Event = ();
4615 }
4616
4617 let handle_1 = cx.add_model(|_| Model::default());
4618 let handle_2 = cx.add_model(|_| Model::default());
4619
4620 handle_1.update(cx, |_, c| {
4621 c.observe(&handle_2, move |model, observed, c| {
4622 model.events.push(observed.read(c).count);
4623 c.observe(&observed, |model, observed, c| {
4624 model.events.push(observed.read(c).count * 2);
4625 })
4626 .detach();
4627 })
4628 .detach();
4629 });
4630
4631 handle_2.update(cx, |model, c| {
4632 model.count = 7;
4633 c.notify()
4634 });
4635 assert_eq!(handle_1.read(cx).events, vec![7]);
4636
4637 handle_2.update(cx, |model, c| {
4638 model.count = 5;
4639 c.notify()
4640 });
4641 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
4642 }
4643
4644 #[crate::test(self)]
4645 fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
4646 #[derive(Default)]
4647 struct Model;
4648
4649 impl Entity for Model {
4650 type Event = ();
4651 }
4652
4653 let events = Rc::new(RefCell::new(Vec::new()));
4654 cx.add_model(|cx| {
4655 drop(cx.observe(&cx.handle(), {
4656 let events = events.clone();
4657 move |_, _, _| events.borrow_mut().push("dropped before flush")
4658 }));
4659 cx.observe(&cx.handle(), {
4660 let events = events.clone();
4661 move |_, _, _| events.borrow_mut().push("before notify")
4662 })
4663 .detach();
4664 cx.notify();
4665 cx.observe(&cx.handle(), {
4666 let events = events.clone();
4667 move |_, _, _| events.borrow_mut().push("after notify")
4668 })
4669 .detach();
4670 Model
4671 });
4672 assert_eq!(*events.borrow(), ["before notify"]);
4673 }
4674
4675 #[crate::test(self)]
4676 fn test_defer_and_after_window_update(cx: &mut TestAppContext) {
4677 struct View {
4678 render_count: usize,
4679 }
4680
4681 impl Entity for View {
4682 type Event = usize;
4683 }
4684
4685 impl super::View for View {
4686 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
4687 post_inc(&mut self.render_count);
4688 Empty::new().boxed()
4689 }
4690
4691 fn ui_name() -> &'static str {
4692 "View"
4693 }
4694 }
4695
4696 let (_, view) = cx.add_window(|_| View { render_count: 0 });
4697 let called_defer = Rc::new(AtomicBool::new(false));
4698 let called_after_window_update = Rc::new(AtomicBool::new(false));
4699
4700 view.update(cx, |this, cx| {
4701 assert_eq!(this.render_count, 1);
4702 cx.defer({
4703 let called_defer = called_defer.clone();
4704 move |this, _| {
4705 assert_eq!(this.render_count, 1);
4706 called_defer.store(true, SeqCst);
4707 }
4708 });
4709 cx.after_window_update({
4710 let called_after_window_update = called_after_window_update.clone();
4711 move |this, cx| {
4712 assert_eq!(this.render_count, 2);
4713 called_after_window_update.store(true, SeqCst);
4714 cx.notify();
4715 }
4716 });
4717 assert!(!called_defer.load(SeqCst));
4718 assert!(!called_after_window_update.load(SeqCst));
4719 cx.notify();
4720 });
4721
4722 assert!(called_defer.load(SeqCst));
4723 assert!(called_after_window_update.load(SeqCst));
4724 assert_eq!(view.read_with(cx, |view, _| view.render_count), 3);
4725 }
4726
4727 #[crate::test(self)]
4728 fn test_view_handles(cx: &mut TestAppContext) {
4729 struct View {
4730 other: Option<ViewHandle<View>>,
4731 events: Vec<String>,
4732 }
4733
4734 impl Entity for View {
4735 type Event = usize;
4736 }
4737
4738 impl super::View for View {
4739 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
4740 Empty::new().boxed()
4741 }
4742
4743 fn ui_name() -> &'static str {
4744 "View"
4745 }
4746 }
4747
4748 impl View {
4749 fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
4750 if let Some(other) = other.as_ref() {
4751 cx.subscribe(other, |me, _, event, _| {
4752 me.events.push(format!("observed event {}", event));
4753 })
4754 .detach();
4755 }
4756 Self {
4757 other,
4758 events: Vec::new(),
4759 }
4760 }
4761 }
4762
4763 let (_, root_view) = cx.add_window(|cx| View::new(None, cx));
4764 let handle_1 = cx.add_view(&root_view, |cx| View::new(None, cx));
4765 let handle_2 = cx.add_view(&root_view, |cx| View::new(Some(handle_1.clone()), cx));
4766 assert_eq!(cx.read(|cx| cx.views.len()), 3);
4767
4768 handle_1.update(cx, |view, cx| {
4769 view.events.push("updated".into());
4770 cx.emit(1);
4771 cx.emit(2);
4772 });
4773 handle_1.read_with(cx, |view, _| {
4774 assert_eq!(view.events, vec!["updated".to_string()]);
4775 });
4776 handle_2.read_with(cx, |view, _| {
4777 assert_eq!(
4778 view.events,
4779 vec![
4780 "observed event 1".to_string(),
4781 "observed event 2".to_string(),
4782 ]
4783 );
4784 });
4785
4786 handle_2.update(cx, |view, _| {
4787 drop(handle_1);
4788 view.other.take();
4789 });
4790
4791 cx.read(|cx| {
4792 assert_eq!(cx.views.len(), 2);
4793 assert!(cx.subscriptions.is_empty());
4794 assert!(cx.observations.is_empty());
4795 });
4796 }
4797
4798 #[crate::test(self)]
4799 fn test_add_window(cx: &mut AppContext) {
4800 struct View {
4801 mouse_down_count: Arc<AtomicUsize>,
4802 }
4803
4804 impl Entity for View {
4805 type Event = ();
4806 }
4807
4808 impl super::View for View {
4809 fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
4810 enum Handler {}
4811 let mouse_down_count = self.mouse_down_count.clone();
4812 MouseEventHandler::<Handler, _>::new(0, cx, |_, _| Empty::new().boxed())
4813 .on_down(MouseButton::Left, move |_, _, _| {
4814 mouse_down_count.fetch_add(1, SeqCst);
4815 })
4816 .boxed()
4817 }
4818
4819 fn ui_name() -> &'static str {
4820 "View"
4821 }
4822 }
4823
4824 let mouse_down_count = Arc::new(AtomicUsize::new(0));
4825 let (window_id, _) = cx.add_window(Default::default(), |_| View {
4826 mouse_down_count: mouse_down_count.clone(),
4827 });
4828
4829 cx.update_window(window_id, |cx| {
4830 // Ensure window's root element is in a valid lifecycle state.
4831 cx.dispatch_event(
4832 Event::MouseDown(MouseButtonEvent {
4833 position: Default::default(),
4834 button: MouseButton::Left,
4835 modifiers: Default::default(),
4836 click_count: 1,
4837 }),
4838 false,
4839 );
4840 assert_eq!(mouse_down_count.load(SeqCst), 1);
4841 });
4842 }
4843
4844 #[crate::test(self)]
4845 fn test_entity_release_hooks(cx: &mut AppContext) {
4846 struct Model {
4847 released: Rc<Cell<bool>>,
4848 }
4849
4850 struct View {
4851 released: Rc<Cell<bool>>,
4852 }
4853
4854 impl Entity for Model {
4855 type Event = ();
4856
4857 fn release(&mut self, _: &mut AppContext) {
4858 self.released.set(true);
4859 }
4860 }
4861
4862 impl Entity for View {
4863 type Event = ();
4864
4865 fn release(&mut self, _: &mut AppContext) {
4866 self.released.set(true);
4867 }
4868 }
4869
4870 impl super::View for View {
4871 fn ui_name() -> &'static str {
4872 "View"
4873 }
4874
4875 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
4876 Empty::new().boxed()
4877 }
4878 }
4879
4880 let model_released = Rc::new(Cell::new(false));
4881 let model_release_observed = Rc::new(Cell::new(false));
4882 let view_released = Rc::new(Cell::new(false));
4883 let view_release_observed = Rc::new(Cell::new(false));
4884
4885 let model = cx.add_model(|_| Model {
4886 released: model_released.clone(),
4887 });
4888 let (window_id, view) = cx.add_window(Default::default(), |_| View {
4889 released: view_released.clone(),
4890 });
4891 assert!(!model_released.get());
4892 assert!(!view_released.get());
4893
4894 cx.observe_release(&model, {
4895 let model_release_observed = model_release_observed.clone();
4896 move |_, _| model_release_observed.set(true)
4897 })
4898 .detach();
4899 cx.observe_release(&view, {
4900 let view_release_observed = view_release_observed.clone();
4901 move |_, _| view_release_observed.set(true)
4902 })
4903 .detach();
4904
4905 cx.update(move |_| {
4906 drop(model);
4907 });
4908 assert!(model_released.get());
4909 assert!(model_release_observed.get());
4910
4911 drop(view);
4912 cx.remove_window(window_id);
4913 assert!(view_released.get());
4914 assert!(view_release_observed.get());
4915 }
4916
4917 #[crate::test(self)]
4918 fn test_view_events(cx: &mut TestAppContext) {
4919 struct Model;
4920
4921 impl Entity for Model {
4922 type Event = String;
4923 }
4924
4925 let (_, handle_1) = cx.add_window(|_| TestView::default());
4926 let handle_2 = cx.add_view(&handle_1, |_| TestView::default());
4927 let handle_3 = cx.add_model(|_| Model);
4928
4929 handle_1.update(cx, |_, cx| {
4930 cx.subscribe(&handle_2, move |me, emitter, event, cx| {
4931 me.events.push(event.clone());
4932
4933 cx.subscribe(&emitter, |me, _, event, _| {
4934 me.events.push(format!("{event} from inner"));
4935 })
4936 .detach();
4937 })
4938 .detach();
4939
4940 cx.subscribe(&handle_3, |me, _, event, _| {
4941 me.events.push(event.clone());
4942 })
4943 .detach();
4944 });
4945
4946 handle_2.update(cx, |_, c| c.emit("7".into()));
4947 handle_1.read_with(cx, |view, _| assert_eq!(view.events, ["7"]));
4948
4949 handle_2.update(cx, |_, c| c.emit("5".into()));
4950 handle_1.read_with(cx, |view, _| {
4951 assert_eq!(view.events, ["7", "5", "5 from inner"])
4952 });
4953
4954 handle_3.update(cx, |_, c| c.emit("9".into()));
4955 handle_1.read_with(cx, |view, _| {
4956 assert_eq!(view.events, ["7", "5", "5 from inner", "9"])
4957 });
4958 }
4959
4960 #[crate::test(self)]
4961 fn test_global_events(cx: &mut AppContext) {
4962 #[derive(Clone, Debug, Eq, PartialEq)]
4963 struct GlobalEvent(u64);
4964
4965 let events = Rc::new(RefCell::new(Vec::new()));
4966 let first_subscription;
4967 let second_subscription;
4968
4969 {
4970 let events = events.clone();
4971 first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
4972 events.borrow_mut().push(("First", e.clone()));
4973 });
4974 }
4975
4976 {
4977 let events = events.clone();
4978 second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
4979 events.borrow_mut().push(("Second", e.clone()));
4980 });
4981 }
4982
4983 cx.update(|cx| {
4984 cx.emit_global(GlobalEvent(1));
4985 cx.emit_global(GlobalEvent(2));
4986 });
4987
4988 drop(first_subscription);
4989
4990 cx.update(|cx| {
4991 cx.emit_global(GlobalEvent(3));
4992 });
4993
4994 drop(second_subscription);
4995
4996 cx.update(|cx| {
4997 cx.emit_global(GlobalEvent(4));
4998 });
4999
5000 assert_eq!(
5001 &*events.borrow(),
5002 &[
5003 ("First", GlobalEvent(1)),
5004 ("Second", GlobalEvent(1)),
5005 ("First", GlobalEvent(2)),
5006 ("Second", GlobalEvent(2)),
5007 ("Second", GlobalEvent(3)),
5008 ]
5009 );
5010 }
5011
5012 #[crate::test(self)]
5013 fn test_global_events_emitted_before_subscription_in_same_update_cycle(cx: &mut AppContext) {
5014 let events = Rc::new(RefCell::new(Vec::new()));
5015 cx.update(|cx| {
5016 {
5017 let events = events.clone();
5018 drop(cx.subscribe_global(move |_: &(), _| {
5019 events.borrow_mut().push("dropped before emit");
5020 }));
5021 }
5022
5023 {
5024 let events = events.clone();
5025 cx.subscribe_global(move |_: &(), _| {
5026 events.borrow_mut().push("before emit");
5027 })
5028 .detach();
5029 }
5030
5031 cx.emit_global(());
5032
5033 {
5034 let events = events.clone();
5035 cx.subscribe_global(move |_: &(), _| {
5036 events.borrow_mut().push("after emit");
5037 })
5038 .detach();
5039 }
5040 });
5041
5042 assert_eq!(*events.borrow(), ["before emit"]);
5043 }
5044
5045 #[crate::test(self)]
5046 fn test_global_nested_events(cx: &mut AppContext) {
5047 #[derive(Clone, Debug, Eq, PartialEq)]
5048 struct GlobalEvent(u64);
5049
5050 let events = Rc::new(RefCell::new(Vec::new()));
5051
5052 {
5053 let events = events.clone();
5054 cx.subscribe_global(move |e: &GlobalEvent, cx| {
5055 events.borrow_mut().push(("Outer", e.clone()));
5056
5057 if e.0 == 1 {
5058 let events = events.clone();
5059 cx.subscribe_global(move |e: &GlobalEvent, _| {
5060 events.borrow_mut().push(("Inner", e.clone()));
5061 })
5062 .detach();
5063 }
5064 })
5065 .detach();
5066 }
5067
5068 cx.update(|cx| {
5069 cx.emit_global(GlobalEvent(1));
5070 cx.emit_global(GlobalEvent(2));
5071 cx.emit_global(GlobalEvent(3));
5072 });
5073 cx.update(|cx| {
5074 cx.emit_global(GlobalEvent(4));
5075 });
5076
5077 assert_eq!(
5078 &*events.borrow(),
5079 &[
5080 ("Outer", GlobalEvent(1)),
5081 ("Outer", GlobalEvent(2)),
5082 ("Outer", GlobalEvent(3)),
5083 ("Outer", GlobalEvent(4)),
5084 ("Inner", GlobalEvent(4)),
5085 ]
5086 );
5087 }
5088
5089 #[crate::test(self)]
5090 fn test_global(cx: &mut AppContext) {
5091 type Global = usize;
5092
5093 let observation_count = Rc::new(RefCell::new(0));
5094 let subscription = cx.observe_global::<Global, _>({
5095 let observation_count = observation_count.clone();
5096 move |_| {
5097 *observation_count.borrow_mut() += 1;
5098 }
5099 });
5100
5101 assert!(!cx.has_global::<Global>());
5102 assert_eq!(cx.default_global::<Global>(), &0);
5103 assert_eq!(*observation_count.borrow(), 1);
5104 assert!(cx.has_global::<Global>());
5105 assert_eq!(
5106 cx.update_global::<Global, _, _>(|global, _| {
5107 *global = 1;
5108 "Update Result"
5109 }),
5110 "Update Result"
5111 );
5112 assert_eq!(*observation_count.borrow(), 2);
5113 assert_eq!(cx.global::<Global>(), &1);
5114
5115 drop(subscription);
5116 cx.update_global::<Global, _, _>(|global, _| {
5117 *global = 2;
5118 });
5119 assert_eq!(*observation_count.borrow(), 2);
5120
5121 type OtherGlobal = f32;
5122
5123 let observation_count = Rc::new(RefCell::new(0));
5124 cx.observe_global::<OtherGlobal, _>({
5125 let observation_count = observation_count.clone();
5126 move |_| {
5127 *observation_count.borrow_mut() += 1;
5128 }
5129 })
5130 .detach();
5131
5132 assert_eq!(
5133 cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5134 assert_eq!(global, &0.0);
5135 *global = 2.0;
5136 "Default update result"
5137 }),
5138 "Default update result"
5139 );
5140 assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5141 assert_eq!(*observation_count.borrow(), 1);
5142 }
5143
5144 #[crate::test(self)]
5145 fn test_dropping_subscribers(cx: &mut TestAppContext) {
5146 struct Model;
5147
5148 impl Entity for Model {
5149 type Event = ();
5150 }
5151
5152 let (_, root_view) = cx.add_window(|_| TestView::default());
5153 let observing_view = cx.add_view(&root_view, |_| TestView::default());
5154 let emitting_view = cx.add_view(&root_view, |_| TestView::default());
5155 let observing_model = cx.add_model(|_| Model);
5156 let observed_model = cx.add_model(|_| Model);
5157
5158 observing_view.update(cx, |_, cx| {
5159 cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5160 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5161 });
5162 observing_model.update(cx, |_, cx| {
5163 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5164 });
5165
5166 cx.update(|_| {
5167 drop(observing_view);
5168 drop(observing_model);
5169 });
5170
5171 emitting_view.update(cx, |_, cx| cx.emit(Default::default()));
5172 observed_model.update(cx, |_, cx| cx.emit(()));
5173 }
5174
5175 #[crate::test(self)]
5176 fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
5177 let (_, view) = cx.add_window::<TestView, _>(Default::default(), |cx| {
5178 drop(cx.subscribe(&cx.handle(), {
5179 move |this, _, _, _| this.events.push("dropped before flush".into())
5180 }));
5181 cx.subscribe(&cx.handle(), {
5182 move |this, _, _, _| this.events.push("before emit".into())
5183 })
5184 .detach();
5185 cx.emit("the event".into());
5186 cx.subscribe(&cx.handle(), {
5187 move |this, _, _, _| this.events.push("after emit".into())
5188 })
5189 .detach();
5190 TestView { events: Vec::new() }
5191 });
5192
5193 assert_eq!(view.read(cx).events, ["before emit"]);
5194 }
5195
5196 #[crate::test(self)]
5197 fn test_observe_and_notify_from_view(cx: &mut TestAppContext) {
5198 #[derive(Default)]
5199 struct Model {
5200 state: String,
5201 }
5202
5203 impl Entity for Model {
5204 type Event = ();
5205 }
5206
5207 let (_, view) = cx.add_window(|_| TestView::default());
5208 let model = cx.add_model(|_| Model {
5209 state: "old-state".into(),
5210 });
5211
5212 view.update(cx, |_, c| {
5213 c.observe(&model, |me, observed, cx| {
5214 me.events.push(observed.read(cx).state.clone())
5215 })
5216 .detach();
5217 });
5218
5219 model.update(cx, |model, cx| {
5220 model.state = "new-state".into();
5221 cx.notify();
5222 });
5223 view.read_with(cx, |view, _| assert_eq!(view.events, ["new-state"]));
5224 }
5225
5226 #[crate::test(self)]
5227 fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
5228 let (_, view) = cx.add_window::<TestView, _>(Default::default(), |cx| {
5229 drop(cx.observe(&cx.handle(), {
5230 move |this, _, _| this.events.push("dropped before flush".into())
5231 }));
5232 cx.observe(&cx.handle(), {
5233 move |this, _, _| this.events.push("before notify".into())
5234 })
5235 .detach();
5236 cx.notify();
5237 cx.observe(&cx.handle(), {
5238 move |this, _, _| this.events.push("after notify".into())
5239 })
5240 .detach();
5241 TestView { events: Vec::new() }
5242 });
5243
5244 assert_eq!(view.read(cx).events, ["before notify"]);
5245 }
5246
5247 #[crate::test(self)]
5248 fn test_notify_and_drop_observe_subscription_in_same_update_cycle(cx: &mut TestAppContext) {
5249 struct Model;
5250 impl Entity for Model {
5251 type Event = ();
5252 }
5253
5254 let model = cx.add_model(|_| Model);
5255 let (_, view) = cx.add_window(|_| TestView::default());
5256
5257 view.update(cx, |_, cx| {
5258 model.update(cx, |_, cx| cx.notify());
5259 drop(cx.observe(&model, move |this, _, _| {
5260 this.events.push("model notified".into());
5261 }));
5262 model.update(cx, |_, cx| cx.notify());
5263 });
5264
5265 for _ in 0..3 {
5266 model.update(cx, |_, cx| cx.notify());
5267 }
5268 view.read_with(cx, |view, _| assert_eq!(view.events, Vec::<&str>::new()));
5269 }
5270
5271 #[crate::test(self)]
5272 fn test_dropping_observers(cx: &mut TestAppContext) {
5273 struct Model;
5274
5275 impl Entity for Model {
5276 type Event = ();
5277 }
5278
5279 let (_, root_view) = cx.add_window(|_| TestView::default());
5280 let observing_view = cx.add_view(&root_view, |_| TestView::default());
5281 let observing_model = cx.add_model(|_| Model);
5282 let observed_model = cx.add_model(|_| Model);
5283
5284 observing_view.update(cx, |_, cx| {
5285 cx.observe(&observed_model, |_, _, _| {}).detach();
5286 });
5287 observing_model.update(cx, |_, cx| {
5288 cx.observe(&observed_model, |_, _, _| {}).detach();
5289 });
5290
5291 cx.update(|_| {
5292 drop(observing_view);
5293 drop(observing_model);
5294 });
5295
5296 observed_model.update(cx, |_, cx| cx.notify());
5297 }
5298
5299 #[crate::test(self)]
5300 fn test_dropping_subscriptions_during_callback(cx: &mut TestAppContext) {
5301 struct Model;
5302
5303 impl Entity for Model {
5304 type Event = u64;
5305 }
5306
5307 // Events
5308 let observing_model = cx.add_model(|_| Model);
5309 let observed_model = cx.add_model(|_| Model);
5310
5311 let events = Rc::new(RefCell::new(Vec::new()));
5312
5313 observing_model.update(cx, |_, cx| {
5314 let events = events.clone();
5315 let subscription = Rc::new(RefCell::new(None));
5316 *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
5317 let subscription = subscription.clone();
5318 move |_, _, e, _| {
5319 subscription.borrow_mut().take();
5320 events.borrow_mut().push(*e);
5321 }
5322 }));
5323 });
5324
5325 observed_model.update(cx, |_, cx| {
5326 cx.emit(1);
5327 cx.emit(2);
5328 });
5329
5330 assert_eq!(*events.borrow(), [1]);
5331
5332 // Global Events
5333 #[derive(Clone, Debug, Eq, PartialEq)]
5334 struct GlobalEvent(u64);
5335
5336 let events = Rc::new(RefCell::new(Vec::new()));
5337
5338 {
5339 let events = events.clone();
5340 let subscription = Rc::new(RefCell::new(None));
5341 *subscription.borrow_mut() = Some(cx.subscribe_global({
5342 let subscription = subscription.clone();
5343 move |e: &GlobalEvent, _| {
5344 subscription.borrow_mut().take();
5345 events.borrow_mut().push(e.clone());
5346 }
5347 }));
5348 }
5349
5350 cx.update(|cx| {
5351 cx.emit_global(GlobalEvent(1));
5352 cx.emit_global(GlobalEvent(2));
5353 });
5354
5355 assert_eq!(*events.borrow(), [GlobalEvent(1)]);
5356
5357 // Model Observation
5358 let observing_model = cx.add_model(|_| Model);
5359 let observed_model = cx.add_model(|_| Model);
5360
5361 let observation_count = Rc::new(RefCell::new(0));
5362
5363 observing_model.update(cx, |_, cx| {
5364 let observation_count = observation_count.clone();
5365 let subscription = Rc::new(RefCell::new(None));
5366 *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
5367 let subscription = subscription.clone();
5368 move |_, _, _| {
5369 subscription.borrow_mut().take();
5370 *observation_count.borrow_mut() += 1;
5371 }
5372 }));
5373 });
5374
5375 observed_model.update(cx, |_, cx| {
5376 cx.notify();
5377 });
5378
5379 observed_model.update(cx, |_, cx| {
5380 cx.notify();
5381 });
5382
5383 assert_eq!(*observation_count.borrow(), 1);
5384
5385 // View Observation
5386 struct View;
5387
5388 impl Entity for View {
5389 type Event = ();
5390 }
5391
5392 impl super::View for View {
5393 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5394 Empty::new().boxed()
5395 }
5396
5397 fn ui_name() -> &'static str {
5398 "View"
5399 }
5400 }
5401
5402 let (_, root_view) = cx.add_window(|_| View);
5403 let observing_view = cx.add_view(&root_view, |_| View);
5404 let observed_view = cx.add_view(&root_view, |_| View);
5405
5406 let observation_count = Rc::new(RefCell::new(0));
5407 observing_view.update(cx, |_, cx| {
5408 let observation_count = observation_count.clone();
5409 let subscription = Rc::new(RefCell::new(None));
5410 *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
5411 let subscription = subscription.clone();
5412 move |_, _, _| {
5413 subscription.borrow_mut().take();
5414 *observation_count.borrow_mut() += 1;
5415 }
5416 }));
5417 });
5418
5419 observed_view.update(cx, |_, cx| {
5420 cx.notify();
5421 });
5422
5423 observed_view.update(cx, |_, cx| {
5424 cx.notify();
5425 });
5426
5427 assert_eq!(*observation_count.borrow(), 1);
5428
5429 // Global Observation
5430 let observation_count = Rc::new(RefCell::new(0));
5431 let subscription = Rc::new(RefCell::new(None));
5432 *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
5433 let observation_count = observation_count.clone();
5434 let subscription = subscription.clone();
5435 move |_| {
5436 subscription.borrow_mut().take();
5437 *observation_count.borrow_mut() += 1;
5438 }
5439 }));
5440
5441 cx.update(|cx| {
5442 cx.default_global::<()>();
5443 cx.set_global(());
5444 });
5445 assert_eq!(*observation_count.borrow(), 1);
5446 }
5447
5448 #[crate::test(self)]
5449 fn test_focus(cx: &mut TestAppContext) {
5450 struct View {
5451 name: String,
5452 events: Arc<Mutex<Vec<String>>>,
5453 }
5454
5455 impl Entity for View {
5456 type Event = ();
5457 }
5458
5459 impl super::View for View {
5460 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5461 Empty::new().boxed()
5462 }
5463
5464 fn ui_name() -> &'static str {
5465 "View"
5466 }
5467
5468 fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
5469 if cx.handle().id() == focused.id() {
5470 self.events.lock().push(format!("{} focused", &self.name));
5471 }
5472 }
5473
5474 fn focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
5475 if cx.handle().id() == blurred.id() {
5476 self.events.lock().push(format!("{} blurred", &self.name));
5477 }
5478 }
5479 }
5480
5481 let view_events: Arc<Mutex<Vec<String>>> = Default::default();
5482 let (window_id, view_1) = cx.add_window(|_| View {
5483 events: view_events.clone(),
5484 name: "view 1".to_string(),
5485 });
5486 let view_2 = cx.add_view(&view_1, |_| View {
5487 events: view_events.clone(),
5488 name: "view 2".to_string(),
5489 });
5490
5491 let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
5492 view_1.update(cx, |_, cx| {
5493 cx.observe_focus(&view_2, {
5494 let observed_events = observed_events.clone();
5495 move |this, view, focused, cx| {
5496 let label = if focused { "focus" } else { "blur" };
5497 observed_events.lock().push(format!(
5498 "{} observed {}'s {}",
5499 this.name,
5500 view.read(cx).name,
5501 label
5502 ))
5503 }
5504 })
5505 .detach();
5506 });
5507 view_2.update(cx, |_, cx| {
5508 cx.observe_focus(&view_1, {
5509 let observed_events = observed_events.clone();
5510 move |this, view, focused, cx| {
5511 let label = if focused { "focus" } else { "blur" };
5512 observed_events.lock().push(format!(
5513 "{} observed {}'s {}",
5514 this.name,
5515 view.read(cx).name,
5516 label
5517 ))
5518 }
5519 })
5520 .detach();
5521 });
5522 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5523 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5524
5525 view_1.update(cx, |_, cx| {
5526 // Ensure focus events are sent for all intermediate focuses
5527 cx.focus(&view_2);
5528 cx.focus(&view_1);
5529 cx.focus(&view_2);
5530 });
5531
5532 cx.read_window(window_id, |cx| {
5533 assert!(cx.is_child_focused(&view_1));
5534 assert!(!cx.is_child_focused(&view_2));
5535 });
5536 assert_eq!(
5537 mem::take(&mut *view_events.lock()),
5538 [
5539 "view 1 blurred",
5540 "view 2 focused",
5541 "view 2 blurred",
5542 "view 1 focused",
5543 "view 1 blurred",
5544 "view 2 focused"
5545 ],
5546 );
5547 assert_eq!(
5548 mem::take(&mut *observed_events.lock()),
5549 [
5550 "view 2 observed view 1's blur",
5551 "view 1 observed view 2's focus",
5552 "view 1 observed view 2's blur",
5553 "view 2 observed view 1's focus",
5554 "view 2 observed view 1's blur",
5555 "view 1 observed view 2's focus"
5556 ]
5557 );
5558
5559 view_1.update(cx, |_, cx| cx.focus(&view_1));
5560 cx.read_window(window_id, |cx| {
5561 assert!(!cx.is_child_focused(&view_1));
5562 assert!(!cx.is_child_focused(&view_2));
5563 });
5564 assert_eq!(
5565 mem::take(&mut *view_events.lock()),
5566 ["view 2 blurred", "view 1 focused"],
5567 );
5568 assert_eq!(
5569 mem::take(&mut *observed_events.lock()),
5570 [
5571 "view 1 observed view 2's blur",
5572 "view 2 observed view 1's focus"
5573 ]
5574 );
5575
5576 view_1.update(cx, |_, cx| cx.focus(&view_2));
5577 assert_eq!(
5578 mem::take(&mut *view_events.lock()),
5579 ["view 1 blurred", "view 2 focused"],
5580 );
5581 assert_eq!(
5582 mem::take(&mut *observed_events.lock()),
5583 [
5584 "view 2 observed view 1's blur",
5585 "view 1 observed view 2's focus"
5586 ]
5587 );
5588
5589 view_1.update(cx, |_, _| drop(view_2));
5590 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5591 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5592 }
5593
5594 #[crate::test(self)]
5595 fn test_deserialize_actions(cx: &mut AppContext) {
5596 #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
5597 pub struct ComplexAction {
5598 arg: String,
5599 count: usize,
5600 }
5601
5602 actions!(test::something, [SimpleAction]);
5603 impl_actions!(test::something, [ComplexAction]);
5604
5605 cx.add_global_action(move |_: &SimpleAction, _: &mut AppContext| {});
5606 cx.add_global_action(move |_: &ComplexAction, _: &mut AppContext| {});
5607
5608 let action1 = cx
5609 .deserialize_action(
5610 "test::something::ComplexAction",
5611 Some(r#"{"arg": "a", "count": 5}"#),
5612 )
5613 .unwrap();
5614 let action2 = cx
5615 .deserialize_action("test::something::SimpleAction", None)
5616 .unwrap();
5617 assert_eq!(
5618 action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
5619 &ComplexAction {
5620 arg: "a".to_string(),
5621 count: 5,
5622 }
5623 );
5624 assert_eq!(
5625 action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
5626 &SimpleAction
5627 );
5628 }
5629
5630 #[crate::test(self)]
5631 fn test_dispatch_action(cx: &mut AppContext) {
5632 struct ViewA {
5633 id: usize,
5634 }
5635
5636 impl Entity for ViewA {
5637 type Event = ();
5638 }
5639
5640 impl View for ViewA {
5641 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5642 Empty::new().boxed()
5643 }
5644
5645 fn ui_name() -> &'static str {
5646 "View"
5647 }
5648 }
5649
5650 struct ViewB {
5651 id: usize,
5652 }
5653
5654 impl Entity for ViewB {
5655 type Event = ();
5656 }
5657
5658 impl View for ViewB {
5659 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5660 Empty::new().boxed()
5661 }
5662
5663 fn ui_name() -> &'static str {
5664 "View"
5665 }
5666 }
5667
5668 #[derive(Clone, Default, Deserialize, PartialEq)]
5669 pub struct Action(pub String);
5670
5671 impl_actions!(test, [Action]);
5672
5673 let actions = Rc::new(RefCell::new(Vec::new()));
5674
5675 cx.add_global_action({
5676 let actions = actions.clone();
5677 move |_: &Action, _: &mut AppContext| {
5678 actions.borrow_mut().push("global".to_string());
5679 }
5680 });
5681
5682 cx.add_action({
5683 let actions = actions.clone();
5684 move |view: &mut ViewA, action: &Action, cx| {
5685 assert_eq!(action.0, "bar");
5686 cx.propagate_action();
5687 actions.borrow_mut().push(format!("{} a", view.id));
5688 }
5689 });
5690
5691 cx.add_action({
5692 let actions = actions.clone();
5693 move |view: &mut ViewA, _: &Action, cx| {
5694 if view.id != 1 {
5695 cx.add_view(|cx| {
5696 cx.propagate_action(); // Still works on a nested ViewContext
5697 ViewB { id: 5 }
5698 });
5699 }
5700 actions.borrow_mut().push(format!("{} b", view.id));
5701 }
5702 });
5703
5704 cx.add_action({
5705 let actions = actions.clone();
5706 move |view: &mut ViewB, _: &Action, cx| {
5707 cx.propagate_action();
5708 actions.borrow_mut().push(format!("{} c", view.id));
5709 }
5710 });
5711
5712 cx.add_action({
5713 let actions = actions.clone();
5714 move |view: &mut ViewB, _: &Action, cx| {
5715 cx.propagate_action();
5716 actions.borrow_mut().push(format!("{} d", view.id));
5717 }
5718 });
5719
5720 cx.capture_action({
5721 let actions = actions.clone();
5722 move |view: &mut ViewA, _: &Action, cx| {
5723 cx.propagate_action();
5724 actions.borrow_mut().push(format!("{} capture", view.id));
5725 }
5726 });
5727
5728 let observed_actions = Rc::new(RefCell::new(Vec::new()));
5729 cx.observe_actions({
5730 let observed_actions = observed_actions.clone();
5731 move |action_id, _| observed_actions.borrow_mut().push(action_id)
5732 })
5733 .detach();
5734
5735 let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
5736 let view_2 = cx.add_view(&view_1, |_| ViewB { id: 2 });
5737 let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
5738 let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
5739
5740 cx.update_window(window_id, |cx| {
5741 cx.handle_dispatch_action_from_effect(Some(view_4.id()), &Action("bar".to_string()))
5742 });
5743
5744 assert_eq!(
5745 *actions.borrow(),
5746 vec![
5747 "1 capture",
5748 "3 capture",
5749 "4 d",
5750 "4 c",
5751 "3 b",
5752 "3 a",
5753 "2 d",
5754 "2 c",
5755 "1 b"
5756 ]
5757 );
5758 assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
5759
5760 // Remove view_1, which doesn't propagate the action
5761
5762 let (window_id, view_2) = cx.add_window(Default::default(), |_| ViewB { id: 2 });
5763 let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
5764 let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
5765
5766 actions.borrow_mut().clear();
5767 cx.update_window(window_id, |cx| {
5768 cx.handle_dispatch_action_from_effect(Some(view_4.id()), &Action("bar".to_string()))
5769 });
5770
5771 assert_eq!(
5772 *actions.borrow(),
5773 vec![
5774 "3 capture",
5775 "4 d",
5776 "4 c",
5777 "3 b",
5778 "3 a",
5779 "2 d",
5780 "2 c",
5781 "global"
5782 ]
5783 );
5784 assert_eq!(
5785 *observed_actions.borrow(),
5786 [Action::default().id(), Action::default().id()]
5787 );
5788 }
5789
5790 #[crate::test(self)]
5791 fn test_dispatch_keystroke(cx: &mut AppContext) {
5792 #[derive(Clone, Deserialize, PartialEq)]
5793 pub struct Action(String);
5794
5795 impl_actions!(test, [Action]);
5796
5797 struct View {
5798 id: usize,
5799 keymap_context: KeymapContext,
5800 }
5801
5802 impl Entity for View {
5803 type Event = ();
5804 }
5805
5806 impl super::View for View {
5807 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5808 Empty::new().boxed()
5809 }
5810
5811 fn ui_name() -> &'static str {
5812 "View"
5813 }
5814
5815 fn keymap_context(&self, _: &AppContext) -> KeymapContext {
5816 self.keymap_context.clone()
5817 }
5818 }
5819
5820 impl View {
5821 fn new(id: usize) -> Self {
5822 View {
5823 id,
5824 keymap_context: KeymapContext::default(),
5825 }
5826 }
5827 }
5828
5829 let mut view_1 = View::new(1);
5830 let mut view_2 = View::new(2);
5831 let mut view_3 = View::new(3);
5832 view_1.keymap_context.add_identifier("a");
5833 view_2.keymap_context.add_identifier("a");
5834 view_2.keymap_context.add_identifier("b");
5835 view_3.keymap_context.add_identifier("a");
5836 view_3.keymap_context.add_identifier("b");
5837 view_3.keymap_context.add_identifier("c");
5838
5839 let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
5840 let view_2 = cx.add_view(&view_1, |_| view_2);
5841 let _view_3 = cx.add_view(&view_2, |cx| {
5842 cx.focus_self();
5843 view_3
5844 });
5845
5846 // This binding only dispatches an action on view 2 because that view will have
5847 // "a" and "b" in its context, but not "c".
5848 cx.add_bindings(vec![Binding::new(
5849 "a",
5850 Action("a".to_string()),
5851 Some("a && b && !c"),
5852 )]);
5853
5854 cx.add_bindings(vec![Binding::new("b", Action("b".to_string()), None)]);
5855
5856 // This binding only dispatches an action on views 2 and 3, because they have
5857 // a parent view with a in its context
5858 cx.add_bindings(vec![Binding::new(
5859 "c",
5860 Action("c".to_string()),
5861 Some("b > c"),
5862 )]);
5863
5864 // This binding only dispatches an action on view 2, because they have
5865 // a parent view with a in its context
5866 cx.add_bindings(vec![Binding::new(
5867 "d",
5868 Action("d".to_string()),
5869 Some("a && !b > b"),
5870 )]);
5871
5872 let actions = Rc::new(RefCell::new(Vec::new()));
5873 cx.add_action({
5874 let actions = actions.clone();
5875 move |view: &mut View, action: &Action, cx| {
5876 actions
5877 .borrow_mut()
5878 .push(format!("{} {}", view.id, action.0));
5879
5880 if action.0 == "b" {
5881 cx.propagate_action();
5882 }
5883 }
5884 });
5885
5886 cx.add_global_action({
5887 let actions = actions.clone();
5888 move |action: &Action, _| {
5889 actions.borrow_mut().push(format!("global {}", action.0));
5890 }
5891 });
5892
5893 cx.update_window(window_id, |cx| {
5894 cx.dispatch_keystroke(&Keystroke::parse("a").unwrap())
5895 });
5896 assert_eq!(&*actions.borrow(), &["2 a"]);
5897 actions.borrow_mut().clear();
5898
5899 cx.update_window(window_id, |cx| {
5900 cx.dispatch_keystroke(&Keystroke::parse("b").unwrap());
5901 });
5902
5903 assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
5904 actions.borrow_mut().clear();
5905
5906 cx.update_window(window_id, |cx| {
5907 cx.dispatch_keystroke(&Keystroke::parse("c").unwrap());
5908 });
5909 assert_eq!(&*actions.borrow(), &["3 c"]);
5910 actions.borrow_mut().clear();
5911
5912 cx.update_window(window_id, |cx| {
5913 cx.dispatch_keystroke(&Keystroke::parse("d").unwrap());
5914 });
5915 assert_eq!(&*actions.borrow(), &["2 d"]);
5916 actions.borrow_mut().clear();
5917 }
5918
5919 #[crate::test(self)]
5920 fn test_keystrokes_for_action(cx: &mut AppContext) {
5921 actions!(test, [Action1, Action2, GlobalAction]);
5922
5923 struct View1 {}
5924 struct View2 {}
5925
5926 impl Entity for View1 {
5927 type Event = ();
5928 }
5929 impl Entity for View2 {
5930 type Event = ();
5931 }
5932
5933 impl super::View for View1 {
5934 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5935 Empty::new().boxed()
5936 }
5937 fn ui_name() -> &'static str {
5938 "View1"
5939 }
5940 }
5941 impl super::View for View2 {
5942 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
5943 Empty::new().boxed()
5944 }
5945 fn ui_name() -> &'static str {
5946 "View2"
5947 }
5948 }
5949
5950 let (window_id, view_1) = cx.add_window(Default::default(), |_| View1 {});
5951 let view_2 = cx.add_view(&view_1, |cx| {
5952 cx.focus_self();
5953 View2 {}
5954 });
5955
5956 cx.add_action(|_: &mut View1, _: &Action1, _cx| {});
5957 cx.add_action(|_: &mut View2, _: &Action2, _cx| {});
5958 cx.add_global_action(|_: &GlobalAction, _| {});
5959
5960 cx.add_bindings(vec![
5961 Binding::new("a", Action1, Some("View1")),
5962 Binding::new("b", Action2, Some("View1 > View2")),
5963 Binding::new("c", GlobalAction, Some("View3")), // View 3 does not exist
5964 ]);
5965
5966 cx.update_window(window_id, |cx| {
5967 // Sanity check
5968 assert_eq!(
5969 cx.keystrokes_for_action(view_1.id(), &Action1)
5970 .unwrap()
5971 .as_slice(),
5972 &[Keystroke::parse("a").unwrap()]
5973 );
5974 assert_eq!(
5975 cx.keystrokes_for_action(view_2.id(), &Action2)
5976 .unwrap()
5977 .as_slice(),
5978 &[Keystroke::parse("b").unwrap()]
5979 );
5980
5981 // The 'a' keystroke propagates up the view tree from view_2
5982 // to view_1. The action, Action1, is handled by view_1.
5983 assert_eq!(
5984 cx.keystrokes_for_action(view_2.id(), &Action1)
5985 .unwrap()
5986 .as_slice(),
5987 &[Keystroke::parse("a").unwrap()]
5988 );
5989
5990 // Actions that are handled below the current view don't have bindings
5991 assert_eq!(cx.keystrokes_for_action(view_1.id(), &Action2), None);
5992
5993 // Actions that are handled in other branches of the tree should not have a binding
5994 assert_eq!(cx.keystrokes_for_action(view_2.id(), &GlobalAction), None);
5995
5996 // Check that global actions do not have a binding, even if a binding does exist in another view
5997 assert_eq!(
5998 &available_actions(view_1.id(), cx),
5999 &[
6000 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
6001 ("test::GlobalAction", vec![])
6002 ],
6003 );
6004
6005 // Check that view 1 actions and bindings are available even when called from view 2
6006 assert_eq!(
6007 &available_actions(view_2.id(), cx),
6008 &[
6009 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
6010 ("test::Action2", vec![Keystroke::parse("b").unwrap()]),
6011 ("test::GlobalAction", vec![]),
6012 ],
6013 );
6014 });
6015
6016 // Produces a list of actions and key bindings
6017 fn available_actions(
6018 view_id: usize,
6019 cx: &WindowContext,
6020 ) -> Vec<(&'static str, Vec<Keystroke>)> {
6021 cx.available_actions(view_id)
6022 .map(|(action_name, _, bindings)| {
6023 (
6024 action_name,
6025 bindings
6026 .iter()
6027 .map(|binding| binding.keystrokes()[0].clone())
6028 .collect::<Vec<_>>(),
6029 )
6030 })
6031 .sorted_by(|(name1, _), (name2, _)| name1.cmp(name2))
6032 .collect()
6033 }
6034 }
6035
6036 #[crate::test(self)]
6037 async fn test_model_condition(cx: &mut TestAppContext) {
6038 struct Counter(usize);
6039
6040 impl super::Entity for Counter {
6041 type Event = ();
6042 }
6043
6044 impl Counter {
6045 fn inc(&mut self, cx: &mut ModelContext<Self>) {
6046 self.0 += 1;
6047 cx.notify();
6048 }
6049 }
6050
6051 let model = cx.add_model(|_| Counter(0));
6052
6053 let condition1 = model.condition(cx, |model, _| model.0 == 2);
6054 let condition2 = model.condition(cx, |model, _| model.0 == 3);
6055 smol::pin!(condition1, condition2);
6056
6057 model.update(cx, |model, cx| model.inc(cx));
6058 assert_eq!(poll_once(&mut condition1).await, None);
6059 assert_eq!(poll_once(&mut condition2).await, None);
6060
6061 model.update(cx, |model, cx| model.inc(cx));
6062 assert_eq!(poll_once(&mut condition1).await, Some(()));
6063 assert_eq!(poll_once(&mut condition2).await, None);
6064
6065 model.update(cx, |model, cx| model.inc(cx));
6066 assert_eq!(poll_once(&mut condition2).await, Some(()));
6067
6068 model.update(cx, |_, cx| cx.notify());
6069 }
6070
6071 #[crate::test(self)]
6072 #[should_panic]
6073 async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6074 struct Model;
6075
6076 impl super::Entity for Model {
6077 type Event = ();
6078 }
6079
6080 let model = cx.add_model(|_| Model);
6081 model.condition(cx, |_, _| false).await;
6082 }
6083
6084 #[crate::test(self)]
6085 #[should_panic(expected = "model dropped with pending condition")]
6086 async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6087 struct Model;
6088
6089 impl super::Entity for Model {
6090 type Event = ();
6091 }
6092
6093 let model = cx.add_model(|_| Model);
6094 let condition = model.condition(cx, |_, _| false);
6095 cx.update(|_| drop(model));
6096 condition.await;
6097 }
6098
6099 #[crate::test(self)]
6100 async fn test_view_condition(cx: &mut TestAppContext) {
6101 struct Counter(usize);
6102
6103 impl super::Entity for Counter {
6104 type Event = ();
6105 }
6106
6107 impl super::View for Counter {
6108 fn ui_name() -> &'static str {
6109 "test view"
6110 }
6111
6112 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6113 Empty::new().boxed()
6114 }
6115 }
6116
6117 impl Counter {
6118 fn inc(&mut self, cx: &mut ViewContext<Self>) {
6119 self.0 += 1;
6120 cx.notify();
6121 }
6122 }
6123
6124 let (_, view) = cx.add_window(|_| Counter(0));
6125
6126 let condition1 = view.condition(cx, |view, _| view.0 == 2);
6127 let condition2 = view.condition(cx, |view, _| view.0 == 3);
6128 smol::pin!(condition1, condition2);
6129
6130 view.update(cx, |view, cx| view.inc(cx));
6131 assert_eq!(poll_once(&mut condition1).await, None);
6132 assert_eq!(poll_once(&mut condition2).await, None);
6133
6134 view.update(cx, |view, cx| view.inc(cx));
6135 assert_eq!(poll_once(&mut condition1).await, Some(()));
6136 assert_eq!(poll_once(&mut condition2).await, None);
6137
6138 view.update(cx, |view, cx| view.inc(cx));
6139 assert_eq!(poll_once(&mut condition2).await, Some(()));
6140 view.update(cx, |_, cx| cx.notify());
6141 }
6142
6143 #[crate::test(self)]
6144 #[should_panic]
6145 async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6146 let (_, view) = cx.add_window(|_| TestView::default());
6147 view.condition(cx, |_, _| false).await;
6148 }
6149
6150 #[crate::test(self)]
6151 #[should_panic(expected = "view dropped with pending condition")]
6152 async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6153 let (_, root_view) = cx.add_window(|_| TestView::default());
6154 let view = cx.add_view(&root_view, |_| TestView::default());
6155
6156 let condition = view.condition(cx, |_, _| false);
6157 cx.update(|_| drop(view));
6158 condition.await;
6159 }
6160
6161 #[crate::test(self)]
6162 fn test_refresh_windows(cx: &mut AppContext) {
6163 struct View(usize);
6164
6165 impl super::Entity for View {
6166 type Event = ();
6167 }
6168
6169 impl super::View for View {
6170 fn ui_name() -> &'static str {
6171 "test view"
6172 }
6173
6174 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6175 Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
6176 }
6177 }
6178
6179 let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
6180 cx.update_window(window_id, |cx| {
6181 assert_eq!(
6182 cx.window.rendered_views[&root_view.id()].name(),
6183 Some("render count: 0")
6184 );
6185 });
6186
6187 let view = cx.add_view(&root_view, |cx| {
6188 cx.refresh_windows();
6189 View(0)
6190 });
6191
6192 cx.update_window(window_id, |cx| {
6193 assert_eq!(
6194 cx.window.rendered_views[&root_view.id()].name(),
6195 Some("render count: 1")
6196 );
6197 assert_eq!(
6198 cx.window.rendered_views[&view.id()].name(),
6199 Some("render count: 0")
6200 );
6201 });
6202
6203 cx.update(|cx| cx.refresh_windows());
6204
6205 cx.update_window(window_id, |cx| {
6206 assert_eq!(
6207 cx.window.rendered_views[&root_view.id()].name(),
6208 Some("render count: 2")
6209 );
6210 assert_eq!(
6211 cx.window.rendered_views[&view.id()].name(),
6212 Some("render count: 1")
6213 );
6214 });
6215
6216 cx.update(|cx| {
6217 cx.refresh_windows();
6218 drop(view);
6219 });
6220
6221 cx.update_window(window_id, |cx| {
6222 assert_eq!(
6223 cx.window.rendered_views[&root_view.id()].name(),
6224 Some("render count: 3")
6225 );
6226 assert_eq!(cx.window.rendered_views.len(), 1);
6227 });
6228 }
6229
6230 #[crate::test(self)]
6231 async fn test_labeled_tasks(cx: &mut TestAppContext) {
6232 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6233 let (mut sender, mut reciever) = postage::oneshot::channel::<()>();
6234 let task = cx
6235 .update(|cx| cx.spawn_labeled("Test Label", |_| async move { reciever.recv().await }));
6236
6237 assert_eq!(
6238 Some("Test Label"),
6239 cx.update(|cx| cx.active_labeled_tasks().next())
6240 );
6241 sender
6242 .send(())
6243 .await
6244 .expect("Could not send message to complete task");
6245 task.await;
6246
6247 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6248 }
6249
6250 #[crate::test(self)]
6251 async fn test_window_activation(cx: &mut TestAppContext) {
6252 struct View(&'static str);
6253
6254 impl super::Entity for View {
6255 type Event = ();
6256 }
6257
6258 impl super::View for View {
6259 fn ui_name() -> &'static str {
6260 "test view"
6261 }
6262
6263 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6264 Empty::new().boxed()
6265 }
6266 }
6267
6268 let events = Rc::new(RefCell::new(Vec::new()));
6269 let (window_1, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6270 cx.observe_window_activation({
6271 let events = events.clone();
6272 move |this, active, _| events.borrow_mut().push((this.0, active))
6273 })
6274 .detach();
6275 View("window 1")
6276 });
6277 assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]);
6278
6279 let (window_2, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6280 cx.observe_window_activation({
6281 let events = events.clone();
6282 move |this, active, _| events.borrow_mut().push((this.0, active))
6283 })
6284 .detach();
6285 View("window 2")
6286 });
6287 assert_eq!(
6288 mem::take(&mut *events.borrow_mut()),
6289 [("window 1", false), ("window 2", true)]
6290 );
6291
6292 let (window_3, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6293 cx.observe_window_activation({
6294 let events = events.clone();
6295 move |this, active, _| events.borrow_mut().push((this.0, active))
6296 })
6297 .detach();
6298 View("window 3")
6299 });
6300 assert_eq!(
6301 mem::take(&mut *events.borrow_mut()),
6302 [("window 2", false), ("window 3", true)]
6303 );
6304
6305 cx.simulate_window_activation(Some(window_2));
6306 assert_eq!(
6307 mem::take(&mut *events.borrow_mut()),
6308 [("window 3", false), ("window 2", true)]
6309 );
6310
6311 cx.simulate_window_activation(Some(window_1));
6312 assert_eq!(
6313 mem::take(&mut *events.borrow_mut()),
6314 [("window 2", false), ("window 1", true)]
6315 );
6316
6317 cx.simulate_window_activation(Some(window_3));
6318 assert_eq!(
6319 mem::take(&mut *events.borrow_mut()),
6320 [("window 1", false), ("window 3", true)]
6321 );
6322
6323 cx.simulate_window_activation(Some(window_3));
6324 assert_eq!(mem::take(&mut *events.borrow_mut()), []);
6325 }
6326
6327 #[crate::test(self)]
6328 fn test_child_view(cx: &mut TestAppContext) {
6329 struct Child {
6330 rendered: Rc<Cell<bool>>,
6331 dropped: Rc<Cell<bool>>,
6332 }
6333
6334 impl super::Entity for Child {
6335 type Event = ();
6336 }
6337
6338 impl super::View for Child {
6339 fn ui_name() -> &'static str {
6340 "child view"
6341 }
6342
6343 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6344 self.rendered.set(true);
6345 Empty::new().boxed()
6346 }
6347 }
6348
6349 impl Drop for Child {
6350 fn drop(&mut self) {
6351 self.dropped.set(true);
6352 }
6353 }
6354
6355 struct Parent {
6356 child: Option<ViewHandle<Child>>,
6357 }
6358
6359 impl super::Entity for Parent {
6360 type Event = ();
6361 }
6362
6363 impl super::View for Parent {
6364 fn ui_name() -> &'static str {
6365 "parent view"
6366 }
6367
6368 fn render(&mut self, cx: &mut ViewContext<Self>) -> Element<Self> {
6369 if let Some(child) = self.child.as_ref() {
6370 ChildView::new(child, cx).boxed()
6371 } else {
6372 Empty::new().boxed()
6373 }
6374 }
6375 }
6376
6377 let child_rendered = Rc::new(Cell::new(false));
6378 let child_dropped = Rc::new(Cell::new(false));
6379 let (_, root_view) = cx.add_window(|cx| Parent {
6380 child: Some(cx.add_view(|_| Child {
6381 rendered: child_rendered.clone(),
6382 dropped: child_dropped.clone(),
6383 })),
6384 });
6385 assert!(child_rendered.take());
6386 assert!(!child_dropped.take());
6387
6388 root_view.update(cx, |view, cx| {
6389 view.child.take();
6390 cx.notify();
6391 });
6392 assert!(!child_rendered.take());
6393 assert!(child_dropped.take());
6394 }
6395
6396 #[derive(Default)]
6397 struct TestView {
6398 events: Vec<String>,
6399 }
6400
6401 impl Entity for TestView {
6402 type Event = String;
6403 }
6404
6405 impl View for TestView {
6406 fn ui_name() -> &'static str {
6407 "TestView"
6408 }
6409
6410 fn render(&mut self, _: &mut ViewContext<Self>) -> Element<Self> {
6411 Empty::new().boxed()
6412 }
6413 }
6414}