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
1125impl ModelAsRef for MutableAppContext {
1126    fn model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1127        if let Some(model) = self.ctx.models.get(&handle.model_id) {
1128            model
1129                .as_any()
1130                .downcast_ref()
1131                .expect("Downcast is type safe")
1132        } else {
1133            panic!("Circular model reference");
1134        }
1135    }
1136}
1137
1138impl UpdateModel for MutableAppContext {
1139    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1140    where
1141        T: Entity,
1142        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1143    {
1144        if let Some(mut model) = self.ctx.models.remove(&handle.model_id) {
1145            self.pending_flushes += 1;
1146            let mut ctx = ModelContext::new(self, handle.model_id);
1147            let result = update(
1148                model
1149                    .as_any_mut()
1150                    .downcast_mut()
1151                    .expect("Downcast is type safe"),
1152                &mut ctx,
1153            );
1154            self.ctx.models.insert(handle.model_id, model);
1155            self.flush_effects();
1156            result
1157        } else {
1158            panic!("Circular model update");
1159        }
1160    }
1161}
1162
1163impl ViewAsRef for MutableAppContext {
1164    fn view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1165        if let Some(window) = self.ctx.windows.get(&handle.window_id) {
1166            if let Some(view) = window.views.get(&handle.view_id) {
1167                view.as_any().downcast_ref().expect("Downcast is type safe")
1168            } else {
1169                panic!("Circular view reference");
1170            }
1171        } else {
1172            panic!("Window does not exist");
1173        }
1174    }
1175}
1176
1177impl UpdateView for MutableAppContext {
1178    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
1179    where
1180        T: View,
1181        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
1182    {
1183        self.pending_flushes += 1;
1184        let mut view = if let Some(window) = self.ctx.windows.get_mut(&handle.window_id) {
1185            if let Some(view) = window.views.remove(&handle.view_id) {
1186                view
1187            } else {
1188                panic!("Circular view update");
1189            }
1190        } else {
1191            panic!("Window does not exist");
1192        };
1193
1194        let mut ctx = ViewContext::new(self, handle.window_id, handle.view_id);
1195        let result = update(
1196            view.as_any_mut()
1197                .downcast_mut()
1198                .expect("Downcast is type safe"),
1199            &mut ctx,
1200        );
1201        self.ctx
1202            .windows
1203            .get_mut(&handle.window_id)
1204            .unwrap()
1205            .views
1206            .insert(handle.view_id, view);
1207        self.flush_effects();
1208        result
1209    }
1210}
1211
1212pub struct AppContext {
1213    models: HashMap<usize, Box<dyn AnyModel>>,
1214    windows: HashMap<usize, Window>,
1215    background: Arc<executor::Background>,
1216    ref_counts: Arc<Mutex<RefCounts>>,
1217}
1218
1219impl AppContext {
1220    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
1221        self.windows
1222            .get(&window_id)
1223            .and_then(|window| window.root_view.as_ref().map(|v| v.id()))
1224    }
1225
1226    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
1227        self.windows
1228            .get(&window_id)
1229            .and_then(|window| window.focused_view)
1230    }
1231
1232    pub fn render_view(&self, window_id: usize, view_id: usize) -> Result<ElementBox> {
1233        self.windows
1234            .get(&window_id)
1235            .and_then(|w| w.views.get(&view_id))
1236            .map(|v| v.render(self))
1237            .ok_or(anyhow!("view not found"))
1238    }
1239
1240    pub fn render_views(&self, window_id: usize) -> Result<HashMap<usize, ElementBox>> {
1241        self.windows
1242            .get(&window_id)
1243            .map(|w| {
1244                w.views
1245                    .iter()
1246                    .map(|(id, view)| (*id, view.render(self)))
1247                    .collect::<HashMap<_, ElementBox>>()
1248            })
1249            .ok_or(anyhow!("window not found"))
1250    }
1251
1252    pub fn background_executor(&self) -> &Arc<executor::Background> {
1253        &self.background
1254    }
1255}
1256
1257impl ModelAsRef for AppContext {
1258    fn model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1259        if let Some(model) = self.models.get(&handle.model_id) {
1260            model
1261                .as_any()
1262                .downcast_ref()
1263                .expect("downcast should be type safe")
1264        } else {
1265            panic!("circular model reference");
1266        }
1267    }
1268}
1269
1270impl ViewAsRef for AppContext {
1271    fn view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1272        if let Some(window) = self.windows.get(&handle.window_id) {
1273            if let Some(view) = window.views.get(&handle.view_id) {
1274                view.as_any()
1275                    .downcast_ref()
1276                    .expect("downcast should be type safe")
1277            } else {
1278                panic!("circular view reference");
1279            }
1280        } else {
1281            panic!("window does not exist");
1282        }
1283    }
1284}
1285
1286#[derive(Default)]
1287struct Window {
1288    views: HashMap<usize, Box<dyn AnyView>>,
1289    root_view: Option<AnyViewHandle>,
1290    focused_view: Option<usize>,
1291}
1292
1293#[derive(Default, Clone)]
1294pub struct WindowInvalidation {
1295    pub updated: HashSet<usize>,
1296    pub removed: Vec<usize>,
1297}
1298
1299pub enum Effect {
1300    Event {
1301        entity_id: usize,
1302        payload: Box<dyn Any>,
1303    },
1304    ModelNotification {
1305        model_id: usize,
1306    },
1307    ViewNotification {
1308        window_id: usize,
1309        view_id: usize,
1310    },
1311    Focus {
1312        window_id: usize,
1313        view_id: usize,
1314    },
1315}
1316
1317pub trait AnyModel: Send + Sync {
1318    fn as_any(&self) -> &dyn Any;
1319    fn as_any_mut(&mut self) -> &mut dyn Any;
1320}
1321
1322impl<T> AnyModel for T
1323where
1324    T: Entity,
1325{
1326    fn as_any(&self) -> &dyn Any {
1327        self
1328    }
1329
1330    fn as_any_mut(&mut self) -> &mut dyn Any {
1331        self
1332    }
1333}
1334
1335pub trait AnyView: Send + Sync {
1336    fn as_any(&self) -> &dyn Any;
1337    fn as_any_mut(&mut self) -> &mut dyn Any;
1338    fn ui_name(&self) -> &'static str;
1339    fn render<'a>(&self, app: &AppContext) -> ElementBox;
1340    fn on_focus(&mut self, app: &mut MutableAppContext, window_id: usize, view_id: usize);
1341    fn on_blur(&mut self, app: &mut MutableAppContext, window_id: usize, view_id: usize);
1342    fn keymap_context(&self, app: &AppContext) -> keymap::Context;
1343}
1344
1345impl<T> AnyView for T
1346where
1347    T: View,
1348{
1349    fn as_any(&self) -> &dyn Any {
1350        self
1351    }
1352
1353    fn as_any_mut(&mut self) -> &mut dyn Any {
1354        self
1355    }
1356
1357    fn ui_name(&self) -> &'static str {
1358        T::ui_name()
1359    }
1360
1361    fn render<'a>(&self, app: &AppContext) -> ElementBox {
1362        View::render(self, app)
1363    }
1364
1365    fn on_focus(&mut self, app: &mut MutableAppContext, window_id: usize, view_id: usize) {
1366        let mut ctx = ViewContext::new(app, window_id, view_id);
1367        View::on_focus(self, &mut ctx);
1368    }
1369
1370    fn on_blur(&mut self, app: &mut MutableAppContext, window_id: usize, view_id: usize) {
1371        let mut ctx = ViewContext::new(app, window_id, view_id);
1372        View::on_blur(self, &mut ctx);
1373    }
1374
1375    fn keymap_context(&self, app: &AppContext) -> keymap::Context {
1376        View::keymap_context(self, app)
1377    }
1378}
1379
1380pub struct ModelContext<'a, T: ?Sized> {
1381    app: &'a mut MutableAppContext,
1382    model_id: usize,
1383    model_type: PhantomData<T>,
1384    halt_stream: bool,
1385}
1386
1387impl<'a, T: Entity> ModelContext<'a, T> {
1388    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
1389        Self {
1390            app,
1391            model_id,
1392            model_type: PhantomData,
1393            halt_stream: false,
1394        }
1395    }
1396
1397    pub fn app(&self) -> &AppContext {
1398        &self.app.ctx
1399    }
1400
1401    pub fn app_mut(&mut self) -> &mut MutableAppContext {
1402        self.app
1403    }
1404
1405    pub fn background_executor(&self) -> &Arc<executor::Background> {
1406        &self.app.ctx.background
1407    }
1408
1409    pub fn halt_stream(&mut self) {
1410        self.halt_stream = true;
1411    }
1412
1413    pub fn model_id(&self) -> usize {
1414        self.model_id
1415    }
1416
1417    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
1418    where
1419        S: Entity,
1420        F: FnOnce(&mut ModelContext<S>) -> S,
1421    {
1422        self.app.add_model(build_model)
1423    }
1424
1425    pub fn subscribe<S: Entity, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1426    where
1427        S::Event: 'static,
1428        F: 'static + FnMut(&mut T, &S::Event, &mut ModelContext<T>),
1429    {
1430        self.app
1431            .subscriptions
1432            .entry(handle.model_id)
1433            .or_default()
1434            .push(Subscription::FromModel {
1435                model_id: self.model_id,
1436                callback: Box::new(move |model, payload, app, model_id| {
1437                    let model = model.downcast_mut().expect("downcast is type safe");
1438                    let payload = payload.downcast_ref().expect("downcast is type safe");
1439                    let mut ctx = ModelContext::new(app, model_id);
1440                    callback(model, payload, &mut ctx);
1441                }),
1442            });
1443    }
1444
1445    pub fn emit(&mut self, payload: T::Event) {
1446        self.app.pending_effects.push_back(Effect::Event {
1447            entity_id: self.model_id,
1448            payload: Box::new(payload),
1449        });
1450    }
1451
1452    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1453    where
1454        S: Entity,
1455        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
1456    {
1457        self.app
1458            .observations
1459            .entry(handle.model_id)
1460            .or_default()
1461            .push(Observation::FromModel {
1462                model_id: self.model_id,
1463                callback: Box::new(move |model, observed_id, app, model_id| {
1464                    let model = model.downcast_mut().expect("downcast is type safe");
1465                    let observed = ModelHandle::new(observed_id, &app.ctx.ref_counts);
1466                    let mut ctx = ModelContext::new(app, model_id);
1467                    callback(model, observed, &mut ctx);
1468                }),
1469            });
1470    }
1471
1472    pub fn notify(&mut self) {
1473        self.app
1474            .pending_effects
1475            .push_back(Effect::ModelNotification {
1476                model_id: self.model_id,
1477            });
1478    }
1479
1480    fn handle(&self) -> ModelHandle<T> {
1481        ModelHandle::new(self.model_id, &self.app.ctx.ref_counts)
1482    }
1483
1484    pub fn spawn<S, F, U>(&mut self, future: S, callback: F) -> EntityTask<U>
1485    where
1486        S: 'static + Future,
1487        F: 'static + FnOnce(&mut T, S::Output, &mut ModelContext<T>) -> U,
1488        U: 'static,
1489    {
1490        let handle = self.handle();
1491        let task = self.app.spawn::<S, U>(future);
1492
1493        self.app.future_handlers.borrow_mut().insert(
1494            task.id,
1495            Box::new(move |output, ctx| {
1496                let output = *output.downcast().unwrap();
1497                handle.update(ctx, |model, ctx| Box::new(callback(model, output, ctx)))
1498            }),
1499        );
1500
1501        task
1502    }
1503
1504    pub fn spawn_stream<S, F, G, U>(
1505        &mut self,
1506        stream: S,
1507        mut item_callback: F,
1508        done_callback: G,
1509    ) -> EntityTask<U>
1510    where
1511        S: 'static + Stream + Unpin,
1512        F: 'static + FnMut(&mut T, S::Item, &mut ModelContext<T>),
1513        G: 'static + FnOnce(&mut T, &mut ModelContext<T>) -> U,
1514        U: 'static + Any,
1515    {
1516        let handle = self.handle();
1517        let task = self.app.spawn_stream(stream);
1518
1519        self.app.stream_handlers.borrow_mut().insert(
1520            task.id,
1521            StreamHandler {
1522                item_callback: {
1523                    let handle = handle.clone();
1524                    Box::new(move |output, app| {
1525                        let output = *output.downcast().unwrap();
1526                        handle.update(app, |model, ctx| {
1527                            item_callback(model, output, ctx);
1528                            ctx.halt_stream
1529                        })
1530                    })
1531                },
1532                done_callback: Box::new(move |app| {
1533                    handle.update(app, |model, ctx| Box::new(done_callback(model, ctx)))
1534                }),
1535            },
1536        );
1537
1538        task
1539    }
1540}
1541
1542impl<M> ModelAsRef for ModelContext<'_, M> {
1543    fn model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1544        self.app.model(handle)
1545    }
1546}
1547
1548impl<M> UpdateModel for ModelContext<'_, M> {
1549    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1550    where
1551        T: Entity,
1552        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1553    {
1554        self.app.update_model(handle, update)
1555    }
1556}
1557
1558pub struct ViewContext<'a, T: ?Sized> {
1559    app: &'a mut MutableAppContext,
1560    window_id: usize,
1561    view_id: usize,
1562    view_type: PhantomData<T>,
1563    halt_action_dispatch: bool,
1564    halt_stream: bool,
1565}
1566
1567impl<'a, T: View> ViewContext<'a, T> {
1568    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
1569        Self {
1570            app,
1571            window_id,
1572            view_id,
1573            view_type: PhantomData,
1574            halt_action_dispatch: true,
1575            halt_stream: false,
1576        }
1577    }
1578
1579    pub fn handle(&self) -> ViewHandle<T> {
1580        ViewHandle::new(self.window_id, self.view_id, &self.app.ctx.ref_counts)
1581    }
1582
1583    pub fn window_id(&self) -> usize {
1584        self.window_id
1585    }
1586
1587    pub fn app(&self) -> &AppContext {
1588        &self.app.ctx
1589    }
1590
1591    pub fn app_mut(&mut self) -> &mut MutableAppContext {
1592        self.app
1593    }
1594
1595    pub fn background_executor(&self) -> &Arc<executor::Background> {
1596        &self.app.ctx.background
1597    }
1598
1599    pub fn debug_elements(&self) -> crate::json::Value {
1600        self.app.debug_elements(self.window_id).unwrap()
1601    }
1602
1603    pub fn focus<S>(&mut self, handle: S)
1604    where
1605        S: Into<AnyViewHandle>,
1606    {
1607        let handle = handle.into();
1608        self.app.pending_effects.push_back(Effect::Focus {
1609            window_id: handle.window_id,
1610            view_id: handle.view_id,
1611        });
1612    }
1613
1614    pub fn focus_self(&mut self) {
1615        self.app.pending_effects.push_back(Effect::Focus {
1616            window_id: self.window_id,
1617            view_id: self.view_id,
1618        });
1619    }
1620
1621    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
1622    where
1623        S: Entity,
1624        F: FnOnce(&mut ModelContext<S>) -> S,
1625    {
1626        self.app.add_model(build_model)
1627    }
1628
1629    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
1630    where
1631        S: View,
1632        F: FnOnce(&mut ViewContext<S>) -> S,
1633    {
1634        self.app.add_view(self.window_id, build_view)
1635    }
1636
1637    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
1638    where
1639        S: View,
1640        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
1641    {
1642        self.app.add_option_view(self.window_id, build_view)
1643    }
1644
1645    pub fn subscribe_to_model<E, F>(&mut self, handle: &ModelHandle<E>, mut callback: F)
1646    where
1647        E: Entity,
1648        E::Event: 'static,
1649        F: 'static + FnMut(&mut T, ModelHandle<E>, &E::Event, &mut ViewContext<T>),
1650    {
1651        let emitter_handle = handle.downgrade();
1652        self.app
1653            .subscriptions
1654            .entry(handle.id())
1655            .or_default()
1656            .push(Subscription::FromView {
1657                window_id: self.window_id,
1658                view_id: self.view_id,
1659                callback: Box::new(move |view, payload, app, window_id, view_id| {
1660                    if let Some(emitter_handle) = emitter_handle.upgrade(app.downgrade()) {
1661                        let model = view.downcast_mut().expect("downcast is type safe");
1662                        let payload = payload.downcast_ref().expect("downcast is type safe");
1663                        let mut ctx = ViewContext::new(app, window_id, view_id);
1664                        callback(model, emitter_handle, payload, &mut ctx);
1665                    }
1666                }),
1667            });
1668    }
1669
1670    pub fn subscribe_to_view<V, F>(&mut self, handle: &ViewHandle<V>, mut callback: F)
1671    where
1672        V: View,
1673        V::Event: 'static,
1674        F: 'static + FnMut(&mut T, ViewHandle<V>, &V::Event, &mut ViewContext<T>),
1675    {
1676        let emitter_handle = handle.downgrade();
1677
1678        self.app
1679            .subscriptions
1680            .entry(handle.id())
1681            .or_default()
1682            .push(Subscription::FromView {
1683                window_id: self.window_id,
1684                view_id: self.view_id,
1685                callback: Box::new(move |view, payload, app, window_id, view_id| {
1686                    if let Some(emitter_handle) = emitter_handle.upgrade(app.downgrade()) {
1687                        let model = view.downcast_mut().expect("downcast is type safe");
1688                        let payload = payload.downcast_ref().expect("downcast is type safe");
1689                        let mut ctx = ViewContext::new(app, window_id, view_id);
1690                        callback(model, emitter_handle, payload, &mut ctx);
1691                    }
1692                }),
1693            });
1694    }
1695
1696    pub fn emit(&mut self, payload: T::Event) {
1697        self.app.pending_effects.push_back(Effect::Event {
1698            entity_id: self.view_id,
1699            payload: Box::new(payload),
1700        });
1701    }
1702
1703    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F)
1704    where
1705        S: Entity,
1706        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ViewContext<T>),
1707    {
1708        self.app
1709            .observations
1710            .entry(handle.id())
1711            .or_default()
1712            .push(Observation::FromView {
1713                window_id: self.window_id,
1714                view_id: self.view_id,
1715                callback: Box::new(move |view, observed_id, app, window_id, view_id| {
1716                    let view = view.downcast_mut().expect("downcast is type safe");
1717                    let observed = ModelHandle::new(observed_id, &app.ctx.ref_counts);
1718                    let mut ctx = ViewContext::new(app, window_id, view_id);
1719                    callback(view, observed, &mut ctx);
1720                }),
1721            });
1722    }
1723
1724    pub fn notify(&mut self) {
1725        self.app
1726            .pending_effects
1727            .push_back(Effect::ViewNotification {
1728                window_id: self.window_id,
1729                view_id: self.view_id,
1730            });
1731    }
1732
1733    pub fn propagate_action(&mut self) {
1734        self.halt_action_dispatch = false;
1735    }
1736
1737    pub fn halt_stream(&mut self) {
1738        self.halt_stream = true;
1739    }
1740
1741    pub fn spawn<S, F, U>(&mut self, future: S, callback: F) -> EntityTask<U>
1742    where
1743        S: 'static + Future,
1744        F: 'static + FnOnce(&mut T, S::Output, &mut ViewContext<T>) -> U,
1745        U: 'static,
1746    {
1747        let handle = self.handle();
1748        let task = self.app.spawn(future);
1749
1750        self.app.future_handlers.borrow_mut().insert(
1751            task.id,
1752            Box::new(move |output, app| {
1753                let output = *output.downcast().unwrap();
1754                handle.update(app, |view, ctx| Box::new(callback(view, output, ctx)))
1755            }),
1756        );
1757
1758        task
1759    }
1760
1761    pub fn spawn_stream<S, F, G, U>(
1762        &mut self,
1763        stream: S,
1764        mut item_callback: F,
1765        done_callback: G,
1766    ) -> EntityTask<U>
1767    where
1768        S: 'static + Stream + Unpin,
1769        F: 'static + FnMut(&mut T, S::Item, &mut ViewContext<T>),
1770        G: 'static + FnOnce(&mut T, &mut ViewContext<T>) -> U,
1771        U: 'static + Any,
1772    {
1773        let handle = self.handle();
1774        let task = self.app.spawn_stream(stream);
1775        self.app.stream_handlers.borrow_mut().insert(
1776            task.id,
1777            StreamHandler {
1778                item_callback: {
1779                    let handle = handle.clone();
1780                    Box::new(move |output, app| {
1781                        let output = *output.downcast().unwrap();
1782                        handle.update(app, |view, ctx| {
1783                            item_callback(view, output, ctx);
1784                            ctx.halt_stream
1785                        })
1786                    })
1787                },
1788                done_callback: Box::new(move |app| {
1789                    handle.update(app, |view, ctx| Box::new(done_callback(view, ctx)))
1790                }),
1791            },
1792        );
1793        task
1794    }
1795}
1796
1797impl<V> ModelAsRef for ViewContext<'_, V> {
1798    fn model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1799        self.app.model(handle)
1800    }
1801}
1802
1803impl<V: View> UpdateModel for ViewContext<'_, V> {
1804    fn update_model<T, F, S>(&mut self, handle: &ModelHandle<T>, update: F) -> S
1805    where
1806        T: Entity,
1807        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1808    {
1809        self.app.update_model(handle, update)
1810    }
1811}
1812
1813impl<V: View> ViewAsRef for ViewContext<'_, V> {
1814    fn view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1815        self.app.view(handle)
1816    }
1817}
1818
1819impl<V: View> UpdateView for ViewContext<'_, V> {
1820    fn update_view<T, F, S>(&mut self, handle: &ViewHandle<T>, update: F) -> S
1821    where
1822        T: View,
1823        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
1824    {
1825        self.app.update_view(handle, update)
1826    }
1827}
1828
1829pub trait Handle<T> {
1830    fn id(&self) -> usize;
1831    fn location(&self) -> EntityLocation;
1832}
1833
1834#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
1835pub enum EntityLocation {
1836    Model(usize),
1837    View(usize, usize),
1838}
1839
1840pub struct ModelHandle<T> {
1841    model_id: usize,
1842    model_type: PhantomData<T>,
1843    ref_counts: Weak<Mutex<RefCounts>>,
1844}
1845
1846impl<T: Entity> ModelHandle<T> {
1847    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
1848        ref_counts.lock().inc(model_id);
1849        Self {
1850            model_id,
1851            model_type: PhantomData,
1852            ref_counts: Arc::downgrade(ref_counts),
1853        }
1854    }
1855
1856    fn downgrade(&self) -> WeakModelHandle<T> {
1857        WeakModelHandle::new(self.model_id)
1858    }
1859
1860    pub fn id(&self) -> usize {
1861        self.model_id
1862    }
1863
1864    pub fn as_ref<'a, A: ModelAsRef>(&self, app: &'a A) -> &'a T {
1865        app.model(self)
1866    }
1867
1868    pub fn read<'a, S, F>(&self, app: &'a App, read: F) -> S
1869    where
1870        F: FnOnce(&T, &AppContext) -> S,
1871    {
1872        app.read_model(self, read)
1873    }
1874
1875    pub fn update<A, F, S>(&self, app: &mut A, update: F) -> S
1876    where
1877        A: UpdateModel,
1878        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
1879    {
1880        app.update_model(self, update)
1881    }
1882}
1883
1884impl<T> Clone for ModelHandle<T> {
1885    fn clone(&self) -> Self {
1886        if let Some(ref_counts) = self.ref_counts.upgrade() {
1887            ref_counts.lock().inc(self.model_id);
1888        }
1889
1890        Self {
1891            model_id: self.model_id,
1892            model_type: PhantomData,
1893            ref_counts: self.ref_counts.clone(),
1894        }
1895    }
1896}
1897
1898impl<T> PartialEq for ModelHandle<T> {
1899    fn eq(&self, other: &Self) -> bool {
1900        self.model_id == other.model_id
1901    }
1902}
1903
1904impl<T> Eq for ModelHandle<T> {}
1905
1906impl<T> Hash for ModelHandle<T> {
1907    fn hash<H: Hasher>(&self, state: &mut H) {
1908        self.model_id.hash(state);
1909    }
1910}
1911
1912impl<T> std::borrow::Borrow<usize> for ModelHandle<T> {
1913    fn borrow(&self) -> &usize {
1914        &self.model_id
1915    }
1916}
1917
1918impl<T> Debug for ModelHandle<T> {
1919    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1920        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
1921            .field(&self.model_id)
1922            .finish()
1923    }
1924}
1925
1926unsafe impl<T> Send for ModelHandle<T> {}
1927unsafe impl<T> Sync for ModelHandle<T> {}
1928
1929impl<T> Drop for ModelHandle<T> {
1930    fn drop(&mut self) {
1931        if let Some(ref_counts) = self.ref_counts.upgrade() {
1932            ref_counts.lock().dec_model(self.model_id);
1933        }
1934    }
1935}
1936
1937impl<T> Handle<T> for ModelHandle<T> {
1938    fn id(&self) -> usize {
1939        self.model_id
1940    }
1941
1942    fn location(&self) -> EntityLocation {
1943        EntityLocation::Model(self.model_id)
1944    }
1945}
1946
1947pub struct WeakModelHandle<T> {
1948    model_id: usize,
1949    model_type: PhantomData<T>,
1950}
1951
1952impl<T: Entity> WeakModelHandle<T> {
1953    fn new(model_id: usize) -> Self {
1954        Self {
1955            model_id,
1956            model_type: PhantomData,
1957        }
1958    }
1959
1960    pub fn upgrade(&self, app: &AppContext) -> Option<ModelHandle<T>> {
1961        if app.models.contains_key(&self.model_id) {
1962            Some(ModelHandle::new(self.model_id, &app.ref_counts))
1963        } else {
1964            None
1965        }
1966    }
1967}
1968
1969pub struct ViewHandle<T> {
1970    window_id: usize,
1971    view_id: usize,
1972    view_type: PhantomData<T>,
1973    ref_counts: Weak<Mutex<RefCounts>>,
1974}
1975
1976impl<T: View> ViewHandle<T> {
1977    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
1978        ref_counts.lock().inc(view_id);
1979        Self {
1980            window_id,
1981            view_id,
1982            view_type: PhantomData,
1983            ref_counts: Arc::downgrade(ref_counts),
1984        }
1985    }
1986
1987    pub fn downgrade(&self) -> WeakViewHandle<T> {
1988        WeakViewHandle::new(self.window_id, self.view_id)
1989    }
1990
1991    pub fn window_id(&self) -> usize {
1992        self.window_id
1993    }
1994
1995    pub fn id(&self) -> usize {
1996        self.view_id
1997    }
1998
1999    pub fn as_ref<'a, A: ViewAsRef>(&self, app: &'a A) -> &'a T {
2000        app.view(self)
2001    }
2002
2003    pub fn read<'a, F, S>(&self, app: &'a App, read: F) -> S
2004    where
2005        F: FnOnce(&T, &AppContext) -> S,
2006    {
2007        app.read_view(self, read)
2008    }
2009
2010    pub fn update<A, F, S>(&self, app: &mut A, update: F) -> S
2011    where
2012        A: UpdateView,
2013        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
2014    {
2015        app.update_view(self, update)
2016    }
2017
2018    pub fn is_focused(&self, app: &AppContext) -> bool {
2019        app.focused_view_id(self.window_id)
2020            .map_or(false, |focused_id| focused_id == self.view_id)
2021    }
2022}
2023
2024impl<T> Clone for ViewHandle<T> {
2025    fn clone(&self) -> Self {
2026        if let Some(ref_counts) = self.ref_counts.upgrade() {
2027            ref_counts.lock().inc(self.view_id);
2028        }
2029
2030        Self {
2031            window_id: self.window_id,
2032            view_id: self.view_id,
2033            view_type: PhantomData,
2034            ref_counts: self.ref_counts.clone(),
2035        }
2036    }
2037}
2038
2039impl<T> PartialEq for ViewHandle<T> {
2040    fn eq(&self, other: &Self) -> bool {
2041        self.window_id == other.window_id && self.view_id == other.view_id
2042    }
2043}
2044
2045impl<T> Eq for ViewHandle<T> {}
2046
2047impl<T> Debug for ViewHandle<T> {
2048    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2049        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
2050            .field("window_id", &self.window_id)
2051            .field("view_id", &self.view_id)
2052            .finish()
2053    }
2054}
2055
2056impl<T> Drop for ViewHandle<T> {
2057    fn drop(&mut self) {
2058        if let Some(ref_counts) = self.ref_counts.upgrade() {
2059            ref_counts.lock().dec_view(self.window_id, self.view_id);
2060        }
2061    }
2062}
2063
2064impl<T> Handle<T> for ViewHandle<T> {
2065    fn id(&self) -> usize {
2066        self.view_id
2067    }
2068
2069    fn location(&self) -> EntityLocation {
2070        EntityLocation::View(self.window_id, self.view_id)
2071    }
2072}
2073
2074#[derive(Clone)]
2075pub struct AnyViewHandle {
2076    window_id: usize,
2077    view_id: usize,
2078    view_type: TypeId,
2079    ref_counts: Weak<Mutex<RefCounts>>,
2080}
2081
2082impl AnyViewHandle {
2083    pub fn id(&self) -> usize {
2084        self.view_id
2085    }
2086
2087    pub fn is<T: 'static>(&self) -> bool {
2088        TypeId::of::<T>() == self.view_type
2089    }
2090
2091    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
2092        if self.is::<T>() {
2093            if let Some(ref_counts) = self.ref_counts.upgrade() {
2094                return Some(ViewHandle::new(self.window_id, self.view_id, &ref_counts));
2095            }
2096        }
2097        None
2098    }
2099}
2100
2101impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
2102    fn from(handle: &ViewHandle<T>) -> Self {
2103        if let Some(ref_counts) = handle.ref_counts.upgrade() {
2104            ref_counts.lock().inc(handle.view_id);
2105        }
2106        AnyViewHandle {
2107            window_id: handle.window_id,
2108            view_id: handle.view_id,
2109            view_type: TypeId::of::<T>(),
2110            ref_counts: handle.ref_counts.clone(),
2111        }
2112    }
2113}
2114
2115impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
2116    fn from(handle: ViewHandle<T>) -> Self {
2117        (&handle).into()
2118    }
2119}
2120
2121pub struct WeakViewHandle<T> {
2122    window_id: usize,
2123    view_id: usize,
2124    view_type: PhantomData<T>,
2125}
2126
2127impl<T: View> WeakViewHandle<T> {
2128    fn new(window_id: usize, view_id: usize) -> Self {
2129        Self {
2130            window_id,
2131            view_id,
2132            view_type: PhantomData,
2133        }
2134    }
2135
2136    pub fn upgrade(&self, app: &AppContext) -> Option<ViewHandle<T>> {
2137        if app
2138            .windows
2139            .get(&self.window_id)
2140            .and_then(|w| w.views.get(&self.view_id))
2141            .is_some()
2142        {
2143            Some(ViewHandle::new(
2144                self.window_id,
2145                self.view_id,
2146                &app.ref_counts,
2147            ))
2148        } else {
2149            None
2150        }
2151    }
2152}
2153
2154impl<T> Clone for WeakViewHandle<T> {
2155    fn clone(&self) -> Self {
2156        Self {
2157            window_id: self.window_id,
2158            view_id: self.view_id,
2159            view_type: PhantomData,
2160        }
2161    }
2162}
2163
2164#[derive(Default)]
2165struct RefCounts {
2166    counts: HashMap<usize, usize>,
2167    dropped_models: HashSet<usize>,
2168    dropped_views: HashSet<(usize, usize)>,
2169}
2170
2171impl RefCounts {
2172    fn inc(&mut self, model_id: usize) {
2173        *self.counts.entry(model_id).or_insert(0) += 1;
2174    }
2175
2176    fn dec_model(&mut self, model_id: usize) {
2177        if let Some(count) = self.counts.get_mut(&model_id) {
2178            *count -= 1;
2179            if *count == 0 {
2180                self.counts.remove(&model_id);
2181                self.dropped_models.insert(model_id);
2182            }
2183        } else {
2184            panic!("Expected ref count to be positive")
2185        }
2186    }
2187
2188    fn dec_view(&mut self, window_id: usize, view_id: usize) {
2189        if let Some(count) = self.counts.get_mut(&view_id) {
2190            *count -= 1;
2191            if *count == 0 {
2192                self.counts.remove(&view_id);
2193                self.dropped_views.insert((window_id, view_id));
2194            }
2195        } else {
2196            panic!("Expected ref count to be positive")
2197        }
2198    }
2199
2200    fn take_dropped(&mut self) -> (HashSet<usize>, HashSet<(usize, usize)>) {
2201        let mut dropped_models = HashSet::new();
2202        let mut dropped_views = HashSet::new();
2203        std::mem::swap(&mut self.dropped_models, &mut dropped_models);
2204        std::mem::swap(&mut self.dropped_views, &mut dropped_views);
2205        (dropped_models, dropped_views)
2206    }
2207}
2208
2209enum Subscription {
2210    FromModel {
2211        model_id: usize,
2212        callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize)>,
2213    },
2214    FromView {
2215        window_id: usize,
2216        view_id: usize,
2217        callback: Box<dyn FnMut(&mut dyn Any, &dyn Any, &mut MutableAppContext, usize, usize)>,
2218    },
2219}
2220
2221enum Observation {
2222    FromModel {
2223        model_id: usize,
2224        callback: Box<dyn FnMut(&mut dyn Any, usize, &mut MutableAppContext, usize)>,
2225    },
2226    FromView {
2227        window_id: usize,
2228        view_id: usize,
2229        callback: Box<dyn FnMut(&mut dyn Any, usize, &mut MutableAppContext, usize, usize)>,
2230    },
2231}
2232
2233type FutureHandler = Box<dyn FnOnce(Box<dyn Any>, &mut MutableAppContext) -> Box<dyn Any>>;
2234
2235struct StreamHandler {
2236    item_callback: Box<dyn FnMut(Box<dyn Any>, &mut MutableAppContext) -> bool>,
2237    done_callback: Box<dyn FnOnce(&mut MutableAppContext) -> Box<dyn Any>>,
2238}
2239
2240#[must_use]
2241pub struct EntityTask<T> {
2242    id: usize,
2243    task: Option<executor::Task<T>>,
2244    handler_map: TaskHandlerMap,
2245    task_done: Arc<Condvar>,
2246}
2247
2248enum TaskHandlerMap {
2249    Detached,
2250    Future(Rc<RefCell<HashMap<usize, FutureHandler>>>),
2251    Stream(Rc<RefCell<HashMap<usize, StreamHandler>>>),
2252}
2253
2254impl<T> EntityTask<T> {
2255    fn new(
2256        id: usize,
2257        task: executor::Task<T>,
2258        handler_map: TaskHandlerMap,
2259        task_done: Arc<Condvar>,
2260    ) -> Self {
2261        Self {
2262            id,
2263            task: Some(task),
2264            handler_map,
2265            task_done,
2266        }
2267    }
2268
2269    pub fn detach(mut self) {
2270        self.handler_map = TaskHandlerMap::Detached;
2271        self.task.take().unwrap().detach();
2272    }
2273
2274    pub async fn cancel(mut self) -> Option<T> {
2275        let task = self.task.take().unwrap();
2276        task.cancel().await
2277    }
2278}
2279
2280impl<T> Future for EntityTask<T> {
2281    type Output = T;
2282
2283    fn poll(
2284        self: std::pin::Pin<&mut Self>,
2285        ctx: &mut std::task::Context<'_>,
2286    ) -> std::task::Poll<Self::Output> {
2287        let task = unsafe { self.map_unchecked_mut(|task| task.task.as_mut().unwrap()) };
2288        task.poll(ctx)
2289    }
2290}
2291
2292impl<T> Drop for EntityTask<T> {
2293    fn drop(self: &mut Self) {
2294        match &self.handler_map {
2295            TaskHandlerMap::Detached => {
2296                return;
2297            }
2298            TaskHandlerMap::Future(map) => {
2299                map.borrow_mut().remove(&self.id);
2300            }
2301            TaskHandlerMap::Stream(map) => {
2302                map.borrow_mut().remove(&self.id);
2303            }
2304        }
2305        self.task_done.notify_all();
2306    }
2307}
2308
2309#[cfg(test)]
2310mod tests {
2311    use super::*;
2312    use crate::elements::*;
2313
2314    #[test]
2315    fn test_model_handles() {
2316        struct Model {
2317            other: Option<ModelHandle<Model>>,
2318            events: Vec<String>,
2319        }
2320
2321        impl Entity for Model {
2322            type Event = usize;
2323        }
2324
2325        impl Model {
2326            fn new(other: Option<ModelHandle<Self>>, ctx: &mut ModelContext<Self>) -> Self {
2327                if let Some(other) = other.as_ref() {
2328                    ctx.observe(other, |me, _, _| {
2329                        me.events.push("notified".into());
2330                    });
2331                    ctx.subscribe(other, |me, event, _| {
2332                        me.events.push(format!("observed event {}", event));
2333                    });
2334                }
2335
2336                Self {
2337                    other,
2338                    events: Vec::new(),
2339                }
2340            }
2341        }
2342
2343        App::test((), |mut app| async move {
2344            let app = &mut app;
2345
2346            let handle_1 = app.add_model(|ctx| Model::new(None, ctx));
2347            let handle_2 = app.add_model(|ctx| Model::new(Some(handle_1.clone()), ctx));
2348            assert_eq!(app.0.borrow().ctx.models.len(), 2);
2349
2350            handle_1.update(app, |model, ctx| {
2351                model.events.push("updated".into());
2352                ctx.emit(1);
2353                ctx.notify();
2354                ctx.emit(2);
2355            });
2356            handle_1.read(app, |model, _| {
2357                assert_eq!(model.events, vec!["updated".to_string()]);
2358            });
2359            handle_2.read(app, |model, _| {
2360                assert_eq!(
2361                    model.events,
2362                    vec![
2363                        "observed event 1".to_string(),
2364                        "notified".to_string(),
2365                        "observed event 2".to_string(),
2366                    ]
2367                );
2368            });
2369
2370            handle_2.update(app, |model, _| {
2371                drop(handle_1);
2372                model.other.take();
2373            });
2374
2375            let app_state = app.0.borrow();
2376            assert_eq!(app_state.ctx.models.len(), 1);
2377            assert!(app_state.subscriptions.is_empty());
2378            assert!(app_state.observations.is_empty());
2379        })
2380    }
2381
2382    #[test]
2383    fn test_subscribe_and_emit_from_model() {
2384        #[derive(Default)]
2385        struct Model {
2386            events: Vec<usize>,
2387        }
2388
2389        impl Entity for Model {
2390            type Event = usize;
2391        }
2392
2393        App::test((), |mut app| async move {
2394            let app = &mut app;
2395            let handle_1 = app.add_model(|_| Model::default());
2396            let handle_2 = app.add_model(|_| Model::default());
2397            let handle_2b = handle_2.clone();
2398
2399            handle_1.update(app, |_, c| {
2400                c.subscribe(&handle_2, move |model: &mut Model, event, c| {
2401                    model.events.push(*event);
2402
2403                    c.subscribe(&handle_2b, |model, event, _| {
2404                        model.events.push(*event * 2);
2405                    });
2406                });
2407            });
2408
2409            handle_2.update(app, |_, c| c.emit(7));
2410            handle_1.read(app, |model, _| assert_eq!(model.events, vec![7]));
2411
2412            handle_2.update(app, |_, c| c.emit(5));
2413            handle_1.read(app, |model, _| assert_eq!(model.events, vec![7, 10, 5]));
2414        })
2415    }
2416
2417    #[test]
2418    fn test_observe_and_notify_from_model() {
2419        #[derive(Default)]
2420        struct Model {
2421            count: usize,
2422            events: Vec<usize>,
2423        }
2424
2425        impl Entity for Model {
2426            type Event = ();
2427        }
2428
2429        App::test((), |mut app| async move {
2430            let app = &mut app;
2431            let handle_1 = app.add_model(|_| Model::default());
2432            let handle_2 = app.add_model(|_| Model::default());
2433            let handle_2b = handle_2.clone();
2434
2435            handle_1.update(app, |_, c| {
2436                c.observe(&handle_2, move |model, observed, c| {
2437                    model.events.push(observed.as_ref(c).count);
2438                    c.observe(&handle_2b, |model, observed, c| {
2439                        model.events.push(observed.as_ref(c).count * 2);
2440                    });
2441                });
2442            });
2443
2444            handle_2.update(app, |model, c| {
2445                model.count = 7;
2446                c.notify()
2447            });
2448            handle_1.read(app, |model, _| assert_eq!(model.events, vec![7]));
2449
2450            handle_2.update(app, |model, c| {
2451                model.count = 5;
2452                c.notify()
2453            });
2454            handle_1.read(app, |model, _| assert_eq!(model.events, vec![7, 10, 5]))
2455        })
2456    }
2457
2458    #[test]
2459    fn test_spawn_from_model() {
2460        #[derive(Default)]
2461        struct Model {
2462            count: usize,
2463        }
2464
2465        impl Entity for Model {
2466            type Event = ();
2467        }
2468
2469        App::test((), |mut app| async move {
2470            let handle = app.add_model(|_| Model::default());
2471            handle
2472                .update(&mut app, |_, c| {
2473                    c.spawn(async { 7 }, |model, output, _| {
2474                        model.count = output;
2475                    })
2476                })
2477                .await;
2478            handle.read(&app, |model, _| assert_eq!(model.count, 7));
2479
2480            handle
2481                .update(&mut app, |_, c| {
2482                    c.spawn(async { 14 }, |model, output, _| {
2483                        model.count = output;
2484                    })
2485                })
2486                .await;
2487            handle.read(&app, |model, _| assert_eq!(model.count, 14));
2488        });
2489    }
2490
2491    #[test]
2492    fn test_spawn_stream_local_from_model() {
2493        #[derive(Default)]
2494        struct Model {
2495            events: Vec<Option<usize>>,
2496        }
2497
2498        impl Entity for Model {
2499            type Event = ();
2500        }
2501
2502        App::test((), |mut app| async move {
2503            let handle = app.add_model(|_| Model::default());
2504            handle
2505                .update(&mut app, |_, c| {
2506                    c.spawn_stream(
2507                        smol::stream::iter(vec![1, 2, 3]),
2508                        |model, output, _| {
2509                            model.events.push(Some(output));
2510                        },
2511                        |model, _| {
2512                            model.events.push(None);
2513                        },
2514                    )
2515                })
2516                .await;
2517
2518            handle.read(&app, |model, _| {
2519                assert_eq!(model.events, [Some(1), Some(2), Some(3), None])
2520            });
2521        })
2522    }
2523
2524    #[test]
2525    fn test_view_handles() {
2526        struct View {
2527            other: Option<ViewHandle<View>>,
2528            events: Vec<String>,
2529        }
2530
2531        impl Entity for View {
2532            type Event = usize;
2533        }
2534
2535        impl super::View for View {
2536            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2537                Empty::new().boxed()
2538            }
2539
2540            fn ui_name() -> &'static str {
2541                "View"
2542            }
2543        }
2544
2545        impl View {
2546            fn new(other: Option<ViewHandle<View>>, ctx: &mut ViewContext<Self>) -> Self {
2547                if let Some(other) = other.as_ref() {
2548                    ctx.subscribe_to_view(other, |me, _, event, _| {
2549                        me.events.push(format!("observed event {}", event));
2550                    });
2551                }
2552                Self {
2553                    other,
2554                    events: Vec::new(),
2555                }
2556            }
2557        }
2558
2559        App::test((), |mut app| async move {
2560            let app = &mut app;
2561            let (window_id, _) = app.add_window(|ctx| View::new(None, ctx));
2562            let handle_1 = app.add_view(window_id, |ctx| View::new(None, ctx));
2563            let handle_2 = app.add_view(window_id, |ctx| View::new(Some(handle_1.clone()), ctx));
2564            assert_eq!(app.0.borrow().ctx.windows[&window_id].views.len(), 3);
2565
2566            handle_1.update(app, |view, ctx| {
2567                view.events.push("updated".into());
2568                ctx.emit(1);
2569                ctx.emit(2);
2570            });
2571            handle_1.read(app, |view, _| {
2572                assert_eq!(view.events, vec!["updated".to_string()]);
2573            });
2574            handle_2.read(app, |view, _| {
2575                assert_eq!(
2576                    view.events,
2577                    vec![
2578                        "observed event 1".to_string(),
2579                        "observed event 2".to_string(),
2580                    ]
2581                );
2582            });
2583
2584            handle_2.update(app, |view, _| {
2585                drop(handle_1);
2586                view.other.take();
2587            });
2588
2589            let app_state = app.0.borrow();
2590            assert_eq!(app_state.ctx.windows[&window_id].views.len(), 2);
2591            assert!(app_state.subscriptions.is_empty());
2592            assert!(app_state.observations.is_empty());
2593        })
2594    }
2595
2596    #[test]
2597    fn test_subscribe_and_emit_from_view() {
2598        #[derive(Default)]
2599        struct View {
2600            events: Vec<usize>,
2601        }
2602
2603        impl Entity for View {
2604            type Event = usize;
2605        }
2606
2607        impl super::View for View {
2608            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2609                Empty::new().boxed()
2610            }
2611
2612            fn ui_name() -> &'static str {
2613                "View"
2614            }
2615        }
2616
2617        struct Model;
2618
2619        impl Entity for Model {
2620            type Event = usize;
2621        }
2622
2623        App::test((), |mut app| async move {
2624            let app = &mut app;
2625            let (window_id, handle_1) = app.add_window(|_| View::default());
2626            let handle_2 = app.add_view(window_id, |_| View::default());
2627            let handle_2b = handle_2.clone();
2628            let handle_3 = app.add_model(|_| Model);
2629
2630            handle_1.update(app, |_, c| {
2631                c.subscribe_to_view(&handle_2, move |me, _, event, c| {
2632                    me.events.push(*event);
2633
2634                    c.subscribe_to_view(&handle_2b, |me, _, event, _| {
2635                        me.events.push(*event * 2);
2636                    });
2637                });
2638
2639                c.subscribe_to_model(&handle_3, |me, _, event, _| {
2640                    me.events.push(*event);
2641                })
2642            });
2643
2644            handle_2.update(app, |_, c| c.emit(7));
2645            handle_1.read(app, |view, _| assert_eq!(view.events, vec![7]));
2646
2647            handle_2.update(app, |_, c| c.emit(5));
2648            handle_1.read(app, |view, _| assert_eq!(view.events, vec![7, 10, 5]));
2649
2650            handle_3.update(app, |_, c| c.emit(9));
2651            handle_1.read(app, |view, _| assert_eq!(view.events, vec![7, 10, 5, 9]));
2652        })
2653    }
2654
2655    #[test]
2656    fn test_dropping_subscribers() {
2657        struct View;
2658
2659        impl Entity for View {
2660            type Event = ();
2661        }
2662
2663        impl super::View for View {
2664            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2665                Empty::new().boxed()
2666            }
2667
2668            fn ui_name() -> &'static str {
2669                "View"
2670            }
2671        }
2672
2673        struct Model;
2674
2675        impl Entity for Model {
2676            type Event = ();
2677        }
2678
2679        App::test((), |mut app| async move {
2680            let app = &mut app;
2681
2682            let (window_id, _) = app.add_window(|_| View);
2683            let observing_view = app.add_view(window_id, |_| View);
2684            let emitting_view = app.add_view(window_id, |_| View);
2685            let observing_model = app.add_model(|_| Model);
2686            let observed_model = app.add_model(|_| Model);
2687
2688            observing_view.update(app, |_, ctx| {
2689                ctx.subscribe_to_view(&emitting_view, |_, _, _, _| {});
2690                ctx.subscribe_to_model(&observed_model, |_, _, _, _| {});
2691            });
2692            observing_model.update(app, |_, ctx| {
2693                ctx.subscribe(&observed_model, |_, _, _| {});
2694            });
2695
2696            app.update(|_| {
2697                drop(observing_view);
2698                drop(observing_model);
2699            });
2700
2701            emitting_view.update(app, |_, ctx| ctx.emit(()));
2702            observed_model.update(app, |_, ctx| ctx.emit(()));
2703        })
2704    }
2705
2706    #[test]
2707    fn test_observe_and_notify_from_view() {
2708        #[derive(Default)]
2709        struct View {
2710            events: Vec<usize>,
2711        }
2712
2713        impl Entity for View {
2714            type Event = usize;
2715        }
2716
2717        impl super::View for View {
2718            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2719                Empty::new().boxed()
2720            }
2721
2722            fn ui_name() -> &'static str {
2723                "View"
2724            }
2725        }
2726
2727        #[derive(Default)]
2728        struct Model {
2729            count: usize,
2730        }
2731
2732        impl Entity for Model {
2733            type Event = ();
2734        }
2735
2736        App::test((), |mut app| async move {
2737            let app = &mut app;
2738            let (_, view) = app.add_window(|_| View::default());
2739            let model = app.add_model(|_| Model::default());
2740
2741            view.update(app, |_, c| {
2742                c.observe(&model, |me, observed, c| {
2743                    me.events.push(observed.as_ref(c).count)
2744                });
2745            });
2746
2747            model.update(app, |model, c| {
2748                model.count = 11;
2749                c.notify();
2750            });
2751            view.read(app, |view, _| assert_eq!(view.events, vec![11]));
2752        })
2753    }
2754
2755    #[test]
2756    fn test_dropping_observers() {
2757        struct View;
2758
2759        impl Entity for View {
2760            type Event = ();
2761        }
2762
2763        impl super::View for View {
2764            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2765                Empty::new().boxed()
2766            }
2767
2768            fn ui_name() -> &'static str {
2769                "View"
2770            }
2771        }
2772
2773        struct Model;
2774
2775        impl Entity for Model {
2776            type Event = ();
2777        }
2778
2779        App::test((), |mut app| async move {
2780            let app = &mut app;
2781
2782            let (window_id, _) = app.add_window(|_| View);
2783            let observing_view = app.add_view(window_id, |_| View);
2784            let observing_model = app.add_model(|_| Model);
2785            let observed_model = app.add_model(|_| Model);
2786
2787            observing_view.update(app, |_, ctx| {
2788                ctx.observe(&observed_model, |_, _, _| {});
2789            });
2790            observing_model.update(app, |_, ctx| {
2791                ctx.observe(&observed_model, |_, _, _| {});
2792            });
2793
2794            app.update(|_| {
2795                drop(observing_view);
2796                drop(observing_model);
2797            });
2798
2799            observed_model.update(app, |_, ctx| ctx.notify());
2800        })
2801    }
2802
2803    #[test]
2804    fn test_focus() {
2805        #[derive(Default)]
2806        struct View {
2807            events: Vec<String>,
2808        }
2809
2810        impl Entity for View {
2811            type Event = String;
2812        }
2813
2814        impl super::View for View {
2815            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2816                Empty::new().boxed()
2817            }
2818
2819            fn ui_name() -> &'static str {
2820                "View"
2821            }
2822
2823            fn on_focus(&mut self, ctx: &mut ViewContext<Self>) {
2824                self.events.push("self focused".into());
2825                ctx.emit("focused".into());
2826            }
2827
2828            fn on_blur(&mut self, ctx: &mut ViewContext<Self>) {
2829                self.events.push("self blurred".into());
2830                ctx.emit("blurred".into());
2831            }
2832        }
2833
2834        App::test((), |mut app| async move {
2835            let app = &mut app;
2836            let (window_id, view_1) = app.add_window(|_| View::default());
2837            let view_2 = app.add_view(window_id, |_| View::default());
2838
2839            view_1.update(app, |_, ctx| {
2840                ctx.subscribe_to_view(&view_2, |view_1, _, event, _| {
2841                    view_1.events.push(format!("view 2 {}", event));
2842                });
2843                ctx.focus(&view_2);
2844            });
2845
2846            view_1.update(app, |_, ctx| {
2847                ctx.focus(&view_1);
2848            });
2849
2850            view_1.read(app, |view_1, _| {
2851                assert_eq!(
2852                    view_1.events,
2853                    [
2854                        "self focused".to_string(),
2855                        "self blurred".to_string(),
2856                        "view 2 focused".to_string(),
2857                        "self focused".to_string(),
2858                        "view 2 blurred".to_string(),
2859                    ],
2860                );
2861            });
2862        })
2863    }
2864
2865    #[test]
2866    fn test_spawn_from_view() {
2867        #[derive(Default)]
2868        struct View {
2869            count: usize,
2870        }
2871
2872        impl Entity for View {
2873            type Event = ();
2874        }
2875
2876        impl super::View for View {
2877            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2878                Empty::new().boxed()
2879            }
2880
2881            fn ui_name() -> &'static str {
2882                "View"
2883            }
2884        }
2885
2886        App::test((), |mut app| async move {
2887            let (_, handle) = app.add_window(|_| View::default());
2888            handle
2889                .update(&mut app, |_, c| {
2890                    c.spawn(async { 7 }, |me, output, _| {
2891                        me.count = output;
2892                    })
2893                })
2894                .await;
2895            handle.read(&app, |view, _| assert_eq!(view.count, 7));
2896            handle
2897                .update(&mut app, |_, c| {
2898                    c.spawn(async { 14 }, |me, output, _| {
2899                        me.count = output;
2900                    })
2901                })
2902                .await;
2903            handle.read(&app, |view, _| assert_eq!(view.count, 14));
2904        });
2905    }
2906
2907    #[test]
2908    fn test_spawn_stream_local_from_view() {
2909        #[derive(Default)]
2910        struct View {
2911            events: Vec<Option<usize>>,
2912        }
2913
2914        impl Entity for View {
2915            type Event = ();
2916        }
2917
2918        impl super::View for View {
2919            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2920                Empty::new().boxed()
2921            }
2922
2923            fn ui_name() -> &'static str {
2924                "View"
2925            }
2926        }
2927
2928        App::test((), |mut app| async move {
2929            let (_, handle) = app.add_window(|_| View::default());
2930            handle
2931                .update(&mut app, |_, c| {
2932                    c.spawn_stream(
2933                        smol::stream::iter(vec![1_usize, 2, 3]),
2934                        |me, output, _| {
2935                            me.events.push(Some(output));
2936                        },
2937                        |me, _| {
2938                            me.events.push(None);
2939                        },
2940                    )
2941                })
2942                .await;
2943
2944            handle.read(&app, |view, _| {
2945                assert_eq!(view.events, [Some(1), Some(2), Some(3), None])
2946            });
2947        });
2948    }
2949
2950    #[test]
2951    fn test_dispatch_action() {
2952        struct ViewA {
2953            id: usize,
2954        }
2955
2956        impl Entity for ViewA {
2957            type Event = ();
2958        }
2959
2960        impl View for ViewA {
2961            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2962                Empty::new().boxed()
2963            }
2964
2965            fn ui_name() -> &'static str {
2966                "View"
2967            }
2968        }
2969
2970        struct ViewB {
2971            id: usize,
2972        }
2973
2974        impl Entity for ViewB {
2975            type Event = ();
2976        }
2977
2978        impl View for ViewB {
2979            fn render<'a>(&self, _: &AppContext) -> ElementBox {
2980                Empty::new().boxed()
2981            }
2982
2983            fn ui_name() -> &'static str {
2984                "View"
2985            }
2986        }
2987
2988        struct ActionArg {
2989            foo: String,
2990        }
2991
2992        App::test((), |mut app| async move {
2993            let actions = Rc::new(RefCell::new(Vec::new()));
2994
2995            let actions_clone = actions.clone();
2996            app.add_global_action("action", move |_: &ActionArg, _: &mut MutableAppContext| {
2997                actions_clone.borrow_mut().push("global a".to_string());
2998            });
2999
3000            let actions_clone = actions.clone();
3001            app.add_global_action("action", move |_: &ActionArg, _: &mut MutableAppContext| {
3002                actions_clone.borrow_mut().push("global b".to_string());
3003            });
3004
3005            let actions_clone = actions.clone();
3006            app.add_action("action", move |view: &mut ViewA, arg: &ActionArg, ctx| {
3007                assert_eq!(arg.foo, "bar");
3008                ctx.propagate_action();
3009                actions_clone.borrow_mut().push(format!("{} a", view.id));
3010            });
3011
3012            let actions_clone = actions.clone();
3013            app.add_action("action", move |view: &mut ViewA, _: &ActionArg, ctx| {
3014                if view.id != 1 {
3015                    ctx.propagate_action();
3016                }
3017                actions_clone.borrow_mut().push(format!("{} b", view.id));
3018            });
3019
3020            let actions_clone = actions.clone();
3021            app.add_action("action", move |view: &mut ViewB, _: &ActionArg, ctx| {
3022                ctx.propagate_action();
3023                actions_clone.borrow_mut().push(format!("{} c", view.id));
3024            });
3025
3026            let actions_clone = actions.clone();
3027            app.add_action("action", move |view: &mut ViewB, _: &ActionArg, ctx| {
3028                ctx.propagate_action();
3029                actions_clone.borrow_mut().push(format!("{} d", view.id));
3030            });
3031
3032            let (window_id, view_1) = app.add_window(|_| ViewA { id: 1 });
3033            let view_2 = app.add_view(window_id, |_| ViewB { id: 2 });
3034            let view_3 = app.add_view(window_id, |_| ViewA { id: 3 });
3035            let view_4 = app.add_view(window_id, |_| ViewB { id: 4 });
3036
3037            app.dispatch_action(
3038                window_id,
3039                vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
3040                "action",
3041                ActionArg { foo: "bar".into() },
3042            );
3043
3044            assert_eq!(
3045                *actions.borrow(),
3046                vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "1 b"]
3047            );
3048
3049            // Remove view_1, which doesn't propagate the action
3050            actions.borrow_mut().clear();
3051            app.dispatch_action(
3052                window_id,
3053                vec![view_2.id(), view_3.id(), view_4.id()],
3054                "action",
3055                ActionArg { foo: "bar".into() },
3056            );
3057
3058            assert_eq!(
3059                *actions.borrow(),
3060                vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "global b", "global a"]
3061            );
3062        })
3063    }
3064
3065    #[test]
3066    fn test_dispatch_keystroke() -> Result<()> {
3067        use std::cell::Cell;
3068
3069        #[derive(Clone)]
3070        struct ActionArg {
3071            key: String,
3072        }
3073
3074        struct View {
3075            id: usize,
3076            keymap_context: keymap::Context,
3077        }
3078
3079        impl Entity for View {
3080            type Event = ();
3081        }
3082
3083        impl super::View for View {
3084            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3085                Empty::new().boxed()
3086            }
3087
3088            fn ui_name() -> &'static str {
3089                "View"
3090            }
3091
3092            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
3093                self.keymap_context.clone()
3094            }
3095        }
3096
3097        impl View {
3098            fn new(id: usize) -> Self {
3099                View {
3100                    id,
3101                    keymap_context: keymap::Context::default(),
3102                }
3103            }
3104        }
3105
3106        App::test((), |mut app| async move {
3107            let mut view_1 = View::new(1);
3108            let mut view_2 = View::new(2);
3109            let mut view_3 = View::new(3);
3110            view_1.keymap_context.set.insert("a".into());
3111            view_2.keymap_context.set.insert("b".into());
3112            view_3.keymap_context.set.insert("c".into());
3113
3114            let (window_id, view_1) = app.add_window(|_| view_1);
3115            let view_2 = app.add_view(window_id, |_| view_2);
3116            let view_3 = app.add_view(window_id, |_| view_3);
3117
3118            // This keymap's only binding dispatches an action on view 2 because that view will have
3119            // "a" and "b" in its context, but not "c".
3120            let binding = keymap::Binding::new("a", "action", Some("a && b && !c"))
3121                .with_arg(ActionArg { key: "a".into() });
3122            app.add_bindings(vec![binding]);
3123
3124            let handled_action = Rc::new(Cell::new(false));
3125            let handled_action_clone = handled_action.clone();
3126            app.add_action("action", move |view: &mut View, arg: &ActionArg, _ctx| {
3127                handled_action_clone.set(true);
3128                assert_eq!(view.id, 2);
3129                assert_eq!(arg.key, "a");
3130            });
3131
3132            app.dispatch_keystroke(
3133                window_id,
3134                vec![view_1.id(), view_2.id(), view_3.id()],
3135                &Keystroke::parse("a")?,
3136            )?;
3137
3138            assert!(handled_action.get());
3139            Ok(())
3140        })
3141    }
3142
3143    // #[test]
3144    // fn test_ui_and_window_updates() {
3145    //     struct View {
3146    //         count: usize,
3147    //     }
3148
3149    //     impl Entity for View {
3150    //         type Event = ();
3151    //     }
3152
3153    //     impl super::View for View {
3154    //         fn render<'a>(&self, _: &AppContext) -> ElementBox {
3155    //             Empty::new().boxed()
3156    //         }
3157
3158    //         fn ui_name() -> &'static str {
3159    //             "View"
3160    //         }
3161    //     }
3162
3163    //     App::test(|mut app| async move {
3164    //         let (window_id, _) = app.add_window(|_| View { count: 3 });
3165    //         let view_1 = app.add_view(window_id, |_| View { count: 1 });
3166    //         let view_2 = app.add_view(window_id, |_| View { count: 2 });
3167
3168    //         // Ensure that registering for UI updates after mutating the app still gives us all the
3169    //         // updates.
3170    //         let ui_updates = Rc::new(RefCell::new(Vec::new()));
3171    //         let ui_updates_ = ui_updates.clone();
3172    //         app.on_ui_update(move |update, _| ui_updates_.borrow_mut().push(update));
3173
3174    //         assert_eq!(
3175    //             ui_updates.borrow_mut().drain(..).collect::<Vec<_>>(),
3176    //             vec![UiUpdate::OpenWindow {
3177    //                 window_id,
3178    //                 width: 1024.0,
3179    //                 height: 768.0,
3180    //             }]
3181    //         );
3182
3183    //         let window_invalidations = Rc::new(RefCell::new(Vec::new()));
3184    //         let window_invalidations_ = window_invalidations.clone();
3185    //         app.on_window_invalidated(window_id, move |update, _| {
3186    //             window_invalidations_.borrow_mut().push(update)
3187    //         });
3188
3189    //         let view_2_id = view_2.id();
3190    //         view_1.update(&mut app, |view, ctx| {
3191    //             view.count = 7;
3192    //             ctx.notify();
3193    //             drop(view_2);
3194    //         });
3195
3196    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3197    //         assert_eq!(invalidation.updated.len(), 1);
3198    //         assert!(invalidation.updated.contains(&view_1.id()));
3199    //         assert_eq!(invalidation.removed, vec![view_2_id]);
3200
3201    //         let view_3 = view_1.update(&mut app, |_, ctx| ctx.add_view(|_| View { count: 8 }));
3202
3203    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3204    //         assert_eq!(invalidation.updated.len(), 1);
3205    //         assert!(invalidation.updated.contains(&view_3.id()));
3206    //         assert!(invalidation.removed.is_empty());
3207
3208    //         view_3
3209    //             .update(&mut app, |_, ctx| {
3210    //                 ctx.spawn_local(async { 9 }, |me, output, ctx| {
3211    //                     me.count = output;
3212    //                     ctx.notify();
3213    //                 })
3214    //             })
3215    //             .await;
3216
3217    //         let invalidation = window_invalidations.borrow_mut().drain(..).next().unwrap();
3218    //         assert_eq!(invalidation.updated.len(), 1);
3219    //         assert!(invalidation.updated.contains(&view_3.id()));
3220    //         assert!(invalidation.removed.is_empty());
3221    //     });
3222    // }
3223
3224    #[test]
3225    fn test_finish_pending_tasks() {
3226        struct View;
3227
3228        impl Entity for View {
3229            type Event = ();
3230        }
3231
3232        impl super::View for View {
3233            fn render<'a>(&self, _: &AppContext) -> ElementBox {
3234                Empty::new().boxed()
3235            }
3236
3237            fn ui_name() -> &'static str {
3238                "View"
3239            }
3240        }
3241
3242        struct Model;
3243
3244        impl Entity for Model {
3245            type Event = ();
3246        }
3247
3248        App::test((), |mut app| async move {
3249            let model = app.add_model(|_| Model);
3250            let (_, view) = app.add_window(|_| View);
3251
3252            model.update(&mut app, |_, ctx| {
3253                ctx.spawn(async {}, |_, _, _| {}).detach();
3254                // Cancel this task
3255                drop(ctx.spawn(async {}, |_, _, _| {}));
3256            });
3257
3258            view.update(&mut app, |_, ctx| {
3259                ctx.spawn(async {}, |_, _, _| {}).detach();
3260                // Cancel this task
3261                drop(ctx.spawn(async {}, |_, _, _| {}));
3262            });
3263
3264            assert!(!app.0.borrow().future_handlers.borrow().is_empty());
3265            app.finish_pending_tasks().await;
3266            assert!(app.0.borrow().future_handlers.borrow().is_empty());
3267            app.finish_pending_tasks().await; // Don't block if there are no tasks
3268
3269            model.update(&mut app, |_, ctx| {
3270                ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {})
3271                    .detach();
3272                // Cancel this task
3273                drop(ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {}));
3274            });
3275
3276            view.update(&mut app, |_, ctx| {
3277                ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {})
3278                    .detach();
3279                // Cancel this task
3280                drop(ctx.spawn_stream(smol::stream::iter(vec![1, 2, 3]), |_, _, _| {}, |_, _| {}));
3281            });
3282
3283            assert!(!app.0.borrow().stream_handlers.borrow().is_empty());
3284            app.finish_pending_tasks().await;
3285            assert!(app.0.borrow().stream_handlers.borrow().is_empty());
3286            app.finish_pending_tasks().await; // Don't block if there are no tasks
3287
3288            // Tasks are considered finished when we drop handles
3289            let mut tasks = Vec::new();
3290            model.update(&mut app, |_, ctx| {
3291                tasks.push(Box::new(ctx.spawn(async {}, |_, _, _| {})));
3292                tasks.push(Box::new(ctx.spawn_stream(
3293                    smol::stream::iter(vec![1, 2, 3]),
3294                    |_, _, _| {},
3295                    |_, _| {},
3296                )));
3297            });
3298
3299            view.update(&mut app, |_, ctx| {
3300                tasks.push(Box::new(ctx.spawn(async {}, |_, _, _| {})));
3301                tasks.push(Box::new(ctx.spawn_stream(
3302                    smol::stream::iter(vec![1, 2, 3]),
3303                    |_, _, _| {},
3304                    |_, _| {},
3305                )));
3306            });
3307
3308            assert!(!app.0.borrow().stream_handlers.borrow().is_empty());
3309
3310            let finish_pending_tasks = app.finish_pending_tasks();
3311            drop(tasks);
3312            finish_pending_tasks.await;
3313            assert!(app.0.borrow().stream_handlers.borrow().is_empty());
3314            app.finish_pending_tasks().await; // Don't block if there are no tasks
3315        });
3316    }
3317}