mirror of
https://github.com/esphome/esphome.git
synced 2025-10-05 03:13:49 +01:00
partition
This commit is contained in:
@@ -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
|
||||
|
Reference in New Issue
Block a user