diff options
author | Adam Szmigin <smidge@xsco.net> | 2020-10-27 23:59:45 +0000 |
---|---|---|
committer | Adam Szmigin <smidge@xsco.net> | 2020-10-28 22:44:29 +0000 |
commit | bfd84d05cccdeb7e060768db3d6af2938f7a84aa (patch) | |
tree | 2c9e2b44b0a7c8629a9fe006373fa58407bbe532 | |
parent | 1148154fb71213965a9b0efab9c616e97b355668 (diff) |
All djinterop exceptions caught, further cleanuppr-2753
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/library/export/dlglibraryexport.cpp | 4 | ||||
-rw-r--r-- | src/library/export/engineprimeexportjob.cpp | 107 | ||||
-rw-r--r-- | src/library/export/engineprimeexportjob.h | 8 | ||||
-rw-r--r-- | src/library/export/libraryexporter.cpp | 46 | ||||
-rw-r--r-- | src/library/export/libraryexporter.h | 4 | ||||
-rw-r--r-- | src/library/library.cpp | 17 | ||||
-rw-r--r-- | src/library/mixxxlibraryfeature.cpp | 6 | ||||
-rw-r--r-- | src/library/mixxxlibraryfeature.h | 4 | ||||
-rw-r--r-- | src/library/trackset/crate/cratefeature.cpp | 26 | ||||
-rw-r--r-- | src/library/trackset/crate/cratefeature.h | 4 | ||||
-rw-r--r-- | src/mixxx.cpp | 13 |
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 } |