1mod app;
2mod color;
3mod element;
4mod elements;
5mod executor;
6mod geometry;
7mod platform;
8mod scene;
9mod style;
10mod style_helpers;
11mod styled;
12mod taffy;
13mod text_system;
14mod util;
15mod view;
16mod window;
17
18pub use anyhow::Result;
19pub use app::*;
20pub use color::*;
21pub use element::*;
22pub use elements::*;
23pub use executor::*;
24pub use geometry::*;
25pub use gpui3_macros::*;
26pub use platform::*;
27pub use refineable::*;
28pub use scene::*;
29pub use serde;
30pub use serde_json;
31pub use smallvec;
32pub use smol::Timer;
33use std::{
34 future::Future,
35 ops::{Deref, DerefMut},
36 sync::Arc,
37};
38pub use style::*;
39pub use style_helpers::*;
40pub use styled::*;
41use taffy::TaffyLayoutEngine;
42pub use taffy::{AvailableSpace, LayoutId};
43pub use text_system::*;
44pub use util::arc_cow::ArcCow;
45pub use view::*;
46pub use window::*;
47
48pub trait Context {
49 type EntityContext<'a, 'w, T: Send + 'static>;
50
51 fn entity<T: 'static + Send>(
52 &mut self,
53 build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
54 ) -> Handle<T>;
55
56 fn update_entity<T: 'static + Send, R>(
57 &mut self,
58 handle: &Handle<T>,
59 update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
60 ) -> R;
61}
62
63#[derive(Clone, Eq, PartialEq)]
64pub struct SharedString(ArcCow<'static, str>);
65
66impl Default for SharedString {
67 fn default() -> Self {
68 Self(ArcCow::Owned("".into()))
69 }
70}
71
72impl AsRef<str> for SharedString {
73 fn as_ref(&self) -> &str {
74 &self.0
75 }
76}
77
78impl std::fmt::Debug for SharedString {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 self.0.fmt(f)
81 }
82}
83
84impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
85 fn from(value: T) -> Self {
86 Self(value.into())
87 }
88}
89
90pub enum Reference<'a, T> {
91 Immutable(&'a T),
92 Mutable(&'a mut T),
93}
94
95impl<'a, T> Deref for Reference<'a, T> {
96 type Target = T;
97
98 fn deref(&self) -> &Self::Target {
99 match self {
100 Reference::Immutable(target) => target,
101 Reference::Mutable(target) => target,
102 }
103 }
104}
105
106impl<'a, T> DerefMut for Reference<'a, T> {
107 fn deref_mut(&mut self) -> &mut Self::Target {
108 match self {
109 Reference::Immutable(_) => {
110 panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
111 }
112 Reference::Mutable(target) => target,
113 }
114 }
115}
116
117pub(crate) struct MainThreadOnly<T: ?Sized> {
118 dispatcher: Arc<dyn PlatformDispatcher>,
119 value: Arc<T>,
120}
121
122impl<T: ?Sized> Clone for MainThreadOnly<T> {
123 fn clone(&self) -> Self {
124 Self {
125 dispatcher: self.dispatcher.clone(),
126 value: self.value.clone(),
127 }
128 }
129}
130
131/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
132/// to become `Send`.
133impl<T: 'static + ?Sized> MainThreadOnly<T> {
134 pub(crate) fn new(value: Arc<T>, dispatcher: Arc<dyn PlatformDispatcher>) -> Self {
135 Self { dispatcher, value }
136 }
137
138 pub(crate) fn borrow_on_main_thread(&self) -> &T {
139 assert!(self.dispatcher.is_main_thread());
140 &self.value
141 }
142
143 pub(crate) fn read<R, F>(
144 &self,
145 f: impl FnOnce(&T) -> F + Send + 'static,
146 ) -> impl Future<Output = R>
147 where
148 F: Future<Output = R> + 'static,
149 R: Send + 'static,
150 {
151 let this = self.clone();
152 crate::spawn_on_main(self.dispatcher.clone(), || async move {
153 // Required so we move `this` instead of this.value. Only `this` is `Send`.
154 let this = this;
155 let result = f(&this.value);
156 result.await
157 })
158 }
159}
160
161unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}