gpui3.rs

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