app.rs

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