Effect¶
-
template<size_t MaxSources = 8>
class Effect : public RxESP32::ReactiveNode¶ Reactive side-effect that automatically re-executes when dependencies change.
Effect represents a side-effect function that runs in response to changes in its dependencies (Signal / Computed). Unlike Computed, Effects don’t produce a value - they perform actions like logging, updating UI, or communicating with hardware.
- Since
v0.1.0
Key Features:
Automatic dependency tracking during effect execution.
Optional cleanup function for resource management.
Lazy or eager execution modes.
Can be suspended/resumed for temporary disabling.
Priority-based scheduling in dispatcher.
Thread-safe via FreeRTOS mutex.
Usage:
Signal<int> counter(0); // Effect runs whenever counter changes Effect logger([]() { Serial.println(counter.get()); // Register dependency with get() // Optional cleanup function, otherwise return nullptr return []() { Serial.println("Cleaning up"); }; }); counter.set(5); // Prints: 5 counter.set(10); // Prints: "Cleaning up" then "10"Public Types¶
-
using CleanupFunction = std::function<void()>¶
-
using EffectFunction = std::function<CleanupFunction()>¶
Public Functions¶
-
inline explicit Effect(EffectFunction effect_function, const Options &options = {})¶
Construct Effect with effect function and options.
Creates a reactive effect that executes when dependencies change. By default, executes immediately in constructor to establish dependencies. Optionally returns a cleanup function to be called before next execution.
- Since
v0.1.0
Signal<bool> ledState(false); // Simple effect Effect<> ledController([]() { digitalWrite(LED_PIN, ledState.get()); // Register dependency with get() return nullptr; // No cleanup needed }); // Effect with cleanup Effect<> timer([]() { int interval = timer_interval.get(); auto handle = startTimer(interval); return [=]() { stopTimer(handle); }; // Cleanup old timer }); // Lazy effect (manual control) Effect<> manual([]() { processData(data.get()); return nullptr; }, {.lazy = true}); // Manually trigger lazy effect manual.run();Note
With
skip_initial_run = true, first execution deferred until first trigger.With
lazy = true, only executes on manual run() call.
Warning
If you don’t need a cleanup function, you must return
nullptr.- Parameters:¶
- EffectFunction effect_function¶
Function to execute (returns optional cleanup function).
- const Options &options = {}¶
Configuration (name, priority, skip_initial_run, lazy).
-
inline ~Effect() override¶
-
inline virtual Type getType() const override¶
Get the runtime type of this node.
- Since
v0.1.0
- Returns:¶
-
inline Status suspend()¶
Suspend effect execution temporarily.
Prevents the effect from running when dependencies change. Changes are still tracked (effect remains dirty), but execution is deferred until resume(). Useful for temporarily disabling effects during batch updates.
- Since
v0.1.0
Effect<> logger([]() { Serial.println(sensor.get()); return nullptr; }); logger.suspend(); // Make many changes without triggering effect sensor.set(1); sensor.set(2); sensor.set(3); logger.resume(); // Effect runs once with final value- Returns:¶
Status::Okon success, error code otherwise.
-
inline Status resume()¶
Resume effect execution after suspend.
Re-enables effect execution. If effect became dirty while suspended, it will be dispatched immediately for execution.
- Since
v0.1.0
- Returns:¶
Status::Okon success, error code otherwise.
-
inline bool isSuspended() const¶
Check if effect is currently suspended.
- Since
v0.1.0
- Returns:¶
true if suspended, false if active.
-
inline Status run()¶
Manually trigger effect execution.
Forces the effect to run immediately, regardless of dirty state. For lazy effects, this is the primary way to trigger execution. For normal effects, can be used to force re-execution.
- Since
v0.1.0
// Lazy effect (doesn't auto-run) Effect processor([]() { processData(dataQueue.get()); return nullptr; }, {.lazy = true}); // Manually trigger when needed if (userButtonPressed) { processor.run(); }Note
First call with option
skip_initial_runtriggers initial execution.Useful for lazy effects that only run on manual trigger.
- Returns:¶
Status::Okon success, error code otherwise.
See Also¶
Reactive Nodes - Nodes Overview