app.rs

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