app.rs

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