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;
1778                            }
1779                        }
1780
1781                        presenter.borrow_mut().dispatch_event(event, cx);
1782                    }
1783                })
1784            }));
1785        }
1786
1787        {
1788            let mut app = self.upgrade();
1789            window.on_active_status_change(Box::new(move |is_active| {
1790                app.update(|cx| cx.window_changed_active_status(window_id, is_active))
1791            }));
1792        }
1793
1794        {
1795            let mut app = self.upgrade();
1796            window.on_resize(Box::new(move || {
1797                app.update(|cx| cx.window_was_resized(window_id))
1798            }));
1799        }
1800
1801        {
1802            let mut app = self.upgrade();
1803            window.on_close(Box::new(move || {
1804                app.update(|cx| cx.remove_window(window_id));
1805            }));
1806        }
1807
1808        let scene =
1809            presenter
1810                .borrow_mut()
1811                .build_scene(window.size(), window.scale_factor(), false, self);
1812        window.present_scene(scene);
1813        self.presenters_and_platform_windows
1814            .insert(window_id, (presenter.clone(), window));
1815    }
1816
1817    pub fn build_presenter(&mut self, window_id: usize, titlebar_height: f32) -> Presenter {
1818        Presenter::new(
1819            window_id,
1820            titlebar_height,
1821            self.cx.font_cache.clone(),
1822            TextLayoutCache::new(self.cx.platform.fonts()),
1823            self.assets.clone(),
1824            self,
1825        )
1826    }
1827
1828    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
1829    where
1830        T: View,
1831        F: FnOnce(&mut ViewContext<T>) -> T,
1832    {
1833        self.add_option_view(window_id, |cx| Some(build_view(cx)))
1834            .unwrap()
1835    }
1836
1837    pub fn add_option_view<T, F>(
1838        &mut self,
1839        window_id: usize,
1840        build_view: F,
1841    ) -> Option<ViewHandle<T>>
1842    where
1843        T: View,
1844        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1845    {
1846        self.update(|this| {
1847            let view_id = post_inc(&mut this.next_entity_id);
1848            let mut cx = ViewContext::new(this, window_id, view_id);
1849            let handle = if let Some(view) = build_view(&mut cx) {
1850                this.cx.views.insert((window_id, view_id), Box::new(view));
1851                if let Some(window) = this.cx.windows.get_mut(&window_id) {
1852                    window
1853                        .invalidation
1854                        .get_or_insert_with(Default::default)
1855                        .updated
1856                        .insert(view_id);
1857                }
1858                Some(ViewHandle::new(window_id, view_id, &this.cx.ref_counts))
1859            } else {
1860                None
1861            };
1862            handle
1863        })
1864    }
1865
1866    fn remove_dropped_entities(&mut self) {
1867        loop {
1868            let (dropped_models, dropped_views, dropped_element_states) =
1869                self.cx.ref_counts.lock().take_dropped();
1870            if dropped_models.is_empty()
1871                && dropped_views.is_empty()
1872                && dropped_element_states.is_empty()
1873            {
1874                break;
1875            }
1876
1877            for model_id in dropped_models {
1878                self.subscriptions.lock().remove(&model_id);
1879                self.observations.lock().remove(&model_id);
1880                let mut model = self.cx.models.remove(&model_id).unwrap();
1881                model.release(self);
1882                self.pending_effects
1883                    .push_back(Effect::ModelRelease { model_id, model });
1884            }
1885
1886            for (window_id, view_id) in dropped_views {
1887                self.subscriptions.lock().remove(&view_id);
1888                self.observations.lock().remove(&view_id);
1889                let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap();
1890                view.release(self);
1891                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
1892                    window
1893                        .invalidation
1894                        .get_or_insert_with(Default::default)
1895                        .removed
1896                        .push(view_id);
1897                    if window.focused_view_id == Some(view_id) {
1898                        Some(window.root_view.id())
1899                    } else {
1900                        None
1901                    }
1902                });
1903
1904                if let Some(view_id) = change_focus_to {
1905                    self.handle_focus_effect(window_id, Some(view_id));
1906                }
1907
1908                self.pending_effects
1909                    .push_back(Effect::ViewRelease { view_id, view });
1910            }
1911
1912            for key in dropped_element_states {
1913                self.cx.element_states.remove(&key);
1914            }
1915        }
1916    }
1917
1918    fn flush_effects(&mut self) {
1919        self.pending_flushes = self.pending_flushes.saturating_sub(1);
1920        let mut after_window_update_callbacks = Vec::new();
1921
1922        if !self.flushing_effects && self.pending_flushes == 0 {
1923            self.flushing_effects = true;
1924
1925            let mut refreshing = false;
1926            loop {
1927                if let Some(effect) = self.pending_effects.pop_front() {
1928                    if let Some(pending_focus_index) = self.pending_focus_index.as_mut() {
1929                        *pending_focus_index = pending_focus_index.saturating_sub(1);
1930                    }
1931                    match effect {
1932                        Effect::Subscription {
1933                            entity_id,
1934                            subscription_id,
1935                            callback,
1936                        } => self.handle_subscription_effect(entity_id, subscription_id, callback),
1937                        Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
1938                        Effect::GlobalSubscription {
1939                            type_id,
1940                            subscription_id,
1941                            callback,
1942                        } => self.handle_global_subscription_effect(
1943                            type_id,
1944                            subscription_id,
1945                            callback,
1946                        ),
1947                        Effect::GlobalEvent { payload } => self.emit_global_event(payload),
1948                        Effect::Observation {
1949                            entity_id,
1950                            subscription_id,
1951                            callback,
1952                        } => self.handle_observation_effect(entity_id, subscription_id, callback),
1953                        Effect::ModelNotification { model_id } => {
1954                            self.handle_model_notification_effect(model_id)
1955                        }
1956                        Effect::ViewNotification { window_id, view_id } => {
1957                            self.handle_view_notification_effect(window_id, view_id)
1958                        }
1959                        Effect::GlobalNotification { type_id } => {
1960                            self.handle_global_notification_effect(type_id)
1961                        }
1962                        Effect::Deferred {
1963                            callback,
1964                            after_window_update,
1965                        } => {
1966                            if after_window_update {
1967                                after_window_update_callbacks.push(callback);
1968                            } else {
1969                                callback(self)
1970                            }
1971                        }
1972                        Effect::ModelRelease { model_id, model } => {
1973                            self.handle_entity_release_effect(model_id, model.as_any())
1974                        }
1975                        Effect::ViewRelease { view_id, view } => {
1976                            self.handle_entity_release_effect(view_id, view.as_any())
1977                        }
1978                        Effect::Focus { window_id, view_id } => {
1979                            self.handle_focus_effect(window_id, view_id);
1980                        }
1981                        Effect::FocusObservation {
1982                            view_id,
1983                            subscription_id,
1984                            callback,
1985                        } => {
1986                            self.handle_focus_observation_effect(view_id, subscription_id, callback)
1987                        }
1988                        Effect::ResizeWindow { window_id } => {
1989                            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1990                                window
1991                                    .invalidation
1992                                    .get_or_insert(WindowInvalidation::default());
1993                            }
1994                        }
1995                        Effect::ActivateWindow {
1996                            window_id,
1997                            is_active,
1998                        } => self.handle_activation_effect(window_id, is_active),
1999                        Effect::RefreshWindows => {
2000                            refreshing = true;
2001                        }
2002                        Effect::ActionDispatchNotification { action_id } => {
2003                            self.handle_action_dispatch_notification_effect(action_id)
2004                        }
2005                    }
2006                    self.pending_notifications.clear();
2007                    self.remove_dropped_entities();
2008                } else {
2009                    self.remove_dropped_entities();
2010                    if refreshing {
2011                        self.perform_window_refresh();
2012                    } else {
2013                        self.update_windows();
2014                    }
2015
2016                    if self.pending_effects.is_empty() {
2017                        for callback in after_window_update_callbacks.drain(..) {
2018                            callback(self);
2019                        }
2020
2021                        if self.pending_effects.is_empty() {
2022                            self.flushing_effects = false;
2023                            self.pending_notifications.clear();
2024                            self.pending_global_notifications.clear();
2025                            break;
2026                        }
2027                    }
2028
2029                    refreshing = false;
2030                }
2031            }
2032        }
2033    }
2034
2035    fn update_windows(&mut self) {
2036        let mut invalidations = HashMap::new();
2037        for (window_id, window) in &mut self.cx.windows {
2038            if let Some(invalidation) = window.invalidation.take() {
2039                invalidations.insert(*window_id, invalidation);
2040            }
2041        }
2042
2043        for (window_id, mut invalidation) in invalidations {
2044            if let Some((presenter, mut window)) =
2045                self.presenters_and_platform_windows.remove(&window_id)
2046            {
2047                {
2048                    let mut presenter = presenter.borrow_mut();
2049                    presenter.invalidate(&mut invalidation, self);
2050                    let scene =
2051                        presenter.build_scene(window.size(), window.scale_factor(), false, self);
2052                    window.present_scene(scene);
2053                }
2054                self.presenters_and_platform_windows
2055                    .insert(window_id, (presenter, window));
2056            }
2057        }
2058    }
2059
2060    fn window_was_resized(&mut self, window_id: usize) {
2061        self.pending_effects
2062            .push_back(Effect::ResizeWindow { window_id });
2063    }
2064
2065    fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) {
2066        self.pending_effects.push_back(Effect::ActivateWindow {
2067            window_id,
2068            is_active,
2069        });
2070    }
2071
2072    pub fn refresh_windows(&mut self) {
2073        self.pending_effects.push_back(Effect::RefreshWindows);
2074    }
2075
2076    fn perform_window_refresh(&mut self) {
2077        let mut presenters = mem::take(&mut self.presenters_and_platform_windows);
2078        for (window_id, (presenter, window)) in &mut presenters {
2079            let mut invalidation = self
2080                .cx
2081                .windows
2082                .get_mut(&window_id)
2083                .unwrap()
2084                .invalidation
2085                .take();
2086            let mut presenter = presenter.borrow_mut();
2087            presenter.refresh(
2088                invalidation.as_mut().unwrap_or(&mut Default::default()),
2089                self,
2090            );
2091            let scene = presenter.build_scene(window.size(), window.scale_factor(), true, self);
2092            window.present_scene(scene);
2093        }
2094        self.presenters_and_platform_windows = presenters;
2095    }
2096
2097    fn handle_subscription_effect(
2098        &mut self,
2099        entity_id: usize,
2100        subscription_id: usize,
2101        callback: SubscriptionCallback,
2102    ) {
2103        match self
2104            .subscriptions
2105            .lock()
2106            .entry(entity_id)
2107            .or_default()
2108            .entry(subscription_id)
2109        {
2110            btree_map::Entry::Vacant(entry) => {
2111                entry.insert(Some(callback));
2112            }
2113            // Subscription was dropped before effect was processed
2114            btree_map::Entry::Occupied(entry) => {
2115                debug_assert!(entry.get().is_none());
2116                entry.remove();
2117            }
2118        }
2119    }
2120
2121    fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
2122        let callbacks = self.subscriptions.lock().remove(&entity_id);
2123        if let Some(callbacks) = callbacks {
2124            for (id, callback) in callbacks {
2125                if let Some(mut callback) = callback {
2126                    let alive = callback(payload.as_ref(), self);
2127                    if alive {
2128                        match self
2129                            .subscriptions
2130                            .lock()
2131                            .entry(entity_id)
2132                            .or_default()
2133                            .entry(id)
2134                        {
2135                            btree_map::Entry::Vacant(entry) => {
2136                                entry.insert(Some(callback));
2137                            }
2138                            btree_map::Entry::Occupied(entry) => {
2139                                entry.remove();
2140                            }
2141                        }
2142                    }
2143                }
2144            }
2145        }
2146    }
2147
2148    fn handle_global_subscription_effect(
2149        &mut self,
2150        type_id: TypeId,
2151        subscription_id: usize,
2152        callback: GlobalSubscriptionCallback,
2153    ) {
2154        match self
2155            .global_subscriptions
2156            .lock()
2157            .entry(type_id)
2158            .or_default()
2159            .entry(subscription_id)
2160        {
2161            btree_map::Entry::Vacant(entry) => {
2162                entry.insert(Some(callback));
2163            }
2164            // Subscription was dropped before effect was processed
2165            btree_map::Entry::Occupied(entry) => {
2166                debug_assert!(entry.get().is_none());
2167                entry.remove();
2168            }
2169        }
2170    }
2171
2172    fn emit_global_event(&mut self, payload: Box<dyn Any>) {
2173        let type_id = (&*payload).type_id();
2174        let callbacks = self.global_subscriptions.lock().remove(&type_id);
2175        if let Some(callbacks) = callbacks {
2176            for (id, callback) in callbacks {
2177                if let Some(mut callback) = callback {
2178                    callback(payload.as_ref(), self);
2179                    match self
2180                        .global_subscriptions
2181                        .lock()
2182                        .entry(type_id)
2183                        .or_default()
2184                        .entry(id)
2185                    {
2186                        btree_map::Entry::Vacant(entry) => {
2187                            entry.insert(Some(callback));
2188                        }
2189                        btree_map::Entry::Occupied(entry) => {
2190                            entry.remove();
2191                        }
2192                    }
2193                }
2194            }
2195        }
2196    }
2197
2198    fn handle_observation_effect(
2199        &mut self,
2200        entity_id: usize,
2201        subscription_id: usize,
2202        callback: ObservationCallback,
2203    ) {
2204        match self
2205            .observations
2206            .lock()
2207            .entry(entity_id)
2208            .or_default()
2209            .entry(subscription_id)
2210        {
2211            btree_map::Entry::Vacant(entry) => {
2212                entry.insert(Some(callback));
2213            }
2214            // Observation was dropped before effect was processed
2215            btree_map::Entry::Occupied(entry) => {
2216                debug_assert!(entry.get().is_none());
2217                entry.remove();
2218            }
2219        }
2220    }
2221
2222    fn handle_focus_observation_effect(
2223        &mut self,
2224        view_id: usize,
2225        subscription_id: usize,
2226        callback: FocusObservationCallback,
2227    ) {
2228        match self
2229            .focus_observations
2230            .lock()
2231            .entry(view_id)
2232            .or_default()
2233            .entry(subscription_id)
2234        {
2235            btree_map::Entry::Vacant(entry) => {
2236                entry.insert(Some(callback));
2237            }
2238            // Observation was dropped before effect was processed
2239            btree_map::Entry::Occupied(entry) => {
2240                debug_assert!(entry.get().is_none());
2241                entry.remove();
2242            }
2243        }
2244    }
2245
2246    fn handle_model_notification_effect(&mut self, observed_id: usize) {
2247        let callbacks = self.observations.lock().remove(&observed_id);
2248        if let Some(callbacks) = callbacks {
2249            if self.cx.models.contains_key(&observed_id) {
2250                for (id, callback) in callbacks {
2251                    if let Some(mut callback) = callback {
2252                        let alive = callback(self);
2253                        if alive {
2254                            match self
2255                                .observations
2256                                .lock()
2257                                .entry(observed_id)
2258                                .or_default()
2259                                .entry(id)
2260                            {
2261                                btree_map::Entry::Vacant(entry) => {
2262                                    entry.insert(Some(callback));
2263                                }
2264                                btree_map::Entry::Occupied(entry) => {
2265                                    entry.remove();
2266                                }
2267                            }
2268                        }
2269                    }
2270                }
2271            }
2272        }
2273    }
2274
2275    fn handle_view_notification_effect(
2276        &mut self,
2277        observed_window_id: usize,
2278        observed_view_id: usize,
2279    ) {
2280        let callbacks = self.observations.lock().remove(&observed_view_id);
2281
2282        if self
2283            .cx
2284            .views
2285            .contains_key(&(observed_window_id, observed_view_id))
2286        {
2287            if let Some(window) = self.cx.windows.get_mut(&observed_window_id) {
2288                window
2289                    .invalidation
2290                    .get_or_insert_with(Default::default)
2291                    .updated
2292                    .insert(observed_view_id);
2293            }
2294
2295            if let Some(callbacks) = callbacks {
2296                for (id, callback) in callbacks {
2297                    if let Some(mut callback) = callback {
2298                        let alive = callback(self);
2299                        if alive {
2300                            match self
2301                                .observations
2302                                .lock()
2303                                .entry(observed_view_id)
2304                                .or_default()
2305                                .entry(id)
2306                            {
2307                                btree_map::Entry::Vacant(entry) => {
2308                                    entry.insert(Some(callback));
2309                                }
2310                                btree_map::Entry::Occupied(entry) => {
2311                                    entry.remove();
2312                                }
2313                            }
2314                        }
2315                    }
2316                }
2317            }
2318        }
2319    }
2320
2321    fn handle_global_notification_effect(&mut self, observed_type_id: TypeId) {
2322        let callbacks = self.global_observations.lock().remove(&observed_type_id);
2323        if let Some(callbacks) = callbacks {
2324            for (id, callback) in callbacks {
2325                if let Some(mut callback) = callback {
2326                    callback(self);
2327                    match self
2328                        .global_observations
2329                        .lock()
2330                        .entry(observed_type_id)
2331                        .or_default()
2332                        .entry(id)
2333                    {
2334                        collections::btree_map::Entry::Vacant(entry) => {
2335                            entry.insert(Some(callback));
2336                        }
2337                        collections::btree_map::Entry::Occupied(entry) => {
2338                            entry.remove();
2339                        }
2340                    }
2341                }
2342            }
2343        }
2344    }
2345
2346    fn handle_entity_release_effect(&mut self, entity_id: usize, entity: &dyn Any) {
2347        let callbacks = self.release_observations.lock().remove(&entity_id);
2348        if let Some(callbacks) = callbacks {
2349            for (_, callback) in callbacks {
2350                callback(entity, self);
2351            }
2352        }
2353    }
2354
2355    fn handle_activation_effect(&mut self, window_id: usize, active: bool) {
2356        if self
2357            .cx
2358            .windows
2359            .get(&window_id)
2360            .map(|w| w.is_active)
2361            .map_or(false, |cur_active| cur_active == active)
2362        {
2363            return;
2364        }
2365
2366        self.update(|this| {
2367            let window = this.cx.windows.get_mut(&window_id)?;
2368            window.is_active = active;
2369            let view_id = window.focused_view_id?;
2370            if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2371                if active {
2372                    view.on_focus(this, window_id, view_id);
2373                } else {
2374                    view.on_blur(this, window_id, view_id);
2375                }
2376                this.cx.views.insert((window_id, view_id), view);
2377            }
2378
2379            Some(())
2380        });
2381    }
2382
2383    fn handle_focus_effect(&mut self, window_id: usize, focused_id: Option<usize>) {
2384        self.pending_focus_index.take();
2385
2386        if self
2387            .cx
2388            .windows
2389            .get(&window_id)
2390            .map(|w| w.focused_view_id)
2391            .map_or(false, |cur_focused| cur_focused == focused_id)
2392        {
2393            return;
2394        }
2395
2396        self.update(|this| {
2397            let blurred_id = this.cx.windows.get_mut(&window_id).and_then(|window| {
2398                let blurred_id = window.focused_view_id;
2399                window.focused_view_id = focused_id;
2400                blurred_id
2401            });
2402
2403            if let Some(blurred_id) = blurred_id {
2404                if let Some(mut blurred_view) = this.cx.views.remove(&(window_id, blurred_id)) {
2405                    blurred_view.on_blur(this, window_id, blurred_id);
2406                    this.cx.views.insert((window_id, blurred_id), blurred_view);
2407                }
2408            }
2409
2410            if let Some(focused_id) = focused_id {
2411                if let Some(mut focused_view) = this.cx.views.remove(&(window_id, focused_id)) {
2412                    focused_view.on_focus(this, window_id, focused_id);
2413                    this.cx.views.insert((window_id, focused_id), focused_view);
2414
2415                    let callbacks = this.focus_observations.lock().remove(&focused_id);
2416                    if let Some(callbacks) = callbacks {
2417                        for (id, callback) in callbacks {
2418                            if let Some(mut callback) = callback {
2419                                let alive = callback(this);
2420                                if alive {
2421                                    match this
2422                                        .focus_observations
2423                                        .lock()
2424                                        .entry(focused_id)
2425                                        .or_default()
2426                                        .entry(id)
2427                                    {
2428                                        btree_map::Entry::Vacant(entry) => {
2429                                            entry.insert(Some(callback));
2430                                        }
2431                                        btree_map::Entry::Occupied(entry) => {
2432                                            entry.remove();
2433                                        }
2434                                    }
2435                                }
2436                            }
2437                        }
2438                    }
2439                }
2440            }
2441        })
2442    }
2443
2444    fn handle_action_dispatch_notification_effect(&mut self, action_id: TypeId) {
2445        let mut callbacks = mem::take(&mut *self.action_dispatch_observations.lock());
2446        for (_, callback) in &mut callbacks {
2447            callback(action_id, self);
2448        }
2449        self.action_dispatch_observations.lock().extend(callbacks);
2450    }
2451
2452    pub fn focus(&mut self, window_id: usize, view_id: Option<usize>) {
2453        if let Some(pending_focus_index) = self.pending_focus_index {
2454            self.pending_effects.remove(pending_focus_index);
2455        }
2456        self.pending_focus_index = Some(self.pending_effects.len());
2457        self.pending_effects
2458            .push_back(Effect::Focus { window_id, view_id });
2459    }
2460
2461    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
2462    where
2463        F: FnOnce(AsyncAppContext) -> Fut,
2464        Fut: 'static + Future<Output = T>,
2465        T: 'static,
2466    {
2467        let future = f(self.to_async());
2468        let cx = self.to_async();
2469        self.foreground.spawn(async move {
2470            let result = future.await;
2471            cx.0.borrow_mut().flush_effects();
2472            result
2473        })
2474    }
2475
2476    pub fn to_async(&self) -> AsyncAppContext {
2477        AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
2478    }
2479
2480    pub fn write_to_clipboard(&self, item: ClipboardItem) {
2481        self.cx.platform.write_to_clipboard(item);
2482    }
2483
2484    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
2485        self.cx.platform.read_from_clipboard()
2486    }
2487
2488    #[cfg(any(test, feature = "test-support"))]
2489    pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
2490        self.cx.ref_counts.lock().leak_detector.clone()
2491    }
2492}
2493
2494impl ReadModel for MutableAppContext {
2495    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2496        if let Some(model) = self.cx.models.get(&handle.model_id) {
2497            model
2498                .as_any()
2499                .downcast_ref()
2500                .expect("downcast is type safe")
2501        } else {
2502            panic!("circular model reference");
2503        }
2504    }
2505}
2506
2507impl UpdateModel for MutableAppContext {
2508    fn update_model<T: Entity, V>(
2509        &mut self,
2510        handle: &ModelHandle<T>,
2511        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2512    ) -> V {
2513        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
2514            self.update(|this| {
2515                let mut cx = ModelContext::new(this, handle.model_id);
2516                let result = update(
2517                    model
2518                        .as_any_mut()
2519                        .downcast_mut()
2520                        .expect("downcast is type safe"),
2521                    &mut cx,
2522                );
2523                this.cx.models.insert(handle.model_id, model);
2524                result
2525            })
2526        } else {
2527            panic!("circular model update");
2528        }
2529    }
2530}
2531
2532impl UpgradeModelHandle for MutableAppContext {
2533    fn upgrade_model_handle<T: Entity>(
2534        &self,
2535        handle: &WeakModelHandle<T>,
2536    ) -> Option<ModelHandle<T>> {
2537        self.cx.upgrade_model_handle(handle)
2538    }
2539
2540    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2541        self.cx.model_handle_is_upgradable(handle)
2542    }
2543
2544    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2545        self.cx.upgrade_any_model_handle(handle)
2546    }
2547}
2548
2549impl UpgradeViewHandle for MutableAppContext {
2550    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2551        self.cx.upgrade_view_handle(handle)
2552    }
2553
2554    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2555        self.cx.upgrade_any_view_handle(handle)
2556    }
2557}
2558
2559impl ReadView for MutableAppContext {
2560    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2561        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
2562            view.as_any().downcast_ref().expect("downcast is type safe")
2563        } else {
2564            panic!("circular view reference");
2565        }
2566    }
2567}
2568
2569impl UpdateView for MutableAppContext {
2570    fn update_view<T, S>(
2571        &mut self,
2572        handle: &ViewHandle<T>,
2573        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
2574    ) -> S
2575    where
2576        T: View,
2577    {
2578        self.update(|this| {
2579            let mut view = this
2580                .cx
2581                .views
2582                .remove(&(handle.window_id, handle.view_id))
2583                .expect("circular view update");
2584
2585            let mut cx = ViewContext::new(this, handle.window_id, handle.view_id);
2586            let result = update(
2587                view.as_any_mut()
2588                    .downcast_mut()
2589                    .expect("downcast is type safe"),
2590                &mut cx,
2591            );
2592            this.cx
2593                .views
2594                .insert((handle.window_id, handle.view_id), view);
2595            result
2596        })
2597    }
2598}
2599
2600impl AsRef<AppContext> for MutableAppContext {
2601    fn as_ref(&self) -> &AppContext {
2602        &self.cx
2603    }
2604}
2605
2606impl Deref for MutableAppContext {
2607    type Target = AppContext;
2608
2609    fn deref(&self) -> &Self::Target {
2610        &self.cx
2611    }
2612}
2613
2614pub struct AppContext {
2615    models: HashMap<usize, Box<dyn AnyModel>>,
2616    views: HashMap<(usize, usize), Box<dyn AnyView>>,
2617    windows: HashMap<usize, Window>,
2618    globals: HashMap<TypeId, Box<dyn Any>>,
2619    element_states: HashMap<ElementStateId, Box<dyn Any>>,
2620    background: Arc<executor::Background>,
2621    ref_counts: Arc<Mutex<RefCounts>>,
2622    font_cache: Arc<FontCache>,
2623    platform: Arc<dyn Platform>,
2624}
2625
2626impl AppContext {
2627    pub(crate) fn root_view(&self, window_id: usize) -> Option<AnyViewHandle> {
2628        self.windows
2629            .get(&window_id)
2630            .map(|window| window.root_view.clone())
2631    }
2632
2633    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
2634        self.windows
2635            .get(&window_id)
2636            .map(|window| window.root_view.id())
2637    }
2638
2639    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
2640        self.windows
2641            .get(&window_id)
2642            .and_then(|window| window.focused_view_id)
2643    }
2644
2645    pub fn background(&self) -> &Arc<executor::Background> {
2646        &self.background
2647    }
2648
2649    pub fn font_cache(&self) -> &Arc<FontCache> {
2650        &self.font_cache
2651    }
2652
2653    pub fn platform(&self) -> &Arc<dyn Platform> {
2654        &self.platform
2655    }
2656
2657    pub fn has_global<T: 'static>(&self) -> bool {
2658        self.globals.contains_key(&TypeId::of::<T>())
2659    }
2660
2661    pub fn global<T: 'static>(&self) -> &T {
2662        if let Some(global) = self.globals.get(&TypeId::of::<T>()) {
2663            global.downcast_ref().unwrap()
2664        } else {
2665            panic!("no global has been added for {}", type_name::<T>());
2666        }
2667    }
2668}
2669
2670impl ReadModel for AppContext {
2671    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2672        if let Some(model) = self.models.get(&handle.model_id) {
2673            model
2674                .as_any()
2675                .downcast_ref()
2676                .expect("downcast should be type safe")
2677        } else {
2678            panic!("circular model reference");
2679        }
2680    }
2681}
2682
2683impl UpgradeModelHandle for AppContext {
2684    fn upgrade_model_handle<T: Entity>(
2685        &self,
2686        handle: &WeakModelHandle<T>,
2687    ) -> Option<ModelHandle<T>> {
2688        if self.models.contains_key(&handle.model_id) {
2689            Some(ModelHandle::new(handle.model_id, &self.ref_counts))
2690        } else {
2691            None
2692        }
2693    }
2694
2695    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2696        self.models.contains_key(&handle.model_id)
2697    }
2698
2699    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2700        if self.models.contains_key(&handle.model_id) {
2701            Some(AnyModelHandle::new(
2702                handle.model_id,
2703                handle.model_type,
2704                self.ref_counts.clone(),
2705            ))
2706        } else {
2707            None
2708        }
2709    }
2710}
2711
2712impl UpgradeViewHandle for AppContext {
2713    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2714        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2715            Some(ViewHandle::new(
2716                handle.window_id,
2717                handle.view_id,
2718                &self.ref_counts,
2719            ))
2720        } else {
2721            None
2722        }
2723    }
2724
2725    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2726        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2727            Some(AnyViewHandle::new(
2728                handle.window_id,
2729                handle.view_id,
2730                handle.view_type,
2731                self.ref_counts.clone(),
2732            ))
2733        } else {
2734            None
2735        }
2736    }
2737}
2738
2739impl ReadView for AppContext {
2740    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2741        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
2742            view.as_any()
2743                .downcast_ref()
2744                .expect("downcast should be type safe")
2745        } else {
2746            panic!("circular view reference");
2747        }
2748    }
2749}
2750
2751struct Window {
2752    root_view: AnyViewHandle,
2753    focused_view_id: Option<usize>,
2754    is_active: bool,
2755    invalidation: Option<WindowInvalidation>,
2756}
2757
2758#[derive(Default, Clone)]
2759pub struct WindowInvalidation {
2760    pub updated: HashSet<usize>,
2761    pub removed: Vec<usize>,
2762}
2763
2764pub enum Effect {
2765    Subscription {
2766        entity_id: usize,
2767        subscription_id: usize,
2768        callback: SubscriptionCallback,
2769    },
2770    Event {
2771        entity_id: usize,
2772        payload: Box<dyn Any>,
2773    },
2774    GlobalSubscription {
2775        type_id: TypeId,
2776        subscription_id: usize,
2777        callback: GlobalSubscriptionCallback,
2778    },
2779    GlobalEvent {
2780        payload: Box<dyn Any>,
2781    },
2782    Observation {
2783        entity_id: usize,
2784        subscription_id: usize,
2785        callback: ObservationCallback,
2786    },
2787    ModelNotification {
2788        model_id: usize,
2789    },
2790    ViewNotification {
2791        window_id: usize,
2792        view_id: usize,
2793    },
2794    Deferred {
2795        callback: Box<dyn FnOnce(&mut MutableAppContext)>,
2796        after_window_update: bool,
2797    },
2798    GlobalNotification {
2799        type_id: TypeId,
2800    },
2801    ModelRelease {
2802        model_id: usize,
2803        model: Box<dyn AnyModel>,
2804    },
2805    ViewRelease {
2806        view_id: usize,
2807        view: Box<dyn AnyView>,
2808    },
2809    Focus {
2810        window_id: usize,
2811        view_id: Option<usize>,
2812    },
2813    FocusObservation {
2814        view_id: usize,
2815        subscription_id: usize,
2816        callback: FocusObservationCallback,
2817    },
2818    ResizeWindow {
2819        window_id: usize,
2820    },
2821    ActivateWindow {
2822        window_id: usize,
2823        is_active: bool,
2824    },
2825    RefreshWindows,
2826    ActionDispatchNotification {
2827        action_id: TypeId,
2828    },
2829}
2830
2831impl Debug for Effect {
2832    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2833        match self {
2834            Effect::Subscription {
2835                entity_id,
2836                subscription_id,
2837                ..
2838            } => f
2839                .debug_struct("Effect::Subscribe")
2840                .field("entity_id", entity_id)
2841                .field("subscription_id", subscription_id)
2842                .finish(),
2843            Effect::Event { entity_id, .. } => f
2844                .debug_struct("Effect::Event")
2845                .field("entity_id", entity_id)
2846                .finish(),
2847            Effect::GlobalSubscription {
2848                type_id,
2849                subscription_id,
2850                ..
2851            } => f
2852                .debug_struct("Effect::Subscribe")
2853                .field("type_id", type_id)
2854                .field("subscription_id", subscription_id)
2855                .finish(),
2856            Effect::GlobalEvent { payload, .. } => f
2857                .debug_struct("Effect::GlobalEvent")
2858                .field("type_id", &(&*payload).type_id())
2859                .finish(),
2860            Effect::Observation {
2861                entity_id,
2862                subscription_id,
2863                ..
2864            } => f
2865                .debug_struct("Effect::Observation")
2866                .field("entity_id", entity_id)
2867                .field("subscription_id", subscription_id)
2868                .finish(),
2869            Effect::ModelNotification { model_id } => f
2870                .debug_struct("Effect::ModelNotification")
2871                .field("model_id", model_id)
2872                .finish(),
2873            Effect::ViewNotification { window_id, view_id } => f
2874                .debug_struct("Effect::ViewNotification")
2875                .field("window_id", window_id)
2876                .field("view_id", view_id)
2877                .finish(),
2878            Effect::GlobalNotification { type_id } => f
2879                .debug_struct("Effect::GlobalNotification")
2880                .field("type_id", type_id)
2881                .finish(),
2882            Effect::Deferred { .. } => f.debug_struct("Effect::Deferred").finish(),
2883            Effect::ModelRelease { model_id, .. } => f
2884                .debug_struct("Effect::ModelRelease")
2885                .field("model_id", model_id)
2886                .finish(),
2887            Effect::ViewRelease { view_id, .. } => f
2888                .debug_struct("Effect::ViewRelease")
2889                .field("view_id", view_id)
2890                .finish(),
2891            Effect::Focus { window_id, view_id } => f
2892                .debug_struct("Effect::Focus")
2893                .field("window_id", window_id)
2894                .field("view_id", view_id)
2895                .finish(),
2896            Effect::FocusObservation {
2897                view_id,
2898                subscription_id,
2899                ..
2900            } => f
2901                .debug_struct("Effect::FocusObservation")
2902                .field("view_id", view_id)
2903                .field("subscription_id", subscription_id)
2904                .finish(),
2905            Effect::ActionDispatchNotification { action_id, .. } => f
2906                .debug_struct("Effect::ActionDispatchNotification")
2907                .field("action_id", action_id)
2908                .finish(),
2909            Effect::ResizeWindow { window_id } => f
2910                .debug_struct("Effect::RefreshWindow")
2911                .field("window_id", window_id)
2912                .finish(),
2913            Effect::ActivateWindow {
2914                window_id,
2915                is_active,
2916            } => f
2917                .debug_struct("Effect::ActivateWindow")
2918                .field("window_id", window_id)
2919                .field("is_active", is_active)
2920                .finish(),
2921            Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
2922        }
2923    }
2924}
2925
2926pub trait AnyModel {
2927    fn as_any(&self) -> &dyn Any;
2928    fn as_any_mut(&mut self) -> &mut dyn Any;
2929    fn release(&mut self, cx: &mut MutableAppContext);
2930    fn app_will_quit(
2931        &mut self,
2932        cx: &mut MutableAppContext,
2933    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2934}
2935
2936impl<T> AnyModel for T
2937where
2938    T: Entity,
2939{
2940    fn as_any(&self) -> &dyn Any {
2941        self
2942    }
2943
2944    fn as_any_mut(&mut self) -> &mut dyn Any {
2945        self
2946    }
2947
2948    fn release(&mut self, cx: &mut MutableAppContext) {
2949        self.release(cx);
2950    }
2951
2952    fn app_will_quit(
2953        &mut self,
2954        cx: &mut MutableAppContext,
2955    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2956        self.app_will_quit(cx)
2957    }
2958}
2959
2960pub trait AnyView {
2961    fn as_any(&self) -> &dyn Any;
2962    fn as_any_mut(&mut self) -> &mut dyn Any;
2963    fn release(&mut self, cx: &mut MutableAppContext);
2964    fn app_will_quit(
2965        &mut self,
2966        cx: &mut MutableAppContext,
2967    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2968    fn ui_name(&self) -> &'static str;
2969    fn render<'a>(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox;
2970    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2971    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2972    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
2973    fn debug_json(&self, cx: &AppContext) -> serde_json::Value;
2974}
2975
2976impl<T> AnyView for T
2977where
2978    T: View,
2979{
2980    fn as_any(&self) -> &dyn Any {
2981        self
2982    }
2983
2984    fn as_any_mut(&mut self) -> &mut dyn Any {
2985        self
2986    }
2987
2988    fn release(&mut self, cx: &mut MutableAppContext) {
2989        self.release(cx);
2990    }
2991
2992    fn app_will_quit(
2993        &mut self,
2994        cx: &mut MutableAppContext,
2995    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2996        self.app_will_quit(cx)
2997    }
2998
2999    fn ui_name(&self) -> &'static str {
3000        T::ui_name()
3001    }
3002
3003    fn render<'a>(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox {
3004        View::render(self, &mut RenderContext::new(params, cx))
3005    }
3006
3007    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
3008        let mut cx = ViewContext::new(cx, window_id, view_id);
3009        View::on_focus(self, &mut cx);
3010    }
3011
3012    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
3013        let mut cx = ViewContext::new(cx, window_id, view_id);
3014        View::on_blur(self, &mut cx);
3015    }
3016
3017    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
3018        View::keymap_context(self, cx)
3019    }
3020
3021    fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
3022        View::debug_json(self, cx)
3023    }
3024}
3025
3026pub struct ModelContext<'a, T: ?Sized> {
3027    app: &'a mut MutableAppContext,
3028    model_id: usize,
3029    model_type: PhantomData<T>,
3030    halt_stream: bool,
3031}
3032
3033impl<'a, T: Entity> ModelContext<'a, T> {
3034    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
3035        Self {
3036            app,
3037            model_id,
3038            model_type: PhantomData,
3039            halt_stream: false,
3040        }
3041    }
3042
3043    pub fn background(&self) -> &Arc<executor::Background> {
3044        &self.app.cx.background
3045    }
3046
3047    pub fn halt_stream(&mut self) {
3048        self.halt_stream = true;
3049    }
3050
3051    pub fn model_id(&self) -> usize {
3052        self.model_id
3053    }
3054
3055    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
3056    where
3057        S: Entity,
3058        F: FnOnce(&mut ModelContext<S>) -> S,
3059    {
3060        self.app.add_model(build_model)
3061    }
3062
3063    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ModelContext<T>)) {
3064        let handle = self.handle();
3065        self.app.defer(move |cx| {
3066            handle.update(cx, |model, cx| {
3067                callback(model, cx);
3068            })
3069        })
3070    }
3071
3072    pub fn emit(&mut self, payload: T::Event) {
3073        self.app.pending_effects.push_back(Effect::Event {
3074            entity_id: self.model_id,
3075            payload: Box::new(payload),
3076        });
3077    }
3078
3079    pub fn notify(&mut self) {
3080        self.app.notify_model(self.model_id);
3081    }
3082
3083    pub fn subscribe<S: Entity, F>(
3084        &mut self,
3085        handle: &ModelHandle<S>,
3086        mut callback: F,
3087    ) -> Subscription
3088    where
3089        S::Event: 'static,
3090        F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
3091    {
3092        let subscriber = self.weak_handle();
3093        self.app
3094            .subscribe_internal(handle, move |emitter, event, cx| {
3095                if let Some(subscriber) = subscriber.upgrade(cx) {
3096                    subscriber.update(cx, |subscriber, cx| {
3097                        callback(subscriber, emitter, event, cx);
3098                    });
3099                    true
3100                } else {
3101                    false
3102                }
3103            })
3104    }
3105
3106    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
3107    where
3108        S: Entity,
3109        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
3110    {
3111        let observer = self.weak_handle();
3112        self.app.observe_internal(handle, move |observed, cx| {
3113            if let Some(observer) = observer.upgrade(cx) {
3114                observer.update(cx, |observer, cx| {
3115                    callback(observer, observed, cx);
3116                });
3117                true
3118            } else {
3119                false
3120            }
3121        })
3122    }
3123
3124    pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
3125    where
3126        G: Any,
3127        F: 'static + FnMut(&mut T, &mut ModelContext<T>),
3128    {
3129        let observer = self.weak_handle();
3130        self.app.observe_global::<G, _>(move |cx| {
3131            if let Some(observer) = observer.upgrade(cx) {
3132                observer.update(cx, |observer, cx| callback(observer, cx));
3133            }
3134        })
3135    }
3136
3137    pub fn observe_release<S, F>(
3138        &mut self,
3139        handle: &ModelHandle<S>,
3140        mut callback: F,
3141    ) -> Subscription
3142    where
3143        S: Entity,
3144        F: 'static + FnMut(&mut T, &S, &mut ModelContext<T>),
3145    {
3146        let observer = self.weak_handle();
3147        self.app.observe_release(handle, move |released, cx| {
3148            if let Some(observer) = observer.upgrade(cx) {
3149                observer.update(cx, |observer, cx| {
3150                    callback(observer, released, cx);
3151                });
3152            }
3153        })
3154    }
3155
3156    pub fn handle(&self) -> ModelHandle<T> {
3157        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
3158    }
3159
3160    pub fn weak_handle(&self) -> WeakModelHandle<T> {
3161        WeakModelHandle::new(self.model_id)
3162    }
3163
3164    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3165    where
3166        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
3167        Fut: 'static + Future<Output = S>,
3168        S: 'static,
3169    {
3170        let handle = self.handle();
3171        self.app.spawn(|cx| f(handle, cx))
3172    }
3173
3174    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3175    where
3176        F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
3177        Fut: 'static + Future<Output = S>,
3178        S: 'static,
3179    {
3180        let handle = self.weak_handle();
3181        self.app.spawn(|cx| f(handle, cx))
3182    }
3183}
3184
3185impl<M> AsRef<AppContext> for ModelContext<'_, M> {
3186    fn as_ref(&self) -> &AppContext {
3187        &self.app.cx
3188    }
3189}
3190
3191impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
3192    fn as_mut(&mut self) -> &mut MutableAppContext {
3193        self.app
3194    }
3195}
3196
3197impl<M> ReadModel for ModelContext<'_, M> {
3198    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3199        self.app.read_model(handle)
3200    }
3201}
3202
3203impl<M> UpdateModel for ModelContext<'_, M> {
3204    fn update_model<T: Entity, V>(
3205        &mut self,
3206        handle: &ModelHandle<T>,
3207        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
3208    ) -> V {
3209        self.app.update_model(handle, update)
3210    }
3211}
3212
3213impl<M> UpgradeModelHandle for ModelContext<'_, M> {
3214    fn upgrade_model_handle<T: Entity>(
3215        &self,
3216        handle: &WeakModelHandle<T>,
3217    ) -> Option<ModelHandle<T>> {
3218        self.cx.upgrade_model_handle(handle)
3219    }
3220
3221    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3222        self.cx.model_handle_is_upgradable(handle)
3223    }
3224
3225    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3226        self.cx.upgrade_any_model_handle(handle)
3227    }
3228}
3229
3230impl<M> Deref for ModelContext<'_, M> {
3231    type Target = MutableAppContext;
3232
3233    fn deref(&self) -> &Self::Target {
3234        &self.app
3235    }
3236}
3237
3238impl<M> DerefMut for ModelContext<'_, M> {
3239    fn deref_mut(&mut self) -> &mut Self::Target {
3240        &mut self.app
3241    }
3242}
3243
3244pub struct ViewContext<'a, T: ?Sized> {
3245    app: &'a mut MutableAppContext,
3246    window_id: usize,
3247    view_id: usize,
3248    view_type: PhantomData<T>,
3249}
3250
3251impl<'a, T: View> ViewContext<'a, T> {
3252    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
3253        Self {
3254            app,
3255            window_id,
3256            view_id,
3257            view_type: PhantomData,
3258        }
3259    }
3260
3261    pub fn handle(&self) -> ViewHandle<T> {
3262        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
3263    }
3264
3265    pub fn weak_handle(&self) -> WeakViewHandle<T> {
3266        WeakViewHandle::new(self.window_id, self.view_id)
3267    }
3268
3269    pub fn window_id(&self) -> usize {
3270        self.window_id
3271    }
3272
3273    pub fn view_id(&self) -> usize {
3274        self.view_id
3275    }
3276
3277    pub fn foreground(&self) -> &Rc<executor::Foreground> {
3278        self.app.foreground()
3279    }
3280
3281    pub fn background_executor(&self) -> &Arc<executor::Background> {
3282        &self.app.cx.background
3283    }
3284
3285    pub fn platform(&self) -> Arc<dyn Platform> {
3286        self.app.platform()
3287    }
3288
3289    pub fn prompt(
3290        &self,
3291        level: PromptLevel,
3292        msg: &str,
3293        answers: &[&str],
3294    ) -> oneshot::Receiver<usize> {
3295        self.app.prompt(self.window_id, level, msg, answers)
3296    }
3297
3298    pub fn prompt_for_paths(
3299        &self,
3300        options: PathPromptOptions,
3301    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
3302        self.app.prompt_for_paths(options)
3303    }
3304
3305    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
3306        self.app.prompt_for_new_path(directory)
3307    }
3308
3309    pub fn debug_elements(&self) -> crate::json::Value {
3310        self.app.debug_elements(self.window_id).unwrap()
3311    }
3312
3313    pub fn focus<S>(&mut self, handle: S)
3314    where
3315        S: Into<AnyViewHandle>,
3316    {
3317        let handle = handle.into();
3318        self.app.focus(handle.window_id, Some(handle.view_id));
3319    }
3320
3321    pub fn focus_self(&mut self) {
3322        self.app.focus(self.window_id, Some(self.view_id));
3323    }
3324
3325    pub fn is_self_focused(&self) -> bool {
3326        self.app.focused_view_id(self.window_id) == Some(self.view_id)
3327    }
3328
3329    pub fn blur(&mut self) {
3330        self.app.focus(self.window_id, None);
3331    }
3332
3333    pub fn set_window_title(&mut self, title: &str) {
3334        let window_id = self.window_id();
3335        if let Some((_, window)) = self.presenters_and_platform_windows.get_mut(&window_id) {
3336            window.set_title(title);
3337        }
3338    }
3339
3340    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
3341    where
3342        S: Entity,
3343        F: FnOnce(&mut ModelContext<S>) -> S,
3344    {
3345        self.app.add_model(build_model)
3346    }
3347
3348    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
3349    where
3350        S: View,
3351        F: FnOnce(&mut ViewContext<S>) -> S,
3352    {
3353        self.app.add_view(self.window_id, build_view)
3354    }
3355
3356    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
3357    where
3358        S: View,
3359        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
3360    {
3361        self.app.add_option_view(self.window_id, build_view)
3362    }
3363
3364    pub fn replace_root_view<V, F>(&mut self, build_root_view: F) -> ViewHandle<V>
3365    where
3366        V: View,
3367        F: FnOnce(&mut ViewContext<V>) -> V,
3368    {
3369        let window_id = self.window_id;
3370        self.update(|this| {
3371            let root_view = this.add_view(window_id, build_root_view);
3372            let window = this.cx.windows.get_mut(&window_id).unwrap();
3373            window.root_view = root_view.clone().into();
3374            window.focused_view_id = Some(root_view.id());
3375            root_view
3376        })
3377    }
3378
3379    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3380    where
3381        E: Entity,
3382        E::Event: 'static,
3383        H: Handle<E>,
3384        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
3385    {
3386        let subscriber = self.weak_handle();
3387        self.app
3388            .subscribe_internal(handle, move |emitter, event, cx| {
3389                if let Some(subscriber) = subscriber.upgrade(cx) {
3390                    subscriber.update(cx, |subscriber, cx| {
3391                        callback(subscriber, emitter, event, cx);
3392                    });
3393                    true
3394                } else {
3395                    false
3396                }
3397            })
3398    }
3399
3400    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3401    where
3402        E: Entity,
3403        H: Handle<E>,
3404        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
3405    {
3406        let observer = self.weak_handle();
3407        self.app.observe_internal(handle, move |observed, cx| {
3408            if let Some(observer) = observer.upgrade(cx) {
3409                observer.update(cx, |observer, cx| {
3410                    callback(observer, observed, cx);
3411                });
3412                true
3413            } else {
3414                false
3415            }
3416        })
3417    }
3418
3419    pub fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
3420    where
3421        F: 'static + FnMut(&mut T, ViewHandle<V>, &mut ViewContext<T>),
3422        V: View,
3423    {
3424        let observer = self.weak_handle();
3425        self.app.observe_focus(handle, move |observed, cx| {
3426            if let Some(observer) = observer.upgrade(cx) {
3427                observer.update(cx, |observer, cx| {
3428                    callback(observer, observed, cx);
3429                });
3430                true
3431            } else {
3432                false
3433            }
3434        })
3435    }
3436
3437    pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3438    where
3439        E: Entity,
3440        H: Handle<E>,
3441        F: 'static + FnMut(&mut T, &E, &mut ViewContext<T>),
3442    {
3443        let observer = self.weak_handle();
3444        self.app.observe_release(handle, move |released, cx| {
3445            if let Some(observer) = observer.upgrade(cx) {
3446                observer.update(cx, |observer, cx| {
3447                    callback(observer, released, cx);
3448                });
3449            }
3450        })
3451    }
3452
3453    pub fn observe_actions<F>(&mut self, mut callback: F) -> Subscription
3454    where
3455        F: 'static + FnMut(&mut T, TypeId, &mut ViewContext<T>),
3456    {
3457        let observer = self.weak_handle();
3458        self.app.observe_actions(move |action_id, cx| {
3459            if let Some(observer) = observer.upgrade(cx) {
3460                observer.update(cx, |observer, cx| {
3461                    callback(observer, action_id, cx);
3462                });
3463            }
3464        })
3465    }
3466
3467    pub fn emit(&mut self, payload: T::Event) {
3468        self.app.pending_effects.push_back(Effect::Event {
3469            entity_id: self.view_id,
3470            payload: Box::new(payload),
3471        });
3472    }
3473
3474    pub fn notify(&mut self) {
3475        self.app.notify_view(self.window_id, self.view_id);
3476    }
3477
3478    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>)) {
3479        let handle = self.handle();
3480        self.app.defer(move |cx| {
3481            handle.update(cx, |view, cx| {
3482                callback(view, cx);
3483            })
3484        })
3485    }
3486
3487    pub fn after_window_update(
3488        &mut self,
3489        callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>),
3490    ) {
3491        let handle = self.handle();
3492        self.app.after_window_update(move |cx| {
3493            handle.update(cx, |view, cx| {
3494                callback(view, cx);
3495            })
3496        })
3497    }
3498
3499    pub fn propagate_action(&mut self) {
3500        self.app.halt_action_dispatch = false;
3501    }
3502
3503    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3504    where
3505        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
3506        Fut: 'static + Future<Output = S>,
3507        S: 'static,
3508    {
3509        let handle = self.handle();
3510        self.app.spawn(|cx| f(handle, cx))
3511    }
3512
3513    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3514    where
3515        F: FnOnce(WeakViewHandle<T>, AsyncAppContext) -> Fut,
3516        Fut: 'static + Future<Output = S>,
3517        S: 'static,
3518    {
3519        let handle = self.weak_handle();
3520        self.app.spawn(|cx| f(handle, cx))
3521    }
3522}
3523
3524pub struct RenderParams {
3525    pub window_id: usize,
3526    pub view_id: usize,
3527    pub titlebar_height: f32,
3528    pub hovered_region_ids: HashSet<MouseRegionId>,
3529    pub clicked_region_id: Option<MouseRegionId>,
3530    pub right_clicked_region_id: Option<MouseRegionId>,
3531    pub refreshing: bool,
3532}
3533
3534pub struct RenderContext<'a, T: View> {
3535    pub(crate) window_id: usize,
3536    pub(crate) view_id: usize,
3537    pub(crate) view_type: PhantomData<T>,
3538    pub(crate) hovered_region_ids: HashSet<MouseRegionId>,
3539    pub(crate) clicked_region_id: Option<MouseRegionId>,
3540    pub(crate) right_clicked_region_id: Option<MouseRegionId>,
3541    pub app: &'a mut MutableAppContext,
3542    pub titlebar_height: f32,
3543    pub refreshing: bool,
3544}
3545
3546#[derive(Clone, Copy, Default)]
3547pub struct MouseState {
3548    pub hovered: bool,
3549    pub clicked: bool,
3550    pub right_clicked: bool,
3551}
3552
3553impl<'a, V: View> RenderContext<'a, V> {
3554    fn new(params: RenderParams, app: &'a mut MutableAppContext) -> Self {
3555        Self {
3556            app,
3557            window_id: params.window_id,
3558            view_id: params.view_id,
3559            view_type: PhantomData,
3560            titlebar_height: params.titlebar_height,
3561            hovered_region_ids: params.hovered_region_ids.clone(),
3562            clicked_region_id: params.clicked_region_id,
3563            right_clicked_region_id: params.right_clicked_region_id,
3564            refreshing: params.refreshing,
3565        }
3566    }
3567
3568    pub fn handle(&self) -> WeakViewHandle<V> {
3569        WeakViewHandle::new(self.window_id, self.view_id)
3570    }
3571
3572    pub fn view_id(&self) -> usize {
3573        self.view_id
3574    }
3575
3576    pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
3577        let region_id = MouseRegionId {
3578            view_id: self.view_id,
3579            discriminant: (TypeId::of::<Tag>(), region_id),
3580        };
3581        MouseState {
3582            hovered: self.hovered_region_ids.contains(&region_id),
3583            clicked: self.clicked_region_id == Some(region_id),
3584            right_clicked: self.right_clicked_region_id == Some(region_id),
3585        }
3586    }
3587
3588    pub fn element_state<Tag: 'static, T: 'static + Default>(
3589        &mut self,
3590        element_id: usize,
3591    ) -> ElementStateHandle<T> {
3592        let id = ElementStateId {
3593            view_id: self.view_id(),
3594            element_id,
3595            tag: TypeId::of::<Tag>(),
3596        };
3597        self.cx
3598            .element_states
3599            .entry(id)
3600            .or_insert_with(|| Box::new(T::default()));
3601        ElementStateHandle::new(id, self.frame_count, &self.cx.ref_counts)
3602    }
3603}
3604
3605impl AsRef<AppContext> for &AppContext {
3606    fn as_ref(&self) -> &AppContext {
3607        self
3608    }
3609}
3610
3611impl<V: View> Deref for RenderContext<'_, V> {
3612    type Target = MutableAppContext;
3613
3614    fn deref(&self) -> &Self::Target {
3615        self.app
3616    }
3617}
3618
3619impl<V: View> DerefMut for RenderContext<'_, V> {
3620    fn deref_mut(&mut self) -> &mut Self::Target {
3621        self.app
3622    }
3623}
3624
3625impl<V: View> ReadModel for RenderContext<'_, V> {
3626    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3627        self.app.read_model(handle)
3628    }
3629}
3630
3631impl<V: View> UpdateModel for RenderContext<'_, V> {
3632    fn update_model<T: Entity, O>(
3633        &mut self,
3634        handle: &ModelHandle<T>,
3635        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3636    ) -> O {
3637        self.app.update_model(handle, update)
3638    }
3639}
3640
3641impl<V: View> ReadView for RenderContext<'_, V> {
3642    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3643        self.app.read_view(handle)
3644    }
3645}
3646
3647impl<M> AsRef<AppContext> for ViewContext<'_, M> {
3648    fn as_ref(&self) -> &AppContext {
3649        &self.app.cx
3650    }
3651}
3652
3653impl<M> Deref for ViewContext<'_, M> {
3654    type Target = MutableAppContext;
3655
3656    fn deref(&self) -> &Self::Target {
3657        &self.app
3658    }
3659}
3660
3661impl<M> DerefMut for ViewContext<'_, M> {
3662    fn deref_mut(&mut self) -> &mut Self::Target {
3663        &mut self.app
3664    }
3665}
3666
3667impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
3668    fn as_mut(&mut self) -> &mut MutableAppContext {
3669        self.app
3670    }
3671}
3672
3673impl<V> ReadModel for ViewContext<'_, V> {
3674    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3675        self.app.read_model(handle)
3676    }
3677}
3678
3679impl<V> UpgradeModelHandle for ViewContext<'_, V> {
3680    fn upgrade_model_handle<T: Entity>(
3681        &self,
3682        handle: &WeakModelHandle<T>,
3683    ) -> Option<ModelHandle<T>> {
3684        self.cx.upgrade_model_handle(handle)
3685    }
3686
3687    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3688        self.cx.model_handle_is_upgradable(handle)
3689    }
3690
3691    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3692        self.cx.upgrade_any_model_handle(handle)
3693    }
3694}
3695
3696impl<V> UpgradeViewHandle for ViewContext<'_, V> {
3697    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3698        self.cx.upgrade_view_handle(handle)
3699    }
3700
3701    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3702        self.cx.upgrade_any_view_handle(handle)
3703    }
3704}
3705
3706impl<V: View> UpgradeViewHandle for RenderContext<'_, V> {
3707    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
3708        self.cx.upgrade_view_handle(handle)
3709    }
3710
3711    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
3712        self.cx.upgrade_any_view_handle(handle)
3713    }
3714}
3715
3716impl<V: View> UpdateModel for ViewContext<'_, V> {
3717    fn update_model<T: Entity, O>(
3718        &mut self,
3719        handle: &ModelHandle<T>,
3720        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
3721    ) -> O {
3722        self.app.update_model(handle, update)
3723    }
3724}
3725
3726impl<V: View> ReadView for ViewContext<'_, V> {
3727    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
3728        self.app.read_view(handle)
3729    }
3730}
3731
3732impl<V: View> UpdateView for ViewContext<'_, V> {
3733    fn update_view<T, S>(
3734        &mut self,
3735        handle: &ViewHandle<T>,
3736        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
3737    ) -> S
3738    where
3739        T: View,
3740    {
3741        self.app.update_view(handle, update)
3742    }
3743}
3744
3745pub trait Handle<T> {
3746    type Weak: 'static;
3747    fn id(&self) -> usize;
3748    fn location(&self) -> EntityLocation;
3749    fn downgrade(&self) -> Self::Weak;
3750    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3751    where
3752        Self: Sized;
3753}
3754
3755pub trait WeakHandle {
3756    fn id(&self) -> usize;
3757}
3758
3759#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3760pub enum EntityLocation {
3761    Model(usize),
3762    View(usize, usize),
3763}
3764
3765pub struct ModelHandle<T: Entity> {
3766    model_id: usize,
3767    model_type: PhantomData<T>,
3768    ref_counts: Arc<Mutex<RefCounts>>,
3769
3770    #[cfg(any(test, feature = "test-support"))]
3771    handle_id: usize,
3772}
3773
3774impl<T: Entity> ModelHandle<T> {
3775    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3776        ref_counts.lock().inc_model(model_id);
3777
3778        #[cfg(any(test, feature = "test-support"))]
3779        let handle_id = ref_counts
3780            .lock()
3781            .leak_detector
3782            .lock()
3783            .handle_created(Some(type_name::<T>()), model_id);
3784
3785        Self {
3786            model_id,
3787            model_type: PhantomData,
3788            ref_counts: ref_counts.clone(),
3789
3790            #[cfg(any(test, feature = "test-support"))]
3791            handle_id,
3792        }
3793    }
3794
3795    pub fn downgrade(&self) -> WeakModelHandle<T> {
3796        WeakModelHandle::new(self.model_id)
3797    }
3798
3799    pub fn id(&self) -> usize {
3800        self.model_id
3801    }
3802
3803    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
3804        cx.read_model(self)
3805    }
3806
3807    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
3808    where
3809        C: ReadModelWith,
3810        F: FnOnce(&T, &AppContext) -> S,
3811    {
3812        let mut read = Some(read);
3813        cx.read_model_with(self, &mut |model, cx| {
3814            let read = read.take().unwrap();
3815            read(model, cx)
3816        })
3817    }
3818
3819    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3820    where
3821        C: UpdateModel,
3822        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
3823    {
3824        let mut update = Some(update);
3825        cx.update_model(self, &mut |model, cx| {
3826            let update = update.take().unwrap();
3827            update(model, cx)
3828        })
3829    }
3830
3831    #[cfg(any(test, feature = "test-support"))]
3832    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
3833        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3834        let mut cx = cx.cx.borrow_mut();
3835        let subscription = cx.observe(self, move |_, _| {
3836            tx.unbounded_send(()).ok();
3837        });
3838
3839        let duration = if std::env::var("CI").is_ok() {
3840            Duration::from_secs(5)
3841        } else {
3842            Duration::from_secs(1)
3843        };
3844
3845        async move {
3846            let notification = crate::util::timeout(duration, rx.next())
3847                .await
3848                .expect("next notification timed out");
3849            drop(subscription);
3850            notification.expect("model dropped while test was waiting for its next notification")
3851        }
3852    }
3853
3854    #[cfg(any(test, feature = "test-support"))]
3855    pub fn next_event(&self, cx: &TestAppContext) -> impl Future<Output = T::Event>
3856    where
3857        T::Event: Clone,
3858    {
3859        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3860        let mut cx = cx.cx.borrow_mut();
3861        let subscription = cx.subscribe(self, move |_, event, _| {
3862            tx.unbounded_send(event.clone()).ok();
3863        });
3864
3865        let duration = if std::env::var("CI").is_ok() {
3866            Duration::from_secs(5)
3867        } else {
3868            Duration::from_secs(1)
3869        };
3870
3871        cx.foreground.start_waiting();
3872        async move {
3873            let event = crate::util::timeout(duration, rx.next())
3874                .await
3875                .expect("next event timed out");
3876            drop(subscription);
3877            event.expect("model dropped while test was waiting for its next event")
3878        }
3879    }
3880
3881    #[cfg(any(test, feature = "test-support"))]
3882    pub fn condition(
3883        &self,
3884        cx: &TestAppContext,
3885        mut predicate: impl FnMut(&T, &AppContext) -> bool,
3886    ) -> impl Future<Output = ()> {
3887        let (tx, mut rx) = futures::channel::mpsc::unbounded();
3888
3889        let mut cx = cx.cx.borrow_mut();
3890        let subscriptions = (
3891            cx.observe(self, {
3892                let tx = tx.clone();
3893                move |_, _| {
3894                    tx.unbounded_send(()).ok();
3895                }
3896            }),
3897            cx.subscribe(self, {
3898                let tx = tx.clone();
3899                move |_, _, _| {
3900                    tx.unbounded_send(()).ok();
3901                }
3902            }),
3903        );
3904
3905        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
3906        let handle = self.downgrade();
3907        let duration = if std::env::var("CI").is_ok() {
3908            Duration::from_secs(5)
3909        } else {
3910            Duration::from_secs(1)
3911        };
3912
3913        async move {
3914            crate::util::timeout(duration, async move {
3915                loop {
3916                    {
3917                        let cx = cx.borrow();
3918                        let cx = cx.as_ref();
3919                        if predicate(
3920                            handle
3921                                .upgrade(cx)
3922                                .expect("model dropped with pending condition")
3923                                .read(cx),
3924                            cx,
3925                        ) {
3926                            break;
3927                        }
3928                    }
3929
3930                    cx.borrow().foreground().start_waiting();
3931                    rx.next()
3932                        .await
3933                        .expect("model dropped with pending condition");
3934                    cx.borrow().foreground().finish_waiting();
3935                }
3936            })
3937            .await
3938            .expect("condition timed out");
3939            drop(subscriptions);
3940        }
3941    }
3942}
3943
3944impl<T: Entity> Clone for ModelHandle<T> {
3945    fn clone(&self) -> Self {
3946        Self::new(self.model_id, &self.ref_counts)
3947    }
3948}
3949
3950impl<T: Entity> PartialEq for ModelHandle<T> {
3951    fn eq(&self, other: &Self) -> bool {
3952        self.model_id == other.model_id
3953    }
3954}
3955
3956impl<T: Entity> Eq for ModelHandle<T> {}
3957
3958impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
3959    fn eq(&self, other: &WeakModelHandle<T>) -> bool {
3960        self.model_id == other.model_id
3961    }
3962}
3963
3964impl<T: Entity> Hash for ModelHandle<T> {
3965    fn hash<H: Hasher>(&self, state: &mut H) {
3966        self.model_id.hash(state);
3967    }
3968}
3969
3970impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
3971    fn borrow(&self) -> &usize {
3972        &self.model_id
3973    }
3974}
3975
3976impl<T: Entity> Debug for ModelHandle<T> {
3977    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3978        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
3979            .field(&self.model_id)
3980            .finish()
3981    }
3982}
3983
3984unsafe impl<T: Entity> Send for ModelHandle<T> {}
3985unsafe impl<T: Entity> Sync for ModelHandle<T> {}
3986
3987impl<T: Entity> Drop for ModelHandle<T> {
3988    fn drop(&mut self) {
3989        let mut ref_counts = self.ref_counts.lock();
3990        ref_counts.dec_model(self.model_id);
3991
3992        #[cfg(any(test, feature = "test-support"))]
3993        ref_counts
3994            .leak_detector
3995            .lock()
3996            .handle_dropped(self.model_id, self.handle_id);
3997    }
3998}
3999
4000impl<T: Entity> Handle<T> for ModelHandle<T> {
4001    type Weak = WeakModelHandle<T>;
4002
4003    fn id(&self) -> usize {
4004        self.model_id
4005    }
4006
4007    fn location(&self) -> EntityLocation {
4008        EntityLocation::Model(self.model_id)
4009    }
4010
4011    fn downgrade(&self) -> Self::Weak {
4012        self.downgrade()
4013    }
4014
4015    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4016    where
4017        Self: Sized,
4018    {
4019        weak.upgrade(cx)
4020    }
4021}
4022
4023pub struct WeakModelHandle<T> {
4024    model_id: usize,
4025    model_type: PhantomData<T>,
4026}
4027
4028impl<T> WeakHandle for WeakModelHandle<T> {
4029    fn id(&self) -> usize {
4030        self.model_id
4031    }
4032}
4033
4034unsafe impl<T> Send for WeakModelHandle<T> {}
4035unsafe impl<T> Sync for WeakModelHandle<T> {}
4036
4037impl<T: Entity> WeakModelHandle<T> {
4038    fn new(model_id: usize) -> Self {
4039        Self {
4040            model_id,
4041            model_type: PhantomData,
4042        }
4043    }
4044
4045    pub fn id(&self) -> usize {
4046        self.model_id
4047    }
4048
4049    pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
4050        cx.model_handle_is_upgradable(self)
4051    }
4052
4053    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
4054        cx.upgrade_model_handle(self)
4055    }
4056}
4057
4058impl<T> Hash for WeakModelHandle<T> {
4059    fn hash<H: Hasher>(&self, state: &mut H) {
4060        self.model_id.hash(state)
4061    }
4062}
4063
4064impl<T> PartialEq for WeakModelHandle<T> {
4065    fn eq(&self, other: &Self) -> bool {
4066        self.model_id == other.model_id
4067    }
4068}
4069
4070impl<T> Eq for WeakModelHandle<T> {}
4071
4072impl<T> Clone for WeakModelHandle<T> {
4073    fn clone(&self) -> Self {
4074        Self {
4075            model_id: self.model_id,
4076            model_type: PhantomData,
4077        }
4078    }
4079}
4080
4081impl<T> Copy for WeakModelHandle<T> {}
4082
4083pub struct ViewHandle<T> {
4084    window_id: usize,
4085    view_id: usize,
4086    view_type: PhantomData<T>,
4087    ref_counts: Arc<Mutex<RefCounts>>,
4088    #[cfg(any(test, feature = "test-support"))]
4089    handle_id: usize,
4090}
4091
4092impl<T: View> ViewHandle<T> {
4093    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4094        ref_counts.lock().inc_view(window_id, view_id);
4095        #[cfg(any(test, feature = "test-support"))]
4096        let handle_id = ref_counts
4097            .lock()
4098            .leak_detector
4099            .lock()
4100            .handle_created(Some(type_name::<T>()), view_id);
4101
4102        Self {
4103            window_id,
4104            view_id,
4105            view_type: PhantomData,
4106            ref_counts: ref_counts.clone(),
4107
4108            #[cfg(any(test, feature = "test-support"))]
4109            handle_id,
4110        }
4111    }
4112
4113    pub fn downgrade(&self) -> WeakViewHandle<T> {
4114        WeakViewHandle::new(self.window_id, self.view_id)
4115    }
4116
4117    pub fn window_id(&self) -> usize {
4118        self.window_id
4119    }
4120
4121    pub fn id(&self) -> usize {
4122        self.view_id
4123    }
4124
4125    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
4126        cx.read_view(self)
4127    }
4128
4129    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
4130    where
4131        C: ReadViewWith,
4132        F: FnOnce(&T, &AppContext) -> S,
4133    {
4134        let mut read = Some(read);
4135        cx.read_view_with(self, &mut |view, cx| {
4136            let read = read.take().unwrap();
4137            read(view, cx)
4138        })
4139    }
4140
4141    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
4142    where
4143        C: UpdateView,
4144        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
4145    {
4146        let mut update = Some(update);
4147        cx.update_view(self, &mut |view, cx| {
4148            let update = update.take().unwrap();
4149            update(view, cx)
4150        })
4151    }
4152
4153    pub fn defer<C, F>(&self, cx: &mut C, update: F)
4154    where
4155        C: AsMut<MutableAppContext>,
4156        F: 'static + FnOnce(&mut T, &mut ViewContext<T>),
4157    {
4158        let this = self.clone();
4159        cx.as_mut().defer(move |cx| {
4160            this.update(cx, |view, cx| update(view, cx));
4161        });
4162    }
4163
4164    pub fn is_focused(&self, cx: &AppContext) -> bool {
4165        cx.focused_view_id(self.window_id)
4166            .map_or(false, |focused_id| focused_id == self.view_id)
4167    }
4168
4169    #[cfg(any(test, feature = "test-support"))]
4170    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
4171        use postage::prelude::{Sink as _, Stream as _};
4172
4173        let (mut tx, mut rx) = postage::mpsc::channel(1);
4174        let mut cx = cx.cx.borrow_mut();
4175        let subscription = cx.observe(self, move |_, _| {
4176            tx.try_send(()).ok();
4177        });
4178
4179        let duration = if std::env::var("CI").is_ok() {
4180            Duration::from_secs(5)
4181        } else {
4182            Duration::from_secs(1)
4183        };
4184
4185        async move {
4186            let notification = crate::util::timeout(duration, rx.recv())
4187                .await
4188                .expect("next notification timed out");
4189            drop(subscription);
4190            notification.expect("model dropped while test was waiting for its next notification")
4191        }
4192    }
4193
4194    #[cfg(any(test, feature = "test-support"))]
4195    pub fn condition(
4196        &self,
4197        cx: &TestAppContext,
4198        mut predicate: impl FnMut(&T, &AppContext) -> bool,
4199    ) -> impl Future<Output = ()> {
4200        use postage::prelude::{Sink as _, Stream as _};
4201
4202        let (tx, mut rx) = postage::mpsc::channel(1024);
4203
4204        let mut cx = cx.cx.borrow_mut();
4205        let subscriptions = self.update(&mut *cx, |_, cx| {
4206            (
4207                cx.observe(self, {
4208                    let mut tx = tx.clone();
4209                    move |_, _, _| {
4210                        tx.blocking_send(()).ok();
4211                    }
4212                }),
4213                cx.subscribe(self, {
4214                    let mut tx = tx.clone();
4215                    move |_, _, _, _| {
4216                        tx.blocking_send(()).ok();
4217                    }
4218                }),
4219            )
4220        });
4221
4222        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
4223        let handle = self.downgrade();
4224        let duration = if std::env::var("CI").is_ok() {
4225            Duration::from_secs(2)
4226        } else {
4227            Duration::from_millis(500)
4228        };
4229
4230        async move {
4231            crate::util::timeout(duration, async move {
4232                loop {
4233                    {
4234                        let cx = cx.borrow();
4235                        let cx = cx.as_ref();
4236                        if predicate(
4237                            handle
4238                                .upgrade(cx)
4239                                .expect("view dropped with pending condition")
4240                                .read(cx),
4241                            cx,
4242                        ) {
4243                            break;
4244                        }
4245                    }
4246
4247                    cx.borrow().foreground().start_waiting();
4248                    rx.recv()
4249                        .await
4250                        .expect("view dropped with pending condition");
4251                    cx.borrow().foreground().finish_waiting();
4252                }
4253            })
4254            .await
4255            .expect("condition timed out");
4256            drop(subscriptions);
4257        }
4258    }
4259}
4260
4261impl<T: View> Clone for ViewHandle<T> {
4262    fn clone(&self) -> Self {
4263        ViewHandle::new(self.window_id, self.view_id, &self.ref_counts)
4264    }
4265}
4266
4267impl<T> PartialEq for ViewHandle<T> {
4268    fn eq(&self, other: &Self) -> bool {
4269        self.window_id == other.window_id && self.view_id == other.view_id
4270    }
4271}
4272
4273impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
4274    fn eq(&self, other: &WeakViewHandle<T>) -> bool {
4275        self.window_id == other.window_id && self.view_id == other.view_id
4276    }
4277}
4278
4279impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
4280    fn eq(&self, other: &ViewHandle<T>) -> bool {
4281        self.window_id == other.window_id && self.view_id == other.view_id
4282    }
4283}
4284
4285impl<T> Eq for ViewHandle<T> {}
4286
4287impl<T> Hash for ViewHandle<T> {
4288    fn hash<H: Hasher>(&self, state: &mut H) {
4289        self.window_id.hash(state);
4290        self.view_id.hash(state);
4291    }
4292}
4293
4294impl<T> Debug for ViewHandle<T> {
4295    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4296        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
4297            .field("window_id", &self.window_id)
4298            .field("view_id", &self.view_id)
4299            .finish()
4300    }
4301}
4302
4303impl<T> Drop for ViewHandle<T> {
4304    fn drop(&mut self) {
4305        self.ref_counts
4306            .lock()
4307            .dec_view(self.window_id, self.view_id);
4308        #[cfg(any(test, feature = "test-support"))]
4309        self.ref_counts
4310            .lock()
4311            .leak_detector
4312            .lock()
4313            .handle_dropped(self.view_id, self.handle_id);
4314    }
4315}
4316
4317impl<T: View> Handle<T> for ViewHandle<T> {
4318    type Weak = WeakViewHandle<T>;
4319
4320    fn id(&self) -> usize {
4321        self.view_id
4322    }
4323
4324    fn location(&self) -> EntityLocation {
4325        EntityLocation::View(self.window_id, self.view_id)
4326    }
4327
4328    fn downgrade(&self) -> Self::Weak {
4329        self.downgrade()
4330    }
4331
4332    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4333    where
4334        Self: Sized,
4335    {
4336        weak.upgrade(cx)
4337    }
4338}
4339
4340pub struct AnyViewHandle {
4341    window_id: usize,
4342    view_id: usize,
4343    view_type: TypeId,
4344    ref_counts: Arc<Mutex<RefCounts>>,
4345
4346    #[cfg(any(test, feature = "test-support"))]
4347    handle_id: usize,
4348}
4349
4350impl AnyViewHandle {
4351    fn new(
4352        window_id: usize,
4353        view_id: usize,
4354        view_type: TypeId,
4355        ref_counts: Arc<Mutex<RefCounts>>,
4356    ) -> Self {
4357        ref_counts.lock().inc_view(window_id, view_id);
4358
4359        #[cfg(any(test, feature = "test-support"))]
4360        let handle_id = ref_counts
4361            .lock()
4362            .leak_detector
4363            .lock()
4364            .handle_created(None, view_id);
4365
4366        Self {
4367            window_id,
4368            view_id,
4369            view_type,
4370            ref_counts,
4371            #[cfg(any(test, feature = "test-support"))]
4372            handle_id,
4373        }
4374    }
4375
4376    pub fn id(&self) -> usize {
4377        self.view_id
4378    }
4379
4380    pub fn is<T: 'static>(&self) -> bool {
4381        TypeId::of::<T>() == self.view_type
4382    }
4383
4384    pub fn is_focused(&self, cx: &AppContext) -> bool {
4385        cx.focused_view_id(self.window_id)
4386            .map_or(false, |focused_id| focused_id == self.view_id)
4387    }
4388
4389    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4390        if self.is::<T>() {
4391            let result = Some(ViewHandle {
4392                window_id: self.window_id,
4393                view_id: self.view_id,
4394                ref_counts: self.ref_counts.clone(),
4395                view_type: PhantomData,
4396                #[cfg(any(test, feature = "test-support"))]
4397                handle_id: self.handle_id,
4398            });
4399            unsafe {
4400                Arc::decrement_strong_count(&self.ref_counts);
4401            }
4402            std::mem::forget(self);
4403            result
4404        } else {
4405            None
4406        }
4407    }
4408
4409    pub fn downgrade(&self) -> AnyWeakViewHandle {
4410        AnyWeakViewHandle {
4411            window_id: self.window_id,
4412            view_id: self.view_id,
4413            view_type: self.view_type,
4414        }
4415    }
4416
4417    pub fn view_type(&self) -> TypeId {
4418        self.view_type
4419    }
4420
4421    pub fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
4422        cx.views
4423            .get(&(self.window_id, self.view_id))
4424            .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4425    }
4426}
4427
4428impl Clone for AnyViewHandle {
4429    fn clone(&self) -> Self {
4430        Self::new(
4431            self.window_id,
4432            self.view_id,
4433            self.view_type,
4434            self.ref_counts.clone(),
4435        )
4436    }
4437}
4438
4439impl From<&AnyViewHandle> for AnyViewHandle {
4440    fn from(handle: &AnyViewHandle) -> Self {
4441        handle.clone()
4442    }
4443}
4444
4445impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
4446    fn from(handle: &ViewHandle<T>) -> Self {
4447        Self::new(
4448            handle.window_id,
4449            handle.view_id,
4450            TypeId::of::<T>(),
4451            handle.ref_counts.clone(),
4452        )
4453    }
4454}
4455
4456impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
4457    fn from(handle: ViewHandle<T>) -> Self {
4458        let any_handle = AnyViewHandle {
4459            window_id: handle.window_id,
4460            view_id: handle.view_id,
4461            view_type: TypeId::of::<T>(),
4462            ref_counts: handle.ref_counts.clone(),
4463            #[cfg(any(test, feature = "test-support"))]
4464            handle_id: handle.handle_id,
4465        };
4466        unsafe {
4467            Arc::decrement_strong_count(&handle.ref_counts);
4468        }
4469        std::mem::forget(handle);
4470        any_handle
4471    }
4472}
4473
4474impl Drop for AnyViewHandle {
4475    fn drop(&mut self) {
4476        self.ref_counts
4477            .lock()
4478            .dec_view(self.window_id, self.view_id);
4479        #[cfg(any(test, feature = "test-support"))]
4480        self.ref_counts
4481            .lock()
4482            .leak_detector
4483            .lock()
4484            .handle_dropped(self.view_id, self.handle_id);
4485    }
4486}
4487
4488pub struct AnyModelHandle {
4489    model_id: usize,
4490    model_type: TypeId,
4491    ref_counts: Arc<Mutex<RefCounts>>,
4492
4493    #[cfg(any(test, feature = "test-support"))]
4494    handle_id: usize,
4495}
4496
4497impl AnyModelHandle {
4498    fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4499        ref_counts.lock().inc_model(model_id);
4500
4501        #[cfg(any(test, feature = "test-support"))]
4502        let handle_id = ref_counts
4503            .lock()
4504            .leak_detector
4505            .lock()
4506            .handle_created(None, model_id);
4507
4508        Self {
4509            model_id,
4510            model_type,
4511            ref_counts,
4512
4513            #[cfg(any(test, feature = "test-support"))]
4514            handle_id,
4515        }
4516    }
4517
4518    pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4519        if self.is::<T>() {
4520            let result = Some(ModelHandle {
4521                model_id: self.model_id,
4522                model_type: PhantomData,
4523                ref_counts: self.ref_counts.clone(),
4524
4525                #[cfg(any(test, feature = "test-support"))]
4526                handle_id: self.handle_id,
4527            });
4528            unsafe {
4529                Arc::decrement_strong_count(&self.ref_counts);
4530            }
4531            std::mem::forget(self);
4532            result
4533        } else {
4534            None
4535        }
4536    }
4537
4538    pub fn downgrade(&self) -> AnyWeakModelHandle {
4539        AnyWeakModelHandle {
4540            model_id: self.model_id,
4541            model_type: self.model_type,
4542        }
4543    }
4544
4545    pub fn is<T: Entity>(&self) -> bool {
4546        self.model_type == TypeId::of::<T>()
4547    }
4548
4549    pub fn model_type(&self) -> TypeId {
4550        self.model_type
4551    }
4552}
4553
4554impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
4555    fn from(handle: ModelHandle<T>) -> Self {
4556        Self::new(
4557            handle.model_id,
4558            TypeId::of::<T>(),
4559            handle.ref_counts.clone(),
4560        )
4561    }
4562}
4563
4564impl Clone for AnyModelHandle {
4565    fn clone(&self) -> Self {
4566        Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4567    }
4568}
4569
4570impl Drop for AnyModelHandle {
4571    fn drop(&mut self) {
4572        let mut ref_counts = self.ref_counts.lock();
4573        ref_counts.dec_model(self.model_id);
4574
4575        #[cfg(any(test, feature = "test-support"))]
4576        ref_counts
4577            .leak_detector
4578            .lock()
4579            .handle_dropped(self.model_id, self.handle_id);
4580    }
4581}
4582
4583pub struct AnyWeakModelHandle {
4584    model_id: usize,
4585    model_type: TypeId,
4586}
4587
4588impl AnyWeakModelHandle {
4589    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
4590        cx.upgrade_any_model_handle(self)
4591    }
4592}
4593
4594impl<T: Entity> From<WeakModelHandle<T>> for AnyWeakModelHandle {
4595    fn from(handle: WeakModelHandle<T>) -> Self {
4596        AnyWeakModelHandle {
4597            model_id: handle.model_id,
4598            model_type: TypeId::of::<T>(),
4599        }
4600    }
4601}
4602
4603pub struct WeakViewHandle<T> {
4604    window_id: usize,
4605    view_id: usize,
4606    view_type: PhantomData<T>,
4607}
4608
4609impl<T> WeakHandle for WeakViewHandle<T> {
4610    fn id(&self) -> usize {
4611        self.view_id
4612    }
4613}
4614
4615impl<T: View> WeakViewHandle<T> {
4616    fn new(window_id: usize, view_id: usize) -> Self {
4617        Self {
4618            window_id,
4619            view_id,
4620            view_type: PhantomData,
4621        }
4622    }
4623
4624    pub fn id(&self) -> usize {
4625        self.view_id
4626    }
4627
4628    pub fn window_id(&self) -> usize {
4629        self.window_id
4630    }
4631
4632    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
4633        cx.upgrade_view_handle(self)
4634    }
4635}
4636
4637impl<T> Clone for WeakViewHandle<T> {
4638    fn clone(&self) -> Self {
4639        Self {
4640            window_id: self.window_id,
4641            view_id: self.view_id,
4642            view_type: PhantomData,
4643        }
4644    }
4645}
4646
4647impl<T> PartialEq for WeakViewHandle<T> {
4648    fn eq(&self, other: &Self) -> bool {
4649        self.window_id == other.window_id && self.view_id == other.view_id
4650    }
4651}
4652
4653impl<T> Eq for WeakViewHandle<T> {}
4654
4655impl<T> Hash for WeakViewHandle<T> {
4656    fn hash<H: Hasher>(&self, state: &mut H) {
4657        self.window_id.hash(state);
4658        self.view_id.hash(state);
4659    }
4660}
4661
4662pub struct AnyWeakViewHandle {
4663    window_id: usize,
4664    view_id: usize,
4665    view_type: TypeId,
4666}
4667
4668impl AnyWeakViewHandle {
4669    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
4670        cx.upgrade_any_view_handle(self)
4671    }
4672}
4673
4674impl<T: View> From<WeakViewHandle<T>> for AnyWeakViewHandle {
4675    fn from(handle: WeakViewHandle<T>) -> Self {
4676        AnyWeakViewHandle {
4677            window_id: handle.window_id,
4678            view_id: handle.view_id,
4679            view_type: TypeId::of::<T>(),
4680        }
4681    }
4682}
4683
4684#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4685pub struct ElementStateId {
4686    view_id: usize,
4687    element_id: usize,
4688    tag: TypeId,
4689}
4690
4691pub struct ElementStateHandle<T> {
4692    value_type: PhantomData<T>,
4693    id: ElementStateId,
4694    ref_counts: Weak<Mutex<RefCounts>>,
4695}
4696
4697impl<T: 'static> ElementStateHandle<T> {
4698    fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4699        ref_counts.lock().inc_element_state(id, frame_id);
4700        Self {
4701            value_type: PhantomData,
4702            id,
4703            ref_counts: Arc::downgrade(ref_counts),
4704        }
4705    }
4706
4707    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4708        cx.element_states
4709            .get(&self.id)
4710            .unwrap()
4711            .downcast_ref()
4712            .unwrap()
4713    }
4714
4715    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4716    where
4717        C: DerefMut<Target = MutableAppContext>,
4718    {
4719        let mut element_state = cx.deref_mut().cx.element_states.remove(&self.id).unwrap();
4720        let result = f(element_state.downcast_mut().unwrap(), cx);
4721        cx.deref_mut()
4722            .cx
4723            .element_states
4724            .insert(self.id, element_state);
4725        result
4726    }
4727}
4728
4729impl<T> Drop for ElementStateHandle<T> {
4730    fn drop(&mut self) {
4731        if let Some(ref_counts) = self.ref_counts.upgrade() {
4732            ref_counts.lock().dec_element_state(self.id);
4733        }
4734    }
4735}
4736
4737#[must_use]
4738pub enum Subscription {
4739    Subscription {
4740        id: usize,
4741        entity_id: usize,
4742        subscriptions:
4743            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<SubscriptionCallback>>>>>>,
4744    },
4745    GlobalSubscription {
4746        id: usize,
4747        type_id: TypeId,
4748        subscriptions: Option<
4749            Weak<Mutex<HashMap<TypeId, BTreeMap<usize, Option<GlobalSubscriptionCallback>>>>>,
4750        >,
4751    },
4752    Observation {
4753        id: usize,
4754        entity_id: usize,
4755        observations:
4756            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<ObservationCallback>>>>>>,
4757    },
4758    GlobalObservation {
4759        id: usize,
4760        type_id: TypeId,
4761        observations: Option<
4762            Weak<Mutex<HashMap<TypeId, BTreeMap<usize, Option<GlobalObservationCallback>>>>>,
4763        >,
4764    },
4765    FocusObservation {
4766        id: usize,
4767        view_id: usize,
4768        observations:
4769            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, Option<FocusObservationCallback>>>>>>,
4770    },
4771    ReleaseObservation {
4772        id: usize,
4773        entity_id: usize,
4774        observations:
4775            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>>,
4776    },
4777    ActionObservation {
4778        id: usize,
4779        observations: Option<Weak<Mutex<BTreeMap<usize, ActionObservationCallback>>>>,
4780    },
4781}
4782
4783impl Subscription {
4784    pub fn detach(&mut self) {
4785        match self {
4786            Subscription::Subscription { subscriptions, .. } => {
4787                subscriptions.take();
4788            }
4789            Subscription::GlobalSubscription { subscriptions, .. } => {
4790                subscriptions.take();
4791            }
4792            Subscription::Observation { observations, .. } => {
4793                observations.take();
4794            }
4795            Subscription::GlobalObservation { observations, .. } => {
4796                observations.take();
4797            }
4798            Subscription::ReleaseObservation { observations, .. } => {
4799                observations.take();
4800            }
4801            Subscription::FocusObservation { observations, .. } => {
4802                observations.take();
4803            }
4804            Subscription::ActionObservation { observations, .. } => {
4805                observations.take();
4806            }
4807        }
4808    }
4809}
4810
4811impl Drop for Subscription {
4812    fn drop(&mut self) {
4813        match self {
4814            Subscription::Subscription {
4815                id,
4816                entity_id,
4817                subscriptions,
4818            } => {
4819                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
4820                    match subscriptions
4821                        .lock()
4822                        .entry(*entity_id)
4823                        .or_default()
4824                        .entry(*id)
4825                    {
4826                        btree_map::Entry::Vacant(entry) => {
4827                            entry.insert(None);
4828                        }
4829                        btree_map::Entry::Occupied(entry) => {
4830                            entry.remove();
4831                        }
4832                    }
4833                }
4834            }
4835            Subscription::GlobalSubscription {
4836                id,
4837                type_id,
4838                subscriptions,
4839            } => {
4840                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
4841                    match subscriptions.lock().entry(*type_id).or_default().entry(*id) {
4842                        btree_map::Entry::Vacant(entry) => {
4843                            entry.insert(None);
4844                        }
4845                        btree_map::Entry::Occupied(entry) => {
4846                            entry.remove();
4847                        }
4848                    }
4849                }
4850            }
4851            Subscription::Observation {
4852                id,
4853                entity_id,
4854                observations,
4855            } => {
4856                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4857                    match observations
4858                        .lock()
4859                        .entry(*entity_id)
4860                        .or_default()
4861                        .entry(*id)
4862                    {
4863                        btree_map::Entry::Vacant(entry) => {
4864                            entry.insert(None);
4865                        }
4866                        btree_map::Entry::Occupied(entry) => {
4867                            entry.remove();
4868                        }
4869                    }
4870                }
4871            }
4872            Subscription::GlobalObservation {
4873                id,
4874                type_id,
4875                observations,
4876            } => {
4877                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4878                    match observations.lock().entry(*type_id).or_default().entry(*id) {
4879                        collections::btree_map::Entry::Vacant(entry) => {
4880                            entry.insert(None);
4881                        }
4882                        collections::btree_map::Entry::Occupied(entry) => {
4883                            entry.remove();
4884                        }
4885                    }
4886                }
4887            }
4888            Subscription::ReleaseObservation {
4889                id,
4890                entity_id,
4891                observations,
4892            } => {
4893                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4894                    if let Some(observations) = observations.lock().get_mut(entity_id) {
4895                        observations.remove(id);
4896                    }
4897                }
4898            }
4899            Subscription::FocusObservation {
4900                id,
4901                view_id,
4902                observations,
4903            } => {
4904                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4905                    match observations.lock().entry(*view_id).or_default().entry(*id) {
4906                        btree_map::Entry::Vacant(entry) => {
4907                            entry.insert(None);
4908                        }
4909                        btree_map::Entry::Occupied(entry) => {
4910                            entry.remove();
4911                        }
4912                    }
4913                }
4914            }
4915            Subscription::ActionObservation { id, observations } => {
4916                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
4917                    observations.lock().remove(&id);
4918                }
4919            }
4920        }
4921    }
4922}
4923
4924lazy_static! {
4925    static ref LEAK_BACKTRACE: bool =
4926        std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty());
4927}
4928
4929#[cfg(any(test, feature = "test-support"))]
4930#[derive(Default)]
4931pub struct LeakDetector {
4932    next_handle_id: usize,
4933    handle_backtraces: HashMap<
4934        usize,
4935        (
4936            Option<&'static str>,
4937            HashMap<usize, Option<backtrace::Backtrace>>,
4938        ),
4939    >,
4940}
4941
4942#[cfg(any(test, feature = "test-support"))]
4943impl LeakDetector {
4944    fn handle_created(&mut self, type_name: Option<&'static str>, entity_id: usize) -> usize {
4945        let handle_id = post_inc(&mut self.next_handle_id);
4946        let entry = self.handle_backtraces.entry(entity_id).or_default();
4947        let backtrace = if *LEAK_BACKTRACE {
4948            Some(backtrace::Backtrace::new_unresolved())
4949        } else {
4950            None
4951        };
4952        if let Some(type_name) = type_name {
4953            entry.0.get_or_insert(type_name);
4954        }
4955        entry.1.insert(handle_id, backtrace);
4956        handle_id
4957    }
4958
4959    fn handle_dropped(&mut self, entity_id: usize, handle_id: usize) {
4960        if let Some((_, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
4961            assert!(backtraces.remove(&handle_id).is_some());
4962            if backtraces.is_empty() {
4963                self.handle_backtraces.remove(&entity_id);
4964            }
4965        }
4966    }
4967
4968    pub fn assert_dropped(&mut self, entity_id: usize) {
4969        if let Some((type_name, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
4970            for trace in backtraces.values_mut() {
4971                if let Some(trace) = trace {
4972                    trace.resolve();
4973                    eprintln!("{:?}", crate::util::CwdBacktrace(trace));
4974                }
4975            }
4976
4977            let hint = if *LEAK_BACKTRACE {
4978                ""
4979            } else {
4980                " – set LEAK_BACKTRACE=1 for more information"
4981            };
4982
4983            panic!(
4984                "{} handles to {} {} still exist{}",
4985                backtraces.len(),
4986                type_name.unwrap_or("entity"),
4987                entity_id,
4988                hint
4989            );
4990        }
4991    }
4992
4993    pub fn detect(&mut self) {
4994        let mut found_leaks = false;
4995        for (id, (type_name, backtraces)) in self.handle_backtraces.iter_mut() {
4996            eprintln!(
4997                "leaked {} handles to {} {}",
4998                backtraces.len(),
4999                type_name.unwrap_or("entity"),
5000                id
5001            );
5002            for trace in backtraces.values_mut() {
5003                if let Some(trace) = trace {
5004                    trace.resolve();
5005                    eprintln!("{:?}", crate::util::CwdBacktrace(trace));
5006                }
5007            }
5008            found_leaks = true;
5009        }
5010
5011        let hint = if *LEAK_BACKTRACE {
5012            ""
5013        } else {
5014            " – set LEAK_BACKTRACE=1 for more information"
5015        };
5016        assert!(!found_leaks, "detected leaked handles{}", hint);
5017    }
5018}
5019
5020#[derive(Default)]
5021struct RefCounts {
5022    entity_counts: HashMap<usize, usize>,
5023    element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
5024    dropped_models: HashSet<usize>,
5025    dropped_views: HashSet<(usize, usize)>,
5026    dropped_element_states: HashSet<ElementStateId>,
5027
5028    #[cfg(any(test, feature = "test-support"))]
5029    leak_detector: Arc<Mutex<LeakDetector>>,
5030}
5031
5032struct ElementStateRefCount {
5033    ref_count: usize,
5034    frame_id: usize,
5035}
5036
5037impl RefCounts {
5038    fn inc_model(&mut self, model_id: usize) {
5039        match self.entity_counts.entry(model_id) {
5040            Entry::Occupied(mut entry) => {
5041                *entry.get_mut() += 1;
5042            }
5043            Entry::Vacant(entry) => {
5044                entry.insert(1);
5045                self.dropped_models.remove(&model_id);
5046            }
5047        }
5048    }
5049
5050    fn inc_view(&mut self, window_id: usize, view_id: usize) {
5051        match self.entity_counts.entry(view_id) {
5052            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
5053            Entry::Vacant(entry) => {
5054                entry.insert(1);
5055                self.dropped_views.remove(&(window_id, view_id));
5056            }
5057        }
5058    }
5059
5060    fn inc_element_state(&mut self, id: ElementStateId, frame_id: usize) {
5061        match self.element_state_counts.entry(id) {
5062            Entry::Occupied(mut entry) => {
5063                let entry = entry.get_mut();
5064                if entry.frame_id == frame_id || entry.ref_count >= 2 {
5065                    panic!("used the same element state more than once in the same frame");
5066                }
5067                entry.ref_count += 1;
5068                entry.frame_id = frame_id;
5069            }
5070            Entry::Vacant(entry) => {
5071                entry.insert(ElementStateRefCount {
5072                    ref_count: 1,
5073                    frame_id,
5074                });
5075                self.dropped_element_states.remove(&id);
5076            }
5077        }
5078    }
5079
5080    fn dec_model(&mut self, model_id: usize) {
5081        let count = self.entity_counts.get_mut(&model_id).unwrap();
5082        *count -= 1;
5083        if *count == 0 {
5084            self.entity_counts.remove(&model_id);
5085            self.dropped_models.insert(model_id);
5086        }
5087    }
5088
5089    fn dec_view(&mut self, window_id: usize, view_id: usize) {
5090        let count = self.entity_counts.get_mut(&view_id).unwrap();
5091        *count -= 1;
5092        if *count == 0 {
5093            self.entity_counts.remove(&view_id);
5094            self.dropped_views.insert((window_id, view_id));
5095        }
5096    }
5097
5098    fn dec_element_state(&mut self, id: ElementStateId) {
5099        let entry = self.element_state_counts.get_mut(&id).unwrap();
5100        entry.ref_count -= 1;
5101        if entry.ref_count == 0 {
5102            self.element_state_counts.remove(&id);
5103            self.dropped_element_states.insert(id);
5104        }
5105    }
5106
5107    fn is_entity_alive(&self, entity_id: usize) -> bool {
5108        self.entity_counts.contains_key(&entity_id)
5109    }
5110
5111    fn take_dropped(
5112        &mut self,
5113    ) -> (
5114        HashSet<usize>,
5115        HashSet<(usize, usize)>,
5116        HashSet<ElementStateId>,
5117    ) {
5118        (
5119            std::mem::take(&mut self.dropped_models),
5120            std::mem::take(&mut self.dropped_views),
5121            std::mem::take(&mut self.dropped_element_states),
5122        )
5123    }
5124}
5125
5126#[cfg(test)]
5127mod tests {
5128    use super::*;
5129    use crate::{actions, elements::*, impl_actions};
5130    use serde::Deserialize;
5131    use smol::future::poll_once;
5132    use std::{
5133        cell::Cell,
5134        sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
5135    };
5136
5137    #[crate::test(self)]
5138    fn test_model_handles(cx: &mut MutableAppContext) {
5139        struct Model {
5140            other: Option<ModelHandle<Model>>,
5141            events: Vec<String>,
5142        }
5143
5144        impl Entity for Model {
5145            type Event = usize;
5146        }
5147
5148        impl Model {
5149            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
5150                if let Some(other) = other.as_ref() {
5151                    cx.observe(other, |me, _, _| {
5152                        me.events.push("notified".into());
5153                    })
5154                    .detach();
5155                    cx.subscribe(other, |me, _, event, _| {
5156                        me.events.push(format!("observed event {}", event));
5157                    })
5158                    .detach();
5159                }
5160
5161                Self {
5162                    other,
5163                    events: Vec::new(),
5164                }
5165            }
5166        }
5167
5168        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
5169        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
5170        assert_eq!(cx.cx.models.len(), 2);
5171
5172        handle_1.update(cx, |model, cx| {
5173            model.events.push("updated".into());
5174            cx.emit(1);
5175            cx.notify();
5176            cx.emit(2);
5177        });
5178        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5179        assert_eq!(
5180            handle_2.read(cx).events,
5181            vec![
5182                "observed event 1".to_string(),
5183                "notified".to_string(),
5184                "observed event 2".to_string(),
5185            ]
5186        );
5187
5188        handle_2.update(cx, |model, _| {
5189            drop(handle_1);
5190            model.other.take();
5191        });
5192
5193        assert_eq!(cx.cx.models.len(), 1);
5194        assert!(cx.subscriptions.lock().is_empty());
5195        assert!(cx.observations.lock().is_empty());
5196    }
5197
5198    #[crate::test(self)]
5199    fn test_model_events(cx: &mut MutableAppContext) {
5200        #[derive(Default)]
5201        struct Model {
5202            events: Vec<usize>,
5203        }
5204
5205        impl Entity for Model {
5206            type Event = usize;
5207        }
5208
5209        let handle_1 = cx.add_model(|_| Model::default());
5210        let handle_2 = cx.add_model(|_| Model::default());
5211
5212        handle_1.update(cx, |_, cx| {
5213            cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
5214                model.events.push(*event);
5215
5216                cx.subscribe(&emitter, |model, _, event, _| {
5217                    model.events.push(*event * 2);
5218                })
5219                .detach();
5220            })
5221            .detach();
5222        });
5223
5224        handle_2.update(cx, |_, c| c.emit(7));
5225        assert_eq!(handle_1.read(cx).events, vec![7]);
5226
5227        handle_2.update(cx, |_, c| c.emit(5));
5228        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5229    }
5230
5231    #[crate::test(self)]
5232    fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5233        #[derive(Default)]
5234        struct Model;
5235
5236        impl Entity for Model {
5237            type Event = ();
5238        }
5239
5240        let events = Rc::new(RefCell::new(Vec::new()));
5241        cx.add_model(|cx| {
5242            drop(cx.subscribe(&cx.handle(), {
5243                let events = events.clone();
5244                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5245            }));
5246            cx.subscribe(&cx.handle(), {
5247                let events = events.clone();
5248                move |_, _, _, _| events.borrow_mut().push("before emit")
5249            })
5250            .detach();
5251            cx.emit(());
5252            cx.subscribe(&cx.handle(), {
5253                let events = events.clone();
5254                move |_, _, _, _| events.borrow_mut().push("after emit")
5255            })
5256            .detach();
5257            Model
5258        });
5259        assert_eq!(*events.borrow(), ["before emit"]);
5260    }
5261
5262    #[crate::test(self)]
5263    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
5264        #[derive(Default)]
5265        struct Model {
5266            count: usize,
5267            events: Vec<usize>,
5268        }
5269
5270        impl Entity for Model {
5271            type Event = ();
5272        }
5273
5274        let handle_1 = cx.add_model(|_| Model::default());
5275        let handle_2 = cx.add_model(|_| Model::default());
5276
5277        handle_1.update(cx, |_, c| {
5278            c.observe(&handle_2, move |model, observed, c| {
5279                model.events.push(observed.read(c).count);
5280                c.observe(&observed, |model, observed, c| {
5281                    model.events.push(observed.read(c).count * 2);
5282                })
5283                .detach();
5284            })
5285            .detach();
5286        });
5287
5288        handle_2.update(cx, |model, c| {
5289            model.count = 7;
5290            c.notify()
5291        });
5292        assert_eq!(handle_1.read(cx).events, vec![7]);
5293
5294        handle_2.update(cx, |model, c| {
5295            model.count = 5;
5296            c.notify()
5297        });
5298        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
5299    }
5300
5301    #[crate::test(self)]
5302    fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
5303        #[derive(Default)]
5304        struct Model;
5305
5306        impl Entity for Model {
5307            type Event = ();
5308        }
5309
5310        let events = Rc::new(RefCell::new(Vec::new()));
5311        cx.add_model(|cx| {
5312            drop(cx.observe(&cx.handle(), {
5313                let events = events.clone();
5314                move |_, _, _| events.borrow_mut().push("dropped before flush")
5315            }));
5316            cx.observe(&cx.handle(), {
5317                let events = events.clone();
5318                move |_, _, _| events.borrow_mut().push("before notify")
5319            })
5320            .detach();
5321            cx.notify();
5322            cx.observe(&cx.handle(), {
5323                let events = events.clone();
5324                move |_, _, _| events.borrow_mut().push("after notify")
5325            })
5326            .detach();
5327            Model
5328        });
5329        assert_eq!(*events.borrow(), ["before notify"]);
5330    }
5331
5332    #[crate::test(self)]
5333    fn test_defer_and_after_window_update(cx: &mut MutableAppContext) {
5334        struct View {
5335            render_count: usize,
5336        }
5337
5338        impl Entity for View {
5339            type Event = usize;
5340        }
5341
5342        impl super::View for View {
5343            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5344                post_inc(&mut self.render_count);
5345                Empty::new().boxed()
5346            }
5347
5348            fn ui_name() -> &'static str {
5349                "View"
5350            }
5351        }
5352
5353        let (_, view) = cx.add_window(Default::default(), |_| View { render_count: 0 });
5354        let called_defer = Rc::new(AtomicBool::new(false));
5355        let called_after_window_update = Rc::new(AtomicBool::new(false));
5356
5357        view.update(cx, |this, cx| {
5358            assert_eq!(this.render_count, 1);
5359            cx.defer({
5360                let called_defer = called_defer.clone();
5361                move |this, _| {
5362                    assert_eq!(this.render_count, 1);
5363                    called_defer.store(true, SeqCst);
5364                }
5365            });
5366            cx.after_window_update({
5367                let called_after_window_update = called_after_window_update.clone();
5368                move |this, cx| {
5369                    assert_eq!(this.render_count, 2);
5370                    called_after_window_update.store(true, SeqCst);
5371                    cx.notify();
5372                }
5373            });
5374            assert!(!called_defer.load(SeqCst));
5375            assert!(!called_after_window_update.load(SeqCst));
5376            cx.notify();
5377        });
5378
5379        assert!(called_defer.load(SeqCst));
5380        assert!(called_after_window_update.load(SeqCst));
5381        assert_eq!(view.read(cx).render_count, 3);
5382    }
5383
5384    #[crate::test(self)]
5385    fn test_view_handles(cx: &mut MutableAppContext) {
5386        struct View {
5387            other: Option<ViewHandle<View>>,
5388            events: Vec<String>,
5389        }
5390
5391        impl Entity for View {
5392            type Event = usize;
5393        }
5394
5395        impl super::View for View {
5396            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5397                Empty::new().boxed()
5398            }
5399
5400            fn ui_name() -> &'static str {
5401                "View"
5402            }
5403        }
5404
5405        impl View {
5406            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
5407                if let Some(other) = other.as_ref() {
5408                    cx.subscribe(other, |me, _, event, _| {
5409                        me.events.push(format!("observed event {}", event));
5410                    })
5411                    .detach();
5412                }
5413                Self {
5414                    other,
5415                    events: Vec::new(),
5416                }
5417            }
5418        }
5419
5420        let (window_id, _) = cx.add_window(Default::default(), |cx| View::new(None, cx));
5421        let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
5422        let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
5423        assert_eq!(cx.cx.views.len(), 3);
5424
5425        handle_1.update(cx, |view, cx| {
5426            view.events.push("updated".into());
5427            cx.emit(1);
5428            cx.emit(2);
5429        });
5430        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5431        assert_eq!(
5432            handle_2.read(cx).events,
5433            vec![
5434                "observed event 1".to_string(),
5435                "observed event 2".to_string(),
5436            ]
5437        );
5438
5439        handle_2.update(cx, |view, _| {
5440            drop(handle_1);
5441            view.other.take();
5442        });
5443
5444        assert_eq!(cx.cx.views.len(), 2);
5445        assert!(cx.subscriptions.lock().is_empty());
5446        assert!(cx.observations.lock().is_empty());
5447    }
5448
5449    #[crate::test(self)]
5450    fn test_add_window(cx: &mut MutableAppContext) {
5451        struct View {
5452            mouse_down_count: Arc<AtomicUsize>,
5453        }
5454
5455        impl Entity for View {
5456            type Event = ();
5457        }
5458
5459        impl super::View for View {
5460            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5461                let mouse_down_count = self.mouse_down_count.clone();
5462                EventHandler::new(Empty::new().boxed())
5463                    .on_mouse_down(move |_| {
5464                        mouse_down_count.fetch_add(1, SeqCst);
5465                        true
5466                    })
5467                    .boxed()
5468            }
5469
5470            fn ui_name() -> &'static str {
5471                "View"
5472            }
5473        }
5474
5475        let mouse_down_count = Arc::new(AtomicUsize::new(0));
5476        let (window_id, _) = cx.add_window(Default::default(), |_| View {
5477            mouse_down_count: mouse_down_count.clone(),
5478        });
5479        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
5480        // Ensure window's root element is in a valid lifecycle state.
5481        presenter.borrow_mut().dispatch_event(
5482            Event::LeftMouseDown {
5483                position: Default::default(),
5484                ctrl: false,
5485                alt: false,
5486                shift: false,
5487                cmd: false,
5488                click_count: 1,
5489            },
5490            cx,
5491        );
5492        assert_eq!(mouse_down_count.load(SeqCst), 1);
5493    }
5494
5495    #[crate::test(self)]
5496    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
5497        struct Model {
5498            released: Rc<Cell<bool>>,
5499        }
5500
5501        struct View {
5502            released: Rc<Cell<bool>>,
5503        }
5504
5505        impl Entity for Model {
5506            type Event = ();
5507
5508            fn release(&mut self, _: &mut MutableAppContext) {
5509                self.released.set(true);
5510            }
5511        }
5512
5513        impl Entity for View {
5514            type Event = ();
5515
5516            fn release(&mut self, _: &mut MutableAppContext) {
5517                self.released.set(true);
5518            }
5519        }
5520
5521        impl super::View for View {
5522            fn ui_name() -> &'static str {
5523                "View"
5524            }
5525
5526            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5527                Empty::new().boxed()
5528            }
5529        }
5530
5531        let model_released = Rc::new(Cell::new(false));
5532        let model_release_observed = Rc::new(Cell::new(false));
5533        let view_released = Rc::new(Cell::new(false));
5534        let view_release_observed = Rc::new(Cell::new(false));
5535
5536        let model = cx.add_model(|_| Model {
5537            released: model_released.clone(),
5538        });
5539        let (window_id, view) = cx.add_window(Default::default(), |_| View {
5540            released: view_released.clone(),
5541        });
5542        assert!(!model_released.get());
5543        assert!(!view_released.get());
5544
5545        cx.observe_release(&model, {
5546            let model_release_observed = model_release_observed.clone();
5547            move |_, _| model_release_observed.set(true)
5548        })
5549        .detach();
5550        cx.observe_release(&view, {
5551            let view_release_observed = view_release_observed.clone();
5552            move |_, _| view_release_observed.set(true)
5553        })
5554        .detach();
5555
5556        cx.update(move |_| {
5557            drop(model);
5558        });
5559        assert!(model_released.get());
5560        assert!(model_release_observed.get());
5561
5562        drop(view);
5563        cx.remove_window(window_id);
5564        assert!(view_released.get());
5565        assert!(view_release_observed.get());
5566    }
5567
5568    #[crate::test(self)]
5569    fn test_view_events(cx: &mut MutableAppContext) {
5570        #[derive(Default)]
5571        struct View {
5572            events: Vec<usize>,
5573        }
5574
5575        impl Entity for View {
5576            type Event = usize;
5577        }
5578
5579        impl super::View for View {
5580            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5581                Empty::new().boxed()
5582            }
5583
5584            fn ui_name() -> &'static str {
5585                "View"
5586            }
5587        }
5588
5589        struct Model;
5590
5591        impl Entity for Model {
5592            type Event = usize;
5593        }
5594
5595        let (window_id, handle_1) = cx.add_window(Default::default(), |_| View::default());
5596        let handle_2 = cx.add_view(window_id, |_| View::default());
5597        let handle_3 = cx.add_model(|_| Model);
5598
5599        handle_1.update(cx, |_, cx| {
5600            cx.subscribe(&handle_2, move |me, emitter, event, cx| {
5601                me.events.push(*event);
5602
5603                cx.subscribe(&emitter, |me, _, event, _| {
5604                    me.events.push(*event * 2);
5605                })
5606                .detach();
5607            })
5608            .detach();
5609
5610            cx.subscribe(&handle_3, |me, _, event, _| {
5611                me.events.push(*event);
5612            })
5613            .detach();
5614        });
5615
5616        handle_2.update(cx, |_, c| c.emit(7));
5617        assert_eq!(handle_1.read(cx).events, vec![7]);
5618
5619        handle_2.update(cx, |_, c| c.emit(5));
5620        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5621
5622        handle_3.update(cx, |_, c| c.emit(9));
5623        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
5624    }
5625
5626    #[crate::test(self)]
5627    fn test_global_events(cx: &mut MutableAppContext) {
5628        #[derive(Clone, Debug, Eq, PartialEq)]
5629        struct GlobalEvent(u64);
5630
5631        let events = Rc::new(RefCell::new(Vec::new()));
5632        let first_subscription;
5633        let second_subscription;
5634
5635        {
5636            let events = events.clone();
5637            first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5638                events.borrow_mut().push(("First", e.clone()));
5639            });
5640        }
5641
5642        {
5643            let events = events.clone();
5644            second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5645                events.borrow_mut().push(("Second", e.clone()));
5646            });
5647        }
5648
5649        cx.update(|cx| {
5650            cx.emit_global(GlobalEvent(1));
5651            cx.emit_global(GlobalEvent(2));
5652        });
5653
5654        drop(first_subscription);
5655
5656        cx.update(|cx| {
5657            cx.emit_global(GlobalEvent(3));
5658        });
5659
5660        drop(second_subscription);
5661
5662        cx.update(|cx| {
5663            cx.emit_global(GlobalEvent(4));
5664        });
5665
5666        assert_eq!(
5667            &*events.borrow(),
5668            &[
5669                ("First", GlobalEvent(1)),
5670                ("Second", GlobalEvent(1)),
5671                ("First", GlobalEvent(2)),
5672                ("Second", GlobalEvent(2)),
5673                ("Second", GlobalEvent(3)),
5674            ]
5675        );
5676    }
5677
5678    #[crate::test(self)]
5679    fn test_global_events_emitted_before_subscription_in_same_update_cycle(
5680        cx: &mut MutableAppContext,
5681    ) {
5682        let events = Rc::new(RefCell::new(Vec::new()));
5683        cx.update(|cx| {
5684            {
5685                let events = events.clone();
5686                drop(cx.subscribe_global(move |_: &(), _| {
5687                    events.borrow_mut().push("dropped before emit");
5688                }));
5689            }
5690
5691            {
5692                let events = events.clone();
5693                cx.subscribe_global(move |_: &(), _| {
5694                    events.borrow_mut().push("before emit");
5695                })
5696                .detach();
5697            }
5698
5699            cx.emit_global(());
5700
5701            {
5702                let events = events.clone();
5703                cx.subscribe_global(move |_: &(), _| {
5704                    events.borrow_mut().push("after emit");
5705                })
5706                .detach();
5707            }
5708        });
5709
5710        assert_eq!(*events.borrow(), ["before emit"]);
5711    }
5712
5713    #[crate::test(self)]
5714    fn test_global_nested_events(cx: &mut MutableAppContext) {
5715        #[derive(Clone, Debug, Eq, PartialEq)]
5716        struct GlobalEvent(u64);
5717
5718        let events = Rc::new(RefCell::new(Vec::new()));
5719
5720        {
5721            let events = events.clone();
5722            cx.subscribe_global(move |e: &GlobalEvent, cx| {
5723                events.borrow_mut().push(("Outer", e.clone()));
5724
5725                if e.0 == 1 {
5726                    let events = events.clone();
5727                    cx.subscribe_global(move |e: &GlobalEvent, _| {
5728                        events.borrow_mut().push(("Inner", e.clone()));
5729                    })
5730                    .detach();
5731                }
5732            })
5733            .detach();
5734        }
5735
5736        cx.update(|cx| {
5737            cx.emit_global(GlobalEvent(1));
5738            cx.emit_global(GlobalEvent(2));
5739            cx.emit_global(GlobalEvent(3));
5740        });
5741        cx.update(|cx| {
5742            cx.emit_global(GlobalEvent(4));
5743        });
5744
5745        assert_eq!(
5746            &*events.borrow(),
5747            &[
5748                ("Outer", GlobalEvent(1)),
5749                ("Outer", GlobalEvent(2)),
5750                ("Outer", GlobalEvent(3)),
5751                ("Outer", GlobalEvent(4)),
5752                ("Inner", GlobalEvent(4)),
5753            ]
5754        );
5755    }
5756
5757    #[crate::test(self)]
5758    fn test_global(cx: &mut MutableAppContext) {
5759        type Global = usize;
5760
5761        let observation_count = Rc::new(RefCell::new(0));
5762        let subscription = cx.observe_global::<Global, _>({
5763            let observation_count = observation_count.clone();
5764            move |_| {
5765                *observation_count.borrow_mut() += 1;
5766            }
5767        });
5768
5769        assert!(!cx.has_global::<Global>());
5770        assert_eq!(cx.default_global::<Global>(), &0);
5771        assert_eq!(*observation_count.borrow(), 1);
5772        assert!(cx.has_global::<Global>());
5773        assert_eq!(
5774            cx.update_global::<Global, _, _>(|global, _| {
5775                *global = 1;
5776                "Update Result"
5777            }),
5778            "Update Result"
5779        );
5780        assert_eq!(*observation_count.borrow(), 2);
5781        assert_eq!(cx.global::<Global>(), &1);
5782
5783        drop(subscription);
5784        cx.update_global::<Global, _, _>(|global, _| {
5785            *global = 2;
5786        });
5787        assert_eq!(*observation_count.borrow(), 2);
5788
5789        type OtherGlobal = f32;
5790
5791        let observation_count = Rc::new(RefCell::new(0));
5792        cx.observe_global::<OtherGlobal, _>({
5793            let observation_count = observation_count.clone();
5794            move |_| {
5795                *observation_count.borrow_mut() += 1;
5796            }
5797        })
5798        .detach();
5799
5800        assert_eq!(
5801            cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5802                assert_eq!(global, &0.0);
5803                *global = 2.0;
5804                "Default update result"
5805            }),
5806            "Default update result"
5807        );
5808        assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5809        assert_eq!(*observation_count.borrow(), 1);
5810    }
5811
5812    #[crate::test(self)]
5813    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
5814        struct View;
5815
5816        impl Entity for View {
5817            type Event = ();
5818        }
5819
5820        impl super::View for View {
5821            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5822                Empty::new().boxed()
5823            }
5824
5825            fn ui_name() -> &'static str {
5826                "View"
5827            }
5828        }
5829
5830        struct Model;
5831
5832        impl Entity for Model {
5833            type Event = ();
5834        }
5835
5836        let (window_id, _) = cx.add_window(Default::default(), |_| View);
5837        let observing_view = cx.add_view(window_id, |_| View);
5838        let emitting_view = cx.add_view(window_id, |_| View);
5839        let observing_model = cx.add_model(|_| Model);
5840        let observed_model = cx.add_model(|_| Model);
5841
5842        observing_view.update(cx, |_, cx| {
5843            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5844            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5845        });
5846        observing_model.update(cx, |_, cx| {
5847            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5848        });
5849
5850        cx.update(|_| {
5851            drop(observing_view);
5852            drop(observing_model);
5853        });
5854
5855        emitting_view.update(cx, |_, cx| cx.emit(()));
5856        observed_model.update(cx, |_, cx| cx.emit(()));
5857    }
5858
5859    #[crate::test(self)]
5860    fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5861        #[derive(Default)]
5862        struct TestView;
5863
5864        impl Entity for TestView {
5865            type Event = ();
5866        }
5867
5868        impl View for TestView {
5869            fn ui_name() -> &'static str {
5870                "TestView"
5871            }
5872
5873            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5874                Empty::new().boxed()
5875            }
5876        }
5877
5878        let events = Rc::new(RefCell::new(Vec::new()));
5879        cx.add_window(Default::default(), |cx| {
5880            drop(cx.subscribe(&cx.handle(), {
5881                let events = events.clone();
5882                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5883            }));
5884            cx.subscribe(&cx.handle(), {
5885                let events = events.clone();
5886                move |_, _, _, _| events.borrow_mut().push("before emit")
5887            })
5888            .detach();
5889            cx.emit(());
5890            cx.subscribe(&cx.handle(), {
5891                let events = events.clone();
5892                move |_, _, _, _| events.borrow_mut().push("after emit")
5893            })
5894            .detach();
5895            TestView
5896        });
5897        assert_eq!(*events.borrow(), ["before emit"]);
5898    }
5899
5900    #[crate::test(self)]
5901    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
5902        #[derive(Default)]
5903        struct View {
5904            events: Vec<usize>,
5905        }
5906
5907        impl Entity for View {
5908            type Event = usize;
5909        }
5910
5911        impl super::View for View {
5912            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5913                Empty::new().boxed()
5914            }
5915
5916            fn ui_name() -> &'static str {
5917                "View"
5918            }
5919        }
5920
5921        #[derive(Default)]
5922        struct Model {
5923            count: usize,
5924        }
5925
5926        impl Entity for Model {
5927            type Event = ();
5928        }
5929
5930        let (_, view) = cx.add_window(Default::default(), |_| View::default());
5931        let model = cx.add_model(|_| Model::default());
5932
5933        view.update(cx, |_, c| {
5934            c.observe(&model, |me, observed, c| {
5935                me.events.push(observed.read(c).count)
5936            })
5937            .detach();
5938        });
5939
5940        model.update(cx, |model, c| {
5941            model.count = 11;
5942            c.notify();
5943        });
5944        assert_eq!(view.read(cx).events, vec![11]);
5945    }
5946
5947    #[crate::test(self)]
5948    fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
5949        #[derive(Default)]
5950        struct TestView;
5951
5952        impl Entity for TestView {
5953            type Event = ();
5954        }
5955
5956        impl View for TestView {
5957            fn ui_name() -> &'static str {
5958                "TestView"
5959            }
5960
5961            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5962                Empty::new().boxed()
5963            }
5964        }
5965
5966        let events = Rc::new(RefCell::new(Vec::new()));
5967        cx.add_window(Default::default(), |cx| {
5968            drop(cx.observe(&cx.handle(), {
5969                let events = events.clone();
5970                move |_, _, _| events.borrow_mut().push("dropped before flush")
5971            }));
5972            cx.observe(&cx.handle(), {
5973                let events = events.clone();
5974                move |_, _, _| events.borrow_mut().push("before notify")
5975            })
5976            .detach();
5977            cx.notify();
5978            cx.observe(&cx.handle(), {
5979                let events = events.clone();
5980                move |_, _, _| events.borrow_mut().push("after notify")
5981            })
5982            .detach();
5983            TestView
5984        });
5985        assert_eq!(*events.borrow(), ["before notify"]);
5986    }
5987
5988    #[crate::test(self)]
5989    fn test_dropping_observers(cx: &mut MutableAppContext) {
5990        struct View;
5991
5992        impl Entity for View {
5993            type Event = ();
5994        }
5995
5996        impl super::View for View {
5997            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5998                Empty::new().boxed()
5999            }
6000
6001            fn ui_name() -> &'static str {
6002                "View"
6003            }
6004        }
6005
6006        struct Model;
6007
6008        impl Entity for Model {
6009            type Event = ();
6010        }
6011
6012        let (window_id, _) = cx.add_window(Default::default(), |_| View);
6013        let observing_view = cx.add_view(window_id, |_| View);
6014        let observing_model = cx.add_model(|_| Model);
6015        let observed_model = cx.add_model(|_| Model);
6016
6017        observing_view.update(cx, |_, cx| {
6018            cx.observe(&observed_model, |_, _, _| {}).detach();
6019        });
6020        observing_model.update(cx, |_, cx| {
6021            cx.observe(&observed_model, |_, _, _| {}).detach();
6022        });
6023
6024        cx.update(|_| {
6025            drop(observing_view);
6026            drop(observing_model);
6027        });
6028
6029        observed_model.update(cx, |_, cx| cx.notify());
6030    }
6031
6032    #[crate::test(self)]
6033    fn test_dropping_subscriptions_during_callback(cx: &mut MutableAppContext) {
6034        struct Model;
6035
6036        impl Entity for Model {
6037            type Event = u64;
6038        }
6039
6040        // Events
6041        let observing_model = cx.add_model(|_| Model);
6042        let observed_model = cx.add_model(|_| Model);
6043
6044        let events = Rc::new(RefCell::new(Vec::new()));
6045
6046        observing_model.update(cx, |_, cx| {
6047            let events = events.clone();
6048            let subscription = Rc::new(RefCell::new(None));
6049            *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
6050                let subscription = subscription.clone();
6051                move |_, _, e, _| {
6052                    subscription.borrow_mut().take();
6053                    events.borrow_mut().push(e.clone());
6054                }
6055            }));
6056        });
6057
6058        observed_model.update(cx, |_, cx| {
6059            cx.emit(1);
6060            cx.emit(2);
6061        });
6062
6063        assert_eq!(*events.borrow(), [1]);
6064
6065        // Global Events
6066        #[derive(Clone, Debug, Eq, PartialEq)]
6067        struct GlobalEvent(u64);
6068
6069        let events = Rc::new(RefCell::new(Vec::new()));
6070
6071        {
6072            let events = events.clone();
6073            let subscription = Rc::new(RefCell::new(None));
6074            *subscription.borrow_mut() = Some(cx.subscribe_global({
6075                let subscription = subscription.clone();
6076                move |e: &GlobalEvent, _| {
6077                    subscription.borrow_mut().take();
6078                    events.borrow_mut().push(e.clone());
6079                }
6080            }));
6081        }
6082
6083        cx.update(|cx| {
6084            cx.emit_global(GlobalEvent(1));
6085            cx.emit_global(GlobalEvent(2));
6086        });
6087
6088        assert_eq!(*events.borrow(), [GlobalEvent(1)]);
6089
6090        // Model Observation
6091        let observing_model = cx.add_model(|_| Model);
6092        let observed_model = cx.add_model(|_| Model);
6093
6094        let observation_count = Rc::new(RefCell::new(0));
6095
6096        observing_model.update(cx, |_, cx| {
6097            let observation_count = observation_count.clone();
6098            let subscription = Rc::new(RefCell::new(None));
6099            *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
6100                let subscription = subscription.clone();
6101                move |_, _, _| {
6102                    subscription.borrow_mut().take();
6103                    *observation_count.borrow_mut() += 1;
6104                }
6105            }));
6106        });
6107
6108        observed_model.update(cx, |_, cx| {
6109            cx.notify();
6110        });
6111
6112        observed_model.update(cx, |_, cx| {
6113            cx.notify();
6114        });
6115
6116        assert_eq!(*observation_count.borrow(), 1);
6117
6118        // View Observation
6119        struct View;
6120
6121        impl Entity for View {
6122            type Event = ();
6123        }
6124
6125        impl super::View for View {
6126            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6127                Empty::new().boxed()
6128            }
6129
6130            fn ui_name() -> &'static str {
6131                "View"
6132            }
6133        }
6134
6135        let (window_id, _) = cx.add_window(Default::default(), |_| View);
6136        let observing_view = cx.add_view(window_id, |_| View);
6137        let observed_view = cx.add_view(window_id, |_| View);
6138
6139        let observation_count = Rc::new(RefCell::new(0));
6140        observing_view.update(cx, |_, cx| {
6141            let observation_count = observation_count.clone();
6142            let subscription = Rc::new(RefCell::new(None));
6143            *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
6144                let subscription = subscription.clone();
6145                move |_, _, _| {
6146                    subscription.borrow_mut().take();
6147                    *observation_count.borrow_mut() += 1;
6148                }
6149            }));
6150        });
6151
6152        observed_view.update(cx, |_, cx| {
6153            cx.notify();
6154        });
6155
6156        observed_view.update(cx, |_, cx| {
6157            cx.notify();
6158        });
6159
6160        assert_eq!(*observation_count.borrow(), 1);
6161
6162        // Global Observation
6163        let observation_count = Rc::new(RefCell::new(0));
6164        let subscription = Rc::new(RefCell::new(None));
6165        *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
6166            let observation_count = observation_count.clone();
6167            let subscription = subscription.clone();
6168            move |_| {
6169                subscription.borrow_mut().take();
6170                *observation_count.borrow_mut() += 1;
6171            }
6172        }));
6173
6174        cx.default_global::<()>();
6175        cx.set_global(());
6176        assert_eq!(*observation_count.borrow(), 1);
6177    }
6178
6179    #[crate::test(self)]
6180    fn test_focus(cx: &mut MutableAppContext) {
6181        struct View {
6182            name: String,
6183            events: Arc<Mutex<Vec<String>>>,
6184        }
6185
6186        impl Entity for View {
6187            type Event = ();
6188        }
6189
6190        impl super::View for View {
6191            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6192                Empty::new().boxed()
6193            }
6194
6195            fn ui_name() -> &'static str {
6196                "View"
6197            }
6198
6199            fn on_focus(&mut self, _: &mut ViewContext<Self>) {
6200                self.events.lock().push(format!("{} focused", &self.name));
6201            }
6202
6203            fn on_blur(&mut self, _: &mut ViewContext<Self>) {
6204                self.events.lock().push(format!("{} blurred", &self.name));
6205            }
6206        }
6207
6208        let view_events: Arc<Mutex<Vec<String>>> = Default::default();
6209        let (window_id, view_1) = cx.add_window(Default::default(), |_| View {
6210            events: view_events.clone(),
6211            name: "view 1".to_string(),
6212        });
6213        let view_2 = cx.add_view(window_id, |_| View {
6214            events: view_events.clone(),
6215            name: "view 2".to_string(),
6216        });
6217
6218        let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
6219        view_1.update(cx, |_, cx| {
6220            cx.observe_focus(&view_2, {
6221                let observed_events = observed_events.clone();
6222                move |this, view, cx| {
6223                    observed_events.lock().push(format!(
6224                        "{} observed {}'s focus",
6225                        this.name,
6226                        view.read(cx).name
6227                    ))
6228                }
6229            })
6230            .detach();
6231        });
6232        view_2.update(cx, |_, cx| {
6233            cx.observe_focus(&view_1, {
6234                let observed_events = observed_events.clone();
6235                move |this, view, cx| {
6236                    observed_events.lock().push(format!(
6237                        "{} observed {}'s focus",
6238                        this.name,
6239                        view.read(cx).name
6240                    ))
6241                }
6242            })
6243            .detach();
6244        });
6245
6246        view_1.update(cx, |_, cx| {
6247            // Ensure only the latest focus is honored.
6248            cx.focus(&view_2);
6249            cx.focus(&view_1);
6250            cx.focus(&view_2);
6251        });
6252        view_1.update(cx, |_, cx| cx.focus(&view_1));
6253        view_1.update(cx, |_, cx| cx.focus(&view_2));
6254        view_1.update(cx, |_, _| drop(view_2));
6255
6256        assert_eq!(
6257            *view_events.lock(),
6258            [
6259                "view 1 focused".to_string(),
6260                "view 1 blurred".to_string(),
6261                "view 2 focused".to_string(),
6262                "view 2 blurred".to_string(),
6263                "view 1 focused".to_string(),
6264                "view 1 blurred".to_string(),
6265                "view 2 focused".to_string(),
6266                "view 1 focused".to_string(),
6267            ],
6268        );
6269        assert_eq!(
6270            *observed_events.lock(),
6271            [
6272                "view 1 observed view 2's focus".to_string(),
6273                "view 2 observed view 1's focus".to_string(),
6274                "view 1 observed view 2's focus".to_string(),
6275            ]
6276        );
6277    }
6278
6279    #[crate::test(self)]
6280    fn test_deserialize_actions(cx: &mut MutableAppContext) {
6281        #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
6282        pub struct ComplexAction {
6283            arg: String,
6284            count: usize,
6285        }
6286
6287        actions!(test::something, [SimpleAction]);
6288        impl_actions!(test::something, [ComplexAction]);
6289
6290        cx.add_global_action(move |_: &SimpleAction, _: &mut MutableAppContext| {});
6291        cx.add_global_action(move |_: &ComplexAction, _: &mut MutableAppContext| {});
6292
6293        let action1 = cx
6294            .deserialize_action(
6295                "test::something::ComplexAction",
6296                Some(r#"{"arg": "a", "count": 5}"#),
6297            )
6298            .unwrap();
6299        let action2 = cx
6300            .deserialize_action("test::something::SimpleAction", None)
6301            .unwrap();
6302        assert_eq!(
6303            action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
6304            &ComplexAction {
6305                arg: "a".to_string(),
6306                count: 5,
6307            }
6308        );
6309        assert_eq!(
6310            action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
6311            &SimpleAction
6312        );
6313    }
6314
6315    #[crate::test(self)]
6316    fn test_dispatch_action(cx: &mut MutableAppContext) {
6317        struct ViewA {
6318            id: usize,
6319        }
6320
6321        impl Entity for ViewA {
6322            type Event = ();
6323        }
6324
6325        impl View for ViewA {
6326            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6327                Empty::new().boxed()
6328            }
6329
6330            fn ui_name() -> &'static str {
6331                "View"
6332            }
6333        }
6334
6335        struct ViewB {
6336            id: usize,
6337        }
6338
6339        impl Entity for ViewB {
6340            type Event = ();
6341        }
6342
6343        impl View for ViewB {
6344            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6345                Empty::new().boxed()
6346            }
6347
6348            fn ui_name() -> &'static str {
6349                "View"
6350            }
6351        }
6352
6353        #[derive(Clone, Default, Deserialize, PartialEq)]
6354        pub struct Action(pub String);
6355
6356        impl_actions!(test, [Action]);
6357
6358        let actions = Rc::new(RefCell::new(Vec::new()));
6359
6360        cx.add_global_action({
6361            let actions = actions.clone();
6362            move |_: &Action, _: &mut MutableAppContext| {
6363                actions.borrow_mut().push("global".to_string());
6364            }
6365        });
6366
6367        cx.add_action({
6368            let actions = actions.clone();
6369            move |view: &mut ViewA, action: &Action, cx| {
6370                assert_eq!(action.0, "bar");
6371                cx.propagate_action();
6372                actions.borrow_mut().push(format!("{} a", view.id));
6373            }
6374        });
6375
6376        cx.add_action({
6377            let actions = actions.clone();
6378            move |view: &mut ViewA, _: &Action, cx| {
6379                if view.id != 1 {
6380                    cx.add_view(|cx| {
6381                        cx.propagate_action(); // Still works on a nested ViewContext
6382                        ViewB { id: 5 }
6383                    });
6384                }
6385                actions.borrow_mut().push(format!("{} b", view.id));
6386            }
6387        });
6388
6389        cx.add_action({
6390            let actions = actions.clone();
6391            move |view: &mut ViewB, _: &Action, cx| {
6392                cx.propagate_action();
6393                actions.borrow_mut().push(format!("{} c", view.id));
6394            }
6395        });
6396
6397        cx.add_action({
6398            let actions = actions.clone();
6399            move |view: &mut ViewB, _: &Action, cx| {
6400                cx.propagate_action();
6401                actions.borrow_mut().push(format!("{} d", view.id));
6402            }
6403        });
6404
6405        cx.capture_action({
6406            let actions = actions.clone();
6407            move |view: &mut ViewA, _: &Action, cx| {
6408                cx.propagate_action();
6409                actions.borrow_mut().push(format!("{} capture", view.id));
6410            }
6411        });
6412
6413        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
6414        let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 });
6415        let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 });
6416        let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 });
6417
6418        let observed_actions = Rc::new(RefCell::new(Vec::new()));
6419        cx.observe_actions({
6420            let observed_actions = observed_actions.clone();
6421            move |action_id, _| observed_actions.borrow_mut().push(action_id)
6422        })
6423        .detach();
6424
6425        cx.dispatch_action(
6426            window_id,
6427            vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
6428            &Action("bar".to_string()),
6429        );
6430
6431        assert_eq!(
6432            *actions.borrow(),
6433            vec![
6434                "1 capture",
6435                "3 capture",
6436                "4 d",
6437                "4 c",
6438                "3 b",
6439                "3 a",
6440                "2 d",
6441                "2 c",
6442                "1 b"
6443            ]
6444        );
6445        assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
6446
6447        // Remove view_1, which doesn't propagate the action
6448        actions.borrow_mut().clear();
6449        cx.dispatch_action(
6450            window_id,
6451            vec![view_2.id(), view_3.id(), view_4.id()],
6452            &Action("bar".to_string()),
6453        );
6454
6455        assert_eq!(
6456            *actions.borrow(),
6457            vec![
6458                "3 capture",
6459                "4 d",
6460                "4 c",
6461                "3 b",
6462                "3 a",
6463                "2 d",
6464                "2 c",
6465                "global"
6466            ]
6467        );
6468        assert_eq!(
6469            *observed_actions.borrow(),
6470            [Action::default().id(), Action::default().id()]
6471        );
6472    }
6473
6474    #[crate::test(self)]
6475    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
6476        #[derive(Clone, Deserialize, PartialEq)]
6477        pub struct Action(String);
6478
6479        impl_actions!(test, [Action]);
6480
6481        struct View {
6482            id: usize,
6483            keymap_context: keymap::Context,
6484        }
6485
6486        impl Entity for View {
6487            type Event = ();
6488        }
6489
6490        impl super::View for View {
6491            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6492                Empty::new().boxed()
6493            }
6494
6495            fn ui_name() -> &'static str {
6496                "View"
6497            }
6498
6499            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
6500                self.keymap_context.clone()
6501            }
6502        }
6503
6504        impl View {
6505            fn new(id: usize) -> Self {
6506                View {
6507                    id,
6508                    keymap_context: keymap::Context::default(),
6509                }
6510            }
6511        }
6512
6513        let mut view_1 = View::new(1);
6514        let mut view_2 = View::new(2);
6515        let mut view_3 = View::new(3);
6516        view_1.keymap_context.set.insert("a".into());
6517        view_2.keymap_context.set.insert("a".into());
6518        view_2.keymap_context.set.insert("b".into());
6519        view_3.keymap_context.set.insert("a".into());
6520        view_3.keymap_context.set.insert("b".into());
6521        view_3.keymap_context.set.insert("c".into());
6522
6523        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
6524        let view_2 = cx.add_view(window_id, |_| view_2);
6525        let view_3 = cx.add_view(window_id, |_| view_3);
6526
6527        // This keymap's only binding dispatches an action on view 2 because that view will have
6528        // "a" and "b" in its context, but not "c".
6529        cx.add_bindings(vec![keymap::Binding::new(
6530            "a",
6531            Action("a".to_string()),
6532            Some("a && b && !c"),
6533        )]);
6534
6535        cx.add_bindings(vec![keymap::Binding::new(
6536            "b",
6537            Action("b".to_string()),
6538            None,
6539        )]);
6540
6541        let actions = Rc::new(RefCell::new(Vec::new()));
6542        cx.add_action({
6543            let actions = actions.clone();
6544            move |view: &mut View, action: &Action, cx| {
6545                if action.0 == "a" {
6546                    actions.borrow_mut().push(format!("{} a", view.id));
6547                } else {
6548                    actions
6549                        .borrow_mut()
6550                        .push(format!("{} {}", view.id, action.0));
6551                    cx.propagate_action();
6552                }
6553            }
6554        });
6555
6556        cx.add_global_action({
6557            let actions = actions.clone();
6558            move |action: &Action, _| {
6559                actions.borrow_mut().push(format!("global {}", action.0));
6560            }
6561        });
6562
6563        cx.dispatch_keystroke(
6564            window_id,
6565            vec![view_1.id(), view_2.id(), view_3.id()],
6566            &Keystroke::parse("a").unwrap(),
6567        );
6568
6569        assert_eq!(&*actions.borrow(), &["2 a"]);
6570
6571        actions.borrow_mut().clear();
6572        cx.dispatch_keystroke(
6573            window_id,
6574            vec![view_1.id(), view_2.id(), view_3.id()],
6575            &Keystroke::parse("b").unwrap(),
6576        );
6577
6578        assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
6579    }
6580
6581    #[crate::test(self)]
6582    async fn test_model_condition(cx: &mut TestAppContext) {
6583        struct Counter(usize);
6584
6585        impl super::Entity for Counter {
6586            type Event = ();
6587        }
6588
6589        impl Counter {
6590            fn inc(&mut self, cx: &mut ModelContext<Self>) {
6591                self.0 += 1;
6592                cx.notify();
6593            }
6594        }
6595
6596        let model = cx.add_model(|_| Counter(0));
6597
6598        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
6599        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
6600        smol::pin!(condition1, condition2);
6601
6602        model.update(cx, |model, cx| model.inc(cx));
6603        assert_eq!(poll_once(&mut condition1).await, None);
6604        assert_eq!(poll_once(&mut condition2).await, None);
6605
6606        model.update(cx, |model, cx| model.inc(cx));
6607        assert_eq!(poll_once(&mut condition1).await, Some(()));
6608        assert_eq!(poll_once(&mut condition2).await, None);
6609
6610        model.update(cx, |model, cx| model.inc(cx));
6611        assert_eq!(poll_once(&mut condition2).await, Some(()));
6612
6613        model.update(cx, |_, cx| cx.notify());
6614    }
6615
6616    #[crate::test(self)]
6617    #[should_panic]
6618    async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6619        struct Model;
6620
6621        impl super::Entity for Model {
6622            type Event = ();
6623        }
6624
6625        let model = cx.add_model(|_| Model);
6626        model.condition(&cx, |_, _| false).await;
6627    }
6628
6629    #[crate::test(self)]
6630    #[should_panic(expected = "model dropped with pending condition")]
6631    async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6632        struct Model;
6633
6634        impl super::Entity for Model {
6635            type Event = ();
6636        }
6637
6638        let model = cx.add_model(|_| Model);
6639        let condition = model.condition(&cx, |_, _| false);
6640        cx.update(|_| drop(model));
6641        condition.await;
6642    }
6643
6644    #[crate::test(self)]
6645    async fn test_view_condition(cx: &mut TestAppContext) {
6646        struct Counter(usize);
6647
6648        impl super::Entity for Counter {
6649            type Event = ();
6650        }
6651
6652        impl super::View for Counter {
6653            fn ui_name() -> &'static str {
6654                "test view"
6655            }
6656
6657            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6658                Empty::new().boxed()
6659            }
6660        }
6661
6662        impl Counter {
6663            fn inc(&mut self, cx: &mut ViewContext<Self>) {
6664                self.0 += 1;
6665                cx.notify();
6666            }
6667        }
6668
6669        let (_, view) = cx.add_window(|_| Counter(0));
6670
6671        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
6672        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
6673        smol::pin!(condition1, condition2);
6674
6675        view.update(cx, |view, cx| view.inc(cx));
6676        assert_eq!(poll_once(&mut condition1).await, None);
6677        assert_eq!(poll_once(&mut condition2).await, None);
6678
6679        view.update(cx, |view, cx| view.inc(cx));
6680        assert_eq!(poll_once(&mut condition1).await, Some(()));
6681        assert_eq!(poll_once(&mut condition2).await, None);
6682
6683        view.update(cx, |view, cx| view.inc(cx));
6684        assert_eq!(poll_once(&mut condition2).await, Some(()));
6685        view.update(cx, |_, cx| cx.notify());
6686    }
6687
6688    #[crate::test(self)]
6689    #[should_panic]
6690    async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6691        struct View;
6692
6693        impl super::Entity for View {
6694            type Event = ();
6695        }
6696
6697        impl super::View for View {
6698            fn ui_name() -> &'static str {
6699                "test view"
6700            }
6701
6702            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6703                Empty::new().boxed()
6704            }
6705        }
6706
6707        let (_, view) = cx.add_window(|_| View);
6708        view.condition(&cx, |_, _| false).await;
6709    }
6710
6711    #[crate::test(self)]
6712    #[should_panic(expected = "view dropped with pending condition")]
6713    async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6714        struct View;
6715
6716        impl super::Entity for View {
6717            type Event = ();
6718        }
6719
6720        impl super::View for View {
6721            fn ui_name() -> &'static str {
6722                "test view"
6723            }
6724
6725            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6726                Empty::new().boxed()
6727            }
6728        }
6729
6730        let window_id = cx.add_window(|_| View).0;
6731        let view = cx.add_view(window_id, |_| View);
6732
6733        let condition = view.condition(&cx, |_, _| false);
6734        cx.update(|_| drop(view));
6735        condition.await;
6736    }
6737
6738    #[crate::test(self)]
6739    fn test_refresh_windows(cx: &mut MutableAppContext) {
6740        struct View(usize);
6741
6742        impl super::Entity for View {
6743            type Event = ();
6744        }
6745
6746        impl super::View for View {
6747            fn ui_name() -> &'static str {
6748                "test view"
6749            }
6750
6751            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6752                Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
6753            }
6754        }
6755
6756        let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
6757        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
6758
6759        assert_eq!(
6760            presenter.borrow().rendered_views[&root_view.id()].name(),
6761            Some("render count: 0")
6762        );
6763
6764        let view = cx.add_view(window_id, |cx| {
6765            cx.refresh_windows();
6766            View(0)
6767        });
6768
6769        assert_eq!(
6770            presenter.borrow().rendered_views[&root_view.id()].name(),
6771            Some("render count: 1")
6772        );
6773        assert_eq!(
6774            presenter.borrow().rendered_views[&view.id()].name(),
6775            Some("render count: 0")
6776        );
6777
6778        cx.update(|cx| cx.refresh_windows());
6779        assert_eq!(
6780            presenter.borrow().rendered_views[&root_view.id()].name(),
6781            Some("render count: 2")
6782        );
6783        assert_eq!(
6784            presenter.borrow().rendered_views[&view.id()].name(),
6785            Some("render count: 1")
6786        );
6787
6788        cx.update(|cx| {
6789            cx.refresh_windows();
6790            drop(view);
6791        });
6792        assert_eq!(
6793            presenter.borrow().rendered_views[&root_view.id()].name(),
6794            Some("render count: 3")
6795        );
6796        assert_eq!(presenter.borrow().rendered_views.len(), 1);
6797    }
6798}