1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-05 03:13:49 +01:00

partition

This commit is contained in:
J. Nick Koston
2025-06-15 18:32:36 -05:00
parent bb2bb128f7
commit 8a06c4380d
4 changed files with 83 additions and 15 deletions

View File

@@ -97,11 +97,12 @@ void Application::loop() {
// Feed WDT with time
this->feed_wdt(last_op_end_time);
for (Component *component : this->looping_components_) {
// Skip components that are done or failed
if (component->should_skip_loop()) {
continue;
}
// Mark that we're in the loop for safe reentrant modifications
this->in_loop_ = true;
for (this->current_loop_index_ = 0; this->current_loop_index_ < this->looping_components_active_end_;
this->current_loop_index_++) {
Component *component = this->looping_components_[this->current_loop_index_];
// Update the cached time before each component runs
this->loop_component_start_time_ = last_op_end_time;
@@ -117,6 +118,8 @@ void Application::loop() {
this->app_state_ |= new_app_state;
this->feed_wdt(last_op_end_time);
}
this->in_loop_ = false;
this->app_state_ = new_app_state;
// Use the last component's end time instead of calling millis() again
@@ -244,6 +247,52 @@ void Application::calculate_looping_components_() {
if (obj->has_overridden_loop())
this->looping_components_.push_back(obj);
}
// Initially all components are active
this->looping_components_active_end_ = this->looping_components_.size();
}
void Application::disable_component_loop(Component *component) {
// Linear search to find component in active section
// Most configs have 10-30 looping components (30 is on the high end)
// O(n) is acceptable here as we optimize for memory, not complexity
for (uint16_t i = 0; i < this->looping_components_active_end_; i++) {
if (this->looping_components_[i] == component) {
// Move last active component to this position
this->looping_components_active_end_--;
if (i != this->looping_components_active_end_) {
this->looping_components_[i] = this->looping_components_[this->looping_components_active_end_];
this->looping_components_[this->looping_components_active_end_] = component;
// If we're currently iterating and just swapped the current position
if (this->in_loop_ && i == this->current_loop_index_) {
// Decrement so we'll process the swapped component next
this->current_loop_index_--;
}
}
return;
}
}
}
void Application::enable_component_loop(Component *component) {
// Single pass through all components to find and move if needed
// With typical 10-30 components, O(n) is faster than maintaining a map
const uint16_t size = this->looping_components_.size();
for (uint16_t i = 0; i < size; i++) {
if (this->looping_components_[i] == component) {
if (i < this->looping_components_active_end_) {
return; // Already active
}
// Found in inactive section - move to active
if (i != this->looping_components_active_end_) {
Component *temp = this->looping_components_[this->looping_components_active_end_];
this->looping_components_[this->looping_components_active_end_] = component;
this->looping_components_[i] = temp;
}
this->looping_components_active_end_++;
return;
}
}
}
#ifdef USE_SOCKET_SELECT_SUPPORT