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