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