|
Aria 2.0.0
C++23 MVVM framework (C++20 minimum) — reactive, coroutine-first, ABI-layered
|
#include <computed.hpp>
Public Types | |
| using | value_type = T |
Public Member Functions | |
| template<std::invocable<> Fn> requires std::convertible_to<std::invoke_result_t<Fn>, T> | |
| Computed (Fn fn) | |
| Construct and perform the initial compute eagerly, so get() immediately returns the correct value without any flush. | |
| Computed (const Computed &)=delete | |
| Computed & | operator= (const Computed &)=delete |
| Computed (Computed &&)=delete | |
| Computed & | operator= (Computed &&)=delete |
| ~Computed () noexcept override | |
| Explicit destructor: detach every upstream edge before the edge pool releases the storage backing them. | |
| T | get () const |
| Return the cached value, ensuring it is up to date. | |
| const T & | get_ref () const |
| Read by const reference. | |
| T | peek () const noexcept(std::is_nothrow_copy_constructible_v< T >) |
| Non-tracking snapshot read. | |
| const T & | peek_ref () const noexcept |
| Non-tracking snapshot read by const reference. | |
| operator T () const | |
| ::aria::Subscription | on_changed (std::function< void(const T &)> fn) |
| ::aria::Subscription | bind (std::function< void(const T &)> fn) |
| ::aria::Subscription | observe (std::function< void(const T &, const T &)> fn) |
| bool | recompute () override |
| Called by the Graph when an upstream has changed. | |
| std::size_t | dependency_count () const noexcept |
| Number of upstreams currently in use. | |
| Public Member Functions inherited from aria::reactive::Node | |
| Node (NodeKind kind) noexcept | |
| virtual | ~Node () noexcept |
| Node (const Node &)=delete | |
| Node & | operator= (const Node &)=delete |
| Node (Node &&)=delete | |
| Node & | operator= (Node &&)=delete |
| NodeKind | kind () const noexcept |
| NodeState | state () const noexcept |
| std::uint64_t | version () const noexcept |
| const std::string & | debug_name () const noexcept |
| void | set_debug_name (std::string name) |
| const std::string & | effective_debug_name () const |
| A non-empty debug label for diagnostic output. | |
| void | notify_changed () |
| Called by a Source after its value has actually changed: bumps the version and colors all downstream nodes MaybeDirty. | |
| void | mark_downstream_maybe_dirty () |
| Mark self and all reachable descendants as MaybeDirty. | |
| void | mark_dirty () noexcept |
| Escalate state to Dirty (used by Graph::pull after confirming an upstream has truly moved). | |
| std::uint32_t | depth () const noexcept |
| Topological depth used by flush ordering. | |
| void | set_depth (std::uint32_t d) noexcept |
| virtual std::shared_ptr< Node > | retain_for_recompute () noexcept |
| Reactions are shared-owned and may cancel themselves while running. | |
| void | attach_as_observer_of (Node &source, Edge &edge) noexcept |
| void | detach_edge (Edge &edge) noexcept |
| void | clear_sources () noexcept |
| Drop every upstream edge. | |
| template<class F> | |
| void | for_each_observer (F &&f) |
| Iterate the observer list (used by Graph to color downstream nodes). | |
| template<class F> | |
| void | for_each_source (F &&f) const |
| Iterate the source list (used by a Derivation in pull() to compare each upstream's current version against observed_version). | |
| bool | has_observers () const noexcept |
| bool | has_sources () const noexcept |
Additional Inherited Members | |
| Static Public Member Functions inherited from aria::reactive::Node | |
| static Graph & | graph () noexcept |
| Returns the process-wide singleton Graph this node belongs to. | |
| Protected Member Functions inherited from aria::reactive::Node | |
| void | retire_ () noexcept |
| Retire before derived members (including user captures) are destroyed. | |
| void | bump_version_ () noexcept |
| void | set_state_ (NodeState s) noexcept |
| using aria::reactive::Computed< T >::value_type = T |
|
inlineexplicit |
Construct and perform the initial compute eagerly, so get() immediately returns the correct value without any flush.
A deliberate choice: eager first-run keeps observer semantics simple (observers never see "empty" / default-constructed state).
|
delete |
|
delete |
|
inlineoverridenoexcept |
Explicit destructor: detach every upstream edge before the edge pool releases the storage backing them.
If we rely on the default destruction sequence, edge_pool_ (a derived-class member) runs first and frees every Edge object; then ~Node() would call clear_sources() and dereference the already-freed list head -> classic use-after-free SIGSEGV.
|
delete |
|
delete |
|
inlinenodiscard |
Return the cached value, ensuring it is up to date.
If the graph has pending changes that could affect us, we pull ourselves first so the caller always sees a glitch-free value.
|
inlinenodiscard |
Read by const reference.
Same semantics as get() (auto-tracking
|
inlinenodiscardnoexcept |
Non-tracking snapshot read.
noexcept is conditional on T's copy ctor; if T may throw we still don't want to terminate.
|
inlinenodiscardnoexcept |
Non-tracking snapshot read by const reference.
|
inline |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
inlineoverridevirtual |
Called by the Graph when an upstream has changed.
Re-establishes edges from scratch using a fresh TrackingContext and commits the new value, returning true iff the cached value actually moved.
Exception safety: if the user-supplied compute_() throws, we MUST keep the previous edge set intact — otherwise this Computed becomes orphaned in the graph and never recomputes again, even after the upstream stabilises. We achieve this by computing the new value FIRST under a temporary tracker (without touching our existing edges), and only swapping edges in once the user code has succeeded.
Reimplemented from aria::reactive::Node.
|
inlinenodiscardnoexcept |
Number of upstreams currently in use.
Exposed for diagnostics / tests; not part of the user-facing API surface.