mirror of
https://github.com/esphome/esphome.git
synced 2026-02-08 08:41:59 +00:00
Merge branch 'dev' into noise_api_zero_copy
This commit is contained in:
@@ -132,13 +132,13 @@ class AlarmControlPanel : public EntityBase {
|
||||
// the call control function
|
||||
virtual void control(const AlarmControlPanelCall &call) = 0;
|
||||
// state callback - triggers check get_state() for specific state
|
||||
CallbackManager<void()> state_callback_{};
|
||||
LazyCallbackManager<void()> state_callback_{};
|
||||
// clear callback - fires when leaving TRIGGERED state
|
||||
CallbackManager<void()> cleared_callback_{};
|
||||
LazyCallbackManager<void()> cleared_callback_{};
|
||||
// chime callback
|
||||
CallbackManager<void()> chime_callback_{};
|
||||
LazyCallbackManager<void()> chime_callback_{};
|
||||
// ready callback
|
||||
CallbackManager<void()> ready_callback_{};
|
||||
LazyCallbackManager<void()> ready_callback_{};
|
||||
};
|
||||
|
||||
} // namespace alarm_control_panel
|
||||
|
||||
@@ -41,7 +41,7 @@ class Button : public EntityBase, public EntityBase_DeviceClass {
|
||||
*/
|
||||
virtual void press_action() = 0;
|
||||
|
||||
CallbackManager<void()> press_callback_{};
|
||||
LazyCallbackManager<void()> press_callback_{};
|
||||
};
|
||||
|
||||
} // namespace esphome::button
|
||||
|
||||
@@ -326,8 +326,8 @@ class Climate : public EntityBase {
|
||||
|
||||
void dump_traits_(const char *tag);
|
||||
|
||||
CallbackManager<void(Climate &)> state_callback_{};
|
||||
CallbackManager<void(ClimateCall &)> control_callback_{};
|
||||
LazyCallbackManager<void(Climate &)> state_callback_{};
|
||||
LazyCallbackManager<void(ClimateCall &)> control_callback_{};
|
||||
ESPPreferenceObject rtc_;
|
||||
#ifdef USE_CLIMATE_VISUAL_OVERRIDES
|
||||
float visual_min_temperature_override_{NAN};
|
||||
|
||||
@@ -152,7 +152,7 @@ class Cover : public EntityBase, public EntityBase_DeviceClass {
|
||||
|
||||
optional<CoverRestoreState> restore_state_();
|
||||
|
||||
CallbackManager<void()> state_callback_{};
|
||||
LazyCallbackManager<void()> state_callback_{};
|
||||
|
||||
ESPPreferenceObject rtc_;
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ class DateTimeBase : public EntityBase {
|
||||
#endif
|
||||
|
||||
protected:
|
||||
CallbackManager<void()> state_callback_;
|
||||
LazyCallbackManager<void()> state_callback_;
|
||||
|
||||
#ifdef USE_TIME
|
||||
time::RealTimeClock *rtc_;
|
||||
|
||||
@@ -50,7 +50,7 @@ class Event : public EntityBase, public EntityBase_DeviceClass {
|
||||
void add_on_event_callback(std::function<void(const std::string &event_type)> &&callback);
|
||||
|
||||
protected:
|
||||
CallbackManager<void(const std::string &event_type)> event_callback_;
|
||||
LazyCallbackManager<void(const std::string &event_type)> event_callback_;
|
||||
FixedVector<const char *> types_;
|
||||
|
||||
private:
|
||||
|
||||
@@ -155,7 +155,7 @@ class Fan : public EntityBase {
|
||||
const char *find_preset_mode_(const char *preset_mode);
|
||||
const char *find_preset_mode_(const char *preset_mode, size_t len);
|
||||
|
||||
CallbackManager<void()> state_callback_{};
|
||||
LazyCallbackManager<void()> state_callback_{};
|
||||
ESPPreferenceObject rtc_;
|
||||
FanRestoreMode restore_mode_;
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ class Lock : public EntityBase {
|
||||
*/
|
||||
virtual void control(const LockCall &call) = 0;
|
||||
|
||||
CallbackManager<void()> state_callback_{};
|
||||
LazyCallbackManager<void()> state_callback_{};
|
||||
Deduplicator<LockState> publish_dedup_;
|
||||
ESPPreferenceObject rtc_;
|
||||
};
|
||||
|
||||
@@ -157,7 +157,7 @@ class MediaPlayer : public EntityBase {
|
||||
|
||||
virtual void control(const MediaPlayerCall &call) = 0;
|
||||
|
||||
CallbackManager<void()> state_callback_{};
|
||||
LazyCallbackManager<void()> state_callback_{};
|
||||
};
|
||||
|
||||
} // namespace media_player
|
||||
|
||||
@@ -49,7 +49,7 @@ class Number : public EntityBase {
|
||||
*/
|
||||
virtual void control(float value) = 0;
|
||||
|
||||
CallbackManager<void(float)> state_callback_;
|
||||
LazyCallbackManager<void(float)> state_callback_;
|
||||
};
|
||||
|
||||
} // namespace esphome::number
|
||||
|
||||
@@ -111,7 +111,7 @@ class Select : public EntityBase {
|
||||
}
|
||||
}
|
||||
|
||||
CallbackManager<void(size_t)> state_callback_;
|
||||
LazyCallbackManager<void(size_t)> state_callback_;
|
||||
};
|
||||
|
||||
} // namespace esphome::select
|
||||
|
||||
@@ -4,17 +4,28 @@ import esphome.codegen as cg
|
||||
from esphome.components import i2c, sensirion_common, sensor
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ALGORITHM_TUNING,
|
||||
CONF_GAIN_FACTOR,
|
||||
CONF_GATING_MAX_DURATION_MINUTES,
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_INDEX_OFFSET,
|
||||
CONF_LEARNING_TIME_GAIN_HOURS,
|
||||
CONF_LEARNING_TIME_OFFSET_HOURS,
|
||||
CONF_NORMALIZED_OFFSET_SLOPE,
|
||||
CONF_NOX,
|
||||
CONF_OFFSET,
|
||||
CONF_PM_1_0,
|
||||
CONF_PM_2_5,
|
||||
CONF_PM_4_0,
|
||||
CONF_PM_10_0,
|
||||
CONF_STD_INITIAL,
|
||||
CONF_STORE_BASELINE,
|
||||
CONF_TEMPERATURE,
|
||||
CONF_TEMPERATURE_COMPENSATION,
|
||||
CONF_TIME_CONSTANT,
|
||||
CONF_VOC,
|
||||
CONF_VOC_BASELINE,
|
||||
DEVICE_CLASS_AQI,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_PM1,
|
||||
@@ -42,18 +53,7 @@ SEN5XComponent = sen5x_ns.class_(
|
||||
RhtAccelerationMode = sen5x_ns.enum("RhtAccelerationMode")
|
||||
|
||||
CONF_ACCELERATION_MODE = "acceleration_mode"
|
||||
CONF_ALGORITHM_TUNING = "algorithm_tuning"
|
||||
CONF_AUTO_CLEANING_INTERVAL = "auto_cleaning_interval"
|
||||
CONF_GATING_MAX_DURATION_MINUTES = "gating_max_duration_minutes"
|
||||
CONF_INDEX_OFFSET = "index_offset"
|
||||
CONF_LEARNING_TIME_GAIN_HOURS = "learning_time_gain_hours"
|
||||
CONF_LEARNING_TIME_OFFSET_HOURS = "learning_time_offset_hours"
|
||||
CONF_NORMALIZED_OFFSET_SLOPE = "normalized_offset_slope"
|
||||
CONF_NOX = "nox"
|
||||
CONF_STD_INITIAL = "std_initial"
|
||||
CONF_TIME_CONSTANT = "time_constant"
|
||||
CONF_VOC = "voc"
|
||||
CONF_VOC_BASELINE = "voc_baseline"
|
||||
|
||||
|
||||
# Actions
|
||||
|
||||
@@ -76,9 +76,7 @@ StateClass Sensor::get_state_class() {
|
||||
|
||||
void Sensor::publish_state(float state) {
|
||||
this->raw_state = state;
|
||||
if (this->raw_callback_) {
|
||||
this->raw_callback_->call(state);
|
||||
}
|
||||
this->raw_callback_.call(state);
|
||||
|
||||
ESP_LOGV(TAG, "'%s': Received new state %f", this->name_.c_str(), state);
|
||||
|
||||
@@ -91,10 +89,7 @@ void Sensor::publish_state(float state) {
|
||||
|
||||
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) {
|
||||
if (!this->raw_callback_) {
|
||||
this->raw_callback_ = make_unique<CallbackManager<void(float)>>();
|
||||
}
|
||||
this->raw_callback_->add(std::move(callback));
|
||||
this->raw_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
void Sensor::add_filter(Filter *filter) {
|
||||
|
||||
@@ -125,8 +125,8 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
|
||||
void internal_send_state_to_frontend(float state);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<CallbackManager<void(float)>> raw_callback_; ///< Storage for raw state callbacks (lazy allocated).
|
||||
CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
|
||||
LazyCallbackManager<void(float)> raw_callback_; ///< Storage for raw state callbacks.
|
||||
LazyCallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
|
||||
|
||||
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
||||
|
||||
|
||||
@@ -2,11 +2,20 @@ import esphome.codegen as cg
|
||||
from esphome.components import i2c, sensirion_common, sensor
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ALGORITHM_TUNING,
|
||||
CONF_COMPENSATION,
|
||||
CONF_GAIN_FACTOR,
|
||||
CONF_GATING_MAX_DURATION_MINUTES,
|
||||
CONF_ID,
|
||||
CONF_INDEX_OFFSET,
|
||||
CONF_LEARNING_TIME_GAIN_HOURS,
|
||||
CONF_LEARNING_TIME_OFFSET_HOURS,
|
||||
CONF_NOX,
|
||||
CONF_STD_INITIAL,
|
||||
CONF_STORE_BASELINE,
|
||||
CONF_TEMPERATURE_SOURCE,
|
||||
CONF_VOC,
|
||||
CONF_VOC_BASELINE,
|
||||
DEVICE_CLASS_AQI,
|
||||
ICON_RADIATOR,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
@@ -24,16 +33,7 @@ SGP4xComponent = sgp4x_ns.class_(
|
||||
sensirion_common.SensirionI2CDevice,
|
||||
)
|
||||
|
||||
CONF_ALGORITHM_TUNING = "algorithm_tuning"
|
||||
CONF_GATING_MAX_DURATION_MINUTES = "gating_max_duration_minutes"
|
||||
CONF_HUMIDITY_SOURCE = "humidity_source"
|
||||
CONF_INDEX_OFFSET = "index_offset"
|
||||
CONF_LEARNING_TIME_GAIN_HOURS = "learning_time_gain_hours"
|
||||
CONF_LEARNING_TIME_OFFSET_HOURS = "learning_time_offset_hours"
|
||||
CONF_NOX = "nox"
|
||||
CONF_STD_INITIAL = "std_initial"
|
||||
CONF_VOC = "voc"
|
||||
CONF_VOC_BASELINE = "voc_baseline"
|
||||
|
||||
|
||||
def validate_sensors(config):
|
||||
|
||||
@@ -134,8 +134,8 @@ class Switch : public EntityBase, public EntityBase_DeviceClass {
|
||||
// Pointer first (4 bytes)
|
||||
ESPPreferenceObject rtc_;
|
||||
|
||||
// CallbackManager (12 bytes on 32-bit - contains vector)
|
||||
CallbackManager<void(bool)> state_callback_{};
|
||||
// LazyCallbackManager (4 bytes on 32-bit - nullptr when empty)
|
||||
LazyCallbackManager<void(bool)> state_callback_{};
|
||||
|
||||
// Small types grouped together
|
||||
Deduplicator<bool> publish_dedup_; // 2 bytes (bool has_value_ + bool last_value_)
|
||||
|
||||
@@ -44,7 +44,7 @@ class Text : public EntityBase {
|
||||
*/
|
||||
virtual void control(const std::string &value) = 0;
|
||||
|
||||
CallbackManager<void(const std::string &)> state_callback_;
|
||||
LazyCallbackManager<void(const std::string &)> state_callback_;
|
||||
};
|
||||
|
||||
} // namespace text
|
||||
|
||||
@@ -30,9 +30,7 @@ void TextSensor::publish_state(const std::string &state) {
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
this->raw_state = state;
|
||||
#pragma GCC diagnostic pop
|
||||
if (this->raw_callback_) {
|
||||
this->raw_callback_->call(state);
|
||||
}
|
||||
this->raw_callback_.call(state);
|
||||
|
||||
ESP_LOGV(TAG, "'%s': Received new state %s", this->name_.c_str(), state.c_str());
|
||||
|
||||
@@ -77,10 +75,7 @@ void TextSensor::add_on_state_callback(std::function<void(std::string)> callback
|
||||
this->callback_.add(std::move(callback));
|
||||
}
|
||||
void TextSensor::add_on_raw_state_callback(std::function<void(std::string)> callback) {
|
||||
if (!this->raw_callback_) {
|
||||
this->raw_callback_ = make_unique<CallbackManager<void(std::string)>>();
|
||||
}
|
||||
this->raw_callback_->add(std::move(callback));
|
||||
this->raw_callback_.add(std::move(callback));
|
||||
}
|
||||
|
||||
std::string TextSensor::get_state() const { return this->state; }
|
||||
|
||||
@@ -65,9 +65,8 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass {
|
||||
void internal_send_state_to_frontend(const std::string &state);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<CallbackManager<void(std::string)>>
|
||||
raw_callback_; ///< Storage for raw state callbacks (lazy allocated).
|
||||
CallbackManager<void(std::string)> callback_; ///< Storage for filtered state callbacks.
|
||||
LazyCallbackManager<void(std::string)> raw_callback_; ///< Storage for raw state callbacks.
|
||||
LazyCallbackManager<void(std::string)> callback_; ///< Storage for filtered state callbacks.
|
||||
|
||||
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
||||
};
|
||||
|
||||
@@ -50,7 +50,7 @@ class UpdateEntity : public EntityBase, public EntityBase_DeviceClass {
|
||||
UpdateState state_{UPDATE_STATE_UNKNOWN};
|
||||
UpdateInfo update_info_;
|
||||
|
||||
CallbackManager<void()> state_callback_{};
|
||||
LazyCallbackManager<void()> state_callback_{};
|
||||
std::unique_ptr<Trigger<const UpdateInfo &>> update_available_trigger_{nullptr};
|
||||
};
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ class Valve : public EntityBase, public EntityBase_DeviceClass {
|
||||
|
||||
optional<ValveRestoreState> restore_state_();
|
||||
|
||||
CallbackManager<void()> state_callback_{};
|
||||
LazyCallbackManager<void()> state_callback_{};
|
||||
|
||||
ESPPreferenceObject rtc_;
|
||||
};
|
||||
|
||||
@@ -528,6 +528,16 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
|
||||
for (auto *listener : global_wifi_component->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(global_wifi_component->wifi_ssid(), global_wifi_component->wifi_bssid());
|
||||
}
|
||||
// For static IP configurations, GOT_IP event may not fire, so notify IP listeners here
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
if (const WiFiAP *config = global_wifi_component->get_selected_sta_();
|
||||
config && config->get_manual_ip().has_value()) {
|
||||
for (auto *listener : global_wifi_component->ip_state_listeners_) {
|
||||
listener->on_ip_state(global_wifi_component->wifi_sta_ip_addresses(),
|
||||
global_wifi_component->get_dns_address(0), global_wifi_component->get_dns_address(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -739,6 +739,14 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid());
|
||||
}
|
||||
// For static IP configurations, GOT_IP event may not fire, so notify IP listeners here
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) {
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} else if (data->event_base == WIFI_EVENT && data->event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
|
||||
@@ -305,6 +305,14 @@ void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid());
|
||||
}
|
||||
// For static IP configurations, GOT_IP event may not fire, so notify IP listeners here
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) {
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -259,6 +259,15 @@ void WiFiComponent::wifi_loop_() {
|
||||
for (auto *listener : this->connect_state_listeners_) {
|
||||
listener->on_wifi_connect_state(this->wifi_ssid(), this->wifi_bssid());
|
||||
}
|
||||
// For static IP configurations, notify IP listeners immediately as the IP is already configured
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_manual_ip().has_value()) {
|
||||
s_sta_had_ip = true;
|
||||
for (auto *listener : this->ip_state_listeners_) {
|
||||
listener->on_ip_state(this->wifi_sta_ip_addresses(), this->get_dns_address(0), this->get_dns_address(1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
} else if (!is_connected && s_sta_was_connected) {
|
||||
// Just disconnected
|
||||
|
||||
@@ -123,6 +123,7 @@ CONF_ADDRESS = "address"
|
||||
CONF_ADDRESSABLE_LIGHT_ID = "addressable_light_id"
|
||||
CONF_ADVANCED = "advanced"
|
||||
CONF_AFTER = "after"
|
||||
CONF_ALGORITHM_TUNING = "algorithm_tuning"
|
||||
CONF_ALL = "all"
|
||||
CONF_ALLOW_OTHER_USES = "allow_other_uses"
|
||||
CONF_ALPHA = "alpha"
|
||||
@@ -435,6 +436,7 @@ CONF_GAIN_FACTOR = "gain_factor"
|
||||
CONF_GAMMA_CORRECT = "gamma_correct"
|
||||
CONF_GAS_RESISTANCE = "gas_resistance"
|
||||
CONF_GATEWAY = "gateway"
|
||||
CONF_GATING_MAX_DURATION_MINUTES = "gating_max_duration_minutes"
|
||||
CONF_GLASS_ATTENUATION_FACTOR = "glass_attenuation_factor"
|
||||
CONF_GLYPHS = "glyphs"
|
||||
CONF_GPIO = "gpio"
|
||||
@@ -497,6 +499,7 @@ CONF_INCLUDE_INTERNAL = "include_internal"
|
||||
CONF_INCLUDES = "includes"
|
||||
CONF_INCLUDES_C = "includes_c"
|
||||
CONF_INDEX = "index"
|
||||
CONF_INDEX_OFFSET = "index_offset"
|
||||
CONF_INDOOR = "indoor"
|
||||
CONF_INFRARED = "infrared"
|
||||
CONF_INIT_SEQUENCE = "init_sequence"
|
||||
@@ -534,6 +537,8 @@ CONF_LAMBDA = "lambda"
|
||||
CONF_LAST_CONFIDENCE = "last_confidence"
|
||||
CONF_LAST_FINGER_ID = "last_finger_id"
|
||||
CONF_LATITUDE = "latitude"
|
||||
CONF_LEARNING_TIME_GAIN_HOURS = "learning_time_gain_hours"
|
||||
CONF_LEARNING_TIME_OFFSET_HOURS = "learning_time_offset_hours"
|
||||
CONF_LED = "led"
|
||||
CONF_LEGEND = "legend"
|
||||
CONF_LENGTH = "length"
|
||||
@@ -645,7 +650,9 @@ CONF_NEVER = "never"
|
||||
CONF_NEW_PASSWORD = "new_password"
|
||||
CONF_NITROGEN_DIOXIDE = "nitrogen_dioxide"
|
||||
CONF_NOISE_LEVEL = "noise_level"
|
||||
CONF_NORMALIZED_OFFSET_SLOPE = "normalized_offset_slope"
|
||||
CONF_NOTIFY = "notify"
|
||||
CONF_NOX = "nox"
|
||||
CONF_NUM_ATTEMPTS = "num_attempts"
|
||||
CONF_NUM_CHANNELS = "num_channels"
|
||||
CONF_NUM_CHIPS = "num_chips"
|
||||
@@ -939,6 +946,7 @@ CONF_STATE_TOPIC = "state_topic"
|
||||
CONF_STATIC_IP = "static_ip"
|
||||
CONF_STATUS = "status"
|
||||
CONF_STB_PIN = "stb_pin"
|
||||
CONF_STD_INITIAL = "std_initial"
|
||||
CONF_STEP = "step"
|
||||
CONF_STEP_DELAY = "step_delay"
|
||||
CONF_STEP_MODE = "step_mode"
|
||||
@@ -1006,6 +1014,7 @@ CONF_TILT_COMMAND_TOPIC = "tilt_command_topic"
|
||||
CONF_TILT_LAMBDA = "tilt_lambda"
|
||||
CONF_TILT_STATE_TOPIC = "tilt_state_topic"
|
||||
CONF_TIME = "time"
|
||||
CONF_TIME_CONSTANT = "time_constant"
|
||||
CONF_TIME_ID = "time_id"
|
||||
CONF_TIMEOUT = "timeout"
|
||||
CONF_TIMES = "times"
|
||||
@@ -1060,6 +1069,8 @@ CONF_VERSION = "version"
|
||||
CONF_VIBRATIONS = "vibrations"
|
||||
CONF_VISIBLE = "visible"
|
||||
CONF_VISUAL = "visual"
|
||||
CONF_VOC = "voc"
|
||||
CONF_VOC_BASELINE = "voc_baseline"
|
||||
CONF_VOLTAGE = "voltage"
|
||||
CONF_VOLTAGE_ATTENUATION = "voltage_attenuation"
|
||||
CONF_VOLTAGE_DIVIDER = "voltage_divider"
|
||||
|
||||
@@ -935,6 +935,50 @@ template<typename... Ts> class CallbackManager<void(Ts...)> {
|
||||
std::vector<std::function<void(Ts...)>> callbacks_;
|
||||
};
|
||||
|
||||
template<typename... X> class LazyCallbackManager;
|
||||
|
||||
/** Lazy-allocating callback manager that only allocates memory when callbacks are registered.
|
||||
*
|
||||
* This is a drop-in replacement for CallbackManager that saves memory when no callbacks
|
||||
* are registered (common case after the Controller Registry eliminated per-entity callbacks
|
||||
* from API and web_server components).
|
||||
*
|
||||
* Memory overhead comparison (32-bit systems):
|
||||
* - CallbackManager: 12 bytes (empty std::vector)
|
||||
* - LazyCallbackManager: 4 bytes (nullptr unique_ptr)
|
||||
*
|
||||
* @tparam Ts The arguments for the callbacks, wrapped in void().
|
||||
*/
|
||||
template<typename... Ts> class LazyCallbackManager<void(Ts...)> {
|
||||
public:
|
||||
/// 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_ = make_unique<CallbackManager<void(Ts...)>>();
|
||||
}
|
||||
this->callbacks_->add(std::move(callback));
|
||||
}
|
||||
|
||||
/// Call all callbacks in this manager. No-op if no callbacks registered.
|
||||
void call(Ts... args) {
|
||||
if (this->callbacks_) {
|
||||
this->callbacks_->call(args...);
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the number of registered callbacks.
|
||||
size_t size() const { return this->callbacks_ ? this->callbacks_->size() : 0; }
|
||||
|
||||
/// Check if any callbacks are registered.
|
||||
bool empty() const { return !this->callbacks_ || this->callbacks_->size() == 0; }
|
||||
|
||||
/// Call all callbacks in this manager.
|
||||
void operator()(Ts... args) { this->call(args...); }
|
||||
|
||||
protected:
|
||||
std::unique_ptr<CallbackManager<void(Ts...)>> callbacks_;
|
||||
};
|
||||
|
||||
/// Helper class to deduplicate items in a series of values.
|
||||
template<typename T> class Deduplicator {
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user