gpui3.rs

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