[core] Fix component state documentation and add state helper method (#9824)

This commit is contained in:
J. Nick Koston 2025-07-23 17:22:42 -10:00 committed by GitHub
parent 99850255f0
commit 544cf9b9c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 20 deletions

View File

@ -151,26 +151,22 @@ void Component::call() {
switch (state) { switch (state) {
case COMPONENT_STATE_CONSTRUCTION: case COMPONENT_STATE_CONSTRUCTION:
// State Construction: Call setup and set state to setup // State Construction: Call setup and set state to setup
this->component_state_ &= ~COMPONENT_STATE_MASK; this->set_component_state_(COMPONENT_STATE_SETUP);
this->component_state_ |= COMPONENT_STATE_SETUP;
this->call_setup(); this->call_setup();
break; break;
case COMPONENT_STATE_SETUP: case COMPONENT_STATE_SETUP:
// State setup: Call first loop and set state to loop // State setup: Call first loop and set state to loop
this->component_state_ &= ~COMPONENT_STATE_MASK; this->set_component_state_(COMPONENT_STATE_LOOP);
this->component_state_ |= COMPONENT_STATE_LOOP;
this->call_loop(); this->call_loop();
break; break;
case COMPONENT_STATE_LOOP: case COMPONENT_STATE_LOOP:
// State loop: Call loop // State loop: Call loop
this->call_loop(); this->call_loop();
break; break;
case COMPONENT_STATE_FAILED: // NOLINT(bugprone-branch-clone) case COMPONENT_STATE_FAILED:
// State failed: Do nothing // State failed: Do nothing
break; case COMPONENT_STATE_LOOP_DONE:
case COMPONENT_STATE_LOOP_DONE: // NOLINT(bugprone-branch-clone)
// State loop done: Do nothing, component has finished its work // State loop done: Do nothing, component has finished its work
break;
default: default:
break; break;
} }
@ -195,25 +191,26 @@ bool Component::should_warn_of_blocking(uint32_t blocking_time) {
} }
void Component::mark_failed() { void Component::mark_failed() {
ESP_LOGE(TAG, "%s was marked as failed", this->get_component_source()); ESP_LOGE(TAG, "%s was marked as failed", this->get_component_source());
this->component_state_ &= ~COMPONENT_STATE_MASK; this->set_component_state_(COMPONENT_STATE_FAILED);
this->component_state_ |= COMPONENT_STATE_FAILED;
this->status_set_error(); this->status_set_error();
// Also remove from loop since failed components shouldn't loop // Also remove from loop since failed components shouldn't loop
App.disable_component_loop_(this); App.disable_component_loop_(this);
} }
void Component::set_component_state_(uint8_t state) {
this->component_state_ &= ~COMPONENT_STATE_MASK;
this->component_state_ |= state;
}
void Component::disable_loop() { void Component::disable_loop() {
if ((this->component_state_ & COMPONENT_STATE_MASK) != COMPONENT_STATE_LOOP_DONE) { if ((this->component_state_ & COMPONENT_STATE_MASK) != COMPONENT_STATE_LOOP_DONE) {
ESP_LOGVV(TAG, "%s loop disabled", this->get_component_source()); ESP_LOGVV(TAG, "%s loop disabled", this->get_component_source());
this->component_state_ &= ~COMPONENT_STATE_MASK; this->set_component_state_(COMPONENT_STATE_LOOP_DONE);
this->component_state_ |= COMPONENT_STATE_LOOP_DONE;
App.disable_component_loop_(this); App.disable_component_loop_(this);
} }
} }
void Component::enable_loop() { void Component::enable_loop() {
if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) { if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) {
ESP_LOGVV(TAG, "%s loop enabled", this->get_component_source()); ESP_LOGVV(TAG, "%s loop enabled", this->get_component_source());
this->component_state_ &= ~COMPONENT_STATE_MASK; this->set_component_state_(COMPONENT_STATE_LOOP);
this->component_state_ |= COMPONENT_STATE_LOOP;
App.enable_component_loop_(this); App.enable_component_loop_(this);
} }
} }
@ -233,8 +230,7 @@ void IRAM_ATTR HOT Component::enable_loop_soon_any_context() {
void Component::reset_to_construction_state() { void Component::reset_to_construction_state() {
if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED) { if ((this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_FAILED) {
ESP_LOGI(TAG, "%s is being reset to construction state", this->get_component_source()); ESP_LOGI(TAG, "%s is being reset to construction state", this->get_component_source());
this->component_state_ &= ~COMPONENT_STATE_MASK; this->set_component_state_(COMPONENT_STATE_CONSTRUCTION);
this->component_state_ |= COMPONENT_STATE_CONSTRUCTION;
// Clear error status when resetting // Clear error status when resetting
this->status_clear_error(); this->status_clear_error();
} }

View File

@ -236,6 +236,9 @@ class Component {
virtual void call_setup(); virtual void call_setup();
virtual void call_dump_config(); virtual void call_dump_config();
/// Helper to set component state (clears state bits and sets new state)
void set_component_state_(uint8_t state);
/** Set an interval function with a unique name. Empty name means no cancelling possible. /** Set an interval function with a unique name. Empty name means no cancelling possible.
* *
* This will call f every interval ms. Can be cancelled via CancelInterval(). * This will call f every interval ms. Can be cancelled via CancelInterval().
@ -405,10 +408,10 @@ class Component {
const char *component_source_{nullptr}; const char *component_source_{nullptr};
uint16_t warn_if_blocking_over_{WARN_IF_BLOCKING_OVER_MS}; ///< Warn if blocked for this many ms (max 65.5s) uint16_t warn_if_blocking_over_{WARN_IF_BLOCKING_OVER_MS}; ///< Warn if blocked for this many ms (max 65.5s)
/// State of this component - each bit has a purpose: /// State of this component - each bit has a purpose:
/// Bits 0-1: Component state (0x00=CONSTRUCTION, 0x01=SETUP, 0x02=LOOP, 0x03=FAILED) /// Bits 0-2: Component state (0x00=CONSTRUCTION, 0x01=SETUP, 0x02=LOOP, 0x03=FAILED, 0x04=LOOP_DONE)
/// Bit 2: STATUS_LED_WARNING /// Bit 3: STATUS_LED_WARNING
/// Bit 3: STATUS_LED_ERROR /// Bit 4: STATUS_LED_ERROR
/// Bits 4-7: Unused - reserved for future expansion (50% of the bits are free) /// Bits 5-7: Unused - reserved for future expansion
uint8_t component_state_{0x00}; uint8_t component_state_{0x00};
volatile bool pending_enable_loop_{false}; ///< ISR-safe flag for enable_loop_soon_any_context volatile bool pending_enable_loop_{false}; ///< ISR-safe flag for enable_loop_soon_any_context
}; };