app.rs

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