1use alloc::{boxed::Box, vec::Vec};
2use core::{
3 any::{Any, TypeId},
4 borrow::Borrow,
5};
6
7use crate::{event::Event, render::Renderer, widget::Widget};
8
9pub enum State {
12 None,
13 Some(Box<dyn Any>),
14}
15
16impl State {
17 pub fn new<T: 'static>(state: T) -> Self {
18 Self::Some(Box::new(state))
19 }
20
21 pub fn downcast_ref<T: 'static>(&self) -> &T {
22 match self {
23 State::None => panic!("Downcast of stateless state"),
24 State::Some(state) => state.downcast_ref().expect("Downcast state"),
25 }
26 }
27
28 pub fn downcast_mut<T: 'static>(&mut self) -> &mut T {
29 match self {
30 State::None => panic!("Downcast of stateless state"),
31 State::Some(state) => state.downcast_mut().expect("Downcast mut state"),
32 }
33 }
34
35 pub fn reset<T: 'static>(&mut self)
36 where
37 T: Default,
38 {
39 match self {
40 State::None => panic!("Reset of stateless state"),
41 State::Some(state) => {
42 *state.downcast_mut::<T>().expect("Downcast reset state") = T::default();
43 },
44 }
45 }
46}
47
48#[derive(Clone, Copy, PartialEq)]
49pub struct StateTag(pub TypeId);
50
51impl StateTag {
52 pub fn stateless() -> Self {
53 Self::of::<()>()
54 }
55
56 pub fn of<T: 'static>() -> Self {
57 Self(TypeId::of::<T>())
58 }
59}
60
61pub struct StateNode {
62 pub tag: StateTag,
63 pub state: State,
64 pub children: Vec<StateNode>,
65}
66
67impl StateNode {
68 pub fn stateless() -> Self {
69 Self { tag: StateTag::stateless(), state: State::None, children: vec![] }
70 }
71
72 pub fn new<'a, Message, R: Renderer, E: Event, S>(
73 widget: impl Borrow<dyn Widget<Message, R, E, S> + 'a>,
74 ) -> Self {
75 let widget = widget.borrow();
76
77 Self { tag: widget.state_tag(), state: widget.state(), children: widget.state_children() }
78 }
79
80 pub fn get<T: 'static>(&self) -> &T {
81 self.state.downcast_ref()
82 }
83
84 pub fn get_mut<T: 'static>(&mut self) -> &mut T {
85 self.state.downcast_mut()
86 }
87
88 pub fn reset<T: 'static>(&mut self)
89 where
90 T: Default,
91 {
92 self.state.reset::<T>()
93 }
94}