Skip to content

Commit 3fa0131

Browse files
committed
lib(NetworkEvents) refactor callback handlers
add a new functional callback type NetworkEventReceiver which accepts two argumnets: an event id and a pointer to optional struct with trailer data. Using this callback would allow to propagate event messages more efficiently. Mandatory allocation for arduino_event_info_t and arduino_event_t objects won't needed and simple events could be passed with only (int32_t)arduino_event_id_t wich fits nice to ESP event loop add NetworkEvents::postEvent() overload with optional arduino_event_info_t* struct use std::variant for various types of callback handlers, event picker depending on callback variant will provide an optimized calls avoiding extra copies when not needed.
1 parent 0a94723 commit 3fa0131

File tree

2 files changed

+105
-50
lines changed

2 files changed

+105
-50
lines changed

Diff for: libraries/Network/src/NetworkEvents.cpp

+61-34
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,18 @@ bool NetworkEvents::initNetworkEvents() {
5454
bool NetworkEvents::postEvent(const arduino_event_t *data, TickType_t timeout) {
5555
if (!data) return false;
5656
esp_err_t err = esp_event_post(ARDUINO_EVENTS, static_cast<int32_t>(data->event_id), &data->event_info, sizeof(data->event_info), timeout);
57-
if (err == pdTRUE)
57+
if (err == ESP_OK)
5858
return true;
5959

6060
log_e("Arduino Event Send Failed!");
6161
return false;
6262
}
6363

64-
bool NetworkEvents::postEvent(arduino_event_id_t event, TickType_t timeout){
65-
return esp_event_post(ARDUINO_EVENTS, static_cast<int32_t>(event), NULL, 0, timeout) == pdTRUE;
64+
bool NetworkEvents::postEvent(arduino_event_id_t event, const arduino_event_info_t *info, TickType_t timeout){
65+
if (info)
66+
return esp_event_post(ARDUINO_EVENTS, static_cast<int32_t>(event), info, sizeof(arduino_event_info_t), timeout) == pdTRUE;
67+
else
68+
return esp_event_post(ARDUINO_EVENTS, static_cast<int32_t>(event), NULL, 0, timeout) == pdTRUE;
6669
}
6770

6871

@@ -73,27 +76,27 @@ void NetworkEvents::_evt_picker(int32_t id, arduino_event_info_t *info){
7376

7477
// iterate over registered callbacks
7578
for (auto &i : _cbEventList) {
76-
if (i.event == static_cast<arduino_event_id_t>(id) || i.event == ARDUINO_EVENT_ANY) {
77-
if (i.cb) {
78-
i.cb(static_cast<arduino_event_id_t>(id));
79-
continue;
80-
}
81-
82-
if (i.fcb) {
83-
if (info)
84-
i.fcb(static_cast<arduino_event_id_t>(id), *info);
85-
else
86-
i.fcb(static_cast<arduino_event_id_t>(id), {});
87-
continue;
88-
}
89-
90-
if (i.scb){
91-
// system event callback needs a ptr to struct
92-
arduino_event_t event{static_cast<arduino_event_id_t>(id), {}};
93-
if (info)
94-
memcpy(&event.event_info, info, sizeof(arduino_event_info_t));
95-
i.scb(&event);
96-
}
79+
if (i.event == ARDUINO_EVENT_ANY || i.event == static_cast<arduino_event_id_t>(id)){
80+
81+
std::visit([id, info](auto&& arg){
82+
using T = std::decay_t<decltype(arg)>;
83+
if constexpr (std::is_same_v<T, NetworkEventReceiver>)
84+
arg(static_cast<arduino_event_id_t>(id), info);
85+
else if constexpr (std::is_same_v<T, NetworkEventCb>)
86+
arg(static_cast<arduino_event_id_t>(id));
87+
else if constexpr (std::is_same_v<T, NetworkEventFuncCb>)
88+
if (info)
89+
arg(static_cast<arduino_event_id_t>(id), *info);
90+
else
91+
arg(static_cast<arduino_event_id_t>(id), {});
92+
else if constexpr (std::is_same_v<T, NetworkEventSysCb>){
93+
// system event callback needs a ptr to struct
94+
arduino_event_t event{static_cast<arduino_event_id_t>(id), {}};
95+
if (info)
96+
memcpy(&event.event_info, info, sizeof(arduino_event_info_t));
97+
arg(&event);
98+
}
99+
}, i.cb_v);
97100
}
98101
}
99102
}
@@ -116,7 +119,7 @@ network_event_handle_t NetworkEvents::onEvent(NetworkEventCb cbEvent, arduino_ev
116119
std::lock_guard<std::mutex> lock(_mtx);
117120
#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
118121

119-
_cbEventList.emplace_back(++_current_id, cbEvent, nullptr, nullptr, event);
122+
_cbEventList.emplace_back(++_current_id, cbEvent, event);
120123
return _cbEventList.back().id;
121124
}
122125

@@ -129,7 +132,7 @@ network_event_handle_t NetworkEvents::onEvent(NetworkEventFuncCb cbEvent, arduin
129132
std::lock_guard<std::mutex> lock(_mtx);
130133
#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
131134

132-
_cbEventList.emplace_back(++_current_id, nullptr, cbEvent, nullptr, event);
135+
_cbEventList.emplace_back(++_current_id, cbEvent, event);
133136
return _cbEventList.back().id;
134137
}
135138

@@ -142,7 +145,7 @@ network_event_handle_t NetworkEvents::onEvent(NetworkEventSysCb cbEvent, arduino
142145
std::lock_guard<std::mutex> lock(_mtx);
143146
#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
144147

145-
_cbEventList.emplace_back(++_current_id, nullptr, nullptr, cbEvent, event);
148+
_cbEventList.emplace_back(++_current_id, cbEvent, event);
146149
return _cbEventList.back().id;
147150
}
148151

@@ -155,7 +158,7 @@ network_event_handle_t NetworkEvents::onSysEvent(NetworkEventCb cbEvent, arduino
155158
std::lock_guard<std::mutex> lock(_mtx);
156159
#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
157160

158-
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, nullptr, nullptr, event);
161+
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, event);
159162
return _cbEventList.front().id;
160163
}
161164

@@ -168,7 +171,7 @@ network_event_handle_t NetworkEvents::onSysEvent(NetworkEventFuncCb cbEvent, ard
168171
std::lock_guard<std::mutex> lock(_mtx);
169172
#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
170173

171-
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, nullptr, cbEvent, nullptr, event);
174+
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, event);
172175
return _cbEventList.front().id;
173176
}
174177

