Skip to content

Commit

Permalink
Merge pull request #2365 from uklotzde/dev_library
Browse files Browse the repository at this point in the history
Extract TrackCollectionManager from Library
  • Loading branch information
daschuer authored Dec 8, 2019
2 parents 9b5f544 + fff663a commit d31c18b
Show file tree
Hide file tree
Showing 109 changed files with 1,964 additions and 1,466 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/errordialoghandler.cpp
src/library/analysisfeature.cpp
src/library/analysislibrarytablemodel.cpp
src/library/trackloader.cpp
src/library/autodj/autodjfeature.cpp
src/library/autodj/autodjprocessor.cpp
src/library/autodj/dlgautodj.cpp
Expand Down Expand Up @@ -401,6 +402,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/library/starrating.cpp
src/library/tableitemdelegate.cpp
src/library/trackcollection.cpp
src/library/trackcollectionmanager.cpp
src/library/traktor/traktorfeature.cpp
src/library/treeitem.cpp
src/library/treeitemmodel.cpp
Expand Down
3 changes: 3 additions & 0 deletions build/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,7 @@ def sources(self, build):
"src/database/schemamanager.cpp",

"src/library/trackcollection.cpp",
"src/library/trackcollectionmanager.cpp",
"src/library/externaltrackcollection.cpp",
"src/library/basesqltablemodel.cpp",
"src/library/basetrackcache.cpp",
Expand Down Expand Up @@ -1112,6 +1113,8 @@ def sources(self, build):
"src/library/parserm3u.cpp",
"src/library/parsercsv.cpp",

"src/library/trackloader.cpp",

"src/widget/wwaveformviewer.cpp",

