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 + Sync + 'static>;
 50    type Result<T>;
 51
 52    fn entity<T: Send + Sync + 'static>(
 53        &mut self,
 54        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 55    ) -> Self::Result<Handle<T>>;
 56
 57    fn update_entity<T: Send + Sync + 'static, R>(
 58        &mut self,
 59        handle: &Handle<T>,
 60        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
 61    ) -> Self::Result<R>;
 62}
 63
 64pub trait Flatten<T> {
 65    fn flatten(self) -> Result<T>;
 66}
 67
 68impl<T> Flatten<T> for Result<Result<T>> {
 69    fn flatten(self) -> Result<T> {
 70        self?
 71    }
 72}
 73
 74impl<T> Flatten<T> for Result<T> {
 75    fn flatten(self) -> Result<T> {
 76        self
 77    }
 78}
 79
 80#[derive(Clone, Eq, PartialEq, Hash)]
 81pub struct SharedString(ArcCow<'static, str>);
 82
 83impl Default for SharedString {
 84    fn default() -> Self {
 85        Self(ArcCow::Owned("".into()))
 86    }
 87}
 88
 89impl AsRef<str> for SharedString {
 90    fn as_ref(&self) -> &str {
 91        &self.0
 92    }
 93}
 94
 95impl std::fmt::Debug for SharedString {
 96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 97        self.0.fmt(f)
 98    }
 99}
100
101impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
102    fn from(value: T) -> Self {
103        Self(value.into())
104    }
105}
106
107pub enum Reference<'a, T> {
108    Immutable(&'a T),
109    Mutable(&'a mut T),
110}
111
112impl<'a, T> Deref for Reference<'a, T> {
113    type Target = T;
114
115    fn deref(&self) -> &Self::Target {
116        match self {
117            Reference::Immutable(target) => target,
118            Reference::Mutable(target) => target,
119        }
120    }
121}
122
123impl<'a, T> DerefMut for Reference<'a, T> {
124    fn deref_mut(&mut self) -> &mut Self::Target {
125        match self {
126            Reference::Immutable(_) => {
127                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
128            }
129            Reference::Mutable(target) => target,
130        }
131    }
132}
133
134pub(crate) struct MainThreadOnly<T: ?Sized> {
135    dispatcher: Arc<dyn PlatformDispatcher>,
136    value: Arc<T>,
137}
138
139impl<T: ?Sized> Clone for MainThreadOnly<T> {
140    fn clone(&self) -> Self {
141        Self {
142            dispatcher: self.dispatcher.clone(),
143            value: self.value.clone(),
144        }
145    }
146}
147
148/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
149/// to become `Send`.
150impl<T: 'static + ?Sized> MainThreadOnly<T> {
151    pub(crate) fn new(value: Arc<T>, dispatcher: Arc<dyn PlatformDispatcher>) -> Self {
152        Self { dispatcher, value }
153    }
154
155    pub(crate) fn borrow_on_main_thread(&self) -> &T {
156        assert!(self.dispatcher.is_main_thread());
157        &self.value
158    }
159
160    pub(crate) fn read<R, F>(
161        &self,
162        f: impl FnOnce(&T) -> F + Send + 'static,
163    ) -> impl Future<Output = R>
164    where
165        F: Future<Output = R> + 'static,
166        R: Send + 'static,
167    {
168        let this = self.clone();
169        crate::spawn_on_main(self.dispatcher.clone(), || async move {
170            // Required so we move `this` instead of this.value. Only `this` is `Send`.
171            let this = this;
172            let result = f(&this.value);
173            result.await
174        })
175    }
176}
177
178unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}