app.rs

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