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,
 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 app_mut(&mut self) -> &mut AppContext;
150
151    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
152    where
153        F: FnOnce(&mut Self) -> R,
154    {
155        self.app_mut().push_text_style(style);
156        let result = f(self);
157        self.app_mut().pop_text_style();
158        result
159    }
160
161    fn set_global<G: Any + Send + Sync>(&mut self, global: G) {
162        self.app_mut().set_global(global)
163    }
164}
165
166pub trait EventEmitter: 'static {
167    type Event: Any;
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 Borrow<str> for SharedString {
202    fn borrow(&self) -> &str {
203        self.as_ref()
204    }
205}
206
207impl std::fmt::Debug for SharedString {
208    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
209        self.0.fmt(f)
210    }
211}
212
213impl std::fmt::Display for SharedString {
214    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215        write!(f, "{}", self.0.as_ref())
216    }
217}
218
219impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
220    fn from(value: T) -> Self {
221        Self(value.into())
222    }
223}
224
225pub enum Reference<'a, T> {
226    Immutable(&'a T),
227    Mutable(&'a mut T),
228}
229
230impl<'a, T> Deref for Reference<'a, T> {
231    type Target = T;
232
233    fn deref(&self) -> &Self::Target {
234        match self {
235            Reference::Immutable(target) => target,
236            Reference::Mutable(target) => target,
237        }
238    }
239}
240
241impl<'a, T> DerefMut for Reference<'a, T> {
242    fn deref_mut(&mut self) -> &mut Self::Target {
243        match self {
244            Reference::Immutable(_) => {
245                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
246            }
247            Reference::Mutable(target) => target,
248        }
249    }
250}
251
252pub(crate) struct MainThreadOnly<T: ?Sized> {
253    executor: Executor,
254    value: Arc<T>,
255}
256
257impl<T: ?Sized> Clone for MainThreadOnly<T> {
258    fn clone(&self) -> Self {
259        Self {
260            executor: self.executor.clone(),
261            value: self.value.clone(),
262        }
263    }
264}
265
266/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
267/// to become `Send`.
268impl<T: 'static + ?Sized> MainThreadOnly<T> {
269    pub(crate) fn new(value: Arc<T>, executor: Executor) -> Self {
270        Self { executor, value }
271    }
272
273    pub(crate) fn borrow_on_main_thread(&self) -> &T {
274        assert!(self.executor.is_main_thread());
275        &self.value
276    }
277}
278
279unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}