app.rs

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