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::*;
56
57#[cfg(feature = "router")]
58mod use_router;
59#[cfg(feature = "router")]
60pub use use_router::*;
61
62pub trait Hook: Unpin + Send {
70 fn poll_change(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<()> {
71 Poll::Pending
72 }
73
74 fn pre_component_update(&mut self, _updater: &mut ComponentUpdater) {}
75 fn post_component_update(&mut self, _updater: &mut ComponentUpdater) {}
76
77 fn pre_component_draw(&mut self, _drawer: &mut ComponentDrawer) {}
78 fn post_component_draw(&mut self, _drawer: &mut ComponentDrawer) {}
79}
80
81pub(crate) trait AnyHook: Hook {
82 fn any_self_mut(&mut self) -> &mut dyn Any;
83}
84
85impl<T: Hook + 'static> AnyHook for T {
86 fn any_self_mut(&mut self) -> &mut dyn Any {
87 self
88 }
89}
90
91impl Hook for Vec<Box<dyn AnyHook>> {
92 fn poll_change(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<()> {
93 let mut is_ready = false;
94 for hook in self.iter_mut() {
95 if Pin::new(&mut **hook).poll_change(_cx).is_ready() {
96 is_ready = true;
97 }
98 }
99
100 if is_ready {
101 Poll::Ready(())
102 } else {
103 Poll::Pending
104 }
105 }
106
107 fn pre_component_update(&mut self, _updater: &mut ComponentUpdater) {
108 for hook in self.iter_mut() {
109 hook.pre_component_update(_updater);
110 }
111 }
112
113 fn post_component_update(&mut self, _updater: &mut ComponentUpdater) {
114 for hook in self.iter_mut() {
115 hook.post_component_update(_updater);
116 }
117 }
118
119 fn pre_component_draw(&mut self, _updater: &mut ComponentDrawer) {
120 for hook in self.iter_mut() {
121 hook.pre_component_draw(_updater);
122 }
123 }
124
125 fn post_component_draw(&mut self, _updater: &mut ComponentDrawer) {
126 for hook in self.iter_mut() {
127 hook.post_component_draw(_updater);
128 }
129 }
130}
131
132pub struct Hooks<'a, 'b: 'a> {
144 hooks: &'a mut Vec<Box<dyn AnyHook>>,
145 first_update: bool,
146 hook_index: usize,
147 pub(crate) context: Option<&'a ContextStack<'b>>,
148}
149
150impl<'a> Hooks<'a, '_> {
151 pub(crate) fn new(hooks: &'a mut Vec<Box<dyn AnyHook>>, first_update: bool) -> Self {
152 Self {
153 hooks,
154 first_update,
155 hook_index: 0,
156 context: None,
157 }
158 }
159
160 pub fn with_context_stack<'c, 'd>(
161 &'c mut self,
162 context: &'c ContextStack<'d>,
163 ) -> Hooks<'c, 'd> {
164 Hooks {
165 hooks: self.hooks,
166 first_update: self.first_update,
167 hook_index: self.hook_index,
168 context: Some(context),
169 }
170 }
171
172 pub fn use_hook<F, H>(&mut self, f: F) -> &mut H
173 where
174 F: FnOnce() -> H,
175 H: Hook + Unpin + 'static,
176 {
177 if self.first_update {
178 self.hooks.push(Box::new(f()));
179 }
180 let idx = self.hook_index;
181 self.hook_index += 1;
182
183 self.hooks
184 .get_mut(idx)
185 .and_then(|hook| hook.any_self_mut().downcast_mut::<H>())
186 .expect("Hook type mismatch, ensure the hook is of the correct type")
187 }
188}