gpui3.rs

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