1use std::cell::{Cell, RefCell, RefMut};
2use std::collections::hash_map::DefaultHasher;
3use std::future::Future;
4use std::hash::{Hash, Hasher};
5use std::ops::{Deref, DerefMut};
6use std::ptr::null_mut;
7use std::task::Poll;
8
9use futures::{FutureExt, Stream, StreamExt};
10
11use crate::bitset::BitSet;
12use crate::component::{Component, Context};
13use crate::draw::Primitive;
14use crate::event::Event;
15use crate::layout::{Rectangle, Size};
16use crate::node::{GenericNode, Node};
17use crate::style::tree::Query;
18use crate::tracker::{ManagedState, ManagedStateTracker};
19use crate::widget::Context as WidgetContext;
20
21pub struct ComponentNode<'a, C: 'a + Component> {
22 props: Box<C>,
23 state: RefCell<Option<&'a mut ManagedState>>,
24 view: RefCell<Option<Node<'a, C::Message>>>,
25 component_state: Cell<*mut (C::State, Runtime<C::Message>)>,
26 style_query: Option<Query>,
27 style_position: (usize, usize),
28 style_matches: BitSet,
29 key: u64,
30}
31
32pub struct Runtime<Message> {
33 futures: Vec<Box<dyn Future<Output = Message> + Send + Sync + Unpin>>,
34 streams: Vec<Box<dyn Stream<Item = Message> + Send + Sync + Unpin>>,
35 modified: bool,
36}
37
38pub struct State<'a, T> {
41 inner: &'a mut T,
42 dirty: &'a mut bool,
43}
44
45impl<'a, C: 'a + Component> ComponentNode<'a, C> {
46 pub fn new(props: C) -> Self {
47 let mut hasher = DefaultHasher::new();
48 std::any::type_name::<C>().hash(&mut hasher);
49 Self {
50 props: Box::new(props),
51 state: RefCell::new(None),
52 view: RefCell::new(None),
53 component_state: Cell::new(null_mut()),
54 style_query: None,
55 style_position: (0, 1),
56 style_matches: BitSet::new(),
57 key: hasher.finish(),
58 }
59 }
60
61 pub fn dirty(&self) -> bool {
62 self.view.borrow().is_none()
63 }
64
65 pub fn set_dirty(&self) {
66 self.view.replace(None);
67 }
68
69 pub fn props(&self) -> &C {
70 self.props.as_ref()
71 }
72
73 pub fn props_mut(&mut self) -> &mut C {
74 self.set_dirty();
75 self.props.as_mut()
76 }
77
78 pub fn update(&mut self, message: C::Message, context: &mut WidgetContext<C::Output>) {
79 let mut dirty = false;
80
81 let (state, runtime) = unsafe { self.component_state.get().as_mut().unwrap() };
82
83 self.props.update(
84 message,
85 State {
86 inner: state,
87 dirty: &mut dirty,
88 },
89 Context::new(context, runtime),
90 );
91
92 if dirty {
93 self.set_dirty();
94 }
95 }
96
97 pub fn view(&self) -> RefMut<Node<'a, C::Message>> {
98 if self.dirty() {
99 let mut tracker = unsafe {
100 self.state
101 .borrow_mut()
102 .as_mut()
103 .map(|s| (*s) as *mut ManagedState)
104 .unwrap_or(null_mut())
105 .as_mut()
106 .unwrap()
107 .tracker()
108 };
109
110 let state = tracker.begin(0, || (self.props.mount(), Runtime::default()));
111 self.component_state.set(state as *mut _);
112
113 let mut root = unsafe { (self.props.as_ref() as *const C).as_ref().unwrap() }.view(&state.0);
114 let mut query = self.style_query.clone().unwrap();
115 root.acquire_state(&mut tracker);
116 root.style(&mut query, self.style_position);
117
118 self.view.replace(Some(root));
119 }
120 RefMut::map(self.view.borrow_mut(), |b| b.as_mut().unwrap())
121 }
122
123 pub(crate) fn needs_poll(&self) -> bool {
124 let (_, runtime) = unsafe { self.component_state.get().as_mut().unwrap() };
125 runtime.modified
126 }
127}
128
129impl<'a, C: 'a + Component> GenericNode<'a, C::Output> for ComponentNode<'a, C> {
130 fn get_key(&self) -> u64 {
131 self.key
132 }
133
134 fn set_key(&mut self, key: u64) {
135 self.key = key;
136 }
137
138 fn set_class(&mut self, _: &'a str) {}
139
140 fn acquire_state(&mut self, tracker: &mut ManagedStateTracker<'a>) {
141 self.state
142 .replace(Some(tracker.begin::<ManagedState, _>(self.key, ManagedState::default)));
143 tracker.end();
144 }
145
146 fn size(&self) -> (Size, Size) {
147 self.view().size()
148 }
149
150 fn hit(&self, layout: Rectangle, clip: Rectangle, x: f32, y: f32) -> bool {
151 self.view().hit(layout, clip, x, y)
152 }
153
154 fn focused(&self) -> bool {
155 self.view().focused()
156 }
157
158 fn draw(&mut self, layout: Rectangle, clip: Rectangle) -> Vec<Primitive<'a>> {
159 self.view().draw(layout, clip)
160 }
161
162 fn style(&mut self, query: &mut Query, position: (usize, usize)) {
163 self.style_matches = query.match_widget::<String>(
164 std::any::type_name::<C>(),
165 "",
166 &[],
167 self.style_position.0,
168 self.style_position.1,
169 );
170 self.style_query = Some(Query {
171 style: query.style.clone(),
172 ancestors: {
173 let mut a = query.ancestors.clone();
174 a.push(self.style_matches.clone());
175 a
176 },
177 siblings: Vec::new(),
178 });
179 self.style_position = position;
180
181 self.set_dirty();
182
183 query.siblings.push(self.style_matches.clone());
184 }
185
186 fn add_matches(&mut self, query: &mut Query) {
187 let additions = query.match_widget::<String>(
188 std::any::type_name::<C>(),
189 "",
190 &[],
191 self.style_position.0,
192 self.style_position.1,
193 );
194
195 let new_style = self.style_matches.union(&additions);
196 if new_style != self.style_matches {
197 self.style_matches = new_style;
198 }
199
200 query.ancestors.push(additions);
201 let own_siblings = std::mem::take(&mut query.siblings);
202 self.view().add_matches(query);
203 query.siblings = own_siblings;
204 query.siblings.push(query.ancestors.pop().unwrap());
205 }
206
207 fn remove_matches(&mut self, query: &mut Query) {
208 let removals = query.match_widget::<String>(
209 std::any::type_name::<C>(),
210 "",
211 &[],
212 self.style_position.0,
213 self.style_position.1,
214 );
215
216 let new_style = self.style_matches.difference(&removals);
217 if new_style != self.style_matches {
218 self.style_matches = new_style;
219 }
220
221 query.ancestors.push(removals);
222 let own_siblings = std::mem::take(&mut query.siblings);
223 self.view().remove_matches(query);
224 query.siblings = own_siblings;
225 query.siblings.push(query.ancestors.pop().unwrap());
226 }
227
228 fn event(
229 &mut self,
230 layout: Rectangle,
231 clip: Rectangle,
232 event: Event,
233 context: &mut WidgetContext<<C as Component>::Output>,
234 ) {
235 let mut sub_context = context.sub_context();
236 self.view().event(layout, clip, event, &mut sub_context);
237
238 if sub_context.redraw_requested() {
239 context.redraw();
240 }
241
242 for message in sub_context {
243 self.update(message, context);
244 }
245
246 let (_, runtime) = unsafe { self.component_state.get().as_mut().unwrap() };
247 while runtime.modified {
248 for message in runtime.poll(&mut context.task_context()) {
249 self.update(message, context);
250 }
251 }
252 }
253
254 fn poll(&mut self, context: &mut WidgetContext<<C as Component>::Output>) {
255 let mut sub_context = context.sub_context();
256 self.view().poll(&mut sub_context);
257
258 if sub_context.redraw_requested() {
259 context.redraw();
260 }
261
262 for message in sub_context {
263 self.update(message, context);
264 }
265
266 let (_, runtime) = unsafe { self.component_state.get().as_mut().unwrap() };
267 loop {
268 for message in runtime.poll(&mut context.task_context()) {
269 self.update(message, context);
270 }
271 if !runtime.modified {
272 break;
273 }
274 }
275 }
276}
277
278unsafe impl<'a, C: 'a + Component> Send for ComponentNode<'a, C> {}
279
280impl<'a, C: 'a + Component> Drop for ComponentNode<'a, C> {
281 fn drop(&mut self) {
282 self.view.replace(None);
283 }
284}
285
286impl<Message> Default for Runtime<Message> {
287 fn default() -> Self {
288 Self {
289 futures: Vec::new(),
290 streams: Vec::new(),
291 modified: false,
292 }
293 }
294}
295
296impl<Message> Runtime<Message> {
297 pub fn wait<F: 'static + Future<Output = Message> + Send + Sync + Unpin>(&mut self, fut: F) {
298 self.futures.push(Box::new(fut));
299 self.modified = true;
300 }
301
302 pub fn stream<S: 'static + Stream<Item = Message> + Send + Sync + Unpin>(&mut self, stream: S) {
303 self.streams.push(Box::new(stream));
304 self.modified = true;
305 }
306
307 pub(crate) fn poll(&mut self, cx: &mut std::task::Context) -> Vec<Message> {
308 self.modified = false;
309
310 let mut result = Vec::new();
311
312 let mut i = 0;
313 while i < self.futures.len() {
314 match self.futures[i].poll_unpin(&mut *cx) {
315 Poll::Ready(message) => {
316 result.push(message);
317 drop(self.futures.remove(i));
318 }
319 Poll::Pending => {
320 i += 1;
321 }
322 }
323 }
324
325 let mut i = 0;
326 while i < self.streams.len() {
327 match self.streams[i].poll_next_unpin(&mut *cx) {
328 Poll::Ready(Some(message)) => {
329 result.push(message);
330 }
331 Poll::Ready(None) => {
332 drop(self.streams.remove(i));
333 }
334 Poll::Pending => {
335 i += 1;
336 }
337 }
338 }
339
340 result
341 }
342}
343
344impl<'a, T> Deref for State<'a, T> {
345 type Target = T;
346
347 fn deref(&self) -> &T {
348 self.inner
349 }
350}
351
352impl<'a, T> DerefMut for State<'a, T> {
353 fn deref_mut(&mut self) -> &mut T {
354 *self.dirty = true;
355 self.inner
356 }
357}