From 050add21d7b3d950524e3fc3e7e236f4274495eb Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 17 Oct 2023 12:56:12 -0500 Subject: [PATCH 1/2] effect-outside-of-runtime --- packages/signals/src/effect.rs | 28 +++++++++++++++++++++------- packages/signals/src/selector.rs | 6 ++++-- packages/signals/src/signal.rs | 7 +++++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/packages/signals/src/effect.rs b/packages/signals/src/effect.rs index 9a54188d9e..ad950b94bf 100644 --- a/packages/signals/src/effect.rs +++ b/packages/signals/src/effect.rs @@ -1,16 +1,28 @@ use core::{self, fmt::Debug}; -use std::cell::RefCell; use std::fmt::{self, Formatter}; -use std::rc::Rc; // use dioxus_core::prelude::*; use crate::use_signal; use crate::{dependency::Dependency, CopyValue}; -#[derive(Default, Clone)] +#[derive(Copy, Clone, PartialEq)] pub(crate) struct EffectStack { - pub(crate) effects: Rc>>, + pub(crate) effects: CopyValue>, +} + +impl Default for EffectStack { + fn default() -> Self { + Self { + effects: CopyValue::new_in_scope(Vec::new(), ScopeId::ROOT), + } + } +} + +impl EffectStack { + pub(crate) fn current(&self) -> Option { + self.effects.read().last().copied() + } } pub(crate) fn get_effect_stack() -> EffectStack { @@ -57,6 +69,7 @@ pub fn use_effect_with_dependencies( pub struct Effect { pub(crate) source: ScopeId, pub(crate) callback: CopyValue>, + pub(crate) effect_stack: EffectStack, } impl Debug for Effect { @@ -67,7 +80,7 @@ impl Debug for Effect { impl Effect { pub(crate) fn current() -> Option { - get_effect_stack().effects.borrow().last().copied() + get_effect_stack().effects.read().last().copied() } /// Create a new effect. The effect will be run immediately and whenever any signal it reads changes. @@ -77,6 +90,7 @@ impl Effect { let myself = Self { source: current_scope_id().expect("in a virtual dom"), callback: CopyValue::new(Box::new(callback)), + effect_stack: get_effect_stack(), }; myself.try_run(); @@ -88,11 +102,11 @@ impl Effect { pub fn try_run(&self) { if let Some(mut callback) = self.callback.try_write() { { - get_effect_stack().effects.borrow_mut().push(*self); + self.effect_stack.effects.write().push(*self); } callback(); { - get_effect_stack().effects.borrow_mut().pop(); + self.effect_stack.effects.write().pop(); } } } diff --git a/packages/signals/src/selector.rs b/packages/signals/src/selector.rs index 91ab920c8b..556c8437c9 100644 --- a/packages/signals/src/selector.rs +++ b/packages/signals/src/selector.rs @@ -78,19 +78,21 @@ pub fn selector(mut f: impl FnMut() -> R + 'static) -> ReadOnlySig let effect = Effect { source: current_scope_id().expect("in a virtual dom"), callback: CopyValue::invalid(), + effect_stack: get_effect_stack(), }; { - get_effect_stack().effects.borrow_mut().push(effect); + get_effect_stack().effects.write().push(effect); } state.inner.value.set(SignalData { subscribers: Default::default(), effect_subscribers: Default::default(), update_any: schedule_update_any().expect("in a virtual dom"), value: f(), + effect_stack: get_effect_stack(), }); { - get_effect_stack().effects.borrow_mut().pop(); + get_effect_stack().effects.write().pop(); } effect.callback.value.set(Box::new(move || { diff --git a/packages/signals/src/signal.rs b/packages/signals/src/signal.rs index c35b040314..9b11572b49 100644 --- a/packages/signals/src/signal.rs +++ b/packages/signals/src/signal.rs @@ -11,7 +11,7 @@ use dioxus_core::{ ScopeId, ScopeState, }; -use crate::{CopyValue, Effect}; +use crate::{get_effect_stack, CopyValue, Effect, EffectStack}; /// Creates a new Signal. Signals are a Copy state management solution with automatic dependency tracking. /// @@ -82,6 +82,7 @@ pub(crate) struct SignalData { pub(crate) subscribers: Rc>>, pub(crate) effect_subscribers: Rc>>, pub(crate) update_any: Arc, + pub(crate) effect_stack: EffectStack, pub(crate) value: T, } @@ -144,6 +145,7 @@ impl Signal { effect_subscribers: Default::default(), update_any: schedule_update_any().expect("in a virtual dom"), value, + effect_stack: get_effect_stack(), }), } } @@ -157,6 +159,7 @@ impl Signal { effect_subscribers: Default::default(), update_any: schedule_update_any().expect("in a virtual dom"), value, + effect_stack: get_effect_stack(), }, owner, ), @@ -172,7 +175,7 @@ impl Signal { /// If the signal has been dropped, this will panic. pub fn read(&self) -> Ref { let inner = self.inner.read(); - if let Some(effect) = Effect::current() { + if let Some(effect) = inner.effect_stack.current() { let mut effect_subscribers = inner.effect_subscribers.borrow_mut(); if !effect_subscribers.contains(&effect) { effect_subscribers.push(effect); From ce86aabf262d53cbf8cbf0a5cbb74630725b8970 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 17 Oct 2023 13:02:51 -0500 Subject: [PATCH 2/2] fix clippy --- packages/desktop/src/protocol.rs | 2 +- packages/signals/src/effect.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/desktop/src/protocol.rs b/packages/desktop/src/protocol.rs index 53652f82f2..2f660b7a2f 100644 --- a/packages/desktop/src/protocol.rs +++ b/packages/desktop/src/protocol.rs @@ -153,7 +153,7 @@ fn get_asset_root() -> Option { /// Get the mime type from a path-like string fn get_mime_from_path(trimmed: &Path) -> Result<&'static str> { - if trimmed.ends_with(".svg") { + if trimmed.extension().is_some_and(|ext| ext == "svg") { return Ok("image/svg+xml"); } diff --git a/packages/signals/src/effect.rs b/packages/signals/src/effect.rs index ad950b94bf..307ee98ab2 100644 --- a/packages/signals/src/effect.rs +++ b/packages/signals/src/effect.rs @@ -30,7 +30,7 @@ pub(crate) fn get_effect_stack() -> EffectStack { Some(rt) => rt, None => { let store = EffectStack::default(); - provide_root_context(store.clone()); + provide_root_context(store); store } }