morph 0.1.0
Asynchronous bridge between GUI thread and business models
Loading...
Searching...
No Matches
effects.hpp File Reference
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iterator>
#include <map>
#include <mutex>
#include <optional>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <utility>
#include <vector>
#include "detail/result_walker.hpp"
#include "records.hpp"
#include "registry.hpp"

Go to the source code of this file.

Classes

struct  morph::model::EffectsRegistrationError
 Thrown on a read of the effects or record registry when the registered configuration is invalid. More...
struct  morph::effects::updates< R >
 Effect: the action edits existing rows of record R, and its result carries them. More...
struct  morph::effects::changes< R >
 Effect: the action may create, remove or change rows of record R, which its result need not carry. More...
struct  morph::effects::changesInstance
 Effect: the state of the instance the action ran on changed. More...
struct  morph::effects::none
 Effect: the action changes nothing, declared explicitly. More...
struct  morph::effects::Effect
 One effect of an action, with its record resolved to a wire name. More...
struct  morph::effects::ActionRecord
 A record an action's result holds, and where. More...
struct  morph::effects::detail::DeclaredEffect
 One effect as a registrar records it: the record still a type, not yet a name. More...
struct  morph::effects::detail::EffectOf< E >
 Maps an effect tag type to its DeclaredEffect. More...
struct  morph::effects::detail::Resolved
 The matched and validated registries: what every read is answered from. More...

Macros

#define BRIDGE_REGISTER_EFFECTS(A, ...)
 Declares what action A changes: any of morph::effects::updates<R>, changes<R>, changesInstance and none.

Typedefs

using morph::effects::detail::EffectsMap = std::map<std::string, std::vector<std::vector<DeclaredEffect>>, std::less<>>
 Every distinct effects declaration, by action id. More than one for an id is a conflict.

Enumerations

enum class  morph::effects::Kind : std::uint8_t { Updates , Changes , ChangesInstance , None }
 The kind of one declared effect. More...

Functions

void morph::effects::detail::addEffects (EffectsMap &map, std::string_view actionId, std::vector< DeclaredEffect > declared)
 Adds one declaration for an action, unless an equal one is already there.
EffectsMap & morph::effects::detail::mutableEffectsRegistry ()
 The process-level effects registry, appended to by static registrars.
template<typename Action, typename... E>
bool morph::effects::detail::registerEffectsOnce () noexcept
 Static-init helper for BRIDGE_REGISTER_EFFECTS.
bool morph::effects::detail::pathWithin (std::string_view prefix, std::string_view path)
 Whether prefix is path or a JSON path that contains it.
bool morph::effects::detail::sameRegistration (record::RecordInfo const &lhs, record::RecordInfo const &rhs)
 Whether two registrations of one record type declared the same record.
void morph::effects::detail::findDerivationCycles (std::vector< record::RecordInfo > const &records, std::map< std::type_index, std::size_t > const &indexOf, std::vector< std::string > &problems)
 Appends a problem for every derivedFrom cycle among the records.
Resolved morph::effects::detail::resolve (std::vector< record::RecordInfo > records, model::detail::ActionResultSlotMap const &resultSlots, EffectsMap const &declared, std::vector< std::string > const &slotConflicts)
 Matches action results against records and validates the configuration.
Resolved morph::effects::detail::resolveForTesting (std::vector< record::RecordInfo > records, model::detail::ActionResultSlotMap const &resultSlots, EffectsMap const &declared, std::vector< std::string > const &slotConflicts={})
 Resolves a registry built by a test, leaving the process registry untouched.
Resolved const & morph::effects::detail::resolved ()
 The process registries, matched and validated on the first call.
std::optional< std::vector< Effect > > morph::effects::effectsOf (std::string_view actionId)
 The effects an action declared.
std::vector< ActionRecord > morph::effects::recordsOf (std::string_view actionId)
 The records an action's result holds, with the paths to each.
record::RecordInfo const * morph::effects::recordNamed (std::string_view name)
 A registered record, by wire name.
