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