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