gpui3.rs

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