app.rs

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