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