From 8cea020fac24badad56178416b12e5ba62b96743 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 22 Jun 2025 17:21:12 +0200 Subject: [PATCH] DeviceManager: Move creating device info to main thread --- src/device/deviceinfo.cpp | 48 ++++++++++++++++--------- src/device/deviceinfo.h | 3 +- src/device/devicemanager.cpp | 69 +++++++++++++++++------------------- src/device/devicemanager.h | 5 +-- 4 files changed, 68 insertions(+), 57 deletions(-) diff --git a/src/device/deviceinfo.cpp b/src/device/deviceinfo.cpp index faea57d52..4e9283d7e 100644 --- a/src/device/deviceinfo.cpp +++ b/src/device/deviceinfo.cpp @@ -36,6 +36,24 @@ using namespace Qt::Literals::StringLiterals; +void DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device &device) { + + database_id_ = device.id_; + friendly_name_ = device.friendly_name_; + size_ = device.size_; + transcode_mode_ = device.transcode_mode_; + transcode_format_ = device.transcode_format_; + icon_name_ = device.icon_name_; + + InitIcon(); + + const QStringList unique_ids = device.unique_id_.split(u','); + for (const QString &id : unique_ids) { + backends_ << Backend(nullptr, id); + } + +} + DeviceDatabaseBackend::Device DeviceInfo::SaveToDb() const { DeviceDatabaseBackend::Device device; @@ -57,22 +75,6 @@ DeviceDatabaseBackend::Device DeviceInfo::SaveToDb() const { } -void DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device &dev) { - - database_id_ = dev.id_; - friendly_name_ = dev.friendly_name_; - size_ = dev.size_; - transcode_mode_ = dev.transcode_mode_; - transcode_format_ = dev.transcode_format_; - icon_name_ = dev.icon_name_; - - const QStringList unique_ids = dev.unique_id_.split(u','); - for (const QString &id : unique_ids) { - backends_ << Backend(nullptr, id); - } - -} - const DeviceInfo::Backend *DeviceInfo::BestBackend() const { int best_priority = -1; @@ -90,7 +92,19 @@ const DeviceInfo::Backend *DeviceInfo::BestBackend() const { } -void DeviceInfo::SetIcon(const QVariantList &icons, const QString &name_hint) { +void DeviceInfo::InitIcon() { + + const QStringList icon_name_list = icon_name_.split(u','); + QVariantList icons; + icons.reserve(icon_name_list.count()); + for (const QString &icon_name : icon_name_list) { + icons << icon_name; + } + LoadIcon(icons, friendly_name_); + +} + +void DeviceInfo::LoadIcon(const QVariantList &icons, const QString &name_hint) { icon_name_ = "device"_L1; diff --git a/src/device/deviceinfo.h b/src/device/deviceinfo.h index 6585759a2..a649c85bd 100644 --- a/src/device/deviceinfo.h +++ b/src/device/deviceinfo.h @@ -97,8 +97,9 @@ class DeviceInfo : public SimpleTreeItem { void InitFromDb(const DeviceDatabaseBackend::Device &dev); DeviceDatabaseBackend::Device SaveToDb() const; + void InitIcon(); // Tries to load a good icon for the device. Sets icon_name_ and icon_. - void SetIcon(const QVariantList &icons, const QString &name_hint); + void LoadIcon(const QVariantList &icons, const QString &name_hint); // Gets the best backend available (the one with the highest priority) const Backend *BestBackend() const; diff --git a/src/device/devicemanager.cpp b/src/device/devicemanager.cpp index a1021d2dc..1f52947f6 100644 --- a/src/device/devicemanager.cpp +++ b/src/device/devicemanager.cpp @@ -109,7 +109,7 @@ DeviceManager::DeviceManager(const SharedPtr task_manager, backend_->moveToThread(database->thread()); backend_->Init(database); - QObject::connect(this, &DeviceManager::DeviceCreatedFromDB, this, &DeviceManager::AddDeviceFromDB); + QObject::connect(this, &DeviceManager::DevicesLoaded, this, &DeviceManager::AddDevicesFromDB); // This reads from the database and contents on the database mutex, which can be very slow on startup. (void)QtConcurrent::run(&thread_pool_, &DeviceManager::LoadAllDevices, this); @@ -237,42 +237,37 @@ void DeviceManager::LoadAllDevices() { Q_ASSERT(QThread::currentThread() != qApp->thread()); const DeviceDatabaseBackend::DeviceList devices = backend_->GetAllDevices(); - for (const DeviceDatabaseBackend::Device &device : devices) { - DeviceInfo *device_info = new DeviceInfo(DeviceInfo::Type::Device, root_); - device_info->InitFromDb(device); - Q_EMIT DeviceCreatedFromDB(device_info); - } + + Q_EMIT DevicesLoaded(devices); // This is done in a concurrent thread so close the unique DB connection. backend_->Close(); } -void DeviceManager::AddDeviceFromDB(DeviceInfo *device_info) { +void DeviceManager::AddDevicesFromDB(const DeviceDatabaseBackend::DeviceList &devices) { - const QStringList icon_names = device_info->icon_name_.split(u','); - QVariantList icons; - icons.reserve(icon_names.count()); - for (const QString &icon_name : icon_names) { - icons << icon_name; - } - device_info->SetIcon(icons, device_info->friendly_name_); - - DeviceInfo *existing_device_info = FindEquivalentDevice(device_info); - if (existing_device_info && existing_device_info->database_id_ == -1) { - qLog(Info) << "Found existing device:" << device_info->friendly_name_; - existing_device_info->database_id_ = device_info->database_id_; - existing_device_info->icon_name_ = device_info->icon_name_; - existing_device_info->icon_ = device_info->icon_; - QModelIndex idx = ItemToIndex(existing_device_info); - if (idx.isValid()) Q_EMIT dataChanged(idx, idx); - root_->Delete(device_info->row); - } - else { - qLog(Info) << "Device added from database:" << device_info->friendly_name_; - beginInsertRows(ItemToIndex(root_), static_cast(devices_.count()), static_cast(devices_.count())); - devices_ << device_info; - endInsertRows(); + for (const DeviceDatabaseBackend::Device &device : devices) { + const QStringList unique_ids = device.unique_id_.split(u','); + DeviceInfo *device_info = FindEquivalentDevice(unique_ids); + if (device_info && device_info->database_id_ == -1) { + qLog(Info) << "Database device linked to physical device:" << device.friendly_name_; + device_info->database_id_ = device.id_; + device_info->icon_name_ = device.icon_name_; + device_info->InitIcon(); + const QModelIndex idx = ItemToIndex(device_info); + if (idx.isValid()) { + Q_EMIT dataChanged(idx, idx); + } + } + else { + qLog(Info) << "Database device:" << device.friendly_name_; + device_info = new DeviceInfo(DeviceInfo::Type::Device, root_); + device_info->InitFromDb(device); + beginInsertRows(ItemToIndex(root_), static_cast(devices_.count()), static_cast(devices_.count())); + devices_ << device_info; + endInsertRows(); + } } } @@ -440,10 +435,10 @@ DeviceInfo *DeviceManager::FindDeviceByUrl(const QList &urls) const { } -DeviceInfo *DeviceManager::FindEquivalentDevice(DeviceInfo *device_info) const { +DeviceInfo *DeviceManager::FindEquivalentDevice(const QStringList &unique_ids) const { - for (const DeviceInfo::Backend &backend : std::as_const(device_info->backends_)) { - DeviceInfo *device_info_match = FindDeviceById(backend.unique_id_); + for (const QString &unique_id : unique_ids) { + DeviceInfo *device_info_match = FindDeviceById(unique_id); if (device_info_match) { return device_info_match; } @@ -483,7 +478,7 @@ void DeviceManager::PhysicalDeviceAdded(const QString &id) { if (device_info->database_id_ == -1 && device_info->BestBackend() && device_info->BestBackend()->lister_ == lister) { device_info->friendly_name_ = lister->MakeFriendlyName(id); device_info->size_ = lister->DeviceCapacity(id); - device_info->SetIcon(lister->DeviceIcons(id), device_info->friendly_name_); + device_info->LoadIcon(lister->DeviceIcons(id), device_info->friendly_name_); } QModelIndex idx = ItemToIndex(device_info); if (idx.isValid()) Q_EMIT dataChanged(idx, idx); @@ -494,7 +489,7 @@ void DeviceManager::PhysicalDeviceAdded(const QString &id) { device_info->backends_ << DeviceInfo::Backend(lister, id); device_info->friendly_name_ = lister->MakeFriendlyName(id); device_info->size_ = lister->DeviceCapacity(id); - device_info->SetIcon(lister->DeviceIcons(id), device_info->friendly_name_); + device_info->LoadIcon(lister->DeviceIcons(id), device_info->friendly_name_); beginInsertRows(ItemToIndex(root_), static_cast(devices_.count()), static_cast(devices_.count())); devices_ << device_info; endInsertRows(); @@ -815,7 +810,7 @@ void DeviceManager::RemoveFromDB(DeviceInfo *device_info, const QModelIndex &idx const QString id = device_info->BestBackend()->unique_id_; device_info->friendly_name_ = device_info->BestBackend()->lister_->MakeFriendlyName(id); - device_info->SetIcon(device_info->BestBackend()->lister_->DeviceIcons(id), device_info->friendly_name_); + device_info->LoadIcon(device_info->BestBackend()->lister_->DeviceIcons(id), device_info->friendly_name_); Q_EMIT dataChanged(idx, idx); } @@ -829,7 +824,7 @@ void DeviceManager::SetDeviceOptions(const QModelIndex &idx, const QString &frie if (!device_info) return; device_info->friendly_name_ = friendly_name; - device_info->SetIcon(QVariantList() << icon_name, friendly_name); + device_info->LoadIcon(QVariantList() << icon_name, friendly_name); device_info->transcode_mode_ = mode; device_info->transcode_format_ = format; diff --git a/src/device/devicemanager.h b/src/device/devicemanager.h index e93c38e64..63a8e4171 100644 --- a/src/device/devicemanager.h +++ b/src/device/devicemanager.h @@ -109,7 +109,7 @@ class DeviceManager : public SimpleTreeModel { DeviceInfo *FindDeviceById(const QString &id) const; DeviceInfo *FindDeviceByUrl(const QList &url) const; QString DeviceNameByID(const QString &unique_id); - DeviceInfo *FindEquivalentDevice(DeviceInfo *device_info) const; + DeviceInfo *FindEquivalentDevice(const QStringList &unique_ids) const; // Actions on devices SharedPtr Connect(DeviceInfo *device_info); @@ -128,6 +128,7 @@ class DeviceManager : public SimpleTreeModel { Q_SIGNALS: void ExitFinished(); + void DevicesLoaded(const DeviceDatabaseBackend::DeviceList &devices); void DeviceConnected(const QModelIndex idx); void DeviceDisconnected(const QModelIndex idx); void DeviceCreatedFromDB(DeviceInfo *device_info); @@ -143,7 +144,7 @@ class DeviceManager : public SimpleTreeModel { void LoadAllDevices(); void DeviceConnectFinished(const QString &id, bool success); void DeviceCloseFinished(const QString &id); - void AddDeviceFromDB(DeviceInfo *device_info); + void AddDevicesFromDB(const DeviceDatabaseBackend::DeviceList &devices); void BackendClosed(); void ListerClosed(); void DeviceDestroyed();