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