std::vector< std::string > morph::effects::actionsHolding (std::string_view record)
 The actions whose result holds a record: those whose recordsOf names it.

Detailed Description

What an action changes, and which records its result holds.

BRIDGE_REGISTER_EFFECTS records an action's effects as data under its id. Nothing is matched or checked at registration, so the order of record, action and effects registrations across translation units does not matter. The first read through effectsOf, recordsOf, recordNamed or actionsHolding matches every action's result slots against the record registry and validates the whole configuration, once. A configuration with problems throws morph::model::EffectsRegistrationError naming all of them, on that read and on every later one.

Definition in file effects.hpp.

Macro Definition Documentation

◆ BRIDGE_REGISTER_EFFECTS

#define BRIDGE_REGISTER_EFFECTS ( A,
... )
Value:
namespace { \
[[maybe_unused]] const bool BRIDGE_DETAIL_CAT(bridge_effects_reg_, __COUNTER__) = \
morph::effects::detail::registerEffectsOnce<A, __VA_ARGS__>(); \
}

Declares what action A changes: any of morph::effects::updates<R>, changes<R>, changesInstance and none.

Place it beside the action's registration, where ActionTraits<A> is visible. It defines no specialisation, so a translation unit that does not see it is consistent with one that does. Repeating the same effects is a no-op; different effects for one action are refused on the first read. Expands to nothing under MORPH_CLIENT_ONLY.

Parameters
AThe action type.
...The effects.

Definition at line 588 of file effects.hpp.

Typedef Documentation

◆ EffectsMap

using morph::effects::detail::EffectsMap = std::map<std::string, std::vector<std::vector<DeclaredEffect>>, std::less<>>

Every distinct effects declaration, by action id. More than one for an id is a conflict.

Definition at line 144 of file effects.hpp.

Enumeration Type Documentation

◆ Kind

enum class morph::effects::Kind : std::uint8_t
strong

The kind of one declared effect.

Enumerator
Updates 

updates<R>

Changes 

changes<R>

ChangesInstance 

changesInstance

None 

none

Definition at line 90 of file effects.hpp.

Function Documentation

◆ addEffects()

void morph::effects::detail::addEffects ( EffectsMap & map,
std::string_view actionId,
std::vector< DeclaredEffect > declared )
inline

Adds one declaration for an action, unless an equal one is already there.

A declaration is a set: a repeated effect is stored once, and two declarations holding the same effects in any order are equal, so one repeated in several translation units is stored once.

Parameters
mapThe registry to add to.
actionIdThe action's id.
declaredThe effects.

Definition at line 186 of file effects.hpp.

◆ mutableEffectsRegistry()

EffectsMap & morph::effects::detail::mutableEffectsRegistry ( )
inline

The process-level effects registry, appended to by static registrars.

Returns
The mutable map.

Definition at line 208 of file effects.hpp.

◆ registerEffectsOnce()

template<typename Action, typename... E>
bool morph::effects::detail::registerEffectsOnce ( )
inlinenoexcept

Static-init helper for BRIDGE_REGISTER_EFFECTS.

Template Parameters
ActionThe action type; ActionTraits<Action> must be visible.
EThe effect tags.
Returns
Always true, so the result can initialise a namespace-scope variable.

Definition at line 218 of file effects.hpp.

◆ pathWithin()

bool morph::effects::detail::pathWithin ( std::string_view prefix,
std::string_view path )
inlinenodiscard

Whether prefix is path or a JSON path that contains it.

Parameters
prefixA shorter path; "" contains every path.
pathThe path.
Returns
True when path is at or below prefix.

Definition at line 285 of file effects.hpp.

◆ sameRegistration()

bool morph::effects::detail::sameRegistration ( record::RecordInfo const & lhs,
record::RecordInfo const & rhs )
inlinenodiscard

Whether two registrations of one record type declared the same record.

Parameters
lhsOne registration.
rhsThe other.
Returns
True when name, key, sources and privacy all match.

Definition at line 296 of file effects.hpp.

◆ findDerivationCycles()

