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>;
 71
 72pub trait Context {
 73    type EntityContext<'a, 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;
 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 trait VisualContext: Context {
 91    type ViewContext<'a, 'w, V>;
 92
 93    fn build_view<E, V>(
 94        &mut self,
 95        build_entity: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
 96        render: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + 'static,
 97    ) -> Self::Result<View<V>>
 98    where
 99        E: Component<V>,
100        V: 'static + Send;
101
102    fn update_view<V: 'static, R>(
103        &mut self,
104        view: &View<V>,
105        update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, '_, V>) -> R,
106    ) -> Self::Result<R>;
107}
108
109pub trait EntityHandle<T> {
110    type Weak: 'static + Send;
111
112    fn entity_id(&self) -> EntityId;
113    fn downgrade(&self) -> Self::Weak;
114    fn upgrade_from(weak: &Self::Weak) -> Option<Self>
115    where
116        Self: Sized;
117}
118
119pub enum GlobalKey {
120    Numeric(usize),
121    View(EntityId),
122    Type(TypeId),
123}
124
125#[repr(transparent)]
126pub struct MainThread<T>(T);
127
128impl<T> Deref for MainThread<T> {
129    type Target = T;
130
131    fn deref(&self) -> &Self::Target {
132        &self.0
133    }
134}
135
136impl<T> DerefMut for MainThread<T> {
137    fn deref_mut(&mut self) -> &mut Self::Target {
138        &mut self.0
139    }
140}
141
142impl<C: Context> Context for MainThread<C> {
143    type EntityContext<'a, T> = MainThread<C::EntityContext<'a, T>>;
144    type Result<T> = C::Result<T>;
145
146    fn entity<T>(
147        &mut self,
148        build_entity: impl FnOnce(&mut Self::EntityContext<'_, T>) -> T,
149    ) -> Self::Result<Handle<T>>
150    where
151        T: 'static + Send,
152    {
153        self.0.entity(|cx| {
154            let cx = unsafe {
155                mem::transmute::<
156                    &mut C::EntityContext<'_, T>,
157                    &mut MainThread<C::EntityContext<'_, T>>,
158                >(cx)
159            };
160            build_entity(cx)
161        })
162    }
163
164    fn update_entity<T: 'static, R>(
165        &mut self,
166        handle: &Handle<T>,
167        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, T>) -> R,
168    ) -> Self::Result<R> {
169        self.0.update_entity(handle, |entity, cx| {
170            let cx = unsafe {
171                mem::transmute::<
172                    &mut C::EntityContext<'_, T>,
173                    &mut MainThread<C::EntityContext<'_, T>>,
174                >(cx)
175            };
176            update(entity, cx)
177        })
178    }
179}
180
181impl<C: VisualContext> VisualContext for MainThread<C> {
182    type ViewContext<'a, 'w, V> = MainThread<C::ViewContext<'a, 'w, V>>;
183
184    fn build_view<E, V>(
185        &mut self,
186        build_entity: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
187        render: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + 'static,
188    ) -> Self::Result<View<V>>
189    where
190        E: Component<V>,
191        V: 'static + Send,
192    {
193        self.0.build_view(
194            |cx| {
195                let cx = unsafe {
196                    mem::transmute::<
197                        &mut C::ViewContext<'_, '_, V>,
198                        &mut MainThread<C::ViewContext<'_, '_, V>>,
199                    >(cx)
200                };
201                build_entity(cx)
202            },
203            render,
204        )
205    }
206
207    fn update_view<V: 'static, R>(
208        &mut self,
209        view: &View<V>,
210        update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, '_, V>) -> R,
211    ) -> Self::Result<R> {
212        self.0.update_view(view, |view_state, cx| {
213            let cx = unsafe {
214                mem::transmute::<
215                    &mut C::ViewContext<'_, '_, V>,
216                    &mut MainThread<C::ViewContext<'_, '_, V>>,
217                >(cx)
218            };
219            update(view_state, cx)
220        })
221    }
222}
223
224pub trait BorrowAppContext {
225    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
226    where
227        F: FnOnce(&mut Self) -> R;
228
229    fn set_global<T: Send + 'static>(&mut self, global: T);
230}
231
232impl<C> BorrowAppContext for C
233where
234    C: BorrowMut<AppContext>,
235{
236    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
237    where
238        F: FnOnce(&mut Self) -> R,
239    {
240        self.borrow_mut().push_text_style(style);
241        let result = f(self);
242        self.borrow_mut().pop_text_style();
243        result
244    }
245
246    fn set_global<G: 'static + Send>(&mut self, global: G) {
247        self.borrow_mut().set_global(global)
248    }
249}
250
251pub trait EventEmitter: 'static {
252    type Event: Any;
253}
254
255pub trait Flatten<T> {
256    fn flatten(self) -> Result<T>;
257}
258
259impl<T> Flatten<T> for Result<Result<T>> {
260    fn flatten(self) -> Result<T> {
261        self?
262    }
263}
264
265impl<T> Flatten<T> for Result<T> {
266    fn flatten(self) -> Result<T> {
267        self
268    }
269}
270
271#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
272pub struct SharedString(ArcCow<'static, str>);
273
274impl Default for SharedString {
275    fn default() -> Self {
276        Self(ArcCow::Owned("".into()))
277    }
278}
279
280impl AsRef<str> for SharedString {
281    fn as_ref(&self) -> &str {
282        &self.0
283    }
284}
285
286impl Borrow<str> for SharedString {
287    fn borrow(&self) -> &str {
288        self.as_ref()
289    }
290}
291
292impl std::fmt::Debug for SharedString {
293    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
294        self.0.fmt(f)
295    }
296}
297
298impl std::fmt::Display for SharedString {
299    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
300        write!(f, "{}", self.0.as_ref())
301    }
302}
303
304impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
305    fn from(value: T) -> Self {
306        Self(value.into())
307    }
308}
309
310pub enum Reference<'a, T> {
311    Immutable(&'a T),
312    Mutable(&'a mut T),
313}
314
315impl<'a, T> Deref for Reference<'a, T> {
316    type Target = T;
317
318    fn deref(&self) -> &Self::Target {
319        match self {
320            Reference::Immutable(target) => target,
321            Reference::Mutable(target) => target,
322        }
323    }
324}
325
326impl<'a, T> DerefMut for Reference<'a, T> {
327    fn deref_mut(&mut self) -> &mut Self::Target {
328        match self {
329            Reference::Immutable(_) => {
330                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
331            }
332            Reference::Mutable(target) => target,
333        }
334    }
335}
336
337pub(crate) struct MainThreadOnly<T: ?Sized> {
338    executor: Executor,
339    value: Arc<T>,
340}
341
342impl<T: ?Sized> Clone for MainThreadOnly<T> {
343    fn clone(&self) -> Self {
344        Self {
345            executor: self.executor.clone(),
346            value: self.value.clone(),
347        }
348    }
349}
350
351/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
352/// to become `Send`.
353impl<T: 'static + ?Sized> MainThreadOnly<T> {
354    pub(crate) fn new(value: Arc<T>, executor: Executor) -> Self {
355        Self { executor, value }
356    }
357
358    pub(crate) fn borrow_on_main_thread(&self) -> &T {
359        assert!(self.executor.is_main_thread());
360        &self.value
361    }
362}
363
364unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}