"src/waveform/sharedglcontext.cpp",
Expand Down
2 changes: 1 addition & 1 deletion src/analyzer/analyzerthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ AnalyzerThread::AnalyzerThread(
: WorkerThread(QString("AnalyzerThread %1").arg(id)),
m_id(id),
m_dbConnectionPool(std::move(dbConnectionPool)),
m_pConfig(std::move(pConfig)),
m_pConfig(pConfig),
m_modeFlags(modeFlags),
m_nextTrack(2), // minimum capacity
m_sampleBuffer(mixxx::kAnalysisSamplesPerChunk),
Expand Down
2 changes: 1 addition & 1 deletion src/analyzer/trackanalysisscheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ bool TrackAnalysisScheduler::submitNextTrack(Worker* worker) {
DEBUG_ASSERT(nextTrackId.isValid());
if (nextTrackId.isValid()) {
TrackPointer nextTrack =
m_library->trackCollection().getTrackDAO().getTrack(nextTrackId);
m_library->trackCollection().getTrackById(nextTrackId);
if (nextTrack) {
if (m_pendingTrackIds.insert(nextTrackId).second) {
if (worker->submitNextTrack(std::move(nextTrack))) {
Expand Down
159 changes: 89 additions & 70 deletions src/library/analysisfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@
#include "sources/soundsourceproxy.h"
#include "util/dnd.h"
#include "util/debug.h"

const QString AnalysisFeature::m_sAnalysisViewName = QString("Analysis");
#include "util/logger.h"

namespace {

const mixxx::Logger kLogger("AnalysisFeature");

const QString kViewName = QStringLiteral("Analysis");

// Utilize all available cores for batch analysis of tracks
const int kNumberOfAnalyzerThreads = math_max(1, QThread::idealThreadCount());

inline
int numberOfAnalyzerThreads() {
return kNumberOfAnalyzerThreads;
}

inline
AnalyzerModeFlags getAnalyzerModeFlags(
const UserSettingsPointer& pConfig) {
Expand All @@ -42,50 +50,34 @@ AnalyzerModeFlags getAnalyzerModeFlags(
} // anonymous namespace

AnalysisFeature::AnalysisFeature(
Library* parent,
Library* pLibrary,
UserSettingsPointer pConfig)
: LibraryFeature(parent),
m_library(parent),
m_pConfig(pConfig),
: LibraryFeature(pLibrary, pConfig),
m_baseTitle(tr("Analyze")),
m_icon(":/images/library/ic_library_prepare.svg"),
m_pTrackAnalysisScheduler(TrackAnalysisScheduler::NullPointer()),
m_analysisTitleName(tr("Analyze")),
m_pAnalysisView(nullptr),
m_icon(":/images/library/ic_library_prepare.svg") {
setTitleDefault();
m_title(m_baseTitle) {
}

void AnalysisFeature::stop() {
if (m_pTrackAnalysisScheduler) {
m_pTrackAnalysisScheduler->stop();
}
}

void AnalysisFeature::setTitleDefault() {
m_Title = m_analysisTitleName;
emit(featureIsLoading(this, false));
void AnalysisFeature::resetTitle() {
m_title = m_baseTitle;
emit featureIsLoading(this, false);
}

void AnalysisFeature::setTitleProgress(int currentTrackNumber, int totalTracksCount) {
m_Title = QString("%1 (%2 / %3)")
.arg(m_analysisTitleName)
m_title = QString("%1 (%2 / %3)")
.arg(m_baseTitle)
.arg(QString::number(currentTrackNumber))
.arg(QString::number(totalTracksCount));
emit(featureIsLoading(this, false));
}

QVariant AnalysisFeature::title() {
return m_Title;
}

QIcon AnalysisFeature::getIcon() {
return m_icon;
emit featureIsLoading(this, false);
}

void AnalysisFeature::bindLibraryWidget(WLibrary* libraryWidget,
KeyboardEventFilter* keyboard) {
m_pAnalysisView = new DlgAnalysis(libraryWidget,
m_pConfig,
m_library);
m_pLibrary);
connect(m_pAnalysisView,
&DlgAnalysis::loadTrack,
this,
Expand Down Expand Up @@ -120,7 +112,7 @@ void AnalysisFeature::bindLibraryWidget(WLibrary* libraryWidget,
// Let the DlgAnalysis know whether or not analysis is active.
emit(analysisActive(static_cast<bool>(m_pTrackAnalysisScheduler)));

libraryWidget->registerView(m_sAnalysisViewName, m_pAnalysisView);
libraryWidget->registerView(kViewName, m_pAnalysisView);
}

TreeItemModel* AnalysisFeature::getChildModel() {
Expand All @@ -135,36 +127,73 @@ void AnalysisFeature::refreshLibraryModels() {

void AnalysisFeature::activate() {
//qDebug() << "AnalysisFeature::activate()";
emit(switchToView(m_sAnalysisViewName));
emit switchToView(kViewName);
if (m_pAnalysisView) {
emit(restoreSearch(m_pAnalysisView->currentSearch()));
emit restoreSearch(m_pAnalysisView->currentSearch());
}
emit(enableCoverArtDisplay(true));
emit enableCoverArtDisplay(true);
}

void AnalysisFeature::analyzeTracks(QList<TrackId> trackIds) {
if (!m_pTrackAnalysisScheduler) {
const int numAnalyzerThreads = numberOfAnalyzerThreads();
kLogger.info()
<< "Starting analysis using"
<< numAnalyzerThreads
<< "analyzer threads";
m_pTrackAnalysisScheduler = TrackAnalysisScheduler::createInstance(
m_library,
kNumberOfAnalyzerThreads,
m_pLibrary,
numAnalyzerThreads,
m_pConfig,
getAnalyzerModeFlags(m_pConfig));

connect(m_pTrackAnalysisScheduler.get(), &TrackAnalysisScheduler::progress,
m_pAnalysisView, &DlgAnalysis::onTrackAnalysisSchedulerProgress);
connect(m_pTrackAnalysisScheduler.get(), &TrackAnalysisScheduler::finished,
m_pAnalysisView, &DlgAnalysis::onTrackAnalysisSchedulerFinished);
connect(m_pTrackAnalysisScheduler.get(), &TrackAnalysisScheduler::progress,
this, &AnalysisFeature::onTrackAnalysisSchedulerProgress);
connect(m_pTrackAnalysisScheduler.get(), &TrackAnalysisScheduler::finished,
this, &AnalysisFeature::stopAnalysis);

emit(analysisActive(true));
connect(m_pTrackAnalysisScheduler.get(),
&TrackAnalysisScheduler::progress,
m_pAnalysisView,
&DlgAnalysis::onTrackAnalysisSchedulerProgress);
connect(m_pTrackAnalysisScheduler.get(),
&TrackAnalysisScheduler::finished,
m_pAnalysisView,
&DlgAnalysis::onTrackAnalysisSchedulerFinished);
connect(m_pTrackAnalysisScheduler.get(),
&TrackAnalysisScheduler::progress,
this,
&AnalysisFeature::onTrackAnalysisSchedulerProgress);
connect(m_pTrackAnalysisScheduler.get(),
&TrackAnalysisScheduler::finished,
this,
&AnalysisFeature::onTrackAnalysisSchedulerFinished);

emit analysisActive(true);
}

if (m_pTrackAnalysisScheduler->scheduleTracksById(trackIds) > 0) {
m_pTrackAnalysisScheduler->resume();
resumeAnalysis();
}
}

void AnalysisFeature::suspendAnalysis() {
if (!m_pTrackAnalysisScheduler) {
return; // inactive
}
kLogger.info() << "Suspending analysis";
m_pTrackAnalysisScheduler->suspend();
}

void AnalysisFeature::resumeAnalysis() {
if (!m_pTrackAnalysisScheduler) {
return; // inactive
}
kLogger.info() << "Resuming analysis";
m_pTrackAnalysisScheduler->resume();
}

void AnalysisFeature::stopAnalysis() {
if (!m_pTrackAnalysisScheduler) {
return; // inactive
}
kLogger.info() << "Stopping analysis";
m_pTrackAnalysisScheduler->stop();
}

void AnalysisFeature::onTrackAnalysisSchedulerProgress(
Expand All @@ -173,31 +202,21 @@ void AnalysisFeature::onTrackAnalysisSchedulerProgress(
int totalTracksCount) {
// Ignore any delayed progress updates after the analysis
// has already been stopped.
if (m_pTrackAnalysisScheduler) {
if (totalTracksCount > 0) {
setTitleProgress(currentTrackNumber, totalTracksCount);
} else {
setTitleDefault();
}
if (!m_pTrackAnalysisScheduler) {
return; // inactive
}
}

void AnalysisFeature::suspendAnalysis() {
//qDebug() << this << "suspendAnalysis";
if (m_pTrackAnalysisScheduler) {
m_pTrackAnalysisScheduler->suspend();
if (totalTracksCount > 0) {
setTitleProgress(currentTrackNumber, totalTracksCount);
} else {
resetTitle();
}
}

void AnalysisFeature::resumeAnalysis() {
//qDebug() << this << "resumeAnalysis";
if (m_pTrackAnalysisScheduler) {
m_pTrackAnalysisScheduler->resume();
void AnalysisFeature::onTrackAnalysisSchedulerFinished() {
if (!m_pTrackAnalysisScheduler) {
return; // already inactive
}
}

void AnalysisFeature::stopAnalysis() {
//qDebug() << this << "stopAnalysis()";
kLogger.info() << "Finishing analysis";
if (m_pTrackAnalysisScheduler) {
// Free resources by abandoning the queue after the batch analysis
// has completed. Batch analysis are not started very frequently
Expand All @@ -206,12 +225,12 @@ void AnalysisFeature::stopAnalysis() {
// for creating the queue with its worker threads are acceptable.
m_pTrackAnalysisScheduler.reset();
}
setTitleDefault();
emit(analysisActive(false));
resetTitle();
emit analysisActive(false);
}

bool AnalysisFeature::dropAccept(QList<QUrl> urls, QObject* pSource) {
QList<TrackId> trackIds = m_library->trackCollection().resolveTrackIdsFromUrls(urls,
QList<TrackId> trackIds = m_pLibrary->trackCollection().resolveTrackIdsFromUrls(urls,
!pSource);
analyzeTracks(trackIds);
return trackIds.size() > 0;
Expand Down
29 changes: 15 additions & 14 deletions src/library/analysisfeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@
#include "analyzer/trackanalysisscheduler.h"
#include "preferences/usersettings.h"

class Library;
class TrackCollection;

class AnalysisFeature : public LibraryFeature {
Q_OBJECT
public:
AnalysisFeature(Library* parent,
AnalysisFeature(Library* pLibrary,
UserSettingsPointer pConfig);
~AnalysisFeature() override = default;

void stop();
QVariant title() override {
return m_title;
}

QVariant title() override;
QIcon getIcon() override;
QIcon getIcon() override {
return m_icon;
}

bool dropAccept(QList<QUrl> urls, QObject* pSource) override;
bool dragMoveAccept(QUrl url) override;
Expand All @@ -50,33 +52,32 @@ class AnalysisFeature : public LibraryFeature {

void suspendAnalysis();
void resumeAnalysis();
void stopAnalysis();

private slots:
void onTrackAnalysisSchedulerProgress(AnalyzerProgress currentTrackProgress, int currentTrackNumber, int totalTracksCount);
void stopAnalysis();
void onTrackAnalysisSchedulerFinished();

private:
// Sets the title of this feature to the default name, given by
// m_sAnalysisTitleName
void setTitleDefault();
void resetTitle();

// Sets the title of this feature to the default name followed by (x / y)
// where x is the current track being analyzed and y is the total number of
// tracks in the job
void setTitleProgress(int currentTrackNumber, int totalTracksCount);

Library* m_library;
const QString m_baseTitle;
const QIcon m_icon;

UserSettingsPointer m_pConfig;
TrackAnalysisScheduler::Pointer m_pTrackAnalysisScheduler;

// The title returned by title()
QVariant m_Title;
TreeItemModel m_childModel;
const static QString m_sAnalysisViewName;
QString m_analysisTitleName;
DlgAnalysis* m_pAnalysisView;
QIcon m_icon;

// The title is dynamic and reflects the current progress
QString m_title;
};


Expand Down
16 changes: 6 additions & 10 deletions src/library/analysislibrarytablemodel.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
#include <QObject>
#include "library/analysislibrarytablemodel.h"

#include "analysislibrarytablemodel.h"
#include "library/trackcollection.h"
namespace {

const QString RECENT_FILTER = "datetime_added > datetime('now', '-7 days')";

} // anonymous namespace

AnalysisLibraryTableModel::AnalysisLibraryTableModel(QObject* parent,
TrackCollection* pTrackCollection)
: LibraryTableModel(parent, pTrackCollection,
TrackCollectionManager* pTrackCollectionManager)
: LibraryTableModel(parent, pTrackCollectionManager,
"mixxx.db.model.prepare") {
// Default to showing recent tracks.
setSearch("", RECENT_FILTER);
}


AnalysisLibraryTableModel::~AnalysisLibraryTableModel() {
}


void AnalysisLibraryTableModel::showRecentSongs() {
// Search with the recent filter.
search(currentSearch(), RECENT_FILTER);
Expand Down
Loading

0 comments on commit d31c18b

Please sign in to comment.