mirror of
https://github.com/DioxusLabs/dioxus
synced 2025-02-17 06:08:26 +00:00
Use a gen
in PartialEq
for UseSharedState
(#1389)
* Special case UseFutureDep for UseSharedState * Add 'gen' to UseSharedState for use in 'PartialEq' * Update 'gen' in 'UseSharedState::new' * Don't require PartialEq for T in UseSharedState --------- Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
This commit is contained in:
parent
ae5dca8f43
commit
18dca07e4b
1 changed files with 14 additions and 7 deletions
|
@ -81,10 +81,12 @@ pub(crate) struct ProvidedStateInner<T> {
|
|||
value: T,
|
||||
notify_any: Arc<dyn Fn(ScopeId)>,
|
||||
consumers: HashSet<ScopeId>,
|
||||
gen: usize,
|
||||
}
|
||||
|
||||
impl<T> ProvidedStateInner<T> {
|
||||
pub(crate) fn notify_consumers(&mut self) {
|
||||
self.gen += 1;
|
||||
for consumer in self.consumers.iter() {
|
||||
(self.notify_any)(*consumer);
|
||||
}
|
||||
|
@ -157,7 +159,7 @@ impl<T> ProvidedStateInner<T> {
|
|||
///
|
||||
/// Right now, there is not a distinction between read-only and write-only, so every consumer will be notified.
|
||||
pub fn use_shared_state<T: 'static>(cx: &ScopeState) -> Option<&UseSharedState<T>> {
|
||||
let state: &Option<UseSharedStateOwner<T>> = &*cx.use_hook(move || {
|
||||
let state_owner: &mut Option<UseSharedStateOwner<T>> = &mut *cx.use_hook(move || {
|
||||
let scope_id = cx.scope_id();
|
||||
let root = cx.consume_context::<ProvidedState<T>>()?;
|
||||
|
||||
|
@ -167,7 +169,10 @@ pub fn use_shared_state<T: 'static>(cx: &ScopeState) -> Option<&UseSharedState<T
|
|||
let owner = UseSharedStateOwner { state, scope_id };
|
||||
Some(owner)
|
||||
});
|
||||
state.as_ref().map(|s| &s.state)
|
||||
state_owner.as_mut().map(|s| {
|
||||
s.state.gen = s.state.inner.borrow().gen;
|
||||
&s.state
|
||||
})
|
||||
}
|
||||
|
||||
/// This wrapper detects when the hook is dropped and will unsubscribe when the component is unmounted
|
||||
|
@ -187,11 +192,13 @@ impl<T> Drop for UseSharedStateOwner<T> {
|
|||
/// State that is shared between components through the context system
|
||||
pub struct UseSharedState<T> {
|
||||
pub(crate) inner: Rc<RefCell<ProvidedStateInner<T>>>,
|
||||
gen: usize,
|
||||
}
|
||||
|
||||
impl<T> UseSharedState<T> {
|
||||
fn new(inner: Rc<RefCell<ProvidedStateInner<T>>>) -> Self {
|
||||
Self { inner }
|
||||
let gen = inner.borrow().gen;
|
||||
Self { inner, gen }
|
||||
}
|
||||
|
||||
/// Notify all consumers of the state that it has changed. (This is called automatically when you call "write")
|
||||
|
@ -302,15 +309,14 @@ impl<T> Clone for UseSharedState<T> {
|
|||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: self.inner.clone(),
|
||||
gen: self.gen,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialEq> PartialEq for UseSharedState<T> {
|
||||
impl<T> PartialEq for UseSharedState<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
let first = self.inner.borrow();
|
||||
let second = other.inner.borrow();
|
||||
first.value == second.value
|
||||
self.gen == other.gen
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,6 +366,7 @@ pub fn use_shared_state_provider<T: 'static>(cx: &ScopeState, f: impl FnOnce() -
|
|||
value: f(),
|
||||
notify_any: cx.schedule_update_any(),
|
||||
consumers: HashSet::new(),
|
||||
gen: 0,
|
||||
}));
|
||||
|
||||
cx.provide_context(state);
|
||||
|
|
Loading…
Add table
Reference in a new issue