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