pub use UseSignal as use_signal;
use std::pin::Pin;
use hooks_core::{Hook, HookPollNextUpdate, HookUnmount};
use crate::{ShareValue, ToOwnedShareValue};
mod sealed {
use hooks_core::{HookValue, HookValueBounds};
use crate::ShareValue;
use super::Signal;
pub trait HookValueImplSignal<'hook, ImplicitBounds: HookValueBounds<'hook, Self> = &'hook Self>:
HookValue<'hook, ImplicitBounds, Value = Self::HookValueImplSignal>
{
type HookValueImplShareValueValue;
type HookValueImplSignal: Signal<
SignalHook = Self,
Value = Self::HookValueImplShareValueValue,
>;
}
impl<'hook, H: ?Sized> HookValueImplSignal<'hook> for H
where
H: HookValue<'hook>,
H::Value: Signal<SignalHook = Self>,
{
type HookValueImplShareValueValue = <H::Value as ShareValue>::Value;
type HookValueImplSignal = H::Value;
}
}
pub trait SignalHook:
Hook
+ Signal<Value = Self::SignalShareValue, SignalHook = Self>
+ for<'hook> sealed::HookValueImplSignal<
'hook,
HookValueImplShareValueValue = Self::SignalShareValue,
>
{
type SignalShareValue;
type SignalHookUninitialized: HookPollNextUpdate + HookUnmount + Default;
fn to_signal(&self) -> crate::Value<'_, Self>;
}
pub trait Signal: ShareValue {
type SignalHook: SignalHook<SignalShareValue = Self::Value>;
fn is_signal_of(&self, signal_hook: &Self::SignalHook) -> bool;
fn to_signal_hook(&self) -> Self::SignalHook;
fn update_signal_hook(&self, hook: Pin<&mut Self::SignalHook>);
fn h_signal_hook<'hook>(
&self,
hook: Pin<&'hook mut <Self::SignalHook as SignalHook>::SignalHookUninitialized>,
) -> crate::Value<'hook, Self::SignalHook>;
fn use_signal(&self) -> UseSignal<'_, Self> {
UseSignal(self)
}
fn notify_changed(&self);
fn map_mut_and_notify_if<R>(&self, f: impl FnOnce(&mut Self::Value) -> (R, bool)) -> R;
}
impl<S: Signal + ?Sized> Signal for &S {
type SignalHook = S::SignalHook;
fn is_signal_of(&self, signal_hook: &Self::SignalHook) -> bool {
S::is_signal_of(self, signal_hook)
}
fn to_signal_hook(&self) -> Self::SignalHook {
S::to_signal_hook(self)
}
fn update_signal_hook(&self, hook: Pin<&mut Self::SignalHook>) {
S::update_signal_hook(self, hook)
}
fn h_signal_hook<'hook>(
&self,
hook: ::core::pin::Pin<
&'hook mut <Self::SignalHook as SignalHook>::SignalHookUninitialized,
>,
) -> crate::Value<'hook, Self::SignalHook> {
S::h_signal_hook(self, hook)
}
fn notify_changed(&self) {
S::notify_changed(self)
}
fn map_mut_and_notify_if<R>(&self, f: impl FnOnce(&mut Self::Value) -> (R, bool)) -> R {
S::map_mut_and_notify_if(self, f)
}
}
pub struct UseSignal<'a, S: Signal + ?Sized>(&'a S);
hooks_core::impl_hook!(
impl<S: Signal> UseSignal<'_, S> {
fn into_hook(self) -> S::SignalHook {
self.0.to_signal_hook()
}
fn update_hook(self, hook: _) {
self.0.update_signal_hook(hook)
}
fn h(self, hook: <S::SignalHook as SignalHook>::SignalHookUninitialized) {
self.0.h_signal_hook(hook)
}
}
);
pub trait ToOwnedSignal: Signal + ToOwnedShareValue<OwnedShareValue = Self::OwnedSignal> {
type OwnedSignal: Signal<SignalHook = Self::SignalHook, Value = Self::Value>;
}
impl<T: ?Sized + ToOwnedShareValue> ToOwnedSignal for T
where
T: Signal,
T::OwnedShareValue: Signal<SignalHook = Self::SignalHook>,
{
type OwnedSignal = T::OwnedShareValue;
}