Fix access: use friend + static comparators for protected member access

This commit is contained in:
J. Nick Koston
2026-03-31 23:11:33 -10:00
parent b63dc719e5
commit 0b59acb922
4 changed files with 29 additions and 6 deletions
@@ -47,9 +47,7 @@ void RuntimeStatsCollector::log_stats_() {
}
// Sort by period runtime (descending)
std::sort(sorted, sorted + count, [](Component *a, Component *b) {
return a->runtime_stats_.period_time_us > b->runtime_stats_.period_time_us;
});
std::sort(sorted, sorted + count, compare_period_time_);
// Log top components by period runtime
for (size_t i = 0; i < count; i++) {
@@ -64,9 +62,7 @@ void RuntimeStatsCollector::log_stats_() {
ESP_LOGI(TAG, " Total stats (since boot): %zu active components", count);
// Re-sort by total runtime for all-time stats
std::sort(sorted, sorted + count, [](Component *a, Component *b) {
return a->runtime_stats_.total_time_us > b->runtime_stats_.total_time_us;
});
std::sort(sorted, sorted + count, compare_total_time_);
for (size_t i = 0; i < count; i++) {
const auto &stats = sorted[i]->runtime_stats_;
@@ -82,6 +78,14 @@ void RuntimeStatsCollector::log_stats_() {
}
}
bool RuntimeStatsCollector::compare_period_time_(Component *a, Component *b) {
return a->runtime_stats_.period_time_us > b->runtime_stats_.period_time_us;
}
bool RuntimeStatsCollector::compare_total_time_(Component *a, Component *b) {
return a->runtime_stats_.total_time_us > b->runtime_stats_.total_time_us;
}
void RuntimeStatsCollector::process_pending_stats(uint32_t current_time) {
if ((int32_t) (current_time - this->next_log_time_) >= 0) {
this->log_stats_();
@@ -31,6 +31,9 @@ class RuntimeStatsCollector {
protected:
void log_stats_();
// Static comparators — member functions have friend access, lambdas do not
static bool compare_period_time_(Component *a, Component *b);
static bool compare_total_time_(Component *a, Component *b);
uint32_t log_interval_;
uint32_t next_log_time_{0};
+9
View File
@@ -130,6 +130,12 @@ bool socket_ready_fd(int fd, bool loop_monitored); // NOLINT(readability-redund
#endif
} // namespace esphome::socket
#ifdef USE_RUNTIME_STATS
namespace esphome::runtime_stats {
class RuntimeStatsCollector;
} // namespace esphome::runtime_stats
#endif
// Forward declarations for friend access from codegen-generated setup()
void setup(); // NOLINT(readability-redundant-declaration) - may be declared in Arduino.h
void original_setup(); // NOLINT(readability-redundant-declaration) - used by cpp unit tests
@@ -590,6 +596,9 @@ class Application {
friend Component;
#if defined(USE_SOCKET_SELECT_SUPPORT) && !defined(USE_LWIP_FAST_SELECT)
friend bool socket::socket_ready_fd(int fd, bool loop_monitored);
#endif
#ifdef USE_RUNTIME_STATS
friend class runtime_stats::RuntimeStatsCollector;
#endif
friend void ::setup();
friend void ::original_setup();
+7
View File
@@ -20,6 +20,12 @@ namespace esphome {
// Forward declaration for LogString
struct LogString;
#ifdef USE_RUNTIME_STATS
namespace runtime_stats {
class RuntimeStatsCollector;
} // namespace runtime_stats
#endif
/** Default setup priorities for components of different types.
*
* Components should return one of these setup priorities in get_setup_priority.
@@ -561,6 +567,7 @@ class Component {
uint8_t component_state_{0x00};
volatile bool pending_enable_loop_{false}; ///< ISR-safe flag for enable_loop_soon_any_context
#ifdef USE_RUNTIME_STATS
friend class runtime_stats::RuntimeStatsCollector;
ComponentRuntimeStats runtime_stats_;
#endif
};