use crate::*;
fn with_dispatch_function<F, R>(callback: F) -> R
where
F: FnOnce(&Function) -> R,
{
DISPATCH_CLOSURE.with(|dispatch_closure| {
let dispatch_function: &Function = dispatch_closure.as_ref().unchecked_ref::<Function>();
callback(dispatch_function)
})
}
pub fn schedule_update(dependents: &[usize]) {
mark_slots_dirty_targeted(dependents);
if SUPPRESS_SCHEDULE.load(Ordering::Relaxed) {
return;
}
if SCHEDULED.load(Ordering::Relaxed) {
return;
}
SCHEDULED.store(true, Ordering::Relaxed);
let window_value: Window = match window() {
Some(window_instance) => window_instance,
None => {
SCHEDULED.store(false, Ordering::Relaxed);
return;
}
};
let queued_microtask: bool = with_dispatch_function(|dispatch_function| {
let queue_microtask_value: JsValue =
Reflect::get(&window_value, &JsValue::from_str(QUEUE_MICROTASK))
.unwrap_or(JsValue::UNDEFINED);
matches!(
queue_microtask_value.dyn_into::<Function>(),
Ok(queue_microtask) if queue_microtask.call1(&window_value, dispatch_function).is_ok()
)
});
if queued_microtask {
return;
}
let scheduled: bool = with_dispatch_function(|dispatch_function| {
window_value
.set_timeout_with_callback_and_timeout_and_arguments_0(dispatch_function, 0)
.is_ok()
});
if scheduled {
return;
}
let requested_frame: bool = with_dispatch_function(|dispatch_function| {
window_value
.request_animation_frame(dispatch_function)
.is_ok()
});
if requested_frame {
return;
}
SCHEDULED.store(false, Ordering::Relaxed);
}
pub fn batch<F, R>(callback: F) -> R
where
F: FnOnce() -> R,
{
let was_outermost: bool = !SUPPRESS_SCHEDULE.load(Ordering::Relaxed);
SUPPRESS_SCHEDULE.store(true, Ordering::Relaxed);
let result: R = callback();
SUPPRESS_SCHEDULE.store(!was_outermost, Ordering::Relaxed);
result
}
pub(crate) fn subscribe_attr<F>(attr_signal: Signal<String>, compute: F)
where
F: Fn() -> String + 'static,
{
register_attr_signal_listener(
attr_signal.get_inner(),
Box::new(move || {
attr_signal.set(compute());
}),
);
}
pub(crate) fn bool_to_attr(source: Signal<bool>) -> AttributeValue {
let string_signal: Signal<String> = Signal::create(source.get().to_string());
let string_signal_clone: Signal<String> = string_signal;
let source_for_sub: Signal<bool> = source;
source_for_sub.replace_subscribe(move || {
string_signal_clone.set(source_for_sub.get().to_string());
});
AttributeValue::Signal(string_signal)
}
#[allow(static_mut_refs)]
pub(crate) fn try_get_current_hook_context_mut() -> &'static mut Option<HookContextRc> {
unsafe { &mut *CURRENT_HOOK_CONTEXT.get_0().get() }
}
#[allow(static_mut_refs)]
pub(crate) fn try_get_current_hook_context() -> &'static Option<HookContextRc> {
unsafe { &*CURRENT_HOOK_CONTEXT.get_0().get() }
}