Lots of owork on a calculator example, transparency, etc.

This commit is contained in:
2026-05-16 16:18:55 -04:00
parent e2c2563b7e
commit 6dcc2d0d00
40 changed files with 5783 additions and 125 deletions

View File

@@ -0,0 +1,70 @@
use alloc::rc::Rc;
use crate::{NodeId, Reactor, current, trace_targets};
/// Creates a low-level reactive source node in the current reactor.
pub fn source() -> Source {
current().source()
}
/// Creates a low-level reactive source node associated with `reactor`.
pub fn source_in(reactor: &Reactor) -> Source {
reactor.source()
}
/// Low-level observable source node.
///
/// `Source` is useful for advanced data structures that want precise control over when reads
/// observe and writes trigger invalidation without storing their state in a [`crate::Cell`].
#[derive(Clone)]
pub struct Source {
inner: Rc<SourceInner>,
}
impl Reactor {
/// Creates a low-level source node associated with this reactor.
pub fn source(&self) -> Source {
Source::new(self.clone())
}
}
impl Source {
fn new(reactor: Reactor) -> Self {
let id = reactor.allocate_node();
tracing::debug!(
target: trace_targets::GRAPH,
event = "create_source",
node_id = id.0,
"created low-level reactive source"
);
Self {
inner: Rc::new(SourceInner { reactor, id }),
}
}
/// Records a dependency on this source for the currently running observer.
pub fn observe(&self) {
self.inner.reactor.observe(self.inner.id);
}
/// Triggers this source's dependents.
pub fn trigger(&self) {
self.inner.reactor.trigger(self.inner.id);
}
/// Returns the source node id.
pub fn id(&self) -> NodeId {
self.inner.id
}
}
struct SourceInner {
reactor: Reactor,
id: NodeId,
}
impl Drop for SourceInner {
fn drop(&mut self) {
self.reactor.dispose(self.id);
}
}