[core] Convert remaining add_on_*_callback methods to templates

Convert all remaining component add_on_*_callback methods from
std::function to templates so lambdas flow through without wrapping.
This avoids a heap allocation regression where passing std::function
through Callback::create would heap-allocate the std::function itself.

Also add NOLINT annotations for clang-analyzer false positive on
byte-wise copy in Callback::create.
This commit is contained in:
J. Nick Koston
2026-03-15 22:36:48 -10:00
parent bfc5a210bc
commit 3c90438947
31 changed files with 114 additions and 142 deletions
+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;
@@ -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);
+10 -10
View File
@@ -91,24 +91,24 @@ 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));
}
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);
+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);
@@ -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
@@ -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,12 +82,12 @@ 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)); }
+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:
+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
@@ -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
@@ -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);
+8 -10
View File
@@ -1747,22 +1747,20 @@ template<typename... Ts> struct Callback<void(Ts...)> {
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
// 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;
cb.ctx = nullptr;
// Store the callable in the ctx pointer itself (type-punning via char* is allowed)
char *dst = reinterpret_cast<char *>(&cb.ctx);
const char *src = reinterpret_cast<const char *>(&callable);
char *dst = reinterpret_cast<char *>(&cb.ctx); // NOLINT(clang-analyzer-core.uninitialized.Assign)
const char *src = reinterpret_cast<const char *>(&callable); // NOLINT(clang-analyzer-core.uninitialized.Assign)
for (size_t i = 0; i < sizeof(DecayF); ++i)
dst[i] = src[i];
dst[i] = src[i]; // NOLINT(clang-analyzer-core.uninitialized.Assign)
cb.fn = [](void *c, Ts... args) {
// Recover the callable from the ctx pointer.
// Safe under C++20 (P0593R6): byte copy into aligned storage implicitly
// creates objects of implicit-lifetime types (trivially copyable qualifies).
alignas(DecayF) char buf[sizeof(DecayF)];
const char *csrc = reinterpret_cast<const char *>(&c);
const char *csrc = reinterpret_cast<const char *>(&c); // NOLINT(clang-analyzer-core.uninitialized.Assign)
for (size_t i = 0; i < sizeof(DecayF); ++i)
buf[i] = csrc[i];
buf[i] = csrc[i]; // NOLINT(clang-analyzer-core.uninitialized.Assign)
reinterpret_cast<DecayF *>(buf)->operator()(args...);
};
return cb;