app.rs

   1pub mod action;
   2mod callback_collection;
   3
   4use crate::{
   5    elements::ElementBox,
   6    executor::{self, Task},
   7    geometry::rect::RectF,
   8    keymap::{self, Binding, Keystroke},
   9    platform::{self, KeyDownEvent, Platform, PromptLevel, WindowOptions},
  10    presenter::Presenter,
  11    util::post_inc,
  12    AssetCache, AssetSource, ClipboardItem, FontCache, InputHandler, MouseRegionId,
  13    PathPromptOptions, TextLayoutCache,
  14};
  15pub use action::*;
  16use anyhow::{anyhow, Context, Result};
  17use callback_collection::CallbackCollection;
  18use collections::{btree_map, hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque};
  19use keymap::MatchResult;
  20use lazy_static::lazy_static;
  21use parking_lot::Mutex;
  22use platform::Event;
  23use postage::oneshot;
  24use smallvec::SmallVec;
  25use smol::prelude::*;
  26use std::{
  27    any::{type_name, Any, TypeId},
  28    cell::RefCell,
  29    fmt::{self, Debug},
  30    hash::{Hash, Hasher},
  31    marker::PhantomData,
  32    mem,
  33    ops::{Deref, DerefMut, Range},
  34    path::{Path, PathBuf},
  35    pin::Pin,
  36    rc::{self, Rc},
  37    sync::{Arc, Weak},
  38    time::Duration,
  39};
  40
  41use self::callback_collection::Mapping;
  42
  43pub trait Entity: 'static {
  44    type Event;
  45
  46    fn release(&mut self, _: &mut MutableAppContext) {}
  47    fn app_will_quit(
  48        &mut self,
  49        _: &mut MutableAppContext,
  50    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
  51        None
  52    }
  53}
  54
  55pub trait View: Entity + Sized {
  56    fn ui_name() -> &'static str;
  57    fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
  58    fn on_focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
  59    fn on_focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
  60    fn keymap_context(&self, _: &AppContext) -> keymap::Context {
  61        Self::default_keymap_context()
  62    }
  63    fn default_keymap_context() -> keymap::Context {
  64        let mut cx = keymap::Context::default();
  65        cx.set.insert(Self::ui_name().into());
  66        cx
  67    }
  68    fn debug_json(&self, _: &AppContext) -> serde_json::Value {
  69        serde_json::Value::Null
  70    }
  71
  72    fn text_for_range(&self, _: Range<usize>, _: &AppContext) -> Option<String> {
  73        None
  74    }
  75    fn selected_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
  76        None
  77    }
  78    fn marked_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
  79        None
  80    }
  81    fn unmark_text(&mut self, _: &mut ViewContext<Self>) {}
  82    fn replace_text_in_range(
  83        &mut self,
  84        _: Option<Range<usize>>,
  85        _: &str,
  86        _: &mut ViewContext<Self>,
  87    ) {
  88    }
  89    fn replace_and_mark_text_in_range(
  90        &mut self,
  91        _: Option<Range<usize>>,
  92        _: &str,
  93        _: Option<Range<usize>>,
  94        _: &mut ViewContext<Self>,
  95    ) {
  96    }
  97}
  98
  99pub trait ReadModel {
 100    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T;
 101}
 102
 103pub trait ReadModelWith {
 104    fn read_model_with<E: Entity, T>(
 105        &self,
 106        handle: &ModelHandle<E>,
 107        read: &mut dyn FnMut(&E, &AppContext) -> T,
 108    ) -> T;
 109}
 110
 111pub trait UpdateModel {
 112    fn update_model<T: Entity, O>(
 113        &mut self,
 114        handle: &ModelHandle<T>,
 115        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
 116    ) -> O;
 117}
 118
 119pub trait UpgradeModelHandle {
 120    fn upgrade_model_handle<T: Entity>(
 121        &self,
 122        handle: &WeakModelHandle<T>,
 123    ) -> Option<ModelHandle<T>>;
 124
 125    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool;
 126
 127    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle>;
 128}
 129
 130pub trait UpgradeViewHandle {
 131    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>>;
 132
 133    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle>;
 134}
 135
 136pub trait ReadView {
 137    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T;
 138}
 139
 140pub trait ReadViewWith {
 141    fn read_view_with<V, T>(
 142        &self,
 143        handle: &ViewHandle<V>,
 144        read: &mut dyn FnMut(&V, &AppContext) -> T,
 145    ) -> T
 146    where
 147        V: View;
 148}
 149
 150pub trait UpdateView {
 151    fn update_view<T, S>(
 152        &mut self,
 153        handle: &ViewHandle<T>,
 154        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 155    ) -> S
 156    where
 157        T: View;
 158}
 159
 160pub struct Menu<'a> {
 161    pub name: &'a str,
 162    pub items: Vec<MenuItem<'a>>,
 163}
 164
 165pub enum MenuItem<'a> {
 166    Separator,
 167    Submenu(Menu<'a>),
 168    Action {
 169        name: &'a str,
 170        action: Box<dyn Action>,
 171    },
 172}
 173
 174#[derive(Clone)]
 175pub struct App(Rc<RefCell<MutableAppContext>>);
 176
 177#[derive(Clone)]
 178pub struct AsyncAppContext(Rc<RefCell<MutableAppContext>>);
 179
 180#[cfg(any(test, feature = "test-support"))]
 181pub struct TestAppContext {
 182    cx: Rc<RefCell<MutableAppContext>>,
 183    foreground_platform: Rc<platform::test::ForegroundPlatform>,
 184    condition_duration: Option<Duration>,
 185}
 186
 187pub struct WindowInputHandler {
 188    app: Rc<RefCell<MutableAppContext>>,
 189    window_id: usize,
 190}
 191
 192impl App {
 193    pub fn new(asset_source: impl AssetSource) -> Result<Self> {
 194        let platform = platform::current::platform();
 195        let foreground_platform = platform::current::foreground_platform();
 196        let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
 197        let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
 198            foreground,
 199            Arc::new(executor::Background::new()),
 200            platform.clone(),
 201            foreground_platform.clone(),
 202            Arc::new(FontCache::new(platform.fonts())),
 203            Default::default(),
 204            asset_source,
 205        ))));
 206
 207        foreground_platform.on_quit(Box::new({
 208            let cx = app.0.clone();
 209            move || {
 210                cx.borrow_mut().quit();
 211            }
 212        }));
 213        foreground_platform.on_will_open_menu(Box::new({
 214            let cx = app.0.clone();
 215            move || {
 216                let mut cx = cx.borrow_mut();
 217                cx.keystroke_matcher.clear_pending();
 218            }
 219        }));
 220        foreground_platform.on_validate_menu_command(Box::new({
 221            let cx = app.0.clone();
 222            move |action| {
 223                let cx = cx.borrow_mut();
 224                !cx.keystroke_matcher.has_pending_keystrokes() && cx.is_action_available(action)
 225            }
 226        }));
 227        foreground_platform.on_menu_command(Box::new({
 228            let cx = app.0.clone();
 229            move |action| {
 230                let mut cx = cx.borrow_mut();
 231                if let Some(key_window_id) = cx.cx.platform.key_window_id() {
 232                    if let Some(view_id) = cx.focused_view_id(key_window_id) {
 233                        cx.handle_dispatch_action_from_effect(key_window_id, Some(view_id), action);
 234                        return;
 235                    }
 236                }
 237                cx.dispatch_global_action_any(action);
 238            }
 239        }));
 240
 241        app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
 242        Ok(app)
 243    }
 244
 245    pub fn background(&self) -> Arc<executor::Background> {
 246        self.0.borrow().background().clone()
 247    }
 248
 249    pub fn on_become_active<F>(self, mut callback: F) -> Self
 250    where
 251        F: 'static + FnMut(&mut MutableAppContext),
 252    {
 253        let cx = self.0.clone();
 254        self.0
 255            .borrow_mut()
 256            .foreground_platform
 257            .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 258        self
 259    }
 260
 261    pub fn on_resign_active<F>(self, mut callback: F) -> Self
 262    where
 263        F: 'static + FnMut(&mut MutableAppContext),
 264    {
 265        let cx = self.0.clone();
 266        self.0
 267            .borrow_mut()
 268            .foreground_platform
 269            .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
 270        self
 271    }
 272
 273    pub fn on_quit<F>(&mut self, mut callback: F) -> &mut Self
 274    where
 275        F: 'static + FnMut(&mut MutableAppContext),
 276    {
 277        let cx = self.0.clone();
 278        self.0
 279            .borrow_mut()
 280            .foreground_platform
 281            .on_quit(Box::new(move || callback(&mut *cx.borrow_mut())));
 282        self
 283    }
 284
 285    pub fn on_event<F>(&mut self, mut callback: F) -> &mut Self
 286    where
 287        F: 'static + FnMut(Event, &mut MutableAppContext) -> bool,
 288    {
 289        let cx = self.0.clone();
 290        self.0
 291            .borrow_mut()
 292            .foreground_platform
 293            .on_event(Box::new(move |event| {
 294                callback(event, &mut *cx.borrow_mut())
 295            }));
 296        self
 297    }
 298
 299    pub fn on_open_urls<F>(&mut self, mut callback: F) -> &mut Self
 300    where
 301        F: 'static + FnMut(Vec<String>, &mut MutableAppContext),
 302    {
 303        let cx = self.0.clone();
 304        self.0
 305            .borrow_mut()
 306            .foreground_platform
 307            .on_open_urls(Box::new(move |paths| {
 308                callback(paths, &mut *cx.borrow_mut())
 309            }));
 310        self
 311    }
 312
 313    pub fn run<F>(self, on_finish_launching: F)
 314    where
 315        F: 'static + FnOnce(&mut MutableAppContext),
 316    {
 317        let platform = self.0.borrow().foreground_platform.clone();
 318        platform.run(Box::new(move || {
 319            let mut cx = self.0.borrow_mut();
 320            let cx = &mut *cx;
 321            crate::views::init(cx);
 322            on_finish_launching(cx);
 323        }))
 324    }
 325
 326    pub fn platform(&self) -> Arc<dyn Platform> {
 327        self.0.borrow().platform()
 328    }
 329
 330    pub fn font_cache(&self) -> Arc<FontCache> {
 331        self.0.borrow().cx.font_cache.clone()
 332    }
 333
 334    fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 335        let mut state = self.0.borrow_mut();
 336        let result = state.update(callback);
 337        state.pending_notifications.clear();
 338        result
 339    }
 340}
 341
 342impl WindowInputHandler {
 343    fn read_focused_view<T, F>(&self, f: F) -> Option<T>
 344    where
 345        F: FnOnce(&dyn AnyView, &AppContext) -> T,
 346    {
 347        let app = self.app.borrow();
 348        let view_id = app.focused_view_id(self.window_id)?;
 349        let view = app.cx.views.get(&(self.window_id, view_id))?;
 350        let result = f(view.as_ref(), &app);
 351        Some(result)
 352    }
 353
 354    fn update_focused_view<T, F>(&mut self, f: F) -> Option<T>
 355    where
 356        F: FnOnce(usize, usize, &mut dyn AnyView, &mut MutableAppContext) -> T,
 357    {
 358        let mut app = self.app.borrow_mut();
 359        app.update(|app| {
 360            let view_id = app.focused_view_id(self.window_id)?;
 361            let mut view = app.cx.views.remove(&(self.window_id, view_id))?;
 362            let result = f(self.window_id, view_id, view.as_mut(), &mut *app);
 363            app.cx.views.insert((self.window_id, view_id), view);
 364            Some(result)
 365        })
 366    }
 367}
 368
 369impl InputHandler for WindowInputHandler {
 370    fn text_for_range(&self, range: Range<usize>) -> Option<String> {
 371        self.read_focused_view(|view, cx| view.text_for_range(range.clone(), cx))
 372            .flatten()
 373    }
 374
 375    fn selected_text_range(&self) -> Option<Range<usize>> {
 376        self.read_focused_view(|view, cx| view.selected_text_range(cx))
 377            .flatten()
 378    }
 379
 380    fn replace_text_in_range(&mut self, range: Option<Range<usize>>, text: &str) {
 381        self.update_focused_view(|window_id, view_id, view, cx| {
 382            view.replace_text_in_range(range, text, cx, window_id, view_id);
 383        });
 384    }
 385
 386    fn marked_text_range(&self) -> Option<Range<usize>> {
 387        self.read_focused_view(|view, cx| view.marked_text_range(cx))
 388            .flatten()
 389    }
 390
 391    fn unmark_text(&mut self) {
 392        self.update_focused_view(|window_id, view_id, view, cx| {
 393            view.unmark_text(cx, window_id, view_id);
 394        });
 395    }
 396
 397    fn replace_and_mark_text_in_range(
 398        &mut self,
 399        range: Option<Range<usize>>,
 400        new_text: &str,
 401        new_selected_range: Option<Range<usize>>,
 402    ) {
 403        self.update_focused_view(|window_id, view_id, view, cx| {
 404            view.replace_and_mark_text_in_range(
 405                range,
 406                new_text,
 407                new_selected_range,
 408                cx,
 409                window_id,
 410                view_id,
 411            );
 412        });
 413    }
 414
 415    fn rect_for_range(&self, range_utf16: Range<usize>) -> Option<RectF> {
 416        let app = self.app.borrow();
 417        let (presenter, _) = app.presenters_and_platform_windows.get(&self.window_id)?;
 418        let presenter = presenter.borrow();
 419        presenter.rect_for_text_range(range_utf16, &app)
 420    }
 421}
 422
 423#[cfg(any(test, feature = "test-support"))]
 424impl TestAppContext {
 425    pub fn new(
 426        foreground_platform: Rc<platform::test::ForegroundPlatform>,
 427        platform: Arc<dyn Platform>,
 428        foreground: Rc<executor::Foreground>,
 429        background: Arc<executor::Background>,
 430        font_cache: Arc<FontCache>,
 431        leak_detector: Arc<Mutex<LeakDetector>>,
 432        first_entity_id: usize,
 433    ) -> Self {
 434        let mut cx = MutableAppContext::new(
 435            foreground.clone(),
 436            background,
 437            platform,
 438            foreground_platform.clone(),
 439            font_cache,
 440            RefCounts {
 441                #[cfg(any(test, feature = "test-support"))]
 442                leak_detector,
 443                ..Default::default()
 444            },
 445            (),
 446        );
 447        cx.next_entity_id = first_entity_id;
 448        let cx = TestAppContext {
 449            cx: Rc::new(RefCell::new(cx)),
 450            foreground_platform,
 451            condition_duration: None,
 452        };
 453        cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
 454        cx
 455    }
 456
 457    pub fn dispatch_action<A: Action>(&self, window_id: usize, action: A) {
 458        let mut cx = self.cx.borrow_mut();
 459        if let Some(view_id) = cx.focused_view_id(window_id) {
 460            cx.handle_dispatch_action_from_effect(window_id, Some(view_id), &action);
 461        }
 462    }
 463
 464    pub fn dispatch_global_action<A: Action>(&self, action: A) {
 465        self.cx.borrow_mut().dispatch_global_action(action);
 466    }
 467
 468    pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: Keystroke, is_held: bool) {
 469        let handled = self.cx.borrow_mut().update(|cx| {
 470            let presenter = cx
 471                .presenters_and_platform_windows
 472                .get(&window_id)
 473                .unwrap()
 474                .0
 475                .clone();
 476
 477            if cx.dispatch_keystroke(window_id, &keystroke) {
 478                return true;
 479            }
 480
 481            if presenter.borrow_mut().dispatch_event(
 482                Event::KeyDown(KeyDownEvent {
 483                    keystroke: keystroke.clone(),
 484                    is_held,
 485                }),
 486                cx,
 487            ) {
 488                return true;
 489            }
 490
 491            false
 492        });
 493
 494        if !handled && !keystroke.cmd && !keystroke.ctrl {
 495            WindowInputHandler {
 496                app: self.cx.clone(),
 497                window_id,
 498            }
 499            .replace_text_in_range(None, &keystroke.key)
 500        }
 501    }
 502
 503    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 504    where
 505        T: Entity,
 506        F: FnOnce(&mut ModelContext<T>) -> T,
 507    {
 508        self.cx.borrow_mut().add_model(build_model)
 509    }
 510
 511    pub fn add_window<T, F>(&mut self, build_root_view: F) -> (usize, ViewHandle<T>)
 512    where
 513        T: View,
 514        F: FnOnce(&mut ViewContext<T>) -> T,
 515    {
 516        let (window_id, view) = self
 517            .cx
 518            .borrow_mut()
 519            .add_window(Default::default(), build_root_view);
 520        self.simulate_window_activation(Some(window_id));
 521        (window_id, view)
 522    }
 523
 524    pub fn add_view<T, F>(
 525        &mut self,
 526        parent_handle: impl Into<AnyViewHandle>,
 527        build_view: F,
 528    ) -> ViewHandle<T>
 529    where
 530        T: View,
 531        F: FnOnce(&mut ViewContext<T>) -> T,
 532    {
 533        self.cx.borrow_mut().add_view(parent_handle, build_view)
 534    }
 535
 536    pub fn window_ids(&self) -> Vec<usize> {
 537        self.cx.borrow().window_ids().collect()
 538    }
 539
 540    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
 541        self.cx.borrow().root_view(window_id)
 542    }
 543
 544    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 545        callback(self.cx.borrow().as_ref())
 546    }
 547
 548    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 549        let mut state = self.cx.borrow_mut();
 550        // Don't increment pending flushes in order for effects to be flushed before the callback
 551        // completes, which is helpful in tests.
 552        let result = callback(&mut *state);
 553        // Flush effects after the callback just in case there are any. This can happen in edge
 554        // cases such as the closure dropping handles.
 555        state.flush_effects();
 556        result
 557    }
 558
 559    pub fn render<F, V, T>(&mut self, handle: &ViewHandle<V>, f: F) -> T
 560    where
 561        F: FnOnce(&mut V, &mut RenderContext<V>) -> T,
 562        V: View,
 563    {
 564        handle.update(&mut *self.cx.borrow_mut(), |view, cx| {
 565            let mut render_cx = RenderContext {
 566                app: cx,
 567                window_id: handle.window_id(),
 568                view_id: handle.id(),
 569                view_type: PhantomData,
 570                titlebar_height: 0.,
 571                hovered_region_ids: Default::default(),
 572                clicked_region_id: None,
 573                right_clicked_region_id: None,
 574                refreshing: false,
 575            };
 576            f(view, &mut render_cx)
 577        })
 578    }
 579
 580    pub fn to_async(&self) -> AsyncAppContext {
 581        AsyncAppContext(self.cx.clone())
 582    }
 583
 584    pub fn font_cache(&self) -> Arc<FontCache> {
 585        self.cx.borrow().cx.font_cache.clone()
 586    }
 587
 588    pub fn foreground_platform(&self) -> Rc<platform::test::ForegroundPlatform> {
 589        self.foreground_platform.clone()
 590    }
 591
 592    pub fn platform(&self) -> Arc<dyn platform::Platform> {
 593        self.cx.borrow().cx.platform.clone()
 594    }
 595
 596    pub fn foreground(&self) -> Rc<executor::Foreground> {
 597        self.cx.borrow().foreground().clone()
 598    }
 599
 600    pub fn background(&self) -> Arc<executor::Background> {
 601        self.cx.borrow().background().clone()
 602    }
 603
 604    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 605    where
 606        F: FnOnce(AsyncAppContext) -> Fut,
 607        Fut: 'static + Future<Output = T>,
 608        T: 'static,
 609    {
 610        let foreground = self.foreground();
 611        let future = f(self.to_async());
 612        let cx = self.to_async();
 613        foreground.spawn(async move {
 614            let result = future.await;
 615            cx.0.borrow_mut().flush_effects();
 616            result
 617        })
 618    }
 619
 620    pub fn simulate_new_path_selection(&self, result: impl FnOnce(PathBuf) -> Option<PathBuf>) {
 621        self.foreground_platform.simulate_new_path_selection(result);
 622    }
 623
 624    pub fn did_prompt_for_new_path(&self) -> bool {
 625        self.foreground_platform.as_ref().did_prompt_for_new_path()
 626    }
 627
 628    pub fn simulate_prompt_answer(&self, window_id: usize, answer: usize) {
 629        use postage::prelude::Sink as _;
 630
 631        let mut done_tx = self
 632            .window_mut(window_id)
 633            .pending_prompts
 634            .borrow_mut()
 635            .pop_front()
 636            .expect("prompt was not called");
 637        let _ = done_tx.try_send(answer);
 638    }
 639
 640    pub fn has_pending_prompt(&self, window_id: usize) -> bool {
 641        let window = self.window_mut(window_id);
 642        let prompts = window.pending_prompts.borrow_mut();
 643        !prompts.is_empty()
 644    }
 645
 646    pub fn current_window_title(&self, window_id: usize) -> Option<String> {
 647        self.window_mut(window_id).title.clone()
 648    }
 649
 650    pub fn simulate_window_close(&self, window_id: usize) -> bool {
 651        let handler = self.window_mut(window_id).should_close_handler.take();
 652        if let Some(mut handler) = handler {
 653            let should_close = handler();
 654            self.window_mut(window_id).should_close_handler = Some(handler);
 655            should_close
 656        } else {
 657            false
 658        }
 659    }
 660
 661    pub fn simulate_window_activation(&self, to_activate: Option<usize>) {
 662        let mut handlers = BTreeMap::new();
 663        {
 664            let mut cx = self.cx.borrow_mut();
 665            for (window_id, (_, window)) in &mut cx.presenters_and_platform_windows {
 666                let window = window
 667                    .as_any_mut()
 668                    .downcast_mut::<platform::test::Window>()
 669                    .unwrap();
 670                handlers.insert(
 671                    *window_id,
 672                    mem::take(&mut window.active_status_change_handlers),
 673                );
 674            }
 675        };
 676        let mut handlers = handlers.into_iter().collect::<Vec<_>>();
 677        handlers.sort_unstable_by_key(|(window_id, _)| Some(*window_id) == to_activate);
 678
 679        for (window_id, mut window_handlers) in handlers {
 680            for window_handler in &mut window_handlers {
 681                window_handler(Some(window_id) == to_activate);
 682            }
 683
 684            self.window_mut(window_id)
 685                .active_status_change_handlers
 686                .extend(window_handlers);
 687        }
 688    }
 689
 690    pub fn is_window_edited(&self, window_id: usize) -> bool {
 691        self.window_mut(window_id).edited
 692    }
 693
 694    pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
 695        self.cx.borrow().leak_detector()
 696    }
 697
 698    pub fn assert_dropped(&self, handle: impl WeakHandle) {
 699        self.cx
 700            .borrow()
 701            .leak_detector()
 702            .lock()
 703            .assert_dropped(handle.id())
 704    }
 705
 706    fn window_mut(&self, window_id: usize) -> std::cell::RefMut<platform::test::Window> {
 707        std::cell::RefMut::map(self.cx.borrow_mut(), |state| {
 708            let (_, window) = state
 709                .presenters_and_platform_windows
 710                .get_mut(&window_id)
 711                .unwrap();
 712            let test_window = window
 713                .as_any_mut()
 714                .downcast_mut::<platform::test::Window>()
 715                .unwrap();
 716            test_window
 717        })
 718    }
 719
 720    pub fn set_condition_duration(&mut self, duration: Option<Duration>) {
 721        self.condition_duration = duration;
 722    }
 723
 724    pub fn condition_duration(&self) -> Duration {
 725        self.condition_duration.unwrap_or_else(|| {
 726            if std::env::var("CI").is_ok() {
 727                Duration::from_secs(2)
 728            } else {
 729                Duration::from_millis(500)
 730            }
 731        })
 732    }
 733
 734    pub fn assert_clipboard_content(&mut self, expected_content: Option<&str>) {
 735        self.update(|cx| {
 736            let actual_content = cx.read_from_clipboard().map(|item| item.text().to_owned());
 737            let expected_content = expected_content.map(|content| content.to_owned());
 738            assert_eq!(actual_content, expected_content);
 739        })
 740    }
 741}
 742
 743impl AsyncAppContext {
 744    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
 745    where
 746        F: FnOnce(AsyncAppContext) -> Fut,
 747        Fut: 'static + Future<Output = T>,
 748        T: 'static,
 749    {
 750        self.0.borrow().foreground.spawn(f(self.clone()))
 751    }
 752
 753    pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
 754        callback(self.0.borrow().as_ref())
 755    }
 756
 757    pub fn update<T, F: FnOnce(&mut MutableAppContext) -> T>(&mut self, callback: F) -> T {
 758        self.0.borrow_mut().update(callback)
 759    }
 760
 761    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
 762    where
 763        T: Entity,
 764        F: FnOnce(&mut ModelContext<T>) -> T,
 765    {
 766        self.update(|cx| cx.add_model(build_model))
 767    }
 768
 769    pub fn add_window<T, F>(
 770        &mut self,
 771        window_options: WindowOptions,
 772        build_root_view: F,
 773    ) -> (usize, ViewHandle<T>)
 774    where
 775        T: View,
 776        F: FnOnce(&mut ViewContext<T>) -> T,
 777    {
 778        self.update(|cx| cx.add_window(window_options, build_root_view))
 779    }
 780
 781    pub fn platform(&self) -> Arc<dyn Platform> {
 782        self.0.borrow().platform()
 783    }
 784
 785    pub fn foreground(&self) -> Rc<executor::Foreground> {
 786        self.0.borrow().foreground.clone()
 787    }
 788
 789    pub fn background(&self) -> Arc<executor::Background> {
 790        self.0.borrow().cx.background.clone()
 791    }
 792}
 793
 794impl UpdateModel for AsyncAppContext {
 795    fn update_model<E: Entity, O>(
 796        &mut self,
 797        handle: &ModelHandle<E>,
 798        update: &mut dyn FnMut(&mut E, &mut ModelContext<E>) -> O,
 799    ) -> O {
 800        self.0.borrow_mut().update_model(handle, update)
 801    }
 802}
 803
 804impl UpgradeModelHandle for AsyncAppContext {
 805    fn upgrade_model_handle<T: Entity>(
 806        &self,
 807        handle: &WeakModelHandle<T>,
 808    ) -> Option<ModelHandle<T>> {
 809        self.0.borrow().upgrade_model_handle(handle)
 810    }
 811
 812    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
 813        self.0.borrow().model_handle_is_upgradable(handle)
 814    }
 815
 816    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
 817        self.0.borrow().upgrade_any_model_handle(handle)
 818    }
 819}
 820
 821impl UpgradeViewHandle for AsyncAppContext {
 822    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
 823        self.0.borrow_mut().upgrade_view_handle(handle)
 824    }
 825
 826    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
 827        self.0.borrow_mut().upgrade_any_view_handle(handle)
 828    }
 829}
 830
 831impl ReadModelWith for AsyncAppContext {
 832    fn read_model_with<E: Entity, T>(
 833        &self,
 834        handle: &ModelHandle<E>,
 835        read: &mut dyn FnMut(&E, &AppContext) -> T,
 836    ) -> T {
 837        let cx = self.0.borrow();
 838        let cx = cx.as_ref();
 839        read(handle.read(cx), cx)
 840    }
 841}
 842
 843impl UpdateView for AsyncAppContext {
 844    fn update_view<T, S>(
 845        &mut self,
 846        handle: &ViewHandle<T>,
 847        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 848    ) -> S
 849    where
 850        T: View,
 851    {
 852        self.0.borrow_mut().update_view(handle, update)
 853    }
 854}
 855
 856impl ReadViewWith for AsyncAppContext {
 857    fn read_view_with<V, T>(
 858        &self,
 859        handle: &ViewHandle<V>,
 860        read: &mut dyn FnMut(&V, &AppContext) -> T,
 861    ) -> T
 862    where
 863        V: View,
 864    {
 865        let cx = self.0.borrow();
 866        let cx = cx.as_ref();
 867        read(handle.read(cx), cx)
 868    }
 869}
 870
 871#[cfg(any(test, feature = "test-support"))]
 872impl UpdateModel for TestAppContext {
 873    fn update_model<T: Entity, O>(
 874        &mut self,
 875        handle: &ModelHandle<T>,
 876        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
 877    ) -> O {
 878        self.cx.borrow_mut().update_model(handle, update)
 879    }
 880}
 881
 882#[cfg(any(test, feature = "test-support"))]
 883impl ReadModelWith for TestAppContext {
 884    fn read_model_with<E: Entity, T>(
 885        &self,
 886        handle: &ModelHandle<E>,
 887        read: &mut dyn FnMut(&E, &AppContext) -> T,
 888    ) -> T {
 889        let cx = self.cx.borrow();
 890        let cx = cx.as_ref();
 891        read(handle.read(cx), cx)
 892    }
 893}
 894
 895#[cfg(any(test, feature = "test-support"))]
 896impl UpdateView for TestAppContext {
 897    fn update_view<T, S>(
 898        &mut self,
 899        handle: &ViewHandle<T>,
 900        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
 901    ) -> S
 902    where
 903        T: View,
 904    {
 905        self.cx.borrow_mut().update_view(handle, update)
 906    }
 907}
 908
 909#[cfg(any(test, feature = "test-support"))]
 910impl ReadViewWith for TestAppContext {
 911    fn read_view_with<V, T>(
 912        &self,
 913        handle: &ViewHandle<V>,
 914        read: &mut dyn FnMut(&V, &AppContext) -> T,
 915    ) -> T
 916    where
 917        V: View,
 918    {
 919        let cx = self.cx.borrow();
 920        let cx = cx.as_ref();
 921        read(handle.read(cx), cx)
 922    }
 923}
 924
 925type ActionCallback =
 926    dyn FnMut(&mut dyn AnyView, &dyn Action, &mut MutableAppContext, usize, usize);
 927type GlobalActionCallback = dyn FnMut(&dyn Action, &mut MutableAppContext);
 928
 929type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>;
 930type GlobalSubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext)>;
 931type ObservationCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
 932type FocusObservationCallback = Box<dyn FnMut(bool, &mut MutableAppContext) -> bool>;
 933type GlobalObservationCallback = Box<dyn FnMut(&mut MutableAppContext)>;
 934type ReleaseObservationCallback = Box<dyn FnOnce(&dyn Any, &mut MutableAppContext)>;
 935type ActionObservationCallback = Box<dyn FnMut(TypeId, &mut MutableAppContext)>;
 936type WindowActivationCallback = Box<dyn FnMut(bool, &mut MutableAppContext) -> bool>;
 937type WindowFullscreenCallback = Box<dyn FnMut(bool, &mut MutableAppContext) -> bool>;
 938type DeserializeActionCallback = fn(json: &str) -> anyhow::Result<Box<dyn Action>>;
 939type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
 940
 941pub struct MutableAppContext {
 942    weak_self: Option<rc::Weak<RefCell<Self>>>,
 943    foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 944    assets: Arc<AssetCache>,
 945    cx: AppContext,
 946    action_deserializers: HashMap<&'static str, (TypeId, DeserializeActionCallback)>,
 947    capture_actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 948    actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
 949    global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
 950    keystroke_matcher: keymap::Matcher,
 951    next_entity_id: usize,
 952    next_window_id: usize,
 953    next_subscription_id: usize,
 954    frame_count: usize,
 955
 956    focus_observations: CallbackCollection<usize, FocusObservationCallback>,
 957    global_subscriptions: CallbackCollection<TypeId, GlobalSubscriptionCallback>,
 958    global_observations: CallbackCollection<TypeId, GlobalObservationCallback>,
 959    subscriptions: CallbackCollection<usize, SubscriptionCallback>,
 960    observations: CallbackCollection<usize, ObservationCallback>,
 961    window_activation_observations: CallbackCollection<usize, WindowActivationCallback>,
 962    window_fullscreen_observations: CallbackCollection<usize, WindowFullscreenCallback>,
 963
 964    release_observations: Arc<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>,
 965    action_dispatch_observations: Arc<Mutex<BTreeMap<usize, ActionObservationCallback>>>,
 966
 967    presenters_and_platform_windows:
 968        HashMap<usize, (Rc<RefCell<Presenter>>, Box<dyn platform::Window>)>,
 969    foreground: Rc<executor::Foreground>,
 970    pending_effects: VecDeque<Effect>,
 971    pending_focus_index: Option<usize>,
 972    pending_notifications: HashSet<usize>,
 973    pending_global_notifications: HashSet<TypeId>,
 974    pending_flushes: usize,
 975    flushing_effects: bool,
 976    halt_action_dispatch: bool,
 977}
 978
 979impl MutableAppContext {
 980    fn new(
 981        foreground: Rc<executor::Foreground>,
 982        background: Arc<executor::Background>,
 983        platform: Arc<dyn platform::Platform>,
 984        foreground_platform: Rc<dyn platform::ForegroundPlatform>,
 985        font_cache: Arc<FontCache>,
 986        ref_counts: RefCounts,
 987        asset_source: impl AssetSource,
 988    ) -> Self {
 989        Self {
 990            weak_self: None,
 991            foreground_platform,
 992            assets: Arc::new(AssetCache::new(asset_source)),
 993            cx: AppContext {
 994                models: Default::default(),
 995                views: Default::default(),
 996                parents: Default::default(),
 997                windows: Default::default(),
 998                globals: Default::default(),
 999                element_states: Default::default(),
1000                ref_counts: Arc::new(Mutex::new(ref_counts)),
1001                background,
1002                font_cache,
1003                platform,
1004            },
1005            action_deserializers: Default::default(),
1006            capture_actions: Default::default(),
1007            actions: Default::default(),
1008            global_actions: Default::default(),
1009            keystroke_matcher: keymap::Matcher::default(),
1010            next_entity_id: 0,
1011            next_window_id: 0,
1012            next_subscription_id: 0,
1013            frame_count: 0,
1014            subscriptions: Default::default(),
1015            global_subscriptions: Default::default(),
1016            observations: Default::default(),
1017            focus_observations: Default::default(),
1018            release_observations: Default::default(),
1019            global_observations: Default::default(),
1020            window_activation_observations: Default::default(),
1021            window_fullscreen_observations: Default::default(),
1022            action_dispatch_observations: Default::default(),
1023            presenters_and_platform_windows: Default::default(),
1024            foreground,
1025            pending_effects: VecDeque::new(),
1026            pending_focus_index: None,
1027            pending_notifications: Default::default(),
1028            pending_global_notifications: Default::default(),
1029            pending_flushes: 0,
1030            flushing_effects: false,
1031            halt_action_dispatch: false,
1032        }
1033    }
1034
1035    pub fn upgrade(&self) -> App {
1036        App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
1037    }
1038
1039    pub fn quit(&mut self) {
1040        let mut futures = Vec::new();
1041        for model_id in self.cx.models.keys().copied().collect::<Vec<_>>() {
1042            let mut model = self.cx.models.remove(&model_id).unwrap();
1043            futures.extend(model.app_will_quit(self));
1044            self.cx.models.insert(model_id, model);
1045        }
1046
1047        for view_id in self.cx.views.keys().copied().collect::<Vec<_>>() {
1048            let mut view = self.cx.views.remove(&view_id).unwrap();
1049            futures.extend(view.app_will_quit(self));
1050            self.cx.views.insert(view_id, view);
1051        }
1052
1053        self.remove_all_windows();
1054
1055        let futures = futures::future::join_all(futures);
1056        if self
1057            .background
1058            .block_with_timeout(Duration::from_millis(100), futures)
1059            .is_err()
1060        {
1061            log::error!("timed out waiting on app_will_quit");
1062        }
1063    }
1064
1065    pub fn remove_all_windows(&mut self) {
1066        for (window_id, _) in self.cx.windows.drain() {
1067            self.presenters_and_platform_windows.remove(&window_id);
1068        }
1069        self.flush_effects();
1070    }
1071
1072    pub fn platform(&self) -> Arc<dyn platform::Platform> {
1073        self.cx.platform.clone()
1074    }
1075
1076    pub fn font_cache(&self) -> &Arc<FontCache> {
1077        &self.cx.font_cache
1078    }
1079
1080    pub fn foreground(&self) -> &Rc<executor::Foreground> {
1081        &self.foreground
1082    }
1083
1084    pub fn background(&self) -> &Arc<executor::Background> {
1085        &self.cx.background
1086    }
1087
1088    pub fn debug_elements(&self, window_id: usize) -> Option<crate::json::Value> {
1089        self.presenters_and_platform_windows
1090            .get(&window_id)
1091            .and_then(|(presenter, _)| presenter.borrow().debug_elements(self))
1092    }
1093
1094    pub fn deserialize_action(
1095        &self,
1096        name: &str,
1097        argument: Option<&str>,
1098    ) -> Result<Box<dyn Action>> {
1099        let callback = self
1100            .action_deserializers
1101            .get(name)
1102            .ok_or_else(|| anyhow!("unknown action {}", name))?
1103            .1;
1104        callback(argument.unwrap_or("{}"))
1105            .with_context(|| format!("invalid data for action {}", name))
1106    }
1107
1108    pub fn add_action<A, V, F>(&mut self, handler: F)
1109    where
1110        A: Action,
1111        V: View,
1112        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
1113    {
1114        self.add_action_internal(handler, false)
1115    }
1116
1117    pub fn capture_action<A, V, F>(&mut self, handler: F)
1118    where
1119        A: Action,
1120        V: View,
1121        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
1122    {
1123        self.add_action_internal(handler, true)
1124    }
1125
1126    fn add_action_internal<A, V, F>(&mut self, mut handler: F, capture: bool)
1127    where
1128        A: Action,
1129        V: View,
1130        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
1131    {
1132        let handler = Box::new(
1133            move |view: &mut dyn AnyView,
1134                  action: &dyn Action,
1135                  cx: &mut MutableAppContext,
1136                  window_id: usize,
1137                  view_id: usize| {
1138                let action = action.as_any().downcast_ref().unwrap();
1139                let mut cx = ViewContext::new(cx, window_id, view_id);
1140                handler(
1141                    view.as_any_mut()
1142                        .downcast_mut()
1143                        .expect("downcast is type safe"),
1144                    action,
1145                    &mut cx,
1146                );
1147            },
1148        );
1149
1150        self.action_deserializers
1151            .entry(A::qualified_name())
1152            .or_insert((TypeId::of::<A>(), A::from_json_str));
1153
1154        let actions = if capture {
1155            &mut self.capture_actions
1156        } else {
1157            &mut self.actions
1158        };
1159
1160        actions
1161            .entry(TypeId::of::<V>())
1162            .or_default()
1163            .entry(TypeId::of::<A>())
1164            .or_default()
1165            .push(handler);
1166    }
1167
1168    pub fn add_async_action<A, V, F>(&mut self, mut handler: F)
1169    where
1170        A: Action,
1171        V: View,
1172        F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> Option<Task<Result<()>>>,
1173    {
1174        self.add_action(move |view, action, cx| {
1175            handler(view, action, cx).map(|task| task.detach_and_log_err(cx));
1176        })
1177    }
1178
1179    pub fn add_global_action<A, F>(&mut self, mut handler: F)
1180    where
1181        A: Action,
1182        F: 'static + FnMut(&A, &mut MutableAppContext),
1183    {
1184        let handler = Box::new(move |action: &dyn Action, cx: &mut MutableAppContext| {
1185            let action = action.as_any().downcast_ref().unwrap();
1186            handler(action, cx);
1187        });
1188
1189        self.action_deserializers
1190            .entry(A::qualified_name())
1191            .or_insert((TypeId::of::<A>(), A::from_json_str));
1192
1193        if self
1194            .global_actions
1195            .insert(TypeId::of::<A>(), handler)
1196            .is_some()
1197        {
1198            panic!(
1199                "registered multiple global handlers for {}",
1200                type_name::<A>()
1201            );
1202        }
1203    }
1204
1205    pub fn window_ids(&self) -> impl Iterator<Item = usize> + '_ {
1206        self.cx.windows.keys().cloned()
1207    }
1208
1209    pub fn activate_window(&self, window_id: usize) {
1210        if let Some((_, window)) = self.presenters_and_platform_windows.get(&window_id) {
1211            window.activate()
1212        }
1213    }
1214
1215    pub fn root_view<T: View>(&self, window_id: usize) -> Option<ViewHandle<T>> {
1216        self.cx
1217            .windows
1218            .get(&window_id)
1219            .and_then(|window| window.root_view.clone().downcast::<T>())
1220    }
1221
1222    pub fn window_is_active(&self, window_id: usize) -> bool {
1223        self.cx
1224            .windows
1225            .get(&window_id)
1226            .map_or(false, |window| window.is_active)
1227    }
1228
1229    pub fn window_is_fullscreen(&self, window_id: usize) -> bool {
1230        self.cx
1231            .windows
1232            .get(&window_id)
1233            .map_or(false, |window| window.is_fullscreen)
1234    }
1235
1236    pub fn render_view(&mut self, params: RenderParams) -> Result<ElementBox> {
1237        let window_id = params.window_id;
1238        let view_id = params.view_id;
1239        let mut view = self
1240            .cx
1241            .views
1242            .remove(&(window_id, view_id))
1243            .ok_or(anyhow!("view not found"))?;
1244        let element = view.render(params, self);
1245        self.cx.views.insert((window_id, view_id), view);
1246        Ok(element)
1247    }
1248
1249    pub fn render_views(
1250        &mut self,
1251        window_id: usize,
1252        titlebar_height: f32,
1253    ) -> HashMap<usize, ElementBox> {
1254        self.start_frame();
1255        let view_ids = self
1256            .views
1257            .keys()
1258            .filter_map(|(win_id, view_id)| {
1259                if *win_id == window_id {
1260                    Some(*view_id)
1261                } else {
1262                    None
1263                }
1264            })
1265            .collect::<Vec<_>>();
1266        view_ids
1267            .into_iter()
1268            .map(|view_id| {
1269                (
1270                    view_id,
1271                    self.render_view(RenderParams {
1272                        window_id,
1273                        view_id,
1274                        titlebar_height,
1275                        hovered_region_ids: Default::default(),
1276                        clicked_region_id: None,
1277                        right_clicked_region_id: None,
1278                        refreshing: false,
1279                    })
1280                    .unwrap(),
1281                )
1282            })
1283            .collect()
1284    }
1285
1286    pub(crate) fn start_frame(&mut self) {
1287        self.frame_count += 1;
1288    }
1289
1290    pub fn update<T, F: FnOnce(&mut Self) -> T>(&mut self, callback: F) -> T {
1291        self.pending_flushes += 1;
1292        let result = callback(self);
1293        self.flush_effects();
1294        result
1295    }
1296
1297    pub fn set_menus(&mut self, menus: Vec<Menu>) {
1298        self.foreground_platform
1299            .set_menus(menus, &self.keystroke_matcher);
1300    }
1301
1302    fn show_character_palette(&self, window_id: usize) {
1303        let (_, window) = &self.presenters_and_platform_windows[&window_id];
1304        window.show_character_palette();
1305    }
1306
1307    pub fn minimize_window(&self, window_id: usize) {
1308        let (_, window) = &self.presenters_and_platform_windows[&window_id];
1309        window.minimize();
1310    }
1311
1312    pub fn zoom_window(&self, window_id: usize) {
1313        let (_, window) = &self.presenters_and_platform_windows[&window_id];
1314        window.zoom();
1315    }
1316
1317    fn prompt(
1318        &self,
1319        window_id: usize,
1320        level: PromptLevel,
1321        msg: &str,
1322        answers: &[&str],
1323    ) -> oneshot::Receiver<usize> {
1324        let (_, window) = &self.presenters_and_platform_windows[&window_id];
1325        window.prompt(level, msg, answers)
1326    }
1327
1328    pub fn prompt_for_paths(
1329        &self,
1330        options: PathPromptOptions,
1331    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
1332        self.foreground_platform.prompt_for_paths(options)
1333    }
1334
1335    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
1336        self.foreground_platform.prompt_for_new_path(directory)
1337    }
1338
1339    pub fn emit_global<E: Any>(&mut self, payload: E) {
1340        self.pending_effects.push_back(Effect::GlobalEvent {
1341            payload: Box::new(payload),
1342        });
1343    }
1344
1345    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1346    where
1347        E: Entity,
1348        E::Event: 'static,
1349        H: Handle<E>,
1350        F: 'static + FnMut(H, &E::Event, &mut Self),
1351    {
1352        self.subscribe_internal(handle, move |handle, event, cx| {
1353            callback(handle, event, cx);
1354            true
1355        })
1356    }
1357
1358    pub fn subscribe_global<E, F>(&mut self, mut callback: F) -> Subscription
1359    where
1360        E: Any,
1361        F: 'static + FnMut(&E, &mut Self),
1362    {
1363        let subscription_id = post_inc(&mut self.next_subscription_id);
1364        let type_id = TypeId::of::<E>();
1365        self.pending_effects.push_back(Effect::GlobalSubscription {
1366            type_id,
1367            subscription_id,
1368            callback: Box::new(move |payload, cx| {
1369                let payload = payload.downcast_ref().expect("downcast is type safe");
1370                callback(payload, cx)
1371            }),
1372        });
1373
1374        Subscription::GlobalSubscription {
1375            id: subscription_id,
1376            type_id,
1377            subscriptions: Some(self.global_subscriptions.downgrade()),
1378        }
1379    }
1380
1381    pub fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1382    where
1383        E: Entity,
1384        E::Event: 'static,
1385        H: Handle<E>,
1386        F: 'static + FnMut(H, &mut Self),
1387    {
1388        self.observe_internal(handle, move |handle, cx| {
1389            callback(handle, cx);
1390            true
1391        })
1392    }
1393
1394    pub fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1395    where
1396        E: Entity,
1397        E::Event: 'static,
1398        H: Handle<E>,
1399        F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
1400    {
1401        let subscription_id = post_inc(&mut self.next_subscription_id);
1402        let emitter = handle.downgrade();
1403        self.pending_effects.push_back(Effect::Subscription {
1404            entity_id: handle.id(),
1405            subscription_id,
1406            callback: Box::new(move |payload, cx| {
1407                if let Some(emitter) = H::upgrade_from(&emitter, cx.as_ref()) {
1408                    let payload = payload.downcast_ref().expect("downcast is type safe");
1409                    callback(emitter, payload, cx)
1410                } else {
1411                    false
1412                }
1413            }),
1414        });
1415        Subscription::Subscription {
1416            id: subscription_id,
1417            entity_id: handle.id(),
1418            subscriptions: Some(self.subscriptions.downgrade()),
1419        }
1420    }
1421
1422    fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
1423    where
1424        E: Entity,
1425        E::Event: 'static,
1426        H: Handle<E>,
1427        F: 'static + FnMut(H, &mut Self) -> bool,
1428    {
1429        let subscription_id = post_inc(&mut self.next_subscription_id);
1430        let observed = handle.downgrade();
1431        let entity_id = handle.id();
1432        self.pending_effects.push_back(Effect::Observation {
1433            entity_id,
1434            subscription_id,
1435            callback: Box::new(move |cx| {
1436                if let Some(observed) = H::upgrade_from(&observed, cx) {
1437                    callback(observed, cx)
1438                } else {
1439                    false
1440                }
1441            }),
1442        });
1443        Subscription::Observation {
1444            id: subscription_id,
1445            entity_id,
1446            observations: Some(self.observations.downgrade()),
1447        }
1448    }
1449
1450    fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
1451    where
1452        F: 'static + FnMut(ViewHandle<V>, bool, &mut MutableAppContext) -> bool,
1453        V: View,
1454    {
1455        let subscription_id = post_inc(&mut self.next_subscription_id);
1456        let observed = handle.downgrade();
1457        let view_id = handle.id();
1458
1459        self.pending_effects.push_back(Effect::FocusObservation {
1460            view_id,
1461            subscription_id,
1462            callback: Box::new(move |focused, cx| {
1463                if let Some(observed) = observed.upgrade(cx) {
1464                    callback(observed, focused, cx)
1465                } else {
1466                    false
1467                }
1468            }),
1469        });
1470
1471        Subscription::FocusObservation {
1472            id: subscription_id,
1473            view_id,
1474            observations: Some(self.focus_observations.downgrade()),
1475        }
1476    }
1477
1478    pub fn observe_global<G, F>(&mut self, mut observe: F) -> Subscription
1479    where
1480        G: Any,
1481        F: 'static + FnMut(&mut MutableAppContext),
1482    {
1483        let type_id = TypeId::of::<G>();
1484        let id = post_inc(&mut self.next_subscription_id);
1485
1486        self.global_observations.add_callback(
1487            type_id,
1488            id,
1489            Box::new(move |cx: &mut MutableAppContext| observe(cx)),
1490        );
1491
1492        Subscription::GlobalObservation {
1493            id,
1494            type_id,
1495            observations: Some(self.global_observations.downgrade()),
1496        }
1497    }
1498
1499    pub fn observe_release<E, H, F>(&mut self, handle: &H, callback: F) -> Subscription
1500    where
1501        E: Entity,
1502        E::Event: 'static,
1503        H: Handle<E>,
1504        F: 'static + FnOnce(&E, &mut Self),
1505    {
1506        let id = post_inc(&mut self.next_subscription_id);
1507        self.release_observations
1508            .lock()
1509            .entry(handle.id())
1510            .or_default()
1511            .insert(
1512                id,
1513                Box::new(move |released, cx| {
1514                    let released = released.downcast_ref().unwrap();
1515                    callback(released, cx)
1516                }),
1517            );
1518        Subscription::ReleaseObservation {
1519            id,
1520            entity_id: handle.id(),
1521            observations: Some(Arc::downgrade(&self.release_observations)),
1522        }
1523    }
1524
1525    pub fn observe_actions<F>(&mut self, callback: F) -> Subscription
1526    where
1527        F: 'static + FnMut(TypeId, &mut MutableAppContext),
1528    {
1529        let id = post_inc(&mut self.next_subscription_id);
1530        self.action_dispatch_observations
1531            .lock()
1532            .insert(id, Box::new(callback));
1533        Subscription::ActionObservation {
1534            id,
1535            observations: Some(Arc::downgrade(&self.action_dispatch_observations)),
1536        }
1537    }
1538
1539    fn observe_window_activation<F>(&mut self, window_id: usize, callback: F) -> Subscription
1540    where
1541        F: 'static + FnMut(bool, &mut MutableAppContext) -> bool,
1542    {
1543        let subscription_id = post_inc(&mut self.next_subscription_id);
1544        self.pending_effects
1545            .push_back(Effect::WindowActivationObservation {
1546                window_id,
1547                subscription_id,
1548                callback: Box::new(callback),
1549            });
1550        Subscription::WindowActivationObservation {
1551            id: subscription_id,
1552            window_id,
1553            observations: Some(self.window_activation_observations.downgrade()),
1554        }
1555    }
1556
1557    fn observe_fullscreen<F>(&mut self, window_id: usize, callback: F) -> Subscription
1558    where
1559        F: 'static + FnMut(bool, &mut MutableAppContext) -> bool,
1560    {
1561        let subscription_id = post_inc(&mut self.next_subscription_id);
1562        self.pending_effects
1563            .push_back(Effect::WindowFullscreenObservation {
1564                window_id,
1565                subscription_id,
1566                callback: Box::new(callback),
1567            });
1568        Subscription::WindowFullscreenObservation {
1569            id: subscription_id,
1570            window_id,
1571            observations: Some(self.window_activation_observations.downgrade()),
1572        }
1573    }
1574
1575    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut MutableAppContext)) {
1576        self.pending_effects.push_back(Effect::Deferred {
1577            callback: Box::new(callback),
1578            after_window_update: false,
1579        })
1580    }
1581
1582    pub fn after_window_update(&mut self, callback: impl 'static + FnOnce(&mut MutableAppContext)) {
1583        self.pending_effects.push_back(Effect::Deferred {
1584            callback: Box::new(callback),
1585            after_window_update: true,
1586        })
1587    }
1588
1589    pub(crate) fn notify_model(&mut self, model_id: usize) {
1590        if self.pending_notifications.insert(model_id) {
1591            self.pending_effects
1592                .push_back(Effect::ModelNotification { model_id });
1593        }
1594    }
1595
1596    pub(crate) fn notify_view(&mut self, window_id: usize, view_id: usize) {
1597        if self.pending_notifications.insert(view_id) {
1598            self.pending_effects
1599                .push_back(Effect::ViewNotification { window_id, view_id });
1600        }
1601    }
1602
1603    pub(crate) fn notify_global(&mut self, type_id: TypeId) {
1604        if self.pending_global_notifications.insert(type_id) {
1605            self.pending_effects
1606                .push_back(Effect::GlobalNotification { type_id });
1607        }
1608    }
1609
1610    pub(crate) fn name_for_view(&self, window_id: usize, view_id: usize) -> Option<&str> {
1611        self.views
1612            .get(&(window_id, view_id))
1613            .map(|view| view.ui_name())
1614    }
1615
1616    pub fn all_action_names<'a>(&'a self) -> impl Iterator<Item = &'static str> + 'a {
1617        self.action_deserializers.keys().copied()
1618    }
1619
1620    pub fn available_actions(
1621        &self,
1622        window_id: usize,
1623        view_id: usize,
1624    ) -> impl Iterator<Item = (&'static str, Box<dyn Action>, SmallVec<[&Binding; 1]>)> {
1625        let mut action_types: HashSet<_> = self.global_actions.keys().copied().collect();
1626
1627        for view_id in self.parents(window_id, view_id) {
1628            if let Some(view) = self.views.get(&(window_id, view_id)) {
1629                let view_type = view.as_any().type_id();
1630                if let Some(actions) = self.actions.get(&view_type) {
1631                    action_types.extend(actions.keys().copied());
1632                }
1633            }
1634        }
1635
1636        self.action_deserializers
1637            .iter()
1638            .filter_map(move |(name, (type_id, deserialize))| {
1639                if action_types.contains(type_id) {
1640                    Some((
1641                        *name,
1642                        deserialize("{}").ok()?,
1643                        self.keystroke_matcher
1644                            .bindings_for_action_type(*type_id)
1645                            .collect(),
1646                    ))
1647                } else {
1648                    None
1649                }
1650            })
1651    }
1652
1653    pub fn is_action_available(&self, action: &dyn Action) -> bool {
1654        let action_type = action.as_any().type_id();
1655        if let Some(window_id) = self.cx.platform.key_window_id() {
1656            if let Some(focused_view_id) = self.focused_view_id(window_id) {
1657                for view_id in self.parents(window_id, focused_view_id) {
1658                    if let Some(view) = self.views.get(&(window_id, view_id)) {
1659                        let view_type = view.as_any().type_id();
1660                        if let Some(actions) = self.actions.get(&view_type) {
1661                            if actions.contains_key(&action_type) {
1662                                return true;
1663                            }
1664                        }
1665                    }
1666                }
1667            }
1668        }
1669        self.global_actions.contains_key(&action_type)
1670    }
1671
1672    /// Return keystrokes that would dispatch the given action closest to the focused view, if there are any.
1673    pub(crate) fn keystrokes_for_action(
1674        &self,
1675        window_id: usize,
1676        dispatch_path: &[usize],
1677        action: &dyn Action,
1678    ) -> Option<SmallVec<[Keystroke; 2]>> {
1679        for view_id in dispatch_path.iter().rev() {
1680            let view = self
1681                .cx
1682                .views
1683                .get(&(window_id, *view_id))
1684                .expect("view in responder chain does not exist");
1685            let cx = view.keymap_context(self.as_ref());
1686            let keystrokes = self.keystroke_matcher.keystrokes_for_action(action, &cx);
1687            if keystrokes.is_some() {
1688                return keystrokes;
1689            }
1690        }
1691
1692        None
1693    }
1694
1695    // Traverses the parent tree. Walks down the tree toward the passed
1696    // view calling visit with true. Then walks back up the tree calling visit with false.
1697    // If `visit` returns false this function will immediately return.
1698    // Returns a bool indicating if the traversal was completed early.
1699    fn visit_dispatch_path(
1700        &mut self,
1701        window_id: usize,
1702        view_id: usize,
1703        mut visit: impl FnMut(usize, bool, &mut MutableAppContext) -> bool,
1704    ) -> bool {
1705        // List of view ids from the leaf to the root of the window
1706        let path = self.parents(window_id, view_id).collect::<Vec<_>>();
1707
1708        // Walk down from the root to the leaf calling visit with capture_phase = true
1709        for view_id in path.iter().rev() {
1710            if !visit(*view_id, true, self) {
1711                return false;
1712            }
1713        }
1714
1715        // Walk up from the leaf to the root calling visit with capture_phase = false
1716        for view_id in path.iter() {
1717            if !visit(*view_id, false, self) {
1718                return false;
1719            }
1720        }
1721
1722        true
1723    }
1724
1725    // Returns an iterator over all of the view ids from the passed view up to the root of the window
1726    // Includes the passed view itself
1727    fn parents(&self, window_id: usize, mut view_id: usize) -> impl Iterator<Item = usize> + '_ {
1728        std::iter::once(view_id)
1729            .into_iter()
1730            .chain(std::iter::from_fn(move || {
1731                if let Some(ParentId::View(parent_id)) = self.parents.get(&(window_id, view_id)) {
1732                    view_id = *parent_id;
1733                    Some(view_id)
1734                } else {
1735                    None
1736                }
1737            }))
1738    }
1739
1740    fn actions_mut(
1741        &mut self,
1742        capture_phase: bool,
1743    ) -> &mut HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>> {
1744        if capture_phase {
1745            &mut self.capture_actions
1746        } else {
1747            &mut self.actions
1748        }
1749    }
1750
1751    pub fn dispatch_global_action<A: Action>(&mut self, action: A) {
1752        self.dispatch_global_action_any(&action);
1753    }
1754
1755    fn dispatch_global_action_any(&mut self, action: &dyn Action) -> bool {
1756        self.update(|this| {
1757            if let Some((name, mut handler)) = this.global_actions.remove_entry(&action.id()) {
1758                handler(action, this);
1759                this.global_actions.insert(name, handler);
1760                true
1761            } else {
1762                false
1763            }
1764        })
1765    }
1766
1767    pub fn add_bindings<T: IntoIterator<Item = keymap::Binding>>(&mut self, bindings: T) {
1768        self.keystroke_matcher.add_bindings(bindings);
1769    }
1770
1771    pub fn clear_bindings(&mut self) {
1772        self.keystroke_matcher.clear_bindings();
1773    }
1774
1775    pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: &Keystroke) -> bool {
1776        let mut pending = false;
1777
1778        if let Some(focused_view_id) = self.focused_view_id(window_id) {
1779            for view_id in self.parents(window_id, focused_view_id).collect::<Vec<_>>() {
1780                let keymap_context = self
1781                    .cx
1782                    .views
1783                    .get(&(window_id, view_id))
1784                    .unwrap()
1785                    .keymap_context(self.as_ref());
1786
1787                match self.keystroke_matcher.push_keystroke(
1788                    keystroke.clone(),
1789                    view_id,
1790                    &keymap_context,
1791                ) {
1792                    MatchResult::None => {}
1793                    MatchResult::Pending => pending = true,
1794                    MatchResult::Action(action) => {
1795                        if self.handle_dispatch_action_from_effect(
1796                            window_id,
1797                            Some(view_id),
1798                            action.as_ref(),
1799                        ) {
1800                            self.keystroke_matcher.clear_pending();
1801                            return true;
1802                        }
1803                    }
1804                }
1805            }
1806        }
1807
1808        pending
1809    }
1810
1811    pub fn default_global<T: 'static + Default>(&mut self) -> &T {
1812        let type_id = TypeId::of::<T>();
1813        self.update(|this| {
1814            if let Entry::Vacant(entry) = this.cx.globals.entry(type_id) {
1815                entry.insert(Box::new(T::default()));
1816                this.notify_global(type_id);
1817            }
1818        });
1819        self.globals.get(&type_id).unwrap().downcast_ref().unwrap()
1820    }
1821
1822    pub fn set_global<T: 'static>(&mut self, state: T) {
1823        self.update(|this| {
1824            let type_id = TypeId::of::<T>();
1825            this.cx.globals.insert(type_id, Box::new(state));
1826            this.notify_global(type_id);
1827        });
1828    }
1829
1830    pub fn update_default_global<T, F, U>(&mut self, update: F) -> U
1831    where
1832        T: 'static + Default,
1833        F: FnOnce(&mut T, &mut MutableAppContext) -> U,
1834    {
1835        self.update(|this| {
1836            let type_id = TypeId::of::<T>();
1837            let mut state = this
1838                .cx
1839                .globals
1840                .remove(&type_id)
1841                .unwrap_or_else(|| Box::new(T::default()));
1842            let result = update(state.downcast_mut().unwrap(), this);
1843            this.cx.globals.insert(type_id, state);
1844            this.notify_global(type_id);
1845            result
1846        })
1847    }
1848
1849    pub fn update_global<T, F, U>(&mut self, update: F) -> U
1850    where
1851        T: 'static,
1852        F: FnOnce(&mut T, &mut MutableAppContext) -> U,
1853    {
1854        self.update(|this| {
1855            let type_id = TypeId::of::<T>();
1856            if let Some(mut state) = this.cx.globals.remove(&type_id) {
1857                let result = update(state.downcast_mut().unwrap(), this);
1858                this.cx.globals.insert(type_id, state);
1859                this.notify_global(type_id);
1860                result
1861            } else {
1862                panic!("No global added for {}", std::any::type_name::<T>());
1863            }
1864        })
1865    }
1866
1867    pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1868    where
1869        T: Entity,
1870        F: FnOnce(&mut ModelContext<T>) -> T,
1871    {
1872        self.update(|this| {
1873            let model_id = post_inc(&mut this.next_entity_id);
1874            let handle = ModelHandle::new(model_id, &this.cx.ref_counts);
1875            let mut cx = ModelContext::new(this, model_id);
1876            let model = build_model(&mut cx);
1877            this.cx.models.insert(model_id, Box::new(model));
1878            handle
1879        })
1880    }
1881
1882    pub fn add_window<T, F>(
1883        &mut self,
1884        window_options: WindowOptions,
1885        build_root_view: F,
1886    ) -> (usize, ViewHandle<T>)
1887    where
1888        T: View,
1889        F: FnOnce(&mut ViewContext<T>) -> T,
1890    {
1891        self.update(|this| {
1892            let window_id = post_inc(&mut this.next_window_id);
1893            let root_view = this
1894                .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx)))
1895                .unwrap();
1896            this.cx.windows.insert(
1897                window_id,
1898                Window {
1899                    root_view: root_view.clone().into(),
1900                    focused_view_id: Some(root_view.id()),
1901                    is_active: false,
1902                    invalidation: None,
1903                    is_fullscreen: false,
1904                },
1905            );
1906            root_view.update(this, |view, cx| view.on_focus_in(cx.handle().into(), cx));
1907            this.open_platform_window(window_id, window_options);
1908
1909            (window_id, root_view)
1910        })
1911    }
1912
1913    pub fn replace_root_view<T, F>(&mut self, window_id: usize, build_root_view: F) -> ViewHandle<T>
1914    where
1915        T: View,
1916        F: FnOnce(&mut ViewContext<T>) -> T,
1917    {
1918        self.update(|this| {
1919            let root_view = this
1920                .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx)))
1921                .unwrap();
1922            let window = this.cx.windows.get_mut(&window_id).unwrap();
1923            window.root_view = root_view.clone().into();
1924            window.focused_view_id = Some(root_view.id());
1925            root_view
1926        })
1927    }
1928
1929    pub fn remove_window(&mut self, window_id: usize) {
1930        self.cx.windows.remove(&window_id);
1931        self.presenters_and_platform_windows.remove(&window_id);
1932        self.flush_effects();
1933    }
1934
1935    fn open_platform_window(&mut self, window_id: usize, window_options: WindowOptions) {
1936        let mut window =
1937            self.cx
1938                .platform
1939                .open_window(window_id, window_options, self.foreground.clone());
1940        let presenter = Rc::new(RefCell::new(
1941            self.build_presenter(window_id, window.titlebar_height()),
1942        ));
1943
1944        {
1945            let mut app = self.upgrade();
1946            let presenter = Rc::downgrade(&presenter);
1947            window.on_event(Box::new(move |event| {
1948                app.update(|cx| {
1949                    if let Some(presenter) = presenter.upgrade() {
1950                        if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event {
1951                            if cx.dispatch_keystroke(window_id, keystroke) {
1952                                return true;
1953                            }
1954                        }
1955
1956                        presenter.borrow_mut().dispatch_event(event, cx)
1957                    } else {
1958                        false
1959                    }
1960                })
1961            }));
1962        }
1963
1964        {
1965            let mut app = self.upgrade();
1966            window.on_active_status_change(Box::new(move |is_active| {
1967                app.update(|cx| cx.window_changed_active_status(window_id, is_active))
1968            }));
1969        }
1970
1971        {
1972            let mut app = self.upgrade();
1973            window.on_resize(Box::new(move || {
1974                app.update(|cx| cx.window_was_resized(window_id))
1975            }));
1976        }
1977
1978        {
1979            let mut app = self.upgrade();
1980            window.on_fullscreen(Box::new(move |is_fullscreen| {
1981                app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen))
1982            }));
1983        }
1984
1985        {
1986            let mut app = self.upgrade();
1987            window.on_close(Box::new(move || {
1988                app.update(|cx| cx.remove_window(window_id));
1989            }));
1990        }
1991
1992        window.set_input_handler(Box::new(WindowInputHandler {
1993            app: self.upgrade().0,
1994            window_id,
1995        }));
1996
1997        let scene =
1998            presenter
1999                .borrow_mut()
2000                .build_scene(window.size(), window.scale_factor(), false, self);
2001        window.present_scene(scene);
2002        self.presenters_and_platform_windows
2003            .insert(window_id, (presenter.clone(), window));
2004    }
2005
2006    pub fn build_presenter(&mut self, window_id: usize, titlebar_height: f32) -> Presenter {
2007        Presenter::new(
2008            window_id,
2009            titlebar_height,
2010            self.cx.font_cache.clone(),
2011            TextLayoutCache::new(self.cx.platform.fonts()),
2012            self.assets.clone(),
2013            self,
2014        )
2015    }
2016
2017    pub fn add_view<T, F>(
2018        &mut self,
2019        parent_handle: impl Into<AnyViewHandle>,
2020        build_view: F,
2021    ) -> ViewHandle<T>
2022    where
2023        T: View,
2024        F: FnOnce(&mut ViewContext<T>) -> T,
2025    {
2026        let parent_handle = parent_handle.into();
2027        self.build_and_insert_view(
2028            parent_handle.window_id,
2029            ParentId::View(parent_handle.view_id),
2030            |cx| Some(build_view(cx)),
2031        )
2032        .unwrap()
2033    }
2034
2035    pub fn add_option_view<T, F>(
2036        &mut self,
2037        parent_handle: impl Into<AnyViewHandle>,
2038        build_view: F,
2039    ) -> Option<ViewHandle<T>>
2040    where
2041        T: View,
2042        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
2043    {
2044        let parent_handle = parent_handle.into();
2045        self.build_and_insert_view(
2046            parent_handle.window_id,
2047            ParentId::View(parent_handle.view_id),
2048            build_view,
2049        )
2050    }
2051
2052    pub(crate) fn build_and_insert_view<T, F>(
2053        &mut self,
2054        window_id: usize,
2055        parent_id: ParentId,
2056        build_view: F,
2057    ) -> Option<ViewHandle<T>>
2058    where
2059        T: View,
2060        F: FnOnce(&mut ViewContext<T>) -> Option<T>,
2061    {
2062        self.update(|this| {
2063            let view_id = post_inc(&mut this.next_entity_id);
2064            let mut cx = ViewContext::new(this, window_id, view_id);
2065            let handle = if let Some(view) = build_view(&mut cx) {
2066                this.cx.views.insert((window_id, view_id), Box::new(view));
2067                this.cx.parents.insert((window_id, view_id), parent_id);
2068                if let Some(window) = this.cx.windows.get_mut(&window_id) {
2069                    window
2070                        .invalidation
2071                        .get_or_insert_with(Default::default)
2072                        .updated
2073                        .insert(view_id);
2074                }
2075                Some(ViewHandle::new(window_id, view_id, &this.cx.ref_counts))
2076            } else {
2077                None
2078            };
2079            handle
2080        })
2081    }
2082
2083    fn remove_dropped_entities(&mut self) {
2084        loop {
2085            let (dropped_models, dropped_views, dropped_element_states) =
2086                self.cx.ref_counts.lock().take_dropped();
2087            if dropped_models.is_empty()
2088                && dropped_views.is_empty()
2089                && dropped_element_states.is_empty()
2090            {
2091                break;
2092            }
2093
2094            for model_id in dropped_models {
2095                self.subscriptions.remove(model_id);
2096                self.observations.remove(model_id);
2097                let mut model = self.cx.models.remove(&model_id).unwrap();
2098                model.release(self);
2099                self.pending_effects
2100                    .push_back(Effect::ModelRelease { model_id, model });
2101            }
2102
2103            for (window_id, view_id) in dropped_views {
2104                self.subscriptions.remove(view_id);
2105                self.observations.remove(view_id);
2106                let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap();
2107                view.release(self);
2108                let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| {
2109                    window
2110                        .invalidation
2111                        .get_or_insert_with(Default::default)
2112                        .removed
2113                        .push(view_id);
2114                    if window.focused_view_id == Some(view_id) {
2115                        Some(window.root_view.id())
2116                    } else {
2117                        None
2118                    }
2119                });
2120                self.cx.parents.remove(&(window_id, view_id));
2121
2122                if let Some(view_id) = change_focus_to {
2123                    self.handle_focus_effect(window_id, Some(view_id));
2124                }
2125
2126                self.pending_effects
2127                    .push_back(Effect::ViewRelease { view_id, view });
2128            }
2129
2130            for key in dropped_element_states {
2131                self.cx.element_states.remove(&key);
2132            }
2133        }
2134    }
2135
2136    fn flush_effects(&mut self) {
2137        self.pending_flushes = self.pending_flushes.saturating_sub(1);
2138        let mut after_window_update_callbacks = Vec::new();
2139
2140        if !self.flushing_effects && self.pending_flushes == 0 {
2141            self.flushing_effects = true;
2142
2143            let mut refreshing = false;
2144            loop {
2145                if let Some(effect) = self.pending_effects.pop_front() {
2146                    if let Some(pending_focus_index) = self.pending_focus_index.as_mut() {
2147                        *pending_focus_index = pending_focus_index.saturating_sub(1);
2148                    }
2149                    match effect {
2150                        Effect::Subscription {
2151                            entity_id,
2152                            subscription_id,
2153                            callback,
2154                        } => self.subscriptions.add_or_remove_callback(
2155                            entity_id,
2156                            subscription_id,
2157                            callback,
2158                        ),
2159
2160                        Effect::Event { entity_id, payload } => {
2161                            let mut subscriptions = self.subscriptions.clone();
2162                            subscriptions.emit_and_cleanup(entity_id, self, |callback, this| {
2163                                callback(payload.as_ref(), this)
2164                            })
2165                        }
2166
2167                        Effect::GlobalSubscription {
2168                            type_id,
2169                            subscription_id,
2170                            callback,
2171                        } => self.global_subscriptions.add_or_remove_callback(
2172                            type_id,
2173                            subscription_id,
2174                            callback,
2175                        ),
2176
2177                        Effect::GlobalEvent { payload } => self.emit_global_event(payload),
2178
2179                        Effect::Observation {
2180                            entity_id,
2181                            subscription_id,
2182                            callback,
2183                        } => self.observations.add_or_remove_callback(
2184                            entity_id,
2185                            subscription_id,
2186                            callback,
2187                        ),
2188
2189                        Effect::ModelNotification { model_id } => {
2190                            let mut observations = self.observations.clone();
2191                            observations
2192                                .emit_and_cleanup(model_id, self, |callback, this| callback(this));
2193                        }
2194
2195                        Effect::ViewNotification { window_id, view_id } => {
2196                            self.handle_view_notification_effect(window_id, view_id)
2197                        }
2198
2199                        Effect::GlobalNotification { type_id } => {
2200                            let mut subscriptions = self.global_observations.clone();
2201                            subscriptions.emit_and_cleanup(type_id, self, |callback, this| {
2202                                callback(this);
2203                                true
2204                            });
2205                        }
2206
2207                        Effect::Deferred {
2208                            callback,
2209                            after_window_update,
2210                        } => {
2211                            if after_window_update {
2212                                after_window_update_callbacks.push(callback);
2213                            } else {
2214                                callback(self)
2215                            }
2216                        }
2217
2218                        Effect::ModelRelease { model_id, model } => {
2219                            self.handle_entity_release_effect(model_id, model.as_any())
2220                        }
2221
2222                        Effect::ViewRelease { view_id, view } => {
2223                            self.handle_entity_release_effect(view_id, view.as_any())
2224                        }
2225
2226                        Effect::Focus { window_id, view_id } => {
2227                            self.handle_focus_effect(window_id, view_id);
2228                        }
2229
2230                        Effect::FocusObservation {
2231                            view_id,
2232                            subscription_id,
2233                            callback,
2234                        } => {
2235                            self.focus_observations.add_or_remove_callback(
2236                                view_id,
2237                                subscription_id,
2238                                callback,
2239                            );
2240                        }
2241
2242                        Effect::ResizeWindow { window_id } => {
2243                            if let Some(window) = self.cx.windows.get_mut(&window_id) {
2244                                window
2245                                    .invalidation
2246                                    .get_or_insert(WindowInvalidation::default());
2247                            }
2248                        }
2249
2250                        Effect::WindowActivationObservation {
2251                            window_id,
2252                            subscription_id,
2253                            callback,
2254                        } => self.window_activation_observations.add_or_remove_callback(
2255                            window_id,
2256                            subscription_id,
2257                            callback,
2258                        ),
2259
2260                        Effect::ActivateWindow {
2261                            window_id,
2262                            is_active,
2263                        } => self.handle_window_activation_effect(window_id, is_active),
2264
2265                        Effect::WindowFullscreenObservation {
2266                            window_id,
2267                            subscription_id,
2268                            callback,
2269                        } => self.window_fullscreen_observations.add_or_remove_callback(
2270                            window_id,
2271                            subscription_id,
2272                            callback,
2273                        ),
2274
2275                        Effect::FullscreenWindow {
2276                            window_id,
2277                            is_fullscreen,
2278                        } => self.handle_fullscreen_effect(window_id, is_fullscreen),
2279
2280                        Effect::RefreshWindows => {
2281                            refreshing = true;
2282                        }
2283                        Effect::DispatchActionFrom {
2284                            window_id,
2285                            view_id,
2286                            action,
2287                        } => {
2288                            self.handle_dispatch_action_from_effect(
2289                                window_id,
2290                                Some(view_id),
2291                                action.as_ref(),
2292                            );
2293                        }
2294                        Effect::ActionDispatchNotification { action_id } => {
2295                            self.handle_action_dispatch_notification_effect(action_id)
2296                        }
2297                        Effect::WindowShouldCloseSubscription {
2298                            window_id,
2299                            callback,
2300                        } => {
2301                            self.handle_window_should_close_subscription_effect(window_id, callback)
2302                        }
2303                    }
2304                    self.pending_notifications.clear();
2305                    self.remove_dropped_entities();
2306                } else {
2307                    self.remove_dropped_entities();
2308                    if refreshing {
2309                        self.perform_window_refresh();
2310                    } else {
2311                        self.update_windows();
2312                    }
2313
2314                    if self.pending_effects.is_empty() {
2315                        for callback in after_window_update_callbacks.drain(..) {
2316                            callback(self);
2317                        }
2318
2319                        if self.pending_effects.is_empty() {
2320                            self.flushing_effects = false;
2321                            self.pending_notifications.clear();
2322                            self.pending_global_notifications.clear();
2323                            break;
2324                        }
2325                    }
2326
2327                    refreshing = false;
2328                }
2329            }
2330        }
2331    }
2332
2333    fn update_windows(&mut self) {
2334        let mut invalidations: HashMap<_, _> = Default::default();
2335        for (window_id, window) in &mut self.cx.windows {
2336            if let Some(invalidation) = window.invalidation.take() {
2337                invalidations.insert(*window_id, invalidation);
2338            }
2339        }
2340
2341        for (window_id, mut invalidation) in invalidations {
2342            if let Some((presenter, mut window)) =
2343                self.presenters_and_platform_windows.remove(&window_id)
2344            {
2345                {
2346                    let mut presenter = presenter.borrow_mut();
2347                    presenter.invalidate(&mut invalidation, self);
2348                    let scene =
2349                        presenter.build_scene(window.size(), window.scale_factor(), false, self);
2350                    window.present_scene(scene);
2351                }
2352                self.presenters_and_platform_windows
2353                    .insert(window_id, (presenter, window));
2354            }
2355        }
2356    }
2357
2358    fn window_was_resized(&mut self, window_id: usize) {
2359        self.pending_effects
2360            .push_back(Effect::ResizeWindow { window_id });
2361    }
2362
2363    fn window_was_fullscreen_changed(&mut self, window_id: usize, is_fullscreen: bool) {
2364        self.pending_effects.push_back(Effect::FullscreenWindow {
2365            window_id,
2366            is_fullscreen,
2367        });
2368    }
2369
2370    fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) {
2371        self.pending_effects.push_back(Effect::ActivateWindow {
2372            window_id,
2373            is_active,
2374        });
2375    }
2376
2377    pub fn refresh_windows(&mut self) {
2378        self.pending_effects.push_back(Effect::RefreshWindows);
2379    }
2380
2381    pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: impl Action) {
2382        self.dispatch_any_action_at(window_id, view_id, Box::new(action));
2383    }
2384
2385    pub fn dispatch_any_action_at(
2386        &mut self,
2387        window_id: usize,
2388        view_id: usize,
2389        action: Box<dyn Action>,
2390    ) {
2391        self.pending_effects.push_back(Effect::DispatchActionFrom {
2392            window_id,
2393            view_id,
2394            action,
2395        });
2396    }
2397
2398    fn perform_window_refresh(&mut self) {
2399        let mut presenters = mem::take(&mut self.presenters_and_platform_windows);
2400        for (window_id, (presenter, window)) in &mut presenters {
2401            let mut invalidation = self
2402                .cx
2403                .windows
2404                .get_mut(&window_id)
2405                .unwrap()
2406                .invalidation
2407                .take();
2408            let mut presenter = presenter.borrow_mut();
2409            presenter.refresh(
2410                invalidation.as_mut().unwrap_or(&mut Default::default()),
2411                self,
2412            );
2413            let scene = presenter.build_scene(window.size(), window.scale_factor(), true, self);
2414            window.present_scene(scene);
2415        }
2416        self.presenters_and_platform_windows = presenters;
2417    }
2418
2419    fn emit_global_event(&mut self, payload: Box<dyn Any>) {
2420        let type_id = (&*payload).type_id();
2421
2422        let mut subscriptions = self.global_subscriptions.clone();
2423        subscriptions.emit_and_cleanup(type_id, self, |callback, this| {
2424            callback(payload.as_ref(), this);
2425            true //Always alive
2426        });
2427    }
2428
2429    fn handle_view_notification_effect(
2430        &mut self,
2431        observed_window_id: usize,
2432        observed_view_id: usize,
2433    ) {
2434        if self
2435            .cx
2436            .views
2437            .contains_key(&(observed_window_id, observed_view_id))
2438        {
2439            if let Some(window) = self.cx.windows.get_mut(&observed_window_id) {
2440                window
2441                    .invalidation
2442                    .get_or_insert_with(Default::default)
2443                    .updated
2444                    .insert(observed_view_id);
2445            }
2446
2447            let mut observations = self.observations.clone();
2448            observations.emit_and_cleanup(observed_view_id, self, |callback, this| callback(this));
2449        }
2450    }
2451
2452    fn handle_entity_release_effect(&mut self, entity_id: usize, entity: &dyn Any) {
2453        let callbacks = self.release_observations.lock().remove(&entity_id);
2454        if let Some(callbacks) = callbacks {
2455            for (_, callback) in callbacks {
2456                callback(entity, self);
2457            }
2458        }
2459    }
2460
2461    fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) {
2462        //Short circuit evaluation if we're already g2g
2463        if self
2464            .cx
2465            .windows
2466            .get(&window_id)
2467            .map(|w| w.is_fullscreen == is_fullscreen)
2468            .unwrap_or(false)
2469        {
2470            return;
2471        }
2472
2473        self.update(|this| {
2474            let window = this.cx.windows.get_mut(&window_id)?;
2475            window.is_fullscreen = is_fullscreen;
2476
2477            let mut observations = this.window_fullscreen_observations.clone();
2478            observations.emit_and_cleanup(window_id, this, |callback, this| {
2479                callback(is_fullscreen, this)
2480            });
2481
2482            Some(())
2483        });
2484    }
2485
2486    fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) {
2487        //Short circuit evaluation if we're already g2g
2488        if self
2489            .cx
2490            .windows
2491            .get(&window_id)
2492            .map(|w| w.is_active == active)
2493            .unwrap_or(false)
2494        {
2495            return;
2496        }
2497
2498        self.update(|this| {
2499            let window = this.cx.windows.get_mut(&window_id)?;
2500            window.is_active = active;
2501
2502            //Handle focus
2503            let focused_id = window.focused_view_id?;
2504            for view_id in this.parents(window_id, focused_id).collect::<Vec<_>>() {
2505                if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2506                    if active {
2507                        view.on_focus_in(this, window_id, view_id, focused_id);
2508                    } else {
2509                        view.on_focus_out(this, window_id, view_id, focused_id);
2510                    }
2511                    this.cx.views.insert((window_id, view_id), view);
2512                }
2513            }
2514
2515            let mut observations = this.window_activation_observations.clone();
2516            observations.emit_and_cleanup(window_id, this, |callback, this| callback(active, this));
2517
2518            Some(())
2519        });
2520    }
2521
2522    fn handle_focus_effect(&mut self, window_id: usize, focused_id: Option<usize>) {
2523        self.pending_focus_index.take();
2524
2525        if self
2526            .cx
2527            .windows
2528            .get(&window_id)
2529            .map(|w| w.focused_view_id)
2530            .map_or(false, |cur_focused| cur_focused == focused_id)
2531        {
2532            return;
2533        }
2534
2535        self.update(|this| {
2536            let blurred_id = this.cx.windows.get_mut(&window_id).and_then(|window| {
2537                let blurred_id = window.focused_view_id;
2538                window.focused_view_id = focused_id;
2539                blurred_id
2540            });
2541
2542            let blurred_parents = blurred_id
2543                .map(|blurred_id| this.parents(window_id, blurred_id).collect::<Vec<_>>())
2544                .unwrap_or_default();
2545            let focused_parents = focused_id
2546                .map(|focused_id| this.parents(window_id, focused_id).collect::<Vec<_>>())
2547                .unwrap_or_default();
2548
2549            if let Some(blurred_id) = blurred_id {
2550                for view_id in blurred_parents.iter().copied() {
2551                    if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2552                        view.on_focus_out(this, window_id, view_id, blurred_id);
2553                        this.cx.views.insert((window_id, view_id), view);
2554                    }
2555                }
2556
2557                let mut subscriptions = this.focus_observations.clone();
2558                subscriptions
2559                    .emit_and_cleanup(blurred_id, this, |callback, this| callback(false, this));
2560            }
2561
2562            if let Some(focused_id) = focused_id {
2563                for view_id in focused_parents {
2564                    if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2565                        view.on_focus_in(this, window_id, view_id, focused_id);
2566                        this.cx.views.insert((window_id, view_id), view);
2567                    }
2568                }
2569
2570                let mut subscriptions = this.focus_observations.clone();
2571                subscriptions
2572                    .emit_and_cleanup(focused_id, this, |callback, this| callback(true, this));
2573            }
2574        })
2575    }
2576
2577    fn handle_dispatch_action_from_effect(
2578        &mut self,
2579        window_id: usize,
2580        view_id: Option<usize>,
2581        action: &dyn Action,
2582    ) -> bool {
2583        self.update(|this| {
2584            if let Some(view_id) = view_id {
2585                this.halt_action_dispatch = false;
2586                this.visit_dispatch_path(window_id, view_id, |view_id, capture_phase, this| {
2587                    if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) {
2588                        let type_id = view.as_any().type_id();
2589
2590                        if let Some((name, mut handlers)) = this
2591                            .actions_mut(capture_phase)
2592                            .get_mut(&type_id)
2593                            .and_then(|h| h.remove_entry(&action.id()))
2594                        {
2595                            for handler in handlers.iter_mut().rev() {
2596                                this.halt_action_dispatch = true;
2597                                handler(view.as_mut(), action, this, window_id, view_id);
2598                                if this.halt_action_dispatch {
2599                                    break;
2600                                }
2601                            }
2602                            this.actions_mut(capture_phase)
2603                                .get_mut(&type_id)
2604                                .unwrap()
2605                                .insert(name, handlers);
2606                        }
2607
2608                        this.cx.views.insert((window_id, view_id), view);
2609                    }
2610
2611                    !this.halt_action_dispatch
2612                });
2613            }
2614
2615            if !this.halt_action_dispatch {
2616                this.halt_action_dispatch = this.dispatch_global_action_any(action);
2617            }
2618
2619            this.pending_effects
2620                .push_back(Effect::ActionDispatchNotification {
2621                    action_id: action.id(),
2622                });
2623            this.halt_action_dispatch
2624        })
2625    }
2626
2627    fn handle_action_dispatch_notification_effect(&mut self, action_id: TypeId) {
2628        let mut callbacks = mem::take(&mut *self.action_dispatch_observations.lock());
2629        for (_, callback) in &mut callbacks {
2630            callback(action_id, self);
2631        }
2632        self.action_dispatch_observations.lock().extend(callbacks);
2633    }
2634
2635    fn handle_window_should_close_subscription_effect(
2636        &mut self,
2637        window_id: usize,
2638        mut callback: WindowShouldCloseSubscriptionCallback,
2639    ) {
2640        let mut app = self.upgrade();
2641        if let Some((_, window)) = self.presenters_and_platform_windows.get_mut(&window_id) {
2642            window.on_should_close(Box::new(move || app.update(|cx| callback(cx))))
2643        }
2644    }
2645
2646    pub fn focus(&mut self, window_id: usize, view_id: Option<usize>) {
2647        if let Some(pending_focus_index) = self.pending_focus_index {
2648            self.pending_effects.remove(pending_focus_index);
2649        }
2650        self.pending_focus_index = Some(self.pending_effects.len());
2651        self.pending_effects
2652            .push_back(Effect::Focus { window_id, view_id });
2653    }
2654
2655    pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
2656    where
2657        F: FnOnce(AsyncAppContext) -> Fut,
2658        Fut: 'static + Future<Output = T>,
2659        T: 'static,
2660    {
2661        let future = f(self.to_async());
2662        let cx = self.to_async();
2663        self.foreground.spawn(async move {
2664            let result = future.await;
2665            cx.0.borrow_mut().flush_effects();
2666            result
2667        })
2668    }
2669
2670    pub fn to_async(&self) -> AsyncAppContext {
2671        AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
2672    }
2673
2674    pub fn write_to_clipboard(&self, item: ClipboardItem) {
2675        self.cx.platform.write_to_clipboard(item);
2676    }
2677
2678    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
2679        self.cx.platform.read_from_clipboard()
2680    }
2681
2682    #[cfg(any(test, feature = "test-support"))]
2683    pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
2684        self.cx.ref_counts.lock().leak_detector.clone()
2685    }
2686}
2687
2688impl ReadModel for MutableAppContext {
2689    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2690        if let Some(model) = self.cx.models.get(&handle.model_id) {
2691            model
2692                .as_any()
2693                .downcast_ref()
2694                .expect("downcast is type safe")
2695        } else {
2696            panic!("circular model reference");
2697        }
2698    }
2699}
2700
2701impl UpdateModel for MutableAppContext {
2702    fn update_model<T: Entity, V>(
2703        &mut self,
2704        handle: &ModelHandle<T>,
2705        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
2706    ) -> V {
2707        if let Some(mut model) = self.cx.models.remove(&handle.model_id) {
2708            self.update(|this| {
2709                let mut cx = ModelContext::new(this, handle.model_id);
2710                let result = update(
2711                    model
2712                        .as_any_mut()
2713                        .downcast_mut()
2714                        .expect("downcast is type safe"),
2715                    &mut cx,
2716                );
2717                this.cx.models.insert(handle.model_id, model);
2718                result
2719            })
2720        } else {
2721            panic!("circular model update");
2722        }
2723    }
2724}
2725
2726impl UpgradeModelHandle for MutableAppContext {
2727    fn upgrade_model_handle<T: Entity>(
2728        &self,
2729        handle: &WeakModelHandle<T>,
2730    ) -> Option<ModelHandle<T>> {
2731        self.cx.upgrade_model_handle(handle)
2732    }
2733
2734    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2735        self.cx.model_handle_is_upgradable(handle)
2736    }
2737
2738    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2739        self.cx.upgrade_any_model_handle(handle)
2740    }
2741}
2742
2743impl UpgradeViewHandle for MutableAppContext {
2744    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2745        self.cx.upgrade_view_handle(handle)
2746    }
2747
2748    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2749        self.cx.upgrade_any_view_handle(handle)
2750    }
2751}
2752
2753impl ReadView for MutableAppContext {
2754    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2755        if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) {
2756            view.as_any().downcast_ref().expect("downcast is type safe")
2757        } else {
2758            panic!("circular view reference for type {}", type_name::<T>());
2759        }
2760    }
2761}
2762
2763impl UpdateView for MutableAppContext {
2764    fn update_view<T, S>(
2765        &mut self,
2766        handle: &ViewHandle<T>,
2767        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
2768    ) -> S
2769    where
2770        T: View,
2771    {
2772        self.update(|this| {
2773            let mut view = this
2774                .cx
2775                .views
2776                .remove(&(handle.window_id, handle.view_id))
2777                .expect("circular view update");
2778
2779            let mut cx = ViewContext::new(this, handle.window_id, handle.view_id);
2780            let result = update(
2781                view.as_any_mut()
2782                    .downcast_mut()
2783                    .expect("downcast is type safe"),
2784                &mut cx,
2785            );
2786            this.cx
2787                .views
2788                .insert((handle.window_id, handle.view_id), view);
2789            result
2790        })
2791    }
2792}
2793
2794impl AsRef<AppContext> for MutableAppContext {
2795    fn as_ref(&self) -> &AppContext {
2796        &self.cx
2797    }
2798}
2799
2800impl Deref for MutableAppContext {
2801    type Target = AppContext;
2802
2803    fn deref(&self) -> &Self::Target {
2804        &self.cx
2805    }
2806}
2807
2808#[derive(Debug)]
2809pub enum ParentId {
2810    View(usize),
2811    Root,
2812}
2813
2814pub struct AppContext {
2815    models: HashMap<usize, Box<dyn AnyModel>>,
2816    views: HashMap<(usize, usize), Box<dyn AnyView>>,
2817    pub(crate) parents: HashMap<(usize, usize), ParentId>,
2818    windows: HashMap<usize, Window>,
2819    globals: HashMap<TypeId, Box<dyn Any>>,
2820    element_states: HashMap<ElementStateId, Box<dyn Any>>,
2821    background: Arc<executor::Background>,
2822    ref_counts: Arc<Mutex<RefCounts>>,
2823    font_cache: Arc<FontCache>,
2824    platform: Arc<dyn Platform>,
2825}
2826
2827impl AppContext {
2828    pub(crate) fn root_view(&self, window_id: usize) -> Option<AnyViewHandle> {
2829        self.windows
2830            .get(&window_id)
2831            .map(|window| window.root_view.clone())
2832    }
2833
2834    pub fn root_view_id(&self, window_id: usize) -> Option<usize> {
2835        self.windows
2836            .get(&window_id)
2837            .map(|window| window.root_view.id())
2838    }
2839
2840    pub fn focused_view_id(&self, window_id: usize) -> Option<usize> {
2841        self.windows
2842            .get(&window_id)
2843            .and_then(|window| window.focused_view_id)
2844    }
2845
2846    pub fn background(&self) -> &Arc<executor::Background> {
2847        &self.background
2848    }
2849
2850    pub fn font_cache(&self) -> &Arc<FontCache> {
2851        &self.font_cache
2852    }
2853
2854    pub fn platform(&self) -> &Arc<dyn Platform> {
2855        &self.platform
2856    }
2857
2858    pub fn has_global<T: 'static>(&self) -> bool {
2859        self.globals.contains_key(&TypeId::of::<T>())
2860    }
2861
2862    pub fn global<T: 'static>(&self) -> &T {
2863        if let Some(global) = self.globals.get(&TypeId::of::<T>()) {
2864            global.downcast_ref().unwrap()
2865        } else {
2866            panic!("no global has been added for {}", type_name::<T>());
2867        }
2868    }
2869}
2870
2871impl ReadModel for AppContext {
2872    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
2873        if let Some(model) = self.models.get(&handle.model_id) {
2874            model
2875                .as_any()
2876                .downcast_ref()
2877                .expect("downcast should be type safe")
2878        } else {
2879            panic!("circular model reference");
2880        }
2881    }
2882}
2883
2884impl UpgradeModelHandle for AppContext {
2885    fn upgrade_model_handle<T: Entity>(
2886        &self,
2887        handle: &WeakModelHandle<T>,
2888    ) -> Option<ModelHandle<T>> {
2889        if self.models.contains_key(&handle.model_id) {
2890            Some(ModelHandle::new(handle.model_id, &self.ref_counts))
2891        } else {
2892            None
2893        }
2894    }
2895
2896    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
2897        self.models.contains_key(&handle.model_id)
2898    }
2899
2900    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
2901        if self.models.contains_key(&handle.model_id) {
2902            Some(AnyModelHandle::new(
2903                handle.model_id,
2904                handle.model_type,
2905                self.ref_counts.clone(),
2906            ))
2907        } else {
2908            None
2909        }
2910    }
2911}
2912
2913impl UpgradeViewHandle for AppContext {
2914    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
2915        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2916            Some(ViewHandle::new(
2917                handle.window_id,
2918                handle.view_id,
2919                &self.ref_counts,
2920            ))
2921        } else {
2922            None
2923        }
2924    }
2925
2926    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
2927        if self.ref_counts.lock().is_entity_alive(handle.view_id) {
2928            Some(AnyViewHandle::new(
2929                handle.window_id,
2930                handle.view_id,
2931                handle.view_type,
2932                self.ref_counts.clone(),
2933            ))
2934        } else {
2935            None
2936        }
2937    }
2938}
2939
2940impl ReadView for AppContext {
2941    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
2942        if let Some(view) = self.views.get(&(handle.window_id, handle.view_id)) {
2943            view.as_any()
2944                .downcast_ref()
2945                .expect("downcast should be type safe")
2946        } else {
2947            panic!("circular view reference");
2948        }
2949    }
2950}
2951
2952struct Window {
2953    root_view: AnyViewHandle,
2954    focused_view_id: Option<usize>,
2955    is_active: bool,
2956    is_fullscreen: bool,
2957    invalidation: Option<WindowInvalidation>,
2958}
2959
2960#[derive(Default, Clone)]
2961pub struct WindowInvalidation {
2962    pub updated: HashSet<usize>,
2963    pub removed: Vec<usize>,
2964}
2965
2966pub enum Effect {
2967    Subscription {
2968        entity_id: usize,
2969        subscription_id: usize,
2970        callback: SubscriptionCallback,
2971    },
2972    Event {
2973        entity_id: usize,
2974        payload: Box<dyn Any>,
2975    },
2976    GlobalSubscription {
2977        type_id: TypeId,
2978        subscription_id: usize,
2979        callback: GlobalSubscriptionCallback,
2980    },
2981    GlobalEvent {
2982        payload: Box<dyn Any>,
2983    },
2984    Observation {
2985        entity_id: usize,
2986        subscription_id: usize,
2987        callback: ObservationCallback,
2988    },
2989    ModelNotification {
2990        model_id: usize,
2991    },
2992    ViewNotification {
2993        window_id: usize,
2994        view_id: usize,
2995    },
2996    Deferred {
2997        callback: Box<dyn FnOnce(&mut MutableAppContext)>,
2998        after_window_update: bool,
2999    },
3000    GlobalNotification {
3001        type_id: TypeId,
3002    },
3003    ModelRelease {
3004        model_id: usize,
3005        model: Box<dyn AnyModel>,
3006    },
3007    ViewRelease {
3008        view_id: usize,
3009        view: Box<dyn AnyView>,
3010    },
3011    Focus {
3012        window_id: usize,
3013        view_id: Option<usize>,
3014    },
3015    FocusObservation {
3016        view_id: usize,
3017        subscription_id: usize,
3018        callback: FocusObservationCallback,
3019    },
3020    ResizeWindow {
3021        window_id: usize,
3022    },
3023    FullscreenWindow {
3024        window_id: usize,
3025        is_fullscreen: bool,
3026    },
3027    ActivateWindow {
3028        window_id: usize,
3029        is_active: bool,
3030    },
3031    WindowActivationObservation {
3032        window_id: usize,
3033        subscription_id: usize,
3034        callback: WindowActivationCallback,
3035    },
3036    WindowFullscreenObservation {
3037        window_id: usize,
3038        subscription_id: usize,
3039        callback: WindowFullscreenCallback,
3040    },
3041    RefreshWindows,
3042    DispatchActionFrom {
3043        window_id: usize,
3044        view_id: usize,
3045        action: Box<dyn Action>,
3046    },
3047    ActionDispatchNotification {
3048        action_id: TypeId,
3049    },
3050    WindowShouldCloseSubscription {
3051        window_id: usize,
3052        callback: WindowShouldCloseSubscriptionCallback,
3053    },
3054}
3055
3056impl Debug for Effect {
3057    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3058        match self {
3059            Effect::Subscription {
3060                entity_id,
3061                subscription_id,
3062                ..
3063            } => f
3064                .debug_struct("Effect::Subscribe")
3065                .field("entity_id", entity_id)
3066                .field("subscription_id", subscription_id)
3067                .finish(),
3068            Effect::Event { entity_id, .. } => f
3069                .debug_struct("Effect::Event")
3070                .field("entity_id", entity_id)
3071                .finish(),
3072            Effect::GlobalSubscription {
3073                type_id,
3074                subscription_id,
3075                ..
3076            } => f
3077                .debug_struct("Effect::Subscribe")
3078                .field("type_id", type_id)
3079                .field("subscription_id", subscription_id)
3080                .finish(),
3081            Effect::GlobalEvent { payload, .. } => f
3082                .debug_struct("Effect::GlobalEvent")
3083                .field("type_id", &(&*payload).type_id())
3084                .finish(),
3085            Effect::Observation {
3086                entity_id,
3087                subscription_id,
3088                ..
3089            } => f
3090                .debug_struct("Effect::Observation")
3091                .field("entity_id", entity_id)
3092                .field("subscription_id", subscription_id)
3093                .finish(),
3094            Effect::ModelNotification { model_id } => f
3095                .debug_struct("Effect::ModelNotification")
3096                .field("model_id", model_id)
3097                .finish(),
3098            Effect::ViewNotification { window_id, view_id } => f
3099                .debug_struct("Effect::ViewNotification")
3100                .field("window_id", window_id)
3101                .field("view_id", view_id)
3102                .finish(),
3103            Effect::GlobalNotification { type_id } => f
3104                .debug_struct("Effect::GlobalNotification")
3105                .field("type_id", type_id)
3106                .finish(),
3107            Effect::Deferred { .. } => f.debug_struct("Effect::Deferred").finish(),
3108            Effect::ModelRelease { model_id, .. } => f
3109                .debug_struct("Effect::ModelRelease")
3110                .field("model_id", model_id)
3111                .finish(),
3112            Effect::ViewRelease { view_id, .. } => f
3113                .debug_struct("Effect::ViewRelease")
3114                .field("view_id", view_id)
3115                .finish(),
3116            Effect::Focus { window_id, view_id } => f
3117                .debug_struct("Effect::Focus")
3118                .field("window_id", window_id)
3119                .field("view_id", view_id)
3120                .finish(),
3121            Effect::FocusObservation {
3122                view_id,
3123                subscription_id,
3124                ..
3125            } => f
3126                .debug_struct("Effect::FocusObservation")
3127                .field("view_id", view_id)
3128                .field("subscription_id", subscription_id)
3129                .finish(),
3130            Effect::DispatchActionFrom {
3131                window_id, view_id, ..
3132            } => f
3133                .debug_struct("Effect::DispatchActionFrom")
3134                .field("window_id", window_id)
3135                .field("view_id", view_id)
3136                .finish(),
3137            Effect::ActionDispatchNotification { action_id, .. } => f
3138                .debug_struct("Effect::ActionDispatchNotification")
3139                .field("action_id", action_id)
3140                .finish(),
3141            Effect::ResizeWindow { window_id } => f
3142                .debug_struct("Effect::RefreshWindow")
3143                .field("window_id", window_id)
3144                .finish(),
3145            Effect::WindowActivationObservation {
3146                window_id,
3147                subscription_id,
3148                ..
3149            } => f
3150                .debug_struct("Effect::WindowActivationObservation")
3151                .field("window_id", window_id)
3152                .field("subscription_id", subscription_id)
3153                .finish(),
3154            Effect::ActivateWindow {
3155                window_id,
3156                is_active,
3157            } => f
3158                .debug_struct("Effect::ActivateWindow")
3159                .field("window_id", window_id)
3160                .field("is_active", is_active)
3161                .finish(),
3162            Effect::FullscreenWindow {
3163                window_id,
3164                is_fullscreen,
3165            } => f
3166                .debug_struct("Effect::FullscreenWindow")
3167                .field("window_id", window_id)
3168                .field("is_fullscreen", is_fullscreen)
3169                .finish(),
3170            Effect::WindowFullscreenObservation {
3171                window_id,
3172                subscription_id,
3173                callback: _,
3174            } => f
3175                .debug_struct("Effect::WindowFullscreenObservation")
3176                .field("window_id", window_id)
3177                .field("subscription_id", subscription_id)
3178                .finish(),
3179            Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
3180            Effect::WindowShouldCloseSubscription { window_id, .. } => f
3181                .debug_struct("Effect::WindowShouldCloseSubscription")
3182                .field("window_id", window_id)
3183                .finish(),
3184        }
3185    }
3186}
3187
3188pub trait AnyModel {
3189    fn as_any(&self) -> &dyn Any;
3190    fn as_any_mut(&mut self) -> &mut dyn Any;
3191    fn release(&mut self, cx: &mut MutableAppContext);
3192    fn app_will_quit(
3193        &mut self,
3194        cx: &mut MutableAppContext,
3195    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
3196}
3197
3198impl<T> AnyModel for T
3199where
3200    T: Entity,
3201{
3202    fn as_any(&self) -> &dyn Any {
3203        self
3204    }
3205
3206    fn as_any_mut(&mut self) -> &mut dyn Any {
3207        self
3208    }
3209
3210    fn release(&mut self, cx: &mut MutableAppContext) {
3211        self.release(cx);
3212    }
3213
3214    fn app_will_quit(
3215        &mut self,
3216        cx: &mut MutableAppContext,
3217    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
3218        self.app_will_quit(cx)
3219    }
3220}
3221
3222pub trait AnyView {
3223    fn as_any(&self) -> &dyn Any;
3224    fn as_any_mut(&mut self) -> &mut dyn Any;
3225    fn release(&mut self, cx: &mut MutableAppContext);
3226    fn app_will_quit(
3227        &mut self,
3228        cx: &mut MutableAppContext,
3229    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
3230    fn ui_name(&self) -> &'static str;
3231    fn render<'a>(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox;
3232    fn on_focus_in(
3233        &mut self,
3234        cx: &mut MutableAppContext,
3235        window_id: usize,
3236        view_id: usize,
3237        focused_id: usize,
3238    );
3239    fn on_focus_out(
3240        &mut self,
3241        cx: &mut MutableAppContext,
3242        window_id: usize,
3243        view_id: usize,
3244        focused_id: usize,
3245    );
3246    fn keymap_context(&self, cx: &AppContext) -> keymap::Context;
3247    fn debug_json(&self, cx: &AppContext) -> serde_json::Value;
3248
3249    fn text_for_range(&self, range: Range<usize>, cx: &AppContext) -> Option<String>;
3250    fn selected_text_range(&self, cx: &AppContext) -> Option<Range<usize>>;
3251    fn marked_text_range(&self, cx: &AppContext) -> Option<Range<usize>>;
3252    fn unmark_text(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize);
3253    fn replace_text_in_range(
3254        &mut self,
3255        range: Option<Range<usize>>,
3256        text: &str,
3257        cx: &mut MutableAppContext,
3258        window_id: usize,
3259        view_id: usize,
3260    );
3261    fn replace_and_mark_text_in_range(
3262        &mut self,
3263        range: Option<Range<usize>>,
3264        new_text: &str,
3265        new_selected_range: Option<Range<usize>>,
3266        cx: &mut MutableAppContext,
3267        window_id: usize,
3268        view_id: usize,
3269    );
3270    fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle {
3271        AnyViewHandle::new(
3272            window_id,
3273            view_id,
3274            self.as_any().type_id(),
3275            cx.ref_counts.clone(),
3276        )
3277    }
3278}
3279
3280impl<T> AnyView for T
3281where
3282    T: View,
3283{
3284    fn as_any(&self) -> &dyn Any {
3285        self
3286    }
3287
3288    fn as_any_mut(&mut self) -> &mut dyn Any {
3289        self
3290    }
3291
3292    fn release(&mut self, cx: &mut MutableAppContext) {
3293        self.release(cx);
3294    }
3295
3296    fn app_will_quit(
3297        &mut self,
3298        cx: &mut MutableAppContext,
3299    ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
3300        self.app_will_quit(cx)
3301    }
3302
3303    fn ui_name(&self) -> &'static str {
3304        T::ui_name()
3305    }
3306
3307    fn render<'a>(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox {
3308        View::render(self, &mut RenderContext::new(params, cx))
3309    }
3310
3311    fn on_focus_in(
3312        &mut self,
3313        cx: &mut MutableAppContext,
3314        window_id: usize,
3315        view_id: usize,
3316        focused_id: usize,
3317    ) {
3318        let mut cx = ViewContext::new(cx, window_id, view_id);
3319        let focused_view_handle: AnyViewHandle = if view_id == focused_id {
3320            cx.handle().into()
3321        } else {
3322            let focused_type = cx
3323                .views
3324                .get(&(window_id, focused_id))
3325                .unwrap()
3326                .as_any()
3327                .type_id();
3328            AnyViewHandle::new(window_id, focused_id, focused_type, cx.ref_counts.clone())
3329        };
3330        View::on_focus_in(self, focused_view_handle, &mut cx);
3331    }
3332
3333    fn on_focus_out(
3334        &mut self,
3335        cx: &mut MutableAppContext,
3336        window_id: usize,
3337        view_id: usize,
3338        blurred_id: usize,
3339    ) {
3340        let mut cx = ViewContext::new(cx, window_id, view_id);
3341        let blurred_view_handle: AnyViewHandle = if view_id == blurred_id {
3342            cx.handle().into()
3343        } else {
3344            let blurred_type = cx
3345                .views
3346                .get(&(window_id, blurred_id))
3347                .unwrap()
3348                .as_any()
3349                .type_id();
3350            AnyViewHandle::new(window_id, blurred_id, blurred_type, cx.ref_counts.clone())
3351        };
3352        View::on_focus_out(self, blurred_view_handle, &mut cx);
3353    }
3354
3355    fn keymap_context(&self, cx: &AppContext) -> keymap::Context {
3356        View::keymap_context(self, cx)
3357    }
3358
3359    fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
3360        View::debug_json(self, cx)
3361    }
3362
3363    fn text_for_range(&self, range: Range<usize>, cx: &AppContext) -> Option<String> {
3364        View::text_for_range(self, range, cx)
3365    }
3366
3367    fn selected_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
3368        View::selected_text_range(self, cx)
3369    }
3370
3371    fn marked_text_range(&self, cx: &AppContext) -> Option<Range<usize>> {
3372        View::marked_text_range(self, cx)
3373    }
3374
3375    fn unmark_text(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) {
3376        let mut cx = ViewContext::new(cx, window_id, view_id);
3377        View::unmark_text(self, &mut cx)
3378    }
3379
3380    fn replace_text_in_range(
3381        &mut self,
3382        range: Option<Range<usize>>,
3383        text: &str,
3384        cx: &mut MutableAppContext,
3385        window_id: usize,
3386        view_id: usize,
3387    ) {
3388        let mut cx = ViewContext::new(cx, window_id, view_id);
3389        View::replace_text_in_range(self, range, text, &mut cx)
3390    }
3391
3392    fn replace_and_mark_text_in_range(
3393        &mut self,
3394        range: Option<Range<usize>>,
3395        new_text: &str,
3396        new_selected_range: Option<Range<usize>>,
3397        cx: &mut MutableAppContext,
3398        window_id: usize,
3399        view_id: usize,
3400    ) {
3401        let mut cx = ViewContext::new(cx, window_id, view_id);
3402        View::replace_and_mark_text_in_range(self, range, new_text, new_selected_range, &mut cx)
3403    }
3404}
3405
3406pub struct ModelContext<'a, T: ?Sized> {
3407    app: &'a mut MutableAppContext,
3408    model_id: usize,
3409    model_type: PhantomData<T>,
3410    halt_stream: bool,
3411}
3412
3413impl<'a, T: Entity> ModelContext<'a, T> {
3414    fn new(app: &'a mut MutableAppContext, model_id: usize) -> Self {
3415        Self {
3416            app,
3417            model_id,
3418            model_type: PhantomData,
3419            halt_stream: false,
3420        }
3421    }
3422
3423    pub fn background(&self) -> &Arc<executor::Background> {
3424        &self.app.cx.background
3425    }
3426
3427    pub fn halt_stream(&mut self) {
3428        self.halt_stream = true;
3429    }
3430
3431    pub fn model_id(&self) -> usize {
3432        self.model_id
3433    }
3434
3435    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
3436    where
3437        S: Entity,
3438        F: FnOnce(&mut ModelContext<S>) -> S,
3439    {
3440        self.app.add_model(build_model)
3441    }
3442
3443    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ModelContext<T>)) {
3444        let handle = self.handle();
3445        self.app.defer(move |cx| {
3446            handle.update(cx, |model, cx| {
3447                callback(model, cx);
3448            })
3449        })
3450    }
3451
3452    pub fn emit(&mut self, payload: T::Event) {
3453        self.app.pending_effects.push_back(Effect::Event {
3454            entity_id: self.model_id,
3455            payload: Box::new(payload),
3456        });
3457    }
3458
3459    pub fn notify(&mut self) {
3460        self.app.notify_model(self.model_id);
3461    }
3462
3463    pub fn subscribe<S: Entity, F>(
3464        &mut self,
3465        handle: &ModelHandle<S>,
3466        mut callback: F,
3467    ) -> Subscription
3468    where
3469        S::Event: 'static,
3470        F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
3471    {
3472        let subscriber = self.weak_handle();
3473        self.app
3474            .subscribe_internal(handle, move |emitter, event, cx| {
3475                if let Some(subscriber) = subscriber.upgrade(cx) {
3476                    subscriber.update(cx, |subscriber, cx| {
3477                        callback(subscriber, emitter, event, cx);
3478                    });
3479                    true
3480                } else {
3481                    false
3482                }
3483            })
3484    }
3485
3486    pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
3487    where
3488        S: Entity,
3489        F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
3490    {
3491        let observer = self.weak_handle();
3492        self.app.observe_internal(handle, move |observed, cx| {
3493            if let Some(observer) = observer.upgrade(cx) {
3494                observer.update(cx, |observer, cx| {
3495                    callback(observer, observed, cx);
3496                });
3497                true
3498            } else {
3499                false
3500            }
3501        })
3502    }
3503
3504    pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
3505    where
3506        G: Any,
3507        F: 'static + FnMut(&mut T, &mut ModelContext<T>),
3508    {
3509        let observer = self.weak_handle();
3510        self.app.observe_global::<G, _>(move |cx| {
3511            if let Some(observer) = observer.upgrade(cx) {
3512                observer.update(cx, |observer, cx| callback(observer, cx));
3513            }
3514        })
3515    }
3516
3517    pub fn observe_release<S, F>(
3518        &mut self,
3519        handle: &ModelHandle<S>,
3520        mut callback: F,
3521    ) -> Subscription
3522    where
3523        S: Entity,
3524        F: 'static + FnMut(&mut T, &S, &mut ModelContext<T>),
3525    {
3526        let observer = self.weak_handle();
3527        self.app.observe_release(handle, move |released, cx| {
3528            if let Some(observer) = observer.upgrade(cx) {
3529                observer.update(cx, |observer, cx| {
3530                    callback(observer, released, cx);
3531                });
3532            }
3533        })
3534    }
3535
3536    pub fn handle(&self) -> ModelHandle<T> {
3537        ModelHandle::new(self.model_id, &self.app.cx.ref_counts)
3538    }
3539
3540    pub fn weak_handle(&self) -> WeakModelHandle<T> {
3541        WeakModelHandle::new(self.model_id)
3542    }
3543
3544    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3545    where
3546        F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
3547        Fut: 'static + Future<Output = S>,
3548        S: 'static,
3549    {
3550        let handle = self.handle();
3551        self.app.spawn(|cx| f(handle, cx))
3552    }
3553
3554    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3555    where
3556        F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
3557        Fut: 'static + Future<Output = S>,
3558        S: 'static,
3559    {
3560        let handle = self.weak_handle();
3561        self.app.spawn(|cx| f(handle, cx))
3562    }
3563}
3564
3565impl<M> AsRef<AppContext> for ModelContext<'_, M> {
3566    fn as_ref(&self) -> &AppContext {
3567        &self.app.cx
3568    }
3569}
3570
3571impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
3572    fn as_mut(&mut self) -> &mut MutableAppContext {
3573        self.app
3574    }
3575}
3576
3577impl<M> ReadModel for ModelContext<'_, M> {
3578    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
3579        self.app.read_model(handle)
3580    }
3581}
3582
3583impl<M> UpdateModel for ModelContext<'_, M> {
3584    fn update_model<T: Entity, V>(
3585        &mut self,
3586        handle: &ModelHandle<T>,
3587        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
3588    ) -> V {
3589        self.app.update_model(handle, update)
3590    }
3591}
3592
3593impl<M> UpgradeModelHandle for ModelContext<'_, M> {
3594    fn upgrade_model_handle<T: Entity>(
3595        &self,
3596        handle: &WeakModelHandle<T>,
3597    ) -> Option<ModelHandle<T>> {
3598        self.cx.upgrade_model_handle(handle)
3599    }
3600
3601    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
3602        self.cx.model_handle_is_upgradable(handle)
3603    }
3604
3605    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
3606        self.cx.upgrade_any_model_handle(handle)
3607    }
3608}
3609
3610impl<M> Deref for ModelContext<'_, M> {
3611    type Target = MutableAppContext;
3612
3613    fn deref(&self) -> &Self::Target {
3614        &self.app
3615    }
3616}
3617
3618impl<M> DerefMut for ModelContext<'_, M> {
3619    fn deref_mut(&mut self) -> &mut Self::Target {
3620        &mut self.app
3621    }
3622}
3623
3624pub struct ViewContext<'a, T: ?Sized> {
3625    app: &'a mut MutableAppContext,
3626    window_id: usize,
3627    view_id: usize,
3628    view_type: PhantomData<T>,
3629}
3630
3631impl<'a, T: View> ViewContext<'a, T> {
3632    fn new(app: &'a mut MutableAppContext, window_id: usize, view_id: usize) -> Self {
3633        Self {
3634            app,
3635            window_id,
3636            view_id,
3637            view_type: PhantomData,
3638        }
3639    }
3640
3641    pub fn handle(&self) -> ViewHandle<T> {
3642        ViewHandle::new(self.window_id, self.view_id, &self.app.cx.ref_counts)
3643    }
3644
3645    pub fn weak_handle(&self) -> WeakViewHandle<T> {
3646        WeakViewHandle::new(self.window_id, self.view_id)
3647    }
3648
3649    pub fn window_id(&self) -> usize {
3650        self.window_id
3651    }
3652
3653    pub fn view_id(&self) -> usize {
3654        self.view_id
3655    }
3656
3657    pub fn foreground(&self) -> &Rc<executor::Foreground> {
3658        self.app.foreground()
3659    }
3660
3661    pub fn background_executor(&self) -> &Arc<executor::Background> {
3662        &self.app.cx.background
3663    }
3664
3665    pub fn platform(&self) -> Arc<dyn Platform> {
3666        self.app.platform()
3667    }
3668
3669    pub fn show_character_palette(&self) {
3670        self.app.show_character_palette(self.window_id);
3671    }
3672
3673    pub fn minimize_window(&self) {
3674        self.app.minimize_window(self.window_id)
3675    }
3676
3677    pub fn zoom_window(&self) {
3678        self.app.zoom_window(self.window_id)
3679    }
3680
3681    pub fn prompt(
3682        &self,
3683        level: PromptLevel,
3684        msg: &str,
3685        answers: &[&str],
3686    ) -> oneshot::Receiver<usize> {
3687        self.app.prompt(self.window_id, level, msg, answers)
3688    }
3689
3690    pub fn prompt_for_paths(
3691        &self,
3692        options: PathPromptOptions,
3693    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
3694        self.app.prompt_for_paths(options)
3695    }
3696
3697    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
3698        self.app.prompt_for_new_path(directory)
3699    }
3700
3701    pub fn debug_elements(&self) -> crate::json::Value {
3702        self.app.debug_elements(self.window_id).unwrap()
3703    }
3704
3705    pub fn focus<S>(&mut self, handle: S)
3706    where
3707        S: Into<AnyViewHandle>,
3708    {
3709        let handle = handle.into();
3710        self.app.focus(handle.window_id, Some(handle.view_id));
3711    }
3712
3713    pub fn focus_self(&mut self) {
3714        self.app.focus(self.window_id, Some(self.view_id));
3715    }
3716
3717    pub fn is_self_focused(&self) -> bool {
3718        self.app.focused_view_id(self.window_id) == Some(self.view_id)
3719    }
3720
3721    pub fn blur(&mut self) {
3722        self.app.focus(self.window_id, None);
3723    }
3724
3725    pub fn set_window_title(&mut self, title: &str) {
3726        let window_id = self.window_id();
3727        if let Some((_, window)) = self.presenters_and_platform_windows.get_mut(&window_id) {
3728            window.set_title(title);
3729        }
3730    }
3731
3732    pub fn set_window_edited(&mut self, edited: bool) {
3733        let window_id = self.window_id();
3734        if let Some((_, window)) = self.presenters_and_platform_windows.get_mut(&window_id) {
3735            window.set_edited(edited);
3736        }
3737    }
3738
3739    pub fn on_window_should_close<F>(&mut self, mut callback: F)
3740    where
3741        F: 'static + FnMut(&mut T, &mut ViewContext<T>) -> bool,
3742    {
3743        let window_id = self.window_id();
3744        let view = self.weak_handle();
3745        self.pending_effects
3746            .push_back(Effect::WindowShouldCloseSubscription {
3747                window_id,
3748                callback: Box::new(move |cx| {
3749                    if let Some(view) = view.upgrade(cx) {
3750                        view.update(cx, |view, cx| callback(view, cx))
3751                    } else {
3752                        true
3753                    }
3754                }),
3755            });
3756    }
3757
3758    pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
3759    where
3760        S: Entity,
3761        F: FnOnce(&mut ModelContext<S>) -> S,
3762    {
3763        self.app.add_model(build_model)
3764    }
3765
3766    pub fn add_view<S, F>(&mut self, build_view: F) -> ViewHandle<S>
3767    where
3768        S: View,
3769        F: FnOnce(&mut ViewContext<S>) -> S,
3770    {
3771        self.app
3772            .build_and_insert_view(self.window_id, ParentId::View(self.view_id), |cx| {
3773                Some(build_view(cx))
3774            })
3775            .unwrap()
3776    }
3777
3778    pub fn add_option_view<S, F>(&mut self, build_view: F) -> Option<ViewHandle<S>>
3779    where
3780        S: View,
3781        F: FnOnce(&mut ViewContext<S>) -> Option<S>,
3782    {
3783        self.app
3784            .build_and_insert_view(self.window_id, ParentId::View(self.view_id), build_view)
3785    }
3786
3787    pub fn reparent(&mut self, view_handle: impl Into<AnyViewHandle>) {
3788        let view_handle = view_handle.into();
3789        if self.window_id != view_handle.window_id {
3790            panic!("Can't reparent view to a view from a different window");
3791        }
3792        self.cx
3793            .parents
3794            .remove(&(view_handle.window_id, view_handle.view_id));
3795        let new_parent_id = self.view_id;
3796        self.cx.parents.insert(
3797            (view_handle.window_id, view_handle.view_id),
3798            ParentId::View(new_parent_id),
3799        );
3800    }
3801
3802    pub fn replace_root_view<V, F>(&mut self, build_root_view: F) -> ViewHandle<V>
3803    where
3804        V: View,
3805        F: FnOnce(&mut ViewContext<V>) -> V,
3806    {
3807        let window_id = self.window_id;
3808        self.update(|this| {
3809            let root_view = this
3810                .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx)))
3811                .unwrap();
3812            let window = this.cx.windows.get_mut(&window_id).unwrap();
3813            window.root_view = root_view.clone().into();
3814            window.focused_view_id = Some(root_view.id());
3815            root_view
3816        })
3817    }
3818
3819    pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3820    where
3821        E: Entity,
3822        E::Event: 'static,
3823        H: Handle<E>,
3824        F: 'static + FnMut(&mut T, H, &E::Event, &mut ViewContext<T>),
3825    {
3826        let subscriber = self.weak_handle();
3827        self.app
3828            .subscribe_internal(handle, move |emitter, event, cx| {
3829                if let Some(subscriber) = subscriber.upgrade(cx) {
3830                    subscriber.update(cx, |subscriber, cx| {
3831                        callback(subscriber, emitter, event, cx);
3832                    });
3833                    true
3834                } else {
3835                    false
3836                }
3837            })
3838    }
3839
3840    pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3841    where
3842        E: Entity,
3843        H: Handle<E>,
3844        F: 'static + FnMut(&mut T, H, &mut ViewContext<T>),
3845    {
3846        let observer = self.weak_handle();
3847        self.app.observe_internal(handle, move |observed, cx| {
3848            if let Some(observer) = observer.upgrade(cx) {
3849                observer.update(cx, |observer, cx| {
3850                    callback(observer, observed, cx);
3851                });
3852                true
3853            } else {
3854                false
3855            }
3856        })
3857    }
3858
3859    pub fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
3860    where
3861        F: 'static + FnMut(&mut T, ViewHandle<V>, bool, &mut ViewContext<T>),
3862        V: View,
3863    {
3864        let observer = self.weak_handle();
3865        self.app
3866            .observe_focus(handle, move |observed, focused, cx| {
3867                if let Some(observer) = observer.upgrade(cx) {
3868                    observer.update(cx, |observer, cx| {
3869                        callback(observer, observed, focused, cx);
3870                    });
3871                    true
3872                } else {
3873                    false
3874                }
3875            })
3876    }
3877
3878    pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3879    where
3880        E: Entity,
3881        H: Handle<E>,
3882        F: 'static + FnMut(&mut T, &E, &mut ViewContext<T>),
3883    {
3884        let observer = self.weak_handle();
3885        self.app.observe_release(handle, move |released, cx| {
3886            if let Some(observer) = observer.upgrade(cx) {
3887                observer.update(cx, |observer, cx| {
3888                    callback(observer, released, cx);
3889                });
3890            }
3891        })
3892    }
3893
3894    pub fn observe_actions<F>(&mut self, mut callback: F) -> Subscription
3895    where
3896        F: 'static + FnMut(&mut T, TypeId, &mut ViewContext<T>),
3897    {
3898        let observer = self.weak_handle();
3899        self.app.observe_actions(move |action_id, cx| {
3900            if let Some(observer) = observer.upgrade(cx) {
3901                observer.update(cx, |observer, cx| {
3902                    callback(observer, action_id, cx);
3903                });
3904            }
3905        })
3906    }
3907
3908    pub fn observe_window_activation<F>(&mut self, mut callback: F) -> Subscription
3909    where
3910        F: 'static + FnMut(&mut T, bool, &mut ViewContext<T>),
3911    {
3912        let observer = self.weak_handle();
3913        self.app
3914            .observe_window_activation(self.window_id(), move |active, cx| {
3915                if let Some(observer) = observer.upgrade(cx) {
3916                    observer.update(cx, |observer, cx| {
3917                        callback(observer, active, cx);
3918                    });
3919                    true
3920                } else {
3921                    false
3922                }
3923            })
3924    }
3925
3926    pub fn observe_fullscreen<F>(&mut self, mut callback: F) -> Subscription
3927    where
3928        F: 'static + FnMut(&mut T, bool, &mut ViewContext<T>),
3929    {
3930        let observer = self.weak_handle();
3931        self.app
3932            .observe_fullscreen(self.window_id(), move |active, cx| {
3933                if let Some(observer) = observer.upgrade(cx) {
3934                    observer.update(cx, |observer, cx| {
3935                        callback(observer, active, cx);
3936                    });
3937                    true
3938                } else {
3939                    false
3940                }
3941            })
3942    }
3943
3944    pub fn emit(&mut self, payload: T::Event) {
3945        self.app.pending_effects.push_back(Effect::Event {
3946            entity_id: self.view_id,
3947            payload: Box::new(payload),
3948        });
3949    }
3950
3951    pub fn notify(&mut self) {
3952        self.app.notify_view(self.window_id, self.view_id);
3953    }
3954
3955    pub fn dispatch_any_action(&mut self, action: Box<dyn Action>) {
3956        self.app
3957            .dispatch_any_action_at(self.window_id, self.view_id, action)
3958    }
3959
3960    pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>)) {
3961        let handle = self.handle();
3962        self.app.defer(move |cx| {
3963            handle.update(cx, |view, cx| {
3964                callback(view, cx);
3965            })
3966        })
3967    }
3968
3969    pub fn after_window_update(
3970        &mut self,
3971        callback: impl 'static + FnOnce(&mut T, &mut ViewContext<T>),
3972    ) {
3973        let handle = self.handle();
3974        self.app.after_window_update(move |cx| {
3975            handle.update(cx, |view, cx| {
3976                callback(view, cx);
3977            })
3978        })
3979    }
3980
3981    pub fn propagate_action(&mut self) {
3982        self.app.halt_action_dispatch = false;
3983    }
3984
3985    pub fn spawn<F, Fut, S>(&self, f: F) -> Task<S>
3986    where
3987        F: FnOnce(ViewHandle<T>, AsyncAppContext) -> Fut,
3988        Fut: 'static + Future<Output = S>,
3989        S: 'static,
3990    {
3991        let handle = self.handle();
3992        self.app.spawn(|cx| f(handle, cx))
3993    }
3994
3995    pub fn spawn_weak<F, Fut, S>(&self, f: F) -> Task<S>
3996    where
3997        F: FnOnce(WeakViewHandle<T>, AsyncAppContext) -> Fut,
3998        Fut: 'static + Future<Output = S>,
3999        S: 'static,
4000    {
4001        let handle = self.weak_handle();
4002        self.app.spawn(|cx| f(handle, cx))
4003    }
4004}
4005
4006pub struct RenderParams {
4007    pub window_id: usize,
4008    pub view_id: usize,
4009    pub titlebar_height: f32,
4010    pub hovered_region_ids: HashSet<MouseRegionId>,
4011    pub clicked_region_id: Option<MouseRegionId>,
4012    pub right_clicked_region_id: Option<MouseRegionId>,
4013    pub refreshing: bool,
4014}
4015
4016pub struct RenderContext<'a, T: View> {
4017    pub(crate) window_id: usize,
4018    pub(crate) view_id: usize,
4019    pub(crate) view_type: PhantomData<T>,
4020    pub(crate) hovered_region_ids: HashSet<MouseRegionId>,
4021    pub(crate) clicked_region_id: Option<MouseRegionId>,
4022    pub(crate) right_clicked_region_id: Option<MouseRegionId>,
4023    pub app: &'a mut MutableAppContext,
4024    pub titlebar_height: f32,
4025    pub refreshing: bool,
4026}
4027
4028#[derive(Clone, Copy, Default)]
4029pub struct MouseState {
4030    pub hovered: bool,
4031    pub clicked: bool,
4032    pub right_clicked: bool,
4033}
4034
4035impl<'a, V: View> RenderContext<'a, V> {
4036    fn new(params: RenderParams, app: &'a mut MutableAppContext) -> Self {
4037        Self {
4038            app,
4039            window_id: params.window_id,
4040            view_id: params.view_id,
4041            view_type: PhantomData,
4042            titlebar_height: params.titlebar_height,
4043            hovered_region_ids: params.hovered_region_ids.clone(),
4044            clicked_region_id: params.clicked_region_id,
4045            right_clicked_region_id: params.right_clicked_region_id,
4046            refreshing: params.refreshing,
4047        }
4048    }
4049
4050    pub fn handle(&self) -> WeakViewHandle<V> {
4051        WeakViewHandle::new(self.window_id, self.view_id)
4052    }
4053
4054    pub fn window_id(&self) -> usize {
4055        self.window_id
4056    }
4057
4058    pub fn view_id(&self) -> usize {
4059        self.view_id
4060    }
4061
4062    pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
4063        let region_id = MouseRegionId {
4064            view_id: self.view_id,
4065            discriminant: (TypeId::of::<Tag>(), region_id),
4066        };
4067        MouseState {
4068            hovered: self.hovered_region_ids.contains(&region_id),
4069            clicked: self.clicked_region_id == Some(region_id),
4070            right_clicked: self.right_clicked_region_id == Some(region_id),
4071        }
4072    }
4073
4074    pub fn element_state<Tag: 'static, T: 'static + Default>(
4075        &mut self,
4076        element_id: usize,
4077    ) -> ElementStateHandle<T> {
4078        let id = ElementStateId {
4079            view_id: self.view_id(),
4080            element_id,
4081            tag: TypeId::of::<Tag>(),
4082        };
4083        self.cx
4084            .element_states
4085            .entry(id)
4086            .or_insert_with(|| Box::new(T::default()));
4087        ElementStateHandle::new(id, self.frame_count, &self.cx.ref_counts)
4088    }
4089}
4090
4091impl AsRef<AppContext> for &AppContext {
4092    fn as_ref(&self) -> &AppContext {
4093        self
4094    }
4095}
4096
4097impl<V: View> Deref for RenderContext<'_, V> {
4098    type Target = MutableAppContext;
4099
4100    fn deref(&self) -> &Self::Target {
4101        self.app
4102    }
4103}
4104
4105impl<V: View> DerefMut for RenderContext<'_, V> {
4106    fn deref_mut(&mut self) -> &mut Self::Target {
4107        self.app
4108    }
4109}
4110
4111impl<V: View> ReadModel for RenderContext<'_, V> {
4112    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
4113        self.app.read_model(handle)
4114    }
4115}
4116
4117impl<V: View> UpdateModel for RenderContext<'_, V> {
4118    fn update_model<T: Entity, O>(
4119        &mut self,
4120        handle: &ModelHandle<T>,
4121        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
4122    ) -> O {
4123        self.app.update_model(handle, update)
4124    }
4125}
4126
4127impl<V: View> ReadView for RenderContext<'_, V> {
4128    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
4129        self.app.read_view(handle)
4130    }
4131}
4132
4133impl<M> AsRef<AppContext> for ViewContext<'_, M> {
4134    fn as_ref(&self) -> &AppContext {
4135        &self.app.cx
4136    }
4137}
4138
4139impl<M> Deref for ViewContext<'_, M> {
4140    type Target = MutableAppContext;
4141
4142    fn deref(&self) -> &Self::Target {
4143        &self.app
4144    }
4145}
4146
4147impl<M> DerefMut for ViewContext<'_, M> {
4148    fn deref_mut(&mut self) -> &mut Self::Target {
4149        &mut self.app
4150    }
4151}
4152
4153impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
4154    fn as_mut(&mut self) -> &mut MutableAppContext {
4155        self.app
4156    }
4157}
4158
4159impl<V> ReadModel for ViewContext<'_, V> {
4160    fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
4161        self.app.read_model(handle)
4162    }
4163}
4164
4165impl<V> UpgradeModelHandle for ViewContext<'_, V> {
4166    fn upgrade_model_handle<T: Entity>(
4167        &self,
4168        handle: &WeakModelHandle<T>,
4169    ) -> Option<ModelHandle<T>> {
4170        self.cx.upgrade_model_handle(handle)
4171    }
4172
4173    fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
4174        self.cx.model_handle_is_upgradable(handle)
4175    }
4176
4177    fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
4178        self.cx.upgrade_any_model_handle(handle)
4179    }
4180}
4181
4182impl<V> UpgradeViewHandle for ViewContext<'_, V> {
4183    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
4184        self.cx.upgrade_view_handle(handle)
4185    }
4186
4187    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
4188        self.cx.upgrade_any_view_handle(handle)
4189    }
4190}
4191
4192impl<V: View> UpgradeViewHandle for RenderContext<'_, V> {
4193    fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
4194        self.cx.upgrade_view_handle(handle)
4195    }
4196
4197    fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
4198        self.cx.upgrade_any_view_handle(handle)
4199    }
4200}
4201
4202impl<V: View> UpdateModel for ViewContext<'_, V> {
4203    fn update_model<T: Entity, O>(
4204        &mut self,
4205        handle: &ModelHandle<T>,
4206        update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> O,
4207    ) -> O {
4208        self.app.update_model(handle, update)
4209    }
4210}
4211
4212impl<V: View> ReadView for ViewContext<'_, V> {
4213    fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
4214        self.app.read_view(handle)
4215    }
4216}
4217
4218impl<V: View> UpdateView for ViewContext<'_, V> {
4219    fn update_view<T, S>(
4220        &mut self,
4221        handle: &ViewHandle<T>,
4222        update: &mut dyn FnMut(&mut T, &mut ViewContext<T>) -> S,
4223    ) -> S
4224    where
4225        T: View,
4226    {
4227        self.app.update_view(handle, update)
4228    }
4229}
4230
4231pub trait Handle<T> {
4232    type Weak: 'static;
4233    fn id(&self) -> usize;
4234    fn location(&self) -> EntityLocation;
4235    fn downgrade(&self) -> Self::Weak;
4236    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4237    where
4238        Self: Sized;
4239}
4240
4241pub trait WeakHandle {
4242    fn id(&self) -> usize;
4243}
4244
4245#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
4246pub enum EntityLocation {
4247    Model(usize),
4248    View(usize, usize),
4249}
4250
4251pub struct ModelHandle<T: Entity> {
4252    model_id: usize,
4253    model_type: PhantomData<T>,
4254    ref_counts: Arc<Mutex<RefCounts>>,
4255
4256    #[cfg(any(test, feature = "test-support"))]
4257    handle_id: usize,
4258}
4259
4260impl<T: Entity> ModelHandle<T> {
4261    fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4262        ref_counts.lock().inc_model(model_id);
4263
4264        #[cfg(any(test, feature = "test-support"))]
4265        let handle_id = ref_counts
4266            .lock()
4267            .leak_detector
4268            .lock()
4269            .handle_created(Some(type_name::<T>()), model_id);
4270
4271        Self {
4272            model_id,
4273            model_type: PhantomData,
4274            ref_counts: ref_counts.clone(),
4275
4276            #[cfg(any(test, feature = "test-support"))]
4277            handle_id,
4278        }
4279    }
4280
4281    pub fn downgrade(&self) -> WeakModelHandle<T> {
4282        WeakModelHandle::new(self.model_id)
4283    }
4284
4285    pub fn id(&self) -> usize {
4286        self.model_id
4287    }
4288
4289    pub fn read<'a, C: ReadModel>(&self, cx: &'a C) -> &'a T {
4290        cx.read_model(self)
4291    }
4292
4293    pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S
4294    where
4295        C: ReadModelWith,
4296        F: FnOnce(&T, &AppContext) -> S,
4297    {
4298        let mut read = Some(read);
4299        cx.read_model_with(self, &mut |model, cx| {
4300            let read = read.take().unwrap();
4301            read(model, cx)
4302        })
4303    }
4304
4305    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
4306    where
4307        C: UpdateModel,
4308        F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
4309    {
4310        let mut update = Some(update);
4311        cx.update_model(self, &mut |model, cx| {
4312            let update = update.take().unwrap();
4313            update(model, cx)
4314        })
4315    }
4316
4317    #[cfg(any(test, feature = "test-support"))]
4318    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
4319        let (tx, mut rx) = futures::channel::mpsc::unbounded();
4320        let mut cx = cx.cx.borrow_mut();
4321        let subscription = cx.observe(self, move |_, _| {
4322            tx.unbounded_send(()).ok();
4323        });
4324
4325        let duration = if std::env::var("CI").is_ok() {
4326            Duration::from_secs(5)
4327        } else {
4328            Duration::from_secs(1)
4329        };
4330
4331        async move {
4332            let notification = crate::util::timeout(duration, rx.next())
4333                .await
4334                .expect("next notification timed out");
4335            drop(subscription);
4336            notification.expect("model dropped while test was waiting for its next notification")
4337        }
4338    }
4339
4340    #[cfg(any(test, feature = "test-support"))]
4341    pub fn next_event(&self, cx: &TestAppContext) -> impl Future<Output = T::Event>
4342    where
4343        T::Event: Clone,
4344    {
4345        let (tx, mut rx) = futures::channel::mpsc::unbounded();
4346        let mut cx = cx.cx.borrow_mut();
4347        let subscription = cx.subscribe(self, move |_, event, _| {
4348            tx.unbounded_send(event.clone()).ok();
4349        });
4350
4351        let duration = if std::env::var("CI").is_ok() {
4352            Duration::from_secs(5)
4353        } else {
4354            Duration::from_secs(1)
4355        };
4356
4357        cx.foreground.start_waiting();
4358        async move {
4359            let event = crate::util::timeout(duration, rx.next())
4360                .await
4361                .expect("next event timed out");
4362            drop(subscription);
4363            event.expect("model dropped while test was waiting for its next event")
4364        }
4365    }
4366
4367    #[cfg(any(test, feature = "test-support"))]
4368    pub fn condition(
4369        &self,
4370        cx: &TestAppContext,
4371        mut predicate: impl FnMut(&T, &AppContext) -> bool,
4372    ) -> impl Future<Output = ()> {
4373        let (tx, mut rx) = futures::channel::mpsc::unbounded();
4374
4375        let mut cx = cx.cx.borrow_mut();
4376        let subscriptions = (
4377            cx.observe(self, {
4378                let tx = tx.clone();
4379                move |_, _| {
4380                    tx.unbounded_send(()).ok();
4381                }
4382            }),
4383            cx.subscribe(self, {
4384                let tx = tx.clone();
4385                move |_, _, _| {
4386                    tx.unbounded_send(()).ok();
4387                }
4388            }),
4389        );
4390
4391        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
4392        let handle = self.downgrade();
4393        let duration = if std::env::var("CI").is_ok() {
4394            Duration::from_secs(5)
4395        } else {
4396            Duration::from_secs(1)
4397        };
4398
4399        async move {
4400            crate::util::timeout(duration, async move {
4401                loop {
4402                    {
4403                        let cx = cx.borrow();
4404                        let cx = cx.as_ref();
4405                        if predicate(
4406                            handle
4407                                .upgrade(cx)
4408                                .expect("model dropped with pending condition")
4409                                .read(cx),
4410                            cx,
4411                        ) {
4412                            break;
4413                        }
4414                    }
4415
4416                    cx.borrow().foreground().start_waiting();
4417                    rx.next()
4418                        .await
4419                        .expect("model dropped with pending condition");
4420                    cx.borrow().foreground().finish_waiting();
4421                }
4422            })
4423            .await
4424            .expect("condition timed out");
4425            drop(subscriptions);
4426        }
4427    }
4428}
4429
4430impl<T: Entity> Clone for ModelHandle<T> {
4431    fn clone(&self) -> Self {
4432        Self::new(self.model_id, &self.ref_counts)
4433    }
4434}
4435
4436impl<T: Entity> PartialEq for ModelHandle<T> {
4437    fn eq(&self, other: &Self) -> bool {
4438        self.model_id == other.model_id
4439    }
4440}
4441
4442impl<T: Entity> Eq for ModelHandle<T> {}
4443
4444impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
4445    fn eq(&self, other: &WeakModelHandle<T>) -> bool {
4446        self.model_id == other.model_id
4447    }
4448}
4449
4450impl<T: Entity> Hash for ModelHandle<T> {
4451    fn hash<H: Hasher>(&self, state: &mut H) {
4452        self.model_id.hash(state);
4453    }
4454}
4455
4456impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
4457    fn borrow(&self) -> &usize {
4458        &self.model_id
4459    }
4460}
4461
4462impl<T: Entity> Debug for ModelHandle<T> {
4463    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4464        f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
4465            .field(&self.model_id)
4466            .finish()
4467    }
4468}
4469
4470unsafe impl<T: Entity> Send for ModelHandle<T> {}
4471unsafe impl<T: Entity> Sync for ModelHandle<T> {}
4472
4473impl<T: Entity> Drop for ModelHandle<T> {
4474    fn drop(&mut self) {
4475        let mut ref_counts = self.ref_counts.lock();
4476        ref_counts.dec_model(self.model_id);
4477
4478        #[cfg(any(test, feature = "test-support"))]
4479        ref_counts
4480            .leak_detector
4481            .lock()
4482            .handle_dropped(self.model_id, self.handle_id);
4483    }
4484}
4485
4486impl<T: Entity> Handle<T> for ModelHandle<T> {
4487    type Weak = WeakModelHandle<T>;
4488
4489    fn id(&self) -> usize {
4490        self.model_id
4491    }
4492
4493    fn location(&self) -> EntityLocation {
4494        EntityLocation::Model(self.model_id)
4495    }
4496
4497    fn downgrade(&self) -> Self::Weak {
4498        self.downgrade()
4499    }
4500
4501    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4502    where
4503        Self: Sized,
4504    {
4505        weak.upgrade(cx)
4506    }
4507}
4508
4509pub struct WeakModelHandle<T> {
4510    model_id: usize,
4511    model_type: PhantomData<T>,
4512}
4513
4514impl<T> WeakHandle for WeakModelHandle<T> {
4515    fn id(&self) -> usize {
4516        self.model_id
4517    }
4518}
4519
4520unsafe impl<T> Send for WeakModelHandle<T> {}
4521unsafe impl<T> Sync for WeakModelHandle<T> {}
4522
4523impl<T: Entity> WeakModelHandle<T> {
4524    fn new(model_id: usize) -> Self {
4525        Self {
4526            model_id,
4527            model_type: PhantomData,
4528        }
4529    }
4530
4531    pub fn id(&self) -> usize {
4532        self.model_id
4533    }
4534
4535    pub fn is_upgradable(&self, cx: &impl UpgradeModelHandle) -> bool {
4536        cx.model_handle_is_upgradable(self)
4537    }
4538
4539    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<ModelHandle<T>> {
4540        cx.upgrade_model_handle(self)
4541    }
4542}
4543
4544impl<T> Hash for WeakModelHandle<T> {
4545    fn hash<H: Hasher>(&self, state: &mut H) {
4546        self.model_id.hash(state)
4547    }
4548}
4549
4550impl<T> PartialEq for WeakModelHandle<T> {
4551    fn eq(&self, other: &Self) -> bool {
4552        self.model_id == other.model_id
4553    }
4554}
4555
4556impl<T> Eq for WeakModelHandle<T> {}
4557
4558impl<T> Clone for WeakModelHandle<T> {
4559    fn clone(&self) -> Self {
4560        Self {
4561            model_id: self.model_id,
4562            model_type: PhantomData,
4563        }
4564    }
4565}
4566
4567impl<T> Copy for WeakModelHandle<T> {}
4568
4569pub struct ViewHandle<T> {
4570    window_id: usize,
4571    view_id: usize,
4572    view_type: PhantomData<T>,
4573    ref_counts: Arc<Mutex<RefCounts>>,
4574    #[cfg(any(test, feature = "test-support"))]
4575    handle_id: usize,
4576}
4577
4578impl<T: View> ViewHandle<T> {
4579    fn new(window_id: usize, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4580        ref_counts.lock().inc_view(window_id, view_id);
4581        #[cfg(any(test, feature = "test-support"))]
4582        let handle_id = ref_counts
4583            .lock()
4584            .leak_detector
4585            .lock()
4586            .handle_created(Some(type_name::<T>()), view_id);
4587
4588        Self {
4589            window_id,
4590            view_id,
4591            view_type: PhantomData,
4592            ref_counts: ref_counts.clone(),
4593
4594            #[cfg(any(test, feature = "test-support"))]
4595            handle_id,
4596        }
4597    }
4598
4599    pub fn downgrade(&self) -> WeakViewHandle<T> {
4600        WeakViewHandle::new(self.window_id, self.view_id)
4601    }
4602
4603    pub fn window_id(&self) -> usize {
4604        self.window_id
4605    }
4606
4607    pub fn id(&self) -> usize {
4608        self.view_id
4609    }
4610
4611    pub fn read<'a, C: ReadView>(&self, cx: &'a C) -> &'a T {
4612        cx.read_view(self)
4613    }
4614
4615    pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
4616    where
4617        C: ReadViewWith,
4618        F: FnOnce(&T, &AppContext) -> S,
4619    {
4620        let mut read = Some(read);
4621        cx.read_view_with(self, &mut |view, cx| {
4622            let read = read.take().unwrap();
4623            read(view, cx)
4624        })
4625    }
4626
4627    pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
4628    where
4629        C: UpdateView,
4630        F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
4631    {
4632        let mut update = Some(update);
4633        cx.update_view(self, &mut |view, cx| {
4634            let update = update.take().unwrap();
4635            update(view, cx)
4636        })
4637    }
4638
4639    pub fn defer<C, F>(&self, cx: &mut C, update: F)
4640    where
4641        C: AsMut<MutableAppContext>,
4642        F: 'static + FnOnce(&mut T, &mut ViewContext<T>),
4643    {
4644        let this = self.clone();
4645        cx.as_mut().defer(move |cx| {
4646            this.update(cx, |view, cx| update(view, cx));
4647        });
4648    }
4649
4650    pub fn is_focused(&self, cx: &AppContext) -> bool {
4651        cx.focused_view_id(self.window_id)
4652            .map_or(false, |focused_id| focused_id == self.view_id)
4653    }
4654
4655    #[cfg(any(test, feature = "test-support"))]
4656    pub fn next_notification(&self, cx: &TestAppContext) -> impl Future<Output = ()> {
4657        use postage::prelude::{Sink as _, Stream as _};
4658
4659        let (mut tx, mut rx) = postage::mpsc::channel(1);
4660        let mut cx = cx.cx.borrow_mut();
4661        let subscription = cx.observe(self, move |_, _| {
4662            tx.try_send(()).ok();
4663        });
4664
4665        let duration = if std::env::var("CI").is_ok() {
4666            Duration::from_secs(5)
4667        } else {
4668            Duration::from_secs(1)
4669        };
4670
4671        async move {
4672            let notification = crate::util::timeout(duration, rx.recv())
4673                .await
4674                .expect("next notification timed out");
4675            drop(subscription);
4676            notification.expect("model dropped while test was waiting for its next notification")
4677        }
4678    }
4679
4680    #[cfg(any(test, feature = "test-support"))]
4681    pub fn condition(
4682        &self,
4683        cx: &TestAppContext,
4684        mut predicate: impl FnMut(&T, &AppContext) -> bool,
4685    ) -> impl Future<Output = ()> {
4686        use postage::prelude::{Sink as _, Stream as _};
4687
4688        let (tx, mut rx) = postage::mpsc::channel(1024);
4689        let timeout_duration = cx.condition_duration();
4690
4691        let mut cx = cx.cx.borrow_mut();
4692        let subscriptions = self.update(&mut *cx, |_, cx| {
4693            (
4694                cx.observe(self, {
4695                    let mut tx = tx.clone();
4696                    move |_, _, _| {
4697                        tx.blocking_send(()).ok();
4698                    }
4699                }),
4700                cx.subscribe(self, {
4701                    let mut tx = tx.clone();
4702                    move |_, _, _, _| {
4703                        tx.blocking_send(()).ok();
4704                    }
4705                }),
4706            )
4707        });
4708
4709        let cx = cx.weak_self.as_ref().unwrap().upgrade().unwrap();
4710        let handle = self.downgrade();
4711
4712        async move {
4713            crate::util::timeout(timeout_duration, async move {
4714                loop {
4715                    {
4716                        let cx = cx.borrow();
4717                        let cx = cx.as_ref();
4718                        if predicate(
4719                            handle
4720                                .upgrade(cx)
4721                                .expect("view dropped with pending condition")
4722                                .read(cx),
4723                            cx,
4724                        ) {
4725                            break;
4726                        }
4727                    }
4728
4729                    cx.borrow().foreground().start_waiting();
4730                    rx.recv()
4731                        .await
4732                        .expect("view dropped with pending condition");
4733                    cx.borrow().foreground().finish_waiting();
4734                }
4735            })
4736            .await
4737            .expect("condition timed out");
4738            drop(subscriptions);
4739        }
4740    }
4741}
4742
4743impl<T: View> Clone for ViewHandle<T> {
4744    fn clone(&self) -> Self {
4745        ViewHandle::new(self.window_id, self.view_id, &self.ref_counts)
4746    }
4747}
4748
4749impl<T> PartialEq for ViewHandle<T> {
4750    fn eq(&self, other: &Self) -> bool {
4751        self.window_id == other.window_id && self.view_id == other.view_id
4752    }
4753}
4754
4755impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
4756    fn eq(&self, other: &WeakViewHandle<T>) -> bool {
4757        self.window_id == other.window_id && self.view_id == other.view_id
4758    }
4759}
4760
4761impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
4762    fn eq(&self, other: &ViewHandle<T>) -> bool {
4763        self.window_id == other.window_id && self.view_id == other.view_id
4764    }
4765}
4766
4767impl<T> Eq for ViewHandle<T> {}
4768
4769impl<T> Hash for ViewHandle<T> {
4770    fn hash<H: Hasher>(&self, state: &mut H) {
4771        self.window_id.hash(state);
4772        self.view_id.hash(state);
4773    }
4774}
4775
4776impl<T> Debug for ViewHandle<T> {
4777    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4778        f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
4779            .field("window_id", &self.window_id)
4780            .field("view_id", &self.view_id)
4781            .finish()
4782    }
4783}
4784
4785impl<T> Drop for ViewHandle<T> {
4786    fn drop(&mut self) {
4787        self.ref_counts
4788            .lock()
4789            .dec_view(self.window_id, self.view_id);
4790        #[cfg(any(test, feature = "test-support"))]
4791        self.ref_counts
4792            .lock()
4793            .leak_detector
4794            .lock()
4795            .handle_dropped(self.view_id, self.handle_id);
4796    }
4797}
4798
4799impl<T: View> Handle<T> for ViewHandle<T> {
4800    type Weak = WeakViewHandle<T>;
4801
4802    fn id(&self) -> usize {
4803        self.view_id
4804    }
4805
4806    fn location(&self) -> EntityLocation {
4807        EntityLocation::View(self.window_id, self.view_id)
4808    }
4809
4810    fn downgrade(&self) -> Self::Weak {
4811        self.downgrade()
4812    }
4813
4814    fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4815    where
4816        Self: Sized,
4817    {
4818        weak.upgrade(cx)
4819    }
4820}
4821
4822pub struct AnyViewHandle {
4823    window_id: usize,
4824    view_id: usize,
4825    view_type: TypeId,
4826    ref_counts: Arc<Mutex<RefCounts>>,
4827
4828    #[cfg(any(test, feature = "test-support"))]
4829    handle_id: usize,
4830}
4831
4832impl AnyViewHandle {
4833    fn new(
4834        window_id: usize,
4835        view_id: usize,
4836        view_type: TypeId,
4837        ref_counts: Arc<Mutex<RefCounts>>,
4838    ) -> Self {
4839        ref_counts.lock().inc_view(window_id, view_id);
4840
4841        #[cfg(any(test, feature = "test-support"))]
4842        let handle_id = ref_counts
4843            .lock()
4844            .leak_detector
4845            .lock()
4846            .handle_created(None, view_id);
4847
4848        Self {
4849            window_id,
4850            view_id,
4851            view_type,
4852            ref_counts,
4853            #[cfg(any(test, feature = "test-support"))]
4854            handle_id,
4855        }
4856    }
4857
4858    pub fn id(&self) -> usize {
4859        self.view_id
4860    }
4861
4862    pub fn is<T: 'static>(&self) -> bool {
4863        TypeId::of::<T>() == self.view_type
4864    }
4865
4866    pub fn is_focused(&self, cx: &AppContext) -> bool {
4867        cx.focused_view_id(self.window_id)
4868            .map_or(false, |focused_id| focused_id == self.view_id)
4869    }
4870
4871    pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4872        if self.is::<T>() {
4873            let result = Some(ViewHandle {
4874                window_id: self.window_id,
4875                view_id: self.view_id,
4876                ref_counts: self.ref_counts.clone(),
4877                view_type: PhantomData,
4878                #[cfg(any(test, feature = "test-support"))]
4879                handle_id: self.handle_id,
4880            });
4881            unsafe {
4882                Arc::decrement_strong_count(Arc::as_ptr(&self.ref_counts));
4883            }
4884            std::mem::forget(self);
4885            result
4886        } else {
4887            None
4888        }
4889    }
4890
4891    pub fn downgrade(&self) -> AnyWeakViewHandle {
4892        AnyWeakViewHandle {
4893            window_id: self.window_id,
4894            view_id: self.view_id,
4895            view_type: self.view_type,
4896        }
4897    }
4898
4899    pub fn view_type(&self) -> TypeId {
4900        self.view_type
4901    }
4902
4903    pub fn debug_json(&self, cx: &AppContext) -> serde_json::Value {
4904        cx.views
4905            .get(&(self.window_id, self.view_id))
4906            .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4907    }
4908}
4909
4910impl Clone for AnyViewHandle {
4911    fn clone(&self) -> Self {
4912        Self::new(
4913            self.window_id,
4914            self.view_id,
4915            self.view_type,
4916            self.ref_counts.clone(),
4917        )
4918    }
4919}
4920
4921impl From<&AnyViewHandle> for AnyViewHandle {
4922    fn from(handle: &AnyViewHandle) -> Self {
4923        handle.clone()
4924    }
4925}
4926
4927impl<T: View> From<&ViewHandle<T>> for AnyViewHandle {
4928    fn from(handle: &ViewHandle<T>) -> Self {
4929        Self::new(
4930            handle.window_id,
4931            handle.view_id,
4932            TypeId::of::<T>(),
4933            handle.ref_counts.clone(),
4934        )
4935    }
4936}
4937
4938impl<T: View> From<ViewHandle<T>> for AnyViewHandle {
4939    fn from(handle: ViewHandle<T>) -> Self {
4940        let any_handle = AnyViewHandle {
4941            window_id: handle.window_id,
4942            view_id: handle.view_id,
4943            view_type: TypeId::of::<T>(),
4944            ref_counts: handle.ref_counts.clone(),
4945            #[cfg(any(test, feature = "test-support"))]
4946            handle_id: handle.handle_id,
4947        };
4948
4949        unsafe {
4950            Arc::decrement_strong_count(Arc::as_ptr(&handle.ref_counts));
4951        }
4952        std::mem::forget(handle);
4953        any_handle
4954    }
4955}
4956
4957impl Drop for AnyViewHandle {
4958    fn drop(&mut self) {
4959        self.ref_counts
4960            .lock()
4961            .dec_view(self.window_id, self.view_id);
4962        #[cfg(any(test, feature = "test-support"))]
4963        self.ref_counts
4964            .lock()
4965            .leak_detector
4966            .lock()
4967            .handle_dropped(self.view_id, self.handle_id);
4968    }
4969}
4970
4971pub struct AnyModelHandle {
4972    model_id: usize,
4973    model_type: TypeId,
4974    ref_counts: Arc<Mutex<RefCounts>>,
4975
4976    #[cfg(any(test, feature = "test-support"))]
4977    handle_id: usize,
4978}
4979
4980impl AnyModelHandle {
4981    fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4982        ref_counts.lock().inc_model(model_id);
4983
4984        #[cfg(any(test, feature = "test-support"))]
4985        let handle_id = ref_counts
4986            .lock()
4987            .leak_detector
4988            .lock()
4989            .handle_created(None, model_id);
4990
4991        Self {
4992            model_id,
4993            model_type,
4994            ref_counts,
4995
4996            #[cfg(any(test, feature = "test-support"))]
4997            handle_id,
4998        }
4999    }
5000
5001    pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
5002        if self.is::<T>() {
5003            let result = Some(ModelHandle {
5004                model_id: self.model_id,
5005                model_type: PhantomData,
5006                ref_counts: self.ref_counts.clone(),
5007
5008                #[cfg(any(test, feature = "test-support"))]
5009                handle_id: self.handle_id,
5010            });
5011            unsafe {
5012                Arc::decrement_strong_count(Arc::as_ptr(&self.ref_counts));
5013            }
5014            std::mem::forget(self);
5015            result
5016        } else {
5017            None
5018        }
5019    }
5020
5021    pub fn downgrade(&self) -> AnyWeakModelHandle {
5022        AnyWeakModelHandle {
5023            model_id: self.model_id,
5024            model_type: self.model_type,
5025        }
5026    }
5027
5028    pub fn is<T: Entity>(&self) -> bool {
5029        self.model_type == TypeId::of::<T>()
5030    }
5031
5032    pub fn model_type(&self) -> TypeId {
5033        self.model_type
5034    }
5035}
5036
5037impl<T: Entity> From<ModelHandle<T>> for AnyModelHandle {
5038    fn from(handle: ModelHandle<T>) -> Self {
5039        Self::new(
5040            handle.model_id,
5041            TypeId::of::<T>(),
5042            handle.ref_counts.clone(),
5043        )
5044    }
5045}
5046
5047impl Clone for AnyModelHandle {
5048    fn clone(&self) -> Self {
5049        Self::new(self.model_id, self.model_type, self.ref_counts.clone())
5050    }
5051}
5052
5053impl Drop for AnyModelHandle {
5054    fn drop(&mut self) {
5055        let mut ref_counts = self.ref_counts.lock();
5056        ref_counts.dec_model(self.model_id);
5057
5058        #[cfg(any(test, feature = "test-support"))]
5059        ref_counts
5060            .leak_detector
5061            .lock()
5062            .handle_dropped(self.model_id, self.handle_id);
5063    }
5064}
5065
5066pub struct AnyWeakModelHandle {
5067    model_id: usize,
5068    model_type: TypeId,
5069}
5070
5071impl AnyWeakModelHandle {
5072    pub fn upgrade(&self, cx: &impl UpgradeModelHandle) -> Option<AnyModelHandle> {
5073        cx.upgrade_any_model_handle(self)
5074    }
5075}
5076
5077impl<T: Entity> From<WeakModelHandle<T>> for AnyWeakModelHandle {
5078    fn from(handle: WeakModelHandle<T>) -> Self {
5079        AnyWeakModelHandle {
5080            model_id: handle.model_id,
5081            model_type: TypeId::of::<T>(),
5082        }
5083    }
5084}
5085
5086pub struct WeakViewHandle<T> {
5087    window_id: usize,
5088    view_id: usize,
5089    view_type: PhantomData<T>,
5090}
5091
5092impl<T> WeakHandle for WeakViewHandle<T> {
5093    fn id(&self) -> usize {
5094        self.view_id
5095    }
5096}
5097
5098impl<T: View> WeakViewHandle<T> {
5099    fn new(window_id: usize, view_id: usize) -> Self {
5100        Self {
5101            window_id,
5102            view_id,
5103            view_type: PhantomData,
5104        }
5105    }
5106
5107    pub fn id(&self) -> usize {
5108        self.view_id
5109    }
5110
5111    pub fn window_id(&self) -> usize {
5112        self.window_id
5113    }
5114
5115    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<ViewHandle<T>> {
5116        cx.upgrade_view_handle(self)
5117    }
5118}
5119
5120impl<T> Clone for WeakViewHandle<T> {
5121    fn clone(&self) -> Self {
5122        Self {
5123            window_id: self.window_id,
5124            view_id: self.view_id,
5125            view_type: PhantomData,
5126        }
5127    }
5128}
5129
5130impl<T> PartialEq for WeakViewHandle<T> {
5131    fn eq(&self, other: &Self) -> bool {
5132        self.window_id == other.window_id && self.view_id == other.view_id
5133    }
5134}
5135
5136impl<T> Eq for WeakViewHandle<T> {}
5137
5138impl<T> Hash for WeakViewHandle<T> {
5139    fn hash<H: Hasher>(&self, state: &mut H) {
5140        self.window_id.hash(state);
5141        self.view_id.hash(state);
5142    }
5143}
5144
5145pub struct AnyWeakViewHandle {
5146    window_id: usize,
5147    view_id: usize,
5148    view_type: TypeId,
5149}
5150
5151impl AnyWeakViewHandle {
5152    pub fn upgrade(&self, cx: &impl UpgradeViewHandle) -> Option<AnyViewHandle> {
5153        cx.upgrade_any_view_handle(self)
5154    }
5155}
5156
5157impl<T: View> From<WeakViewHandle<T>> for AnyWeakViewHandle {
5158    fn from(handle: WeakViewHandle<T>) -> Self {
5159        AnyWeakViewHandle {
5160            window_id: handle.window_id,
5161            view_id: handle.view_id,
5162            view_type: TypeId::of::<T>(),
5163        }
5164    }
5165}
5166
5167#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
5168pub struct ElementStateId {
5169    view_id: usize,
5170    element_id: usize,
5171    tag: TypeId,
5172}
5173
5174pub struct ElementStateHandle<T> {
5175    value_type: PhantomData<T>,
5176    id: ElementStateId,
5177    ref_counts: Weak<Mutex<RefCounts>>,
5178}
5179
5180impl<T: 'static> ElementStateHandle<T> {
5181    fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
5182        ref_counts.lock().inc_element_state(id, frame_id);
5183        Self {
5184            value_type: PhantomData,
5185            id,
5186            ref_counts: Arc::downgrade(ref_counts),
5187        }
5188    }
5189
5190    pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
5191        cx.element_states
5192            .get(&self.id)
5193            .unwrap()
5194            .downcast_ref()
5195            .unwrap()
5196    }
5197
5198    pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
5199    where
5200        C: DerefMut<Target = MutableAppContext>,
5201    {
5202        let mut element_state = cx.deref_mut().cx.element_states.remove(&self.id).unwrap();
5203        let result = f(element_state.downcast_mut().unwrap(), cx);
5204        cx.deref_mut()
5205            .cx
5206            .element_states
5207            .insert(self.id, element_state);
5208        result
5209    }
5210}
5211
5212impl<T> Drop for ElementStateHandle<T> {
5213    fn drop(&mut self) {
5214        if let Some(ref_counts) = self.ref_counts.upgrade() {
5215            ref_counts.lock().dec_element_state(self.id);
5216        }
5217    }
5218}
5219
5220#[must_use]
5221pub enum Subscription {
5222    Subscription {
5223        id: usize,
5224        entity_id: usize,
5225        subscriptions: Option<Weak<Mapping<usize, SubscriptionCallback>>>,
5226    },
5227    GlobalSubscription {
5228        id: usize,
5229        type_id: TypeId,
5230        subscriptions: Option<Weak<Mapping<TypeId, GlobalSubscriptionCallback>>>,
5231    },
5232    Observation {
5233        id: usize,
5234        entity_id: usize,
5235        observations: Option<Weak<Mapping<usize, ObservationCallback>>>,
5236    },
5237    GlobalObservation {
5238        id: usize,
5239        type_id: TypeId,
5240        observations: Option<Weak<Mapping<TypeId, GlobalObservationCallback>>>,
5241    },
5242    FocusObservation {
5243        id: usize,
5244        view_id: usize,
5245        observations: Option<Weak<Mapping<usize, FocusObservationCallback>>>,
5246    },
5247    WindowActivationObservation {
5248        id: usize,
5249        window_id: usize,
5250        observations: Option<Weak<Mapping<usize, WindowActivationCallback>>>,
5251    },
5252    WindowFullscreenObservation {
5253        id: usize,
5254        window_id: usize,
5255        observations: Option<Weak<Mapping<usize, WindowFullscreenCallback>>>,
5256    },
5257
5258    ReleaseObservation {
5259        id: usize,
5260        entity_id: usize,
5261        observations:
5262            Option<Weak<Mutex<HashMap<usize, BTreeMap<usize, ReleaseObservationCallback>>>>>,
5263    },
5264    ActionObservation {
5265        id: usize,
5266        observations: Option<Weak<Mutex<BTreeMap<usize, ActionObservationCallback>>>>,
5267    },
5268}
5269
5270impl Subscription {
5271    pub fn detach(&mut self) {
5272        match self {
5273            Subscription::Subscription { subscriptions, .. } => {
5274                subscriptions.take();
5275            }
5276            Subscription::GlobalSubscription { subscriptions, .. } => {
5277                subscriptions.take();
5278            }
5279            Subscription::Observation { observations, .. } => {
5280                observations.take();
5281            }
5282            Subscription::GlobalObservation { observations, .. } => {
5283                observations.take();
5284            }
5285            Subscription::ReleaseObservation { observations, .. } => {
5286                observations.take();
5287            }
5288            Subscription::FocusObservation { observations, .. } => {
5289                observations.take();
5290            }
5291            Subscription::ActionObservation { observations, .. } => {
5292                observations.take();
5293            }
5294            Subscription::WindowActivationObservation { observations, .. } => {
5295                observations.take();
5296            }
5297            Subscription::WindowFullscreenObservation { observations, .. } => {
5298                observations.take();
5299            }
5300        }
5301    }
5302}
5303
5304impl Drop for Subscription {
5305    fn drop(&mut self) {
5306        match self {
5307            Subscription::Subscription {
5308                id,
5309                entity_id,
5310                subscriptions,
5311            } => {
5312                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
5313                    match subscriptions
5314                        .lock()
5315                        .entry(*entity_id)
5316                        .or_default()
5317                        .entry(*id)
5318                    {
5319                        btree_map::Entry::Vacant(entry) => {
5320                            entry.insert(None);
5321                        }
5322                        btree_map::Entry::Occupied(entry) => {
5323                            entry.remove();
5324                        }
5325                    }
5326                }
5327            }
5328            Subscription::GlobalSubscription {
5329                id,
5330                type_id,
5331                subscriptions,
5332            } => {
5333                if let Some(subscriptions) = subscriptions.as_ref().and_then(Weak::upgrade) {
5334                    match subscriptions.lock().entry(*type_id).or_default().entry(*id) {
5335                        btree_map::Entry::Vacant(entry) => {
5336                            entry.insert(None);
5337                        }
5338                        btree_map::Entry::Occupied(entry) => {
5339                            entry.remove();
5340                        }
5341                    }
5342                }
5343            }
5344            Subscription::Observation {
5345                id,
5346                entity_id,
5347                observations,
5348            } => {
5349                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
5350                    match observations
5351                        .lock()
5352                        .entry(*entity_id)
5353                        .or_default()
5354                        .entry(*id)
5355                    {
5356                        btree_map::Entry::Vacant(entry) => {
5357                            entry.insert(None);
5358                        }
5359                        btree_map::Entry::Occupied(entry) => {
5360                            entry.remove();
5361                        }
5362                    }
5363                }
5364            }
5365            Subscription::GlobalObservation {
5366                id,
5367                type_id,
5368                observations,
5369            } => {
5370                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
5371                    match observations.lock().entry(*type_id).or_default().entry(*id) {
5372                        collections::btree_map::Entry::Vacant(entry) => {
5373                            entry.insert(None);
5374                        }
5375                        collections::btree_map::Entry::Occupied(entry) => {
5376                            entry.remove();
5377                        }
5378                    }
5379                }
5380            }
5381            Subscription::ReleaseObservation {
5382                id,
5383                entity_id,
5384                observations,
5385            } => {
5386                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
5387                    if let Some(observations) = observations.lock().get_mut(entity_id) {
5388                        observations.remove(id);
5389                    }
5390                }
5391            }
5392            Subscription::FocusObservation {
5393                id,
5394                view_id,
5395                observations,
5396            } => {
5397                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
5398                    match observations.lock().entry(*view_id).or_default().entry(*id) {
5399                        btree_map::Entry::Vacant(entry) => {
5400                            entry.insert(None);
5401                        }
5402                        btree_map::Entry::Occupied(entry) => {
5403                            entry.remove();
5404                        }
5405                    }
5406                }
5407            }
5408            Subscription::ActionObservation { id, observations } => {
5409                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
5410                    observations.lock().remove(&id);
5411                }
5412            }
5413            Subscription::WindowActivationObservation {
5414                id,
5415                window_id,
5416                observations,
5417            } => {
5418                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
5419                    match observations
5420                        .lock()
5421                        .entry(*window_id)
5422                        .or_default()
5423                        .entry(*id)
5424                    {
5425                        btree_map::Entry::Vacant(entry) => {
5426                            entry.insert(None);
5427                        }
5428                        btree_map::Entry::Occupied(entry) => {
5429                            entry.remove();
5430                        }
5431                    }
5432                }
5433            }
5434            Subscription::WindowFullscreenObservation {
5435                id,
5436                window_id,
5437                observations,
5438            } => {
5439                if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) {
5440                    match observations
5441                        .lock()
5442                        .entry(*window_id)
5443                        .or_default()
5444                        .entry(*id)
5445                    {
5446                        btree_map::Entry::Vacant(entry) => {
5447                            entry.insert(None);
5448                        }
5449                        btree_map::Entry::Occupied(entry) => {
5450                            entry.remove();
5451                        }
5452                    }
5453                }
5454            }
5455        }
5456    }
5457}
5458
5459lazy_static! {
5460    static ref LEAK_BACKTRACE: bool =
5461        std::env::var("LEAK_BACKTRACE").map_or(false, |b| !b.is_empty());
5462}
5463
5464#[cfg(any(test, feature = "test-support"))]
5465#[derive(Default)]
5466pub struct LeakDetector {
5467    next_handle_id: usize,
5468    handle_backtraces: HashMap<
5469        usize,
5470        (
5471            Option<&'static str>,
5472            HashMap<usize, Option<backtrace::Backtrace>>,
5473        ),
5474    >,
5475}
5476
5477#[cfg(any(test, feature = "test-support"))]
5478impl LeakDetector {
5479    fn handle_created(&mut self, type_name: Option<&'static str>, entity_id: usize) -> usize {
5480        let handle_id = post_inc(&mut self.next_handle_id);
5481        let entry = self.handle_backtraces.entry(entity_id).or_default();
5482        let backtrace = if *LEAK_BACKTRACE {
5483            Some(backtrace::Backtrace::new_unresolved())
5484        } else {
5485            None
5486        };
5487        if let Some(type_name) = type_name {
5488            entry.0.get_or_insert(type_name);
5489        }
5490        entry.1.insert(handle_id, backtrace);
5491        handle_id
5492    }
5493
5494    fn handle_dropped(&mut self, entity_id: usize, handle_id: usize) {
5495        if let Some((_, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
5496            assert!(backtraces.remove(&handle_id).is_some());
5497            if backtraces.is_empty() {
5498                self.handle_backtraces.remove(&entity_id);
5499            }
5500        }
5501    }
5502
5503    pub fn assert_dropped(&mut self, entity_id: usize) {
5504        if let Some((type_name, backtraces)) = self.handle_backtraces.get_mut(&entity_id) {
5505            for trace in backtraces.values_mut() {
5506                if let Some(trace) = trace {
5507                    trace.resolve();
5508                    eprintln!("{:?}", crate::util::CwdBacktrace(trace));
5509                }
5510            }
5511
5512            let hint = if *LEAK_BACKTRACE {
5513                ""
5514            } else {
5515                " – set LEAK_BACKTRACE=1 for more information"
5516            };
5517
5518            panic!(
5519                "{} handles to {} {} still exist{}",
5520                backtraces.len(),
5521                type_name.unwrap_or("entity"),
5522                entity_id,
5523                hint
5524            );
5525        }
5526    }
5527
5528    pub fn detect(&mut self) {
5529        let mut found_leaks = false;
5530        for (id, (type_name, backtraces)) in self.handle_backtraces.iter_mut() {
5531            eprintln!(
5532                "leaked {} handles to {} {}",
5533                backtraces.len(),
5534                type_name.unwrap_or("entity"),
5535                id
5536            );
5537            for trace in backtraces.values_mut() {
5538                if let Some(trace) = trace {
5539                    trace.resolve();
5540                    eprintln!("{:?}", crate::util::CwdBacktrace(trace));
5541                }
5542            }
5543            found_leaks = true;
5544        }
5545
5546        let hint = if *LEAK_BACKTRACE {
5547            ""
5548        } else {
5549            " – set LEAK_BACKTRACE=1 for more information"
5550        };
5551        assert!(!found_leaks, "detected leaked handles{}", hint);
5552    }
5553}
5554
5555#[derive(Default)]
5556struct RefCounts {
5557    entity_counts: HashMap<usize, usize>,
5558    element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
5559    dropped_models: HashSet<usize>,
5560    dropped_views: HashSet<(usize, usize)>,
5561    dropped_element_states: HashSet<ElementStateId>,
5562
5563    #[cfg(any(test, feature = "test-support"))]
5564    leak_detector: Arc<Mutex<LeakDetector>>,
5565}
5566
5567struct ElementStateRefCount {
5568    ref_count: usize,
5569    frame_id: usize,
5570}
5571
5572impl RefCounts {
5573    fn inc_model(&mut self, model_id: usize) {
5574        match self.entity_counts.entry(model_id) {
5575            Entry::Occupied(mut entry) => {
5576                *entry.get_mut() += 1;
5577            }
5578            Entry::Vacant(entry) => {
5579                entry.insert(1);
5580                self.dropped_models.remove(&model_id);
5581            }
5582        }
5583    }
5584
5585    fn inc_view(&mut self, window_id: usize, view_id: usize) {
5586        match self.entity_counts.entry(view_id) {
5587            Entry::Occupied(mut entry) => *entry.get_mut() += 1,
5588            Entry::Vacant(entry) => {
5589                entry.insert(1);
5590                self.dropped_views.remove(&(window_id, view_id));
5591            }
5592        }
5593    }
5594
5595    fn inc_element_state(&mut self, id: ElementStateId, frame_id: usize) {
5596        match self.element_state_counts.entry(id) {
5597            Entry::Occupied(mut entry) => {
5598                let entry = entry.get_mut();
5599                if entry.frame_id == frame_id || entry.ref_count >= 2 {
5600                    panic!("used the same element state more than once in the same frame");
5601                }
5602                entry.ref_count += 1;
5603                entry.frame_id = frame_id;
5604            }
5605            Entry::Vacant(entry) => {
5606                entry.insert(ElementStateRefCount {
5607                    ref_count: 1,
5608                    frame_id,
5609                });
5610                self.dropped_element_states.remove(&id);
5611            }
5612        }
5613    }
5614
5615    fn dec_model(&mut self, model_id: usize) {
5616        let count = self.entity_counts.get_mut(&model_id).unwrap();
5617        *count -= 1;
5618        if *count == 0 {
5619            self.entity_counts.remove(&model_id);
5620            self.dropped_models.insert(model_id);
5621        }
5622    }
5623
5624    fn dec_view(&mut self, window_id: usize, view_id: usize) {
5625        let count = self.entity_counts.get_mut(&view_id).unwrap();
5626        *count -= 1;
5627        if *count == 0 {
5628            self.entity_counts.remove(&view_id);
5629            self.dropped_views.insert((window_id, view_id));
5630        }
5631    }
5632
5633    fn dec_element_state(&mut self, id: ElementStateId) {
5634        let entry = self.element_state_counts.get_mut(&id).unwrap();
5635        entry.ref_count -= 1;
5636        if entry.ref_count == 0 {
5637            self.element_state_counts.remove(&id);
5638            self.dropped_element_states.insert(id);
5639        }
5640    }
5641
5642    fn is_entity_alive(&self, entity_id: usize) -> bool {
5643        self.entity_counts.contains_key(&entity_id)
5644    }
5645
5646    fn take_dropped(
5647        &mut self,
5648    ) -> (
5649        HashSet<usize>,
5650        HashSet<(usize, usize)>,
5651        HashSet<ElementStateId>,
5652    ) {
5653        (
5654            std::mem::take(&mut self.dropped_models),
5655            std::mem::take(&mut self.dropped_views),
5656            std::mem::take(&mut self.dropped_element_states),
5657        )
5658    }
5659}
5660
5661#[cfg(test)]
5662mod tests {
5663    use super::*;
5664    use crate::{actions, elements::*, impl_actions, MouseButton, MouseButtonEvent};
5665    use serde::Deserialize;
5666    use smol::future::poll_once;
5667    use std::{
5668        cell::Cell,
5669        sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
5670    };
5671
5672    #[crate::test(self)]
5673    fn test_model_handles(cx: &mut MutableAppContext) {
5674        struct Model {
5675            other: Option<ModelHandle<Model>>,
5676            events: Vec<String>,
5677        }
5678
5679        impl Entity for Model {
5680            type Event = usize;
5681        }
5682
5683        impl Model {
5684            fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
5685                if let Some(other) = other.as_ref() {
5686                    cx.observe(other, |me, _, _| {
5687                        me.events.push("notified".into());
5688                    })
5689                    .detach();
5690                    cx.subscribe(other, |me, _, event, _| {
5691                        me.events.push(format!("observed event {}", event));
5692                    })
5693                    .detach();
5694                }
5695
5696                Self {
5697                    other,
5698                    events: Vec::new(),
5699                }
5700            }
5701        }
5702
5703        let handle_1 = cx.add_model(|cx| Model::new(None, cx));
5704        let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
5705        assert_eq!(cx.cx.models.len(), 2);
5706
5707        handle_1.update(cx, |model, cx| {
5708            model.events.push("updated".into());
5709            cx.emit(1);
5710            cx.notify();
5711            cx.emit(2);
5712        });
5713        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5714        assert_eq!(
5715            handle_2.read(cx).events,
5716            vec![
5717                "observed event 1".to_string(),
5718                "notified".to_string(),
5719                "observed event 2".to_string(),
5720            ]
5721        );
5722
5723        handle_2.update(cx, |model, _| {
5724            drop(handle_1);
5725            model.other.take();
5726        });
5727
5728        assert_eq!(cx.cx.models.len(), 1);
5729        assert!(cx.subscriptions.is_empty());
5730        assert!(cx.observations.is_empty());
5731    }
5732
5733    #[crate::test(self)]
5734    fn test_model_events(cx: &mut MutableAppContext) {
5735        #[derive(Default)]
5736        struct Model {
5737            events: Vec<usize>,
5738        }
5739
5740        impl Entity for Model {
5741            type Event = usize;
5742        }
5743
5744        let handle_1 = cx.add_model(|_| Model::default());
5745        let handle_2 = cx.add_model(|_| Model::default());
5746
5747        handle_1.update(cx, |_, cx| {
5748            cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
5749                model.events.push(*event);
5750
5751                cx.subscribe(&emitter, |model, _, event, _| {
5752                    model.events.push(*event * 2);
5753                })
5754                .detach();
5755            })
5756            .detach();
5757        });
5758
5759        handle_2.update(cx, |_, c| c.emit(7));
5760        assert_eq!(handle_1.read(cx).events, vec![7]);
5761
5762        handle_2.update(cx, |_, c| c.emit(5));
5763        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
5764    }
5765
5766    #[crate::test(self)]
5767    fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
5768        #[derive(Default)]
5769        struct Model;
5770
5771        impl Entity for Model {
5772            type Event = ();
5773        }
5774
5775        let events = Rc::new(RefCell::new(Vec::new()));
5776        cx.add_model(|cx| {
5777            drop(cx.subscribe(&cx.handle(), {
5778                let events = events.clone();
5779                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
5780            }));
5781            cx.subscribe(&cx.handle(), {
5782                let events = events.clone();
5783                move |_, _, _, _| events.borrow_mut().push("before emit")
5784            })
5785            .detach();
5786            cx.emit(());
5787            cx.subscribe(&cx.handle(), {
5788                let events = events.clone();
5789                move |_, _, _, _| events.borrow_mut().push("after emit")
5790            })
5791            .detach();
5792            Model
5793        });
5794        assert_eq!(*events.borrow(), ["before emit"]);
5795    }
5796
5797    #[crate::test(self)]
5798    fn test_observe_and_notify_from_model(cx: &mut MutableAppContext) {
5799        #[derive(Default)]
5800        struct Model {
5801            count: usize,
5802            events: Vec<usize>,
5803        }
5804
5805        impl Entity for Model {
5806            type Event = ();
5807        }
5808
5809        let handle_1 = cx.add_model(|_| Model::default());
5810        let handle_2 = cx.add_model(|_| Model::default());
5811
5812        handle_1.update(cx, |_, c| {
5813            c.observe(&handle_2, move |model, observed, c| {
5814                model.events.push(observed.read(c).count);
5815                c.observe(&observed, |model, observed, c| {
5816                    model.events.push(observed.read(c).count * 2);
5817                })
5818                .detach();
5819            })
5820            .detach();
5821        });
5822
5823        handle_2.update(cx, |model, c| {
5824            model.count = 7;
5825            c.notify()
5826        });
5827        assert_eq!(handle_1.read(cx).events, vec![7]);
5828
5829        handle_2.update(cx, |model, c| {
5830            model.count = 5;
5831            c.notify()
5832        });
5833        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
5834    }
5835
5836    #[crate::test(self)]
5837    fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
5838        #[derive(Default)]
5839        struct Model;
5840
5841        impl Entity for Model {
5842            type Event = ();
5843        }
5844
5845        let events = Rc::new(RefCell::new(Vec::new()));
5846        cx.add_model(|cx| {
5847            drop(cx.observe(&cx.handle(), {
5848                let events = events.clone();
5849                move |_, _, _| events.borrow_mut().push("dropped before flush")
5850            }));
5851            cx.observe(&cx.handle(), {
5852                let events = events.clone();
5853                move |_, _, _| events.borrow_mut().push("before notify")
5854            })
5855            .detach();
5856            cx.notify();
5857            cx.observe(&cx.handle(), {
5858                let events = events.clone();
5859                move |_, _, _| events.borrow_mut().push("after notify")
5860            })
5861            .detach();
5862            Model
5863        });
5864        assert_eq!(*events.borrow(), ["before notify"]);
5865    }
5866
5867    #[crate::test(self)]
5868    fn test_defer_and_after_window_update(cx: &mut MutableAppContext) {
5869        struct View {
5870            render_count: usize,
5871        }
5872
5873        impl Entity for View {
5874            type Event = usize;
5875        }
5876
5877        impl super::View for View {
5878            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5879                post_inc(&mut self.render_count);
5880                Empty::new().boxed()
5881            }
5882
5883            fn ui_name() -> &'static str {
5884                "View"
5885            }
5886        }
5887
5888        let (_, view) = cx.add_window(Default::default(), |_| View { render_count: 0 });
5889        let called_defer = Rc::new(AtomicBool::new(false));
5890        let called_after_window_update = Rc::new(AtomicBool::new(false));
5891
5892        view.update(cx, |this, cx| {
5893            assert_eq!(this.render_count, 1);
5894            cx.defer({
5895                let called_defer = called_defer.clone();
5896                move |this, _| {
5897                    assert_eq!(this.render_count, 1);
5898                    called_defer.store(true, SeqCst);
5899                }
5900            });
5901            cx.after_window_update({
5902                let called_after_window_update = called_after_window_update.clone();
5903                move |this, cx| {
5904                    assert_eq!(this.render_count, 2);
5905                    called_after_window_update.store(true, SeqCst);
5906                    cx.notify();
5907                }
5908            });
5909            assert!(!called_defer.load(SeqCst));
5910            assert!(!called_after_window_update.load(SeqCst));
5911            cx.notify();
5912        });
5913
5914        assert!(called_defer.load(SeqCst));
5915        assert!(called_after_window_update.load(SeqCst));
5916        assert_eq!(view.read(cx).render_count, 3);
5917    }
5918
5919    #[crate::test(self)]
5920    fn test_view_handles(cx: &mut MutableAppContext) {
5921        struct View {
5922            other: Option<ViewHandle<View>>,
5923            events: Vec<String>,
5924        }
5925
5926        impl Entity for View {
5927            type Event = usize;
5928        }
5929
5930        impl super::View for View {
5931            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5932                Empty::new().boxed()
5933            }
5934
5935            fn ui_name() -> &'static str {
5936                "View"
5937            }
5938        }
5939
5940        impl View {
5941            fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
5942                if let Some(other) = other.as_ref() {
5943                    cx.subscribe(other, |me, _, event, _| {
5944                        me.events.push(format!("observed event {}", event));
5945                    })
5946                    .detach();
5947                }
5948                Self {
5949                    other,
5950                    events: Vec::new(),
5951                }
5952            }
5953        }
5954
5955        let (_, root_view) = cx.add_window(Default::default(), |cx| View::new(None, cx));
5956        let handle_1 = cx.add_view(&root_view, |cx| View::new(None, cx));
5957        let handle_2 = cx.add_view(&root_view, |cx| View::new(Some(handle_1.clone()), cx));
5958        assert_eq!(cx.cx.views.len(), 3);
5959
5960        handle_1.update(cx, |view, cx| {
5961            view.events.push("updated".into());
5962            cx.emit(1);
5963            cx.emit(2);
5964        });
5965        assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
5966        assert_eq!(
5967            handle_2.read(cx).events,
5968            vec![
5969                "observed event 1".to_string(),
5970                "observed event 2".to_string(),
5971            ]
5972        );
5973
5974        handle_2.update(cx, |view, _| {
5975            drop(handle_1);
5976            view.other.take();
5977        });
5978
5979        assert_eq!(cx.cx.views.len(), 2);
5980        assert!(cx.subscriptions.is_empty());
5981        assert!(cx.observations.is_empty());
5982    }
5983
5984    #[crate::test(self)]
5985    fn test_add_window(cx: &mut MutableAppContext) {
5986        struct View {
5987            mouse_down_count: Arc<AtomicUsize>,
5988        }
5989
5990        impl Entity for View {
5991            type Event = ();
5992        }
5993
5994        impl super::View for View {
5995            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
5996                let mouse_down_count = self.mouse_down_count.clone();
5997                EventHandler::new(Empty::new().boxed())
5998                    .on_mouse_down(move |_| {
5999                        mouse_down_count.fetch_add(1, SeqCst);
6000                        true
6001                    })
6002                    .boxed()
6003            }
6004
6005            fn ui_name() -> &'static str {
6006                "View"
6007            }
6008        }
6009
6010        let mouse_down_count = Arc::new(AtomicUsize::new(0));
6011        let (window_id, _) = cx.add_window(Default::default(), |_| View {
6012            mouse_down_count: mouse_down_count.clone(),
6013        });
6014        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
6015        // Ensure window's root element is in a valid lifecycle state.
6016        presenter.borrow_mut().dispatch_event(
6017            Event::MouseDown(MouseButtonEvent {
6018                position: Default::default(),
6019                button: MouseButton::Left,
6020                ctrl: false,
6021                alt: false,
6022                shift: false,
6023                cmd: false,
6024                click_count: 1,
6025            }),
6026            cx,
6027        );
6028        assert_eq!(mouse_down_count.load(SeqCst), 1);
6029    }
6030
6031    #[crate::test(self)]
6032    fn test_entity_release_hooks(cx: &mut MutableAppContext) {
6033        struct Model {
6034            released: Rc<Cell<bool>>,
6035        }
6036
6037        struct View {
6038            released: Rc<Cell<bool>>,
6039        }
6040
6041        impl Entity for Model {
6042            type Event = ();
6043
6044            fn release(&mut self, _: &mut MutableAppContext) {
6045                self.released.set(true);
6046            }
6047        }
6048
6049        impl Entity for View {
6050            type Event = ();
6051
6052            fn release(&mut self, _: &mut MutableAppContext) {
6053                self.released.set(true);
6054            }
6055        }
6056
6057        impl super::View for View {
6058            fn ui_name() -> &'static str {
6059                "View"
6060            }
6061
6062            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6063                Empty::new().boxed()
6064            }
6065        }
6066
6067        let model_released = Rc::new(Cell::new(false));
6068        let model_release_observed = Rc::new(Cell::new(false));
6069        let view_released = Rc::new(Cell::new(false));
6070        let view_release_observed = Rc::new(Cell::new(false));
6071
6072        let model = cx.add_model(|_| Model {
6073            released: model_released.clone(),
6074        });
6075        let (window_id, view) = cx.add_window(Default::default(), |_| View {
6076            released: view_released.clone(),
6077        });
6078        assert!(!model_released.get());
6079        assert!(!view_released.get());
6080
6081        cx.observe_release(&model, {
6082            let model_release_observed = model_release_observed.clone();
6083            move |_, _| model_release_observed.set(true)
6084        })
6085        .detach();
6086        cx.observe_release(&view, {
6087            let view_release_observed = view_release_observed.clone();
6088            move |_, _| view_release_observed.set(true)
6089        })
6090        .detach();
6091
6092        cx.update(move |_| {
6093            drop(model);
6094        });
6095        assert!(model_released.get());
6096        assert!(model_release_observed.get());
6097
6098        drop(view);
6099        cx.remove_window(window_id);
6100        assert!(view_released.get());
6101        assert!(view_release_observed.get());
6102    }
6103
6104    #[crate::test(self)]
6105    fn test_view_events(cx: &mut MutableAppContext) {
6106        #[derive(Default)]
6107        struct View {
6108            events: Vec<usize>,
6109        }
6110
6111        impl Entity for View {
6112            type Event = usize;
6113        }
6114
6115        impl super::View for View {
6116            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6117                Empty::new().boxed()
6118            }
6119
6120            fn ui_name() -> &'static str {
6121                "View"
6122            }
6123        }
6124
6125        struct Model;
6126
6127        impl Entity for Model {
6128            type Event = usize;
6129        }
6130
6131        let (_, handle_1) = cx.add_window(Default::default(), |_| View::default());
6132        let handle_2 = cx.add_view(&handle_1, |_| View::default());
6133        let handle_3 = cx.add_model(|_| Model);
6134
6135        handle_1.update(cx, |_, cx| {
6136            cx.subscribe(&handle_2, move |me, emitter, event, cx| {
6137                me.events.push(*event);
6138
6139                cx.subscribe(&emitter, |me, _, event, _| {
6140                    me.events.push(*event * 2);
6141                })
6142                .detach();
6143            })
6144            .detach();
6145
6146            cx.subscribe(&handle_3, |me, _, event, _| {
6147                me.events.push(*event);
6148            })
6149            .detach();
6150        });
6151
6152        handle_2.update(cx, |_, c| c.emit(7));
6153        assert_eq!(handle_1.read(cx).events, vec![7]);
6154
6155        handle_2.update(cx, |_, c| c.emit(5));
6156        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
6157
6158        handle_3.update(cx, |_, c| c.emit(9));
6159        assert_eq!(handle_1.read(cx).events, vec![7, 5, 10, 9]);
6160    }
6161
6162    #[crate::test(self)]
6163    fn test_global_events(cx: &mut MutableAppContext) {
6164        #[derive(Clone, Debug, Eq, PartialEq)]
6165        struct GlobalEvent(u64);
6166
6167        let events = Rc::new(RefCell::new(Vec::new()));
6168        let first_subscription;
6169        let second_subscription;
6170
6171        {
6172            let events = events.clone();
6173            first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
6174                events.borrow_mut().push(("First", e.clone()));
6175            });
6176        }
6177
6178        {
6179            let events = events.clone();
6180            second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
6181                events.borrow_mut().push(("Second", e.clone()));
6182            });
6183        }
6184
6185        cx.update(|cx| {
6186            cx.emit_global(GlobalEvent(1));
6187            cx.emit_global(GlobalEvent(2));
6188        });
6189
6190        drop(first_subscription);
6191
6192        cx.update(|cx| {
6193            cx.emit_global(GlobalEvent(3));
6194        });
6195
6196        drop(second_subscription);
6197
6198        cx.update(|cx| {
6199            cx.emit_global(GlobalEvent(4));
6200        });
6201
6202        assert_eq!(
6203            &*events.borrow(),
6204            &[
6205                ("First", GlobalEvent(1)),
6206                ("Second", GlobalEvent(1)),
6207                ("First", GlobalEvent(2)),
6208                ("Second", GlobalEvent(2)),
6209                ("Second", GlobalEvent(3)),
6210            ]
6211        );
6212    }
6213
6214    #[crate::test(self)]
6215    fn test_global_events_emitted_before_subscription_in_same_update_cycle(
6216        cx: &mut MutableAppContext,
6217    ) {
6218        let events = Rc::new(RefCell::new(Vec::new()));
6219        cx.update(|cx| {
6220            {
6221                let events = events.clone();
6222                drop(cx.subscribe_global(move |_: &(), _| {
6223                    events.borrow_mut().push("dropped before emit");
6224                }));
6225            }
6226
6227            {
6228                let events = events.clone();
6229                cx.subscribe_global(move |_: &(), _| {
6230                    events.borrow_mut().push("before emit");
6231                })
6232                .detach();
6233            }
6234
6235            cx.emit_global(());
6236
6237            {
6238                let events = events.clone();
6239                cx.subscribe_global(move |_: &(), _| {
6240                    events.borrow_mut().push("after emit");
6241                })
6242                .detach();
6243            }
6244        });
6245
6246        assert_eq!(*events.borrow(), ["before emit"]);
6247    }
6248
6249    #[crate::test(self)]
6250    fn test_global_nested_events(cx: &mut MutableAppContext) {
6251        #[derive(Clone, Debug, Eq, PartialEq)]
6252        struct GlobalEvent(u64);
6253
6254        let events = Rc::new(RefCell::new(Vec::new()));
6255
6256        {
6257            let events = events.clone();
6258            cx.subscribe_global(move |e: &GlobalEvent, cx| {
6259                events.borrow_mut().push(("Outer", e.clone()));
6260
6261                if e.0 == 1 {
6262                    let events = events.clone();
6263                    cx.subscribe_global(move |e: &GlobalEvent, _| {
6264                        events.borrow_mut().push(("Inner", e.clone()));
6265                    })
6266                    .detach();
6267                }
6268            })
6269            .detach();
6270        }
6271
6272        cx.update(|cx| {
6273            cx.emit_global(GlobalEvent(1));
6274            cx.emit_global(GlobalEvent(2));
6275            cx.emit_global(GlobalEvent(3));
6276        });
6277        cx.update(|cx| {
6278            cx.emit_global(GlobalEvent(4));
6279        });
6280
6281        assert_eq!(
6282            &*events.borrow(),
6283            &[
6284                ("Outer", GlobalEvent(1)),
6285                ("Outer", GlobalEvent(2)),
6286                ("Outer", GlobalEvent(3)),
6287                ("Outer", GlobalEvent(4)),
6288                ("Inner", GlobalEvent(4)),
6289            ]
6290        );
6291    }
6292
6293    #[crate::test(self)]
6294    fn test_global(cx: &mut MutableAppContext) {
6295        type Global = usize;
6296
6297        let observation_count = Rc::new(RefCell::new(0));
6298        let subscription = cx.observe_global::<Global, _>({
6299            let observation_count = observation_count.clone();
6300            move |_| {
6301                *observation_count.borrow_mut() += 1;
6302            }
6303        });
6304
6305        assert!(!cx.has_global::<Global>());
6306        assert_eq!(cx.default_global::<Global>(), &0);
6307        assert_eq!(*observation_count.borrow(), 1);
6308        assert!(cx.has_global::<Global>());
6309        assert_eq!(
6310            cx.update_global::<Global, _, _>(|global, _| {
6311                *global = 1;
6312                "Update Result"
6313            }),
6314            "Update Result"
6315        );
6316        assert_eq!(*observation_count.borrow(), 2);
6317        assert_eq!(cx.global::<Global>(), &1);
6318
6319        drop(subscription);
6320        cx.update_global::<Global, _, _>(|global, _| {
6321            *global = 2;
6322        });
6323        assert_eq!(*observation_count.borrow(), 2);
6324
6325        type OtherGlobal = f32;
6326
6327        let observation_count = Rc::new(RefCell::new(0));
6328        cx.observe_global::<OtherGlobal, _>({
6329            let observation_count = observation_count.clone();
6330            move |_| {
6331                *observation_count.borrow_mut() += 1;
6332            }
6333        })
6334        .detach();
6335
6336        assert_eq!(
6337            cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
6338                assert_eq!(global, &0.0);
6339                *global = 2.0;
6340                "Default update result"
6341            }),
6342            "Default update result"
6343        );
6344        assert_eq!(cx.global::<OtherGlobal>(), &2.0);
6345        assert_eq!(*observation_count.borrow(), 1);
6346    }
6347
6348    #[crate::test(self)]
6349    fn test_dropping_subscribers(cx: &mut MutableAppContext) {
6350        struct View;
6351
6352        impl Entity for View {
6353            type Event = ();
6354        }
6355
6356        impl super::View for View {
6357            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6358                Empty::new().boxed()
6359            }
6360
6361            fn ui_name() -> &'static str {
6362                "View"
6363            }
6364        }
6365
6366        struct Model;
6367
6368        impl Entity for Model {
6369            type Event = ();
6370        }
6371
6372        let (_, root_view) = cx.add_window(Default::default(), |_| View);
6373        let observing_view = cx.add_view(&root_view, |_| View);
6374        let emitting_view = cx.add_view(&root_view, |_| View);
6375        let observing_model = cx.add_model(|_| Model);
6376        let observed_model = cx.add_model(|_| Model);
6377
6378        observing_view.update(cx, |_, cx| {
6379            cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
6380            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
6381        });
6382        observing_model.update(cx, |_, cx| {
6383            cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
6384        });
6385
6386        cx.update(|_| {
6387            drop(observing_view);
6388            drop(observing_model);
6389        });
6390
6391        emitting_view.update(cx, |_, cx| cx.emit(()));
6392        observed_model.update(cx, |_, cx| cx.emit(()));
6393    }
6394
6395    #[crate::test(self)]
6396    fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut MutableAppContext) {
6397        #[derive(Default)]
6398        struct TestView;
6399
6400        impl Entity for TestView {
6401            type Event = ();
6402        }
6403
6404        impl View for TestView {
6405            fn ui_name() -> &'static str {
6406                "TestView"
6407            }
6408
6409            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6410                Empty::new().boxed()
6411            }
6412        }
6413
6414        let events = Rc::new(RefCell::new(Vec::new()));
6415        cx.add_window(Default::default(), |cx| {
6416            drop(cx.subscribe(&cx.handle(), {
6417                let events = events.clone();
6418                move |_, _, _, _| events.borrow_mut().push("dropped before flush")
6419            }));
6420            cx.subscribe(&cx.handle(), {
6421                let events = events.clone();
6422                move |_, _, _, _| events.borrow_mut().push("before emit")
6423            })
6424            .detach();
6425            cx.emit(());
6426            cx.subscribe(&cx.handle(), {
6427                let events = events.clone();
6428                move |_, _, _, _| events.borrow_mut().push("after emit")
6429            })
6430            .detach();
6431            TestView
6432        });
6433        assert_eq!(*events.borrow(), ["before emit"]);
6434    }
6435
6436    #[crate::test(self)]
6437    fn test_observe_and_notify_from_view(cx: &mut MutableAppContext) {
6438        #[derive(Default)]
6439        struct View {
6440            events: Vec<usize>,
6441        }
6442
6443        impl Entity for View {
6444            type Event = usize;
6445        }
6446
6447        impl super::View for View {
6448            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6449                Empty::new().boxed()
6450            }
6451
6452            fn ui_name() -> &'static str {
6453                "View"
6454            }
6455        }
6456
6457        #[derive(Default)]
6458        struct Model {
6459            count: usize,
6460        }
6461
6462        impl Entity for Model {
6463            type Event = ();
6464        }
6465
6466        let (_, view) = cx.add_window(Default::default(), |_| View::default());
6467        let model = cx.add_model(|_| Model::default());
6468
6469        view.update(cx, |_, c| {
6470            c.observe(&model, |me, observed, c| {
6471                me.events.push(observed.read(c).count)
6472            })
6473            .detach();
6474        });
6475
6476        model.update(cx, |model, c| {
6477            model.count = 11;
6478            c.notify();
6479        });
6480        assert_eq!(view.read(cx).events, vec![11]);
6481    }
6482
6483    #[crate::test(self)]
6484    fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut MutableAppContext) {
6485        #[derive(Default)]
6486        struct TestView;
6487
6488        impl Entity for TestView {
6489            type Event = ();
6490        }
6491
6492        impl View for TestView {
6493            fn ui_name() -> &'static str {
6494                "TestView"
6495            }
6496
6497            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6498                Empty::new().boxed()
6499            }
6500        }
6501
6502        let events = Rc::new(RefCell::new(Vec::new()));
6503        cx.add_window(Default::default(), |cx| {
6504            drop(cx.observe(&cx.handle(), {
6505                let events = events.clone();
6506                move |_, _, _| events.borrow_mut().push("dropped before flush")
6507            }));
6508            cx.observe(&cx.handle(), {
6509                let events = events.clone();
6510                move |_, _, _| events.borrow_mut().push("before notify")
6511            })
6512            .detach();
6513            cx.notify();
6514            cx.observe(&cx.handle(), {
6515                let events = events.clone();
6516                move |_, _, _| events.borrow_mut().push("after notify")
6517            })
6518            .detach();
6519            TestView
6520        });
6521        assert_eq!(*events.borrow(), ["before notify"]);
6522    }
6523
6524    #[crate::test(self)]
6525    fn test_dropping_observers(cx: &mut MutableAppContext) {
6526        struct View;
6527
6528        impl Entity for View {
6529            type Event = ();
6530        }
6531
6532        impl super::View for View {
6533            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6534                Empty::new().boxed()
6535            }
6536
6537            fn ui_name() -> &'static str {
6538                "View"
6539            }
6540        }
6541
6542        struct Model;
6543
6544        impl Entity for Model {
6545            type Event = ();
6546        }
6547
6548        let (_, root_view) = cx.add_window(Default::default(), |_| View);
6549        let observing_view = cx.add_view(root_view, |_| View);
6550        let observing_model = cx.add_model(|_| Model);
6551        let observed_model = cx.add_model(|_| Model);
6552
6553        observing_view.update(cx, |_, cx| {
6554            cx.observe(&observed_model, |_, _, _| {}).detach();
6555        });
6556        observing_model.update(cx, |_, cx| {
6557            cx.observe(&observed_model, |_, _, _| {}).detach();
6558        });
6559
6560        cx.update(|_| {
6561            drop(observing_view);
6562            drop(observing_model);
6563        });
6564
6565        observed_model.update(cx, |_, cx| cx.notify());
6566    }
6567
6568    #[crate::test(self)]
6569    fn test_dropping_subscriptions_during_callback(cx: &mut MutableAppContext) {
6570        struct Model;
6571
6572        impl Entity for Model {
6573            type Event = u64;
6574        }
6575
6576        // Events
6577        let observing_model = cx.add_model(|_| Model);
6578        let observed_model = cx.add_model(|_| Model);
6579
6580        let events = Rc::new(RefCell::new(Vec::new()));
6581
6582        observing_model.update(cx, |_, cx| {
6583            let events = events.clone();
6584            let subscription = Rc::new(RefCell::new(None));
6585            *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
6586                let subscription = subscription.clone();
6587                move |_, _, e, _| {
6588                    subscription.borrow_mut().take();
6589                    events.borrow_mut().push(e.clone());
6590                }
6591            }));
6592        });
6593
6594        observed_model.update(cx, |_, cx| {
6595            cx.emit(1);
6596            cx.emit(2);
6597        });
6598
6599        assert_eq!(*events.borrow(), [1]);
6600
6601        // Global Events
6602        #[derive(Clone, Debug, Eq, PartialEq)]
6603        struct GlobalEvent(u64);
6604
6605        let events = Rc::new(RefCell::new(Vec::new()));
6606
6607        {
6608            let events = events.clone();
6609            let subscription = Rc::new(RefCell::new(None));
6610            *subscription.borrow_mut() = Some(cx.subscribe_global({
6611                let subscription = subscription.clone();
6612                move |e: &GlobalEvent, _| {
6613                    subscription.borrow_mut().take();
6614                    events.borrow_mut().push(e.clone());
6615                }
6616            }));
6617        }
6618
6619        cx.update(|cx| {
6620            cx.emit_global(GlobalEvent(1));
6621            cx.emit_global(GlobalEvent(2));
6622        });
6623
6624        assert_eq!(*events.borrow(), [GlobalEvent(1)]);
6625
6626        // Model Observation
6627        let observing_model = cx.add_model(|_| Model);
6628        let observed_model = cx.add_model(|_| Model);
6629
6630        let observation_count = Rc::new(RefCell::new(0));
6631
6632        observing_model.update(cx, |_, cx| {
6633            let observation_count = observation_count.clone();
6634            let subscription = Rc::new(RefCell::new(None));
6635            *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
6636                let subscription = subscription.clone();
6637                move |_, _, _| {
6638                    subscription.borrow_mut().take();
6639                    *observation_count.borrow_mut() += 1;
6640                }
6641            }));
6642        });
6643
6644        observed_model.update(cx, |_, cx| {
6645            cx.notify();
6646        });
6647
6648        observed_model.update(cx, |_, cx| {
6649            cx.notify();
6650        });
6651
6652        assert_eq!(*observation_count.borrow(), 1);
6653
6654        // View Observation
6655        struct View;
6656
6657        impl Entity for View {
6658            type Event = ();
6659        }
6660
6661        impl super::View for View {
6662            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6663                Empty::new().boxed()
6664            }
6665
6666            fn ui_name() -> &'static str {
6667                "View"
6668            }
6669        }
6670
6671        let (_, root_view) = cx.add_window(Default::default(), |_| View);
6672        let observing_view = cx.add_view(&root_view, |_| View);
6673        let observed_view = cx.add_view(&root_view, |_| View);
6674
6675        let observation_count = Rc::new(RefCell::new(0));
6676        observing_view.update(cx, |_, cx| {
6677            let observation_count = observation_count.clone();
6678            let subscription = Rc::new(RefCell::new(None));
6679            *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
6680                let subscription = subscription.clone();
6681                move |_, _, _| {
6682                    subscription.borrow_mut().take();
6683                    *observation_count.borrow_mut() += 1;
6684                }
6685            }));
6686        });
6687
6688        observed_view.update(cx, |_, cx| {
6689            cx.notify();
6690        });
6691
6692        observed_view.update(cx, |_, cx| {
6693            cx.notify();
6694        });
6695
6696        assert_eq!(*observation_count.borrow(), 1);
6697
6698        // Global Observation
6699        let observation_count = Rc::new(RefCell::new(0));
6700        let subscription = Rc::new(RefCell::new(None));
6701        *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
6702            let observation_count = observation_count.clone();
6703            let subscription = subscription.clone();
6704            move |_| {
6705                subscription.borrow_mut().take();
6706                *observation_count.borrow_mut() += 1;
6707            }
6708        }));
6709
6710        cx.default_global::<()>();
6711        cx.set_global(());
6712        assert_eq!(*observation_count.borrow(), 1);
6713    }
6714
6715    #[crate::test(self)]
6716    fn test_focus(cx: &mut MutableAppContext) {
6717        struct View {
6718            name: String,
6719            events: Arc<Mutex<Vec<String>>>,
6720        }
6721
6722        impl Entity for View {
6723            type Event = ();
6724        }
6725
6726        impl super::View for View {
6727            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6728                Empty::new().boxed()
6729            }
6730
6731            fn ui_name() -> &'static str {
6732                "View"
6733            }
6734
6735            fn on_focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
6736                if cx.handle().id() == focused.id() {
6737                    self.events.lock().push(format!("{} focused", &self.name));
6738                }
6739            }
6740
6741            fn on_focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
6742                if cx.handle().id() == blurred.id() {
6743                    self.events.lock().push(format!("{} blurred", &self.name));
6744                }
6745            }
6746        }
6747
6748        let view_events: Arc<Mutex<Vec<String>>> = Default::default();
6749        let (_, view_1) = cx.add_window(Default::default(), |_| View {
6750            events: view_events.clone(),
6751            name: "view 1".to_string(),
6752        });
6753        let view_2 = cx.add_view(&view_1, |_| View {
6754            events: view_events.clone(),
6755            name: "view 2".to_string(),
6756        });
6757
6758        let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
6759        view_1.update(cx, |_, cx| {
6760            cx.observe_focus(&view_2, {
6761                let observed_events = observed_events.clone();
6762                move |this, view, focused, cx| {
6763                    let label = if focused { "focus" } else { "blur" };
6764                    observed_events.lock().push(format!(
6765                        "{} observed {}'s {}",
6766                        this.name,
6767                        view.read(cx).name,
6768                        label
6769                    ))
6770                }
6771            })
6772            .detach();
6773        });
6774        view_2.update(cx, |_, cx| {
6775            cx.observe_focus(&view_1, {
6776                let observed_events = observed_events.clone();
6777                move |this, view, focused, cx| {
6778                    let label = if focused { "focus" } else { "blur" };
6779                    observed_events.lock().push(format!(
6780                        "{} observed {}'s {}",
6781                        this.name,
6782                        view.read(cx).name,
6783                        label
6784                    ))
6785                }
6786            })
6787            .detach();
6788        });
6789        assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
6790        assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
6791
6792        view_1.update(cx, |_, cx| {
6793            // Ensure only the latest focus is honored.
6794            cx.focus(&view_2);
6795            cx.focus(&view_1);
6796            cx.focus(&view_2);
6797        });
6798        assert_eq!(
6799            mem::take(&mut *view_events.lock()),
6800            ["view 1 blurred", "view 2 focused"],
6801        );
6802        assert_eq!(
6803            mem::take(&mut *observed_events.lock()),
6804            [
6805                "view 2 observed view 1's blur",
6806                "view 1 observed view 2's focus"
6807            ]
6808        );
6809
6810        view_1.update(cx, |_, cx| cx.focus(&view_1));
6811        assert_eq!(
6812            mem::take(&mut *view_events.lock()),
6813            ["view 2 blurred", "view 1 focused"],
6814        );
6815        assert_eq!(
6816            mem::take(&mut *observed_events.lock()),
6817            [
6818                "view 1 observed view 2's blur",
6819                "view 2 observed view 1's focus"
6820            ]
6821        );
6822
6823        view_1.update(cx, |_, cx| cx.focus(&view_2));
6824        assert_eq!(
6825            mem::take(&mut *view_events.lock()),
6826            ["view 1 blurred", "view 2 focused"],
6827        );
6828        assert_eq!(
6829            mem::take(&mut *observed_events.lock()),
6830            [
6831                "view 2 observed view 1's blur",
6832                "view 1 observed view 2's focus"
6833            ]
6834        );
6835
6836        view_1.update(cx, |_, _| drop(view_2));
6837        assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
6838        assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
6839    }
6840
6841    #[crate::test(self)]
6842    fn test_deserialize_actions(cx: &mut MutableAppContext) {
6843        #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
6844        pub struct ComplexAction {
6845            arg: String,
6846            count: usize,
6847        }
6848
6849        actions!(test::something, [SimpleAction]);
6850        impl_actions!(test::something, [ComplexAction]);
6851
6852        cx.add_global_action(move |_: &SimpleAction, _: &mut MutableAppContext| {});
6853        cx.add_global_action(move |_: &ComplexAction, _: &mut MutableAppContext| {});
6854
6855        let action1 = cx
6856            .deserialize_action(
6857                "test::something::ComplexAction",
6858                Some(r#"{"arg": "a", "count": 5}"#),
6859            )
6860            .unwrap();
6861        let action2 = cx
6862            .deserialize_action("test::something::SimpleAction", None)
6863            .unwrap();
6864        assert_eq!(
6865            action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
6866            &ComplexAction {
6867                arg: "a".to_string(),
6868                count: 5,
6869            }
6870        );
6871        assert_eq!(
6872            action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
6873            &SimpleAction
6874        );
6875    }
6876
6877    #[crate::test(self)]
6878    fn test_dispatch_action(cx: &mut MutableAppContext) {
6879        struct ViewA {
6880            id: usize,
6881        }
6882
6883        impl Entity for ViewA {
6884            type Event = ();
6885        }
6886
6887        impl View for ViewA {
6888            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6889                Empty::new().boxed()
6890            }
6891
6892            fn ui_name() -> &'static str {
6893                "View"
6894            }
6895        }
6896
6897        struct ViewB {
6898            id: usize,
6899        }
6900
6901        impl Entity for ViewB {
6902            type Event = ();
6903        }
6904
6905        impl View for ViewB {
6906            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
6907                Empty::new().boxed()
6908            }
6909
6910            fn ui_name() -> &'static str {
6911                "View"
6912            }
6913        }
6914
6915        #[derive(Clone, Default, Deserialize, PartialEq)]
6916        pub struct Action(pub String);
6917
6918        impl_actions!(test, [Action]);
6919
6920        let actions = Rc::new(RefCell::new(Vec::new()));
6921
6922        cx.add_global_action({
6923            let actions = actions.clone();
6924            move |_: &Action, _: &mut MutableAppContext| {
6925                actions.borrow_mut().push("global".to_string());
6926            }
6927        });
6928
6929        cx.add_action({
6930            let actions = actions.clone();
6931            move |view: &mut ViewA, action: &Action, cx| {
6932                assert_eq!(action.0, "bar");
6933                cx.propagate_action();
6934                actions.borrow_mut().push(format!("{} a", view.id));
6935            }
6936        });
6937
6938        cx.add_action({
6939            let actions = actions.clone();
6940            move |view: &mut ViewA, _: &Action, cx| {
6941                if view.id != 1 {
6942                    cx.add_view(|cx| {
6943                        cx.propagate_action(); // Still works on a nested ViewContext
6944                        ViewB { id: 5 }
6945                    });
6946                }
6947                actions.borrow_mut().push(format!("{} b", view.id));
6948            }
6949        });
6950
6951        cx.add_action({
6952            let actions = actions.clone();
6953            move |view: &mut ViewB, _: &Action, cx| {
6954                cx.propagate_action();
6955                actions.borrow_mut().push(format!("{} c", view.id));
6956            }
6957        });
6958
6959        cx.add_action({
6960            let actions = actions.clone();
6961            move |view: &mut ViewB, _: &Action, cx| {
6962                cx.propagate_action();
6963                actions.borrow_mut().push(format!("{} d", view.id));
6964            }
6965        });
6966
6967        cx.capture_action({
6968            let actions = actions.clone();
6969            move |view: &mut ViewA, _: &Action, cx| {
6970                cx.propagate_action();
6971                actions.borrow_mut().push(format!("{} capture", view.id));
6972            }
6973        });
6974
6975        let observed_actions = Rc::new(RefCell::new(Vec::new()));
6976        cx.observe_actions({
6977            let observed_actions = observed_actions.clone();
6978            move |action_id, _| observed_actions.borrow_mut().push(action_id)
6979        })
6980        .detach();
6981
6982        let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 });
6983        let view_2 = cx.add_view(&view_1, |_| ViewB { id: 2 });
6984        let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
6985        let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
6986
6987        cx.handle_dispatch_action_from_effect(
6988            window_id,
6989            Some(view_4.id()),
6990            &Action("bar".to_string()),
6991        );
6992
6993        assert_eq!(
6994            *actions.borrow(),
6995            vec![
6996                "1 capture",
6997                "3 capture",
6998                "4 d",
6999                "4 c",
7000                "3 b",
7001                "3 a",
7002                "2 d",
7003                "2 c",
7004                "1 b"
7005            ]
7006        );
7007        assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
7008
7009        // Remove view_1, which doesn't propagate the action
7010
7011        let (window_id, view_2) = cx.add_window(Default::default(), |_| ViewB { id: 2 });
7012        let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 });
7013        let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 });
7014
7015        actions.borrow_mut().clear();
7016        cx.handle_dispatch_action_from_effect(
7017            window_id,
7018            Some(view_4.id()),
7019            &Action("bar".to_string()),
7020        );
7021
7022        assert_eq!(
7023            *actions.borrow(),
7024            vec![
7025                "3 capture",
7026                "4 d",
7027                "4 c",
7028                "3 b",
7029                "3 a",
7030                "2 d",
7031                "2 c",
7032                "global"
7033            ]
7034        );
7035        assert_eq!(
7036            *observed_actions.borrow(),
7037            [Action::default().id(), Action::default().id()]
7038        );
7039    }
7040
7041    #[crate::test(self)]
7042    fn test_dispatch_keystroke(cx: &mut MutableAppContext) {
7043        #[derive(Clone, Deserialize, PartialEq)]
7044        pub struct Action(String);
7045
7046        impl_actions!(test, [Action]);
7047
7048        struct View {
7049            id: usize,
7050            keymap_context: keymap::Context,
7051        }
7052
7053        impl Entity for View {
7054            type Event = ();
7055        }
7056
7057        impl super::View for View {
7058            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
7059                Empty::new().boxed()
7060            }
7061
7062            fn ui_name() -> &'static str {
7063                "View"
7064            }
7065
7066            fn keymap_context(&self, _: &AppContext) -> keymap::Context {
7067                self.keymap_context.clone()
7068            }
7069        }
7070
7071        impl View {
7072            fn new(id: usize) -> Self {
7073                View {
7074                    id,
7075                    keymap_context: keymap::Context::default(),
7076                }
7077            }
7078        }
7079
7080        let mut view_1 = View::new(1);
7081        let mut view_2 = View::new(2);
7082        let mut view_3 = View::new(3);
7083        view_1.keymap_context.set.insert("a".into());
7084        view_2.keymap_context.set.insert("a".into());
7085        view_2.keymap_context.set.insert("b".into());
7086        view_3.keymap_context.set.insert("a".into());
7087        view_3.keymap_context.set.insert("b".into());
7088        view_3.keymap_context.set.insert("c".into());
7089
7090        let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1);
7091        let view_2 = cx.add_view(&view_1, |_| view_2);
7092        let _view_3 = cx.add_view(&view_2, |cx| {
7093            cx.focus_self();
7094            view_3
7095        });
7096
7097        // This keymap's only binding dispatches an action on view 2 because that view will have
7098        // "a" and "b" in its context, but not "c".
7099        cx.add_bindings(vec![keymap::Binding::new(
7100            "a",
7101            Action("a".to_string()),
7102            Some("a && b && !c"),
7103        )]);
7104
7105        cx.add_bindings(vec![keymap::Binding::new(
7106            "b",
7107            Action("b".to_string()),
7108            None,
7109        )]);
7110
7111        let actions = Rc::new(RefCell::new(Vec::new()));
7112        cx.add_action({
7113            let actions = actions.clone();
7114            move |view: &mut View, action: &Action, cx| {
7115                if action.0 == "a" {
7116                    actions.borrow_mut().push(format!("{} a", view.id));
7117                } else {
7118                    actions
7119                        .borrow_mut()
7120                        .push(format!("{} {}", view.id, action.0));
7121                    cx.propagate_action();
7122                }
7123            }
7124        });
7125
7126        cx.add_global_action({
7127            let actions = actions.clone();
7128            move |action: &Action, _| {
7129                actions.borrow_mut().push(format!("global {}", action.0));
7130            }
7131        });
7132
7133        cx.dispatch_keystroke(window_id, &Keystroke::parse("a").unwrap());
7134
7135        assert_eq!(&*actions.borrow(), &["2 a"]);
7136
7137        actions.borrow_mut().clear();
7138
7139        cx.dispatch_keystroke(window_id, &Keystroke::parse("b").unwrap());
7140
7141        assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
7142    }
7143
7144    #[crate::test(self)]
7145    async fn test_model_condition(cx: &mut TestAppContext) {
7146        struct Counter(usize);
7147
7148        impl super::Entity for Counter {
7149            type Event = ();
7150        }
7151
7152        impl Counter {
7153            fn inc(&mut self, cx: &mut ModelContext<Self>) {
7154                self.0 += 1;
7155                cx.notify();
7156            }
7157        }
7158
7159        let model = cx.add_model(|_| Counter(0));
7160
7161        let condition1 = model.condition(&cx, |model, _| model.0 == 2);
7162        let condition2 = model.condition(&cx, |model, _| model.0 == 3);
7163        smol::pin!(condition1, condition2);
7164
7165        model.update(cx, |model, cx| model.inc(cx));
7166        assert_eq!(poll_once(&mut condition1).await, None);
7167        assert_eq!(poll_once(&mut condition2).await, None);
7168
7169        model.update(cx, |model, cx| model.inc(cx));
7170        assert_eq!(poll_once(&mut condition1).await, Some(()));
7171        assert_eq!(poll_once(&mut condition2).await, None);
7172
7173        model.update(cx, |model, cx| model.inc(cx));
7174        assert_eq!(poll_once(&mut condition2).await, Some(()));
7175
7176        model.update(cx, |_, cx| cx.notify());
7177    }
7178
7179    #[crate::test(self)]
7180    #[should_panic]
7181    async fn test_model_condition_timeout(cx: &mut TestAppContext) {
7182        struct Model;
7183
7184        impl super::Entity for Model {
7185            type Event = ();
7186        }
7187
7188        let model = cx.add_model(|_| Model);
7189        model.condition(&cx, |_, _| false).await;
7190    }
7191
7192    #[crate::test(self)]
7193    #[should_panic(expected = "model dropped with pending condition")]
7194    async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
7195        struct Model;
7196
7197        impl super::Entity for Model {
7198            type Event = ();
7199        }
7200
7201        let model = cx.add_model(|_| Model);
7202        let condition = model.condition(&cx, |_, _| false);
7203        cx.update(|_| drop(model));
7204        condition.await;
7205    }
7206
7207    #[crate::test(self)]
7208    async fn test_view_condition(cx: &mut TestAppContext) {
7209        struct Counter(usize);
7210
7211        impl super::Entity for Counter {
7212            type Event = ();
7213        }
7214
7215        impl super::View for Counter {
7216            fn ui_name() -> &'static str {
7217                "test view"
7218            }
7219
7220            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
7221                Empty::new().boxed()
7222            }
7223        }
7224
7225        impl Counter {
7226            fn inc(&mut self, cx: &mut ViewContext<Self>) {
7227                self.0 += 1;
7228                cx.notify();
7229            }
7230        }
7231
7232        let (_, view) = cx.add_window(|_| Counter(0));
7233
7234        let condition1 = view.condition(&cx, |view, _| view.0 == 2);
7235        let condition2 = view.condition(&cx, |view, _| view.0 == 3);
7236        smol::pin!(condition1, condition2);
7237
7238        view.update(cx, |view, cx| view.inc(cx));
7239        assert_eq!(poll_once(&mut condition1).await, None);
7240        assert_eq!(poll_once(&mut condition2).await, None);
7241
7242        view.update(cx, |view, cx| view.inc(cx));
7243        assert_eq!(poll_once(&mut condition1).await, Some(()));
7244        assert_eq!(poll_once(&mut condition2).await, None);
7245
7246        view.update(cx, |view, cx| view.inc(cx));
7247        assert_eq!(poll_once(&mut condition2).await, Some(()));
7248        view.update(cx, |_, cx| cx.notify());
7249    }
7250
7251    #[crate::test(self)]
7252    #[should_panic]
7253    async fn test_view_condition_timeout(cx: &mut TestAppContext) {
7254        struct View;
7255
7256        impl super::Entity for View {
7257            type Event = ();
7258        }
7259
7260        impl super::View for View {
7261            fn ui_name() -> &'static str {
7262                "test view"
7263            }
7264
7265            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
7266                Empty::new().boxed()
7267            }
7268        }
7269
7270        let (_, view) = cx.add_window(|_| View);
7271        view.condition(&cx, |_, _| false).await;
7272    }
7273
7274    #[crate::test(self)]
7275    #[should_panic(expected = "view dropped with pending condition")]
7276    async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
7277        struct View;
7278
7279        impl super::Entity for View {
7280            type Event = ();
7281        }
7282
7283        impl super::View for View {
7284            fn ui_name() -> &'static str {
7285                "test view"
7286            }
7287
7288            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
7289                Empty::new().boxed()
7290            }
7291        }
7292
7293        let (_, root_view) = cx.add_window(|_| View);
7294        let view = cx.add_view(&root_view, |_| View);
7295
7296        let condition = view.condition(&cx, |_, _| false);
7297        cx.update(|_| drop(view));
7298        condition.await;
7299    }
7300
7301    #[crate::test(self)]
7302    fn test_refresh_windows(cx: &mut MutableAppContext) {
7303        struct View(usize);
7304
7305        impl super::Entity for View {
7306            type Event = ();
7307        }
7308
7309        impl super::View for View {
7310            fn ui_name() -> &'static str {
7311                "test view"
7312            }
7313
7314            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
7315                Empty::new().named(format!("render count: {}", post_inc(&mut self.0)))
7316            }
7317        }
7318
7319        let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
7320        let presenter = cx.presenters_and_platform_windows[&window_id].0.clone();
7321
7322        assert_eq!(
7323            presenter.borrow().rendered_views[&root_view.id()].name(),
7324            Some("render count: 0")
7325        );
7326
7327        let view = cx.add_view(&root_view, |cx| {
7328            cx.refresh_windows();
7329            View(0)
7330        });
7331
7332        assert_eq!(
7333            presenter.borrow().rendered_views[&root_view.id()].name(),
7334            Some("render count: 1")
7335        );
7336        assert_eq!(
7337            presenter.borrow().rendered_views[&view.id()].name(),
7338            Some("render count: 0")
7339        );
7340
7341        cx.update(|cx| cx.refresh_windows());
7342        assert_eq!(
7343            presenter.borrow().rendered_views[&root_view.id()].name(),
7344            Some("render count: 2")
7345        );
7346        assert_eq!(
7347            presenter.borrow().rendered_views[&view.id()].name(),
7348            Some("render count: 1")
7349        );
7350
7351        cx.update(|cx| {
7352            cx.refresh_windows();
7353            drop(view);
7354        });
7355        assert_eq!(
7356            presenter.borrow().rendered_views[&root_view.id()].name(),
7357            Some("render count: 3")
7358        );
7359        assert_eq!(presenter.borrow().rendered_views.len(), 1);
7360    }
7361
7362    #[crate::test(self)]
7363    async fn test_window_activation(cx: &mut TestAppContext) {
7364        struct View(&'static str);
7365
7366        impl super::Entity for View {
7367            type Event = ();
7368        }
7369
7370        impl super::View for View {
7371            fn ui_name() -> &'static str {
7372                "test view"
7373            }
7374
7375            fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
7376                Empty::new().boxed()
7377            }
7378        }
7379
7380        let events = Rc::new(RefCell::new(Vec::new()));
7381        let (window_1, _) = cx.add_window(|cx: &mut ViewContext<View>| {
7382            cx.observe_window_activation({
7383                let events = events.clone();
7384                move |this, active, _| events.borrow_mut().push((this.0, active))
7385            })
7386            .detach();
7387            View("window 1")
7388        });
7389        assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]);
7390
7391        let (window_2, _) = cx.add_window(|cx: &mut ViewContext<View>| {
7392            cx.observe_window_activation({
7393                let events = events.clone();
7394                move |this, active, _| events.borrow_mut().push((this.0, active))
7395            })
7396            .detach();
7397            View("window 2")
7398        });
7399        assert_eq!(
7400            mem::take(&mut *events.borrow_mut()),
7401            [("window 1", false), ("window 2", true)]
7402        );
7403
7404        let (window_3, _) = cx.add_window(|cx: &mut ViewContext<View>| {
7405            cx.observe_window_activation({
7406                let events = events.clone();
7407                move |this, active, _| events.borrow_mut().push((this.0, active))
7408            })
7409            .detach();
7410            View("window 3")
7411        });
7412        assert_eq!(
7413            mem::take(&mut *events.borrow_mut()),
7414            [("window 2", false), ("window 3", true)]
7415        );
7416
7417        cx.simulate_window_activation(Some(window_2));
7418        assert_eq!(
7419            mem::take(&mut *events.borrow_mut()),
7420            [("window 3", false), ("window 2", true)]
7421        );
7422
7423        cx.simulate_window_activation(Some(window_1));
7424        assert_eq!(
7425            mem::take(&mut *events.borrow_mut()),
7426            [("window 2", false), ("window 1", true)]
7427        );
7428
7429        cx.simulate_window_activation(Some(window_3));
7430        assert_eq!(
7431            mem::take(&mut *events.borrow_mut()),
7432            [("window 1", false), ("window 3", true)]
7433        );
7434
7435        cx.simulate_window_activation(Some(window_3));
7436        assert_eq!(mem::take(&mut *events.borrow_mut()), []);
7437    }
7438}