From f754682adf2874041e0eddff708cfd396c805e72 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 12:45:04 -0600 Subject: [PATCH 01/11] introduce CoreServices to decouple backend from QWidgets --- CMakeLists.txt | 1 + src/coreservices.cpp | 588 +++++++++++++++++++++++ src/coreservices.h | 143 ++++++ src/main.cpp | 15 +- src/mixer/basetrackplayer.cpp | 3 - src/mixer/basetrackplayer.h | 1 - src/mixer/deck.cpp | 2 - src/mixer/deck.h | 1 - src/mixer/playermanager.cpp | 19 +- src/mixer/playermanager.h | 4 +- src/mixer/previewdeck.cpp | 2 - src/mixer/previewdeck.h | 1 - src/mixer/sampler.cpp | 2 - src/mixer/sampler.h | 1 - src/mixxx.cpp | 855 ++++++---------------------------- src/mixxx.h | 58 +-- src/skin/launchimage.cpp | 6 +- src/skin/launchimage.h | 3 +- src/test/signalpathtest.h | 8 - 19 files changed, 922 insertions(+), 791 deletions(-) create mode 100644 src/coreservices.cpp create mode 100644 src/coreservices.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 591fd6ba64f..00a70264bf2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -636,6 +636,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/mixer/previewdeck.cpp src/mixer/sampler.cpp src/mixer/samplerbank.cpp + src/coreservices.cpp src/mixxx.cpp src/mixxxapplication.cpp src/musicbrainz/chromaprinter.cpp diff --git a/src/coreservices.cpp b/src/coreservices.cpp new file mode 100644 index 00000000000..228d5df5300 --- /dev/null +++ b/src/coreservices.cpp @@ -0,0 +1,588 @@ +#include "coreservices.h" + +#include +#include +#include + +#ifdef __BROADCAST__ +#include "broadcast/broadcastmanager.h" +#endif +#include "controllers/controllermanager.h" +#include "controllers/keyboard/keyboardeventfilter.h" +#include "database/mixxxdb.h" +#include "effects/builtin/builtinbackend.h" +#include "effects/effectsmanager.h" +#include "effects/lv2/lv2backend.h" +#include "engine/enginemaster.h" +#include "library/coverartcache.h" +#include "library/library.h" +#include "library/trackcollectionmanager.h" +#include "mixer/playerinfo.h" +#include "mixer/playermanager.h" +#include "preferences/settingsmanager.h" +#include "soundio/soundmanager.h" +#include "sources/soundsourceproxy.h" +#include "util/db/dbconnectionpooled.h" +#include "util/font.h" +#include "util/logger.h" +#include "util/screensaver.h" +#include "util/statsmanager.h" +#include "util/time.h" +#include "util/translations.h" +#include "util/version.h" +#include "vinylcontrol/vinylcontrolmanager.h" + +#ifdef __APPLE__ +#include "util/sandbox.h" +#endif + +#if defined(Q_OS_LINUX) +#include +#include + +#include + +#include "engine/channelhandle.h" +// Xlibint.h predates C++ and defines macros which conflict +// with references to std::max and std::min +#undef max +#undef min +#endif + +namespace { +const mixxx::Logger kLogger("CoreServices"); + +#define CLEAR_AND_CHECK_DELETED(x) clearHelper(x, #x); + +template +void clearHelper(std::shared_ptr& ref_ptr, const char* name) { + std::weak_ptr weak(ref_ptr); + ref_ptr.reset(); + if (auto shared = weak.lock()) { + qWarning() << name << "was leaked! Use count:" << shared.use_count(); + DEBUG_ASSERT(false); + } +} + +// hack around https://gitlab.freedesktop.org/xorg/lib/libx11/issues/25 +// https://bugs.launchpad.net/mixxx/+bug/1805559 +#if defined(Q_OS_LINUX) +typedef Bool (*WireToErrorType)(Display*, XErrorEvent*, xError*); + +const int NUM_HANDLERS = 256; +WireToErrorType __oldHandlers[NUM_HANDLERS] = {0}; + +Bool __xErrorHandler(Display* display, XErrorEvent* event, xError* error) { + // Call any previous handler first in case it needs to do real work. + auto code = static_cast(event->error_code); + if (__oldHandlers[code] != NULL) { + __oldHandlers[code](display, event, error); + } + + // Always return false so the error does not get passed to the normal + // application defined handler. + return False; +} + +#endif + +inline QLocale inputLocale() { + // Use the default config for local keyboard + QInputMethod* pInputMethod = QGuiApplication::inputMethod(); + return pInputMethod ? pInputMethod->locale() : QLocale(QLocale::English); +} +} // anonymous namespace + +namespace mixxx { + +// static +const int CoreServices::kMicrophoneCount = 4; +// static +const int CoreServices::kAuxiliaryCount = 4; + +CoreServices::CoreServices(const CmdlineArgs& args) + : m_runtime_timer(QLatin1String("CoreServices::runtime")), + m_cmdlineArgs(args) { +} + +void CoreServices::initializeSettings() { + QString settingsPath = m_cmdlineArgs.getSettingsPath(); +#ifdef __APPLE__ + if (!m_cmdlineArgs.getSettingsPathSet()) { + settingsPath = Sandbox::migrateOldSettings(); + } +#endif + m_pSettingsManager = std::make_unique(settingsPath); +} + +void CoreServices::initialize(QApplication* pApp) { + m_runtime_timer.start(); + mixxx::Time::start(); + ScopedTimer t("CoreServices::initialize"); + + mixxx::Logging::initialize( + m_pSettingsManager->settings()->getSettingsPath(), + m_cmdlineArgs.getLogLevel(), + m_cmdlineArgs.getLogFlushLevel(), + m_cmdlineArgs.getDebugAssertBreak()); + + VERIFY_OR_DEBUG_ASSERT(SoundSourceProxy::registerProviders()) { + qCritical() << "Failed to register any SoundSource providers"; + return; + } + + Version::logBuildDetails(); + + // Only record stats in developer mode. + if (m_cmdlineArgs.getDeveloper()) { + StatsManager::createInstance(); + } + + initializeKeyboard(); + + mixxx::Translations::initializeTranslations( + m_pSettingsManager->settings(), pApp, m_cmdlineArgs.getLocale()); + +#if defined(Q_OS_LINUX) + // XESetWireToError will segfault if running as a Wayland client + if (pApp->platformName() == QLatin1String("xcb")) { + for (auto i = 0; i < NUM_HANDLERS; ++i) { + XESetWireToError(QX11Info::display(), i, &__xErrorHandler); + } + } +#endif + + UserSettingsPointer pConfig = m_pSettingsManager->settings(); + + Sandbox::initialize(QDir(pConfig->getSettingsPath()).filePath("sandbox.cfg")); + + QString resourcePath = pConfig->getResourcePath(); + + emit initializationProgressUpdate(0, tr("fonts")); + + FontUtils::initializeFonts(resourcePath); // takes a long time + + // Set the visibility of tooltips, default "1" = ON + m_toolTipsCfg = static_cast( + pConfig->getValue(ConfigKey("[Controls]", "Tooltips"), + static_cast(mixxx::TooltipsPreference::TOOLTIPS_ON))); + + emit initializationProgressUpdate(10, tr("database")); + m_pDbConnectionPool = MixxxDb(pConfig).connectionPool(); + if (!m_pDbConnectionPool) { + exit(-1); + } + // Create a connection for the main thread + m_pDbConnectionPool->createThreadLocalConnection(); + if (!initializeDatabase()) { + exit(-1); + } + + auto pChannelHandleFactory = std::make_shared(); + + emit initializationProgressUpdate(20, tr("effects")); + m_pEffectsManager = std::make_shared(this, pConfig, pChannelHandleFactory); + + m_pEngine = std::make_shared( + pConfig, + "[Master]", + m_pEffectsManager.get(), + pChannelHandleFactory, + true); + + // Create effect backends. We do this after creating EngineMaster to allow + // effect backends to refer to controls that are produced by the engine. + BuiltInBackend* pBuiltInBackend = new BuiltInBackend(m_pEffectsManager.get()); + m_pEffectsManager->addEffectsBackend(pBuiltInBackend); +#ifdef __LILV__ + m_pLV2Backend = new LV2Backend(m_pEffectsManager.get()); + // EffectsManager takes ownership + m_pEffectsManager->addEffectsBackend(m_pLV2Backend); +#else + m_pLV2Backend = nullptr; +#endif + + m_pEffectsManager->setup(); + + emit initializationProgressUpdate(30, tr("audio interface")); + // Although m_pSoundManager is created here, m_pSoundManager->setupDevices() + // needs to be called after m_pPlayerManager registers sound IO for each EngineChannel. + m_pSoundManager = std::make_shared(pConfig, m_pEngine.get()); + m_pEngine->registerNonEngineChannelSoundIO(m_pSoundManager.get()); + + m_pRecordingManager = std::make_shared(pConfig, m_pEngine.get()); + +#ifdef __BROADCAST__ + m_pBroadcastManager = std::make_shared( + m_pSettingsManager.get(), + m_pSoundManager.get()); +#endif + +#ifdef __VINYLCONTROL__ + m_pVCManager = std::make_shared(this, pConfig, m_pSoundManager.get()); +#else + m_pVCManager = nullptr; +#endif + + emit initializationProgressUpdate(40, tr("decks")); + // Create the player manager. (long) + m_pPlayerManager = std::make_shared( + pConfig, + m_pSoundManager.get(), + m_pEffectsManager.get(), + m_pEngine.get()); + // TODO: connect input not configured error dialog slots + PlayerInfo::create(); + + for (int i = 0; i < kMicrophoneCount; ++i) { + m_pPlayerManager->addMicrophone(); + } + + for (int i = 0; i < kAuxiliaryCount; ++i) { + m_pPlayerManager->addAuxiliary(); + } + + m_pPlayerManager->addConfiguredDecks(); + m_pPlayerManager->addSampler(); + m_pPlayerManager->addSampler(); + m_pPlayerManager->addSampler(); + m_pPlayerManager->addSampler(); + m_pPlayerManager->addPreviewDeck(); + + m_pEffectsManager->loadEffectChains(); + +#ifdef __VINYLCONTROL__ + m_pVCManager->init(); +#endif + + emit initializationProgressUpdate(50, tr("library")); + CoverArtCache::createInstance(); + + m_pTrackCollectionManager = std::make_shared( + this, + pConfig, + m_pDbConnectionPool); + + m_pLibrary = std::make_shared( + this, + pConfig, + m_pDbConnectionPool, + m_pTrackCollectionManager.get(), + m_pPlayerManager.get(), + m_pRecordingManager.get()); + + // Binding the PlayManager to the Library may already trigger + // loading of tracks which requires that the GlobalTrackCache has + // been created. Otherwise Mixxx might hang when accessing + // the uninitialized singleton instance! + m_pPlayerManager->bindToLibrary(m_pLibrary.get()); + + bool hasChanged_MusicDir = false; + + QStringList dirs = m_pLibrary->getDirs(); + if (dirs.size() < 1) { + // TODO(XXX) this needs to be smarter, we can't distinguish between an empty + // path return value (not sure if this is normally possible, but it is + // possible with the Windows 7 "Music" library, which is what + // QStandardPaths::writableLocation(QStandardPaths::MusicLocation) + // resolves to) and a user hitting 'cancel'. If we get a blank return + // but the user didn't hit cancel, we need to know this and let the + // user take some course of action -- bkgood + QString fd = QFileDialog::getExistingDirectory(nullptr, + tr("Choose music library directory"), + QStandardPaths::writableLocation( + QStandardPaths::MusicLocation)); + if (!fd.isEmpty()) { + // adds Folder to database. + m_pLibrary->slotRequestAddDir(fd); + hasChanged_MusicDir = true; + } + } + + emit initializationProgressUpdate(60, tr("controllers")); + // Initialize controller sub-system, + // but do not set up controllers until the end of the application startup + // (long) + qDebug() << "Creating ControllerManager"; + m_pControllerManager = std::make_shared(pConfig); + + // Inhibit the screensaver if the option is set. (Do it before creating the preferences dialog) + int inhibit = pConfig->getValue(ConfigKey("[Config]", "InhibitScreensaver"), -1); + if (inhibit == -1) { + inhibit = static_cast(mixxx::ScreenSaverPreference::PREVENT_ON); + pConfig->setValue(ConfigKey("[Config]", "InhibitScreensaver"), inhibit); + } + m_inhibitScreensaver = static_cast(inhibit); + if (m_inhibitScreensaver == mixxx::ScreenSaverPreference::PREVENT_ON) { + mixxx::ScreenSaverHelper::inhibit(); + } + + // Wait until all other ControlObjects are set up before initializing + // controllers + m_pControllerManager->setUpDevices(); + + // Scan the library for new files and directories + bool rescan = pConfig->getValue( + ConfigKey("[Library]", "RescanOnStartup")); + // rescan the library if we get a new plugin + QList prev_plugins_list = + pConfig->getValueString( + ConfigKey("[Library]", "SupportedFileExtensions")) + .split(',', +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + Qt::SkipEmptyParts); +#else + QString::SkipEmptyParts); +#endif + + // TODO: QSet::fromList(const QList&) is deprecated and should be + // replaced with QSet(list.begin(), list.end()). + // However, the proposed alternative has just been introduced in Qt + // 5.14. Until the minimum required Qt version of Mixxx is increased, + // we need a version check here + QSet prev_plugins = +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + QSet(prev_plugins_list.begin(), prev_plugins_list.end()); +#else + QSet::fromList(prev_plugins_list); +#endif + + const QList curr_plugins_list = SoundSourceProxy::getSupportedFileExtensions(); + QSet curr_plugins = +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + QSet(curr_plugins_list.begin(), curr_plugins_list.end()); +#else + QSet::fromList(curr_plugins_list); +#endif + + rescan = rescan || (prev_plugins != curr_plugins); + pConfig->set(ConfigKey("[Library]", "SupportedFileExtensions"), curr_plugins_list.join(",")); + + // Scan the library directory. Do this after the skinloader has + // loaded a skin, see Bug #1047435 + if (rescan || hasChanged_MusicDir || m_pSettingsManager->shouldRescanLibrary()) { + m_pTrackCollectionManager->startLibraryScan(); + } + + // This has to be done before m_pSoundManager->setupDevices() + // https://bugs.launchpad.net/mixxx/+bug/1758189 + m_pPlayerManager->loadSamplers(); + + // Load tracks in args.qlMusicFiles (command line arguments) into player + // 1 and 2: + const QList& musicFiles = m_cmdlineArgs.getMusicFiles(); + for (int i = 0; i < (int)m_pPlayerManager->numDecks() && i < musicFiles.count(); ++i) { + if (SoundSourceProxy::isFileNameSupported(musicFiles.at(i))) { + m_pPlayerManager->slotLoadToDeck(musicFiles.at(i), i + 1); + } + } +} + +void CoreServices::initializeKeyboard() { + UserSettingsPointer pConfig = m_pSettingsManager->settings(); + QString resourcePath = pConfig->getResourcePath(); + + // Set the default value in settings file + if (pConfig->getValueString(ConfigKey("[Keyboard]", "Enabled")).length() == 0) + pConfig->set(ConfigKey("[Keyboard]", "Enabled"), ConfigValue(1)); + + // Read keyboard configuration and set kdbConfig object in WWidget + // Check first in user's Mixxx directory + QString userKeyboard = QDir(pConfig->getSettingsPath()).filePath("Custom.kbd.cfg"); + + // Empty keyboard configuration + m_pKbdConfigEmpty = std::make_shared>(QString()); + + if (QFile::exists(userKeyboard)) { + qDebug() << "Found and will use custom keyboard preset" << userKeyboard; + m_pKbdConfig = std::make_shared>(userKeyboard); + } else { + // Default to the locale for the main input method (e.g. keyboard). + QLocale locale = inputLocale(); + + // check if a default keyboard exists + QString defaultKeyboard = QString(resourcePath).append("keyboard/"); + defaultKeyboard += locale.name(); + defaultKeyboard += ".kbd.cfg"; + qDebug() << "Found and will use default keyboard preset" << defaultKeyboard; + + if (!QFile::exists(defaultKeyboard)) { + qDebug() << defaultKeyboard << " not found, using en_US.kbd.cfg"; + defaultKeyboard = QString(resourcePath).append("keyboard/").append("en_US.kbd.cfg"); + if (!QFile::exists(defaultKeyboard)) { + qDebug() << defaultKeyboard << " not found, starting without shortcuts"; + defaultKeyboard = ""; + } + } + m_pKbdConfig = std::make_shared>(defaultKeyboard); + } + + // TODO(XXX) leak pKbdConfig, KeyboardEventFilter owns it? Maybe roll all keyboard + // initialization into KeyboardEventFilter + // Workaround for today: KeyboardEventFilter calls delete + bool keyboardShortcutsEnabled = pConfig->getValue( + ConfigKey("[Keyboard]", "Enabled")); + m_pKeyboardEventFilter = std::make_shared( + keyboardShortcutsEnabled ? m_pKbdConfig.get() : m_pKbdConfigEmpty.get()); +} + +void CoreServices::slotOptionsKeyboard(bool toggle) { + UserSettingsPointer pConfig = m_pSettingsManager->settings(); + if (toggle) { + //qDebug() << "Enable keyboard shortcuts/mappings"; + m_pKeyboardEventFilter->setKeyboardConfig(m_pKbdConfig.get()); + pConfig->set(ConfigKey("[Keyboard]", "Enabled"), ConfigValue(1)); + } else { + //qDebug() << "Disable keyboard shortcuts/mappings"; + m_pKeyboardEventFilter->setKeyboardConfig(m_pKbdConfigEmpty.get()); + pConfig->set(ConfigKey("[Keyboard]", "Enabled"), ConfigValue(0)); + } +} + +bool CoreServices::initializeDatabase() { + kLogger.info() << "Connecting to database"; + QSqlDatabase dbConnection = mixxx::DbConnectionPooled(m_pDbConnectionPool); + if (!dbConnection.isOpen()) { + QMessageBox::critical(0, + tr("Cannot open database"), + tr("Unable to establish a database connection.\n" + "Mixxx requires QT with SQLite support. Please read " + "the Qt SQL driver documentation for information on how " + "to build it.\n\n" + "Click OK to exit."), + QMessageBox::Ok); + return false; + } + + kLogger.info() << "Initializing or upgrading database schema"; + return MixxxDb::initDatabaseSchema(dbConnection); +} + +void CoreServices::shutdown() { + Timer t("CoreServices::shutdown"); + t.start(); + + if (m_inhibitScreensaver != mixxx::ScreenSaverPreference::PREVENT_OFF) { + mixxx::ScreenSaverHelper::uninhibit(); + } + + // Stop all pending library operations + qDebug() << t.elapsed(false).debugMillisWithUnit() << "stopping pending Library tasks"; + m_pTrackCollectionManager->stopLibraryScan(); + m_pLibrary->stopPendingTasks(); + + qDebug() << t.elapsed(false).debugMillisWithUnit() << "saving configuration"; + m_pSettingsManager->save(); + + // SoundManager depend on Engine and Config + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting SoundManager"; + CLEAR_AND_CHECK_DELETED(m_pSoundManager); + + // ControllerManager depends on Config + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting ControllerManager"; + CLEAR_AND_CHECK_DELETED(m_pControllerManager); + +#ifdef __VINYLCONTROL__ + // VinylControlManager depends on a CO the engine owns + // (vinylcontrol_enabled in VinylControlControl) + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting VinylControlManager"; + CLEAR_AND_CHECK_DELETED(m_pVCManager); +#endif + + // CoverArtCache is fairly independent of everything else. + CoverArtCache::destroy(); + + // PlayerManager depends on Engine, SoundManager, VinylControlManager, and Config + // The player manager has to be deleted before the library to ensure + // that all modified track metadata of loaded tracks is saved. + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting PlayerManager"; + CLEAR_AND_CHECK_DELETED(m_pPlayerManager); + + // Destroy PlayerInfo explicitly to release the track + // pointers of tracks that were still loaded in decks + // or samplers when PlayerManager was destroyed! + PlayerInfo::destroy(); + + // Delete the library after the view so there are no dangling pointers to + // the data models. + // Depends on RecordingManager and PlayerManager + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting Library"; + CLEAR_AND_CHECK_DELETED(m_pLibrary); + + // RecordingManager depends on config, engine + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting RecordingManager"; + CLEAR_AND_CHECK_DELETED(m_pRecordingManager); + +#ifdef __BROADCAST__ + // BroadcastManager depends on config, engine + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting BroadcastManager"; + CLEAR_AND_CHECK_DELETED(m_pBroadcastManager); +#endif + + // EngineMaster depends on Config and m_pEffectsManager. + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting EngineMaster"; + CLEAR_AND_CHECK_DELETED(m_pEngine); + + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting EffectsManager"; + CLEAR_AND_CHECK_DELETED(m_pEffectsManager); + + // Delete the track collections after all internal track pointers + // in other components have been released by deleting those components + // beforehand! + qDebug() << t.elapsed(false).debugMillisWithUnit() << "detaching all track collections"; + CLEAR_AND_CHECK_DELETED(m_pTrackCollectionManager); + + qDebug() << t.elapsed(false).debugMillisWithUnit() << "closing database connection(s)"; + m_pDbConnectionPool->destroyThreadLocalConnection(); + m_pDbConnectionPool.reset(); // should drop the last reference + + // HACK: Save config again. We saved it once before doing some dangerous + // stuff. We only really want to save it here, but the first one was just + // a precaution. The earlier one can be removed when stuff is more stable + // at exit. + m_pSettingsManager->save(); + + // Check for leaked ControlObjects and give warnings. + { + const QList> leakedControls = + ControlDoublePrivate::takeAllInstances(); + if (!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(); + } + } + DEBUG_ASSERT(!"Controls were leaked!"); + } + // Finally drop all shared pointers by exiting this scope + } + + Sandbox::shutdown(); + + qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting SettingsManager"; + m_pSettingsManager.reset(); + + CLEAR_AND_CHECK_DELETED(m_pKeyboardEventFilter); + CLEAR_AND_CHECK_DELETED(m_pKbdConfig); + CLEAR_AND_CHECK_DELETED(m_pKbdConfigEmpty); + + t.elapsed(true); + // Report the total time we have been running. + m_runtime_timer.elapsed(true); + + if (m_cmdlineArgs.getDeveloper()) { + StatsManager::destroy(); + } +} + +} // namespace mixxx diff --git a/src/coreservices.h b/src/coreservices.h new file mode 100644 index 00000000000..33125edfcf7 --- /dev/null +++ b/src/coreservices.h @@ -0,0 +1,143 @@ +#pragma once + +class QApplication; +class CmdlineArgs; +class KeyboardEventFilter; +class EffectsManager; +class EngineMaster; +class SoundManager; +class PlayerManager; +class RecordingManager; +class BroadcastManager; +class ControllerManager; +class VinylControlManager; +class TrackCollectionManager; +class Library; +class LV2Backend; + +#include "preferences/configobject.h" +#include "preferences/constants.h" +#include "preferences/settingsmanager.h" +#include "soundio/sounddeviceerror.h" +#include "util/cmdlineargs.h" +#include "util/timer.h" + +namespace mixxx { + +class DbConnectionPool; + +class CoreServices : public QObject { + Q_OBJECT + + public: + CoreServices(const CmdlineArgs& args); + ~CoreServices() = default; + + void initializeSettings(); + // FIXME: should be private, but WMainMenuBar needs it initialized early + void initializeKeyboard(); + void initialize(QApplication* pApp); + void shutdown(); + + std::shared_ptr getKeyboardEventFilter() const { + return m_pKeyboardEventFilter; + } + + std::shared_ptr> getKeyboardConfig() const { + return m_pKbdConfig; + } + + std::shared_ptr getSoundManager() const { + return m_pSoundManager; + } + + std::shared_ptr getPlayerManager() const { + return m_pPlayerManager; + } + + std::shared_ptr getRecordingManager() const { + return m_pRecordingManager; + } + + std::shared_ptr getBroadcastManager() const { + return m_pBroadcastManager; + } + + std::shared_ptr getControllerManager() const { + return m_pControllerManager; + } + + std::shared_ptr getVinylControlManager() const { + return m_pVCManager; + } + + LV2Backend* getLV2Backend() const { + return m_pLV2Backend; + } + + std::shared_ptr getEffectsManager() const { + return m_pEffectsManager; + } + + std::shared_ptr getLibrary() const { + return m_pLibrary; + } + + std::shared_ptr getTrackCollectionManager() const { + return m_pTrackCollectionManager; + } + + std::shared_ptr getSettingsManager() const { + return m_pSettingsManager; + } + + UserSettingsPointer getSettings() const { + return m_pSettingsManager->settings(); + } + + signals: + void initializationProgressUpdate(int progress, const QString& serviceName); + + public slots: + void slotOptionsKeyboard(bool toggle); + + private: + bool initializeDatabase(); + + std::shared_ptr m_pSettingsManager; + std::shared_ptr m_pEffectsManager; + // owned by EffectsManager + LV2Backend* m_pLV2Backend; + std::shared_ptr m_pEngine; + std::shared_ptr m_pSoundManager; + std::shared_ptr m_pPlayerManager; + std::shared_ptr m_pRecordingManager; +#ifdef __BROADCAST__ + std::shared_ptr m_pBroadcastManager; +#endif + std::shared_ptr m_pControllerManager; + + std::shared_ptr m_pVCManager; + + std::shared_ptr m_pDbConnectionPool; + std::shared_ptr m_pTrackCollectionManager; + std::shared_ptr m_pLibrary; + + std::shared_ptr m_pKeyboardEventFilter; + std::shared_ptr> m_pKbdConfig; + std::shared_ptr> m_pKbdConfigEmpty; + + TooltipsPreference m_toolTipsCfg; + + Timer m_runtime_timer; + const CmdlineArgs& m_cmdlineArgs; + + ScreenSaverPreference m_inhibitScreensaver; + + QSet m_skinCreatedControls; + + static const int kMicrophoneCount; + static const int kAuxiliaryCount; +}; + +} // namespace mixxx diff --git a/src/main.cpp b/src/main.cpp index 4cf913ed125..12aa7f1e0eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,15 +1,16 @@ -#include -#include -#include #include -#include +#include #include +#include #include +#include +#include +#include "coreservices.h" +#include "errordialoghandler.h" #include "mixxx.h" #include "mixxxapplication.h" #include "sources/soundsourceproxy.h" -#include "errordialoghandler.h" #include "util/cmdlineargs.h" #include "util/console.h" #include "util/logging.h" @@ -26,11 +27,11 @@ constexpr int kFatalErrorOnStartupExitCode = 1; constexpr int kParseCmdlineArgsErrorExitCode = 2; int runMixxx(MixxxApplication* app, const CmdlineArgs& args) { - MixxxMainWindow mainWindow(app, args); + auto coreServices = std::make_shared(args); + MixxxMainWindow mainWindow(app, coreServices); // If startup produced a fatal error, then don't even start the // Qt event loop. if (ErrorDialogHandler::instance()->checkError()) { - mainWindow.finalize(); return kFatalErrorOnStartupExitCode; } else { qDebug() << "Displaying main window"; diff --git a/src/mixer/basetrackplayer.cpp b/src/mixer/basetrackplayer.cpp index 92e43b53ebb..9b336d9b161 100644 --- a/src/mixer/basetrackplayer.cpp +++ b/src/mixer/basetrackplayer.cpp @@ -40,7 +40,6 @@ BaseTrackPlayerImpl::BaseTrackPlayerImpl( UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineChannel::ChannelOrientation defaultOrientation, const ChannelHandleAndGroup& handleGroup, bool defaultMaster, @@ -193,8 +192,6 @@ BaseTrackPlayerImpl::BaseTrackPlayerImpl( m_pRateRatio = make_parented(getGroup(), "rate_ratio", this); m_pPitchAdjust = make_parented(getGroup(), "pitch_adjust", this); - - pVisualsManager->addDeck(getGroup()); } BaseTrackPlayerImpl::~BaseTrackPlayerImpl() { diff --git a/src/mixer/basetrackplayer.h b/src/mixer/basetrackplayer.h index 8e6186d99f2..87bceec0b74 100644 --- a/src/mixer/basetrackplayer.h +++ b/src/mixer/basetrackplayer.h @@ -57,7 +57,6 @@ class BaseTrackPlayerImpl : public BaseTrackPlayer { UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineChannel::ChannelOrientation defaultOrientation, const ChannelHandleAndGroup& handleGroup, bool defaultMaster, diff --git a/src/mixer/deck.cpp b/src/mixer/deck.cpp index 06be4a5bbf1..b3a1effe9c8 100644 --- a/src/mixer/deck.cpp +++ b/src/mixer/deck.cpp @@ -6,14 +6,12 @@ Deck::Deck(QObject* pParent, UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineChannel::ChannelOrientation defaultOrientation, const ChannelHandleAndGroup& handleGroup) : BaseTrackPlayerImpl(pParent, pConfig, pMixingEngine, pEffectsManager, - pVisualsManager, defaultOrientation, handleGroup, /*defaultMaster*/ true, diff --git a/src/mixer/deck.h b/src/mixer/deck.h index f53dcd3893c..f6c47a1ebb3 100644 --- a/src/mixer/deck.h +++ b/src/mixer/deck.h @@ -11,7 +11,6 @@ class Deck : public BaseTrackPlayerImpl { UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineChannel::ChannelOrientation defaultOrientation, const ChannelHandleAndGroup& handleGroup); ~Deck() override = default; diff --git a/src/mixer/playermanager.cpp b/src/mixer/playermanager.cpp index 75bb78ca42f..f608c544059 100644 --- a/src/mixer/playermanager.cpp +++ b/src/mixer/playermanager.cpp @@ -42,13 +42,11 @@ QAtomicPointer PlayerManager::m_pCOPNumPreviewDecks; PlayerManager::PlayerManager(UserSettingsPointer pConfig, SoundManager* pSoundManager, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineMaster* pEngine) : m_mutex(QMutex::Recursive), m_pConfig(pConfig), m_pSoundManager(pSoundManager), m_pEffectsManager(pEffectsManager), - m_pVisualsManager(pVisualsManager), m_pEngine(pEngine), // NOTE(XXX) LegacySkinParser relies on these controls being Controls // and not ControlProxies. @@ -157,6 +155,20 @@ void PlayerManager::bindToLibrary(Library* pLibrary) { } } +QStringList PlayerManager::getVisualPlayerGroups() { + QStringList groups; + for (const auto& pDeck : std::as_const(m_decks)) { + groups.append(pDeck->getGroup()); + } + for (const auto& pPreview : std::as_const(m_previewDecks)) { + groups.append(pPreview->getGroup()); + } + for (const auto& pSampler : std::as_const(m_samplers)) { + groups.append(pSampler->getGroup()); + } + return groups; +} + // static bool PlayerManager::isDeckGroup(const QString& group, int* number) { if (!group.startsWith("[Channel")) { @@ -374,7 +386,6 @@ void PlayerManager::addDeckInner() { m_pConfig, m_pEngine, m_pEffectsManager, - m_pVisualsManager, deckIndex % 2 == 1 ? EngineChannel::RIGHT : EngineChannel::LEFT, handleGroup); connect(pDeck->getEngineDeck(), @@ -452,7 +463,6 @@ void PlayerManager::addSamplerInner() { m_pConfig, m_pEngine, m_pEffectsManager, - m_pVisualsManager, orientation, handleGroup); if (m_pTrackAnalysisScheduler) { @@ -486,7 +496,6 @@ void PlayerManager::addPreviewDeckInner() { m_pConfig, m_pEngine, m_pEffectsManager, - m_pVisualsManager, orientation, handleGroup); if (m_pTrackAnalysisScheduler) { diff --git a/src/mixer/playermanager.h b/src/mixer/playermanager.h index eaab5d5c128..2a6ddce2c4c 100644 --- a/src/mixer/playermanager.h +++ b/src/mixer/playermanager.h @@ -58,7 +58,6 @@ class PlayerManager : public QObject, public PlayerManagerInterface { PlayerManager(UserSettingsPointer pConfig, SoundManager* pSoundManager, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineMaster* pEngine); ~PlayerManager() override; @@ -135,6 +134,8 @@ class PlayerManager : public QObject, public PlayerManagerInterface { // must exist at least for the lifetime of this instance. void bindToLibrary(Library* pLibrary); + QStringList getVisualPlayerGroups(); + // Returns the group for the ith sampler where i is zero indexed static QString groupForSampler(int i) { DEBUG_ASSERT(i >= 0); @@ -258,7 +259,6 @@ class PlayerManager : public QObject, public PlayerManagerInterface { UserSettingsPointer m_pConfig; SoundManager* m_pSoundManager; EffectsManager* m_pEffectsManager; - VisualsManager* m_pVisualsManager; EngineMaster* m_pEngine; SamplerBank* m_pSamplerBank; ControlObject* m_pCONumDecks; diff --git a/src/mixer/previewdeck.cpp b/src/mixer/previewdeck.cpp index dee63bfb584..cd44e0aa1f6 100644 --- a/src/mixer/previewdeck.cpp +++ b/src/mixer/previewdeck.cpp @@ -6,14 +6,12 @@ PreviewDeck::PreviewDeck(QObject* pParent, UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineChannel::ChannelOrientation defaultOrientation, const ChannelHandleAndGroup& handleGroup) : BaseTrackPlayerImpl(pParent, pConfig, pMixingEngine, pEffectsManager, - pVisualsManager, defaultOrientation, handleGroup, /*defaultMaster*/ false, diff --git a/src/mixer/previewdeck.h b/src/mixer/previewdeck.h index 2da64603c49..ceca7f6ae2d 100644 --- a/src/mixer/previewdeck.h +++ b/src/mixer/previewdeck.h @@ -9,7 +9,6 @@ class PreviewDeck : public BaseTrackPlayerImpl { UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineChannel::ChannelOrientation defaultOrientation, const ChannelHandleAndGroup& handleGroup); ~PreviewDeck() override = default; diff --git a/src/mixer/sampler.cpp b/src/mixer/sampler.cpp index 1ee1aef8c6c..697fd8687d5 100644 --- a/src/mixer/sampler.cpp +++ b/src/mixer/sampler.cpp @@ -7,14 +7,12 @@ Sampler::Sampler(QObject* pParent, UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineChannel::ChannelOrientation defaultOrientation, const ChannelHandleAndGroup& handleGroup) : BaseTrackPlayerImpl(pParent, pConfig, pMixingEngine, pEffectsManager, - pVisualsManager, defaultOrientation, handleGroup, /*defaultMaster*/ true, diff --git a/src/mixer/sampler.h b/src/mixer/sampler.h index f17cbc4ccab..213b2063798 100644 --- a/src/mixer/sampler.h +++ b/src/mixer/sampler.h @@ -9,7 +9,6 @@ class Sampler : public BaseTrackPlayerImpl { UserSettingsPointer pConfig, EngineMaster* pMixingEngine, EffectsManager* pEffectsManager, - VisualsManager* pVisualsManager, EngineChannel::ChannelOrientation defaultOrientation, const ChannelHandleAndGroup& handleGroup); ~Sampler() override = default; diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 3add3279d9f..8b56ac1d5a2 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -82,116 +82,23 @@ #undef min #endif -namespace { - -const mixxx::Logger kLogger("MixxxMainWindow"); - -// hack around https://gitlab.freedesktop.org/xorg/lib/libx11/issues/25 -// https://bugs.launchpad.net/mixxx/+bug/1805559 -#if defined(Q_OS_LINUX) -typedef Bool (*WireToErrorType)(Display*, XErrorEvent*, xError*); - -const int NUM_HANDLERS = 256; -WireToErrorType __oldHandlers[NUM_HANDLERS] = {0}; - -Bool __xErrorHandler(Display* display, XErrorEvent* event, xError* error) { - // Call any previous handler first in case it needs to do real work. - auto code = static_cast(event->error_code); - if (__oldHandlers[code] != NULL) { - __oldHandlers[code](display, event, error); - } - - // Always return false so the error does not get passed to the normal - // application defined handler. - return False; -} - -#endif - -inline QLocale inputLocale() { - // Use the default config for local keyboard - QInputMethod* pInputMethod = QGuiApplication::inputMethod(); - return pInputMethod ? pInputMethod->locale() : - QLocale(QLocale::English); -} - -} // anonymous namespace - -// static -const int MixxxMainWindow::kMicrophoneCount = 4; -// static -const int MixxxMainWindow::kAuxiliaryCount = 4; - -MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) - : m_pCentralWidget(nullptr), +MixxxMainWindow::MixxxMainWindow( + QApplication* pApp, std::shared_ptr pCoreServices) + : m_pCoreServices(pCoreServices), + m_pCentralWidget(nullptr), m_pLaunchImage(nullptr), - m_pEffectsManager(nullptr), - m_pEngine(nullptr), - m_pSkinLoader(nullptr), - m_pSoundManager(nullptr), - m_pPlayerManager(nullptr), - m_pRecordingManager(nullptr), -#ifdef __BROADCAST__ - m_pBroadcastManager(nullptr), -#endif - m_pControllerManager(nullptr), m_pGuiTick(nullptr), -#ifdef __VINYLCONTROL__ - m_pVCManager(nullptr), -#endif - m_pKeyboard(nullptr), - m_pLibrary(nullptr), m_pDeveloperToolsDlg(nullptr), - m_pPrefDlg(nullptr), - m_pKbdConfig(nullptr), - m_pKbdConfigEmpty(nullptr), m_toolTipsCfg(mixxx::TooltipsPreference::TOOLTIPS_ON), - m_runtime_timer("MixxxMainWindow::runtime"), - m_cmdLineArgs(args), m_pTouchShift(nullptr) { - m_runtime_timer.start(); - mixxx::Time::start(); - - QString settingsPath = args.getSettingsPath(); -#ifdef __APPLE__ - if (!args.getSettingsPathSet()) { - settingsPath = Sandbox::migrateOldSettings(); - } -#endif - - mixxx::Logging::initialize( - settingsPath, - args.getLogLevel(), - args.getLogFlushLevel(), - args.getDebugAssertBreak()); - - VERIFY_OR_DEBUG_ASSERT(SoundSourceProxy::registerProviders()) { - qCritical() << "Failed to register any SoundSource providers"; - return; - } - - Version::logBuildDetails(); - - // Only record stats in developer mode. - if (m_cmdLineArgs.getDeveloper()) { - StatsManager::createInstance(); - } - - m_pSettingsManager = std::make_unique(args.getSettingsPath()); - - initializeKeyboard(); - installEventFilter(m_pKeyboard); - - // Menubar depends on translations. - mixxx::Translations::initializeTranslations( - m_pSettingsManager->settings(), pApp, args.getLocale()); - + m_pCoreServices->initializeSettings(); + m_pCoreServices->initializeKeyboard(); + // These depend on the settings createMenuBar(); - initializeWindow(); - // First load launch image to show a the user a quick responds - m_pSkinLoader = new SkinLoader(m_pSettingsManager->settings()); + // Show launch image immediately so the user knows Mixxx is starting + m_pSkinLoader = std::make_unique(m_pCoreServices->getSettings()); m_pLaunchImage = m_pSkinLoader->loadLaunchImage(this); m_pCentralWidget = (QWidget*)m_pLaunchImage; setCentralWidget(m_pCentralWidget); @@ -199,221 +106,24 @@ MixxxMainWindow::MixxxMainWindow(QApplication* pApp, const CmdlineArgs& args) show(); pApp->processEvents(); - initialize(pApp, args); -} - -MixxxMainWindow::~MixxxMainWindow() { - finalize(); - // SkinLoader depends on Config; - delete m_pSkinLoader; -} - -void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { - ScopedTimer t("MixxxMainWindow::initialize"); - -#if defined(Q_OS_LINUX) - // XESetWireToError will segfault if running as a Wayland client - if (pApp->platformName() == QLatin1String("xcb")) { - for (auto i = 0; i < NUM_HANDLERS; ++i) { - XESetWireToError(QX11Info::display(), i, &__xErrorHandler); - } - } -#endif - - UserSettingsPointer pConfig = m_pSettingsManager->settings(); - - Sandbox::initialize(QDir(pConfig->getSettingsPath()).filePath("sandbox.cfg")); - - QString resourcePath = pConfig->getResourcePath(); - - FontUtils::initializeFonts(resourcePath); // takes a long time - - launchProgress(2); - - // Set the visibility of tooltips, default "1" = ON - m_toolTipsCfg = static_cast( - pConfig->getValue(ConfigKey("[Controls]", "Tooltips"), - static_cast(mixxx::TooltipsPreference::TOOLTIPS_ON))); - - m_pTouchShift = new ControlPushButton(ConfigKey("[Controls]", "touch_shift")); - - m_pDbConnectionPool = MixxxDb(pConfig).connectionPool(); - if (!m_pDbConnectionPool) { - // TODO(XXX) something a little more elegant - exit(-1); - } - // Create a connection for the main thread - m_pDbConnectionPool->createThreadLocalConnection(); - if (!initializeDatabase()) { - // TODO(XXX) something a little more elegant - exit(-1); - } - - auto pChannelHandleFactory = std::make_shared(); - - // Create the Effects subsystem. - m_pEffectsManager = new EffectsManager(this, pConfig, pChannelHandleFactory); - - // Starting the master (mixing of the channels and effects): - m_pEngine = new EngineMaster( - pConfig, - "[Master]", - m_pEffectsManager, - pChannelHandleFactory, - true); - - // Create effect backends. We do this after creating EngineMaster to allow - // effect backends to refer to controls that are produced by the engine. - BuiltInBackend* pBuiltInBackend = new BuiltInBackend(m_pEffectsManager); - m_pEffectsManager->addEffectsBackend(pBuiltInBackend); -#ifdef __LILV__ - LV2Backend* pLV2Backend = new LV2Backend(m_pEffectsManager); - m_pEffectsManager->addEffectsBackend(pLV2Backend); -#else - LV2Backend* pLV2Backend = nullptr; -#endif - - // Sets up the EffectChains and EffectRacks (long) - m_pEffectsManager->setup(); - - launchProgress(8); + connect( + m_pCoreServices.get(), + &mixxx::CoreServices::initializationProgressUpdate, + this, + &MixxxMainWindow::initializationProgressUpdate); - // Although m_pSoundManager is created here, m_pSoundManager->setupDevices() - // needs to be called after m_pPlayerManager registers sound IO for each EngineChannel. - m_pSoundManager = new SoundManager(pConfig, m_pEngine); - m_pEngine->registerNonEngineChannelSoundIO(m_pSoundManager); + m_pCoreServices->initialize(pApp); - m_pRecordingManager = new RecordingManager(pConfig, m_pEngine); + initializationProgressUpdate(65, tr("skin")); -#ifdef __BROADCAST__ - m_pBroadcastManager = new BroadcastManager( - m_pSettingsManager.get(), - m_pSoundManager); -#endif + installEventFilter(m_pCoreServices->getKeyboardEventFilter().get()); - launchProgress(11); - - // Needs to be created before CueControl (decks) and WTrackTableView. m_pGuiTick = new GuiTick(); m_pVisualsManager = new VisualsManager(); - -#ifdef __VINYLCONTROL__ - m_pVCManager = new VinylControlManager(this, pConfig, m_pSoundManager); -#else - m_pVCManager = NULL; -#endif - - // Create the player manager. (long) - m_pPlayerManager = new PlayerManager(pConfig, m_pSoundManager, - m_pEffectsManager, m_pVisualsManager, m_pEngine); - connect(m_pPlayerManager, - &PlayerManager::noMicrophoneInputConfigured, - this, - &MixxxMainWindow::slotNoMicrophoneInputConfigured); - connect(m_pPlayerManager, - &PlayerManager::noAuxiliaryInputConfigured, - this, - &MixxxMainWindow::slotNoAuxiliaryInputConfigured); - connect(m_pPlayerManager, - &PlayerManager::noDeckPassthroughInputConfigured, - this, - &MixxxMainWindow::slotNoDeckPassthroughInputConfigured); - connect(m_pPlayerManager, - &PlayerManager::noVinylControlInputConfigured, - this, - &MixxxMainWindow::slotNoVinylControlInputConfigured); - PlayerInfo::create(); - - for (int i = 0; i < kMicrophoneCount; ++i) { - m_pPlayerManager->addMicrophone(); - } - - for (int i = 0; i < kAuxiliaryCount; ++i) { - m_pPlayerManager->addAuxiliary(); + for (const auto& group : m_pCoreServices->getPlayerManager()->getVisualPlayerGroups()) { + m_pVisualsManager->addDeck(group); } - m_pPlayerManager->addConfiguredDecks(); - m_pPlayerManager->addSampler(); - m_pPlayerManager->addSampler(); - m_pPlayerManager->addSampler(); - m_pPlayerManager->addSampler(); - m_pPlayerManager->addPreviewDeck(); - - launchProgress(30); - - m_pEffectsManager->loadEffectChains(); - -#ifdef __VINYLCONTROL__ - m_pVCManager->init(); -#endif - -#ifdef __MODPLUG__ - // restore the configuration for the modplug library before trying to load a module - DlgPrefModplug* pModplugPrefs = new DlgPrefModplug(0, pConfig); - pModplugPrefs->loadSettings(); - pModplugPrefs->applySettings(); - delete pModplugPrefs; // not needed anymore -#endif - - CoverArtCache::createInstance(); - - launchProgress(30); - - m_pTrackCollectionManager = new TrackCollectionManager( - this, - pConfig, - m_pDbConnectionPool); - - launchProgress(35); - - m_pLibrary = new Library( - this, - pConfig, - m_pDbConnectionPool, - m_pTrackCollectionManager, - m_pPlayerManager, - m_pRecordingManager); - - // Binding the PlayManager to the Library may already trigger - // loading of tracks which requires that the GlobalTrackCache has - // been created. Otherwise Mixxx might hang when accessing - // the uninitialized singleton instance! - m_pPlayerManager->bindToLibrary(m_pLibrary); - - launchProgress(40); - - // Get Music dir - bool hasChanged_MusicDir = false; - - QStringList dirs = m_pLibrary->getDirs(); - if (dirs.size() < 1) { - // TODO(XXX) this needs to be smarter, we can't distinguish between an empty - // path return value (not sure if this is normally possible, but it is - // possible with the Windows 7 "Music" library, which is what - // QStandardPaths::writableLocation(QStandardPaths::MusicLocation) - // resolves to) and a user hitting 'cancel'. If we get a blank return - // but the user didn't hit cancel, we need to know this and let the - // user take some course of action -- bkgood - QString fd = QFileDialog::getExistingDirectory( - this, tr("Choose music library directory"), - QStandardPaths::writableLocation(QStandardPaths::MusicLocation)); - if (!fd.isEmpty()) { - // adds Folder to database. - m_pLibrary->slotRequestAddDir(fd); - hasChanged_MusicDir = true; - } - } - - // Call inits to invoke all other construction parts - - // Initialize controller sub-system, - // but do not set up controllers until the end of the application startup - // (long) - qDebug() << "Creating ControllerManager"; - m_pControllerManager = new ControllerManager(pConfig); - - launchProgress(47); - // Before creating the first skin we need to create a QGLWidget so that all // the QGLWidget's we create can use it as a shared QGLContext. if (!CmdlineArgs::Instance().getSafeMode() && QGLFormat::hasOpenGL()) { @@ -445,14 +155,12 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { } WaveformWidgetFactory::createInstance(); // takes a long time - WaveformWidgetFactory::instance()->setConfig(pConfig); + WaveformWidgetFactory::instance()->setConfig(m_pCoreServices->getSettings()); WaveformWidgetFactory::instance()->startVSync(m_pGuiTick, m_pVisualsManager); - launchProgress(52); - connect(this, &MixxxMainWindow::skinLoaded, - m_pLibrary, + m_pCoreServices->getLibrary().get(), &Library::onSkinLoadFinished); connect(this, @@ -460,40 +168,23 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { WaveformWidgetFactory::instance(), &WaveformWidgetFactory::slotSkinLoaded); - // Inhibit the screensaver if the option is set. (Do it before creating the preferences dialog) - int inhibit = pConfig->getValue(ConfigKey("[Config]","InhibitScreensaver"),-1); - if (inhibit == -1) { - inhibit = static_cast(mixxx::ScreenSaverPreference::PREVENT_ON); - pConfig->setValue(ConfigKey("[Config]","InhibitScreensaver"), inhibit); - } - m_inhibitScreensaver = static_cast(inhibit); - if (m_inhibitScreensaver == mixxx::ScreenSaverPreference::PREVENT_ON) { - mixxx::ScreenSaverHelper::inhibit(); - } - // Initialize preference dialog m_pPrefDlg = new DlgPreferences( this, - m_pSkinLoader, - m_pSoundManager, - m_pPlayerManager, - m_pControllerManager, - m_pVCManager, - pLV2Backend, - m_pEffectsManager, - m_pSettingsManager.get(), - m_pLibrary); + m_pSkinLoader.get(), + m_pCoreServices->getSoundManager().get(), + m_pCoreServices->getPlayerManager().get(), + m_pCoreServices->getControllerManager().get(), + m_pCoreServices->getVinylControlManager().get(), + m_pCoreServices->getLV2Backend(), + m_pCoreServices->getEffectsManager().get(), + m_pCoreServices->getSettingsManager().get(), + m_pCoreServices->getLibrary().get()); m_pPrefDlg->setWindowIcon(QIcon(":/images/mixxx_icon.svg")); m_pPrefDlg->setHidden(true); - launchProgress(60); - - // Connect signals to the menubar. Should be done before we go fullscreen - // and emit newSkinLoaded. connectMenuBar(); - launchProgress(63); - QWidget* oldWidget = m_pCentralWidget; // Load default styles that can be overridden by skins @@ -516,11 +207,6 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { m_pMenuBar->setStyleSheet(m_pCentralWidget->styleSheet()); } - // Fake a 100 % progress here. - // At a later place it will newer shown up, since it is - // immediately replaced by the real widget. - launchProgress(100); - // Check direct rendering and warn user if they don't have it if (!CmdlineArgs::Instance().getSafeMode()) { checkDirectRendering(); @@ -534,70 +220,18 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { // If we were told to start in fullscreen mode on the command-line or if // user chose always starts in fullscreen mode, then turn on fullscreen // mode. - bool fullscreenPref = pConfig->getValue( + bool fullscreenPref = m_pCoreServices->getSettings()->getValue( ConfigKey("[Config]", "StartInFullscreen")); - if (args.getStartInFullscreen() || fullscreenPref) { + if (CmdlineArgs::Instance().getStartInFullscreen() || fullscreenPref) { slotViewFullScreen(true); } emit skinLoaded(); - - // Wait until all other ControlObjects are set up before initializing - // controllers - m_pControllerManager->setUpDevices(); - - // Scan the library for new files and directories - bool rescan = pConfig->getValue( - ConfigKey("[Library]","RescanOnStartup")); - // rescan the library if we get a new plugin - QList prev_plugins_list = - pConfig->getValueString( - ConfigKey("[Library]", "SupportedFileExtensions")) - .split(',', -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - Qt::SkipEmptyParts); -#else - QString::SkipEmptyParts); -#endif - - // TODO: QSet::fromList(const QList&) is deprecated and should be - // replaced with QSet(list.begin(), list.end()). - // However, the proposed alternative has just been introduced in Qt - // 5.14. Until the minimum required Qt version of Mixxx is increased, - // we need a version check here - QSet prev_plugins = -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - QSet(prev_plugins_list.begin(), prev_plugins_list.end()); -#else - QSet::fromList(prev_plugins_list); -#endif - - const QList curr_plugins_list = SoundSourceProxy::getSupportedFileExtensions(); - QSet curr_plugins = -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - QSet(curr_plugins_list.begin(), curr_plugins_list.end()); -#else - QSet::fromList(curr_plugins_list); -#endif - - rescan = rescan || (prev_plugins != curr_plugins); - pConfig->set(ConfigKey("[Library]", "SupportedFileExtensions"), curr_plugins_list.join(",")); - - // Scan the library directory. Do this after the skinloader has - // loaded a skin, see Bug #1047435 - if (rescan || hasChanged_MusicDir || m_pSettingsManager->shouldRescanLibrary()) { - m_pTrackCollectionManager->startLibraryScan(); - } - - // This has to be done before m_pSoundManager->setupDevices() - // https://bugs.launchpad.net/mixxx/+bug/1758189 - m_pPlayerManager->loadSamplers(); - // Try open player device If that fails, the preference panel is opened. bool retryClicked; do { retryClicked = false; - SoundDeviceError result = m_pSoundManager->setupDevices(); + SoundDeviceError result = m_pCoreServices->getSoundManager()->setupDevices(); if (result == SOUNDDEVICE_ERROR_DEVICE_COUNT || result == SOUNDDEVICE_ERROR_EXCESSIVE_OUTPUT_CHANNEL) { if (soundDeviceBusyDlg(&retryClicked) != QDialog::Accepted) { @@ -616,7 +250,7 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { // In case persisting errors, the user has already received a message // box from the preferences dialog above. So we can watch here just the // output count. - while (m_pSoundManager->getConfig().getOutputs().count() == 0) { + while (m_pCoreServices->getSoundManager()->getConfig().getOutputs().count() == 0) { // Exit when we press the Exit button in the noSoundDlg dialog // only call it if result != OK bool continueClicked = false; @@ -624,61 +258,51 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { exit(0); } if (continueClicked) break; - } - - // Load tracks in args.qlMusicFiles (command line arguments) into player - // 1 and 2: - const QList& musicFiles = args.getMusicFiles(); - for (int i = 0; i < (int)m_pPlayerManager->numDecks() - && i < musicFiles.count(); ++i) { - if (SoundSourceProxy::isFileNameSupported(musicFiles.at(i))) { - m_pPlayerManager->slotLoadToDeck(musicFiles.at(i), i+1); - } } + // this has to be after the OpenGL widgets are created or depending on a + // million different variables the first waveform may be horribly + // corrupted. See bug 521509 -- bkgood ?? -- vrince + setCentralWidget(m_pCentralWidget); + // The launch image widget is automatically disposed, but we still have a + // pointer to it. + m_pLaunchImage = nullptr; + + connect(m_pCoreServices->getPlayerManager().get(), + &PlayerManager::noMicrophoneInputConfigured, + this, + &MixxxMainWindow::slotNoMicrophoneInputConfigured); + connect(m_pCoreServices->getPlayerManager().get(), + &PlayerManager::noAuxiliaryInputConfigured, + this, + &MixxxMainWindow::slotNoAuxiliaryInputConfigured); + connect(m_pCoreServices->getPlayerManager().get(), + &PlayerManager::noDeckPassthroughInputConfigured, + this, + &MixxxMainWindow::slotNoDeckPassthroughInputConfigured); + connect(m_pCoreServices->getPlayerManager().get(), + &PlayerManager::noVinylControlInputConfigured, + this, + &MixxxMainWindow::slotNoVinylControlInputConfigured); + connect(&PlayerInfo::instance(), &PlayerInfo::currentPlayingTrackChanged, this, &MixxxMainWindow::slotUpdateWindowTitle); - connect(&PlayerInfo::instance(), &PlayerInfo::currentPlayingDeckChanged, this, &MixxxMainWindow::slotChangedPlayingDeck); - - // this has to be after the OpenGL widgets are created or depending on a - // million different variables the first waveform may be horribly - // corrupted. See bug 521509 -- bkgood ?? -- vrince - setCentralWidget(m_pCentralWidget); - // The launch image widget is automatically disposed, but we still have a - // pointer to it. - m_pLaunchImage = nullptr; } -void MixxxMainWindow::finalize() { - Timer t("MixxxMainWindow::~finalize"); +MixxxMainWindow::~MixxxMainWindow() { + Timer t("~MixxxMainWindow"); t.start(); if (m_inhibitScreensaver != mixxx::ScreenSaverPreference::PREVENT_OFF) { mixxx::ScreenSaverHelper::uninhibit(); } - // Stop all pending library operations - qDebug() << t.elapsed(false).debugMillisWithUnit() << "stopping pending Library tasks"; - m_pTrackCollectionManager->stopLibraryScan(); - m_pLibrary->stopPendingTasks(); - - // Save the current window state (position, maximized, etc) - m_pSettingsManager->settings()->set(ConfigKey("[MainWindow]", "geometry"), - QString(saveGeometry().toBase64())); - m_pSettingsManager->settings()->set(ConfigKey("[MainWindow]", "state"), - QString(saveState().toBase64())); - - qDebug() << "Destroying MixxxMainWindow"; - - qDebug() << t.elapsed(false).debugMillisWithUnit() << "saving configuration"; - m_pSettingsManager->save(); - // GUI depends on KeyboardEventFilter, PlayerManager, Library qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting skin"; m_pCentralWidget = nullptr; @@ -719,62 +343,9 @@ void MixxxMainWindow::finalize() { qWarning() << "WMainMenuBar was not deleted by our sendPostedEvents trick."; } - // SoundManager depend on Engine and Config - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting SoundManager"; - delete m_pSoundManager; - - // ControllerManager depends on Config - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting ControllerManager"; - delete m_pControllerManager; - -#ifdef __VINYLCONTROL__ - // VinylControlManager depends on a CO the engine owns - // (vinylcontrol_enabled in VinylControlControl) - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting VinylControlManager"; - delete m_pVCManager; -#endif - - // CoverArtCache is fairly independent of everything else. - CoverArtCache::destroy(); - - // PlayerManager depends on Engine, SoundManager, VinylControlManager, and Config - // The player manager has to be deleted before the library to ensure - // that all modified track metadata of loaded tracks is saved. - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting PlayerManager"; - delete m_pPlayerManager; - - // Destroy PlayerInfo explicitly to release the track - // pointers of tracks that were still loaded in decks - // or samplers when PlayerManager was destroyed! - PlayerInfo::destroy(); - - // Delete the library after the view so there are no dangling pointers to - // the data models. - // Depends on RecordingManager and PlayerManager - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting Library"; - delete m_pLibrary; - - // RecordingManager depends on config, engine - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting RecordingManager"; - delete m_pRecordingManager; - -#ifdef __BROADCAST__ - // BroadcastManager depends on config, engine - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting BroadcastManager"; - delete m_pBroadcastManager; -#endif - - // EngineMaster depends on Config and m_pEffectsManager. - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting EngineMaster"; - delete m_pEngine; - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting DlgPreferences"; delete m_pPrefDlg; - // Must delete after EngineMaster and DlgPrefEq. - qDebug() << t.elapsed(false).debugMillisWithUnit() << "deleting EffectsManager"; - delete m_pEffectsManager; - delete m_pTouchShift; WaveformWidgetFactory::destroy(); @@ -782,80 +353,7 @@ void MixxxMainWindow::finalize() { delete m_pGuiTick; delete m_pVisualsManager; - // Delete the track collections after all internal track pointers - // in other components have been released by deleting those components - // beforehand! - qDebug() << t.elapsed(false).debugMillisWithUnit() << "detaching all track collections"; - delete m_pTrackCollectionManager; - - qDebug() << t.elapsed(false).debugMillisWithUnit() << "closing database connection(s)"; - m_pDbConnectionPool->destroyThreadLocalConnection(); - m_pDbConnectionPool.reset(); // should drop the last reference - - // HACK: Save config again. We saved it once before doing some dangerous - // stuff. We only really want to save it here, but the first one was just - // a precaution. The earlier one can be removed when stuff is more stable - // at exit. - m_pSettingsManager->save(); - - // Check for leaked ControlObjects and give warnings. - { - const QList> leakedControls = - ControlDoublePrivate::takeAllInstances(); - if (!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(); - } - } - DEBUG_ASSERT(!"Controls were leaked!"); - } - // 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; - delete m_pKbdConfigEmpty; - - t.elapsed(true); - // Report the total time we have been running. - m_runtime_timer.elapsed(true); - - if (m_cmdLineArgs.getDeveloper()) { - StatsManager::destroy(); - } -} - -bool MixxxMainWindow::initializeDatabase() { - kLogger.info() << "Connecting to database"; - QSqlDatabase dbConnection = mixxx::DbConnectionPooled(m_pDbConnectionPool); - if (!dbConnection.isOpen()) { - QMessageBox::critical(0, tr("Cannot open database"), - tr("Unable to establish a database connection.\n" - "Mixxx requires QT with SQLite support. Please read " - "the Qt SQL driver documentation for information on how " - "to build it.\n\n" - "Click OK to exit."), QMessageBox::Ok); - return false; - } - - kLogger.info() << "Initializing or upgrading database schema"; - return MixxxDb::initDatabaseSchema(dbConnection); + m_pCoreServices->shutdown(); } void MixxxMainWindow::initializeWindow() { @@ -873,62 +371,19 @@ void MixxxMainWindow::initializeWindow() { m_pMenuBar->setPalette(Pal); // Restore the current window state (position, maximized, etc) - restoreGeometry(QByteArray::fromBase64(m_pSettingsManager->settings()->getValueString( - ConfigKey("[MainWindow]", "geometry")).toUtf8())); - restoreState(QByteArray::fromBase64(m_pSettingsManager->settings()->getValueString( - ConfigKey("[MainWindow]", "state")).toUtf8())); + restoreGeometry(QByteArray::fromBase64( + m_pCoreServices->getSettings() + ->getValueString(ConfigKey("[MainWindow]", "geometry")) + .toUtf8())); + restoreState(QByteArray::fromBase64( + m_pCoreServices->getSettings() + ->getValueString(ConfigKey("[MainWindow]", "state")) + .toUtf8())); setWindowIcon(QIcon(":/images/mixxx_icon.svg")); slotUpdateWindowTitle(TrackPointer()); } -void MixxxMainWindow::initializeKeyboard() { - UserSettingsPointer pConfig = m_pSettingsManager->settings(); - QString resourcePath = pConfig->getResourcePath(); - - // Set the default value in settings file - if (pConfig->getValueString(ConfigKey("[Keyboard]","Enabled")).length() == 0) - pConfig->set(ConfigKey("[Keyboard]","Enabled"), ConfigValue(1)); - - // Read keyboard configuration and set kdbConfig object in WWidget - // Check first in user's Mixxx directory - QString userKeyboard = QDir(pConfig->getSettingsPath()).filePath("Custom.kbd.cfg"); - - // Empty keyboard configuration - m_pKbdConfigEmpty = new ConfigObject(QString()); - - if (QFile::exists(userKeyboard)) { - qDebug() << "Found and will use custom keyboard preset" << userKeyboard; - m_pKbdConfig = new ConfigObject(userKeyboard); - } else { - // Default to the locale for the main input method (e.g. keyboard). - QLocale locale = inputLocale(); - - // check if a default keyboard exists - QString defaultKeyboard = QString(resourcePath).append("keyboard/"); - defaultKeyboard += locale.name(); - defaultKeyboard += ".kbd.cfg"; - qDebug() << "Found and will use default keyboard preset" << defaultKeyboard; - - if (!QFile::exists(defaultKeyboard)) { - qDebug() << defaultKeyboard << " not found, using en_US.kbd.cfg"; - defaultKeyboard = QString(resourcePath).append("keyboard/").append("en_US.kbd.cfg"); - if (!QFile::exists(defaultKeyboard)) { - qDebug() << defaultKeyboard << " not found, starting without shortcuts"; - defaultKeyboard = ""; - } - } - m_pKbdConfig = new ConfigObject(defaultKeyboard); - } - - // TODO(XXX) leak pKbdConfig, KeyboardEventFilter owns it? Maybe roll all keyboard - // initialization into KeyboardEventFilter - // Workaround for today: KeyboardEventFilter calls delete - bool keyboardShortcutsEnabled = pConfig->getValue( - ConfigKey("[Keyboard]", "Enabled")); - m_pKeyboard = new KeyboardEventFilter(keyboardShortcutsEnabled ? m_pKbdConfig : m_pKbdConfigEmpty); -} - QDialog::DialogCode MixxxMainWindow::soundDeviceErrorDlg( const QString &title, const QString &text, bool* retryClicked) { QMessageBox msgBox; @@ -950,7 +405,7 @@ QDialog::DialogCode MixxxMainWindow::soundDeviceErrorDlg( msgBox.exec(); if (msgBox.clickedButton() == retryButton) { - m_pSoundManager->clearAndQueryDevices(); + m_pCoreServices->getSoundManager()->clearAndQueryDevices(); *retryClicked = true; return QDialog::Accepted; } else if (msgBox.clickedButton() == wikiButton) { @@ -961,7 +416,7 @@ QDialog::DialogCode MixxxMainWindow::soundDeviceErrorDlg( } else if (msgBox.clickedButton() == reconfigureButton) { msgBox.hide(); - m_pSoundManager->clearAndQueryDevices(); + m_pCoreServices->getSoundManager()->clearAndQueryDevices(); // This way of opening the dialog allows us to use it synchronously m_pPrefDlg->setWindowModality(Qt::ApplicationModal); m_pPrefDlg->exec(); @@ -981,26 +436,25 @@ QDialog::DialogCode MixxxMainWindow::soundDeviceBusyDlg(bool* retryClicked) { QString title(tr("Sound Device Busy")); QString text( "

