gpui3.rs

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