mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Merge branch 'scheduler_copy' into integration
This commit is contained in:
		| @@ -68,6 +68,10 @@ bool Component::cancel_interval(const std::string &name) {  // NOLINT | ||||
|   return App.scheduler.cancel_interval(this, name); | ||||
| } | ||||
|  | ||||
| bool Component::cancel_interval(const char *name) {  // NOLINT | ||||
|   return App.scheduler.cancel_interval(this, name); | ||||
| } | ||||
|  | ||||
| void Component::set_retry(const std::string &name, uint32_t initial_wait_time, uint8_t max_attempts, | ||||
|                           std::function<RetryResult(uint8_t)> &&f, float backoff_increase_factor) {  // NOLINT | ||||
|   App.scheduler.set_retry(this, name, initial_wait_time, max_attempts, std::move(f), backoff_increase_factor); | ||||
| @@ -89,6 +93,10 @@ bool Component::cancel_timeout(const std::string &name) {  // NOLINT | ||||
|   return App.scheduler.cancel_timeout(this, name); | ||||
| } | ||||
|  | ||||
| bool Component::cancel_timeout(const char *name) {  // NOLINT | ||||
|   return App.scheduler.cancel_timeout(this, name); | ||||
| } | ||||
|  | ||||
| void Component::call_loop() { this->loop(); } | ||||
| void Component::call_setup() { this->setup(); } | ||||
| void Component::call_dump_config() { | ||||
|   | ||||
| @@ -285,6 +285,7 @@ class Component { | ||||
|    * @return Whether an interval functions was deleted. | ||||
|    */ | ||||
|   bool cancel_interval(const std::string &name);  // NOLINT | ||||
|   bool cancel_interval(const char *name);         // NOLINT | ||||
|  | ||||
|   /** Set an retry function with a unique name. Empty name means no cancelling possible. | ||||
|    * | ||||
| @@ -369,6 +370,7 @@ class Component { | ||||
|    * @return Whether a timeout functions was deleted. | ||||
|    */ | ||||
|   bool cancel_timeout(const std::string &name);  // NOLINT | ||||
|   bool cancel_timeout(const char *name);         // NOLINT | ||||
|  | ||||
|   /** Defer a callback to the next loop() call. | ||||
|    * | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
| #include "esphome/core/log.h" | ||||
| #include <algorithm> | ||||
| #include <cinttypes> | ||||
| #include <cstring> | ||||
|  | ||||
| namespace esphome { | ||||
|  | ||||
| @@ -124,6 +125,9 @@ void HOT Scheduler::set_timeout(Component *component, const std::string &name, u | ||||
| bool HOT Scheduler::cancel_timeout(Component *component, const std::string &name) { | ||||
|   return this->cancel_item_(component, name, SchedulerItem::TIMEOUT); | ||||
| } | ||||
| bool HOT Scheduler::cancel_timeout(Component *component, const char *name) { | ||||
|   return this->cancel_item_(component, name, SchedulerItem::TIMEOUT); | ||||
| } | ||||
| void HOT Scheduler::set_interval(Component *component, const std::string &name, uint32_t interval, | ||||
|                                  std::function<void()> func) { | ||||
|   this->set_timer_common_(component, SchedulerItem::INTERVAL, false, &name, interval, std::move(func)); | ||||
| @@ -136,6 +140,9 @@ void HOT Scheduler::set_interval(Component *component, const char *name, uint32_ | ||||
| bool HOT Scheduler::cancel_interval(Component *component, const std::string &name) { | ||||
|   return this->cancel_item_(component, name, SchedulerItem::INTERVAL); | ||||
| } | ||||
| bool HOT Scheduler::cancel_interval(Component *component, const char *name) { | ||||
|   return this->cancel_item_(component, name, SchedulerItem::INTERVAL); | ||||
| } | ||||
|  | ||||
| struct RetryArgs { | ||||
|   std::function<RetryResult(uint8_t)> func; | ||||
| @@ -357,13 +364,25 @@ void HOT Scheduler::push_(std::unique_ptr<Scheduler::SchedulerItem> item) { | ||||
|   LockGuard guard{this->lock_}; | ||||
|   this->to_add_.push_back(std::move(item)); | ||||
| } | ||||
| bool HOT Scheduler::cancel_item_(Component *component, const std::string &name, Scheduler::SchedulerItem::Type type) { | ||||
| // Common implementation for cancel operations | ||||
| bool HOT Scheduler::cancel_item_common_(Component *component, bool is_static_string, const void *name_ptr, | ||||
|                                         SchedulerItem::Type type) { | ||||
|   // Get the name as const char* | ||||
|   const char *name_cstr = | ||||
|       is_static_string ? static_cast<const char *>(name_ptr) : static_cast<const std::string *>(name_ptr)->c_str(); | ||||
|  | ||||
|   // Handle null or empty names | ||||
|   if (name_cstr == nullptr) | ||||
|     return false; | ||||
|  | ||||
|   // obtain lock because this function iterates and can be called from non-loop task context | ||||
|   LockGuard guard{this->lock_}; | ||||
|   bool ret = false; | ||||
|  | ||||
|   for (auto &it : this->items_) { | ||||
|     const char *item_name = it->get_name(); | ||||
|     if (it->component == component && item_name != nullptr && name == item_name && it->type == type && !it->remove) { | ||||
|     if (it->component == component && item_name != nullptr && strcmp(name_cstr, item_name) == 0 && it->type == type && | ||||
|         !it->remove) { | ||||
|       to_remove_++; | ||||
|       it->remove = true; | ||||
|       ret = true; | ||||
| @@ -371,7 +390,7 @@ bool HOT Scheduler::cancel_item_(Component *component, const std::string &name, | ||||
|   } | ||||
|   for (auto &it : this->to_add_) { | ||||
|     const char *item_name = it->get_name(); | ||||
|     if (it->component == component && item_name != nullptr && name == item_name && it->type == type) { | ||||
|     if (it->component == component && item_name != nullptr && strcmp(name_cstr, item_name) == 0 && it->type == type) { | ||||
|       it->remove = true; | ||||
|       ret = true; | ||||
|     } | ||||
| @@ -379,6 +398,15 @@ bool HOT Scheduler::cancel_item_(Component *component, const std::string &name, | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| bool HOT Scheduler::cancel_item_(Component *component, const std::string &name, Scheduler::SchedulerItem::Type type) { | ||||
|   return this->cancel_item_common_(component, false, &name, type); | ||||
| } | ||||
|  | ||||
| bool HOT Scheduler::cancel_item_(Component *component, const char *name, SchedulerItem::Type type) { | ||||
|   return this->cancel_item_common_(component, true, name, type); | ||||
| } | ||||
|  | ||||
| uint64_t Scheduler::millis_() { | ||||
|   // Get the current 32-bit millis value | ||||
|   const uint32_t now = millis(); | ||||
|   | ||||
| @@ -28,6 +28,7 @@ class Scheduler { | ||||
|   void set_timeout(Component *component, const char *name, uint32_t timeout, std::function<void()> func); | ||||
|  | ||||
|   bool cancel_timeout(Component *component, const std::string &name); | ||||
|   bool cancel_timeout(Component *component, const char *name); | ||||
|  | ||||
|   void set_interval(Component *component, const std::string &name, uint32_t interval, std::function<void()> func); | ||||
|  | ||||
| @@ -44,6 +45,7 @@ class Scheduler { | ||||
|   void set_interval(Component *component, const char *name, uint32_t interval, std::function<void()> func); | ||||
|  | ||||
|   bool cancel_interval(Component *component, const std::string &name); | ||||
|   bool cancel_interval(Component *component, const char *name); | ||||
|   void set_retry(Component *component, const std::string &name, uint32_t initial_wait_time, uint8_t max_attempts, | ||||
|                  std::function<RetryResult(uint8_t)> func, float backoff_increase_factor = 1.0f); | ||||
|   bool cancel_retry(Component *component, const std::string &name); | ||||
| @@ -137,7 +139,12 @@ class Scheduler { | ||||
|   void cleanup_(); | ||||
|   void pop_raw_(); | ||||
|   void push_(std::unique_ptr<SchedulerItem> item); | ||||
|   // Common implementation for cancel operations | ||||
|   bool cancel_item_common_(Component *component, bool is_static_string, const void *name_ptr, SchedulerItem::Type type); | ||||
|  | ||||
|   bool cancel_item_(Component *component, const std::string &name, SchedulerItem::Type type); | ||||
|   bool cancel_item_(Component *component, const char *name, SchedulerItem::Type type); | ||||
|  | ||||
|   bool empty_() { | ||||
|     this->cleanup_(); | ||||
|     return this->items_.empty(); | ||||
|   | ||||
| @@ -111,7 +111,7 @@ async def test_scheduler_string_test( | ||||
|         try: | ||||
|             await asyncio.wait_for(static_interval_fired.wait(), timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|             pytest.fail("Static interval did not fire within 1 seconds") | ||||
|             pytest.fail("Static interval did not fire within 1 second") | ||||
|  | ||||
|         try: | ||||
|             await asyncio.wait_for(static_interval_cancelled.wait(), timeout=2.0) | ||||
| @@ -127,7 +127,7 @@ async def test_scheduler_string_test( | ||||
|         try: | ||||
|             await asyncio.wait_for(dynamic_timeout_fired.wait(), timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|             pytest.fail("Dynamic timeout did not fire within 1 seconds") | ||||
|             pytest.fail("Dynamic timeout did not fire within 1 second") | ||||
|  | ||||
|         try: | ||||
|             await asyncio.wait_for(dynamic_interval_fired.wait(), timeout=1.5) | ||||
| @@ -138,7 +138,7 @@ async def test_scheduler_string_test( | ||||
|         try: | ||||
|             await asyncio.wait_for(cancel_test_done.wait(), timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|             pytest.fail("Cancel test did not complete within 1 seconds") | ||||
|             pytest.fail("Cancel test did not complete within 1 second") | ||||
|  | ||||
|         # Wait for final results | ||||
|         try: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user