app.rs

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