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