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> {}