app.rs

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