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