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