@@ -181,7 +184,20 @@ network_event_handle_t NetworkEvents::onSysEvent(NetworkEventSysCb cbEvent, ardu
181184
std::lock_guard<std::mutex> lock(_mtx);
182185
#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
183186

184-
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, nullptr, nullptr, cbEvent, event);
187+
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, event);
188+
return _cbEventList.front().id;
189+
}
190+
191+
network_event_handle_t NetworkEvents::onSysEvent(NetworkEventReceiver cbEvent, arduino_event_id_t event){
192+
if (!cbEvent) {
193+
return 0;
194+
}
195+
196+
#if defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
197+
std::lock_guard<std::mutex> lock(_mtx);
198+
#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
199+
200+
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, event);
185201
return _cbEventList.front().id;
186202
}
187203

@@ -198,7 +214,11 @@ void NetworkEvents::removeEvent(NetworkEventCb cbEvent, arduino_event_id_t event
198214
std::remove_if(
199215
_cbEventList.begin(), _cbEventList.end(),
200216
[cbEvent, event](const NetworkEventCbList_t &e) {
201-
return e.cb == cbEvent && e.event == event;
217+
return e.event == event && std::visit([cbEvent](auto&& arg) -> bool {
218+
if constexpr (std::is_same_v<NetworkEventCb, std::decay_t<decltype(arg)>>)
219+
return cbEvent == arg;
220+
else return false;
221+
}, e.cb_v);
202222
}
203223
),
204224
_cbEventList.end()
@@ -213,12 +233,15 @@ void NetworkEvents::removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t e
213233
#if defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
214234
std::lock_guard<std::mutex> lock(_mtx);
215235
#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
216-
217236
_cbEventList.erase(
218237
std::remove_if(
219238
_cbEventList.begin(), _cbEventList.end(),
220239
[cbEvent, event](const NetworkEventCbList_t &e) {
221-
return getStdFunctionAddress(e.fcb) == getStdFunctionAddress(cbEvent) && e.event == event;
240+
return e.event == event && std::visit([cbEvent](auto&& arg) -> bool {
241+
if constexpr (std::is_same_v<NetworkEventFuncCb, std::decay_t<decltype(arg)>>)
242+
return getStdFunctionAddress(cbEvent) == getStdFunctionAddress(arg);
243+
else return false;
244+
}, e.cb_v);
222245
}
223246
),
224247
_cbEventList.end()
@@ -238,7 +261,11 @@ void NetworkEvents::removeEvent(NetworkEventSysCb cbEvent, arduino_event_id_t ev
238261
std::remove_if(
239262
_cbEventList.begin(), _cbEventList.end(),
240263
[cbEvent, event](const NetworkEventCbList_t &e) {
241-
return e.scb == cbEvent && e.event == event;
264+
return e.event == event && std::visit([cbEvent](auto&& arg) -> bool {
265+
if constexpr (std::is_same_v<NetworkEventSysCb, std::decay_t<decltype(arg)>>)
266+
return cbEvent == arg;
267+
else return false;
268+
}, e.cb_v);
242269
}
243270
),
244271
_cbEventList.end()

Diff for: libraries/Network/src/NetworkEvents.h

+44-16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "esp_eth_driver.h"
1515
#endif
1616
#include <functional>
17+
#include <variant>
1718
#include "freertos/FreeRTOS.h"
1819
#include "freertos/event_groups.h"
1920
#if defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1
@@ -134,10 +135,15 @@ struct arduino_event_t {
134135
};
135136

136137
// type aliases
138+
using network_event_handle_t = size_t;
139+
// static callback
137140
using NetworkEventCb = void (*)(arduino_event_id_t event);
141+
// Generic Arduno NetworkEvent Functional Callback for events propagated via ESP Event loop
142+
using NetworkEventReceiver = std::function<void(arduino_event_id_t event, const arduino_event_info_t *info)>;
143+
// deprecated ones
138144
using NetworkEventFuncCb = std::function<void(arduino_event_id_t event, arduino_event_info_t info)>;
139145
using NetworkEventSysCb = void (*)(arduino_event_t *event);
140-
using network_event_handle_t = size_t;
146+
141147

142148
/**
143149
* @brief Class that provides network events callback handling
@@ -151,6 +157,16 @@ class NetworkEvents {
151157
NetworkEvents(){};
152158
~NetworkEvents();
153159

160+
/**
161+
* @brief register callback function to be executed on arduino event(s)
162+
* @note if same handler is registered twice or more than same handler would be called twice or more times
163+
*
164+
* @param cbEvent functional callback
165+
* @param event event to process, any event by default
166+
* @return network_event_handle_t
167+
*/
168+
network_event_handle_t onEvent(NetworkEventReceiver cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY);
169+
154170
/**
155171
* @brief register callback function to be executed on arduino event(s)
156172
* @note if same handler is registered twice or more than same handler would be called twice or more times
@@ -166,22 +182,23 @@ class NetworkEvents {
166182
* also used for lambda callbacks
167183
* @note if same handler is registered twice or more than same handler would be called twice or more times
168184
*
169-
* @param cbEvent static callback function
185+
* @param cbEvent functional callback
170186
* @param event event to process, any event by default
171187
* @return network_event_handle_t
172188
*/
189+
[[deprecated( "NetworkEventFuncCb deprecated, pls, use NetworkEventReceiver instead" )]]
173190
network_event_handle_t onEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY);
174191

175192
/**
176193
* @brief register static system callback to be executed on arduino event(s)
177194
* callback function would be supplied with a pointer to arduino_event_t structure as an argument
178-
*
179195
* @note if same handler is registered twice or more than same handler would be called twice or more times
180196
*
181197
* @param cbEvent static callback function
182198
* @param event event to process, any event by default
183199
* @return network_event_handle_t
184200
*/
201+
[[deprecated( "NetworkEventSysCb deprecated, pls, use NetworkEventReceiver instead" )]]
185202
network_event_handle_t onEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY);
186203

187204
/**
@@ -201,8 +218,8 @@ class NetworkEvents {
201218
* @param cbEvent functional callback
202219
* @param event event to process, any event by default
203220
*/
204-
void removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY)
205-
__attribute__((deprecated("removing functional callbacks via pointer is deprecated, use removeEvent(network_event_handle_t) instead")));
221+
[[deprecated( "removing functional callbacks via pointer is deprecated, use removeEvent(network_event_handle_t) instead" )]]
222+
void removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY);
206223

