use crate::*;
pub(crate) fn get_current_hook_context() -> HookContext {
match current_hook_context() {
Some(hook_context_rc) => HookContext::new(hook_context_rc.clone()),
None => {
let rc: HookContextRc = Rc::new(RefCell::new(HookContextInner::default()));
*current_hook_context_mut() = Some(rc.clone());
HookContext::new(rc)
}
}
}
pub(crate) fn with_hook_context<F, R>(context: HookContext, f: F) -> R
where
F: FnOnce() -> R,
{
let previous: Option<HookContextRc> = current_hook_context_mut().take();
*current_hook_context_mut() = Some(context.get_inner().clone());
let result: R = f();
*current_hook_context_mut() = previous;
result
}
pub(crate) fn create_hook_context() -> HookContext {
HookContext::default()
}
pub fn use_signal<T, F>(init: F) -> Signal<T>
where
T: Clone + PartialEq + 'static,
F: FnOnce() -> T,
{
let hook_context: HookContext = get_current_hook_context();
let mut inner: RefMut<HookContextInner> = hook_context.get_inner().borrow_mut();
let index: usize = inner.get_hook_index();
inner.set_hook_index(index + 1);
if index < inner.get_hooks().len()
&& let Some(existing) = inner.get_hooks()[index].downcast_ref::<Signal<T>>()
{
return *existing;
}
let signal: Signal<T> = Signal::create(init());
inner
.get_mut_cleanups()
.push(Box::new(move || signal.clear_listeners()));
if index < inner.get_hooks().len() {
inner.get_mut_hooks()[index] = Box::new(signal);
} else {
inner.get_mut_hooks().push(Box::new(signal));
}
signal
}
pub fn use_cleanup<F>(cleanup: F)
where
F: FnOnce() + 'static,
{
let hook_context: HookContext = get_current_hook_context();
let mut inner: RefMut<HookContextInner> = hook_context.get_inner().borrow_mut();
let index: usize = inner.get_hook_index();
inner.set_hook_index(index + 1);
if index < inner.get_hooks().len() {
return;
}
inner.get_mut_cleanups().push(Box::new(cleanup));
inner.get_mut_hooks().push(Box::new(()));
}