gpui3.rs

  1mod app;
  2mod assets;
  3mod color;
  4mod display_linker;
  5mod element;
  6mod elements;
  7mod executor;
  8mod geometry;
  9mod image_cache;
 10mod platform;
 11mod scene;
 12mod style;
 13mod style_helpers;
 14mod styled;
 15mod svg_renderer;
 16mod taffy;
 17mod text_system;
 18mod util;
 19mod view;
 20mod window;
 21
 22pub use anyhow::Result;
 23pub use app::*;
 24pub use assets::*;
 25pub use color::*;
 26pub use display_linker::*;
 27pub use element::*;
 28pub use elements::*;
 29pub use executor::*;
 30pub use geometry::*;
 31pub use gpui3_macros::*;
 32pub use image_cache::*;
 33pub use platform::*;
 34pub use refineable::*;
 35pub use scene::*;
 36pub use serde;
 37pub use serde_json;
 38pub use smallvec;
 39pub use smol::Timer;
 40use std::{
 41    mem,
 42    ops::{Deref, DerefMut},
 43    sync::Arc,
 44};
 45pub use style::*;
 46pub use style_helpers::*;
 47pub use styled::*;
 48pub use svg_renderer::*;
 49use taffy::TaffyLayoutEngine;
 50pub use taffy::{AvailableSpace, LayoutId};
 51pub use text_system::*;
 52pub use util::arc_cow::ArcCow;
 53pub use view::*;
 54pub use window::*;
 55
 56pub trait Context {
 57    type EntityContext<'a, 'w, T: 'static + Send + Sync>;
 58    type Result<T>;
 59
 60    fn entity<T: Send + Sync + 'static>(
 61        &mut self,
 62        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 63    ) -> Self::Result<Handle<T>>;
 64
 65    fn update_entity<T: Send + Sync + 'static, R>(
 66        &mut self,
 67        handle: &Handle<T>,
 68        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
 69    ) -> Self::Result<R>;
 70}
 71
 72#[repr(transparent)]
 73pub struct MainThread<T>(T);
 74
 75impl<T> Deref for MainThread<T> {
 76    type Target = T;
 77
 78    fn deref(&self) -> &Self::Target {
 79        &self.0
 80    }
 81}
 82
 83impl<T> DerefMut for MainThread<T> {
 84    fn deref_mut(&mut self) -> &mut Self::Target {
 85        &mut self.0
 86    }
 87}
 88
 89impl<C: Context> Context for MainThread<C> {
 90    type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread<C::EntityContext<'a, 'w, T>>;
 91    type Result<T> = C::Result<T>;
 92
 93    fn entity<T: Send + Sync + 'static>(
 94        &mut self,
 95        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 96    ) -> Self::Result<Handle<T>> {
 97        self.0.entity(|cx| {
 98            let cx = unsafe {
 99                mem::transmute::<
100                    &mut C::EntityContext<'_, '_, T>,
101                    &mut MainThread<C::EntityContext<'_, '_, T>>,
102                >(cx)
103            };
104            build_entity(cx)
105        })
106    }
107
108    fn update_entity<T: Send + Sync + 'static, R>(
109        &mut self,
110        handle: &Handle<T>,
111        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
112    ) -> Self::Result<R> {
113        self.0.update_entity(handle, |entity, cx| {
114            let cx = unsafe {
115                mem::transmute::<
116                    &mut C::EntityContext<'_, '_, T>,
117                    &mut MainThread<C::EntityContext<'_, '_, T>>,
118                >(cx)
119            };
120            update(entity, cx)
121        })
122    }
123}
124
125pub trait BorrowAppContext {
126    fn app_mut(&mut self) -> &mut AppContext;
127
128    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
129    where
130        F: FnOnce(&mut Self) -> R,
131    {
132        self.app_mut().push_text_style(style);
133        let result = f(self);
134        self.app_mut().pop_text_style();
135        result
136    }
137
138    fn with_state<T: Send + Sync + 'static, F, R>(&mut self, state: T, f: F) -> R
139    where
140        F: FnOnce(&mut Self) -> R,
141    {
142        self.app_mut().push_state(state);
143        let result = f(self);
144        self.app_mut().pop_state::<T>();
145        result
146    }
147}
148
149pub trait Flatten<T> {
150    fn flatten(self) -> Result<T>;
151}
152
153impl<T> Flatten<T> for Result<Result<T>> {
154    fn flatten(self) -> Result<T> {
155        self?
156    }
157}
158
159impl<T> Flatten<T> for Result<T> {
160    fn flatten(self) -> Result<T> {
161        self
162    }
163}
164
165#[derive(Clone, Eq, PartialEq, Hash)]
166pub struct SharedString(ArcCow<'static, str>);
167
168impl Default for SharedString {
169    fn default() -> Self {
170        Self(ArcCow::Owned("".into()))
171    }
172}
173
174impl AsRef<str> for SharedString {
175    fn as_ref(&self) -> &str {
176        &self.0
177    }
178}
179
180impl std::fmt::Debug for SharedString {
181    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182        self.0.fmt(f)
183    }
184}
185
186impl std::fmt::Display for SharedString {
187    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188        write!(f, "{}", self.0.as_ref())
189    }
190}
191
192impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
193    fn from(value: T) -> Self {
194        Self(value.into())
195    }
196}
197
198pub enum Reference<'a, T> {
199    Immutable(&'a T),
200    Mutable(&'a mut T),
201}
202
203impl<'a, T> Deref for Reference<'a, T> {
204    type Target = T;
205
206    fn deref(&self) -> &Self::Target {
207        match self {
208            Reference::Immutable(target) => target,
209            Reference::Mutable(target) => target,
210        }
211    }
212}
213
214impl<'a, T> DerefMut for Reference<'a, T> {
215    fn deref_mut(&mut self) -> &mut Self::Target {
216        match self {
217            Reference::Immutable(_) => {
218                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
219            }
220            Reference::Mutable(target) => target,
221        }
222    }
223}
224
225pub(crate) struct MainThreadOnly<T: ?Sized> {
226    executor: Executor,
227    value: Arc<T>,
228}
229
230impl<T: ?Sized> Clone for MainThreadOnly<T> {
231    fn clone(&self) -> Self {
232        Self {
233            executor: self.executor.clone(),
234            value: self.value.clone(),
235        }
236    }
237}
238
239/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
240/// to become `Send`.
241impl<T: 'static + ?Sized> MainThreadOnly<T> {
242    pub(crate) fn new(value: Arc<T>, executor: Executor) -> Self {
243        Self { executor, value }
244    }
245
246    pub(crate) fn borrow_on_main_thread(&self) -> &T {
247        assert!(self.executor.is_main_thread());
248        &self.value
249    }
250}
251
252unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}