app.rs

   1use crate::{
   2    elements::ElementBox,
   3    executor,
   4    keymap::{self, Keystroke},
   5    platform::{self, PromptLevel, WindowOptions},
   6    presenter::Presenter,
   7    util::{post_inc, timeout},
   8    AssetCache, AssetSource, ClipboardItem, FontCache, PathPromptOptions, TextLayoutCache,
   9};
  10use anyhow::{anyhow, Result};
  11use async_task::Task;
  12use keymap::MatchResult;
  13use parking_lot::{Mutex, RwLock};
  14use pathfinder_geometry::{rect::RectF, vector::vec2f};
  15use platform::Event;
  16use postage::{mpsc, sink::Sink as _, stream::Stream as _};
  17use smol::prelude::*;
  18use std::{
  19    any::{type_name, Any, TypeId},
  20    cell::RefCell,
  21    collections::{hash_map::Entry, HashMap, HashSet, VecDeque},
  22    fmt::{self, Debug},
  23    hash::{Hash, Hasher},
  24    marker::PhantomData,
  25    path::{Path, PathBuf},
  26    rc::{self, Rc},
  27    sync::{Arc, Weak},
  28    time::Duration,
  29};
  30
  31pub trait Entity: 'static + Send + Sync {
  32    type Event;
  33}
  34
  35pub trait View: Entity {
  36    fn ui_name() -> &'static str;
  37    fn render<'a>(&self, cx: &AppContext) -> ElementBox;
  38    fn on_focus(&mut self, _: &mut ViewContext<Self>) {}
  39    fn on_blur(&mut self, _: &mut ViewContext<Self>) {}
  40    fn keymap_context(&self, _: &AppContext) -> keymap::Context {
  41        Self::default_keymap_context()
  42    }
  43    fn default_keymap_context() -> keymap::Context {
  44        let mut cx = keymap::Context::default();
  45        cx.set.insert(Self::ui_name().into());
  46        cx
  47    }
  48}
  49
  50pub trait ReadModel {
  51    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
  52}
  53
  54pub trait ReadModelWith {
  55    fn read_model_with<E: Entity, F: FnOnce(&E, &AppContext) -> T, T>(
  56        &self,
  57        handle: &ModelHandle<E>,
  58        read: F,
  59    ) -> T;
  60}
  61
  62pub trait UpdateModel {
  63    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
  64    where
  65        T: Entity,
  66        F: FnOnce(&mut T, &mut ModelContext<T>) -> S;
  67}
  68
  69pub trait ReadView {
  70    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
  71}
  72
  73pub trait ReadViewWith {
  74    fn read_view_with<V, F, T>(&self, handle: &ViewHandle<V>, read: F) -> T
  75    where
  76        V: View,
  77        F: FnOnce(&V, &AppContext) -> T;
  78}
  79
  80pub trait UpdateView {
  81    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
  82    where
  83        T: View,
  84        F: FnOnce(&mut T, &mut ViewContext<T>) -> S;
  85}
  86
  87pub struct Menu<'a> {
  88    pub name: &'a str,
  89    pub items: Vec<MenuItem<'a>>,
  90}
  91
  92pub enum MenuItem<'a> {
  93    Action {
  94        name: &'a str,
  95        keystroke: Option<&'a str>,
  96        action: &'a str,
  97        arg: Option<Box<dyn Any + 'static>>,
  98    },
  99    Separator,
 100}
 101
 102#[derive(Clone)]
 103pub struct App(Rc<RefCell<MutableAppContext>>);
 104
 105pub struct AsyncAppContext(Rc<RefCell<MutableAppContext>>);
 106
 107#[derive(Clone)]
 108pub struct TestAppContext {
 109    cx: Rc<RefCell<MutableAppContext>>,
 110    main_thread_platform: Rc<platform::test::MainThreadPlatform>,
 111}
 112
 113impl App {
 114    pub fn test<T, A: AssetSource, F: FnOnce(&mut MutableAppContext) -> T>(
 115        asset_source: A,
 116        f: F,
 117    ) -> T {
 118        let main_thread_platform = platform::test::main_thread_platform();
 119        let platform = platform::test::platform();
 120        let foreground = Rc::new(executor::Foreground::test());
 121        let cx = Rc::new(RefCell::new(MutableAppContext::new(
 122            foreground,
 123            Arc::new(platform),
 124            Rc::new(main_thread_platform),
 125            asset_source,
 126        )));
 127        cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx));
 128        let mut cx = cx.borrow_mut();
 129        f(&mut *cx)
 130    }
 131
 132    pub fn test_async<T, F, A: AssetSource, Fn>(asset_source: A, f: Fn) -> T
 133    where
 134        Fn: FnOnce(TestAppContext) -> F,
 135        F: Future<Output = T>,
 136    {
 137        let platform = Arc::new(platform::test::platform());
 138        let main_thread_platform = Rc::new(platform::test::main_thread_platform());
 139        let foreground = Rc::new(executor::Foreground::test());
 140        let cx = TestAppContext {
 141            cx: Rc::new(RefCell::new(MutableAppContext::new(
 142                foreground.clone(),
 143                platform,
 144                main_thread_platform.clone(),
 145                asset_source,
 146            ))),
 147            main_thread_platform,
 148        };
 149        cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
 150
 151        let future = f(cx);
 152        smol::block_on(foreground.run(future))
 153    }
 154
 155    pub fn new(asset_source: impl AssetSource) -> Result<Self> {
 156        let platform = platform::current::platform();
 157        let main_thread_platform = platform::current::main_thread_platform();
 158        let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
 159        let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
 160            foreground,
 161            platform.clone(),
 162            main_thread_platform.clone(),
 163            asset_source,
 164        ))));
 165
 166        let cx = app.0.clone();
 167        main_thread_platform.on_menu_command(Box::new(move |command, arg| {
 168            let mut cx = cx.borrow_mut();
 169            if let Some(key_window_id) = cx.platform.key_window_id() {
 170                if let Some((presenter, _)) = cx.presenters_and_platform_windows.get(&key_window_id)
 171                {
 172                    let presenter = presenter.clone();
 173                    let path = presenter.borrow().dispatch_path(cx.as_ref());
 174                    cx.dispatch_action_any(key_window_id, &path, command, arg.unwrap_or(&()));
 175                } else {
 176                    cx.dispatch_global_action_any(command, arg.unwrap_or(&()));
 177                }
 178            } else {
 179                cx.dispatch_global_action_any(command, arg.unwrap_or(&()));
 180            }
 181        }));
 182
 183        app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
 184        Ok(app)
 185    }
 186
 187    pub fn on_become_active<F>(self, mut callback: F) -> Self
 188    where
 189        F: 'static + FnMut(&mut MutableAppContext),
 190    {
 191        let cx = self.0.clone();
 192        self.0
 193            .borrow_mut()
 194            .main_thread_platform
 195            .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 196        self
 197    }
 198
 199    pub fn on_resign_active<F>(self, mut callback: F) -> Self
 200    where
 201        F: 'static + FnMut(&mut MutableAppContext),
 202    {
 203        let cx = self.0.clone();
 204        self.0
 205            .borrow_mut()
 206            .main_thread_platform
 207            .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 208        self
 209    }
 210
 211    pub fn on_event<F>(self, mut callback: F) -> Self
 212    where
 213        F: 'static + FnMut(Event, &mut MutableAppContext) -> bool,
 214    {
 215        let cx = self.0.clone();
 216        self.0
 217            .borrow_mut()
 218            .main_thread_platform
 219            .on_event(Box::new(move |event| {
 220                callback(event, &mut *cx.borrow_mut())
 221            }));
 222        self
 223    }
 224
 225    pub fn on_open_files<F>(self, mut callback: F) -> Self
 226    where
 227        F: 'static + FnMut(Vec<PathBuf>, &mut MutableAppContext),
 228    {
 229        let cx = self.0.clone();
 230        self.0
 231            .borrow_mut()
 232            .main_thread_platform
 233            .on_open_files(Box::new(move |paths| {
 234                callback(paths, &mut *cx.borrow_mut())
 235            }));
 236        self
 237    }
 238
 239    pub fn run<F>(self, on_finish_launching: F)
 240    where
 241        F: 'static + FnOnce(&mut MutableAppContext),
 242    {
 243        let platform = self.0.borrow().main_thread_platform.clone();
 244        platform.run(Box::new(move || {
 245            let mut cx = self.0.borrow_mut();
 246            on_finish_launching(&mut *cx);
 247        }))
 248    }
 249
 250    pub fn font_cache(&self) -> Arc<FontCache> {
 251        self.0.borrow().cx.font_cache.clone()
 252    }
 253
 254    fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 255        let mut state = self.0.borrow_mut();
 256        state.pending_flushes += 1;
 257        let result = callback(&mut *state);
 258        state.flush_effects();
 259        result
 260    }
 261}
 262
 263impl TestAppContext {
 264    pub fn dispatch_action<T: 'static + Any>(
 265        &self,
 266        window_id: usize,
 267        responder_chain: Vec<usize>,
 268        name: &str,
 269        arg: T,
 270    ) {
 271        self.cx.borrow_mut().dispatch_action_any(
 272            window_id,
 273            &responder_chain,
 274            name,
 275            Box::new(arg).as_ref(),
 276        );
 277    }
 278
 279    pub fn dispatch_keystroke(
 280        &self,
 281        window_id: usize,
 282        responder_chain: Vec<usize>,
 283        keystroke: &Keystroke,
 284    ) -> Result<bool> {
 285        let mut state = self.cx.borrow_mut();
 286        state.dispatch_keystroke(window_id, responder_chain, keystroke)
 287    }
 288
 289    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 290    where
 291        T: Entity,
 292        F: FnOnce(&mut ModelContext<T>) -> T,
 293    {
 294        let mut state = self.cx.borrow_mut();
 295        state.pending_flushes += 1;
 296        let handle = state.add_model(build_model);
 297        state.flush_effects();
 298        handle
 299    }
 300
 301    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 302    where
 303        T: View,
 304        F: FnOnce(&mut ViewContext<T>) -> T,
 305    {
 306        self.cx.borrow_mut().add_window(build_root_view)
 307    }
 308
 309    pub fn window_ids(&self) -> Vec<usize> {
 310        self.cx.borrow().window_ids().collect()
 311    }
 312
 313    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 314        self.cx.borrow().root_view(window_id)
 315    }
 316
 317    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
 318    where
 319        T: View,
 320        F: FnOnce(&mut ViewContext<T>) -> T,
 321    {
 322        let mut state = self.cx.borrow_mut();
 323        state.pending_flushes += 1;
 324        let handle = state.add_view(window_id, build_view);
 325        state.flush_effects();
 326        handle
 327    }
 328
 329    pub fn add_option_view<T, F>(
 330        &mut self,
 331        window_id: usize,
 332        build_view: F,
 333    ) -> Option<ViewHandle<T>>
 334    where
 335        T: View,
 336        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 337    {
 338        let mut state = self.cx.borrow_mut();
 339        state.pending_flushes += 1;
 340        let handle = state.add_option_view(window_id, build_view);
 341        state.flush_effects();
 342        handle
 343    }
 344
 345    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 346        callback(self.cx.borrow().as_ref())
 347    }
 348
 349    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 350        let mut state = self.cx.borrow_mut();
 351        // Don't increment pending flushes in order to effects to be flushed before the callback
 352        // completes, which is helpful in tests.
 353        let result = callback(&mut *state);
 354        // Flush effects after the callback just in case there are any. This can happen in edge
 355        // cases such as the closure dropping handles.
 356        state.flush_effects();
 357        result
 358    }
 359
 360    pub fn font_cache(&self) -> Arc<FontCache> {
 361        self.cx.borrow().cx.font_cache.clone()
 362    }
 363
 364    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 365        self.cx.borrow().platform.clone()
 366    }
 367
 368    pub fn simulate_new_path_selection(&self, result: impl FnOnce(PathBuf) -> Option<PathBuf>) {
 369        self.main_thread_platform
 370            .simulate_new_path_selection(result);
 371    }
 372
 373    pub fn did_prompt_for_new_path(&self) -> bool {
 374        self.main_thread_platform.as_ref().did_prompt_for_new_path()
 375    }
 376
 377    pub fn simulate_prompt_answer(&self, window_id: usize, answer: usize) {
 378        let mut state = self.cx.borrow_mut();
 379        let (_, window) = state
 380            .presenters_and_platform_windows
 381            .get_mut(&window_id)
 382            .unwrap();
 383        let test_window = window
 384            .as_any_mut()
 385            .downcast_mut::<platform::test::Window>()
 386            .unwrap();
 387        let callback = test_window
 388            .last_prompt
 389            .take()
 390            .expect("prompt was not called");
 391        (callback)(answer);
 392    }
 393}
 394
 395impl AsyncAppContext {
 396    pub fn read<T, F: FnOnce(&AppContext) -> T>(&mut self, callback: F) -> T {
 397        callback(self.0.borrow().as_ref())
 398    }
 399
 400    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 401        let mut state = self.0.borrow_mut();
 402        state.pending_flushes += 1;
 403        let result = callback(&mut *state);
 404        state.flush_effects();
 405        result
 406    }
 407
 408    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 409    where
 410        T: Entity,
 411        F: FnOnce(&mut ModelContext<T>) -> T,
 412    {
 413        self.update(|cx| cx.add_model(build_model))
 414    }
 415
 416    pub fn background_executor(&self) -> Arc<executor::Background> {
 417        self.0.borrow().cx.background.clone()
 418    }
 419}
 420
 421impl UpdateModel for AsyncAppContext {
 422    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
 423    where
 424        T: Entity,
 425        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
 426    {
 427        let mut state = self.0.borrow_mut();
 428        state.pending_flushes += 1;
 429        let result = state.update_model(handle, update);
 430        state.flush_effects();
 431        result
 432    }
 433}
 434
 435impl ReadModelWith for AsyncAppContext {
 436    fn read_model_with<E: Entity, F: FnOnce(&E, &AppContext) -> T, T>(
 437        &self,
 438        handle: &ModelHandle<E>,
 439        read: F,
 440    ) -> T {
 441        let cx = self.0.borrow();
 442        let cx = cx.as_ref();
 443        read(handle.read(cx), cx)
 444    }
 445}
 446
 447impl UpdateView for AsyncAppContext {
 448    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
 449    where
 450        T: View,
 451        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
 452    {
 453        let mut state = self.0.borrow_mut();
 454        state.pending_flushes += 1;
 455        let result = state.update_view(handle, update);
 456        state.flush_effects();
 457        result
 458    }
 459}
 460
 461impl ReadViewWith for AsyncAppContext {
 462    fn read_view_with<V, F, T>(&self, handle: &ViewHandle<V>, read: F) -> T
 463    where
 464        V: View,
 465        F: FnOnce(&V, &AppContext) -> T,
 466    {
 467        let cx = self.0.borrow();
 468        let cx = cx.as_ref();
 469        read(handle.read(cx), cx)
 470    }
 471}
 472
 473impl UpdateModel for TestAppContext {
 474    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
 475    where
 476        T: Entity,
 477        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
 478    {
 479        let mut state = self.cx.borrow_mut();
 480        state.pending_flushes += 1;
 481        let result = state.update_model(handle, update);
 482        state.flush_effects();
 483        result
 484    }
 485}
 486
 487impl ReadModelWith for TestAppContext {
 488    fn read_model_with<E: Entity, F: FnOnce(&E, &AppContext) -> T, T>(
 489        &self,
 490        handle: &ModelHandle<E>,
 491        read: F,
 492    ) -> T {
 493        let cx = self.cx.borrow();
 494        let cx = cx.as_ref();
 495        read(handle.read(cx), cx)
 496    }
 497}
 498
 499impl UpdateView for TestAppContext {
 500    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
 501    where
 502        T: View,
 503        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
 504    {
 505        let mut state = self.cx.borrow_mut();
 506        state.pending_flushes += 1;
 507        let result = state.update_view(handle, update);
 508        state.flush_effects();
 509        result
 510    }
 511}
 512
 513impl ReadViewWith for TestAppContext {
 514    fn read_view_with<V, F, T>(&self, handle: &ViewHandle<V>, read: F) -> T
 515    where
 516        V: View,
 517        F: FnOnce(&V, &AppContext) -> T,
 518    {
 519        let cx = self.cx.borrow();
 520        let cx = cx.as_ref();
 521        read(handle.read(cx), cx)
 522    }
 523}
 524
 525type ActionCallback =
 526    dyn FnMut(&mut dyn AnyView, &dyn Any, &mut MutableAppContext, usize, usize) -> bool;
 527
 528type GlobalActionCallback = dyn FnMut(&dyn Any, &mut MutableAppContext);
 529
 530pub struct MutableAppContext {
 531    weak_self: Option<rc::Weak<RefCell<Self>>>,
 532    main_thread_platform: Rc<dyn platform::MainThreadPlatform>,
 533    platform: Arc<dyn platform::Platform>,
 534    assets: Arc<AssetCache>,
 535    cx: AppContext,
 536    actions: HashMap<TypeId, HashMap<String, Vec<Box<ActionCallback>>>>,
 537    global_actions: HashMap<String, Vec<Box<GlobalActionCallback>>>,
 538    keystroke_matcher: keymap::Matcher,
 539    next_entity_id: usize,
 540    next_window_id: usize,
 541    subscriptions: HashMap<usize, Vec<Subscription>>,
 542    model_observations: HashMap<usize, Vec<ModelObservation>>,
 543    view_observations: HashMap<usize, Vec<ViewObservation>>,
 544    presenters_and_platform_windows:
 545        HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
 546    debug_elements_callbacks: HashMap<usize, Box<dyn Fn(&AppContext) -> crate::json::Value>>,
 547    foreground: Rc<executor::Foreground>,
 548    pending_effects: VecDeque<Effect>,
 549    pending_flushes: usize,
 550    flushing_effects: bool,
 551}
 552
 553impl MutableAppContext {
 554    fn new(
 555        foreground: Rc<executor::Foreground>,
 556        platform: Arc<dyn platform::Platform>,
 557        main_thread_platform: Rc<dyn platform::MainThreadPlatform>,
 558        asset_source: impl AssetSource,
 559    ) -> Self {
 560        let fonts = platform.fonts();
 561        Self {
 562            weak_self: None,
 563            main_thread_platform,
 564            platform,
 565            assets: Arc::new(AssetCache::new(asset_source)),
 566            cx: AppContext {
 567                models: Default::default(),
 568                views: Default::default(),
 569                windows: Default::default(),
 570                values: Default::default(),
 571                ref_counts: Arc::new(Mutex::new(RefCounts::default())),
 572                background: Arc::new(executor::Background::new()),
 573                thread_pool: scoped_pool::Pool::new(num_cpus::get(), "app"),
 574                font_cache: Arc::new(FontCache::new(fonts)),
 575            },
 576            actions: HashMap::new(),
 577            global_actions: HashMap::new(),
 578            keystroke_matcher: keymap::Matcher::default(),
 579            next_entity_id: 0,
 580            next_window_id: 0,
 581            subscriptions: HashMap::new(),
 582            model_observations: HashMap::new(),
 583            view_observations: HashMap::new(),
 584            presenters_and_platform_windows: HashMap::new(),
 585            debug_elements_callbacks: HashMap::new(),
 586            foreground,
 587            pending_effects: VecDeque::new(),
 588            pending_flushes: 0,
 589            flushing_effects: false,
 590        }
 591    }
 592
 593    pub fn upgrade(&self) -> App {
 594        App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
 595    }
 596
 597    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 598        self.platform.clone()
 599    }
 600
 601    pub fn font_cache(&self) -> &Arc<FontCache> {
 602        &self.cx.font_cache
 603    }
 604
 605    pub fn foreground_executor(&self) -> &Rc<executor::Foreground> {
 606        &self.foreground
 607    }
 608
 609    pub fn background_executor(&self) -> &Arc<executor::Background> {
 610        &self.cx.background
 611    }
 612
 613    pub fn on_debug_elements<F>(&mut self, window_id: usize, callback: F)
 614    where
 615        F: 'static + Fn(&AppContext) -> crate::json::Value,
 616    {
 617        self.debug_elements_callbacks
 618            .insert(window_id, Box::new(callback));
 619    }
 620
 621    pub fn debug_elements(&self, window_id: usize) -> Option<crate::json::Value> {
 622        self.debug_elements_callbacks
 623            .get(&window_id)
 624            .map(|debug_elements| debug_elements(&self.cx))
 625    }
 626
 627    pub fn add_action<S, V, T, F>(&mut self, name: S, mut handler: F)
 628    where
 629        S: Into<String>,
 630        V: View,
 631        T: Any,
 632        F: 'static + FnMut(&mut V, &T, &mut ViewContext<V>),
 633    {
 634        let name = name.into();
 635        let name_clone = name.clone();
 636        let handler = Box::new(
 637            move |view: &mut dyn AnyView,
 638                  arg: &dyn Any,
 639                  cx: &mut MutableAppContext,
 640                  window_id: usize,
 641                  view_id: usize| {
 642                match arg.downcast_ref() {
 643                    Some(arg) => {
 644                        let mut cx = ViewContext::new(cx, window_id, view_id);
 645                        handler(
 646                            view.as_any_mut()
 647                                .downcast_mut()
 648                                .expect("downcast is type safe"),
 649                            arg,
 650                            &mut cx,
 651                        );
 652                        cx.halt_action_dispatch
 653                    }
 654                    None => {
 655                        log::error!("Could not downcast argument for action {}", name_clone);
 656                        false
 657                    }
 658                }
 659            },
 660        );
 661
 662        self.actions
 663            .entry(TypeId::of::<V>())
 664            .or_default()
 665            .entry(name)
 666            .or_default()
 667            .push(handler);
 668    }
 669
 670    pub fn add_global_action<S, T, F>(&mut self, name: S, mut handler: F)
 671    where
 672        S: Into<String>,
 673        T: 'static + Any,
 674        F: 'static + FnMut(&T, &mut MutableAppContext),
 675    {
 676        let name = name.into();
 677        let name_clone = name.clone();
 678        let handler = Box::new(move |arg: &dyn Any, cx: &mut MutableAppContext| {
 679            if let Some(arg) = arg.downcast_ref() {
 680                handler(arg, cx);
 681            } else {
 682                log::error!("Could not downcast argument for action {}", name_clone);
 683            }
 684        });
 685
 686        self.global_actions.entry(name).or_default().push(handler);
 687    }
 688
 689    pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
 690        self.cx.windows.keys().cloned()
 691    }
 692
 693    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 694        self.cx
 695            .windows
 696            .get(&window_id)
 697            .and_then(|window| window.root_view.clone().downcast::<T>())
 698    }
 699
 700    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
 701        self.cx.root_view_id(window_id)
 702    }
 703
 704    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
 705        self.cx.focused_view_id(window_id)
 706    }
 707
 708    pub fn render_view(&self, window_id: usize, view_id: usize) -> Result<ElementBox> {
 709        self.cx.render_view(window_id, view_id)
 710    }
 711
 712    pub fn render_views(&self, window_id: usize) -> HashMap<usize, ElementBox> {
 713        self.cx.render_views(window_id)
 714    }
 715
 716    pub fn update<T, F: FnOnce() -> T>(&mut self, callback: F) -> T {
 717        self.pending_flushes += 1;
 718        let result = callback();
 719        self.flush_effects();
 720        result
 721    }
 722
 723    pub fn set_menus(&mut self, menus: Vec<Menu>) {
 724        self.main_thread_platform.set_menus(menus);
 725    }
 726
 727    fn prompt<F>(
 728        &self,
 729        window_id: usize,
 730        level: PromptLevel,
 731        msg: &str,
 732        answers: &[&str],
 733        done_fn: F,
 734    ) where
 735        F: 'static + FnOnce(usize, &mut MutableAppContext),
 736    {
 737        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 738        let foreground = self.foreground.clone();
 739        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 740        window.prompt(
 741            level,
 742            msg,
 743            answers,
 744            Box::new(move |answer| {
 745                foreground
 746                    .spawn(async move { (done_fn)(answer, &mut *app.borrow_mut()) })
 747                    .detach();
 748            }),
 749        );
 750    }
 751
 752    pub fn prompt_for_paths<F>(&self, options: PathPromptOptions, done_fn: F)
 753    where
 754        F: 'static + FnOnce(Option<Vec<PathBuf>>, &mut MutableAppContext),
 755    {
 756        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 757        let foreground = self.foreground.clone();
 758        self.main_thread_platform.prompt_for_paths(
 759            options,
 760            Box::new(move |paths| {
 761                foreground
 762                    .spawn(async move { (done_fn)(paths, &mut *app.borrow_mut()) })
 763                    .detach();
 764            }),
 765        );
 766    }
 767
 768    pub fn prompt_for_new_path<F>(&self, directory: &Path, done_fn: F)
 769    where
 770        F: 'static + FnOnce(Option<PathBuf>, &mut MutableAppContext),
 771    {
 772        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 773        let foreground = self.foreground.clone();
 774        self.main_thread_platform.prompt_for_new_path(
 775            directory,
 776            Box::new(move |path| {
 777                foreground
 778                    .spawn(async move { (done_fn)(path, &mut *app.borrow_mut()) })
 779                    .detach();
 780            }),
 781        );
 782    }
 783
 784    pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
 785        self.pending_effects
 786            .push_back(Effect::ViewNotification { window_id, view_id });
 787    }
 788
 789    pub fn dispatch_action<T: 'static + Any>(
 790        &mut self,
 791        window_id: usize,
 792        responder_chain: Vec<usize>,
 793        name: &str,
 794        arg: T,
 795    ) {
 796        self.dispatch_action_any(window_id, &responder_chain, name, Box::new(arg).as_ref());
 797    }
 798
 799    pub(crate) fn dispatch_action_any(
 800        &mut self,
 801        window_id: usize,
 802        path: &[usize],
 803        name: &str,
 804        arg: &dyn Any,
 805    ) -> bool {
 806        self.pending_flushes += 1;
 807        let mut halted_dispatch = false;
 808
 809        for view_id in path.iter().rev() {
 810            if let Some(mut view) = self.cx.views.remove(&(window_id, *view_id)) {
 811                let type_id = view.as_any().type_id();
 812
 813                if let Some((name, mut handlers)) = self
 814                    .actions
 815                    .get_mut(&type_id)
 816                    .and_then(|h| h.remove_entry(name))
 817                {
 818                    for handler in handlers.iter_mut().rev() {
 819                        let halt_dispatch = handler(view.as_mut(), arg, self, window_id, *view_id);
 820                        if halt_dispatch {
 821                            halted_dispatch = true;
 822                            break;
 823                        }
 824                    }
 825                    self.actions
 826                        .get_mut(&type_id)
 827                        .unwrap()
 828                        .insert(name, handlers);
 829                }
 830
 831                self.cx.views.insert((window_id, *view_id), view);
 832
 833                if halted_dispatch {
 834                    break;
 835                }
 836            }
 837        }
 838
 839        if !halted_dispatch {
 840            self.dispatch_global_action_any(name, arg);
 841        }
 842
 843        self.flush_effects();
 844        halted_dispatch
 845    }
 846
 847    pub fn dispatch_global_action<T: 'static + Any>(&mut self, name: &str, arg: T) {
 848        self.dispatch_global_action_any(name, Box::new(arg).as_ref());
 849    }
 850
 851    fn dispatch_global_action_any(&mut self, name: &str, arg: &dyn Any) {
 852        if let Some((name, mut handlers)) = self.global_actions.remove_entry(name) {
 853            self.pending_flushes += 1;
 854            for handler in handlers.iter_mut().rev() {
 855                handler(arg, self);
 856            }
 857            self.global_actions.insert(name, handlers);
 858            self.flush_effects();
 859        }
 860    }
 861
 862    pub fn add_bindings<T: IntoIterator<Item = keymap::Binding>>(&mut self, bindings: T) {
 863        self.keystroke_matcher.add_bindings(bindings);
 864    }
 865
 866    pub fn dispatch_keystroke(
 867        &mut self,
 868        window_id: usize,
 869        responder_chain: Vec<usize>,
 870        keystroke: &Keystroke,
 871    ) -> Result<bool> {
 872        let mut context_chain = Vec::new();
 873        let mut context = keymap::Context::default();
 874        for view_id in &responder_chain {
 875            if let Some(view) = self.cx.views.get(&(window_id, *view_id)) {
 876                context.extend(view.keymap_context(self.as_ref()));
 877                context_chain.push(context.clone());
 878            } else {
 879                return Err(anyhow!(
 880                    "View {} in responder chain does not exist",
 881                    view_id
 882                ));
 883            }
 884        }
 885
 886        let mut pending = false;
 887        for (i, cx) in context_chain.iter().enumerate().rev() {
 888            match self
 889                .keystroke_matcher
 890                .push_keystroke(keystroke.clone(), responder_chain[i], cx)
 891            {
 892                MatchResult::None => {}
 893                MatchResult::Pending => pending = true,
 894                MatchResult::Action { name, arg } => {
 895                    if self.dispatch_action_any(
 896                        window_id,
 897                        &responder_chain[0..=i],
 898                        &name,
 899                        arg.as_ref().map(|arg| arg.as_ref()).unwrap_or(&()),
 900                    ) {
 901                        return Ok(true);
 902                    }
 903                }
 904            }
 905        }
 906
 907        Ok(pending)
 908    }
 909
 910    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 911    where
 912        T: Entity,
 913        F: FnOnce(&mut ModelContext<T>) -> T,
 914    {
 915        self.pending_flushes += 1;
 916        let model_id = post_inc(&mut self.next_entity_id);
 917        let handle = ModelHandle::new(model_id, &self.cx.ref_counts);
 918        let mut cx = ModelContext::new(self, model_id);
 919        let model = build_model(&mut cx);
 920        self.cx.models.insert(model_id, Box::new(model));
 921        self.flush_effects();
 922        handle
 923    }
 924
 925    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 926    where
 927        T: View,
 928        F: FnOnce(&mut ViewContext<T>) -> T,
 929    {
 930        self.pending_flushes += 1;
 931        let window_id = post_inc(&mut self.next_window_id);
 932        let root_view = self.add_view(window_id, build_root_view);
 933
 934        self.cx.windows.insert(
 935            window_id,
 936            Window {
 937                root_view: root_view.clone().into(),
 938                focused_view_id: root_view.id(),
 939                invalidation: None,
 940            },
 941        );
 942        self.open_platform_window(window_id);
 943        root_view.update(self, |view, cx| view.on_focus(cx));
 944        self.flush_effects();
 945
 946        (window_id, root_view)
 947    }
 948
 949    pub fn remove_window(&mut self, window_id: usize) {
 950        self.cx.windows.remove(&window_id);
 951        self.presenters_and_platform_windows.remove(&window_id);
 952        self.remove_dropped_entities();
 953    }
 954
 955    fn open_platform_window(&mut self, window_id: usize) {
 956        let mut window = self.platform.open_window(
 957            window_id,
 958            WindowOptions {
 959                bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
 960                title: "Zed".into(),
 961            },
 962            self.foreground.clone(),
 963        );
 964        let text_layout_cache = TextLayoutCache::new(self.platform.fonts());
 965        let presenter = Rc::new(RefCell::new(Presenter::new(
 966            window_id,
 967            self.cx.font_cache.clone(),
 968            text_layout_cache,
 969            self.assets.clone(),
 970            self,
 971        )));
 972
 973        {
 974            let mut app = self.upgrade();
 975            let presenter = presenter.clone();
 976            window.on_event(Box::new(move |event| {
 977                app.update(|cx| {
 978                    if let Event::KeyDown { keystroke, .. } = &event {
 979                        if cx
 980                            .dispatch_keystroke(
 981                                window_id,
 982                                presenter.borrow().dispatch_path(cx.as_ref()),
 983                                keystroke,
 984                            )
 985                            .unwrap()
 986                        {
 987                            return;
 988                        }
 989                    }
 990
 991                    presenter.borrow_mut().dispatch_event(event, cx);
 992                })
 993            }));
 994        }
 995
 996        {
 997            let mut app = self.upgrade();
 998            let presenter = presenter.clone();
 999            window.on_resize(Box::new(move |window| {
1000                app.update(|cx| {
1001                    let scene = presenter.borrow_mut().build_scene(
1002                        window.size(),
1003                        window.scale_factor(),
1004                        cx,
1005                    );
1006                    window.present_scene(scene);
1007                })
1008            }));
1009        }
1010
1011        {
1012            let mut app = self.upgrade();
1013            window.on_close(Box::new(move || {
1014                app.update(|cx| cx.remove_window(window_id));
1015            }));
1016        }
1017
1018        self.presenters_and_platform_windows
1019            .insert(window_id, (presenter.clone(), window));
1020
1021        self.on_debug_elements(window_id, move |cx| {
1022            presenter.borrow().debug_elements(cx).unwrap()
1023        });
1024    }
1025
1026    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
1027    where
1028        T: View,
1029        F: FnOnce(&mut ViewContext<T>) -> T,
1030    {
1031        self.add_option_view(window_id, |cx| Some(build_view(cx)))
1032            .unwrap()
1033    }
1034
1035    pub fn add_option_view<T, F>(
1036        &mut self,
1037        window_id: usize,
1038        build_view: F,
1039    ) -> Option<ViewHandle<T>>
1040    where
1041        T: View,
1042        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1043    {
1044        let view_id = post_inc(&mut self.next_entity_id);
1045        self.pending_flushes += 1;
1046        let handle = ViewHandle::new(window_id, view_id, &self.cx.ref_counts);
1047        let mut cx = ViewContext::new(self, window_id, view_id);
1048        let handle = if let Some(view) = build_view(&mut cx) {
1049            self.cx.views.insert((window_id, view_id), Box::new(view));
1050            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1051                window
1052                    .invalidation
1053                    .get_or_insert_with(Default::default)
1054                    .updated
1055                    .insert(view_id);
1056            }
1057            Some(handle)
1058        } else {
1059            None
1060        };
1061        self.flush_effects();
1062        handle
1063    }
1064
1065    fn remove_dropped_entities(&mut self) {
1066        loop {
1067            let (dropped_models, dropped_views, dropped_values) =
1068                self.cx.ref_counts.lock().take_dropped();
1069            if dropped_models.is_empty() && dropped_views.is_empty() && dropped_values.is_empty() {
1070                break;
1071            }
1072
1073            for model_id in dropped_models {
1074                self.cx.models.remove(&model_id);
1075                self.subscriptions.remove(&model_id);
1076                self.model_observations.remove(&model_id);
1077            }
1078
1079            for (window_id, view_id) in dropped_views {
1080                self.subscriptions.remove(&view_id);
1081                self.model_observations.remove(&view_id);
1082                self.cx.views.remove(&(window_id, view_id));
1083                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
1084                    window
1085                        .invalidation
1086                        .get_or_insert_with(Default::default)
1087                        .removed
1088                        .push(view_id);
1089                    if window.focused_view_id == view_id {
1090                        Some(window.root_view.id())
1091                    } else {
1092                        None
1093                    }
1094                });
1095
1096                if let Some(view_id) = change_focus_to {
1097                    self.focus(window_id, view_id);
1098                }
1099            }
1100
1101            let mut values = self.cx.values.write();
1102            for key in dropped_values {
1103                values.remove(&key);
1104            }
1105        }
1106    }
1107
1108    fn flush_effects(&mut self) {
1109        self.pending_flushes = self.pending_flushes.saturating_sub(1);
1110
1111        if !self.flushing_effects && self.pending_flushes == 0 {
1112            self.flushing_effects = true;
1113
1114            loop {
1115                if let Some(effect) = self.pending_effects.pop_front() {
1116                    match effect {
1117                        Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
1118                        Effect::ModelNotification { model_id } => {
1119                            self.notify_model_observers(model_id)
1120                        }
1121                        Effect::ViewNotification { window_id, view_id } => {
1122                            self.notify_view_observers(window_id, view_id)
1123                        }
1124                        Effect::Focus { window_id, view_id } => {
1125                            self.focus(window_id, view_id);
1126                        }
1127                    }
1128                    self.remove_dropped_entities();
1129                } else {
1130                    self.remove_dropped_entities();
1131                    self.update_windows();
1132
1133                    if self.pending_effects.is_empty() {
1134                        self.flushing_effects = false;
1135                        break;
1136                    }
1137                }
1138            }
1139        }
1140    }
1141
1142    fn update_windows(&mut self) {
1143        let mut invalidations = HashMap::new();
1144        for (window_id, window) in &mut self.cx.windows {
1145            if let Some(invalidation) = window.invalidation.take() {
1146                invalidations.insert(*window_id, invalidation);
1147            }
1148        }
1149
1150        for (window_id, invalidation) in invalidations {
1151            if let Some((presenter, mut window)) =
1152                self.presenters_and_platform_windows.remove(&window_id)
1153            {
1154                {
1155                    let mut presenter = presenter.borrow_mut();
1156                    presenter.invalidate(invalidation, self.as_ref());
1157                    let scene = presenter.build_scene(window.size(), window.scale_factor(), self);
1158                    window.present_scene(scene);
1159                }
1160                self.presenters_and_platform_windows
1161                    .insert(window_id, (presenter, window));
1162            }
1163        }
1164    }
1165
1166    fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
1167        if let Some(subscriptions) = self.subscriptions.remove(&entity_id) {
1168            for mut subscription in subscriptions {
1169                let alive = match &mut subscription {
1170                    Subscription::FromModel { model_id, callback } => {
1171                        if let Some(mut model) = self.cx.models.remove(model_id) {
1172                            callback(model.as_any_mut(), payload.as_ref(), self, *model_id);
1173                            self.cx.models.insert(*model_id, model);
1174                            true
1175                        } else {
1176                            false
1177                        }
1178                    }
1179                    Subscription::FromView {
1180                        window_id,
1181                        view_id,
1182                        callback,
1183                    } => {
1184                        if let Some(mut view) = self.cx.views.remove(&(*window_id, *view_id)) {
1185                            callback(
1186                                view.as_any_mut(),
1187                                payload.as_ref(),
1188                                self,
1189                                *window_id,
1190                                *view_id,
1191                            );
1192                            self.cx.views.insert((*window_id, *view_id), view);
1193                            true
1194                        } else {
1195                            false
1196                        }
1197                    }
1198                };
1199
1200                if alive {
1201                    self.subscriptions
1202                        .entry(entity_id)
1203                        .or_default()
1204                        .push(subscription);
1205                }
1206            }
1207        }
1208    }
1209
1210    fn notify_model_observers(&mut self, observed_id: usize) {
1211        if let Some(observations) = self.model_observations.remove(&observed_id) {
1212            if self.cx.models.contains_key(&observed_id) {
1213                for mut observation in observations {
1214                    let alive = match &mut observation {
1215                        ModelObservation::FromModel { model_id, callback } => {
1216                            if let Some(mut model) = self.cx.models.remove(model_id) {
1217                                callback(model.as_any_mut(), observed_id, self, *model_id);
1218                                self.cx.models.insert(*model_id, model);
1219                                true
1220                            } else {
1221                                false
1222                            }
1223                        }
1224                        ModelObservation::FromView {
1225                            window_id,
1226                            view_id,
1227                            callback,
1228                        } => {
1229                            if let Some(mut view) = self.cx.views.remove(&(*window_id, *view_id)) {
1230                                callback(
1231                                    view.as_any_mut(),
1232                                    observed_id,
1233                                    self,
1234                                    *window_id,
1235                                    *view_id,
1236                                );
1237                                self.cx.views.insert((*window_id, *view_id), view);
1238                                true
1239                            } else {
1240                                false
1241                            }
1242                        }
1243                    };
1244
1245                    if alive {
1246                        self.model_observations
1247                            .entry(observed_id)
1248                            .or_default()
1249                            .push(observation);
1250                    }
1251                }
1252            }
1253        }
1254    }
1255
1256    fn notify_view_observers(&mut self, window_id: usize, view_id: usize) {
1257        if let Some(window) = self.cx.windows.get_mut(&window_id) {
1258            window
1259                .invalidation
1260                .get_or_insert_with(Default::default)
1261                .updated
1262                .insert(view_id);
1263        }
1264
1265        if let Some(observations) = self.view_observations.remove(&view_id) {
1266            if self.cx.views.contains_key(&(window_id, view_id)) {
1267                for mut observation in observations {
1268                    let alive = if let Some(mut view) = self
1269                        .cx
1270                        .views
1271                        .remove(&(observation.window_id, observation.view_id))
1272                    {
1273                        (observation.callback)(
1274                            view.as_any_mut(),
1275                            view_id,
1276                            window_id,
1277                            self,
1278                            observation.window_id,
1279                            observation.view_id,
1280                        );
1281                        self.cx
1282                            .views
1283                            .insert((observation.window_id, observation.view_id), view);
1284                        true
1285                    } else {
1286                        false
1287                    };
1288
1289                    if alive {
1290                        self.view_observations
1291                            .entry(view_id)
1292                            .or_default()
1293                            .push(observation);
1294                    }
1295                }
1296            }
1297        }
1298    }
1299
1300    fn focus(&mut self, window_id: usize, focused_id: usize) {
1301        if self
1302            .cx
1303            .windows
1304            .get(&window_id)
1305            .map(|w| w.focused_view_id)
1306            .map_or(false, |cur_focused| cur_focused == focused_id)
1307        {
1308            return;
1309        }
1310
1311        self.pending_flushes += 1;
1312
1313        let blurred_id = self.cx.windows.get_mut(&window_id).map(|window| {
1314            let blurred_id = window.focused_view_id;
1315            window.focused_view_id = focused_id;
1316            blurred_id
1317        });
1318
1319        if let Some(blurred_id) = blurred_id {
1320            if let Some(mut blurred_view) = self.cx.views.remove(&(window_id, blurred_id)) {
1321                blurred_view.on_blur(self, window_id, blurred_id);
1322                self.cx.views.insert((window_id, blurred_id), blurred_view);
1323            }
1324        }
1325
1326        if let Some(mut focused_view) = self.cx.views.remove(&(window_id, focused_id)) {
1327            focused_view.on_focus(self, window_id, focused_id);
1328            self.cx.views.insert((window_id, focused_id), focused_view);
1329        }
1330
1331        self.flush_effects();
1332    }
1333
1334    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
1335    where
1336        F: FnOnce(AsyncAppContext) -> Fut,
1337        Fut: 'static + Future<Output = T>,
1338        T: 'static,
1339    {
1340        let cx = AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap());
1341        self.foreground.spawn(f(cx))
1342    }
1343
1344    pub fn write_to_clipboard(&self, item: ClipboardItem) {
1345        self.platform.write_to_clipboard(item);
1346    }
1347
1348    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
1349        self.platform.read_from_clipboard()
1350    }
1351}
1352
1353impl ReadModel for MutableAppContext {
1354    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1355        if let Some(model) = self.cx.models.get(&handle.model_id) {
1356            model
1357                .as_any()
1358                .downcast_ref()
1359                .expect("downcast is type safe")
1360        } else {
1361            panic!("circular model reference");
1362        }
1363    }
1364}
1365
1366impl UpdateModel for MutableAppContext {
1367    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1368    where
1369        T: Entity,
1370        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1371    {
1372        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
1373            self.pending_flushes += 1;
1374            let mut cx = ModelContext::new(self, handle.model_id);
1375            let result = update(
1376                model
1377                    .as_any_mut()
1378                    .downcast_mut()
1379                    .expect("downcast is type safe"),
1380                &mut cx,
1381            );
1382            self.cx.models.insert(handle.model_id, model);
1383            self.flush_effects();
1384            result
1385        } else {
1386            panic!("circular model update");
1387        }
1388    }
1389}
1390
1391impl ReadView for MutableAppContext {
1392    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1393        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
1394            view.as_any().downcast_ref().expect("downcast is type safe")
1395        } else {
1396            panic!("circular view reference");
1397        }
1398    }
1399}
1400
1401impl UpdateView for MutableAppContext {
1402    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
1403    where
1404        T: View,
1405        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
1406    {
1407        self.pending_flushes += 1;
1408        let mut view = self
1409            .cx
1410            .views
1411            .remove(&(handle.window_id, handle.view_id))
1412            .expect("circular view update");
1413
1414        let mut cx = ViewContext::new(self, handle.window_id, handle.view_id);
1415        let result = update(
1416            view.as_any_mut()
1417                .downcast_mut()
1418                .expect("downcast is type safe"),
1419            &mut cx,
1420        );
1421        self.cx
1422            .views
1423            .insert((handle.window_id, handle.view_id), view);
1424        self.flush_effects();
1425        result
1426    }
1427}
1428
1429impl AsRef<AppContext> for MutableAppContext {
1430    fn as_ref(&self) -> &AppContext {
1431        &self.cx
1432    }
1433}
1434
1435pub struct AppContext {
1436    models: HashMap<usize, Box<dyn AnyModel>>,
1437    views: HashMap<(usize, usize), Box<dyn AnyView>>,
1438    windows: HashMap<usize, Window>,
1439    values: RwLock<HashMap<(TypeId, usize), Box<dyn Any>>>,
1440    background: Arc<executor::Background>,
1441    ref_counts: Arc<Mutex<RefCounts>>,
1442    thread_pool: scoped_pool::Pool,
1443    font_cache: Arc<FontCache>,
1444}
1445
1446impl AppContext {
1447    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
1448        self.windows
1449            .get(&window_id)
1450            .map(|window| window.root_view.id())
1451    }
1452
1453    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
1454        self.windows
1455            .get(&window_id)
1456            .map(|window| window.focused_view_id)
1457    }
1458
1459    pub fn render_view(&self, window_id: usize, view_id: usize) -> Result<ElementBox> {
1460        self.views
1461            .get(&(window_id, view_id))
1462            .map(|v| v.render(self))
1463            .ok_or(anyhow!("view not found"))
1464    }
1465
1466    pub fn render_views(&self, window_id: usize) -> HashMap<usize, ElementBox> {
1467        self.views
1468            .iter()
1469            .filter_map(|((win_id, view_id), view)| {
1470                if *win_id == window_id {
1471                    Some((*view_id, view.render(self)))
1472                } else {
1473                    None
1474                }
1475            })
1476            .collect::<HashMap<_, ElementBox>>()
1477    }
1478
1479    pub fn background_executor(&self) -> &Arc<executor::Background> {
1480        &self.background
1481    }
1482
1483    pub fn font_cache(&self) -> &FontCache {
1484        &self.font_cache
1485    }
1486
1487    pub fn thread_pool(&self) -> &scoped_pool::Pool {
1488        &self.thread_pool
1489    }
1490
1491    pub fn value<Tag: 'static, T: 'static + Default>(&self, id: usize) -> ValueHandle<T> {
1492        let key = (TypeId::of::<Tag>(), id);
1493        let mut values = self.values.write();
1494        values.entry(key).or_insert_with(|| Box::new(T::default()));
1495        ValueHandle::new(TypeId::of::<Tag>(), id, &self.ref_counts)
1496    }
1497}
1498
1499impl ReadModel for AppContext {
1500    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1501        if let Some(model) = self.models.get(&handle.model_id) {
1502            model
1503                .as_any()
1504                .downcast_ref()
1505                .expect("downcast should be type safe")
1506        } else {
1507            panic!("circular model reference");
1508        }
1509    }
1510}
1511
1512impl ReadView for AppContext {
1513    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1514        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
1515            view.as_any()
1516                .downcast_ref()
1517                .expect("downcast should be type safe")
1518        } else {
1519            panic!("circular view reference");
1520        }
1521    }
1522}
1523
1524struct Window {
1525    root_view: AnyViewHandle,
1526    focused_view_id: usize,
1527    invalidation: Option<WindowInvalidation>,
1528}
1529
1530#[derive(Default, Clone)]
1531pub struct WindowInvalidation {
1532    pub updated: HashSet<usize>,
1533    pub removed: Vec<usize>,
1534}
1535
1536pub enum Effect {
1537    Event {
1538        entity_id: usize,
1539        payload: Box<dyn Any>,
1540    },
1541    ModelNotification {
1542        model_id: usize,
1543    },
1544    ViewNotification {
1545        window_id: usize,
1546        view_id: usize,
1547    },
1548    Focus {
1549        window_id: usize,
1550        view_id: usize,
1551    },
1552}
1553
1554pub trait AnyModel: Send + Sync {
1555    fn as_any(&self) -> &dyn Any;
1556    fn as_any_mut(&mut self) -> &mut dyn Any;
1557}
1558
1559impl<T> AnyModel for T
1560where
1561    T: Entity,
1562{
1563    fn as_any(&self) -> &dyn Any {
1564        self
1565    }
1566
1567    fn as_any_mut(&mut self) -> &mut dyn Any {
1568        self
1569    }
1570}
1571
1572pub trait AnyView: Send + Sync {
1573    fn as_any(&self) -> &dyn Any;
1574    fn as_any_mut(&mut self) -> &mut dyn Any;
1575    fn ui_name(&self) -> &'static str;
1576    fn render<'a>(&self, cx: &AppContext) -> ElementBox;
1577    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
1578    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
1579    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
1580}
1581
1582impl<T> AnyView for T
1583where
1584    T: View,
1585{
1586    fn as_any(&self) -> &dyn Any {
1587        self
1588    }
1589
1590    fn as_any_mut(&mut self) -> &mut dyn Any {
1591        self
1592    }
1593
1594    fn ui_name(&self) -> &'static str {
1595        T::ui_name()
1596    }
1597
1598    fn render<'a>(&self, cx: &AppContext) -> ElementBox {
1599        View::render(self, cx)
1600    }
1601
1602    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
1603        let mut cx = ViewContext::new(cx, window_id, view_id);
1604        View::on_focus(self, &mut cx);
1605    }
1606
1607    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
1608        let mut cx = ViewContext::new(cx, window_id, view_id);
1609        View::on_blur(self, &mut cx);
1610    }
1611
1612    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
1613        View::keymap_context(self, cx)
1614    }
1615}
1616
1617pub struct ModelContext<'a, T: ?Sized> {
1618    app: &'a mut MutableAppContext,
1619    model_id: usize,
1620    model_type: PhantomData<T>,
1621    halt_stream: bool,
1622}
1623
1624impl<'a, T: Entity> ModelContext<'a, T> {
1625    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
1626        Self {
1627            app,
1628            model_id,
1629            model_type: PhantomData,
1630            halt_stream: false,
1631        }
1632    }
1633
1634    pub fn background_executor(&self) -> &Arc<executor::Background> {
1635        &self.app.cx.background
1636    }
1637
1638    pub fn thread_pool(&self) -> &scoped_pool::Pool {
1639        &self.app.cx.thread_pool
1640    }
1641
1642    pub fn halt_stream(&mut self) {
1643        self.halt_stream = true;
1644    }
1645
1646    pub fn model_id(&self) -> usize {
1647        self.model_id
1648    }
1649
1650    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
1651    where
1652        S: Entity,
1653        F: FnOnce(&mut ModelContext<S>) -> S,
1654    {
1655        self.app.add_model(build_model)
1656    }
1657
1658    pub fn subscribe<S: Entity, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1659    where
1660        S::Event: 'static,
1661        F: 'static + FnMut(&mut T, &S::Event, &mut ModelContext<T>),
1662    {
1663        self.app
1664            .subscriptions
1665            .entry(handle.model_id)
1666            .or_default()
1667            .push(Subscription::FromModel {
1668                model_id: self.model_id,
1669                callback: Box::new(move |model, payload, app, model_id| {
1670                    let model = model.downcast_mut().expect("downcast is type safe");
1671                    let payload = payload.downcast_ref().expect("downcast is type safe");
1672                    let mut cx = ModelContext::new(app, model_id);
1673                    callback(model, payload, &mut cx);
1674                }),
1675            });
1676    }
1677
1678    pub fn emit(&mut self, payload: T::Event) {
1679        self.app.pending_effects.push_back(Effect::Event {
1680            entity_id: self.model_id,
1681            payload: Box::new(payload),
1682        });
1683    }
1684
1685    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1686    where
1687        S: Entity,
1688        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
1689    {
1690        self.app
1691            .model_observations
1692            .entry(handle.model_id)
1693            .or_default()
1694            .push(ModelObservation::FromModel {
1695                model_id: self.model_id,
1696                callback: Box::new(move |model, observed_id, app, model_id| {
1697                    let model = model.downcast_mut().expect("downcast is type safe");
1698                    let observed = ModelHandle::new(observed_id, &app.cx.ref_counts);
1699                    let mut cx = ModelContext::new(app, model_id);
1700                    callback(model, observed, &mut cx);
1701                }),
1702            });
1703    }
1704
1705    pub fn notify(&mut self) {
1706        self.app
1707            .pending_effects
1708            .push_back(Effect::ModelNotification {
1709                model_id: self.model_id,
1710            });
1711    }
1712
1713    pub fn handle(&self) -> ModelHandle<T> {
1714        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
1715    }
1716
1717    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
1718    where
1719        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
1720        Fut: 'static + Future<Output = S>,
1721        S: 'static,
1722    {
1723        let handle = self.handle();
1724        self.app.spawn(|cx| f(handle, cx))
1725    }
1726}
1727
1728impl<M> AsRef<AppContext> for ModelContext<'_, M> {
1729    fn as_ref(&self) -> &AppContext {
1730        &self.app.cx
1731    }
1732}
1733
1734impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
1735    fn as_mut(&mut self) -> &mut MutableAppContext {
1736        self.app
1737    }
1738}
1739
1740impl<M> ReadModel for ModelContext<'_, M> {
1741    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1742        self.app.read_model(handle)
1743    }
1744}
1745
1746impl<M> UpdateModel for ModelContext<'_, M> {
1747    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1748    where
1749        T: Entity,
1750        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1751    {
1752        self.app.update_model(handle, update)
1753    }
1754}
1755
1756pub struct ViewContext<'a, T: ?Sized> {
1757    app: &'a mut MutableAppContext,
1758    window_id: usize,
1759    view_id: usize,
1760    view_type: PhantomData<T>,
1761    halt_action_dispatch: bool,
1762}
1763
1764impl<'a, T: View> ViewContext<'a, T> {
1765    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
1766        Self {
1767            app,
1768            window_id,
1769            view_id,
1770            view_type: PhantomData,
1771            halt_action_dispatch: true,
1772        }
1773    }
1774
1775    pub fn handle(&self) -> ViewHandle<T> {
1776        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
1777    }
1778
1779    pub fn window_id(&self) -> usize {
1780        self.window_id
1781    }
1782
1783    pub fn view_id(&self) -> usize {
1784        self.view_id
1785    }
1786
1787    pub fn foreground(&self) -> &Rc<executor::Foreground> {
1788        self.app.foreground_executor()
1789    }
1790
1791    pub fn background_executor(&self) -> &Arc<executor::Background> {
1792        &self.app.cx.background
1793    }
1794
1795    pub fn prompt<F>(&self, level: PromptLevel, msg: &str, answers: &[&str], done_fn: F)
1796    where
1797        F: 'static + FnOnce(usize, &mut MutableAppContext),
1798    {
1799        self.app
1800            .prompt(self.window_id, level, msg, answers, done_fn)
1801    }
1802
1803    pub fn prompt_for_paths<F>(&self, options: PathPromptOptions, done_fn: F)
1804    where
1805        F: 'static + FnOnce(Option<Vec<PathBuf>>, &mut MutableAppContext),
1806    {
1807        self.app.prompt_for_paths(options, done_fn)
1808    }
1809
1810    pub fn prompt_for_new_path<F>(&self, directory: &Path, done_fn: F)
1811    where
1812        F: 'static + FnOnce(Option<PathBuf>, &mut MutableAppContext),
1813    {
1814        self.app.prompt_for_new_path(directory, done_fn)
1815    }
1816
1817    pub fn debug_elements(&self) -> crate::json::Value {
1818        self.app.debug_elements(self.window_id).unwrap()
1819    }
1820
1821    pub fn focus<S>(&mut self, handle: S)
1822    where
1823        S: Into<AnyViewHandle>,
1824    {
1825        let handle = handle.into();
1826        self.app.pending_effects.push_back(Effect::Focus {
1827            window_id: handle.window_id,
1828            view_id: handle.view_id,
1829        });
1830    }
1831
1832    pub fn focus_self(&mut self) {
1833        self.app.pending_effects.push_back(Effect::Focus {
1834            window_id: self.window_id,
1835            view_id: self.view_id,
1836        });
1837    }
1838
1839    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
1840    where
1841        S: Entity,
1842        F: FnOnce(&mut ModelContext<S>) -> S,
1843    {
1844        self.app.add_model(build_model)
1845    }
1846
1847    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
1848    where
1849        S: View,
1850        F: FnOnce(&mut ViewContext<S>) -> S,
1851    {
1852        self.app.add_view(self.window_id, build_view)
1853    }
1854
1855    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
1856    where
1857        S: View,
1858        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
1859    {
1860        self.app.add_option_view(self.window_id, build_view)
1861    }
1862
1863    pub fn subscribe_to_model<E, F>(&mut self, handle: &ModelHandle<E>, mut callback: F)
1864    where
1865        E: Entity,
1866        E::Event: 'static,
1867        F: 'static + FnMut(&mut T, ModelHandle<E>, &E::Event, &mut ViewContext<T>),
1868    {
1869        let emitter_handle = handle.downgrade();
1870        self.subscribe(handle, move |model, payload, cx| {
1871            if let Some(emitter_handle) = emitter_handle.upgrade(cx.as_ref()) {
1872                callback(model, emitter_handle, payload, cx);
1873            }
1874        });
1875    }
1876
1877    pub fn subscribe_to_view<V, F>(&mut self, handle: &ViewHandle<V>, mut callback: F)
1878    where
1879        V: View,
1880        V::Event: 'static,
1881        F: 'static + FnMut(&mut T, ViewHandle<V>, &V::Event, &mut ViewContext<T>),
1882    {
1883        let emitter_handle = handle.downgrade();
1884        self.subscribe(handle, move |view, payload, cx| {
1885            if let Some(emitter_handle) = emitter_handle.upgrade(cx.as_ref()) {
1886                callback(view, emitter_handle, payload, cx);
1887            }
1888        });
1889    }
1890
1891    pub fn subscribe<E, F>(&mut self, handle: &impl Handle<E>, mut callback: F)
1892    where
1893        E: Entity,
1894        E::Event: 'static,
1895        F: 'static + FnMut(&mut T, &E::Event, &mut ViewContext<T>),
1896    {
1897        self.app
1898            .subscriptions
1899            .entry(handle.id())
1900            .or_default()
1901            .push(Subscription::FromView {
1902                window_id: self.window_id,
1903                view_id: self.view_id,
1904                callback: Box::new(move |entity, payload, app, window_id, view_id| {
1905                    let entity = entity.downcast_mut().expect("downcast is type safe");
1906                    let payload = payload.downcast_ref().expect("downcast is type safe");
1907                    let mut cx = ViewContext::new(app, window_id, view_id);
1908                    callback(entity, payload, &mut cx);
1909                }),
1910            });
1911    }
1912
1913    pub fn emit(&mut self, payload: T::Event) {
1914        self.app.pending_effects.push_back(Effect::Event {
1915            entity_id: self.view_id,
1916            payload: Box::new(payload),
1917        });
1918    }
1919
1920    pub fn observe_model<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1921    where
1922        S: Entity,
1923        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ViewContext<T>),
1924    {
1925        self.app
1926            .model_observations
1927            .entry(handle.id())
1928            .or_default()
1929            .push(ModelObservation::FromView {
1930                window_id: self.window_id,
1931                view_id: self.view_id,
1932                callback: Box::new(move |view, observed_id, app, window_id, view_id| {
1933                    let view = view.downcast_mut().expect("downcast is type safe");
1934                    let observed = ModelHandle::new(observed_id, &app.cx.ref_counts);
1935                    let mut cx = ViewContext::new(app, window_id, view_id);
1936                    callback(view, observed, &mut cx);
1937                }),
1938            });
1939    }
1940
1941    pub fn observe_view<S, F>(&mut self, handle: &ViewHandle<S>, mut callback: F)
1942    where
1943        S: View,
1944        F: 'static + FnMut(&mut T, ViewHandle<S>, &mut ViewContext<T>),
1945    {
1946        self.app
1947            .view_observations
1948            .entry(handle.id())
1949            .or_default()
1950            .push(ViewObservation {
1951                window_id: self.window_id,
1952                view_id: self.view_id,
1953                callback: Box::new(
1954                    move |view,
1955                          observed_view_id,
1956                          observed_window_id,
1957                          app,
1958                          observing_window_id,
1959                          observing_view_id| {
1960                        let view = view.downcast_mut().expect("downcast is type safe");
1961                        let observed_handle = ViewHandle::new(
1962                            observed_view_id,
1963                            observed_window_id,
1964                            &app.cx.ref_counts,
1965                        );
1966                        let mut cx = ViewContext::new(app, observing_window_id, observing_view_id);
1967                        callback(view, observed_handle, &mut cx);
1968                    },
1969                ),
1970            });
1971    }
1972
1973    pub fn notify(&mut self) {
1974        self.app.notify_view(self.window_id, self.view_id);
1975    }
1976
1977    pub fn propagate_action(&mut self) {
1978        self.halt_action_dispatch = false;
1979    }
1980
1981    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
1982    where
1983        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
1984        Fut: 'static + Future<Output = S>,
1985        S: 'static,
1986    {
1987        let handle = self.handle();
1988        self.app.spawn(|cx| f(handle, cx))
1989    }
1990}
1991
1992impl AsRef<AppContext> for &AppContext {
1993    fn as_ref(&self) -> &AppContext {
1994        self
1995    }
1996}
1997
1998impl<M> AsRef<AppContext> for ViewContext<'_, M> {
1999    fn as_ref(&self) -> &AppContext {
2000        &self.app.cx
2001    }
2002}
2003
2004impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
2005    fn as_mut(&mut self) -> &mut MutableAppContext {
2006        self.app
2007    }
2008}
2009
2010impl<V> ReadModel for ViewContext<'_, V> {
2011    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2012        self.app.read_model(handle)
2013    }
2014}
2015
2016impl<V: View> UpdateModel for ViewContext<'_, V> {
2017    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
2018    where
2019        T: Entity,
2020        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
2021    {
2022        self.app.update_model(handle, update)
2023    }
2024}
2025
2026impl<V: View> ReadView for ViewContext<'_, V> {
2027    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2028        self.app.read_view(handle)
2029    }
2030}
2031
2032impl<V: View> UpdateView for ViewContext<'_, V> {
2033    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
2034    where
2035        T: View,
2036        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
2037    {
2038        self.app.update_view(handle, update)
2039    }
2040}
2041
2042pub trait Handle<T> {
2043    fn id(&self) -> usize;
2044    fn location(&self) -> EntityLocation;
2045}
2046
2047#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
2048pub enum EntityLocation {
2049    Model(usize),
2050    View(usize, usize),
2051}
2052
2053pub struct ModelHandle<T> {
2054    model_id: usize,
2055    model_type: PhantomData<T>,
2056    ref_counts: Arc<Mutex<RefCounts>>,
2057}
2058
2059impl<T: Entity> ModelHandle<T> {
2060    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2061        ref_counts.lock().inc_model(model_id);
2062        Self {
2063            model_id,
2064            model_type: PhantomData,
2065            ref_counts: ref_counts.clone(),
2066        }
2067    }
2068
2069    pub fn downgrade(&self) -> WeakModelHandle<T> {
2070        WeakModelHandle::new(self.model_id)
2071    }
2072
2073    pub fn id(&self) -> usize {
2074        self.model_id
2075    }
2076
2077    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
2078        cx.read_model(self)
2079    }
2080
2081    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
2082    where
2083        C: ReadModelWith,
2084        F: FnOnce(&T, &AppContext) -> S,
2085    {
2086        cx.read_model_with(self, read)
2087    }
2088
2089    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
2090    where
2091        C: UpdateModel,
2092        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
2093    {
2094        cx.update_model(self, update)
2095    }
2096
2097    pub fn condition(
2098        &self,
2099        cx: &TestAppContext,
2100        mut predicate: impl FnMut(&T, &AppContext) -> bool,
2101    ) -> impl Future<Output = ()> {
2102        let (tx, mut rx) = mpsc::channel(1024);
2103
2104        let mut cx = cx.cx.borrow_mut();
2105        self.update(&mut *cx, |_, cx| {
2106            cx.observe(self, {
2107                let mut tx = tx.clone();
2108                move |_, _, _| {
2109                    tx.blocking_send(()).ok();
2110                }
2111            });
2112            cx.subscribe(self, {
2113                let mut tx = tx.clone();
2114                move |_, _, _| {
2115                    tx.blocking_send(()).ok();
2116                }
2117            })
2118        });
2119
2120        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
2121        let handle = self.downgrade();
2122        let duration = if std::env::var("CI").is_ok() {
2123            Duration::from_secs(2)
2124        } else {
2125            Duration::from_millis(500)
2126        };
2127
2128        async move {
2129            timeout(duration, async move {
2130                loop {
2131                    {
2132                        let cx = cx.borrow();
2133                        let cx = cx.as_ref();
2134                        if predicate(
2135                            handle
2136                                .upgrade(cx)
2137                                .expect("model dropped with pending condition")
2138                                .read(cx),
2139                            cx,
2140                        ) {
2141                            break;
2142                        }
2143                    }
2144
2145                    rx.recv()
2146                        .await
2147                        .expect("model dropped with pending condition");
2148                }
2149            })
2150            .await
2151            .expect("condition timed out");
2152        }
2153    }
2154}
2155
2156impl<T> Clone for ModelHandle<T> {
2157    fn clone(&self) -> Self {
2158        self.ref_counts.lock().inc_model(self.model_id);
2159        Self {
2160            model_id: self.model_id,
2161            model_type: PhantomData,
2162            ref_counts: self.ref_counts.clone(),
2163        }
2164    }
2165}
2166
2167impl<T> PartialEq for ModelHandle<T> {
2168    fn eq(&self, other: &Self) -> bool {
2169        self.model_id == other.model_id
2170    }
2171}
2172
2173impl<T> Eq for ModelHandle<T> {}
2174
2175impl<T> Hash for ModelHandle<T> {
2176    fn hash<H: Hasher>(&self, state: &mut H) {
2177        self.model_id.hash(state);
2178    }
2179}
2180
2181impl<T> std::borrow::Borrow<usize> for ModelHandle<T> {
2182    fn borrow(&self) -> &usize {
2183        &self.model_id
2184    }
2185}
2186
2187impl<T> Debug for ModelHandle<T> {
2188    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2189        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
2190            .field(&self.model_id)
2191            .finish()
2192    }
2193}
2194
2195unsafe impl<T> Send for ModelHandle<T> {}
2196unsafe impl<T> Sync for ModelHandle<T> {}
2197
2198impl<T> Drop for ModelHandle<T> {
2199    fn drop(&mut self) {
2200        self.ref_counts.lock().dec_model(self.model_id);
2201    }
2202}
2203
2204impl<T> Handle<T> for ModelHandle<T> {
2205    fn id(&self) -> usize {
2206        self.model_id
2207    }
2208
2209    fn location(&self) -> EntityLocation {
2210        EntityLocation::Model(self.model_id)
2211    }
2212}
2213
2214pub struct WeakModelHandle<T> {
2215    model_id: usize,
2216    model_type: PhantomData<T>,
2217}
2218
2219impl<T: Entity> WeakModelHandle<T> {
2220    fn new(model_id: usize) -> Self {
2221        Self {
2222            model_id,
2223            model_type: PhantomData,
2224        }
2225    }
2226
2227    pub fn upgrade(&self, cx: impl AsRef<AppContext>) -> Option<ModelHandle<T>> {
2228        let cx = cx.as_ref();
2229        if cx.models.contains_key(&self.model_id) {
2230            Some(ModelHandle::new(self.model_id, &cx.ref_counts))
2231        } else {
2232            None
2233        }
2234    }
2235}
2236
2237impl<T> Clone for WeakModelHandle<T> {
2238    fn clone(&self) -> Self {
2239        Self {
2240            model_id: self.model_id,
2241            model_type: PhantomData,
2242        }
2243    }
2244}
2245
2246pub struct ViewHandle<T> {
2247    window_id: usize,
2248    view_id: usize,
2249    view_type: PhantomData<T>,
2250    ref_counts: Arc<Mutex<RefCounts>>,
2251}
2252
2253impl<T: View> ViewHandle<T> {
2254    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2255        ref_counts.lock().inc_view(window_id, view_id);
2256        Self {
2257            window_id,
2258            view_id,
2259            view_type: PhantomData,
2260            ref_counts: ref_counts.clone(),
2261        }
2262    }
2263
2264    pub fn downgrade(&self) -> WeakViewHandle<T> {
2265        WeakViewHandle::new(self.window_id, self.view_id)
2266    }
2267
2268    pub fn window_id(&self) -> usize {
2269        self.window_id
2270    }
2271
2272    pub fn id(&self) -> usize {
2273        self.view_id
2274    }
2275
2276    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
2277        cx.read_view(self)
2278    }
2279
2280    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
2281    where
2282        C: ReadViewWith,
2283        F: FnOnce(&T, &AppContext) -> S,
2284    {
2285        cx.read_view_with(self, read)
2286    }
2287
2288    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
2289    where
2290        C: UpdateView,
2291        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
2292    {
2293        cx.update_view(self, update)
2294    }
2295
2296    pub fn is_focused(&self, cx: &AppContext) -> bool {
2297        cx.focused_view_id(self.window_id)
2298            .map_or(false, |focused_id| focused_id == self.view_id)
2299    }
2300
2301    pub fn condition(
2302        &self,
2303        cx: &TestAppContext,
2304        mut predicate: impl FnMut(&T, &AppContext) -> bool,
2305    ) -> impl Future<Output = ()> {
2306        let (tx, mut rx) = mpsc::channel(1024);
2307
2308        let mut cx = cx.cx.borrow_mut();
2309        self.update(&mut *cx, |_, cx| {
2310            cx.observe_view(self, {
2311                let mut tx = tx.clone();
2312                move |_, _, _| {
2313                    tx.blocking_send(()).ok();
2314                }
2315            });
2316
2317            cx.subscribe(self, {
2318                let mut tx = tx.clone();
2319                move |_, _, _| {
2320                    tx.blocking_send(()).ok();
2321                }
2322            })
2323        });
2324
2325        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
2326        let handle = self.downgrade();
2327        let duration = if std::env::var("CI").is_ok() {
2328            Duration::from_secs(2)
2329        } else {
2330            Duration::from_millis(500)
2331        };
2332
2333        async move {
2334            timeout(duration, async move {
2335                loop {
2336                    {
2337                        let cx = cx.borrow();
2338                        let cx = cx.as_ref();
2339                        if predicate(
2340                            handle
2341                                .upgrade(cx)
2342                                .expect("view dropped with pending condition")
2343                                .read(cx),
2344                            cx,
2345                        ) {
2346                            break;
2347                        }
2348                    }
2349
2350                    rx.recv()
2351                        .await
2352                        .expect("view dropped with pending condition");
2353                }
2354            })
2355            .await
2356            .expect("condition timed out");
2357        }
2358    }
2359}
2360
2361impl<T> Clone for ViewHandle<T> {
2362    fn clone(&self) -> Self {
2363        self.ref_counts
2364            .lock()
2365            .inc_view(self.window_id, self.view_id);
2366        Self {
2367            window_id: self.window_id,
2368            view_id: self.view_id,
2369            view_type: PhantomData,
2370            ref_counts: self.ref_counts.clone(),
2371        }
2372    }
2373}
2374
2375impl<T> PartialEq for ViewHandle<T> {
2376    fn eq(&self, other: &Self) -> bool {
2377        self.window_id == other.window_id && self.view_id == other.view_id
2378    }
2379}
2380
2381impl<T> Eq for ViewHandle<T> {}
2382
2383impl<T> Debug for ViewHandle<T> {
2384    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2385        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
2386            .field("window_id", &self.window_id)
2387            .field("view_id", &self.view_id)
2388            .finish()
2389    }
2390}
2391
2392impl<T> Drop for ViewHandle<T> {
2393    fn drop(&mut self) {
2394        self.ref_counts
2395            .lock()
2396            .dec_view(self.window_id, self.view_id);
2397    }
2398}
2399
2400impl<T> Handle<T> for ViewHandle<T> {
2401    fn id(&self) -> usize {
2402        self.view_id
2403    }
2404
2405    fn location(&self) -> EntityLocation {
2406        EntityLocation::View(self.window_id, self.view_id)
2407    }
2408}
2409
2410pub struct AnyViewHandle {
2411    window_id: usize,
2412    view_id: usize,
2413    view_type: TypeId,
2414    ref_counts: Arc<Mutex<RefCounts>>,
2415}
2416
2417impl AnyViewHandle {
2418    pub fn id(&self) -> usize {
2419        self.view_id
2420    }
2421
2422    pub fn is<T: 'static>(&self) -> bool {
2423        TypeId::of::<T>() == self.view_type
2424    }
2425
2426    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
2427        if self.is::<T>() {
2428            let result = Some(ViewHandle {
2429                window_id: self.window_id,
2430                view_id: self.view_id,
2431                ref_counts: self.ref_counts.clone(),
2432                view_type: PhantomData,
2433            });
2434            unsafe {
2435                Arc::decrement_strong_count(&self.ref_counts);
2436            }
2437            std::mem::forget(self);
2438            result
2439        } else {
2440            None
2441        }
2442    }
2443}
2444
2445impl Clone for AnyViewHandle {
2446    fn clone(&self) -> Self {
2447        self.ref_counts
2448            .lock()
2449            .inc_view(self.window_id, self.view_id);
2450        Self {
2451            window_id: self.window_id,
2452            view_id: self.view_id,
2453            view_type: self.view_type,
2454            ref_counts: self.ref_counts.clone(),
2455        }
2456    }
2457}
2458
2459impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
2460    fn from(handle: &ViewHandle<T>) -> Self {
2461        handle
2462            .ref_counts
2463            .lock()
2464            .inc_view(handle.window_id, handle.view_id);
2465        AnyViewHandle {
2466            window_id: handle.window_id,
2467            view_id: handle.view_id,
2468            view_type: TypeId::of::<T>(),
2469            ref_counts: handle.ref_counts.clone(),
2470        }
2471    }
2472}
2473
2474impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
2475    fn from(handle: ViewHandle<T>) -> Self {
2476        let any_handle = AnyViewHandle {
2477            window_id: handle.window_id,
2478            view_id: handle.view_id,
2479            view_type: TypeId::of::<T>(),
2480            ref_counts: handle.ref_counts.clone(),
2481        };
2482        unsafe {
2483            Arc::decrement_strong_count(&handle.ref_counts);
2484        }
2485        std::mem::forget(handle);
2486        any_handle
2487    }
2488}
2489
2490impl Drop for AnyViewHandle {
2491    fn drop(&mut self) {
2492        self.ref_counts
2493            .lock()
2494            .dec_view(self.window_id, self.view_id);
2495    }
2496}
2497
2498pub struct AnyModelHandle {
2499    model_id: usize,
2500    ref_counts: Arc<Mutex<RefCounts>>,
2501}
2502
2503impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
2504    fn from(handle: ModelHandle<T>) -> Self {
2505        handle.ref_counts.lock().inc_model(handle.model_id);
2506        Self {
2507            model_id: handle.model_id,
2508            ref_counts: handle.ref_counts.clone(),
2509        }
2510    }
2511}
2512
2513impl Drop for AnyModelHandle {
2514    fn drop(&mut self) {
2515        self.ref_counts.lock().dec_model(self.model_id);
2516    }
2517}
2518pub struct WeakViewHandle<T> {
2519    window_id: usize,
2520    view_id: usize,
2521    view_type: PhantomData<T>,
2522}
2523
2524impl<T: View> WeakViewHandle<T> {
2525    fn new(window_id: usize, view_id: usize) -> Self {
2526        Self {
2527            window_id,
2528            view_id,
2529            view_type: PhantomData,
2530        }
2531    }
2532
2533    pub fn upgrade(&self, cx: impl AsRef<AppContext>) -> Option<ViewHandle<T>> {
2534        let cx = cx.as_ref();
2535        if cx.ref_counts.lock().is_entity_alive(self.view_id) {
2536            Some(ViewHandle::new(
2537                self.window_id,
2538                self.view_id,
2539                &cx.ref_counts,
2540            ))
2541        } else {
2542            None
2543        }
2544    }
2545}
2546
2547impl<T> Clone for WeakViewHandle<T> {
2548    fn clone(&self) -> Self {
2549        Self {
2550            window_id: self.window_id,
2551            view_id: self.view_id,
2552            view_type: PhantomData,
2553        }
2554    }
2555}
2556
2557pub struct ValueHandle<T> {
2558    value_type: PhantomData<T>,
2559    tag_type_id: TypeId,
2560    id: usize,
2561    ref_counts: Weak<Mutex<RefCounts>>,
2562}
2563
2564impl<T: 'static> ValueHandle<T> {
2565    fn new(tag_type_id: TypeId, id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2566        ref_counts.lock().inc_value(tag_type_id, id);
2567        Self {
2568            value_type: PhantomData,
2569            tag_type_id,
2570            id,
2571            ref_counts: Arc::downgrade(ref_counts),
2572        }
2573    }
2574
2575    pub fn read<R>(&self, cx: &AppContext, f: impl FnOnce(&T) -> R) -> R {
2576        f(cx.values
2577            .read()
2578            .get(&(self.tag_type_id, self.id))
2579            .unwrap()
2580            .downcast_ref()
2581            .unwrap())
2582    }
2583
2584    pub fn update<R>(&self, cx: &AppContext, f: impl FnOnce(&mut T) -> R) -> R {
2585        f(cx.values
2586            .write()
2587            .get_mut(&(self.tag_type_id, self.id))
2588            .unwrap()
2589            .downcast_mut()
2590            .unwrap())
2591    }
2592}
2593
2594impl<T> Drop for ValueHandle<T> {
2595    fn drop(&mut self) {
2596        if let Some(ref_counts) = self.ref_counts.upgrade() {
2597            ref_counts.lock().dec_value(self.tag_type_id, self.id);
2598        }
2599    }
2600}
2601
2602#[derive(Default)]
2603struct RefCounts {
2604    entity_counts: HashMap<usize, usize>,
2605    value_counts: HashMap<(TypeId, usize), usize>,
2606    dropped_models: HashSet<usize>,
2607    dropped_views: HashSet<(usize, usize)>,
2608    dropped_values: HashSet<(TypeId, usize)>,
2609}
2610
2611impl RefCounts {
2612    fn inc_model(&mut self, model_id: usize) {
2613        match self.entity_counts.entry(model_id) {
2614            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
2615            Entry::Vacant(entry) => {
2616                entry.insert(1);
2617                self.dropped_models.remove(&model_id);
2618            }
2619        }
2620    }
2621
2622    fn inc_view(&mut self, window_id: usize, view_id: usize) {
2623        match self.entity_counts.entry(view_id) {
2624            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
2625            Entry::Vacant(entry) => {
2626                entry.insert(1);
2627                self.dropped_views.remove(&(window_id, view_id));
2628            }
2629        }
2630    }
2631
2632    fn inc_value(&mut self, tag_type_id: TypeId, id: usize) {
2633        *self.value_counts.entry((tag_type_id, id)).or_insert(0) += 1;
2634    }
2635
2636    fn dec_model(&mut self, model_id: usize) {
2637        let count = self.entity_counts.get_mut(&model_id).unwrap();
2638        *count -= 1;
2639        if *count == 0 {
2640            self.entity_counts.remove(&model_id);
2641            self.dropped_models.insert(model_id);
2642        }
2643    }
2644
2645    fn dec_view(&mut self, window_id: usize, view_id: usize) {
2646        let count = self.entity_counts.get_mut(&view_id).unwrap();
2647        *count -= 1;
2648        if *count == 0 {
2649            self.entity_counts.remove(&view_id);
2650            self.dropped_views.insert((window_id, view_id));
2651        }
2652    }
2653
2654    fn dec_value(&mut self, tag_type_id: TypeId, id: usize) {
2655        let key = (tag_type_id, id);
2656        let count = self.value_counts.get_mut(&key).unwrap();
2657        *count -= 1;
2658        if *count == 0 {
2659            self.value_counts.remove(&key);
2660            self.dropped_values.insert(key);
2661        }
2662    }
2663
2664    fn is_entity_alive(&self, entity_id: usize) -> bool {
2665        self.entity_counts.contains_key(&entity_id)
2666    }
2667
2668    fn take_dropped(
2669        &mut self,
2670    ) -> (
2671        HashSet<usize>,
2672        HashSet<(usize, usize)>,
2673        HashSet<(TypeId, usize)>,
2674    ) {
2675        let mut dropped_models = HashSet::new();
2676        let mut dropped_views = HashSet::new();
2677        let mut dropped_values = HashSet::new();
2678        std::mem::swap(&mut self.dropped_models, &mut dropped_models);
2679        std::mem::swap(&mut self.dropped_views, &mut dropped_views);
2680        std::mem::swap(&mut self.dropped_values, &mut dropped_values);
2681        (dropped_models, dropped_views, dropped_values)
2682    }
2683}
2684
2685enum Subscription {
2686    FromModel {
2687        model_id: usize,
2688        callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize)>,
2689    },
2690    FromView {
2691        window_id: usize,
2692        view_id: usize,
2693        callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize, usize)>,
2694    },
2695}
2696
2697enum ModelObservation {
2698    FromModel {
2699        model_id: usize,
2700        callback: Box<dyn FnMut(&mut dyn Any, usize, &mut MutableAppContext, usize)>,
2701    },
2702    FromView {
2703        window_id: usize,
2704        view_id: usize,
2705        callback: Box<dyn FnMut(&mut dyn Any, usize, &mut MutableAppContext, usize, usize)>,
2706    },
2707}
2708
2709struct ViewObservation {
2710    window_id: usize,
2711    view_id: usize,
2712    callback: Box<dyn FnMut(&mut dyn Any, usize, usize, &mut MutableAppContext, usize, usize)>,
2713}
2714
2715#[cfg(test)]
2716mod tests {
2717    use super::*;
2718    use crate::elements::*;
2719    use smol::future::poll_once;
2720
2721    #[crate::test(self)]
2722    fn test_model_handles(cx: &mut MutableAppContext) {
2723        struct Model {
2724            other: Option<ModelHandle<Model>>,
2725            events: Vec<String>,
2726        }
2727
2728        impl Entity for Model {
2729            type Event = usize;
2730        }
2731
2732        impl Model {
2733            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
2734                if let Some(other) = other.as_ref() {
2735                    cx.observe(other, |me, _, _| {
2736                        me.events.push("notified".into());
2737                    });
2738                    cx.subscribe(other, |me, event, _| {
2739                        me.events.push(format!("observed event {}", event));
2740                    });
2741                }
2742
2743                Self {
2744                    other,
2745                    events: Vec::new(),
2746                }
2747            }
2748        }
2749
2750        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
2751        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
2752        assert_eq!(cx.cx.models.len(), 2);
2753
2754        handle_1.update(cx, |model, cx| {
2755            model.events.push("updated".into());
2756            cx.emit(1);
2757            cx.notify();
2758            cx.emit(2);
2759        });
2760        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
2761        assert_eq!(
2762            handle_2.read(cx).events,
2763            vec![
2764                "observed event 1".to_string(),
2765                "notified".to_string(),
2766                "observed event 2".to_string(),
2767            ]
2768        );
2769
2770        handle_2.update(cx, |model, _| {
2771            drop(handle_1);
2772            model.other.take();
2773        });
2774
2775        assert_eq!(cx.cx.models.len(), 1);
2776        assert!(cx.subscriptions.is_empty());
2777        assert!(cx.model_observations.is_empty());
2778    }
2779
2780    #[crate::test(self)]
2781    fn test_subscribe_and_emit_from_model(cx: &mut MutableAppContext) {
2782        #[derive(Default)]
2783        struct Model {
2784            events: Vec<usize>,
2785        }
2786
2787        impl Entity for Model {
2788            type Event = usize;
2789        }
2790
2791        let handle_1 = cx.add_model(|_| Model::default());
2792        let handle_2 = cx.add_model(|_| Model::default());
2793        let handle_2b = handle_2.clone();
2794
2795        handle_1.update(cx, |_, c| {
2796            c.subscribe(&handle_2, move |model: &mut Model, event, c| {
2797                model.events.push(*event);
2798
2799                c.subscribe(&handle_2b, |model, event, _| {
2800                    model.events.push(*event * 2);
2801                });
2802            });
2803        });
2804
2805        handle_2.update(cx, |_, c| c.emit(7));
2806        assert_eq!(handle_1.read(cx).events, vec![7]);
2807
2808        handle_2.update(cx, |_, c| c.emit(5));
2809        assert_eq!(handle_1.read(cx).events, vec![7, 10, 5]);
2810    }
2811
2812    #[crate::test(self)]
2813    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
2814        #[derive(Default)]
2815        struct Model {
2816            count: usize,
2817            events: Vec<usize>,
2818        }
2819
2820        impl Entity for Model {
2821            type Event = ();
2822        }
2823
2824        let handle_1 = cx.add_model(|_| Model::default());
2825        let handle_2 = cx.add_model(|_| Model::default());
2826        let handle_2b = handle_2.clone();
2827
2828        handle_1.update(cx, |_, c| {
2829            c.observe(&handle_2, move |model, observed, c| {
2830                model.events.push(observed.read(c).count);
2831                c.observe(&handle_2b, |model, observed, c| {
2832                    model.events.push(observed.read(c).count * 2);
2833                });
2834            });
2835        });
2836
2837        handle_2.update(cx, |model, c| {
2838            model.count = 7;
2839            c.notify()
2840        });
2841        assert_eq!(handle_1.read(cx).events, vec![7]);
2842
2843        handle_2.update(cx, |model, c| {
2844            model.count = 5;
2845            c.notify()
2846        });
2847        assert_eq!(handle_1.read(cx).events, vec![7, 10, 5])
2848    }
2849
2850    #[crate::test(self)]
2851    fn test_view_handles(cx: &mut MutableAppContext) {
2852        struct View {
2853            other: Option<ViewHandle<View>>,
2854            events: Vec<String>,
2855        }
2856
2857        impl Entity for View {
2858            type Event = usize;
2859        }
2860
2861        impl super::View for View {
2862            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2863                Empty::new().boxed()
2864            }
2865
2866            fn ui_name() -> &'static str {
2867                "View"
2868            }
2869        }
2870
2871        impl View {
2872            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
2873                if let Some(other) = other.as_ref() {
2874                    cx.subscribe_to_view(other, |me, _, event, _| {
2875                        me.events.push(format!("observed event {}", event));
2876                    });
2877                }
2878                Self {
2879                    other,
2880                    events: Vec::new(),
2881                }
2882            }
2883        }
2884
2885        let (window_id, _) = cx.add_window(|cx| View::new(None, cx));
2886        let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
2887        let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
2888        assert_eq!(cx.cx.views.len(), 3);
2889
2890        handle_1.update(cx, |view, cx| {
2891            view.events.push("updated".into());
2892            cx.emit(1);
2893            cx.emit(2);
2894        });
2895        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
2896        assert_eq!(
2897            handle_2.read(cx).events,
2898            vec![
2899                "observed event 1".to_string(),
2900                "observed event 2".to_string(),
2901            ]
2902        );
2903
2904        handle_2.update(cx, |view, _| {
2905            drop(handle_1);
2906            view.other.take();
2907        });
2908
2909        assert_eq!(cx.cx.views.len(), 2);
2910        assert!(cx.subscriptions.is_empty());
2911        assert!(cx.model_observations.is_empty());
2912    }
2913
2914    #[crate::test(self)]
2915    fn test_subscribe_and_emit_from_view(cx: &mut MutableAppContext) {
2916        #[derive(Default)]
2917        struct View {
2918            events: Vec<usize>,
2919        }
2920
2921        impl Entity for View {
2922            type Event = usize;
2923        }
2924
2925        impl super::View for View {
2926            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2927                Empty::new().boxed()
2928            }
2929
2930            fn ui_name() -> &'static str {
2931                "View"
2932            }
2933        }
2934
2935        struct Model;
2936
2937        impl Entity for Model {
2938            type Event = usize;
2939        }
2940
2941        let (window_id, handle_1) = cx.add_window(|_| View::default());
2942        let handle_2 = cx.add_view(window_id, |_| View::default());
2943        let handle_2b = handle_2.clone();
2944        let handle_3 = cx.add_model(|_| Model);
2945
2946        handle_1.update(cx, |_, c| {
2947            c.subscribe_to_view(&handle_2, move |me, _, event, c| {
2948                me.events.push(*event);
2949
2950                c.subscribe_to_view(&handle_2b, |me, _, event, _| {
2951                    me.events.push(*event * 2);
2952                });
2953            });
2954
2955            c.subscribe_to_model(&handle_3, |me, _, event, _| {
2956                me.events.push(*event);
2957            })
2958        });
2959
2960        handle_2.update(cx, |_, c| c.emit(7));
2961        assert_eq!(handle_1.read(cx).events, vec![7]);
2962
2963        handle_2.update(cx, |_, c| c.emit(5));
2964        assert_eq!(handle_1.read(cx).events, vec![7, 10, 5]);
2965
2966        handle_3.update(cx, |_, c| c.emit(9));
2967        assert_eq!(handle_1.read(cx).events, vec![7, 10, 5, 9]);
2968    }
2969
2970    #[crate::test(self)]
2971    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
2972        struct View;
2973
2974        impl Entity for View {
2975            type Event = ();
2976        }
2977
2978        impl super::View for View {
2979            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2980                Empty::new().boxed()
2981            }
2982
2983            fn ui_name() -> &'static str {
2984                "View"
2985            }
2986        }
2987
2988        struct Model;
2989
2990        impl Entity for Model {
2991            type Event = ();
2992        }
2993
2994        let (window_id, _) = cx.add_window(|_| View);
2995        let observing_view = cx.add_view(window_id, |_| View);
2996        let emitting_view = cx.add_view(window_id, |_| View);
2997        let observing_model = cx.add_model(|_| Model);
2998        let observed_model = cx.add_model(|_| Model);
2999
3000        observing_view.update(cx, |_, cx| {
3001            cx.subscribe_to_view(&emitting_view, |_, _, _, _| {});
3002            cx.subscribe_to_model(&observed_model, |_, _, _, _| {});
3003        });
3004        observing_model.update(cx, |_, cx| {
3005            cx.subscribe(&observed_model, |_, _, _| {});
3006        });
3007
3008        cx.update(|| {
3009            drop(observing_view);
3010            drop(observing_model);
3011        });
3012
3013        emitting_view.update(cx, |_, cx| cx.emit(()));
3014        observed_model.update(cx, |_, cx| cx.emit(()));
3015    }
3016
3017    #[crate::test(self)]
3018    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
3019        #[derive(Default)]
3020        struct View {
3021            events: Vec<usize>,
3022        }
3023
3024        impl Entity for View {
3025            type Event = usize;
3026        }
3027
3028        impl super::View for View {
3029            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3030                Empty::new().boxed()
3031            }
3032
3033            fn ui_name() -> &'static str {
3034                "View"
3035            }
3036        }
3037
3038        #[derive(Default)]
3039        struct Model {
3040            count: usize,
3041        }
3042
3043        impl Entity for Model {
3044            type Event = ();
3045        }
3046
3047        let (_, view) = cx.add_window(|_| View::default());
3048        let model = cx.add_model(|_| Model::default());
3049
3050        view.update(cx, |_, c| {
3051            c.observe_model(&model, |me, observed, c| {
3052                me.events.push(observed.read(c).count)
3053            });
3054        });
3055
3056        model.update(cx, |model, c| {
3057            model.count = 11;
3058            c.notify();
3059        });
3060        assert_eq!(view.read(cx).events, vec![11]);
3061    }
3062
3063    #[crate::test(self)]
3064    fn test_dropping_observers(cx: &mut MutableAppContext) {
3065        struct View;
3066
3067        impl Entity for View {
3068            type Event = ();
3069        }
3070
3071        impl super::View for View {
3072            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3073                Empty::new().boxed()
3074            }
3075
3076            fn ui_name() -> &'static str {
3077                "View"
3078            }
3079        }
3080
3081        struct Model;
3082
3083        impl Entity for Model {
3084            type Event = ();
3085        }
3086
3087        let (window_id, _) = cx.add_window(|_| View);
3088        let observing_view = cx.add_view(window_id, |_| View);
3089        let observing_model = cx.add_model(|_| Model);
3090        let observed_model = cx.add_model(|_| Model);
3091
3092        observing_view.update(cx, |_, cx| {
3093            cx.observe_model(&observed_model, |_, _, _| {});
3094        });
3095        observing_model.update(cx, |_, cx| {
3096            cx.observe(&observed_model, |_, _, _| {});
3097        });
3098
3099        cx.update(|| {
3100            drop(observing_view);
3101            drop(observing_model);
3102        });
3103
3104        observed_model.update(cx, |_, cx| cx.notify());
3105    }
3106
3107    #[crate::test(self)]
3108    fn test_focus(cx: &mut MutableAppContext) {
3109        struct View {
3110            name: String,
3111            events: Arc<Mutex<Vec<String>>>,
3112        }
3113
3114        impl Entity for View {
3115            type Event = ();
3116        }
3117
3118        impl super::View for View {
3119            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3120                Empty::new().boxed()
3121            }
3122
3123            fn ui_name() -> &'static str {
3124                "View"
3125            }
3126
3127            fn on_focus(&mut self, _: &mut ViewContext<Self>) {
3128                self.events.lock().push(format!("{} focused", &self.name));
3129            }
3130
3131            fn on_blur(&mut self, _: &mut ViewContext<Self>) {
3132                self.events.lock().push(format!("{} blurred", &self.name));
3133            }
3134        }
3135
3136        let events: Arc<Mutex<Vec<String>>> = Default::default();
3137        let (window_id, view_1) = cx.add_window(|_| View {
3138            events: events.clone(),
3139            name: "view 1".to_string(),
3140        });
3141        let view_2 = cx.add_view(window_id, |_| View {
3142            events: events.clone(),
3143            name: "view 2".to_string(),
3144        });
3145
3146        view_1.update(cx, |_, cx| cx.focus(&view_2));
3147        view_1.update(cx, |_, cx| cx.focus(&view_1));
3148        view_1.update(cx, |_, cx| cx.focus(&view_2));
3149        view_1.update(cx, |_, _| drop(view_2));
3150
3151        assert_eq!(
3152            *events.lock(),
3153            [
3154                "view 1 focused".to_string(),
3155                "view 1 blurred".to_string(),
3156                "view 2 focused".to_string(),
3157                "view 2 blurred".to_string(),
3158                "view 1 focused".to_string(),
3159                "view 1 blurred".to_string(),
3160                "view 2 focused".to_string(),
3161                "view 1 focused".to_string(),
3162            ],
3163        );
3164    }
3165
3166    #[crate::test(self)]
3167    fn test_dispatch_action(cx: &mut MutableAppContext) {
3168        struct ViewA {
3169            id: usize,
3170        }
3171
3172        impl Entity for ViewA {
3173            type Event = ();
3174        }
3175
3176        impl View for ViewA {
3177            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3178                Empty::new().boxed()
3179            }
3180
3181            fn ui_name() -> &'static str {
3182                "View"
3183            }
3184        }
3185
3186        struct ViewB {
3187            id: usize,
3188        }
3189
3190        impl Entity for ViewB {
3191            type Event = ();
3192        }
3193
3194        impl View for ViewB {
3195            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3196                Empty::new().boxed()
3197            }
3198
3199            fn ui_name() -> &'static str {
3200                "View"
3201            }
3202        }
3203
3204        struct ActionArg {
3205            foo: String,
3206        }
3207
3208        let actions = Rc::new(RefCell::new(Vec::new()));
3209
3210        let actions_clone = actions.clone();
3211        cx.add_global_action("action", move |_: &ActionArg, _: &mut MutableAppContext| {
3212            actions_clone.borrow_mut().push("global a".to_string());
3213        });
3214
3215        let actions_clone = actions.clone();
3216        cx.add_global_action("action", move |_: &ActionArg, _: &mut MutableAppContext| {
3217            actions_clone.borrow_mut().push("global b".to_string());
3218        });
3219
3220        let actions_clone = actions.clone();
3221        cx.add_action("action", move |view: &mut ViewA, arg: &ActionArg, cx| {
3222            assert_eq!(arg.foo, "bar");
3223            cx.propagate_action();
3224            actions_clone.borrow_mut().push(format!("{} a", view.id));
3225        });
3226
3227        let actions_clone = actions.clone();
3228        cx.add_action("action", move |view: &mut ViewA, _: &ActionArg, cx| {
3229            if view.id != 1 {
3230                cx.propagate_action();
3231            }
3232            actions_clone.borrow_mut().push(format!("{} b", view.id));
3233        });
3234
3235        let actions_clone = actions.clone();
3236        cx.add_action("action", move |view: &mut ViewB, _: &ActionArg, cx| {
3237            cx.propagate_action();
3238            actions_clone.borrow_mut().push(format!("{} c", view.id));
3239        });
3240
3241        let actions_clone = actions.clone();
3242        cx.add_action("action", move |view: &mut ViewB, _: &ActionArg, cx| {
3243            cx.propagate_action();
3244            actions_clone.borrow_mut().push(format!("{} d", view.id));
3245        });
3246
3247        let (window_id, view_1) = cx.add_window(|_| ViewA { id: 1 });
3248        let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 });
3249        let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 });
3250        let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 });
3251
3252        cx.dispatch_action(
3253            window_id,
3254            vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
3255            "action",
3256            ActionArg { foo: "bar".into() },
3257        );
3258
3259        assert_eq!(
3260            *actions.borrow(),
3261            vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "1 b"]
3262        );
3263
3264        // Remove view_1, which doesn't propagate the action
3265        actions.borrow_mut().clear();
3266        cx.dispatch_action(
3267            window_id,
3268            vec![view_2.id(), view_3.id(), view_4.id()],
3269            "action",
3270            ActionArg { foo: "bar".into() },
3271        );
3272
3273        assert_eq!(
3274            *actions.borrow(),
3275            vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "global b", "global a"]
3276        );
3277    }
3278
3279    #[crate::test(self)]
3280    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
3281        use std::cell::Cell;
3282
3283        #[derive(Clone)]
3284        struct ActionArg {
3285            key: String,
3286        }
3287
3288        struct View {
3289            id: usize,
3290            keymap_context: keymap::Context,
3291        }
3292
3293        impl Entity for View {
3294            type Event = ();
3295        }
3296
3297        impl super::View for View {
3298            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3299                Empty::new().boxed()
3300            }
3301
3302            fn ui_name() -> &'static str {
3303                "View"
3304            }
3305
3306            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
3307                self.keymap_context.clone()
3308            }
3309        }
3310
3311        impl View {
3312            fn new(id: usize) -> Self {
3313                View {
3314                    id,
3315                    keymap_context: keymap::Context::default(),
3316                }
3317            }
3318        }
3319
3320        let mut view_1 = View::new(1);
3321        let mut view_2 = View::new(2);
3322        let mut view_3 = View::new(3);
3323        view_1.keymap_context.set.insert("a".into());
3324        view_2.keymap_context.set.insert("b".into());
3325        view_3.keymap_context.set.insert("c".into());
3326
3327        let (window_id, view_1) = cx.add_window(|_| view_1);
3328        let view_2 = cx.add_view(window_id, |_| view_2);
3329        let view_3 = cx.add_view(window_id, |_| view_3);
3330
3331        // This keymap's only binding dispatches an action on view 2 because that view will have
3332        // "a" and "b" in its context, but not "c".
3333        let binding = keymap::Binding::new("a", "action", Some("a && b && !c"))
3334            .with_arg(ActionArg { key: "a".into() });
3335        cx.add_bindings(vec![binding]);
3336
3337        let handled_action = Rc::new(Cell::new(false));
3338        let handled_action_clone = handled_action.clone();
3339        cx.add_action("action", move |view: &mut View, arg: &ActionArg, _| {
3340            handled_action_clone.set(true);
3341            assert_eq!(view.id, 2);
3342            assert_eq!(arg.key, "a");
3343        });
3344
3345        cx.dispatch_keystroke(
3346            window_id,
3347            vec![view_1.id(), view_2.id(), view_3.id()],
3348            &Keystroke::parse("a").unwrap(),
3349        )
3350        .unwrap();
3351
3352        assert!(handled_action.get());
3353    }
3354
3355    #[crate::test(self)]
3356    async fn test_model_condition(mut cx: TestAppContext) {
3357        struct Counter(usize);
3358
3359        impl super::Entity for Counter {
3360            type Event = ();
3361        }
3362
3363        impl Counter {
3364            fn inc(&mut self, cx: &mut ModelContext<Self>) {
3365                self.0 += 1;
3366                cx.notify();
3367            }
3368        }
3369
3370        let model = cx.add_model(|_| Counter(0));
3371
3372        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
3373        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
3374        smol::pin!(condition1, condition2);
3375
3376        model.update(&mut cx, |model, cx| model.inc(cx));
3377        assert_eq!(poll_once(&mut condition1).await, None);
3378        assert_eq!(poll_once(&mut condition2).await, None);
3379
3380        model.update(&mut cx, |model, cx| model.inc(cx));
3381        assert_eq!(poll_once(&mut condition1).await, Some(()));
3382        assert_eq!(poll_once(&mut condition2).await, None);
3383
3384        model.update(&mut cx, |model, cx| model.inc(cx));
3385        assert_eq!(poll_once(&mut condition2).await, Some(()));
3386
3387        model.update(&mut cx, |_, cx| cx.notify());
3388    }
3389
3390    #[crate::test(self)]
3391    #[should_panic]
3392    async fn test_model_condition_timeout(mut cx: TestAppContext) {
3393        struct Model;
3394
3395        impl super::Entity for Model {
3396            type Event = ();
3397        }
3398
3399        let model = cx.add_model(|_| Model);
3400        model.condition(&cx, |_, _| false).await;
3401    }
3402
3403    #[crate::test(self)]
3404    #[should_panic(expected = "model dropped with pending condition")]
3405    async fn test_model_condition_panic_on_drop(mut cx: TestAppContext) {
3406        struct Model;
3407
3408        impl super::Entity for Model {
3409            type Event = ();
3410        }
3411
3412        let model = cx.add_model(|_| Model);
3413        let condition = model.condition(&cx, |_, _| false);
3414        cx.update(|_| drop(model));
3415        condition.await;
3416    }
3417
3418    #[crate::test(self)]
3419    async fn test_view_condition(mut cx: TestAppContext) {
3420        struct Counter(usize);
3421
3422        impl super::Entity for Counter {
3423            type Event = ();
3424        }
3425
3426        impl super::View for Counter {
3427            fn ui_name() -> &'static str {
3428                "test view"
3429            }
3430
3431            fn render(&self, _: &AppContext) -> ElementBox {
3432                Empty::new().boxed()
3433            }
3434        }
3435
3436        impl Counter {
3437            fn inc(&mut self, cx: &mut ViewContext<Self>) {
3438                self.0 += 1;
3439                cx.notify();
3440            }
3441        }
3442
3443        let (_, view) = cx.add_window(|_| Counter(0));
3444
3445        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
3446        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
3447        smol::pin!(condition1, condition2);
3448
3449        view.update(&mut cx, |view, cx| view.inc(cx));
3450        assert_eq!(poll_once(&mut condition1).await, None);
3451        assert_eq!(poll_once(&mut condition2).await, None);
3452
3453        view.update(&mut cx, |view, cx| view.inc(cx));
3454        assert_eq!(poll_once(&mut condition1).await, Some(()));
3455        assert_eq!(poll_once(&mut condition2).await, None);
3456
3457        view.update(&mut cx, |view, cx| view.inc(cx));
3458        assert_eq!(poll_once(&mut condition2).await, Some(()));
3459        view.update(&mut cx, |_, cx| cx.notify());
3460    }
3461
3462    #[crate::test(self)]
3463    #[should_panic]
3464    async fn test_view_condition_timeout(mut cx: TestAppContext) {
3465        struct View;
3466
3467        impl super::Entity for View {
3468            type Event = ();
3469        }
3470
3471        impl super::View for View {
3472            fn ui_name() -> &'static str {
3473                "test view"
3474            }
3475
3476            fn render(&self, _: &AppContext) -> ElementBox {
3477                Empty::new().boxed()
3478            }
3479        }
3480
3481        let (_, view) = cx.add_window(|_| View);
3482        view.condition(&cx, |_, _| false).await;
3483    }
3484
3485    #[crate::test(self)]
3486    #[should_panic(expected = "view dropped with pending condition")]
3487    async fn test_view_condition_panic_on_drop(mut cx: TestAppContext) {
3488        struct View;
3489
3490        impl super::Entity for View {
3491            type Event = ();
3492        }
3493
3494        impl super::View for View {
3495            fn ui_name() -> &'static str {
3496                "test view"
3497            }
3498
3499            fn render(&self, _: &AppContext) -> ElementBox {
3500                Empty::new().boxed()
3501            }
3502        }
3503
3504        let window_id = cx.add_window(|_| View).0;
3505        let view = cx.add_view(window_id, |_| View);
3506
3507        let condition = view.condition(&cx, |_, _| false);
3508        cx.update(|_| drop(view));
3509        condition.await;
3510    }
3511}