Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 37 additions & 25 deletions src/mixer/playermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,30 @@ bool extractIntFromRegex(const QRegularExpression& regex, const QString& group,
return true;
}

/// Returns the first object from a list of `BaseTrackPlayer` instances where
/// the corresponding `play` CO is set to 0.
template<class T>
T* findFirstStoppedPlayerInList(const QList<T*>& players) {
for (T* pPlayer : players) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be const if BasePlayer::getGroup() was const (which it should be IMO).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean this?

Suggested change
for (T* pPlayer : players) {
for (const T* pPlayer : players) {

This does not work, because in that case the return type would also have to be const. This would severly limit what you can do with the result (or you'd need to use const_cast which I consider a terrible hack).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I didn't think about that. LGTM me then.

VERIFY_OR_DEBUG_ASSERT(pPlayer != nullptr) {
continue;
}

ControlObject* pPlayControl = ControlObject::getControl(
ConfigKey(pPlayer->getGroup(), "play"));
VERIFY_OR_DEBUG_ASSERT(pPlayControl != nullptr) {
continue;
}

if (!pPlayControl->toBool()) {
return pPlayer;
}
}

// There is no stopped player in the list.
return nullptr;
}

} // anonymous namespace

//static
Expand Down Expand Up @@ -658,37 +682,25 @@ void PlayerManager::slotLoadToSampler(const QString& location, int sampler) {

void PlayerManager::slotLoadTrackIntoNextAvailableDeck(TrackPointer pTrack) {
auto locker = lockMutex(&m_mutex);
QList<Deck*>::iterator it = m_decks.begin();
while (it != m_decks.end()) {
Deck* pDeck = *it;
ControlObject* playControl =
ControlObject::getControl(ConfigKey(pDeck->getGroup(), "play"));
if (playControl && playControl->get() != 1.) {
locker.unlock();
pDeck->slotLoadTrack(pTrack, false);
// Test for a fixed race condition with fast loads
//SleepableQThread::sleep(1);
//pDeck->slotLoadTrack(TrackPointer(), false);
return;
}
++it;
BaseTrackPlayer* pDeck = findFirstStoppedPlayerInList(m_decks);
if (pDeck == nullptr) {
qDebug() << "PlayerManager: No stopped deck found, not loading track!";
return;
}

pDeck->slotLoadTrack(pTrack, false);
}

void PlayerManager::slotLoadTrackIntoNextAvailableSampler(TrackPointer pTrack) {
auto locker = lockMutex(&m_mutex);
QList<Sampler*>::iterator it = m_samplers.begin();
while (it != m_samplers.end()) {
Sampler* pSampler = *it;
ControlObject* playControl =
ControlObject::getControl(ConfigKey(pSampler->getGroup(), "play"));
if (playControl && playControl->get() != 1.) {
locker.unlock();
pSampler->slotLoadTrack(pTrack, false);
return;
}
++it;
BaseTrackPlayer* pSampler = findFirstStoppedPlayerInList(m_samplers);
if (pSampler == nullptr) {
qDebug() << "PlayerManager: No stopped sampler found, not loading track!";
return;
}
locker.unlock();

pSampler->slotLoadTrack(pTrack, false);
}

void PlayerManager::slotAnalyzeTrack(TrackPointer track) {
Expand Down