Skip to content

Commit

Permalink
move num functions to singleton PlayerInfo class, to get around stati…
Browse files Browse the repository at this point in the history
…c lifetime issues.
  • Loading branch information
daschuer committed Jan 2, 2025
1 parent e460466 commit 4c1560e
Show file tree
Hide file tree
Showing 14 changed files with 62 additions and 94 deletions.
3 changes: 2 additions & 1 deletion src/controllers/midi/midicontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "controllers/scripting/legacy/controllerscriptenginelegacy.h"
#include "defs_urls.h"
#include "errordialoghandler.h"
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#include "moc_midicontroller.cpp"
#include "util/make_const_iterator.h"
Expand Down Expand Up @@ -145,7 +146,7 @@ void MidiController::createOutputHandlers() {
if (m_logBase().isDebugEnabled()) {
failures.append(errorLog);
} else if (PlayerManager::isDeckGroup(group, &deckNum)) {
int numDecks = PlayerManager::numDecks();
int numDecks = PlayerInfo::instance().numDecks();
if (deckNum <= numDecks) {
failures.append(errorLog);
}
Expand Down
3 changes: 2 additions & 1 deletion src/library/banshee/bansheeplaylistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "library/dao/trackschema.h"
#include "library/queryutil.h"
#include "library/trackcollectionmanager.h"
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#include "moc_bansheeplaylistmodel.cpp"
#include "track/track.h"
Expand Down Expand Up @@ -363,6 +364,6 @@ QString BansheePlaylistModel::getTrackLocation(const QModelIndex& index) const {

bool BansheePlaylistModel::isColumnInternal(int column) {
return (column == fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_TRACKID) ||
(PlayerManager::numPreviewDecks() == 0 &&
(PlayerInfo::instance().numPreviewDecks() == 0 &&
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW)));
}
3 changes: 2 additions & 1 deletion src/library/baseexternalplaylistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "library/queryutil.h"
#include "library/trackcollection.h"
#include "library/trackcollectionmanager.h"
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#include "moc_baseexternalplaylistmodel.cpp"
#include "track/track.h"
Expand Down Expand Up @@ -82,7 +83,7 @@ TrackId BaseExternalPlaylistModel::getTrackId(const QModelIndex& index) const {

bool BaseExternalPlaylistModel::isColumnInternal(int column) {
return column == fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_TRACKID) ||
(PlayerManager::numPreviewDecks() == 0 &&
(PlayerInfo::instance().numPreviewDecks() == 0 &&
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW));
}

Expand Down
3 changes: 2 additions & 1 deletion src/library/baseexternaltrackmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "library/dao/trackschema.h"
#include "library/queryutil.h"
#include "library/trackcollectionmanager.h"
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#include "moc_baseexternaltrackmodel.cpp"
#include "track/track.h"
Expand Down Expand Up @@ -110,7 +111,7 @@ TrackId BaseExternalTrackModel::doGetTrackId(const TrackPointer& pTrack) const {

bool BaseExternalTrackModel::isColumnInternal(int column) {
return column == fieldIndex(LIBRARYTABLE_ID) ||
(PlayerManager::numPreviewDecks() == 0 &&
(PlayerInfo::instance().numPreviewDecks() == 0 &&
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW));
}

Expand Down
2 changes: 1 addition & 1 deletion src/library/basetracktablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ QAbstractItemDelegate* BaseTrackTableModel::delegateForColumn(
return new BPMDelegate(pTableView);
} else if (index == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TIMESPLAYED)) {
return new CheckboxDelegate(pTableView, QStringLiteral("LibraryPlayedCheckbox"));
} else if (PlayerManager::numPreviewDecks() > 0 &&
} else if (PlayerInfo::instance().numPreviewDecks() > 0 &&
index == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW)) {
return new PreviewButtonDelegate(pTableView, index);
} else if (index == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMMENT)) {
Expand Down
2 changes: 1 addition & 1 deletion src/library/browse/browsetablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ bool BrowseTableModel::isColumnSortable(int column) const {
QAbstractItemDelegate* BrowseTableModel::delegateForColumn(const int i, QObject* pParent) {
WLibraryTableView* pTableView = qobject_cast<WLibraryTableView*>(pParent);
DEBUG_ASSERT(pTableView);
if (PlayerManager::numPreviewDecks() > 0 && i == COLUMN_PREVIEW) {
if (PlayerInfo::instance().numPreviewDecks() > 0 && i == COLUMN_PREVIEW) {
return new PreviewButtonDelegate(pTableView, i);
}
return nullptr;
Expand Down
8 changes: 4 additions & 4 deletions src/library/dao/autodjcratesdao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ bool AutoDJCratesDAO::updateAutoDjPlaylistReferences() {
// Incorporate all tracks loaded into decks.
// Each track has to be done as a separate database query, in case the same
// track is loaded into multiple decks.
int iDecks = PlayerManager::numDecks();
int iDecks = PlayerInfo::instance().numDecks();
for (int i = 0; i < iDecks; ++i) {
QString group = PlayerManager::groupForDeck(i);
TrackPointer pTrack = PlayerInfo::instance().getTrackInfo(group);
Expand Down Expand Up @@ -1103,7 +1103,7 @@ void AutoDJCratesDAO::playerInfoTrackLoaded(const QString& group,
}
// This counts as an auto-DJ reference. The idea is to prevent tracks that
// are loaded into a deck from being randomly chosen.
int numDecks = PlayerManager::numDecks();
int numDecks = PlayerInfo::instance().numDecks();
for (int i = 0; i < numDecks; ++i) {
if (group == PlayerManager::groupForDeck(i)) {
// Update the number of auto-DJ-playlist references to this track.
Expand Down Expand Up @@ -1131,8 +1131,8 @@ void AutoDJCratesDAO::playerInfoTrackUnloaded(const QString& group,
}
// This counts as an auto-DJ reference. The idea is to prevent tracks that
// are loaded into a deck from being randomly chosen.
unsigned int numDecks = PlayerManager::numDecks();
for (unsigned int i = 0; i < numDecks; ++i) {
int numDecks = PlayerInfo::instance().numDecks();
for (int i = 0; i < numDecks; ++i) {
if (group == PlayerManager::groupForDeck(i)) {
// Get rid of the ID of the track in this deck.
QSqlQuery oQuery(m_database);
Expand Down
3 changes: 2 additions & 1 deletion src/library/librarytablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "library/queryutil.h"
#include "library/trackcollection.h"
#include "library/trackcollectionmanager.h"
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#include "moc_librarytablemodel.cpp"

Expand Down Expand Up @@ -77,7 +78,7 @@ bool LibraryTableModel::isColumnInternal(int column) {
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM_LOCK) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_CHANNELS) ||
column == fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_FSDELETED) ||
(PlayerManager::numPreviewDecks() == 0 &&
(PlayerInfo::instance().numPreviewDecks() == 0 &&
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW)) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_SOURCE) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_TYPE) ||
Expand Down
3 changes: 2 additions & 1 deletion src/library/trackset/tracksettablemodel.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "library/trackset/tracksettablemodel.h"

#include "library/trackcollectionmanager.h"
#include "mixer/playerinfo.h"
#include "mixer/playermanager.h"
#include "moc_tracksettablemodel.cpp"

Expand All @@ -18,7 +19,7 @@ bool TrackSetTableModel::isColumnInternal(int column) {
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM_LOCK) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID) ||
column == fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_FSDELETED) ||
(PlayerManager::numPreviewDecks() == 0 &&
(PlayerInfo::instance().numPreviewDecks() == 0 &&
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PREVIEW)) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_SOURCE) ||
column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_TYPE) ||
Expand Down
24 changes: 21 additions & 3 deletions src/mixer/playerinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ constexpr int kPlayingDeckUpdateIntervalMillis = 2000;

PlayerInfo* s_pPlayerInfo = nullptr;

const QString kAppGroup = QStringLiteral("[App]");
const QString kMasterGroup = QStringLiteral("[Master]");

} // namespace

PlayerInfo::PlayerInfo()
: m_pCOxfader(new ControlProxy("[Master]","crossfader", this)),
: m_xfader(kMasterGroup, QStringLiteral("crossfader")),
m_numDecks(kAppGroup, QStringLiteral("num_decks")),
m_numSamplers(kAppGroup, QStringLiteral("num_samplers")),
m_numPreviewDecks(kAppGroup, QStringLiteral("num_preview_decks")),
m_currentlyPlayingDeck(-1) {
startTimer(kPlayingDeckUpdateIntervalMillis);
}
Expand Down Expand Up @@ -135,15 +141,15 @@ void PlayerInfo::updateCurrentPlayingDeck() {
CSAMPLE_GAIN xfl, xfr;
// TODO: supply correct parameters to the function. If the hamster style
// for the crossfader is enabled, the result is currently wrong.
EngineXfader::getXfadeGains(m_pCOxfader->get(),
EngineXfader::getXfadeGains(m_xfader.get(),
1.0,
0.0,
MIXXX_XFADER_ADDITIVE,
false,
&xfl,
&xfr);

for (int i = 0; i < PlayerManager::numDecks(); ++i) {
for (int i = 0; i < numDecks(); ++i) {
DeckControls* pDc = getDeckControls(i);

if (pDc->m_play.get() == 0.0) {
Expand Down Expand Up @@ -213,3 +219,15 @@ void PlayerInfo::clearControlCache() {
}
m_deckControlList.clear();
}

int PlayerInfo::numDecks() const {
return static_cast<int>(m_numDecks.get());
}

int PlayerInfo::numPreviewDecks() const {
return static_cast<int>(m_numSamplers.get());
}

int PlayerInfo::numSamplers() const {
return static_cast<int>(m_numPreviewDecks.get());
}
21 changes: 15 additions & 6 deletions src/mixer/playerinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <QMutex>
#include <QObject>

#include "control/controlproxy.h"
#include "control/pollingcontrolproxy.h"
#include "track/track_decl.h"

class PlayerInfo : public QObject {
Expand All @@ -24,6 +24,10 @@ class PlayerInfo : public QObject {
bool isTrackLoaded(const TrackPointer& pTrack) const;
bool isFileLoaded(const QString& track_location) const;

int numDecks() const;
int numPreviewDecks() const;
int numSamplers() const;

signals:
void currentPlayingDeckChanged(int deck);
void currentPlayingTrackChanged(TrackPointer pTrack);
Expand All @@ -39,10 +43,10 @@ class PlayerInfo : public QObject {
m_orientation(group, "orientation") {
}

ControlProxy m_play;
ControlProxy m_pregain;
ControlProxy m_volume;
ControlProxy m_orientation;
PollingControlProxy m_play;
PollingControlProxy m_pregain;
PollingControlProxy m_volume;
PollingControlProxy m_orientation;
};

void clearControlCache();
Expand All @@ -54,7 +58,12 @@ class PlayerInfo : public QObject {
~PlayerInfo() override;

mutable QMutex m_mutex;
ControlProxy* m_pCOxfader;

PollingControlProxy m_xfader;
PollingControlProxy m_numDecks;
PollingControlProxy m_numSamplers;
PollingControlProxy m_numPreviewDecks;

// QMap is faster than QHash for small count of elements < 50
QMap<QString, TrackPointer> m_loadedTrackMap;
QAtomicInt m_currentlyPlayingDeck;
Expand Down
66 changes: 0 additions & 66 deletions src/mixer/playermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,6 @@ inline QString getDefaultSamplerPath(UserSettingsPointer pConfig) {

} // anonymous namespace

//static
QAtomicPointer<ControlProxy> PlayerManager::m_pCOPNumDecks;
//static
QAtomicPointer<ControlProxy> PlayerManager::m_pCOPNumSamplers;
//static
QAtomicPointer<ControlProxy> PlayerManager::m_pCOPNumPreviewDecks;

PlayerManager::PlayerManager(UserSettingsPointer pConfig,
SoundManager* pSoundManager,
EffectsManager* pEffectsManager,
Expand Down Expand Up @@ -159,10 +152,6 @@ PlayerManager::~PlayerManager() {
m_microphones.clear();
m_auxiliaries.clear();

delete m_pCOPNumDecks.fetchAndStoreAcquire(nullptr);
delete m_pCOPNumSamplers.fetchAndStoreAcquire(nullptr);
delete m_pCOPNumPreviewDecks.fetchAndStoreAcquire(nullptr);

if (m_pTrackAnalysisScheduler) {
m_pTrackAnalysisScheduler->stop();
m_pTrackAnalysisScheduler.reset();
Expand Down Expand Up @@ -243,61 +232,6 @@ bool PlayerManager::isPreviewDeckGroup(const QString& group, int* number) {
return extractIntFromRegex(kPreviewDeckRegex, group, number);
}

// static
int PlayerManager::numDecks() {
// We do this to cache the control once it is created so callers don't incur
// a hashtable lookup every time they call this.
ControlProxy* pCOPNumDecks = atomicLoadRelaxed(m_pCOPNumDecks);
if (pCOPNumDecks == nullptr) {
pCOPNumDecks = new ControlProxy(ConfigKey(kAppGroup, QStringLiteral("num_decks")));
if (!pCOPNumDecks->valid()) {
delete pCOPNumDecks;
pCOPNumDecks = nullptr;
} else {
m_pCOPNumDecks = pCOPNumDecks;
}
}
// m_pCOPNumDecks->get() fails on MacOs
return pCOPNumDecks ? static_cast<int>(pCOPNumDecks->get()) : 0;
}

// static
int PlayerManager::numSamplers() {
// We do this to cache the control once it is created so callers don't incur
// a hashtable lookup every time they call this.
ControlProxy* pCOPNumSamplers = atomicLoadRelaxed(m_pCOPNumSamplers);
if (pCOPNumSamplers == nullptr) {
pCOPNumSamplers = new ControlProxy(ConfigKey(kAppGroup, QStringLiteral("num_samplers")));
if (!pCOPNumSamplers->valid()) {
delete pCOPNumSamplers;
pCOPNumSamplers = nullptr;
} else {
m_pCOPNumSamplers = pCOPNumSamplers;
}
}
// m_pCOPNumSamplers->get() fails on MacOs
return pCOPNumSamplers ? static_cast<int>(pCOPNumSamplers->get()) : 0;
}

// static
int PlayerManager::numPreviewDecks() {
// We do this to cache the control once it is created so callers don't incur
// a hashtable lookup every time they call this.
ControlProxy* pCOPNumPreviewDecks = atomicLoadRelaxed(m_pCOPNumPreviewDecks);
if (pCOPNumPreviewDecks == nullptr) {
pCOPNumPreviewDecks = new ControlProxy(
ConfigKey(kAppGroup, QStringLiteral("num_preview_decks")));
if (!pCOPNumPreviewDecks->valid()) {
delete pCOPNumPreviewDecks;
pCOPNumPreviewDecks = nullptr;
} else {
m_pCOPNumPreviewDecks = pCOPNumPreviewDecks;
}
}
// m_pCOPNumPreviewDecks->get() fails on MacOs
return pCOPNumPreviewDecks ? static_cast<int>(pCOPNumPreviewDecks->get()) : 0;
}

void PlayerManager::slotChangeNumDecks(double v) {
const auto locker = lockMutex(&m_mutex);
int num = (int)v;
Expand Down
7 changes: 0 additions & 7 deletions src/mixer/playermanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,16 @@ class PlayerManager : public QObject, public PlayerManagerInterface {
BaseTrackPlayer* getDeckBase(int deckIndex) const override;

// Return the number of players. Thread-safe.
static int numDecks();
int numberOfDecks() const override;

// Get the preview deck by its index.
PreviewDeck* getPreviewDeck(int previewDeckIndex) const override;
// Return the number of preview decks. Thread-safe.
static int numPreviewDecks();
int numberOfPreviewDecks() const override;

// Get the sampler by its index.
Sampler* getSampler(int samplerIndex) const override;
// Return the number of samplers. Thread-safe.
static int numSamplers();
int numberOfSamplers() const override;

// Returns the track that was last ejected or unloaded. Can return nullptr or
Expand Down Expand Up @@ -175,10 +172,6 @@ class PlayerManager : public QObject, public PlayerManagerInterface {
return QStringLiteral("[Auxiliary") + QString::number(i + 1) + ']';
}

static QAtomicPointer<ControlProxy> m_pCOPNumDecks;
static QAtomicPointer<ControlProxy> m_pCOPNumSamplers;
static QAtomicPointer<ControlProxy> m_pCOPNumPreviewDecks;

public slots:
// Slots for loading tracks into a Player, which is either a Sampler or a Deck
void slotLoadTrackToPlayer(TrackPointer pTrack, const QString& group, bool play);
Expand Down
8 changes: 8 additions & 0 deletions src/test/signalpathtest.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ class BaseSignalPathTest : public MixxxTest, SoundSourceProviderRegistration {
m_pChannelHandleFactory = std::make_shared<ChannelHandleFactory>();
m_pNumDecks = new ControlObject(ConfigKey(
QStringLiteral("[App]"), QStringLiteral("num_decks")));
m_pNumSamplers = new ControlObject(ConfigKey(
QStringLiteral("[App]"), QStringLiteral("num_samplers")));
m_pNumPreviewDecks = new ControlObject(ConfigKey(
QStringLiteral("[App]"), QStringLiteral("num_preview_decks")));
m_pEffectsManager = new EffectsManager(config(), m_pChannelHandleFactory);
m_pEngineMixer = new TestEngineMixer(m_pConfig,
m_sMainGroup,
Expand Down Expand Up @@ -139,6 +143,8 @@ class BaseSignalPathTest : public MixxxTest, SoundSourceProviderRegistration {
delete m_pEngineMixer;
delete m_pEffectsManager;
delete m_pNumDecks;
delete m_pNumSamplers;
delete m_pNumPreviewDecks;
PlayerInfo::destroy();
}

Expand Down Expand Up @@ -242,6 +248,8 @@ class BaseSignalPathTest : public MixxxTest, SoundSourceProviderRegistration {

ChannelHandleFactoryPointer m_pChannelHandleFactory;
ControlObject* m_pNumDecks;
ControlObject* m_pNumSamplers;
ControlObject* m_pNumPreviewDecks;
std::unique_ptr<mixxx::ControlIndicatorTimer> m_pControlIndicatorTimer;
EffectsManager* m_pEffectsManager;
EngineSync* m_pEngineSync;
Expand Down

0 comments on commit 4c1560e

Please sign in to comment.