#pragma once #include "esphome/core/component.h" #include #include namespace esphome { class Component; class Scheduler { public: void set_timeout(Component *component, const std::string &name, uint32_t timeout, std::function &&func); bool cancel_timeout(Component *component, const std::string &name); void set_interval(Component *component, const std::string &name, uint32_t interval, std::function &&func); bool cancel_interval(Component *component, const std::string &name); optional next_schedule_in(); void call(); void process_to_add(); protected: struct SchedulerItem { Component *component; std::string name; enum Type { TIMEOUT, INTERVAL } type; union { uint32_t interval; uint32_t timeout; }; uint32_t last_execution; std::function f; bool remove; uint8_t last_execution_major; inline uint32_t next_execution() { return this->last_execution + this->timeout; } inline uint8_t next_execution_major() { uint32_t next_exec = this->next_execution(); uint8_t next_exec_major = this->last_execution_major; if (next_exec < this->last_execution) next_exec_major++; return next_exec_major; } static bool cmp(const std::unique_ptr &a, const std::unique_ptr &b); }; uint32_t millis_(); void cleanup_(); void pop_raw_(); void push_(std::unique_ptr item); bool cancel_item_(Component *component, const std::string &name, SchedulerItem::Type type); bool empty_() { this->cleanup_(); return this->items_.empty(); } std::vector> items_; std::vector> to_add_; uint32_t last_millis_{0}; uint8_t millis_major_{0}; uint32_t to_remove_{0}; }; } // namespace esphome