1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-24 12:43:51 +01:00

max_runs was actually correct after re-testing dev

This commit is contained in:
J. Nick Koston
2025-10-16 13:20:42 -10:00
parent 353d8b8fb2
commit f2ec2c3fbf
3 changed files with 27 additions and 29 deletions

View File

@@ -99,12 +99,12 @@ template<typename... Ts> class RestartScript : public Script<Ts...> {
* Ring buffer implementation:
* - num_queued_ tracks the number of queued (waiting) instances, NOT including the currently running one
* - queue_front_ points to the next item to execute (read position)
* - Buffer size is max_queued_ (the maximum number that can be queued)
* - Write position is calculated as: (queue_front_ + num_queued_) % max_queued_
* - When an item finishes, queue_front_ advances: (queue_front_ + 1) % max_queued_
* - Buffer size is max_runs_ - 1 (max total instances minus the running one)
* - Write position is calculated as: (queue_front_ + num_queued_) % (max_runs_ - 1)
* - When an item finishes, queue_front_ advances: (queue_front_ + 1) % (max_runs_ - 1)
* - First execute() runs immediately without queuing (num_queued_ stays 0)
* - Subsequent executes while running are queued starting at position 0
* - Maximum total instances = 1 running + max_queued_ queued
* - Maximum total instances = max_runs_ (includes 1 running + (max_runs_ - 1) queued)
*/
template<typename... Ts> class QueueingScript : public Script<Ts...>, public Component {
public:
@@ -113,9 +113,9 @@ template<typename... Ts> class QueueingScript : public Script<Ts...>, public Com
if (this->is_action_running() || this->num_queued_ > 0) {
// num_queued_ is the number of *queued* instances (waiting, not including currently running)
// max_queued_ is the maximum number that can be queued
// So we reject when num_queued_ >= max_queued_
if (this->num_queued_ >= this->max_queued_) {
// max_runs_ is the maximum *total* instances (running + queued)
// So we reject when num_queued_ + 1 >= max_runs_ (queued + running >= max)
if (this->num_queued_ + 1 >= this->max_runs_) {
this->esp_logw_(__LINE__, ESPHOME_LOG_FORMAT("Script '%s' maximum number of queued runs exceeded!"),
LOG_STR_ARG(this->name_));
return;
@@ -123,8 +123,8 @@ template<typename... Ts> class QueueingScript : public Script<Ts...>, public Com
this->esp_logd_(__LINE__, ESPHOME_LOG_FORMAT("Script '%s' queueing new instance (mode: queued)"),
LOG_STR_ARG(this->name_));
// Ring buffer: write to (queue_front_ + num_queued_) % max_queued_
size_t write_pos = (this->queue_front_ + this->num_queued_) % this->max_queued_;
// Ring buffer: write to (queue_front_ + num_queued_) % (max_runs_ - 1)
size_t write_pos = (this->queue_front_ + this->num_queued_) % (this->max_runs_ - 1);
// Use reset() to replace the unique_ptr
this->var_queue_[write_pos].reset(new std::tuple<Ts...>(std::make_tuple(x...)));
this->num_queued_++;
@@ -147,24 +147,22 @@ template<typename... Ts> class QueueingScript : public Script<Ts...>, public Com
// Dequeue: decrement count, read from front, advance read position
this->num_queued_--;
auto &vars = *this->var_queue_[this->queue_front_];
this->queue_front_ = (this->queue_front_ + 1) % this->max_queued_;
this->queue_front_ = (this->queue_front_ + 1) % (this->max_runs_ - 1);
this->trigger_tuple_(vars, typename gens<sizeof...(Ts)>::type());
}
}
// Note: Method named set_max_runs() for backward compatibility with existing configs,
// but internally uses max_queued_ to clarify that it sets the max *queued* instances
void set_max_runs(int max_runs) { max_queued_ = max_runs; }
void set_max_runs(int max_runs) { max_runs_ = max_runs; }
protected:
// Lazy init queue on first use - avoids setup() ordering issues and saves memory
// if script is never executed during this boot cycle
inline void lazy_init_queue_() {
if (this->var_queue_.capacity() == 0) {
// Allocate max_queued_ slots for queued items (running item is separate)
this->var_queue_.init(this->max_queued_);
// Allocate max_runs_ - 1 slots for queued items (running item is separate)
this->var_queue_.init(this->max_runs_ - 1);
// Initialize all unique_ptr slots to nullptr
for (int i = 0; i < this->max_queued_; i++) {
for (int i = 0; i < this->max_runs_ - 1; i++) {
this->var_queue_.push_back(nullptr);
}
}
@@ -175,7 +173,7 @@ template<typename... Ts> class QueueingScript : public Script<Ts...>, public Com
}
int num_queued_ = 0; // Number of queued instances (not including currently running)
int max_queued_ = 0; // Maximum number of queued instances (not including running)
int max_runs_ = 0; // Maximum total instances (running + queued)
size_t queue_front_ = 0; // Ring buffer read position (next item to execute)
FixedVector<std::unique_ptr<std::tuple<Ts...>>> var_queue_; // Ring buffer of queued parameters
};