Lots of owork on a calculator example, transparency, etc.
This commit is contained in:
70
lib/reactivity/src/source.rs
Normal file
70
lib/reactivity/src/source.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user