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