app.rs

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