diff --git a/dynatos-reactive/src/effect.rs b/dynatos-reactive/src/effect.rs index 9078c65..8ee17fe 100644 --- a/dynatos-reactive/src/effect.rs +++ b/dynatos-reactive/src/effect.rs @@ -3,7 +3,7 @@ //! An effect is a function that is re-run whenever //! one of it's dependencies changes. -// TODO: Downcasting? It isn't trivial due to the usages of `Rc>`, +// TODO: Downcasting? It isn't trivial due to the usages of `Rc>`, // which doesn't allow casting to `Rc`, required by `Rc::downcast`. // Imports @@ -69,7 +69,7 @@ impl Effect { #[track_caller] pub fn new(run: F) -> Self where - F: Fn() + 'static, + F: EffectRun + 'static, { Self::new_in(run, WorldDefault::default()) } @@ -89,7 +89,7 @@ impl Effect { #[track_caller] pub fn try_new(run: F) -> Option where - F: Fn() + 'static, + F: EffectRun + 'static, { Self::try_new_in(run, WorldDefault::default()) } @@ -102,7 +102,7 @@ impl Effect { #[track_caller] pub fn new_in(run: F, world: W) -> Self where - F: Fn() + UnsizeF + 'static, + F: EffectRun + UnsizeF + 'static, { // Create the effect let effect = Self::new_raw_in(run, world); @@ -140,7 +140,7 @@ impl Effect { #[track_caller] pub fn try_new_in(run: F, world: W) -> Option where - F: Fn() + UnsizeF + 'static, + F: EffectRun + UnsizeF + 'static, { let effect = Self::new_in(run, world); match effect.is_inert() { @@ -220,7 +220,7 @@ impl Effect { /// Runs the effect pub fn run(&self) where - F: Fn() + UnsizeF + 'static, + F: EffectRun + UnsizeF + 'static, { // If we're suppressed, don't do anything if self.inner.suppressed.load(atomic::Ordering::Acquire) { @@ -228,7 +228,7 @@ impl Effect { } // Otherwise, run it - self.gather_dependencies(move || (self.inner.run)()); + self.gather_dependencies(move || self.inner.run.run()); } /// Suppresses this effect from running while calling this function @@ -342,7 +342,7 @@ impl WeakEffect { /// Returns if the effect still existed pub fn try_run(&self) -> bool where - F: Fn() + UnsizeF + 'static, + F: EffectRun + UnsizeF + 'static, { // Try to upgrade, else return that it was missing let Some(effect) = self.upgrade() else { @@ -424,6 +424,20 @@ pub fn running() -> Option, W>> { world::top_effect::() } +/// Effect run +pub trait EffectRun { + /// Runs the effect + fn run(&self); +} + +impl EffectRun for F +where + F: Fn(), +{ + fn run(&self) { + self(); + } +} #[cfg(test)] mod test { @@ -455,7 +469,7 @@ mod test { #[test] fn running() { #[thread_local] - static RUNNING: OnceCell> = OnceCell::new(); + static RUNNING: OnceCell> = OnceCell::new(); // Create an effect, and save the running effect within it to `RUNNING`. let effect = Effect::new(move || { @@ -478,10 +492,10 @@ mod test { #[test] fn running_stacked() { #[thread_local] - static RUNNING_TOP: OnceCell> = OnceCell::new(); + static RUNNING_TOP: OnceCell> = OnceCell::new(); #[thread_local] - static RUNNING_BOTTOM: OnceCell> = OnceCell::new(); + static RUNNING_BOTTOM: OnceCell> = OnceCell::new(); // Create 2 stacked effects, saving the running within each to `running1` and `running2`. // `running1` contains the top-level effect, while `running2` contains the inner one. diff --git a/dynatos-reactive/src/lib.rs b/dynatos-reactive/src/lib.rs index 5275aea..bfe0bcd 100644 --- a/dynatos-reactive/src/lib.rs +++ b/dynatos-reactive/src/lib.rs @@ -31,7 +31,7 @@ pub mod world; pub use self::{ async_signal::AsyncSignal, derived::Derived, - effect::{Effect, WeakEffect}, + effect::{Effect, EffectRun, WeakEffect}, memo::Memo, signal::{ Signal, diff --git a/dynatos-reactive/src/world/effect_stack.rs b/dynatos-reactive/src/world/effect_stack.rs index edb7726..2561fa5 100644 --- a/dynatos-reactive/src/world/effect_stack.rs +++ b/dynatos-reactive/src/world/effect_stack.rs @@ -2,7 +2,7 @@ // Imports use { - crate::{effect::EffectWorld, ReactiveWorld, WeakEffect}, + crate::{effect::EffectWorld, EffectRun, ReactiveWorld, WeakEffect}, core::marker::Unsize, dynatos_world::{IMut, IMutLike, WorldGlobal, WorldThreadLocal}, }; @@ -10,7 +10,7 @@ use { /// Effect stack pub trait EffectStack: Sized { /// Effect function - type F: ?Sized + Fn() + Unsize + 'static; + type F: ?Sized + EffectRun + Unsize + 'static; /// Pushes an effect to the stack. fn push_effect(f: WeakEffect) @@ -35,11 +35,11 @@ pub struct EffectStackThreadLocal; /// Effect stack for `EffectStackThreadLocal` #[thread_local] -static EFFECT_STACK_STD_RC: EffectStackImpl = +static EFFECT_STACK_STD_RC: EffectStackImpl = EffectStackImpl::<_, WorldThreadLocal>::new(vec![]); impl EffectStack for EffectStackThreadLocal { - type F = dyn Fn() + 'static; + type F = dyn EffectRun + 'static; fn push_effect(f: WeakEffect) where @@ -61,12 +61,12 @@ impl EffectStack for EffectStackThreadLocal { pub struct EffectStackGlobal; /// Effect stack for `EffectStackGlobal` -static EFFECT_STACK_STD_ARC: EffectStackImpl = +static EFFECT_STACK_STD_ARC: EffectStackImpl = EffectStackImpl::<_, WorldGlobal>::new(vec![]); impl EffectStack for EffectStackGlobal { - type F = dyn Fn() + Send + Sync + 'static; + type F = dyn EffectRun + Send + Sync + 'static; fn push_effect(f: WeakEffect) where