DeviceManager: Move creating device info to main thread

This commit is contained in:
Jonas Kvinge
2025-06-22 17:21:12 +02:00
parent f6b38fecb0
commit 8cea020fac
4 changed files with 68 additions and 57 deletions

View File

@@ -36,6 +36,24 @@
using namespace Qt::Literals::StringLiterals; 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 DeviceInfo::SaveToDb() const {
DeviceDatabaseBackend::Device device; 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 { const DeviceInfo::Backend *DeviceInfo::BestBackend() const {
int best_priority = -1; 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; icon_name_ = "device"_L1;

View File

@@ -97,8 +97,9 @@ class DeviceInfo : public SimpleTreeItem<DeviceInfo> {
void InitFromDb(const DeviceDatabaseBackend::Device &dev); void InitFromDb(const DeviceDatabaseBackend::Device &dev);
DeviceDatabaseBackend::Device SaveToDb() const; DeviceDatabaseBackend::Device SaveToDb() const;
void InitIcon();
// Tries to load a good icon for the device. Sets icon_name_ and icon_. // 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) // Gets the best backend available (the one with the highest priority)
const Backend *BestBackend() const; const Backend *BestBackend() const;

View File

@@ -109,7 +109,7 @@ DeviceManager::DeviceManager(const SharedPtr<TaskManager> task_manager,
backend_->moveToThread(database->thread()); backend_->moveToThread(database->thread());
backend_->Init(database); 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. // 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); (void)QtConcurrent::run(&thread_pool_, &DeviceManager::LoadAllDevices, this);
@@ -237,42 +237,37 @@ void DeviceManager::LoadAllDevices() {
Q_ASSERT(QThread::currentThread() != qApp->thread()); Q_ASSERT(QThread::currentThread() != qApp->thread());
const DeviceDatabaseBackend::DeviceList devices = backend_->GetAllDevices(); const DeviceDatabaseBackend::DeviceList devices = backend_->GetAllDevices();
for (const DeviceDatabaseBackend::Device &device : devices) {
DeviceInfo *device_info = new DeviceInfo(DeviceInfo::Type::Device, root_); Q_EMIT DevicesLoaded(devices);
device_info->InitFromDb(device);
Q_EMIT DeviceCreatedFromDB(device_info);
}
// This is done in a concurrent thread so close the unique DB connection. // This is done in a concurrent thread so close the unique DB connection.
backend_->Close(); 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','); for (const DeviceDatabaseBackend::Device &device : devices) {
QVariantList icons; const QStringList unique_ids = device.unique_id_.split(u',');
icons.reserve(icon_names.count()); DeviceInfo *device_info = FindEquivalentDevice(unique_ids);
for (const QString &icon_name : icon_names) { if (device_info && device_info->database_id_ == -1) {
icons << icon_name; qLog(Info) << "Database device linked to physical device:" << device.friendly_name_;
} device_info->database_id_ = device.id_;
device_info->SetIcon(icons, device_info->friendly_name_); device_info->icon_name_ = device.icon_name_;
device_info->InitIcon();
DeviceInfo *existing_device_info = FindEquivalentDevice(device_info); const QModelIndex idx = ItemToIndex(device_info);
if (existing_device_info && existing_device_info->database_id_ == -1) { if (idx.isValid()) {
qLog(Info) << "Found existing device:" << device_info->friendly_name_; Q_EMIT dataChanged(idx, idx);
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_; else {
QModelIndex idx = ItemToIndex(existing_device_info); qLog(Info) << "Database device:" << device.friendly_name_;
if (idx.isValid()) Q_EMIT dataChanged(idx, idx); device_info = new DeviceInfo(DeviceInfo::Type::Device, root_);
root_->Delete(device_info->row); device_info->InitFromDb(device);
} beginInsertRows(ItemToIndex(root_), static_cast<int>(devices_.count()), static_cast<int>(devices_.count()));
else { devices_ << device_info;
qLog(Info) << "Device added from database:" << device_info->friendly_name_; endInsertRows();
beginInsertRows(ItemToIndex(root_), static_cast<int>(devices_.count()), static_cast<int>(devices_.count())); }
devices_ << device_info;
endInsertRows();
} }
} }
@@ -440,10 +435,10 @@ DeviceInfo *DeviceManager::FindDeviceByUrl(const QList<QUrl> &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_)) { for (const QString &unique_id : unique_ids) {
DeviceInfo *device_info_match = FindDeviceById(backend.unique_id_); DeviceInfo *device_info_match = FindDeviceById(unique_id);
if (device_info_match) { if (device_info_match) {
return 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) { if (device_info->database_id_ == -1 && device_info->BestBackend() && device_info->BestBackend()->lister_ == lister) {
device_info->friendly_name_ = lister->MakeFriendlyName(id); device_info->friendly_name_ = lister->MakeFriendlyName(id);
device_info->size_ = lister->DeviceCapacity(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); QModelIndex idx = ItemToIndex(device_info);
if (idx.isValid()) Q_EMIT dataChanged(idx, idx); 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->backends_ << DeviceInfo::Backend(lister, id);
device_info->friendly_name_ = lister->MakeFriendlyName(id); device_info->friendly_name_ = lister->MakeFriendlyName(id);
device_info->size_ = lister->DeviceCapacity(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<int>(devices_.count()), static_cast<int>(devices_.count())); beginInsertRows(ItemToIndex(root_), static_cast<int>(devices_.count()), static_cast<int>(devices_.count()));
devices_ << device_info; devices_ << device_info;
endInsertRows(); endInsertRows();
@@ -815,7 +810,7 @@ void DeviceManager::RemoveFromDB(DeviceInfo *device_info, const QModelIndex &idx
const QString id = device_info->BestBackend()->unique_id_; const QString id = device_info->BestBackend()->unique_id_;
device_info->friendly_name_ = device_info->BestBackend()->lister_->MakeFriendlyName(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); Q_EMIT dataChanged(idx, idx);
} }
@@ -829,7 +824,7 @@ void DeviceManager::SetDeviceOptions(const QModelIndex &idx, const QString &frie
if (!device_info) return; if (!device_info) return;
device_info->friendly_name_ = friendly_name; 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_mode_ = mode;
device_info->transcode_format_ = format; device_info->transcode_format_ = format;

View File

@@ -109,7 +109,7 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
DeviceInfo *FindDeviceById(const QString &id) const; DeviceInfo *FindDeviceById(const QString &id) const;
DeviceInfo *FindDeviceByUrl(const QList<QUrl> &url) const; DeviceInfo *FindDeviceByUrl(const QList<QUrl> &url) const;
QString DeviceNameByID(const QString &unique_id); QString DeviceNameByID(const QString &unique_id);
DeviceInfo *FindEquivalentDevice(DeviceInfo *device_info) const; DeviceInfo *FindEquivalentDevice(const QStringList &unique_ids) const;
// Actions on devices // Actions on devices
SharedPtr<ConnectedDevice> Connect(DeviceInfo *device_info); SharedPtr<ConnectedDevice> Connect(DeviceInfo *device_info);
@@ -128,6 +128,7 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
Q_SIGNALS: Q_SIGNALS:
void ExitFinished(); void ExitFinished();
void DevicesLoaded(const DeviceDatabaseBackend::DeviceList &devices);
void DeviceConnected(const QModelIndex idx); void DeviceConnected(const QModelIndex idx);
void DeviceDisconnected(const QModelIndex idx); void DeviceDisconnected(const QModelIndex idx);
void DeviceCreatedFromDB(DeviceInfo *device_info); void DeviceCreatedFromDB(DeviceInfo *device_info);
@@ -143,7 +144,7 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
void LoadAllDevices(); void LoadAllDevices();
void DeviceConnectFinished(const QString &id, bool success); void DeviceConnectFinished(const QString &id, bool success);
void DeviceCloseFinished(const QString &id); void DeviceCloseFinished(const QString &id);
void AddDeviceFromDB(DeviceInfo *device_info); void AddDevicesFromDB(const DeviceDatabaseBackend::DeviceList &devices);
void BackendClosed(); void BackendClosed();
void ListerClosed(); void ListerClosed();
void DeviceDestroyed(); void DeviceDestroyed();