Folds values from an event stream into a signal.
// (1)
template
<
typename D,
typename E,
typename V,
typename F,
typename S = decay<V>::type
>
Signal<D,S> Iterate(const Events<D,E>& events, V&& init, F&& func);
// (2)
template
<
typename D,
typename E,
typename V,
typename F,
typename ... TDepValues,
typename S = decay<V>::type
>
Signal<D,S> Iterate(const Events<D,E>& events, V&& init,
const SignalPack<D,TDepValues...>& depPack, F&& func);
(1) Creates a signal with an initial value v = init
.
If the return type of func
is S
: For every received event e
in events
, v
is updated to v = func(e,v)
.
If the return type of func
is void
: For every received event e
in events
, v
is passed by non-cost reference to func(e,v)
, making it mutable.
This variant can be used if copying and comparing S
is prohibitively expensive.
Because the old and new values cannot be compared, updates will always trigger a change.
(2) Similar to (1), 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.
The signature of func
should be equivalent to:
S func(const E&, const S&)
void func(const E&, S&)
S func(const E&, const S&, const TDepValues& ...)
void func(const E&, S&, const TDepValues& ...)
The event parameter const E&
can also be replaced by an event range, i.e. S func(EventRange<E> range, const S&)
for case (1a).
This allows for explicit batch processing of events of a single turn.
(1a)
(2a)