1#![allow(unused)]
2use crate::{
3 context::ContextStack,
4 render::{ComponentDrawer, ComponentUpdater},
5};
6use std::{
7 any::Any,
8 pin::Pin,
9 task::{Context, Poll},
10};
11mod use_context;
12pub use use_context::UseContext;
13mod use_events;
14pub use use_events::UseEvents;
15mod use_future;
16pub use use_future::UseFuture;
17mod use_state;
18pub use use_state::UseState;
19
20pub trait Hook: Unpin + Send {
21 fn poll_change(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<()> {
22 Poll::Pending
23 }
24
25 fn pre_component_update(&mut self, _updater: &mut ComponentUpdater) {}
26 fn post_component_update(&mut self, _updater: &mut ComponentUpdater) {}
27
28 fn pre_component_draw(&mut self, _drawer: &mut ComponentDrawer) {}
29 fn post_component_draw(&mut self, _drawer: &mut ComponentDrawer) {}
30}
31
32pub(crate) trait AnyHook: Hook {
33 fn any_self_mut(&mut self) -> &mut dyn Any;
34}
35
36impl<T: Hook + 'static> AnyHook for T {
37 fn any_self_mut(&mut self) -> &mut dyn Any {
38 self
39 }
40}
41
42impl Hook for Vec<Box<dyn AnyHook>> {
43 fn poll_change(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<()> {
44 let mut is_ready = false;
45 for hook in self.iter_mut() {
46 if Pin::new(&mut **hook).poll_change(_cx).is_ready() {
47 is_ready = true;
48 }
49 }
50
51 if is_ready {
52 Poll::Ready(())
53 } else {
54 Poll::Pending
55 }
56 }
57
58 fn pre_component_update(&mut self, _updater: &mut ComponentUpdater) {
59 for hook in self.iter_mut() {
60 hook.pre_component_update(_updater);
61 }
62 }
63
64 fn post_component_update(&mut self, _updater: &mut ComponentUpdater) {
65 for hook in self.iter_mut() {
66 hook.post_component_update(_updater);
67 }
68 }
69
70 fn pre_component_draw(&mut self, _updater: &mut ComponentDrawer) {
71 for hook in self.iter_mut() {
72 hook.pre_component_draw(_updater);
73 }
74 }
75
76 fn post_component_draw(&mut self, _updater: &mut ComponentDrawer) {
77 for hook in self.iter_mut() {
78 hook.post_component_draw(_updater);
79 }
80 }
81}
82
83pub struct Hooks<'a, 'b: 'a> {
84 hooks: &'a mut Vec<Box<dyn AnyHook>>,
85 first_update: bool,
86 hook_index: usize,
87 pub(crate) context: Option<&'a ContextStack<'b>>,
88}
89
90impl<'a> Hooks<'a, '_> {
91 pub(crate) fn new(hooks: &'a mut Vec<Box<dyn AnyHook>>, first_update: bool) -> Self {
92 Self {
93 hooks,
94 first_update,
95 hook_index: 0,
96 context: None,
97 }
98 }
99
100 pub fn with_context_stack<'c, 'd>(
101 &'c mut self,
102 context: &'c ContextStack<'d>,
103 ) -> Hooks<'c, 'd> {
104 Hooks {
105 hooks: self.hooks,
106 first_update: self.first_update,
107 hook_index: self.hook_index,
108 context: Some(context),
109 }
110 }
111
112 pub fn use_hook<F, H>(&mut self, f: F) -> &mut H
113 where
114 F: FnOnce() -> H,
115 H: Hook + Unpin + 'static,
116 {
117 if self.first_update {
118 self.hooks.push(Box::new(f()));
119 }
120 let idx = self.hook_index;
121 self.hook_index += 1;
122
123 self.hooks
124 .get_mut(idx)
125 .and_then(|hook| hook.any_self_mut().downcast_mut::<H>())
126 .expect("Hook type mismatch, ensure the hook is of the correct type")
127 }
128}