app.rs

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