app.rs

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