-
Notifications
You must be signed in to change notification settings - Fork 134
Domain.h
#include "react/Domain.h"
Contains the base class for reactive domains and the macro to define them.
This class contains the functionality for domains defined with REACTIVE_DOMAIN.
A domain cannot be instantiated. It is used to group domain-specific type aliases and static functions.
namespace react
{
template <typename D>
class DomainBase
{
public:
DomainBase() = delete;
// Type aliases for this domain
template <typename S>
using SignalT = Signal<D,S>;
template <typename S>
using VarSignalT = VarSignal<D,S>;
template <typename E = Token>
using EventsT = Events<D,E>;
template <typename E = Token>
using EventSourceT = EventSource<D,E>;
using ObserverT = Observer<D>;
using ReactorT = Reactor<D>;
// Run given function in transaction mode
static void DoTransaction(F&& func);
static void DoTransaction(TurnFlagsT flags, F&& func);
};
}DomainBase() = delete;Deleted default constructor to prevent instantiation.
template <typename F>
static void DoTransaction(F&& func); // (1)
template <typename F>
static void DoTransaction(TurnFlagsT flags, F&& func); // (2)Runs func in transaction mode. During transaction mode, all reactive inputs are collected and propagated in a single turn after func returns.
The purpose of this is
- to ensure consistency, if there exist certain invariants between reactive inputs;
- to avoid redundant re-calculations;
- to avoid the overhead of additional turns.
(1) uses the default turn flags for the transaction. (2) allows to set flags explicitly.
This class contains the functionality for domains defined with REACTIVE_DOMAIN.
A domain cannot be instantiated. It is used to group domain-specific type aliases and static functions.
namespace react
{
template
<
typename TSourceDomain,
typename TTargetDomain
>
class Continuation
{
// Type aliases
using SourceDomainT = TSourceDomain;
using TargetDomainT = TTargetDomain;
// Constructor
Continuation();
Continuation(Continuation&& other);
// Assignemnt
Continuation& operator=(Continuation&& other);
};
}namespace react
{
// Creates a continuation from domain D to D2
Observer<D,D2>
MakeContinuation<D,D2>(const Signal<D,S>& trigger, F&& func);
Observer<D,D2>
MakeContinuation<D,D2>(const Events<D,E>& trigger, F&& func);
Observer<D,D2>
MakeContinuation<D,D2>(const Events<D,E>& trigger,
const SignalPack<D,TDepValues...>& depPack, F&& func);
}// (1)
template
<
typename D,
typename D2 = D,
typename S,
typename FIn
>
Continuation<D,D2> MakeContinuation(const Signal<D,S>& trigger, FIn&& func);
// (2)
template
<
typename D,
typename D2 = D,
typename E,
typename FIn
>
Continuation<D,D2> MakeContinuation(const Events<D,E>& trigger, FIn&& func);
// (3)
template
<
typename D,
typename D2 = D,
typename E,
typename FIn,
typename ... TDepValues
>
Continuation<D,D2>
MakeContinuation(const Events<D,E>& trigger,
const SignalPack<D,TDepValues...>& depPack, FIn&& func);(1) When the signal value s of trigger changes, func(s) is executed in a transaction of domain D2.
As pseudo code:
D2::DoTransaction([func, s] {
func(s)
});(2) For every event e in trigger, func(e) is called in a transaction of domain D2.
Multiple events from the same turn are captured in a single transaction.
As pseudo code:
D2::DoTransaction([func, events] {
for (const auto& e : events)
func(e)
});(3) Similar to (2), but the synchronized values of signals in depPack are passed to func as additional arguments.
Changes of signals in depPack do not trigger an update - only received events do.
As pseudo code:
D2::DoTransaction([func, events, depValues...] {
for (const auto& e : events)
func(e, depValues ...)
});The signature of func should be equivalent to:
- (1)
void func(const S&) - (2)
void func(const E&) - (3)
void func(const E&, const TDepValues& ...)
D2::DoTransaction([func, events, depValues...] {
for (const auto& e : events)
func(e, depValues ...)
});REACTIVE_DOMAIN(name, ...)Defines a reactive domain name, declared as class name : public DomainBase<name>. Also initializes static data for this domain.
The optional parameter is the propagation engine. If omitted, Toposort<sequential> is used as default.
USING_REACTIVE_DOMAIN(name)Defines the following type aliases for the given domain name in the current scope:
template <typename S>
using SignalT = Signal<name,S>;
template <typename S>
using VarSignalT = VarSignal<name,S>;
template <typename E = Token>
using EventsT = Events<name,E>;
template <typename E = Token>
using EventSourceT = EventSource<name,E>;
using ObserverT = Observer<name>;
using ReactorT = Reactor<name>;