app.rs

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