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