diff options
author | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2020-07-08 11:33:52 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-08 11:33:52 +0200 |
commit | d967b0ee7b416be34a6c5774385b9157a00a2156 (patch) | |
tree | a9dd7212ed4c8ae5a75e883a11191c7fc041a193 | |
parent | 89bd191bae5d03a0257cdc5407e8d25f77de36d9 (diff) | |
parent | 04017eb9ac296b5dcf1afa02d32929ec79a3e724 (diff) |
Merge pull request #2918 from uklotzde/controlobject
ControlObject/ControlPrivateDouble: Various Fixes
-rw-r--r-- | src/control/control.cpp | 141 | ||||
-rw-r--r-- | src/control/control.h | 90 | ||||
-rw-r--r-- | src/control/controlobject.cpp | 4 | ||||
-rw-r--r-- | src/control/controlobject.h | 5 | ||||
-rw-r--r-- | src/dialog/dlgdevelopertools.cpp | 10 | ||||
-rw-r--r-- | src/mixxx.cpp | 84 | ||||
-rw-r--r-- | src/mixxx.h | 32 | ||||
-rw-r--r-- | src/preferences/dialog/dlgprefdeck.cpp | 43 | ||||
-rw-r--r-- | src/preferences/dialog/dlgprefdeck.h | 26 | ||||
-rw-r--r-- | src/preferences/settingsmanager.cpp | 6 | ||||
-rw-r--r-- | src/preferences/settingsmanager.h | 14 | ||||
-rw-r--r-- | src/test/mixxxtest.cpp | 10 |
12 files changed, 238 insertions, 227 deletions
diff --git a/src/control/control.cpp b/src/control/control.cpp index d46fcb1d78..99f72ce37f 100644 --- a/src/control/control.cpp +++ b/src/control/control.cpp @@ -1,46 +1,38 @@ -#include <QtDebug> -#include <QSharedPointer> - #include "control/control.h" +#include "control/controlobject.h" #include "util/stat.h" -// Static member variable definition +//static UserSettingsPointer ControlDoublePrivate::s_pUserConfig; -QHash<ConfigKey, QWeakPointer<ControlDoublePrivate> > ControlDoublePrivate::s_qCOHash -GUARDED_BY(ControlDoublePrivate::s_qCOHashMutex); +//static +QHash<ConfigKey, QWeakPointer<ControlDoublePrivate>> ControlDoublePrivate::s_qCOHash + GUARDED_BY(ControlDoublePrivate::s_qCOHashMutex); +//static QHash<ConfigKey, ConfigKey> ControlDoublePrivate::s_qCOAliasHash -GUARDED_BY(ControlDoublePrivate::s_qCOHashMutex); + GUARDED_BY(ControlDoublePrivate::s_qCOHashMutex); +//static MMutex ControlDoublePrivate::s_qCOHashMutex; -/* -ControlDoublePrivate::ControlDoublePrivate() - : m_bIgnoreNops(true), - m_bTrack(false), - m_trackType(Stat::UNSPECIFIED), - m_trackFlags(Stat::COUNT | Stat::SUM | Stat::AVERAGE | - Stat::SAMPLE_VARIANCE | Stat::MIN | Stat::MAX), - m_confirmRequired(false) { - initialize(); -} -*/ - -ControlDoublePrivate::ControlDoublePrivate(ConfigKey key, - ControlObject* pCreatorCO, - bool bIgnoreNops, bool bTrack, - bool bPersist, double defaultValue) +ControlDoublePrivate::ControlDoublePrivate( + ConfigKey key, + ControlObject* pCreatorCO, + bool bIgnoreNops, + bool bTrack, + bool bPersist, + double defaultValue) : m_key(key), + m_pCreatorCO(pCreatorCO), m_bPersistInConfiguration(bPersist), m_bIgnoreNops(bIgnoreNops), m_bTrack(bTrack), m_trackType(Stat::UNSPECIFIED), m_trackFlags(Stat::COUNT | Stat::SUM | Stat::AVERAGE | - Stat::SAMPLE_VARIANCE | Stat::MIN | Stat::MAX), - m_confirmRequired(false), - m_pCreatorCO(pCreatorCO) { + Stat::SAMPLE_VARIANCE | Stat::MIN | Stat::MAX), + m_confirmRequired(false) { initialize(defaultValue); } @@ -112,59 +104,88 @@ QSharedPointer<ControlDoublePrivate> ControlDoublePrivate::getControl( VERIFY_OR_DEBUG_ASSERT(!key.isEmpty()) { qWarning() << "ControlDoublePrivate::getControl returning NULL" << "for empty ConfigKey."; - return QSharedPointer<ControlDoublePrivate>(); + return nullptr; } - QSharedPointer<ControlDoublePrivate> pControl; // Scope for MMutexLocker. { - MMutexLocker locker(&s_qCOHashMutex); - auto it = s_qCOHash.constFind(key); - if (it != s_qCOHash.constEnd()) { - if (pCreatorCO) { - qWarning() << "ControlObject" << key.group << key.item << "already created"; - DEBUG_ASSERT(!"ControlObject already created"); + const MMutexLocker locker(&s_qCOHashMutex); + const auto it = s_qCOHash.find(key); + if (it != s_qCOHash.end()) { + auto pControl = it.value().lock(); + if (pControl) { + // Control object already exists + VERIFY_OR_DEBUG_ASSERT(!pCreatorCO) { + qWarning() + << "ControlObject" + << key.group << key.item + << "already created"; + return nullptr; + } + return pControl; } else { - pControl = it.value(); + // The weak pointer has become invalid and can be cleaned up + s_qCOHash.erase(it); } } } - if (pControl == NULL) { - if (pCreatorCO) { - pControl = QSharedPointer<ControlDoublePrivate>( - new ControlDoublePrivate(key, pCreatorCO, bIgnoreNops, - bTrack, bPersist, defaultValue)); - MMutexLocker locker(&s_qCOHashMutex); - //qDebug() << "ControlDoublePrivate::s_qCOHash.insert(" << key.group << "," << key.item << ")"; - s_qCOHash.insert(key, pControl); - } else if (!flags.testFlag(ControlFlag::NoWarnIfMissing)) { - qWarning() << "ControlDoublePrivate::getControl returning NULL for (" - << key.group << "," << key.item << ")"; - DEBUG_ASSERT(flags.testFlag(ControlFlag::NoAssertIfMissing)); - } + if (pCreatorCO) { + auto pControl = QSharedPointer<ControlDoublePrivate>( + new ControlDoublePrivate(key, + pCreatorCO, + bIgnoreNops, + bTrack, + bPersist, + defaultValue)); + const MMutexLocker locker(&s_qCOHashMutex); + //qDebug() << "ControlDoublePrivate::s_qCOHash.insert(" << key.group << "," << key.item << ")"; + s_qCOHash.insert(key, pControl); + return pControl; + } + + if (!flags.testFlag(ControlFlag::NoWarnIfMissing)) { + qWarning() << "ControlDoublePrivate::getControl returning NULL for (" + << key.group << "," << key.item << ")"; + DEBUG_ASSERT(flags.testFlag(ControlFlag::NoAssertIfMissing)); } - return pControl; + return nullptr; } // static -void ControlDoublePrivate::getControls( - QList<QSharedPointer<ControlDoublePrivate> >* pControlList) { - s_qCOHashMutex.lock(); - pControlList->clear(); - for (auto it = s_qCOHash.constBegin(); it != s_qCOHash.constEnd(); ++it) { - QSharedPointer<ControlDoublePrivate> pControl = it.value(); - if (!pControl.isNull()) { - pControlList->push_back(pControl); +QList<QSharedPointer<ControlDoublePrivate>> ControlDoublePrivate::getAllInstances() { + QList<QSharedPointer<ControlDoublePrivate>> result; + MMutexLocker locker(&s_qCOHashMutex); + result.reserve(s_qCOHash.size()); + for (auto it = s_qCOHash.begin(); it != s_qCOHash.end(); ++it) { + auto pControl = it.value().lock(); + if (pControl) { + result.append(std::move(pControl)); + } else { + // The weak pointer has become invalid and can be cleaned up + s_qCOHash.erase(it); } } - s_qCOHashMutex.unlock(); + return result; } // static -QHash<ConfigKey, ConfigKey> ControlDoublePrivate::getControlAliases() { +QList<QSharedPointer<ControlDoublePrivate>> ControlDoublePrivate::takeAllInstances() { + QList<QSharedPointer<ControlDoublePrivate>> result; MMutexLocker locker(&s_qCOHashMutex); - return s_qCOAliasHash; + result.reserve(s_qCOHash.size()); + for (auto it = s_qCOHash.begin(); it != s_qCOHash.end(); ++it) { + auto pControl = it.value().lock(); + if (pControl) { + result.append(std::move(pControl)); + } + } + s_qCOHash.clear(); + return result; +} + +void ControlDoublePrivate::deleteCreatorCO() { + delete m_pCreatorCO.fetchAndStoreOrdered(nullptr); } void ControlDoublePrivate::reset() { diff --git a/src/control/control.h b/src/control/control.h index 56df7d5ae2..5ff49bcd4b 100644 --- a/src/control/control.h +++ b/src/control/control.h @@ -1,10 +1,10 @@ -#ifndef CONTROL_H -#define CONTROL_H +#pragma once +#include <QAtomicPointer> #include <QHash> -#include <QString> #include <QObject> -#include <QAtomicPointer> +#include <QSharedPointer> +#include <QString> #include "control/controlbehavior.h" #include "control/controlvalue.h" @@ -26,7 +26,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(ControlFlags) class ControlDoublePrivate : public QObject { Q_OBJECT public: - virtual ~ControlDoublePrivate(); + ~ControlDoublePrivate() override; // Used to implement control persistence. All controls that are marked // "persist in user config" get and set their value on creation/deletion @@ -43,18 +43,24 @@ class ControlDoublePrivate : public QObject { // Gets the ControlDoublePrivate matching the given ConfigKey. If pCreatorCO // is non-NULL, allocates a new ControlDoublePrivate for the ConfigKey if // one does not exist. - static QSharedPointer<ControlDoublePrivate> getControl(const ConfigKey& key, + static QSharedPointer<ControlDoublePrivate> getControl( + const ConfigKey& key, ControlFlags flags = ControlFlag::None, - ControlObject* pCreatorCO = NULL, + ControlObject* pCreatorCO = nullptr, bool bIgnoreNops = true, bool bTrack = false, bool bPersist = false, double defaultValue = 0.0); - // Adds all ControlDoublePrivate that currently exist to pControlList - static void getControls(QList<QSharedPointer<ControlDoublePrivate> >* pControlsList); + // Returns a list of all existing instances. + static QList<QSharedPointer<ControlDoublePrivate>> getAllInstances(); + // Clears all existing instances and returns them as a list. + static QList<QSharedPointer<ControlDoublePrivate>> takeAllInstances(); - static QHash<ConfigKey, ConfigKey> getControlAliases(); + static QHash<ConfigKey, ConfigKey> getControlAliases() { + // Implicitly shared classes can safely be copied across threads + return s_qCOAliasHash; + } const QString& name() const { return m_name; @@ -78,7 +84,7 @@ class ControlDoublePrivate : public QObject { // ValueChangeRequest slot. void setAndConfirm(double value, QObject* pSender); // Gets the control value. - inline double get() const { + double get() const { return m_value.getValue(); } // Resets the control value to its default. @@ -86,8 +92,10 @@ class ControlDoublePrivate : public QObject { // Set the behavior to be used when setting values and translating between // parameter and value space. Returns the previously set behavior (if any). - // The caller must not delete the behavior at any time. The memory is managed - // by this function. + // Callers must allocate the passed behavior using new and ownership to this + // memory is passed with the function call!! + // TODO: Pass a std::unique_ptr instead of a plain pointer to ensure this + // transfer of ownership. void setBehavior(ControlNumericBehavior* pBehavior); void setParameter(double dParam, QObject* pSender); @@ -98,27 +106,28 @@ class ControlDoublePrivate : public QObject { void setValueFromMidi(MidiOpCode opcode, double dParam); double getMidiParameter() const; - inline bool ignoreNops() const { + bool ignoreNops() const { return m_bIgnoreNops; } - inline void setDefaultValue(double dValue) { + void setDefaultValue(double dValue) { m_defaultValue.setValue(dValue); } - inline double defaultValue() const { + double defaultValue() const { return m_defaultValue.getValue(); } - inline ControlObject* getCreatorCO() const { - return m_pCreatorCO; + ControlObject* getCreatorCO() const { + return m_pCreatorCO.loadAcquire(); } - inline void removeCreatorCO() { - m_pCreatorCO = NULL; + bool resetCreatorCO(ControlObject* pCreatorCO) { + return m_pCreatorCO.testAndSetOrdered(pCreatorCO, nullptr); } + void deleteCreatorCO(); - inline ConfigKey getKey() { + ConfigKey getKey() { return m_key; } @@ -144,25 +153,30 @@ class ControlDoublePrivate : public QObject { void valueChangeRequest(double value); private: - ControlDoublePrivate(ConfigKey key, ControlObject* pCreatorCO, - bool bIgnoreNops, bool bTrack, bool bPersist, - double defaultValue); + ControlDoublePrivate( + ConfigKey key, + ControlObject* pCreatorCO, + bool bIgnoreNops, + bool bTrack, + bool bPersist, + double defaultValue); + ControlDoublePrivate(ControlDoublePrivate&&) = delete; + ControlDoublePrivate(const ControlDoublePrivate&) = delete; + ControlDoublePrivate& operator=(ControlDoublePrivate&&) = delete; + ControlDoublePrivate& operator=(const ControlDoublePrivate&) = delete; + void initialize(double defaultValue); void setInner(double value, QObject* pSender); - ConfigKey m_key; + const ConfigKey m_key; + + QAtomicPointer<ControlObject> m_pCreatorCO; // Whether the control should persist in the Mixxx user configuration. The // value is loaded from configuration when the control is created and // written to the configuration when the control is deleted. bool m_bPersistInConfiguration; - // User-visible, i18n name for what the control is. - QString m_name; - - // User-visible, i18n description for what the control does. - QString m_description; - // Whether to ignore sets which would have no effect. bool m_bIgnoreNops; @@ -173,6 +187,12 @@ class ControlDoublePrivate : public QObject { int m_trackFlags; bool m_confirmRequired; + // User-visible, i18n name for what the control is. + QString m_name; + + // User-visible, i18n description for what the control does. + QString m_description; + // The control value. ControlValueAtomic<double> m_value; // The default control value. @@ -180,8 +200,6 @@ class ControlDoublePrivate : public QObject { QSharedPointer<ControlNumericBehavior> m_pBehavior; - ControlObject* m_pCreatorCO; - // Hack to implement persistent controls. This is a pointer to the current // user configuration object (if one exists). In general, we do not want the // user configuration to be a singleton -- objects that need access to it @@ -191,7 +209,8 @@ class ControlDoublePrivate : public QObject { static UserSettingsPointer s_pUserConfig; // Hash of ControlDoublePrivate instantiations. - static QHash<ConfigKey, QWeakPointer<ControlDoublePrivate> > s_qCOHash; + static QHash<ConfigKey, QWeakPointer<ControlDoublePrivate>> s_qCOHash; + // Hash of aliases between ConfigKeys. Solely used for looking up the first // alias associated with a key. static QHash<ConfigKey, ConfigKey> s_qCOAliasHash; @@ -199,6 +218,3 @@ class ControlDoublePrivate : public QObject { // Mutex guarding access to s_qCOHash and s_qCOAliasHash. static MMutex s_qCOHashMutex; }; - - -#endif /* CONTROL_H */ diff --git a/src/control/controlobject.cpp b/src/control/controlobject.cpp index 2de1c38683..988681cc50 100644 --- a/src/control/controlobject.cpp +++ b/src/control/controlobject.cpp @@ -54,7 +54,9 @@ ControlObject::ControlObject(ConfigKey key, bool bIgnoreNops, bool bTrack, ControlObject::~ControlObject() { if (m_pControl) { - m_pControl->removeCreatorCO(); + const bool success = m_pControl->resetCreatorCO(this); + Q_UNUSED(success); + DEBUG_ASSERT(success); } } diff --git a/src/control/controlobject.h b/src/control/controlobject.h index 56af1aefd5..a3e247f846 100644 --- a/src/control/controlobject.h +++ b/src/control/controlobject.h @@ -180,6 +180,11 @@ class ControlObject : public QObject { void readOnlyHandler(double v); private: + ControlObject(ControlObject&&) = delete; + ControlObject(const ControlObject&) = delete; + ControlObject& operator=(ControlObject&&) = delete; + ControlObject& operator=(const ControlObject&) = delete; + inline bool ignoreNops() const { return m_pControl ? m_pControl->ignoreNops() : true; } diff --git a/src/dialog/dlgdevelopertools.cpp b/src/dialog/dlgdevelopertools.cpp index 4642c649cc..9e5b462e1c 100644 --- a/src/dialog/dlgdevelopertools.cpp +++ b/src/dialog/dlgdevelopertools.cpp @@ -13,9 +13,9 @@ DlgDeveloperTools::DlgDeveloperTools(QWidget* pParent, m_pConfig(pConfig) { setupUi(this); - QList<QSharedPointer<ControlDoublePrivate> > controlsList; - ControlDoublePrivate::getControls(&controlsList); - QHash<ConfigKey, ConfigKey> controlAliases = + const QList<QSharedPointer<ControlDoublePrivate>> controlsList = + ControlDoublePrivate::getAllInstances(); + const QHash<ConfigKey, ConfigKey> controlAliases = ControlDoublePrivate::getControlAliases(); for (auto it = controlsList.constBegin(); @@ -144,8 +144,8 @@ void DlgDeveloperTools::slotControlDump() { return; } - QList<QSharedPointer<ControlDoublePrivate> > controlsList; - ControlDoublePrivate::getControls(&controlsList); + const QList<QSharedPointer<ControlDoublePrivate>> controlsList = + ControlDoublePrivate::getAllInstances(); for (auto it = controlsList.constBegin(); it != controlsList.constEnd(); ++it) { const QSharedPointer<ControlDoublePrivate>& pControl = *it; if (pControl) { diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 0fd9dde2a6..54b30bf3d2 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -142,7 +142,6 @@ const int MixxxMainWindow::kAuxiliaryCount = 4; MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) : m_pWidgetParent(nullptr), m_pLaunchImage(nullptr), - m_pSettingsManager(nullptr), m_pEffectsManager(nullptr), m_pEngine(nullptr), m_pSkinLoader(nullptr), @@ -177,7 +176,7 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) StatsManager::createInstance(); } - m_pSettingsManager = new SettingsManager(this, args.getSettingsPath()); + m_pSettingsManager = std::make_unique<SettingsManager>(args.getSettingsPath()); initializeKeyboard(); @@ -285,10 +284,10 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { m_pRecordingManager = new RecordingManager(pConfig, m_pEngine); - #ifdef __BROADCAST__ - m_pBroadcastManager = new BroadcastManager(m_pSettingsManager, - m_pSoundManager); + m_pBroadcastManager = new BroadcastManager( + m_pSettingsManager.get(), + m_pSoundManager); #endif launchProgress(11); @@ -471,9 +470,17 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { } // Initialize preference dialog - m_pPrefDlg = new DlgPreferences(this, m_pSkinLoader, m_pSoundManager, m_pPlayerManager, - m_pControllerManager, m_pVCManager, pLV2Backend, m_pEffectsManager, - m_pSettingsManager, m_pLibrary); + m_pPrefDlg = new DlgPreferences( + this, + m_pSkinLoader, + m_pSoundManager, + m_pPlayerManager, + m_pControllerManager, + m_pVCManager, + pLV2Backend, + m_pEffectsManager, + m_pSettingsManager.get(), + m_pLibrary); m_pPrefDlg->setWindowIcon(QIcon(":/images/mixxx_icon.svg")); m_pPrefDlg->setHidden(true); @@ -777,42 +784,6 @@ void MixxxMainWindow::finalize() { delete m_pGuiTick; delete m_pVisualsManager; - // Check for leaked ControlObjects and give warnings. - QList<QSharedPointer<ControlDoublePrivate> > leakedControls; - QList<ConfigKey> leakedConfigKeys; - - ControlDoublePrivate::getControls(&leakedControls); - - if (leakedControls.size() > 0) { - qDebug() << "WARNING: The following" << leakedControls.size() - << "controls were leaked:"; - foreach (QSharedPointer<ControlDoublePrivate> pCDP, leakedControls) { - if (pCDP.isNull()) { - continue; - } - ConfigKey key = pCDP->getKey(); - qDebug() << key.group << key.item << pCDP->getCreatorCO(); - leakedConfigKeys.append(key); - } - - // Deleting leaked objects helps to satisfy valgrind. - // These delete calls could cause crashes if a destructor for a control - // we thought was leaked is triggered after this one exits. - // So, only delete so if developer mode is on. - if (CmdlineArgs::Instance().getDeveloper()) { - foreach (ConfigKey key, leakedConfigKeys) { - // A deletion early in the list may trigger a destructor - // for a control later in the list, so we check for a null - // pointer each time. - ControlObject* pCo = ControlObject::getControl(key, ControlFlag::NoAssertIfMissing); - if (pCo) { - delete pCo; - } - } - } - leakedControls.clear(); - } - // Delete the track collections after all internal track pointers // in other components have been released by deleting those components // beforehand! @@ -829,9 +800,34 @@ void MixxxMainWindow::finalize() { // at exit. m_pSettingsManager->save(); + // Check for leaked ControlObjects and give warnings. + { + QList<QSharedPointer<ControlDoublePrivate>> leakedControls = + ControlDoublePrivate::takeAllInstances(); + VERIFY_OR_DEBUG_ASSERT(leakedControls.isEmpty()) { + qWarning() + << "The following" + << leakedControls.size() + << "controls were leaked:"; + for (auto pCDP : leakedControls) { + ConfigKey key = pCDP->getKey(); + qWarning() << key.group << key.item << pCDP->getCreatorCO(); + // Deleting leaked objects helps to satisfy valgrind. + // These delete calls could cause crashes if a destructor for a control + // we thought was leaked is triggered after this one exits. + // So, only delete so if developer mode is on. + if (CmdlineArgs::Instance().getDeveloper()) { + pCDP->deleteCreatorCO(); + } + } + } + // Finally drop all shared pointers by exiting this scope + } + Sandbox::shutdown(); qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting SettingsManager"; + m_pSettingsManager.reset(); delete m_pKeyboard; delete m_pKbdConfig; diff --git a/src/mixxx.h b/src/mixxx.h index 765a7c065c..f34157f888 100644 --- a/src/mixxx.h +++ b/src/mixxx.h @@ -1,35 +1,19 @@ -/*************************************************************************** - mixxx.h - description - ------------------- - begin : Mon Feb 18 09:48:17 CET 2002 - copyright : (C) 2002 by Tue and Ken Haste Andersen - email : - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef MIXXX_H -#define MIXXX_H +#pragma once #include <QMainWindow> #include <QSharedPointer> #include <QString> +#include <memory> #include "preferences/configobject.h" -#include "preferences/usersettings.h" #include "preferences/constants.h" +#include "preferences/usersettings.h" +#include "soundio/sounddeviceerror.h" #include "track/track.h" #include "util/cmdlineargs.h" -#include "util/timer.h" #include "util/db/dbconnectionpool.h" -#include "soundio/sounddeviceerror.h" +#include "util/parented_ptr.h" +#include "util/timer.h" class ChannelHandleFactory; class ControlPushButton; @@ -142,7 +126,7 @@ class MixxxMainWindow : public QMainWindow { QWidget* m_pWidgetParent; LaunchImage* m_pLaunchImage; - SettingsManager* m_pSettingsManager; + std::unique_ptr<SettingsManager> m_pSettingsManager; // The effects processing system EffectsManager* m_pEffectsManager; @@ -203,5 +187,3 @@ class MixxxMainWindow : public QMainWindow { static const int kMicrophoneCount; static const int kAuxiliaryCount; }; - -#endif diff --git a/src/preferences/dialog/dlgprefdeck.cpp b/src/preferences/dialog/dlgprefdeck.cpp index 9ce38c8158..79799bd4ad 100644 --- a/src/preferences/dialog/dlgprefdeck.cpp +++ b/src/preferences/dialog/dlgprefdeck.cpp @@ -34,22 +34,29 @@ constexpr int kDefaultRateRampSensitivity = 250; // to playermanager.cpp } -DlgPrefDeck::DlgPrefDeck(QWidget * parent, MixxxMainWindow * mixxx, - PlayerManager* pPlayerManager, - UserSettingsPointer pConfig) - : DlgPreferencePage(parent), - m_pConfig(pConfig), - m_mixxx(mixxx), - m_pPlayerManager(pPlayerManager), - m_iNumConfiguredDecks(0), - m_iNumConfiguredSamplers(0) { +DlgPrefDeck::DlgPrefDeck(QWidget* parent, + MixxxMainWindow* mixxx, + PlayerManager* pPlayerManager, + UserSettingsPointer pConfig) + : DlgPreferencePage(parent), + m_mixxx(mixxx), + m_pPlayerManager(pPlayerManager), + m_pConfig(pConfig), + m_pControlTrackTimeDisplay(std::make_unique<ControlObject>( + ConfigKey("[Controls]", "ShowDurationRemaining"))), + m_pControlTrackTimeFormat(std::make_unique<ControlObject>( + ConfigKey("[Controls]", "TimeFormat"))), + m_pNumDecks( + make_parented<ControlProxy>("[Master]", "num_decks", this)), + m_pNumSamplers(make_parented<ControlProxy>( + "[Master]", "num_samplers", this)), + m_iNumConfiguredDecks(0), + m_iNumConfiguredSamplers(0) { setupUi(this); - m_pNumDecks = new ControlProxy("[Master]", "num_decks", this); m_pNumDecks->connectValueChanged(this, [=](double value){slotNumDecksChanged(value);}); slotNumDecksChanged(m_pNumDecks->get(), true); - m_pNumSamplers = new ControlProxy("[Master]", "num_samplers", this); m_pNumSamplers->connectValueChanged(this, [=](double value){slotNumSamplersChanged(value);}); slotNumSamplersChanged(m_pNumSamplers->get(), true); @@ -74,10 +81,10 @@ DlgPrefDeck::DlgPrefDeck(QWidget * parent, MixxxMainWindow * mixxx, connect(ComboBoxCueMode, SIGNAL(activated(int)), this, SLOT(slotCueModeCombobox(int))); // Track time display configuration - m_pControlTrackTimeDisplay = new ControlObject( - ConfigKey("[Controls]", "ShowDurationRemaining")); - connect(m_pControlTrackTimeDisplay, SIGNAL(valueChanged(double)), - this, SLOT(slotSetTrackTimeDisplay(double))); + connect(m_pControlTrackTimeDisplay.get(), + &ControlObject::valueChanged, + this, + QOverload<double>::of(&DlgPrefDeck::slotSetTrackTimeDisplay)); double positionDisplayType = m_pConfig->getValue( ConfigKey("[Controls]", "PositionDisplay"), @@ -101,10 +108,7 @@ DlgPrefDeck::DlgPrefDeck(QWidget * parent, MixxxMainWindow * mixxx, this, SLOT(slotSetTrackTimeDisplay(QAbstractButton *))); // display time format - - m_pControlTrackTimeFormat = new ControlObject( - ConfigKey("[Controls]", "TimeFormat")); - connect(m_pControlTrackTimeFormat, + connect(m_pControlTrackTimeFormat.get(), &ControlObject::valueChanged, this, &DlgPrefDeck::slotTimeFormatChanged); @@ -351,7 +355,6 @@ DlgPrefDeck::DlgPrefDeck(QWidget * parent, MixxxMainWindow * mixxx, } DlgPrefDeck::~DlgPrefDeck() { - delete m_pControlTrackTimeDisplay; qDeleteAll(m_rateControls); qDeleteAll(m_rateDirectionControls); qDeleteAll(m_cueControls); diff --git a/src/preferences/dialog/dlgprefdeck.h b/src/preferences/dialog/dlgprefdeck.h index 41788ab9cf..dde7bff85a 100644 --- a/src/preferences/dialog/dlgprefdeck.h +++ b/src/preferences/dialog/dlgprefdeck.h @@ -1,7 +1,7 @@ -#ifndef DLGPREFDECK_H -#define DLGPREFDECK_H +#pragma once #include <QWidget> +#include <memory> #include "engine/controls/cuecontrol.h" #include "engine/controls/ratecontrol.h" @@ -9,6 +9,7 @@ #include "preferences/dialog/ui_dlgprefdeckdlg.h" #include "preferences/dlgpreferencepage.h" #include "preferences/usersettings.h" +#include "util/parented_ptr.h" class ControlProxy; class ControlPotmeter; @@ -58,7 +59,7 @@ class DlgPrefDeck : public DlgPreferencePage, public Ui::DlgPrefDeckDlg { DlgPrefDeck(QWidget *parent, MixxxMainWindow *mixxx, PlayerManager* pPlayerManager, UserSettingsPointer pConfig); - virtual ~DlgPrefDeck(); + ~DlgPrefDeck() override; public slots: void slotUpdate() override; @@ -101,19 +102,22 @@ class DlgPrefDeck : public DlgPreferencePage, public Ui::DlgPrefDeckDlg { void setRateRangeForAllDecks(int rangePercent); void setRateDirectionForAllDecks(bool inverted); - UserSettingsPointer m_pConfig; - ControlObject* m_pControlTrackTimeDisplay; - ControlObject* m_pControlTrackTimeFormat; - ControlProxy* m_pNumDecks; - ControlProxy* m_pNumSamplers; + MixxxMainWindow* const m_mixxx; + PlayerManager* const m_pPlayerManager; + const UserSettingsPointer m_pConfig; + + const std::unique_ptr<ControlObject> m_pControlTrackTimeDisplay; + const std::unique_ptr<ControlObject> m_pControlTrackTimeFormat; + + const parented_ptr<ControlProxy> m_pNumDecks; + const parented_ptr<ControlProxy> m_pNumSamplers; + QList<ControlProxy*> m_cueControls; QList<ControlProxy*> m_rateControls; QList<ControlProxy*> m_rateDirectionControls; QList<ControlProxy*> m_rateRangeControls; QList<ControlProxy*> m_keylockModeControls; QList<ControlProxy*> m_keyunlockModeControls; - MixxxMainWindow *m_mixxx; - PlayerManager* m_pPlayerManager; int m_iNumConfiguredDecks; int m_iNumConfiguredSamplers; @@ -143,5 +147,3 @@ class DlgPrefDeck : public DlgPreferencePage, public Ui::DlgPrefDeckDlg { double m_dRatePermCoarse; double m_dRatePermFine; }; - -#endif diff --git a/src/preferences/settingsmanager.cpp b/src/preferences/settingsmanager.cpp index f5bb8c680f..efae608981 100644 --- a/src/preferences/settingsmanager.cpp +++ b/src/preferences/settingsmanager.cpp @@ -6,10 +6,8 @@ #include "preferences/upgrade.h" #include "util/assert.h" -SettingsManager::SettingsManager(QObject* pParent, - const QString& settingsPath) - : QObject(pParent), - m_bShouldRescanLibrary(false) { +SettingsManager::SettingsManager(const QString& settingsPath) + : m_bShouldRescanLibrary(false) { // First make sure the settings path exists. If we don't then other parts of // Mixxx (such as the library) will produce confusing errors. if (!QDir(settingsPath).exists()) { diff --git a/src/preferences/settingsmanager.h b/src/preferences/settingsmanager.h index d45ba67754..2f9dcd9dfb 100644 --- a/src/preferences/settingsmanager.h +++ b/src/preferences/settingsmanager.h @@ -1,17 +1,11 @@ -#ifndef PREFERENCES_SETTINGSMANAGER_H -#define PREFERENCES_SETTINGSMANAGER_H - -#include <QObject> -#include <QSharedPointer> -#include <QString> +#pragma once #include "preferences/broadcastsettings.h" #include "preferences/usersettings.h" -class SettingsManager : public QObject { - Q_OBJECT +class SettingsManager { public: - SettingsManager(QObject* pParent, const QString& settingsPath); + explicit SettingsManager(const QString& settingsPath); virtual ~SettingsManager(); UserSettingsPointer settings() const { @@ -37,5 +31,3 @@ class SettingsManager : public QObject { bool m_bShouldRescanLibrary; BroadcastSettingsPointer m_pBroadcastSettings; }; - -#endif /* PREFERENCES_SETTINGSMANAGER_H */ diff --git a/src/test/mixxxtest.cpp b/src/test/mixxxtest.cpp index f70495e225..a57debe7c7 100644 --- a/src/test/mixxxtest.cpp +++ b/src/test/mixxxtest.cpp @@ -45,13 +45,7 @@ MixxxTest::MixxxTest() { MixxxTest::~MixxxTest() { // Mixxx leaks a ton of COs normally. To make new tests not affected by |