1#![allow(unused)]
29use crate::{
30 context::ContextStack,
31 render::{ComponentDrawer, ComponentUpdater},
32};
33use std::{
34 any::Any,
35 task::{Context, Poll},
36};
37mod use_context;
38pub use use_context::*;
39mod use_input;
40pub use use_input::*;
41mod use_future;
42pub use use_future::*;
43mod use_state;
44pub use use_state::*;
45mod use_memo;
46pub use use_memo::*;
47mod use_effect;
48pub use use_effect::*;
49mod use_async_state;
50pub use use_async_state::*;
51mod use_insert_before;
52pub use use_insert_before::*;
53mod use_size;
54pub use use_size::*;
55mod use_exit;
56pub use use_exit::*;
57mod use_on_drop;
58pub use use_on_drop::*;
59
60#[cfg(feature = "router")]
61mod use_router;
62#[cfg(feature = "router")]
63pub use use_router::*;
64
65pub trait Hook: Unpin {
73 fn poll_change(&mut self, _cx: &mut Context) -> Poll<()> {
74 Poll::Pending
75 }
76
77 fn pre_component_update(&mut self, _updater: &mut ComponentUpdater) {}
78 fn post_component_update(&mut self, _updater: &mut ComponentUpdater) {}
79
80 fn pre_component_draw(&mut self, _drawer: &mut ComponentDrawer) {}
81 fn post_component_draw(&mut self, _drawer: &mut ComponentDrawer) {}
82
83 fn on_drop(&mut self) {}
84}
85
86pub(crate) trait AnyHook: Hook {
87 fn any_self_mut(&mut self) -> &mut dyn Any;
88}
89
90impl<T: Hook + 'static> AnyHook for T {
91 fn any_self_mut(&mut self) -> &mut dyn Any {
92 self
93 }
94}
95
96impl Hook for Vec<Box<dyn AnyHook>> {
97 fn poll_change(&mut self, _cx: &mut Context) -> Poll<()> {
98 let mut is_ready = false;
99 for hook in self.iter_mut() {
100 if hook.poll_change(_cx).is_ready() {
101 is_ready = true;
102 }
103 }
104
105 if is_ready {
106 Poll::Ready(())
107 } else {
108 Poll::Pending
109 }
110 }
111
112 fn pre_component_update(&mut self, _updater: &mut ComponentUpdater) {
113 for hook in self.iter_mut() {
114 hook.pre_component_update(_updater);
115 }
116 }
117
118 fn post_component_update(&mut self, _updater: &mut ComponentUpdater) {
119 for hook in self.iter_mut() {
120 hook.post_component_update(_updater);
121 }
122 }
123
124 fn pre_component_draw(&mut self, _updater: &mut ComponentDrawer) {
125 for hook in self.iter_mut() {
126 hook.pre_component_draw(_updater);
127 }
128 }
129
130 fn post_component_draw(&mut self, _updater: &mut ComponentDrawer) {
131 for hook in self.iter_mut() {
132 hook.post_component_draw(_updater);
133 }
134 }
135
136 fn on_drop(&mut self) {
137 for hook in self.iter_mut() {
138 hook.on_drop();
139 }
140 }
141}
142
143pub struct Hooks<'a, 'b: 'a> {
155 hooks: &'a mut Vec<Box<dyn AnyHook>>,
156 first_update: bool,
157 hook_index: usize,
158 pub(crate) context: Option<&'a ContextStack<'b>>,
159}
160
161impl<'a> Hooks<'a, '_> {
162 pub(crate) fn new(hooks: &'a mut Vec<Box<dyn AnyHook>>, first_update: bool) -> Self {
163 Self {
164 hooks,
165 first_update,
166 hook_index: 0,
167 context: None,
168 }
169 }
170
171 pub fn with_context_stack<'c, 'd>(
172 &'c mut self,
173 context: &'c ContextStack<'d>,
174 ) -> Hooks<'c, 'd> {
175 Hooks {
176 hooks: self.hooks,
177 first_update: self.first_update,
178 hook_index: self.hook_index,
179 context: Some(context),
180 }
181 }
182
183 pub fn use_hook<F, H>(&mut self, f: F) -> &mut H
184 where
185 F: FnOnce() -> H,
186 H: Hook + Unpin + 'static,
187 {
188 if self.first_update {
189 self.hooks.push(Box::new(f()));
190 }
191 let idx = self.hook_index;
192 self.hook_index += 1;
193
194 self.hooks
195 .get_mut(idx)
196 .and_then(|hook| hook.any_self_mut().downcast_mut::<H>())
197 .expect("Hook type mismatch, ensure the hook is of the correct type")
198 }
199}