app.rs

   1use crate::{
   2    elements::ElementBox,
   3    executor::{self, Task},
   4    keymap::{self, Keystroke},
   5    platform::{self, CursorStyle, Platform, PromptLevel, WindowOptions},
   6    presenter::Presenter,
   7    util::{post_inc, timeout, CwdBacktrace},
   8    AssetCache, AssetSource, ClipboardItem, FontCache, PathPromptOptions, TextLayoutCache,
   9};
  10use anyhow::{anyhow, Result};
  11use backtrace::Backtrace;
  12use keymap::MatchResult;
  13use parking_lot::Mutex;
  14use platform::Event;
  15use postage::{mpsc, oneshot, sink::Sink as _, stream::Stream as _};
  16use smol::prelude::*;
  17use std::{
  18    any::{type_name, Any, TypeId},
  19    cell::RefCell,
  20    collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque},
  21    fmt::{self, Debug},
  22    hash::{Hash, Hasher},
  23    marker::PhantomData,
  24    mem,
  25    ops::{Deref, DerefMut},
  26    path::{Path, PathBuf},
  27    pin::Pin,
  28    rc::{self, Rc},
  29    sync::{
  30        atomic::{AtomicUsize, Ordering::SeqCst},
  31        Arc, Weak,
  32    },
  33    time::Duration,
  34};
  35
  36pub trait Entity: 'static {
  37    type Event;
  38
  39    fn release(&mut self, _: &mut MutableAppContext) {}
  40    fn app_will_quit(
  41        &mut self,
  42        _: &mut MutableAppContext,
  43    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
  44        None
  45    }
  46}
  47
  48pub trait View: Entity + Sized {
  49    fn ui_name() -> &'static str;
  50    fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
  51    fn on_focus(&mut self, _: &mut ViewContext<Self>) {}
  52    fn on_blur(&mut self, _: &mut ViewContext<Self>) {}
  53    fn keymap_context(&self, _: &AppContext) -> keymap::Context {
  54        Self::default_keymap_context()
  55    }
  56    fn default_keymap_context() -> keymap::Context {
  57        let mut cx = keymap::Context::default();
  58        cx.set.insert(Self::ui_name().into());
  59        cx
  60    }
  61}
  62
  63pub trait ReadModel {
  64    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
  65}
  66
  67pub trait ReadModelWith {
  68    fn read_model_with<E: Entity, T>(
  69        &self,
  70        handle: &ModelHandle<E>,
  71        read: &mut dyn FnMut(&E, &AppContext) -> T,
  72    ) -> T;
  73}
  74
  75pub trait UpdateModel {
  76    fn update_model<T: Entity, O>(
  77        &mut self,
  78        handle: &ModelHandle<T>,
  79        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
  80    ) -> O;
  81}
  82
  83pub trait UpgradeModelHandle {
  84    fn upgrade_model_handle<T: Entity>(
  85        &self,
  86        handle: &WeakModelHandle<T>,
  87    ) -> Option<ModelHandle<T>>;
  88
  89    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool;
  90
  91    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle>;
  92}
  93
  94pub trait UpgradeViewHandle {
  95    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>>;
  96}
  97
  98pub trait ReadView {
  99    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
 100}
 101
 102pub trait ReadViewWith {
 103    fn read_view_with<V, T>(
 104        &self,
 105        handle: &ViewHandle<V>,
 106        read: &mut dyn FnMut(&V, &AppContext) -> T,
 107    ) -> T
 108    where
 109        V: View;
 110}
 111
 112pub trait UpdateView {
 113    fn update_view<T, S>(
 114        &mut self,
 115        handle: &ViewHandle<T>,
 116        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 117    ) -> S
 118    where
 119        T: View;
 120}
 121
 122pub trait ElementStateContext: DerefMut<Target = MutableAppContext> {
 123    fn current_view_id(&self) -> usize;
 124
 125    fn element_state<Tag: 'static, T: 'static + Default>(
 126        &mut self,
 127        element_id: usize,
 128    ) -> ElementStateHandle<T> {
 129        let id = ElementStateId {
 130            view_id: self.current_view_id(),
 131            element_id,
 132            tag: TypeId::of::<Tag>(),
 133        };
 134        self.cx
 135            .element_states
 136            .entry(id)
 137            .or_insert_with(|| Box::new(T::default()));
 138        ElementStateHandle::new(id, self.frame_count, &self.cx.ref_counts)
 139    }
 140}
 141
 142pub trait Action: 'static + AnyAction {
 143    type Argument: 'static + Clone;
 144}
 145
 146pub trait AnyAction {
 147    fn id(&self) -> TypeId;
 148    fn name(&self) -> &'static str;
 149    fn as_any(&self) -> &dyn Any;
 150    fn boxed_clone(&self) -> Box<dyn AnyAction>;
 151    fn boxed_clone_as_any(&self) -> Box<dyn Any>;
 152}
 153
 154#[macro_export]
 155macro_rules! action {
 156    ($name:ident, $arg:ty) => {
 157        #[derive(Clone)]
 158        pub struct $name(pub $arg);
 159
 160        impl $crate::Action for $name {
 161            type Argument = $arg;
 162        }
 163
 164        impl $crate::AnyAction for $name {
 165            fn id(&self) -> std::any::TypeId {
 166                std::any::TypeId::of::<$name>()
 167            }
 168
 169            fn name(&self) -> &'static str {
 170                stringify!($name)
 171            }
 172
 173            fn as_any(&self) -> &dyn std::any::Any {
 174                self
 175            }
 176
 177            fn boxed_clone(&self) -> Box<dyn $crate::AnyAction> {
 178                Box::new(self.clone())
 179            }
 180
 181            fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
 182                Box::new(self.clone())
 183            }
 184        }
 185    };
 186
 187    ($name:ident) => {
 188        #[derive(Clone, Debug, Eq, PartialEq)]
 189        pub struct $name;
 190
 191        impl $crate::Action for $name {
 192            type Argument = ();
 193        }
 194
 195        impl $crate::AnyAction for $name {
 196            fn id(&self) -> std::any::TypeId {
 197                std::any::TypeId::of::<$name>()
 198            }
 199
 200            fn name(&self) -> &'static str {
 201                stringify!($name)
 202            }
 203
 204            fn as_any(&self) -> &dyn std::any::Any {
 205                self
 206            }
 207
 208            fn boxed_clone(&self) -> Box<dyn $crate::AnyAction> {
 209                Box::new(self.clone())
 210            }
 211
 212            fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
 213                Box::new(self.clone())
 214            }
 215        }
 216    };
 217}
 218
 219pub struct Menu<'a> {
 220    pub name: &'a str,
 221    pub items: Vec<MenuItem<'a>>,
 222}
 223
 224pub enum MenuItem<'a> {
 225    Action {
 226        name: &'a str,
 227        keystroke: Option<&'a str>,
 228        action: Box<dyn AnyAction>,
 229    },
 230    Separator,
 231}
 232
 233#[derive(Clone)]
 234pub struct App(Rc<RefCell<MutableAppContext>>);
 235
 236#[derive(Clone)]
 237pub struct AsyncAppContext(Rc<RefCell<MutableAppContext>>);
 238
 239pub struct TestAppContext {
 240    cx: Rc<RefCell<MutableAppContext>>,
 241    foreground_platform: Rc<platform::test::ForegroundPlatform>,
 242}
 243
 244impl App {
 245    pub fn new(asset_source: impl AssetSource) -> Result<Self> {
 246        let platform = platform::current::platform();
 247        let foreground_platform = platform::current::foreground_platform();
 248        let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
 249        let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
 250            foreground,
 251            Arc::new(executor::Background::new()),
 252            platform.clone(),
 253            foreground_platform.clone(),
 254            Arc::new(FontCache::new(platform.fonts())),
 255            Default::default(),
 256            asset_source,
 257        ))));
 258
 259        foreground_platform.on_quit(Box::new({
 260            let cx = app.0.clone();
 261            move || {
 262                cx.borrow_mut().quit();
 263            }
 264        }));
 265        foreground_platform.on_menu_command(Box::new({
 266            let cx = app.0.clone();
 267            move |action| {
 268                let mut cx = cx.borrow_mut();
 269                if let Some(key_window_id) = cx.cx.platform.key_window_id() {
 270                    if let Some((presenter, _)) =
 271                        cx.presenters_and_platform_windows.get(&key_window_id)
 272                    {
 273                        let presenter = presenter.clone();
 274                        let path = presenter.borrow().dispatch_path(cx.as_ref());
 275                        cx.dispatch_action_any(key_window_id, &path, action);
 276                    } else {
 277                        cx.dispatch_global_action_any(action);
 278                    }
 279                } else {
 280                    cx.dispatch_global_action_any(action);
 281                }
 282            }
 283        }));
 284
 285        app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
 286        Ok(app)
 287    }
 288
 289    pub fn background(&self) -> Arc<executor::Background> {
 290        self.0.borrow().background().clone()
 291    }
 292
 293    pub fn on_become_active<F>(self, mut callback: F) -> Self
 294    where
 295        F: 'static + FnMut(&mut MutableAppContext),
 296    {
 297        let cx = self.0.clone();
 298        self.0
 299            .borrow_mut()
 300            .foreground_platform
 301            .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 302        self
 303    }
 304
 305    pub fn on_resign_active<F>(self, mut callback: F) -> Self
 306    where
 307        F: 'static + FnMut(&mut MutableAppContext),
 308    {
 309        let cx = self.0.clone();
 310        self.0
 311            .borrow_mut()
 312            .foreground_platform
 313            .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 314        self
 315    }
 316
 317    pub fn on_quit<F>(self, mut callback: F) -> Self
 318    where
 319        F: 'static + FnMut(&mut MutableAppContext),
 320    {
 321        let cx = self.0.clone();
 322        self.0
 323            .borrow_mut()
 324            .foreground_platform
 325            .on_quit(Box::new(move || callback(&mut *cx.borrow_mut())));
 326        self
 327    }
 328
 329    pub fn on_event<F>(self, mut callback: F) -> Self
 330    where
 331        F: 'static + FnMut(Event, &mut MutableAppContext) -> bool,
 332    {
 333        let cx = self.0.clone();
 334        self.0
 335            .borrow_mut()
 336            .foreground_platform
 337            .on_event(Box::new(move |event| {
 338                callback(event, &mut *cx.borrow_mut())
 339            }));
 340        self
 341    }
 342
 343    pub fn on_open_files<F>(self, mut callback: F) -> Self
 344    where
 345        F: 'static + FnMut(Vec<PathBuf>, &mut MutableAppContext),
 346    {
 347        let cx = self.0.clone();
 348        self.0
 349            .borrow_mut()
 350            .foreground_platform
 351            .on_open_files(Box::new(move |paths| {
 352                callback(paths, &mut *cx.borrow_mut())
 353            }));
 354        self
 355    }
 356
 357    pub fn run<F>(self, on_finish_launching: F)
 358    where
 359        F: 'static + FnOnce(&mut MutableAppContext),
 360    {
 361        let platform = self.0.borrow().foreground_platform.clone();
 362        platform.run(Box::new(move || {
 363            let mut cx = self.0.borrow_mut();
 364            let cx = &mut *cx;
 365            crate::views::init(cx);
 366            on_finish_launching(cx);
 367        }))
 368    }
 369
 370    pub fn platform(&self) -> Arc<dyn Platform> {
 371        self.0.borrow().platform()
 372    }
 373
 374    pub fn font_cache(&self) -> Arc<FontCache> {
 375        self.0.borrow().cx.font_cache.clone()
 376    }
 377
 378    fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 379        let mut state = self.0.borrow_mut();
 380        let result = state.update(callback);
 381        state.pending_notifications.clear();
 382        result
 383    }
 384}
 385
 386impl TestAppContext {
 387    pub fn new(
 388        foreground_platform: Rc<platform::test::ForegroundPlatform>,
 389        platform: Arc<dyn Platform>,
 390        foreground: Rc<executor::Foreground>,
 391        background: Arc<executor::Background>,
 392        font_cache: Arc<FontCache>,
 393        leak_detector: Arc<Mutex<LeakDetector>>,
 394        first_entity_id: usize,
 395    ) -> Self {
 396        let mut cx = MutableAppContext::new(
 397            foreground.clone(),
 398            background,
 399            platform,
 400            foreground_platform.clone(),
 401            font_cache,
 402            RefCounts {
 403                #[cfg(feature = "test-support")]
 404                leak_detector,
 405                ..Default::default()
 406            },
 407            (),
 408        );
 409        cx.next_entity_id = first_entity_id;
 410        let cx = TestAppContext {
 411            cx: Rc::new(RefCell::new(cx)),
 412            foreground_platform,
 413        };
 414        cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
 415        cx
 416    }
 417
 418    pub fn dispatch_action<A: Action>(
 419        &self,
 420        window_id: usize,
 421        responder_chain: Vec<usize>,
 422        action: A,
 423    ) {
 424        self.cx
 425            .borrow_mut()
 426            .dispatch_action_any(window_id, &responder_chain, &action);
 427    }
 428
 429    pub fn dispatch_global_action<A: Action>(&self, action: A) {
 430        self.cx.borrow_mut().dispatch_global_action(action);
 431    }
 432
 433    pub fn dispatch_keystroke(
 434        &self,
 435        window_id: usize,
 436        responder_chain: Vec<usize>,
 437        keystroke: &Keystroke,
 438    ) -> Result<bool> {
 439        let mut state = self.cx.borrow_mut();
 440        state.dispatch_keystroke(window_id, responder_chain, keystroke)
 441    }
 442
 443    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 444    where
 445        T: Entity,
 446        F: FnOnce(&mut ModelContext<T>) -> T,
 447    {
 448        self.cx.borrow_mut().add_model(build_model)
 449    }
 450
 451    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 452    where
 453        T: View,
 454        F: FnOnce(&mut ViewContext<T>) -> T,
 455    {
 456        self.cx
 457            .borrow_mut()
 458            .add_window(Default::default(), build_root_view)
 459    }
 460
 461    pub fn window_ids(&self) -> Vec<usize> {
 462        self.cx.borrow().window_ids().collect()
 463    }
 464
 465    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 466        self.cx.borrow().root_view(window_id)
 467    }
 468
 469    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
 470    where
 471        T: View,
 472        F: FnOnce(&mut ViewContext<T>) -> T,
 473    {
 474        self.cx.borrow_mut().add_view(window_id, build_view)
 475    }
 476
 477    pub fn add_option_view<T, F>(
 478        &mut self,
 479        window_id: usize,
 480        build_view: F,
 481    ) -> Option<ViewHandle<T>>
 482    where
 483        T: View,
 484        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 485    {
 486        self.cx.borrow_mut().add_option_view(window_id, build_view)
 487    }
 488
 489    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 490        callback(self.cx.borrow().as_ref())
 491    }
 492
 493    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 494        let mut state = self.cx.borrow_mut();
 495        // Don't increment pending flushes in order to effects to be flushed before the callback
 496        // completes, which is helpful in tests.
 497        let result = callback(&mut *state);
 498        // Flush effects after the callback just in case there are any. This can happen in edge
 499        // cases such as the closure dropping handles.
 500        state.flush_effects();
 501        result
 502    }
 503
 504    pub fn to_async(&self) -> AsyncAppContext {
 505        AsyncAppContext(self.cx.clone())
 506    }
 507
 508    pub fn font_cache(&self) -> Arc<FontCache> {
 509        self.cx.borrow().cx.font_cache.clone()
 510    }
 511
 512    pub fn foreground_platform(&self) -> Rc<platform::test::ForegroundPlatform> {
 513        self.foreground_platform.clone()
 514    }
 515
 516    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 517        self.cx.borrow().cx.platform.clone()
 518    }
 519
 520    pub fn foreground(&self) -> Rc<executor::Foreground> {
 521        self.cx.borrow().foreground().clone()
 522    }
 523
 524    pub fn background(&self) -> Arc<executor::Background> {
 525        self.cx.borrow().background().clone()
 526    }
 527
 528    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 529    where
 530        F: FnOnce(AsyncAppContext) -> Fut,
 531        Fut: 'static + Future<Output = T>,
 532        T: 'static,
 533    {
 534        self.cx.borrow_mut().spawn(f)
 535    }
 536
 537    pub fn simulate_new_path_selection(&self, result: impl FnOnce(PathBuf) -> Option<PathBuf>) {
 538        self.foreground_platform.simulate_new_path_selection(result);
 539    }
 540
 541    pub fn did_prompt_for_new_path(&self) -> bool {
 542        self.foreground_platform.as_ref().did_prompt_for_new_path()
 543    }
 544
 545    pub fn simulate_prompt_answer(&self, window_id: usize, answer: usize) {
 546        let mut state = self.cx.borrow_mut();
 547        let (_, window) = state
 548            .presenters_and_platform_windows
 549            .get_mut(&window_id)
 550            .unwrap();
 551        let test_window = window
 552            .as_any_mut()
 553            .downcast_mut::<platform::test::Window>()
 554            .unwrap();
 555        let mut done_tx = test_window
 556            .last_prompt
 557            .take()
 558            .expect("prompt was not called");
 559        let _ = done_tx.try_send(answer);
 560    }
 561
 562    #[cfg(feature = "test-support")]
 563    pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
 564        self.cx.borrow().leak_detector()
 565    }
 566}
 567
 568impl Drop for TestAppContext {
 569    fn drop(&mut self) {
 570        self.cx.borrow_mut().remove_all_windows();
 571    }
 572}
 573
 574impl AsyncAppContext {
 575    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 576    where
 577        F: FnOnce(AsyncAppContext) -> Fut,
 578        Fut: 'static + Future<Output = T>,
 579        T: 'static,
 580    {
 581        self.0.borrow().foreground.spawn(f(self.clone()))
 582    }
 583
 584    pub fn read<T, F: FnOnce(&AppContext) -> T>(&mut self, callback: F) -> T {
 585        callback(self.0.borrow().as_ref())
 586    }
 587
 588    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 589        self.0.borrow_mut().update(callback)
 590    }
 591
 592    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 593    where
 594        T: Entity,
 595        F: FnOnce(&mut ModelContext<T>) -> T,
 596    {
 597        self.update(|cx| cx.add_model(build_model))
 598    }
 599
 600    pub fn platform(&self) -> Arc<dyn Platform> {
 601        self.0.borrow().platform()
 602    }
 603
 604    pub fn foreground(&self) -> Rc<executor::Foreground> {
 605        self.0.borrow().foreground.clone()
 606    }
 607
 608    pub fn background(&self) -> Arc<executor::Background> {
 609        self.0.borrow().cx.background.clone()
 610    }
 611}
 612
 613impl UpdateModel for AsyncAppContext {
 614    fn update_model<E: Entity, O>(
 615        &mut self,
 616        handle: &ModelHandle<E>,
 617        update: &mut dyn FnMut(&mut E, &mut ModelContext<E>) -> O,
 618    ) -> O {
 619        self.0.borrow_mut().update_model(handle, update)
 620    }
 621}
 622
 623impl UpgradeModelHandle for AsyncAppContext {
 624    fn upgrade_model_handle<T: Entity>(
 625        &self,
 626        handle: &WeakModelHandle<T>,
 627    ) -> Option<ModelHandle<T>> {
 628        self.0.borrow().upgrade_model_handle(handle)
 629    }
 630
 631    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
 632        self.0.borrow().model_handle_is_upgradable(handle)
 633    }
 634
 635    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
 636        self.0.borrow().upgrade_any_model_handle(handle)
 637    }
 638}
 639
 640impl UpgradeViewHandle for AsyncAppContext {
 641    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
 642        self.0.borrow_mut().upgrade_view_handle(handle)
 643    }
 644}
 645
 646impl ReadModelWith for AsyncAppContext {
 647    fn read_model_with<E: Entity, T>(
 648        &self,
 649        handle: &ModelHandle<E>,
 650        read: &mut dyn FnMut(&E, &AppContext) -> T,
 651    ) -> T {
 652        let cx = self.0.borrow();
 653        let cx = cx.as_ref();
 654        read(handle.read(cx), cx)
 655    }
 656}
 657
 658impl UpdateView for AsyncAppContext {
 659    fn update_view<T, S>(
 660        &mut self,
 661        handle: &ViewHandle<T>,
 662        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 663    ) -> S
 664    where
 665        T: View,
 666    {
 667        self.0.borrow_mut().update_view(handle, update)
 668    }
 669}
 670
 671impl ReadViewWith for AsyncAppContext {
 672    fn read_view_with<V, T>(
 673        &self,
 674        handle: &ViewHandle<V>,
 675        read: &mut dyn FnMut(&V, &AppContext) -> T,
 676    ) -> T
 677    where
 678        V: View,
 679    {
 680        let cx = self.0.borrow();
 681        let cx = cx.as_ref();
 682        read(handle.read(cx), cx)
 683    }
 684}
 685
 686impl UpdateModel for TestAppContext {
 687    fn update_model<T: Entity, O>(
 688        &mut self,
 689        handle: &ModelHandle<T>,
 690        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
 691    ) -> O {
 692        self.cx.borrow_mut().update_model(handle, update)
 693    }
 694}
 695
 696impl ReadModelWith for TestAppContext {
 697    fn read_model_with<E: Entity, T>(
 698        &self,
 699        handle: &ModelHandle<E>,
 700        read: &mut dyn FnMut(&E, &AppContext) -> T,
 701    ) -> T {
 702        let cx = self.cx.borrow();
 703        let cx = cx.as_ref();
 704        read(handle.read(cx), cx)
 705    }
 706}
 707
 708impl UpdateView for TestAppContext {
 709    fn update_view<T, S>(
 710        &mut self,
 711        handle: &ViewHandle<T>,
 712        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 713    ) -> S
 714    where
 715        T: View,
 716    {
 717        self.cx.borrow_mut().update_view(handle, update)
 718    }
 719}
 720
 721impl ReadViewWith for TestAppContext {
 722    fn read_view_with<V, T>(
 723        &self,
 724        handle: &ViewHandle<V>,
 725        read: &mut dyn FnMut(&V, &AppContext) -> T,
 726    ) -> T
 727    where
 728        V: View,
 729    {
 730        let cx = self.cx.borrow();
 731        let cx = cx.as_ref();
 732        read(handle.read(cx), cx)
 733    }
 734}
 735
 736type ActionCallback =
 737    dyn FnMut(&mut dyn AnyView, &dyn AnyAction, &mut MutableAppContext, usize, usize);
 738type GlobalActionCallback = dyn FnMut(&dyn AnyAction, &mut MutableAppContext);
 739
 740type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>;
 741type ObservationCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
 742type ReleaseObservationCallback = Box<dyn FnMut(&mut MutableAppContext)>;
 743
 744pub struct MutableAppContext {
 745    weak_self: Option<rc::Weak<RefCell<Self>>>,
 746    foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 747    assets: Arc<AssetCache>,
 748    cx: AppContext,
 749    capture_actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 750    actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 751    global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
 752    keystroke_matcher: keymap::Matcher,
 753    next_entity_id: usize,
 754    next_window_id: usize,
 755    next_subscription_id: usize,
 756    frame_count: usize,
 757    subscriptions: Arc<Mutex<HashMap<usize, BTreeMap<usize, SubscriptionCallback>>>>,
 758    observations: Arc<Mutex<HashMap<usize, BTreeMap<usize, ObservationCallback>>>>,
 759    release_observations: Arc<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>,
 760    presenters_and_platform_windows:
 761        HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
 762    debug_elements_callbacks: HashMap<usize, Box<dyn Fn(&AppContext) -> crate::json::Value>>,
 763    foreground: Rc<executor::Foreground>,
 764    pending_effects: VecDeque<Effect>,
 765    pending_notifications: HashSet<usize>,
 766    pending_flushes: usize,
 767    flushing_effects: bool,
 768    next_cursor_style_handle_id: Arc<AtomicUsize>,
 769    halt_action_dispatch: bool,
 770}
 771
 772impl MutableAppContext {
 773    fn new(
 774        foreground: Rc<executor::Foreground>,
 775        background: Arc<executor::Background>,
 776        platform: Arc<dyn platform::Platform>,
 777        foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 778        font_cache: Arc<FontCache>,
 779        ref_counts: RefCounts,
 780        asset_source: impl AssetSource,
 781    ) -> Self {
 782        Self {
 783            weak_self: None,
 784            foreground_platform,
 785            assets: Arc::new(AssetCache::new(asset_source)),
 786            cx: AppContext {
 787                models: Default::default(),
 788                views: Default::default(),
 789                windows: Default::default(),
 790                app_states: Default::default(),
 791                element_states: Default::default(),
 792                ref_counts: Arc::new(Mutex::new(ref_counts)),
 793                background,
 794                font_cache,
 795                platform,
 796            },
 797            capture_actions: HashMap::new(),
 798            actions: HashMap::new(),
 799            global_actions: HashMap::new(),
 800            keystroke_matcher: keymap::Matcher::default(),
 801            next_entity_id: 0,
 802            next_window_id: 0,
 803            next_subscription_id: 0,
 804            frame_count: 0,
 805            subscriptions: Default::default(),
 806            observations: Default::default(),
 807            release_observations: Default::default(),
 808            presenters_and_platform_windows: HashMap::new(),
 809            debug_elements_callbacks: HashMap::new(),
 810            foreground,
 811            pending_effects: VecDeque::new(),
 812            pending_notifications: HashSet::new(),
 813            pending_flushes: 0,
 814            flushing_effects: false,
 815            next_cursor_style_handle_id: Default::default(),
 816            halt_action_dispatch: false,
 817        }
 818    }
 819
 820    pub fn upgrade(&self) -> App {
 821        App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
 822    }
 823
 824    pub fn quit(&mut self) {
 825        let mut futures = Vec::new();
 826        for model_id in self.cx.models.keys().copied().collect::<Vec<_>>() {
 827            let mut model = self.cx.models.remove(&model_id).unwrap();
 828            futures.extend(model.app_will_quit(self));
 829            self.cx.models.insert(model_id, model);
 830        }
 831
 832        for view_id in self.cx.views.keys().copied().collect::<Vec<_>>() {
 833            let mut view = self.cx.views.remove(&view_id).unwrap();
 834            futures.extend(view.app_will_quit(self));
 835            self.cx.views.insert(view_id, view);
 836        }
 837
 838        self.remove_all_windows();
 839
 840        let futures = futures::future::join_all(futures);
 841        if self
 842            .background
 843            .block_with_timeout(Duration::from_millis(100), futures)
 844            .is_err()
 845        {
 846            log::error!("timed out waiting on app_will_quit");
 847        }
 848    }
 849
 850    fn remove_all_windows(&mut self) {
 851        for (window_id, _) in self.cx.windows.drain() {
 852            self.presenters_and_platform_windows.remove(&window_id);
 853        }
 854        self.flush_effects();
 855    }
 856
 857    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 858        self.cx.platform.clone()
 859    }
 860
 861    pub fn font_cache(&self) -> &Arc<FontCache> {
 862        &self.cx.font_cache
 863    }
 864
 865    pub fn foreground(&self) -> &Rc<executor::Foreground> {
 866        &self.foreground
 867    }
 868
 869    pub fn background(&self) -> &Arc<executor::Background> {
 870        &self.cx.background
 871    }
 872
 873    pub fn on_debug_elements<F>(&mut self, window_id: usize, callback: F)
 874    where
 875        F: 'static + Fn(&AppContext) -> crate::json::Value,
 876    {
 877        self.debug_elements_callbacks
 878            .insert(window_id, Box::new(callback));
 879    }
 880
 881    pub fn debug_elements(&self, window_id: usize) -> Option<crate::json::Value> {
 882        self.debug_elements_callbacks
 883            .get(&window_id)
 884            .map(|debug_elements| debug_elements(&self.cx))
 885    }
 886
 887    pub fn add_action<A, V, F>(&mut self, handler: F)
 888    where
 889        A: Action,
 890        V: View,
 891        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 892    {
 893        self.add_action_internal(handler, false)
 894    }
 895
 896    pub fn capture_action<A, V, F>(&mut self, handler: F)
 897    where
 898        A: Action,
 899        V: View,
 900        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 901    {
 902        self.add_action_internal(handler, true)
 903    }
 904
 905    fn add_action_internal<A, V, F>(&mut self, mut handler: F, capture: bool)
 906    where
 907        A: Action,
 908        V: View,
 909        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 910    {
 911        let handler = Box::new(
 912            move |view: &mut dyn AnyView,
 913                  action: &dyn AnyAction,
 914                  cx: &mut MutableAppContext,
 915                  window_id: usize,
 916                  view_id: usize| {
 917                let action = action.as_any().downcast_ref().unwrap();
 918                let mut cx = ViewContext::new(cx, window_id, view_id);
 919                handler(
 920                    view.as_any_mut()
 921                        .downcast_mut()
 922                        .expect("downcast is type safe"),
 923                    action,
 924                    &mut cx,
 925                );
 926            },
 927        );
 928
 929        let actions = if capture {
 930            &mut self.capture_actions
 931        } else {
 932            &mut self.actions
 933        };
 934
 935        actions
 936            .entry(TypeId::of::<V>())
 937            .or_default()
 938            .entry(TypeId::of::<A>())
 939            .or_default()
 940            .push(handler);
 941    }
 942
 943    pub fn add_async_action<A, V, F>(&mut self, mut handler: F)
 944    where
 945        A: Action,
 946        V: View,
 947        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> Option<Task<Result<()>>>,
 948    {
 949        self.add_action(move |view, action, cx| {
 950            handler(view, action, cx).map(|task| task.detach_and_log_err(cx));
 951        })
 952    }
 953
 954    pub fn add_global_action<A, F>(&mut self, mut handler: F)
 955    where
 956        A: Action,
 957        F: 'static + FnMut(&A, &mut MutableAppContext),
 958    {
 959        let handler = Box::new(move |action: &dyn AnyAction, cx: &mut MutableAppContext| {
 960            let action = action.as_any().downcast_ref().unwrap();
 961            handler(action, cx);
 962        });
 963
 964        if self
 965            .global_actions
 966            .insert(TypeId::of::<A>(), handler)
 967            .is_some()
 968        {
 969            panic!("registered multiple global handlers for the same action type");
 970        }
 971    }
 972
 973    pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
 974        self.cx.windows.keys().cloned()
 975    }
 976
 977    pub fn activate_window(&self, window_id: usize) {
 978        if let Some((_, window)) = self.presenters_and_platform_windows.get(&window_id) {
 979            window.activate()
 980        }
 981    }
 982
 983    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 984        self.cx
 985            .windows
 986            .get(&window_id)
 987            .and_then(|window| window.root_view.clone().downcast::<T>())
 988    }
 989
 990    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
 991        self.cx.root_view_id(window_id)
 992    }
 993
 994    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
 995        self.cx.focused_view_id(window_id)
 996    }
 997
 998    pub fn render_view(
 999        &mut self,
1000        window_id: usize,
1001        view_id: usize,
1002        titlebar_height: f32,
1003        refreshing: bool,
1004    ) -> Result<ElementBox> {
1005        let mut view = self
1006            .cx
1007            .views
1008            .remove(&(window_id, view_id))
1009            .ok_or(anyhow!("view not found"))?;
1010        let element = view.render(window_id, view_id, titlebar_height, refreshing, self);
1011        self.cx.views.insert((window_id, view_id), view);
1012        Ok(element)
1013    }
1014
1015    pub fn render_views(
1016        &mut self,
1017        window_id: usize,
1018        titlebar_height: f32,
1019    ) -> HashMap<usize, ElementBox> {
1020        self.start_frame();
1021        let view_ids = self
1022            .views
1023            .keys()
1024            .filter_map(|(win_id, view_id)| {
1025                if *win_id == window_id {
1026                    Some(*view_id)
1027                } else {
1028                    None
1029                }
1030            })
1031            .collect::<Vec<_>>();
1032        view_ids
1033            .into_iter()
1034            .map(|view_id| {
1035                (
1036                    view_id,
1037                    self.render_view(window_id, view_id, titlebar_height, false)
1038                        .unwrap(),
1039                )
1040            })
1041            .collect()
1042    }
1043
1044    pub(crate) fn start_frame(&mut self) {
1045        self.frame_count += 1;
1046    }
1047
1048    pub fn update<T, F: FnOnce(&mut Self) -> T>(&mut self, callback: F) -> T {
1049        self.pending_flushes += 1;
1050        let result = callback(self);
1051        self.flush_effects();
1052        result
1053    }
1054
1055    pub fn set_menus(&mut self, menus: Vec<Menu>) {
1056        self.foreground_platform.set_menus(menus);
1057    }
1058
1059    fn prompt(
1060        &self,
1061        window_id: usize,
1062        level: PromptLevel,
1063        msg: &str,
1064        answers: &[&str],
1065    ) -> oneshot::Receiver<usize> {
1066        let (_, window) = &self.presenters_and_platform_windows[&window_id];
1067        window.prompt(level, msg, answers)
1068    }
1069
1070    pub fn prompt_for_paths(
1071        &self,
1072        options: PathPromptOptions,
1073    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
1074        self.foreground_platform.prompt_for_paths(options)
1075    }
1076
1077    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
1078        self.foreground_platform.prompt_for_new_path(directory)
1079    }
1080
1081    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1082    where
1083        E: Entity,
1084        E::Event: 'static,
1085        H: Handle<E>,
1086        F: 'static + FnMut(H, &E::Event, &mut Self),
1087    {
1088        self.subscribe_internal(handle, move |handle, event, cx| {
1089            callback(handle, event, cx);
1090            true
1091        })
1092    }
1093
1094    pub fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1095    where
1096        E: Entity,
1097        E::Event: 'static,
1098        H: Handle<E>,
1099        F: 'static + FnMut(H, &mut Self),
1100    {
1101        self.observe_internal(handle, move |handle, cx| {
1102            callback(handle, cx);
1103            true
1104        })
1105    }
1106
1107    pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1108    where
1109        E: Entity,
1110        E::Event: 'static,
1111        H: Handle<E>,
1112        F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
1113    {
1114        let id = post_inc(&mut self.next_subscription_id);
1115        let emitter = handle.downgrade();
1116        self.subscriptions
1117            .lock()
1118            .entry(handle.id())
1119            .or_default()
1120            .insert(
1121                id,
1122                Box::new(move |payload, cx| {
1123                    if let Some(emitter) = H::upgrade_from(&emitter, cx.as_ref()) {
1124                        let payload = payload.downcast_ref().expect("downcast is type safe");
1125                        callback(emitter, payload, cx)
1126                    } else {
1127                        false
1128                    }
1129                }),
1130            );
1131        Subscription::Subscription {
1132            id,
1133            entity_id: handle.id(),
1134            subscriptions: Some(Arc::downgrade(&self.subscriptions)),
1135        }
1136    }
1137
1138    fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1139    where
1140        E: Entity,
1141        E::Event: 'static,
1142        H: Handle<E>,
1143        F: 'static + FnMut(H, &mut Self) -> bool,
1144    {
1145        let id = post_inc(&mut self.next_subscription_id);
1146        let observed = handle.downgrade();
1147        self.observations
1148            .lock()
1149            .entry(handle.id())
1150            .or_default()
1151            .insert(
1152                id,
1153                Box::new(move |cx| {
1154                    if let Some(observed) = H::upgrade_from(&observed, cx) {
1155                        callback(observed, cx)
1156                    } else {
1157                        false
1158                    }
1159                }),
1160            );
1161        Subscription::Observation {
1162            id,
1163            entity_id: handle.id(),
1164            observations: Some(Arc::downgrade(&self.observations)),
1165        }
1166    }
1167
1168    pub fn observe_release<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1169    where
1170        E: Entity,
1171        E::Event: 'static,
1172        H: Handle<E>,
1173        F: 'static + FnMut(&mut Self),
1174    {
1175        let id = post_inc(&mut self.next_subscription_id);
1176        self.release_observations
1177            .lock()
1178            .entry(handle.id())
1179            .or_default()
1180            .insert(id, Box::new(move |cx| callback(cx)));
1181        Subscription::ReleaseObservation {
1182            id,
1183            entity_id: handle.id(),
1184            observations: Some(Arc::downgrade(&self.release_observations)),
1185        }
1186    }
1187
1188    fn defer(&mut self, callback: Box<dyn FnOnce(&mut MutableAppContext)>) {
1189        self.pending_effects.push_back(Effect::Deferred(callback))
1190    }
1191
1192    pub(crate) fn notify_model(&mut self, model_id: usize) {
1193        if self.pending_notifications.insert(model_id) {
1194            self.pending_effects
1195                .push_back(Effect::ModelNotification { model_id });
1196        }
1197    }
1198
1199    pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
1200        if self.pending_notifications.insert(view_id) {
1201            self.pending_effects
1202                .push_back(Effect::ViewNotification { window_id, view_id });
1203        }
1204    }
1205
1206    pub fn dispatch_action<A: Action>(
1207        &mut self,
1208        window_id: usize,
1209        responder_chain: Vec<usize>,
1210        action: &A,
1211    ) {
1212        self.dispatch_action_any(window_id, &responder_chain, action);
1213    }
1214
1215    pub(crate) fn dispatch_action_any(
1216        &mut self,
1217        window_id: usize,
1218        path: &[usize],
1219        action: &dyn AnyAction,
1220    ) -> bool {
1221        self.update(|this| {
1222            this.halt_action_dispatch = false;
1223            for (capture_phase, view_id) in path
1224                .iter()
1225                .map(|view_id| (true, *view_id))
1226                .chain(path.iter().rev().map(|view_id| (false, *view_id)))
1227            {
1228                if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
1229                    let type_id = view.as_any().type_id();
1230
1231                    if let Some((name, mut handlers)) = this
1232                        .actions_mut(capture_phase)
1233                        .get_mut(&type_id)
1234                        .and_then(|h| h.remove_entry(&action.id()))
1235                    {
1236                        for handler in handlers.iter_mut().rev() {
1237                            this.halt_action_dispatch = true;
1238                            handler(view.as_mut(), action, this, window_id, view_id);
1239                            if this.halt_action_dispatch {
1240                                break;
1241                            }
1242                        }
1243                        this.actions_mut(capture_phase)
1244                            .get_mut(&type_id)
1245                            .unwrap()
1246                            .insert(name, handlers);
1247                    }
1248
1249                    this.cx.views.insert((window_id, view_id), view);
1250
1251                    if this.halt_action_dispatch {
1252                        break;
1253                    }
1254                }
1255            }
1256
1257            if !this.halt_action_dispatch {
1258                this.dispatch_global_action_any(action);
1259            }
1260            this.halt_action_dispatch
1261        })
1262    }
1263
1264    fn actions_mut(
1265        &mut self,
1266        capture_phase: bool,
1267    ) -> &mut HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>> {
1268        if capture_phase {
1269            &mut self.capture_actions
1270        } else {
1271            &mut self.actions
1272        }
1273    }
1274
1275    pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
1276        self.dispatch_global_action_any(&action);
1277    }
1278
1279    fn dispatch_global_action_any(&mut self, action: &dyn AnyAction) -> bool {
1280        self.update(|this| {
1281            if let Some((name, mut handler)) = this.global_actions.remove_entry(&action.id()) {
1282                handler(action, this);
1283                this.global_actions.insert(name, handler);
1284                true
1285            } else {
1286                false
1287            }
1288        })
1289    }
1290
1291    pub fn add_bindings<T: IntoIterator<Item = keymap::Binding>>(&mut self, bindings: T) {
1292        self.keystroke_matcher.add_bindings(bindings);
1293    }
1294
1295    pub fn dispatch_keystroke(
1296        &mut self,
1297        window_id: usize,
1298        responder_chain: Vec<usize>,
1299        keystroke: &Keystroke,
1300    ) -> Result<bool> {
1301        let mut context_chain = Vec::new();
1302        for view_id in &responder_chain {
1303            if let Some(view) = self.cx.views.get(&(window_id, *view_id)) {
1304                context_chain.push(view.keymap_context(self.as_ref()));
1305            } else {
1306                return Err(anyhow!(
1307                    "View {} in responder chain does not exist",
1308                    view_id
1309                ));
1310            }
1311        }
1312
1313        let mut pending = false;
1314        for (i, cx) in context_chain.iter().enumerate().rev() {
1315            match self
1316                .keystroke_matcher
1317                .push_keystroke(keystroke.clone(), responder_chain[i], cx)
1318            {
1319                MatchResult::None => {}
1320                MatchResult::Pending => pending = true,
1321                MatchResult::Action(action) => {
1322                    if self.dispatch_action_any(window_id, &responder_chain[0..=i], action.as_ref())
1323                    {
1324                        self.keystroke_matcher.clear_pending();
1325                        return Ok(true);
1326                    }
1327                }
1328            }
1329        }
1330
1331        Ok(pending)
1332    }
1333
1334    pub fn add_app_state<T: 'static>(&mut self, state: T) {
1335        self.cx
1336            .app_states
1337            .insert(TypeId::of::<T>(), Box::new(state));
1338    }
1339
1340    pub fn update_app_state<T: 'static, F, U>(&mut self, update: F) -> U
1341    where
1342        F: FnOnce(&mut T, &mut MutableAppContext) -> U,
1343    {
1344        let type_id = TypeId::of::<T>();
1345        let mut state = self
1346            .cx
1347            .app_states
1348            .remove(&type_id)
1349            .expect("no app state has been added for this type");
1350        let result = update(state.downcast_mut().unwrap(), self);
1351        self.cx.app_states.insert(type_id, state);
1352        result
1353    }
1354
1355    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1356    where
1357        T: Entity,
1358        F: FnOnce(&mut ModelContext<T>) -> T,
1359    {
1360        self.update(|this| {
1361            let model_id = post_inc(&mut this.next_entity_id);
1362            let handle = ModelHandle::new(model_id, &this.cx.ref_counts);
1363            let mut cx = ModelContext::new(this, model_id);
1364            let model = build_model(&mut cx);
1365            this.cx.models.insert(model_id, Box::new(model));
1366            handle
1367        })
1368    }
1369
1370    pub fn add_window<T, F>(
1371        &mut self,
1372        window_options: WindowOptions,
1373        build_root_view: F,
1374    ) -> (usize, ViewHandle<T>)
1375    where
1376        T: View,
1377        F: FnOnce(&mut ViewContext<T>) -> T,
1378    {
1379        self.update(|this| {
1380            let window_id = post_inc(&mut this.next_window_id);
1381            let root_view = this.add_view(window_id, build_root_view);
1382
1383            this.cx.windows.insert(
1384                window_id,
1385                Window {
1386                    root_view: root_view.clone().into(),
1387                    focused_view_id: root_view.id(),
1388                    invalidation: None,
1389                },
1390            );
1391            this.open_platform_window(window_id, window_options);
1392            root_view.update(this, |view, cx| {
1393                view.on_focus(cx);
1394                cx.notify();
1395            });
1396
1397            (window_id, root_view)
1398        })
1399    }
1400
1401    pub fn remove_window(&mut self, window_id: usize) {
1402        self.cx.windows.remove(&window_id);
1403        self.presenters_and_platform_windows.remove(&window_id);
1404        self.flush_effects();
1405    }
1406
1407    fn open_platform_window(&mut self, window_id: usize, window_options: WindowOptions) {
1408        let mut window =
1409            self.cx
1410                .platform
1411                .open_window(window_id, window_options, self.foreground.clone());
1412        let presenter = Rc::new(RefCell::new(
1413            self.build_presenter(window_id, window.titlebar_height()),
1414        ));
1415
1416        {
1417            let mut app = self.upgrade();
1418            let presenter = presenter.clone();
1419            window.on_event(Box::new(move |event| {
1420                app.update(|cx| {
1421                    if let Event::KeyDown { keystroke, .. } = &event {
1422                        if cx
1423                            .dispatch_keystroke(
1424                                window_id,
1425                                presenter.borrow().dispatch_path(cx.as_ref()),
1426                                keystroke,
1427                            )
1428                            .unwrap()
1429                        {
1430                            return;
1431                        }
1432                    }
1433
1434                    presenter.borrow_mut().dispatch_event(event, cx);
1435                })
1436            }));
1437        }
1438
1439        {
1440            let mut app = self.upgrade();
1441            window.on_resize(Box::new(move || {
1442                app.update(|cx| cx.resize_window(window_id))
1443            }));
1444        }
1445
1446        {
1447            let mut app = self.upgrade();
1448            window.on_close(Box::new(move || {
1449                app.update(|cx| cx.remove_window(window_id));
1450            }));
1451        }
1452
1453        self.presenters_and_platform_windows
1454            .insert(window_id, (presenter.clone(), window));
1455
1456        self.on_debug_elements(window_id, move |cx| {
1457            presenter.borrow().debug_elements(cx).unwrap()
1458        });
1459    }
1460
1461    pub fn build_presenter(&mut self, window_id: usize, titlebar_height: f32) -> Presenter {
1462        Presenter::new(
1463            window_id,
1464            titlebar_height,
1465            self.cx.font_cache.clone(),
1466            TextLayoutCache::new(self.cx.platform.fonts()),
1467            self.assets.clone(),
1468            self,
1469        )
1470    }
1471
1472    pub fn build_render_context<V: View>(
1473        &mut self,
1474        window_id: usize,
1475        view_id: usize,
1476        titlebar_height: f32,
1477        refreshing: bool,
1478    ) -> RenderContext<V> {
1479        RenderContext {
1480            app: self,
1481            titlebar_height,
1482            refreshing,
1483            window_id,
1484            view_id,
1485            view_type: PhantomData,
1486        }
1487    }
1488
1489    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
1490    where
1491        T: View,
1492        F: FnOnce(&mut ViewContext<T>) -> T,
1493    {
1494        self.add_option_view(window_id, |cx| Some(build_view(cx)))
1495            .unwrap()
1496    }
1497
1498    pub fn add_option_view<T, F>(
1499        &mut self,
1500        window_id: usize,
1501        build_view: F,
1502    ) -> Option<ViewHandle<T>>
1503    where
1504        T: View,
1505        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1506    {
1507        self.update(|this| {
1508            let view_id = post_inc(&mut this.next_entity_id);
1509            let mut cx = ViewContext::new(this, window_id, view_id);
1510            let handle = if let Some(view) = build_view(&mut cx) {
1511                this.cx.views.insert((window_id, view_id), Box::new(view));
1512                if let Some(window) = this.cx.windows.get_mut(&window_id) {
1513                    window
1514                        .invalidation
1515                        .get_or_insert_with(Default::default)
1516                        .updated
1517                        .insert(view_id);
1518                }
1519                Some(ViewHandle::new(window_id, view_id, &this.cx.ref_counts))
1520            } else {
1521                None
1522            };
1523            handle
1524        })
1525    }
1526
1527    fn remove_dropped_entities(&mut self) {
1528        loop {
1529            let (dropped_models, dropped_views, dropped_element_states) =
1530                self.cx.ref_counts.lock().take_dropped();
1531            if dropped_models.is_empty()
1532                && dropped_views.is_empty()
1533                && dropped_element_states.is_empty()
1534            {
1535                break;
1536            }
1537
1538            for model_id in dropped_models {
1539                self.subscriptions.lock().remove(&model_id);
1540                self.observations.lock().remove(&model_id);
1541                let mut model = self.cx.models.remove(&model_id).unwrap();
1542                model.release(self);
1543                self.pending_effects.push_back(Effect::Release {
1544                    entity_id: model_id,
1545                });
1546            }
1547
1548            for (window_id, view_id) in dropped_views {
1549                self.subscriptions.lock().remove(&view_id);
1550                self.observations.lock().remove(&view_id);
1551                let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap();
1552                view.release(self);
1553                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
1554                    window
1555                        .invalidation
1556                        .get_or_insert_with(Default::default)
1557                        .removed
1558                        .push(view_id);
1559                    if window.focused_view_id == view_id {
1560                        Some(window.root_view.id())
1561                    } else {
1562                        None
1563                    }
1564                });
1565
1566                if let Some(view_id) = change_focus_to {
1567                    self.focus(window_id, view_id);
1568                }
1569
1570                self.pending_effects
1571                    .push_back(Effect::Release { entity_id: view_id });
1572            }
1573
1574            for key in dropped_element_states {
1575                self.cx.element_states.remove(&key);
1576            }
1577        }
1578    }
1579
1580    fn flush_effects(&mut self) {
1581        self.pending_flushes = self.pending_flushes.saturating_sub(1);
1582
1583        if !self.flushing_effects && self.pending_flushes == 0 {
1584            self.flushing_effects = true;
1585
1586            let mut refreshing = false;
1587            loop {
1588                if let Some(effect) = self.pending_effects.pop_front() {
1589                    match effect {
1590                        Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
1591                        Effect::ModelNotification { model_id } => {
1592                            self.notify_model_observers(model_id)
1593                        }
1594                        Effect::ViewNotification { window_id, view_id } => {
1595                            self.notify_view_observers(window_id, view_id)
1596                        }
1597                        Effect::Deferred(callback) => callback(self),
1598                        Effect::Release { entity_id } => self.notify_release_observers(entity_id),
1599                        Effect::Focus { window_id, view_id } => {
1600                            self.focus(window_id, view_id);
1601                        }
1602                        Effect::ResizeWindow { window_id } => {
1603                            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1604                                window
1605                                    .invalidation
1606                                    .get_or_insert(WindowInvalidation::default());
1607                            }
1608                        }
1609                        Effect::RefreshWindows => {
1610                            refreshing = true;
1611                        }
1612                    }
1613                    self.pending_notifications.clear();
1614                    self.remove_dropped_entities();
1615                } else {
1616                    self.remove_dropped_entities();
1617                    if refreshing {
1618                        self.perform_window_refresh();
1619                    } else {
1620                        self.update_windows();
1621                    }
1622
1623                    if self.pending_effects.is_empty() {
1624                        self.flushing_effects = false;
1625                        self.pending_notifications.clear();
1626                        break;
1627                    } else {
1628                        refreshing = false;
1629                    }
1630                }
1631            }
1632        }
1633    }
1634
1635    fn update_windows(&mut self) {
1636        let mut invalidations = HashMap::new();
1637        for (window_id, window) in &mut self.cx.windows {
1638            if let Some(invalidation) = window.invalidation.take() {
1639                invalidations.insert(*window_id, invalidation);
1640            }
1641        }
1642
1643        for (window_id, invalidation) in invalidations {
1644            if let Some((presenter, mut window)) =
1645                self.presenters_and_platform_windows.remove(&window_id)
1646            {
1647                {
1648                    let mut presenter = presenter.borrow_mut();
1649                    presenter.invalidate(invalidation, self);
1650                    let scene =
1651                        presenter.build_scene(window.size(), window.scale_factor(), false, self);
1652                    window.present_scene(scene);
1653                }
1654                self.presenters_and_platform_windows
1655                    .insert(window_id, (presenter, window));
1656            }
1657        }
1658    }
1659
1660    fn resize_window(&mut self, window_id: usize) {
1661        self.pending_effects
1662            .push_back(Effect::ResizeWindow { window_id });
1663    }
1664
1665    pub fn refresh_windows(&mut self) {
1666        self.pending_effects.push_back(Effect::RefreshWindows);
1667    }
1668
1669    fn perform_window_refresh(&mut self) {
1670        let mut presenters = mem::take(&mut self.presenters_and_platform_windows);
1671        for (window_id, (presenter, window)) in &mut presenters {
1672            let invalidation = self
1673                .cx
1674                .windows
1675                .get_mut(&window_id)
1676                .unwrap()
1677                .invalidation
1678                .take();
1679            let mut presenter = presenter.borrow_mut();
1680            presenter.refresh(invalidation, self);
1681            let scene = presenter.build_scene(window.size(), window.scale_factor(), true, self);
1682            window.present_scene(scene);
1683        }
1684        self.presenters_and_platform_windows = presenters;
1685    }
1686
1687    pub fn set_cursor_style(&mut self, style: CursorStyle) -> CursorStyleHandle {
1688        self.platform.set_cursor_style(style);
1689        let id = self.next_cursor_style_handle_id.fetch_add(1, SeqCst);
1690        CursorStyleHandle {
1691            id,
1692            next_cursor_style_handle_id: self.next_cursor_style_handle_id.clone(),
1693            platform: self.platform(),
1694        }
1695    }
1696
1697    fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
1698        let callbacks = self.subscriptions.lock().remove(&entity_id);
1699        if let Some(callbacks) = callbacks {
1700            for (id, mut callback) in callbacks {
1701                let alive = callback(payload.as_ref(), self);
1702                if alive {
1703                    self.subscriptions
1704                        .lock()
1705                        .entry(entity_id)
1706                        .or_default()
1707                        .insert(id, callback);
1708                }
1709            }
1710        }
1711    }
1712
1713    fn notify_model_observers(&mut self, observed_id: usize) {
1714        let callbacks = self.observations.lock().remove(&observed_id);
1715        if let Some(callbacks) = callbacks {
1716            if self.cx.models.contains_key(&observed_id) {
1717                for (id, mut callback) in callbacks {
1718                    let alive = callback(self);
1719                    if alive {
1720                        self.observations
1721                            .lock()
1722                            .entry(observed_id)
1723                            .or_default()
1724                            .insert(id, callback);
1725                    }
1726                }
1727            }
1728        }
1729    }
1730
1731    fn notify_view_observers(&mut self, observed_window_id: usize, observed_view_id: usize) {
1732        if let Some(window) = self.cx.windows.get_mut(&observed_window_id) {
1733            window
1734                .invalidation
1735                .get_or_insert_with(Default::default)
1736                .updated
1737                .insert(observed_view_id);
1738        }
1739
1740        let callbacks = self.observations.lock().remove(&observed_view_id);
1741        if let Some(callbacks) = callbacks {
1742            if self
1743                .cx
1744                .views
1745                .contains_key(&(observed_window_id, observed_view_id))
1746            {
1747                for (id, mut callback) in callbacks {
1748                    let alive = callback(self);
1749                    if alive {
1750                        self.observations
1751                            .lock()
1752                            .entry(observed_view_id)
1753                            .or_default()
1754                            .insert(id, callback);
1755                    }
1756                }
1757            }
1758        }
1759    }
1760
1761    fn notify_release_observers(&mut self, entity_id: usize) {
1762        let callbacks = self.release_observations.lock().remove(&entity_id);
1763        if let Some(callbacks) = callbacks {
1764            for (_, mut callback) in callbacks {
1765                callback(self);
1766            }
1767        }
1768    }
1769
1770    fn focus(&mut self, window_id: usize, focused_id: usize) {
1771        if self
1772            .cx
1773            .windows
1774            .get(&window_id)
1775            .map(|w| w.focused_view_id)
1776            .map_or(false, |cur_focused| cur_focused == focused_id)
1777        {
1778            return;
1779        }
1780
1781        self.update(|this| {
1782            let blurred_id = this.cx.windows.get_mut(&window_id).map(|window| {
1783                let blurred_id = window.focused_view_id;
1784                window.focused_view_id = focused_id;
1785                blurred_id
1786            });
1787
1788            if let Some(blurred_id) = blurred_id {
1789                if let Some(mut blurred_view) = this.cx.views.remove(&(window_id, blurred_id)) {
1790                    blurred_view.on_blur(this, window_id, blurred_id);
1791                    this.cx.views.insert((window_id, blurred_id), blurred_view);
1792                }
1793            }
1794
1795            if let Some(mut focused_view) = this.cx.views.remove(&(window_id, focused_id)) {
1796                focused_view.on_focus(this, window_id, focused_id);
1797                this.cx.views.insert((window_id, focused_id), focused_view);
1798            }
1799        })
1800    }
1801
1802    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
1803    where
1804        F: FnOnce(AsyncAppContext) -> Fut,
1805        Fut: 'static + Future<Output = T>,
1806        T: 'static,
1807    {
1808        let future = f(self.to_async());
1809        let cx = self.to_async();
1810        self.foreground.spawn(async move {
1811            let result = future.await;
1812            cx.0.borrow_mut().flush_effects();
1813            result
1814        })
1815    }
1816
1817    pub fn to_async(&self) -> AsyncAppContext {
1818        AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
1819    }
1820
1821    pub fn write_to_clipboard(&self, item: ClipboardItem) {
1822        self.cx.platform.write_to_clipboard(item);
1823    }
1824
1825    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
1826        self.cx.platform.read_from_clipboard()
1827    }
1828
1829    #[cfg(feature = "test-support")]
1830    pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
1831        self.cx.ref_counts.lock().leak_detector.clone()
1832    }
1833}
1834
1835impl ReadModel for MutableAppContext {
1836    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1837        if let Some(model) = self.cx.models.get(&handle.model_id) {
1838            model
1839                .as_any()
1840                .downcast_ref()
1841                .expect("downcast is type safe")
1842        } else {
1843            panic!("circular model reference");
1844        }
1845    }
1846}
1847
1848impl UpdateModel for MutableAppContext {
1849    fn update_model<T: Entity, V>(
1850        &mut self,
1851        handle: &ModelHandle<T>,
1852        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
1853    ) -> V {
1854        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
1855            self.update(|this| {
1856                let mut cx = ModelContext::new(this, handle.model_id);
1857                let result = update(
1858                    model
1859                        .as_any_mut()
1860                        .downcast_mut()
1861                        .expect("downcast is type safe"),
1862                    &mut cx,
1863                );
1864                this.cx.models.insert(handle.model_id, model);
1865                result
1866            })
1867        } else {
1868            panic!("circular model update");
1869        }
1870    }
1871}
1872
1873impl UpgradeModelHandle for MutableAppContext {
1874    fn upgrade_model_handle<T: Entity>(
1875        &self,
1876        handle: &WeakModelHandle<T>,
1877    ) -> Option<ModelHandle<T>> {
1878        self.cx.upgrade_model_handle(handle)
1879    }
1880
1881    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
1882        self.cx.model_handle_is_upgradable(handle)
1883    }
1884
1885    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
1886        self.cx.upgrade_any_model_handle(handle)
1887    }
1888}
1889
1890impl UpgradeViewHandle for MutableAppContext {
1891    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
1892        self.cx.upgrade_view_handle(handle)
1893    }
1894}
1895
1896impl ReadView for MutableAppContext {
1897    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1898        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
1899            view.as_any().downcast_ref().expect("downcast is type safe")
1900        } else {
1901            panic!("circular view reference");
1902        }
1903    }
1904}
1905
1906impl UpdateView for MutableAppContext {
1907    fn update_view<T, S>(
1908        &mut self,
1909        handle: &ViewHandle<T>,
1910        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
1911    ) -> S
1912    where
1913        T: View,
1914    {
1915        self.update(|this| {
1916            let mut view = this
1917                .cx
1918                .views
1919                .remove(&(handle.window_id, handle.view_id))
1920                .expect("circular view update");
1921
1922            let mut cx = ViewContext::new(this, handle.window_id, handle.view_id);
1923            let result = update(
1924                view.as_any_mut()
1925                    .downcast_mut()
1926                    .expect("downcast is type safe"),
1927                &mut cx,
1928            );
1929            this.cx
1930                .views
1931                .insert((handle.window_id, handle.view_id), view);
1932            result
1933        })
1934    }
1935}
1936
1937impl AsRef<AppContext> for MutableAppContext {
1938    fn as_ref(&self) -> &AppContext {
1939        &self.cx
1940    }
1941}
1942
1943impl Deref for MutableAppContext {
1944    type Target = AppContext;
1945
1946    fn deref(&self) -> &Self::Target {
1947        &self.cx
1948    }
1949}
1950
1951pub struct AppContext {
1952    models: HashMap<usize, Box<dyn AnyModel>>,
1953    views: HashMap<(usize, usize), Box<dyn AnyView>>,
1954    windows: HashMap<usize, Window>,
1955    app_states: HashMap<TypeId, Box<dyn Any>>,
1956    element_states: HashMap<ElementStateId, Box<dyn Any>>,
1957    background: Arc<executor::Background>,
1958    ref_counts: Arc<Mutex<RefCounts>>,
1959    font_cache: Arc<FontCache>,
1960    platform: Arc<dyn Platform>,
1961}
1962
1963impl AppContext {
1964    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
1965        self.windows
1966            .get(&window_id)
1967            .map(|window| window.root_view.id())
1968    }
1969
1970    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
1971        self.windows
1972            .get(&window_id)
1973            .map(|window| window.focused_view_id)
1974    }
1975
1976    pub fn background(&self) -> &Arc<executor::Background> {
1977        &self.background
1978    }
1979
1980    pub fn font_cache(&self) -> &Arc<FontCache> {
1981        &self.font_cache
1982    }
1983
1984    pub fn platform(&self) -> &Arc<dyn Platform> {
1985        &self.platform
1986    }
1987
1988    pub fn app_state<T: 'static>(&self) -> &T {
1989        self.app_states
1990            .get(&TypeId::of::<T>())
1991            .expect("no app state has been added for this type")
1992            .downcast_ref()
1993            .unwrap()
1994    }
1995}
1996
1997impl ReadModel for AppContext {
1998    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1999        if let Some(model) = self.models.get(&handle.model_id) {
2000            model
2001                .as_any()
2002                .downcast_ref()
2003                .expect("downcast should be type safe")
2004        } else {
2005            panic!("circular model reference");
2006        }
2007    }
2008}
2009
2010impl UpgradeModelHandle for AppContext {
2011    fn upgrade_model_handle<T: Entity>(
2012        &self,
2013        handle: &WeakModelHandle<T>,
2014    ) -> Option<ModelHandle<T>> {
2015        if self.models.contains_key(&handle.model_id) {
2016            Some(ModelHandle::new(handle.model_id, &self.ref_counts))
2017        } else {
2018            None
2019        }
2020    }
2021
2022    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2023        self.models.contains_key(&handle.model_id)
2024    }
2025
2026    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2027        if self.models.contains_key(&handle.model_id) {
2028            Some(AnyModelHandle::new(
2029                handle.model_id,
2030                handle.model_type,
2031                self.ref_counts.clone(),
2032            ))
2033        } else {
2034            None
2035        }
2036    }
2037}
2038
2039impl UpgradeViewHandle for AppContext {
2040    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2041        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2042            Some(ViewHandle::new(
2043                handle.window_id,
2044                handle.view_id,
2045                &self.ref_counts,
2046            ))
2047        } else {
2048            None
2049        }
2050    }
2051}
2052
2053impl ReadView for AppContext {
2054    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2055        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
2056            view.as_any()
2057                .downcast_ref()
2058                .expect("downcast should be type safe")
2059        } else {
2060            panic!("circular view reference");
2061        }
2062    }
2063}
2064
2065struct Window {
2066    root_view: AnyViewHandle,
2067    focused_view_id: usize,
2068    invalidation: Option<WindowInvalidation>,
2069}
2070
2071#[derive(Default, Clone)]
2072pub struct WindowInvalidation {
2073    pub updated: HashSet<usize>,
2074    pub removed: Vec<usize>,
2075}
2076
2077pub enum Effect {
2078    Event {
2079        entity_id: usize,
2080        payload: Box<dyn Any>,
2081    },
2082    ModelNotification {
2083        model_id: usize,
2084    },
2085    ViewNotification {
2086        window_id: usize,
2087        view_id: usize,
2088    },
2089    Deferred(Box<dyn FnOnce(&mut MutableAppContext)>),
2090    Release {
2091        entity_id: usize,
2092    },
2093    Focus {
2094        window_id: usize,
2095        view_id: usize,
2096    },
2097    ResizeWindow {
2098        window_id: usize,
2099    },
2100    RefreshWindows,
2101}
2102
2103impl Debug for Effect {
2104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2105        match self {
2106            Effect::Event { entity_id, .. } => f
2107                .debug_struct("Effect::Event")
2108                .field("entity_id", entity_id)
2109                .finish(),
2110            Effect::ModelNotification { model_id } => f
2111                .debug_struct("Effect::ModelNotification")
2112                .field("model_id", model_id)
2113                .finish(),
2114            Effect::ViewNotification { window_id, view_id } => f
2115                .debug_struct("Effect::ViewNotification")
2116                .field("window_id", window_id)
2117                .field("view_id", view_id)
2118                .finish(),
2119            Effect::Deferred(_) => f.debug_struct("Effect::Deferred").finish(),
2120            Effect::Release { entity_id } => f
2121                .debug_struct("Effect::Release")
2122                .field("entity_id", entity_id)
2123                .finish(),
2124            Effect::Focus { window_id, view_id } => f
2125                .debug_struct("Effect::Focus")
2126                .field("window_id", window_id)
2127                .field("view_id", view_id)
2128                .finish(),
2129            Effect::ResizeWindow { window_id } => f
2130                .debug_struct("Effect::RefreshWindow")
2131                .field("window_id", window_id)
2132                .finish(),
2133            Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
2134        }
2135    }
2136}
2137
2138pub trait AnyModel {
2139    fn as_any(&self) -> &dyn Any;
2140    fn as_any_mut(&mut self) -> &mut dyn Any;
2141    fn release(&mut self, cx: &mut MutableAppContext);
2142    fn app_will_quit(
2143        &mut self,
2144        cx: &mut MutableAppContext,
2145    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2146}
2147
2148impl<T> AnyModel for T
2149where
2150    T: Entity,
2151{
2152    fn as_any(&self) -> &dyn Any {
2153        self
2154    }
2155
2156    fn as_any_mut(&mut self) -> &mut dyn Any {
2157        self
2158    }
2159
2160    fn release(&mut self, cx: &mut MutableAppContext) {
2161        self.release(cx);
2162    }
2163
2164    fn app_will_quit(
2165        &mut self,
2166        cx: &mut MutableAppContext,
2167    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2168        self.app_will_quit(cx)
2169    }
2170}
2171
2172pub trait AnyView {
2173    fn as_any(&self) -> &dyn Any;
2174    fn as_any_mut(&mut self) -> &mut dyn Any;
2175    fn release(&mut self, cx: &mut MutableAppContext);
2176    fn app_will_quit(
2177        &mut self,
2178        cx: &mut MutableAppContext,
2179    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2180    fn ui_name(&self) -> &'static str;
2181    fn render<'a>(
2182        &mut self,
2183        window_id: usize,
2184        view_id: usize,
2185        titlebar_height: f32,
2186        refreshing: bool,
2187        cx: &mut MutableAppContext,
2188    ) -> ElementBox;
2189    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2190    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
2191    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
2192}
2193
2194impl<T> AnyView for T
2195where
2196    T: View,
2197{
2198    fn as_any(&self) -> &dyn Any {
2199        self
2200    }
2201
2202    fn as_any_mut(&mut self) -> &mut dyn Any {
2203        self
2204    }
2205
2206    fn release(&mut self, cx: &mut MutableAppContext) {
2207        self.release(cx);
2208    }
2209
2210    fn app_will_quit(
2211        &mut self,
2212        cx: &mut MutableAppContext,
2213    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2214        self.app_will_quit(cx)
2215    }
2216
2217    fn ui_name(&self) -> &'static str {
2218        T::ui_name()
2219    }
2220
2221    fn render<'a>(
2222        &mut self,
2223        window_id: usize,
2224        view_id: usize,
2225        titlebar_height: f32,
2226        refreshing: bool,
2227        cx: &mut MutableAppContext,
2228    ) -> ElementBox {
2229        View::render(
2230            self,
2231            &mut RenderContext {
2232                window_id,
2233                view_id,
2234                app: cx,
2235                view_type: PhantomData::<T>,
2236                titlebar_height,
2237                refreshing,
2238            },
2239        )
2240    }
2241
2242    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
2243        let mut cx = ViewContext::new(cx, window_id, view_id);
2244        View::on_focus(self, &mut cx);
2245    }
2246
2247    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
2248        let mut cx = ViewContext::new(cx, window_id, view_id);
2249        View::on_blur(self, &mut cx);
2250    }
2251
2252    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
2253        View::keymap_context(self, cx)
2254    }
2255}
2256
2257pub struct ModelContext<'a, T: ?Sized> {
2258    app: &'a mut MutableAppContext,
2259    model_id: usize,
2260    model_type: PhantomData<T>,
2261    halt_stream: bool,
2262}
2263
2264impl<'a, T: Entity> ModelContext<'a, T> {
2265    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
2266        Self {
2267            app,
2268            model_id,
2269            model_type: PhantomData,
2270            halt_stream: false,
2271        }
2272    }
2273
2274    pub fn background(&self) -> &Arc<executor::Background> {
2275        &self.app.cx.background
2276    }
2277
2278    pub fn halt_stream(&mut self) {
2279        self.halt_stream = true;
2280    }
2281
2282    pub fn model_id(&self) -> usize {
2283        self.model_id
2284    }
2285
2286    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2287    where
2288        S: Entity,
2289        F: FnOnce(&mut ModelContext<S>) -> S,
2290    {
2291        self.app.add_model(build_model)
2292    }
2293
2294    pub fn emit(&mut self, payload: T::Event) {
2295        self.app.pending_effects.push_back(Effect::Event {
2296            entity_id: self.model_id,
2297            payload: Box::new(payload),
2298        });
2299    }
2300
2301    pub fn notify(&mut self) {
2302        self.app.notify_model(self.model_id);
2303    }
2304
2305    pub fn subscribe<S: Entity, F>(
2306        &mut self,
2307        handle: &ModelHandle<S>,
2308        mut callback: F,
2309    ) -> Subscription
2310    where
2311        S::Event: 'static,
2312        F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
2313    {
2314        let subscriber = self.weak_handle();
2315        self.app
2316            .subscribe_internal(handle, move |emitter, event, cx| {
2317                if let Some(subscriber) = subscriber.upgrade(cx) {
2318                    subscriber.update(cx, |subscriber, cx| {
2319                        callback(subscriber, emitter, event, cx);
2320                    });
2321                    true
2322                } else {
2323                    false
2324                }
2325            })
2326    }
2327
2328    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
2329    where
2330        S: Entity,
2331        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
2332    {
2333        let observer = self.weak_handle();
2334        self.app.observe_internal(handle, move |observed, cx| {
2335            if let Some(observer) = observer.upgrade(cx) {
2336                observer.update(cx, |observer, cx| {
2337                    callback(observer, observed, cx);
2338                });
2339                true
2340            } else {
2341                false
2342            }
2343        })
2344    }
2345
2346    pub fn observe_release<S, F>(
2347        &mut self,
2348        handle: &ModelHandle<S>,
2349        mut callback: F,
2350    ) -> Subscription
2351    where
2352        S: Entity,
2353        F: 'static + FnMut(&mut T, &mut ModelContext<T>),
2354    {
2355        let observer = self.weak_handle();
2356        self.app.observe_release(handle, move |cx| {
2357            if let Some(observer) = observer.upgrade(cx) {
2358                observer.update(cx, |observer, cx| {
2359                    callback(observer, cx);
2360                });
2361            }
2362        })
2363    }
2364
2365    pub fn handle(&self) -> ModelHandle<T> {
2366        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
2367    }
2368
2369    pub fn weak_handle(&self) -> WeakModelHandle<T> {
2370        WeakModelHandle::new(self.model_id)
2371    }
2372
2373    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
2374    where
2375        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
2376        Fut: 'static + Future<Output = S>,
2377        S: 'static,
2378    {
2379        let handle = self.handle();
2380        self.app.spawn(|cx| f(handle, cx))
2381    }
2382
2383    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
2384    where
2385        F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
2386        Fut: 'static + Future<Output = S>,
2387        S: 'static,
2388    {
2389        let handle = self.weak_handle();
2390        self.app.spawn(|cx| f(handle, cx))
2391    }
2392}
2393
2394impl<M> AsRef<AppContext> for ModelContext<'_, M> {
2395    fn as_ref(&self) -> &AppContext {
2396        &self.app.cx
2397    }
2398}
2399
2400impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
2401    fn as_mut(&mut self) -> &mut MutableAppContext {
2402        self.app
2403    }
2404}
2405
2406impl<M> ReadModel for ModelContext<'_, M> {
2407    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2408        self.app.read_model(handle)
2409    }
2410}
2411
2412impl<M> UpdateModel for ModelContext<'_, M> {
2413    fn update_model<T: Entity, V>(
2414        &mut self,
2415        handle: &ModelHandle<T>,
2416        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2417    ) -> V {
2418        self.app.update_model(handle, update)
2419    }
2420}
2421
2422impl<M> UpgradeModelHandle for ModelContext<'_, M> {
2423    fn upgrade_model_handle<T: Entity>(
2424        &self,
2425        handle: &WeakModelHandle<T>,
2426    ) -> Option<ModelHandle<T>> {
2427        self.cx.upgrade_model_handle(handle)
2428    }
2429
2430    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2431        self.cx.model_handle_is_upgradable(handle)
2432    }
2433
2434    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2435        self.cx.upgrade_any_model_handle(handle)
2436    }
2437}
2438
2439impl<M> Deref for ModelContext<'_, M> {
2440    type Target = MutableAppContext;
2441
2442    fn deref(&self) -> &Self::Target {
2443        &self.app
2444    }
2445}
2446
2447impl<M> DerefMut for ModelContext<'_, M> {
2448    fn deref_mut(&mut self) -> &mut Self::Target {
2449        &mut self.app
2450    }
2451}
2452
2453pub struct ViewContext<'a, T: ?Sized> {
2454    app: &'a mut MutableAppContext,
2455    window_id: usize,
2456    view_id: usize,
2457    view_type: PhantomData<T>,
2458}
2459
2460impl<'a, T: View> ViewContext<'a, T> {
2461    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
2462        Self {
2463            app,
2464            window_id,
2465            view_id,
2466            view_type: PhantomData,
2467        }
2468    }
2469
2470    pub fn handle(&self) -> ViewHandle<T> {
2471        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
2472    }
2473
2474    pub fn weak_handle(&self) -> WeakViewHandle<T> {
2475        WeakViewHandle::new(self.window_id, self.view_id)
2476    }
2477
2478    pub fn window_id(&self) -> usize {
2479        self.window_id
2480    }
2481
2482    pub fn view_id(&self) -> usize {
2483        self.view_id
2484    }
2485
2486    pub fn foreground(&self) -> &Rc<executor::Foreground> {
2487        self.app.foreground()
2488    }
2489
2490    pub fn background_executor(&self) -> &Arc<executor::Background> {
2491        &self.app.cx.background
2492    }
2493
2494    pub fn platform(&self) -> Arc<dyn Platform> {
2495        self.app.platform()
2496    }
2497
2498    pub fn prompt(
2499        &self,
2500        level: PromptLevel,
2501        msg: &str,
2502        answers: &[&str],
2503    ) -> oneshot::Receiver<usize> {
2504        self.app.prompt(self.window_id, level, msg, answers)
2505    }
2506
2507    pub fn prompt_for_paths(
2508        &self,
2509        options: PathPromptOptions,
2510    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
2511        self.app.prompt_for_paths(options)
2512    }
2513
2514    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
2515        self.app.prompt_for_new_path(directory)
2516    }
2517
2518    pub fn debug_elements(&self) -> crate::json::Value {
2519        self.app.debug_elements(self.window_id).unwrap()
2520    }
2521
2522    pub fn focus<S>(&mut self, handle: S)
2523    where
2524        S: Into<AnyViewHandle>,
2525    {
2526        let handle = handle.into();
2527        self.app.pending_effects.push_back(Effect::Focus {
2528            window_id: handle.window_id,
2529            view_id: handle.view_id,
2530        });
2531    }
2532
2533    pub fn focus_self(&mut self) {
2534        self.app.pending_effects.push_back(Effect::Focus {
2535            window_id: self.window_id,
2536            view_id: self.view_id,
2537        });
2538    }
2539
2540    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2541    where
2542        S: Entity,
2543        F: FnOnce(&mut ModelContext<S>) -> S,
2544    {
2545        self.app.add_model(build_model)
2546    }
2547
2548    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
2549    where
2550        S: View,
2551        F: FnOnce(&mut ViewContext<S>) -> S,
2552    {
2553        self.app.add_view(self.window_id, build_view)
2554    }
2555
2556    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
2557    where
2558        S: View,
2559        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
2560    {
2561        self.app.add_option_view(self.window_id, build_view)
2562    }
2563
2564    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
2565    where
2566        E: Entity,
2567        E::Event: 'static,
2568        H: Handle<E>,
2569        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
2570    {
2571        let subscriber = self.weak_handle();
2572        self.app
2573            .subscribe_internal(handle, move |emitter, event, cx| {
2574                if let Some(subscriber) = subscriber.upgrade(cx) {
2575                    subscriber.update(cx, |subscriber, cx| {
2576                        callback(subscriber, emitter, event, cx);
2577                    });
2578                    true
2579                } else {
2580                    false
2581                }
2582            })
2583    }
2584
2585    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
2586    where
2587        E: Entity,
2588        H: Handle<E>,
2589        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
2590    {
2591        let observer = self.weak_handle();
2592        self.app.observe_internal(handle, move |observed, cx| {
2593            if let Some(observer) = observer.upgrade(cx) {
2594                observer.update(cx, |observer, cx| {
2595                    callback(observer, observed, cx);
2596                });
2597                true
2598            } else {
2599                false
2600            }
2601        })
2602    }
2603
2604    pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
2605    where
2606        E: Entity,
2607        H: Handle<E>,
2608        F: 'static + FnMut(&mut T, &mut ViewContext<T>),
2609    {
2610        let observer = self.weak_handle();
2611        self.app.observe_release(handle, move |cx| {
2612            if let Some(observer) = observer.upgrade(cx) {
2613                observer.update(cx, |observer, cx| {
2614                    callback(observer, cx);
2615                });
2616            }
2617        })
2618    }
2619
2620    pub fn emit(&mut self, payload: T::Event) {
2621        self.app.pending_effects.push_back(Effect::Event {
2622            entity_id: self.view_id,
2623            payload: Box::new(payload),
2624        });
2625    }
2626
2627    pub fn notify(&mut self) {
2628        self.app.notify_view(self.window_id, self.view_id);
2629    }
2630
2631    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>)) {
2632        let handle = self.handle();
2633        self.app.defer(Box::new(move |cx| {
2634            handle.update(cx, |view, cx| {
2635                callback(view, cx);
2636            })
2637        }))
2638    }
2639
2640    pub fn propagate_action(&mut self) {
2641        self.app.halt_action_dispatch = false;
2642    }
2643
2644    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
2645    where
2646        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
2647        Fut: 'static + Future<Output = S>,
2648        S: 'static,
2649    {
2650        let handle = self.handle();
2651        self.app.spawn(|cx| f(handle, cx))
2652    }
2653
2654    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
2655    where
2656        F: FnOnce(WeakViewHandle<T>, AsyncAppContext) -> Fut,
2657        Fut: 'static + Future<Output = S>,
2658        S: 'static,
2659    {
2660        let handle = self.weak_handle();
2661        self.app.spawn(|cx| f(handle, cx))
2662    }
2663}
2664
2665pub struct RenderContext<'a, T: View> {
2666    pub app: &'a mut MutableAppContext,
2667    pub titlebar_height: f32,
2668    pub refreshing: bool,
2669    window_id: usize,
2670    view_id: usize,
2671    view_type: PhantomData<T>,
2672}
2673
2674impl<'a, T: View> RenderContext<'a, T> {
2675    pub fn handle(&self) -> WeakViewHandle<T> {
2676        WeakViewHandle::new(self.window_id, self.view_id)
2677    }
2678
2679    pub fn view_id(&self) -> usize {
2680        self.view_id
2681    }
2682}
2683
2684impl AsRef<AppContext> for &AppContext {
2685    fn as_ref(&self) -> &AppContext {
2686        self
2687    }
2688}
2689
2690impl<V: View> Deref for RenderContext<'_, V> {
2691    type Target = MutableAppContext;
2692
2693    fn deref(&self) -> &Self::Target {
2694        self.app
2695    }
2696}
2697
2698impl<V: View> DerefMut for RenderContext<'_, V> {
2699    fn deref_mut(&mut self) -> &mut Self::Target {
2700        self.app
2701    }
2702}
2703
2704impl<V: View> ReadModel for RenderContext<'_, V> {
2705    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2706        self.app.read_model(handle)
2707    }
2708}
2709
2710impl<V: View> UpdateModel for RenderContext<'_, V> {
2711    fn update_model<T: Entity, O>(
2712        &mut self,
2713        handle: &ModelHandle<T>,
2714        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
2715    ) -> O {
2716        self.app.update_model(handle, update)
2717    }
2718}
2719
2720impl<V: View> ReadView for RenderContext<'_, V> {
2721    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2722        self.app.read_view(handle)
2723    }
2724}
2725
2726impl<V: View> ElementStateContext for RenderContext<'_, V> {
2727    fn current_view_id(&self) -> usize {
2728        self.view_id
2729    }
2730}
2731
2732impl<M> AsRef<AppContext> for ViewContext<'_, M> {
2733    fn as_ref(&self) -> &AppContext {
2734        &self.app.cx
2735    }
2736}
2737
2738impl<M> Deref for ViewContext<'_, M> {
2739    type Target = MutableAppContext;
2740
2741    fn deref(&self) -> &Self::Target {
2742        &self.app
2743    }
2744}
2745
2746impl<M> DerefMut for ViewContext<'_, M> {
2747    fn deref_mut(&mut self) -> &mut Self::Target {
2748        &mut self.app
2749    }
2750}
2751
2752impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
2753    fn as_mut(&mut self) -> &mut MutableAppContext {
2754        self.app
2755    }
2756}
2757
2758impl<V> ReadModel for ViewContext<'_, V> {
2759    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2760        self.app.read_model(handle)
2761    }
2762}
2763
2764impl<V> UpgradeModelHandle for ViewContext<'_, V> {
2765    fn upgrade_model_handle<T: Entity>(
2766        &self,
2767        handle: &WeakModelHandle<T>,
2768    ) -> Option<ModelHandle<T>> {
2769        self.cx.upgrade_model_handle(handle)
2770    }
2771
2772    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2773        self.cx.model_handle_is_upgradable(handle)
2774    }
2775
2776    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2777        self.cx.upgrade_any_model_handle(handle)
2778    }
2779}
2780
2781impl<V> UpgradeViewHandle for ViewContext<'_, V> {
2782    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2783        self.cx.upgrade_view_handle(handle)
2784    }
2785}
2786
2787impl<V: View> UpdateModel for ViewContext<'_, V> {
2788    fn update_model<T: Entity, O>(
2789        &mut self,
2790        handle: &ModelHandle<T>,
2791        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
2792    ) -> O {
2793        self.app.update_model(handle, update)
2794    }
2795}
2796
2797impl<V: View> ReadView for ViewContext<'_, V> {
2798    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2799        self.app.read_view(handle)
2800    }
2801}
2802
2803impl<V: View> UpdateView for ViewContext<'_, V> {
2804    fn update_view<T, S>(
2805        &mut self,
2806        handle: &ViewHandle<T>,
2807        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
2808    ) -> S
2809    where
2810        T: View,
2811    {
2812        self.app.update_view(handle, update)
2813    }
2814}
2815
2816impl<V: View> ElementStateContext for ViewContext<'_, V> {
2817    fn current_view_id(&self) -> usize {
2818        self.view_id
2819    }
2820}
2821
2822pub trait Handle<T> {
2823    type Weak: 'static;
2824    fn id(&self) -> usize;
2825    fn location(&self) -> EntityLocation;
2826    fn downgrade(&self) -> Self::Weak;
2827    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2828    where
2829        Self: Sized;
2830}
2831
2832#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
2833pub enum EntityLocation {
2834    Model(usize),
2835    View(usize, usize),
2836}
2837
2838pub struct ModelHandle<T: Entity> {
2839    model_id: usize,
2840    model_type: PhantomData<T>,
2841    ref_counts: Arc<Mutex<RefCounts>>,
2842
2843    #[cfg(feature = "test-support")]
2844    handle_id: usize,
2845}
2846
2847impl<T: Entity> ModelHandle<T> {
2848    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2849        ref_counts.lock().inc_model(model_id);
2850
2851        #[cfg(feature = "test-support")]
2852        let handle_id = ref_counts
2853            .lock()
2854            .leak_detector
2855            .lock()
2856            .handle_created(Some(type_name::<T>()), model_id);
2857
2858        Self {
2859            model_id,
2860            model_type: PhantomData,
2861            ref_counts: ref_counts.clone(),
2862
2863            #[cfg(feature = "test-support")]
2864            handle_id,
2865        }
2866    }
2867
2868    pub fn downgrade(&self) -> WeakModelHandle<T> {
2869        WeakModelHandle::new(self.model_id)
2870    }
2871
2872    pub fn id(&self) -> usize {
2873        self.model_id
2874    }
2875
2876    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
2877        cx.read_model(self)
2878    }
2879
2880    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
2881    where
2882        C: ReadModelWith,
2883        F: FnOnce(&T, &AppContext) -> S,
2884    {
2885        let mut read = Some(read);
2886        cx.read_model_with(self, &mut |model, cx| {
2887            let read = read.take().unwrap();
2888            read(model, cx)
2889        })
2890    }
2891
2892    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
2893    where
2894        C: UpdateModel,
2895        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
2896    {
2897        let mut update = Some(update);
2898        cx.update_model(self, &mut |model, cx| {
2899            let update = update.take().unwrap();
2900            update(model, cx)
2901        })
2902    }
2903
2904    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
2905        let (mut tx, mut rx) = mpsc::channel(1);
2906        let mut cx = cx.cx.borrow_mut();
2907        let subscription = cx.observe(self, move |_, _| {
2908            tx.try_send(()).ok();
2909        });
2910
2911        let duration = if std::env::var("CI").is_ok() {
2912            Duration::from_secs(5)
2913        } else {
2914            Duration::from_secs(1)
2915        };
2916
2917        async move {
2918            let notification = timeout(duration, rx.recv())
2919                .await
2920                .expect("next notification timed out");
2921            drop(subscription);
2922            notification.expect("model dropped while test was waiting for its next notification")
2923        }
2924    }
2925
2926    pub fn next_event(&self, cx: &TestAppContext) -> impl Future<Output = T::Event>
2927    where
2928        T::Event: Clone,
2929    {
2930        let (mut tx, mut rx) = mpsc::channel(1);
2931        let mut cx = cx.cx.borrow_mut();
2932        let subscription = cx.subscribe(self, move |_, event, _| {
2933            tx.blocking_send(event.clone()).ok();
2934        });
2935
2936        let duration = if std::env::var("CI").is_ok() {
2937            Duration::from_secs(5)
2938        } else {
2939            Duration::from_secs(1)
2940        };
2941
2942        async move {
2943            let event = timeout(duration, rx.recv())
2944                .await
2945                .expect("next event timed out");
2946            drop(subscription);
2947            event.expect("model dropped while test was waiting for its next event")
2948        }
2949    }
2950
2951    pub fn condition(
2952        &self,
2953        cx: &TestAppContext,
2954        mut predicate: impl FnMut(&T, &AppContext) -> bool,
2955    ) -> impl Future<Output = ()> {
2956        let (tx, mut rx) = mpsc::channel(1024);
2957
2958        let mut cx = cx.cx.borrow_mut();
2959        let subscriptions = (
2960            cx.observe(self, {
2961                let mut tx = tx.clone();
2962                move |_, _| {
2963                    tx.blocking_send(()).ok();
2964                }
2965            }),
2966            cx.subscribe(self, {
2967                let mut tx = tx.clone();
2968                move |_, _, _| {
2969                    tx.blocking_send(()).ok();
2970                }
2971            }),
2972        );
2973
2974        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
2975        let handle = self.downgrade();
2976        let duration = if std::env::var("CI").is_ok() {
2977            Duration::from_secs(5)
2978        } else {
2979            Duration::from_secs(1)
2980        };
2981
2982        async move {
2983            timeout(duration, async move {
2984                loop {
2985                    {
2986                        let cx = cx.borrow();
2987                        let cx = cx.as_ref();
2988                        if predicate(
2989                            handle
2990                                .upgrade(cx)
2991                                .expect("model dropped with pending condition")
2992                                .read(cx),
2993                            cx,
2994                        ) {
2995                            break;
2996                        }
2997                    }
2998
2999                    cx.borrow().foreground().start_waiting();
3000                    rx.recv()
3001                        .await
3002                        .expect("model dropped with pending condition");
3003                    cx.borrow().foreground().finish_waiting();
3004                }
3005            })
3006            .await
3007            .expect("condition timed out");
3008            drop(subscriptions);
3009        }
3010    }
3011}
3012
3013impl<T: Entity> Clone for ModelHandle<T> {
3014    fn clone(&self) -> Self {
3015        Self::new(self.model_id, &self.ref_counts)
3016    }
3017}
3018
3019impl<T: Entity> PartialEq for ModelHandle<T> {
3020    fn eq(&self, other: &Self) -> bool {
3021        self.model_id == other.model_id
3022    }
3023}
3024
3025impl<T: Entity> Eq for ModelHandle<T> {}
3026
3027impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
3028    fn eq(&self, other: &WeakModelHandle<T>) -> bool {
3029        self.model_id == other.model_id
3030    }
3031}
3032
3033impl<T: Entity> Hash for ModelHandle<T> {
3034    fn hash<H: Hasher>(&self, state: &mut H) {
3035        self.model_id.hash(state);
3036    }
3037}
3038
3039impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
3040    fn borrow(&self) -> &usize {
3041        &self.model_id
3042    }
3043}
3044
3045impl<T: Entity> Debug for ModelHandle<T> {
3046    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3047        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
3048            .field(&self.model_id)
3049            .finish()
3050    }
3051}
3052
3053unsafe impl<T: Entity> Send for ModelHandle<T> {}
3054unsafe impl<T: Entity> Sync for ModelHandle<T> {}
3055
3056impl<T: Entity> Drop for ModelHandle<T> {
3057    fn drop(&mut self) {
3058        let mut ref_counts = self.ref_counts.lock();
3059        ref_counts.dec_model(self.model_id);
3060
3061        #[cfg(feature = "test-support")]
3062        ref_counts
3063            .leak_detector
3064            .lock()
3065            .handle_dropped(self.model_id, self.handle_id);
3066    }
3067}
3068
3069impl<T: Entity> Handle<T> for ModelHandle<T> {
3070    type Weak = WeakModelHandle<T>;
3071
3072    fn id(&self) -> usize {
3073        self.model_id
3074    }
3075
3076    fn location(&self) -> EntityLocation {
3077        EntityLocation::Model(self.model_id)
3078    }
3079
3080    fn downgrade(&self) -> Self::Weak {
3081        self.downgrade()
3082    }
3083
3084    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3085    where
3086        Self: Sized,
3087    {
3088        weak.upgrade(cx)
3089    }
3090}
3091
3092pub struct WeakModelHandle<T> {
3093    model_id: usize,
3094    model_type: PhantomData<T>,
3095}
3096
3097unsafe impl<T> Send for WeakModelHandle<T> {}
3098unsafe impl<T> Sync for WeakModelHandle<T> {}
3099
3100impl<T: Entity> WeakModelHandle<T> {
3101    fn new(model_id: usize) -> Self {
3102        Self {
3103            model_id,
3104            model_type: PhantomData,
3105        }
3106    }
3107
3108    pub fn id(&self) -> usize {
3109        self.model_id
3110    }
3111
3112    pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
3113        cx.model_handle_is_upgradable(self)
3114    }
3115
3116    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
3117        cx.upgrade_model_handle(self)
3118    }
3119}
3120
3121impl<T> Hash for WeakModelHandle<T> {
3122    fn hash<H: Hasher>(&self, state: &mut H) {
3123        self.model_id.hash(state)
3124    }
3125}
3126
3127impl<T> PartialEq for WeakModelHandle<T> {
3128    fn eq(&self, other: &Self) -> bool {
3129        self.model_id == other.model_id
3130    }
3131}
3132
3133impl<T> Eq for WeakModelHandle<T> {}
3134
3135impl<T> Clone for WeakModelHandle<T> {
3136    fn clone(&self) -> Self {
3137        Self {
3138            model_id: self.model_id,
3139            model_type: PhantomData,
3140        }
3141    }
3142}
3143
3144impl<T> Copy for WeakModelHandle<T> {}
3145
3146pub struct ViewHandle<T> {
3147    window_id: usize,
3148    view_id: usize,
3149    view_type: PhantomData<T>,
3150    ref_counts: Arc<Mutex<RefCounts>>,
3151}
3152
3153impl<T: View> ViewHandle<T> {
3154    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3155        ref_counts.lock().inc_view(window_id, view_id);
3156        Self {
3157            window_id,
3158            view_id,
3159            view_type: PhantomData,
3160            ref_counts: ref_counts.clone(),
3161        }
3162    }
3163
3164    pub fn downgrade(&self) -> WeakViewHandle<T> {
3165        WeakViewHandle::new(self.window_id, self.view_id)
3166    }
3167
3168    pub fn window_id(&self) -> usize {
3169        self.window_id
3170    }
3171
3172    pub fn id(&self) -> usize {
3173        self.view_id
3174    }
3175
3176    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
3177        cx.read_view(self)
3178    }
3179
3180    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3181    where
3182        C: ReadViewWith,
3183        F: FnOnce(&T, &AppContext) -> S,
3184    {
3185        let mut read = Some(read);
3186        cx.read_view_with(self, &mut |view, cx| {
3187            let read = read.take().unwrap();
3188            read(view, cx)
3189        })
3190    }
3191
3192    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3193    where
3194        C: UpdateView,
3195        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
3196    {
3197        let mut update = Some(update);
3198        cx.update_view(self, &mut |view, cx| {
3199            let update = update.take().unwrap();
3200            update(view, cx)
3201        })
3202    }
3203
3204    pub fn defer<C, F>(&self, cx: &mut C, update: F)
3205    where
3206        C: AsMut<MutableAppContext>,
3207        F: 'static + FnOnce(&mut T, &mut ViewContext<T>),
3208    {
3209        let this = self.clone();
3210        cx.as_mut().defer(Box::new(move |cx| {
3211            this.update(cx, |view, cx| update(view, cx));
3212        }));
3213    }
3214
3215    pub fn is_focused(&self, cx: &AppContext) -> bool {
3216        cx.focused_view_id(self.window_id)
3217            .map_or(false, |focused_id| focused_id == self.view_id)
3218    }
3219
3220    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
3221        let (mut tx, mut rx) = mpsc::channel(1);
3222        let mut cx = cx.cx.borrow_mut();
3223        let subscription = cx.observe(self, move |_, _| {
3224            tx.try_send(()).ok();
3225        });
3226
3227        let duration = if std::env::var("CI").is_ok() {
3228            Duration::from_secs(5)
3229        } else {
3230            Duration::from_secs(1)
3231        };
3232
3233        async move {
3234            let notification = timeout(duration, rx.recv())
3235                .await
3236                .expect("next notification timed out");
3237            drop(subscription);
3238            notification.expect("model dropped while test was waiting for its next notification")
3239        }
3240    }
3241
3242    pub fn condition(
3243        &self,
3244        cx: &TestAppContext,
3245        mut predicate: impl FnMut(&T, &AppContext) -> bool,
3246    ) -> impl Future<Output = ()> {
3247        let (tx, mut rx) = mpsc::channel(1024);
3248
3249        let mut cx = cx.cx.borrow_mut();
3250        let subscriptions = self.update(&mut *cx, |_, cx| {
3251            (
3252                cx.observe(self, {
3253                    let mut tx = tx.clone();
3254                    move |_, _, _| {
3255                        tx.blocking_send(()).ok();
3256                    }
3257                }),
3258                cx.subscribe(self, {
3259                    let mut tx = tx.clone();
3260                    move |_, _, _, _| {
3261                        tx.blocking_send(()).ok();
3262                    }
3263                }),
3264            )
3265        });
3266
3267        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
3268        let handle = self.downgrade();
3269        let duration = if std::env::var("CI").is_ok() {
3270            Duration::from_secs(2)
3271        } else {
3272            Duration::from_millis(500)
3273        };
3274
3275        async move {
3276            timeout(duration, async move {
3277                loop {
3278                    {
3279                        let cx = cx.borrow();
3280                        let cx = cx.as_ref();
3281                        if predicate(
3282                            handle
3283                                .upgrade(cx)
3284                                .expect("view dropped with pending condition")
3285                                .read(cx),
3286                            cx,
3287                        ) {
3288                            break;
3289                        }
3290                    }
3291
3292                    cx.borrow().foreground().start_waiting();
3293                    rx.recv()
3294                        .await
3295                        .expect("view dropped with pending condition");
3296                    cx.borrow().foreground().finish_waiting();
3297                }
3298            })
3299            .await
3300            .expect("condition timed out");
3301            drop(subscriptions);
3302        }
3303    }
3304}
3305
3306impl<T> Clone for ViewHandle<T> {
3307    fn clone(&self) -> Self {
3308        self.ref_counts
3309            .lock()
3310            .inc_view(self.window_id, self.view_id);
3311        Self {
3312            window_id: self.window_id,
3313            view_id: self.view_id,
3314            view_type: PhantomData,
3315            ref_counts: self.ref_counts.clone(),
3316        }
3317    }
3318}
3319
3320impl<T> PartialEq for ViewHandle<T> {
3321    fn eq(&self, other: &Self) -> bool {
3322        self.window_id == other.window_id && self.view_id == other.view_id
3323    }
3324}
3325
3326impl<T> Eq for ViewHandle<T> {}
3327
3328impl<T> Debug for ViewHandle<T> {
3329    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3330        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
3331            .field("window_id", &self.window_id)
3332            .field("view_id", &self.view_id)
3333            .finish()
3334    }
3335}
3336
3337impl<T> Drop for ViewHandle<T> {
3338    fn drop(&mut self) {
3339        self.ref_counts
3340            .lock()
3341            .dec_view(self.window_id, self.view_id);
3342    }
3343}
3344
3345impl<T: View> Handle<T> for ViewHandle<T> {
3346    type Weak = WeakViewHandle<T>;
3347
3348    fn id(&self) -> usize {
3349        self.view_id
3350    }
3351
3352    fn location(&self) -> EntityLocation {
3353        EntityLocation::View(self.window_id, self.view_id)
3354    }
3355
3356    fn downgrade(&self) -> Self::Weak {
3357        self.downgrade()
3358    }
3359
3360    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3361    where
3362        Self: Sized,
3363    {
3364        weak.upgrade(cx)
3365    }
3366}
3367
3368pub struct AnyViewHandle {
3369    window_id: usize,
3370    view_id: usize,
3371    view_type: TypeId,
3372    ref_counts: Arc<Mutex<RefCounts>>,
3373}
3374
3375impl AnyViewHandle {
3376    pub fn id(&self) -> usize {
3377        self.view_id
3378    }
3379
3380    pub fn is<T: 'static>(&self) -> bool {
3381        TypeId::of::<T>() == self.view_type
3382    }
3383
3384    pub fn is_focused(&self, cx: &AppContext) -> bool {
3385        cx.focused_view_id(self.window_id)
3386            .map_or(false, |focused_id| focused_id == self.view_id)
3387    }
3388
3389    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
3390        if self.is::<T>() {
3391            let result = Some(ViewHandle {
3392                window_id: self.window_id,
3393                view_id: self.view_id,
3394                ref_counts: self.ref_counts.clone(),
3395                view_type: PhantomData,
3396            });
3397            unsafe {
3398                Arc::decrement_strong_count(&self.ref_counts);
3399            }
3400            std::mem::forget(self);
3401            result
3402        } else {
3403            None
3404        }
3405    }
3406}
3407
3408impl Clone for AnyViewHandle {
3409    fn clone(&self) -> Self {
3410        self.ref_counts
3411            .lock()
3412            .inc_view(self.window_id, self.view_id);
3413        Self {
3414            window_id: self.window_id,
3415            view_id: self.view_id,
3416            view_type: self.view_type,
3417            ref_counts: self.ref_counts.clone(),
3418        }
3419    }
3420}
3421
3422impl From<&AnyViewHandle> for AnyViewHandle {
3423    fn from(handle: &AnyViewHandle) -> Self {
3424        handle.clone()
3425    }
3426}
3427
3428impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
3429    fn from(handle: &ViewHandle<T>) -> Self {
3430        handle
3431            .ref_counts
3432            .lock()
3433            .inc_view(handle.window_id, handle.view_id);
3434        AnyViewHandle {
3435            window_id: handle.window_id,
3436            view_id: handle.view_id,
3437            view_type: TypeId::of::<T>(),
3438            ref_counts: handle.ref_counts.clone(),
3439        }
3440    }
3441}
3442
3443impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
3444    fn from(handle: ViewHandle<T>) -> Self {
3445        let any_handle = AnyViewHandle {
3446            window_id: handle.window_id,
3447            view_id: handle.view_id,
3448            view_type: TypeId::of::<T>(),
3449            ref_counts: handle.ref_counts.clone(),
3450        };
3451        unsafe {
3452            Arc::decrement_strong_count(&handle.ref_counts);
3453        }
3454        std::mem::forget(handle);
3455        any_handle
3456    }
3457}
3458
3459impl Drop for AnyViewHandle {
3460    fn drop(&mut self) {
3461        self.ref_counts
3462            .lock()
3463            .dec_view(self.window_id, self.view_id);
3464    }
3465}
3466
3467pub struct AnyModelHandle {
3468    model_id: usize,
3469    model_type: TypeId,
3470    ref_counts: Arc<Mutex<RefCounts>>,
3471
3472    #[cfg(feature = "test-support")]
3473    handle_id: usize,
3474}
3475
3476impl AnyModelHandle {
3477    fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
3478        ref_counts.lock().inc_model(model_id);
3479
3480        #[cfg(feature = "test-support")]
3481        let handle_id = ref_counts
3482            .lock()
3483            .leak_detector
3484            .lock()
3485            .handle_created(None, model_id);
3486
3487        Self {
3488            model_id,
3489            model_type,
3490            ref_counts,
3491
3492            #[cfg(feature = "test-support")]
3493            handle_id,
3494        }
3495    }
3496
3497    pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
3498        if self.is::<T>() {
3499            let result = Some(ModelHandle {
3500                model_id: self.model_id,
3501                model_type: PhantomData,
3502                ref_counts: self.ref_counts.clone(),
3503
3504                #[cfg(feature = "test-support")]
3505                handle_id: self.handle_id,
3506            });
3507            unsafe {
3508                Arc::decrement_strong_count(&self.ref_counts);
3509            }
3510            std::mem::forget(self);
3511            result
3512        } else {
3513            None
3514        }
3515    }
3516
3517    pub fn downgrade(&self) -> AnyWeakModelHandle {
3518        AnyWeakModelHandle {
3519            model_id: self.model_id,
3520            model_type: self.model_type,
3521        }
3522    }
3523
3524    pub fn is<T: Entity>(&self) -> bool {
3525        self.model_type == TypeId::of::<T>()
3526    }
3527}
3528
3529impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
3530    fn from(handle: ModelHandle<T>) -> Self {
3531        Self::new(
3532            handle.model_id,
3533            TypeId::of::<T>(),
3534            handle.ref_counts.clone(),
3535        )
3536    }
3537}
3538
3539impl Clone for AnyModelHandle {
3540    fn clone(&self) -> Self {
3541        Self::new(self.model_id, self.model_type, self.ref_counts.clone())
3542    }
3543}
3544
3545impl Drop for AnyModelHandle {
3546    fn drop(&mut self) {
3547        let mut ref_counts = self.ref_counts.lock();
3548        ref_counts.dec_model(self.model_id);
3549
3550        #[cfg(feature = "test-support")]
3551        ref_counts
3552            .leak_detector
3553            .lock()
3554            .handle_dropped(self.model_id, self.handle_id);
3555    }
3556}
3557
3558pub struct AnyWeakModelHandle {
3559    model_id: usize,
3560    model_type: TypeId,
3561}
3562
3563impl AnyWeakModelHandle {
3564    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
3565        cx.upgrade_any_model_handle(self)
3566    }
3567}
3568
3569impl<T: Entity> From<WeakModelHandle<T>> for AnyWeakModelHandle {
3570    fn from(handle: WeakModelHandle<T>) -> Self {
3571        AnyWeakModelHandle {
3572            model_id: handle.model_id,
3573            model_type: TypeId::of::<T>(),
3574        }
3575    }
3576}
3577
3578pub struct WeakViewHandle<T> {
3579    window_id: usize,
3580    view_id: usize,
3581    view_type: PhantomData<T>,
3582}
3583
3584impl<T: View> WeakViewHandle<T> {
3585    fn new(window_id: usize, view_id: usize) -> Self {
3586        Self {
3587            window_id,
3588            view_id,
3589            view_type: PhantomData,
3590        }
3591    }
3592
3593    pub fn id(&self) -> usize {
3594        self.view_id
3595    }
3596
3597    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
3598        cx.upgrade_view_handle(self)
3599    }
3600}
3601
3602impl<T> Clone for WeakViewHandle<T> {
3603    fn clone(&self) -> Self {
3604        Self {
3605            window_id: self.window_id,
3606            view_id: self.view_id,
3607            view_type: PhantomData,
3608        }
3609    }
3610}
3611
3612impl<T> PartialEq for WeakViewHandle<T> {
3613    fn eq(&self, other: &Self) -> bool {
3614        self.window_id == other.window_id && self.view_id == other.view_id
3615    }
3616}
3617
3618impl<T> Eq for WeakViewHandle<T> {}
3619
3620impl<T> Hash for WeakViewHandle<T> {
3621    fn hash<H: Hasher>(&self, state: &mut H) {
3622        self.window_id.hash(state);
3623        self.view_id.hash(state);
3624    }
3625}
3626
3627#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3628pub struct ElementStateId {
3629    view_id: usize,
3630    element_id: usize,
3631    tag: TypeId,
3632}
3633
3634pub struct ElementStateHandle<T> {
3635    value_type: PhantomData<T>,
3636    id: ElementStateId,
3637    ref_counts: Weak<Mutex<RefCounts>>,
3638}
3639
3640impl<T: 'static> ElementStateHandle<T> {
3641    fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3642        ref_counts.lock().inc_element_state(id, frame_id);
3643        Self {
3644            value_type: PhantomData,
3645            id,
3646            ref_counts: Arc::downgrade(ref_counts),
3647        }
3648    }
3649
3650    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
3651        cx.element_states
3652            .get(&self.id)
3653            .unwrap()
3654            .downcast_ref()
3655            .unwrap()
3656    }
3657
3658    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
3659    where
3660        C: DerefMut<Target = MutableAppContext>,
3661    {
3662        let mut element_state = cx.deref_mut().cx.element_states.remove(&self.id).unwrap();
3663        let result = f(element_state.downcast_mut().unwrap(), cx);
3664        cx.deref_mut()
3665            .cx
3666            .element_states
3667            .insert(self.id, element_state);
3668        result
3669    }
3670}
3671
3672impl<T> Drop for ElementStateHandle<T> {
3673    fn drop(&mut self) {
3674        if let Some(ref_counts) = self.ref_counts.upgrade() {
3675            ref_counts.lock().dec_element_state(self.id);
3676        }
3677    }
3678}
3679
3680pub struct CursorStyleHandle {
3681    id: usize,
3682    next_cursor_style_handle_id: Arc<AtomicUsize>,
3683    platform: Arc<dyn Platform>,
3684}
3685
3686impl Drop for CursorStyleHandle {
3687    fn drop(&mut self) {
3688        if self.id + 1 == self.next_cursor_style_handle_id.load(SeqCst) {
3689            self.platform.set_cursor_style(CursorStyle::Arrow);
3690        }
3691    }
3692}
3693
3694#[must_use]
3695pub enum Subscription {
3696    Subscription {
3697        id: usize,
3698        entity_id: usize,
3699        subscriptions: Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, SubscriptionCallback>>>>>,
3700    },
3701    Observation {
3702        id: usize,
3703        entity_id: usize,
3704        observations: Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ObservationCallback>>>>>,
3705    },
3706    ReleaseObservation {
3707        id: usize,
3708        entity_id: usize,
3709        observations:
3710            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>>,
3711    },
3712}
3713
3714impl Subscription {
3715    pub fn detach(&mut self) {
3716        match self {
3717            Subscription::Subscription { subscriptions, .. } => {
3718                subscriptions.take();
3719            }
3720            Subscription::Observation { observations, .. } => {
3721                observations.take();
3722            }
3723            Subscription::ReleaseObservation { observations, .. } => {
3724                observations.take();
3725            }
3726        }
3727    }
3728}
3729
3730impl Drop for Subscription {
3731    fn drop(&mut self) {
3732        match self {
3733            Subscription::Observation {
3734                id,
3735                entity_id,
3736                observations,
3737            } => {
3738                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
3739                    if let Some(observations) = observations.lock().get_mut(entity_id) {
3740                        observations.remove(id);
3741                    }
3742                }
3743            }
3744            Subscription::ReleaseObservation {
3745                id,
3746                entity_id,
3747                observations,
3748            } => {
3749                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
3750                    if let Some(observations) = observations.lock().get_mut(entity_id) {
3751                        observations.remove(id);
3752                    }
3753                }
3754            }
3755            Subscription::Subscription {
3756                id,
3757                entity_id,
3758                subscriptions,
3759            } => {
3760                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
3761                    if let Some(subscriptions) = subscriptions.lock().get_mut(entity_id) {
3762                        subscriptions.remove(id);
3763                    }
3764                }
3765            }
3766        }
3767    }
3768}
3769
3770#[derive(Default)]
3771pub struct LeakDetector {
3772    next_handle_id: usize,
3773    handle_backtraces: HashMap<usize, (Option<&'static str>, HashMap<usize, Backtrace>)>,
3774}
3775
3776impl LeakDetector {
3777    fn handle_created(&mut self, type_name: Option<&'static str>, entity_id: usize) -> usize {
3778        let handle_id = post_inc(&mut self.next_handle_id);
3779        let entry = self.handle_backtraces.entry(entity_id).or_default();
3780        if let Some(type_name) = type_name {
3781            entry.0.get_or_insert(type_name);
3782        }
3783        entry.1.insert(handle_id, Backtrace::new_unresolved());
3784        handle_id
3785    }
3786
3787    fn handle_dropped(&mut self, entity_id: usize, handle_id: usize) {
3788        if let Some((_, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
3789            assert!(backtraces.remove(&handle_id).is_some());
3790            if backtraces.is_empty() {
3791                self.handle_backtraces.remove(&entity_id);
3792            }
3793        }
3794    }
3795
3796    pub fn detect(&mut self) {
3797        let mut found_leaks = false;
3798        for (id, (type_name, backtraces)) in self.handle_backtraces.iter_mut() {
3799            eprintln!(
3800                "leaked {} handles to {:?} {}",
3801                backtraces.len(),
3802                type_name.unwrap_or("entity"),
3803                id
3804            );
3805            for trace in backtraces.values_mut() {
3806                trace.resolve();
3807                eprintln!("{:?}", CwdBacktrace(trace));
3808            }
3809            found_leaks = true;
3810        }
3811        assert!(!found_leaks, "detected leaked handles");
3812    }
3813}
3814
3815#[derive(Default)]
3816struct RefCounts {
3817    entity_counts: HashMap<usize, usize>,
3818    element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
3819    dropped_models: HashSet<usize>,
3820    dropped_views: HashSet<(usize, usize)>,
3821    dropped_element_states: HashSet<ElementStateId>,
3822
3823    #[cfg(feature = "test-support")]
3824    leak_detector: Arc<Mutex<LeakDetector>>,
3825}
3826
3827struct ElementStateRefCount {
3828    ref_count: usize,
3829    frame_id: usize,
3830}
3831
3832impl RefCounts {
3833    fn inc_model(&mut self, model_id: usize) {
3834        match self.entity_counts.entry(model_id) {
3835            Entry::Occupied(mut entry) => {
3836                *entry.get_mut() += 1;
3837            }
3838            Entry::Vacant(entry) => {
3839                entry.insert(1);
3840                self.dropped_models.remove(&model_id);
3841            }
3842        }
3843    }
3844
3845    fn inc_view(&mut self, window_id: usize, view_id: usize) {
3846        match self.entity_counts.entry(view_id) {
3847            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
3848            Entry::Vacant(entry) => {
3849                entry.insert(1);
3850                self.dropped_views.remove(&(window_id, view_id));
3851            }
3852        }
3853    }
3854
3855    fn inc_element_state(&mut self, id: ElementStateId, frame_id: usize) {
3856        match self.element_state_counts.entry(id) {
3857            Entry::Occupied(mut entry) => {
3858                let entry = entry.get_mut();
3859                if entry.frame_id == frame_id || entry.ref_count >= 2 {
3860                    panic!("used the same element state more than once in the same frame");
3861                }
3862                entry.ref_count += 1;
3863                entry.frame_id = frame_id;
3864            }
3865            Entry::Vacant(entry) => {
3866                entry.insert(ElementStateRefCount {
3867                    ref_count: 1,
3868                    frame_id,
3869                });
3870                self.dropped_element_states.remove(&id);
3871            }
3872        }
3873    }
3874
3875    fn dec_model(&mut self, model_id: usize) {
3876        let count = self.entity_counts.get_mut(&model_id).unwrap();
3877        *count -= 1;
3878        if *count == 0 {
3879            self.entity_counts.remove(&model_id);
3880            self.dropped_models.insert(model_id);
3881        }
3882    }
3883
3884    fn dec_view(&mut self, window_id: usize, view_id: usize) {
3885        let count = self.entity_counts.get_mut(&view_id).unwrap();
3886        *count -= 1;
3887        if *count == 0 {
3888            self.entity_counts.remove(&view_id);
3889            self.dropped_views.insert((window_id, view_id));
3890        }
3891    }
3892
3893    fn dec_element_state(&mut self, id: ElementStateId) {
3894        let entry = self.element_state_counts.get_mut(&id).unwrap();
3895        entry.ref_count -= 1;
3896        if entry.ref_count == 0 {
3897            self.element_state_counts.remove(&id);
3898            self.dropped_element_states.insert(id);
3899        }
3900    }
3901
3902    fn is_entity_alive(&self, entity_id: usize) -> bool {
3903        self.entity_counts.contains_key(&entity_id)
3904    }
3905
3906    fn take_dropped(
3907        &mut self,
3908    ) -> (
3909        HashSet<usize>,
3910        HashSet<(usize, usize)>,
3911        HashSet<ElementStateId>,
3912    ) {
3913        (
3914            std::mem::take(&mut self.dropped_models),
3915            std::mem::take(&mut self.dropped_views),
3916            std::mem::take(&mut self.dropped_element_states),
3917        )
3918    }
3919}
3920
3921#[cfg(test)]
3922mod tests {
3923    use super::*;
3924    use crate::elements::*;
3925    use smol::future::poll_once;
3926    use std::{
3927        cell::Cell,
3928        sync::atomic::{AtomicUsize, Ordering::SeqCst},
3929    };
3930
3931    #[crate::test(self)]
3932    fn test_model_handles(cx: &mut MutableAppContext) {
3933        struct Model {
3934            other: Option<ModelHandle<Model>>,
3935            events: Vec<String>,
3936        }
3937
3938        impl Entity for Model {
3939            type Event = usize;
3940        }
3941
3942        impl Model {
3943            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
3944                if let Some(other) = other.as_ref() {
3945                    cx.observe(other, |me, _, _| {
3946                        me.events.push("notified".into());
3947                    })
3948                    .detach();
3949                    cx.subscribe(other, |me, _, event, _| {
3950                        me.events.push(format!("observed event {}", event));
3951                    })
3952                    .detach();
3953                }
3954
3955                Self {
3956                    other,
3957                    events: Vec::new(),
3958                }
3959            }
3960        }
3961
3962        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
3963        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
3964        assert_eq!(cx.cx.models.len(), 2);
3965
3966        handle_1.update(cx, |model, cx| {
3967            model.events.push("updated".into());
3968            cx.emit(1);
3969            cx.notify();
3970            cx.emit(2);
3971        });
3972        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
3973        assert_eq!(
3974            handle_2.read(cx).events,
3975            vec![
3976                "observed event 1".to_string(),
3977                "notified".to_string(),
3978                "observed event 2".to_string(),
3979            ]
3980        );
3981
3982        handle_2.update(cx, |model, _| {
3983            drop(handle_1);
3984            model.other.take();
3985        });
3986
3987        assert_eq!(cx.cx.models.len(), 1);
3988        assert!(cx.subscriptions.lock().is_empty());
3989        assert!(cx.observations.lock().is_empty());
3990    }
3991
3992    #[crate::test(self)]
3993    fn test_subscribe_and_emit_from_model(cx: &mut MutableAppContext) {
3994        #[derive(Default)]
3995        struct Model {
3996            events: Vec<usize>,
3997        }
3998
3999        impl Entity for Model {
4000            type Event = usize;
4001        }
4002
4003        let handle_1 = cx.add_model(|_| Model::default());
4004        let handle_2 = cx.add_model(|_| Model::default());
4005        let handle_2b = handle_2.clone();
4006
4007        handle_1.update(cx, |_, c| {
4008            c.subscribe(&handle_2, move |model: &mut Model, _, event, c| {
4009                model.events.push(*event);
4010
4011                c.subscribe(&handle_2b, |model, _, event, _| {
4012                    model.events.push(*event * 2);
4013                })
4014                .detach();
4015            })
4016            .detach();
4017        });
4018
4019        handle_2.update(cx, |_, c| c.emit(7));
4020        assert_eq!(handle_1.read(cx).events, vec![7]);
4021
4022        handle_2.update(cx, |_, c| c.emit(5));
4023        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
4024    }
4025
4026    #[crate::test(self)]
4027    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
4028        #[derive(Default)]
4029        struct Model {
4030            count: usize,
4031            events: Vec<usize>,
4032        }
4033
4034        impl Entity for Model {
4035            type Event = ();
4036        }
4037
4038        let handle_1 = cx.add_model(|_| Model::default());
4039        let handle_2 = cx.add_model(|_| Model::default());
4040        let handle_2b = handle_2.clone();
4041
4042        handle_1.update(cx, |_, c| {
4043            c.observe(&handle_2, move |model, observed, c| {
4044                model.events.push(observed.read(c).count);
4045                c.observe(&handle_2b, |model, observed, c| {
4046                    model.events.push(observed.read(c).count * 2);
4047                })
4048                .detach();
4049            })
4050            .detach();
4051        });
4052
4053        handle_2.update(cx, |model, c| {
4054            model.count = 7;
4055            c.notify()
4056        });
4057        assert_eq!(handle_1.read(cx).events, vec![7]);
4058
4059        handle_2.update(cx, |model, c| {
4060            model.count = 5;
4061            c.notify()
4062        });
4063        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
4064    }
4065
4066    #[crate::test(self)]
4067    fn test_view_handles(cx: &mut MutableAppContext) {
4068        struct View {
4069            other: Option<ViewHandle<View>>,
4070            events: Vec<String>,
4071        }
4072
4073        impl Entity for View {
4074            type Event = usize;
4075        }
4076
4077        impl super::View for View {
4078            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4079                Empty::new().boxed()
4080            }
4081
4082            fn ui_name() -> &'static str {
4083                "View"
4084            }
4085        }
4086
4087        impl View {
4088            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
4089                if let Some(other) = other.as_ref() {
4090                    cx.subscribe(other, |me, _, event, _| {
4091                        me.events.push(format!("observed event {}", event));
4092                    })
4093                    .detach();
4094                }
4095                Self {
4096                    other,
4097                    events: Vec::new(),
4098                }
4099            }
4100        }
4101
4102        let (window_id, _) = cx.add_window(Default::default(), |cx| View::new(None, cx));
4103        let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
4104        let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
4105        assert_eq!(cx.cx.views.len(), 3);
4106
4107        handle_1.update(cx, |view, cx| {
4108            view.events.push("updated".into());
4109            cx.emit(1);
4110            cx.emit(2);
4111        });
4112        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
4113        assert_eq!(
4114            handle_2.read(cx).events,
4115            vec![
4116                "observed event 1".to_string(),
4117                "observed event 2".to_string(),
4118            ]
4119        );
4120
4121        handle_2.update(cx, |view, _| {
4122            drop(handle_1);
4123            view.other.take();
4124        });
4125
4126        assert_eq!(cx.cx.views.len(), 2);
4127        assert!(cx.subscriptions.lock().is_empty());
4128        assert!(cx.observations.lock().is_empty());
4129    }
4130
4131    #[crate::test(self)]
4132    fn test_add_window(cx: &mut MutableAppContext) {
4133        struct View {
4134            mouse_down_count: Arc<AtomicUsize>,
4135        }
4136
4137        impl Entity for View {
4138            type Event = ();
4139        }
4140
4141        impl super::View for View {
4142            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4143                let mouse_down_count = self.mouse_down_count.clone();
4144                EventHandler::new(Empty::new().boxed())
4145                    .on_mouse_down(move |_| {
4146                        mouse_down_count.fetch_add(1, SeqCst);
4147                        true
4148                    })
4149                    .boxed()
4150            }
4151
4152            fn ui_name() -> &'static str {
4153                "View"
4154            }
4155        }
4156
4157        let mouse_down_count = Arc::new(AtomicUsize::new(0));
4158        let (window_id, _) = cx.add_window(Default::default(), |_| View {
4159            mouse_down_count: mouse_down_count.clone(),
4160        });
4161        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
4162        // Ensure window's root element is in a valid lifecycle state.
4163        presenter.borrow_mut().dispatch_event(
4164            Event::LeftMouseDown {
4165                position: Default::default(),
4166                ctrl: false,
4167                alt: false,
4168                shift: false,
4169                cmd: false,
4170                click_count: 1,
4171            },
4172            cx,
4173        );
4174        assert_eq!(mouse_down_count.load(SeqCst), 1);
4175    }
4176
4177    #[crate::test(self)]
4178    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
4179        struct Model {
4180            released: Rc<Cell<bool>>,
4181        }
4182
4183        struct View {
4184            released: Rc<Cell<bool>>,
4185        }
4186
4187        impl Entity for Model {
4188            type Event = ();
4189
4190            fn release(&mut self, _: &mut MutableAppContext) {
4191                self.released.set(true);
4192            }
4193        }
4194
4195        impl Entity for View {
4196            type Event = ();
4197
4198            fn release(&mut self, _: &mut MutableAppContext) {
4199                self.released.set(true);
4200            }
4201        }
4202
4203        impl super::View for View {
4204            fn ui_name() -> &'static str {
4205                "View"
4206            }
4207
4208            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4209                Empty::new().boxed()
4210            }
4211        }
4212
4213        let model_released = Rc::new(Cell::new(false));
4214        let model_release_observed = Rc::new(Cell::new(false));
4215        let view_released = Rc::new(Cell::new(false));
4216        let view_release_observed = Rc::new(Cell::new(false));
4217
4218        let model = cx.add_model(|_| Model {
4219            released: model_released.clone(),
4220        });
4221        let (window_id, view) = cx.add_window(Default::default(), |_| View {
4222            released: view_released.clone(),
4223        });
4224        assert!(!model_released.get());
4225        assert!(!view_released.get());
4226
4227        cx.observe_release(&model, {
4228            let model_release_observed = model_release_observed.clone();
4229            move |_| model_release_observed.set(true)
4230        })
4231        .detach();
4232        cx.observe_release(&view, {
4233            let view_release_observed = view_release_observed.clone();
4234            move |_| view_release_observed.set(true)
4235        })
4236        .detach();
4237
4238        cx.update(move |_| {
4239            drop(model);
4240        });
4241        assert!(model_released.get());
4242        assert!(model_release_observed.get());
4243
4244        drop(view);
4245        cx.remove_window(window_id);
4246        assert!(view_released.get());
4247        assert!(view_release_observed.get());
4248    }
4249
4250    #[crate::test(self)]
4251    fn test_subscribe_and_emit_from_view(cx: &mut MutableAppContext) {
4252        #[derive(Default)]
4253        struct View {
4254            events: Vec<usize>,
4255        }
4256
4257        impl Entity for View {
4258            type Event = usize;
4259        }
4260
4261        impl super::View for View {
4262            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4263                Empty::new().boxed()
4264            }
4265
4266            fn ui_name() -> &'static str {
4267                "View"
4268            }
4269        }
4270
4271        struct Model;
4272
4273        impl Entity for Model {
4274            type Event = usize;
4275        }
4276
4277        let (window_id, handle_1) = cx.add_window(Default::default(), |_| View::default());
4278        let handle_2 = cx.add_view(window_id, |_| View::default());
4279        let handle_2b = handle_2.clone();
4280        let handle_3 = cx.add_model(|_| Model);
4281
4282        handle_1.update(cx, |_, c| {
4283            c.subscribe(&handle_2, move |me, _, event, c| {
4284                me.events.push(*event);
4285
4286                c.subscribe(&handle_2b, |me, _, event, _| {
4287                    me.events.push(*event * 2);
4288                })
4289                .detach();
4290            })
4291            .detach();
4292
4293            c.subscribe(&handle_3, |me, _, event, _| {
4294                me.events.push(*event);
4295            })
4296            .detach();
4297        });
4298
4299        handle_2.update(cx, |_, c| c.emit(7));
4300        assert_eq!(handle_1.read(cx).events, vec![7]);
4301
4302        handle_2.update(cx, |_, c| c.emit(5));
4303        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
4304
4305        handle_3.update(cx, |_, c| c.emit(9));
4306        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
4307    }
4308
4309    #[crate::test(self)]
4310    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
4311        struct View;
4312
4313        impl Entity for View {
4314            type Event = ();
4315        }
4316
4317        impl super::View for View {
4318            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4319                Empty::new().boxed()
4320            }
4321
4322            fn ui_name() -> &'static str {
4323                "View"
4324            }
4325        }
4326
4327        struct Model;
4328
4329        impl Entity for Model {
4330            type Event = ();
4331        }
4332
4333        let (window_id, _) = cx.add_window(Default::default(), |_| View);
4334        let observing_view = cx.add_view(window_id, |_| View);
4335        let emitting_view = cx.add_view(window_id, |_| View);
4336        let observing_model = cx.add_model(|_| Model);
4337        let observed_model = cx.add_model(|_| Model);
4338
4339        observing_view.update(cx, |_, cx| {
4340            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
4341            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
4342        });
4343        observing_model.update(cx, |_, cx| {
4344            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
4345        });
4346
4347        cx.update(|_| {
4348            drop(observing_view);
4349            drop(observing_model);
4350        });
4351
4352        emitting_view.update(cx, |_, cx| cx.emit(()));
4353        observed_model.update(cx, |_, cx| cx.emit(()));
4354    }
4355
4356    #[crate::test(self)]
4357    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
4358        #[derive(Default)]
4359        struct View {
4360            events: Vec<usize>,
4361        }
4362
4363        impl Entity for View {
4364            type Event = usize;
4365        }
4366
4367        impl super::View for View {
4368            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4369                Empty::new().boxed()
4370            }
4371
4372            fn ui_name() -> &'static str {
4373                "View"
4374            }
4375        }
4376
4377        #[derive(Default)]
4378        struct Model {
4379            count: usize,
4380        }
4381
4382        impl Entity for Model {
4383            type Event = ();
4384        }
4385
4386        let (_, view) = cx.add_window(Default::default(), |_| View::default());
4387        let model = cx.add_model(|_| Model::default());
4388
4389        view.update(cx, |_, c| {
4390            c.observe(&model, |me, observed, c| {
4391                me.events.push(observed.read(c).count)
4392            })
4393            .detach();
4394        });
4395
4396        model.update(cx, |model, c| {
4397            model.count = 11;
4398            c.notify();
4399        });
4400        assert_eq!(view.read(cx).events, vec![11]);
4401    }
4402
4403    #[crate::test(self)]
4404    fn test_dropping_observers(cx: &mut MutableAppContext) {
4405        struct View;
4406
4407        impl Entity for View {
4408            type Event = ();
4409        }
4410
4411        impl super::View for View {
4412            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4413                Empty::new().boxed()
4414            }
4415
4416            fn ui_name() -> &'static str {
4417                "View"
4418            }
4419        }
4420
4421        struct Model;
4422
4423        impl Entity for Model {
4424            type Event = ();
4425        }
4426
4427        let (window_id, _) = cx.add_window(Default::default(), |_| View);
4428        let observing_view = cx.add_view(window_id, |_| View);
4429        let observing_model = cx.add_model(|_| Model);
4430        let observed_model = cx.add_model(|_| Model);
4431
4432        observing_view.update(cx, |_, cx| {
4433            cx.observe(&observed_model, |_, _, _| {}).detach();
4434        });
4435        observing_model.update(cx, |_, cx| {
4436            cx.observe(&observed_model, |_, _, _| {}).detach();
4437        });
4438
4439        cx.update(|_| {
4440            drop(observing_view);
4441            drop(observing_model);
4442        });
4443
4444        observed_model.update(cx, |_, cx| cx.notify());
4445    }
4446
4447    #[crate::test(self)]
4448    fn test_focus(cx: &mut MutableAppContext) {
4449        struct View {
4450            name: String,
4451            events: Arc<Mutex<Vec<String>>>,
4452        }
4453
4454        impl Entity for View {
4455            type Event = ();
4456        }
4457
4458        impl super::View for View {
4459            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4460                Empty::new().boxed()
4461            }
4462
4463            fn ui_name() -> &'static str {
4464                "View"
4465            }
4466
4467            fn on_focus(&mut self, _: &mut ViewContext<Self>) {
4468                self.events.lock().push(format!("{} focused", &self.name));
4469            }
4470
4471            fn on_blur(&mut self, _: &mut ViewContext<Self>) {
4472                self.events.lock().push(format!("{} blurred", &self.name));
4473            }
4474        }
4475
4476        let events: Arc<Mutex<Vec<String>>> = Default::default();
4477        let (window_id, view_1) = cx.add_window(Default::default(), |_| View {
4478            events: events.clone(),
4479            name: "view 1".to_string(),
4480        });
4481        let view_2 = cx.add_view(window_id, |_| View {
4482            events: events.clone(),
4483            name: "view 2".to_string(),
4484        });
4485
4486        view_1.update(cx, |_, cx| cx.focus(&view_2));
4487        view_1.update(cx, |_, cx| cx.focus(&view_1));
4488        view_1.update(cx, |_, cx| cx.focus(&view_2));
4489        view_1.update(cx, |_, _| drop(view_2));
4490
4491        assert_eq!(
4492            *events.lock(),
4493            [
4494                "view 1 focused".to_string(),
4495                "view 1 blurred".to_string(),
4496                "view 2 focused".to_string(),
4497                "view 2 blurred".to_string(),
4498                "view 1 focused".to_string(),
4499                "view 1 blurred".to_string(),
4500                "view 2 focused".to_string(),
4501                "view 1 focused".to_string(),
4502            ],
4503        );
4504    }
4505
4506    #[crate::test(self)]
4507    fn test_dispatch_action(cx: &mut MutableAppContext) {
4508        struct ViewA {
4509            id: usize,
4510        }
4511
4512        impl Entity for ViewA {
4513            type Event = ();
4514        }
4515
4516        impl View for ViewA {
4517            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4518                Empty::new().boxed()
4519            }
4520
4521            fn ui_name() -> &'static str {
4522                "View"
4523            }
4524        }
4525
4526        struct ViewB {
4527            id: usize,
4528        }
4529
4530        impl Entity for ViewB {
4531            type Event = ();
4532        }
4533
4534        impl View for ViewB {
4535            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4536                Empty::new().boxed()
4537            }
4538
4539            fn ui_name() -> &'static str {
4540                "View"
4541            }
4542        }
4543
4544        action!(Action, &'static str);
4545
4546        let actions = Rc::new(RefCell::new(Vec::new()));
4547
4548        {
4549            let actions = actions.clone();
4550            cx.add_global_action(move |_: &Action, _: &mut MutableAppContext| {
4551                actions.borrow_mut().push("global".to_string());
4552            });
4553        }
4554
4555        {
4556            let actions = actions.clone();
4557            cx.add_action(move |view: &mut ViewA, action: &Action, cx| {
4558                assert_eq!(action.0, "bar");
4559                cx.propagate_action();
4560                actions.borrow_mut().push(format!("{} a", view.id));
4561            });
4562        }
4563
4564        {
4565            let actions = actions.clone();
4566            cx.add_action(move |view: &mut ViewA, _: &Action, cx| {
4567                if view.id != 1 {
4568                    cx.add_view(|cx| {
4569                        cx.propagate_action(); // Still works on a nested ViewContext
4570                        ViewB { id: 5 }
4571                    });
4572                }
4573                actions.borrow_mut().push(format!("{} b", view.id));
4574            });
4575        }
4576
4577        {
4578            let actions = actions.clone();
4579            cx.add_action(move |view: &mut ViewB, _: &Action, cx| {
4580                cx.propagate_action();
4581                actions.borrow_mut().push(format!("{} c", view.id));
4582            });
4583        }
4584
4585        {
4586            let actions = actions.clone();
4587            cx.add_action(move |view: &mut ViewB, _: &Action, cx| {
4588                cx.propagate_action();
4589                actions.borrow_mut().push(format!("{} d", view.id));
4590            });
4591        }
4592
4593        {
4594            let actions = actions.clone();
4595            cx.capture_action(move |view: &mut ViewA, _: &Action, cx| {
4596                cx.propagate_action();
4597                actions.borrow_mut().push(format!("{} capture", view.id));
4598            });
4599        }
4600
4601        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
4602        let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 });
4603        let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 });
4604        let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 });
4605
4606        cx.dispatch_action(
4607            window_id,
4608            vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
4609            &Action("bar"),
4610        );
4611
4612        assert_eq!(
4613            *actions.borrow(),
4614            vec![
4615                "1 capture",
4616                "3 capture",
4617                "4 d",
4618                "4 c",
4619                "3 b",
4620                "3 a",
4621                "2 d",
4622                "2 c",
4623                "1 b"
4624            ]
4625        );
4626
4627        // Remove view_1, which doesn't propagate the action
4628        actions.borrow_mut().clear();
4629        cx.dispatch_action(
4630            window_id,
4631            vec![view_2.id(), view_3.id(), view_4.id()],
4632            &Action("bar"),
4633        );
4634
4635        assert_eq!(
4636            *actions.borrow(),
4637            vec![
4638                "3 capture",
4639                "4 d",
4640                "4 c",
4641                "3 b",
4642                "3 a",
4643                "2 d",
4644                "2 c",
4645                "global"
4646            ]
4647        );
4648    }
4649
4650    #[crate::test(self)]
4651    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
4652        use std::cell::Cell;
4653
4654        action!(Action, &'static str);
4655
4656        struct View {
4657            id: usize,
4658            keymap_context: keymap::Context,
4659        }
4660
4661        impl Entity for View {
4662            type Event = ();
4663        }
4664
4665        impl super::View for View {
4666            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4667                Empty::new().boxed()
4668            }
4669
4670            fn ui_name() -> &'static str {
4671                "View"
4672            }
4673
4674            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
4675                self.keymap_context.clone()
4676            }
4677        }
4678
4679        impl View {
4680            fn new(id: usize) -> Self {
4681                View {
4682                    id,
4683                    keymap_context: keymap::Context::default(),
4684                }
4685            }
4686        }
4687
4688        let mut view_1 = View::new(1);
4689        let mut view_2 = View::new(2);
4690        let mut view_3 = View::new(3);
4691        view_1.keymap_context.set.insert("a".into());
4692        view_2.keymap_context.set.insert("a".into());
4693        view_2.keymap_context.set.insert("b".into());
4694        view_3.keymap_context.set.insert("a".into());
4695        view_3.keymap_context.set.insert("b".into());
4696        view_3.keymap_context.set.insert("c".into());
4697
4698        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
4699        let view_2 = cx.add_view(window_id, |_| view_2);
4700        let view_3 = cx.add_view(window_id, |_| view_3);
4701
4702        // This keymap's only binding dispatches an action on view 2 because that view will have
4703        // "a" and "b" in its context, but not "c".
4704        cx.add_bindings(vec![keymap::Binding::new(
4705            "a",
4706            Action("a"),
4707            Some("a && b && !c"),
4708        )]);
4709
4710        let handled_action = Rc::new(Cell::new(false));
4711        let handled_action_clone = handled_action.clone();
4712        cx.add_action(move |view: &mut View, action: &Action, _| {
4713            handled_action_clone.set(true);
4714            assert_eq!(view.id, 2);
4715            assert_eq!(action.0, "a");
4716        });
4717
4718        cx.dispatch_keystroke(
4719            window_id,
4720            vec![view_1.id(), view_2.id(), view_3.id()],
4721            &Keystroke::parse("a").unwrap(),
4722        )
4723        .unwrap();
4724
4725        assert!(handled_action.get());
4726    }
4727
4728    #[crate::test(self)]
4729    async fn test_model_condition(cx: &mut TestAppContext) {
4730        struct Counter(usize);
4731
4732        impl super::Entity for Counter {
4733            type Event = ();
4734        }
4735
4736        impl Counter {
4737            fn inc(&mut self, cx: &mut ModelContext<Self>) {
4738                self.0 += 1;
4739                cx.notify();
4740            }
4741        }
4742
4743        let model = cx.add_model(|_| Counter(0));
4744
4745        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
4746        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
4747        smol::pin!(condition1, condition2);
4748
4749        model.update(cx, |model, cx| model.inc(cx));
4750        assert_eq!(poll_once(&mut condition1).await, None);
4751        assert_eq!(poll_once(&mut condition2).await, None);
4752
4753        model.update(cx, |model, cx| model.inc(cx));
4754        assert_eq!(poll_once(&mut condition1).await, Some(()));
4755        assert_eq!(poll_once(&mut condition2).await, None);
4756
4757        model.update(cx, |model, cx| model.inc(cx));
4758        assert_eq!(poll_once(&mut condition2).await, Some(()));
4759
4760        model.update(cx, |_, cx| cx.notify());
4761    }
4762
4763    #[crate::test(self)]
4764    #[should_panic]
4765    async fn test_model_condition_timeout(cx: &mut TestAppContext) {
4766        struct Model;
4767
4768        impl super::Entity for Model {
4769            type Event = ();
4770        }
4771
4772        let model = cx.add_model(|_| Model);
4773        model.condition(&cx, |_, _| false).await;
4774    }
4775
4776    #[crate::test(self)]
4777    #[should_panic(expected = "model dropped with pending condition")]
4778    async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
4779        struct Model;
4780
4781        impl super::Entity for Model {
4782            type Event = ();
4783        }
4784
4785        let model = cx.add_model(|_| Model);
4786        let condition = model.condition(&cx, |_, _| false);
4787        cx.update(|_| drop(model));
4788        condition.await;
4789    }
4790
4791    #[crate::test(self)]
4792    async fn test_view_condition(cx: &mut TestAppContext) {
4793        struct Counter(usize);
4794
4795        impl super::Entity for Counter {
4796            type Event = ();
4797        }
4798
4799        impl super::View for Counter {
4800            fn ui_name() -> &'static str {
4801                "test view"
4802            }
4803
4804            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4805                Empty::new().boxed()
4806            }
4807        }
4808
4809        impl Counter {
4810            fn inc(&mut self, cx: &mut ViewContext<Self>) {
4811                self.0 += 1;
4812                cx.notify();
4813            }
4814        }
4815
4816        let (_, view) = cx.add_window(|_| Counter(0));
4817
4818        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
4819        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
4820        smol::pin!(condition1, condition2);
4821
4822        view.update(cx, |view, cx| view.inc(cx));
4823        assert_eq!(poll_once(&mut condition1).await, None);
4824        assert_eq!(poll_once(&mut condition2).await, None);
4825
4826        view.update(cx, |view, cx| view.inc(cx));
4827        assert_eq!(poll_once(&mut condition1).await, Some(()));
4828        assert_eq!(poll_once(&mut condition2).await, None);
4829
4830        view.update(cx, |view, cx| view.inc(cx));
4831        assert_eq!(poll_once(&mut condition2).await, Some(()));
4832        view.update(cx, |_, cx| cx.notify());
4833    }
4834
4835    #[crate::test(self)]
4836    #[should_panic]
4837    async fn test_view_condition_timeout(cx: &mut TestAppContext) {
4838        struct View;
4839
4840        impl super::Entity for View {
4841            type Event = ();
4842        }
4843
4844        impl super::View for View {
4845            fn ui_name() -> &'static str {
4846                "test view"
4847            }
4848
4849            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4850                Empty::new().boxed()
4851            }
4852        }
4853
4854        let (_, view) = cx.add_window(|_| View);
4855        view.condition(&cx, |_, _| false).await;
4856    }
4857
4858    #[crate::test(self)]
4859    #[should_panic(expected = "view dropped with pending condition")]
4860    async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
4861        struct View;
4862
4863        impl super::Entity for View {
4864            type Event = ();
4865        }
4866
4867        impl super::View for View {
4868            fn ui_name() -> &'static str {
4869                "test view"
4870            }
4871
4872            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4873                Empty::new().boxed()
4874            }
4875        }
4876
4877        let window_id = cx.add_window(|_| View).0;
4878        let view = cx.add_view(window_id, |_| View);
4879
4880        let condition = view.condition(&cx, |_, _| false);
4881        cx.update(|_| drop(view));
4882        condition.await;
4883    }
4884}