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