app.rs

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