Skip to content

Commit

Permalink
Merge pull request #12657 from ronso0/samplers-dont-create-extra-empt…
Browse files Browse the repository at this point in the history
…y-players

Samplers: dont create extra empty players during startup
  • Loading branch information
daschuer authored Feb 6, 2024
2 parents f04df4b + 5a5d206 commit f0587b8
Show file tree
Hide file tree
Showing 10 changed files with 502 additions and 377 deletions.
712 changes: 386 additions & 326 deletions src/controllers/controlpickermenu.cpp

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion src/controllers/dlgprefcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ DlgPrefController::DlgPrefController(
// Create text color for the file and wiki links
createLinkColor();

m_pControlPickerMenu = new ControlPickerMenu(this);
m_pControlPickerMenu = make_parented<ControlPickerMenu>(this);

initTableView(m_ui.m_pInputMappingTableView);
initTableView(m_ui.m_pOutputMappingTableView);
Expand Down Expand Up @@ -169,6 +169,10 @@ DlgPrefController::DlgPrefController(
DlgPrefController::~DlgPrefController() {
}

void DlgPrefController::slotRecreateControlPickerMenu() {
m_pControlPickerMenu = make_parented<ControlPickerMenu>(this);
}

void DlgPrefController::showLearningWizard() {
if (isDirty()) {
QMessageBox::StandardButton result = QMessageBox::question(this,
Expand Down
14 changes: 8 additions & 6 deletions src/controllers/dlgprefcontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
#include "controllers/ui_dlgprefcontrollerdlg.h"
#include "preferences/dialog/dlgpreferencepage.h"
#include "preferences/usersettings.h"
#include "util/parented_ptr.h"

// Forward declarations
class Controller;
class ControllerManager;
class MappingInfoEnumerator;
class ControlPickerMenu;
class DlgControllerLearning;
class ControllerInputMappingTableModel;
class ControllerMappingTableProxyModel;
class ControllerManager;
class ControllerOutputMappingTableModel;
class ControllerMappingTableProxyModel;
class ControlPickerMenu;
class DlgControllerLearning;
class MappingInfoEnumerator;

/// Configuration dialog for a single DJ controller
class DlgPrefController : public DlgPreferencePage {
Expand All @@ -40,6 +40,8 @@ class DlgPrefController : public DlgPreferencePage {
/// Called when the user clicks the global "Reset to Defaults" button.
void slotResetToDefaults() override;

void slotRecreateControlPickerMenu();

signals:
void applyMapping(Controller* pController,
std::shared_ptr<LegacyControllerMapping> pMapping,
Expand Down Expand Up @@ -119,7 +121,7 @@ class DlgPrefController : public DlgPreferencePage {
const QString m_pUserDir;
std::shared_ptr<ControllerManager> m_pControllerManager;
Controller* m_pController;
ControlPickerMenu* m_pControlPickerMenu;
parented_ptr<ControlPickerMenu> m_pControlPickerMenu;
DlgControllerLearning* m_pDlgControllerLearning;
std::shared_ptr<LegacyControllerMapping> m_pMapping;
QMap<QString, bool> m_pOverwriteMappings;
Expand Down
16 changes: 15 additions & 1 deletion src/controllers/dlgprefcontrollers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <QDesktopServices>

#include "control/controlproxy.h"
#include "controllers/controller.h"
#include "controllers/controllermanager.h"
#include "controllers/defs_controllers.h"
Expand All @@ -11,6 +12,10 @@
#include "preferences/dialog/dlgpreferences.h"
#include "util/string.h"

namespace {
const QString kAppGroup = QStringLiteral("[App]");
} // namespace

DlgPrefControllers::DlgPrefControllers(DlgPreferences* pPreferences,
UserSettingsPointer pConfig,
std::shared_ptr<ControllerManager> pControllerManager,
Expand All @@ -19,7 +24,11 @@ DlgPrefControllers::DlgPrefControllers(DlgPreferences* pPreferences,
m_pDlgPreferences(pPreferences),
m_pConfig(pConfig),
m_pControllerManager(pControllerManager),
m_pControllersRootItem(pControllersRootItem) {
m_pControllersRootItem(pControllersRootItem),
m_pNumDecks(make_parented<ControlProxy>(
kAppGroup, QStringLiteral("num_decks"), this)),
m_pNumSamplers(make_parented<ControlProxy>(
kAppGroup, QStringLiteral("num_samplers"), this)) {
setupUi(this);
// Create text color for the cue mode link "?" to the manual
createLinkColor();
Expand Down Expand Up @@ -178,6 +187,11 @@ void DlgPrefControllers::setupControllerWidgets() {
&DlgPrefController::mappingEnded,
m_pDlgPreferences,
&DlgPreferences::show);
// Recreate the control picker menus when decks or samplers are added
m_pNumDecks->connectValueChanged(pControllerDlg,
&DlgPrefController::slotRecreateControlPickerMenu);
m_pNumSamplers->connectValueChanged(pControllerDlg,
&DlgPrefController::slotRecreateControlPickerMenu);

m_controllerPages.append(pControllerDlg);

Expand Down
5 changes: 5 additions & 0 deletions src/controllers/dlgprefcontrollers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include "controllers/ui_dlgprefcontrollersdlg.h"
#include "preferences/dialog/dlgpreferencepage.h"
#include "preferences/usersettings.h"
#include "util/parented_ptr.h"

class ControlProxy;
class DlgPreferences;
class DlgPrefController;
class ControllerManager;
Expand Down Expand Up @@ -52,4 +54,7 @@ class DlgPrefControllers : public DlgPreferencePage, public Ui::DlgPrefControlle
QTreeWidgetItem* m_pControllersRootItem;
QList<DlgPrefController*> m_controllerPages;
QList<QTreeWidgetItem*> m_controllerTreeItems;

const parented_ptr<ControlProxy> m_pNumDecks;
const parented_ptr<ControlProxy> m_pNumSamplers;
};
7 changes: 6 additions & 1 deletion src/mixer/playermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,12 @@ void PlayerManager::addDeckInner() {
}

void PlayerManager::loadSamplers() {
m_pSamplerBank->loadSamplerBankFromPath(getDefaultSamplerPath(m_pConfig));
// This is only called by CoreServices during startup to restore
// samplers from the previous session.
// We don't want it to create more players than necessary.
bool dontCreateEmptySamplers = true;
m_pSamplerBank->loadSamplerBankFromPath(getDefaultSamplerPath(m_pConfig),
dontCreateEmptySamplers);
}

void PlayerManager::addSampler() {
Expand Down
65 changes: 40 additions & 25 deletions src/mixer/samplerbank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ void SamplerBank::slotLoadSamplerBank(double v) {
}
}

bool SamplerBank::loadSamplerBankFromPath(const QString& samplerBankPath) {
bool SamplerBank::loadSamplerBankFromPath(const QString& samplerBankPath,
bool dontCreateEmptySamplers) {
// The user has picked a new directory via a file dialog. This means the
// system sandboxer (if we are sandboxed) has granted us permission to this
// folder. We don't need access to this file on a regular basis so we do not
Expand Down Expand Up @@ -195,33 +196,47 @@ bool SamplerBank::loadSamplerBankFromPath(const QString& samplerBankPath) {
return false;
}

QDomNode n = root.firstChild();

while (!n.isNull()) {
const auto samplerNodes = root.childNodes();
if (samplerNodes.isEmpty()) {
return true;
}
for (int i = 0; i < samplerNodes.size(); i++) {
QDomNode n = samplerNodes.at(i);
QDomElement e = n.toElement();
if (e.isNull() || e.tagName() != "sampler") {
continue;
}

const QString group = e.attribute("group", "");
const QString location = e.attribute("location", "");
int samplerNum;

if (group.isEmpty() || !m_pPlayerManager->isSamplerGroup(group, &samplerNum)) {
continue;
}

// During startup we only increase the sampler count if there is
// a track to be loaded. This avoids
// * creating more sampler players than strictly necessary
// * an unnecessary large Load To > Sampler N submenu in the track menu
if (dontCreateEmptySamplers && location.isEmpty()) {
continue;
}

// Later on, when the user loads a samplers file manually, we
// want to eject loaded tracks if the file's sample slot is empty.
// We also create new players even if they are not present in the
// GUI to not drop tracks loaded to invisible samplers when saving
// the samplers file.
if (static_cast<int>(m_pPlayerManager->numSamplers()) < samplerNum) {
m_pCONumSamplers->set(samplerNum);
}

if (!e.isNull()) {
if (e.tagName() == "sampler") {
QString group = e.attribute("group", "");
QString location = e.attribute("location", "");
int samplerNum;

if (!group.isEmpty()
&& m_pPlayerManager->isSamplerGroup(group, &samplerNum)) {
if (m_pPlayerManager->numSamplers() < (unsigned) samplerNum) {
m_pCONumSamplers->set(samplerNum);
}

if (location.isEmpty()) {
m_pPlayerManager->slotLoadTrackToPlayer(TrackPointer(), group, false);
} else {
m_pPlayerManager->slotLoadLocationToPlayer(location, group, false);
}
}

}
if (location.isEmpty()) {
m_pPlayerManager->slotLoadTrackToPlayer(TrackPointer(), group, false);
} else {
m_pPlayerManager->slotLoadLocationToPlayer(location, group, false);
}
n = n.nextSibling();
}

file.close();
Expand Down
3 changes: 2 additions & 1 deletion src/mixer/samplerbank.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class SamplerBank : public QObject {
PlayerManager* pPlayerManager);

bool saveSamplerBankToPath(const QString& samplerBankPath);
bool loadSamplerBankFromPath(const QString& samplerBankPath);
bool loadSamplerBankFromPath(const QString& samplerBankPath,
bool dontCreateEmptySamplers = false);

private slots:
void slotSaveSamplerBank(double v);
Expand Down
41 changes: 30 additions & 11 deletions src/widget/wtrackmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "analyzer/analyzersilence.h"
#include "analyzer/analyzertrack.h"
#include "control/controlobject.h"
#include "control/controlproxy.h"
#include "library/coverartutils.h"
#include "library/dao/trackschema.h"
#include "library/dlgtagfetcher.h"
Expand Down Expand Up @@ -49,6 +48,11 @@

namespace {
const QString kAppGroup = QStringLiteral("[App]");

const QString samplerTrString(int i) {
return QObject::tr("Sampler %1").arg(i);
}

} // namespace

WTrackMenu::WTrackMenu(
Expand All @@ -61,14 +65,13 @@ WTrackMenu::WTrackMenu(
m_pTrackModel(trackModel),
m_pConfig(pConfig),
m_pLibrary(pLibrary),
m_pNumSamplers(kAppGroup, QStringLiteral("num_samplers")),
m_pNumDecks(kAppGroup, QStringLiteral("num_decks")),
m_pNumPreviewDecks(kAppGroup, QStringLiteral("num_preview_decks")),
m_bPlaylistMenuLoaded(false),
m_bCrateMenuLoaded(false),
m_eActiveFeatures(flags),
m_eTrackModelFeatures(Feature::TrackModelFeatures) {
m_pNumSamplers = new ControlProxy(kAppGroup, QStringLiteral("num_samplers"), this);
m_pNumDecks = new ControlProxy(kAppGroup, QStringLiteral("num_decks"), this);
m_pNumPreviewDecks = new ControlProxy(kAppGroup, QStringLiteral("num_preview_decks"), this);

// Warn if any of the chosen features depend on a TrackModel
VERIFY_OR_DEBUG_ASSERT(trackModel || (m_eTrackModelFeatures & flags) == 0) {
// Remove unsupported features
Expand Down Expand Up @@ -507,7 +510,7 @@ void WTrackMenu::setupActions() {

m_pLoadToMenu->addMenu(m_pSamplerMenu);

if (m_pNumPreviewDecks->get() > 0.0) {
if (m_pNumPreviewDecks.get() > 0.0) {
m_pLoadToMenu->addAction(m_pAddToPreviewDeck);
}

Expand Down Expand Up @@ -783,7 +786,7 @@ void WTrackMenu::updateMenus() {
const bool singleTrackSelected = getTrackCount() == 1;

if (featureIsEnabled(Feature::LoadTo)) {
int iNumDecks = static_cast<int>(m_pNumDecks->get());
int iNumDecks = static_cast<int>(m_pNumDecks.get());
m_pDeckMenu->clear();
if (iNumDecks > 0) {
for (int i = 1; i <= iNumDecks; ++i) {
Expand Down Expand Up @@ -818,19 +821,35 @@ void WTrackMenu::updateMenus() {
}
}

int iNumSamplers = static_cast<int>(m_pNumSamplers->get());
int iNumSamplers = static_cast<int>(m_pNumSamplers.get());
const int maxSamplersPerMenu = 16;
if (iNumSamplers > 0) {
m_pSamplerMenu->clear();
QMenu* pMenu = m_pSamplerMenu;
int samplersInMenu = 0;
for (int i = 1; i <= iNumSamplers; ++i) {
if (samplersInMenu == maxSamplersPerMenu) {
samplersInMenu = 0;
int limit = iNumSamplers > i + 15 ? i + 15 : iNumSamplers;
const QString label = samplerTrString(i) + QStringLiteral("- %1").arg(limit);
pMenu = new QMenu(label, m_pSamplerMenu);
m_pSamplerMenu->addMenu(pMenu);
}
samplersInMenu++;
// PlayerManager::groupForSampler is 0-indexed.
QString samplerGroup = PlayerManager::groupForSampler(i - 1);
bool samplerPlaying = ControlObject::get(
ConfigKey(samplerGroup, "play")) > 0.0;
bool samplerEnabled = !samplerPlaying && singleTrackSelected;
QAction* pAction = new QAction(tr("Sampler %1").arg(i), m_pSamplerMenu);
QAction* pAction = new QAction(samplerTrString(i), pMenu);
pAction->setEnabled(samplerEnabled);
m_pSamplerMenu->addAction(pAction);
connect(pAction, &QAction::triggered, this, [this, samplerGroup] { loadSelectionToGroup(samplerGroup); });
pMenu->addAction(pAction);
connect(pAction,
&QAction::triggered,
this,
[this, samplerGroup] {
loadSelectionToGroup(samplerGroup);
});
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/widget/wtrackmenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <memory>

#include "analyzer/analyzertrack.h"
#include "control/pollingcontrolproxy.h"
#include "library/coverart.h"
#include "library/dao/playlistdao.h"
#include "library/trackprocessing.h"
Expand All @@ -15,7 +16,6 @@
#include "util/color/rgbcolor.h"
#include "util/parented_ptr.h"

class ControlProxy;
class DlgTagFetcher;
class DlgTrackInfo;
//class DlgDeleteFilesConfirmation;
Expand Down Expand Up @@ -218,10 +218,6 @@ class WTrackMenu : public QMenu {
/// deck made the request.
QString m_deckGroup;

const ControlProxy* m_pNumSamplers{};
const ControlProxy* m_pNumDecks{};
const ControlProxy* m_pNumPreviewDecks{};

// Submenus
QMenu* m_pLoadToMenu{};
QMenu* m_pDeckMenu{};
Expand Down Expand Up @@ -315,6 +311,10 @@ class WTrackMenu : public QMenu {
const UserSettingsPointer m_pConfig;
Library* const m_pLibrary;

PollingControlProxy m_pNumSamplers;
PollingControlProxy m_pNumDecks;
PollingControlProxy m_pNumPreviewDecks;

std::unique_ptr<DlgTrackInfo> m_pDlgTrackInfo;
std::unique_ptr<DlgTagFetcher> m_pDlgTagFetcher;

Expand Down

0 comments on commit f0587b8

Please sign in to comment.