mirror of
https://github.com/esphome/esphome.git
synced 2025-09-15 17:52:19 +01:00
[core] Refactor insertion sort functions to eliminate code duplication (#10653)
This commit is contained in:
@@ -34,37 +34,20 @@ namespace esphome {
|
|||||||
|
|
||||||
static const char *const TAG = "app";
|
static const char *const TAG = "app";
|
||||||
|
|
||||||
// Helper function for insertion sort of components by setup priority
|
// Helper function for insertion sort of components by priority
|
||||||
// Using insertion sort instead of std::stable_sort saves ~1.3KB of flash
|
// Using insertion sort instead of std::stable_sort saves ~1.3KB of flash
|
||||||
// by avoiding template instantiations (std::rotate, std::stable_sort, lambdas)
|
// by avoiding template instantiations (std::rotate, std::stable_sort, lambdas)
|
||||||
// IMPORTANT: This sort is stable (preserves relative order of equal elements),
|
// IMPORTANT: This sort is stable (preserves relative order of equal elements),
|
||||||
// which is necessary to maintain user-defined component order for same priority
|
// which is necessary to maintain user-defined component order for same priority
|
||||||
template<typename Iterator> static void insertion_sort_by_setup_priority(Iterator first, Iterator last) {
|
template<typename Iterator, float (Component::*GetPriority)() const>
|
||||||
|
static void insertion_sort_by_priority(Iterator first, Iterator last) {
|
||||||
for (auto it = first + 1; it != last; ++it) {
|
for (auto it = first + 1; it != last; ++it) {
|
||||||
auto key = *it;
|
auto key = *it;
|
||||||
float key_priority = key->get_actual_setup_priority();
|
float key_priority = (key->*GetPriority)();
|
||||||
auto j = it - 1;
|
auto j = it - 1;
|
||||||
|
|
||||||
// Using '<' (not '<=') ensures stability - equal priority components keep their order
|
// Using '<' (not '<=') ensures stability - equal priority components keep their order
|
||||||
while (j >= first && (*j)->get_actual_setup_priority() < key_priority) {
|
while (j >= first && ((*j)->*GetPriority)() < key_priority) {
|
||||||
*(j + 1) = *j;
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
*(j + 1) = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function for insertion sort of components by loop priority
|
|
||||||
// IMPORTANT: This sort is stable (preserves relative order of equal elements),
|
|
||||||
// which is required when components are re-sorted during setup() if they block
|
|
||||||
template<typename Iterator> static void insertion_sort_by_loop_priority(Iterator first, Iterator last) {
|
|
||||||
for (auto it = first + 1; it != last; ++it) {
|
|
||||||
auto key = *it;
|
|
||||||
float key_priority = key->get_loop_priority();
|
|
||||||
auto j = it - 1;
|
|
||||||
|
|
||||||
// Using '<' (not '<=') ensures stability - equal priority components keep their order
|
|
||||||
while (j >= first && (*j)->get_loop_priority() < key_priority) {
|
|
||||||
*(j + 1) = *j;
|
*(j + 1) = *j;
|
||||||
j--;
|
j--;
|
||||||
}
|
}
|
||||||
@@ -91,7 +74,8 @@ void Application::setup() {
|
|||||||
ESP_LOGV(TAG, "Sorting components by setup priority");
|
ESP_LOGV(TAG, "Sorting components by setup priority");
|
||||||
|
|
||||||
// Sort by setup priority using our helper function
|
// Sort by setup priority using our helper function
|
||||||
insertion_sort_by_setup_priority(this->components_.begin(), this->components_.end());
|
insertion_sort_by_priority<decltype(this->components_.begin()), &Component::get_actual_setup_priority>(
|
||||||
|
this->components_.begin(), this->components_.end());
|
||||||
|
|
||||||
// Initialize looping_components_ early so enable_pending_loops_() works during setup
|
// Initialize looping_components_ early so enable_pending_loops_() works during setup
|
||||||
this->calculate_looping_components_();
|
this->calculate_looping_components_();
|
||||||
@@ -108,7 +92,8 @@ void Application::setup() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Sort components 0 through i by loop priority
|
// Sort components 0 through i by loop priority
|
||||||
insertion_sort_by_loop_priority(this->components_.begin(), this->components_.begin() + i + 1);
|
insertion_sort_by_priority<decltype(this->components_.begin()), &Component::get_loop_priority>(
|
||||||
|
this->components_.begin(), this->components_.begin() + i + 1);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
uint8_t new_app_state = STATUS_LED_WARNING;
|
uint8_t new_app_state = STATUS_LED_WARNING;
|
||||||
|
Reference in New Issue
Block a user