AlteriomPainlessMesh v2.1.1
Easy ESP32/ESP8266 mesh networking with Alteriom IoT extensions
Loading...
Searching...
No Matches
callback.hpp
Go to the documentation of this file.
1#ifndef _PAINLESS_MESH_CALLBACK_HPP_
2#define _PAINLESS_MESH_CALLBACK_HPP_
3
4#include <map>
5#include <memory>
6
8
10
11namespace painlessmesh {
12
16namespace callback {
17template <typename... Args>
18class List {
19 public:
20 int execute(Args... args) {
21 for (auto&& f : callbacks) {
22 f(args...);
23 }
24 return callbacks.size();
25 }
26
27 size_t size() { return callbacks.size(); }
28
29 void clear() { return callbacks.clear(); }
30
31 /*
32 * Needs to be wrapped into semaphore
33 *
34 int executeWithScheduler(Scheduler& scheduler, Args... args) {
35 scheduler.execute();
36 for (auto&& f : callbacks) {
37 f(args...);
38 scheduler.execute();
39 }
40 return callbacks.size();
41 }*/
42
45 void push_back(std::function<void(Args...)> func) {
46 callbacks.push_back(func);
47 }
48
49 protected:
50 std::list<std::function<void(Args...)>> callbacks;
51};
52
56template <typename... Args>
58 public:
62 void onPackage(int id, std::function<void(Args...)> func) {
63 if (clearPending) {
64 (*pendingCallbackMap)[id].push_back(func);
65 } else {
66 (*callbackMap)[id].push_back(func);
67 }
68 }
69
70 size_t size() {
71 size_t size = 0;
72 auto generation = clearPending ? pendingCallbackMap : callbackMap;
73 for (auto&& key_value : *generation) {
74 size += key_value.second.size();
75 }
76 return size;
77 }
78
80 size_t count(int id) {
81 auto generation = clearPending ? pendingCallbackMap : callbackMap;
82 auto it = generation->find(id);
83 return it == generation->end() ? 0 : it->second.size();
84 }
85
86 void clear() {
87 if (dispatchDepth > 0) {
88 clearPending = true;
89 pendingCallbackMap = std::make_shared<CallbackMap>();
90 return;
91 }
92 callbackMap->clear();
93 }
94
98 int execute(int id, Args... args) {
99 // Retain the selected generation for the complete call. A nested callback
100 // may clear and replace the pending generation without destroying the
101 // List/std::function currently executing on this stack.
102 auto generation = clearPending ? pendingCallbackMap : callbackMap;
104 auto result = (*generation)[id].execute(args...);
106 if (dispatchDepth == 0 && clearPending) {
108 pendingCallbackMap.reset();
109 clearPending = false;
110 }
111 return result;
112 }
113
114 protected:
115 using CallbackMap = std::map<int, List<Args...>>;
116 std::shared_ptr<CallbackMap> callbackMap = std::make_shared<CallbackMap>();
117 // Registrations made after clear() during an active dispatch belong to
118 // the next callback generation (for example stop(); init(); from a user
119 // callback) and must survive removal of the currently executing one.
120 std::shared_ptr<CallbackMap> pendingCallbackMap;
121 size_t dispatchDepth = 0;
122 bool clearPending = false;
123};
124
125template <typename T>
128} // namespace callback
129} // namespace painlessmesh
130
131#endif
Definition callback.hpp:18
void clear()
Definition callback.hpp:29
size_t size()
Definition callback.hpp:27
int execute(Args... args)
Definition callback.hpp:20
std::list< std::function< void(Args...)> > callbacks
Definition callback.hpp:50
void push_back(std::function< void(Args...)> func)
Definition callback.hpp:45
size_t size()
Definition callback.hpp:70
size_t count(int id)
Definition callback.hpp:80
int execute(int id, Args... args)
Definition callback.hpp:98
void onPackage(int id, std::function< void(Args...)> func)
Definition callback.hpp:62
std::shared_ptr< CallbackMap > pendingCallbackMap
Definition callback.hpp:120
std::shared_ptr< CallbackMap > callbackMap
Definition callback.hpp:116
std::map< int, List< Args... > > CallbackMap
Definition callback.hpp:115
bool clearPending
Definition callback.hpp:122
size_t dispatchDepth
Definition callback.hpp:121
void clear()
Definition callback.hpp:86
Definition wifi.hpp:34