mirror of
https://github.com/esphome/esphome.git
synced 2024-11-24 16:08:10 +01:00
remove duplication from component_iterator
This commit is contained in:
parent
455df35e50
commit
c1fd71cd4f
3 changed files with 84 additions and 261 deletions
|
@ -15,6 +15,8 @@ class UserServiceDescriptor {
|
||||||
virtual ListEntitiesServicesResponse encode_list_service_response() = 0;
|
virtual ListEntitiesServicesResponse encode_list_service_response() = 0;
|
||||||
|
|
||||||
virtual bool execute_service(const ExecuteServiceRequest &req) = 0;
|
virtual bool execute_service(const ExecuteServiceRequest &req) = 0;
|
||||||
|
|
||||||
|
bool is_internal() { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> T get_execute_arg_value(const ExecuteServiceArgument &arg);
|
template<typename T> T get_execute_arg_value(const ExecuteServiceArgument &arg);
|
||||||
|
|
|
@ -14,373 +14,190 @@ void ComponentIterator::begin(bool include_internal) {
|
||||||
this->at_ = 0;
|
this->at_ = 0;
|
||||||
this->include_internal_ = include_internal;
|
this->include_internal_ = include_internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Entity>
|
||||||
|
void ComponentIterator::process_entity_(const std::vector<Entity *> &items,
|
||||||
|
bool (ComponentIterator::*on_item)(Entity *)) {
|
||||||
|
if (this->at_ >= items.size()) {
|
||||||
|
advance_platform_();
|
||||||
|
} else {
|
||||||
|
Entity *entity = items[this->at_];
|
||||||
|
if (entity->is_internal() && !this->include_internal_) {
|
||||||
|
this->at_++;
|
||||||
|
} else {
|
||||||
|
if ((this->*on_item)(entity)) {
|
||||||
|
this->at_++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComponentIterator::advance_platform_() {
|
||||||
|
this->state_ = static_cast<IteratorState>(static_cast<uint32_t>(this->state_) + 1);
|
||||||
|
this->at_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ComponentIterator::advance() {
|
void ComponentIterator::advance() {
|
||||||
bool advance_platform = false;
|
|
||||||
bool success = true;
|
|
||||||
switch (this->state_) {
|
switch (this->state_) {
|
||||||
case IteratorState::NONE:
|
case IteratorState::NONE:
|
||||||
// not started
|
// not started
|
||||||
return;
|
return;
|
||||||
case IteratorState::BEGIN:
|
case IteratorState::BEGIN:
|
||||||
if (this->on_begin()) {
|
if (this->on_begin()) {
|
||||||
advance_platform = true;
|
advance_platform_();
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
case IteratorState::BINARY_SENSOR:
|
case IteratorState::BINARY_SENSOR:
|
||||||
if (this->at_ >= App.get_binary_sensors().size()) {
|
process_entity_(App.get_binary_sensors(), &ComponentIterator::on_binary_sensor);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *binary_sensor = App.get_binary_sensors()[this->at_];
|
|
||||||
if (binary_sensor->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_binary_sensor(binary_sensor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_COVER
|
#ifdef USE_COVER
|
||||||
case IteratorState::COVER:
|
case IteratorState::COVER:
|
||||||
if (this->at_ >= App.get_covers().size()) {
|
process_entity_(App.get_covers(), &ComponentIterator::on_cover);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *cover = App.get_covers()[this->at_];
|
|
||||||
if (cover->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_cover(cover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_FAN
|
#ifdef USE_FAN
|
||||||
case IteratorState::FAN:
|
case IteratorState::FAN:
|
||||||
if (this->at_ >= App.get_fans().size()) {
|
process_entity_(App.get_fans(), &ComponentIterator::on_fan);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *fan = App.get_fans()[this->at_];
|
|
||||||
if (fan->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_fan(fan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIGHT
|
#ifdef USE_LIGHT
|
||||||
case IteratorState::LIGHT:
|
case IteratorState::LIGHT:
|
||||||
if (this->at_ >= App.get_lights().size()) {
|
process_entity_(App.get_lights(), &ComponentIterator::on_light);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *light = App.get_lights()[this->at_];
|
|
||||||
if (light->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_light(light);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SENSOR
|
#ifdef USE_SENSOR
|
||||||
case IteratorState::SENSOR:
|
case IteratorState::SENSOR:
|
||||||
if (this->at_ >= App.get_sensors().size()) {
|
process_entity_(App.get_sensors(), &ComponentIterator::on_sensor);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *sensor = App.get_sensors()[this->at_];
|
|
||||||
if (sensor->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_sensor(sensor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SWITCH
|
#ifdef USE_SWITCH
|
||||||
case IteratorState::SWITCH:
|
case IteratorState::SWITCH:
|
||||||
if (this->at_ >= App.get_switches().size()) {
|
process_entity_(App.get_switches(), &ComponentIterator::on_switch);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *a_switch = App.get_switches()[this->at_];
|
|
||||||
if (a_switch->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_switch(a_switch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_BUTTON
|
#ifdef USE_BUTTON
|
||||||
case IteratorState::BUTTON:
|
case IteratorState::BUTTON:
|
||||||
if (this->at_ >= App.get_buttons().size()) {
|
process_entity_(App.get_buttons(), &ComponentIterator::on_button);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *button = App.get_buttons()[this->at_];
|
|
||||||
if (button->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_button(button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT_SENSOR
|
#ifdef USE_TEXT_SENSOR
|
||||||
case IteratorState::TEXT_SENSOR:
|
case IteratorState::TEXT_SENSOR:
|
||||||
if (this->at_ >= App.get_text_sensors().size()) {
|
process_entity_(App.get_text_sensors(), &ComponentIterator::on_text_sensor);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *text_sensor = App.get_text_sensors()[this->at_];
|
|
||||||
if (text_sensor->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_text_sensor(text_sensor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_API
|
#ifdef USE_API
|
||||||
case IteratorState::SERVICE:
|
case IteratorState::SERVICE:
|
||||||
if (this->at_ >= api::global_api_server->get_user_services().size()) {
|
process_entity_(api::global_api_server->get_user_services(), &ComponentIterator::on_service);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *service = api::global_api_server->get_user_services()[this->at_];
|
|
||||||
success = this->on_service(service);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ESP32_CAMERA
|
#ifdef USE_ESP32_CAMERA
|
||||||
case IteratorState::CAMERA:
|
case IteratorState::CAMERA: {
|
||||||
if (esp32_camera::global_esp32_camera == nullptr) {
|
std::vector<esp32_camera::ESP32Camera *> cameras;
|
||||||
advance_platform = true;
|
if (esp32_camera::global_esp32_camera) {
|
||||||
} else {
|
cameras.push_back(esp32_camera::global_esp32_camera);
|
||||||
if (esp32_camera::global_esp32_camera->is_internal() && !this->include_internal_) {
|
|
||||||
advance_platform = success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
advance_platform = success = this->on_camera(esp32_camera::global_esp32_camera);
|
|
||||||
}
|
}
|
||||||
}
|
process_entity_(cameras, &ComponentIterator::on_camera);
|
||||||
break;
|
} break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CLIMATE
|
#ifdef USE_CLIMATE
|
||||||
case IteratorState::CLIMATE:
|
case IteratorState::CLIMATE:
|
||||||
if (this->at_ >= App.get_climates().size()) {
|
process_entity_(App.get_climates(), &ComponentIterator::on_climate);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *climate = App.get_climates()[this->at_];
|
|
||||||
if (climate->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_climate(climate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_NUMBER
|
#ifdef USE_NUMBER
|
||||||
case IteratorState::NUMBER:
|
case IteratorState::NUMBER:
|
||||||
if (this->at_ >= App.get_numbers().size()) {
|
process_entity_(App.get_numbers(), &ComponentIterator::on_number);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *number = App.get_numbers()[this->at_];
|
|
||||||
if (number->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_number(number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_DATE
|
#ifdef USE_DATETIME_DATE
|
||||||
case IteratorState::DATETIME_DATE:
|
case IteratorState::DATETIME_DATE:
|
||||||
if (this->at_ >= App.get_dates().size()) {
|
process_entity_(App.get_dates(), &ComponentIterator::on_date);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *date = App.get_dates()[this->at_];
|
|
||||||
if (date->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_date(date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_TIME
|
#ifdef USE_DATETIME_TIME
|
||||||
case IteratorState::DATETIME_TIME:
|
case IteratorState::DATETIME_TIME:
|
||||||
if (this->at_ >= App.get_times().size()) {
|
process_entity_(App.get_times(), &ComponentIterator::on_time);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *time = App.get_times()[this->at_];
|
|
||||||
if (time->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_time(time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_DATETIME_DATETIME
|
#ifdef USE_DATETIME_DATETIME
|
||||||
case IteratorState::DATETIME_DATETIME:
|
case IteratorState::DATETIME_DATETIME:
|
||||||
if (this->at_ >= App.get_datetimes().size()) {
|
process_entity_(App.get_datetimes(), &ComponentIterator::on_datetime);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *datetime = App.get_datetimes()[this->at_];
|
|
||||||
if (datetime->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_datetime(datetime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_TEXT
|
#ifdef USE_TEXT
|
||||||
case IteratorState::TEXT:
|
case IteratorState::TEXT:
|
||||||
if (this->at_ >= App.get_texts().size()) {
|
process_entity_(App.get_texts(), &ComponentIterator::on_text);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *text = App.get_texts()[this->at_];
|
|
||||||
if (text->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_text(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SELECT
|
#ifdef USE_SELECT
|
||||||
case IteratorState::SELECT:
|
case IteratorState::SELECT:
|
||||||
if (this->at_ >= App.get_selects().size()) {
|
process_entity_(App.get_selects(), &ComponentIterator::on_select);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *select = App.get_selects()[this->at_];
|
|
||||||
if (select->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_select(select);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LOCK
|
#ifdef USE_LOCK
|
||||||
case IteratorState::LOCK:
|
case IteratorState::LOCK:
|
||||||
if (this->at_ >= App.get_locks().size()) {
|
process_entity_(App.get_locks(), &ComponentIterator::on_lock);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *a_lock = App.get_locks()[this->at_];
|
|
||||||
if (a_lock->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_lock(a_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_VALVE
|
#ifdef USE_VALVE
|
||||||
case IteratorState::VALVE:
|
case IteratorState::VALVE:
|
||||||
if (this->at_ >= App.get_valves().size()) {
|
process_entity_(App.get_valves(), &ComponentIterator::on_valve);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *valve = App.get_valves()[this->at_];
|
|
||||||
if (valve->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_valve(valve);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MEDIA_PLAYER
|
#ifdef USE_MEDIA_PLAYER
|
||||||
case IteratorState::MEDIA_PLAYER:
|
case IteratorState::MEDIA_PLAYER:
|
||||||
if (this->at_ >= App.get_media_players().size()) {
|
process_entity_(App.get_media_players(), &ComponentIterator::on_media_player);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *media_player = App.get_media_players()[this->at_];
|
|
||||||
if (media_player->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_media_player(media_player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ALARM_CONTROL_PANEL
|
#ifdef USE_ALARM_CONTROL_PANEL
|
||||||
case IteratorState::ALARM_CONTROL_PANEL:
|
case IteratorState::ALARM_CONTROL_PANEL:
|
||||||
if (this->at_ >= App.get_alarm_control_panels().size()) {
|
process_entity_(App.get_alarm_control_panels(), &ComponentIterator::on_alarm_control_panel);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *a_alarm_control_panel = App.get_alarm_control_panels()[this->at_];
|
|
||||||
if (a_alarm_control_panel->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_alarm_control_panel(a_alarm_control_panel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_EVENT
|
#ifdef USE_EVENT
|
||||||
case IteratorState::EVENT:
|
case IteratorState::EVENT:
|
||||||
if (this->at_ >= App.get_events().size()) {
|
process_entity_(App.get_events(), &ComponentIterator::on_event);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *event = App.get_events()[this->at_];
|
|
||||||
if (event->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_event(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_UPDATE
|
#ifdef USE_UPDATE
|
||||||
case IteratorState::UPDATE:
|
case IteratorState::UPDATE:
|
||||||
if (this->at_ >= App.get_updates().size()) {
|
process_entity_(App.get_updates(), &ComponentIterator::on_update);
|
||||||
advance_platform = true;
|
|
||||||
} else {
|
|
||||||
auto *update = App.get_updates()[this->at_];
|
|
||||||
if (update->is_internal() && !this->include_internal_) {
|
|
||||||
success = true;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
success = this->on_update(update);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case IteratorState::MAX:
|
case IteratorState::MAX:
|
||||||
if (this->on_end()) {
|
if (this->on_end()) {
|
||||||
this->state_ = IteratorState::NONE;
|
this->state_ = IteratorState::NONE;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (advance_platform) {
|
|
||||||
this->state_ = static_cast<IteratorState>(static_cast<uint32_t>(this->state_) + 1);
|
|
||||||
this->at_ = 0;
|
|
||||||
} else if (success) {
|
|
||||||
this->at_++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool ComponentIterator::on_end() { return true; }
|
bool ComponentIterator::on_end() { return true; }
|
||||||
bool ComponentIterator::on_begin() { return true; }
|
bool ComponentIterator::on_begin() { return true; }
|
||||||
#ifdef USE_API
|
#ifdef USE_API
|
||||||
|
|
|
@ -169,6 +169,10 @@ class ComponentIterator {
|
||||||
} state_{IteratorState::NONE};
|
} state_{IteratorState::NONE};
|
||||||
size_t at_{0};
|
size_t at_{0};
|
||||||
bool include_internal_{false};
|
bool include_internal_{false};
|
||||||
|
|
||||||
|
template<typename Entity>
|
||||||
|
void process_entity_(const std::vector<Entity *> &items, bool (ComponentIterator::*on_item)(Entity *));
|
||||||
|
void advance_platform_();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
Loading…
Reference in a new issue