void morph::effects::detail::findDerivationCycles ( std::vector< record::RecordInfo > const & records,
std::map< std::type_index, std::size_t > const & indexOf,
std::vector< std::string > & problems )
inline

Appends a problem for every derivedFrom cycle among the records.

Parameters
recordsThe records, one registration per type.
indexOfEach record type's first registration.
problemsWhere to append.

Definition at line 306 of file effects.hpp.

◆ resolve()

Resolved morph::effects::detail::resolve ( std::vector< record::RecordInfo > records,
model::detail::ActionResultSlotMap const & resultSlots,
EffectsMap const & declared,
std::vector< std::string > const & slotConflicts )
inlinenodiscard

Matches action results against records and validates the configuration.

Parameters
recordsThe records, as registered.
resultSlotsEvery action's result slots, by action id.
declaredEvery action's effects declarations, by action id.
slotConflictsAction ids registered by more than one action type.
Returns
The resolved registries.
Exceptions
morph::model::EffectsRegistrationErrorlisting every problem, when there is one.

Definition at line 350 of file effects.hpp.

◆ resolveForTesting()

Resolved morph::effects::detail::resolveForTesting ( std::vector< record::RecordInfo > records,
model::detail::ActionResultSlotMap const & resultSlots,
EffectsMap const & declared,
std::vector< std::string > const & slotConflicts = {} )
inlinenodiscard

Resolves a registry built by a test, leaving the process registry untouched.

Parameters
recordsThe records.
resultSlotsThe action result slots, by action id.
declaredThe effects declarations, by action id.
slotConflictsAction ids registered by more than one action type.
Returns
The resolved registries.
Exceptions
morph::model::EffectsRegistrationErrorlisting every problem, when there is one.

Definition at line 496 of file effects.hpp.

◆ resolved()

Resolved const & morph::effects::detail::resolved ( )
inlinenodiscard

The process registries, matched and validated on the first call.

Every call is a read of a process-level registry and closes the registration latch in a debug build. The first call resolves, under std::call_once; an invalid configuration's error is kept and thrown again on every call.

Returns
The resolved registries.
Exceptions
morph::model::EffectsRegistrationErrorwhen the registered configuration is invalid.

Definition at line 511 of file effects.hpp.

◆ effectsOf()

std::optional< std::vector< Effect > > morph::effects::effectsOf ( std::string_view actionId)
inlinenodiscard

The effects an action declared.

Parameters
actionIdThe action's id.
Returns
Its effects, or nullopt when it declared none: the action reads.
Exceptions
morph::model::EffectsRegistrationErrorwhen the registered configuration is invalid.

Definition at line 539 of file effects.hpp.

◆ recordsOf()

std::vector< ActionRecord > morph::effects::recordsOf ( std::string_view actionId)
inlinenodiscard

The records an action's result holds, with the paths to each.

Each path stops at the first registered record on it, so the members of a record are not searched for further records.

Parameters
actionIdThe action's id.
Returns
One entry per record, in the order their first path sorts; empty for an unknown action.
Exceptions
morph::model::EffectsRegistrationErrorwhen the registered configuration is invalid.

Definition at line 550 of file effects.hpp.

◆ recordNamed()

record::RecordInfo const * morph::effects::recordNamed ( std::string_view name)
inlinenodiscard

A registered record, by wire name.

Parameters
nameThe record's wire name.
Returns
The record, valid for the life of the process, or null when no record has that name.
Exceptions
morph::model::EffectsRegistrationErrorwhen the registered configuration is invalid.

Definition at line 558 of file effects.hpp.

◆ actionsHolding()

std::vector< std::string > morph::effects::actionsHolding ( std::string_view record)
inlinenodiscard

The actions whose result holds a record: those whose recordsOf names it.

Parameters
recordThe record's wire name.
Returns
The action ids, in id order; empty for a record no result holds.
Exceptions
morph::model::EffectsRegistrationErrorwhen the registered configuration is invalid.

Definition at line 566 of file effects.hpp.