morph 0.1.0
Asynchronous bridge between GUI thread and business models
Loading...
Searching...
No Matches
morph::reactive::Scope Class Reference

Owns effects, computeds and adopted objects; destroys them in reverse creation order. More...

#include <scope.hpp>

Public Member Functions

 Scope (Runtime &runtime, std::size_t depth=0) noexcept
 Constructs a scope.
 ~Scope ()
 Destroys everything owned, newest first, and tells every make() still constructing that the scope is gone.
 Scope (Scope const &)=delete
Scope & operator= (Scope const &)=delete
 Scope (Scope &&)=delete
Scope & operator= (Scope &&)=delete
template<typename T, typename... Args>
T & make (Args &&... args)
 Constructs a T from args and owns it.
template<typename T>
T & adopt (std::unique_ptr< T > owned)
 Takes ownership of owned.
template<typename F>
Effect & effect (F &&fn)
 Makes an Effect owned by this scope, at this scope's depth.
Scope & child ()
 Makes a scope one level deeper, owned by this one.
template<typename F>
auto & computed (F &&fn)
 Makes a Computed owned by this scope; its type is what fn returns.
void clear () noexcept
 Destroys everything owned, newest first.
std::size_t size () const noexcept
 How many objects the scope owns.
Runtime & runtime () const noexcept
 The runtime.
std::size_t depth () const noexcept
 How deeply this scope is nested.

Detailed Description

Owns effects, computeds and adopted objects; destroys them in reverse creation order.

A mounted view, a Switch case and a ForEach row each own one, so tearing one down stops every binding it made before anything those bindings point at goes away.

Scopes nest: a scope made by child() is one level deeper, and the Effects a scope makes carry its depth. Queued Effects run shallowest first, so an owner's Effects run before those of the scopes it owns, whatever order the writes came in and whichever Effect was made first: a row binding never evaluates against a parent that is about to remove the row.

An Effect the scope owns may clear or destroy the scope from its own body (a remount): the graph keeps the running body alive, and the body must not touch the scope or anything it owned afterwards. That holds for an Effect's first run too, which happens inside effect() before the scope stores it:

  • If the first run clears the scope, the new Effect is stored after the clear and stays.
  • If it destroys the scope, the new Effect is destroyed at once, since a dead scope owns nothing, and the reference effect() returns dangles (as does every reference to an object the scope owned). That destructor runs after the scope is gone, so it must not use the scope.

Only the nodes check the owner (detail::site::kOffOwner); the scope's own list is unguarded. Using a scope off its Runtime's owner is a misuse that is not reported.

An owned object's destructor may call back into the scope. It leaves the list before it is destroyed. A destructor that keeps calling make() while the scope is clearing never lets clear() finish.

Definition at line 44 of file scope.hpp.

Constructor & Destructor Documentation

◆ Scope()

morph::reactive::Scope::Scope ( Runtime & runtime,
std::size_t depth = 0 )
inlineexplicitnoexcept

Constructs a scope.

Parameters
runtimeThe runtime the nodes made here belong to. Borrowed: it must outlive the scope.
depthHow deeply the scope is nested: zero for a root, one more than its owner's for a scope another owns (child() passes that).

Definition at line 50 of file scope.hpp.

◆ ~Scope()

morph::reactive::Scope::~Scope ( )
inline

Destroys everything owned, newest first, and tells every make() still constructing that the scope is gone.

Definition at line 55 of file scope.hpp.

Member Function Documentation

◆ make()

template<typename T, typename... Args>
T & morph::reactive::Scope::make ( Args &&... args)
inline

Constructs a T from args and owns it.

Template Parameters
TThe object type.
ArgsConstructor argument types.
Parameters
argsForwarded to T's constructor.
Returns
The new object, alive until the scope is cleared or destroyed.

Definition at line 72 of file scope.hpp.

◆ adopt()

template<typename T>
T & morph::reactive::Scope::adopt ( std::unique_ptr< T > owned)
inline

Takes ownership of owned.

Template Parameters
TThe object type.
Parameters
ownedThe object; must not be null.
Returns
The object, alive until the scope is cleared or destroyed.

Definition at line 100 of file scope.hpp.

◆ effect()

template<typename F>
Effect & morph::reactive::Scope::effect ( F && fn)
inline

Makes an Effect owned by this scope, at this scope's depth.

Template Parameters
FA callable taking no arguments.
Parameters
fnThe effect body.
Returns
The Effect.

Definition at line 114 of file scope.hpp.

◆ child()

Scope & morph::reactive::Scope::child ( )
inline

Makes a scope one level deeper, owned by this one.

Returns
The child scope, alive until this scope is cleared or destroyed.

Definition at line 120 of file scope.hpp.

◆ computed()

template<typename F>
auto & morph::reactive::Scope::computed ( F && fn)
inline

Makes a Computed owned by this scope; its type is what fn returns.

Template Parameters
FA callable taking no arguments.
Parameters
fnThe computation.
Returns
The Computed.

Definition at line 127 of file scope.hpp.

◆ clear()

void morph::reactive::Scope::clear ( )
inlinenoexcept

Destroys everything owned, newest first.

Each object leaves the list before it is destroyed, so a destructor or a running Effect body that calls back into the scope (clear(), make()) sees a consistent list.

Definition at line 136 of file scope.hpp.

◆ size()

std::size_t morph::reactive::Scope::size ( ) const
inlinenodiscardnoexcept

How many objects the scope owns.

Returns
The count.

Definition at line 145 of file scope.hpp.

◆ runtime()

Runtime & morph::reactive::Scope::runtime ( ) const
inlinenodiscardnoexcept

The runtime.

Returns
The runtime passed at construction.

Definition at line 149 of file scope.hpp.

◆ depth()

std::size_t morph::reactive::Scope::depth ( ) const
inlinenodiscardnoexcept

How deeply this scope is nested.

Returns
Zero for a root scope; one more than the parent's for a child.

Definition at line 153 of file scope.hpp.


The documentation for this class was generated from the following file: