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