207224
/**
208225
* @brief unregister static system function callback
@@ -228,14 +245,17 @@ class NetworkEvents {
228245
static const char *eventName(arduino_event_id_t id);
229246

230247
/**
231-
* @brief post an event to the queue
232-
* and propagade and event to subscribed handlers
248+
* @brief post an event to the queue and propagade it to subscribed handlers
233249
* @note posting an event will trigger context switch from a lower priority task
234250
*
235251
* @param event a pointer to arduino_event_t struct
252+
* @param info optional struct with side data related to event
236253
* @return true if event was queued susccessfuly
237-
* @return false on memrory allocation error or queue is full
254+
* @return false on memory allocation error or queue is full
238255
*/
256+
bool postEvent(arduino_event_id_t event, const arduino_event_info_t *info = nullptr, TickType_t timeout = portMAX_DELAY);
257+
258+
[[deprecated( "posting arduino_event_t is deprecated, pls, use postEvent(arduino_event_id_t event, const arduino_event_info_t *info) instead" )]]
239259
bool postEvent(const arduino_event_t *event, TickType_t timeout = portMAX_DELAY);
240260

241261
int getStatusBits() const;
@@ -257,8 +277,12 @@ class NetworkEvents {
257277
// same as onEvent() but places newly added handler at the beginning of registered events list
258278
network_event_handle_t onSysEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY);
259279
// same as onEvent() but places newly added handler at the beginning of registered events list
280+
network_event_handle_t onSysEvent(NetworkEventReceiver cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY);
281+
// same as onEvent() but places newly added handler at the beginning of registered events list
282+
[[deprecated( "NetworkEventFuncCb deprecated, pls, use NetworkEventReceiver instead" )]]
260283
network_event_handle_t onSysEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY);
261284
// same as onEvent() but places newly added handler at the beginning of registered events list
285+
[[deprecated( "NetworkEventSysCb deprecated, pls, use NetworkEventReceiver instead" )]]
262286
network_event_handle_t onSysEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY);
263287

