diff --git a/examples/compose.rs b/examples/compose.rs index 823e47a57..133192281 100644 --- a/examples/compose.rs +++ b/examples/compose.rs @@ -61,7 +61,7 @@ fn compose(cx: Scope) -> Element { }, "Click to send" } - + input { oninput: move |e| user_input.set(e.value()), value: "{user_input}" } } }) diff --git a/packages/core/tests/event_propagation.rs b/packages/core/tests/event_propagation.rs index d9d96ac32..fb87bb16a 100644 --- a/packages/core/tests/event_propagation.rs +++ b/packages/core/tests/event_propagation.rs @@ -12,7 +12,12 @@ fn events_propagate() { _ = dom.rebuild(); // Top-level click is registered - dom.handle_event("click", Rc::new(PlatformEventData::new(Box::::default())), ElementId(1), true); + dom.handle_event( + "click", + Rc::new(PlatformEventData::new(Box::::default())), + ElementId(1), + true, + ); assert_eq!(*CLICKS.lock().unwrap(), 1); // break reference.... @@ -22,7 +27,12 @@ fn events_propagate() { } // Lower click is registered - dom.handle_event("click", Rc::new(PlatformEventData::new(Box::::default())), ElementId(2), true); + dom.handle_event( + "click", + Rc::new(PlatformEventData::new(Box::::default())), + ElementId(2), + true, + ); assert_eq!(*CLICKS.lock().unwrap(), 3); // break reference.... @@ -32,7 +42,12 @@ fn events_propagate() { } // Stop propagation occurs - dom.handle_event("click", Rc::new(PlatformEventData::new(Box::::default())), ElementId(2), true); + dom.handle_event( + "click", + Rc::new(PlatformEventData::new(Box::::default())), + ElementId(2), + true, + ); assert_eq!(*CLICKS.lock().unwrap(), 3); } diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index 9d66ddfb6..b9be87071 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -149,7 +149,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) // Copy over any assets we find crate::collect_assets::copy_assets(); - + // Set the event converter dioxus_html::set_event_converter(Box::new(SerializedHtmlEventConverter)); diff --git a/packages/signals/src/comparer.rs b/packages/signals/src/comparer.rs index e55654ced..90b407bba 100644 --- a/packages/signals/src/comparer.rs +++ b/packages/signals/src/comparer.rs @@ -1,19 +1,82 @@ use std::hash::Hash; use dioxus_core::prelude::*; +use generational_box::{Storage, UnsyncStorage}; -use crate::{CopyValue, Effect, ReadOnlySignal, Signal}; +use crate::{CopyValue, Effect, ReadOnlySignal, Signal, SignalData}; use rustc_hash::FxHashMap; /// An object that can efficiently compare a value to a set of values. #[derive(Debug)] -pub struct Comparer { - subscribers: CopyValue>>, +pub struct Comparer> = UnsyncStorage> { + subscribers: CopyValue>>, } impl Comparer { + /// Creates a new Comparer which efficiently tracks when a value changes to check if it is equal to a set of values. + /// + /// Generally, you shouldn't need to use this hook. Instead you can use [`crate::use_selector`]. If you have many values that you need to compare to a single value, this hook will change updates from O(n) to O(1) where n is the number of values you are comparing to. + pub fn new(mut f: impl FnMut() -> R + 'static) -> Comparer { + let subscribers: CopyValue>> = + CopyValue::new(FxHashMap::default()); + let previous = CopyValue::new(None); + + Effect::new(move || { + let subscribers = subscribers.read(); + let mut previous = previous.write(); + + if let Some(previous) = previous.take() { + if let Some(value) = subscribers.get(&previous) { + value.set(false); + } + } + + let current = f(); + + if let Some(value) = subscribers.get(¤t) { + value.set(true); + } + + *previous = Some(current); + }); + + Comparer { subscribers } + } +} + +impl>> Comparer { + /// Creates a new Comparer that may be `Sync + Send` which efficiently tracks when a value changes to check if it is equal to a set of values. + /// + /// Generally, you shouldn't need to use this hook. Instead you can use [`crate::use_selector`]. If you have many values that you need to compare to a single value, this hook will change updates from O(n) to O(1) where n is the number of values you are comparing to. + pub fn new_maybe_sync(mut f: impl FnMut() -> R + 'static) -> Comparer { + let subscribers: CopyValue>> = + CopyValue::new(FxHashMap::default()); + let previous = CopyValue::new(None); + + Effect::new(move || { + let subscribers = subscribers.read(); + let mut previous = previous.write(); + + if let Some(previous) = previous.take() { + if let Some(value) = subscribers.get(&previous) { + value.set(false); + } + } + + let current = f(); + + if let Some(value) = subscribers.get(¤t) { + value.set(true); + } + + *previous = Some(current); + }); + + Comparer { subscribers } + } + /// Returns a signal which is true when the value is equal to the value passed to this function. - pub fn equal(&self, value: R) -> ReadOnlySignal { + pub fn equal(&self, value: R) -> ReadOnlySignal { let subscribers = self.subscribers.read(); match subscribers.get(&value) { @@ -21,7 +84,7 @@ impl Comparer { None => { drop(subscribers); let mut subscribers = self.subscribers.write(); - let signal = Signal::new(false); + let signal = Signal::new_maybe_sync(false); subscribers.insert(value, signal); signal.into() } @@ -29,13 +92,13 @@ impl Comparer { } } -impl Clone for Comparer { +impl>> Clone for Comparer { fn clone(&self) -> Self { *self } } -impl Copy for Comparer {} +impl>> Copy for Comparer {} /// Creates a new Comparer which efficiently tracks when a value changes to check if it is equal to a set of values. /// @@ -74,34 +137,5 @@ impl Copy for Comparer {} /// ``` #[must_use] pub fn use_comparer(cx: &ScopeState, f: impl FnMut() -> R + 'static) -> Comparer { - *cx.use_hook(move || comparer(f)) -} - -/// Creates a new Comparer which efficiently tracks when a value changes to check if it is equal to a set of values. -/// -/// Generally, you shouldn't need to use this hook. Instead you can use [`crate::use_selector`]. If you have many values that you need to compare to a single value, this hook will change updates from O(n) to O(1) where n is the number of values you are comparing to. -pub fn comparer(mut f: impl FnMut() -> R + 'static) -> Comparer { - let subscribers: CopyValue>> = CopyValue::new(FxHashMap::default()); - let previous = CopyValue::new(None); - - Effect::new(move || { - let subscribers = subscribers.read(); - let mut previous = previous.write(); - - if let Some(previous) = previous.take() { - if let Some(value) = subscribers.get(&previous) { - value.set(false); - } - } - - let current = f(); - - if let Some(value) = subscribers.get(¤t) { - value.set(true); - } - - *previous = Some(current); - }); - - Comparer { subscribers } + *cx.use_hook(move || Comparer::new(f)) } diff --git a/packages/signals/src/signal.rs b/packages/signals/src/signal.rs index bccf294b5..b9080d348 100644 --- a/packages/signals/src/signal.rs +++ b/packages/signals/src/signal.rs @@ -536,8 +536,8 @@ pub struct ReadOnlySignal> = UnsyncStorage> inner: Signal, } -impl From> for ReadOnlySignal { - fn from(inner: Signal) -> Self { +impl>> From> for ReadOnlySignal { + fn from(inner: Signal) -> Self { Self { inner } } } @@ -634,9 +634,3 @@ impl> + 'static> Deref for ReadOnlySignal { reference_to_closure as &Self::Target } } - -impl From> for ReadOnlySignal { - fn from(signal: Signal) -> Self { - Self::new(signal) - } -} diff --git a/packages/signals/tests/effect.rs b/packages/signals/tests/effect.rs index f06f740f6..b19ae1136 100644 --- a/packages/signals/tests/effect.rs +++ b/packages/signals/tests/effect.rs @@ -32,9 +32,7 @@ async fn effects_rerun() { }); signal += 1; - render! { - div {} - } + render! { div {} } }, counter.clone(), );