app.rs

   1use crate::{
   2    elements::ElementBox,
   3    executor::{self, Task},
   4    keymap::{self, Keystroke},
   5    platform::{self, CursorStyle, Platform, PromptLevel, WindowOptions},
   6    presenter::Presenter,
   7    util::{post_inc, timeout},
   8    AssetCache, AssetSource, ClipboardItem, FontCache, PathPromptOptions, TextLayoutCache,
   9};
  10use anyhow::{anyhow, Result};
  11use keymap::MatchResult;
  12use parking_lot::Mutex;
  13use platform::Event;
  14use postage::{mpsc, sink::Sink as _, stream::Stream as _};
  15use smol::prelude::*;
  16use std::{
  17    any::{type_name, Any, TypeId},
  18    cell::RefCell,
  19    collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque},
  20    fmt::{self, Debug},
  21    hash::{Hash, Hasher},
  22    marker::PhantomData,
  23    mem,
  24    ops::{Deref, DerefMut},
  25    path::{Path, PathBuf},
  26    rc::{self, Rc},
  27    sync::{
  28        atomic::{AtomicUsize, Ordering::SeqCst},
  29        Arc, Weak,
  30    },
  31    time::Duration,
  32};
  33
  34pub trait Entity: 'static {
  35    type Event;
  36
  37    fn release(&mut self, _: &mut MutableAppContext) {}
  38}
  39
  40pub trait View: Entity + Sized {
  41    fn ui_name() -> &'static str;
  42    fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
  43    fn on_focus(&mut self, _: &mut ViewContext<Self>) {}
  44    fn on_blur(&mut self, _: &mut ViewContext<Self>) {}
  45    fn keymap_context(&self, _: &AppContext) -> keymap::Context {
  46        Self::default_keymap_context()
  47    }
  48    fn default_keymap_context() -> keymap::Context {
  49        let mut cx = keymap::Context::default();
  50        cx.set.insert(Self::ui_name().into());
  51        cx
  52    }
  53}
  54
  55pub trait ReadModel {
  56    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
  57}
  58
  59pub trait ReadModelWith {
  60    fn read_model_with<E: Entity, T>(
  61        &self,
  62        handle: &ModelHandle<E>,
  63        read: &mut dyn FnMut(&E, &AppContext) -> T,
  64    ) -> T;
  65}
  66
  67pub trait UpdateModel {
  68    fn update_model<T: Entity, O>(
  69        &mut self,
  70        handle: &ModelHandle<T>,
  71        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
  72    ) -> O;
  73}
  74
  75pub trait UpgradeModelHandle {
  76    fn upgrade_model_handle<T: Entity>(&self, handle: WeakModelHandle<T>)
  77        -> Option<ModelHandle<T>>;
  78}
  79
  80pub trait ReadView {
  81    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
  82}
  83
  84pub trait ReadViewWith {
  85    fn read_view_with<V, T>(
  86        &self,
  87        handle: &ViewHandle<V>,
  88        read: &mut dyn FnMut(&V, &AppContext) -> T,
  89    ) -> T
  90    where
  91        V: View;
  92}
  93
  94pub trait UpdateView {
  95    fn update_view<T, S>(
  96        &mut self,
  97        handle: &ViewHandle<T>,
  98        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
  99    ) -> S
 100    where
 101        T: View;
 102}
 103
 104pub trait Action: 'static + AnyAction {
 105    type Argument: 'static + Clone;
 106}
 107
 108pub trait AnyAction {
 109    fn id(&self) -> TypeId;
 110    fn name(&self) -> &'static str;
 111    fn as_any(&self) -> &dyn Any;
 112    fn boxed_clone(&self) -> Box<dyn AnyAction>;
 113    fn boxed_clone_as_any(&self) -> Box<dyn Any>;
 114}
 115
 116#[macro_export]
 117macro_rules! action {
 118    ($name:ident, $arg:ty) => {
 119        #[derive(Clone)]
 120        pub struct $name(pub $arg);
 121
 122        impl $crate::Action for $name {
 123            type Argument = $arg;
 124        }
 125
 126        impl $crate::AnyAction for $name {
 127            fn id(&self) -> std::any::TypeId {
 128                std::any::TypeId::of::<$name>()
 129            }
 130
 131            fn name(&self) -> &'static str {
 132                stringify!($name)
 133            }
 134
 135            fn as_any(&self) -> &dyn std::any::Any {
 136                self
 137            }
 138
 139            fn boxed_clone(&self) -> Box<dyn $crate::AnyAction> {
 140                Box::new(self.clone())
 141            }
 142
 143            fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
 144                Box::new(self.clone())
 145            }
 146        }
 147    };
 148
 149    ($name:ident) => {
 150        #[derive(Clone, Debug, Eq, PartialEq)]
 151        pub struct $name;
 152
 153        impl $crate::Action for $name {
 154            type Argument = ();
 155        }
 156
 157        impl $crate::AnyAction for $name {
 158            fn id(&self) -> std::any::TypeId {
 159                std::any::TypeId::of::<$name>()
 160            }
 161
 162            fn name(&self) -> &'static str {
 163                stringify!($name)
 164            }
 165
 166            fn as_any(&self) -> &dyn std::any::Any {
 167                self
 168            }
 169
 170            fn boxed_clone(&self) -> Box<dyn $crate::AnyAction> {
 171                Box::new(self.clone())
 172            }
 173
 174            fn boxed_clone_as_any(&self) -> Box<dyn std::any::Any> {
 175                Box::new(self.clone())
 176            }
 177        }
 178    };
 179}
 180
 181pub struct Menu<'a> {
 182    pub name: &'a str,
 183    pub items: Vec<MenuItem<'a>>,
 184}
 185
 186pub enum MenuItem<'a> {
 187    Action {
 188        name: &'a str,
 189        keystroke: Option<&'a str>,
 190        action: Box<dyn AnyAction>,
 191    },
 192    Separator,
 193}
 194
 195#[derive(Clone)]
 196pub struct App(Rc<RefCell<MutableAppContext>>);
 197
 198#[derive(Clone)]
 199pub struct AsyncAppContext(Rc<RefCell<MutableAppContext>>);
 200
 201pub struct BackgroundAppContext(*const RefCell<MutableAppContext>);
 202
 203#[derive(Clone)]
 204pub struct TestAppContext {
 205    cx: Rc<RefCell<MutableAppContext>>,
 206    foreground_platform: Rc<platform::test::ForegroundPlatform>,
 207}
 208
 209impl App {
 210    pub fn new(asset_source: impl AssetSource) -> Result<Self> {
 211        let platform = platform::current::platform();
 212        let foreground_platform = platform::current::foreground_platform();
 213        let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
 214        let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
 215            foreground,
 216            Arc::new(executor::Background::new()),
 217            platform.clone(),
 218            foreground_platform.clone(),
 219            Arc::new(FontCache::new(platform.fonts())),
 220            asset_source,
 221        ))));
 222
 223        let cx = app.0.clone();
 224        foreground_platform.on_menu_command(Box::new(move |action| {
 225            let mut cx = cx.borrow_mut();
 226            if let Some(key_window_id) = cx.cx.platform.key_window_id() {
 227                if let Some((presenter, _)) = cx.presenters_and_platform_windows.get(&key_window_id)
 228                {
 229                    let presenter = presenter.clone();
 230                    let path = presenter.borrow().dispatch_path(cx.as_ref());
 231                    cx.dispatch_action_any(key_window_id, &path, action);
 232                } else {
 233                    cx.dispatch_global_action_any(action);
 234                }
 235            } else {
 236                cx.dispatch_global_action_any(action);
 237            }
 238        }));
 239
 240        app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
 241        Ok(app)
 242    }
 243
 244    pub fn on_become_active<F>(self, mut callback: F) -> Self
 245    where
 246        F: 'static + FnMut(&mut MutableAppContext),
 247    {
 248        let cx = self.0.clone();
 249        self.0
 250            .borrow_mut()
 251            .foreground_platform
 252            .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 253        self
 254    }
 255
 256    pub fn on_resign_active<F>(self, mut callback: F) -> Self
 257    where
 258        F: 'static + FnMut(&mut MutableAppContext),
 259    {
 260        let cx = self.0.clone();
 261        self.0
 262            .borrow_mut()
 263            .foreground_platform
 264            .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 265        self
 266    }
 267
 268    pub fn on_quit<F>(self, mut callback: F) -> Self
 269    where
 270        F: 'static + FnMut(&mut MutableAppContext),
 271    {
 272        let cx = self.0.clone();
 273        self.0
 274            .borrow_mut()
 275            .foreground_platform
 276            .on_quit(Box::new(move || callback(&mut *cx.borrow_mut())));
 277        self
 278    }
 279
 280    pub fn on_event<F>(self, mut callback: F) -> Self
 281    where
 282        F: 'static + FnMut(Event, &mut MutableAppContext) -> bool,
 283    {
 284        let cx = self.0.clone();
 285        self.0
 286            .borrow_mut()
 287            .foreground_platform
 288            .on_event(Box::new(move |event| {
 289                callback(event, &mut *cx.borrow_mut())
 290            }));
 291        self
 292    }
 293
 294    pub fn on_open_files<F>(self, mut callback: F) -> Self
 295    where
 296        F: 'static + FnMut(Vec<PathBuf>, &mut MutableAppContext),
 297    {
 298        let cx = self.0.clone();
 299        self.0
 300            .borrow_mut()
 301            .foreground_platform
 302            .on_open_files(Box::new(move |paths| {
 303                callback(paths, &mut *cx.borrow_mut())
 304            }));
 305        self
 306    }
 307
 308    pub fn run<F>(self, on_finish_launching: F)
 309    where
 310        F: 'static + FnOnce(&mut MutableAppContext),
 311    {
 312        let platform = self.0.borrow().foreground_platform.clone();
 313        platform.run(Box::new(move || {
 314            let mut cx = self.0.borrow_mut();
 315            let cx = &mut *cx;
 316            crate::views::init(cx);
 317            on_finish_launching(cx);
 318        }))
 319    }
 320
 321    pub fn platform(&self) -> Arc<dyn Platform> {
 322        self.0.borrow().platform()
 323    }
 324
 325    pub fn font_cache(&self) -> Arc<FontCache> {
 326        self.0.borrow().cx.font_cache.clone()
 327    }
 328
 329    fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 330        let mut state = self.0.borrow_mut();
 331        state.pending_flushes += 1;
 332        let result = callback(&mut *state);
 333        state.pending_notifications.clear();
 334        state.flush_effects();
 335        result
 336    }
 337}
 338
 339impl TestAppContext {
 340    pub fn new(
 341        foreground_platform: Rc<platform::test::ForegroundPlatform>,
 342        platform: Arc<dyn Platform>,
 343        foreground: Rc<executor::Foreground>,
 344        background: Arc<executor::Background>,
 345        font_cache: Arc<FontCache>,
 346        first_entity_id: usize,
 347    ) -> Self {
 348        let mut cx = MutableAppContext::new(
 349            foreground.clone(),
 350            background,
 351            platform,
 352            foreground_platform.clone(),
 353            font_cache,
 354            (),
 355        );
 356        cx.next_entity_id = first_entity_id;
 357        let cx = TestAppContext {
 358            cx: Rc::new(RefCell::new(cx)),
 359            foreground_platform,
 360        };
 361        cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
 362        cx
 363    }
 364
 365    pub fn dispatch_action<A: Action>(
 366        &self,
 367        window_id: usize,
 368        responder_chain: Vec<usize>,
 369        action: A,
 370    ) {
 371        self.cx
 372            .borrow_mut()
 373            .dispatch_action_any(window_id, &responder_chain, &action);
 374    }
 375
 376    pub fn dispatch_global_action<A: Action>(&self, action: A) {
 377        self.cx.borrow_mut().dispatch_global_action(action);
 378    }
 379
 380    pub fn dispatch_keystroke(
 381        &self,
 382        window_id: usize,
 383        responder_chain: Vec<usize>,
 384        keystroke: &Keystroke,
 385    ) -> Result<bool> {
 386        let mut state = self.cx.borrow_mut();
 387        state.dispatch_keystroke(window_id, responder_chain, keystroke)
 388    }
 389
 390    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 391    where
 392        T: Entity,
 393        F: FnOnce(&mut ModelContext<T>) -> T,
 394    {
 395        let mut state = self.cx.borrow_mut();
 396        state.pending_flushes += 1;
 397        let handle = state.add_model(build_model);
 398        state.flush_effects();
 399        handle
 400    }
 401
 402    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 403    where
 404        T: View,
 405        F: FnOnce(&mut ViewContext<T>) -> T,
 406    {
 407        self.cx
 408            .borrow_mut()
 409            .add_window(Default::default(), build_root_view)
 410    }
 411
 412    pub fn window_ids(&self) -> Vec<usize> {
 413        self.cx.borrow().window_ids().collect()
 414    }
 415
 416    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 417        self.cx.borrow().root_view(window_id)
 418    }
 419
 420    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
 421    where
 422        T: View,
 423        F: FnOnce(&mut ViewContext<T>) -> T,
 424    {
 425        let mut state = self.cx.borrow_mut();
 426        state.pending_flushes += 1;
 427        let handle = state.add_view(window_id, build_view);
 428        state.flush_effects();
 429        handle
 430    }
 431
 432    pub fn add_option_view<T, F>(
 433        &mut self,
 434        window_id: usize,
 435        build_view: F,
 436    ) -> Option<ViewHandle<T>>
 437    where
 438        T: View,
 439        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
 440    {
 441        let mut state = self.cx.borrow_mut();
 442        state.pending_flushes += 1;
 443        let handle = state.add_option_view(window_id, build_view);
 444        state.flush_effects();
 445        handle
 446    }
 447
 448    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 449        callback(self.cx.borrow().as_ref())
 450    }
 451
 452    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 453        let mut state = self.cx.borrow_mut();
 454        // Don't increment pending flushes in order to effects to be flushed before the callback
 455        // completes, which is helpful in tests.
 456        let result = callback(&mut *state);
 457        // Flush effects after the callback just in case there are any. This can happen in edge
 458        // cases such as the closure dropping handles.
 459        state.flush_effects();
 460        result
 461    }
 462
 463    pub fn to_async(&self) -> AsyncAppContext {
 464        AsyncAppContext(self.cx.clone())
 465    }
 466
 467    pub fn font_cache(&self) -> Arc<FontCache> {
 468        self.cx.borrow().cx.font_cache.clone()
 469    }
 470
 471    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 472        self.cx.borrow().cx.platform.clone()
 473    }
 474
 475    pub fn foreground(&self) -> Rc<executor::Foreground> {
 476        self.cx.borrow().foreground().clone()
 477    }
 478
 479    pub fn background(&self) -> Arc<executor::Background> {
 480        self.cx.borrow().background().clone()
 481    }
 482
 483    pub fn simulate_new_path_selection(&self, result: impl FnOnce(PathBuf) -> Option<PathBuf>) {
 484        self.foreground_platform.simulate_new_path_selection(result);
 485    }
 486
 487    pub fn did_prompt_for_new_path(&self) -> bool {
 488        self.foreground_platform.as_ref().did_prompt_for_new_path()
 489    }
 490
 491    pub fn simulate_prompt_answer(&self, window_id: usize, answer: usize) {
 492        let mut state = self.cx.borrow_mut();
 493        let (_, window) = state
 494            .presenters_and_platform_windows
 495            .get_mut(&window_id)
 496            .unwrap();
 497        let test_window = window
 498            .as_any_mut()
 499            .downcast_mut::<platform::test::Window>()
 500            .unwrap();
 501        let callback = test_window
 502            .last_prompt
 503            .take()
 504            .expect("prompt was not called");
 505        (callback)(answer);
 506    }
 507}
 508
 509impl AsyncAppContext {
 510    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 511    where
 512        F: FnOnce(AsyncAppContext) -> Fut,
 513        Fut: 'static + Future<Output = T>,
 514        T: 'static,
 515    {
 516        self.0.borrow().foreground.spawn(f(self.clone()))
 517    }
 518
 519    pub fn read<T, F: FnOnce(&AppContext) -> T>(&mut self, callback: F) -> T {
 520        callback(self.0.borrow().as_ref())
 521    }
 522
 523    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 524        let mut state = self.0.borrow_mut();
 525        state.pending_flushes += 1;
 526        let result = callback(&mut *state);
 527        state.flush_effects();
 528        result
 529    }
 530
 531    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 532    where
 533        T: Entity,
 534        F: FnOnce(&mut ModelContext<T>) -> T,
 535    {
 536        self.update(|cx| cx.add_model(build_model))
 537    }
 538
 539    pub fn platform(&self) -> Arc<dyn Platform> {
 540        self.0.borrow().platform()
 541    }
 542
 543    pub fn foreground(&self) -> Rc<executor::Foreground> {
 544        self.0.borrow().foreground.clone()
 545    }
 546
 547    pub fn background(&self) -> Arc<executor::Background> {
 548        self.0.borrow().cx.background.clone()
 549    }
 550}
 551
 552impl UpdateModel for AsyncAppContext {
 553    fn update_model<E: Entity, O>(
 554        &mut self,
 555        handle: &ModelHandle<E>,
 556        update: &mut dyn FnMut(&mut E, &mut ModelContext<E>) -> O,
 557    ) -> O {
 558        let mut state = self.0.borrow_mut();
 559        state.pending_flushes += 1;
 560        let result = state.update_model(handle, update);
 561        state.flush_effects();
 562        result
 563    }
 564}
 565
 566impl UpgradeModelHandle for AsyncAppContext {
 567    fn upgrade_model_handle<T: Entity>(
 568        &self,
 569        handle: WeakModelHandle<T>,
 570    ) -> Option<ModelHandle<T>> {
 571        self.0.borrow_mut().upgrade_model_handle(handle)
 572    }
 573}
 574
 575impl ReadModelWith for AsyncAppContext {
 576    fn read_model_with<E: Entity, T>(
 577        &self,
 578        handle: &ModelHandle<E>,
 579        read: &mut dyn FnMut(&E, &AppContext) -> T,
 580    ) -> T {
 581        let cx = self.0.borrow();
 582        let cx = cx.as_ref();
 583        read(handle.read(cx), cx)
 584    }
 585}
 586
 587impl UpdateView for AsyncAppContext {
 588    fn update_view<T, S>(
 589        &mut self,
 590        handle: &ViewHandle<T>,
 591        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 592    ) -> S
 593    where
 594        T: View,
 595    {
 596        let mut state = self.0.borrow_mut();
 597        state.pending_flushes += 1;
 598        let result = state.update_view(handle, update);
 599        state.flush_effects();
 600        result
 601    }
 602}
 603
 604impl ReadViewWith for AsyncAppContext {
 605    fn read_view_with<V, T>(
 606        &self,
 607        handle: &ViewHandle<V>,
 608        read: &mut dyn FnMut(&V, &AppContext) -> T,
 609    ) -> T
 610    where
 611        V: View,
 612    {
 613        let cx = self.0.borrow();
 614        let cx = cx.as_ref();
 615        read(handle.read(cx), cx)
 616    }
 617}
 618
 619impl UpdateModel for TestAppContext {
 620    fn update_model<T: Entity, O>(
 621        &mut self,
 622        handle: &ModelHandle<T>,
 623        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
 624    ) -> O {
 625        let mut state = self.cx.borrow_mut();
 626        state.pending_flushes += 1;
 627        let result = state.update_model(handle, update);
 628        state.flush_effects();
 629        result
 630    }
 631}
 632
 633impl ReadModelWith for TestAppContext {
 634    fn read_model_with<E: Entity, T>(
 635        &self,
 636        handle: &ModelHandle<E>,
 637        read: &mut dyn FnMut(&E, &AppContext) -> T,
 638    ) -> T {
 639        let cx = self.cx.borrow();
 640        let cx = cx.as_ref();
 641        read(handle.read(cx), cx)
 642    }
 643}
 644
 645impl UpdateView for TestAppContext {
 646    fn update_view<T, S>(
 647        &mut self,
 648        handle: &ViewHandle<T>,
 649        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 650    ) -> S
 651    where
 652        T: View,
 653    {
 654        let mut state = self.cx.borrow_mut();
 655        state.pending_flushes += 1;
 656        let result = state.update_view(handle, update);
 657        state.flush_effects();
 658        result
 659    }
 660}
 661
 662impl ReadViewWith for TestAppContext {
 663    fn read_view_with<V, T>(
 664        &self,
 665        handle: &ViewHandle<V>,
 666        read: &mut dyn FnMut(&V, &AppContext) -> T,
 667    ) -> T
 668    where
 669        V: View,
 670    {
 671        let cx = self.cx.borrow();
 672        let cx = cx.as_ref();
 673        read(handle.read(cx), cx)
 674    }
 675}
 676
 677type ActionCallback =
 678    dyn FnMut(&mut dyn AnyView, &dyn AnyAction, &mut MutableAppContext, usize, usize) -> bool;
 679type GlobalActionCallback = dyn FnMut(&dyn AnyAction, &mut MutableAppContext);
 680
 681type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>;
 682type ObservationCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
 683
 684pub struct MutableAppContext {
 685    weak_self: Option<rc::Weak<RefCell<Self>>>,
 686    foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 687    assets: Arc<AssetCache>,
 688    cx: AppContext,
 689    actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 690    global_actions: HashMap<TypeId, Vec<Box<GlobalActionCallback>>>,
 691    keystroke_matcher: keymap::Matcher,
 692    next_entity_id: usize,
 693    next_window_id: usize,
 694    next_subscription_id: usize,
 695    subscriptions: Arc<Mutex<HashMap<usize, BTreeMap<usize, SubscriptionCallback>>>>,
 696    observations: Arc<Mutex<HashMap<usize, BTreeMap<usize, ObservationCallback>>>>,
 697    presenters_and_platform_windows:
 698        HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
 699    debug_elements_callbacks: HashMap<usize, Box<dyn Fn(&AppContext) -> crate::json::Value>>,
 700    foreground: Rc<executor::Foreground>,
 701    pending_effects: VecDeque<Effect>,
 702    pending_notifications: HashSet<usize>,
 703    pending_flushes: usize,
 704    flushing_effects: bool,
 705    next_cursor_style_handle_id: Arc<AtomicUsize>,
 706}
 707
 708impl MutableAppContext {
 709    fn new(
 710        foreground: Rc<executor::Foreground>,
 711        background: Arc<executor::Background>,
 712        platform: Arc<dyn platform::Platform>,
 713        foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 714        font_cache: Arc<FontCache>,
 715        asset_source: impl AssetSource,
 716    ) -> Self {
 717        Self {
 718            weak_self: None,
 719            foreground_platform,
 720            assets: Arc::new(AssetCache::new(asset_source)),
 721            cx: AppContext {
 722                models: Default::default(),
 723                views: Default::default(),
 724                windows: Default::default(),
 725                element_states: Default::default(),
 726                ref_counts: Arc::new(Mutex::new(RefCounts::default())),
 727                background,
 728                font_cache,
 729                platform,
 730            },
 731            actions: HashMap::new(),
 732            global_actions: HashMap::new(),
 733            keystroke_matcher: keymap::Matcher::default(),
 734            next_entity_id: 0,
 735            next_window_id: 0,
 736            next_subscription_id: 0,
 737            subscriptions: Default::default(),
 738            observations: Default::default(),
 739            presenters_and_platform_windows: HashMap::new(),
 740            debug_elements_callbacks: HashMap::new(),
 741            foreground,
 742            pending_effects: VecDeque::new(),
 743            pending_notifications: HashSet::new(),
 744            pending_flushes: 0,
 745            flushing_effects: false,
 746            next_cursor_style_handle_id: Default::default(),
 747        }
 748    }
 749
 750    pub fn upgrade(&self) -> App {
 751        App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
 752    }
 753
 754    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 755        self.cx.platform.clone()
 756    }
 757
 758    pub fn font_cache(&self) -> &Arc<FontCache> {
 759        &self.cx.font_cache
 760    }
 761
 762    pub fn foreground(&self) -> &Rc<executor::Foreground> {
 763        &self.foreground
 764    }
 765
 766    pub fn background(&self) -> &Arc<executor::Background> {
 767        &self.cx.background
 768    }
 769
 770    pub fn on_debug_elements<F>(&mut self, window_id: usize, callback: F)
 771    where
 772        F: 'static + Fn(&AppContext) -> crate::json::Value,
 773    {
 774        self.debug_elements_callbacks
 775            .insert(window_id, Box::new(callback));
 776    }
 777
 778    pub fn debug_elements(&self, window_id: usize) -> Option<crate::json::Value> {
 779        self.debug_elements_callbacks
 780            .get(&window_id)
 781            .map(|debug_elements| debug_elements(&self.cx))
 782    }
 783
 784    pub fn add_action<A, V, F>(&mut self, mut handler: F)
 785    where
 786        A: Action,
 787        V: View,
 788        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
 789    {
 790        let handler = Box::new(
 791            move |view: &mut dyn AnyView,
 792                  action: &dyn AnyAction,
 793                  cx: &mut MutableAppContext,
 794                  window_id: usize,
 795                  view_id: usize| {
 796                let action = action.as_any().downcast_ref().unwrap();
 797                let mut cx = ViewContext::new(cx, window_id, view_id);
 798                handler(
 799                    view.as_any_mut()
 800                        .downcast_mut()
 801                        .expect("downcast is type safe"),
 802                    action,
 803                    &mut cx,
 804                );
 805                cx.halt_action_dispatch
 806            },
 807        );
 808
 809        self.actions
 810            .entry(TypeId::of::<V>())
 811            .or_default()
 812            .entry(TypeId::of::<A>())
 813            .or_default()
 814            .push(handler);
 815    }
 816
 817    pub fn add_global_action<A, F>(&mut self, mut handler: F)
 818    where
 819        A: Action,
 820        F: 'static + FnMut(&A, &mut MutableAppContext),
 821    {
 822        let handler = Box::new(move |action: &dyn AnyAction, cx: &mut MutableAppContext| {
 823            let action = action.as_any().downcast_ref().unwrap();
 824            handler(action, cx);
 825        });
 826
 827        self.global_actions
 828            .entry(TypeId::of::<A>())
 829            .or_default()
 830            .push(handler);
 831    }
 832
 833    pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
 834        self.cx.windows.keys().cloned()
 835    }
 836
 837    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 838        self.cx
 839            .windows
 840            .get(&window_id)
 841            .and_then(|window| window.root_view.clone().downcast::<T>())
 842    }
 843
 844    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
 845        self.cx.root_view_id(window_id)
 846    }
 847
 848    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
 849        self.cx.focused_view_id(window_id)
 850    }
 851
 852    pub fn render_view(
 853        &mut self,
 854        window_id: usize,
 855        view_id: usize,
 856        titlebar_height: f32,
 857        refreshing: bool,
 858    ) -> Result<ElementBox> {
 859        let mut view = self
 860            .cx
 861            .views
 862            .remove(&(window_id, view_id))
 863            .ok_or(anyhow!("view not found"))?;
 864        let element = view.render(window_id, view_id, titlebar_height, refreshing, self);
 865        self.cx.views.insert((window_id, view_id), view);
 866        Ok(element)
 867    }
 868
 869    pub fn render_views(
 870        &mut self,
 871        window_id: usize,
 872        titlebar_height: f32,
 873    ) -> HashMap<usize, ElementBox> {
 874        let view_ids = self
 875            .views
 876            .keys()
 877            .filter_map(|(win_id, view_id)| {
 878                if *win_id == window_id {
 879                    Some(*view_id)
 880                } else {
 881                    None
 882                }
 883            })
 884            .collect::<Vec<_>>();
 885        view_ids
 886            .into_iter()
 887            .map(|view_id| {
 888                (
 889                    view_id,
 890                    self.render_view(window_id, view_id, titlebar_height, false)
 891                        .unwrap(),
 892                )
 893            })
 894            .collect()
 895    }
 896
 897    pub fn update<T, F: FnOnce() -> T>(&mut self, callback: F) -> T {
 898        self.pending_flushes += 1;
 899        let result = callback();
 900        self.flush_effects();
 901        result
 902    }
 903
 904    pub fn set_menus(&mut self, menus: Vec<Menu>) {
 905        self.foreground_platform.set_menus(menus);
 906    }
 907
 908    fn prompt<F>(
 909        &self,
 910        window_id: usize,
 911        level: PromptLevel,
 912        msg: &str,
 913        answers: &[&str],
 914        done_fn: F,
 915    ) where
 916        F: 'static + FnOnce(usize, &mut MutableAppContext),
 917    {
 918        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 919        let foreground = self.foreground.clone();
 920        let (_, window) = &self.presenters_and_platform_windows[&window_id];
 921        window.prompt(
 922            level,
 923            msg,
 924            answers,
 925            Box::new(move |answer| {
 926                foreground
 927                    .spawn(async move { (done_fn)(answer, &mut *app.borrow_mut()) })
 928                    .detach();
 929            }),
 930        );
 931    }
 932
 933    pub fn prompt_for_paths<F>(&self, options: PathPromptOptions, done_fn: F)
 934    where
 935        F: 'static + FnOnce(Option<Vec<PathBuf>>, &mut MutableAppContext),
 936    {
 937        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 938        let foreground = self.foreground.clone();
 939        self.foreground_platform.prompt_for_paths(
 940            options,
 941            Box::new(move |paths| {
 942                foreground
 943                    .spawn(async move { (done_fn)(paths, &mut *app.borrow_mut()) })
 944                    .detach();
 945            }),
 946        );
 947    }
 948
 949    pub fn prompt_for_new_path<F>(&self, directory: &Path, done_fn: F)
 950    where
 951        F: 'static + FnOnce(Option<PathBuf>, &mut MutableAppContext),
 952    {
 953        let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
 954        let foreground = self.foreground.clone();
 955        self.foreground_platform.prompt_for_new_path(
 956            directory,
 957            Box::new(move |path| {
 958                foreground
 959                    .spawn(async move { (done_fn)(path, &mut *app.borrow_mut()) })
 960                    .detach();
 961            }),
 962        );
 963    }
 964
 965    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
 966    where
 967        E: Entity,
 968        E::Event: 'static,
 969        H: Handle<E>,
 970        F: 'static + FnMut(H, &E::Event, &mut Self),
 971    {
 972        self.subscribe_internal(handle, move |handle, event, cx| {
 973            callback(handle, event, cx);
 974            true
 975        })
 976    }
 977
 978    fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
 979    where
 980        E: Entity,
 981        E::Event: 'static,
 982        H: Handle<E>,
 983        F: 'static + FnMut(H, &mut Self),
 984    {
 985        self.observe_internal(handle, move |handle, cx| {
 986            callback(handle, cx);
 987            true
 988        })
 989    }
 990
 991    pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
 992    where
 993        E: Entity,
 994        E::Event: 'static,
 995        H: Handle<E>,
 996        F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
 997    {
 998        let id = post_inc(&mut self.next_subscription_id);
 999        let emitter = handle.downgrade();
1000        self.subscriptions
1001            .lock()
1002            .entry(handle.id())
1003            .or_default()
1004            .insert(
1005                id,
1006                Box::new(move |payload, cx| {
1007                    if let Some(emitter) = H::upgrade_from(&emitter, cx.as_ref()) {
1008                        let payload = payload.downcast_ref().expect("downcast is type safe");
1009                        callback(emitter, payload, cx)
1010                    } else {
1011                        false
1012                    }
1013                }),
1014            );
1015        Subscription::Subscription {
1016            id,
1017            entity_id: handle.id(),
1018            subscriptions: Some(Arc::downgrade(&self.subscriptions)),
1019        }
1020    }
1021
1022    fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1023    where
1024        E: Entity,
1025        E::Event: 'static,
1026        H: Handle<E>,
1027        F: 'static + FnMut(H, &mut Self) -> bool,
1028    {
1029        let id = post_inc(&mut self.next_subscription_id);
1030        let observed = handle.downgrade();
1031        self.observations
1032            .lock()
1033            .entry(handle.id())
1034            .or_default()
1035            .insert(
1036                id,
1037                Box::new(move |cx| {
1038                    if let Some(observed) = H::upgrade_from(&observed, cx) {
1039                        callback(observed, cx)
1040                    } else {
1041                        false
1042                    }
1043                }),
1044            );
1045        Subscription::Observation {
1046            id,
1047            entity_id: handle.id(),
1048            observations: Some(Arc::downgrade(&self.observations)),
1049        }
1050    }
1051    pub(crate) fn notify_model(&mut self, model_id: usize) {
1052        if self.pending_notifications.insert(model_id) {
1053            self.pending_effects
1054                .push_back(Effect::ModelNotification { model_id });
1055        }
1056    }
1057
1058    pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
1059        if self.pending_notifications.insert(view_id) {
1060            self.pending_effects
1061                .push_back(Effect::ViewNotification { window_id, view_id });
1062        }
1063    }
1064
1065    pub fn dispatch_action<A: Action>(
1066        &mut self,
1067        window_id: usize,
1068        responder_chain: Vec<usize>,
1069        action: &A,
1070    ) {
1071        self.dispatch_action_any(window_id, &responder_chain, action);
1072    }
1073
1074    pub(crate) fn dispatch_action_any(
1075        &mut self,
1076        window_id: usize,
1077        path: &[usize],
1078        action: &dyn AnyAction,
1079    ) -> bool {
1080        self.pending_flushes += 1;
1081        let mut halted_dispatch = false;
1082
1083        for view_id in path.iter().rev() {
1084            if let Some(mut view) = self.cx.views.remove(&(window_id, *view_id)) {
1085                let type_id = view.as_any().type_id();
1086
1087                if let Some((name, mut handlers)) = self
1088                    .actions
1089                    .get_mut(&type_id)
1090                    .and_then(|h| h.remove_entry(&action.id()))
1091                {
1092                    for handler in handlers.iter_mut().rev() {
1093                        let halt_dispatch =
1094                            handler(view.as_mut(), action, self, window_id, *view_id);
1095                        if halt_dispatch {
1096                            halted_dispatch = true;
1097                            break;
1098                        }
1099                    }
1100                    self.actions
1101                        .get_mut(&type_id)
1102                        .unwrap()
1103                        .insert(name, handlers);
1104                }
1105
1106                self.cx.views.insert((window_id, *view_id), view);
1107
1108                if halted_dispatch {
1109                    break;
1110                }
1111            }
1112        }
1113
1114        if !halted_dispatch {
1115            self.dispatch_global_action_any(action);
1116        }
1117
1118        self.flush_effects();
1119        halted_dispatch
1120    }
1121
1122    pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
1123        self.dispatch_global_action_any(&action);
1124    }
1125
1126    fn dispatch_global_action_any(&mut self, action: &dyn AnyAction) {
1127        if let Some((name, mut handlers)) = self.global_actions.remove_entry(&action.id()) {
1128            self.pending_flushes += 1;
1129            for handler in handlers.iter_mut().rev() {
1130                handler(action, self);
1131            }
1132            self.global_actions.insert(name, handlers);
1133            self.flush_effects();
1134        }
1135    }
1136
1137    pub fn add_bindings<T: IntoIterator<Item = keymap::Binding>>(&mut self, bindings: T) {
1138        self.keystroke_matcher.add_bindings(bindings);
1139    }
1140
1141    pub fn dispatch_keystroke(
1142        &mut self,
1143        window_id: usize,
1144        responder_chain: Vec<usize>,
1145        keystroke: &Keystroke,
1146    ) -> Result<bool> {
1147        let mut context_chain = Vec::new();
1148        let mut context = keymap::Context::default();
1149        for view_id in &responder_chain {
1150            if let Some(view) = self.cx.views.get(&(window_id, *view_id)) {
1151                context.extend(view.keymap_context(self.as_ref()));
1152                context_chain.push(context.clone());
1153            } else {
1154                return Err(anyhow!(
1155                    "View {} in responder chain does not exist",
1156                    view_id
1157                ));
1158            }
1159        }
1160
1161        let mut pending = false;
1162        for (i, cx) in context_chain.iter().enumerate().rev() {
1163            match self
1164                .keystroke_matcher
1165                .push_keystroke(keystroke.clone(), responder_chain[i], cx)
1166            {
1167                MatchResult::None => {}
1168                MatchResult::Pending => pending = true,
1169                MatchResult::Action(action) => {
1170                    if self.dispatch_action_any(window_id, &responder_chain[0..=i], action.as_ref())
1171                    {
1172                        return Ok(true);
1173                    }
1174                }
1175            }
1176        }
1177
1178        Ok(pending)
1179    }
1180
1181    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1182    where
1183        T: Entity,
1184        F: FnOnce(&mut ModelContext<T>) -> T,
1185    {
1186        self.pending_flushes += 1;
1187        let model_id = post_inc(&mut self.next_entity_id);
1188        let handle = ModelHandle::new(model_id, &self.cx.ref_counts);
1189        let mut cx = ModelContext::new(self, model_id);
1190        let model = build_model(&mut cx);
1191        self.cx.models.insert(model_id, Box::new(model));
1192        self.flush_effects();
1193        handle
1194    }
1195
1196    pub fn add_window<T, F>(
1197        &mut self,
1198        window_options: WindowOptions,
1199        build_root_view: F,
1200    ) -> (usize, ViewHandle<T>)
1201    where
1202        T: View,
1203        F: FnOnce(&mut ViewContext<T>) -> T,
1204    {
1205        self.pending_flushes += 1;
1206        let window_id = post_inc(&mut self.next_window_id);
1207        let root_view = self.add_view(window_id, build_root_view);
1208
1209        self.cx.windows.insert(
1210            window_id,
1211            Window {
1212                root_view: root_view.clone().into(),
1213                focused_view_id: root_view.id(),
1214                invalidation: None,
1215            },
1216        );
1217        self.open_platform_window(window_id, window_options);
1218        root_view.update(self, |view, cx| {
1219            view.on_focus(cx);
1220            cx.notify();
1221        });
1222        self.flush_effects();
1223
1224        (window_id, root_view)
1225    }
1226
1227    pub fn remove_window(&mut self, window_id: usize) {
1228        self.cx.windows.remove(&window_id);
1229        self.presenters_and_platform_windows.remove(&window_id);
1230        self.remove_dropped_entities();
1231    }
1232
1233    pub fn remove_all_windows(&mut self) {
1234        for (window_id, _) in self.cx.windows.drain() {
1235            self.presenters_and_platform_windows.remove(&window_id);
1236        }
1237        self.remove_dropped_entities();
1238    }
1239
1240    fn open_platform_window(&mut self, window_id: usize, window_options: WindowOptions) {
1241        let mut window =
1242            self.cx
1243                .platform
1244                .open_window(window_id, window_options, self.foreground.clone());
1245        let presenter = Rc::new(RefCell::new(
1246            self.build_presenter(window_id, window.titlebar_height()),
1247        ));
1248
1249        {
1250            let mut app = self.upgrade();
1251            let presenter = presenter.clone();
1252            window.on_event(Box::new(move |event| {
1253                app.update(|cx| {
1254                    if let Event::KeyDown { keystroke, .. } = &event {
1255                        if cx
1256                            .dispatch_keystroke(
1257                                window_id,
1258                                presenter.borrow().dispatch_path(cx.as_ref()),
1259                                keystroke,
1260                            )
1261                            .unwrap()
1262                        {
1263                            return;
1264                        }
1265                    }
1266
1267                    presenter.borrow_mut().dispatch_event(event, cx);
1268                })
1269            }));
1270        }
1271
1272        {
1273            let mut app = self.upgrade();
1274            window.on_resize(Box::new(move || {
1275                app.update(|cx| cx.resize_window(window_id))
1276            }));
1277        }
1278
1279        {
1280            let mut app = self.upgrade();
1281            window.on_close(Box::new(move || {
1282                app.update(|cx| cx.remove_window(window_id));
1283            }));
1284        }
1285
1286        self.presenters_and_platform_windows
1287            .insert(window_id, (presenter.clone(), window));
1288
1289        self.on_debug_elements(window_id, move |cx| {
1290            presenter.borrow().debug_elements(cx).unwrap()
1291        });
1292    }
1293
1294    pub fn build_presenter(&mut self, window_id: usize, titlebar_height: f32) -> Presenter {
1295        Presenter::new(
1296            window_id,
1297            titlebar_height,
1298            self.cx.font_cache.clone(),
1299            TextLayoutCache::new(self.cx.platform.fonts()),
1300            self.assets.clone(),
1301            self,
1302        )
1303    }
1304
1305    pub fn build_render_context<V: View>(
1306        &mut self,
1307        window_id: usize,
1308        view_id: usize,
1309        titlebar_height: f32,
1310        refreshing: bool,
1311    ) -> RenderContext<V> {
1312        RenderContext {
1313            app: self,
1314            titlebar_height,
1315            refreshing,
1316            window_id,
1317            view_id,
1318            view_type: PhantomData,
1319        }
1320    }
1321
1322    pub fn add_view<T, F>(&mut self, window_id: usize, build_view: F) -> ViewHandle<T>
1323    where
1324        T: View,
1325        F: FnOnce(&mut ViewContext<T>) -> T,
1326    {
1327        self.add_option_view(window_id, |cx| Some(build_view(cx)))
1328            .unwrap()
1329    }
1330
1331    pub fn add_option_view<T, F>(
1332        &mut self,
1333        window_id: usize,
1334        build_view: F,
1335    ) -> Option<ViewHandle<T>>
1336    where
1337        T: View,
1338        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
1339    {
1340        let view_id = post_inc(&mut self.next_entity_id);
1341        self.pending_flushes += 1;
1342        let handle = ViewHandle::new(window_id, view_id, &self.cx.ref_counts);
1343        let mut cx = ViewContext::new(self, window_id, view_id);
1344        let handle = if let Some(view) = build_view(&mut cx) {
1345            self.cx.views.insert((window_id, view_id), Box::new(view));
1346            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1347                window
1348                    .invalidation
1349                    .get_or_insert_with(Default::default)
1350                    .updated
1351                    .insert(view_id);
1352            }
1353            Some(handle)
1354        } else {
1355            None
1356        };
1357        self.flush_effects();
1358        handle
1359    }
1360
1361    pub fn element_state<Tag: 'static, T: 'static + Default>(
1362        &mut self,
1363        id: ElementStateId,
1364    ) -> ElementStateHandle<T> {
1365        let key = (TypeId::of::<Tag>(), id);
1366        self.cx
1367            .element_states
1368            .entry(key)
1369            .or_insert_with(|| Box::new(T::default()));
1370        ElementStateHandle::new(TypeId::of::<Tag>(), id, &self.cx.ref_counts)
1371    }
1372
1373    fn remove_dropped_entities(&mut self) {
1374        loop {
1375            let (dropped_models, dropped_views, dropped_element_states) =
1376                self.cx.ref_counts.lock().take_dropped();
1377            if dropped_models.is_empty()
1378                && dropped_views.is_empty()
1379                && dropped_element_states.is_empty()
1380            {
1381                break;
1382            }
1383
1384            for model_id in dropped_models {
1385                self.subscriptions.lock().remove(&model_id);
1386                self.observations.lock().remove(&model_id);
1387                let mut model = self.cx.models.remove(&model_id).unwrap();
1388                model.release(self);
1389            }
1390
1391            for (window_id, view_id) in dropped_views {
1392                self.subscriptions.lock().remove(&view_id);
1393                self.observations.lock().remove(&view_id);
1394                let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap();
1395                view.release(self);
1396                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
1397                    window
1398                        .invalidation
1399                        .get_or_insert_with(Default::default)
1400                        .removed
1401                        .push(view_id);
1402                    if window.focused_view_id == view_id {
1403                        Some(window.root_view.id())
1404                    } else {
1405                        None
1406                    }
1407                });
1408
1409                if let Some(view_id) = change_focus_to {
1410                    self.focus(window_id, view_id);
1411                }
1412            }
1413
1414            for key in dropped_element_states {
1415                self.cx.element_states.remove(&key);
1416            }
1417        }
1418    }
1419
1420    fn flush_effects(&mut self) {
1421        self.pending_flushes = self.pending_flushes.saturating_sub(1);
1422
1423        if !self.flushing_effects && self.pending_flushes == 0 {
1424            self.flushing_effects = true;
1425
1426            let mut refreshing = false;
1427            loop {
1428                if let Some(effect) = self.pending_effects.pop_front() {
1429                    match effect {
1430                        Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload),
1431                        Effect::ModelNotification { model_id } => {
1432                            self.notify_model_observers(model_id)
1433                        }
1434                        Effect::ViewNotification { window_id, view_id } => {
1435                            self.notify_view_observers(window_id, view_id)
1436                        }
1437                        Effect::Focus { window_id, view_id } => {
1438                            self.focus(window_id, view_id);
1439                        }
1440                        Effect::ResizeWindow { window_id } => {
1441                            if let Some(window) = self.cx.windows.get_mut(&window_id) {
1442                                window
1443                                    .invalidation
1444                                    .get_or_insert(WindowInvalidation::default());
1445                            }
1446                        }
1447                        Effect::RefreshWindows => {
1448                            refreshing = true;
1449                        }
1450                    }
1451                    self.pending_notifications.clear();
1452                    self.remove_dropped_entities();
1453                } else {
1454                    self.remove_dropped_entities();
1455                    if refreshing {
1456                        self.perform_window_refresh();
1457                    } else {
1458                        self.update_windows();
1459                    }
1460
1461                    if self.pending_effects.is_empty() {
1462                        self.flushing_effects = false;
1463                        self.pending_notifications.clear();
1464                        break;
1465                    } else {
1466                        refreshing = false;
1467                    }
1468                }
1469            }
1470        }
1471    }
1472
1473    fn update_windows(&mut self) {
1474        let mut invalidations = HashMap::new();
1475        for (window_id, window) in &mut self.cx.windows {
1476            if let Some(invalidation) = window.invalidation.take() {
1477                invalidations.insert(*window_id, invalidation);
1478            }
1479        }
1480
1481        for (window_id, invalidation) in invalidations {
1482            if let Some((presenter, mut window)) =
1483                self.presenters_and_platform_windows.remove(&window_id)
1484            {
1485                {
1486                    let mut presenter = presenter.borrow_mut();
1487                    presenter.invalidate(invalidation, self);
1488                    let scene =
1489                        presenter.build_scene(window.size(), window.scale_factor(), false, self);
1490                    window.present_scene(scene);
1491                }
1492                self.presenters_and_platform_windows
1493                    .insert(window_id, (presenter, window));
1494            }
1495        }
1496    }
1497
1498    fn resize_window(&mut self, window_id: usize) {
1499        self.pending_effects
1500            .push_back(Effect::ResizeWindow { window_id });
1501    }
1502
1503    pub fn refresh_windows(&mut self) {
1504        self.pending_effects.push_back(Effect::RefreshWindows);
1505    }
1506
1507    fn perform_window_refresh(&mut self) {
1508        let mut presenters = mem::take(&mut self.presenters_and_platform_windows);
1509        for (window_id, (presenter, window)) in &mut presenters {
1510            let invalidation = self
1511                .cx
1512                .windows
1513                .get_mut(&window_id)
1514                .unwrap()
1515                .invalidation
1516                .take();
1517            let mut presenter = presenter.borrow_mut();
1518            presenter.refresh(invalidation, self);
1519            let scene = presenter.build_scene(window.size(), window.scale_factor(), true, self);
1520            window.present_scene(scene);
1521        }
1522        self.presenters_and_platform_windows = presenters;
1523    }
1524
1525    pub fn set_cursor_style(&mut self, style: CursorStyle) -> CursorStyleHandle {
1526        self.platform.set_cursor_style(style);
1527        let id = self.next_cursor_style_handle_id.fetch_add(1, SeqCst);
1528        CursorStyleHandle {
1529            id,
1530            next_cursor_style_handle_id: self.next_cursor_style_handle_id.clone(),
1531            platform: self.platform(),
1532        }
1533    }
1534
1535    fn emit_event(&mut self, entity_id: usize, payload: Box<dyn Any>) {
1536        let callbacks = self.subscriptions.lock().remove(&entity_id);
1537        if let Some(callbacks) = callbacks {
1538            for (id, mut callback) in callbacks {
1539                let alive = callback(payload.as_ref(), self);
1540                if alive {
1541                    self.subscriptions
1542                        .lock()
1543                        .entry(entity_id)
1544                        .or_default()
1545                        .insert(id, callback);
1546                }
1547            }
1548        }
1549    }
1550
1551    fn notify_model_observers(&mut self, observed_id: usize) {
1552        let callbacks = self.observations.lock().remove(&observed_id);
1553        if let Some(callbacks) = callbacks {
1554            if self.cx.models.contains_key(&observed_id) {
1555                for (id, mut callback) in callbacks {
1556                    let alive = callback(self);
1557                    if alive {
1558                        self.observations
1559                            .lock()
1560                            .entry(observed_id)
1561                            .or_default()
1562                            .insert(id, callback);
1563                    }
1564                }
1565            }
1566        }
1567    }
1568
1569    fn notify_view_observers(&mut self, observed_window_id: usize, observed_view_id: usize) {
1570        if let Some(window) = self.cx.windows.get_mut(&observed_window_id) {
1571            window
1572                .invalidation
1573                .get_or_insert_with(Default::default)
1574                .updated
1575                .insert(observed_view_id);
1576        }
1577
1578        let callbacks = self.observations.lock().remove(&observed_view_id);
1579        if let Some(callbacks) = callbacks {
1580            if self
1581                .cx
1582                .views
1583                .contains_key(&(observed_window_id, observed_view_id))
1584            {
1585                for (id, mut callback) in callbacks {
1586                    let alive = callback(self);
1587                    if alive {
1588                        self.observations
1589                            .lock()
1590                            .entry(observed_view_id)
1591                            .or_default()
1592                            .insert(id, callback);
1593                    }
1594                }
1595            }
1596        }
1597    }
1598
1599    fn focus(&mut self, window_id: usize, focused_id: usize) {
1600        if self
1601            .cx
1602            .windows
1603            .get(&window_id)
1604            .map(|w| w.focused_view_id)
1605            .map_or(false, |cur_focused| cur_focused == focused_id)
1606        {
1607            return;
1608        }
1609
1610        self.pending_flushes += 1;
1611
1612        let blurred_id = self.cx.windows.get_mut(&window_id).map(|window| {
1613            let blurred_id = window.focused_view_id;
1614            window.focused_view_id = focused_id;
1615            blurred_id
1616        });
1617
1618        if let Some(blurred_id) = blurred_id {
1619            if let Some(mut blurred_view) = self.cx.views.remove(&(window_id, blurred_id)) {
1620                blurred_view.on_blur(self, window_id, blurred_id);
1621                self.cx.views.insert((window_id, blurred_id), blurred_view);
1622            }
1623        }
1624
1625        if let Some(mut focused_view) = self.cx.views.remove(&(window_id, focused_id)) {
1626            focused_view.on_focus(self, window_id, focused_id);
1627            self.cx.views.insert((window_id, focused_id), focused_view);
1628        }
1629
1630        self.flush_effects();
1631    }
1632
1633    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
1634    where
1635        F: FnOnce(AsyncAppContext) -> Fut,
1636        Fut: 'static + Future<Output = T>,
1637        T: 'static,
1638    {
1639        let cx = self.to_async();
1640        self.foreground.spawn(f(cx))
1641    }
1642
1643    pub fn to_async(&self) -> AsyncAppContext {
1644        AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
1645    }
1646
1647    pub fn write_to_clipboard(&self, item: ClipboardItem) {
1648        self.cx.platform.write_to_clipboard(item);
1649    }
1650
1651    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
1652        self.cx.platform.read_from_clipboard()
1653    }
1654}
1655
1656impl ReadModel for MutableAppContext {
1657    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1658        if let Some(model) = self.cx.models.get(&handle.model_id) {
1659            model
1660                .as_any()
1661                .downcast_ref()
1662                .expect("downcast is type safe")
1663        } else {
1664            panic!("circular model reference");
1665        }
1666    }
1667}
1668
1669impl UpdateModel for MutableAppContext {
1670    fn update_model<T: Entity, V>(
1671        &mut self,
1672        handle: &ModelHandle<T>,
1673        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
1674    ) -> V {
1675        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
1676            self.pending_flushes += 1;
1677            let mut cx = ModelContext::new(self, handle.model_id);
1678            let result = update(
1679                model
1680                    .as_any_mut()
1681                    .downcast_mut()
1682                    .expect("downcast is type safe"),
1683                &mut cx,
1684            );
1685            self.cx.models.insert(handle.model_id, model);
1686            self.flush_effects();
1687            result
1688        } else {
1689            panic!("circular model update");
1690        }
1691    }
1692}
1693
1694impl UpgradeModelHandle for MutableAppContext {
1695    fn upgrade_model_handle<T: Entity>(
1696        &self,
1697        handle: WeakModelHandle<T>,
1698    ) -> Option<ModelHandle<T>> {
1699        self.cx.upgrade_model_handle(handle)
1700    }
1701}
1702
1703impl ReadView for MutableAppContext {
1704    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1705        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
1706            view.as_any().downcast_ref().expect("downcast is type safe")
1707        } else {
1708            panic!("circular view reference");
1709        }
1710    }
1711}
1712
1713impl UpdateView for MutableAppContext {
1714    fn update_view<T, S>(
1715        &mut self,
1716        handle: &ViewHandle<T>,
1717        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
1718    ) -> S
1719    where
1720        T: View,
1721    {
1722        self.pending_flushes += 1;
1723        let mut view = self
1724            .cx
1725            .views
1726            .remove(&(handle.window_id, handle.view_id))
1727            .expect("circular view update");
1728
1729        let mut cx = ViewContext::new(self, handle.window_id, handle.view_id);
1730        let result = update(
1731            view.as_any_mut()
1732                .downcast_mut()
1733                .expect("downcast is type safe"),
1734            &mut cx,
1735        );
1736        self.cx
1737            .views
1738            .insert((handle.window_id, handle.view_id), view);
1739        self.flush_effects();
1740        result
1741    }
1742}
1743
1744impl AsRef<AppContext> for MutableAppContext {
1745    fn as_ref(&self) -> &AppContext {
1746        &self.cx
1747    }
1748}
1749
1750impl Deref for MutableAppContext {
1751    type Target = AppContext;
1752
1753    fn deref(&self) -> &Self::Target {
1754        &self.cx
1755    }
1756}
1757
1758pub struct AppContext {
1759    models: HashMap<usize, Box<dyn AnyModel>>,
1760    views: HashMap<(usize, usize), Box<dyn AnyView>>,
1761    windows: HashMap<usize, Window>,
1762    element_states: HashMap<(TypeId, ElementStateId), Box<dyn Any>>,
1763    background: Arc<executor::Background>,
1764    ref_counts: Arc<Mutex<RefCounts>>,
1765    font_cache: Arc<FontCache>,
1766    platform: Arc<dyn Platform>,
1767}
1768
1769impl AppContext {
1770    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
1771        self.windows
1772            .get(&window_id)
1773            .map(|window| window.root_view.id())
1774    }
1775
1776    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
1777        self.windows
1778            .get(&window_id)
1779            .map(|window| window.focused_view_id)
1780    }
1781
1782    pub fn background(&self) -> &Arc<executor::Background> {
1783        &self.background
1784    }
1785
1786    pub fn font_cache(&self) -> &Arc<FontCache> {
1787        &self.font_cache
1788    }
1789
1790    pub fn platform(&self) -> &Arc<dyn Platform> {
1791        &self.platform
1792    }
1793}
1794
1795impl ReadModel for AppContext {
1796    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1797        if let Some(model) = self.models.get(&handle.model_id) {
1798            model
1799                .as_any()
1800                .downcast_ref()
1801                .expect("downcast should be type safe")
1802        } else {
1803            panic!("circular model reference");
1804        }
1805    }
1806}
1807
1808impl UpgradeModelHandle for AppContext {
1809    fn upgrade_model_handle<T: Entity>(
1810        &self,
1811        handle: WeakModelHandle<T>,
1812    ) -> Option<ModelHandle<T>> {
1813        if self.models.contains_key(&handle.model_id) {
1814            Some(ModelHandle::new(handle.model_id, &self.ref_counts))
1815        } else {
1816            None
1817        }
1818    }
1819}
1820
1821impl ReadView for AppContext {
1822    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1823        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
1824            view.as_any()
1825                .downcast_ref()
1826                .expect("downcast should be type safe")
1827        } else {
1828            panic!("circular view reference");
1829        }
1830    }
1831}
1832
1833struct Window {
1834    root_view: AnyViewHandle,
1835    focused_view_id: usize,
1836    invalidation: Option<WindowInvalidation>,
1837}
1838
1839#[derive(Default, Clone)]
1840pub struct WindowInvalidation {
1841    pub updated: HashSet<usize>,
1842    pub removed: Vec<usize>,
1843}
1844
1845pub enum Effect {
1846    Event {
1847        entity_id: usize,
1848        payload: Box<dyn Any>,
1849    },
1850    ModelNotification {
1851        model_id: usize,
1852    },
1853    ViewNotification {
1854        window_id: usize,
1855        view_id: usize,
1856    },
1857    Focus {
1858        window_id: usize,
1859        view_id: usize,
1860    },
1861    ResizeWindow {
1862        window_id: usize,
1863    },
1864    RefreshWindows,
1865}
1866
1867impl Debug for Effect {
1868    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1869        match self {
1870            Effect::Event { entity_id, .. } => f
1871                .debug_struct("Effect::Event")
1872                .field("entity_id", entity_id)
1873                .finish(),
1874            Effect::ModelNotification { model_id } => f
1875                .debug_struct("Effect::ModelNotification")
1876                .field("model_id", model_id)
1877                .finish(),
1878            Effect::ViewNotification { window_id, view_id } => f
1879                .debug_struct("Effect::ViewNotification")
1880                .field("window_id", window_id)
1881                .field("view_id", view_id)
1882                .finish(),
1883            Effect::Focus { window_id, view_id } => f
1884                .debug_struct("Effect::Focus")
1885                .field("window_id", window_id)
1886                .field("view_id", view_id)
1887                .finish(),
1888            Effect::ResizeWindow { window_id } => f
1889                .debug_struct("Effect::RefreshWindow")
1890                .field("window_id", window_id)
1891                .finish(),
1892            Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
1893        }
1894    }
1895}
1896
1897pub trait AnyModel {
1898    fn as_any(&self) -> &dyn Any;
1899    fn as_any_mut(&mut self) -> &mut dyn Any;
1900    fn release(&mut self, cx: &mut MutableAppContext);
1901}
1902
1903impl<T> AnyModel for T
1904where
1905    T: Entity,
1906{
1907    fn as_any(&self) -> &dyn Any {
1908        self
1909    }
1910
1911    fn as_any_mut(&mut self) -> &mut dyn Any {
1912        self
1913    }
1914
1915    fn release(&mut self, cx: &mut MutableAppContext) {
1916        self.release(cx);
1917    }
1918}
1919
1920pub trait AnyView {
1921    fn as_any(&self) -> &dyn Any;
1922    fn as_any_mut(&mut self) -> &mut dyn Any;
1923    fn release(&mut self, cx: &mut MutableAppContext);
1924    fn ui_name(&self) -> &'static str;
1925    fn render<'a>(
1926        &mut self,
1927        window_id: usize,
1928        view_id: usize,
1929        titlebar_height: f32,
1930        refreshing: bool,
1931        cx: &mut MutableAppContext,
1932    ) -> ElementBox;
1933    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
1934    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
1935    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
1936}
1937
1938impl<T> AnyView for T
1939where
1940    T: View,
1941{
1942    fn as_any(&self) -> &dyn Any {
1943        self
1944    }
1945
1946    fn as_any_mut(&mut self) -> &mut dyn Any {
1947        self
1948    }
1949
1950    fn release(&mut self, cx: &mut MutableAppContext) {
1951        self.release(cx);
1952    }
1953
1954    fn ui_name(&self) -> &'static str {
1955        T::ui_name()
1956    }
1957
1958    fn render<'a>(
1959        &mut self,
1960        window_id: usize,
1961        view_id: usize,
1962        titlebar_height: f32,
1963        refreshing: bool,
1964        cx: &mut MutableAppContext,
1965    ) -> ElementBox {
1966        View::render(
1967            self,
1968            &mut RenderContext {
1969                window_id,
1970                view_id,
1971                app: cx,
1972                view_type: PhantomData::<T>,
1973                titlebar_height,
1974                refreshing,
1975            },
1976        )
1977    }
1978
1979    fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
1980        let mut cx = ViewContext::new(cx, window_id, view_id);
1981        View::on_focus(self, &mut cx);
1982    }
1983
1984    fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
1985        let mut cx = ViewContext::new(cx, window_id, view_id);
1986        View::on_blur(self, &mut cx);
1987    }
1988
1989    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
1990        View::keymap_context(self, cx)
1991    }
1992}
1993
1994pub struct ModelContext<'a, T: ?Sized> {
1995    app: &'a mut MutableAppContext,
1996    model_id: usize,
1997    model_type: PhantomData<T>,
1998    halt_stream: bool,
1999}
2000
2001impl<'a, T: Entity> ModelContext<'a, T> {
2002    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
2003        Self {
2004            app,
2005            model_id,
2006            model_type: PhantomData,
2007            halt_stream: false,
2008        }
2009    }
2010
2011    pub fn background(&self) -> &Arc<executor::Background> {
2012        &self.app.cx.background
2013    }
2014
2015    pub fn halt_stream(&mut self) {
2016        self.halt_stream = true;
2017    }
2018
2019    pub fn model_id(&self) -> usize {
2020        self.model_id
2021    }
2022
2023    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2024    where
2025        S: Entity,
2026        F: FnOnce(&mut ModelContext<S>) -> S,
2027    {
2028        self.app.add_model(build_model)
2029    }
2030
2031    pub fn emit(&mut self, payload: T::Event) {
2032        self.app.pending_effects.push_back(Effect::Event {
2033            entity_id: self.model_id,
2034            payload: Box::new(payload),
2035        });
2036    }
2037
2038    pub fn notify(&mut self) {
2039        self.app.notify_model(self.model_id);
2040    }
2041
2042    pub fn subscribe<S: Entity, F>(
2043        &mut self,
2044        handle: &ModelHandle<S>,
2045        mut callback: F,
2046    ) -> Subscription
2047    where
2048        S::Event: 'static,
2049        F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
2050    {
2051        let subscriber = self.handle().downgrade();
2052        self.app
2053            .subscribe_internal(handle, move |emitter, event, cx| {
2054                if let Some(subscriber) = subscriber.upgrade(cx) {
2055                    subscriber.update(cx, |subscriber, cx| {
2056                        callback(subscriber, emitter, event, cx);
2057                    });
2058                    true
2059                } else {
2060                    false
2061                }
2062            })
2063    }
2064
2065    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
2066    where
2067        S: Entity,
2068        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
2069    {
2070        let observer = self.handle().downgrade();
2071        self.app.observe_internal(handle, move |observed, cx| {
2072            if let Some(observer) = observer.upgrade(cx) {
2073                observer.update(cx, |observer, cx| {
2074                    callback(observer, observed, cx);
2075                });
2076                true
2077            } else {
2078                false
2079            }
2080        })
2081    }
2082
2083    pub fn handle(&self) -> ModelHandle<T> {
2084        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
2085    }
2086
2087    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
2088    where
2089        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
2090        Fut: 'static + Future<Output = S>,
2091        S: 'static,
2092    {
2093        let handle = self.handle();
2094        self.app.spawn(|cx| f(handle, cx))
2095    }
2096
2097    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
2098    where
2099        F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
2100        Fut: 'static + Future<Output = S>,
2101        S: 'static,
2102    {
2103        let handle = self.handle().downgrade();
2104        self.app.spawn(|cx| f(handle, cx))
2105    }
2106}
2107
2108impl<M> AsRef<AppContext> for ModelContext<'_, M> {
2109    fn as_ref(&self) -> &AppContext {
2110        &self.app.cx
2111    }
2112}
2113
2114impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
2115    fn as_mut(&mut self) -> &mut MutableAppContext {
2116        self.app
2117    }
2118}
2119
2120impl<M> ReadModel for ModelContext<'_, M> {
2121    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2122        self.app.read_model(handle)
2123    }
2124}
2125
2126impl<M> UpdateModel for ModelContext<'_, M> {
2127    fn update_model<T: Entity, V>(
2128        &mut self,
2129        handle: &ModelHandle<T>,
2130        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2131    ) -> V {
2132        self.app.update_model(handle, update)
2133    }
2134}
2135
2136impl<M> UpgradeModelHandle for ModelContext<'_, M> {
2137    fn upgrade_model_handle<T: Entity>(
2138        &self,
2139        handle: WeakModelHandle<T>,
2140    ) -> Option<ModelHandle<T>> {
2141        self.cx.upgrade_model_handle(handle)
2142    }
2143}
2144
2145impl<M> Deref for ModelContext<'_, M> {
2146    type Target = MutableAppContext;
2147
2148    fn deref(&self) -> &Self::Target {
2149        &self.app
2150    }
2151}
2152
2153impl<M> DerefMut for ModelContext<'_, M> {
2154    fn deref_mut(&mut self) -> &mut Self::Target {
2155        &mut self.app
2156    }
2157}
2158
2159pub struct ViewContext<'a, T: ?Sized> {
2160    app: &'a mut MutableAppContext,
2161    window_id: usize,
2162    view_id: usize,
2163    view_type: PhantomData<T>,
2164    halt_action_dispatch: bool,
2165}
2166
2167impl<'a, T: View> ViewContext<'a, T> {
2168    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
2169        Self {
2170            app,
2171            window_id,
2172            view_id,
2173            view_type: PhantomData,
2174            halt_action_dispatch: true,
2175        }
2176    }
2177
2178    pub fn handle(&self) -> ViewHandle<T> {
2179        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
2180    }
2181
2182    pub fn window_id(&self) -> usize {
2183        self.window_id
2184    }
2185
2186    pub fn view_id(&self) -> usize {
2187        self.view_id
2188    }
2189
2190    pub fn foreground(&self) -> &Rc<executor::Foreground> {
2191        self.app.foreground()
2192    }
2193
2194    pub fn background_executor(&self) -> &Arc<executor::Background> {
2195        &self.app.cx.background
2196    }
2197
2198    pub fn platform(&self) -> Arc<dyn Platform> {
2199        self.app.platform()
2200    }
2201
2202    pub fn prompt<F>(&self, level: PromptLevel, msg: &str, answers: &[&str], done_fn: F)
2203    where
2204        F: 'static + FnOnce(usize, &mut MutableAppContext),
2205    {
2206        self.app
2207            .prompt(self.window_id, level, msg, answers, done_fn)
2208    }
2209
2210    pub fn prompt_for_paths<F>(&self, options: PathPromptOptions, done_fn: F)
2211    where
2212        F: 'static + FnOnce(Option<Vec<PathBuf>>, &mut MutableAppContext),
2213    {
2214        self.app.prompt_for_paths(options, done_fn)
2215    }
2216
2217    pub fn prompt_for_new_path<F>(&self, directory: &Path, done_fn: F)
2218    where
2219        F: 'static + FnOnce(Option<PathBuf>, &mut MutableAppContext),
2220    {
2221        self.app.prompt_for_new_path(directory, done_fn)
2222    }
2223
2224    pub fn debug_elements(&self) -> crate::json::Value {
2225        self.app.debug_elements(self.window_id).unwrap()
2226    }
2227
2228    pub fn focus<S>(&mut self, handle: S)
2229    where
2230        S: Into<AnyViewHandle>,
2231    {
2232        let handle = handle.into();
2233        self.app.pending_effects.push_back(Effect::Focus {
2234            window_id: handle.window_id,
2235            view_id: handle.view_id,
2236        });
2237    }
2238
2239    pub fn focus_self(&mut self) {
2240        self.app.pending_effects.push_back(Effect::Focus {
2241            window_id: self.window_id,
2242            view_id: self.view_id,
2243        });
2244    }
2245
2246    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2247    where
2248        S: Entity,
2249        F: FnOnce(&mut ModelContext<S>) -> S,
2250    {
2251        self.app.add_model(build_model)
2252    }
2253
2254    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
2255    where
2256        S: View,
2257        F: FnOnce(&mut ViewContext<S>) -> S,
2258    {
2259        self.app.add_view(self.window_id, build_view)
2260    }
2261
2262    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
2263    where
2264        S: View,
2265        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
2266    {
2267        self.app.add_option_view(self.window_id, build_view)
2268    }
2269
2270    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
2271    where
2272        E: Entity,
2273        E::Event: 'static,
2274        H: Handle<E>,
2275        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
2276    {
2277        let subscriber = self.handle().downgrade();
2278        self.app
2279            .subscribe_internal(handle, move |emitter, event, cx| {
2280                if let Some(subscriber) = subscriber.upgrade(cx) {
2281                    subscriber.update(cx, |subscriber, cx| {
2282                        callback(subscriber, emitter, event, cx);
2283                    });
2284                    true
2285                } else {
2286                    false
2287                }
2288            })
2289    }
2290
2291    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
2292    where
2293        E: Entity,
2294        H: Handle<E>,
2295        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
2296    {
2297        let observer = self.handle().downgrade();
2298        self.app.observe_internal(handle, move |observed, cx| {
2299            if let Some(observer) = observer.upgrade(cx) {
2300                observer.update(cx, |observer, cx| {
2301                    callback(observer, observed, cx);
2302                });
2303                true
2304            } else {
2305                false
2306            }
2307        })
2308    }
2309
2310    pub fn emit(&mut self, payload: T::Event) {
2311        self.app.pending_effects.push_back(Effect::Event {
2312            entity_id: self.view_id,
2313            payload: Box::new(payload),
2314        });
2315    }
2316
2317    pub fn notify(&mut self) {
2318        self.app.notify_view(self.window_id, self.view_id);
2319    }
2320
2321    pub fn propagate_action(&mut self) {
2322        self.halt_action_dispatch = false;
2323    }
2324
2325    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
2326    where
2327        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
2328        Fut: 'static + Future<Output = S>,
2329        S: 'static,
2330    {
2331        let handle = self.handle();
2332        self.app.spawn(|cx| f(handle, cx))
2333    }
2334
2335    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
2336    where
2337        F: FnOnce(WeakViewHandle<T>, AsyncAppContext) -> Fut,
2338        Fut: 'static + Future<Output = S>,
2339        S: 'static,
2340    {
2341        let handle = self.handle().downgrade();
2342        self.app.spawn(|cx| f(handle, cx))
2343    }
2344}
2345
2346pub struct RenderContext<'a, T: View> {
2347    pub app: &'a mut MutableAppContext,
2348    pub titlebar_height: f32,
2349    pub refreshing: bool,
2350    window_id: usize,
2351    view_id: usize,
2352    view_type: PhantomData<T>,
2353}
2354
2355impl<'a, T: View> RenderContext<'a, T> {
2356    pub fn handle(&self) -> WeakViewHandle<T> {
2357        WeakViewHandle::new(self.window_id, self.view_id)
2358    }
2359}
2360
2361impl AsRef<AppContext> for &AppContext {
2362    fn as_ref(&self) -> &AppContext {
2363        self
2364    }
2365}
2366
2367impl<V: View> Deref for RenderContext<'_, V> {
2368    type Target = MutableAppContext;
2369
2370    fn deref(&self) -> &Self::Target {
2371        self.app
2372    }
2373}
2374
2375impl<V: View> DerefMut for RenderContext<'_, V> {
2376    fn deref_mut(&mut self) -> &mut Self::Target {
2377        self.app
2378    }
2379}
2380
2381impl<V: View> ReadModel for RenderContext<'_, V> {
2382    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2383        self.app.read_model(handle)
2384    }
2385}
2386
2387impl<V: View> UpdateModel for RenderContext<'_, V> {
2388    fn update_model<T: Entity, O>(
2389        &mut self,
2390        handle: &ModelHandle<T>,
2391        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
2392    ) -> O {
2393        self.app.update_model(handle, update)
2394    }
2395}
2396
2397impl<M> AsRef<AppContext> for ViewContext<'_, M> {
2398    fn as_ref(&self) -> &AppContext {
2399        &self.app.cx
2400    }
2401}
2402
2403impl<M> Deref for ViewContext<'_, M> {
2404    type Target = MutableAppContext;
2405
2406    fn deref(&self) -> &Self::Target {
2407        &self.app
2408    }
2409}
2410
2411impl<M> DerefMut for ViewContext<'_, M> {
2412    fn deref_mut(&mut self) -> &mut Self::Target {
2413        &mut self.app
2414    }
2415}
2416
2417impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
2418    fn as_mut(&mut self) -> &mut MutableAppContext {
2419        self.app
2420    }
2421}
2422
2423impl<V> ReadModel for ViewContext<'_, V> {
2424    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2425        self.app.read_model(handle)
2426    }
2427}
2428
2429impl<V> UpgradeModelHandle for ViewContext<'_, V> {
2430    fn upgrade_model_handle<T: Entity>(
2431        &self,
2432        handle: WeakModelHandle<T>,
2433    ) -> Option<ModelHandle<T>> {
2434        self.cx.upgrade_model_handle(handle)
2435    }
2436}
2437
2438impl<V: View> UpdateModel for ViewContext<'_, V> {
2439    fn update_model<T: Entity, O>(
2440        &mut self,
2441        handle: &ModelHandle<T>,
2442        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
2443    ) -> O {
2444        self.app.update_model(handle, update)
2445    }
2446}
2447
2448impl<V: View> ReadView for ViewContext<'_, V> {
2449    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2450        self.app.read_view(handle)
2451    }
2452}
2453
2454impl<V: View> UpdateView for ViewContext<'_, V> {
2455    fn update_view<T, S>(
2456        &mut self,
2457        handle: &ViewHandle<T>,
2458        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
2459    ) -> S
2460    where
2461        T: View,
2462    {
2463        self.app.update_view(handle, update)
2464    }
2465}
2466
2467pub trait Handle<T> {
2468    type Weak: 'static;
2469    fn id(&self) -> usize;
2470    fn location(&self) -> EntityLocation;
2471    fn downgrade(&self) -> Self::Weak;
2472    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2473    where
2474        Self: Sized;
2475}
2476
2477#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
2478pub enum EntityLocation {
2479    Model(usize),
2480    View(usize, usize),
2481}
2482
2483pub struct ModelHandle<T> {
2484    model_id: usize,
2485    model_type: PhantomData<T>,
2486    ref_counts: Arc<Mutex<RefCounts>>,
2487}
2488
2489impl<T: Entity> ModelHandle<T> {
2490    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2491        ref_counts.lock().inc_model(model_id);
2492        Self {
2493            model_id,
2494            model_type: PhantomData,
2495            ref_counts: ref_counts.clone(),
2496        }
2497    }
2498
2499    pub fn downgrade(&self) -> WeakModelHandle<T> {
2500        WeakModelHandle::new(self.model_id)
2501    }
2502
2503    pub fn id(&self) -> usize {
2504        self.model_id
2505    }
2506
2507    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
2508        cx.read_model(self)
2509    }
2510
2511    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
2512    where
2513        C: ReadModelWith,
2514        F: FnOnce(&T, &AppContext) -> S,
2515    {
2516        let mut read = Some(read);
2517        cx.read_model_with(self, &mut |model, cx| {
2518            let read = read.take().unwrap();
2519            read(model, cx)
2520        })
2521    }
2522
2523    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
2524    where
2525        C: UpdateModel,
2526        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
2527    {
2528        let mut update = Some(update);
2529        cx.update_model(self, &mut |model, cx| {
2530            let update = update.take().unwrap();
2531            update(model, cx)
2532        })
2533    }
2534
2535    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
2536        let (mut tx, mut rx) = mpsc::channel(1);
2537        let mut cx = cx.cx.borrow_mut();
2538        let subscription = cx.observe(self, move |_, _| {
2539            tx.blocking_send(()).ok();
2540        });
2541
2542        let duration = if std::env::var("CI").is_ok() {
2543            Duration::from_secs(5)
2544        } else {
2545            Duration::from_secs(1)
2546        };
2547
2548        async move {
2549            let notification = timeout(duration, rx.recv())
2550                .await
2551                .expect("next notification timed out");
2552            drop(subscription);
2553            notification.expect("model dropped while test was waiting for its next notification")
2554        }
2555    }
2556
2557    pub fn next_event(&self, cx: &TestAppContext) -> impl Future<Output = T::Event>
2558    where
2559        T::Event: Clone,
2560    {
2561        let (mut tx, mut rx) = mpsc::channel(1);
2562        let mut cx = cx.cx.borrow_mut();
2563        let subscription = cx.subscribe(self, move |_, event, _| {
2564            tx.blocking_send(event.clone()).ok();
2565        });
2566
2567        let duration = if std::env::var("CI").is_ok() {
2568            Duration::from_secs(5)
2569        } else {
2570            Duration::from_secs(1)
2571        };
2572
2573        async move {
2574            let event = timeout(duration, rx.recv())
2575                .await
2576                .expect("next event timed out");
2577            drop(subscription);
2578            event.expect("model dropped while test was waiting for its next event")
2579        }
2580    }
2581
2582    pub fn condition(
2583        &self,
2584        cx: &TestAppContext,
2585        mut predicate: impl FnMut(&T, &AppContext) -> bool,
2586    ) -> impl Future<Output = ()> {
2587        let (tx, mut rx) = mpsc::channel(1024);
2588
2589        let mut cx = cx.cx.borrow_mut();
2590        let subscriptions = (
2591            cx.observe(self, {
2592                let mut tx = tx.clone();
2593                move |_, _| {
2594                    tx.blocking_send(()).ok();
2595                }
2596            }),
2597            cx.subscribe(self, {
2598                let mut tx = tx.clone();
2599                move |_, _, _| {
2600                    tx.blocking_send(()).ok();
2601                }
2602            }),
2603        );
2604
2605        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
2606        let handle = self.downgrade();
2607        let duration = if std::env::var("CI").is_ok() {
2608            Duration::from_secs(5)
2609        } else {
2610            Duration::from_secs(1)
2611        };
2612
2613        async move {
2614            timeout(duration, async move {
2615                loop {
2616                    {
2617                        let cx = cx.borrow();
2618                        let cx = cx.as_ref();
2619                        if predicate(
2620                            handle
2621                                .upgrade(cx)
2622                                .expect("model dropped with pending condition")
2623                                .read(cx),
2624                            cx,
2625                        ) {
2626                            break;
2627                        }
2628                    }
2629
2630                    rx.recv()
2631                        .await
2632                        .expect("model dropped with pending condition");
2633                }
2634            })
2635            .await
2636            .expect("condition timed out");
2637            drop(subscriptions);
2638        }
2639    }
2640}
2641
2642impl<T> Clone for ModelHandle<T> {
2643    fn clone(&self) -> Self {
2644        self.ref_counts.lock().inc_model(self.model_id);
2645        Self {
2646            model_id: self.model_id,
2647            model_type: PhantomData,
2648            ref_counts: self.ref_counts.clone(),
2649        }
2650    }
2651}
2652
2653impl<T> PartialEq for ModelHandle<T> {
2654    fn eq(&self, other: &Self) -> bool {
2655        self.model_id == other.model_id
2656    }
2657}
2658
2659impl<T> Eq for ModelHandle<T> {}
2660
2661impl<T> Hash for ModelHandle<T> {
2662    fn hash<H: Hasher>(&self, state: &mut H) {
2663        self.model_id.hash(state);
2664    }
2665}
2666
2667impl<T> std::borrow::Borrow<usize> for ModelHandle<T> {
2668    fn borrow(&self) -> &usize {
2669        &self.model_id
2670    }
2671}
2672
2673impl<T> Debug for ModelHandle<T> {
2674    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2675        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
2676            .field(&self.model_id)
2677            .finish()
2678    }
2679}
2680
2681unsafe impl<T> Send for ModelHandle<T> {}
2682unsafe impl<T> Sync for ModelHandle<T> {}
2683
2684impl<T> Drop for ModelHandle<T> {
2685    fn drop(&mut self) {
2686        self.ref_counts.lock().dec_model(self.model_id);
2687    }
2688}
2689
2690impl<T: Entity> Handle<T> for ModelHandle<T> {
2691    type Weak = WeakModelHandle<T>;
2692
2693    fn id(&self) -> usize {
2694        self.model_id
2695    }
2696
2697    fn location(&self) -> EntityLocation {
2698        EntityLocation::Model(self.model_id)
2699    }
2700
2701    fn downgrade(&self) -> Self::Weak {
2702        self.downgrade()
2703    }
2704
2705    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2706    where
2707        Self: Sized,
2708    {
2709        weak.upgrade(cx)
2710    }
2711}
2712
2713pub struct WeakModelHandle<T> {
2714    model_id: usize,
2715    model_type: PhantomData<T>,
2716}
2717
2718unsafe impl<T> Send for WeakModelHandle<T> {}
2719unsafe impl<T> Sync for WeakModelHandle<T> {}
2720
2721impl<T: Entity> WeakModelHandle<T> {
2722    fn new(model_id: usize) -> Self {
2723        Self {
2724            model_id,
2725            model_type: PhantomData,
2726        }
2727    }
2728
2729    pub fn upgrade(self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
2730        cx.upgrade_model_handle(self)
2731    }
2732}
2733
2734impl<T> Hash for WeakModelHandle<T> {
2735    fn hash<H: Hasher>(&self, state: &mut H) {
2736        self.model_id.hash(state)
2737    }
2738}
2739
2740impl<T> PartialEq for WeakModelHandle<T> {
2741    fn eq(&self, other: &Self) -> bool {
2742        self.model_id == other.model_id
2743    }
2744}
2745
2746impl<T> Eq for WeakModelHandle<T> {}
2747
2748impl<T> Clone for WeakModelHandle<T> {
2749    fn clone(&self) -> Self {
2750        Self {
2751            model_id: self.model_id,
2752            model_type: PhantomData,
2753        }
2754    }
2755}
2756
2757impl<T> Copy for WeakModelHandle<T> {}
2758
2759pub struct ViewHandle<T> {
2760    window_id: usize,
2761    view_id: usize,
2762    view_type: PhantomData<T>,
2763    ref_counts: Arc<Mutex<RefCounts>>,
2764}
2765
2766impl<T: View> ViewHandle<T> {
2767    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
2768        ref_counts.lock().inc_view(window_id, view_id);
2769        Self {
2770            window_id,
2771            view_id,
2772            view_type: PhantomData,
2773            ref_counts: ref_counts.clone(),
2774        }
2775    }
2776
2777    pub fn downgrade(&self) -> WeakViewHandle<T> {
2778        WeakViewHandle::new(self.window_id, self.view_id)
2779    }
2780
2781    pub fn window_id(&self) -> usize {
2782        self.window_id
2783    }
2784
2785    pub fn id(&self) -> usize {
2786        self.view_id
2787    }
2788
2789    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
2790        cx.read_view(self)
2791    }
2792
2793    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
2794    where
2795        C: ReadViewWith,
2796        F: FnOnce(&T, &AppContext) -> S,
2797    {
2798        let mut read = Some(read);
2799        cx.read_view_with(self, &mut |view, cx| {
2800            let read = read.take().unwrap();
2801            read(view, cx)
2802        })
2803    }
2804
2805    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
2806    where
2807        C: UpdateView,
2808        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
2809    {
2810        let mut update = Some(update);
2811        cx.update_view(self, &mut |view, cx| {
2812            let update = update.take().unwrap();
2813            update(view, cx)
2814        })
2815    }
2816
2817    pub fn is_focused(&self, cx: &AppContext) -> bool {
2818        cx.focused_view_id(self.window_id)
2819            .map_or(false, |focused_id| focused_id == self.view_id)
2820    }
2821
2822    pub fn condition(
2823        &self,
2824        cx: &TestAppContext,
2825        mut predicate: impl FnMut(&T, &AppContext) -> bool,
2826    ) -> impl Future<Output = ()> {
2827        let (tx, mut rx) = mpsc::channel(1024);
2828
2829        let mut cx = cx.cx.borrow_mut();
2830        let subscriptions = self.update(&mut *cx, |_, cx| {
2831            (
2832                cx.observe(self, {
2833                    let mut tx = tx.clone();
2834                    move |_, _, _| {
2835                        tx.blocking_send(()).ok();
2836                    }
2837                }),
2838                cx.subscribe(self, {
2839                    let mut tx = tx.clone();
2840                    move |_, _, _, _| {
2841                        tx.blocking_send(()).ok();
2842                    }
2843                }),
2844            )
2845        });
2846
2847        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
2848        let handle = self.downgrade();
2849        let duration = if std::env::var("CI").is_ok() {
2850            Duration::from_secs(2)
2851        } else {
2852            Duration::from_millis(500)
2853        };
2854
2855        async move {
2856            timeout(duration, async move {
2857                loop {
2858                    {
2859                        let cx = cx.borrow();
2860                        let cx = cx.as_ref();
2861                        if predicate(
2862                            handle
2863                                .upgrade(cx)
2864                                .expect("view dropped with pending condition")
2865                                .read(cx),
2866                            cx,
2867                        ) {
2868                            break;
2869                        }
2870                    }
2871
2872                    rx.recv()
2873                        .await
2874                        .expect("view dropped with pending condition");
2875                }
2876            })
2877            .await
2878            .expect("condition timed out");
2879            drop(subscriptions);
2880        }
2881    }
2882}
2883
2884impl<T> Clone for ViewHandle<T> {
2885    fn clone(&self) -> Self {
2886        self.ref_counts
2887            .lock()
2888            .inc_view(self.window_id, self.view_id);
2889        Self {
2890            window_id: self.window_id,
2891            view_id: self.view_id,
2892            view_type: PhantomData,
2893            ref_counts: self.ref_counts.clone(),
2894        }
2895    }
2896}
2897
2898impl<T> PartialEq for ViewHandle<T> {
2899    fn eq(&self, other: &Self) -> bool {
2900        self.window_id == other.window_id && self.view_id == other.view_id
2901    }
2902}
2903
2904impl<T> Eq for ViewHandle<T> {}
2905
2906impl<T> Debug for ViewHandle<T> {
2907    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2908        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
2909            .field("window_id", &self.window_id)
2910            .field("view_id", &self.view_id)
2911            .finish()
2912    }
2913}
2914
2915impl<T> Drop for ViewHandle<T> {
2916    fn drop(&mut self) {
2917        self.ref_counts
2918            .lock()
2919            .dec_view(self.window_id, self.view_id);
2920    }
2921}
2922
2923impl<T: View> Handle<T> for ViewHandle<T> {
2924    type Weak = WeakViewHandle<T>;
2925
2926    fn id(&self) -> usize {
2927        self.view_id
2928    }
2929
2930    fn location(&self) -> EntityLocation {
2931        EntityLocation::View(self.window_id, self.view_id)
2932    }
2933
2934    fn downgrade(&self) -> Self::Weak {
2935        self.downgrade()
2936    }
2937
2938    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
2939    where
2940        Self: Sized,
2941    {
2942        weak.upgrade(cx)
2943    }
2944}
2945
2946pub struct AnyViewHandle {
2947    window_id: usize,
2948    view_id: usize,
2949    view_type: TypeId,
2950    ref_counts: Arc<Mutex<RefCounts>>,
2951}
2952
2953impl AnyViewHandle {
2954    pub fn id(&self) -> usize {
2955        self.view_id
2956    }
2957
2958    pub fn is<T: 'static>(&self) -> bool {
2959        TypeId::of::<T>() == self.view_type
2960    }
2961
2962    pub fn is_focused(&self, cx: &AppContext) -> bool {
2963        cx.focused_view_id(self.window_id)
2964            .map_or(false, |focused_id| focused_id == self.view_id)
2965    }
2966
2967    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
2968        if self.is::<T>() {
2969            let result = Some(ViewHandle {
2970                window_id: self.window_id,
2971                view_id: self.view_id,
2972                ref_counts: self.ref_counts.clone(),
2973                view_type: PhantomData,
2974            });
2975            unsafe {
2976                Arc::decrement_strong_count(&self.ref_counts);
2977            }
2978            std::mem::forget(self);
2979            result
2980        } else {
2981            None
2982        }
2983    }
2984}
2985
2986impl Clone for AnyViewHandle {
2987    fn clone(&self) -> Self {
2988        self.ref_counts
2989            .lock()
2990            .inc_view(self.window_id, self.view_id);
2991        Self {
2992            window_id: self.window_id,
2993            view_id: self.view_id,
2994            view_type: self.view_type,
2995            ref_counts: self.ref_counts.clone(),
2996        }
2997    }
2998}
2999
3000impl From<&AnyViewHandle> for AnyViewHandle {
3001    fn from(handle: &AnyViewHandle) -> Self {
3002        handle.clone()
3003    }
3004}
3005
3006impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
3007    fn from(handle: &ViewHandle<T>) -> Self {
3008        handle
3009            .ref_counts
3010            .lock()
3011            .inc_view(handle.window_id, handle.view_id);
3012        AnyViewHandle {
3013            window_id: handle.window_id,
3014            view_id: handle.view_id,
3015            view_type: TypeId::of::<T>(),
3016            ref_counts: handle.ref_counts.clone(),
3017        }
3018    }
3019}
3020
3021impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
3022    fn from(handle: ViewHandle<T>) -> Self {
3023        let any_handle = AnyViewHandle {
3024            window_id: handle.window_id,
3025            view_id: handle.view_id,
3026            view_type: TypeId::of::<T>(),
3027            ref_counts: handle.ref_counts.clone(),
3028        };
3029        unsafe {
3030            Arc::decrement_strong_count(&handle.ref_counts);
3031        }
3032        std::mem::forget(handle);
3033        any_handle
3034    }
3035}
3036
3037impl Drop for AnyViewHandle {
3038    fn drop(&mut self) {
3039        self.ref_counts
3040            .lock()
3041            .dec_view(self.window_id, self.view_id);
3042    }
3043}
3044
3045pub struct AnyModelHandle {
3046    model_id: usize,
3047    ref_counts: Arc<Mutex<RefCounts>>,
3048}
3049
3050impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
3051    fn from(handle: ModelHandle<T>) -> Self {
3052        handle.ref_counts.lock().inc_model(handle.model_id);
3053        Self {
3054            model_id: handle.model_id,
3055            ref_counts: handle.ref_counts.clone(),
3056        }
3057    }
3058}
3059
3060impl Drop for AnyModelHandle {
3061    fn drop(&mut self) {
3062        self.ref_counts.lock().dec_model(self.model_id);
3063    }
3064}
3065pub struct WeakViewHandle<T> {
3066    window_id: usize,
3067    view_id: usize,
3068    view_type: PhantomData<T>,
3069}
3070
3071impl<T: View> WeakViewHandle<T> {
3072    fn new(window_id: usize, view_id: usize) -> Self {
3073        Self {
3074            window_id,
3075            view_id,
3076            view_type: PhantomData,
3077        }
3078    }
3079
3080    pub fn id(&self) -> usize {
3081        self.view_id
3082    }
3083
3084    pub fn upgrade(&self, cx: &AppContext) -> Option<ViewHandle<T>> {
3085        if cx.ref_counts.lock().is_entity_alive(self.view_id) {
3086            Some(ViewHandle::new(
3087                self.window_id,
3088                self.view_id,
3089                &cx.ref_counts,
3090            ))
3091        } else {
3092            None
3093        }
3094    }
3095}
3096
3097impl<T> Clone for WeakViewHandle<T> {
3098    fn clone(&self) -> Self {
3099        Self {
3100            window_id: self.window_id,
3101            view_id: self.view_id,
3102            view_type: PhantomData,
3103        }
3104    }
3105}
3106
3107#[derive(Clone, Copy, PartialEq, Eq, Hash)]
3108pub struct ElementStateId(usize, usize);
3109
3110impl From<usize> for ElementStateId {
3111    fn from(id: usize) -> Self {
3112        Self(id, 0)
3113    }
3114}
3115
3116impl From<(usize, usize)> for ElementStateId {
3117    fn from(id: (usize, usize)) -> Self {
3118        Self(id.0, id.1)
3119    }
3120}
3121
3122pub struct ElementStateHandle<T> {
3123    value_type: PhantomData<T>,
3124    tag_type_id: TypeId,
3125    id: ElementStateId,
3126    ref_counts: Weak<Mutex<RefCounts>>,
3127}
3128
3129impl<T: 'static> ElementStateHandle<T> {
3130    fn new(tag_type_id: TypeId, id: ElementStateId, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3131        ref_counts.lock().inc_element_state(tag_type_id, id);
3132        Self {
3133            value_type: PhantomData,
3134            tag_type_id,
3135            id,
3136            ref_counts: Arc::downgrade(ref_counts),
3137        }
3138    }
3139
3140    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
3141        cx.element_states
3142            .get(&(self.tag_type_id, self.id))
3143            .unwrap()
3144            .downcast_ref()
3145            .unwrap()
3146    }
3147
3148    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
3149    where
3150        C: DerefMut<Target = MutableAppContext>,
3151    {
3152        let mut element_state = cx
3153            .deref_mut()
3154            .cx
3155            .element_states
3156            .remove(&(self.tag_type_id, self.id))
3157            .unwrap();
3158        let result = f(element_state.downcast_mut().unwrap(), cx);
3159        cx.deref_mut()
3160            .cx
3161            .element_states
3162            .insert((self.tag_type_id, self.id), element_state);
3163        result
3164    }
3165}
3166
3167impl<T> Drop for ElementStateHandle<T> {
3168    fn drop(&mut self) {
3169        if let Some(ref_counts) = self.ref_counts.upgrade() {
3170            ref_counts
3171                .lock()
3172                .dec_element_state(self.tag_type_id, self.id);
3173        }
3174    }
3175}
3176
3177pub struct CursorStyleHandle {
3178    id: usize,
3179    next_cursor_style_handle_id: Arc<AtomicUsize>,
3180    platform: Arc<dyn Platform>,
3181}
3182
3183impl Drop for CursorStyleHandle {
3184    fn drop(&mut self) {
3185        if self.id + 1 == self.next_cursor_style_handle_id.load(SeqCst) {
3186            self.platform.set_cursor_style(CursorStyle::Arrow);
3187        }
3188    }
3189}
3190
3191#[must_use]
3192pub enum Subscription {
3193    Subscription {
3194        id: usize,
3195        entity_id: usize,
3196        subscriptions: Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, SubscriptionCallback>>>>>,
3197    },
3198    Observation {
3199        id: usize,
3200        entity_id: usize,
3201        observations: Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ObservationCallback>>>>>,
3202    },
3203}
3204
3205impl Subscription {
3206    pub fn detach(&mut self) {
3207        match self {
3208            Subscription::Subscription { subscriptions, .. } => {
3209                subscriptions.take();
3210            }
3211            Subscription::Observation { observations, .. } => {
3212                observations.take();
3213            }
3214        }
3215    }
3216}
3217
3218impl Drop for Subscription {
3219    fn drop(&mut self) {
3220        match self {
3221            Subscription::Observation {
3222                id,
3223                entity_id,
3224                observations,
3225            } => {
3226                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
3227                    if let Some(observations) = observations.lock().get_mut(entity_id) {
3228                        observations.remove(id);
3229                    }
3230                }
3231            }
3232            Subscription::Subscription {
3233                id,
3234                entity_id,
3235                subscriptions,
3236            } => {
3237                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
3238                    if let Some(subscriptions) = subscriptions.lock().get_mut(entity_id) {
3239                        subscriptions.remove(id);
3240                    }
3241                }
3242            }
3243        }
3244    }
3245}
3246
3247#[derive(Default)]
3248struct RefCounts {
3249    entity_counts: HashMap<usize, usize>,
3250    element_state_counts: HashMap<(TypeId, ElementStateId), usize>,
3251    dropped_models: HashSet<usize>,
3252    dropped_views: HashSet<(usize, usize)>,
3253    dropped_element_states: HashSet<(TypeId, ElementStateId)>,
3254}
3255
3256impl RefCounts {
3257    fn inc_model(&mut self, model_id: usize) {
3258        match self.entity_counts.entry(model_id) {
3259            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
3260            Entry::Vacant(entry) => {
3261                entry.insert(1);
3262                self.dropped_models.remove(&model_id);
3263            }
3264        }
3265    }
3266
3267    fn inc_view(&mut self, window_id: usize, view_id: usize) {
3268        match self.entity_counts.entry(view_id) {
3269            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
3270            Entry::Vacant(entry) => {
3271                entry.insert(1);
3272                self.dropped_views.remove(&(window_id, view_id));
3273            }
3274        }
3275    }
3276
3277    fn inc_element_state(&mut self, tag_type_id: TypeId, id: ElementStateId) {
3278        match self.element_state_counts.entry((tag_type_id, id)) {
3279            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
3280            Entry::Vacant(entry) => {
3281                entry.insert(1);
3282                self.dropped_element_states.remove(&(tag_type_id, id));
3283            }
3284        }
3285    }
3286
3287    fn dec_model(&mut self, model_id: usize) {
3288        let count = self.entity_counts.get_mut(&model_id).unwrap();
3289        *count -= 1;
3290        if *count == 0 {
3291            self.entity_counts.remove(&model_id);
3292            self.dropped_models.insert(model_id);
3293        }
3294    }
3295
3296    fn dec_view(&mut self, window_id: usize, view_id: usize) {
3297        let count = self.entity_counts.get_mut(&view_id).unwrap();
3298        *count -= 1;
3299        if *count == 0 {
3300            self.entity_counts.remove(&view_id);
3301            self.dropped_views.insert((window_id, view_id));
3302        }
3303    }
3304
3305    fn dec_element_state(&mut self, tag_type_id: TypeId, id: ElementStateId) {
3306        let key = (tag_type_id, id);
3307        let count = self.element_state_counts.get_mut(&key).unwrap();
3308        *count -= 1;
3309        if *count == 0 {
3310            self.element_state_counts.remove(&key);
3311            self.dropped_element_states.insert(key);
3312        }
3313    }
3314
3315    fn is_entity_alive(&self, entity_id: usize) -> bool {
3316        self.entity_counts.contains_key(&entity_id)
3317    }
3318
3319    fn take_dropped(
3320        &mut self,
3321    ) -> (
3322        HashSet<usize>,
3323        HashSet<(usize, usize)>,
3324        HashSet<(TypeId, ElementStateId)>,
3325    ) {
3326        let mut dropped_models = HashSet::new();
3327        let mut dropped_views = HashSet::new();
3328        let mut dropped_element_states = HashSet::new();
3329        std::mem::swap(&mut self.dropped_models, &mut dropped_models);
3330        std::mem::swap(&mut self.dropped_views, &mut dropped_views);
3331        std::mem::swap(
3332            &mut self.dropped_element_states,
3333            &mut dropped_element_states,
3334        );
3335        (dropped_models, dropped_views, dropped_element_states)
3336    }
3337}
3338
3339#[cfg(test)]
3340mod tests {
3341    use super::*;
3342    use crate::elements::*;
3343    use smol::future::poll_once;
3344    use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
3345
3346    #[crate::test(self)]
3347    fn test_model_handles(cx: &mut MutableAppContext) {
3348        struct Model {
3349            other: Option<ModelHandle<Model>>,
3350            events: Vec<String>,
3351        }
3352
3353        impl Entity for Model {
3354            type Event = usize;
3355        }
3356
3357        impl Model {
3358            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
3359                if let Some(other) = other.as_ref() {
3360                    cx.observe(other, |me, _, _| {
3361                        me.events.push("notified".into());
3362                    })
3363                    .detach();
3364                    cx.subscribe(other, |me, _, event, _| {
3365                        me.events.push(format!("observed event {}", event));
3366                    })
3367                    .detach();
3368                }
3369
3370                Self {
3371                    other,
3372                    events: Vec::new(),
3373                }
3374            }
3375        }
3376
3377        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
3378        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
3379        assert_eq!(cx.cx.models.len(), 2);
3380
3381        handle_1.update(cx, |model, cx| {
3382            model.events.push("updated".into());
3383            cx.emit(1);
3384            cx.notify();
3385            cx.emit(2);
3386        });
3387        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
3388        assert_eq!(
3389            handle_2.read(cx).events,
3390            vec![
3391                "observed event 1".to_string(),
3392                "notified".to_string(),
3393                "observed event 2".to_string(),
3394            ]
3395        );
3396
3397        handle_2.update(cx, |model, _| {
3398            drop(handle_1);
3399            model.other.take();
3400        });
3401
3402        assert_eq!(cx.cx.models.len(), 1);
3403        assert!(cx.subscriptions.lock().is_empty());
3404        assert!(cx.observations.lock().is_empty());
3405    }
3406
3407    #[crate::test(self)]
3408    fn test_subscribe_and_emit_from_model(cx: &mut MutableAppContext) {
3409        #[derive(Default)]
3410        struct Model {
3411            events: Vec<usize>,
3412        }
3413
3414        impl Entity for Model {
3415            type Event = usize;
3416        }
3417
3418        let handle_1 = cx.add_model(|_| Model::default());
3419        let handle_2 = cx.add_model(|_| Model::default());
3420        let handle_2b = handle_2.clone();
3421
3422        handle_1.update(cx, |_, c| {
3423            c.subscribe(&handle_2, move |model: &mut Model, _, event, c| {
3424                model.events.push(*event);
3425
3426                c.subscribe(&handle_2b, |model, _, event, _| {
3427                    model.events.push(*event * 2);
3428                })
3429                .detach();
3430            })
3431            .detach();
3432        });
3433
3434        handle_2.update(cx, |_, c| c.emit(7));
3435        assert_eq!(handle_1.read(cx).events, vec![7]);
3436
3437        handle_2.update(cx, |_, c| c.emit(5));
3438        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
3439    }
3440
3441    #[crate::test(self)]
3442    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
3443        #[derive(Default)]
3444        struct Model {
3445            count: usize,
3446            events: Vec<usize>,
3447        }
3448
3449        impl Entity for Model {
3450            type Event = ();
3451        }
3452
3453        let handle_1 = cx.add_model(|_| Model::default());
3454        let handle_2 = cx.add_model(|_| Model::default());
3455        let handle_2b = handle_2.clone();
3456
3457        handle_1.update(cx, |_, c| {
3458            c.observe(&handle_2, move |model, observed, c| {
3459                model.events.push(observed.read(c).count);
3460                c.observe(&handle_2b, |model, observed, c| {
3461                    model.events.push(observed.read(c).count * 2);
3462                })
3463                .detach();
3464            })
3465            .detach();
3466        });
3467
3468        handle_2.update(cx, |model, c| {
3469            model.count = 7;
3470            c.notify()
3471        });
3472        assert_eq!(handle_1.read(cx).events, vec![7]);
3473
3474        handle_2.update(cx, |model, c| {
3475            model.count = 5;
3476            c.notify()
3477        });
3478        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
3479    }
3480
3481    #[crate::test(self)]
3482    fn test_view_handles(cx: &mut MutableAppContext) {
3483        struct View {
3484            other: Option<ViewHandle<View>>,
3485            events: Vec<String>,
3486        }
3487
3488        impl Entity for View {
3489            type Event = usize;
3490        }
3491
3492        impl super::View for View {
3493            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3494                Empty::new().boxed()
3495            }
3496
3497            fn ui_name() -> &'static str {
3498                "View"
3499            }
3500        }
3501
3502        impl View {
3503            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
3504                if let Some(other) = other.as_ref() {
3505                    cx.subscribe(other, |me, _, event, _| {
3506                        me.events.push(format!("observed event {}", event));
3507                    })
3508                    .detach();
3509                }
3510                Self {
3511                    other,
3512                    events: Vec::new(),
3513                }
3514            }
3515        }
3516
3517        let (window_id, _) = cx.add_window(Default::default(), |cx| View::new(None, cx));
3518        let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
3519        let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
3520        assert_eq!(cx.cx.views.len(), 3);
3521
3522        handle_1.update(cx, |view, cx| {
3523            view.events.push("updated".into());
3524            cx.emit(1);
3525            cx.emit(2);
3526        });
3527        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
3528        assert_eq!(
3529            handle_2.read(cx).events,
3530            vec![
3531                "observed event 1".to_string(),
3532                "observed event 2".to_string(),
3533            ]
3534        );
3535
3536        handle_2.update(cx, |view, _| {
3537            drop(handle_1);
3538            view.other.take();
3539        });
3540
3541        assert_eq!(cx.cx.views.len(), 2);
3542        assert!(cx.subscriptions.lock().is_empty());
3543        assert!(cx.observations.lock().is_empty());
3544    }
3545
3546    #[crate::test(self)]
3547    fn test_add_window(cx: &mut MutableAppContext) {
3548        struct View {
3549            mouse_down_count: Arc<AtomicUsize>,
3550        }
3551
3552        impl Entity for View {
3553            type Event = ();
3554        }
3555
3556        impl super::View for View {
3557            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3558                let mouse_down_count = self.mouse_down_count.clone();
3559                EventHandler::new(Empty::new().boxed())
3560                    .on_mouse_down(move |_| {
3561                        mouse_down_count.fetch_add(1, SeqCst);
3562                        true
3563                    })
3564                    .boxed()
3565            }
3566
3567            fn ui_name() -> &'static str {
3568                "View"
3569            }
3570        }
3571
3572        let mouse_down_count = Arc::new(AtomicUsize::new(0));
3573        let (window_id, _) = cx.add_window(Default::default(), |_| View {
3574            mouse_down_count: mouse_down_count.clone(),
3575        });
3576        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
3577        // Ensure window's root element is in a valid lifecycle state.
3578        presenter.borrow_mut().dispatch_event(
3579            Event::LeftMouseDown {
3580                position: Default::default(),
3581                cmd: false,
3582            },
3583            cx,
3584        );
3585        assert_eq!(mouse_down_count.load(SeqCst), 1);
3586    }
3587
3588    #[crate::test(self)]
3589    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
3590        struct Model {
3591            released: Arc<Mutex<bool>>,
3592        }
3593
3594        struct View {
3595            released: Arc<Mutex<bool>>,
3596        }
3597
3598        impl Entity for Model {
3599            type Event = ();
3600
3601            fn release(&mut self, _: &mut MutableAppContext) {
3602                *self.released.lock() = true;
3603            }
3604        }
3605
3606        impl Entity for View {
3607            type Event = ();
3608
3609            fn release(&mut self, _: &mut MutableAppContext) {
3610                *self.released.lock() = true;
3611            }
3612        }
3613
3614        impl super::View for View {
3615            fn ui_name() -> &'static str {
3616                "View"
3617            }
3618
3619            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3620                Empty::new().boxed()
3621            }
3622        }
3623
3624        let model_released = Arc::new(Mutex::new(false));
3625        let view_released = Arc::new(Mutex::new(false));
3626
3627        let model = cx.add_model(|_| Model {
3628            released: model_released.clone(),
3629        });
3630
3631        let (window_id, _) = cx.add_window(Default::default(), |_| View {
3632            released: view_released.clone(),
3633        });
3634
3635        assert!(!*model_released.lock());
3636        assert!(!*view_released.lock());
3637
3638        cx.update(move || {
3639            drop(model);
3640        });
3641        assert!(*model_released.lock());
3642
3643        drop(cx.remove_window(window_id));
3644        assert!(*view_released.lock());
3645    }
3646
3647    #[crate::test(self)]
3648    fn test_subscribe_and_emit_from_view(cx: &mut MutableAppContext) {
3649        #[derive(Default)]
3650        struct View {
3651            events: Vec<usize>,
3652        }
3653
3654        impl Entity for View {
3655            type Event = usize;
3656        }
3657
3658        impl super::View for View {
3659            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3660                Empty::new().boxed()
3661            }
3662
3663            fn ui_name() -> &'static str {
3664                "View"
3665            }
3666        }
3667
3668        struct Model;
3669
3670        impl Entity for Model {
3671            type Event = usize;
3672        }
3673
3674        let (window_id, handle_1) = cx.add_window(Default::default(), |_| View::default());
3675        let handle_2 = cx.add_view(window_id, |_| View::default());
3676        let handle_2b = handle_2.clone();
3677        let handle_3 = cx.add_model(|_| Model);
3678
3679        handle_1.update(cx, |_, c| {
3680            c.subscribe(&handle_2, move |me, _, event, c| {
3681                me.events.push(*event);
3682
3683                c.subscribe(&handle_2b, |me, _, event, _| {
3684                    me.events.push(*event * 2);
3685                })
3686                .detach();
3687            })
3688            .detach();
3689
3690            c.subscribe(&handle_3, |me, _, event, _| {
3691                me.events.push(*event);
3692            })
3693            .detach();
3694        });
3695
3696        handle_2.update(cx, |_, c| c.emit(7));
3697        assert_eq!(handle_1.read(cx).events, vec![7]);
3698
3699        handle_2.update(cx, |_, c| c.emit(5));
3700        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
3701
3702        handle_3.update(cx, |_, c| c.emit(9));
3703        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
3704    }
3705
3706    #[crate::test(self)]
3707    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
3708        struct View;
3709
3710        impl Entity for View {
3711            type Event = ();
3712        }
3713
3714        impl super::View for View {
3715            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3716                Empty::new().boxed()
3717            }
3718
3719            fn ui_name() -> &'static str {
3720                "View"
3721            }
3722        }
3723
3724        struct Model;
3725
3726        impl Entity for Model {
3727            type Event = ();
3728        }
3729
3730        let (window_id, _) = cx.add_window(Default::default(), |_| View);
3731        let observing_view = cx.add_view(window_id, |_| View);
3732        let emitting_view = cx.add_view(window_id, |_| View);
3733        let observing_model = cx.add_model(|_| Model);
3734        let observed_model = cx.add_model(|_| Model);
3735
3736        observing_view.update(cx, |_, cx| {
3737            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
3738            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
3739        });
3740        observing_model.update(cx, |_, cx| {
3741            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
3742        });
3743
3744        cx.update(|| {
3745            drop(observing_view);
3746            drop(observing_model);
3747        });
3748
3749        emitting_view.update(cx, |_, cx| cx.emit(()));
3750        observed_model.update(cx, |_, cx| cx.emit(()));
3751    }
3752
3753    #[crate::test(self)]
3754    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
3755        #[derive(Default)]
3756        struct View {
3757            events: Vec<usize>,
3758        }
3759
3760        impl Entity for View {
3761            type Event = usize;
3762        }
3763
3764        impl super::View for View {
3765            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3766                Empty::new().boxed()
3767            }
3768
3769            fn ui_name() -> &'static str {
3770                "View"
3771            }
3772        }
3773
3774        #[derive(Default)]
3775        struct Model {
3776            count: usize,
3777        }
3778
3779        impl Entity for Model {
3780            type Event = ();
3781        }
3782
3783        let (_, view) = cx.add_window(Default::default(), |_| View::default());
3784        let model = cx.add_model(|_| Model::default());
3785
3786        view.update(cx, |_, c| {
3787            c.observe(&model, |me, observed, c| {
3788                me.events.push(observed.read(c).count)
3789            })
3790            .detach();
3791        });
3792
3793        model.update(cx, |model, c| {
3794            model.count = 11;
3795            c.notify();
3796        });
3797        assert_eq!(view.read(cx).events, vec![11]);
3798    }
3799
3800    #[crate::test(self)]
3801    fn test_dropping_observers(cx: &mut MutableAppContext) {
3802        struct View;
3803
3804        impl Entity for View {
3805            type Event = ();
3806        }
3807
3808        impl super::View for View {
3809            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3810                Empty::new().boxed()
3811            }
3812
3813            fn ui_name() -> &'static str {
3814                "View"
3815            }
3816        }
3817
3818        struct Model;
3819
3820        impl Entity for Model {
3821            type Event = ();
3822        }
3823
3824        let (window_id, _) = cx.add_window(Default::default(), |_| View);
3825        let observing_view = cx.add_view(window_id, |_| View);
3826        let observing_model = cx.add_model(|_| Model);
3827        let observed_model = cx.add_model(|_| Model);
3828
3829        observing_view.update(cx, |_, cx| {
3830            cx.observe(&observed_model, |_, _, _| {}).detach();
3831        });
3832        observing_model.update(cx, |_, cx| {
3833            cx.observe(&observed_model, |_, _, _| {}).detach();
3834        });
3835
3836        cx.update(|| {
3837            drop(observing_view);
3838            drop(observing_model);
3839        });
3840
3841        observed_model.update(cx, |_, cx| cx.notify());
3842    }
3843
3844    #[crate::test(self)]
3845    fn test_focus(cx: &mut MutableAppContext) {
3846        struct View {
3847            name: String,
3848            events: Arc<Mutex<Vec<String>>>,
3849        }
3850
3851        impl Entity for View {
3852            type Event = ();
3853        }
3854
3855        impl super::View for View {
3856            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3857                Empty::new().boxed()
3858            }
3859
3860            fn ui_name() -> &'static str {
3861                "View"
3862            }
3863
3864            fn on_focus(&mut self, _: &mut ViewContext<Self>) {
3865                self.events.lock().push(format!("{} focused", &self.name));
3866            }
3867
3868            fn on_blur(&mut self, _: &mut ViewContext<Self>) {
3869                self.events.lock().push(format!("{} blurred", &self.name));
3870            }
3871        }
3872
3873        let events: Arc<Mutex<Vec<String>>> = Default::default();
3874        let (window_id, view_1) = cx.add_window(Default::default(), |_| View {
3875            events: events.clone(),
3876            name: "view 1".to_string(),
3877        });
3878        let view_2 = cx.add_view(window_id, |_| View {
3879            events: events.clone(),
3880            name: "view 2".to_string(),
3881        });
3882
3883        view_1.update(cx, |_, cx| cx.focus(&view_2));
3884        view_1.update(cx, |_, cx| cx.focus(&view_1));
3885        view_1.update(cx, |_, cx| cx.focus(&view_2));
3886        view_1.update(cx, |_, _| drop(view_2));
3887
3888        assert_eq!(
3889            *events.lock(),
3890            [
3891                "view 1 focused".to_string(),
3892                "view 1 blurred".to_string(),
3893                "view 2 focused".to_string(),
3894                "view 2 blurred".to_string(),
3895                "view 1 focused".to_string(),
3896                "view 1 blurred".to_string(),
3897                "view 2 focused".to_string(),
3898                "view 1 focused".to_string(),
3899            ],
3900        );
3901    }
3902
3903    #[crate::test(self)]
3904    fn test_dispatch_action(cx: &mut MutableAppContext) {
3905        struct ViewA {
3906            id: usize,
3907        }
3908
3909        impl Entity for ViewA {
3910            type Event = ();
3911        }
3912
3913        impl View for ViewA {
3914            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3915                Empty::new().boxed()
3916            }
3917
3918            fn ui_name() -> &'static str {
3919                "View"
3920            }
3921        }
3922
3923        struct ViewB {
3924            id: usize,
3925        }
3926
3927        impl Entity for ViewB {
3928            type Event = ();
3929        }
3930
3931        impl View for ViewB {
3932            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
3933                Empty::new().boxed()
3934            }
3935
3936            fn ui_name() -> &'static str {
3937                "View"
3938            }
3939        }
3940
3941        action!(Action, &'static str);
3942
3943        let actions = Rc::new(RefCell::new(Vec::new()));
3944
3945        let actions_clone = actions.clone();
3946        cx.add_global_action(move |_: &Action, _: &mut MutableAppContext| {
3947            actions_clone.borrow_mut().push("global a".to_string());
3948        });
3949
3950        let actions_clone = actions.clone();
3951        cx.add_global_action(move |_: &Action, _: &mut MutableAppContext| {
3952            actions_clone.borrow_mut().push("global b".to_string());
3953        });
3954
3955        let actions_clone = actions.clone();
3956        cx.add_action(move |view: &mut ViewA, action: &Action, cx| {
3957            assert_eq!(action.0, "bar");
3958            cx.propagate_action();
3959            actions_clone.borrow_mut().push(format!("{} a", view.id));
3960        });
3961
3962        let actions_clone = actions.clone();
3963        cx.add_action(move |view: &mut ViewA, _: &Action, cx| {
3964            if view.id != 1 {
3965                cx.propagate_action();
3966            }
3967            actions_clone.borrow_mut().push(format!("{} b", view.id));
3968        });
3969
3970        let actions_clone = actions.clone();
3971        cx.add_action(move |view: &mut ViewB, _: &Action, cx| {
3972            cx.propagate_action();
3973            actions_clone.borrow_mut().push(format!("{} c", view.id));
3974        });
3975
3976        let actions_clone = actions.clone();
3977        cx.add_action(move |view: &mut ViewB, _: &Action, cx| {
3978            cx.propagate_action();
3979            actions_clone.borrow_mut().push(format!("{} d", view.id));
3980        });
3981
3982        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
3983        let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 });
3984        let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 });
3985        let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 });
3986
3987        cx.dispatch_action(
3988            window_id,
3989            vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()],
3990            &Action("bar"),
3991        );
3992
3993        assert_eq!(
3994            *actions.borrow(),
3995            vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "1 b"]
3996        );
3997
3998        // Remove view_1, which doesn't propagate the action
3999        actions.borrow_mut().clear();
4000        cx.dispatch_action(
4001            window_id,
4002            vec![view_2.id(), view_3.id(), view_4.id()],
4003            &Action("bar"),
4004        );
4005
4006        assert_eq!(
4007            *actions.borrow(),
4008            vec!["4 d", "4 c", "3 b", "3 a", "2 d", "2 c", "global b", "global a"]
4009        );
4010    }
4011
4012    #[crate::test(self)]
4013    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
4014        use std::cell::Cell;
4015
4016        action!(Action, &'static str);
4017
4018        struct View {
4019            id: usize,
4020            keymap_context: keymap::Context,
4021        }
4022
4023        impl Entity for View {
4024            type Event = ();
4025        }
4026
4027        impl super::View for View {
4028            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4029                Empty::new().boxed()
4030            }
4031
4032            fn ui_name() -> &'static str {
4033                "View"
4034            }
4035
4036            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
4037                self.keymap_context.clone()
4038            }
4039        }
4040
4041        impl View {
4042            fn new(id: usize) -> Self {
4043                View {
4044                    id,
4045                    keymap_context: keymap::Context::default(),
4046                }
4047            }
4048        }
4049
4050        let mut view_1 = View::new(1);
4051        let mut view_2 = View::new(2);
4052        let mut view_3 = View::new(3);
4053        view_1.keymap_context.set.insert("a".into());
4054        view_2.keymap_context.set.insert("b".into());
4055        view_3.keymap_context.set.insert("c".into());
4056
4057        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
4058        let view_2 = cx.add_view(window_id, |_| view_2);
4059        let view_3 = cx.add_view(window_id, |_| view_3);
4060
4061        // This keymap's only binding dispatches an action on view 2 because that view will have
4062        // "a" and "b" in its context, but not "c".
4063        cx.add_bindings(vec![keymap::Binding::new(
4064            "a",
4065            Action("a"),
4066            Some("a && b && !c"),
4067        )]);
4068
4069        let handled_action = Rc::new(Cell::new(false));
4070        let handled_action_clone = handled_action.clone();
4071        cx.add_action(move |view: &mut View, action: &Action, _| {
4072            handled_action_clone.set(true);
4073            assert_eq!(view.id, 2);
4074            assert_eq!(action.0, "a");
4075        });
4076
4077        cx.dispatch_keystroke(
4078            window_id,
4079            vec![view_1.id(), view_2.id(), view_3.id()],
4080            &Keystroke::parse("a").unwrap(),
4081        )
4082        .unwrap();
4083
4084        assert!(handled_action.get());
4085    }
4086
4087    #[crate::test(self)]
4088    async fn test_model_condition(mut cx: TestAppContext) {
4089        struct Counter(usize);
4090
4091        impl super::Entity for Counter {
4092            type Event = ();
4093        }
4094
4095        impl Counter {
4096            fn inc(&mut self, cx: &mut ModelContext<Self>) {
4097                self.0 += 1;
4098                cx.notify();
4099            }
4100        }
4101
4102        let model = cx.add_model(|_| Counter(0));
4103
4104        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
4105        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
4106        smol::pin!(condition1, condition2);
4107
4108        model.update(&mut cx, |model, cx| model.inc(cx));
4109        assert_eq!(poll_once(&mut condition1).await, None);
4110        assert_eq!(poll_once(&mut condition2).await, None);
4111
4112        model.update(&mut cx, |model, cx| model.inc(cx));
4113        assert_eq!(poll_once(&mut condition1).await, Some(()));
4114        assert_eq!(poll_once(&mut condition2).await, None);
4115
4116        model.update(&mut cx, |model, cx| model.inc(cx));
4117        assert_eq!(poll_once(&mut condition2).await, Some(()));
4118
4119        model.update(&mut cx, |_, cx| cx.notify());
4120    }
4121
4122    #[crate::test(self)]
4123    #[should_panic]
4124    async fn test_model_condition_timeout(mut cx: TestAppContext) {
4125        struct Model;
4126
4127        impl super::Entity for Model {
4128            type Event = ();
4129        }
4130
4131        let model = cx.add_model(|_| Model);
4132        model.condition(&cx, |_, _| false).await;
4133    }
4134
4135    #[crate::test(self)]
4136    #[should_panic(expected = "model dropped with pending condition")]
4137    async fn test_model_condition_panic_on_drop(mut cx: TestAppContext) {
4138        struct Model;
4139
4140        impl super::Entity for Model {
4141            type Event = ();
4142        }
4143
4144        let model = cx.add_model(|_| Model);
4145        let condition = model.condition(&cx, |_, _| false);
4146        cx.update(|_| drop(model));
4147        condition.await;
4148    }
4149
4150    #[crate::test(self)]
4151    async fn test_view_condition(mut cx: TestAppContext) {
4152        struct Counter(usize);
4153
4154        impl super::Entity for Counter {
4155            type Event = ();
4156        }
4157
4158        impl super::View for Counter {
4159            fn ui_name() -> &'static str {
4160                "test view"
4161            }
4162
4163            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4164                Empty::new().boxed()
4165            }
4166        }
4167
4168        impl Counter {
4169            fn inc(&mut self, cx: &mut ViewContext<Self>) {
4170                self.0 += 1;
4171                cx.notify();
4172            }
4173        }
4174
4175        let (_, view) = cx.add_window(|_| Counter(0));
4176
4177        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
4178        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
4179        smol::pin!(condition1, condition2);
4180
4181        view.update(&mut cx, |view, cx| view.inc(cx));
4182        assert_eq!(poll_once(&mut condition1).await, None);
4183        assert_eq!(poll_once(&mut condition2).await, None);
4184
4185        view.update(&mut cx, |view, cx| view.inc(cx));
4186        assert_eq!(poll_once(&mut condition1).await, Some(()));
4187        assert_eq!(poll_once(&mut condition2).await, None);
4188
4189        view.update(&mut cx, |view, cx| view.inc(cx));
4190        assert_eq!(poll_once(&mut condition2).await, Some(()));
4191        view.update(&mut cx, |_, cx| cx.notify());
4192    }
4193
4194    #[crate::test(self)]
4195    #[should_panic]
4196    async fn test_view_condition_timeout(mut cx: TestAppContext) {
4197        struct View;
4198
4199        impl super::Entity for View {
4200            type Event = ();
4201        }
4202
4203        impl super::View for View {
4204            fn ui_name() -> &'static str {
4205                "test view"
4206            }
4207
4208            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4209                Empty::new().boxed()
4210            }
4211        }
4212
4213        let (_, view) = cx.add_window(|_| View);
4214        view.condition(&cx, |_, _| false).await;
4215    }
4216
4217    #[crate::test(self)]
4218    #[should_panic(expected = "view dropped with pending condition")]
4219    async fn test_view_condition_panic_on_drop(mut cx: TestAppContext) {
4220        struct View;
4221
4222        impl super::Entity for View {
4223            type Event = ();
4224        }
4225
4226        impl super::View for View {
4227            fn ui_name() -> &'static str {
4228                "test view"
4229            }
4230
4231            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
4232                Empty::new().boxed()
4233            }
4234        }
4235
4236        let window_id = cx.add_window(|_| View).0;
4237        let view = cx.add_view(window_id, |_| View);
4238
4239        let condition = view.condition(&cx, |_, _| false);
4240        cx.update(|_| drop(view));
4241        condition.await;
4242    }
4243}