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