[core] Replace std::function with lightweight Callback in CallbackManager (#14853)

This commit is contained in:
J. Nick Koston
2026-03-18 18:41:05 -10:00
committed by GitHub
parent fdd5956c1e
commit 8fe36cde23
85 changed files with 319 additions and 385 deletions
@@ -51,22 +51,6 @@ void AlarmControlPanel::publish_state(AlarmControlPanelState state) {
}
}
void AlarmControlPanel::add_on_state_callback(std::function<void()> &&callback) {
this->state_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_cleared_callback(std::function<void()> &&callback) {
this->cleared_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_chime_callback(std::function<void()> &&callback) {
this->chime_callback_.add(std::move(callback));
}
void AlarmControlPanel::add_on_ready_callback(std::function<void()> &&callback) {
this->ready_callback_.add(std::move(callback));
}
void AlarmControlPanel::arm_with_code_(AlarmControlPanelCall &(AlarmControlPanelCall::*arm_method)(),
const char *code) {
auto call = this->make_call();
@@ -37,25 +37,24 @@ class AlarmControlPanel : public EntityBase {
*
* @param callback The callback function
*/
void add_on_state_callback(std::function<void()> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
/** Add a callback for when the state of the alarm_control_panel clears from triggered
*
* @param callback The callback function
*/
void add_on_cleared_callback(std::function<void()> &&callback);
/** Add a callback for when the state of the alarm_control_panel clears from triggered. */
template<typename F> void add_on_cleared_callback(F &&callback) {
this->cleared_callback_.add(std::forward<F>(callback));
}
/** Add a callback for when a chime zone goes from closed to open
*
* @param callback The callback function
*/
void add_on_chime_callback(std::function<void()> &&callback);
/** Add a callback for when a chime zone goes from closed to open. */
template<typename F> void add_on_chime_callback(F &&callback) {
this->chime_callback_.add(std::forward<F>(callback));
}
/** Add a callback for when a ready state changes
*
* @param callback The callback function
*/
void add_on_ready_callback(std::function<void()> &&callback);
/** Add a callback for when a ready state changes. */
template<typename F> void add_on_ready_callback(F &&callback) {
this->ready_callback_.add(std::forward<F>(callback));
}
/** A numeric representation of the supported features as per HomeAssistant
*
-1
View File
@@ -20,6 +20,5 @@ void Button::press() {
this->press_action();
this->press_callback_.call();
}
void Button::add_on_press_callback(std::function<void()> &&callback) { this->press_callback_.add(std::move(callback)); }
} // namespace esphome::button
+3 -1
View File
@@ -34,7 +34,9 @@ class Button : public EntityBase {
*
* @param callback The void() callback.
*/
void add_on_press_callback(std::function<void()> &&callback);
template<typename F> void add_on_press_callback(F &&callback) {
this->press_callback_.add(std::forward<F>(callback));
}
protected:
/** You should implement this virtual method if you want to create your own button.
+1 -4
View File
@@ -91,10 +91,7 @@ class Canbus : public Component {
* - rtr If this is a remote transmission request
* - data The message data
*/
void add_callback(
std::function<void(uint32_t can_id, bool extended_id, bool rtr, const std::vector<uint8_t> &data)> callback) {
this->callback_manager_.add(std::move(callback));
}
template<typename F> void add_callback(F &&callback) { this->callback_manager_.add(std::forward<F>(callback)); }
protected:
template<typename... Ts> friend class CanbusSendAction;
-8
View File
@@ -356,14 +356,6 @@ ClimateCall &ClimateCall::set_swing_mode(optional<ClimateSwingMode> swing_mode)
return *this;
}
void Climate::add_on_state_callback(std::function<void(Climate &)> &&callback) {
this->state_callback_.add(std::move(callback));
}
void Climate::add_on_control_callback(std::function<void(ClimateCall &)> &&callback) {
this->control_callback_.add(std::move(callback));
}
// Random 32bit value; If this changes existing restore preferences are invalidated
static const uint32_t RESTORE_STATE_VERSION = 0x848EA6ADUL;
+6 -2
View File
@@ -192,7 +192,9 @@ class Climate : public EntityBase {
*
* @param callback The callback to call.
*/
void add_on_state_callback(std::function<void(Climate &)> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
/**
* Add a callback for the climate device configuration; each time the configuration parameters of a climate device
@@ -200,7 +202,9 @@ class Climate : public EntityBase {
*
* @param callback The callback to call.
*/
void add_on_control_callback(std::function<void(ClimateCall &)> &&callback);
template<typename F> void add_on_control_callback(F &&callback) {
this->control_callback_.add(std::forward<F>(callback));
}
/** Make a climate device control call, this is used to control the climate device, see the ClimateCall description
* for more info.
-1
View File
@@ -139,7 +139,6 @@ bool CoverCall::get_stop() const { return this->stop_; }
CoverCall Cover::make_call() { return {this}; }
void Cover::add_on_state_callback(std::function<void()> &&f) { this->state_callback_.add(std::move(f)); }
void Cover::publish_state(bool save) {
this->position = clamp(this->position, 0.0f, 1.0f);
this->tilt = clamp(this->tilt, 0.0f, 1.0f);
+1 -1
View File
@@ -125,7 +125,7 @@ class Cover : public EntityBase {
/// Construct a new cover call used to control the cover.
CoverCall make_call();
void add_on_state_callback(std::function<void()> &&f);
template<typename F> void add_on_state_callback(F &&f) { this->state_callback_.add(std::forward<F>(f)); }
/** Publish the current state of the cover.
*
+3 -1
View File
@@ -14,7 +14,9 @@ class DateTimeBase : public EntityBase {
public:
virtual ESPTime state_as_esptime() const = 0;
void add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
#ifdef USE_TIME
void set_rtc(time::RealTimeClock *rtc) { this->rtc_ = rtc; }
+2 -2
View File
@@ -51,8 +51,8 @@ class DFPlayer : public uart::UARTDevice, public Component {
bool is_playing() { return is_playing_; }
void dump_config() override;
void add_on_finished_playback_callback(std::function<void()> callback) {
this->on_finished_playback_callback_.add(std::move(callback));
template<typename F> void add_on_finished_playback_callback(F &&callback) {
this->on_finished_playback_callback_.add(std::forward<F>(callback));
}
protected:
@@ -44,9 +44,9 @@ class MenuItem {
MenuItemMenu *get_parent() { return this->parent_; }
MenuItemType get_type() const { return this->item_type_; }
template<typename V> void set_text(V val) { this->text_ = val; }
void add_on_enter_callback(std::function<void()> &&cb) { this->on_enter_callbacks_.add(std::move(cb)); }
void add_on_leave_callback(std::function<void()> &&cb) { this->on_leave_callbacks_.add(std::move(cb)); }
void add_on_value_callback(std::function<void()> &&cb) { this->on_value_callbacks_.add(std::move(cb)); }
template<typename F> void add_on_enter_callback(F &&cb) { this->on_enter_callbacks_.add(std::forward<F>(cb)); }
template<typename F> void add_on_leave_callback(F &&cb) { this->on_leave_callbacks_.add(std::forward<F>(cb)); }
template<typename F> void add_on_value_callback(F &&cb) { this->on_value_callbacks_.add(std::forward<F>(cb)); }
std::string get_text() const { return const_cast<MenuItem *>(this)->text_.value(this); }
virtual bool get_immediate_edit() const { return false; }
@@ -170,8 +170,8 @@ class MenuItemCommand : public MenuItem {
class MenuItemCustom : public MenuItemEditable {
public:
explicit MenuItemCustom() : MenuItemEditable(MENU_ITEM_CUSTOM) {}
void add_on_next_callback(std::function<void()> &&cb) { this->on_next_callbacks_.add(std::move(cb)); }
void add_on_prev_callback(std::function<void()> &&cb) { this->on_prev_callbacks_.add(std::move(cb)); }
template<typename F> void add_on_next_callback(F &&cb) { this->on_next_callbacks_.add(std::forward<F>(cb)); }
template<typename F> void add_on_prev_callback(F &&cb) { this->on_prev_callbacks_.add(std::forward<F>(cb)); }
bool has_value() const override { return this->value_getter_.has_value(); }
std::string get_value_text() const override;
@@ -48,8 +48,8 @@ class ESP32ImprovComponent : public Component, public improv_base::ImprovBase {
bool should_start() const { return this->should_start_; }
#ifdef USE_ESP32_IMPROV_STATE_CALLBACK
void add_on_state_callback(std::function<void(improv::State, improv::Error)> &&callback) {
this->state_callback_.add(std::move(callback));
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
#endif
#ifdef USE_BINARY_SENSOR
-4
View File
@@ -45,9 +45,5 @@ void Event::set_event_types(const std::vector<const char *> &event_types) {
this->last_event_type_ = nullptr; // Reset when types change
}
void Event::add_on_event_callback(std::function<void(StringRef event_type)> &&callback) {
this->event_callback_.add(std::move(callback));
}
} // namespace event
} // namespace esphome
+3 -1
View File
@@ -66,7 +66,9 @@ class Event : public EntityBase {
/// Check if an event has been triggered.
bool has_event() const { return this->last_event_type_ != nullptr; }
void add_on_event_callback(std::function<void(StringRef event_type)> &&callback);
template<typename F> void add_on_event_callback(F &&callback) {
this->event_callback_.add(std::forward<F>(callback));
}
protected:
LazyCallbackManager<void(StringRef event_type)> event_callback_;
+8 -12
View File
@@ -44,8 +44,8 @@ class EZOSensor : public sensor::Sensor, public PollingComponent, public i2c::I2
// Device Information
void get_device_information();
void add_device_infomation_callback(std::function<void(std::string)> &&callback) {
this->device_infomation_callback_.add(std::move(callback));
template<typename F> void add_device_infomation_callback(F &&callback) {
this->device_infomation_callback_.add(std::forward<F>(callback));
}
// Sleep
@@ -56,15 +56,13 @@ class EZOSensor : public sensor::Sensor, public PollingComponent, public i2c::I2
// Slope
void get_slope();
void add_slope_callback(std::function<void(std::string)> &&callback) {
this->slope_callback_.add(std::move(callback));
}
template<typename F> void add_slope_callback(F &&callback) { this->slope_callback_.add(std::forward<F>(callback)); }
// T
void get_t();
void set_t(float value);
void set_tempcomp_value(float temp); // For backwards compatibility
void add_t_callback(std::function<void(std::string)> &&callback) { this->t_callback_.add(std::move(callback)); }
template<typename F> void add_t_callback(F &&callback) { this->t_callback_.add(std::forward<F>(callback)); }
// Calibration
void get_calibration();
@@ -73,20 +71,18 @@ class EZOSensor : public sensor::Sensor, public PollingComponent, public i2c::I2
void set_calibration_point_high(float value);
void set_calibration_generic(float value);
void clear_calibration();
void add_calibration_callback(std::function<void(std::string)> &&callback) {
this->calibration_callback_.add(std::move(callback));
template<typename F> void add_calibration_callback(F &&callback) {
this->calibration_callback_.add(std::forward<F>(callback));
}
// LED
void get_led_state();
void set_led_state(bool on);
void add_led_state_callback(std::function<void(bool)> &&callback) { this->led_callback_.add(std::move(callback)); }
template<typename F> void add_led_state_callback(F &&callback) { this->led_callback_.add(std::forward<F>(callback)); }
// Custom
void send_custom(const std::string &to_send);
void add_custom_callback(std::function<void(std::string)> &&callback) {
this->custom_callback_.add(std::move(callback));
}
template<typename F> void add_custom_callback(F &&callback) { this->custom_callback_.add(std::forward<F>(callback)); }
protected:
std::deque<std::unique_ptr<EzoCommand>> commands_;
@@ -17,8 +17,8 @@ class FactoryResetComponent : public Component {
void dump_config() override;
void setup() override;
void add_increment_callback(std::function<void(uint8_t, uint8_t)> &&callback) {
this->increment_callback_.add(std::move(callback));
template<typename F> void add_increment_callback(F &&callback) {
this->increment_callback_.add(std::forward<F>(callback));
}
protected:
-1
View File
@@ -193,7 +193,6 @@ void Fan::apply_preset_mode_(const FanCall &call) {
}
}
void Fan::add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
void Fan::publish_state() {
auto traits = this->get_traits();
+3 -1
View File
@@ -122,7 +122,9 @@ class Fan : public EntityBase {
FanCall make_call();
/// Register a callback that will be called each time the state changes.
void add_on_state_callback(std::function<void()> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
void publish_state();
@@ -127,30 +127,30 @@ class FingerprintGrowComponent : public PollingComponent, public uart::UARTDevic
void set_enrolling_binary_sensor(binary_sensor::BinarySensor *enrolling_binary_sensor) {
this->enrolling_binary_sensor_ = enrolling_binary_sensor;
}
void add_on_finger_scan_start_callback(std::function<void()> callback) {
this->finger_scan_start_callback_.add(std::move(callback));
template<typename F> void add_on_finger_scan_start_callback(F &&callback) {
this->finger_scan_start_callback_.add(std::forward<F>(callback));
}
void add_on_finger_scan_matched_callback(std::function<void(uint16_t, uint16_t)> callback) {
this->finger_scan_matched_callback_.add(std::move(callback));
template<typename F> void add_on_finger_scan_matched_callback(F &&callback) {
this->finger_scan_matched_callback_.add(std::forward<F>(callback));
}
void add_on_finger_scan_unmatched_callback(std::function<void()> callback) {
this->finger_scan_unmatched_callback_.add(std::move(callback));
template<typename F> void add_on_finger_scan_unmatched_callback(F &&callback) {
this->finger_scan_unmatched_callback_.add(std::forward<F>(callback));
}
void add_on_finger_scan_misplaced_callback(std::function<void()> callback) {
this->finger_scan_misplaced_callback_.add(std::move(callback));
template<typename F> void add_on_finger_scan_misplaced_callback(F &&callback) {
this->finger_scan_misplaced_callback_.add(std::forward<F>(callback));
}
void add_on_finger_scan_invalid_callback(std::function<void()> callback) {
this->finger_scan_invalid_callback_.add(std::move(callback));
template<typename F> void add_on_finger_scan_invalid_callback(F &&callback) {
this->finger_scan_invalid_callback_.add(std::forward<F>(callback));
}
void add_on_enrollment_scan_callback(std::function<void(uint8_t, uint16_t)> callback) {
this->enrollment_scan_callback_.add(std::move(callback));
template<typename F> void add_on_enrollment_scan_callback(F &&callback) {
this->enrollment_scan_callback_.add(std::forward<F>(callback));
}
void add_on_enrollment_done_callback(std::function<void(uint16_t)> callback) {
this->enrollment_done_callback_.add(std::move(callback));
template<typename F> void add_on_enrollment_done_callback(F &&callback) {
this->enrollment_done_callback_.add(std::forward<F>(callback));
}
void add_on_enrollment_failed_callback(std::function<void(uint16_t)> callback) {
this->enrollment_failed_callback_.add(std::move(callback));
template<typename F> void add_on_enrollment_failed_callback(F &&callback) {
this->enrollment_failed_callback_.add(std::forward<F>(callback));
}
void enroll_fingerprint(uint16_t finger_id, uint8_t num_buffers);
@@ -44,7 +44,7 @@ class GraphicalDisplayMenu : public display_menu_base::DisplayMenuComponent {
void set_foreground_color(Color foreground_color);
void set_background_color(Color background_color);
void add_on_redraw_callback(std::function<void()> &&cb) { this->on_redraw_callbacks_.add(std::move(cb)); }
template<typename F> void add_on_redraw_callback(F &&cb) { this->on_redraw_callbacks_.add(std::forward<F>(cb)); }
void draw(display::Display *display, const display::Rect *bounds);
-4
View File
@@ -197,10 +197,6 @@ void HaierClimateBase::send_custom_command(const haier_protocol::HaierMessage &m
this->action_request_ = PendingAction({ActionRequest::SEND_CUSTOM_COMMAND, message});
}
void HaierClimateBase::add_status_message_callback(std::function<void(const char *, size_t)> &&callback) {
this->status_message_callback_.add(std::move(callback));
}
haier_protocol::HandlerError HaierClimateBase::answer_preprocess_(
haier_protocol::FrameType request_message_type, haier_protocol::FrameType expected_request_message_type,
haier_protocol::FrameType answer_message_type, haier_protocol::FrameType expected_answer_message_type,
+3 -1
View File
@@ -74,7 +74,9 @@ class HaierClimateBase : public esphome::Component,
void set_answer_timeout(uint32_t timeout);
void set_send_wifi(bool send_wifi);
void send_custom_command(const haier_protocol::HaierMessage &message);
void add_status_message_callback(std::function<void(const char *, size_t)> &&callback);
template<typename F> void add_status_message_callback(F &&callback) {
this->status_message_callback_.add(std::forward<F>(callback));
}
protected:
enum class ProtocolPhases {
-8
View File
@@ -114,14 +114,6 @@ void HonClimate::start_steri_cleaning() {
}
}
void HonClimate::add_alarm_start_callback(std::function<void(uint8_t, const char *)> &&callback) {
this->alarm_start_callback_.add(std::move(callback));
}
void HonClimate::add_alarm_end_callback(std::function<void(uint8_t, const char *)> &&callback) {
this->alarm_end_callback_.add(std::move(callback));
}
haier_protocol::HandlerError HonClimate::get_device_version_answer_handler_(haier_protocol::FrameType request_type,
haier_protocol::FrameType message_type,
const uint8_t *data, size_t data_size) {
+6 -2
View File
@@ -124,8 +124,12 @@ class HonClimate : public HaierClimateBase {
void set_extra_sensors_packet_bytes_size(size_t size) { this->extra_sensors_packet_bytes_ = size; };
void set_status_message_header_size(size_t size) { this->status_message_header_size_ = size; };
void set_control_method(HonControlMethod method) { this->control_method_ = method; };
void add_alarm_start_callback(std::function<void(uint8_t, const char *)> &&callback);
void add_alarm_end_callback(std::function<void(uint8_t, const char *)> &&callback);
template<typename F> void add_alarm_start_callback(F &&callback) {
this->alarm_start_callback_.add(std::forward<F>(callback));
}
template<typename F> void add_alarm_end_callback(F &&callback) {
this->alarm_end_callback_.add(std::forward<F>(callback));
}
float get_active_alarm_count() const { return this->active_alarm_count_; }
protected:
+12 -13
View File
@@ -91,24 +91,23 @@ class HlkFm22xComponent : public PollingComponent, public uart::UARTDevice {
void set_version_text_sensor(text_sensor::TextSensor *version_text_sensor) {
this->version_text_sensor_ = version_text_sensor;
}
void add_on_face_scan_matched_callback(std::function<void(int16_t, std::string)> callback) {
this->face_scan_matched_callback_.add(std::move(callback));
template<typename F> void add_on_face_scan_matched_callback(F &&callback) {
this->face_scan_matched_callback_.add(std::forward<F>(callback));
}
void add_on_face_scan_unmatched_callback(std::function<void()> callback) {
this->face_scan_unmatched_callback_.add(std::move(callback));
template<typename F> void add_on_face_scan_unmatched_callback(F &&callback) {
this->face_scan_unmatched_callback_.add(std::forward<F>(callback));
}
void add_on_face_scan_invalid_callback(std::function<void(uint8_t)> callback) {
this->face_scan_invalid_callback_.add(std::move(callback));
template<typename F> void add_on_face_scan_invalid_callback(F &&callback) {
this->face_scan_invalid_callback_.add(std::forward<F>(callback));
}
void add_on_face_info_callback(
std::function<void(int16_t, int16_t, int16_t, int16_t, int16_t, int16_t, int16_t, int16_t)> callback) {
this->face_info_callback_.add(std::move(callback));
template<typename F> void add_on_face_info_callback(F &&callback) {
this->face_info_callback_.add(std::forward<F>(callback));
}
void add_on_enrollment_done_callback(std::function<void(int16_t, uint8_t)> callback) {
this->enrollment_done_callback_.add(std::move(callback));
template<typename F> void add_on_enrollment_done_callback(F &&callback) {
this->enrollment_done_callback_.add(std::forward<F>(callback));
}
void add_on_enrollment_failed_callback(std::function<void(uint8_t)> callback) {
this->enrollment_failed_callback_.add(std::move(callback));
template<typename F> void add_on_enrollment_failed_callback(F &&callback) {
this->enrollment_failed_callback_.add(std::forward<F>(callback));
}
void enroll_face(const std::string &name, HlkFm22xFaceDirection direction);
@@ -21,14 +21,14 @@ class KeyCollector : public Component {
void set_back_keys(std::string back_keys) { this->back_keys_ = std::move(back_keys); };
void set_clear_keys(std::string clear_keys) { this->clear_keys_ = std::move(clear_keys); };
void set_allowed_keys(std::string allowed_keys) { this->allowed_keys_ = std::move(allowed_keys); };
void add_on_progress_callback(std::function<void(const std::string &, uint8_t)> &&callback) {
this->progress_callbacks_.add(std::move(callback));
template<typename F> void add_on_progress_callback(F &&callback) {
this->progress_callbacks_.add(std::forward<F>(callback));
}
void add_on_result_callback(std::function<void(const std::string &, uint8_t, uint8_t)> &&callback) {
this->result_callbacks_.add(std::move(callback));
template<typename F> void add_on_result_callback(F &&callback) {
this->result_callbacks_.add(std::forward<F>(callback));
}
void add_on_timeout_callback(std::function<void(const std::string &, uint8_t)> &&callback) {
this->timeout_callbacks_.add(std::move(callback));
template<typename F> void add_on_timeout_callback(F &&callback) {
this->timeout_callbacks_.add(std::forward<F>(callback));
}
void set_timeout(int timeout) { this->timeout_ = timeout; };
void set_enabled(bool enabled);
@@ -3,10 +3,6 @@
namespace esphome {
namespace key_provider {
void KeyProvider::add_on_key_callback(std::function<void(uint8_t)> &&callback) {
this->key_callback_.add(std::move(callback));
}
void KeyProvider::send_key_(uint8_t key) { this->key_callback_.call(key); }
} // namespace key_provider
@@ -9,7 +9,7 @@ namespace key_provider {
/// interface for components that provide keypresses
class KeyProvider {
public:
void add_on_key_callback(std::function<void(uint8_t)> &&callback);
template<typename F> void add_on_key_callback(F &&callback) { this->key_callback_.add(std::forward<F>(callback)); }
protected:
void send_key_(uint8_t key);
-4
View File
@@ -407,10 +407,6 @@ void LD2450Component::restart_and_read_all_info() {
this->set_timeout(1500, [this]() { this->read_all_info(); });
}
void LD2450Component::add_on_data_callback(std::function<void()> &&callback) {
this->data_callback_.add(std::move(callback));
}
// Send command with values to LD2450
void LD2450Component::send_command_(uint8_t command, const uint8_t *command_value, uint8_t command_value_len) {
ESP_LOGV(TAG, "Sending COMMAND %02X", command);
+1 -1
View File
@@ -145,7 +145,7 @@ class LD2450Component : public Component, public uart::UARTDevice {
int32_t zone3_y1, int32_t zone3_x2, int32_t zone3_y2);
/// Add a callback that will be called after each successfully processed periodic data frame.
void add_on_data_callback(std::function<void()> &&callback);
template<typename F> void add_on_data_callback(F &&callback) { this->data_callback_.add(std::forward<F>(callback)); }
protected:
void send_command_(uint8_t command_str, const uint8_t *command_value, uint8_t command_value_len);
-2
View File
@@ -48,8 +48,6 @@ void Lock::publish_state(LockState state) {
#endif
}
void Lock::add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
void LockCall::perform() {
ESP_LOGD(TAG, "'%s' - Setting", this->parent_->get_name().c_str());
this->validate_();
+3 -1
View File
@@ -150,7 +150,9 @@ class Lock : public EntityBase {
*
* @param callback The void(bool) callback.
*/
void add_on_state_callback(std::function<void()> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
protected:
friend LockCall;
+4 -4
View File
@@ -160,12 +160,12 @@ class LTRAlsPs501Component : public PollingComponent, public i2c::I2CDevice {
CallbackManager<void()> on_ps_high_trigger_callback_;
CallbackManager<void()> on_ps_low_trigger_callback_;
void add_on_ps_high_trigger_callback_(std::function<void()> callback) {
this->on_ps_high_trigger_callback_.add(std::move(callback));
template<typename F> void add_on_ps_high_trigger_callback_(F &&callback) {
this->on_ps_high_trigger_callback_.add(std::forward<F>(callback));
}
void add_on_ps_low_trigger_callback_(std::function<void()> callback) {
this->on_ps_low_trigger_callback_.add(std::move(callback));
template<typename F> void add_on_ps_low_trigger_callback_(F &&callback) {
this->on_ps_low_trigger_callback_.add(std::forward<F>(callback));
}
};
+4 -4
View File
@@ -160,12 +160,12 @@ class LTRAlsPsComponent : public PollingComponent, public i2c::I2CDevice {
CallbackManager<void()> on_ps_high_trigger_callback_;
CallbackManager<void()> on_ps_low_trigger_callback_;
void add_on_ps_high_trigger_callback_(std::function<void()> callback) {
this->on_ps_high_trigger_callback_.add(std::move(callback));
template<typename F> void add_on_ps_high_trigger_callback_(F &&callback) {
this->on_ps_high_trigger_callback_.add(std::forward<F>(callback));
}
void add_on_ps_low_trigger_callback_(std::function<void()> callback) {
this->on_ps_low_trigger_callback_.add(std::move(callback));
template<typename F> void add_on_ps_low_trigger_callback_(F &&callback) {
this->on_ps_low_trigger_callback_.add(std::forward<F>(callback));
}
};
+1 -3
View File
@@ -158,9 +158,7 @@ class LvglComponent : public PollingComponent {
void setup() override;
void update() override;
void loop() override;
void add_on_idle_callback(std::function<void(uint32_t)> &&callback) {
this->idle_callbacks_.add(std::move(callback));
}
template<typename F> void add_on_idle_callback(F &&callback) { this->idle_callbacks_.add(std::forward<F>(callback)); }
static void monitor_cb(lv_disp_drv_t *disp_drv, uint32_t time, uint32_t px);
static void render_start_cb(lv_disp_drv_t *disp_drv);
@@ -198,10 +198,6 @@ MediaPlayerCall &MediaPlayerCall::set_announcement(bool announce) {
return *this;
}
void MediaPlayer::add_on_state_callback(std::function<void()> &&callback) {
this->state_callback_.add(std::move(callback));
}
void MediaPlayer::publish_state() {
this->state_callback_.call();
#if defined(USE_MEDIA_PLAYER) && defined(USE_CONTROLLER_REGISTRY)
@@ -155,7 +155,9 @@ class MediaPlayer : public EntityBase {
void publish_state();
void add_on_state_callback(std::function<void()> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
virtual bool is_muted() const { return false; }
@@ -1,19 +0,0 @@
#include "microphone.h"
namespace esphome {
namespace microphone {
void Microphone::add_data_callback(std::function<void(const std::vector<uint8_t> &)> &&data_callback) {
std::function<void(const std::vector<uint8_t> &)> mute_handled_callback =
[this, data_callback](const std::vector<uint8_t> &data) {
if (this->mute_state_) {
data_callback(std::vector<uint8_t>(data.size(), 0));
} else {
data_callback(data);
};
};
this->data_callbacks_.add(std::move(mute_handled_callback));
}
} // namespace microphone
} // namespace esphome
+9 -2
View File
@@ -4,7 +4,6 @@
#include <cstddef>
#include <cstdint>
#include <functional>
#include <vector>
#include "esphome/core/helpers.h"
@@ -22,7 +21,15 @@ class Microphone {
public:
virtual void start() = 0;
virtual void stop() = 0;
void add_data_callback(std::function<void(const std::vector<uint8_t> &)> &&data_callback);
template<typename F> void add_data_callback(F &&data_callback) {
this->data_callbacks_.add([this, data_callback](const std::vector<uint8_t> &data) {
if (this->mute_state_) {
data_callback(std::vector<uint8_t>(data.size(), 0));
} else {
data_callback(data);
}
});
}
bool is_running() const { return this->state_ == STATE_RUNNING; }
bool is_stopped() const { return this->state_ == STATE_STOPPED; }
@@ -6,24 +6,6 @@ namespace microphone {
static const int32_t Q25_MAX_VALUE = (1 << 25) - 1;
static const int32_t Q25_MIN_VALUE = ~Q25_MAX_VALUE;
void MicrophoneSource::add_data_callback(std::function<void(const std::vector<uint8_t> &)> &&data_callback) {
std::function<void(const std::vector<uint8_t> &)> filtered_callback =
[this, data_callback](const std::vector<uint8_t> &data) {
if (this->enabled_ || this->passive_) {
if (this->processed_samples_.use_count() == 0) {
// Create vector if its unused
this->processed_samples_ = std::make_shared<std::vector<uint8_t>>();
}
// Take temporary ownership of samples vector to avoid deallaction before the callback finishes
std::shared_ptr<std::vector<uint8_t>> output_samples = this->processed_samples_;
this->process_audio_(data, *output_samples);
data_callback(*output_samples);
}
};
this->mic_->add_data_callback(std::move(filtered_callback));
}
audio::AudioStreamInfo MicrophoneSource::get_audio_stream_info() {
return audio::AudioStreamInfo(this->bits_per_sample_, this->channels_.count(),
this->mic_->get_audio_stream_info().get_sample_rate());
@@ -7,7 +7,6 @@
#include <bitset>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <vector>
namespace esphome {
@@ -47,7 +46,21 @@ class MicrophoneSource {
/// @param channel 0-indexed channel number to enable
void add_channel(uint8_t channel) { this->channels_.set(channel); }
void add_data_callback(std::function<void(const std::vector<uint8_t> &)> &&data_callback);
template<typename F> void add_data_callback(F &&data_callback) {
this->mic_->add_data_callback([this, data_callback](const std::vector<uint8_t> &data) {
if (this->enabled_ || this->passive_) {
if (this->processed_samples_.use_count() == 0) {
// Create vector if its unused
this->processed_samples_ = std::make_shared<std::vector<uint8_t>>();
}
// Take temporary ownership of samples vector to avoid deallocation before the callback finishes
std::shared_ptr<std::vector<uint8_t>> output_samples = this->processed_samples_;
this->process_audio_(data, *output_samples);
data_callback(*output_samples);
}
});
}
void set_gain_factor(int32_t gain_factor) { this->gain_factor_ = clamp<int32_t>(gain_factor, 1, MAX_GAIN_FACTOR); }
int32_t get_gain_factor() { return this->gain_factor_; }
@@ -837,17 +837,5 @@ int64_t payload_to_number(const std::vector<uint8_t> &data, SensorValueType sens
return value;
}
void ModbusController::add_on_command_sent_callback(std::function<void(int, int)> &&callback) {
this->command_sent_callback_.add(std::move(callback));
}
void ModbusController::add_on_online_callback(std::function<void(int, int)> &&callback) {
this->online_callback_.add(std::move(callback));
}
void ModbusController::add_on_offline_callback(std::function<void(int, int)> &&callback) {
this->offline_callback_.add(std::move(callback));
}
} // namespace modbus_controller
} // namespace esphome
@@ -508,11 +508,17 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
/// get if the module is offline, didn't respond the last command
bool get_module_offline() { return module_offline_; }
/// Set callback for commands
void add_on_command_sent_callback(std::function<void(int, int)> &&callback);
template<typename F> void add_on_command_sent_callback(F &&callback) {
this->command_sent_callback_.add(std::forward<F>(callback));
}
/// Set callback for online changes
void add_on_online_callback(std::function<void(int, int)> &&callback);
template<typename F> void add_on_online_callback(F &&callback) {
this->online_callback_.add(std::forward<F>(callback));
}
/// Set callback for offline changes
void add_on_offline_callback(std::function<void(int, int)> &&callback);
template<typename F> void add_on_offline_callback(F &&callback) {
this->offline_callback_.add(std::forward<F>(callback));
}
/// called by esphome generated code to set the max_cmd_retries.
void set_max_cmd_retries(uint8_t max_cmd_retries) { this->max_cmd_retries_ = max_cmd_retries; }
/// get how many times a command will be (re)sent if no response is received
-24
View File
@@ -214,30 +214,6 @@ void Nextion::update() {
}
}
void Nextion::add_sleep_state_callback(std::function<void()> &&callback) {
this->sleep_callback_.add(std::move(callback));
}
void Nextion::add_wake_state_callback(std::function<void()> &&callback) {
this->wake_callback_.add(std::move(callback));
}
void Nextion::add_setup_state_callback(std::function<void()> &&callback) {
this->setup_callback_.add(std::move(callback));
}
void Nextion::add_new_page_callback(std::function<void(uint8_t)> &&callback) {
this->page_callback_.add(std::move(callback));
}
void Nextion::add_touch_event_callback(std::function<void(uint8_t, uint8_t, bool)> &&callback) {
this->touch_callback_.add(std::move(callback));
}
void Nextion::add_buffer_overflow_event_callback(std::function<void()> &&callback) {
this->buffer_overflow_callback_.add(std::move(callback));
}
void Nextion::update_all_components() {
if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || this->is_sleeping())
return;
+16 -6
View File
@@ -1138,37 +1138,47 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe
*
* @param callback The void() callback.
*/
void add_sleep_state_callback(std::function<void()> &&callback);
template<typename F> void add_sleep_state_callback(F &&callback) {
this->sleep_callback_.add(std::forward<F>(callback));
}
/** Add a callback to be notified of wake state changes.
*
* @param callback The void() callback.
*/
void add_wake_state_callback(std::function<void()> &&callback);
template<typename F> void add_wake_state_callback(F &&callback) {
this->wake_callback_.add(std::forward<F>(callback));
}
/** Add a callback to be notified when the nextion completes its initialize setup.
*
* @param callback The void() callback.
*/
void add_setup_state_callback(std::function<void()> &&callback);
template<typename F> void add_setup_state_callback(F &&callback) {
this->setup_callback_.add(std::forward<F>(callback));
}
/** Add a callback to be notified when the nextion changes pages.
*
* @param callback The void(std::string) callback.
*/
void add_new_page_callback(std::function<void(uint8_t)> &&callback);
template<typename F> void add_new_page_callback(F &&callback) { this->page_callback_.add(std::forward<F>(callback)); }
/** Add a callback to be notified when Nextion has a touch event.
*
* @param callback The void() callback.
*/
void add_touch_event_callback(std::function<void(uint8_t, uint8_t, bool)> &&callback);
template<typename F> void add_touch_event_callback(F &&callback) {
this->touch_callback_.add(std::forward<F>(callback));
}
/** Add a callback to be notified when the nextion reports a buffer overflow.
*
* @param callback The void() callback.
*/
void add_buffer_overflow_event_callback(std::function<void()> &&callback);
template<typename F> void add_buffer_overflow_event_callback(F &&callback) {
this->buffer_overflow_callback_.add(std::forward<F>(callback));
}
void update_all_components();
-4
View File
@@ -29,8 +29,4 @@ void Number::publish_state(float state) {
#endif
}
void Number::add_on_state_callback(std::function<void(float)> &&callback) {
this->state_callback_.add(std::move(callback));
}
} // namespace esphome::number
+3 -1
View File
@@ -34,7 +34,9 @@ class Number : public EntityBase {
NumberCall make_call() { return NumberCall(this); }
void add_on_state_callback(std::function<void(float)> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
NumberTraits traits;
@@ -228,14 +228,6 @@ void OnlineImage::end_connection_() {
this->disable_loop();
}
void OnlineImage::add_on_finished_callback(std::function<void(bool)> &&callback) {
this->download_finished_callback_.add(std::move(callback));
}
void OnlineImage::add_on_error_callback(std::function<void()> &&callback) {
this->download_error_callback_.add(std::move(callback));
}
void OnlineImage::release() {
// Clear cache headers
this->etag_ = "";
@@ -65,8 +65,12 @@ class OnlineImage : public PollingComponent,
*/
void release();
void add_on_finished_callback(std::function<void(bool)> &&callback);
void add_on_error_callback(std::function<void()> &&callback);
template<typename F> void add_on_finished_callback(F &&callback) {
this->download_finished_callback_.add(std::forward<F>(callback));
}
template<typename F> void add_on_error_callback(F &&callback) {
this->download_error_callback_.add(std::forward<F>(callback));
}
protected:
bool validate_url_(const std::string &url);
+4 -4
View File
@@ -160,11 +160,11 @@ class OpenthermHub : public Component {
void set_dhw_block(bool value) { this->dhw_block = value; }
void set_sync_mode(bool sync_mode) { this->sync_mode_ = sync_mode; }
void add_on_before_send_callback(std::function<void(OpenthermData &)> &&callback) {
this->before_send_callback_.add(std::move(callback));
template<typename F> void add_on_before_send_callback(F &&callback) {
this->before_send_callback_.add(std::forward<F>(callback));
}
void add_on_before_process_response_callback(std::function<void(OpenthermData &)> &&callback) {
this->before_process_response_callback_.add(std::move(callback));
template<typename F> void add_on_before_process_response_callback(F &&callback) {
this->before_process_response_callback_.add(std::forward<F>(callback));
}
float get_setup_priority() const override { return setup_priority::HARDWARE; }
+2 -2
View File
@@ -72,8 +72,8 @@ class PIDClimate : public climate::Climate, public Component {
// float get_deadband() const { return controller_.deadband; }
// float get_proportional_deadband_multiplier() const { return controller_.proportional_deadband_multiplier; }
void add_on_pid_computed_callback(std::function<void()> &&callback) {
pid_computed_callback_.add(std::move(callback));
template<typename F> void add_on_pid_computed_callback(F &&callback) {
this->pid_computed_callback_.add(std::forward<F>(callback));
}
void set_default_target_temperature(float default_target_temperature) {
default_target_temperature_ = default_target_temperature;
+2 -2
View File
@@ -43,8 +43,8 @@ class PN532 : public PollingComponent {
void register_ontag_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontag_.push_back(trig); }
void register_ontagremoved_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontagremoved_.push_back(trig); }
void add_on_finished_write_callback(std::function<void()> callback) {
this->on_finished_write_callback_.add(std::move(callback));
template<typename F> void add_on_finished_write_callback(F &&callback) {
this->on_finished_write_callback_.add(std::forward<F>(callback));
}
bool is_writing() { return this->next_task_ != READ; };
+4 -4
View File
@@ -167,12 +167,12 @@ class PN7150 : public nfc::Nfcc, public Component {
void register_ontag_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontag_.push_back(trig); }
void register_ontagremoved_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontagremoved_.push_back(trig); }
void add_on_emulated_tag_scan_callback(std::function<void()> callback) {
this->on_emulated_tag_scan_callback_.add(std::move(callback));
template<typename F> void add_on_emulated_tag_scan_callback(F &&callback) {
this->on_emulated_tag_scan_callback_.add(std::forward<F>(callback));
}
void add_on_finished_write_callback(std::function<void()> callback) {
this->on_finished_write_callback_.add(std::move(callback));
template<typename F> void add_on_finished_write_callback(F &&callback) {
this->on_finished_write_callback_.add(std::forward<F>(callback));
}
bool is_writing() { return this->next_task_ != EP_READ; };
+4 -4
View File
@@ -184,12 +184,12 @@ class PN7160 : public nfc::Nfcc, public Component {
void register_ontag_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontag_.push_back(trig); }
void register_ontagremoved_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontagremoved_.push_back(trig); }
void add_on_emulated_tag_scan_callback(std::function<void()> callback) {
this->on_emulated_tag_scan_callback_.add(std::move(callback));
template<typename F> void add_on_emulated_tag_scan_callback(F &&callback) {
this->on_emulated_tag_scan_callback_.add(std::forward<F>(callback));
}
void add_on_finished_write_callback(std::function<void()> callback) {
this->on_finished_write_callback_.add(std::move(callback));
template<typename F> void add_on_finished_write_callback(F &&callback) {
this->on_finished_write_callback_.add(std::forward<F>(callback));
}
bool is_writing() { return this->next_task_ != EP_READ; };
+4 -4
View File
@@ -49,11 +49,11 @@ class RFBridgeComponent : public uart::UARTDevice, public Component {
public:
void loop() override;
void dump_config() override;
void add_on_code_received_callback(std::function<void(RFBridgeData)> callback) {
this->data_callback_.add(std::move(callback));
template<typename F> void add_on_code_received_callback(F &&callback) {
this->data_callback_.add(std::forward<F>(callback));
}
void add_on_advanced_code_received_callback(std::function<void(RFBridgeAdvancedData)> callback) {
this->advanced_data_callback_.add(std::move(callback));
template<typename F> void add_on_advanced_code_received_callback(F &&callback) {
this->advanced_data_callback_.add(std::forward<F>(callback));
}
void send_code(RFBridgeData data);
void send_advanced_code(const RFBridgeAdvancedData &data);
@@ -82,15 +82,15 @@ class RotaryEncoderSensor : public sensor::Sensor, public Component {
void dump_config() override;
void loop() override;
void add_on_clockwise_callback(std::function<void()> callback) {
this->on_clockwise_callback_.add(std::move(callback));
template<typename F> void add_on_clockwise_callback(F &&callback) {
this->on_clockwise_callback_.add(std::forward<F>(callback));
}
void add_on_anticlockwise_callback(std::function<void()> callback) {
this->on_anticlockwise_callback_.add(std::move(callback));
template<typename F> void add_on_anticlockwise_callback(F &&callback) {
this->on_anticlockwise_callback_.add(std::forward<F>(callback));
}
void register_listener(std::function<void(uint32_t)> listener) { this->listeners_.add(std::move(listener)); }
template<typename F> void register_listener(F &&listener) { this->listeners_.add(std::forward<F>(listener)); }
protected:
InternalGPIOPin *pin_a_;
+2 -2
View File
@@ -45,8 +45,8 @@ class Rtttl : public Component {
bool is_playing() { return this->state_ != State::STOPPED; }
void add_on_finished_playback_callback(std::function<void()> callback) {
this->on_finished_playback_callback_.add(std::move(callback));
template<typename F> void add_on_finished_playback_callback(F &&callback) {
this->on_finished_playback_callback_.add(std::forward<F>(callback));
}
protected:
+2 -2
View File
@@ -34,8 +34,8 @@ class SafeModeComponent final : public Component {
void mark_successful();
#ifdef USE_SAFE_MODE_CALLBACK
void add_on_safe_mode_callback(std::function<void()> &&callback) {
this->safe_mode_callback_.add(std::move(callback));
template<typename F> void add_on_safe_mode_callback(F &&callback) {
this->safe_mode_callback_.add(std::forward<F>(callback));
}
#endif
+2 -2
View File
@@ -37,11 +37,11 @@ class Sdl : public display::Display {
int get_height() override { return this->height_; }
float get_setup_priority() const override { return setup_priority::HARDWARE; }
void dump_config() override { LOG_DISPLAY("", "SDL", this); }
void add_key_listener(int32_t keycode, std::function<void(bool)> &&callback) {
template<typename F> void add_key_listener(int32_t keycode, F &&callback) {
if (!this->key_callbacks_.count(keycode)) {
this->key_callbacks_[keycode] = CallbackManager<void(bool)>();
}
this->key_callbacks_[keycode].add(std::move(callback));
this->key_callbacks_[keycode].add(std::forward<F>(callback));
}
int mouse_x{};
-4
View File
@@ -42,10 +42,6 @@ StringRef Select::current_option() const {
return this->has_state() ? StringRef(this->option_at(this->active_index_)) : StringRef();
}
void Select::add_on_state_callback(std::function<void(size_t)> &&callback) {
this->state_callback_.add(std::move(callback));
}
bool Select::has_option(const std::string &option) const { return this->index_of(option.c_str()).has_value(); }
bool Select::has_option(const char *option) const { return this->index_of(option).has_value(); }
+3 -1
View File
@@ -76,7 +76,9 @@ class Select : public EntityBase {
/// Return the option value at the provided index offset (as const char* from flash).
const char *option_at(size_t index) const;
void add_on_state_callback(std::function<void(size_t)> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
protected:
friend class SelectCall;
-5
View File
@@ -79,11 +79,6 @@ void Sensor::publish_state(float state) {
#endif
}
void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); }
void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) {
this->raw_callback_.add(std::move(callback));
}
#ifdef USE_SENSOR_FILTER
void Sensor::add_filter(Filter *filter) {
// inefficient, but only happens once on every sensor setup and nobody's going to have massive amounts of
+4 -2
View File
@@ -111,9 +111,11 @@ class Sensor : public EntityBase {
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)
/// Add a callback that will be called every time a filtered value arrives.
void add_on_state_callback(std::function<void(float)> &&callback);
template<typename F> void add_on_state_callback(F &&callback) { this->callback_.add(std::forward<F>(callback)); }
/// Add a callback that will be called every time the sensor sends a raw value.
void add_on_raw_state_callback(std::function<void(float)> &&callback);
template<typename F> void add_on_raw_state_callback(F &&callback) {
this->raw_callback_.add(std::forward<F>(callback));
}
/** This member variable stores the last state that has passed through all filters.
*
+10 -10
View File
@@ -61,20 +61,20 @@ class Sim800LComponent : public uart::UARTDevice, public PollingComponent {
#ifdef USE_SENSOR
void set_rssi_sensor(sensor::Sensor *rssi_sensor) { rssi_sensor_ = rssi_sensor; }
#endif
void add_on_sms_received_callback(std::function<void(std::string, std::string)> callback) {
this->sms_received_callback_.add(std::move(callback));
template<typename F> void add_on_sms_received_callback(F &&callback) {
this->sms_received_callback_.add(std::forward<F>(callback));
}
void add_on_incoming_call_callback(std::function<void(std::string)> callback) {
this->incoming_call_callback_.add(std::move(callback));
template<typename F> void add_on_incoming_call_callback(F &&callback) {
this->incoming_call_callback_.add(std::forward<F>(callback));
}
void add_on_call_connected_callback(std::function<void()> callback) {
this->call_connected_callback_.add(std::move(callback));
template<typename F> void add_on_call_connected_callback(F &&callback) {
this->call_connected_callback_.add(std::forward<F>(callback));
}
void add_on_call_disconnected_callback(std::function<void()> callback) {
this->call_disconnected_callback_.add(std::move(callback));
template<typename F> void add_on_call_disconnected_callback(F &&callback) {
this->call_disconnected_callback_.add(std::forward<F>(callback));
}
void add_on_ussd_received_callback(std::function<void(std::string)> callback) {
this->ussd_received_callback_.add(std::move(callback));
template<typename F> void add_on_ussd_received_callback(F &&callback) {
this->ussd_received_callback_.add(std::forward<F>(callback));
}
void send_sms(const std::string &recipient, const std::string &message);
void send_ussd(const std::string &ussd_code);
-4
View File
@@ -61,10 +61,6 @@ void Sml::loop() {
}
}
void Sml::add_on_data_callback(std::function<void(std::vector<uint8_t>, bool)> &&callback) {
this->data_callbacks_.add(std::move(callback));
}
void Sml::process_sml_file_(const BytesView &sml_data) {
SmlFile sml_file(sml_data);
std::vector<ObisInfo> obis_info = sml_file.get_obis_info();
+1 -1
View File
@@ -24,7 +24,7 @@ class Sml : public Component, public uart::UARTDevice {
void loop() override;
void dump_config() override;
std::vector<SmlListener *> sml_listeners_{};
void add_on_data_callback(std::function<void(std::vector<uint8_t>, bool)> &&callback);
template<typename F> void add_on_data_callback(F &&callback) { this->data_callbacks_.add(std::forward<F>(callback)); }
protected:
void process_sml_file_(const BytesView &sml_data);
+2 -2
View File
@@ -106,8 +106,8 @@ class Speaker {
/// Parameters:
/// - Frames played
/// - System time in microseconds when the frames were written to the DAC
void add_audio_output_callback(std::function<void(uint32_t, int64_t)> &&callback) {
this->audio_output_callback_.add(std::move(callback));
template<typename F> void add_audio_output_callback(F &&callback) {
this->audio_output_callback_.add(std::forward<F>(callback));
}
protected:
-3
View File
@@ -69,9 +69,6 @@ void Switch::publish_state(bool state) {
}
bool Switch::assumed_state() { return false; }
void Switch::add_on_state_callback(std::function<void(bool)> &&callback) {
this->state_callback_.add(std::move(callback));
}
void Switch::set_inverted(bool inverted) { this->inverted_ = inverted; }
bool Switch::is_inverted() const { return this->inverted_; }
+3 -1
View File
@@ -93,7 +93,9 @@ class Switch : public EntityBase {
*
* @param callback The void(bool) callback.
*/
void add_on_state_callback(std::function<void(bool)> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
/** Returns the initial state of the switch, as persisted previously,
or empty if never persisted.
-4
View File
@@ -29,8 +29,4 @@ void Text::publish_state(const char *state, size_t len) {
#endif
}
void Text::add_on_state_callback(std::function<void(const std::string &)> &&callback) {
this->state_callback_.add(std::move(callback));
}
} // namespace esphome::text
+3 -1
View File
@@ -30,7 +30,9 @@ class Text : public EntityBase {
/// Instantiate a TextCall object to modify this text component's state.
TextCall make_call() { return TextCall(this); }
void add_on_state_callback(std::function<void(const std::string &)> &&callback);
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
protected:
friend class TextCall;
@@ -83,13 +83,6 @@ void TextSensor::clear_filters() {
}
#endif // USE_TEXT_SENSOR_FILTER
void TextSensor::add_on_state_callback(std::function<void(const std::string &)> callback) {
this->callback_.add(std::move(callback));
}
void TextSensor::add_on_raw_state_callback(std::function<void(const std::string &)> callback) {
this->raw_callback_.add(std::move(callback));
}
const std::string &TextSensor::get_state() const { return this->state; }
const std::string &TextSensor::get_raw_state() const {
#ifdef USE_TEXT_SENSOR_FILTER
+4 -2
View File
@@ -62,9 +62,11 @@ class TextSensor : public EntityBase {
void clear_filters();
#endif
void add_on_state_callback(std::function<void(const std::string &)> callback);
template<typename F> void add_on_state_callback(F &&callback) { this->callback_.add(std::forward<F>(callback)); }
/// Add a callback that will be called every time the sensor sends a raw value.
void add_on_raw_state_callback(std::function<void(const std::string &)> callback);
template<typename F> void add_on_raw_state_callback(F &&callback) {
this->raw_callback_.add(std::forward<F>(callback));
}
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)
+3 -3
View File
@@ -55,9 +55,9 @@ class RealTimeClock : public PollingComponent {
/// Get the current time as the UTC epoch since January 1st 1970.
time_t timestamp_now() { return ::time(nullptr); }
void add_on_time_sync_callback(std::function<void()> &&callback) {
this->time_sync_callback_.add(std::move(callback));
};
template<typename F> void add_on_time_sync_callback(F &&callback) {
this->time_sync_callback_.add(std::forward<F>(callback));
}
void dump_config() override;
+2 -2
View File
@@ -112,8 +112,8 @@ class Tuya : public Component, public uart::UARTDevice {
void add_ignore_mcu_update_on_datapoints(uint8_t ignore_mcu_update_on_datapoints) {
this->ignore_mcu_update_on_datapoints_.push_back(ignore_mcu_update_on_datapoints);
}
void add_on_initialized_callback(std::function<void()> callback) {
this->initialized_callback_.add(std::move(callback));
template<typename F> void add_on_initialized_callback(F &&callback) {
this->initialized_callback_.add(std::forward<F>(callback));
}
protected:
+1 -3
View File
@@ -190,9 +190,7 @@ class UARTComponent {
#endif // USE_ESP8266 || USE_ESP32
#ifdef USE_UART_DEBUGGER
void add_debug_callback(std::function<void(UARTDirection, uint8_t)> &&callback) {
this->debug_callback_.add(std::move(callback));
}
template<typename F> void add_debug_callback(F &&callback) { this->debug_callback_.add(std::forward<F>(callback)); }
#endif
protected:
+1 -3
View File
@@ -28,9 +28,7 @@ class UDPComponent : public Component {
void set_broadcast_port(uint16_t port) { this->broadcast_port_ = port; }
void set_should_broadcast() { this->should_broadcast_ = true; }
void set_should_listen() { this->should_listen_ = true; }
void add_listener(std::function<void(std::span<const uint8_t>)> &&listener) {
this->packet_listeners_.add(std::move(listener));
}
template<typename F> void add_listener(F &&listener) { this->packet_listeners_.add(std::forward<F>(listener)); }
void setup() override;
void loop() override;
void dump_config() override;
+3 -1
View File
@@ -40,7 +40,9 @@ class UpdateEntity : public EntityBase {
const UpdateInfo &update_info = update_info_;
const UpdateState &state = state_;
void add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); }
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callback_.add(std::forward<F>(callback));
}
Trigger<const UpdateInfo &> *get_update_available_trigger() {
if (!update_available_trigger_) {
update_available_trigger_ = std::make_unique<Trigger<const UpdateInfo &>>();
-1
View File
@@ -125,7 +125,6 @@ bool ValveCall::get_stop() const { return this->stop_; }
ValveCall Valve::make_call() { return {this}; }
void Valve::add_on_state_callback(std::function<void()> &&f) { this->state_callback_.add(std::move(f)); }
void Valve::publish_state(bool save) {
this->position = clamp(this->position, 0.0f, 1.0f);
+1 -1
View File
@@ -117,7 +117,7 @@ class Valve : public EntityBase {
/// Construct a new valve call used to control the valve.
ValveCall make_call();
void add_on_state_callback(std::function<void()> &&f);
template<typename F> void add_on_state_callback(F &&f) { this->state_callback_.add(std::forward<F>(f)); }
/** Publish the current state of the valve.
*
+1 -3
View File
@@ -11,9 +11,7 @@ class CdcAcm : public Component {
public:
CdcAcm();
void setup() override;
void add_on_rate_callback(std::function<void(const device *, uint32_t)> &&callback) {
this->rate_callbacks_.add(std::move(callback));
}
template<typename F> void add_on_rate_callback(F &&callback) { this->rate_callbacks_.add(std::forward<F>(callback)); }
protected:
static void cdc_dte_rate_callback_(const device *device, uint32_t rate);
+1 -1
View File
@@ -74,7 +74,7 @@ class ZigbeeComponent : public Component {
// endpoints are enumerated from 1
this->callbacks_[endpoint - 1] = std::move(cb);
}
void add_join_callback(std::function<void()> &&cb) { this->join_cb_.add(std::move(cb)); }
template<typename F> void add_join_callback(F &&cb) { this->join_cb_.add(std::forward<F>(cb)); }
void zboss_signal_handler_esphome(zb_bufid_t bufid);
void factory_reset();
Trigger<> *get_join_trigger() { return &this->join_trigger_; };
+9 -15
View File
@@ -307,15 +307,11 @@ template<typename T> class StatefulEntityBase : public EntityBase {
virtual T get_state_default(T default_value) const { return this->state_.value_or(default_value); }
void invalidate_state() { this->set_new_state({}); }
void add_full_state_callback(std::function<void(optional<T> previous, optional<T> current)> &&callback) {
if (this->full_state_callbacks_ == nullptr)
this->full_state_callbacks_ = new CallbackManager<void(optional<T> previous, optional<T> current)>(); // NOLINT
this->full_state_callbacks_->add(std::move(callback));
template<typename F> void add_full_state_callback(F &&callback) {
this->full_state_callbacks_.add(std::forward<F>(callback));
}
void add_on_state_callback(std::function<void(T)> &&callback) {
if (this->state_callbacks_ == nullptr)
this->state_callbacks_ = new CallbackManager<void(T)>(); // NOLINT
this->state_callbacks_->add(std::move(callback));
template<typename F> void add_on_state_callback(F &&callback) {
this->state_callbacks_.add(std::forward<F>(callback));
}
void set_trigger_on_initial_state(bool trigger_on_initial_state) {
@@ -333,21 +329,19 @@ template<typename T> class StatefulEntityBase : public EntityBase {
virtual bool set_new_state(const optional<T> &new_state) {
if (this->state_ != new_state) {
// call the full state callbacks with the previous and new state
if (this->full_state_callbacks_ != nullptr)
this->full_state_callbacks_->call(this->state_, new_state);
this->full_state_callbacks_.call(this->state_, new_state);
// trigger legacy callbacks only if the new state is valid and either the trigger on initial state is enabled or
// the previous state was valid
auto had_state = this->has_state();
this->state_ = new_state;
if (this->state_callbacks_ != nullptr && new_state.has_value() && (this->trigger_on_initial_state_ || had_state))
this->state_callbacks_->call(new_state.value());
if (new_state.has_value() && (this->trigger_on_initial_state_ || had_state))
this->state_callbacks_.call(new_state.value());
return true;
}
return false;
}
bool trigger_on_initial_state_{true};
// callbacks with full state and previous state
CallbackManager<void(optional<T> previous, optional<T> current)> *full_state_callbacks_{};
CallbackManager<void(T)> *state_callbacks_{};
LazyCallbackManager<void(optional<T> previous, optional<T> current)> full_state_callbacks_;
LazyCallbackManager<void(T)> state_callbacks_;
};
} // namespace esphome
+63 -12
View File
@@ -1729,6 +1729,51 @@ constexpr float fahrenheit_to_celsius(float value) { return (value - 32.0f) / 1.
/// @name Utilities
/// @{
/// Lightweight type-erased callback (8 bytes on 32-bit) that avoids std::function overhead.
/// No null check, no exceptions, no heap allocation for small trivially-copyable callables.
///
/// With C++20 if constexpr, automatically detects [this] lambdas (sizeof <= sizeof(void*),
/// trivially copyable) and stores them inline. Larger callables are heap-allocated.
template<typename... X> struct Callback;
template<typename... Ts> struct Callback<void(Ts...)> {
// The inline storage path stores callable bytes in ctx_ via memcpy.
// sizeof equality with uintptr_t ensures void* can round-trip arbitrary bit patterns,
// which combined with flat address spaces on all ESPHome targets means no trap representations.
static_assert(sizeof(void *) == sizeof(std::uintptr_t), "void* must be the same size as uintptr_t");
void (*fn_)(void *, Ts...){nullptr};
void *ctx_{nullptr};
/// Invoke the callback. Only valid on Callbacks created via create(), never on default-constructed instances.
void call(Ts... args) const { this->fn_(this->ctx_, args...); }
/// Create from any callable. Small trivially-copyable callables (like [this] lambdas)
/// are stored inline in the ctx pointer without heap allocation.
template<typename F> static Callback create(F &&callable) {
using DecayF = std::decay_t<F>;
if constexpr (sizeof(DecayF) <= sizeof(void *) && std::is_trivially_copyable_v<DecayF>) {
// Small trivial callable (e.g. [this]() { this->method(); }) - store inline in ctx.
// Safe under C++20 (P0593R6): byte copy into aligned storage implicitly
// creates objects of implicit-lifetime types (trivially copyable qualifies).
Callback cb; // fn and ctx are zero-initialized by default
__builtin_memcpy(&cb.ctx_, &callable, sizeof(DecayF));
cb.fn_ = [](void *c, Ts... args) {
alignas(DecayF) char buf[sizeof(DecayF)];
__builtin_memcpy(buf, &c, sizeof(DecayF));
(*std::launder(reinterpret_cast<DecayF *>(buf)))(args...);
};
return cb;
} else {
// Large or non-trivial callable - heap allocate.
// Intentionally never freed: callbacks in ESPHome are registered during setup()
// and live for device lifetime. Same lifetime as the previous std::function approach.
auto *stored = new DecayF(std::forward<F>(callable));
return {[](void *c, Ts... args) { (*static_cast<DecayF *>(c))(args...); }, static_cast<void *>(stored)};
}
}
};
template<typename... X> class CallbackManager;
/** Helper class to allow having multiple subscribers to a callback.
@@ -1737,13 +1782,14 @@ template<typename... X> class CallbackManager;
*/
template<typename... Ts> class CallbackManager<void(Ts...)> {
public:
/// Add a callback to the list.
void add(std::function<void(Ts...)> &&callback) { this->callbacks_.push_back(std::move(callback)); }
/// Add any callable. Small trivially-copyable callables (like [this] lambdas)
/// are stored inline without heap allocation or std::function.
template<typename F> void add(F &&callback) { this->add_(Callback<void(Ts...)>::create(std::forward<F>(callback))); }
/// Call all callbacks in this manager.
/// Call all callbacks in this manager. No null check on invoke.
void call(Ts... args) {
for (auto &cb : this->callbacks_)
cb(args...);
cb.call(args...);
}
size_t size() const { return this->callbacks_.size(); }
@@ -1751,7 +1797,10 @@ template<typename... Ts> class CallbackManager<void(Ts...)> {
void operator()(Ts... args) { call(args...); }
protected:
std::vector<std::function<void(Ts...)>> callbacks_;
template<typename...> friend class LazyCallbackManager;
/// Non-template core to avoid code duplication per lambda type.
void add_(Callback<void(Ts...)> cb) { this->callbacks_.push_back(cb); }
std::vector<Callback<void(Ts...)>> callbacks_;
};
template<typename... X> class LazyCallbackManager;
@@ -1784,13 +1833,8 @@ template<typename... Ts> class LazyCallbackManager<void(Ts...)> {
LazyCallbackManager(LazyCallbackManager &&) = delete;
LazyCallbackManager &operator=(LazyCallbackManager &&) = delete;
/// Add a callback to the list. Allocates the underlying CallbackManager on first use.
void add(std::function<void(Ts...)> &&callback) {
if (!this->callbacks_) {
this->callbacks_ = new CallbackManager<void(Ts...)>();
}
this->callbacks_->add(std::move(callback));
}
/// Add any callable. Allocates the underlying CallbackManager on first use.
template<typename F> void add(F &&callback) { this->add_(Callback<void(Ts...)>::create(std::forward<F>(callback))); }
/// Call all callbacks in this manager. No-op if no callbacks registered.
void call(Ts... args) {
@@ -1809,6 +1853,13 @@ template<typename... Ts> class LazyCallbackManager<void(Ts...)> {
void operator()(Ts... args) { this->call(args...); }
protected:
/// Non-template core to avoid code duplication per lambda type.
void add_(Callback<void(Ts...)> cb) {
if (!this->callbacks_) {
this->callbacks_ = new CallbackManager<void(Ts...)>();
}
this->callbacks_->add_(cb);
}
CallbackManager<void(Ts...)> *callbacks_{nullptr};
};