app.rs

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