app.rs

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