app.rs

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