app.rs

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