You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Rename "serialize" and "deserialize" functions to "read" and "update" to reflect API in StatefulService
* Move new definitions to StatefulService.h so it is obvious it is not general purpose
* Update README
Copy file name to clipboardExpand all lines: README.md
+43-20
Original file line number
Diff line number
Diff line change
@@ -350,7 +350,9 @@ The following diagram visualises how the framework's modular components fit toge
350
350
351
351
#### Stateful service
352
352
353
-
The [StatefulService.h](lib/framework/StatefulService.h) class is a responsible for managing state and interfacing with code which wants to change or respond to changes in that state. You can define a data class to hold some state, then build a StatefulService class to manage its state:
353
+
The [StatefulService.h](lib/framework/StatefulService.h) class is responsible for managing state. It has an API which allows other code to update or respond to updates in the state it manages. You can define a data class to hold state, then build a StatefulService class to manage it. After that you may attach HTTP endpoints, WebSockets or MQTT topics to the StatefulService instance to provide commonly required features.
354
+
355
+
Here is a simple example of a state class and a StatefulService to manage it:
354
356
355
357
```cpp
356
358
classLightState {
@@ -369,15 +371,16 @@ You may listen for changes to state by registering an update handler callback. I
An "originId" is passed to the update handler which may be used to identify the origin of the update. The default origin values the framework provides are:
383
+
An "originId" is passed to the update handler which may be used to identify the origin of an update. The default origin values the framework provides are:
StatefulService also exposes an update function which allows the caller to update the state with a callback. This approach automatically calls the registered update handlers when complete. The example below turns on the lights using the arbitrary origin "timer":
399
+
StatefulService also exposes an update function which allows the caller to update the state with a callback. This function automatically calls the registered update handlers if the state has been changed. The example below changes the state of the light (turns it on) using the arbitrary origin "timer" and returns the "CHANGED" state update result, indicating that a change was made:
397
400
398
401
```cpp
399
402
lightStateService.update([&](LightState& state) {
400
-
state.on = true; // turn on the lights!
403
+
if (state.on) {
404
+
return StateUpdateResult::UNCHANGED; // lights were already on, return UNCHANGED
405
+
}
406
+
state.on = true; // turn on the lights
407
+
return StateUpdateResult::CHANGED; // notify StatefulService by returning CHANGED
401
408
}, "timer");
402
409
```
403
410
411
+
There are three possible return values for an update function which are as follows:
StateUpdateResult::CHANGED | The update changed the state, propagation should take place if required
416
+
StateUpdateResult::UNCHANGED | The state was unchanged, propagation should not take place
417
+
StateUpdateResult::ERROR | There was an error updating the state, propagation should not take place
418
+
404
419
#### Serialization
405
420
406
-
When transmitting state over HTTP, WebSockets, or MQTT it must to be marshalled into a serializable form (JSON). The framework uses ArduinoJson for serialization and the functions defined in [JsonSerializer.h](lib/framework/JsonSerializer.h) and [JsonDeserializer.h](lib/framework/JsonDeserializer.h) facilitate this.
421
+
When reading or updating state from an external source (HTTP, WebSockets, or MQTT for example) the state must be marshalled into a serializable form (JSON). SettingsService provides two callback patterns which facilitate this internally:
JsonStateReader | void read(T& settings, JsonObject& root) | Reading the state object into a JsonObject
426
+
JsonStateUpdater | StateUpdateResult update(JsonObject& root, T& settings) | Updating the state from a JsonObject, returning the appropriate StateUpdateResult
427
+
407
428
408
429
The static functions below can be used to facilitate the serialization/deserialization of the light state:
0 commit comments