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