51 friend class ::aria::reactive::Node;
53 NodeHandle() noexcept = default;
54 explicit NodeHandle(Node* node) noexcept;
55 NodeHandle(const NodeHandle& other) noexcept : NodeHandle(other.node_) {}
56 NodeHandle(NodeHandle&& other)
noexcept;
57 NodeHandle& operator=(
const NodeHandle& other)
noexcept;
58 NodeHandle& operator=(NodeHandle&& other)
noexcept;
59 ~NodeHandle() { reset_(); }
61 [[nodiscard]] Node* get() const noexcept {
return node_; }
62 [[nodiscard]] Node& operator*() const noexcept {
return *node_; }
63 [[nodiscard]] Node* operator->() const noexcept {
return node_; }
64 explicit operator bool() const noexcept {
return node_ !=
nullptr; }
65 friend bool operator==(
const NodeHandle& a,
const NodeHandle& b)
noexcept {
66 return a.node_ == b.node_;
70 void reset_() noexcept;
71 void take_(NodeHandle& other) noexcept;
72 Node* node_ =
nullptr;
73 NodeHandle* previous_ =
nullptr;
74 NodeHandle* next_ =
nullptr;
141 friend class detail::NodeHandle;
145 virtual ~Node() noexcept;
155 [[nodiscard]] std::uint64_t
version() const noexcept {
return version_; }
156 [[nodiscard]]
const std::string&
debug_name() const noexcept {
return debug_name_; }
173 if (!debug_name_.empty())
return debug_name_;
174 if (fallback_name_.empty()) {
175 const char*
kind =
nullptr;
181 fallback_name_ = std::string(
kind ?
kind :
"Node")
182 +
"#" + std::to_string(node_id_);
184 return fallback_name_;
188 static Graph& graph() noexcept;
196 void notify_changed();
200 void mark_downstream_maybe_dirty();
208 [[nodiscard]] std::uint32_t
depth() const noexcept {
return depth_; }
209 void set_depth(std::uint32_t d)
noexcept { depth_ = d; }
225 void attach_as_observer_of(
Node& source,
Edge& edge)
noexcept;
226 void detach_edge(
Edge& edge)
noexcept;
230 void clear_sources() noexcept;
244 for (
const Edge* e = sources_head_; e !=
nullptr; e = e->
next_source) {
249 [[nodiscard]]
bool has_observers() const noexcept {
return observers_head_ !=
nullptr; }
250 [[nodiscard]]
bool has_sources() const noexcept {
return sources_head_ !=
nullptr; }
255 void retire_() noexcept;
264 bool queued_ =
false;
265 bool resolving_ =
false;
266 std::uint32_t depth_ = 0;
267 std::uint64_t version_ = 1;
271 Edge* observers_head_ =
nullptr;
272 Edge* sources_head_ =
nullptr;
273 detail::NodeHandle* handles_head_ =
nullptr;
275 std::string debug_name_;
276 mutable std::string fallback_name_;
280 std::uint64_t node_id_ = next_node_id_();
282 ARIA_ABI_API static std::uint64_t next_node_id_() noexcept;
285inline detail::NodeHandle::NodeHandle(
Node* node) noexcept : node_(node) {
287 next_ = node_->handles_head_;
288 if (next_) next_->previous_ =
this;
289 node_->handles_head_ =
this;
292inline void detail::NodeHandle::reset_() noexcept {
294 if (previous_) previous_->next_ = next_;
295 else node_->handles_head_ = next_;
296 if (next_) next_->previous_ = previous_;
298 previous_ = next_ =
nullptr;
301inline void detail::NodeHandle::take_(NodeHandle& other)
noexcept {
303 previous_ = other.previous_;
306 if (previous_) previous_->next_ =
this;
307 else node_->handles_head_ =
this;
308 if (next_) next_->previous_ =
this;
310 other.node_ =
nullptr;
311 other.previous_ = other.next_ =
nullptr;
314inline detail::NodeHandle::NodeHandle(NodeHandle&& other)
noexcept { take_(other); }
316inline detail::NodeHandle& detail::NodeHandle::operator=(
const NodeHandle& other)
noexcept {
317 if (
this != &other) {
318 NodeHandle copy{other};
319 *
this = std::move(copy);
324inline detail::NodeHandle& detail::NodeHandle::operator=(NodeHandle&& other)
noexcept {
325 if (
this != &other) {
Process-wide singleton reactive graph (accessed via Node::graph()).
Definition graph.hpp:139
Common base for every node participating in the reactive graph.
Definition node.hpp:136
void bump_version_() noexcept
Definition node.hpp:258
const std::string & effective_debug_name() const
A non-empty debug label for diagnostic output.
Definition node.hpp:172
bool has_observers() const noexcept
Definition node.hpp:249
void set_debug_name(std::string name)
Definition node.hpp:158
std::uint64_t version() const noexcept
Definition node.hpp:155
void mark_dirty() noexcept
Escalate state to Dirty (used by Graph::pull after confirming an upstream has truly moved).
Definition node.hpp:204
virtual std::shared_ptr< Node > retain_for_recompute() noexcept
Reactions are shared-owned and may cancel themselves while running.
Definition node.hpp:220
void set_depth(std::uint32_t d) noexcept
Definition node.hpp:209
bool has_sources() const noexcept
Definition node.hpp:250
Node(NodeKind kind) noexcept
Definition node.hpp:144
const std::string & debug_name() const noexcept
Definition node.hpp:156
std::uint32_t depth() const noexcept
Topological depth used by flush ordering.
Definition node.hpp:208
void for_each_source(F &&f) const
Iterate the source list (used by a Derivation in pull() to compare each upstream's current version ag...
Definition node.hpp:243
void for_each_observer(F &&f)
Iterate the observer list (used by Graph to color downstream nodes).
Definition node.hpp:234
virtual bool recompute()
Recompute hook for Derivation / Reaction nodes.
Definition node.hpp:216
NodeState state() const noexcept
Definition node.hpp:154
void set_state_(NodeState s) noexcept
Definition node.hpp:259
NodeKind kind() const noexcept
Definition node.hpp:153
friend class Graph
Definition node.hpp:140
Type that participates in the reactive graph: inherits from aria::reactive::Node.
Definition node.hpp:344
#define ARIA_ABI_API
Definition export.hpp:21
Definition computed.hpp:60
NodeState
Definition node.hpp:102
@ Computing
Definition node.hpp:106
@ Clean
Definition node.hpp:103
@ MaybeDirty
Definition node.hpp:104
@ Dirty
Definition node.hpp:105
NodeKind
Definition node.hpp:87
@ Derivation
Definition node.hpp:89
@ Reaction
Definition node.hpp:90
@ Source
Definition node.hpp:88
Definition validation_key.hpp:110
A single dependency edge: (upstream source) -> (downstream observer).
Definition node.hpp:113
Edge * prev_source
Definition node.hpp:125
Node * observer
The downstream node that depends on it.
Definition node.hpp:115
Edge * prev_observer
Definition node.hpp:120
std::uint64_t observed_version
Upstream version observed at the moment this edge was established or last confirmed.
Definition node.hpp:130
Edge * next_observer
Thread in the source's "observers" list (from the source's point of view: "these are the nodes watchi...
Definition node.hpp:119
Edge * next_source
Thread in the observer's "sources" list (from the observer's point of view: "these are the nodes I de...
Definition node.hpp:124
Node * source
The upstream node being observed.
Definition node.hpp:114