Nested Nodes Example

examples/Basic/NestedNodes/NestedNodes.ino
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
 * SPDX-FileCopyrightText: 2026 Maximiliano Ramirez <maximiliano.ramirezbravo@gmail.com>
 *
 * SPDX-License-Identifier: MIT
 */

/**
 * ReactiveESP32 Example Overview:
 * - This example demonstrates the basic usage of nested nodes.
 * - A Signal<uint8_t> named 'number' is defined and updated every second.
 * - A Computed<uint16_t> named 'doubled' is created that computes double the value of 'number'.
 * - A second Computed<uint16_t> named 'quadrupled' computes double the value of 'doubled'.
 * - An Effect is defined to print the value of 'quadrupled' whenever it changes.
 *
 * - The Serial interface is used to interact with the program:
 *   - 'g': Get the current value of all nodes.
 *   - 's': Set the signal to a new value.
 *   - 'm': Mutate the signal value by adding 5.
 *
 * - Pressing '0' restarts the ESP32.
 */

#include <ReactiveESP32.h>
using namespace RxESP32;

/* ---------------------------------------------------------------------------------------------- */
// Define a simple signal
Signal<uint8_t> number(0);

// Define a computed value that doubles the signal
Computed<uint16_t> doubled([]() {
  uint16_t value = number.get() * 2;
  return value;
});

// Define a computed value that doubles the doubled value (number quadrupled)
Computed<uint16_t> quadrupled([]() {
  uint16_t value = doubled.get() * 2;
  return value;
});

// Define an effect that prints when the quadrupled value changes
Effect<> print_quadrupled([]() {
  uint16_t value = quadrupled.get();
  Serial.printf("\tQuadrupled value updated: %u\n", value);
  return nullptr; // No cleanup function needed
});

// Read Serial input and process commands
void serialRead();
/* ---------------------------------------------------------------------------------------------- */

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("=========================================");
  Serial.println("ReactiveESP32 - Basic NestedNodes Example");
  Serial.println("=========================================");

  // Start the ReactiveESP32 dispatcher
  if (!Dispatcher::start()) {
    Serial.println("Failed to start ReactiveESP32 Dispatcher!");
    while (true) {
      delay(1000);
    }
  }
}

void loop() {
  serialRead();

  // Update the signal every second
  static uint32_t start = 0;
  if (millis() - start >= 1000) {
    start = millis();

    // Update the signal using update()
    number.update([](const uint8_t& value) {
      uint8_t new_value = value + 1;
      Serial.printf("Number updated: %u\n", new_value);
      return new_value;
    });
  }
}

void serialRead() {
  if (!Serial.available()) return;

  char c = Serial.read();

  if (c == '\r') return;
  if (c == '\n') c = ' ';
  Serial.printf("> %c\n", c);

  switch (c) {
    case '0':
    {
      // Restart the ESP32
      ESP.restart();
    } break;

    case 'g':
    {
      // Get the current value of all signals and computeds
      uint8_t value_number      = number.get();
      uint16_t value_doubled    = doubled.get();
      uint16_t value_quadrupled = quadrupled.get();

      Serial.printf("Number - Doubled - Quadrupled: %u - %u - %u\n",
        value_number,
        value_doubled,
        value_quadrupled);
    } break;

    case 's':
    {
      // Set the signal to a new value using set()
      static uint8_t new_value = 0;

      if (!number.set(new_value)) {
        Serial.printf("Number unchanged: %u\n", new_value);
        break;
      }

      Serial.printf("Number set to: %u\n", new_value);
      new_value++;
    } break;

    case 'm':
    {
      // Mutate the signal value using mutate()
      number.mutate([](uint8_t& value) {
        value += 5;
        Serial.printf("Number mutated to: %u\n", value);
      });
    } break;
  }
}

See Also

  • Core - Core API Reference

  • Filters - Filters API Reference

  • Helpers - Helpers API Reference