🪄 Formats StatefulService
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user