" % - tr("Mixxx was unable to open all the configured sound devices.") + + tr("Mixxx was unable to open all the configured sound devices.") + "

" % - m_pSoundManager->getErrorDeviceName() % - " is used by another application or not plugged in." - "

    " - "
  • " % + m_pCoreServices->getSoundManager()->getErrorDeviceName() % + " is used by another application or not plugged in." + "

      " + "
    • " % tr("Retry after closing the other application " - "or reconnecting a sound device") % - "
    • " - "
    • " % + "or reconnecting a sound device") % + "
    • " + "
    • " % tr("Reconfigure Mixxx's sound device settings.") % - "
    • " - "
    • " % + "
    • " + "
    • " % tr("Get Help from the Mixxx Wiki.") % - "
    • " - "
    • " % + "
    • " + "
    • " % tr("Exit Mixxx.") % - "
    • " - "
    " - ); + "
  • " + "
"); return soundDeviceErrorDlg(title, text, retryClicked); } @@ -1008,26 +462,27 @@ QDialog::DialogCode MixxxMainWindow::soundDeviceBusyDlg(bool* retryClicked) { QDialog::DialogCode MixxxMainWindow::soundDeviceErrorMsgDlg( SoundDeviceError err, bool* retryClicked) { QString title(tr("Sound Device Error")); - QString text( - "

