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