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