" % - tr("Mixxx was unable to open all the configured sound devices.") + + QString text("

" % + tr("Mixxx was unable to open all the configured sound " + "devices.") + "

" % - m_pSoundManager->getLastErrorMessage(err).replace("\n", "
") % - "

    " - "
  • " % + m_pCoreServices->getSoundManager() + ->getLastErrorMessage(err) + .replace("\n", "
    ") % + "

      " + "
    • " % tr("Retry after fixing an issue") % - "
    • " - "
    • " % + "
    • " + "
    • " % tr("Reconfigure Mixxx's sound device settings.") % - "
    • " - "
    • " % + "
    • " + "
    • " % tr("Get Help from the Mixxx Wiki.") % - "
    • " - "
    • " % + "
    • " + "
    • " % tr("Exit Mixxx.") % - "
    • " - "
    " - ); + "
  • " + "
"); return soundDeviceErrorDlg(title, text, retryClicked); } @@ -1101,8 +556,9 @@ void MixxxMainWindow::slotUpdateWindowTitle(TrackPointer pTrack) { void MixxxMainWindow::createMenuBar() { ScopedTimer t("MixxxMainWindow::createMenuBar"); - DEBUG_ASSERT(m_pKbdConfig != nullptr); - m_pMenuBar = make_parented(this, m_pSettingsManager->settings(), m_pKbdConfig); + DEBUG_ASSERT(m_pCoreServices->getKeyboardConfig()); + m_pMenuBar = make_parented( + this, m_pCoreServices->getSettings(), m_pCoreServices->getKeyboardConfig().get()); if (m_pCentralWidget) { m_pMenuBar->setStyleSheet(m_pCentralWidget->styleSheet()); } @@ -1140,8 +596,8 @@ void MixxxMainWindow::connectMenuBar() { // Keyboard shortcuts connect(m_pMenuBar, &WMainMenuBar::toggleKeyboardShortcuts, - this, - &MixxxMainWindow::slotOptionsKeyboard); + m_pCoreServices.get(), + &mixxx::CoreServices::slotOptionsKeyboard); // Help connect(m_pMenuBar, @@ -1159,82 +615,83 @@ void MixxxMainWindow::connectMenuBar() { this, &MixxxMainWindow::slotDeveloperTools); - if (m_pRecordingManager) { - connect(m_pRecordingManager, + if (m_pCoreServices->getRecordingManager()) { + connect(m_pCoreServices->getRecordingManager().get(), &RecordingManager::isRecording, m_pMenuBar, &WMainMenuBar::onRecordingStateChange); connect(m_pMenuBar, &WMainMenuBar::toggleRecording, - m_pRecordingManager, + m_pCoreServices->getRecordingManager().get(), &RecordingManager::slotSetRecording); - m_pMenuBar->onRecordingStateChange(m_pRecordingManager->isRecordingActive()); + m_pMenuBar->onRecordingStateChange( + m_pCoreServices->getRecordingManager()->isRecordingActive()); } #ifdef __BROADCAST__ - if (m_pBroadcastManager) { - connect(m_pBroadcastManager, + if (m_pCoreServices->getBroadcastManager()) { + connect(m_pCoreServices->getBroadcastManager().get(), &BroadcastManager::broadcastEnabled, m_pMenuBar, &WMainMenuBar::onBroadcastingStateChange); connect(m_pMenuBar, &WMainMenuBar::toggleBroadcasting, - m_pBroadcastManager, + m_pCoreServices->getBroadcastManager().get(), &BroadcastManager::setEnabled); - m_pMenuBar->onBroadcastingStateChange(m_pBroadcastManager->isEnabled()); + m_pMenuBar->onBroadcastingStateChange(m_pCoreServices->getBroadcastManager()->isEnabled()); } #endif #ifdef __VINYLCONTROL__ - if (m_pVCManager) { + if (m_pCoreServices->getVinylControlManager()) { connect(m_pMenuBar, &WMainMenuBar::toggleVinylControl, - m_pVCManager, + m_pCoreServices->getVinylControlManager().get(), &VinylControlManager::toggleVinylControl); - connect(m_pVCManager, + connect(m_pCoreServices->getVinylControlManager().get(), &VinylControlManager::vinylControlDeckEnabled, m_pMenuBar, &WMainMenuBar::onVinylControlDeckEnabledStateChange); } #endif - if (m_pPlayerManager) { - connect(m_pPlayerManager, + if (m_pCoreServices->getPlayerManager()) { + connect(m_pCoreServices->getPlayerManager().get(), &PlayerManager::numberOfDecksChanged, m_pMenuBar, &WMainMenuBar::onNumberOfDecksChanged); - m_pMenuBar->onNumberOfDecksChanged(m_pPlayerManager->numberOfDecks()); + m_pMenuBar->onNumberOfDecksChanged(m_pCoreServices->getPlayerManager()->numberOfDecks()); } - if (m_pTrackCollectionManager) { + if (m_pCoreServices->getTrackCollectionManager()) { connect(m_pMenuBar, &WMainMenuBar::rescanLibrary, - m_pTrackCollectionManager, + m_pCoreServices->getTrackCollectionManager().get(), &TrackCollectionManager::startLibraryScan); - connect(m_pTrackCollectionManager, + connect(m_pCoreServices->getTrackCollectionManager().get(), &TrackCollectionManager::libraryScanStarted, m_pMenuBar, &WMainMenuBar::onLibraryScanStarted); - connect(m_pTrackCollectionManager, + connect(m_pCoreServices->getTrackCollectionManager().get(), &TrackCollectionManager::libraryScanFinished, m_pMenuBar, &WMainMenuBar::onLibraryScanFinished); } - if (m_pLibrary) { + if (m_pCoreServices->getLibrary()) { connect(m_pMenuBar, &WMainMenuBar::createCrate, - m_pLibrary, + m_pCoreServices->getLibrary().get(), &Library::slotCreateCrate); connect(m_pMenuBar, &WMainMenuBar::createPlaylist, - m_pLibrary, + m_pCoreServices->getLibrary().get(), &Library::slotCreatePlaylist); } } void MixxxMainWindow::slotFileLoadSongPlayer(int deck) { - QString group = m_pPlayerManager->groupForDeck(deck-1); + QString group = m_pCoreServices->getPlayerManager()->groupForDeck(deck - 1); QString loadTrackText = tr("Load track to Deck %1").arg(QString::number(deck)); QString deckWarningMessage = tr("Deck %1 is currently playing a track.") @@ -1251,7 +708,7 @@ void MixxxMainWindow::slotFileLoadSongPlayer(int deck) { return; } - UserSettingsPointer pConfig = m_pSettingsManager->settings(); + UserSettingsPointer pConfig = m_pCoreServices->getSettings(); QString trackPath = QFileDialog::getOpenFileName( this, @@ -1270,28 +727,14 @@ void MixxxMainWindow::slotFileLoadSongPlayer(int deck) { QFileInfo trackInfo(trackPath); Sandbox::createSecurityToken(trackInfo); - m_pPlayerManager->slotLoadToDeck(trackPath, deck); - } -} - - -void MixxxMainWindow::slotOptionsKeyboard(bool toggle) { - UserSettingsPointer pConfig = m_pSettingsManager->settings(); - if (toggle) { - //qDebug() << "Enable keyboard shortcuts/mappings"; - m_pKeyboard->setKeyboardConfig(m_pKbdConfig); - pConfig->set(ConfigKey("[Keyboard]","Enabled"), ConfigValue(1)); - } else { - //qDebug() << "Disable keyboard shortcuts/mappings"; - m_pKeyboard->setKeyboardConfig(m_pKbdConfigEmpty); - pConfig->set(ConfigKey("[Keyboard]","Enabled"), ConfigValue(0)); + m_pCoreServices->getPlayerManager()->slotLoadToDeck(trackPath, deck); } } void MixxxMainWindow::slotDeveloperTools(bool visible) { if (visible) { if (m_pDeveloperToolsDlg == nullptr) { - UserSettingsPointer pConfig = m_pSettingsManager->settings(); + UserSettingsPointer pConfig = m_pCoreServices->getSettings(); m_pDeveloperToolsDlg = new DlgDeveloperTools(this, pConfig); connect(m_pDeveloperToolsDlg, &DlgDeveloperTools::destroyed, @@ -1420,7 +863,7 @@ void MixxxMainWindow::slotHelpAbout() { } void MixxxMainWindow::setToolTipsCfg(mixxx::TooltipsPreference tt) { - UserSettingsPointer pConfig = m_pSettingsManager->settings(); + UserSettingsPointer pConfig = m_pCoreServices->getSettings(); pConfig->set(ConfigKey("[Controls]","Tooltips"), ConfigValue(static_cast(tt))); m_toolTipsCfg = tt; @@ -1489,15 +932,19 @@ void MixxxMainWindow::rebootMixxxView() { } bool MixxxMainWindow::loadConfiguredSkin() { + // TODO: use std::shared_ptr throughout skin widgets instead of these hacky get() calls m_pCentralWidget = m_pSkinLoader->loadConfiguredSkin(this, &m_skinCreatedControls, - m_pKeyboard, - m_pPlayerManager, - m_pControllerManager, - m_pLibrary, - m_pVCManager, - m_pEffectsManager, - m_pRecordingManager); + m_pCoreServices->getKeyboardEventFilter().get(), + m_pCoreServices->getPlayerManager().get(), + m_pCoreServices->getControllerManager().get(), + m_pCoreServices->getLibrary().get(), + m_pCoreServices->getVinylControlManager().get(), + m_pCoreServices->getEffectsManager().get(), + m_pCoreServices->getRecordingManager().get()); + if (centralWidget() == m_pLaunchImage) { + initializationProgressUpdate(100, ""); + } return m_pCentralWidget != nullptr; } @@ -1549,7 +996,7 @@ void MixxxMainWindow::checkDirectRendering() { if (!factory) return; - UserSettingsPointer pConfig = m_pSettingsManager->settings(); + UserSettingsPointer pConfig = m_pCoreServices->getSettings(); if (!factory->isOpenGlAvailable() && !factory->isOpenGlesAvailable() && pConfig->getValueString(ConfigKey("[Direct Rendering]", "Warned")) != QString("yes")) { @@ -1568,8 +1015,8 @@ void MixxxMainWindow::checkDirectRendering() { bool MixxxMainWindow::confirmExit() { bool playing(false); bool playingSampler(false); - unsigned int deckCount = m_pPlayerManager->numDecks(); - unsigned int samplerCount = m_pPlayerManager->numSamplers(); + unsigned int deckCount = m_pCoreServices->getPlayerManager()->numDecks(); + unsigned int samplerCount = m_pCoreServices->getPlayerManager()->numSamplers(); for (unsigned int i = 0; i < deckCount; ++i) { if (ControlObject::toBool( ConfigKey(PlayerManager::groupForDeck(i), "play"))) { @@ -1620,7 +1067,7 @@ bool MixxxMainWindow::confirmExit() { void MixxxMainWindow::setInhibitScreensaver(mixxx::ScreenSaverPreference newInhibit) { - UserSettingsPointer pConfig = m_pSettingsManager->settings(); + UserSettingsPointer pConfig = m_pCoreServices->getSettings(); if (m_inhibitScreensaver != mixxx::ScreenSaverPreference::PREVENT_OFF) { mixxx::ScreenSaverHelper::uninhibit(); @@ -1642,9 +1089,9 @@ mixxx::ScreenSaverPreference MixxxMainWindow::getInhibitScreensaver() return m_inhibitScreensaver; } -void MixxxMainWindow::launchProgress(int progress) { +void MixxxMainWindow::initializationProgressUpdate(int progress, const QString& serviceName) { if (m_pLaunchImage) { - m_pLaunchImage->progress(progress); + m_pLaunchImage->progress(progress, serviceName); } qApp->processEvents(); } diff --git a/src/mixxx.h b/src/mixxx.h index c606b42ff2f..52dec841faa 100644 --- a/src/mixxx.h +++ b/src/mixxx.h @@ -5,6 +5,7 @@ #include #include +#include "coreservices.h" #include "preferences/configobject.h" #include "preferences/constants.h" #include "preferences/usersettings.h" @@ -44,11 +45,9 @@ class WMainMenuBar; class MixxxMainWindow : public QMainWindow { Q_OBJECT public: - MixxxMainWindow(QApplication *app, const CmdlineArgs& args); + MixxxMainWindow(QApplication* app, std::shared_ptr pCoreServices); ~MixxxMainWindow() override; - void finalize(); - /// creates the menu_bar and inserts the file Menu void createMenuBar(); void connectMenuBar(); @@ -64,8 +63,6 @@ class MixxxMainWindow : public QMainWindow { void rebootMixxxView(); void slotFileLoadSongPlayer(int deck); - /// toggle keyboard on-off - void slotOptionsKeyboard(bool toggle); /// show the preferences dialog void slotOptionsPreferences(); /// show the about dialog @@ -97,19 +94,13 @@ class MixxxMainWindow : public QMainWindow { bool eventFilter(QObject *obj, QEvent *event) override; void closeEvent(QCloseEvent *event) override; - private: - void initialize(QApplication *app, const CmdlineArgs& args); - - /// progresses the launch image progress bar - /// this must be called from the GUI thread only - void launchProgress(int progress); + private slots: + void initializationProgressUpdate(int progress, const QString& serviceName); + private: void initializeWindow(); - void initializeKeyboard(); void checkDirectRendering(); - bool initializeDatabase(); - /// Load skin to a QWidget that we set as the central widget. bool loadConfiguredSkin(); @@ -121,55 +112,22 @@ class MixxxMainWindow : public QMainWindow { SoundDeviceError err, bool* retryClicked); QDialog::DialogCode noOutputDlg(bool* continueClicked); + std::shared_ptr m_pCoreServices; + QWidget* m_pCentralWidget; LaunchImage* m_pLaunchImage; - std::unique_ptr m_pSettingsManager; - - /// The effects processing system - EffectsManager* m_pEffectsManager; - - /// The mixing engine - EngineMaster* m_pEngine; - - SkinLoader* m_pSkinLoader; // TODO(rryan): doesn't need to be a member variable - - SoundManager* m_pSoundManager; - - PlayerManager* m_pPlayerManager; - RecordingManager* m_pRecordingManager; -#ifdef __BROADCAST__ - BroadcastManager* m_pBroadcastManager; -#endif - ControllerManager* m_pControllerManager; - + std::unique_ptr m_pSkinLoader; GuiTick* m_pGuiTick; VisualsManager* m_pVisualsManager; - VinylControlManager* m_pVCManager; - - KeyboardEventFilter* m_pKeyboard; - - mixxx::DbConnectionPoolPtr m_pDbConnectionPool; - - TrackCollectionManager* m_pTrackCollectionManager; - - Library* m_pLibrary; - parented_ptr m_pMenuBar; DlgDeveloperTools* m_pDeveloperToolsDlg; DlgPreferences* m_pPrefDlg; - ConfigObject* m_pKbdConfig; - ConfigObject* m_pKbdConfigEmpty; - mixxx::TooltipsPreference m_toolTipsCfg; - /// tracks how long Mixxx has been running - Timer m_runtime_timer; - - const CmdlineArgs& m_cmdLineArgs; ControlPushButton* m_pTouchShift; mixxx::ScreenSaverPreference m_inhibitScreensaver; diff --git a/src/skin/launchimage.cpp b/src/skin/launchimage.cpp index 8751ed2495e..03775921574 100644 --- a/src/skin/launchimage.cpp +++ b/src/skin/launchimage.cpp @@ -1,5 +1,7 @@ #include "skin/launchimage.h" +#include + #include #include #include @@ -56,8 +58,10 @@ LaunchImage::LaunchImage(QWidget* pParent, const QString& styleSheet) LaunchImage::~LaunchImage() { } -void LaunchImage::progress(int value) { +void LaunchImage::progress(int value, const QString& serviceName) { m_pProgressBar->setValue(value); + // TODO: show serviceName + Q_UNUSED(serviceName); } void LaunchImage::paintEvent(QPaintEvent *) diff --git a/src/skin/launchimage.h b/src/skin/launchimage.h index 288fd59b3b3..fbf335619b2 100644 --- a/src/skin/launchimage.h +++ b/src/skin/launchimage.h @@ -3,6 +3,7 @@ #include QT_FORWARD_DECLARE_CLASS(QProgressBar); +QT_FORWARD_DECLARE_CLASS(QLabel); // This is a widget that is shown in the Mixxx main window // until the skin is ready to use. @@ -38,7 +39,7 @@ class LaunchImage: public QWidget { public: LaunchImage(QWidget* pParent, const QString& styleSheet); virtual ~LaunchImage(); - void progress(int value); + void progress(int value, const QString& serviceName); protected: virtual void paintEvent(QPaintEvent *); diff --git a/src/test/signalpathtest.h b/src/test/signalpathtest.h index 766ef1be5e7..bbb057b630d 100644 --- a/src/test/signalpathtest.h +++ b/src/test/signalpathtest.h @@ -27,7 +27,6 @@ #include "util/sample.h" #include "util/types.h" #include "waveform/guitick.h" -#include "waveform/visualsmanager.h" using ::testing::Return; using ::testing::_; @@ -63,7 +62,6 @@ class BaseSignalPathTest : public MixxxTest { m_pChannelHandleFactory = std::make_shared(); m_pNumDecks = new ControlObject(ConfigKey(m_sMasterGroup, "num_decks")); m_pEffectsManager = new EffectsManager(NULL, config(), m_pChannelHandleFactory); - m_pVisualsManager = new VisualsManager(); m_pEngineMaster = new TestEngineMaster(m_pConfig, m_sMasterGroup, m_pEffectsManager, @@ -74,21 +72,18 @@ class BaseSignalPathTest : public MixxxTest { m_pConfig, m_pEngineMaster, m_pEffectsManager, - m_pVisualsManager, EngineChannel::CENTER, m_pEngineMaster->registerChannelGroup(m_sGroup1)); m_pMixerDeck2 = new Deck(nullptr, m_pConfig, m_pEngineMaster, m_pEffectsManager, - m_pVisualsManager, EngineChannel::CENTER, m_pEngineMaster->registerChannelGroup(m_sGroup2)); m_pMixerDeck3 = new Deck(nullptr, m_pConfig, m_pEngineMaster, m_pEffectsManager, - m_pVisualsManager, EngineChannel::CENTER, m_pEngineMaster->registerChannelGroup(m_sGroup3)); @@ -99,7 +94,6 @@ class BaseSignalPathTest : public MixxxTest { m_pConfig, m_pEngineMaster, m_pEffectsManager, - m_pVisualsManager, EngineChannel::CENTER, m_pEngineMaster->registerChannelGroup(m_sPreviewGroup)); ControlObject::set(ConfigKey(m_sPreviewGroup, "file_bpm"), 2.0); @@ -134,7 +128,6 @@ class BaseSignalPathTest : public MixxxTest { // Deletes all EngineChannels added to it. delete m_pEngineMaster; delete m_pEffectsManager; - delete m_pVisualsManager; delete m_pNumDecks; PlayerInfo::destroy(); } @@ -230,7 +223,6 @@ class BaseSignalPathTest : public MixxxTest { ChannelHandleFactoryPointer m_pChannelHandleFactory; ControlObject* m_pNumDecks; std::unique_ptr m_pGuiTick; - VisualsManager* m_pVisualsManager; EffectsManager* m_pEffectsManager; EngineSync* m_pEngineSync; TestEngineMaster* m_pEngineMaster; From f90e4ecb735007486299ed7a6543afca410bf952 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 13:39:56 -0600 Subject: [PATCH 02/11] use std::shared_ptr for managers in preferences --- src/controllers/dlgprefcontroller.cpp | 4 +- src/controllers/dlgprefcontroller.h | 9 +- src/controllers/dlgprefcontrollers.cpp | 8 +- src/controllers/dlgprefcontrollers.h | 8 +- src/mixxx.cpp | 16 ++-- src/mixxx.h | 2 +- src/preferences/dialog/dlgprefcolors.cpp | 4 +- src/preferences/dialog/dlgprefcolors.h | 5 +- src/preferences/dialog/dlgprefeffects.cpp | 8 +- src/preferences/dialog/dlgprefeffects.h | 6 +- src/preferences/dialog/dlgprefeq.cpp | 8 +- src/preferences/dialog/dlgprefeq.h | 8 +- src/preferences/dialog/dlgpreferences.cpp | 12 ++- src/preferences/dialog/dlgpreferences.h | 18 ++-- src/preferences/dialog/dlgprefinterface.cpp | 26 +++--- src/preferences/dialog/dlgprefinterface.h | 10 ++- src/preferences/dialog/dlgpreflibrary.cpp | 8 +- src/preferences/dialog/dlgpreflibrary.h | 4 +- src/preferences/dialog/dlgpreflv2.cpp | 7 +- src/preferences/dialog/dlgpreflv2.h | 8 +- src/preferences/dialog/dlgprefsound.cpp | 17 ++-- src/preferences/dialog/dlgprefsound.h | 7 +- src/preferences/dialog/dlgprefvinyl.cpp | 6 +- src/preferences/dialog/dlgprefvinyl.h | 7 +- src/preferences/dialog/dlgprefwaveform.cpp | 7 +- src/preferences/dialog/dlgprefwaveform.h | 9 +- src/soundio/soundmanagerconfig.cpp | 2 +- src/soundio/soundmanagerconfig.h | 96 +++++++++++---------- 28 files changed, 187 insertions(+), 143 deletions(-) diff --git a/src/controllers/dlgprefcontroller.cpp b/src/controllers/dlgprefcontroller.cpp index 34964ae2c87..ee6b8bfb3e6 100644 --- a/src/controllers/dlgprefcontroller.cpp +++ b/src/controllers/dlgprefcontroller.cpp @@ -25,7 +25,7 @@ const QString kPresetExt(".midi.xml"); DlgPrefController::DlgPrefController( QWidget* parent, Controller* controller, - ControllerManager* controllerManager, + std::shared_ptr controllerManager, UserSettingsPointer pConfig) : DlgPreferencePage(parent), m_pConfig(pConfig), @@ -86,7 +86,7 @@ DlgPrefController::DlgPrefController( // Connect our signals to controller manager. connect(this, &DlgPrefController::applyPreset, - m_pControllerManager, + m_pControllerManager.get(), &ControllerManager::slotApplyPreset); // Open script file links diff --git a/src/controllers/dlgprefcontroller.h b/src/controllers/dlgprefcontroller.h index 8b114d9719a..8b4ab0e7922 100644 --- a/src/controllers/dlgprefcontroller.h +++ b/src/controllers/dlgprefcontroller.h @@ -21,9 +21,10 @@ class PresetInfoEnumerator; class DlgPrefController : public DlgPreferencePage { Q_OBJECT public: - DlgPrefController(QWidget *parent, Controller* controller, - ControllerManager* controllerManager, - UserSettingsPointer pConfig); + DlgPrefController(QWidget* parent, + Controller* controller, + std::shared_ptr controllerManager, + UserSettingsPointer pConfig); virtual ~DlgPrefController(); QUrl helpUrl() const override; @@ -106,7 +107,7 @@ class DlgPrefController : public DlgPreferencePage { Ui::DlgPrefControllerDlg m_ui; UserSettingsPointer m_pConfig; const QString m_pUserDir; - ControllerManager* m_pControllerManager; + std::shared_ptr m_pControllerManager; Controller* m_pController; DlgControllerLearning* m_pDlgControllerLearning; ControllerPresetPointer m_pPreset; diff --git a/src/controllers/dlgprefcontrollers.cpp b/src/controllers/dlgprefcontrollers.cpp index 99a23e76211..118ffea136d 100644 --- a/src/controllers/dlgprefcontrollers.cpp +++ b/src/controllers/dlgprefcontrollers.cpp @@ -10,9 +10,9 @@ #include "preferences/dialog/dlgpreferences.h" DlgPrefControllers::DlgPrefControllers(DlgPreferences* pPreferences, - UserSettingsPointer pConfig, - ControllerManager* pControllerManager, - QTreeWidgetItem* pControllerTreeItem) + UserSettingsPointer pConfig, + std::shared_ptr pControllerManager, + QTreeWidgetItem* pControllerTreeItem) : DlgPreferencePage(pPreferences), m_pDlgPreferences(pPreferences), m_pConfig(pConfig), @@ -27,7 +27,7 @@ DlgPrefControllers::DlgPrefControllers(DlgPreferences* pPreferences, }); // Connections - connect(m_pControllerManager, + connect(m_pControllerManager.get(), &ControllerManager::devicesChanged, this, &DlgPrefControllers::rescanControllers); diff --git a/src/controllers/dlgprefcontrollers.h b/src/controllers/dlgprefcontrollers.h index 2943ae3bfcc..8a74add548f 100644 --- a/src/controllers/dlgprefcontrollers.h +++ b/src/controllers/dlgprefcontrollers.h @@ -18,9 +18,9 @@ class DlgPrefControllers : public DlgPreferencePage, public Ui::DlgPrefControlle Q_OBJECT public: DlgPrefControllers(DlgPreferences* pDlgPreferences, - UserSettingsPointer pConfig, - ControllerManager* pControllerManager, - QTreeWidgetItem* pControllerTreeItem); + UserSettingsPointer pConfig, + std::shared_ptr pControllerManager, + QTreeWidgetItem* pControllerTreeItem); virtual ~DlgPrefControllers(); bool handleTreeItemClick(QTreeWidgetItem* clickedItem); @@ -47,7 +47,7 @@ class DlgPrefControllers : public DlgPreferencePage, public Ui::DlgPrefControlle DlgPreferences* m_pDlgPreferences; UserSettingsPointer m_pConfig; - ControllerManager* m_pControllerManager; + std::shared_ptr m_pControllerManager; QTreeWidgetItem* m_pControllerTreeItem; QList m_controllerWindows; QList m_controllerTreeItems; diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 8b56ac1d5a2..791901ae228 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -171,15 +171,15 @@ MixxxMainWindow::MixxxMainWindow( // Initialize preference dialog m_pPrefDlg = new DlgPreferences( this, - m_pSkinLoader.get(), - m_pCoreServices->getSoundManager().get(), - m_pCoreServices->getPlayerManager().get(), - m_pCoreServices->getControllerManager().get(), - m_pCoreServices->getVinylControlManager().get(), + m_pSkinLoader, + m_pCoreServices->getSoundManager(), + m_pCoreServices->getPlayerManager(), + m_pCoreServices->getControllerManager(), + m_pCoreServices->getVinylControlManager(), m_pCoreServices->getLV2Backend(), - m_pCoreServices->getEffectsManager().get(), - m_pCoreServices->getSettingsManager().get(), - m_pCoreServices->getLibrary().get()); + m_pCoreServices->getEffectsManager(), + m_pCoreServices->getSettingsManager(), + m_pCoreServices->getLibrary()); m_pPrefDlg->setWindowIcon(QIcon(":/images/mixxx_icon.svg")); m_pPrefDlg->setHidden(true); diff --git a/src/mixxx.h b/src/mixxx.h index 52dec841faa..5f9853d4cfa 100644 --- a/src/mixxx.h +++ b/src/mixxx.h @@ -117,7 +117,7 @@ class MixxxMainWindow : public QMainWindow { QWidget* m_pCentralWidget; LaunchImage* m_pLaunchImage; - std::unique_ptr m_pSkinLoader; + std::shared_ptr m_pSkinLoader; GuiTick* m_pGuiTick; VisualsManager* m_pVisualsManager; diff --git a/src/preferences/dialog/dlgprefcolors.cpp b/src/preferences/dialog/dlgprefcolors.cpp index 13e71fadfcd..9bbaaf5b463 100644 --- a/src/preferences/dialog/dlgprefcolors.cpp +++ b/src/preferences/dialog/dlgprefcolors.cpp @@ -28,7 +28,9 @@ const ConfigKey kLoopDefaultColorIndexConfigKey("[Controls]", "LoopDefaultColorI } // anonymous namespace DlgPrefColors::DlgPrefColors( - QWidget* parent, UserSettingsPointer pConfig, Library* pLibrary) + QWidget* parent, + UserSettingsPointer pConfig, + std::shared_ptr pLibrary) : DlgPreferencePage(parent), m_pConfig(pConfig), m_colorPaletteSettings(ColorPaletteSettings(pConfig)), diff --git a/src/preferences/dialog/dlgprefcolors.h b/src/preferences/dialog/dlgprefcolors.h index 058523cc8b1..f63959cc119 100644 --- a/src/preferences/dialog/dlgprefcolors.h +++ b/src/preferences/dialog/dlgprefcolors.h @@ -16,7 +16,10 @@ class Library; class DlgPrefColors : public DlgPreferencePage, public Ui::DlgPrefColorsDlg { Q_OBJECT public: - DlgPrefColors(QWidget* parent, UserSettingsPointer pConfig, Library* pLibrary); + DlgPrefColors( + QWidget* parent, + UserSettingsPointer pConfig, + std::shared_ptr pLibrary); virtual ~DlgPrefColors(); public slots: diff --git a/src/preferences/dialog/dlgprefeffects.cpp b/src/preferences/dialog/dlgprefeffects.cpp index 34e2b5c3e37..8e0a985325a 100644 --- a/src/preferences/dialog/dlgprefeffects.cpp +++ b/src/preferences/dialog/dlgprefeffects.cpp @@ -6,14 +6,14 @@ #include "moc_dlgprefeffects.cpp" DlgPrefEffects::DlgPrefEffects(QWidget* pParent, - UserSettingsPointer pConfig, - EffectsManager* pEffectsManager) + UserSettingsPointer pConfig, + std::shared_ptr pEffectsManager) : DlgPreferencePage(pParent), m_pConfig(pConfig), m_pEffectsManager(pEffectsManager) { setupUi(this); - m_availableEffectsModel.resetFromEffectManager(pEffectsManager); + m_availableEffectsModel.resetFromEffectManager(pEffectsManager.get()); const QList effectProfiles = m_availableEffectsModel.profiles(); for (auto& profile : effectProfiles) { EffectManifestPointer pManifest = profile->pManifest; @@ -49,7 +49,7 @@ DlgPrefEffects::~DlgPrefEffects() { void DlgPrefEffects::slotUpdate() { clear(); - m_availableEffectsModel.resetFromEffectManager(m_pEffectsManager); + m_availableEffectsModel.resetFromEffectManager(m_pEffectsManager.get()); if (!m_availableEffectsModel.isEmpty()) { availableEffectsList->selectRow(0); diff --git a/src/preferences/dialog/dlgprefeffects.h b/src/preferences/dialog/dlgprefeffects.h index c787804bc1b..d88d1ec3e60 100644 --- a/src/preferences/dialog/dlgprefeffects.h +++ b/src/preferences/dialog/dlgprefeffects.h @@ -13,8 +13,8 @@ class DlgPrefEffects : public DlgPreferencePage, public Ui::DlgPrefEffectsDlg { Q_OBJECT public: DlgPrefEffects(QWidget* pParent, - UserSettingsPointer pConfig, - EffectsManager* pEffectsManager); + UserSettingsPointer pConfig, + std::shared_ptr pEffectsManager); virtual ~DlgPrefEffects(); void slotUpdate() override; @@ -29,5 +29,5 @@ class DlgPrefEffects : public DlgPreferencePage, public Ui::DlgPrefEffectsDlg { EffectSettingsModel m_availableEffectsModel; UserSettingsPointer m_pConfig; - EffectsManager* m_pEffectsManager; + std::shared_ptr m_pEffectsManager; }; diff --git a/src/preferences/dialog/dlgprefeq.cpp b/src/preferences/dialog/dlgprefeq.cpp index e20ab978ca7..6a989fa70ac 100644 --- a/src/preferences/dialog/dlgprefeq.cpp +++ b/src/preferences/dialog/dlgprefeq.cpp @@ -27,8 +27,10 @@ const QString kDefaultQuickEffectId = FilterEffect::getId(); const int kFrequencyUpperLimit = 20050; const int kFrequencyLowerLimit = 16; -DlgPrefEQ::DlgPrefEQ(QWidget* pParent, EffectsManager* pEffectsManager, - UserSettingsPointer pConfig) +DlgPrefEQ::DlgPrefEQ( + QWidget* pParent, + std::shared_ptr pEffectsManager, + UserSettingsPointer pConfig) : DlgPreferencePage(pParent), m_COLoFreq(kConfigKey, "LoEQFrequency"), m_COHiFreq(kConfigKey, "HiEQFrequency"), @@ -722,7 +724,7 @@ void DlgPrefEQ::slotMasterEqEffectChanged(int effectIndex) { if (pChainSlot) { EffectChainPointer pChain = pChainSlot->getEffectChain(); VERIFY_OR_DEBUG_ASSERT(pChain) { - pChain = pChainSlot->getOrCreateEffectChain(m_pEffectsManager); + pChain = pChainSlot->getOrCreateEffectChain(m_pEffectsManager.get()); } EffectPointer pEffect = m_pEffectsManager->instantiateEffect(effectId); pChain->replaceEffect(0, pEffect); diff --git a/src/preferences/dialog/dlgprefeq.h b/src/preferences/dialog/dlgprefeq.h index f6c10c96291..33e48fd8ab2 100644 --- a/src/preferences/dialog/dlgprefeq.h +++ b/src/preferences/dialog/dlgprefeq.h @@ -13,8 +13,10 @@ class DlgPrefEQ : public DlgPreferencePage, public Ui::DlgPrefEQDlg { Q_OBJECT public: - DlgPrefEQ(QWidget *parent, EffectsManager* pEffectsManager, - UserSettingsPointer _config); + DlgPrefEQ( + QWidget* parent, + std::shared_ptr pEffectsManager, + UserSettingsPointer _config); virtual ~DlgPrefEQ(); QUrl helpUrl() const override; @@ -66,7 +68,7 @@ class DlgPrefEQ : public DlgPreferencePage, public Ui::DlgPrefEQDlg { double m_lowEqFreq, m_highEqFreq; // Members needed for changing the effects loaded on the EQ Effect Rack - EffectsManager* m_pEffectsManager; + std::shared_ptr m_pEffectsManager; EqualizerRackPointer m_pEQEffectRack; QuickEffectRackPointer m_pQuickEffectRack; OutputEffectRackPointer m_pOutputEffectRack; diff --git a/src/preferences/dialog/dlgpreferences.cpp b/src/preferences/dialog/dlgpreferences.cpp index 072cc112595..6aa7dc8e142 100644 --- a/src/preferences/dialog/dlgpreferences.cpp +++ b/src/preferences/dialog/dlgpreferences.cpp @@ -52,7 +52,17 @@ #include "skin/skinloader.h" #include "util/widgethelper.h" -DlgPreferences::DlgPreferences(MixxxMainWindow* mixxx, SkinLoader* pSkinLoader, SoundManager* soundman, PlayerManager* pPlayerManager, ControllerManager* controllers, VinylControlManager* pVCManager, LV2Backend* pLV2Backend, EffectsManager* pEffectsManager, SettingsManager* pSettingsManager, Library* pLibrary) +DlgPreferences::DlgPreferences( + MixxxMainWindow* mixxx, + std::shared_ptr pSkinLoader, + std::shared_ptr soundman, + std::shared_ptr pPlayerManager, + std::shared_ptr controllers, + std::shared_ptr pVCManager, + LV2Backend* pLV2Backend, + std::shared_ptr pEffectsManager, + std::shared_ptr pSettingsManager, + std::shared_ptr pLibrary) : m_allPages(), m_pConfig(pSettingsManager->settings()), m_pageSizeHint(QSize(0, 0)) { diff --git a/src/preferences/dialog/dlgpreferences.h b/src/preferences/dialog/dlgpreferences.h index ac05188f402..b1503a996ea 100644 --- a/src/preferences/dialog/dlgpreferences.h +++ b/src/preferences/dialog/dlgpreferences.h @@ -60,16 +60,16 @@ class DlgPreferences : public QDialog, public Ui::DlgPreferencesDlg { QTreeWidgetItem* pTreeItem; }; -DlgPreferences(MixxxMainWindow* mixxx, - SkinLoader* pSkinLoader, - SoundManager* soundman, - PlayerManager* pPlayerManager, - ControllerManager* controllers, - VinylControlManager* pVCManager, + DlgPreferences(MixxxMainWindow* mixxx, + std::shared_ptr pSkinLoader, + std::shared_ptr soundman, + std::shared_ptr pPlayerManager, + std::shared_ptr controllers, + std::shared_ptr pVCManager, LV2Backend* pLV2Backend, - EffectsManager* pEffectsManager, - SettingsManager* pSettingsManager, - Library* pLibrary); + std::shared_ptr pEffectsManager, + std::shared_ptr pSettingsManager, + std::shared_ptr pLibrary); virtual ~DlgPreferences(); void addPageWidget(PreferencesPage page); diff --git a/src/preferences/dialog/dlgprefinterface.cpp b/src/preferences/dialog/dlgprefinterface.cpp index 698c5e2f480..07e8a141b4c 100644 --- a/src/preferences/dialog/dlgprefinterface.cpp +++ b/src/preferences/dialog/dlgprefinterface.cpp @@ -59,18 +59,20 @@ bool skinFitsScreenSize( } // namespace -DlgPrefInterface::DlgPrefInterface(QWidget * parent, MixxxMainWindow * mixxx, - SkinLoader* pSkinLoader, - UserSettingsPointer pConfig) - : DlgPreferencePage(parent), - m_pConfig(pConfig), - m_mixxx(mixxx), - m_pSkinLoader(pSkinLoader), - m_dScaleFactorAuto(1.0), - m_bUseAutoScaleFactor(false), - m_dScaleFactor(1.0), - m_bStartWithFullScreen(false), - m_bRebootMixxxView(false) { +DlgPrefInterface::DlgPrefInterface( + QWidget* parent, + MixxxMainWindow* mixxx, + std::shared_ptr pSkinLoader, + UserSettingsPointer pConfig) + : DlgPreferencePage(parent), + m_pConfig(pConfig), + m_mixxx(mixxx), + m_pSkinLoader(pSkinLoader), + m_dScaleFactorAuto(1.0), + m_bUseAutoScaleFactor(false), + m_dScaleFactor(1.0), + m_bStartWithFullScreen(false), + m_bRebootMixxxView(false) { setupUi(this); // diff --git a/src/preferences/dialog/dlgprefinterface.h b/src/preferences/dialog/dlgprefinterface.h index 1dfe7aaf6e2..f7ad65c1a89 100644 --- a/src/preferences/dialog/dlgprefinterface.h +++ b/src/preferences/dialog/dlgprefinterface.h @@ -17,8 +17,11 @@ class ControlObject; class DlgPrefInterface : public DlgPreferencePage, public Ui::DlgPrefControlsDlg { Q_OBJECT public: - DlgPrefInterface(QWidget *parent, MixxxMainWindow *mixxx, - SkinLoader* pSkinLoader, UserSettingsPointer pConfig); + DlgPrefInterface( + QWidget* parent, + MixxxMainWindow* mixxx, + std::shared_ptr pSkinLoader, + UserSettingsPointer pConfig); ~DlgPrefInterface() override = default; public slots: @@ -48,8 +51,7 @@ class DlgPrefInterface : public DlgPreferencePage, public Ui::DlgPrefControlsDlg UserSettingsPointer m_pConfig; ControlObject* m_pControlTrackTimeDisplay; MixxxMainWindow *m_mixxx; - SkinLoader* m_pSkinLoader; - PlayerManager* m_pPlayerManager; + std::shared_ptr m_pSkinLoader; QString m_skin; QString m_skinOnUpdate; diff --git a/src/preferences/dialog/dlgpreflibrary.cpp b/src/preferences/dialog/dlgpreflibrary.cpp index c5702dd549a..080459d5547 100644 --- a/src/preferences/dialog/dlgpreflibrary.cpp +++ b/src/preferences/dialog/dlgpreflibrary.cpp @@ -23,7 +23,7 @@ namespace { DlgPrefLibrary::DlgPrefLibrary( QWidget* pParent, UserSettingsPointer pConfig, - Library* pLibrary) + std::shared_ptr pLibrary) : DlgPreferencePage(pParent), m_dirListModel(), m_pConfig(pConfig), @@ -34,15 +34,15 @@ DlgPrefLibrary::DlgPrefLibrary( connect(this, &DlgPrefLibrary::requestAddDir, - m_pLibrary, + m_pLibrary.get(), &Library::slotRequestAddDir); connect(this, &DlgPrefLibrary::requestRemoveDir, - m_pLibrary, + m_pLibrary.get(), &Library::slotRequestRemoveDir); connect(this, &DlgPrefLibrary::requestRelocateDir, - m_pLibrary, + m_pLibrary.get(), &Library::slotRequestRelocateDir); connect(PushButtonAddDir, &QPushButton::clicked, diff --git a/src/preferences/dialog/dlgpreflibrary.h b/src/preferences/dialog/dlgpreflibrary.h index 09bbd9a3360..366b10003e9 100644 --- a/src/preferences/dialog/dlgpreflibrary.h +++ b/src/preferences/dialog/dlgpreflibrary.h @@ -24,7 +24,7 @@ class DlgPrefLibrary : public DlgPreferencePage, public Ui::DlgPrefLibraryDlg { DlgPrefLibrary( QWidget* pParent, UserSettingsPointer pConfig, - Library* pLibrary); + std::shared_ptr pLibrary); ~DlgPrefLibrary() override {} QUrl helpUrl() const override; @@ -62,7 +62,7 @@ class DlgPrefLibrary : public DlgPreferencePage, public Ui::DlgPrefLibraryDlg { QStandardItemModel m_dirListModel; UserSettingsPointer m_pConfig; - Library* m_pLibrary; + std::shared_ptr m_pLibrary; bool m_bAddedDirectory; QFont m_originalTrackTableFont; int m_iOriginalTrackTableRowHeight; diff --git a/src/preferences/dialog/dlgpreflv2.cpp b/src/preferences/dialog/dlgpreflv2.cpp index ba4fb42fc8d..9ceb3eda199 100644 --- a/src/preferences/dialog/dlgpreflv2.cpp +++ b/src/preferences/dialog/dlgpreflv2.cpp @@ -12,9 +12,10 @@ #include "moc_dlgpreflv2.cpp" #include "util/math.h" -DlgPrefLV2::DlgPrefLV2(QWidget* pParent, LV2Backend* lv2Backend, - UserSettingsPointer pConfig, - EffectsManager* pEffectsManager) +DlgPrefLV2::DlgPrefLV2(QWidget* pParent, + LV2Backend* lv2Backend, + UserSettingsPointer pConfig, + std::shared_ptr pEffectsManager) : DlgPreferencePage(pParent), m_pLV2Backend(lv2Backend), m_iCheckedParameters(0), diff --git a/src/preferences/dialog/dlgpreflv2.h b/src/preferences/dialog/dlgpreflv2.h index b3c9318d6c9..6e535204dce 100644 --- a/src/preferences/dialog/dlgpreflv2.h +++ b/src/preferences/dialog/dlgpreflv2.h @@ -13,8 +13,10 @@ class EffectsManager; class DlgPrefLV2 : public DlgPreferencePage, public Ui::DlgPrefLV2Dlg { Q_OBJECT public: - DlgPrefLV2(QWidget *parent, LV2Backend* lv2Backend, - UserSettingsPointer pConfig, EffectsManager* pEffectsManager); + DlgPrefLV2(QWidget* parent, + LV2Backend* lv2Backend, + UserSettingsPointer pConfig, + std::shared_ptr pEffectsManager); virtual ~DlgPrefLV2(); public slots: @@ -34,5 +36,5 @@ class DlgPrefLV2 : public DlgPreferencePage, public Ui::DlgPrefLV2Dlg { QString m_currentEffectId; QList m_pluginParameters; int m_iCheckedParameters; - EffectsManager* m_pEffectsManager; + std::shared_ptr m_pEffectsManager; }; diff --git a/src/preferences/dialog/dlgprefsound.cpp b/src/preferences/dialog/dlgprefsound.cpp index 7309f936d74..5d9201833ae 100644 --- a/src/preferences/dialog/dlgprefsound.cpp +++ b/src/preferences/dialog/dlgprefsound.cpp @@ -18,19 +18,22 @@ * all the controls to the values obtained from SoundManager. */ DlgPrefSound::DlgPrefSound(QWidget* pParent, - SoundManager* pSoundManager, + std::shared_ptr pSoundManager, UserSettingsPointer pSettings) : DlgPreferencePage(pParent), m_pSoundManager(pSoundManager), m_pSettings(pSettings), - m_config(pSoundManager), + m_config(pSoundManager.get()), m_settingsModified(false), m_bLatencyChanged(false), m_bSkipConfigClear(true), m_loading(false) { setupUi(this); - connect(m_pSoundManager, &SoundManager::devicesUpdated, this, &DlgPrefSound::refreshDevices); + connect(m_pSoundManager.get(), + &SoundManager::devicesUpdated, + this, + &DlgPrefSound::refreshDevices); apiComboBox->clear(); apiComboBox->addItem(tr("None"), "None"); @@ -161,7 +164,7 @@ DlgPrefSound::DlgPrefSound(QWidget* pParent, connect(queryButton, &QAbstractButton::clicked, this, &DlgPrefSound::queryClicked); - connect(m_pSoundManager, + connect(m_pSoundManager.get(), &SoundManager::outputRegistered, this, [this](const AudioOutput& output, AudioSource* source) { @@ -170,7 +173,7 @@ DlgPrefSound::DlgPrefSound(QWidget* pParent, loadSettings(); }); - connect(m_pSoundManager, + connect(m_pSoundManager.get(), &SoundManager::inputRegistered, this, [this](const AudioInput& input, AudioDestination* dest) { @@ -651,8 +654,8 @@ void DlgPrefSound::queryClicked() { * Slot called when the "Reset to Defaults" button is clicked. */ void DlgPrefSound::slotResetToDefaults() { - SoundManagerConfig newConfig(m_pSoundManager); - newConfig.loadDefaults(m_pSoundManager, SoundManagerConfig::ALL); + SoundManagerConfig newConfig(m_pSoundManager.get()); + newConfig.loadDefaults(m_pSoundManager.get(), SoundManagerConfig::ALL); loadSettings(newConfig); keylockComboBox->setCurrentIndex(EngineBuffer::RUBBERBAND); m_pKeylockEngine->set(EngineBuffer::RUBBERBAND); diff --git a/src/preferences/dialog/dlgprefsound.h b/src/preferences/dialog/dlgprefsound.h index 8eea151afe0..283027b4372 100644 --- a/src/preferences/dialog/dlgprefsound.h +++ b/src/preferences/dialog/dlgprefsound.h @@ -27,8 +27,9 @@ class ControlProxy; class DlgPrefSound : public DlgPreferencePage, public Ui::DlgPrefSoundDlg { Q_OBJECT; public: - DlgPrefSound(QWidget *parent, SoundManager *soundManager, - UserSettingsPointer pSettings); + DlgPrefSound(QWidget* parent, + std::shared_ptr soundManager, + UserSettingsPointer pSettings); virtual ~DlgPrefSound(); QUrl helpUrl() const override; @@ -81,7 +82,7 @@ class DlgPrefSound : public DlgPreferencePage, public Ui::DlgPrefSoundDlg { void checkLatencyCompensation(); bool eventFilter(QObject* object, QEvent* event) override; - SoundManager *m_pSoundManager; + std::shared_ptr m_pSoundManager; UserSettingsPointer m_pSettings; SoundManagerConfig m_config; ControlProxy* m_pMasterAudioLatencyOverloadCount; diff --git a/src/preferences/dialog/dlgprefvinyl.cpp b/src/preferences/dialog/dlgprefvinyl.cpp index 31c09ba830d..fceb23233cc 100644 --- a/src/preferences/dialog/dlgprefvinyl.cpp +++ b/src/preferences/dialog/dlgprefvinyl.cpp @@ -11,8 +11,10 @@ #include "vinylcontrol/defs_vinylcontrol.h" #include "vinylcontrol/vinylcontrolmanager.h" -DlgPrefVinyl::DlgPrefVinyl(QWidget * parent, VinylControlManager *pVCMan, - UserSettingsPointer _config) +DlgPrefVinyl::DlgPrefVinyl( + QWidget* parent, + std::shared_ptr pVCMan, + UserSettingsPointer _config) : DlgPreferencePage(parent), m_pVCManager(pVCMan), config(_config) { diff --git a/src/preferences/dialog/dlgprefvinyl.h b/src/preferences/dialog/dlgprefvinyl.h index 16f6fd20c1c..ae2b03832b0 100644 --- a/src/preferences/dialog/dlgprefvinyl.h +++ b/src/preferences/dialog/dlgprefvinyl.h @@ -14,7 +14,10 @@ class VinylControlManager; class DlgPrefVinyl : public DlgPreferencePage, Ui::DlgPrefVinylDlg { Q_OBJECT public: - DlgPrefVinyl(QWidget* pParent, VinylControlManager* m_pVCMan, UserSettingsPointer _config); + DlgPrefVinyl( + QWidget* pParent, + std::shared_ptr m_pVCMan, + UserSettingsPointer _config); virtual ~DlgPrefVinyl(); QUrl helpUrl() const override; @@ -48,7 +51,7 @@ class DlgPrefVinyl : public DlgPreferencePage, Ui::DlgPrefVinylDlg { QList m_signalWidgets; - VinylControlManager* m_pVCManager; + std::shared_ptr m_pVCManager; UserSettingsPointer config; QList m_COSpeeds; ControlProxy* m_pNumDecks; diff --git a/src/preferences/dialog/dlgprefwaveform.cpp b/src/preferences/dialog/dlgprefwaveform.cpp index 03113b816ef..7b4a51065b8 100644 --- a/src/preferences/dialog/dlgprefwaveform.cpp +++ b/src/preferences/dialog/dlgprefwaveform.cpp @@ -9,8 +9,11 @@ #include "waveform/renderers/waveformwidgetrenderer.h" #include "waveform/waveformwidgetfactory.h" -DlgPrefWaveform::DlgPrefWaveform(QWidget* pParent, MixxxMainWindow* pMixxx, - UserSettingsPointer pConfig, Library* pLibrary) +DlgPrefWaveform::DlgPrefWaveform( + QWidget* pParent, + MixxxMainWindow* pMixxx, + UserSettingsPointer pConfig, + std::shared_ptr pLibrary) : DlgPreferencePage(pParent), m_pConfig(pConfig), m_pLibrary(pLibrary), diff --git a/src/preferences/dialog/dlgprefwaveform.h b/src/preferences/dialog/dlgprefwaveform.h index e3325cf1ec6..2bfca0dc586 100644 --- a/src/preferences/dialog/dlgprefwaveform.h +++ b/src/preferences/dialog/dlgprefwaveform.h @@ -12,8 +12,11 @@ class Library; class DlgPrefWaveform : public DlgPreferencePage, public Ui::DlgPrefWaveformDlg { Q_OBJECT public: - DlgPrefWaveform(QWidget* pParent, MixxxMainWindow* pMixxx, - UserSettingsPointer pConfig, Library* pLibrary); + DlgPrefWaveform( + QWidget* pParent, + MixxxMainWindow* pMixxx, + UserSettingsPointer pConfig, + std::shared_ptr pLibrary); virtual ~DlgPrefWaveform(); public slots: @@ -44,6 +47,6 @@ class DlgPrefWaveform : public DlgPreferencePage, public Ui::DlgPrefWaveformDlg void notifyRebootNecessary(); UserSettingsPointer m_pConfig; - Library* m_pLibrary; + std::shared_ptr m_pLibrary; MixxxMainWindow* m_pMixxx; }; diff --git a/src/soundio/soundmanagerconfig.cpp b/src/soundio/soundmanagerconfig.cpp index 1ffa35fb7b9..91423189478 100644 --- a/src/soundio/soundmanagerconfig.cpp +++ b/src/soundio/soundmanagerconfig.cpp @@ -445,7 +445,7 @@ bool SoundManagerConfig::hasExternalRecordBroadcast() { * like SoundManagerConfig::API | SoundManagerConfig::DEVICES to * load default API and master device. */ -void SoundManagerConfig::loadDefaults(SoundManager *soundManager, unsigned int flags) { +void SoundManagerConfig::loadDefaults(SoundManager* soundManager, unsigned int flags) { if (flags & SoundManagerConfig::API) { QList apiList = soundManager->getHostAPIList(); if (!apiList.isEmpty()) { diff --git a/src/soundio/soundmanagerconfig.h b/src/soundio/soundmanagerconfig.h index d158ae3cd6f..c50a118d8f4 100644 --- a/src/soundio/soundmanagerconfig.h +++ b/src/soundio/soundmanagerconfig.h @@ -15,58 +15,60 @@ class SoundManager; class SoundManagerConfig { public: - explicit SoundManagerConfig(SoundManager* pSoundManager); + explicit SoundManagerConfig( + SoundManager* pSoundManager); - enum Defaults { - API = (1 << 0), - DEVICES = (1 << 1), - OTHER = (1 << 2), - ALL = (API | DEVICES | OTHER), - }; - static const unsigned int kMaxAudioBufferSizeIndex; - static const QString kDefaultAPI; - static const unsigned int kFallbackSampleRate; - static const unsigned int kDefaultDeckCount; - static const int kDefaultAudioBufferSizeIndex; - static const int kDefaultSyncBuffers; + enum Defaults { + API = (1 << 0), + DEVICES = (1 << 1), + OTHER = (1 << 2), + ALL = (API | DEVICES | OTHER), + }; + static const unsigned int kMaxAudioBufferSizeIndex; + static const QString kDefaultAPI; + static const unsigned int kFallbackSampleRate; + static const unsigned int kDefaultDeckCount; + static const int kDefaultAudioBufferSizeIndex; + static const int kDefaultSyncBuffers; - SoundManagerConfig(); - ~SoundManagerConfig(); + SoundManagerConfig(); + ~SoundManagerConfig(); - bool readFromDisk(); - bool writeToDisk() const; - QString getAPI() const; - void setAPI(const QString &api); - bool checkAPI(); - unsigned int getSampleRate() const; - void setSampleRate(unsigned int sampleRate); - bool checkSampleRate(const SoundManager &soundManager); + bool readFromDisk(); + bool writeToDisk() const; + QString getAPI() const; + void setAPI(const QString& api); + bool checkAPI(); + unsigned int getSampleRate() const; + void setSampleRate(unsigned int sampleRate); + bool checkSampleRate(const SoundManager& soundManager); - // Record the number of decks configured with this setup so they can - // be created and configured. - unsigned int getDeckCount() const; - void setDeckCount(unsigned int deckCount); - void setCorrectDeckCount(int configuredDeckCount); - QSet getDevices() const; + // Record the number of decks configured with this setup so they can + // be created and configured. + unsigned int getDeckCount() const; + void setDeckCount(unsigned int deckCount); + void setCorrectDeckCount(int configuredDeckCount); + QSet getDevices() const; + + unsigned int getAudioBufferSizeIndex() const; + unsigned int getFramesPerBuffer() const; + // Returns the processing latency in milliseconds + double getProcessingLatency() const; + void setAudioBufferSizeIndex(unsigned int latency); + unsigned int getSyncBuffers() const; + void setSyncBuffers(unsigned int sampleRate); + bool getForceNetworkClock() const; + void setForceNetworkClock(bool force); + void addOutput(const SoundDeviceId& device, const AudioOutput& out); + void addInput(const SoundDeviceId& device, const AudioInput& in); + QMultiHash getOutputs() const; + QMultiHash getInputs() const; + void clearOutputs(); + void clearInputs(); + bool hasMicInputs(); + bool hasExternalRecordBroadcast(); + void loadDefaults(SoundManager* soundManager, unsigned int flags); - unsigned int getAudioBufferSizeIndex() const; - unsigned int getFramesPerBuffer() const; - // Returns the processing latency in milliseconds - double getProcessingLatency() const; - void setAudioBufferSizeIndex(unsigned int latency); - unsigned int getSyncBuffers() const; - void setSyncBuffers(unsigned int sampleRate); - bool getForceNetworkClock() const; - void setForceNetworkClock(bool force); - void addOutput(const SoundDeviceId &device, const AudioOutput &out); - void addInput(const SoundDeviceId &device, const AudioInput &in); - QMultiHash getOutputs() const; - QMultiHash getInputs() const; - void clearOutputs(); - void clearInputs(); - bool hasMicInputs(); - bool hasExternalRecordBroadcast(); - void loadDefaults(SoundManager *soundManager, unsigned int flags); private: QFileInfo m_configFile; QString m_api; From 60c7a538426df0b260641aaa5ca75fdd8ccc4ee4 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 14:50:16 -0600 Subject: [PATCH 03/11] CoreServices: move constants to anonymous namespace --- src/coreservices.cpp | 7 ++----- src/coreservices.h | 3 --- src/mixxx.h | 3 --- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/coreservices.cpp b/src/coreservices.cpp index 228d5df5300..875e07eaa71 100644 --- a/src/coreservices.cpp +++ b/src/coreservices.cpp @@ -51,6 +51,8 @@ namespace { const mixxx::Logger kLogger("CoreServices"); +constexpr int kMicrophoneCount = 4; +constexpr int kAuxiliaryCount = 4; #define CLEAR_AND_CHECK_DELETED(x) clearHelper(x, #x); @@ -95,11 +97,6 @@ inline QLocale inputLocale() { namespace mixxx { -// static -const int CoreServices::kMicrophoneCount = 4; -// static -const int CoreServices::kAuxiliaryCount = 4; - CoreServices::CoreServices(const CmdlineArgs& args) : m_runtime_timer(QLatin1String("CoreServices::runtime")), m_cmdlineArgs(args) { diff --git a/src/coreservices.h b/src/coreservices.h index 33125edfcf7..5102604dcf9 100644 --- a/src/coreservices.h +++ b/src/coreservices.h @@ -135,9 +135,6 @@ class CoreServices : public QObject { ScreenSaverPreference m_inhibitScreensaver; QSet m_skinCreatedControls; - - static const int kMicrophoneCount; - static const int kAuxiliaryCount; }; } // namespace mixxx diff --git a/src/mixxx.h b/src/mixxx.h index 5f9853d4cfa..2032375d6aa 100644 --- a/src/mixxx.h +++ b/src/mixxx.h @@ -133,7 +133,4 @@ class MixxxMainWindow : public QMainWindow { mixxx::ScreenSaverPreference m_inhibitScreensaver; QSet m_skinCreatedControls; - - static const int kMicrophoneCount; - static const int kAuxiliaryCount; }; From af3c656b46557162d7424e22e91e6694c4ee8242 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 14:32:50 -0600 Subject: [PATCH 04/11] fix Ubuntu 18.04 build --- src/controllers/dlgprefcontroller.h | 3 ++- src/controllers/dlgprefcontrollers.h | 3 ++- src/preferences/dialog/dlgpreferences.h | 5 +++-- src/preferences/dialog/dlgprefinterface.h | 3 ++- src/preferences/dialog/dlgprefsound.h | 2 ++ src/preferences/dialog/dlgprefvinyl.h | 1 + src/preferences/dialog/dlgprefwaveform.h | 3 ++- 7 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/controllers/dlgprefcontroller.h b/src/controllers/dlgprefcontroller.h index 8b4ab0e7922..e04e377a762 100644 --- a/src/controllers/dlgprefcontroller.h +++ b/src/controllers/dlgprefcontroller.h @@ -2,6 +2,7 @@ #include #include +#include #include "controllers/controllerinputmappingtablemodel.h" #include "controllers/controlleroutputmappingtablemodel.h" @@ -9,8 +10,8 @@ #include "controllers/controllerpresetinfo.h" #include "controllers/dlgcontrollerlearning.h" #include "controllers/ui_dlgprefcontrollerdlg.h" -#include "preferences/usersettings.h" #include "preferences/dlgpreferencepage.h" +#include "preferences/usersettings.h" // Forward declarations class Controller; diff --git a/src/controllers/dlgprefcontrollers.h b/src/controllers/dlgprefcontrollers.h index 8a74add548f..3242a4104b2 100644 --- a/src/controllers/dlgprefcontrollers.h +++ b/src/controllers/dlgprefcontrollers.h @@ -1,10 +1,11 @@ #pragma once #include +#include -#include "preferences/usersettings.h" #include "controllers/ui_dlgprefcontrollersdlg.h" #include "preferences/dlgpreferencepage.h" +#include "preferences/usersettings.h" class DlgPreferences; class DlgPrefController; diff --git a/src/preferences/dialog/dlgpreferences.h b/src/preferences/dialog/dlgpreferences.h index b1503a996ea..95b5d78f49b 100644 --- a/src/preferences/dialog/dlgpreferences.h +++ b/src/preferences/dialog/dlgpreferences.h @@ -4,12 +4,13 @@ #include #include #include +#include -#include "preferences/dialog/ui_dlgpreferencesdlg.h" -#include "preferences/usersettings.h" #include "control/controlpushbutton.h" +#include "preferences/dialog/ui_dlgpreferencesdlg.h" #include "preferences/dlgpreferencepage.h" #include "preferences/settingsmanager.h" +#include "preferences/usersettings.h" class MixxxMainWindow; class SoundManager; diff --git a/src/preferences/dialog/dlgprefinterface.h b/src/preferences/dialog/dlgprefinterface.h index f7ad65c1a89..b5acf367988 100644 --- a/src/preferences/dialog/dlgprefinterface.h +++ b/src/preferences/dialog/dlgprefinterface.h @@ -1,11 +1,12 @@ #pragma once #include +#include #include "preferences/constants.h" #include "preferences/dialog/ui_dlgprefinterfacedlg.h" -#include "preferences/usersettings.h" #include "preferences/dlgpreferencepage.h" +#include "preferences/usersettings.h" class ControlProxy; class ControlPotmeter; diff --git a/src/preferences/dialog/dlgprefsound.h b/src/preferences/dialog/dlgprefsound.h index 283027b4372..90069508068 100644 --- a/src/preferences/dialog/dlgprefsound.h +++ b/src/preferences/dialog/dlgprefsound.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "defs_urls.h" #include "preferences/dialog/ui_dlgprefsounddlg.h" #include "preferences/dlgpreferencepage.h" diff --git a/src/preferences/dialog/dlgprefvinyl.h b/src/preferences/dialog/dlgprefvinyl.h index ae2b03832b0..77c5d1c43a4 100644 --- a/src/preferences/dialog/dlgprefvinyl.h +++ b/src/preferences/dialog/dlgprefvinyl.h @@ -2,6 +2,7 @@ #include #include +#include #include "preferences/dialog/ui_dlgprefvinyldlg.h" #include "preferences/dlgpreferencepage.h" diff --git a/src/preferences/dialog/dlgprefwaveform.h b/src/preferences/dialog/dlgprefwaveform.h index 2bfca0dc586..7f7758f7b28 100644 --- a/src/preferences/dialog/dlgprefwaveform.h +++ b/src/preferences/dialog/dlgprefwaveform.h @@ -1,10 +1,11 @@ #pragma once #include +#include #include "preferences/dialog/ui_dlgprefwaveformdlg.h" -#include "preferences/usersettings.h" #include "preferences/dlgpreferencepage.h" +#include "preferences/usersettings.h" class MixxxMainWindow; class Library; From 9faf5ad0073f62aec66dc6b6cc25b95b9dc694fa Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 16:04:59 -0600 Subject: [PATCH 05/11] fix build without lilv --- src/coreservices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreservices.cpp b/src/coreservices.cpp index 875e07eaa71..5f8d84b932c 100644 --- a/src/coreservices.cpp +++ b/src/coreservices.cpp @@ -12,7 +12,9 @@ #include "database/mixxxdb.h" #include "effects/builtin/builtinbackend.h" #include "effects/effectsmanager.h" +#ifdef __LILV__ #include "effects/lv2/lv2backend.h" +#endif #include "engine/enginemaster.h" #include "library/coverartcache.h" #include "library/library.h" From 08aab172e4c797bead3dd6dba15d97842adb1a06 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 16:10:01 -0600 Subject: [PATCH 06/11] DlgPreferences: rename controllers -> pControllerManager --- src/preferences/dialog/dlgpreferences.cpp | 5 +++-- src/preferences/dialog/dlgpreferences.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/preferences/dialog/dlgpreferences.cpp b/src/preferences/dialog/dlgpreferences.cpp index 6aa7dc8e142..dd7bb2fa0e0 100644 --- a/src/preferences/dialog/dlgpreferences.cpp +++ b/src/preferences/dialog/dlgpreferences.cpp @@ -57,7 +57,7 @@ DlgPreferences::DlgPreferences( std::shared_ptr pSkinLoader, std::shared_ptr soundman, std::shared_ptr pPlayerManager, - std::shared_ptr controllers, + std::shared_ptr pControllerManager, std::shared_ptr pVCManager, LV2Backend* pLV2Backend, std::shared_ptr pEffectsManager, @@ -105,7 +105,8 @@ DlgPreferences::DlgPreferences( QTreeWidgetItem* pControllersTreeItem = createTreeItem( tr("Controllers"), QIcon(":/images/preferences/ic_preferences_controllers.svg")); - m_pControllersDlg = new DlgPrefControllers(this, m_pConfig, controllers, pControllersTreeItem); + m_pControllersDlg = new DlgPrefControllers( + this, m_pConfig, pControllerManager, pControllersTreeItem); addPageWidget(PreferencesPage(m_pControllersDlg, pControllersTreeItem)); #ifdef __VINYLCONTROL__ diff --git a/src/preferences/dialog/dlgpreferences.h b/src/preferences/dialog/dlgpreferences.h index 95b5d78f49b..5e62a66345e 100644 --- a/src/preferences/dialog/dlgpreferences.h +++ b/src/preferences/dialog/dlgpreferences.h @@ -65,7 +65,7 @@ class DlgPreferences : public QDialog, public Ui::DlgPreferencesDlg { std::shared_ptr pSkinLoader, std::shared_ptr soundman, std::shared_ptr pPlayerManager, - std::shared_ptr controllers, + std::shared_ptr pControllerManager, std::shared_ptr pVCManager, LV2Backend* pLV2Backend, std::shared_ptr pEffectsManager, From 06f3c2854208f4af914d137c1d87595805a31730 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 16:11:18 -0600 Subject: [PATCH 07/11] CoreServices: move #includes above forward declarations --- src/coreservices.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/coreservices.h b/src/coreservices.h index 5102604dcf9..60632204787 100644 --- a/src/coreservices.h +++ b/src/coreservices.h @@ -1,5 +1,12 @@ #pragma once +#include "preferences/configobject.h" +#include "preferences/constants.h" +#include "preferences/settingsmanager.h" +#include "soundio/sounddeviceerror.h" +#include "util/cmdlineargs.h" +#include "util/timer.h" + class QApplication; class CmdlineArgs; class KeyboardEventFilter; @@ -15,13 +22,6 @@ class TrackCollectionManager; class Library; class LV2Backend; -#include "preferences/configobject.h" -#include "preferences/constants.h" -#include "preferences/settingsmanager.h" -#include "soundio/sounddeviceerror.h" -#include "util/cmdlineargs.h" -#include "util/timer.h" - namespace mixxx { class DbConnectionPool; From 6fee01ffa32ab6c5c05fad9891b19c77bef4b912 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 16:30:40 -0600 Subject: [PATCH 08/11] auto -> QString --- src/mixxx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 791901ae228..c12ac500bd2 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -120,7 +120,7 @@ MixxxMainWindow::MixxxMainWindow( m_pGuiTick = new GuiTick(); m_pVisualsManager = new VisualsManager(); - for (const auto& group : m_pCoreServices->getPlayerManager()->getVisualPlayerGroups()) { + for (const QString& group : m_pCoreServices->getPlayerManager()->getVisualPlayerGroups()) { m_pVisualsManager->addDeck(group); } From b0b823f4fce6cea91d1a62c2c8ec84ba30ab6544 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 16:33:27 -0600 Subject: [PATCH 09/11] add debug assertion --- src/mixxx.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index c12ac500bd2..9e29dd28e47 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -120,6 +120,7 @@ MixxxMainWindow::MixxxMainWindow( m_pGuiTick = new GuiTick(); m_pVisualsManager = new VisualsManager(); + DEBUG_ASSERT(m_pCoreServices->getPlayerManager()); for (const QString& group : m_pCoreServices->getPlayerManager()->getVisualPlayerGroups()) { m_pVisualsManager->addDeck(group); } From bd8f0f461a6e092df934745ca6d7c6542bb870b4 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 16:36:55 -0600 Subject: [PATCH 10/11] make clazy happy --- src/mixxx.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 9e29dd28e47..4f690cb685e 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -121,7 +121,8 @@ MixxxMainWindow::MixxxMainWindow( m_pGuiTick = new GuiTick(); m_pVisualsManager = new VisualsManager(); DEBUG_ASSERT(m_pCoreServices->getPlayerManager()); - for (const QString& group : m_pCoreServices->getPlayerManager()->getVisualPlayerGroups()) { + const QStringList visualGroups = m_pCoreServices->getPlayerManager()->getVisualPlayerGroups(); + for (const QString& group : visualGroups) { m_pVisualsManager->addDeck(group); } @@ -226,7 +227,6 @@ MixxxMainWindow::MixxxMainWindow( if (CmdlineArgs::Instance().getStartInFullscreen() || fullscreenPref) { slotViewFullScreen(true); } - emit skinLoaded(); // Try open player device If that fails, the preference panel is opened. bool retryClicked; @@ -929,7 +929,6 @@ void MixxxMainWindow::rebootMixxxView() { } qDebug() << "rebootMixxxView DONE"; - emit skinLoaded(); } bool MixxxMainWindow::loadConfiguredSkin() { @@ -946,6 +945,7 @@ bool MixxxMainWindow::loadConfiguredSkin() { if (centralWidget() == m_pLaunchImage) { initializationProgressUpdate(100, ""); } + emit skinLoaded(); return m_pCentralWidget != nullptr; } From 2b1eb59adec40783537e50792b125a0e467be5b3 Mon Sep 17 00:00:00 2001 From: Be Date: Mon, 14 Dec 2020 16:45:53 -0600 Subject: [PATCH 11/11] add more debug assertions --- src/mixxx.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 4f690cb685e..f15df155164 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -91,6 +91,8 @@ MixxxMainWindow::MixxxMainWindow( m_pDeveloperToolsDlg(nullptr), m_toolTipsCfg(mixxx::TooltipsPreference::TOOLTIPS_ON), m_pTouchShift(nullptr) { + DEBUG_ASSERT(pApp); + DEBUG_ASSERT(pCoreServices); m_pCoreServices->initializeSettings(); m_pCoreServices->initializeKeyboard(); // These depend on the settings