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