Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
acolombier committed Feb 2, 2025
1 parent 691ebc1 commit 880db57
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 39 deletions.
31 changes: 4 additions & 27 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,39 +57,16 @@ constexpr int kPixmapCacheLimitAt100PercentZoom = 32 * 1024; // 32 MByte
int runMixxx(MixxxApplication* pApp, const CmdlineArgs& args) {
CmdlineArgs::Instance().parseForUserFeedback();

auto pCoreServices = std::make_shared<mixxx::CoreServices>(args, pApp);

int exitCode;
#ifdef MIXXX_USE_QML
if (args.isQml()) {
auto pTick = std::make_unique<GuiTick>();
auto pVisuals = std::make_unique<VisualsManager>();
WaveformWidgetFactory::createInstance(); // takes a long time
WaveformWidgetFactory::instance()->setConfig(pCoreServices->getSettings());
WaveformWidgetFactory::instance()->startVSync(pTick.get(), pVisuals.get(), true);
{
mixxx::qml::QmlApplication qmlApplication(pApp, pCoreServices);
const QStringList visualGroups =
pCoreServices->getPlayerManager()->getVisualPlayerGroups();
for (const QString& group : visualGroups) {
pVisuals->addDeck(group);
}
pCoreServices->getPlayerManager()->connect(pCoreServices->getPlayerManager().get(),
&PlayerManager::numberOfDecksChanged,
&qmlApplication,
[&pVisuals](int decks) {
for (int i = 0; i < decks; ++i) {
QString group = PlayerManager::groupForDeck(i);
pVisuals->addDeckIfNotExist(group);
}
});
exitCode = pApp->exec();
}
pCoreServices.reset();
WaveformWidgetFactory::destroy();
mixxx::qml::QmlApplication qmlApplication(pApp, args);
exitCode = pApp->exec();
} else
#endif
{
auto pCoreServices = std::make_shared<mixxx::CoreServices>(args, pApp);

// This scope ensures that `MixxxMainWindow` is destroyed *before*
// CoreServices is shut down. Otherwise a debug assertion complaining about
// leaked COs may be triggered.
Expand Down
45 changes: 39 additions & 6 deletions src/qml/qmlapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "qml/qmlvisibleeffectsmodel.h"
#include "qml/qmlwaveformoverview.h"
#include "soundio/soundmanager.h"
#include "waveform/guitick.h"
#include "waveform/visualsmanager.h"
#include "waveform/waveformwidgetfactory.h"
Q_IMPORT_QML_PLUGIN(MixxxPlugin)
Q_IMPORT_QML_PLUGIN(Mixxx_ControlsPlugin)

Expand All @@ -42,13 +45,19 @@ namespace qml {

QmlApplication::QmlApplication(
QApplication* app,
std::shared_ptr<CoreServices> pCoreServices)
: m_pCoreServices(pCoreServices),
m_mainFilePath(pCoreServices->getSettings()->getResourcePath() + kMainQmlFileName),
const CmdlineArgs& args)
: m_pCoreServices(std::make_unique<mixxx::CoreServices>(args, app)),
m_guiTick(std::make_unique<GuiTick>()),
m_visualsManager(std::make_unique<VisualsManager>()),
m_mainFilePath(m_pCoreServices->getSettings()->getResourcePath() + kMainQmlFileName),
m_pAppEngine(nullptr),
m_autoReload() {
QQuickStyle::setStyle("Basic");

WaveformWidgetFactory::createInstance(); // takes a long time
WaveformWidgetFactory::instance()->setConfig(m_pCoreServices->getSettings());
WaveformWidgetFactory::instance()->startVSync(m_guiTick.get(), m_visualsManager.get(), true);

m_pCoreServices->initialize(app);
SoundDeviceStatus result = m_pCoreServices->getSoundManager()->setupDevices();
if (result != SoundDeviceStatus::Ok) {
Expand All @@ -67,22 +76,46 @@ QmlApplication::QmlApplication(

// Since DlgPreferences is only meant to be used in the main QML engine, it
// follows a strict singleton pattern design
QmlDlgPreferencesProxy::s_pInstance = new QmlDlgPreferencesProxy(pDlgPreferences, this);
QmlDlgPreferencesProxy::s_pInstance =
std::make_unique<QmlDlgPreferencesProxy>(pDlgPreferences, this);
loadQml(m_mainFilePath);

pCoreServices->getControllerManager()->setUpDevices();
m_pCoreServices->getControllerManager()->setUpDevices();

connect(&m_autoReload,
&QmlAutoReload::triggered,
this,
[this]() {
loadQml(m_mainFilePath);
});

const QStringList visualGroups =
m_pCoreServices->getPlayerManager()->getVisualPlayerGroups();
for (const QString& group : visualGroups) {
m_visualsManager->addDeck(group);
}

m_pCoreServices->getPlayerManager()->connect(
m_pCoreServices->getPlayerManager().get(),
&PlayerManager::numberOfDecksChanged,
this,
[this](int decks) {
for (int i = 0; i < decks; ++i) {
QString group = PlayerManager::groupForDeck(i);
m_visualsManager->addDeckIfNotExist(group);
}
});
}

QmlApplication::~QmlApplication() {
// Delete all the QML singletons in order to prevent leak detection in CoreService
QmlDlgPreferencesProxy::s_pInstance->deleteLater();
QmlDlgPreferencesProxy::s_pInstance.reset();

WaveformWidgetFactory::destroy();
m_guiTick.reset();
m_visualsManager.reset();
m_pAppEngine.reset();
m_pCoreServices.reset();
}

void QmlApplication::loadQml(const QString& path) {
Expand Down
10 changes: 8 additions & 2 deletions src/qml/qmlapplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#include "coreservices.h"
#include "qmlautoreload.h"

class GuiTick;
class VisualsManager;

namespace mixxx {
namespace qml {

Expand All @@ -14,14 +17,17 @@ class QmlApplication : public QObject {
public:
QmlApplication(
QApplication* app,
std::shared_ptr<CoreServices> pCoreServices);
const CmdlineArgs& args);
~QmlApplication() override;

public slots:
void loadQml(const QString& path);

private:
std::shared_ptr<CoreServices> m_pCoreServices;
std::unique_ptr<CoreServices> m_pCoreServices;

std::unique_ptr<::GuiTick> m_guiTick;
std::unique_ptr<::VisualsManager> m_visualsManager;

QString m_mainFilePath;

Expand Down
4 changes: 2 additions & 2 deletions src/qml/qmldlgpreferencesproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ QmlDlgPreferencesProxy* QmlDlgPreferencesProxy::create(

// Explicitly specify C++ ownership so that the engine doesn't delete
// the instance.
QJSEngine::setObjectOwnership(s_pInstance, QJSEngine::CppOwnership);
return s_pInstance;
QJSEngine::setObjectOwnership(s_pInstance.get(), QJSEngine::CppOwnership);
return s_pInstance.get();
}

} // namespace qml
Expand Down
2 changes: 1 addition & 1 deletion src/qml/qmldlgpreferencesproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class QmlDlgPreferencesProxy : public QObject {
Q_INVOKABLE void show();

static QmlDlgPreferencesProxy* create(QQmlEngine* pQmlEngine, QJSEngine* pJsEngine);
static inline QmlDlgPreferencesProxy* s_pInstance = nullptr;
static inline std::unique_ptr<QmlDlgPreferencesProxy> s_pInstance;

private:
static inline QJSEngine* s_pJsEngine = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion src/soundio/soundmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void SoundManager::closeDevices(bool sleepAfterClosing) {
#ifdef __LINUX__
// Sleep for 5 sec to allow asynchronously sound APIs like "pulse" to free
// its resources as well
QThread::sleep(kSleepSecondsAfterClosingDevice);
// QThread::sleep(kSleepSecondsAfterClosingDevice);
#endif
}

Expand Down

0 comments on commit 880db57

Please sign in to comment.