app.rs

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