Skip to content

Commit

Permalink
Add batch (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
MinusGix authored Nov 1, 2023
1 parent f72679a commit d552d7e
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 3 deletions.
1 change: 1 addition & 0 deletions reactive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ edition = "2021"
license.workspace = true

[dependencies]
smallvec = "1.10.0"
13 changes: 13 additions & 0 deletions reactive/src/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ pub fn untrack<T>(f: impl FnOnce() -> T) -> T {
result
}

pub fn batch<T>(f: impl FnOnce() -> T) -> T {
RUNTIME.with(|runtime| {
runtime.batching.set(true);
});
let result = f();
RUNTIME.with(|runtime| {
runtime.batching.set(false);
runtime.run_pending_effects();
});

result
}

pub(crate) fn run_effect(effect: Rc<dyn EffectTrait>) {
let effect_id = effect.id();
effect_id.dispose();
Expand Down
2 changes: 1 addition & 1 deletion reactive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod signal;
mod trigger;

pub use context::{provide_context, use_context};
pub use effect::{create_effect, untrack};
pub use effect::{batch, create_effect, untrack};
pub use memo::{create_memo, Memo};
pub use scope::{as_child_of_current_scope, with_scope, Scope};
pub use signal::{create_rw_signal, create_signal, ReadSignal, RwSignal, WriteSignal};
Expand Down
32 changes: 30 additions & 2 deletions reactive/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
use std::{
any::{Any, TypeId},
cell::RefCell,
cell::{Cell, RefCell},
collections::{HashMap, HashSet},
rc::Rc,
};

use crate::{effect::EffectTrait, id::Id, signal::Signal};
use smallvec::SmallVec;

use crate::{
effect::{run_effect, EffectTrait},
id::Id,
signal::Signal,
};

thread_local! {
pub(crate) static RUNTIME: Runtime = Runtime::new();
Expand All @@ -19,6 +25,8 @@ pub(crate) struct Runtime {
pub(crate) children: RefCell<HashMap<Id, HashSet<Id>>>,
pub(crate) signals: RefCell<HashMap<Id, Signal>>,
pub(crate) contexts: RefCell<HashMap<TypeId, Box<dyn Any>>>,
pub(crate) batching: Cell<bool>,
pub(crate) pending_effects: RefCell<SmallVec<[Rc<dyn EffectTrait>; 10]>>,
}

impl Default for Runtime {
Expand All @@ -35,6 +43,26 @@ impl Runtime {
children: RefCell::new(HashMap::new()),
signals: Default::default(),
contexts: Default::default(),
batching: Cell::new(false),
pending_effects: RefCell::new(SmallVec::new()),
}
}

pub(crate) fn add_pending_effect(&self, effect: Rc<dyn EffectTrait>) {
let has_effect = self
.pending_effects
.borrow()
.iter()
.any(|e| e.id() == effect.id());
if !has_effect {
self.pending_effects.borrow_mut().push(effect);
}
}

pub(crate) fn run_pending_effects(&self) {
let pending_effects = self.pending_effects.take();
for effect in pending_effects {
run_effect(effect);
}
}
}
10 changes: 10 additions & 0 deletions reactive/src/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,16 @@ impl Signal {
}

pub(crate) fn run_effects(&self) {
// If we are batching then add it as a pending effect
if RUNTIME.with(|r| r.batching.get()) {
RUNTIME.with(|r| {
for (_, subscriber) in self.subscribers() {
r.add_pending_effect(subscriber);
}
});
return;
}

for (_, subscriber) in self.subscribers() {
run_effect(subscriber);
}
Expand Down

0 comments on commit d552d7e

Please sign in to comment.