app.rs

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