Skip to main content

cljrs_runtime/env/
taps.rs

1use cljrs_value::Value;
2use std::cell::RefCell;
3
4struct TapState {
5    fns: Vec<Value>,
6}
7
8thread_local! {
9    static TAP: RefCell<TapState> = const { RefCell::new(TapState { fns: Vec::new() }) };
10}
11
12pub fn add_tap(f: Value) {
13    TAP.with(|tap| {
14        let mut state = tap.borrow_mut();
15        if !state.fns.iter().any(|existing| existing == &f) {
16            state.fns.push(f);
17        }
18    });
19}
20
21pub fn remove_tap(f: &Value) {
22    TAP.with(|tap| {
23        tap.borrow_mut().fns.retain(|existing| existing != f);
24    });
25}
26
27pub fn send(val: Value) -> bool {
28    let fns: Vec<Value> = TAP.with(|tap| tap.borrow().fns.clone());
29    if fns.is_empty() {
30        return false;
31    }
32    for f in &fns {
33        let _ = crate::env::callback::invoke(f, vec![val.clone()]);
34    }
35    true
36}
37
38/// Trace all GcPtr values in the tap system as GC roots.
39pub fn trace_roots(visitor: &mut cljrs_gc::MarkVisitor) {
40    use cljrs_gc::Trace;
41    TAP.with(|tap| {
42        for val in &tap.borrow().fns {
43            val.trace(visitor);
44        }
45    });
46}