rename use_selector to use_memo
This commit is contained in:
16 files changed
+127
-77
No files matched your search
@@ -25,7 +25,7 @@ const RECT_STYLE: &str = r#"
|
|||||||
"#;
|
"#;
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
let mut events = use_signal(|| std::collections::VecDeque::new() as VecDeque<Rc<dyn Debug>>);
|
let mut events = use_signal(|| VecDeque::new() as VecDeque<Rc<dyn Debug>>);
|
||||||
|
|
||||||
let mut log_event = move |event: Rc<dyn Debug>| {
|
let mut log_event = move |event: Rc<dyn Debug>| {
|
||||||
let mut events = events.write();
|
let mut events = events.write();
|
||||||
|
|||||||
+13
-32
@@ -27,7 +27,6 @@ fn app() -> Element {
|
|||||||
if val() == "0" {
|
if val() == "0" {
|
||||||
val.set(String::new());
|
val.set(String::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
val.write().push_str(num.as_str());
|
val.write().push_str(num.as_str());
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,15 +34,12 @@ fn app() -> Element {
|
|||||||
|
|
||||||
let mut handle_key_down_event = move |evt: KeyboardEvent| match evt.key() {
|
let mut handle_key_down_event = move |evt: KeyboardEvent| match evt.key() {
|
||||||
Key::Backspace => {
|
Key::Backspace => {
|
||||||
if !val.cloned().is_empty() {
|
if !val().is_empty() {
|
||||||
val.write().pop();
|
val.write().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Key::Character(character) => match character.as_str() {
|
Key::Character(character) => match character.as_str() {
|
||||||
"+" => input_operator("+"),
|
"+" | "-" | "/" | "*" => input_operator(&character),
|
||||||
"-" => input_operator("-"),
|
|
||||||
"/" => input_operator("/"),
|
|
||||||
"*" => input_operator("*"),
|
|
||||||
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" => input_digit(character),
|
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" => input_digit(character),
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
@@ -72,20 +68,18 @@ fn app() -> Element {
|
|||||||
button {
|
button {
|
||||||
class: "calculator-key key-sign",
|
class: "calculator-key key-sign",
|
||||||
onclick: move |_| {
|
onclick: move |_| {
|
||||||
let temp = calc_val(val.cloned().as_str());
|
let new_val = calc_val(val.cloned().as_str());
|
||||||
if temp > 0.0 {
|
if new_val > 0.0 {
|
||||||
val.set(format!("-{temp}"));
|
val.set(format!("-{new_val}"));
|
||||||
} else {
|
} else {
|
||||||
val.set(format!("{}", temp.abs()));
|
val.set(format!("{}", new_val.abs()));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"±"
|
"±"
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
class: "calculator-key key-percent",
|
class: "calculator-key key-percent",
|
||||||
onclick: move |_| {
|
onclick: move |_| val.set(format!("{}", calc_val(val.cloned().as_str()) / 100.0)),
|
||||||
val.set(format!("{}", calc_val(val.cloned().as_str()) / 100.0));
|
|
||||||
},
|
|
||||||
"%"
|
"%"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,25 +105,12 @@ fn app() -> Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
div { class: "operator-keys",
|
div { class: "operator-keys",
|
||||||
button {
|
for (key, class) in [("/", "key-divide"), ("*", "key-multiply"), ("-", "key-subtract"), ("+", "key-add")] {
|
||||||
class: "calculator-key key-divide",
|
button {
|
||||||
onclick: move |_| input_operator("/"),
|
class: "calculator-key {class}",
|
||||||
"÷"
|
onclick: move |_| input_operator(key),
|
||||||
}
|
"{key}"
|
||||||
button {
|
}
|
||||||
class: "calculator-key key-multiply",
|
|
||||||
onclick: move |_| input_operator("*"),
|
|
||||||
"×"
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
class: "calculator-key key-subtract",
|
|
||||||
onclick: move |_| input_operator("-"),
|
|
||||||
"−"
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
class: "calculator-key key-add",
|
|
||||||
onclick: move |_| input_operator("+"),
|
|
||||||
"+"
|
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
class: "calculator-key key-equals",
|
class: "calculator-key key-equals",
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ fn main() {
|
|||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
let mut counters = use_signal(|| vec![0, 0, 0]);
|
let mut counters = use_signal(|| vec![0, 0, 0]);
|
||||||
let sum = use_selector(move || counters.read().iter().copied().sum::<i32>());
|
let sum = use_memo(move || counters.read().iter().copied().sum::<i32>());
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
|
|||||||
+3
-3
@@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
static COUNT: GlobalSignal<i32> = Signal::global(|| 0);
|
|
||||||
static DOUBLED_COUNT: GlobalSelector<i32> = Signal::global_selector(|| COUNT() * 2);
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static COUNT: GlobalSignal<i32> = Signal::global(|| 0);
|
||||||
|
static DOUBLED_COUNT: GlobalMemo<i32> = Signal::global_memo(|| COUNT() * 2);
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
rsx! {
|
rsx! {
|
||||||
h1 { "{COUNT} x 2 = {DOUBLED_COUNT}" }
|
h1 { "{COUNT} x 2 = {DOUBLED_COUNT}" }
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ fn Dice() -> Element {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let mut value = use_signal(|| 5);
|
let mut value = use_signal(|| 5);
|
||||||
let active_dots = use_selector(move || &DOTS_FOR_VALUE[(value() - 1) as usize]);
|
let active_dots = use_memo(move || &DOTS_FOR_VALUE[(value() - 1) as usize]);
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
svg {
|
svg {
|
||||||
|
|||||||
+5
-5
@@ -28,9 +28,9 @@ fn app() -> Element {
|
|||||||
let mut filter = use_signal(|| FilterState::All);
|
let mut filter = use_signal(|| FilterState::All);
|
||||||
|
|
||||||
let active_todo_count =
|
let active_todo_count =
|
||||||
use_selector(move || todos.read().values().filter(|item| !item.checked).count());
|
use_memo(move || todos.read().values().filter(|item| !item.checked).count());
|
||||||
|
|
||||||
let filtered_todos = use_selector(move || {
|
let filtered_todos = use_memo(move || {
|
||||||
let mut filtered_todos = todos
|
let mut filtered_todos = todos
|
||||||
.read()
|
.read()
|
||||||
.iter()
|
.iter()
|
||||||
@@ -120,8 +120,8 @@ fn TodoHeader(mut todos: Signal<HashMap<u32, TodoItem>>) -> Element {
|
|||||||
#[component]
|
#[component]
|
||||||
fn TodoEntry(mut todos: Signal<HashMap<u32, TodoItem>>, id: u32) -> Element {
|
fn TodoEntry(mut todos: Signal<HashMap<u32, TodoItem>>, id: u32) -> Element {
|
||||||
let mut is_editing = use_signal(|| false);
|
let mut is_editing = use_signal(|| false);
|
||||||
let checked = use_selector(move || todos.read().get(&id).unwrap().checked);
|
let checked = use_memo(move || todos.read().get(&id).unwrap().checked);
|
||||||
let contents = use_selector(move || todos.read().get(&id).unwrap().contents.clone());
|
let contents = use_memo(move || todos.read().get(&id).unwrap().contents.clone());
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
li { class: if checked() { "completed" }, class: if is_editing() { "editing" },
|
li { class: if checked() { "completed" }, class: if is_editing() { "editing" },
|
||||||
@@ -170,7 +170,7 @@ fn ListFooter(
|
|||||||
active_todo_count: ReadOnlySignal<usize>,
|
active_todo_count: ReadOnlySignal<usize>,
|
||||||
mut filter: Signal<FilterState>,
|
mut filter: Signal<FilterState>,
|
||||||
) -> Element {
|
) -> Element {
|
||||||
let show_clear_completed = use_selector(move || todos.read().values().any(|todo| todo.checked));
|
let show_clear_completed = use_memo(move || todos.read().values().any(|todo| todo.checked));
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
footer { class: "footer",
|
footer { class: "footer",
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ pub use use_coroutine::*;
|
|||||||
mod use_future;
|
mod use_future;
|
||||||
pub use use_future::*;
|
pub use use_future::*;
|
||||||
|
|
||||||
|
mod use_sorted;
|
||||||
|
pub use use_sorted::*;
|
||||||
|
|
||||||
// mod use_on_create;
|
// mod use_on_create;
|
||||||
// pub use use_on_create::*;
|
// pub use use_on_create::*;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
use dioxus_signals::{use_memo, ReadOnlySignal, Signal};
|
||||||
|
|
||||||
|
pub fn use_sorted<V: 'static, T: PartialEq>(
|
||||||
|
collection: impl FnMut() -> Signal<V>,
|
||||||
|
) -> ReadOnlySignal<Vec<T>>
|
||||||
|
// pub fn use_sorted<S, I, T>(iterable: impl FnMut() -> Signal<V>) -> ReadOnlySignal<T>
|
||||||
|
// where
|
||||||
|
// S: Into<MaybeSignal<I>>,
|
||||||
|
// T: Ord,
|
||||||
|
// I: DerefMut<Target = [T]> + Clone + PartialEq,
|
||||||
|
{
|
||||||
|
use_memo(move || {
|
||||||
|
todo!()
|
||||||
|
// let mut iterable = collection();
|
||||||
|
// iterable.sort();
|
||||||
|
// iterable
|
||||||
|
})
|
||||||
|
// let iterable = iterable.into();
|
||||||
|
|
||||||
|
// // use_memo(f)
|
||||||
|
|
||||||
|
// create_memo(move |_| {
|
||||||
|
// let mut iterable = iterable.get();
|
||||||
|
// iterable.sort();
|
||||||
|
// iterable
|
||||||
|
// })
|
||||||
|
// .into()
|
||||||
|
}
|
||||||
|
|
||||||
|
// /// Version of [`use_sorted`] with a compare function.
|
||||||
|
// pub fn use_sorted_by<S, I, T, F>(iterable: S, cmp_fn: F) -> Signal<I>
|
||||||
|
// where
|
||||||
|
// S: Into<MaybeSignal<I>>,
|
||||||
|
// I: DerefMut<Target = [T]> + Clone + PartialEq,
|
||||||
|
// F: FnMut(&T, &T) -> Ordering + Clone + 'static,
|
||||||
|
// {
|
||||||
|
// let iterable = iterable.into();
|
||||||
|
|
||||||
|
// create_memo(move |_| {
|
||||||
|
// let mut iterable = iterable.get();
|
||||||
|
// iterable.sort_by(cmp_fn.clone());
|
||||||
|
// iterable
|
||||||
|
// })
|
||||||
|
// .into()
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// Version of [`use_sorted`] by key.
|
||||||
|
// pub fn use_sorted_by_key<S, I, T, K, F>(iterable: S, key_fn: F) -> Signal<I>
|
||||||
|
// where
|
||||||
|
// S: Into<MaybeSignal<I>>,
|
||||||
|
// I: DerefMut<Target = [T]> + Clone + PartialEq,
|
||||||
|
// K: Ord,
|
||||||
|
// F: FnMut(&T) -> K + Clone + 'static,
|
||||||
|
// {
|
||||||
|
// let iterable = iterable.into();
|
||||||
|
|
||||||
|
// create_memo(move |_| {
|
||||||
|
// let mut iterable = iterable.get();
|
||||||
|
// iterable.sort_by_key(key_fn.clone());
|
||||||
|
// iterable
|
||||||
|
// })
|
||||||
|
// .into()
|
||||||
|
// }
|
||||||
@@ -97,7 +97,7 @@ fn Child() -> Element {
|
|||||||
|
|
||||||
In addition to local subscriptions in components, `dioxus-signals` provides a way to derive data with local subscriptions.
|
In addition to local subscriptions in components, `dioxus-signals` provides a way to derive data with local subscriptions.
|
||||||
|
|
||||||
The use_selector hook will only rerun when any signals inside the hook change:
|
The use_memo hook will only rerun when any signals inside the hook change:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
@@ -106,7 +106,7 @@ use dioxus_signals::*;
|
|||||||
#[component]
|
#[component]
|
||||||
fn App() -> Element {
|
fn App() -> Element {
|
||||||
let signal = use_signal(|| 0);
|
let signal = use_signal(|| 0);
|
||||||
let doubled = use_selector(|| signal * 2);
|
let doubled = use_memo(|| signal * 2);
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
button {
|
button {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ fn app() -> Element {
|
|||||||
|
|
||||||
let mut local_state = use_signal(|| 0);
|
let mut local_state = use_signal(|| 0);
|
||||||
|
|
||||||
let computed = use_selector_with_dependencies((&local_state(),), move |(local_state,)| {
|
let computed = use_memo_with_dependencies((&local_state(),), move |(local_state,)| {
|
||||||
local_state * 2 + signal.cloned()
|
local_state * 2 + signal.cloned()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ fn main() {
|
|||||||
#[component]
|
#[component]
|
||||||
fn App() -> Element {
|
fn App() -> Element {
|
||||||
let mut signal = use_signal(|| 0);
|
let mut signal = use_signal(|| 0);
|
||||||
let doubled = use_selector(move || signal * 2);
|
let doubled = use_memo(move || signal * 2);
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
button {
|
button {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub struct Comparer<R: 'static, S: Storage<SignalData<bool>> = UnsyncStorage> {
|
|||||||
impl<R: Eq + Hash> Comparer<R> {
|
impl<R: Eq + Hash> Comparer<R> {
|
||||||
/// Creates a new Comparer which efficiently tracks when a value changes to check if it is equal to a set of values.
|
/// 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.
|
/// Generally, you shouldn't need to use this hook. Instead you can use [`crate::use_memo`]. 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<R> {
|
pub fn new(mut f: impl FnMut() -> R + 'static) -> Comparer<R> {
|
||||||
let subscribers: CopyValue<FxHashMap<R, Signal<bool>>> =
|
let subscribers: CopyValue<FxHashMap<R, Signal<bool>>> =
|
||||||
CopyValue::new(FxHashMap::default());
|
CopyValue::new(FxHashMap::default());
|
||||||
@@ -47,7 +47,7 @@ impl<R: Eq + Hash> Comparer<R> {
|
|||||||
impl<R: Eq + Hash, S: Storage<SignalData<bool>>> Comparer<R, S> {
|
impl<R: Eq + Hash, S: Storage<SignalData<bool>>> Comparer<R, S> {
|
||||||
/// 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.
|
/// 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.
|
/// Generally, you shouldn't need to use this hook. Instead you can use [`crate::use_memo`]. 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<R> {
|
pub fn new_maybe_sync(mut f: impl FnMut() -> R + 'static) -> Comparer<R> {
|
||||||
let subscribers: CopyValue<FxHashMap<R, Signal<bool>>> =
|
let subscribers: CopyValue<FxHashMap<R, Signal<bool>>> =
|
||||||
CopyValue::new(FxHashMap::default());
|
CopyValue::new(FxHashMap::default());
|
||||||
@@ -102,7 +102,7 @@ impl<R, S: Storage<SignalData<bool>>> Copy for Comparer<R, S> {}
|
|||||||
|
|
||||||
/// Creates a new Comparer which efficiently tracks when a value changes to check if it is equal to a set of values.
|
/// 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.
|
/// Generally, you shouldn't need to use this hook. Instead you can use [`crate::use_memo`]. 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.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use dioxus::prelude::*;
|
/// use dioxus::prelude::*;
|
||||||
|
|||||||
@@ -201,17 +201,17 @@ impl<T: Clone + 'static> Deref for GlobalSignal<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A signal that can be accessed from anywhere in the application and created in a static
|
/// A signal that can be accessed from anywhere in the application and created in a static
|
||||||
pub struct GlobalSelector<T: 'static> {
|
pub struct GlobalMemo<T: 'static> {
|
||||||
selector: fn() -> T,
|
selector: fn() -> T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq + 'static> GlobalSelector<T> {
|
impl<T: PartialEq + 'static> GlobalMemo<T> {
|
||||||
/// Create a new global signal
|
/// Create a new global signal
|
||||||
pub const fn new(selector: fn() -> T) -> GlobalSelector<T>
|
pub const fn new(selector: fn() -> T) -> GlobalMemo<T>
|
||||||
where
|
where
|
||||||
T: PartialEq,
|
T: PartialEq,
|
||||||
{
|
{
|
||||||
GlobalSelector { selector }
|
GlobalMemo { selector }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the signal that backs this global.
|
/// Get the signal that backs this global.
|
||||||
@@ -266,7 +266,7 @@ impl<T: PartialEq + 'static> GlobalSelector<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq + 'static> IntoAttributeValue for GlobalSelector<T>
|
impl<T: PartialEq + 'static> IntoAttributeValue for GlobalMemo<T>
|
||||||
where
|
where
|
||||||
T: Clone + IntoAttributeValue,
|
T: Clone + IntoAttributeValue,
|
||||||
{
|
{
|
||||||
@@ -275,7 +275,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq + Clone + 'static> GlobalSelector<T> {
|
impl<T: PartialEq + Clone + 'static> GlobalMemo<T> {
|
||||||
/// Get the current value of the signal. This will subscribe the current scope to the signal.
|
/// Get the current value of the signal. This will subscribe the current scope to the signal.
|
||||||
/// If the signal has been dropped, this will panic.
|
/// If the signal has been dropped, this will panic.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
@@ -284,7 +284,7 @@ impl<T: PartialEq + Clone + 'static> GlobalSelector<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq + 'static> PartialEq for GlobalSelector<T> {
|
impl<T: PartialEq + 'static> PartialEq for GlobalMemo<T> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
std::ptr::eq(self, other)
|
std::ptr::eq(self, other)
|
||||||
}
|
}
|
||||||
@@ -293,7 +293,7 @@ impl<T: PartialEq + 'static> PartialEq for GlobalSelector<T> {
|
|||||||
/// Allow calling a signal with signal() syntax
|
/// Allow calling a signal with signal() syntax
|
||||||
///
|
///
|
||||||
/// Currently only limited to copy types, though could probably specialize for string/arc/rc
|
/// Currently only limited to copy types, though could probably specialize for string/arc/rc
|
||||||
impl<T: PartialEq + Clone + 'static> Deref for GlobalSelector<T> {
|
impl<T: PartialEq + Clone + 'static> Deref for GlobalMemo<T> {
|
||||||
type Target = dyn Fn() -> T;
|
type Target = dyn Fn() -> T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::rt::CopyValue;
|
use crate::rt::CopyValue;
|
||||||
use crate::signal::{ReadOnlySignal, Signal, Write};
|
use crate::signal::{ReadOnlySignal, Signal, Write};
|
||||||
use crate::{GlobalSelector, GlobalSignal, SignalData};
|
use crate::{GlobalMemo, GlobalSignal, SignalData};
|
||||||
use generational_box::{GenerationalRef, Mappable};
|
use generational_box::{GenerationalRef, Mappable};
|
||||||
use generational_box::{MappableMut, Storage};
|
use generational_box::{MappableMut, Storage};
|
||||||
|
|
||||||
@@ -414,16 +414,16 @@ impl<T: 'static> GlobalSignal<Option<T>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
read_impls!(GlobalSelector: PartialEq);
|
read_impls!(GlobalMemo: PartialEq);
|
||||||
|
|
||||||
impl<T: PartialEq + 'static> GlobalSelector<Vec<T>> {
|
impl<T: PartialEq + 'static> GlobalMemo<Vec<T>> {
|
||||||
/// Read a value from the inner vector.
|
/// Read a value from the inner vector.
|
||||||
pub fn get(&'static self, index: usize) -> Option<GenerationalRef<T, Ref<'static, T>>> {
|
pub fn get(&'static self, index: usize) -> Option<GenerationalRef<T, Ref<'static, T>>> {
|
||||||
GenerationalRef::<Vec<T>, Ref<'static, Vec<T>>>::try_map(self.read(), move |v| v.get(index))
|
GenerationalRef::<Vec<T>, Ref<'static, Vec<T>>>::try_map(self.read(), move |v| v.get(index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq + 'static> GlobalSelector<Option<T>> {
|
impl<T: PartialEq + 'static> GlobalMemo<Option<T>> {
|
||||||
/// Unwraps the inner value and clones it.
|
/// Unwraps the inner value and clones it.
|
||||||
pub fn unwrap(&'static self) -> T
|
pub fn unwrap(&'static self) -> T
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use crate::{signal::SignalData, ReadOnlySignal, Signal};
|
|||||||
///
|
///
|
||||||
/// fn App() -> Element {
|
/// fn App() -> Element {
|
||||||
/// let mut count = use_signal(|| 0);
|
/// let mut count = use_signal(|| 0);
|
||||||
/// let double = use_selector(move || count * 2);
|
/// let double = use_memo(move || count * 2);
|
||||||
/// count += 1;
|
/// count += 1;
|
||||||
/// assert_eq!(double.value(), count * 2);
|
/// assert_eq!(double.value(), count * 2);
|
||||||
///
|
///
|
||||||
@@ -24,8 +24,8 @@ use crate::{signal::SignalData, ReadOnlySignal, Signal};
|
|||||||
/// ```
|
/// ```
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
||||||
pub fn use_selector<R: PartialEq>(f: impl FnMut() -> R + 'static) -> ReadOnlySignal<R> {
|
pub fn use_memo<R: PartialEq>(f: impl FnMut() -> R + 'static) -> ReadOnlySignal<R> {
|
||||||
use_maybe_sync_selector(f)
|
use_maybe_sync_memo(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new Selector that may be sync. The selector will be run immediately and whenever any signal it reads changes.
|
/// Creates a new Selector that may be sync. The selector will be run immediately and whenever any signal it reads changes.
|
||||||
@@ -38,7 +38,7 @@ pub fn use_selector<R: PartialEq>(f: impl FnMut() -> R + 'static) -> ReadOnlySig
|
|||||||
///
|
///
|
||||||
/// fn App(cx: Scope) -> Element {
|
/// fn App(cx: Scope) -> Element {
|
||||||
/// let mut count = use_signal(cx, || 0);
|
/// let mut count = use_signal(cx, || 0);
|
||||||
/// let double = use_selector(cx, move || count * 2);
|
/// let double = use_memo(cx, move || count * 2);
|
||||||
/// count += 1;
|
/// count += 1;
|
||||||
/// assert_eq!(double.value(), count * 2);
|
/// assert_eq!(double.value(), count * 2);
|
||||||
///
|
///
|
||||||
@@ -47,10 +47,10 @@ pub fn use_selector<R: PartialEq>(f: impl FnMut() -> R + 'static) -> ReadOnlySig
|
|||||||
/// ```
|
/// ```
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
||||||
pub fn use_maybe_sync_selector<R: PartialEq, S: Storage<SignalData<R>>>(
|
pub fn use_maybe_sync_memo<R: PartialEq, S: Storage<SignalData<R>>>(
|
||||||
f: impl FnMut() -> R + 'static,
|
f: impl FnMut() -> R + 'static,
|
||||||
) -> ReadOnlySignal<R, S> {
|
) -> ReadOnlySignal<R, S> {
|
||||||
use_hook(|| Signal::maybe_sync_selector(f))
|
use_hook(|| Signal::maybe_sync_memo(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new unsync Selector with some local dependencies. The selector will be run immediately and whenever any signal it reads or any dependencies it tracks changes
|
/// Creates a new unsync Selector with some local dependencies. The selector will be run immediately and whenever any signal it reads or any dependencies it tracks changes
|
||||||
@@ -63,7 +63,7 @@ pub fn use_maybe_sync_selector<R: PartialEq, S: Storage<SignalData<R>>>(
|
|||||||
///
|
///
|
||||||
/// fn App(cx: Scope) -> Element {
|
/// fn App(cx: Scope) -> Element {
|
||||||
/// let mut local_state = use_state(cx, || 0);
|
/// let mut local_state = use_state(cx, || 0);
|
||||||
/// let double = use_selector_with_dependencies(cx, (local_state.get(),), move |(local_state,)| local_state * 2);
|
/// let double = use_memo_with_dependencies(cx, (local_state.get(),), move |(local_state,)| local_state * 2);
|
||||||
/// local_state.set(1);
|
/// local_state.set(1);
|
||||||
///
|
///
|
||||||
/// render! { "{double}" }
|
/// render! { "{double}" }
|
||||||
@@ -71,7 +71,7 @@ pub fn use_maybe_sync_selector<R: PartialEq, S: Storage<SignalData<R>>>(
|
|||||||
/// ```
|
/// ```
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
||||||
pub fn use_selector_with_dependencies<R: PartialEq, D: Dependency>(
|
pub fn use_memo_with_dependencies<R: PartialEq, D: Dependency>(
|
||||||
dependencies: D,
|
dependencies: D,
|
||||||
f: impl FnMut(D::Out) -> R + 'static,
|
f: impl FnMut(D::Out) -> R + 'static,
|
||||||
) -> ReadOnlySignal<R>
|
) -> ReadOnlySignal<R>
|
||||||
@@ -91,7 +91,7 @@ where
|
|||||||
///
|
///
|
||||||
/// fn App(cx: Scope) -> Element {
|
/// fn App(cx: Scope) -> Element {
|
||||||
/// let mut local_state = use_state(cx, || 0);
|
/// let mut local_state = use_state(cx, || 0);
|
||||||
/// let double = use_selector_with_dependencies(cx, (local_state.get(),), move |(local_state,)| local_state * 2);
|
/// let double = use_memo_with_dependencies(cx, (local_state.get(),), move |(local_state,)| local_state * 2);
|
||||||
/// local_state.set(1);
|
/// local_state.set(1);
|
||||||
///
|
///
|
||||||
/// render! { "{double}" }
|
/// render! { "{double}" }
|
||||||
@@ -112,7 +112,7 @@ where
|
|||||||
{
|
{
|
||||||
let mut dependencies_signal = use_signal(|| dependencies.out());
|
let mut dependencies_signal = use_signal(|| dependencies.out());
|
||||||
let selector = use_hook(|| {
|
let selector = use_hook(|| {
|
||||||
Signal::maybe_sync_selector(move || {
|
Signal::maybe_sync_memo(move || {
|
||||||
let deref = &*dependencies_signal.read();
|
let deref = &*dependencies_signal.read();
|
||||||
f(deref.clone())
|
f(deref.clone())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::{Effect, EffectInner, GlobalSelector, GlobalSignal, MappedSignal};
|
use crate::{Effect, EffectInner, GlobalMemo, GlobalSignal, MappedSignal};
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
@@ -232,11 +232,11 @@ impl<T: 'static> Signal<T> {
|
|||||||
|
|
||||||
impl<T: PartialEq + 'static> Signal<T> {
|
impl<T: PartialEq + 'static> Signal<T> {
|
||||||
/// Creates a new global Signal that can be used in a global static.
|
/// Creates a new global Signal that can be used in a global static.
|
||||||
pub const fn global_selector(constructor: fn() -> T) -> GlobalSelector<T>
|
pub const fn global_memo(constructor: fn() -> T) -> GlobalMemo<T>
|
||||||
where
|
where
|
||||||
T: PartialEq,
|
T: PartialEq,
|
||||||
{
|
{
|
||||||
GlobalSelector::new(constructor)
|
GlobalMemo::new(constructor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new unsync Selector. The selector will be run immediately and whenever any signal it reads changes.
|
/// Creates a new unsync Selector. The selector will be run immediately and whenever any signal it reads changes.
|
||||||
@@ -244,14 +244,14 @@ impl<T: PartialEq + 'static> Signal<T> {
|
|||||||
/// Selectors can be used to efficiently compute derived data from signals.
|
/// Selectors can be used to efficiently compute derived data from signals.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn selector(f: impl FnMut() -> T + 'static) -> ReadOnlySignal<T> {
|
pub fn selector(f: impl FnMut() -> T + 'static) -> ReadOnlySignal<T> {
|
||||||
Self::maybe_sync_selector(f)
|
Self::maybe_sync_memo(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new Selector that may be Sync + Send. The selector will be run immediately and whenever any signal it reads changes.
|
/// Creates a new Selector that may be Sync + Send. The selector will be run immediately and whenever any signal it reads changes.
|
||||||
///
|
///
|
||||||
/// Selectors can be used to efficiently compute derived data from signals.
|
/// Selectors can be used to efficiently compute derived data from signals.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn maybe_sync_selector<S: Storage<SignalData<T>>>(
|
pub fn maybe_sync_memo<S: Storage<SignalData<T>>>(
|
||||||
mut f: impl FnMut() -> T + 'static,
|
mut f: impl FnMut() -> T + 'static,
|
||||||
) -> ReadOnlySignal<T, S> {
|
) -> ReadOnlySignal<T, S> {
|
||||||
let mut state = Signal::<T, S> {
|
let mut state = Signal::<T, S> {
|
||||||
|
|||||||
Reference in new issue
Block a user