Skip to content

Trigger

Binds a reaction to fire every time a given type is emitted, providing the most recent data.

Syntax

on<Trigger<T>>().then([](const T& value) { /* ... */ });

on<Trigger<T1>, Trigger<T2>>().then([](const T1& a, const T2& b) { /* ... */ });

Parameters

Parameter Description
T The datatype that triggers the reaction when emitted

Multiple triggers are specified as separate Trigger<> words: Trigger<T1>, Trigger<T2>, ....

Behavior

When T is emitted, all reactions registered with Trigger<T> are scheduled for execution. The callback receives const T& (a dereferenced std::shared_ptr<const T>) containing the most recent emission of that type from the data store.

If T has never been emitted, the task is dropped and the callback is not invoked.

Multi-Trigger

Trigger<T1>, Trigger<T2> fires when any of the listed types is emitted. Regardless of which type triggered the reaction, the latest data for all listed types is provided to the callback. If any of the triggered types has never been emitted, the task is dropped.

sequenceDiagram
    participant E as emit<T>
    participant S as TypeCallbackStore
    participant R as Scheduler
    participant C as Callback

    E->>S: Store new T, lookup bound reactions
    S->>R: Schedule task for each bound reaction
    R->>C: Invoke callback with latest T from cache

Extension Points

Trigger<T> implements two extension points:

  • bind — registers the reaction so it is notified on emission of T.
  • get — retrieves the data for T during task creation (on the emitter's thread). It reads from ThreadStore first (the exact data from this emit) and falls back to DataStore (latest value).

Data access is thread-safe; the underlying std::shared_ptr<const T> ensures the data remains valid for the lifetime of the callback.

Example

struct SensorReading {
    double value;
};

struct Command {
    int id;
};

// Single trigger
on<Trigger<SensorReading>>().then([](const SensorReading& reading) {
    // Fires every time a SensorReading is emitted
});

// Multi-trigger — fires when EITHER type is emitted
on<Trigger<SensorReading>, Trigger<Command>>().then([](const SensorReading& reading, const Command& cmd) {
    // Fires when EITHER SensorReading or Command is emitted
    // Both arguments always contain the most recent data
});

Notes

  • The callback argument is a reference into a shared pointer. Do not store the reference beyond the callback's lifetime; copy the data or take it as std::shared_ptr<const T> if you need to retain it (see below).
  • To access data without triggering on it, use With.
  • To allow missing data instead of dropping the task, wrap the type in Optional.
  • Trigger<T1>, Trigger<T2> is the canonical form for multi-trigger. Trigger<T1, T2> is also supported but less idiomatic.

See Also

  • With — access data without triggering
  • Optional — permit missing data instead of dropping the task
  • emit/Local — emit data visible only within the current PowerPlant