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