@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.
Files changed (129) hide show
  1. package/CHANGELOG.md +380 -143
  2. package/LICENSE +674 -674
  3. package/README.md +477 -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 +77 -70
  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/getting-started/first-mesh.md +409 -409
  25. package/docs/getting-started/installation.md +274 -274
  26. package/docs/getting-started/quickstart.md +157 -157
  27. package/docs/improvements/FEATURE_PROPOSALS.md +337 -0
  28. package/docs/improvements/PHASE1_IMPLEMENTATION.md +325 -0
  29. package/docs/improvements/PHASE2_IMPLEMENTATION.md +567 -0
  30. package/docs/improvements/README.md +86 -68
  31. package/docs/improvements/ota-and-status-enhancements.md +911 -0
  32. package/docs/improvements/ota-status-architecture-diagrams.md +658 -0
  33. package/docs/improvements/ota-status-quick-reference.md +284 -0
  34. package/docs/platformio-publishing.md +255 -0
  35. package/docs/platformio-setup-summary.md +121 -0
  36. package/docs/troubleshooting/common-issues.md +520 -520
  37. package/docs/troubleshooting/faq.md +472 -472
  38. package/docs/tutorials/basic-examples.md +717 -717
  39. package/docs/wiki/API-Reference.md +245 -245
  40. package/docs/wiki/Complete-Documentation.md +122 -122
  41. package/examples/alteriom/README.md +139 -81
  42. package/examples/alteriom/alteriom.ino +186 -185
  43. package/examples/alteriom/alteriom_sensor_package.hpp +240 -127
  44. package/examples/alteriom/platformio.ini +24 -24
  45. package/examples/alteriomImproved/alteriom_sensor_package.hpp +224 -0
  46. package/examples/{alteriom → alteriomImproved}/improved_sensor_node.ino +245 -245
  47. package/examples/alteriomImproved/platformio.ini +25 -0
  48. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +224 -0
  49. package/examples/alteriomPhase1/phase1_features.ino +242 -0
  50. package/examples/alteriomPhase1/platformio.ini +25 -0
  51. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +224 -0
  52. package/examples/alteriomPhase2/phase2_features.ino +186 -0
  53. package/examples/alteriomPhase2/platformio.ini +25 -0
  54. package/examples/{alteriom → alteriomSensorNode}/alteriom_sensor_node.ino +183 -183
  55. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +224 -0
  56. package/examples/alteriomSensorNode/platformio.ini +25 -0
  57. package/examples/basic/basic.ino +66 -66
  58. package/examples/basic/platformio.ini +25 -25
  59. package/examples/bridge/bridge.ino +51 -51
  60. package/examples/bridge/mesh_event_publisher.hpp +253 -0
  61. package/examples/bridge/mesh_topology_reporter.hpp +303 -0
  62. package/examples/bridge/mqtt_command_bridge.hpp +459 -0
  63. package/examples/bridge/mqtt_status_bridge.hpp +519 -0
  64. package/examples/bridge/platformio.ini +25 -25
  65. package/examples/echoNode/echoNode.ino +33 -33
  66. package/examples/echoNode/platformio.ini +25 -25
  67. package/examples/logClient/logClient.ino +109 -109
  68. package/examples/logClient/platformio.ini +25 -25
  69. package/examples/logServer/logServer.ino +81 -81
  70. package/examples/logServer/platformio.ini +25 -25
  71. package/examples/meshCommandNode/alteriom_sensor_package.hpp +235 -0
  72. package/examples/meshCommandNode/meshCommandNode.ino +263 -0
  73. package/examples/meshCommandNode/platformio.ini +25 -0
  74. package/examples/mqttBridge/mqttBridge.ino +118 -118
  75. package/examples/mqttBridge/platformio.ini +26 -26
  76. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +235 -0
  77. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +253 -0
  78. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +303 -0
  79. package/examples/mqttCommandBridge/mqttCommandBridge.ino +252 -0
  80. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +459 -0
  81. package/examples/mqttCommandBridge/platformio.ini +26 -0
  82. package/examples/mqttStatusBridge/mqttStatusBridge.ino +216 -0
  83. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +522 -0
  84. package/examples/mqttStatusBridge/platformio.ini +26 -0
  85. package/examples/mqttTopologyTest/README.md +467 -0
  86. package/examples/mqttTopologyTest/mqttTopologyTest.ino +748 -0
  87. package/examples/mqttTopologyTest/platformio.ini +26 -0
  88. package/examples/namedMesh/namedMesh.ino +97 -97
  89. package/examples/namedMesh/platformio.ini +25 -25
  90. package/examples/otaReceiver/otaReceiver.ino +79 -79
  91. package/examples/otaReceiver/platformio.ini +25 -25
  92. package/examples/otaSender/otaSender.ino +160 -151
  93. package/examples/otaSender/platformio.ini +25 -25
  94. package/examples/startHere/platformio.ini +25 -25
  95. package/examples/startHere/startHere.ino +159 -159
  96. package/examples/webServer/platformio.ini +27 -27
  97. package/examples/webServer/webServer.ino +89 -89
  98. package/keywords.txt +48 -48
  99. package/library.json +55 -34
  100. package/library.properties +10 -10
  101. package/package.json +86 -78
  102. package/src/AlteriomPainlessMesh.h +97 -97
  103. package/src/arduino/wifi.hpp +365 -365
  104. package/src/boost/asynctcp.hpp +279 -279
  105. package/src/painlessMesh.h +70 -70
  106. package/src/painlessMeshSTA.cpp +236 -236
  107. package/src/painlessMeshSTA.h +58 -58
  108. package/src/painlessTaskOptions.h +4 -4
  109. package/src/painlessmesh/base64.hpp +111 -111
  110. package/src/painlessmesh/buffer.hpp +229 -229
  111. package/src/painlessmesh/callback.hpp +91 -91
  112. package/src/painlessmesh/configuration.hpp +77 -77
  113. package/src/painlessmesh/connection.hpp +192 -192
  114. package/src/painlessmesh/layout.hpp +188 -188
  115. package/src/painlessmesh/logger.hpp +158 -158
  116. package/src/painlessmesh/memory.hpp +119 -119
  117. package/src/painlessmesh/mesh.hpp +761 -560
  118. package/src/painlessmesh/metrics.hpp +322 -322
  119. package/src/painlessmesh/ntp.hpp +263 -263
  120. package/src/painlessmesh/ota.hpp +582 -553
  121. package/src/painlessmesh/plugin.hpp +188 -188
  122. package/src/painlessmesh/protocol.hpp +813 -813
  123. package/src/painlessmesh/router.hpp +322 -322
  124. package/src/painlessmesh/tcp.hpp +71 -71
  125. package/src/painlessmesh/validation.hpp +238 -238
  126. package/src/plugin/performance.hpp +214 -214
  127. package/src/plugin/remote.hpp +64 -64
  128. package/src/scheduler.cpp +10 -10
  129. 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_