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