gpui3.rs

  1mod app;
  2mod color;
  3mod element;
  4mod elements;
  5mod executor;
  6mod geometry;
  7mod platform;
  8mod scene;
  9mod style;
 10mod style_helpers;
 11mod styled;
 12mod taffy;
 13mod text_system;
 14mod util;
 15mod view;
 16mod window;
 17
 18pub use anyhow::Result;
 19pub use app::*;
 20pub use color::*;
 21pub use element::*;
 22pub use elements::*;
 23pub use executor::*;
 24pub use geometry::*;
 25pub use gpui3_macros::*;
 26pub use platform::*;
 27pub use refineable::*;
 28pub use scene::*;
 29pub use serde;
 30pub use serde_json;
 31pub use smallvec;
 32pub use smol::Timer;
 33use std::{
 34    future::Future,
 35    ops::{Deref, DerefMut},
 36    sync::Arc,
 37};
 38pub use style::*;
 39pub use style_helpers::*;
 40pub use styled::*;
 41use taffy::TaffyLayoutEngine;
 42pub use taffy::{AvailableSpace, LayoutId};
 43pub use text_system::*;
 44pub use util::arc_cow::ArcCow;
 45pub use view::*;
 46pub use window::*;
 47
 48pub trait Context {
 49    type EntityContext<'a, 'w, T: Send + 'static>;
 50
 51    fn entity<T: 'static + Send>(
 52        &mut self,
 53        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 54    ) -> Handle<T>;
 55
 56    fn update_entity<T: 'static + Send, R>(
 57        &mut self,
 58        handle: &Handle<T>,
 59        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
 60    ) -> R;
 61}
 62
 63#[derive(Clone, Eq, PartialEq)]
 64pub struct SharedString(ArcCow<'static, str>);
 65
 66impl Default for SharedString {
 67    fn default() -> Self {
 68        Self(ArcCow::Owned("".into()))
 69    }
 70}
 71
 72impl AsRef<str> for SharedString {
 73    fn as_ref(&self) -> &str {
 74        &self.0
 75    }
 76}
 77
 78impl std::fmt::Debug for SharedString {
 79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 80        self.0.fmt(f)
 81    }
 82}
 83
 84impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
 85    fn from(value: T) -> Self {
 86        Self(value.into())
 87    }
 88}
 89
 90pub enum Reference<'a, T> {
 91    Immutable(&'a T),
 92    Mutable(&'a mut T),
 93}
 94
 95impl<'a, T> Deref for Reference<'a, T> {
 96    type Target = T;
 97
 98    fn deref(&self) -> &Self::Target {
 99        match self {
100            Reference::Immutable(target) => target,
101            Reference::Mutable(target) => target,
102        }
103    }
104}
105
106impl<'a, T> DerefMut for Reference<'a, T> {
107    fn deref_mut(&mut self) -> &mut Self::Target {
108        match self {
109            Reference::Immutable(_) => {
110                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
111            }
112            Reference::Mutable(target) => target,
113        }
114    }
115}
116
117pub(crate) struct MainThreadOnly<T: ?Sized> {
118    dispatcher: Arc<dyn PlatformDispatcher>,
119    value: Arc<T>,
120}
121
122impl<T: ?Sized> Clone for MainThreadOnly<T> {
123    fn clone(&self) -> Self {
124        Self {
125            dispatcher: self.dispatcher.clone(),
126            value: self.value.clone(),
127        }
128    }
129}
130
131/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
132/// to become `Send`.
133impl<T: 'static + ?Sized> MainThreadOnly<T> {
134    pub(crate) fn new(value: Arc<T>, dispatcher: Arc<dyn PlatformDispatcher>) -> Self {
135        Self { dispatcher, value }
136    }
137
138    pub(crate) fn borrow_on_main_thread(&self) -> &T {
139        assert!(self.dispatcher.is_main_thread());
140        &self.value
141    }
142
143    pub(crate) fn read<R, F>(
144        &self,
145        f: impl FnOnce(&T) -> F + Send + 'static,
146    ) -> impl Future<Output = R>
147    where
148        F: Future<Output = R> + 'static,
149        R: Send + 'static,
150    {
151        let this = self.clone();
152        crate::spawn_on_main(self.dispatcher.clone(), || async move {
153            // Required so we move `this` instead of this.value. Only `this` is `Send`.
154            let this = this;
155            let result = f(&this.value);
156            result.await
157        })
158    }
159}
160
161unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}