gpui3.rs

  1mod app;
  2mod color;
  3mod element;
  4mod elements;
  5mod executor;
  6mod geometry;
  7mod platform;
  8mod renderer;
  9mod scene;
 10mod style;
 11mod style_helpers;
 12mod styled;
 13mod taffy;
 14mod text_system;
 15mod util;
 16mod view;
 17mod window;
 18
 19pub use anyhow::Result;
 20pub use app::*;
 21pub use color::*;
 22pub use element::*;
 23pub use elements::*;
 24pub use executor::*;
 25use futures::channel::oneshot;
 26pub use geometry::*;
 27pub use gpui3_macros::*;
 28pub use platform::*;
 29pub use refineable::*;
 30pub use scene::*;
 31pub use serde;
 32pub use serde_json;
 33pub use smallvec;
 34pub use smol::Timer;
 35use std::{
 36    future::Future,
 37    ops::{Deref, DerefMut},
 38    sync::Arc,
 39};
 40pub use style::*;
 41pub use style_helpers::*;
 42pub use styled::*;
 43use taffy::TaffyLayoutEngine;
 44pub use taffy::{AvailableSpace, LayoutId};
 45pub use text_system::*;
 46pub use util::arc_cow::ArcCow;
 47pub use view::*;
 48pub use window::*;
 49
 50pub trait Context {
 51    type EntityContext<'a, 'w, T: Send + 'static>;
 52
 53    fn entity<T: 'static + Send>(
 54        &mut self,
 55        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 56    ) -> Handle<T>;
 57
 58    fn update_entity<T: 'static + Send, R>(
 59        &mut self,
 60        handle: &Handle<T>,
 61        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
 62    ) -> R;
 63}
 64
 65#[derive(Clone, Eq, PartialEq)]
 66pub struct SharedString(ArcCow<'static, str>);
 67
 68impl Default for SharedString {
 69    fn default() -> Self {
 70        Self(ArcCow::Owned("".into()))
 71    }
 72}
 73
 74impl AsRef<str> for SharedString {
 75    fn as_ref(&self) -> &str {
 76        &self.0
 77    }
 78}
 79
 80impl std::fmt::Debug for SharedString {
 81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 82        self.0.fmt(f)
 83    }
 84}
 85
 86impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
 87    fn from(value: T) -> Self {
 88        Self(value.into())
 89    }
 90}
 91
 92pub enum Reference<'a, T> {
 93    Immutable(&'a T),
 94    Mutable(&'a mut T),
 95}
 96
 97impl<'a, T> Deref for Reference<'a, T> {
 98    type Target = T;
 99
100    fn deref(&self) -> &Self::Target {
101        match self {
102            Reference::Immutable(target) => target,
103            Reference::Mutable(target) => target,
104        }
105    }
106}
107
108impl<'a, T> DerefMut for Reference<'a, T> {
109    fn deref_mut(&mut self) -> &mut Self::Target {
110        match self {
111            Reference::Immutable(_) => {
112                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
113            }
114            Reference::Mutable(target) => target,
115        }
116    }
117}
118
119pub(crate) struct MainThreadOnly<T: ?Sized> {
120    dispatcher: Arc<dyn PlatformDispatcher>,
121    value: Arc<T>,
122}
123
124impl<T: ?Sized> Clone for MainThreadOnly<T> {
125    fn clone(&self) -> Self {
126        Self {
127            dispatcher: self.dispatcher.clone(),
128            value: self.value.clone(),
129        }
130    }
131}
132
133/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
134/// to become `Send`.
135impl<T: 'static + ?Sized> MainThreadOnly<T> {
136    pub(crate) fn new(value: Arc<T>, dispatcher: Arc<dyn PlatformDispatcher>) -> Self {
137        Self { dispatcher, value }
138    }
139
140    pub(crate) fn borrow_on_main_thread(&self) -> &T {
141        assert!(self.dispatcher.is_main_thread());
142        &self.value
143    }
144
145    pub(crate) fn read<R>(
146        &self,
147        f: impl FnOnce(&T) -> R + Send + 'static,
148    ) -> impl Future<Output = R>
149    where
150        R: Send + 'static,
151    {
152        let (tx, rx) = oneshot::channel();
153        if self.dispatcher.is_main_thread() {
154            let _ = tx.send(f(&self.value));
155        } else {
156            let this = self.clone();
157            let _ = crate::spawn_on_main(self.dispatcher.clone(), async move {
158                // Required so we move `this` instead of this.value. Only `this` is `Send`.
159                let this = this;
160                let _ = tx.send(f(&this.value));
161            });
162        }
163
164        async move { rx.await.unwrap() }
165    }
166}
167
168unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}