use crate::*;
impl<T> SignalInner<T>
where
T: Clone,
{
pub fn new(value: T) -> Self {
let inner: SignalInner<T> = SignalInner {
value,
listeners: Vec::new(),
};
inner
}
}
impl<T> SignalInner<T>
where
T: Clone,
{
pub fn notify(&mut self) {
for listener in self.get_listeners() {
let mut borrowed = listener.borrow_mut();
borrowed();
}
}
}
impl<T> Signal<T>
where
T: Clone + PartialEq,
{
pub fn from_inner(inner: *mut SignalInner<T>) -> Self {
Signal { inner }
}
#[allow(clippy::mut_from_ref)]
fn get_inner_mut(&self) -> &mut SignalInner<T> {
unsafe { &mut *self.inner }
}
pub fn get(&self) -> T {
self.get_inner_mut().get_value().clone()
}
pub fn try_get(&self) -> Option<T> {
Some(self.get_inner_mut().get_value().clone())
}
pub fn subscribe<F>(&self, callback: F)
where
F: FnMut() + 'static,
{
self.get_inner_mut()
.get_mut_listeners()
.push(Rc::new(RefCell::new(callback)));
}
pub fn set(&self, value: T) {
let inner: &mut SignalInner<T> = self.get_inner_mut();
if inner.get_value() == &value {
return;
}
let listeners: ListenerList = {
inner.set_value(value);
inner.get_listeners().iter().map(Rc::clone).collect()
};
for listener in &listeners {
let mut borrowed = listener.borrow_mut();
borrowed();
}
schedule_signal_update();
}
pub fn try_set(&self, value: T) -> bool {
let inner: &mut SignalInner<T> = self.get_inner_mut();
if inner.get_value() == &value {
return false;
}
let listeners: ListenerList = {
inner.set_value(value);
inner.get_listeners().iter().map(Rc::clone).collect()
};
for listener in &listeners {
listener.borrow_mut()();
}
schedule_signal_update();
true
}
}
impl<T> Deref for Signal<T>
where
T: Clone + PartialEq,
{
type Target = T;
fn deref(&self) -> &Self::Target {
panic!("Signal does not support direct dereference; use .get() instead");
}
}
impl<T> DerefMut for Signal<T>
where
T: Clone + PartialEq,
{
fn deref_mut(&mut self) -> &mut Self::Target {
panic!("Signal does not support direct dereference; use .set() instead");
}
}
impl<T> Clone for Signal<T>
where
T: Clone + PartialEq,
{
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for Signal<T> where T: Clone + PartialEq {}
impl IntoReactiveValue for String {
fn into_reactive_value(self) -> AttributeValue {
AttributeValue::Text(self)
}
}
impl IntoReactiveValue for &str {
fn into_reactive_value(self) -> AttributeValue {
AttributeValue::Text(self.to_string())
}
}
impl IntoReactiveValue for Signal<String> {
fn into_reactive_value(self) -> AttributeValue {
AttributeValue::Signal(self)
}
}
impl IntoReactiveValue for Signal<bool> {
fn into_reactive_value(self) -> AttributeValue {
bool_signal_to_string_attribute_value(self)
}
}
impl IntoReactiveValue for crate::vdom::CssClass {
fn into_reactive_value(self) -> AttributeValue {
AttributeValue::Css(self)
}
}
impl IntoReactiveValue for &'static crate::vdom::CssClass {
fn into_reactive_value(self) -> AttributeValue {
AttributeValue::Css(self.clone())
}
}
impl<F> IntoCallbackAttribute for F
where
F: FnMut(NativeEvent) + 'static,
{
fn into_callback_attribute(self) -> AttributeValue {
AttributeValue::Event(NativeEventHandler::new(
NativeEventName::Other("callback".to_string()),
self,
))
}
}
impl IntoCallbackAttribute for NativeEventHandler {
fn into_callback_attribute(self) -> AttributeValue {
AttributeValue::Event(self)
}
}
impl IntoCallbackAttribute for Option<NativeEventHandler> {
fn into_callback_attribute(self) -> AttributeValue {
match self {
Some(handler) => AttributeValue::Event(handler),
None => AttributeValue::Text(String::new()),
}
}
}
impl HookContext {
pub fn from_inner(inner: *mut HookContextInner) -> Self {
HookContext { inner }
}
#[allow(clippy::mut_from_ref)]
fn get_inner_mut(&self) -> &mut HookContextInner {
unsafe { &mut *self.inner }
}
pub fn get_hook_index(&self) -> usize {
*self.get_inner_mut().get_hook_index()
}
pub fn set_hook_index(&mut self, index: usize) {
self.get_inner_mut().set_hook_index(index);
}
pub fn get_hooks(&self) -> &Vec<Box<dyn Any>> {
self.get_inner_mut().get_hooks()
}
pub fn get_mut_hooks(&mut self) -> &mut Vec<Box<dyn Any>> {
self.get_inner_mut().get_mut_hooks()
}
pub fn reset_hook_index(&mut self) {
self.set_hook_index(0_usize);
}
}
impl Clone for HookContext {
fn clone(&self) -> Self {
*self
}
}
impl Copy for HookContext {}
impl Default for HookContext {
fn default() -> Self {
let boxed: Box<HookContextInner> = Box::default();
HookContext::from_inner(Box::leak(boxed) as *mut HookContextInner)
}
}
impl HookContextInner {
pub const fn new() -> Self {
HookContextInner {
hooks: Vec::new(),
hook_index: 0_usize,
}
}
}
impl Default for HookContextInner {
fn default() -> Self {
Self::new()
}
}
unsafe impl Sync for HookContextCell {}