Refactor API entity update dispatch to reduce code duplication (#9372)

This commit is contained in:
J. Nick Koston 2025-07-07 15:51:17 -05:00 committed by GitHub
parent fe258e1007
commit b122112d58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -260,180 +260,114 @@ bool APIServer::check_password(const std::string &password) const {
void APIServer::handle_disconnect(APIConnection *conn) {} void APIServer::handle_disconnect(APIConnection *conn) {}
// Macro for entities without extra parameters
#define API_DISPATCH_UPDATE(entity_type, entity_name) \
void APIServer::on_##entity_name##_update(entity_type *obj) { /* NOLINT(bugprone-macro-parentheses) */ \
if (obj->is_internal()) \
return; \
for (auto &c : this->clients_) \
c->send_##entity_name##_state(obj); \
}
// Macro for entities with extra parameters (but parameters not used in send)
#define API_DISPATCH_UPDATE_IGNORE_PARAMS(entity_type, entity_name, ...) \
void APIServer::on_##entity_name##_update(entity_type *obj, __VA_ARGS__) { /* NOLINT(bugprone-macro-parentheses) */ \
if (obj->is_internal()) \
return; \
for (auto &c : this->clients_) \
c->send_##entity_name##_state(obj); \
}
#ifdef USE_BINARY_SENSOR #ifdef USE_BINARY_SENSOR
void APIServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj) { API_DISPATCH_UPDATE(binary_sensor::BinarySensor, binary_sensor)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_binary_sensor_state(obj);
}
#endif #endif
#ifdef USE_COVER #ifdef USE_COVER
void APIServer::on_cover_update(cover::Cover *obj) { API_DISPATCH_UPDATE(cover::Cover, cover)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_cover_state(obj);
}
#endif #endif
#ifdef USE_FAN #ifdef USE_FAN
void APIServer::on_fan_update(fan::Fan *obj) { API_DISPATCH_UPDATE(fan::Fan, fan)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_fan_state(obj);
}
#endif #endif
#ifdef USE_LIGHT #ifdef USE_LIGHT
void APIServer::on_light_update(light::LightState *obj) { API_DISPATCH_UPDATE(light::LightState, light)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_light_state(obj);
}
#endif #endif
#ifdef USE_SENSOR #ifdef USE_SENSOR
void APIServer::on_sensor_update(sensor::Sensor *obj, float state) { API_DISPATCH_UPDATE_IGNORE_PARAMS(sensor::Sensor, sensor, float state)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_sensor_state(obj);
}
#endif #endif
#ifdef USE_SWITCH #ifdef USE_SWITCH
void APIServer::on_switch_update(switch_::Switch *obj, bool state) { API_DISPATCH_UPDATE_IGNORE_PARAMS(switch_::Switch, switch, bool state)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_switch_state(obj);
}
#endif #endif
#ifdef USE_TEXT_SENSOR #ifdef USE_TEXT_SENSOR
void APIServer::on_text_sensor_update(text_sensor::TextSensor *obj, const std::string &state) { API_DISPATCH_UPDATE_IGNORE_PARAMS(text_sensor::TextSensor, text_sensor, const std::string &state)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_text_sensor_state(obj);
}
#endif #endif
#ifdef USE_CLIMATE #ifdef USE_CLIMATE
void APIServer::on_climate_update(climate::Climate *obj) { API_DISPATCH_UPDATE(climate::Climate, climate)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_climate_state(obj);
}
#endif #endif
#ifdef USE_NUMBER #ifdef USE_NUMBER
void APIServer::on_number_update(number::Number *obj, float state) { API_DISPATCH_UPDATE_IGNORE_PARAMS(number::Number, number, float state)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_number_state(obj);
}
#endif #endif
#ifdef USE_DATETIME_DATE #ifdef USE_DATETIME_DATE
void APIServer::on_date_update(datetime::DateEntity *obj) { API_DISPATCH_UPDATE(datetime::DateEntity, date)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_date_state(obj);
}
#endif #endif
#ifdef USE_DATETIME_TIME #ifdef USE_DATETIME_TIME
void APIServer::on_time_update(datetime::TimeEntity *obj) { API_DISPATCH_UPDATE(datetime::TimeEntity, time)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_time_state(obj);
}
#endif #endif
#ifdef USE_DATETIME_DATETIME #ifdef USE_DATETIME_DATETIME
void APIServer::on_datetime_update(datetime::DateTimeEntity *obj) { API_DISPATCH_UPDATE(datetime::DateTimeEntity, datetime)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_datetime_state(obj);
}
#endif #endif
#ifdef USE_TEXT #ifdef USE_TEXT
void APIServer::on_text_update(text::Text *obj, const std::string &state) { API_DISPATCH_UPDATE_IGNORE_PARAMS(text::Text, text, const std::string &state)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_text_state(obj);
}
#endif #endif
#ifdef USE_SELECT #ifdef USE_SELECT
void APIServer::on_select_update(select::Select *obj, const std::string &state, size_t index) { API_DISPATCH_UPDATE_IGNORE_PARAMS(select::Select, select, const std::string &state, size_t index)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_select_state(obj);
}
#endif #endif
#ifdef USE_LOCK #ifdef USE_LOCK
void APIServer::on_lock_update(lock::Lock *obj) { API_DISPATCH_UPDATE(lock::Lock, lock)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_lock_state(obj);
}
#endif #endif
#ifdef USE_VALVE #ifdef USE_VALVE
void APIServer::on_valve_update(valve::Valve *obj) { API_DISPATCH_UPDATE(valve::Valve, valve)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_valve_state(obj);
}
#endif #endif
#ifdef USE_MEDIA_PLAYER #ifdef USE_MEDIA_PLAYER
void APIServer::on_media_player_update(media_player::MediaPlayer *obj) { API_DISPATCH_UPDATE(media_player::MediaPlayer, media_player)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_media_player_state(obj);
}
#endif #endif
#ifdef USE_EVENT #ifdef USE_EVENT
// Event is a special case - it's the only entity that passes extra parameters to the send method
void APIServer::on_event(event::Event *obj, const std::string &event_type) { void APIServer::on_event(event::Event *obj, const std::string &event_type) {
if (obj->is_internal())
return;
for (auto &c : this->clients_) for (auto &c : this->clients_)
c->send_event(obj, event_type); c->send_event(obj, event_type);
} }
#endif #endif
#ifdef USE_UPDATE #ifdef USE_UPDATE
// Update is a special case - the method is called on_update, not on_update_update
void APIServer::on_update(update::UpdateEntity *obj) { void APIServer::on_update(update::UpdateEntity *obj) {
if (obj->is_internal())
return;
for (auto &c : this->clients_) for (auto &c : this->clients_)
c->send_update_state(obj); c->send_update_state(obj);
} }
#endif #endif
#ifdef USE_ALARM_CONTROL_PANEL #ifdef USE_ALARM_CONTROL_PANEL
void APIServer::on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) { API_DISPATCH_UPDATE(alarm_control_panel::AlarmControlPanel, alarm_control_panel)
if (obj->is_internal())
return;
for (auto &c : this->clients_)
c->send_alarm_control_panel_state(obj);
}
#endif #endif
float APIServer::get_setup_priority() const { return setup_priority::AFTER_WIFI; } float APIServer::get_setup_priority() const { return setup_priority::AFTER_WIFI; }