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