app.rs

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