gpui2.rs

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