@alteriom/painlessmesh 1.6.1 → 1.7.3

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.
Files changed (152) hide show
  1. package/CHANGELOG.md +435 -144
  2. package/LICENSE +674 -674
  3. package/README.md +491 -434
  4. package/RELEASE_GUIDE.md +504 -418
  5. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +175 -175
  6. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +1062 -0
  7. package/docs/MESH_TOPOLOGY_GUIDE.md +992 -0
  8. package/docs/MESH_TOPOLOGY_PROGRESS.md +422 -0
  9. package/docs/MQTT_BRIDGE_COMMANDS.md +894 -0
  10. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +324 -0
  11. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +576 -0
  12. package/docs/MQTT_SCHEMA_COMPLIANCE.md +285 -0
  13. package/docs/MQTT_SCHEMA_PROPOSALS.md +446 -0
  14. package/docs/MQTT_SCHEMA_REVIEW.md +690 -0
  15. package/docs/OTA_COMMANDS_REFERENCE.md +554 -0
  16. package/docs/PHASE1_GUIDE.md +349 -0
  17. package/docs/PHASE2_GUIDE.md +543 -0
  18. package/docs/README.md +130 -71
  19. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +222 -0
  20. package/docs/alteriom/overview.md +507 -507
  21. package/docs/api/core-api.md +606 -606
  22. package/docs/architecture/mesh-architecture.md +378 -378
  23. package/docs/architecture/plugin-system.md +516 -516
  24. package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +166 -0
  25. package/docs/archive/FEATURE_PROPOSALS.md +337 -0
  26. package/docs/archive/LIBRARY_JSON_FIX.md +98 -0
  27. package/docs/archive/LIBRARY_STRUCTURE_FIX.md +215 -0
  28. package/docs/archive/PHASE1_IMPLEMENTATION.md +325 -0
  29. package/docs/archive/PHASE2_IMPLEMENTATION.md +567 -0
  30. package/docs/archive/RELEASE_SUMMARY.md +173 -0
  31. package/docs/archive/SCONS_BUILD_FIX.md +313 -0
  32. package/docs/archive/TRIGGER_RELEASE.md +280 -0
  33. package/docs/archive/VECTOR_INCLUDE_FIX.md +129 -0
  34. package/docs/archive/ota-and-status-enhancements.md +911 -0
  35. package/docs/archive/ota-status-architecture-diagrams.md +658 -0
  36. package/docs/archive/ota-status-quick-reference.md +284 -0
  37. package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +71 -0
  38. package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +1011 -0
  39. package/docs/development/DOCKER_TESTING.md +196 -0
  40. package/docs/development/PLATFORMIO_USAGE.md +180 -0
  41. package/docs/development/TESTING_SUMMARY.md +126 -0
  42. package/docs/development/contributing.md +301 -0
  43. package/docs/development/documentation.md +583 -0
  44. package/docs/getting-started/first-mesh.md +409 -409
  45. package/docs/getting-started/installation.md +274 -274
  46. package/docs/getting-started/quickstart.md +157 -157
  47. package/docs/improvements/FUTURE_PROPOSALS.md +1016 -0
  48. package/docs/improvements/IMPLEMENTATION_HISTORY.md +1091 -0
  49. package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +709 -0
  50. package/docs/improvements/README.md +212 -69
  51. package/docs/platformio-publishing.md +255 -0
  52. package/docs/platformio-setup-summary.md +121 -0
  53. package/docs/releases/FEATURE_HISTORY.md +543 -0
  54. package/docs/releases/PATCH_v1.7.3.md +262 -0
  55. package/docs/releases/PHASE1_SUMMARY.md +246 -0
  56. package/docs/releases/PHASE2_SUMMARY.md +499 -0
  57. package/docs/releases/RELEASE_NOTES_1.7.0.md +539 -0
  58. package/docs/troubleshooting/common-issues.md +520 -520
  59. package/docs/troubleshooting/debugging.md +455 -0
  60. package/docs/troubleshooting/faq.md +472 -472
  61. package/docs/tutorials/basic-examples.md +717 -717
  62. package/docs/wiki/API-Reference.md +245 -245
  63. package/docs/wiki/Complete-Documentation.md +122 -122
  64. package/examples/alteriom/README.md +139 -81
  65. package/examples/alteriom/alteriom.ino +186 -185
  66. package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
  67. package/examples/alteriom/platformio.ini +24 -24
  68. package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
  69. package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
  70. package/examples/alteriomImproved/platformio.ini +25 -0
  71. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
  72. package/examples/alteriomPhase1/phase1_features.ino +242 -0
  73. package/examples/alteriomPhase1/platformio.ini +25 -0
  74. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
  75. package/examples/alteriomPhase2/phase2_features.ino +186 -0
  76. package/examples/alteriomPhase2/platformio.ini +25 -0
  77. package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
  78. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
  79. package/examples/alteriomSensorNode/platformio.ini +25 -0
  80. package/examples/basic/basic.ino +66 -66
  81. package/examples/basic/platformio.ini +25 -25
  82. package/examples/bridge/bridge.ino +51 -51
  83. package/examples/bridge/mesh_event_publisher.hpp +253 -0
  84. package/examples/bridge/mesh_topology_reporter.hpp +303 -0
  85. package/examples/bridge/mqtt_command_bridge.hpp +459 -0
  86. package/examples/bridge/mqtt_status_bridge.hpp +519 -0
  87. package/examples/bridge/platformio.ini +25 -25
  88. package/examples/echoNode/echoNode.ino +33 -33
  89. package/examples/echoNode/platformio.ini +25 -25
  90. package/examples/logClient/logClient.ino +109 -109
  91. package/examples/logClient/platformio.ini +25 -25
  92. package/examples/logServer/logServer.ino +81 -81
  93. package/examples/logServer/platformio.ini +25 -25
  94. package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
  95. package/examples/meshCommandNode/meshCommandNode.ino +263 -0
  96. package/examples/meshCommandNode/platformio.ini +25 -0
  97. package/examples/mqttBridge/mqttBridge.ino +118 -118
  98. package/examples/mqttBridge/platformio.ini +26 -26
  99. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
  100. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
  101. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
  102. package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
  103. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
  104. package/examples/mqttCommandBridge/platformio.ini +26 -0
  105. package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
  106. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
  107. package/examples/mqttStatusBridge/platformio.ini +26 -0
  108. package/examples/mqttTopologyTest/README.md +467 -0
  109. package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
  110. package/examples/mqttTopologyTest/platformio.ini +26 -0
  111. package/examples/namedMesh/namedMesh.ino +97 -97
  112. package/examples/namedMesh/platformio.ini +25 -25
  113. package/examples/otaReceiver/otaReceiver.ino +79 -79
  114. package/examples/otaReceiver/platformio.ini +25 -25
  115. package/examples/otaSender/otaSender.ino +160 -151
  116. package/examples/otaSender/platformio.ini +25 -25
  117. package/examples/startHere/platformio.ini +25 -25
  118. package/examples/startHere/startHere.ino +159 -159
  119. package/examples/webServer/platformio.ini +27 -27
  120. package/examples/webServer/webServer.ino +89 -89
  121. package/keywords.txt +48 -48
  122. package/library.json +55 -34
  123. package/library.properties +10 -10
  124. package/package.json +86 -78
  125. package/src/AlteriomPainlessMesh.h +97 -97
  126. package/src/arduino/wifi.hpp +365 -365
  127. package/src/boost/asynctcp.hpp +279 -279
  128. package/src/painlessMesh.h +70 -70
  129. package/src/painlessMeshSTA.cpp +236 -236
  130. package/src/painlessMeshSTA.h +58 -58
  131. package/src/painlessTaskOptions.h +4 -4
  132. package/src/painlessmesh/base64.hpp +111 -111
  133. package/src/painlessmesh/buffer.hpp +229 -229
  134. package/src/painlessmesh/callback.hpp +91 -91
  135. package/src/painlessmesh/configuration.hpp +77 -77
  136. package/src/painlessmesh/connection.hpp +192 -192
  137. package/src/painlessmesh/layout.hpp +188 -188
  138. package/src/painlessmesh/logger.hpp +158 -158
  139. package/src/painlessmesh/memory.hpp +119 -119
  140. package/src/painlessmesh/mesh.hpp +761 -560
  141. package/src/painlessmesh/metrics.hpp +322 -322
  142. package/src/painlessmesh/ntp.hpp +263 -263
  143. package/src/painlessmesh/ota.hpp +582 -553
  144. package/src/painlessmesh/plugin.hpp +188 -188
  145. package/src/painlessmesh/protocol.hpp +813 -813
  146. package/src/painlessmesh/router.hpp +338 -322
  147. package/src/painlessmesh/tcp.hpp +71 -71
  148. package/src/painlessmesh/validation.hpp +238 -238
  149. package/src/plugin/performance.hpp +214 -214
  150. package/src/plugin/remote.hpp +64 -64
  151. package/src/scheduler.cpp +10 -10
  152. 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_