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