@alteriom/painlessmesh 1.6.1 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +380 -143
- package/LICENSE +674 -674
- package/README.md +477 -434
- package/RELEASE_GUIDE.md +504 -418
- package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
- package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
- package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
- package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
- package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
- package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
- package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
- package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
- package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
- package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
- package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
- package/docs/PHASE1_GUIDE.md +349 -0
- package/docs/PHASE2_GUIDE.md +543 -0
- package/docs/README.md +77 -70
- package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
- package/docs/alteriom/overview.md +507 -507
- package/docs/api/core-api.md +606 -606
- package/docs/architecture/mesh-architecture.md +378 -378
- package/docs/architecture/plugin-system.md +516 -516
- package/docs/getting-started/first-mesh.md +409 -409
- package/docs/getting-started/installation.md +274 -274
- package/docs/getting-started/quickstart.md +157 -157
- package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
- package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
- package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
- package/docs/improvements/README.md +86 -68
- package/docs/improvements/ota-and-status-enhancements.md +911 -0
- package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
- package/docs/improvements/ota-status-quick-reference.md +284 -0
- package/docs/platformio-publishing.md +255 -0
- package/docs/platformio-setup-summary.md +121 -0
- package/docs/troubleshooting/common-issues.md +520 -520
- package/docs/troubleshooting/faq.md +472 -472
- package/docs/tutorials/basic-examples.md +717 -717
- package/docs/wiki/API-Reference.md +245 -245
- package/docs/wiki/Complete-Documentation.md +122 -122
- package/examples/alteriom/README.md +139 -81
- package/examples/alteriom/alteriom.ino +186 -185
- package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
- package/examples/alteriom/platformio.ini +24 -24
- package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
- package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
- package/examples/alteriomImproved/platformio.ini +25 -0
- package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomPhase1/phase1_features.ino +242 -0
- package/examples/alteriomPhase1/platformio.ini +25 -0
- package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomPhase2/phase2_features.ino +186 -0
- package/examples/alteriomPhase2/platformio.ini +25 -0
- package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
- package/examples/alteriomSensorNode/platformio.ini +25 -0
- package/examples/basic/basic.ino +66 -66
- package/examples/basic/platformio.ini +25 -25
- package/examples/bridge/bridge.ino +51 -51
- package/examples/bridge/mesh_event_publisher.hpp +253 -0
- package/examples/bridge/mesh_topology_reporter.hpp +303 -0
- package/examples/bridge/mqtt_command_bridge.hpp +459 -0
- package/examples/bridge/mqtt_status_bridge.hpp +519 -0
- package/examples/bridge/platformio.ini +25 -25
- package/examples/echoNode/echoNode.ino +33 -33
- package/examples/echoNode/platformio.ini +25 -25
- package/examples/logClient/logClient.ino +109 -109
- package/examples/logClient/platformio.ini +25 -25
- package/examples/logServer/logServer.ino +81 -81
- package/examples/logServer/platformio.ini +25 -25
- package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
- package/examples/meshCommandNode/meshCommandNode.ino +263 -0
- package/examples/meshCommandNode/platformio.ini +25 -0
- package/examples/mqttBridge/mqttBridge.ino +118 -118
- package/examples/mqttBridge/platformio.ini +26 -26
- package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
- package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
- package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
- package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
- package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
- package/examples/mqttCommandBridge/platformio.ini +26 -0
- package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
- package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
- package/examples/mqttStatusBridge/platformio.ini +26 -0
- package/examples/mqttTopologyTest/README.md +467 -0
- package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
- package/examples/mqttTopologyTest/platformio.ini +26 -0
- package/examples/namedMesh/namedMesh.ino +97 -97
- package/examples/namedMesh/platformio.ini +25 -25
- package/examples/otaReceiver/otaReceiver.ino +79 -79
- package/examples/otaReceiver/platformio.ini +25 -25
- package/examples/otaSender/otaSender.ino +160 -151
- package/examples/otaSender/platformio.ini +25 -25
- package/examples/startHere/platformio.ini +25 -25
- package/examples/startHere/startHere.ino +159 -159
- package/examples/webServer/platformio.ini +27 -27
- package/examples/webServer/webServer.ino +89 -89
- package/keywords.txt +48 -48
- package/library.json +55 -34
- package/library.properties +10 -10
- package/package.json +86 -78
- package/src/AlteriomPainlessMesh.h +97 -97
- package/src/arduino/wifi.hpp +365 -365
- package/src/boost/asynctcp.hpp +279 -279
- package/src/painlessMesh.h +70 -70
- package/src/painlessMeshSTA.cpp +236 -236
- package/src/painlessMeshSTA.h +58 -58
- package/src/painlessTaskOptions.h +4 -4
- package/src/painlessmesh/base64.hpp +111 -111
- package/src/painlessmesh/buffer.hpp +229 -229
- package/src/painlessmesh/callback.hpp +91 -91
- package/src/painlessmesh/configuration.hpp +77 -77
- package/src/painlessmesh/connection.hpp +192 -192
- package/src/painlessmesh/layout.hpp +188 -188
- package/src/painlessmesh/logger.hpp +158 -158
- package/src/painlessmesh/memory.hpp +119 -119
- package/src/painlessmesh/mesh.hpp +761 -560
- package/src/painlessmesh/metrics.hpp +322 -322
- package/src/painlessmesh/ntp.hpp +263 -263
- package/src/painlessmesh/ota.hpp +582 -553
- package/src/painlessmesh/plugin.hpp +188 -188
- package/src/painlessmesh/protocol.hpp +813 -813
- package/src/painlessmesh/router.hpp +322 -322
- package/src/painlessmesh/tcp.hpp +71 -71
- package/src/painlessmesh/validation.hpp +238 -238
- package/src/plugin/performance.hpp +214 -214
- package/src/plugin/remote.hpp +64 -64
- package/src/scheduler.cpp +10 -10
- package/src/wifi.cpp +2 -2
|
@@ -1,158 +1,158 @@
|
|
|
1
|
-
#ifndef _PAINLESS_MESH_LOGGER_HPP_
|
|
2
|
-
#define _PAINLESS_MESH_LOGGER_HPP_
|
|
3
|
-
|
|
4
|
-
#include <list>
|
|
5
|
-
|
|
6
|
-
namespace painlessmesh {
|
|
7
|
-
namespace logger {
|
|
8
|
-
#include <stdarg.h>
|
|
9
|
-
#include "Arduino.h"
|
|
10
|
-
|
|
11
|
-
#define REMOTE_QUEUE_SIZE 10
|
|
12
|
-
|
|
13
|
-
typedef enum {
|
|
14
|
-
ERROR = 1 << 0,
|
|
15
|
-
STARTUP = 1 << 1,
|
|
16
|
-
MESH_STATUS = 1 << 2,
|
|
17
|
-
CONNECTION = 1 << 3,
|
|
18
|
-
SYNC = 1 << 4,
|
|
19
|
-
S_TIME = 1 << 5,
|
|
20
|
-
COMMUNICATION = 1 << 6,
|
|
21
|
-
GENERAL = 1 << 7,
|
|
22
|
-
MSG_TYPES = 1 << 8,
|
|
23
|
-
REMOTE = 1 << 9, // not yet implemented
|
|
24
|
-
APPLICATION = 1 << 10,
|
|
25
|
-
DEBUG = 1 << 11
|
|
26
|
-
} LogLevel;
|
|
27
|
-
|
|
28
|
-
class LogClass {
|
|
29
|
-
public:
|
|
30
|
-
void setLogLevel(uint16_t newTypes) {
|
|
31
|
-
// set the different kinds of debug messages you want to generate.
|
|
32
|
-
types = newTypes;
|
|
33
|
-
Serial.print(F("\nsetLogLevel:"));
|
|
34
|
-
if (types & ERROR) {
|
|
35
|
-
Serial.print(F(" ERROR |"));
|
|
36
|
-
}
|
|
37
|
-
if (types & STARTUP) {
|
|
38
|
-
Serial.print(F(" STARTUP |"));
|
|
39
|
-
}
|
|
40
|
-
if (types & MESH_STATUS) {
|
|
41
|
-
Serial.print(F(" MESH_STATUS |"));
|
|
42
|
-
}
|
|
43
|
-
if (types & CONNECTION) {
|
|
44
|
-
Serial.print(F(" CONNECTION |"));
|
|
45
|
-
}
|
|
46
|
-
if (types & SYNC) {
|
|
47
|
-
Serial.print(F(" SYNC |"));
|
|
48
|
-
}
|
|
49
|
-
if (types & S_TIME) {
|
|
50
|
-
Serial.print(F(" S_TIME |"));
|
|
51
|
-
}
|
|
52
|
-
if (types & COMMUNICATION) {
|
|
53
|
-
Serial.print(F(" COMMUNICATION |"));
|
|
54
|
-
}
|
|
55
|
-
if (types & GENERAL) {
|
|
56
|
-
Serial.print(F(" GENERAL |"));
|
|
57
|
-
}
|
|
58
|
-
if (types & MSG_TYPES) {
|
|
59
|
-
Serial.print(F(" MSG_TYPES |"));
|
|
60
|
-
}
|
|
61
|
-
if (types & REMOTE) {
|
|
62
|
-
Serial.print(F(" REMOTE |"));
|
|
63
|
-
}
|
|
64
|
-
if (types & APPLICATION) {
|
|
65
|
-
Serial.print(F(" APPLICATION |"));
|
|
66
|
-
}
|
|
67
|
-
if (types & DEBUG) {
|
|
68
|
-
Serial.print(F(" DEBUG |"));
|
|
69
|
-
}
|
|
70
|
-
Serial.println();
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
void operator()(LogLevel type, const char *format...) {
|
|
74
|
-
if (type & types) { // Print only the message types set for output
|
|
75
|
-
va_list args;
|
|
76
|
-
va_start(args, format);
|
|
77
|
-
|
|
78
|
-
vsnprintf(str, 200, format, args);
|
|
79
|
-
|
|
80
|
-
if (types) {
|
|
81
|
-
switch (type) {
|
|
82
|
-
case ERROR:
|
|
83
|
-
Serial.print(F("ERROR: "));
|
|
84
|
-
break;
|
|
85
|
-
case STARTUP:
|
|
86
|
-
Serial.print(F("STARTUP: "));
|
|
87
|
-
break;
|
|
88
|
-
case MESH_STATUS:
|
|
89
|
-
Serial.print(F("MESH_STATUS: "));
|
|
90
|
-
break;
|
|
91
|
-
case CONNECTION:
|
|
92
|
-
Serial.print(F("CONNECTION: "));
|
|
93
|
-
break;
|
|
94
|
-
case SYNC:
|
|
95
|
-
Serial.print(F("SYNC: "));
|
|
96
|
-
break;
|
|
97
|
-
case S_TIME:
|
|
98
|
-
Serial.print(F("S_TIME: "));
|
|
99
|
-
break;
|
|
100
|
-
case COMMUNICATION:
|
|
101
|
-
Serial.print(F("COMMUNICATION: "));
|
|
102
|
-
break;
|
|
103
|
-
case GENERAL:
|
|
104
|
-
Serial.print(F("GENERAL: "));
|
|
105
|
-
break;
|
|
106
|
-
case MSG_TYPES:
|
|
107
|
-
Serial.print(F("MSG_TYPES: "));
|
|
108
|
-
break;
|
|
109
|
-
case REMOTE:
|
|
110
|
-
this->remote(format);
|
|
111
|
-
Serial.print(F("REMOTE: "));
|
|
112
|
-
break;
|
|
113
|
-
case APPLICATION:
|
|
114
|
-
Serial.print(F("APPLICATION: "));
|
|
115
|
-
break;
|
|
116
|
-
case DEBUG:
|
|
117
|
-
Serial.print(F("DEBUG: "));
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
Serial.print(str);
|
|
123
|
-
|
|
124
|
-
va_end(args);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
void remote(const char *format...) {
|
|
129
|
-
if (REMOTE & types) { // Store only the message if REMOTE set
|
|
130
|
-
va_list args;
|
|
131
|
-
va_start(args, format);
|
|
132
|
-
|
|
133
|
-
vsnprintf(str, 200, format, args);
|
|
134
|
-
|
|
135
|
-
remote_queue.push_back(std::pair<uint, TSTRING>(remote_uuid, str));
|
|
136
|
-
++remote_uuid;
|
|
137
|
-
if (remote_queue.size() > REMOTE_QUEUE_SIZE) {
|
|
138
|
-
// No place to store the reason, but do signify the queue is full,
|
|
139
|
-
// discard any follow up
|
|
140
|
-
remote_queue.pop_front();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
std::list<std::pair<uint, TSTRING>> &get_remote_queue() {
|
|
146
|
-
return remote_queue;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
private:
|
|
150
|
-
uint16_t types = 0;
|
|
151
|
-
char str[200];
|
|
152
|
-
std::list<std::pair<uint, TSTRING>> remote_queue;
|
|
153
|
-
uint remote_uuid;
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
} // namespace logger
|
|
157
|
-
} // namespace painlessmesh
|
|
158
|
-
#endif
|
|
1
|
+
#ifndef _PAINLESS_MESH_LOGGER_HPP_
|
|
2
|
+
#define _PAINLESS_MESH_LOGGER_HPP_
|
|
3
|
+
|
|
4
|
+
#include <list>
|
|
5
|
+
|
|
6
|
+
namespace painlessmesh {
|
|
7
|
+
namespace logger {
|
|
8
|
+
#include <stdarg.h>
|
|
9
|
+
#include "Arduino.h"
|
|
10
|
+
|
|
11
|
+
#define REMOTE_QUEUE_SIZE 10
|
|
12
|
+
|
|
13
|
+
typedef enum {
|
|
14
|
+
ERROR = 1 << 0,
|
|
15
|
+
STARTUP = 1 << 1,
|
|
16
|
+
MESH_STATUS = 1 << 2,
|
|
17
|
+
CONNECTION = 1 << 3,
|
|
18
|
+
SYNC = 1 << 4,
|
|
19
|
+
S_TIME = 1 << 5,
|
|
20
|
+
COMMUNICATION = 1 << 6,
|
|
21
|
+
GENERAL = 1 << 7,
|
|
22
|
+
MSG_TYPES = 1 << 8,
|
|
23
|
+
REMOTE = 1 << 9, // not yet implemented
|
|
24
|
+
APPLICATION = 1 << 10,
|
|
25
|
+
DEBUG = 1 << 11
|
|
26
|
+
} LogLevel;
|
|
27
|
+
|
|
28
|
+
class LogClass {
|
|
29
|
+
public:
|
|
30
|
+
void setLogLevel(uint16_t newTypes) {
|
|
31
|
+
// set the different kinds of debug messages you want to generate.
|
|
32
|
+
types = newTypes;
|
|
33
|
+
Serial.print(F("\nsetLogLevel:"));
|
|
34
|
+
if (types & ERROR) {
|
|
35
|
+
Serial.print(F(" ERROR |"));
|
|
36
|
+
}
|
|
37
|
+
if (types & STARTUP) {
|
|
38
|
+
Serial.print(F(" STARTUP |"));
|
|
39
|
+
}
|
|
40
|
+
if (types & MESH_STATUS) {
|
|
41
|
+
Serial.print(F(" MESH_STATUS |"));
|
|
42
|
+
}
|
|
43
|
+
if (types & CONNECTION) {
|
|
44
|
+
Serial.print(F(" CONNECTION |"));
|
|
45
|
+
}
|
|
46
|
+
if (types & SYNC) {
|
|
47
|
+
Serial.print(F(" SYNC |"));
|
|
48
|
+
}
|
|
49
|
+
if (types & S_TIME) {
|
|
50
|
+
Serial.print(F(" S_TIME |"));
|
|
51
|
+
}
|
|
52
|
+
if (types & COMMUNICATION) {
|
|
53
|
+
Serial.print(F(" COMMUNICATION |"));
|
|
54
|
+
}
|
|
55
|
+
if (types & GENERAL) {
|
|
56
|
+
Serial.print(F(" GENERAL |"));
|
|
57
|
+
}
|
|
58
|
+
if (types & MSG_TYPES) {
|
|
59
|
+
Serial.print(F(" MSG_TYPES |"));
|
|
60
|
+
}
|
|
61
|
+
if (types & REMOTE) {
|
|
62
|
+
Serial.print(F(" REMOTE |"));
|
|
63
|
+
}
|
|
64
|
+
if (types & APPLICATION) {
|
|
65
|
+
Serial.print(F(" APPLICATION |"));
|
|
66
|
+
}
|
|
67
|
+
if (types & DEBUG) {
|
|
68
|
+
Serial.print(F(" DEBUG |"));
|
|
69
|
+
}
|
|
70
|
+
Serial.println();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
void operator()(LogLevel type, const char *format...) {
|
|
74
|
+
if (type & types) { // Print only the message types set for output
|
|
75
|
+
va_list args;
|
|
76
|
+
va_start(args, format);
|
|
77
|
+
|
|
78
|
+
vsnprintf(str, 200, format, args);
|
|
79
|
+
|
|
80
|
+
if (types) {
|
|
81
|
+
switch (type) {
|
|
82
|
+
case ERROR:
|
|
83
|
+
Serial.print(F("ERROR: "));
|
|
84
|
+
break;
|
|
85
|
+
case STARTUP:
|
|
86
|
+
Serial.print(F("STARTUP: "));
|
|
87
|
+
break;
|
|
88
|
+
case MESH_STATUS:
|
|
89
|
+
Serial.print(F("MESH_STATUS: "));
|
|
90
|
+
break;
|
|
91
|
+
case CONNECTION:
|
|
92
|
+
Serial.print(F("CONNECTION: "));
|
|
93
|
+
break;
|
|
94
|
+
case SYNC:
|
|
95
|
+
Serial.print(F("SYNC: "));
|
|
96
|
+
break;
|
|
97
|
+
case S_TIME:
|
|
98
|
+
Serial.print(F("S_TIME: "));
|
|
99
|
+
break;
|
|
100
|
+
case COMMUNICATION:
|
|
101
|
+
Serial.print(F("COMMUNICATION: "));
|
|
102
|
+
break;
|
|
103
|
+
case GENERAL:
|
|
104
|
+
Serial.print(F("GENERAL: "));
|
|
105
|
+
break;
|
|
106
|
+
case MSG_TYPES:
|
|
107
|
+
Serial.print(F("MSG_TYPES: "));
|
|
108
|
+
break;
|
|
109
|
+
case REMOTE:
|
|
110
|
+
this->remote(format);
|
|
111
|
+
Serial.print(F("REMOTE: "));
|
|
112
|
+
break;
|
|
113
|
+
case APPLICATION:
|
|
114
|
+
Serial.print(F("APPLICATION: "));
|
|
115
|
+
break;
|
|
116
|
+
case DEBUG:
|
|
117
|
+
Serial.print(F("DEBUG: "));
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
Serial.print(str);
|
|
123
|
+
|
|
124
|
+
va_end(args);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
void remote(const char *format...) {
|
|
129
|
+
if (REMOTE & types) { // Store only the message if REMOTE set
|
|
130
|
+
va_list args;
|
|
131
|
+
va_start(args, format);
|
|
132
|
+
|
|
133
|
+
vsnprintf(str, 200, format, args);
|
|
134
|
+
|
|
135
|
+
remote_queue.push_back(std::pair<uint, TSTRING>(remote_uuid, str));
|
|
136
|
+
++remote_uuid;
|
|
137
|
+
if (remote_queue.size() > REMOTE_QUEUE_SIZE) {
|
|
138
|
+
// No place to store the reason, but do signify the queue is full,
|
|
139
|
+
// discard any follow up
|
|
140
|
+
remote_queue.pop_front();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
std::list<std::pair<uint, TSTRING>> &get_remote_queue() {
|
|
146
|
+
return remote_queue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private:
|
|
150
|
+
uint16_t types = 0;
|
|
151
|
+
char str[200];
|
|
152
|
+
std::list<std::pair<uint, TSTRING>> remote_queue;
|
|
153
|
+
uint remote_uuid;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
} // namespace logger
|
|
157
|
+
} // namespace painlessmesh
|
|
158
|
+
#endif
|
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
#ifndef _PAINLESS_MESH_MEMORY_HPP_
|
|
2
|
-
#define _PAINLESS_MESH_MEMORY_HPP_
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Memory management utilities for painlessMesh
|
|
6
|
-
*
|
|
7
|
-
* This module provides optimized memory management utilities to reduce
|
|
8
|
-
* allocations and improve performance in memory-constrained environments.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
#include "painlessmesh/configuration.hpp"
|
|
12
|
-
#include <memory>
|
|
13
|
-
#include <vector>
|
|
14
|
-
|
|
15
|
-
namespace painlessmesh {
|
|
16
|
-
namespace memory {
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Object pool for frequently allocated types
|
|
20
|
-
* Reduces allocation overhead for commonly used objects
|
|
21
|
-
*/
|
|
22
|
-
template<typename T>
|
|
23
|
-
class ObjectPool {
|
|
24
|
-
public:
|
|
25
|
-
ObjectPool(size_t initial_size = 10) {
|
|
26
|
-
pool_.reserve(initial_size);
|
|
27
|
-
for (size_t i = 0; i < initial_size; ++i) {
|
|
28
|
-
pool_.emplace_back(std::make_unique<T>());
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
std::unique_ptr<T> acquire() {
|
|
33
|
-
if (!pool_.empty()) {
|
|
34
|
-
auto obj = std::move(pool_.back());
|
|
35
|
-
pool_.pop_back();
|
|
36
|
-
return obj;
|
|
37
|
-
}
|
|
38
|
-
return std::make_unique<T>();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
void release(std::unique_ptr<T> obj) {
|
|
42
|
-
if (pool_.size() < max_pool_size_) {
|
|
43
|
-
// Reset object to default state before returning to pool
|
|
44
|
-
*obj = T{};
|
|
45
|
-
pool_.push_back(std::move(obj));
|
|
46
|
-
}
|
|
47
|
-
// If pool is full, let unique_ptr destroy the object automatically
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
size_t size() const { return pool_.size(); }
|
|
51
|
-
|
|
52
|
-
private:
|
|
53
|
-
std::vector<std::unique_ptr<T>> pool_;
|
|
54
|
-
static constexpr size_t max_pool_size_ = 20; // Prevent unlimited growth
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Pre-sized string buffer to avoid frequent reallocations
|
|
59
|
-
*/
|
|
60
|
-
class StringBuffer {
|
|
61
|
-
public:
|
|
62
|
-
explicit StringBuffer(size_t initial_capacity = 512) {
|
|
63
|
-
buffer_.reserve(initial_capacity);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
void clear() { buffer_.clear(); }
|
|
67
|
-
|
|
68
|
-
void append(const TSTRING& str) {
|
|
69
|
-
if (buffer_.capacity() < buffer_.size() + str.length()) {
|
|
70
|
-
buffer_.reserve(std::max(buffer_.capacity() * 2, buffer_.size() + str.length()));
|
|
71
|
-
}
|
|
72
|
-
buffer_ += str;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const TSTRING& str() const { return buffer_; }
|
|
76
|
-
TSTRING& str() { return buffer_; }
|
|
77
|
-
|
|
78
|
-
size_t capacity() const { return buffer_.capacity(); }
|
|
79
|
-
size_t size() const { return buffer_.size(); }
|
|
80
|
-
|
|
81
|
-
private:
|
|
82
|
-
TSTRING buffer_;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Memory usage statistics for monitoring
|
|
87
|
-
*/
|
|
88
|
-
struct MemoryStats {
|
|
89
|
-
size_t total_allocated = 0;
|
|
90
|
-
size_t total_freed = 0;
|
|
91
|
-
size_t current_usage = 0;
|
|
92
|
-
size_t peak_usage = 0;
|
|
93
|
-
size_t allocation_count = 0;
|
|
94
|
-
|
|
95
|
-
void record_allocation(size_t size) {
|
|
96
|
-
total_allocated += size;
|
|
97
|
-
current_usage += size;
|
|
98
|
-
peak_usage = std::max(peak_usage, current_usage);
|
|
99
|
-
++allocation_count;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
void record_deallocation(size_t size) {
|
|
103
|
-
total_freed += size;
|
|
104
|
-
current_usage = (current_usage >= size) ? current_usage - size : 0;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
void reset() {
|
|
108
|
-
*this = MemoryStats{};
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
// Global memory statistics (optional, can be disabled for production)
|
|
113
|
-
#ifdef PAINLESS_MESH_ENABLE_MEMORY_STATS
|
|
114
|
-
extern MemoryStats global_memory_stats;
|
|
115
|
-
#endif
|
|
116
|
-
|
|
117
|
-
} // namespace memory
|
|
118
|
-
} // namespace painlessmesh
|
|
119
|
-
|
|
1
|
+
#ifndef _PAINLESS_MESH_MEMORY_HPP_
|
|
2
|
+
#define _PAINLESS_MESH_MEMORY_HPP_
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Memory management utilities for painlessMesh
|
|
6
|
+
*
|
|
7
|
+
* This module provides optimized memory management utilities to reduce
|
|
8
|
+
* allocations and improve performance in memory-constrained environments.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include "painlessmesh/configuration.hpp"
|
|
12
|
+
#include <memory>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
namespace painlessmesh {
|
|
16
|
+
namespace memory {
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Object pool for frequently allocated types
|
|
20
|
+
* Reduces allocation overhead for commonly used objects
|
|
21
|
+
*/
|
|
22
|
+
template<typename T>
|
|
23
|
+
class ObjectPool {
|
|
24
|
+
public:
|
|
25
|
+
ObjectPool(size_t initial_size = 10) {
|
|
26
|
+
pool_.reserve(initial_size);
|
|
27
|
+
for (size_t i = 0; i < initial_size; ++i) {
|
|
28
|
+
pool_.emplace_back(std::make_unique<T>());
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
std::unique_ptr<T> acquire() {
|
|
33
|
+
if (!pool_.empty()) {
|
|
34
|
+
auto obj = std::move(pool_.back());
|
|
35
|
+
pool_.pop_back();
|
|
36
|
+
return obj;
|
|
37
|
+
}
|
|
38
|
+
return std::make_unique<T>();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
void release(std::unique_ptr<T> obj) {
|
|
42
|
+
if (pool_.size() < max_pool_size_) {
|
|
43
|
+
// Reset object to default state before returning to pool
|
|
44
|
+
*obj = T{};
|
|
45
|
+
pool_.push_back(std::move(obj));
|
|
46
|
+
}
|
|
47
|
+
// If pool is full, let unique_ptr destroy the object automatically
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
size_t size() const { return pool_.size(); }
|
|
51
|
+
|
|
52
|
+
private:
|
|
53
|
+
std::vector<std::unique_ptr<T>> pool_;
|
|
54
|
+
static constexpr size_t max_pool_size_ = 20; // Prevent unlimited growth
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Pre-sized string buffer to avoid frequent reallocations
|
|
59
|
+
*/
|
|
60
|
+
class StringBuffer {
|
|
61
|
+
public:
|
|
62
|
+
explicit StringBuffer(size_t initial_capacity = 512) {
|
|
63
|
+
buffer_.reserve(initial_capacity);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void clear() { buffer_.clear(); }
|
|
67
|
+
|
|
68
|
+
void append(const TSTRING& str) {
|
|
69
|
+
if (buffer_.capacity() < buffer_.size() + str.length()) {
|
|
70
|
+
buffer_.reserve(std::max(buffer_.capacity() * 2, buffer_.size() + str.length()));
|
|
71
|
+
}
|
|
72
|
+
buffer_ += str;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const TSTRING& str() const { return buffer_; }
|
|
76
|
+
TSTRING& str() { return buffer_; }
|
|
77
|
+
|
|
78
|
+
size_t capacity() const { return buffer_.capacity(); }
|
|
79
|
+
size_t size() const { return buffer_.size(); }
|
|
80
|
+
|
|
81
|
+
private:
|
|
82
|
+
TSTRING buffer_;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Memory usage statistics for monitoring
|
|
87
|
+
*/
|
|
88
|
+
struct MemoryStats {
|
|
89
|
+
size_t total_allocated = 0;
|
|
90
|
+
size_t total_freed = 0;
|
|
91
|
+
size_t current_usage = 0;
|
|
92
|
+
size_t peak_usage = 0;
|
|
93
|
+
size_t allocation_count = 0;
|
|
94
|
+
|
|
95
|
+
void record_allocation(size_t size) {
|
|
96
|
+
total_allocated += size;
|
|
97
|
+
current_usage += size;
|
|
98
|
+
peak_usage = std::max(peak_usage, current_usage);
|
|
99
|
+
++allocation_count;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
void record_deallocation(size_t size) {
|
|
103
|
+
total_freed += size;
|
|
104
|
+
current_usage = (current_usage >= size) ? current_usage - size : 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void reset() {
|
|
108
|
+
*this = MemoryStats{};
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Global memory statistics (optional, can be disabled for production)
|
|
113
|
+
#ifdef PAINLESS_MESH_ENABLE_MEMORY_STATS
|
|
114
|
+
extern MemoryStats global_memory_stats;
|
|
115
|
+
#endif
|
|
116
|
+
|
|
117
|
+
} // namespace memory
|
|
118
|
+
} // namespace painlessmesh
|
|
119
|
+
|
|
120
120
|
#endif // _PAINLESS_MESH_MEMORY_HPP_
|