summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Szmigin <smidge@xsco.net>2020-10-27 23:59:45 +0000
committerAdam Szmigin <smidge@xsco.net>2020-10-28 22:44:29 +0000
commitbfd84d05cccdeb7e060768db3d6af2938f7a84aa (patch)
tree2c9e2b44b0a7c8629a9fe006373fa58407bbe532
parent1148154fb71213965a9b0efab9c616e97b355668 (diff)
All djinterop exceptions caught, further cleanuppr-2753
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/library/export/dlglibraryexport.cpp4
-rw-r--r--src/library/export/engineprimeexportjob.cpp107
-rw-r--r--src/library/export/engineprimeexportjob.h8
-rw-r--r--src/library/export/libraryexporter.cpp46
-rw-r--r--src/library/export/libraryexporter.h4
-rw-r--r--src/library/library.cpp17
-rw-r--r--src/library/mixxxlibraryfeature.cpp6
-rw-r--r--src/library/mixxxlibraryfeature.h4
-rw-r--r--src/library/trackset/crate/cratefeature.cpp26
-rw-r--r--src/library/trackset/crate/cratefeature.h4
-rw-r--r--src/mixxx.cpp13
12 files changed, 149 insertions, 92 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 33e12dfa89..8ee0c79548 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1507,7 +1507,7 @@ if(ENGINEPRIME)
set(DJINTEROP_LIBRARY "lib/${CMAKE_STATIC_LIBRARY_PREFIX}djinterop${CMAKE_STATIC_LIBRARY_SUFFIX}")
ExternalProject_Add(libdjinterop
GIT_REPOSITORY https://github.com/xsco/libdjinterop.git
- GIT_TAG tags/0.14.3
+ GIT_TAG tags/0.14.4
GIT_SHALLOW TRUE
INSTALL_DIR ${DJINTEROP_INSTALL_DIR}
CMAKE_ARGS
diff --git a/src/library/export/dlglibraryexport.cpp b/src/library/export/dlglibraryexport.cpp
index c32d60ac17..56ac2abac8 100644
--- a/src/library/export/dlglibraryexport.cpp
+++ b/src/library/export/dlglibraryexport.cpp
@@ -157,8 +157,8 @@ void DlgLibraryExport::browseExportDirectory() {
QString lastExportDirectory =
m_pConfig->getValue(ConfigKey("[Library]", "LastLibraryExportDirectory"),
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
- auto baseDirectory =
- QFileDialog::getExistingDirectory(nullptr, tr("Export Library To"), lastExportDirectory);
+ auto baseDirectory = QFileDialog::getExistingDirectory(
+ nullptr, tr("Export Library To"), lastExportDirectory);
if (baseDirectory.isEmpty()) {
return;
}
diff --git a/src/library/export/engineprimeexportjob.cpp b/src/library/export/engineprimeexportjob.cpp
index ff6ffe99d5..b217c4199d 100644
--- a/src/library/export/engineprimeexportjob.cpp
+++ b/src/library/export/engineprimeexportjob.cpp
@@ -14,6 +14,7 @@
#include "library/trackset/crate/crate.h"
#include "track/track.h"
#include "util/optional.h"
+#include "util/thread_affinity.h"
#include "waveform/waveformfactory.h"
namespace el = djinterop::enginelibrary;
@@ -293,18 +294,20 @@ EnginePrimeExportJob::EnginePrimeExportJob(
QObject* parent,
TrackCollectionManager* pTrackCollectionManager,
EnginePrimeExportRequest request)
- : QThread(parent),
+ : QThread{parent},
m_pTrackCollectionManager(pTrackCollectionManager),
m_request{std::move(request)} {
// Must be collocated with the TrackCollectionManager.
- DEBUG_ASSERT(m_pTrackCollectionManager != nullptr);
- moveToThread(m_pTrackCollectionManager->thread());
+ if (parent != nullptr) {
+ DEBUG_ASSERT_QOBJECT_THREAD_AFFINITY(m_pTrackCollectionManager);
+ } else {
+ DEBUG_ASSERT(m_pTrackCollectionManager);
+ moveToThread(m_pTrackCollectionManager->thread());
+ }
}
void EnginePrimeExportJob::loadIds(QSet<CrateId> crateIds) {
- // Note: this slot exists to ensure the track collection is never accessed
- // from outside its own thread.
- DEBUG_ASSERT(thread() == m_pTrackCollectionManager->thread());
+ DEBUG_ASSERT_QOBJECT_THREAD_AFFINITY(m_pTrackCollectionManager);
if (crateIds.isEmpty()) {
// No explicit crate ids specified, meaning we want to export the
@@ -373,9 +376,7 @@ void EnginePrimeExportJob::loadIds(QSet<CrateId> crateIds) {
}
void EnginePrimeExportJob::loadTrack(TrackRef trackRef) {
- // Note: this slot exists to ensure the track collection is never accessed
- // from outside its own thread.
- DEBUG_ASSERT(thread() == m_pTrackCollectionManager->thread());
+ DEBUG_ASSERT_QOBJECT_THREAD_AFFINITY(m_pTrackCollectionManager);
// Load the track.
m_pLastLoadedTrack = m_pTrackCollectionManager->getOrAddTrack(trackRef);
@@ -392,9 +393,7 @@ void EnginePrimeExportJob::loadTrack(TrackRef trackRef) {
}
void EnginePrimeExportJob::loadCrate(CrateId crateId) {
- // Note: this slot exists to ensure the track collection is never accessed
- // from outside its own thread.
- DEBUG_ASSERT(thread() == m_pTrackCollectionManager->thread());
+ DEBUG_ASSERT_QOBJECT_THREAD_AFFINITY(m_pTrackCollectionManager);
// Load crate details.
m_pTrackCollectionManager->internalCollection()->crates().readCrateById(
@@ -431,11 +430,19 @@ void EnginePrimeExportJob::run() {
emit jobProgress(currProgress);
// Ensure that the database exists, creating an empty one if not.
- bool created;
- djinterop::database db = el::create_or_load_database(
- m_request.engineLibraryDbDir.path().toStdString(),
- m_request.exportVersion,
- created);
+ std::unique_ptr<djinterop::database> pDb;
+ try {
+ bool created;
+ pDb = std::make_unique<djinterop::database>(el::create_or_load_database(
+ m_request.engineLibraryDbDir.path().toStdString(),
+ m_request.exportVersion,
+ created));
+ } catch (std::exception& e) {
+ qCritical() << "Failed to create/load database:" << e.what();
+ emit failed(e.what());
+ return;
+ }
+
++currProgress;
emit jobProgress(currProgress);
@@ -461,11 +468,20 @@ void EnginePrimeExportJob::run() {
qInfo() << "Exporting track" << m_pLastLoadedTrack->getId().value()
<< "at" << m_pLastLoadedTrack->getFileInfo().location() << "...";
- exportTrack(m_request,
- db,
- mixxxToEnginePrimeTrackIdMap,
- m_pLastLoadedTrack,
- std::move(m_pLastLoadedWaveform));
+ try {
+ exportTrack(m_request,
+ *pDb,
+ mixxxToEnginePrimeTrackIdMap,
+ m_pLastLoadedTrack,
+ std::move(m_pLastLoadedWaveform));
+ } catch (std::exception& e) {
+ qCritical() << "Failed to export track"
+ << m_pLastLoadedTrack->getId().value() << ":"
+ << e.what();
+ emit failed(e.what());
+ return;
+ }
+
m_pLastLoadedTrack.reset();
++currProgress;
@@ -475,12 +491,20 @@ void EnginePrimeExportJob::run() {
// We will ensure that there is a special top-level crate representing the
// root of all Mixxx-exported items. Mixxx tracks and crates will exist
// underneath this crate.
- auto optionalExtRootCrate = db.root_crate_by_name(kMixxxRootCrateName);
- auto extRootCrate = optionalExtRootCrate
- ? *optionalExtRootCrate
- : db.create_root_crate(kMixxxRootCrateName);
+ std::unique_ptr<djinterop::crate> pExtRootCrate;
+ try {
+ auto optionalExtRootCrate = pDb->root_crate_by_name(kMixxxRootCrateName);
+ pExtRootCrate = std::make_unique<djinterop::crate>(optionalExtRootCrate
+ ? *optionalExtRootCrate
+ : pDb->create_root_crate(kMixxxRootCrateName));
+ } catch (std::exception& e) {
+ qCritical() << "Failed to create/identify root crate:" << e.what();
+ emit failed(e.what());
+ return;
+ }
+
+ // Add each track to the root crate, even if it also belongs to others.
for (const TrackRef& trackRef : m_trackRefs) {
- // Add each track to the root crate, even if it also belongs to others.
if (!mixxxToEnginePrimeTrackIdMap.contains(trackRef.getId())) {
qInfo() << "Not adding track" << trackRef.getId()
<< "to any crates, as it was not exported";
@@ -489,7 +513,14 @@ void EnginePrimeExportJob::run() {
auto extTrackId = mixxxToEnginePrimeTrackIdMap.value(
trackRef.getId());
- extRootCrate.add_track(extTrackId);
+ try {
+ pExtRootCrate->add_track(extTrackId);
+ } catch (std::exception& e) {
+ qCritical() << "Failed to add track" << trackRef.getId()
+ << "to root crate:" << e.what();
+ emit failed(e.what());
+ return;
+ }
}
++currProgress;
@@ -512,20 +543,28 @@ void EnginePrimeExportJob::run() {
}
qInfo() << "Exporting crate" << m_lastLoadedCrate.getId().value() << "...";
- exportCrate(
- extRootCrate,
- mixxxToEnginePrimeTrackIdMap,
- m_lastLoadedCrate,
- m_lastLoadedCrateTrackIds);
+ try {
+ exportCrate(
+ *pExtRootCrate,
+ mixxxToEnginePrimeTrackIdMap,
+ m_lastLoadedCrate,
+ m_lastLoadedCrateTrackIds);
+ } catch (std::exception& e) {
+ qCritical() << "Failed to add crate" << m_lastLoadedCrate.getId().value()
+ << ":" << e.what();
+ emit failed(e.what());
+ return;
+ }
++currProgress;
emit jobProgress(currProgress);
}
qInfo() << "Engine Prime Export Job completed successfully";
+ emit completed(m_trackRefs.size(), m_crateIds.size());
}
-void EnginePrimeExportJob::cancel() {
+void EnginePrimeExportJob::slotCancel() {
m_cancellationRequested = 1;
}
diff --git a/src/library/export/engineprimeexportjob.h b/src/library/export/engineprimeexportjob.h
index ba64f80a39..e3ce9ab35d 100644
--- a/src/library/export/engineprimeexportjob.h
+++ b/src/library/export/engineprimeexportjob.h
@@ -41,9 +41,15 @@ class EnginePrimeExportJob : public QThread {
/// Informs of progress through the job, up to the pre-signalled maximum.
void jobProgress(int progress);
+ /// Inform of a completed export job.
+ void completed(int numTracksExported, int numCratesExported);
+
+ /// Inform of a failed export job.
+ void failed(QString message);
+
public slots:
/// Request cancellation of any running export job.
- void cancel();
+ void slotCancel();
private slots:
// These slots are used to load data from the Mixxx database on the main
diff --git a/src/library/export/libraryexporter.cpp b/src/library/export/libraryexporter.cpp
index 97c7ba5fcc..25d8ba6de2 100644
--- a/src/library/export/libraryexporter.cpp
+++ b/src/library/export/libraryexporter.cpp
@@ -21,7 +21,10 @@ void LibraryExporter::requestExportWithOptionalInitialCrate(
if (!m_pDialog) {
m_pDialog = make_parented<DlgLibraryExport>(
this, m_pConfig, m_pTrackCollectionManager);
- connect(m_pDialog.get(), &DlgLibraryExport::startEnginePrimeExport, this, &LibraryExporter::beginEnginePrimeExport);
+ connect(m_pDialog.get(),
+ &DlgLibraryExport::startEnginePrimeExport,
+ this,
+ &LibraryExporter::beginEnginePrimeExport);
} else {
m_pDialog->show();
m_pDialog->raise();
@@ -41,15 +44,42 @@ void LibraryExporter::beginEnginePrimeExport(
m_pTrackCollectionManager,
std::move(request));
connect(pJobThread, &EnginePrimeExportJob::finished, pJobThread, &QObject::deleteLater);
+ connect(pJobThread,
+ &EnginePrimeExportJob::completed,
+ this,
+ [](int numTracks, int numCrates) {
+ QMessageBox::information(nullptr,
+ tr("Export Completed"),
+ QString{tr("Exported %1 track(s) and %2 crate(s).")}
+ .arg(numTracks)
+ .arg(numCrates));
+ });
+ connect(pJobThread,
+ &EnginePrimeExportJob::failed,
+ this,
+ [](QString message) {
+ QMessageBox::critical(nullptr,
+ tr("Export Failed"),
+ QString{tr("Export failed: %1")}.arg(message));
+ });
// Construct a dialog to monitor job progress and offer cancellation.
- auto pd = make_parented<QProgressDialog>(this);
- pd->setLabelText(tr("Exporting to Engine Prime..."));
- pd->setMinimumDuration(0);
- connect(pJobThread, &EnginePrimeExportJob::jobMaximum, pd, &QProgressDialog::setMaximum);
- connect(pJobThread, &EnginePrimeExportJob::jobProgress, pd, &QProgressDialog::setValue);
- connect(pJobThread, &EnginePrimeExportJob::finished, pd, &QObject::deleteLater);
- connect(pd, &QProgressDialog::canceled, pJobThread, &EnginePrimeExportJob::cancel);
+ auto pProgressDlg = make_parented<QProgressDialog>(this);
+ pProgressDlg->setLabelText(tr("Exporting to Engine Prime..."));
+ pProgressDlg->setMinimumDuration(0);
+ connect(pJobThread,
+ &EnginePrimeExportJob::jobMaximum,
+ pProgressDlg,
+ &QProgressDialog::setMaximum);
+ connect(pJobThread,
+ &EnginePrimeExportJob::jobProgress,
+ pProgressDlg,
+ &QProgressDialog::setValue);
+ connect(pJobThread, &EnginePrimeExportJob::finished, pProgressDlg, &QObject::deleteLater);
+ connect(pProgressDlg,
+ &QProgressDialog::canceled,
+ pJobThread,
+ &EnginePrimeExportJob::slotCancel);
pJobThread->start();
}
diff --git a/src/library/export/libraryexporter.h b/src/library/export/libraryexporter.h
index 41a7ae228f..643a3d32e4 100644
--- a/src/library/export/libraryexporter.h
+++ b/src/library/export/libraryexporter.h
@@ -26,12 +26,12 @@ class LibraryExporter : public QWidget {
public slots:
/// Begin the process of a library export.
- void requestExport() {
+ void slotRequestExport() {
requestExportWithOptionalInitialCrate(std::nullopt);
}
/// Begin the process of a library export, with an initial crate set.
- void requestExportWithInitialCrate(CrateId initialSelectedCrate) {
+ void slotRequestExportWithInitialCrate(CrateId initialSelectedCrate) {
requestExportWithOptionalInitialCrate(
std::make_optional(initialSelectedCrate));
}
diff --git a/src/library/library.cpp b/src/library/library.cpp
index 915b78d939..423c83f135 100644
--- a/src/library/library.cpp
+++ b/src/library/library.cpp
@@ -97,7 +97,8 @@ Library::Library(
connect(m_pMixxxLibraryFeature,
&MixxxLibraryFeature::exportLibrary,
this,
- &Library::exportLibrary);
+ &Library::exportLibrary,
+ Qt::DirectConnection /* signal-to-signal */);
#endif
addFeature(new AutoDJFeature(this, m_pConfig, pPlayerManager));
@@ -107,8 +108,16 @@ Library::Library(
m_pCrateFeature = new CrateFeature(this, m_pConfig);
addFeature(m_pCrateFeature);
#ifdef __ENGINEPRIME__
- connect(m_pCrateFeature, &CrateFeature::exportAllCrates, this, &Library::exportLibrary);
- connect(m_pCrateFeature, &CrateFeature::exportCrate, this, &Library::exportCrate);
+ connect(m_pCrateFeature,
+ &CrateFeature::exportAllCrates,
+ this,
+ &Library::exportLibrary,
+ Qt::DirectConnection);
+ connect(m_pCrateFeature,
+ &CrateFeature::exportCrate,
+ this,
+ &Library::exportCrate,
+ Qt::DirectConnection);
#endif
BrowseFeature* browseFeature = new BrowseFeature(
@@ -578,8 +587,6 @@ void Library::searchTracksInCollection(const QString& query) {
#ifdef __ENGINEPRIME__
std::unique_ptr<mixxx::LibraryExporter> Library::makeLibraryExporter(
QWidget* parent) {
- // New object is expected to be owned (and lifecycle-managed)
- // by the supplied parent widget.
return std::make_unique<mixxx::LibraryExporter>(
parent, m_pConfig, m_pTrackCollectionManager);
}
diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp
index 00cb7652b0..0c845ff47b 100644
--- a/src/library/mixxxlibraryfeature.cpp
+++ b/src/library/mixxxlibraryfeature.cpp
@@ -119,7 +119,7 @@ MixxxLibraryFeature::MixxxLibraryFeature(Library* pLibrary,
connect(m_pExportLibraryAction.get(),
&QAction::triggered,
this,
- &MixxxLibraryFeature::slotExportLibrary);
+ &MixxxLibraryFeature::exportLibrary);
#endif
}
@@ -218,8 +218,4 @@ void MixxxLibraryFeature::onRightClick(const QPoint& globalPos) {
menu.addAction(m_pExportLibraryAction.get());
menu.exec(globalPos);
}
-
-void MixxxLibraryFeature::slotExportLibrary() {
- emit exportLibrary();
-}
#endif
diff --git a/src/library/mixxxlibraryfeature.h b/src/library/mixxxlibraryfeature.h
index b65751f090..87b8823772 100644
--- a/src/library/mixxxlibraryfeature.h
+++ b/src/library/mixxxlibraryfeature.h
@@ -64,10 +64,8 @@ class MixxxLibraryFeature final : public LibraryFeature {
#ifdef __ENGINEPRIME__
signals:
+ /// Inform that a request has been made to export the whole Mixxx library.
void exportLibrary();
-
- private slots:
- void slotExportLibrary();
#endif
private:
diff --git a/src/library/trackset/crate/cratefeature.cpp b/src/library/trackset/crate/cratefeature.cpp
index 5ce069acb8..06c01ab6d1 100644
--- a/src/library/trackset/crate/cratefeature.cpp
+++ b/src/library/trackset/crate/cratefeature.cpp
@@ -121,12 +121,17 @@ void CrateFeature::initActions() {
connect(m_pExportAllCratesAction.get(),
&QAction::triggered,
this,
- &CrateFeature::slotExportAllCrates);
+ &CrateFeature::exportAllCrates);
m_pExportCrateAction = make_parented<QAction>(tr("Export to Engine Prime"), this);
connect(m_pExportCrateAction.get(),
&QAction::triggered,
this,
- &CrateFeature::slotExportCrate);
+ [this]() {
+ CrateId crateId = crateIdFromIndex(m_lastRightClickedIndex);
+ if (crateId.isValid()) {
+ emit exportCrate(crateId);
+ }
+ });
#endif
}
@@ -833,20 +838,3 @@ void CrateFeature::slotTrackSelected(TrackPointer pTrack) {
void CrateFeature::slotResetSelectedTrack() {
slotTrackSelected(TrackPointer());
}
-
-#ifdef __ENGINEPRIME__
-void CrateFeature::slotExportAllCrates() {
- emit exportAllCrates();
-}
-
-void CrateFeature::slotExportCrate() {
- if (!m_lastRightClickedIndex.isValid()) {
- return;
- }
-
- CrateId crateId = crateIdFromIndex(m_lastRightClickedIndex);
- if (crateId.isValid()) {
- emit exportCrate(crateId);
- }
-}
-#endif
diff --git a/src/library/trackset/crate/cratefeature.h b/src/library/trackset/crate/cratefeature.h
index 1d5bb2bdcb..1de4bbc4d3 100644
--- a/src/library/trackset/crate/cratefeature.h
+++ b/src/library/trackset/crate/cratefeature.h
@@ -65,10 +65,6 @@ class CrateFeature : public BaseTrackSetFeature {
void slotExportPlaylist();
// Copy all of the tracks in a crate to a new directory (like a thumbdrive).
void slotExportTrackFiles();
-#ifdef __ENGINEPRIME__
- void slotExportAllCrates();
- void slotExportCrate();
-#endif
void slotAnalyzeCrate();
void slotCrateTableChanged(CrateId crateId);
void slotCrateContentChanged(CrateId crateId);
diff --git a/src/mixxx.cpp b/src/mixxx.cpp
index d4eee13f5b..04b4f55328 100644
--- a/src/mixxx.cpp
+++ b/src/mixxx.cpp
@@ -146,9 +146,6 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args)
m_pLibrary(nullptr),
m_pDeveloperToolsDlg(nullptr),
m_pPrefDlg(nullptr),
-#ifdef __ENGINEPRIME__
- m_pLibraryExporter(nullptr),
-#endif
m_pKbdConfig(nullptr),
m_pKbdConfigEmpty(nullptr),
m_toolTipsCfg(mixxx::TooltipsPreference::TOOLTIPS_ON),
@@ -480,11 +477,11 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) {
connect(m_pLibrary,
&Library::exportLibrary,
m_pLibraryExporter.get(),
- &mixxx::LibraryExporter::requestExport);
+ &mixxx::LibraryExporter::slotRequestExport);
connect(m_pLibrary,
&Library::exportCrate,
m_pLibraryExporter.get(),
- &mixxx::LibraryExporter::requestExportWithInitialCrate);
+ &mixxx::LibraryExporter::slotRequestExportWithInitialCrate);
#endif
launchProgress(60);
@@ -750,7 +747,7 @@ void MixxxMainWindow::finalize() {
#ifdef __ENGINEPRIME__
qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting LibraryExporter";
- m_pLibraryExporter = nullptr; // is a unique_ptr
+ m_pLibraryExporter.reset();
#endif
// Delete the library after the view so there are no dangling pointers to
@@ -1239,9 +1236,9 @@ void MixxxMainWindow::connectMenuBar() {
#ifdef __ENGINEPRIME__
if (m_pLibraryExporter) {
connect(m_pMenuBar,
- SIGNAL(exportLibrary()),
+ &WMainMenuBar::exportLibrary,
m_pLibraryExporter.get(),
- SLOT(requestExport()));
+ &mixxx::LibraryExporter::slotRequestExport);
}
#endif
}