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