🪄 Formats StatefulService

This commit is contained in:
Rune Harlyk
2024-07-09 20:05:08 +02:00
committed by Rune Harlyk
parent 49e4291f2d
commit 7d586eec90
+36 -71
View File
@@ -23,8 +23,7 @@
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/semphr.h> #include <freertos/semphr.h>
enum class StateUpdateResult enum class StateUpdateResult {
{
CHANGED = 0, // The update changed the state and propagation should take place if required CHANGED = 0, // The update changed the state and propagation should take place if required
UNCHANGED, // The state was unchanged, propagation should not take place UNCHANGED, // The state was unchanged, propagation should not take place
ERROR // There was a problem updating the state, propagation should not take place ERROR // There was a problem updating the state, propagation should not take place
@@ -41,37 +40,33 @@ typedef size_t hook_handler_id_t;
typedef std::function<void(const String &originId)> StateUpdateCallback; typedef std::function<void(const String &originId)> StateUpdateCallback;
typedef std::function<void(const String &originId, StateUpdateResult &result)> StateHookCallback; typedef std::function<void(const String &originId, StateUpdateResult &result)> StateHookCallback;
typedef struct StateUpdateHandlerInfo typedef struct StateUpdateHandlerInfo {
{
static update_handler_id_t currentUpdatedHandlerId; static update_handler_id_t currentUpdatedHandlerId;
update_handler_id_t _id; update_handler_id_t _id;
StateUpdateCallback _cb; StateUpdateCallback _cb;
bool _allowRemove; bool _allowRemove;
StateUpdateHandlerInfo(StateUpdateCallback cb, bool allowRemove) : _id(++currentUpdatedHandlerId), _cb(cb), _allowRemove(allowRemove){}; StateUpdateHandlerInfo(StateUpdateCallback cb, bool allowRemove)
: _id(++currentUpdatedHandlerId), _cb(cb), _allowRemove(allowRemove) {};
} StateUpdateHandlerInfo_t; } StateUpdateHandlerInfo_t;
typedef struct StateHookHandlerInfo typedef struct StateHookHandlerInfo {
{
static hook_handler_id_t currentHookHandlerId; static hook_handler_id_t currentHookHandlerId;
hook_handler_id_t _id; hook_handler_id_t _id;
StateHookCallback _cb; StateHookCallback _cb;
bool _allowRemove; bool _allowRemove;
StateHookHandlerInfo(StateHookCallback cb, bool allowRemove) : _id(++currentHookHandlerId), _cb(cb), _allowRemove(allowRemove){}; StateHookHandlerInfo(StateHookCallback cb, bool allowRemove)
: _id(++currentHookHandlerId), _cb(cb), _allowRemove(allowRemove) {};
} StateHookHandlerInfo_t; } StateHookHandlerInfo_t;
template <class T> template <class T>
class StatefulService class StatefulService {
{
public: public:
template <typename... Args> template <typename... Args>
StatefulService(Args &&...args) : _state(std::forward<Args>(args)...), _accessMutex(xSemaphoreCreateRecursiveMutex()) StatefulService(Args &&...args)
{ : _state(std::forward<Args>(args)...), _accessMutex(xSemaphoreCreateRecursiveMutex()) {}
}
update_handler_id_t addUpdateHandler(StateUpdateCallback cb, bool allowRemove = true) update_handler_id_t addUpdateHandler(StateUpdateCallback cb, bool allowRemove = true) {
{ if (!cb) {
if (!cb)
{
return 0; return 0;
} }
StateUpdateHandlerInfo_t updateHandler(cb, allowRemove); StateUpdateHandlerInfo_t updateHandler(cb, allowRemove);
@@ -79,25 +74,18 @@ public:
return updateHandler._id; return updateHandler._id;
} }
void removeUpdateHandler(update_handler_id_t id) void removeUpdateHandler(update_handler_id_t id) {
{ for (auto i = _updateHandlers.begin(); i != _updateHandlers.end();) {
for (auto i = _updateHandlers.begin(); i != _updateHandlers.end();) if ((*i)._allowRemove && (*i)._id == id) {
{
if ((*i)._allowRemove && (*i)._id == id)
{
i = _updateHandlers.erase(i); i = _updateHandlers.erase(i);
} } else {
else
{
++i; ++i;
} }
} }
} }
hook_handler_id_t addHookHandler(StateHookCallback cb, bool allowRemove = true) hook_handler_id_t addHookHandler(StateHookCallback cb, bool allowRemove = true) {
{ if (!cb) {
if (!cb)
{
return 0; return 0;
} }
StateHookHandlerInfo_t hookHandler(cb, allowRemove); StateHookHandlerInfo_t hookHandler(cb, allowRemove);
@@ -105,89 +93,72 @@ public:
return hookHandler._id; return hookHandler._id;
} }
void removeHookHandler(hook_handler_id_t id) void removeHookHandler(hook_handler_id_t id) {
{ for (auto i = _hookHandlers.begin(); i != _hookHandlers.end();) {
for (auto i = _hookHandlers.begin(); i != _hookHandlers.end();) if ((*i)._allowRemove && (*i)._id == id) {
{
if ((*i)._allowRemove && (*i)._id == id)
{
i = _hookHandlers.erase(i); i = _hookHandlers.erase(i);
} } else {
else
{
++i; ++i;
} }
} }
} }
StateUpdateResult update(std::function<StateUpdateResult(T &)> stateUpdater, const String &originId) StateUpdateResult update(std::function<StateUpdateResult(T &)> stateUpdater, const String &originId) {
{
beginTransaction(); beginTransaction();
StateUpdateResult result = stateUpdater(_state); StateUpdateResult result = stateUpdater(_state);
endTransaction(); endTransaction();
callHookHandlers(originId, result); callHookHandlers(originId, result);
if (result == StateUpdateResult::CHANGED) if (result == StateUpdateResult::CHANGED) {
{
callUpdateHandlers(originId); callUpdateHandlers(originId);
} }
return result; return result;
} }
StateUpdateResult updateWithoutPropagation(std::function<StateUpdateResult(T &)> stateUpdater) StateUpdateResult updateWithoutPropagation(std::function<StateUpdateResult(T &)> stateUpdater) {
{
beginTransaction(); beginTransaction();
StateUpdateResult result = stateUpdater(_state); StateUpdateResult result = stateUpdater(_state);
endTransaction(); endTransaction();
return result; return result;
} }
StateUpdateResult update(JsonObject &jsonObject, JsonStateUpdater<T> stateUpdater, const String &originId) StateUpdateResult update(JsonObject &jsonObject, JsonStateUpdater<T> stateUpdater, const String &originId) {
{
beginTransaction(); beginTransaction();
StateUpdateResult result = stateUpdater(jsonObject, _state); StateUpdateResult result = stateUpdater(jsonObject, _state);
endTransaction(); endTransaction();
callHookHandlers(originId, result); callHookHandlers(originId, result);
if (result == StateUpdateResult::CHANGED) if (result == StateUpdateResult::CHANGED) {
{
callUpdateHandlers(originId); callUpdateHandlers(originId);
} }
return result; return result;
} }
StateUpdateResult updateWithoutPropagation(JsonObject &jsonObject, JsonStateUpdater<T> stateUpdater) StateUpdateResult updateWithoutPropagation(JsonObject &jsonObject, JsonStateUpdater<T> stateUpdater) {
{
beginTransaction(); beginTransaction();
StateUpdateResult result = stateUpdater(jsonObject, _state); StateUpdateResult result = stateUpdater(jsonObject, _state);
endTransaction(); endTransaction();
return result; return result;
} }
void read(std::function<void(T &)> stateReader) void read(std::function<void(T &)> stateReader) {
{
beginTransaction(); beginTransaction();
stateReader(_state); stateReader(_state);
endTransaction(); endTransaction();
} }
void read(JsonObject &jsonObject, JsonStateReader<T> stateReader) void read(JsonObject &jsonObject, JsonStateReader<T> stateReader) {
{
beginTransaction(); beginTransaction();
stateReader(_state, jsonObject); stateReader(_state, jsonObject);
endTransaction(); endTransaction();
} }
void callUpdateHandlers(const String &originId) void callUpdateHandlers(const String &originId) {
{ for (const StateUpdateHandlerInfo_t &updateHandler : _updateHandlers) {
for (const StateUpdateHandlerInfo_t &updateHandler : _updateHandlers)
{
updateHandler._cb(originId); updateHandler._cb(originId);
} }
} }
void callHookHandlers(const String &originId, StateUpdateResult &result) void callHookHandlers(const String &originId, StateUpdateResult &result) {
{ for (const StateHookHandlerInfo_t &hookHandler : _hookHandlers) {
for (const StateHookHandlerInfo_t &hookHandler : _hookHandlers)
{
hookHandler._cb(originId, result); hookHandler._cb(originId, result);
} }
} }
@@ -195,15 +166,9 @@ public:
protected: protected:
T _state; T _state;
inline void beginTransaction() inline void beginTransaction() { xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY); }
{
xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY);
}
inline void endTransaction() inline void endTransaction() { xSemaphoreGiveRecursive(_accessMutex); }
{
xSemaphoreGiveRecursive(_accessMutex);
}
private: private:
SemaphoreHandle_t _accessMutex; SemaphoreHandle_t _accessMutex;