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