|
morph 0.1.0
Asynchronous bridge between GUI thread and business models
|
A derived value: computed lazily on first read, cached, and recomputed only after a source it read really changed. More...
#include <signal.hpp>
Public Member Functions | |
| template<typename F> requires std::invocable<F&> && std::move_constructible<F> && std::convertible_to<std::invoke_result_t<F&>, T> | |
| Computed (Runtime &runtime, F fn, EqualityPolicy policy=EqualityPolicy::Auto) | |
| Constructs the Computed without computing it: the first read does. | |
| Computed (Computed const &)=delete | |
| Computed & | operator= (Computed const &)=delete |
| Computed (Computed &&)=delete | |
| Computed & | operator= (Computed &&)=delete |
| T const & | get () const |
| Reads the value, bringing it up to date first, and subscribes the innermost tracked run. | |
| T const & | peek () const |
| Reads the value, bringing it up to date first, without subscribing anything. | |
| Public Member Functions inherited from morph::reactive::detail::Node | |
| Node (std::shared_ptr< RuntimeCore > core, std::size_t depth=0) | |
| Constructs a node. Off the owner this is reported (site::kOffOwner) and the node is not counted towards the core's live nodes, whose counter belongs to the owner. | |
| virtual | ~Node () |
| Unlinks this node from its sources and observers, drops every reference the core holds to it, and tells a pull running on it that it is gone. | |
| Node (Node const &)=delete | |
| Node & | operator= (Node const &)=delete |
| Node (Node &&)=delete | |
| Node & | operator= (Node &&)=delete |
| void | markStale (Colour colour) |
Push phase: raises this node to colour and marks its observers Check. | |
| bool | updateIfNecessary () |
| Pull phase: brings this node up to date, recomputing only if a source really changed. | |
| std::size_t | countRun (std::uint64_t epoch) noexcept |
Counts one run of this Effect in the flush numbered epoch. | |
| std::size_t | depth () const noexcept |
| How deeply the scope owning this node is nested; the flush runs shallower Effects first. | |
| bool | runsAfter (Node const &other) const noexcept |
Whether this node runs after other when both are queued: it is deeper, or as deep and newer. | |
| std::uint64_t | creationOrder () const noexcept |
| Where this node stands in its runtime's creation order; among Effects of one depth, the flush runs older ones first. | |
| void | settle () noexcept |
| Marks this node Clean without running it (a dropped queue entry). | |
Additional Inherited Members | |
| Protected Member Functions inherited from morph::reactive::detail::Node | |
| RuntimeCore & | core () const noexcept |
| The runtime core. | |
| bool | bornOnOwner () const noexcept |
| Whether this node was constructed on the owner; one that was not is refused its work. | |
| void | trackRead () const |
| Registers this node as a source of the innermost tracked run, if any. | |
| void | forceDirty () noexcept |
| Marks this node Dirty, so the next pull recomputes it. | |
| bool | isPulling () const noexcept |
| Whether a pull is bringing this node up to date right now. A read of the node from inside that pull can only come from its own run or from a source's run that reads it: a cycle. | |
| void | markObserversStale (Colour colour) |
Marks every observer of this node colour. | |
| void | adoptSources (std::vector< Node * > fresh) |
Replaces this node's sources with fresh, unlinking the ones no longer read. | |
| void | mergeSources (std::vector< Node * > fresh) |
Adds fresh to this node's sources without dropping any: what a failed run keeps. | |
A derived value: computed lazily on first read, cached, and recomputed only after a source it read really changed.
Observers are notified when the result changes. When == is usable for T (kEqualityUsable) and the policy is EqualityPolicy::Auto, an equal result stops propagation; otherwise every recomputation propagates.
A computation that throws leaves the Computed failed, and that is a change: observers re-run. While it is failed, a read behaves as follows:
A retry that fails again counts as unchanged and notifies nobody, so readers that retry do not wake each other. A failure after a source changed always propagates, as does a recovery, even to the value the Computed had before it failed, because its observers last saw a failure. A retry that recovers outside a flush posts one, so the observers it wakes run. A failed run keeps every source it has read, before and during that run, so a later change to any of them recomputes it.
Writing a signal inside the computation is reported and refused. So is reading the Computed while it is being brought up to date: from inside its own computation, or from the computation of a node it reads (a cycle, which may form only after the first evaluation). Such a read throws std::logic_error.
A computation may destroy its own Computed: the callable stays alive until it returns, and the Computed is not touched afterwards.
| T | The value type; move-constructible. It need not be default-constructible. |
Definition at line 168 of file signal.hpp.
|
inline |
Constructs the Computed without computing it: the first read does.
| F | A callable taking no arguments and returning something convertible to T; it may be move-only. |
| runtime | The runtime this computed belongs to. |
| fn | The computation; every signal or computed it reads becomes a dependency. |
| policy | Whether a result equal to the last one stops propagation. |
Definition at line 178 of file signal.hpp.
|
inlinenodiscard |
Reads the value, bringing it up to date first, and subscribes the innermost tracked run.
Off the owner the read is reported (detail::site::kOffOwner) and refused: it recomputes nothing and subscribes nothing, and returns the value the last successful computation produced, read without synchronisation against the owner.
| Whatever | the computation throws. std::logic_error when the Computed is read while it is being brought up to date (reported, detail::site::kComputedReadsItself), when its computation destroys it, or off the owner when it has never been computed successfully. |
Definition at line 198 of file signal.hpp.
|
inlinenodiscard |
Reads the value, bringing it up to date first, without subscribing anything.
Off the owner it behaves as get() does there.
| Whatever | get() throws. |
Definition at line 212 of file signal.hpp.