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 add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
3343    where
3344        S: Entity,
3345        F: FnOnce(&mut ModelContext<S>) -> S,
3346    {
3347        self.app.add_model(build_model)
3348    }
3349
3350    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
3351    where
3352        S: View,
3353        F: FnOnce(&mut ViewContext<S>) -> S,
3354    {
3355        self.app.add_view(self.window_id, build_view)
3356    }
3357
3358    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
3359    where
3360        S: View,
3361        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
3362    {
3363        self.app.add_option_view(self.window_id, build_view)
3364    }
3365
3366    pub fn replace_root_view<V, F>(&mut self, build_root_view: F) -> ViewHandle<V>
3367    where
3368        V: View,
3369        F: FnOnce(&mut ViewContext<V>) -> V,
3370    {
3371        let window_id = self.window_id;
3372        self.update(|this| {
3373            let root_view = this.add_view(window_id, build_root_view);
3374            let window = this.cx.windows.get_mut(&window_id).unwrap();
3375            window.root_view = root_view.clone().into();
3376            window.focused_view_id = Some(root_view.id());
3377            root_view
3378        })
3379    }
3380
3381    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3382    where
3383        E: Entity,
3384        E::Event: 'static,
3385        H: Handle<E>,
3386        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
3387    {
3388        let subscriber = self.weak_handle();
3389        self.app
3390            .subscribe_internal(handle, move |emitter, event, cx| {
3391                if let Some(subscriber) = subscriber.upgrade(cx) {
3392                    subscriber.update(cx, |subscriber, cx| {
3393                        callback(subscriber, emitter, event, cx);
3394                    });
3395                    true
3396                } else {
3397                    false
3398                }
3399            })
3400    }
3401
3402    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3403    where
3404        E: Entity,
3405        H: Handle<E>,
3406        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
3407    {
3408        let observer = self.weak_handle();
3409        self.app.observe_internal(handle, move |observed, cx| {
3410            if let Some(observer) = observer.upgrade(cx) {
3411                observer.update(cx, |observer, cx| {
3412                    callback(observer, observed, cx);
3413                });
3414                true
3415            } else {
3416                false
3417            }
3418        })
3419    }
3420
3421    pub fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
3422    where
3423        F: 'static + FnMut(&mut T, ViewHandle<V>, &mut ViewContext<T>),
3424        V: View,
3425    {
3426        let observer = self.weak_handle();
3427        self.app.observe_focus(handle, move |observed, cx| {
3428            if let Some(observer) = observer.upgrade(cx) {
3429                observer.update(cx, |observer, cx| {
3430                    callback(observer, observed, cx);
3431                });
3432                true
3433            } else {
3434                false
3435            }
3436        })
3437    }
3438
3439    pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3440    where
3441        E: Entity,
3442        H: Handle<E>,
3443        F: 'static + FnMut(&mut T, &E, &mut ViewContext<T>),
3444    {
3445        let observer = self.weak_handle();
3446        self.app.observe_release(handle, move |released, cx| {
3447            if let Some(observer) = observer.upgrade(cx) {
3448                observer.update(cx, |observer, cx| {
3449                    callback(observer, released, cx);
3450                });
3451            }
3452        })
3453    }
3454
3455    pub fn observe_actions<F>(&mut self, mut callback: F) -> Subscription
3456    where
3457        F: 'static + FnMut(&mut T, TypeId, &mut ViewContext<T>),
3458    {
3459        let observer = self.weak_handle();
3460        self.app.observe_actions(move |action_id, cx| {
3461            if let Some(observer) = observer.upgrade(cx) {
3462                observer.update(cx, |observer, cx| {
3463                    callback(observer, action_id, cx);
3464                });
3465            }
3466        })
3467    }
3468
3469    pub fn emit(&mut self, payload: T::Event) {
3470        self.app.pending_effects.push_back(Effect::Event {
3471            entity_id: self.view_id,
3472            payload: Box::new(payload),
3473        });
3474    }
3475
3476    pub fn notify(&mut self) {
3477        self.app.notify_view(self.window_id, self.view_id);
3478    }
3479
3480    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>)) {
3481        let handle = self.handle();
3482        self.app.defer(move |cx| {
3483            handle.update(cx, |view, cx| {
3484                callback(view, cx);
3485            })
3486        })
3487    }
3488
3489    pub fn after_window_update(
3490        &mut self,
3491        callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>),
3492    ) {
3493        let handle = self.handle();
3494        self.app.after_window_update(move |cx| {
3495            handle.update(cx, |view, cx| {
3496                callback(view, cx);
3497            })
3498        })
3499    }
3500
3501    pub fn propagate_action(&mut self) {
3502        self.app.halt_action_dispatch = false;
3503    }
3504
3505    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3506    where
3507        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
3508        Fut: 'static + Future<Output = S>,
3509        S: 'static,
3510    {
3511        let handle = self.handle();
3512        self.app.spawn(|cx| f(handle, cx))
3513    }
3514
3515    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3516    where
3517        F: FnOnce(WeakViewHandle<T>, AsyncAppContext) -> Fut,
3518        Fut: 'static + Future<Output = S>,
3519        S: 'static,
3520    {
3521        let handle = self.weak_handle();
3522        self.app.spawn(|cx| f(handle, cx))
3523    }
3524}
3525
3526pub struct RenderParams {
3527    pub window_id: usize,
3528    pub view_id: usize,
3529    pub titlebar_height: f32,
3530    pub hovered_region_ids: HashSet<MouseRegionId>,
3531    pub clicked_region_id: Option<MouseRegionId>,
3532    pub right_clicked_region_id: Option<MouseRegionId>,
3533    pub refreshing: bool,
3534}
3535
3536pub struct RenderContext<'a, T: View> {
3537    pub(crate) window_id: usize,
3538    pub(crate) view_id: usize,
3539    pub(crate) view_type: PhantomData<T>,
3540    pub(crate) hovered_region_ids: HashSet<MouseRegionId>,
3541    pub(crate) clicked_region_id: Option<MouseRegionId>,
3542    pub(crate) right_clicked_region_id: Option<MouseRegionId>,
3543    pub app: &'a mut MutableAppContext,
3544    pub titlebar_height: f32,
3545    pub refreshing: bool,
3546}
3547
3548#[derive(Clone, Copy, Default)]
3549pub struct MouseState {
3550    pub hovered: bool,
3551    pub clicked: bool,
3552    pub right_clicked: bool,
3553}
3554
3555impl<'a, V: View> RenderContext<'a, V> {
3556    fn new(params: RenderParams, app: &'a mut MutableAppContext) -> Self {
3557        Self {
3558            app,
3559            window_id: params.window_id,
3560            view_id: params.view_id,
3561            view_type: PhantomData,
3562            titlebar_height: params.titlebar_height,
3563            hovered_region_ids: params.hovered_region_ids.clone(),
3564            clicked_region_id: params.clicked_region_id,
3565            right_clicked_region_id: params.right_clicked_region_id,
3566            refreshing: params.refreshing,
3567        }
3568    }
3569
3570    pub fn handle(&self) -> WeakViewHandle<V> {
3571        WeakViewHandle::new(self.window_id, self.view_id)
3572    }
3573
3574    pub fn view_id(&self) -> usize {
3575        self.view_id
3576    }
3577
3578    pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
3579        let region_id = MouseRegionId {
3580            view_id: self.view_id,
3581            discriminant: (TypeId::of::<Tag>(), region_id),
3582        };
3583        MouseState {
3584            hovered: self.hovered_region_ids.contains(&region_id),
3585            clicked: self.clicked_region_id == Some(region_id),
3586            right_clicked: self.right_clicked_region_id == Some(region_id),
3587        }
3588    }
3589
3590    pub fn element_state<Tag: 'static, T: 'static + Default>(
3591        &mut self,
3592        element_id: usize,
3593    ) -> ElementStateHandle<T> {
3594        let id = ElementStateId {
3595            view_id: self.view_id(),
3596            element_id,
3597            tag: TypeId::of::<Tag>(),
3598        };
3599        self.cx
3600            .element_states
3601            .entry(id)
3602            .or_insert_with(|| Box::new(T::default()));
3603        ElementStateHandle::new(id, self.frame_count, &self.cx.ref_counts)
3604    }
3605}
3606
3607impl AsRef<AppContext> for &AppContext {
3608    fn as_ref(&self) -> &AppContext {
3609        self
3610    }
3611}
3612
3613impl<V: View> Deref for RenderContext<'_, V> {
3614    type Target = MutableAppContext;
3615
3616    fn deref(&self) -> &Self::Target {
3617        self.app
3618    }
3619}
3620
3621impl<V: View> DerefMut for RenderContext<'_, V> {
3622    fn deref_mut(&mut self) -> &mut Self::Target {
3623        self.app
3624    }
3625}
3626
3627impl<V: View> ReadModel for RenderContext<'_, V> {
3628    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3629        self.app.read_model(handle)
3630    }
3631}
3632
3633impl<V: View> UpdateModel for RenderContext<'_, V> {
3634    fn update_model<T: Entity, O>(
3635        &mut self,
3636        handle: &ModelHandle<T>,
3637        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3638    ) -> O {
3639        self.app.update_model(handle, update)
3640    }
3641}
3642
3643impl<V: View> ReadView for RenderContext<'_, V> {
3644    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3645        self.app.read_view(handle)
3646    }
3647}
3648
3649impl<M> AsRef<AppContext> for ViewContext<'_, M> {
3650    fn as_ref(&self) -> &AppContext {
3651        &self.app.cx
3652    }
3653}
3654
3655impl<M> Deref for ViewContext<'_, M> {
3656    type Target = MutableAppContext;
3657
3658    fn deref(&self) -> &Self::Target {
3659        &self.app
3660    }
3661}
3662
3663impl<M> DerefMut for ViewContext<'_, M> {
3664    fn deref_mut(&mut self) -> &mut Self::Target {
3665        &mut self.app
3666    }
3667}
3668
3669impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
3670    fn as_mut(&mut self) -> &mut MutableAppContext {
3671        self.app
3672    }
3673}
3674
3675impl<V> ReadModel for ViewContext<'_, V> {
3676    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3677        self.app.read_model(handle)
3678    }
3679}
3680
3681impl<V> UpgradeModelHandle for ViewContext<'_, V> {
3682    fn upgrade_model_handle<T: Entity>(
3683        &self,
3684        handle: &WeakModelHandle<T>,
3685    ) -> Option<ModelHandle<T>> {
3686        self.cx.upgrade_model_handle(handle)
3687    }
3688
3689    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3690        self.cx.model_handle_is_upgradable(handle)
3691    }
3692
3693    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3694        self.cx.upgrade_any_model_handle(handle)
3695    }
3696}
3697
3698impl<V> UpgradeViewHandle for ViewContext<'_, V> {
3699    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3700        self.cx.upgrade_view_handle(handle)
3701    }
3702
3703    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3704        self.cx.upgrade_any_view_handle(handle)
3705    }
3706}
3707
3708impl<V: View> UpgradeViewHandle for RenderContext<'_, V> {
3709    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3710        self.cx.upgrade_view_handle(handle)
3711    }
3712
3713    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3714        self.cx.upgrade_any_view_handle(handle)
3715    }
3716}
3717
3718impl<V: View> UpdateModel for ViewContext<'_, V> {
3719    fn update_model<T: Entity, O>(
3720        &mut self,
3721        handle: &ModelHandle<T>,
3722        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3723    ) -> O {
3724        self.app.update_model(handle, update)
3725    }
3726}
3727
3728impl<V: View> ReadView for ViewContext<'_, V> {
3729    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3730        self.app.read_view(handle)
3731    }
3732}
3733
3734impl<V: View> UpdateView for ViewContext<'_, V> {
3735    fn update_view<T, S>(
3736        &mut self,
3737        handle: &ViewHandle<T>,
3738        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3739    ) -> S
3740    where
3741        T: View,
3742    {
3743        self.app.update_view(handle, update)
3744    }
3745}
3746
3747pub trait Handle<T> {
3748    type Weak: 'static;
3749    fn id(&self) -> usize;
3750    fn location(&self) -> EntityLocation;
3751    fn downgrade(&self) -> Self::Weak;
3752    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3753    where
3754        Self: Sized;
3755}
3756
3757pub trait WeakHandle {
3758    fn id(&self) -> usize;
3759}
3760
3761#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3762pub enum EntityLocation {
3763    Model(usize),
3764    View(usize, usize),
3765}
3766
3767pub struct ModelHandle<T: Entity> {
3768    model_id: usize,
3769    model_type: PhantomData<T>,
3770    ref_counts: Arc<Mutex<RefCounts>>,
3771
3772    #[cfg(any(test, feature = "test-support"))]
3773    handle_id: usize,
3774}
3775
3776impl<T: Entity> ModelHandle<T> {
3777    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3778        ref_counts.lock().inc_model(model_id);
3779
3780        #[cfg(any(test, feature = "test-support"))]
3781        let handle_id = ref_counts
3782            .lock()
3783            .leak_detector
3784            .lock()
3785            .handle_created(Some(type_name::<T>()), model_id);
3786
3787        Self {
3788            model_id,
3789            model_type: PhantomData,
3790            ref_counts: ref_counts.clone(),
3791
3792            #[cfg(any(test, feature = "test-support"))]
3793            handle_id,
3794        }
3795    }
3796
3797    pub fn downgrade(&self) -> WeakModelHandle<T> {
3798        WeakModelHandle::new(self.model_id)
3799    }
3800
3801    pub fn id(&self) -> usize {
3802        self.model_id
3803    }
3804
3805    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
3806        cx.read_model(self)
3807    }
3808
3809    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
3810    where
3811        C: ReadModelWith,
3812        F: FnOnce(&T, &AppContext) -> S,
3813    {
3814        let mut read = Some(read);
3815        cx.read_model_with(self, &mut |model, cx| {
3816            let read = read.take().unwrap();
3817            read(model, cx)
3818        })
3819    }
3820
3821    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3822    where
3823        C: UpdateModel,
3824        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
3825    {
3826        let mut update = Some(update);
3827        cx.update_model(self, &mut |model, cx| {
3828            let update = update.take().unwrap();
3829            update(model, cx)
3830        })
3831    }
3832
3833    #[cfg(any(test, feature = "test-support"))]
3834    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
3835        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3836        let mut cx = cx.cx.borrow_mut();
3837        let subscription = cx.observe(self, move |_, _| {
3838            tx.unbounded_send(()).ok();
3839        });
3840
3841        let duration = if std::env::var("CI").is_ok() {
3842            Duration::from_secs(5)
3843        } else {
3844            Duration::from_secs(1)
3845        };
3846
3847        async move {
3848            let notification = crate::util::timeout(duration, rx.next())
3849                .await
3850                .expect("next notification timed out");
3851            drop(subscription);
3852            notification.expect("model dropped while test was waiting for its next notification")
3853        }
3854    }
3855
3856    #[cfg(any(test, feature = "test-support"))]
3857    pub fn next_event(&self, cx: &TestAppContext) -> impl Future<Output = T::Event>
3858    where
3859        T::Event: Clone,
3860    {
3861        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3862        let mut cx = cx.cx.borrow_mut();
3863        let subscription = cx.subscribe(self, move |_, event, _| {
3864            tx.unbounded_send(event.clone()).ok();
3865        });
3866
3867        let duration = if std::env::var("CI").is_ok() {
3868            Duration::from_secs(5)
3869        } else {
3870            Duration::from_secs(1)
3871        };
3872
3873        cx.foreground.start_waiting();
3874        async move {
3875            let event = crate::util::timeout(duration, rx.next())
3876                .await
3877                .expect("next event timed out");
3878            drop(subscription);
3879            event.expect("model dropped while test was waiting for its next event")
3880        }
3881    }
3882
3883    #[cfg(any(test, feature = "test-support"))]
3884    pub fn condition(
3885        &self,
3886        cx: &TestAppContext,
3887        mut predicate: impl FnMut(&T, &AppContext) -> bool,
3888    ) -> impl Future<Output = ()> {
3889        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3890
3891        let mut cx = cx.cx.borrow_mut();
3892        let subscriptions = (
3893            cx.observe(self, {
3894                let tx = tx.clone();
3895                move |_, _| {
3896                    tx.unbounded_send(()).ok();
3897                }
3898            }),
3899            cx.subscribe(self, {
3900                let tx = tx.clone();
3901                move |_, _, _| {
3902                    tx.unbounded_send(()).ok();
3903                }
3904            }),
3905        );
3906
3907        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
3908        let handle = self.downgrade();
3909        let duration = if std::env::var("CI").is_ok() {
3910            Duration::from_secs(5)
3911        } else {
3912            Duration::from_secs(1)
3913        };
3914
3915        async move {
3916            crate::util::timeout(duration, async move {
3917                loop {
3918                    {
3919                        let cx = cx.borrow();
3920                        let cx = cx.as_ref();
3921                        if predicate(
3922                            handle
3923                                .upgrade(cx)
3924                                .expect("model dropped with pending condition")
3925                                .read(cx),
3926                            cx,
3927                        ) {
3928                            break;
3929                        }
3930                    }
3931
3932                    cx.borrow().foreground().start_waiting();
3933                    rx.next()
3934                        .await
3935                        .expect("model dropped with pending condition");
3936                    cx.borrow().foreground().finish_waiting();
3937                }
3938            })
3939            .await
3940            .expect("condition timed out");
3941            drop(subscriptions);
3942        }
3943    }
3944}
3945
3946impl<T: Entity> Clone for ModelHandle<T> {
3947    fn clone(&self) -> Self {
3948        Self::new(self.model_id, &self.ref_counts)
3949    }
3950}
3951
3952impl<T: Entity> PartialEq for ModelHandle<T> {
3953    fn eq(&self, other: &Self) -> bool {
3954        self.model_id == other.model_id
3955    }
3956}
3957
3958impl<T: Entity> Eq for ModelHandle<T> {}
3959
3960impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
3961    fn eq(&self, other: &WeakModelHandle<T>) -> bool {
3962        self.model_id == other.model_id
3963    }
3964}
3965
3966impl<T: Entity> Hash for ModelHandle<T> {
3967    fn hash<H: Hasher>(&self, state: &mut H) {
3968        self.model_id.hash(state);
3969    }
3970}
3971
3972impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
3973    fn borrow(&self) -> &usize {
3974        &self.model_id
3975    }
3976}
3977
3978impl<T: Entity> Debug for ModelHandle<T> {
3979    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3980        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
3981            .field(&self.model_id)
3982            .finish()
3983    }
3984}
3985
3986unsafe impl<T: Entity> Send for ModelHandle<T> {}
3987unsafe impl<T: Entity> Sync for ModelHandle<T> {}
3988
3989impl<T: Entity> Drop for ModelHandle<T> {
3990    fn drop(&mut self) {
3991        let mut ref_counts = self.ref_counts.lock();
3992        ref_counts.dec_model(self.model_id);
3993
3994        #[cfg(any(test, feature = "test-support"))]
3995        ref_counts
3996            .leak_detector
3997            .lock()
3998            .handle_dropped(self.model_id, self.handle_id);
3999    }
4000}
4001
4002impl<T: Entity> Handle<T> for ModelHandle<T> {
4003    type Weak = WeakModelHandle<T>;
4004
4005    fn id(&self) -> usize {
4006        self.model_id
4007    }
4008
4009    fn location(&self) -> EntityLocation {
4010        EntityLocation::Model(self.model_id)
4011    }
4012
4013    fn downgrade(&self) -> Self::Weak {
4014        self.downgrade()
4015    }
4016
4017    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4018    where
4019        Self: Sized,
4020    {
4021        weak.upgrade(cx)
4022    }
4023}
4024
4025pub struct WeakModelHandle<T> {
4026    model_id: usize,
4027    model_type: PhantomData<T>,
4028}
4029
4030impl<T> WeakHandle for WeakModelHandle<T> {
4031    fn id(&self) -> usize {
4032        self.model_id
4033    }
4034}
4035
4036unsafe impl<T> Send for WeakModelHandle<T> {}
4037unsafe impl<T> Sync for WeakModelHandle<T> {}
4038
4039impl<T: Entity> WeakModelHandle<T> {
4040    fn new(model_id: usize) -> Self {
4041        Self {
4042            model_id,
4043            model_type: PhantomData,
4044        }
4045    }
4046
4047    pub fn id(&self) -> usize {
4048        self.model_id
4049    }
4050
4051    pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
4052        cx.model_handle_is_upgradable(self)
4053    }
4054
4055    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
4056        cx.upgrade_model_handle(self)
4057    }
4058}
4059
4060impl<T> Hash for WeakModelHandle<T> {
4061    fn hash<H: Hasher>(&self, state: &mut H) {
4062        self.model_id.hash(state)
4063    }
4064}
4065
4066impl<T> PartialEq for WeakModelHandle<T> {
4067    fn eq(&self, other: &Self) -> bool {
4068        self.model_id == other.model_id
4069    }
4070}
4071
4072impl<T> Eq for WeakModelHandle<T> {}
4073
4074impl<T> Clone for WeakModelHandle<T> {
4075    fn clone(&self) -> Self {
4076        Self {
4077            model_id: self.model_id,
4078            model_type: PhantomData,
4079        }
4080    }
4081}
4082
4083impl<T> Copy for WeakModelHandle<T> {}
4084
4085pub struct ViewHandle<T> {
4086    window_id: usize,
4087    view_id: usize,
4088    view_type: PhantomData<T>,
4089    ref_counts: Arc<Mutex<RefCounts>>,
4090    #[cfg(any(test, feature = "test-support"))]
4091    handle_id: usize,
4092}
4093
4094impl<T: View> ViewHandle<T> {
4095    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4096        ref_counts.lock().inc_view(window_id, view_id);
4097        #[cfg(any(test, feature = "test-support"))]
4098        let handle_id = ref_counts
4099            .lock()
4100            .leak_detector
4101            .lock()
4102            .handle_created(Some(type_name::<T>()), view_id);
4103
4104        Self {
4105            window_id,
4106            view_id,
4107            view_type: PhantomData,
4108            ref_counts: ref_counts.clone(),
4109
4110            #[cfg(any(test, feature = "test-support"))]
4111            handle_id,
4112        }
4113    }
4114
4115    pub fn downgrade(&self) -> WeakViewHandle<T> {
4116        WeakViewHandle::new(self.window_id, self.view_id)
4117    }
4118
4119    pub fn window_id(&self) -> usize {
4120        self.window_id
4121    }
4122
4123    pub fn id(&self) -> usize {
4124        self.view_id
4125    }
4126
4127    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
4128        cx.read_view(self)
4129    }
4130
4131    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
4132    where
4133        C: ReadViewWith,
4134        F: FnOnce(&T, &AppContext) -> S,
4135    {
4136        let mut read = Some(read);
4137        cx.read_view_with(self, &mut |view, cx| {
4138            let read = read.take().unwrap();
4139            read(view, cx)
4140        })
4141    }
4142
4143    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
4144    where
4145        C: UpdateView,
4146        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
4147    {
4148        let mut update = Some(update);
4149        cx.update_view(self, &mut |view, cx| {
4150            let update = update.take().unwrap();
4151            update(view, cx)
4152        })
4153    }
4154
4155    pub fn defer<C, F>(&self, cx: &mut C, update: F)
4156    where
4157        C: AsMut<MutableAppContext>,
4158        F: 'static + FnOnce(&mut T, &mut ViewContext<T>),
4159    {
4160        let this = self.clone();
4161        cx.as_mut().defer(move |cx| {
4162            this.update(cx, |view, cx| update(view, cx));
4163        });
4164    }
4165
4166    pub fn is_focused(&self, cx: &AppContext) -> bool {
4167        cx.focused_view_id(self.window_id)
4168            .map_or(false, |focused_id| focused_id == self.view_id)
4169    }
4170
4171    #[cfg(any(test, feature = "test-support"))]
4172    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
4173        use postage::prelude::{Sink as _, Stream as _};
4174
4175        let (mut tx, mut rx) = postage::mpsc::channel(1);
4176        let mut cx = cx.cx.borrow_mut();
4177        let subscription = cx.observe(self, move |_, _| {
4178            tx.try_send(()).ok();
4179        });
4180
4181        let duration = if std::env::var("CI").is_ok() {
4182            Duration::from_secs(5)
4183        } else {
4184            Duration::from_secs(1)
4185        };
4186
4187        async move {
4188            let notification = crate::util::timeout(duration, rx.recv())
4189                .await
4190                .expect("next notification timed out");
4191            drop(subscription);
4192            notification.expect("model dropped while test was waiting for its next notification")
4193        }
4194    }
4195
4196    #[cfg(any(test, feature = "test-support"))]
4197    pub fn condition(
4198        &self,
4199        cx: &TestAppContext,
4200        mut predicate: impl FnMut(&T, &AppContext) -> bool,
4201    ) -> impl Future<Output = ()> {
4202        use postage::prelude::{Sink as _, Stream as _};
4203
4204        let (tx, mut rx) = postage::mpsc::channel(1024);
4205
4206        let mut cx = cx.cx.borrow_mut();
4207        let subscriptions = self.update(&mut *cx, |_, cx| {
4208            (
4209                cx.observe(self, {
4210                    let mut tx = tx.clone();
4211                    move |_, _, _| {
4212                        tx.blocking_send(()).ok();
4213                    }
4214                }),
4215                cx.subscribe(self, {
4216                    let mut tx = tx.clone();
4217                    move |_, _, _, _| {
4218                        tx.blocking_send(()).ok();
4219                    }
4220                }),
4221            )
4222        });
4223
4224        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
4225        let handle = self.downgrade();
4226        let duration = if std::env::var("CI").is_ok() {
4227            Duration::from_secs(2)
4228        } else {
4229            Duration::from_millis(500)
4230        };
4231
4232        async move {
4233            crate::util::timeout(duration, async move {
4234                loop {
4235                    {
4236                        let cx = cx.borrow();
4237                        let cx = cx.as_ref();
4238                        if predicate(
4239                            handle
4240                                .upgrade(cx)
4241                                .expect("view dropped with pending condition")
4242                                .read(cx),
4243                            cx,
4244                        ) {
4245                            break;
4246                        }
4247                    }
4248
4249                    cx.borrow().foreground().start_waiting();
4250                    rx.recv()
4251                        .await
4252                        .expect("view dropped with pending condition");
4253                    cx.borrow().foreground().finish_waiting();
4254                }
4255            })
4256            .await
4257            .expect("condition timed out");
4258            drop(subscriptions);
4259        }
4260    }
4261}
4262
4263impl<T: View> Clone for ViewHandle<T> {
4264    fn clone(&self) -> Self {
4265        ViewHandle::new(self.window_id, self.view_id, &self.ref_counts)
4266    }
4267}
4268
4269impl<T> PartialEq for ViewHandle<T> {
4270    fn eq(&self, other: &Self) -> bool {
4271        self.window_id == other.window_id && self.view_id == other.view_id
4272    }
4273}
4274
4275impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
4276    fn eq(&self, other: &WeakViewHandle<T>) -> bool {
4277        self.window_id == other.window_id && self.view_id == other.view_id
4278    }
4279}
4280
4281impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
4282    fn eq(&self, other: &ViewHandle<T>) -> bool {
4283        self.window_id == other.window_id && self.view_id == other.view_id
4284    }
4285}
4286
4287impl<T> Eq for ViewHandle<T> {}
4288
4289impl<T> Hash for ViewHandle<T> {
4290    fn hash<H: Hasher>(&self, state: &mut H) {
4291        self.window_id.hash(state);
4292        self.view_id.hash(state);
4293    }
4294}
4295
4296impl<T> Debug for ViewHandle<T> {
4297    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4298        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
4299            .field("window_id", &self.window_id)
4300            .field("view_id", &self.view_id)
4301            .finish()
4302    }
4303}
4304
4305impl<T> Drop for ViewHandle<T> {
4306    fn drop(&mut self) {
4307        self.ref_counts
4308            .lock()
4309            .dec_view(self.window_id, self.view_id);
4310        #[cfg(any(test, feature = "test-support"))]
4311        self.ref_counts
4312            .lock()
4313            .leak_detector
4314            .lock()
4315            .handle_dropped(self.view_id, self.handle_id);
4316    }
4317}
4318
4319impl<T: View> Handle<T> for ViewHandle<T> {
4320    type Weak = WeakViewHandle<T>;
4321
4322    fn id(&self) -> usize {
4323        self.view_id
4324    }
4325
4326    fn location(&self) -> EntityLocation {
4327        EntityLocation::View(self.window_id, self.view_id)
4328    }
4329
4330    fn downgrade(&self) -> Self::Weak {
4331        self.downgrade()
4332    }
4333
4334    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4335    where
4336        Self: Sized,
4337    {
4338        weak.upgrade(cx)
4339    }
4340}
4341
4342pub struct AnyViewHandle {
4343    window_id: usize,
4344    view_id: usize,
4345    view_type: TypeId,
4346    ref_counts: Arc<Mutex<RefCounts>>,
4347
4348    #[cfg(any(test, feature = "test-support"))]
4349    handle_id: usize,
4350}
4351
4352impl AnyViewHandle {
4353    fn new(
4354        window_id: usize,
4355        view_id: usize,
4356        view_type: TypeId,
4357        ref_counts: Arc<Mutex<RefCounts>>,
4358    ) -> Self {
4359        ref_counts.lock().inc_view(window_id, view_id);
4360
4361        #[cfg(any(test, feature = "test-support"))]
4362        let handle_id = ref_counts
4363            .lock()
4364            .leak_detector
4365            .lock()
4366            .handle_created(None, view_id);
4367
4368        Self {
4369            window_id,
4370            view_id,
4371            view_type,
4372            ref_counts,
4373            #[cfg(any(test, feature = "test-support"))]
4374            handle_id,
4375        }
4376    }
4377
4378    pub fn id(&self) -> usize {
4379        self.view_id
4380    }
4381
4382    pub fn is<T: 'static>(&self) -> bool {
4383        TypeId::of::<T>() == self.view_type
4384    }
4385
4386    pub fn is_focused(&self, cx: &AppContext) -> bool {
4387        cx.focused_view_id(self.window_id)
4388            .map_or(false, |focused_id| focused_id == self.view_id)
4389    }
4390
4391    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4392        if self.is::<T>() {
4393            let result = Some(ViewHandle {
4394                window_id: self.window_id,
4395                view_id: self.view_id,
4396                ref_counts: self.ref_counts.clone(),
4397                view_type: PhantomData,
4398                #[cfg(any(test, feature = "test-support"))]
4399                handle_id: self.handle_id,
4400            });
4401            unsafe {
4402                Arc::decrement_strong_count(&self.ref_counts);
4403            }
4404            std::mem::forget(self);
4405            result
4406        } else {
4407            None
4408        }
4409    }
4410
4411    pub fn downgrade(&self) -> AnyWeakViewHandle {
4412        AnyWeakViewHandle {
4413            window_id: self.window_id,
4414            view_id: self.view_id,
4415            view_type: self.view_type,
4416        }
4417    }
4418
4419    pub fn view_type(&self) -> TypeId {
4420        self.view_type
4421    }
4422
4423    pub fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
4424        cx.views
4425            .get(&(self.window_id, self.view_id))
4426            .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4427    }
4428}
4429
4430impl Clone for AnyViewHandle {
4431    fn clone(&self) -> Self {
4432        Self::new(
4433            self.window_id,
4434            self.view_id,
4435            self.view_type,
4436            self.ref_counts.clone(),
4437        )
4438    }
4439}
4440
4441impl From<&AnyViewHandle> for AnyViewHandle {
4442    fn from(handle: &AnyViewHandle) -> Self {
4443        handle.clone()
4444    }
4445}
4446
4447impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
4448    fn from(handle: &ViewHandle<T>) -> Self {
4449        Self::new(
4450            handle.window_id,
4451            handle.view_id,
4452            TypeId::of::<T>(),
4453            handle.ref_counts.clone(),
4454        )
4455    }
4456}
4457
4458impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
4459    fn from(handle: ViewHandle<T>) -> Self {
4460        let any_handle = AnyViewHandle {
4461            window_id: handle.window_id,
4462            view_id: handle.view_id,
4463            view_type: TypeId::of::<T>(),
4464            ref_counts: handle.ref_counts.clone(),
4465            #[cfg(any(test, feature = "test-support"))]
4466            handle_id: handle.handle_id,
4467        };
4468        unsafe {
4469            Arc::decrement_strong_count(&handle.ref_counts);
4470        }
4471        std::mem::forget(handle);
4472        any_handle
4473    }
4474}
4475
4476impl Drop for AnyViewHandle {
4477    fn drop(&mut self) {
4478        self.ref_counts
4479            .lock()
4480            .dec_view(self.window_id, self.view_id);
4481        #[cfg(any(test, feature = "test-support"))]
4482        self.ref_counts
4483            .lock()
4484            .leak_detector
4485            .lock()
4486            .handle_dropped(self.view_id, self.handle_id);
4487    }
4488}
4489
4490pub struct AnyModelHandle {
4491    model_id: usize,
4492    model_type: TypeId,
4493    ref_counts: Arc<Mutex<RefCounts>>,
4494
4495    #[cfg(any(test, feature = "test-support"))]
4496    handle_id: usize,
4497}
4498
4499impl AnyModelHandle {
4500    fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4501        ref_counts.lock().inc_model(model_id);
4502
4503        #[cfg(any(test, feature = "test-support"))]
4504        let handle_id = ref_counts
4505            .lock()
4506            .leak_detector
4507            .lock()
4508            .handle_created(None, model_id);
4509
4510        Self {
4511            model_id,
4512            model_type,
4513            ref_counts,
4514
4515            #[cfg(any(test, feature = "test-support"))]
4516            handle_id,
4517        }
4518    }
4519
4520    pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4521        if self.is::<T>() {
4522            let result = Some(ModelHandle {
4523                model_id: self.model_id,
4524                model_type: PhantomData,
4525                ref_counts: self.ref_counts.clone(),
4526
4527                #[cfg(any(test, feature = "test-support"))]
4528                handle_id: self.handle_id,
4529            });
4530            unsafe {
4531                Arc::decrement_strong_count(&self.ref_counts);
4532            }
4533            std::mem::forget(self);
4534            result
4535        } else {
4536            None
4537        }
4538    }
4539
4540    pub fn downgrade(&self) -> AnyWeakModelHandle {
4541        AnyWeakModelHandle {
4542            model_id: self.model_id,
4543            model_type: self.model_type,
4544        }
4545    }
4546
4547    pub fn is<T: Entity>(&self) -> bool {
4548        self.model_type == TypeId::of::<T>()
4549    }
4550
4551    pub fn model_type(&self) -> TypeId {
4552        self.model_type
4553    }
4554}
4555
4556impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
4557    fn from(handle: ModelHandle<T>) -> Self {
4558        Self::new(
4559            handle.model_id,
4560            TypeId::of::<T>(),
4561            handle.ref_counts.clone(),
4562        )
4563    }
4564}
4565
4566impl Clone for AnyModelHandle {
4567    fn clone(&self) -> Self {
4568        Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4569    }
4570}
4571
4572impl Drop for AnyModelHandle {
4573    fn drop(&mut self) {
4574        let mut ref_counts = self.ref_counts.lock();
4575        ref_counts.dec_model(self.model_id);
4576
4577        #[cfg(any(test, feature = "test-support"))]
4578        ref_counts
4579            .leak_detector
4580            .lock()
4581            .handle_dropped(self.model_id, self.handle_id);
4582    }
4583}
4584
4585pub struct AnyWeakModelHandle {
4586    model_id: usize,
4587    model_type: TypeId,
4588}
4589
4590impl AnyWeakModelHandle {
4591    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
4592        cx.upgrade_any_model_handle(self)
4593    }
4594}
4595
4596impl<T: Entity> From<WeakModelHandle<T>> for AnyWeakModelHandle {
4597    fn from(handle: WeakModelHandle<T>) -> Self {
4598        AnyWeakModelHandle {
4599            model_id: handle.model_id,
4600            model_type: TypeId::of::<T>(),
4601        }
4602    }
4603}
4604
4605pub struct WeakViewHandle<T> {
4606    window_id: usize,
4607    view_id: usize,
4608    view_type: PhantomData<T>,
4609}
4610
4611impl<T> WeakHandle for WeakViewHandle<T> {
4612    fn id(&self) -> usize {
4613        self.view_id
4614    }
4615}
4616
4617impl<T: View> WeakViewHandle<T> {
4618    fn new(window_id: usize, view_id: usize) -> Self {
4619        Self {
4620            window_id,
4621            view_id,
4622            view_type: PhantomData,
4623        }
4624    }
4625
4626    pub fn id(&self) -> usize {
4627        self.view_id
4628    }
4629
4630    pub fn window_id(&self) -> usize {
4631        self.window_id
4632    }
4633
4634    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
4635        cx.upgrade_view_handle(self)
4636    }
4637}
4638
4639impl<T> Clone for WeakViewHandle<T> {
4640    fn clone(&self) -> Self {
4641        Self {
4642            window_id: self.window_id,
4643            view_id: self.view_id,
4644            view_type: PhantomData,
4645        }
4646    }
4647}
4648
4649impl<T> PartialEq for WeakViewHandle<T> {
4650    fn eq(&self, other: &Self) -> bool {
4651        self.window_id == other.window_id && self.view_id == other.view_id
4652    }
4653}
4654
4655impl<T> Eq for WeakViewHandle<T> {}
4656
4657impl<T> Hash for WeakViewHandle<T> {
4658    fn hash<H: Hasher>(&self, state: &mut H) {
4659        self.window_id.hash(state);
4660        self.view_id.hash(state);
4661    }
4662}
4663
4664pub struct AnyWeakViewHandle {
4665    window_id: usize,
4666    view_id: usize,
4667    view_type: TypeId,
4668}
4669
4670impl AnyWeakViewHandle {
4671    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
4672        cx.upgrade_any_view_handle(self)
4673    }
4674}
4675
4676impl<T: View> From<WeakViewHandle<T>> for AnyWeakViewHandle {
4677    fn from(handle: WeakViewHandle<T>) -> Self {
4678        AnyWeakViewHandle {
4679            window_id: handle.window_id,
4680            view_id: handle.view_id,
4681            view_type: TypeId::of::<T>(),
4682        }
4683    }
4684}
4685
4686#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4687pub struct ElementStateId {
4688    view_id: usize,
4689    element_id: usize,
4690    tag: TypeId,
4691}
4692
4693pub struct ElementStateHandle<T> {
4694    value_type: PhantomData<T>,
4695    id: ElementStateId,
4696    ref_counts: Weak<Mutex<RefCounts>>,
4697}
4698
4699impl<T: 'static> ElementStateHandle<T> {
4700    fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4701        ref_counts.lock().inc_element_state(id, frame_id);
4702        Self {
4703            value_type: PhantomData,
4704            id,
4705            ref_counts: Arc::downgrade(ref_counts),
4706        }
4707    }
4708
4709    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4710        cx.element_states
4711            .get(&self.id)
4712            .unwrap()
4713            .downcast_ref()
4714            .unwrap()
4715    }
4716
4717    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4718    where
4719        C: DerefMut<Target = MutableAppContext>,
4720    {
4721        let mut element_state = cx.deref_mut().cx.element_states.remove(&self.id).unwrap();
4722        let result = f(element_state.downcast_mut().unwrap(), cx);
4723        cx.deref_mut()
4724            .cx
4725            .element_states
4726            .insert(self.id, element_state);
4727        result
4728    }
4729}
4730
4731impl<T> Drop for ElementStateHandle<T> {
4732    fn drop(&mut self) {
4733        if let Some(ref_counts) = self.ref_counts.upgrade() {
4734            ref_counts.lock().dec_element_state(self.id);
4735        }
4736    }
4737}
4738
4739#[must_use]
4740pub enum Subscription {
4741    Subscription {
4742        id: usize,
4743        entity_id: usize,
4744        subscriptions:
4745            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<SubscriptionCallback>>>>>>,
4746    },
4747    GlobalSubscription {
4748        id: usize,
4749        type_id: TypeId,
4750        subscriptions: Option<
4751            Weak<Mutex<HashMap<TypeId, BTreeMap<usize, Option<GlobalSubscriptionCallback>>>>>,
4752        >,
4753    },
4754    Observation {
4755        id: usize,
4756        entity_id: usize,
4757        observations:
4758            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<ObservationCallback>>>>>>,
4759    },
4760    GlobalObservation {
4761        id: usize,
4762        type_id: TypeId,
4763        observations: Option<
4764            Weak<Mutex<HashMap<TypeId, BTreeMap<usize, Option<GlobalObservationCallback>>>>>,
4765        >,
4766    },
4767    FocusObservation {
4768        id: usize,
4769        view_id: usize,
4770        observations:
4771            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<FocusObservationCallback>>>>>>,
4772    },
4773    ReleaseObservation {
4774        id: usize,
4775        entity_id: usize,
4776        observations:
4777            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>>,
4778    },
4779    ActionObservation {
4780        id: usize,
4781        observations: Option<Weak<Mutex<BTreeMap<usize, ActionObservationCallback>>>>,
4782    },
4783}
4784
4785impl Subscription {
4786    pub fn detach(&mut self) {
4787        match self {
4788            Subscription::Subscription { subscriptions, .. } => {
4789                subscriptions.take();
4790            }
4791            Subscription::GlobalSubscription { subscriptions, .. } => {
4792                subscriptions.take();
4793            }
4794            Subscription::Observation { observations, .. } => {
4795                observations.take();
4796            }
4797            Subscription::GlobalObservation { observations, .. } => {
4798                observations.take();
4799            }
4800            Subscription::ReleaseObservation { observations, .. } => {
4801                observations.take();
4802            }
4803            Subscription::FocusObservation { observations, .. } => {
4804                observations.take();
4805            }
4806            Subscription::ActionObservation { observations, .. } => {
4807                observations.take();
4808            }
4809        }
4810    }
4811}
4812
4813impl Drop for Subscription {
4814    fn drop(&mut self) {
4815        match self {
4816            Subscription::Subscription {
4817                id,
4818                entity_id,
4819                subscriptions,
4820            } => {
4821                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
4822                    match subscriptions
4823                        .lock()
4824                        .entry(*entity_id)
4825                        .or_default()
4826                        .entry(*id)
4827                    {
4828                        btree_map::Entry::Vacant(entry) => {
4829                            entry.insert(None);
4830                        }
4831                        btree_map::Entry::Occupied(entry) => {
4832                            entry.remove();
4833                        }
4834                    }
4835                }
4836            }
4837            Subscription::GlobalSubscription {
4838                id,
4839                type_id,
4840                subscriptions,
4841            } => {
4842                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
4843                    match subscriptions.lock().entry(*type_id).or_default().entry(*id) {
4844                        btree_map::Entry::Vacant(entry) => {
4845                            entry.insert(None);
4846                        }
4847                        btree_map::Entry::Occupied(entry) => {
4848                            entry.remove();
4849                        }
4850                    }
4851                }
4852            }
4853            Subscription::Observation {
4854                id,
4855                entity_id,
4856                observations,
4857            } => {
4858                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4859                    match observations
4860                        .lock()
4861                        .entry(*entity_id)
4862                        .or_default()
4863                        .entry(*id)
4864                    {
4865                        btree_map::Entry::Vacant(entry) => {
4866                            entry.insert(None);
4867                        }
4868                        btree_map::Entry::Occupied(entry) => {
4869                            entry.remove();
4870                        }
4871                    }
4872                }
4873            }
4874            Subscription::GlobalObservation {
4875                id,
4876                type_id,
4877                observations,
4878            } => {
4879                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4880                    match observations.lock().entry(*type_id).or_default().entry(*id) {
4881                        collections::btree_map::Entry::Vacant(entry) => {
4882                            entry.insert(None);
4883                        }
4884                        collections::btree_map::Entry::Occupied(entry) => {
4885                            entry.remove();
4886                        }
4887                    }
4888                }
4889            }
4890            Subscription::ReleaseObservation {
4891                id,
4892                entity_id,
4893                observations,
4894            } => {
4895                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4896                    if let Some(observations) = observations.lock().get_mut(entity_id) {
4897                        observations.remove(id);
4898                    }
4899                }
4900            }
4901            Subscription::FocusObservation {
4902                id,
4903                view_id,
4904                observations,
4905            } => {
4906                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4907                    match observations.lock().entry(*view_id).or_default().entry(*id) {
4908                        btree_map::Entry::Vacant(entry) => {
4909                            entry.insert(None);
4910                        }
4911                        btree_map::Entry::Occupied(entry) => {
4912                            entry.remove();
4913                        }
4914                    }
4915                }
4916            }
4917            Subscription::ActionObservation { id, observations } => {
4918                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4919                    observations.lock().remove(&id);
4920                }
4921            }
4922        }
4923    }
4924}
4925
4926lazy_static! {
4927    static ref LEAK_BACKTRACE: bool =
4928        std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty());
4929}
4930
4931#[cfg(any(test, feature = "test-support"))]
4932#[derive(Default)]
4933pub struct LeakDetector {
4934    next_handle_id: usize,
4935    handle_backtraces: HashMap<
4936        usize,
4937        (
4938            Option<&'static str>,
4939            HashMap<usize, Option<backtrace::Backtrace>>,
4940        ),
4941    >,
4942}
4943
4944#[cfg(any(test, feature = "test-support"))]
4945impl LeakDetector {
4946    fn handle_created(&mut self, type_name: Option<&'static str>, entity_id: usize) -> usize {
4947        let handle_id = post_inc(&mut self.next_handle_id);
4948        let entry = self.handle_backtraces.entry(entity_id).or_default();
4949        let backtrace = if *LEAK_BACKTRACE {
4950            Some(backtrace::Backtrace::new_unresolved())
4951        } else {
4952            None
4953        };
4954        if let Some(type_name) = type_name {
4955            entry.0.get_or_insert(type_name);
4956        }
4957        entry.1.insert(handle_id, backtrace);
4958        handle_id
4959    }
4960
4961    fn handle_dropped(&mut self, entity_id: usize, handle_id: usize) {
4962        if let Some((_, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
4963            assert!(backtraces.remove(&handle_id).is_some());
4964            if backtraces.is_empty() {
4965                self.handle_backtraces.remove(&entity_id);
4966            }
4967        }
4968    }
4969
4970    pub fn assert_dropped(&mut self, entity_id: usize) {
4971        if let Some((type_name, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
4972            for trace in backtraces.values_mut() {
4973                if let Some(trace) = trace {
4974                    trace.resolve();
4975                    eprintln!("{:?}", crate::util::CwdBacktrace(trace));
4976                }
4977            }
4978
4979            let hint = if *LEAK_BACKTRACE {
4980                ""
4981            } else {
4982                " – set LEAK_BACKTRACE=1 for more information"
4983            };
4984
4985            panic!(
4986                "{} handles to {} {} still exist{}",
4987                backtraces.len(),
4988                type_name.unwrap_or("entity"),
4989                entity_id,
4990                hint
4991            );
4992        }
4993    }
4994
4995    pub fn detect(&mut self) {
4996        let mut found_leaks = false;
4997        for (id, (type_name, backtraces)) in self.handle_backtraces.iter_mut() {
4998            eprintln!(
4999                "leaked {} handles to {} {}",
5000                backtraces.len(),
5001                type_name.unwrap_or("entity"),
5002                id
5003            );
5004            for trace in backtraces.values_mut() {
5005                if let Some(trace) = trace {
5006                    trace.resolve();
5007                    eprintln!("{:?}", crate::util::CwdBacktrace(trace));
5008                }
5009            }
5010            found_leaks = true;
5011        }
5012
5013        let hint = if *LEAK_BACKTRACE {
5014            ""
5015        } else {
5016            " – set LEAK_BACKTRACE=1 for more information"
5017        };
5018        assert!(!found_leaks, "detected leaked handles{}", hint);
5019    }
5020}
5021
5022#[derive(Default)]
5023struct RefCounts {
5024    entity_counts: HashMap<usize, usize>,
5025    element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
5026    dropped_models: HashSet<usize>,
5027    dropped_views: HashSet<(usize, usize)>,
5028    dropped_element_states: HashSet<ElementStateId>,
5029
5030    #[cfg(any(test, feature = "test-support"))]
5031    leak_detector: Arc<Mutex<LeakDetector>>,
5032}
5033
5034struct ElementStateRefCount {
5035    ref_count: usize,
5036    frame_id: usize,
5037}
5038
5039impl RefCounts {
5040    fn inc_model(&mut self, model_id: usize) {
5041        match self.entity_counts.entry(model_id) {
5042            Entry::Occupied(mut entry) => {
5043                *entry.get_mut() += 1;
5044            }
5045            Entry::Vacant(entry) => {
5046                entry.insert(1);
5047                self.dropped_models.remove(&model_id);
5048            }
5049        }
5050    }
5051
5052    fn inc_view(&mut self, window_id: usize, view_id: usize) {
5053        match self.entity_counts.entry(view_id) {
5054            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
5055            Entry::Vacant(entry) => {
5056                entry.insert(1);
5057                self.dropped_views.remove(&(window_id, view_id));
5058            }
5059        }
5060    }
5061
5062    fn inc_element_state(&mut self, id: ElementStateId, frame_id: usize) {
5063        match self.element_state_counts.entry(id) {
5064            Entry::Occupied(mut entry) => {
5065                let entry = entry.get_mut();
5066                if entry.frame_id == frame_id || entry.ref_count >= 2 {
5067                    panic!("used the same element state more than once in the same frame");
5068                }
5069                entry.ref_count += 1;
5070                entry.frame_id = frame_id;
5071            }
5072            Entry::Vacant(entry) => {
5073                entry.insert(ElementStateRefCount {
5074                    ref_count: 1,
5075                    frame_id,
5076                });
5077                self.dropped_element_states.remove(&id);
5078            }
5079        }
5080    }
5081
5082    fn dec_model(&mut self, model_id: usize) {
5083        let count = self.entity_counts.get_mut(&model_id).unwrap();
5084        *count -= 1;
5085        if *count == 0 {
5086            self.entity_counts.remove(&model_id);
5087            self.dropped_models.insert(model_id);
5088        }
5089    }
5090
5091    fn dec_view(&mut self, window_id: usize, view_id: usize) {
5092        let count = self.entity_counts.get_mut(&view_id).unwrap();
5093        *count -= 1;
5094        if *count == 0 {
5095            self.entity_counts.remove(&view_id);
5096            self.dropped_views.insert((window_id, view_id));
5097        }
5098    }
5099
5100    fn dec_element_state(&mut self, id: ElementStateId) {
5101        let entry = self.element_state_counts.get_mut(&id).unwrap();
5102        entry.ref_count -= 1;
5103        if entry.ref_count == 0 {
5104            self.element_state_counts.remove(&id);
5105            self.dropped_element_states.insert(id);
5106        }
5107    }
5108
5109    fn is_entity_alive(&self, entity_id: usize) -> bool {
5110        self.entity_counts.contains_key(&entity_id)
5111    }
5112
5113    fn take_dropped(
5114        &mut self,
5115    ) -> (
5116        HashSet<usize>,
5117        HashSet<(usize, usize)>,
5118        HashSet<ElementStateId>,
5119    ) {
5120        (
5121            std::mem::take(&mut self.dropped_models),
5122            std::mem::take(&mut self.dropped_views),
5123            std::mem::take(&mut self.dropped_element_states),
5124        )
5125    }
5126}
5127
5128#[cfg(test)]
5129mod tests {
5130    use super::*;
5131    use crate::{actions, elements::*, impl_actions};
5132    use serde::Deserialize;
5133    use smol::future::poll_once;
5134    use std::{
5135        cell::Cell,
5136        sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
5137    };
5138
5139    #[crate::test(self)]
5140    fn test_model_handles(cx: &mut MutableAppContext) {
5141        struct Model {
5142            other: Option<ModelHandle<Model>>,
5143            events: Vec<String>,
5144        }
5145
5146        impl Entity for Model {
5147            type Event = usize;
5148        }
5149
5150        impl Model {
5151            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
5152                if let Some(other) = other.as_ref() {
5153                    cx.observe(other, |me, _, _| {
5154                        me.events.push("notified".into());
5155                    })
5156                    .detach();
5157                    cx.subscribe(other, |me, _, event, _| {
5158                        me.events.push(format!("observed event {}", event));
5159                    })
5160                    .detach();
5161                }
5162
5163                Self {
5164                    other,
5165                    events: Vec::new(),
5166                }
5167            }
5168        }
5169
5170        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
5171        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
5172        assert_eq!(cx.cx.models.len(), 2);
5173
5174        handle_1.update(cx, |model, cx| {
5175            model.events.push("updated".into());
5176            cx.emit(1);
5177            cx.notify();
5178            cx.emit(2);
5179        });
5180        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5181        assert_eq!(
5182            handle_2.read(cx).events,
5183            vec![
5184                "observed event 1".to_string(),
5185                "notified".to_string(),
5186                "observed event 2".to_string(),
5187            ]
5188        );
5189
5190        handle_2.update(cx, |model, _| {
5191            drop(handle_1);
5192            model.other.take();
5193        });
5194
5195        assert_eq!(cx.cx.models.len(), 1);
5196        assert!(cx.subscriptions.lock().is_empty());
5197        assert!(cx.observations.lock().is_empty());
5198    }
5199
5200    #[crate::test(self)]
5201    fn test_model_events(cx: &mut MutableAppContext) {
5202        #[derive(Default)]
5203        struct Model {
5204            events: Vec<usize>,
5205        }
5206
5207        impl Entity for Model {
5208            type Event = usize;
5209        }
5210
5211        let handle_1 = cx.add_model(|_| Model::default());
5212        let handle_2 = cx.add_model(|_| Model::default());
5213
5214        handle_1.update(cx, |_, cx| {
5215            cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
5216                model.events.push(*event);
5217
5218                cx.subscribe(&emitter, |model, _, event, _| {
5219                    model.events.push(*event * 2);
5220                })
5221                .detach();
5222            })
5223            .detach();
5224        });
5225
5226        handle_2.update(cx, |_, c| c.emit(7));
5227        assert_eq!(handle_1.read(cx).events, vec![7]);
5228
5229        handle_2.update(cx, |_, c| c.emit(5));
5230        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5231    }
5232
5233    #[crate::test(self)]
5234    fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5235        #[derive(Default)]
5236        struct Model;
5237
5238        impl Entity for Model {
5239            type Event = ();
5240        }
5241
5242        let events = Rc::new(RefCell::new(Vec::new()));
5243        cx.add_model(|cx| {
5244            drop(cx.subscribe(&cx.handle(), {
5245                let events = events.clone();
5246                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5247            }));
5248            cx.subscribe(&cx.handle(), {
5249                let events = events.clone();
5250                move |_, _, _, _| events.borrow_mut().push("before emit")
5251            })
5252            .detach();
5253            cx.emit(());
5254            cx.subscribe(&cx.handle(), {
5255                let events = events.clone();
5256                move |_, _, _, _| events.borrow_mut().push("after emit")
5257            })
5258            .detach();
5259            Model
5260        });
5261        assert_eq!(*events.borrow(), ["before emit"]);
5262    }
5263
5264    #[crate::test(self)]
5265    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
5266        #[derive(Default)]
5267        struct Model {
5268            count: usize,
5269            events: Vec<usize>,
5270        }
5271
5272        impl Entity for Model {
5273            type Event = ();
5274        }
5275
5276        let handle_1 = cx.add_model(|_| Model::default());
5277        let handle_2 = cx.add_model(|_| Model::default());
5278
5279        handle_1.update(cx, |_, c| {
5280            c.observe(&handle_2, move |model, observed, c| {
5281                model.events.push(observed.read(c).count);
5282                c.observe(&observed, |model, observed, c| {
5283                    model.events.push(observed.read(c).count * 2);
5284                })
5285                .detach();
5286            })
5287            .detach();
5288        });
5289
5290        handle_2.update(cx, |model, c| {
5291            model.count = 7;
5292            c.notify()
5293        });
5294        assert_eq!(handle_1.read(cx).events, vec![7]);
5295
5296        handle_2.update(cx, |model, c| {
5297            model.count = 5;
5298            c.notify()
5299        });
5300        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
5301    }
5302
5303    #[crate::test(self)]
5304    fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
5305        #[derive(Default)]
5306        struct Model;
5307
5308        impl Entity for Model {
5309            type Event = ();
5310        }
5311
5312        let events = Rc::new(RefCell::new(Vec::new()));
5313        cx.add_model(|cx| {
5314            drop(cx.observe(&cx.handle(), {
5315                let events = events.clone();
5316                move |_, _, _| events.borrow_mut().push("dropped before flush")
5317            }));
5318            cx.observe(&cx.handle(), {
5319                let events = events.clone();
5320                move |_, _, _| events.borrow_mut().push("before notify")
5321            })
5322            .detach();
5323            cx.notify();
5324            cx.observe(&cx.handle(), {
5325                let events = events.clone();
5326                move |_, _, _| events.borrow_mut().push("after notify")
5327            })
5328            .detach();
5329            Model
5330        });
5331        assert_eq!(*events.borrow(), ["before notify"]);
5332    }
5333
5334    #[crate::test(self)]
5335    fn test_defer_and_after_window_update(cx: &mut MutableAppContext) {
5336        struct View {
5337            render_count: usize,
5338        }
5339
5340        impl Entity for View {
5341            type Event = usize;
5342        }
5343
5344        impl super::View for View {
5345            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5346                post_inc(&mut self.render_count);
5347                Empty::new().boxed()
5348            }
5349
5350            fn ui_name() -> &'static str {
5351                "View"
5352            }
5353        }
5354
5355        let (_, view) = cx.add_window(Default::default(), |_| View { render_count: 0 });
5356        let called_defer = Rc::new(AtomicBool::new(false));
5357        let called_after_window_update = Rc::new(AtomicBool::new(false));
5358
5359        view.update(cx, |this, cx| {
5360            assert_eq!(this.render_count, 1);
5361            cx.defer({
5362                let called_defer = called_defer.clone();
5363                move |this, _| {
5364                    assert_eq!(this.render_count, 1);
5365                    called_defer.store(true, SeqCst);
5366                }
5367            });
5368            cx.after_window_update({
5369                let called_after_window_update = called_after_window_update.clone();
5370                move |this, cx| {
5371                    assert_eq!(this.render_count, 2);
5372                    called_after_window_update.store(true, SeqCst);
5373                    cx.notify();
5374                }
5375            });
5376            assert!(!called_defer.load(SeqCst));
5377            assert!(!called_after_window_update.load(SeqCst));
5378            cx.notify();
5379        });
5380
5381        assert!(called_defer.load(SeqCst));
5382        assert!(called_after_window_update.load(SeqCst));
5383        assert_eq!(view.read(cx).render_count, 3);
5384    }
5385
5386    #[crate::test(self)]
5387    fn test_view_handles(cx: &mut MutableAppContext) {
5388        struct View {
5389            other: Option<ViewHandle<View>>,
5390            events: Vec<String>,
5391        }
5392
5393        impl Entity for View {
5394            type Event = usize;
5395        }
5396
5397        impl super::View for View {
5398            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5399                Empty::new().boxed()
5400            }
5401
5402            fn ui_name() -> &'static str {
5403                "View"
5404            }
5405        }
5406
5407        impl View {
5408            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
5409                if let Some(other) = other.as_ref() {
5410                    cx.subscribe(other, |me, _, event, _| {
5411                        me.events.push(format!("observed event {}", event));
5412                    })
5413                    .detach();
5414                }
5415                Self {
5416                    other,
5417                    events: Vec::new(),
5418                }
5419            }
5420        }
5421
5422        let (window_id, _) = cx.add_window(Default::default(), |cx| View::new(None, cx));
5423        let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
5424        let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
5425        assert_eq!(cx.cx.views.len(), 3);
5426
5427        handle_1.update(cx, |view, cx| {
5428            view.events.push("updated".into());
5429            cx.emit(1);
5430            cx.emit(2);
5431        });
5432        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5433        assert_eq!(
5434            handle_2.read(cx).events,
5435            vec![
5436                "observed event 1".to_string(),
5437                "observed event 2".to_string(),
5438            ]
5439        );
5440
5441        handle_2.update(cx, |view, _| {
5442            drop(handle_1);
5443            view.other.take();
5444        });
5445
5446        assert_eq!(cx.cx.views.len(), 2);
5447        assert!(cx.subscriptions.lock().is_empty());
5448        assert!(cx.observations.lock().is_empty());
5449    }
5450
5451    #[crate::test(self)]
5452    fn test_add_window(cx: &mut MutableAppContext) {
5453        struct View {
5454            mouse_down_count: Arc<AtomicUsize>,
5455        }
5456
5457        impl Entity for View {
5458            type Event = ();
5459        }
5460
5461        impl super::View for View {
5462            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5463                let mouse_down_count = self.mouse_down_count.clone();
5464                EventHandler::new(Empty::new().boxed())
5465                    .on_mouse_down(move |_| {
5466                        mouse_down_count.fetch_add(1, SeqCst);
5467                        true
5468                    })
5469                    .boxed()
5470            }
5471
5472            fn ui_name() -> &'static str {
5473                "View"
5474            }
5475        }
5476
5477        let mouse_down_count = Arc::new(AtomicUsize::new(0));
5478        let (window_id, _) = cx.add_window(Default::default(), |_| View {
5479            mouse_down_count: mouse_down_count.clone(),
5480        });
5481        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
5482        // Ensure window's root element is in a valid lifecycle state.
5483        presenter.borrow_mut().dispatch_event(
5484            Event::LeftMouseDown {
5485                position: Default::default(),
5486                ctrl: false,
5487                alt: false,
5488                shift: false,
5489                cmd: false,
5490                click_count: 1,
5491            },
5492            cx,
5493        );
5494        assert_eq!(mouse_down_count.load(SeqCst), 1);
5495    }
5496
5497    #[crate::test(self)]
5498    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
5499        struct Model {
5500            released: Rc<Cell<bool>>,
5501        }
5502
5503        struct View {
5504            released: Rc<Cell<bool>>,
5505        }
5506
5507        impl Entity for Model {
5508            type Event = ();
5509
5510            fn release(&mut self, _: &mut MutableAppContext) {
5511                self.released.set(true);
5512            }
5513        }
5514
5515        impl Entity for View {
5516            type Event = ();
5517
5518            fn release(&mut self, _: &mut MutableAppContext) {
5519                self.released.set(true);
5520            }
5521        }
5522
5523        impl super::View for View {
5524            fn ui_name() -> &'static str {
5525                "View"
5526            }
5527
5528            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5529                Empty::new().boxed()
5530            }
5531        }
5532
5533        let model_released = Rc::new(Cell::new(false));
5534        let model_release_observed = Rc::new(Cell::new(false));
5535        let view_released = Rc::new(Cell::new(false));
5536        let view_release_observed = Rc::new(Cell::new(false));
5537
5538        let model = cx.add_model(|_| Model {
5539            released: model_released.clone(),
5540        });
5541        let (window_id, view) = cx.add_window(Default::default(), |_| View {
5542            released: view_released.clone(),
5543        });
5544        assert!(!model_released.get());
5545        assert!(!view_released.get());
5546
5547        cx.observe_release(&model, {
5548            let model_release_observed = model_release_observed.clone();
5549            move |_, _| model_release_observed.set(true)
5550        })
5551        .detach();
5552        cx.observe_release(&view, {
5553            let view_release_observed = view_release_observed.clone();
5554            move |_, _| view_release_observed.set(true)
5555        })
5556        .detach();
5557
5558        cx.update(move |_| {
5559            drop(model);
5560        });
5561        assert!(model_released.get());
5562        assert!(model_release_observed.get());
5563
5564        drop(view);
5565        cx.remove_window(window_id);
5566        assert!(view_released.get());
5567        assert!(view_release_observed.get());
5568    }
5569
5570    #[crate::test(self)]
5571    fn test_view_events(cx: &mut MutableAppContext) {
5572        #[derive(Default)]
5573        struct View {
5574            events: Vec<usize>,
5575        }
5576
5577        impl Entity for View {
5578            type Event = usize;
5579        }
5580
5581        impl super::View for View {
5582            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5583                Empty::new().boxed()
5584            }
5585
5586            fn ui_name() -> &'static str {
5587                "View"
5588            }
5589        }
5590
5591        struct Model;
5592
5593        impl Entity for Model {
5594            type Event = usize;
5595        }
5596
5597        let (window_id, handle_1) = cx.add_window(Default::default(), |_| View::default());
5598        let handle_2 = cx.add_view(window_id, |_| View::default());
5599        let handle_3 = cx.add_model(|_| Model);
5600
5601        handle_1.update(cx, |_, cx| {
5602            cx.subscribe(&handle_2, move |me, emitter, event, cx| {
5603                me.events.push(*event);
5604
5605                cx.subscribe(&emitter, |me, _, event, _| {
5606                    me.events.push(*event * 2);
5607                })
5608                .detach();
5609            })
5610            .detach();
5611
5612            cx.subscribe(&handle_3, |me, _, event, _| {
5613                me.events.push(*event);
5614            })
5615            .detach();
5616        });
5617
5618        handle_2.update(cx, |_, c| c.emit(7));
5619        assert_eq!(handle_1.read(cx).events, vec![7]);
5620
5621        handle_2.update(cx, |_, c| c.emit(5));
5622        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5623
5624        handle_3.update(cx, |_, c| c.emit(9));
5625        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
5626    }
5627
5628    #[crate::test(self)]
5629    fn test_global_events(cx: &mut MutableAppContext) {
5630        #[derive(Clone, Debug, Eq, PartialEq)]
5631        struct GlobalEvent(u64);
5632
5633        let events = Rc::new(RefCell::new(Vec::new()));
5634        let first_subscription;
5635        let second_subscription;
5636
5637        {
5638            let events = events.clone();
5639            first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5640                events.borrow_mut().push(("First", e.clone()));
5641            });
5642        }
5643
5644        {
5645            let events = events.clone();
5646            second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5647                events.borrow_mut().push(("Second", e.clone()));
5648            });
5649        }
5650
5651        cx.update(|cx| {
5652            cx.emit_global(GlobalEvent(1));
5653            cx.emit_global(GlobalEvent(2));
5654        });
5655
5656        drop(first_subscription);
5657
5658        cx.update(|cx| {
5659            cx.emit_global(GlobalEvent(3));
5660        });
5661
5662        drop(second_subscription);
5663
5664        cx.update(|cx| {
5665            cx.emit_global(GlobalEvent(4));
5666        });
5667
5668        assert_eq!(
5669            &*events.borrow(),
5670            &[
5671                ("First", GlobalEvent(1)),
5672                ("Second", GlobalEvent(1)),
5673                ("First", GlobalEvent(2)),
5674                ("Second", GlobalEvent(2)),
5675                ("Second", GlobalEvent(3)),
5676            ]
5677        );
5678    }
5679
5680    #[crate::test(self)]
5681    fn test_global_events_emitted_before_subscription_in_same_update_cycle(
5682        cx: &mut MutableAppContext,
5683    ) {
5684        let events = Rc::new(RefCell::new(Vec::new()));
5685        cx.update(|cx| {
5686            {
5687                let events = events.clone();
5688                drop(cx.subscribe_global(move |_: &(), _| {
5689                    events.borrow_mut().push("dropped before emit");
5690                }));
5691            }
5692
5693            {
5694                let events = events.clone();
5695                cx.subscribe_global(move |_: &(), _| {
5696                    events.borrow_mut().push("before emit");
5697                })
5698                .detach();
5699            }
5700
5701            cx.emit_global(());
5702
5703            {
5704                let events = events.clone();
5705                cx.subscribe_global(move |_: &(), _| {
5706                    events.borrow_mut().push("after emit");
5707                })
5708                .detach();
5709            }
5710        });
5711
5712        assert_eq!(*events.borrow(), ["before emit"]);
5713    }
5714
5715    #[crate::test(self)]
5716    fn test_global_nested_events(cx: &mut MutableAppContext) {
5717        #[derive(Clone, Debug, Eq, PartialEq)]
5718        struct GlobalEvent(u64);
5719
5720        let events = Rc::new(RefCell::new(Vec::new()));
5721
5722        {
5723            let events = events.clone();
5724            cx.subscribe_global(move |e: &GlobalEvent, cx| {
5725                events.borrow_mut().push(("Outer", e.clone()));
5726
5727                if e.0 == 1 {
5728                    let events = events.clone();
5729                    cx.subscribe_global(move |e: &GlobalEvent, _| {
5730                        events.borrow_mut().push(("Inner", e.clone()));
5731                    })
5732                    .detach();
5733                }
5734            })
5735            .detach();
5736        }
5737
5738        cx.update(|cx| {
5739            cx.emit_global(GlobalEvent(1));
5740            cx.emit_global(GlobalEvent(2));
5741            cx.emit_global(GlobalEvent(3));
5742        });
5743        cx.update(|cx| {
5744            cx.emit_global(GlobalEvent(4));
5745        });
5746
5747        assert_eq!(
5748            &*events.borrow(),
5749            &[
5750                ("Outer", GlobalEvent(1)),
5751                ("Outer", GlobalEvent(2)),
5752                ("Outer", GlobalEvent(3)),
5753                ("Outer", GlobalEvent(4)),
5754                ("Inner", GlobalEvent(4)),
5755            ]
5756        );
5757    }
5758
5759    #[crate::test(self)]
5760    fn test_global(cx: &mut MutableAppContext) {
5761        type Global = usize;
5762
5763        let observation_count = Rc::new(RefCell::new(0));
5764        let subscription = cx.observe_global::<Global, _>({
5765            let observation_count = observation_count.clone();
5766            move |_| {
5767                *observation_count.borrow_mut() += 1;
5768            }
5769        });
5770
5771        assert!(!cx.has_global::<Global>());
5772        assert_eq!(cx.default_global::<Global>(), &0);
5773        assert_eq!(*observation_count.borrow(), 1);
5774        assert!(cx.has_global::<Global>());
5775        assert_eq!(
5776            cx.update_global::<Global, _, _>(|global, _| {
5777                *global = 1;
5778                "Update Result"
5779            }),
5780            "Update Result"
5781        );
5782        assert_eq!(*observation_count.borrow(), 2);
5783        assert_eq!(cx.global::<Global>(), &1);
5784
5785        drop(subscription);
5786        cx.update_global::<Global, _, _>(|global, _| {
5787            *global = 2;
5788        });
5789        assert_eq!(*observation_count.borrow(), 2);
5790
5791        type OtherGlobal = f32;
5792
5793        let observation_count = Rc::new(RefCell::new(0));
5794        cx.observe_global::<OtherGlobal, _>({
5795            let observation_count = observation_count.clone();
5796            move |_| {
5797                *observation_count.borrow_mut() += 1;
5798            }
5799        })
5800        .detach();
5801
5802        assert_eq!(
5803            cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5804                assert_eq!(global, &0.0);
5805                *global = 2.0;
5806                "Default update result"
5807            }),
5808            "Default update result"
5809        );
5810        assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5811        assert_eq!(*observation_count.borrow(), 1);
5812    }
5813
5814    #[crate::test(self)]
5815    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
5816        struct View;
5817
5818        impl Entity for View {
5819            type Event = ();
5820        }
5821
5822        impl super::View for View {
5823            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5824                Empty::new().boxed()
5825            }
5826
5827            fn ui_name() -> &'static str {
5828                "View"
5829            }
5830        }
5831
5832        struct Model;
5833
5834        impl Entity for Model {
5835            type Event = ();
5836        }
5837
5838        let (window_id, _) = cx.add_window(Default::default(), |_| View);
5839        let observing_view = cx.add_view(window_id, |_| View);
5840        let emitting_view = cx.add_view(window_id, |_| View);
5841        let observing_model = cx.add_model(|_| Model);
5842        let observed_model = cx.add_model(|_| Model);
5843
5844        observing_view.update(cx, |_, cx| {
5845            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5846            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5847        });
5848        observing_model.update(cx, |_, cx| {
5849            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5850        });
5851
5852        cx.update(|_| {
5853            drop(observing_view);
5854            drop(observing_model);
5855        });
5856
5857        emitting_view.update(cx, |_, cx| cx.emit(()));
5858        observed_model.update(cx, |_, cx| cx.emit(()));
5859    }
5860
5861    #[crate::test(self)]
5862    fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5863        #[derive(Default)]
5864        struct TestView;
5865
5866        impl Entity for TestView {
5867            type Event = ();
5868        }
5869
5870        impl View for TestView {
5871            fn ui_name() -> &'static str {
5872                "TestView"
5873            }
5874
5875            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5876                Empty::new().boxed()
5877            }
5878        }
5879
5880        let events = Rc::new(RefCell::new(Vec::new()));
5881        cx.add_window(Default::default(), |cx| {
5882            drop(cx.subscribe(&cx.handle(), {
5883                let events = events.clone();
5884                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5885            }));
5886            cx.subscribe(&cx.handle(), {
5887                let events = events.clone();
5888                move |_, _, _, _| events.borrow_mut().push("before emit")
5889            })
5890            .detach();
5891            cx.emit(());
5892            cx.subscribe(&cx.handle(), {
5893                let events = events.clone();
5894                move |_, _, _, _| events.borrow_mut().push("after emit")
5895            })
5896            .detach();
5897            TestView
5898        });
5899        assert_eq!(*events.borrow(), ["before emit"]);
5900    }
5901
5902    #[crate::test(self)]
5903    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
5904        #[derive(Default)]
5905        struct View {
5906            events: Vec<usize>,
5907        }
5908
5909        impl Entity for View {
5910            type Event = usize;
5911        }
5912
5913        impl super::View for View {
5914            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5915                Empty::new().boxed()
5916            }
5917
5918            fn ui_name() -> &'static str {
5919                "View"
5920            }
5921        }
5922
5923        #[derive(Default)]
5924        struct Model {
5925            count: usize,
5926        }
5927
5928        impl Entity for Model {
5929            type Event = ();
5930        }
5931
5932        let (_, view) = cx.add_window(Default::default(), |_| View::default());
5933        let model = cx.add_model(|_| Model::default());
5934
5935        view.update(cx, |_, c| {
5936            c.observe(&model, |me, observed, c| {
5937                me.events.push(observed.read(c).count)
5938            })
5939            .detach();
5940        });
5941
5942        model.update(cx, |model, c| {
5943            model.count = 11;
5944            c.notify();
5945        });
5946        assert_eq!(view.read(cx).events, vec![11]);
5947    }
5948
5949    #[crate::test(self)]
5950    fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
5951        #[derive(Default)]
5952        struct TestView;
5953
5954        impl Entity for TestView {
5955            type Event = ();
5956        }
5957
5958        impl View for TestView {
5959            fn ui_name() -> &'static str {
5960                "TestView"
5961            }
5962
5963            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5964                Empty::new().boxed()
5965            }
5966        }
5967
5968        let events = Rc::new(RefCell::new(Vec::new()));
5969        cx.add_window(Default::default(), |cx| {
5970            drop(cx.observe(&cx.handle(), {
5971                let events = events.clone();
5972                move |_, _, _| events.borrow_mut().push("dropped before flush")
5973            }));
5974            cx.observe(&cx.handle(), {
5975                let events = events.clone();
5976                move |_, _, _| events.borrow_mut().push("before notify")
5977            })
5978            .detach();
5979            cx.notify();
5980            cx.observe(&cx.handle(), {
5981                let events = events.clone();
5982                move |_, _, _| events.borrow_mut().push("after notify")
5983            })
5984            .detach();
5985            TestView
5986        });
5987        assert_eq!(*events.borrow(), ["before notify"]);
5988    }
5989
5990    #[crate::test(self)]
5991    fn test_dropping_observers(cx: &mut MutableAppContext) {
5992        struct View;
5993
5994        impl Entity for View {
5995            type Event = ();
5996        }
5997
5998        impl super::View for View {
5999            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6000                Empty::new().boxed()
6001            }
6002
6003            fn ui_name() -> &'static str {
6004                "View"
6005            }
6006        }
6007
6008        struct Model;
6009
6010        impl Entity for Model {
6011            type Event = ();
6012        }
6013
6014        let (window_id, _) = cx.add_window(Default::default(), |_| View);
6015        let observing_view = cx.add_view(window_id, |_| View);
6016        let observing_model = cx.add_model(|_| Model);
6017        let observed_model = cx.add_model(|_| Model);
6018
6019        observing_view.update(cx, |_, cx| {
6020            cx.observe(&observed_model, |_, _, _| {}).detach();
6021        });
6022        observing_model.update(cx, |_, cx| {
6023            cx.observe(&observed_model, |_, _, _| {}).detach();
6024        });
6025
6026        cx.update(|_| {
6027            drop(observing_view);
6028            drop(observing_model);
6029        });
6030
6031        observed_model.update(cx, |_, cx| cx.notify());
6032    }
6033
6034    #[crate::test(self)]
6035    fn test_dropping_subscriptions_during_callback(cx: &mut MutableAppContext) {
6036        struct Model;
6037
6038        impl Entity for Model {
6039            type Event = u64;
6040        }
6041
6042        // Events
6043        let observing_model = cx.add_model(|_| Model);
6044        let observed_model = cx.add_model(|_| Model);
6045
6046        let events = Rc::new(RefCell::new(Vec::new()));
6047
6048        observing_model.update(cx, |_, cx| {
6049            let events = events.clone();
6050            let subscription = Rc::new(RefCell::new(None));
6051            *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
6052                let subscription = subscription.clone();
6053                move |_, _, e, _| {
6054                    subscription.borrow_mut().take();
6055                    events.borrow_mut().push(e.clone());
6056                }
6057            }));
6058        });
6059
6060        observed_model.update(cx, |_, cx| {
6061            cx.emit(1);
6062            cx.emit(2);
6063        });
6064
6065        assert_eq!(*events.borrow(), [1]);
6066
6067        // Global Events
6068        #[derive(Clone, Debug, Eq, PartialEq)]
6069        struct GlobalEvent(u64);
6070
6071        let events = Rc::new(RefCell::new(Vec::new()));
6072
6073        {
6074            let events = events.clone();
6075            let subscription = Rc::new(RefCell::new(None));
6076            *subscription.borrow_mut() = Some(cx.subscribe_global({
6077                let subscription = subscription.clone();
6078                move |e: &GlobalEvent, _| {
6079                    subscription.borrow_mut().take();
6080                    events.borrow_mut().push(e.clone());
6081                }
6082            }));
6083        }
6084
6085        cx.update(|cx| {
6086            cx.emit_global(GlobalEvent(1));
6087            cx.emit_global(GlobalEvent(2));
6088        });
6089
6090        assert_eq!(*events.borrow(), [GlobalEvent(1)]);
6091
6092        // Model Observation
6093        let observing_model = cx.add_model(|_| Model);
6094        let observed_model = cx.add_model(|_| Model);
6095
6096        let observation_count = Rc::new(RefCell::new(0));
6097
6098        observing_model.update(cx, |_, cx| {
6099            let observation_count = observation_count.clone();
6100            let subscription = Rc::new(RefCell::new(None));
6101            *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
6102                let subscription = subscription.clone();
6103                move |_, _, _| {
6104                    subscription.borrow_mut().take();
6105                    *observation_count.borrow_mut() += 1;
6106                }
6107            }));
6108        });
6109
6110        observed_model.update(cx, |_, cx| {
6111            cx.notify();
6112        });
6113
6114        observed_model.update(cx, |_, cx| {
6115            cx.notify();
6116        });
6117
6118        assert_eq!(*observation_count.borrow(), 1);
6119
6120        // View Observation
6121        struct View;
6122
6123        impl Entity for View {
6124            type Event = ();
6125        }
6126
6127        impl super::View for View {
6128            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6129                Empty::new().boxed()
6130            }
6131
6132            fn ui_name() -> &'static str {
6133                "View"
6134            }
6135        }
6136
6137        let (window_id, _) = cx.add_window(Default::default(), |_| View);
6138        let observing_view = cx.add_view(window_id, |_| View);
6139        let observed_view = cx.add_view(window_id, |_| View);
6140
6141        let observation_count = Rc::new(RefCell::new(0));
6142        observing_view.update(cx, |_, cx| {
6143            let observation_count = observation_count.clone();
6144            let subscription = Rc::new(RefCell::new(None));
6145            *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
6146                let subscription = subscription.clone();
6147                move |_, _, _| {
6148                    subscription.borrow_mut().take();
6149                    *observation_count.borrow_mut() += 1;
6150                }
6151            }));
6152        });
6153
6154        observed_view.update(cx, |_, cx| {
6155            cx.notify();
6156        });
6157
6158        observed_view.update(cx, |_, cx| {
6159            cx.notify();
6160        });
6161
6162        assert_eq!(*observation_count.borrow(), 1);
6163
6164        // Global Observation
6165        let observation_count = Rc::new(RefCell::new(0));
6166        let subscription = Rc::new(RefCell::new(None));
6167        *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
6168            let observation_count = observation_count.clone();
6169            let subscription = subscription.clone();
6170            move |_| {
6171                subscription.borrow_mut().take();
6172                *observation_count.borrow_mut() += 1;
6173            }
6174        }));
6175
6176        cx.default_global::<()>();
6177        cx.set_global(());
6178        assert_eq!(*observation_count.borrow(), 1);
6179    }
6180
6181    #[crate::test(self)]
6182    fn test_focus(cx: &mut MutableAppContext) {
6183        struct View {
6184            name: String,
6185            events: Arc<Mutex<Vec<String>>>,
6186        }
6187
6188        impl Entity for View {
6189            type Event = ();
6190        }
6191
6192        impl super::View for View {
6193            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6194                Empty::new().boxed()
6195            }
6196
6197            fn ui_name() -> &'static str {
6198                "View"
6199            }
6200
6201            fn on_focus(&mut self, _: &mut ViewContext<Self>) {
6202                self.events.lock().push(format!("{} focused", &self.name));
6203            }
6204
6205            fn on_blur(&mut self, _: &mut ViewContext<Self>) {
6206                self.events.lock().push(format!("{} blurred", &self.name));
6207            }
6208        }
6209
6210        let view_events: Arc<Mutex<Vec<String>>> = Default::default();
6211        let (window_id, view_1) = cx.add_window(Default::default(), |_| View {
6212            events: view_events.clone(),
6213            name: "view 1".to_string(),
6214        });
6215        let view_2 = cx.add_view(window_id, |_| View {
6216            events: view_events.clone(),
6217            name: "view 2".to_string(),
6218        });
6219
6220        let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
6221        view_1.update(cx, |_, cx| {
6222            cx.observe_focus(&view_2, {
6223                let observed_events = observed_events.clone();
6224                move |this, view, cx| {
6225                    observed_events.lock().push(format!(
6226                        "{} observed {}'s focus",
6227                        this.name,
6228                        view.read(cx).name
6229                    ))
6230                }
6231            })
6232            .detach();
6233        });
6234        view_2.update(cx, |_, cx| {
6235            cx.observe_focus(&view_1, {
6236                let observed_events = observed_events.clone();
6237                move |this, view, cx| {
6238                    observed_events.lock().push(format!(
6239                        "{} observed {}'s focus",
6240                        this.name,
6241                        view.read(cx).name
6242                    ))
6243                }
6244            })
6245            .detach();
6246        });
6247
6248        view_1.update(cx, |_, cx| {
6249            // Ensure only the latest focus is honored.
6250            cx.focus(&view_2);
6251            cx.focus(&view_1);
6252            cx.focus(&view_2);
6253        });
6254        view_1.update(cx, |_, cx| cx.focus(&view_1));
6255        view_1.update(cx, |_, cx| cx.focus(&view_2));
6256        view_1.update(cx, |_, _| drop(view_2));
6257
6258        assert_eq!(
6259            *view_events.lock(),
6260            [
6261                "view 1 focused".to_string(),
6262                "view 1 blurred".to_string(),
6263                "view 2 focused".to_string(),
6264                "view 2 blurred".to_string(),
6265                "view 1 focused".to_string(),
6266                "view 1 blurred".to_string(),
6267                "view 2 focused".to_string(),
6268                "view 1 focused".to_string(),
6269            ],
6270        );
6271        assert_eq!(
6272            *observed_events.lock(),
6273            [
6274                "view 1 observed view 2's focus".to_string(),
6275                "view 2 observed view 1's focus".to_string(),
6276                "view 1 observed view 2's focus".to_string(),
6277            ]
6278        );
6279    }
6280
6281    #[crate::test(self)]
6282    fn test_deserialize_actions(cx: &mut MutableAppContext) {
6283        #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
6284        pub struct ComplexAction {
6285            arg: String,
6286            count: usize,
6287        }
6288
6289        actions!(test::something, [SimpleAction]);
6290        impl_actions!(test::something, [ComplexAction]);
6291
6292        cx.add_global_action(move |_: &SimpleAction, _: &mut MutableAppContext| {});
6293        cx.add_global_action(move |_: &ComplexAction, _: &mut MutableAppContext| {});
6294
6295        let action1 = cx
6296            .deserialize_action(
6297                "test::something::ComplexAction",
6298                Some(r#"{"arg": "a", "count": 5}"#),
6299            )
6300            .unwrap();
6301        let action2 = cx
6302            .deserialize_action("test::something::SimpleAction", None)
6303            .unwrap();
6304        assert_eq!(
6305            action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
6306            &ComplexAction {
6307                arg: "a".to_string(),
6308                count: 5,
6309            }
6310        );
6311        assert_eq!(
6312            action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
6313            &SimpleAction
6314        );
6315    }
6316
6317    #[crate::test(self)]
6318    fn test_dispatch_action(cx: &mut MutableAppContext) {
6319        struct ViewA {
6320            id: usize,
6321        }
6322
6323        impl Entity for ViewA {
6324            type Event = ();
6325        }
6326
6327        impl View for ViewA {
6328            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6329                Empty::new().boxed()
6330            }
6331
6332            fn ui_name() -> &'static str {
6333                "View"
6334            }
6335        }
6336
6337        struct ViewB {
6338            id: usize,
6339        }
6340
6341        impl Entity for ViewB {
6342            type Event = ();
6343        }
6344
6345        impl View for ViewB {
6346            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6347                Empty::new().boxed()
6348            }
6349
6350            fn ui_name() -> &'static str {
6351                "View"
6352            }
6353        }
6354
6355        #[derive(Clone, Default, Deserialize, PartialEq)]
6356        pub struct Action(pub String);
6357
6358        impl_actions!(test, [Action]);
6359
6360        let actions = Rc::new(RefCell::new(Vec::new()));
6361
6362        cx.add_global_action({
6363            let actions = actions.clone();
6364            move |_: &Action, _: &mut MutableAppContext| {
6365                actions.borrow_mut().push("global".to_string());
6366            }
6367        });
6368
6369        cx.add_action({
6370            let actions = actions.clone();
6371            move |view: &mut ViewA, action: &Action, cx| {
6372                assert_eq!(action.0, "bar");
6373                cx.propagate_action();
6374                actions.borrow_mut().push(format!("{} a", view.id));
6375            }
6376        });
6377
6378        cx.add_action({
6379            let actions = actions.clone();
6380            move |view: &mut ViewA, _: &Action, cx| {
6381                if view.id != 1 {
6382                    cx.add_view(|cx| {
6383                        cx.propagate_action(); // Still works on a nested ViewContext
6384                        ViewB { id: 5 }
6385                    });
6386                }
6387                actions.borrow_mut().push(format!("{} b", view.id));
6388            }
6389        });
6390
6391        cx.add_action({
6392            let actions = actions.clone();
6393            move |view: &mut ViewB, _: &Action, cx| {
6394                cx.propagate_action();
6395                actions.borrow_mut().push(format!("{} c", view.id));
6396            }
6397        });
6398
6399        cx.add_action({
6400            let actions = actions.clone();
6401            move |view: &mut ViewB, _: &Action, cx| {
6402                cx.propagate_action();
6403                actions.borrow_mut().push(format!("{} d", view.id));
6404            }
6405        });
6406
6407        cx.capture_action({
6408            let actions = actions.clone();
6409            move |view: &mut ViewA, _: &Action, cx| {
6410                cx.propagate_action();
6411                actions.borrow_mut().push(format!("{} capture", view.id));
6412            }
6413        });
6414
6415        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
6416        let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 });
6417        let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 });
6418        let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 });
6419
6420        let observed_actions = Rc::new(RefCell::new(Vec::new()));
6421        cx.observe_actions({
6422            let observed_actions = observed_actions.clone();
6423            move |action_id, _| observed_actions.borrow_mut().push(action_id)
6424        })
6425        .detach();
6426
6427        cx.dispatch_action(
6428            window_id,
6429            vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
6430            &Action("bar".to_string()),
6431        );
6432
6433        assert_eq!(
6434            *actions.borrow(),
6435            vec![
6436                "1 capture",
6437                "3 capture",
6438                "4 d",
6439                "4 c",
6440                "3 b",
6441                "3 a",
6442                "2 d",
6443                "2 c",
6444                "1 b"
6445            ]
6446        );
6447        assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
6448
6449        // Remove view_1, which doesn't propagate the action
6450        actions.borrow_mut().clear();
6451        cx.dispatch_action(
6452            window_id,
6453            vec![view_2.id(), view_3.id(), view_4.id()],
6454            &Action("bar".to_string()),
6455        );
6456
6457        assert_eq!(
6458            *actions.borrow(),
6459            vec![
6460                "3 capture",
6461                "4 d",
6462                "4 c",
6463                "3 b",
6464                "3 a",
6465                "2 d",
6466                "2 c",
6467                "global"
6468            ]
6469        );
6470        assert_eq!(
6471            *observed_actions.borrow(),
6472            [Action::default().id(), Action::default().id()]
6473        );
6474    }
6475
6476    #[crate::test(self)]
6477    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
6478        #[derive(Clone, Deserialize, PartialEq)]
6479        pub struct Action(String);
6480
6481        impl_actions!(test, [Action]);
6482
6483        struct View {
6484            id: usize,
6485            keymap_context: keymap::Context,
6486        }
6487
6488        impl Entity for View {
6489            type Event = ();
6490        }
6491
6492        impl super::View for View {
6493            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6494                Empty::new().boxed()
6495            }
6496
6497            fn ui_name() -> &'static str {
6498                "View"
6499            }
6500
6501            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
6502                self.keymap_context.clone()
6503            }
6504        }
6505
6506        impl View {
6507            fn new(id: usize) -> Self {
6508                View {
6509                    id,
6510                    keymap_context: keymap::Context::default(),
6511                }
6512            }
6513        }
6514
6515        let mut view_1 = View::new(1);
6516        let mut view_2 = View::new(2);
6517        let mut view_3 = View::new(3);
6518        view_1.keymap_context.set.insert("a".into());
6519        view_2.keymap_context.set.insert("a".into());
6520        view_2.keymap_context.set.insert("b".into());
6521        view_3.keymap_context.set.insert("a".into());
6522        view_3.keymap_context.set.insert("b".into());
6523        view_3.keymap_context.set.insert("c".into());
6524
6525        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
6526        let view_2 = cx.add_view(window_id, |_| view_2);
6527        let view_3 = cx.add_view(window_id, |_| view_3);
6528
6529        // This keymap's only binding dispatches an action on view 2 because that view will have
6530        // "a" and "b" in its context, but not "c".
6531        cx.add_bindings(vec![keymap::Binding::new(
6532            "a",
6533            Action("a".to_string()),
6534            Some("a && b && !c"),
6535        )]);
6536
6537        cx.add_bindings(vec![keymap::Binding::new(
6538            "b",
6539            Action("b".to_string()),
6540            None,
6541        )]);
6542
6543        let actions = Rc::new(RefCell::new(Vec::new()));
6544        cx.add_action({
6545            let actions = actions.clone();
6546            move |view: &mut View, action: &Action, cx| {
6547                if action.0 == "a" {
6548                    actions.borrow_mut().push(format!("{} a", view.id));
6549                } else {
6550                    actions
6551                        .borrow_mut()
6552                        .push(format!("{} {}", view.id, action.0));
6553                    cx.propagate_action();
6554                }
6555            }
6556        });
6557
6558        cx.add_global_action({
6559            let actions = actions.clone();
6560            move |action: &Action, _| {
6561                actions.borrow_mut().push(format!("global {}", action.0));
6562            }
6563        });
6564
6565        cx.dispatch_keystroke(
6566            window_id,
6567            vec![view_1.id(), view_2.id(), view_3.id()],
6568            &Keystroke::parse("a").unwrap(),
6569        );
6570
6571        assert_eq!(&*actions.borrow(), &["2 a"]);
6572
6573        actions.borrow_mut().clear();
6574        cx.dispatch_keystroke(
6575            window_id,
6576            vec![view_1.id(), view_2.id(), view_3.id()],
6577            &Keystroke::parse("b").unwrap(),
6578        );
6579
6580        assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
6581    }
6582
6583    #[crate::test(self)]
6584    async fn test_model_condition(cx: &mut TestAppContext) {
6585        struct Counter(usize);
6586
6587        impl super::Entity for Counter {
6588            type Event = ();
6589        }
6590
6591        impl Counter {
6592            fn inc(&mut self, cx: &mut ModelContext<Self>) {
6593                self.0 += 1;
6594                cx.notify();
6595            }
6596        }
6597
6598        let model = cx.add_model(|_| Counter(0));
6599
6600        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
6601        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
6602        smol::pin!(condition1, condition2);
6603
6604        model.update(cx, |model, cx| model.inc(cx));
6605        assert_eq!(poll_once(&mut condition1).await, None);
6606        assert_eq!(poll_once(&mut condition2).await, None);
6607
6608        model.update(cx, |model, cx| model.inc(cx));
6609        assert_eq!(poll_once(&mut condition1).await, Some(()));
6610        assert_eq!(poll_once(&mut condition2).await, None);
6611
6612        model.update(cx, |model, cx| model.inc(cx));
6613        assert_eq!(poll_once(&mut condition2).await, Some(()));
6614
6615        model.update(cx, |_, cx| cx.notify());
6616    }
6617
6618    #[crate::test(self)]
6619    #[should_panic]
6620    async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6621        struct Model;
6622
6623        impl super::Entity for Model {
6624            type Event = ();
6625        }
6626
6627        let model = cx.add_model(|_| Model);
6628        model.condition(&cx, |_, _| false).await;
6629    }
6630
6631    #[crate::test(self)]
6632    #[should_panic(expected = "model dropped with pending condition")]
6633    async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6634        struct Model;
6635
6636        impl super::Entity for Model {
6637            type Event = ();
6638        }
6639
6640        let model = cx.add_model(|_| Model);
6641        let condition = model.condition(&cx, |_, _| false);
6642        cx.update(|_| drop(model));
6643        condition.await;
6644    }
6645
6646    #[crate::test(self)]
6647    async fn test_view_condition(cx: &mut TestAppContext) {
6648        struct Counter(usize);
6649
6650        impl super::Entity for Counter {
6651            type Event = ();
6652        }
6653
6654        impl super::View for Counter {
6655            fn ui_name() -> &'static str {
6656                "test view"
6657            }
6658
6659            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6660                Empty::new().boxed()
6661            }
6662        }
6663
6664        impl Counter {
6665            fn inc(&mut self, cx: &mut ViewContext<Self>) {
6666                self.0 += 1;
6667                cx.notify();
6668            }
6669        }
6670
6671        let (_, view) = cx.add_window(|_| Counter(0));
6672
6673        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
6674        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
6675        smol::pin!(condition1, condition2);
6676
6677        view.update(cx, |view, cx| view.inc(cx));
6678        assert_eq!(poll_once(&mut condition1).await, None);
6679        assert_eq!(poll_once(&mut condition2).await, None);
6680
6681        view.update(cx, |view, cx| view.inc(cx));
6682        assert_eq!(poll_once(&mut condition1).await, Some(()));
6683        assert_eq!(poll_once(&mut condition2).await, None);
6684
6685        view.update(cx, |view, cx| view.inc(cx));
6686        assert_eq!(poll_once(&mut condition2).await, Some(()));
6687        view.update(cx, |_, cx| cx.notify());
6688    }
6689
6690    #[crate::test(self)]
6691    #[should_panic]
6692    async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6693        struct View;
6694
6695        impl super::Entity for View {
6696            type Event = ();
6697        }
6698
6699        impl super::View for View {
6700            fn ui_name() -> &'static str {
6701                "test view"
6702            }
6703
6704            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6705                Empty::new().boxed()
6706            }
6707        }
6708
6709        let (_, view) = cx.add_window(|_| View);
6710        view.condition(&cx, |_, _| false).await;
6711    }
6712
6713    #[crate::test(self)]
6714    #[should_panic(expected = "view dropped with pending condition")]
6715    async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6716        struct View;
6717
6718        impl super::Entity for View {
6719            type Event = ();
6720        }
6721
6722        impl super::View for View {
6723            fn ui_name() -> &'static str {
6724                "test view"
6725            }
6726
6727            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6728                Empty::new().boxed()
6729            }
6730        }
6731
6732        let window_id = cx.add_window(|_| View).0;
6733        let view = cx.add_view(window_id, |_| View);
6734
6735        let condition = view.condition(&cx, |_, _| false);
6736        cx.update(|_| drop(view));
6737        condition.await;
6738    }
6739
6740    #[crate::test(self)]
6741    fn test_refresh_windows(cx: &mut MutableAppContext) {
6742        struct View(usize);
6743
6744        impl super::Entity for View {
6745            type Event = ();
6746        }
6747
6748        impl super::View for View {
6749            fn ui_name() -> &'static str {
6750                "test view"
6751            }
6752
6753            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6754                Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
6755            }
6756        }
6757
6758        let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
6759        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
6760
6761        assert_eq!(
6762            presenter.borrow().rendered_views[&root_view.id()].name(),
6763            Some("render count: 0")
6764        );
6765
6766        let view = cx.add_view(window_id, |cx| {
6767            cx.refresh_windows();
6768            View(0)
6769        });
6770
6771        assert_eq!(
6772            presenter.borrow().rendered_views[&root_view.id()].name(),
6773            Some("render count: 1")
6774        );
6775        assert_eq!(
6776            presenter.borrow().rendered_views[&view.id()].name(),
6777            Some("render count: 0")
6778        );
6779
6780        cx.update(|cx| cx.refresh_windows());
6781        assert_eq!(
6782            presenter.borrow().rendered_views[&root_view.id()].name(),
6783            Some("render count: 2")
6784        );
6785        assert_eq!(
6786            presenter.borrow().rendered_views[&view.id()].name(),
6787            Some("render count: 1")
6788        );
6789
6790        cx.update(|cx| {
6791            cx.refresh_windows();
6792            drop(view);
6793        });
6794        assert_eq!(
6795            presenter.borrow().rendered_views[&root_view.id()].name(),
6796            Some("render count: 3")
6797        );
6798        assert_eq!(presenter.borrow().rendered_views.len(), 1);
6799    }
6800}