264288
private:
@@ -271,16 +295,20 @@ class NetworkEvents {
271295
*/
272296
struct NetworkEventCbList_t {
273297
network_event_handle_t id;
274-
NetworkEventCb cb;
275-
NetworkEventFuncCb fcb;
276-
NetworkEventSysCb scb;
298+
std::variant<NetworkEventCb, NetworkEventReceiver, NetworkEventFuncCb, NetworkEventSysCb>cb_v;
277299
arduino_event_id_t event;
278300

279-
explicit NetworkEventCbList_t(
280-
network_event_handle_t id, NetworkEventCb cb = nullptr, NetworkEventFuncCb fcb = nullptr, NetworkEventSysCb scb = nullptr,
281-
arduino_event_id_t event = ARDUINO_EVENT_ANY
282-
)
283-
: id(id), cb(cb), fcb(fcb), scb(scb), event(event) {}
301+
explicit NetworkEventCbList_t(network_event_handle_t id, NetworkEventCb callback, arduino_event_id_t event = ARDUINO_EVENT_ANY )
302+
: id(id), cb_v(callback), event(event) {}
303+
304+
explicit NetworkEventCbList_t(network_event_handle_t id, NetworkEventReceiver callback, arduino_event_id_t event = ARDUINO_EVENT_ANY )
305+
: id(id), cb_v(callback), event(event) {}
306+
307+
explicit NetworkEventCbList_t(network_event_handle_t id, NetworkEventFuncCb callback, arduino_event_id_t event = ARDUINO_EVENT_ANY )
308+
: id(id), cb_v(callback), event(event) {}
309+
310+
explicit NetworkEventCbList_t(network_event_handle_t id, NetworkEventSysCb callback, arduino_event_id_t event = ARDUINO_EVENT_ANY )
311+
: id(id), cb_v(callback), event(event) {}
284312
};
285313

286314
// define initial id's value

0 commit comments

Comments
 (0)