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