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