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