Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor MixxxMainWindow. #941

Closed
wants to merge 8 commits into from
Closed

Refactor MixxxMainWindow. #941

wants to merge 8 commits into from

Conversation

rryan
Copy link
Member

@rryan rryan commented May 4, 2016

Splits MixxxMainWindow into two pieces: CoreServices and WMainWindow.

This will allow us to iterate on new frontends that do not make use of
QtWidgets / QtGui (such as an Android or iOS port) and generally
enforces a cleaner separation between Mixxx services (provided by
individual manager classes) and the Mixxx UI.

This is also a step towards refactoring the bootup process (which
prompted us to add a loading" launch screen because it's so
slow). With a cleaner concept of "phases" of bootup (construction,
initialize, configure, finalize, destruction) we can start the UI
after construction/initialization and delay the longer tasks
(e.g. connecting audio devices and controllers) or push them onto a
different thread.

Ideally all manager classes and Core will remain buildable with the
QtWidgets module disabled.

@rryan
Copy link
Member Author

rryan commented May 5, 2016

This is step 2 (step 1 was WMainMenuBar) on a long-term refactor journey for me. I wrote down some of the goals in this design doc:
http://mixxx.org/wiki/doku.php/mixxx_init_refactor

@daschuer
Copy link
Member

daschuer commented May 5, 2016

I have just read the linked document and I like the underlying ideas. The multi-threading approach will help to utilize the n-cores of recent CPUs.

However, I think it is not a good idea to present the GUI before Mixxx is ready to used.
This is one of the annoyances (old) Windows compared to Linux, Windows predicts to be ready, but you cannot use it util the HDD has stopped seeking.

An other general thought is: Multitheading increased the complexity significant. If you aim to reduce the complexity this might be a bad deal. But we will see, when it comes to the implementation.

src/main.cpp Outdated
qDebug() << "Running Mixxx";
result = a.exec();
mixxx::Core::initializeStaticServices();
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// scope for core

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done -- though this seems a bit obvious, no?

@daschuer
Copy link
Member

daschuer commented May 5, 2016

OK, I assume there where nothing changed in the business logic, only moving functions around, right? I have only added some minor nits.

The other main issue is the release schedule. We have already published a release date for Mixxx 2.1
for February 2016. The current master version contains a lot of improvements worth a soon release without any further additions. So we should brake out a 2.1 branch and announce the beta phase now.

( The alpha seams to be blocked by the broken windows build server though
@Pegasus-RPG: how is your progress?
I have played with https://www.appveyor.com/ , will it be an alternative?
)

These planed refactorings will not have a user impact, but have some degree of regression risk.
So the should go to a master. The same is true for the GSOC projects.

@rryan
Copy link
Member Author

rryan commented May 6, 2016

OK, I assume there where nothing changed in the business logic, only moving functions around, right? I have only added some minor nits.

Yep, that's right.

@rryan
Copy link
Member Author

rryan commented May 6, 2016

The other main issue is the release schedule. We have already published a release date for Mixxx 2.1
for February 2016. The current master version contains a lot of improvements worth a soon release without any further additions. So we should brake out a 2.1 branch and announce the beta phase now.

I agree this shouldn't go in 2.1.

@Be-ing
Copy link
Contributor

Be-ing commented Dec 27, 2017

@rryan are you interested in picking this up again? Now would be the time to do it. Our startup time has gotten really bad.

@Be-ing
Copy link
Contributor

Be-ing commented Apr 18, 2018

This pull request has not been updated in years so I am closing it to reduce the clutter of open PRs. If you solve the merge conflicts and would like to have it merged in the future, please reopen it. However, considering how many merge conflicts there are, it may be easier to start over from the current master branch.

@Be-ing Be-ing closed this Apr 18, 2018
@rryan
Copy link
Member Author

rryan commented Apr 18, 2018

@rryan are you interested in picking this up again? Now would be the time to do it. Our startup time has gotten really bad.

Yea, I am. I'll re-open when/if I get to it though.

@rryan
Copy link
Member Author

rryan commented Sep 17, 2018

Re-based against master, tests are passing on macOS and no shared_ptr leaks occur.

@Be-ing
Copy link
Contributor

Be-ing commented Sep 17, 2018

Thanks for picking up work on this again!

@rryan rryan force-pushed the core branch 2 times, most recently from 19d9e56 to e7bebe3 Compare September 17, 2018 23:51
@mixxxdj mixxxdj deleted a comment Sep 18, 2018
@mixxxdj mixxxdj deleted a comment Sep 18, 2018
@Be-ing
Copy link
Contributor

Be-ing commented Sep 18, 2018

I think there will be a few small merge conflicts between this and #1705, but it looks like they will be easy to resolve.

Splits MixxxMainWindow into two pieces: CoreServices and WMainWindow.

This will allow us to iterate on new frontends that do not make use of
QtWidgets / QtGui (such as an Android or iOS port) and generally
enforces a cleaner separation between Mixxx services (provided by
individual manager classes) and the Mixxx UI.

This is also a step towards refactoring the bootup process (which
prompted us to add a loading" launch screen because it's so
slow). With a cleaner concept of "phases" of bootup (construction,
initialize, configure, finalize, destruction) we can start the UI
after construction/initialization and delay the longer tasks
(e.g. connecting audio devices and controllers) or push them onto a
different thread.

Ideally all manager classes and CoreServices will remain buildable with the
QtWidgets module disabled.
This adds safety against use-after-free to the interaction between
EngineMaster, SoundManager, EngineSideChain, VinylControlProcessor,
EngineDeck, EngineMicrophone, and EngineAux.

Note that this effectively reverts
db3b503. The reason this was done
initially was to avoid coupling between SoundManager and
EngineMaster. Ideally neither of them should know about each other,
and they could communicate via interfaces alone. They are currently
coupled (SoundManager has a reference to EngineMaster) because of the
callback, but I've always wanted to remove that so they are totally
independent.

PlayerManager (which could have been named EngineManager) as I
originally imagined it, is where EngineMaster and SoundManager are
bound together, since PlayerManager has a reference to both; for
example, when a deck is added, it's added to EngineMaster and
registered with SoundManager in PlayerManager. That's why the logic to
register EngineMaster's non-EngineChannel AudioInputs/AudioOutputs
originally went in PlayerManager. Thinking of PlayerManager as
EngineManager, this kind of makes sense.

In this PR, the logic can no longer live in EngineMaster for the
simple reason that EngineMaster does not have a shared_ptr to itself,
and so it can't call SoundManager::registerXXX(..., this) anymore. We
could plumb a shared_ptr into EngineMaster, but that creates a
reference leak.
@rryan
Copy link
Member Author

rryan commented Oct 2, 2018

I think this is ready to go. It's a first step toward the plan for an init refactor that only moves code around without intentionally changing any logic. The ordering of some steps in bootup and shutdown have changed slightly, but it should only be incidental. Any comments?

@rryan
Copy link
Member Author

rryan commented Oct 2, 2018

I think there will be a few small merge conflicts between this and #1705, but it looks like they will be easy to resolve.

Yea, I tried to make this minimally invasive w.r.t. any changes made to the effects system or library.

Copy link
Contributor

@Be-ing Be-ing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for starting to clean this up!

void clearHelper(std::shared_ptr<T>& ref_ptr, const char* name) {
std::weak_ptr<T> weak(ref_ptr);
ref_ptr.reset();
if (auto shared = weak.lock()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEBUG_ASSERT?

@@ -778,7 +397,7 @@ void MixxxMainWindow::initializeKeyboard() {
m_pKeyboard = new KeyboardEventFilter(keyboardShortcutsEnabled ? m_pKbdConfig : m_pKbdConfigEmpty);
}

QDialog::DialogCode MixxxMainWindow::soundDeviceErrorDlg(
QDialog::DialogCode WMainWindow::soundDeviceErrorDlg(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels out of place in WMainWindow. Should it be moved into SoundManager?

namespace mixxx {

class CoreServices : public QObject {
Q_OBJECT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be a Q_OBJECT?


m_pGuiTick = std::make_shared<GuiTick>();

// TODO(rryan): Move this back into EngineMaster. The only reason it got
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I agree this should be moved back to EngineMaster. There some places throughout the code that rely on parsing strings to identify a channel. I think it would be better to make use of ChannelHandles more widely throughout Mixxx than confine them to EngineMaster.

m_pEffectsManager = std::make_shared<EffectsManager>(this, pConfig, m_pChannelHandleFactory);

// Starting the master (mixing of the channels and effects):
m_pEngine = std::make_shared<EngineMaster>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we drop the "Master" from "EngineMaster"? Or maybe call it "EngineMixer"?

std::static_pointer_cast<GlobalTrackCacheSaver>(m_pLibrary));

// TODO(rryan): de-singleton
// TODO(rryan): Where does this belong?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LibraryManager?

m_pPlayerManager->addSampler();
m_pPlayerManager->addPreviewDeck();

// TODO(rryan): Why is this here?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC this has to be called after creating mics, aux channels, and samplers in case those are routed to any saved chains. (I could be wrong about that.)

auto core = std::make_shared<mixxx::CoreServices>(nullptr, app, args.getSettingsPath());
core->initialize();
{ // Scope for WMainWindow.
WMainWindow window(app, core);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduces a regression. No GUI is shown for about 3 seconds, then when the main window is first shown, the loading progress bar is already over half way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping. I propose moving the construction of services in the CoreServices class from the constructor to a new method that would get called by WMainWindow. Then have CoreServices emit a signal after each service is started that triggers a progress bar update in WMainWindow.

@Be-ing
Copy link
Contributor

Be-ing commented Nov 21, 2018

I would like to merge this relatively soon before more merge conflicts develop.

@Be-ing
Copy link
Contributor

Be-ing commented Dec 27, 2018

@rryan will you have time to continue this soon? If not I might pick it up.

@Be-ing Be-ing mentioned this pull request Dec 28, 2018
@rryan
Copy link
Member Author

rryan commented Dec 28, 2018

@rryan will you have time to continue this soon? If not I might pick it up.

Yea, it's on my list after #926.

@Be-ing Be-ing modified the milestones: 2.3.0, 2.4.0 Feb 7, 2019
@Be-ing Be-ing modified the milestones: 2.4.0, stalled Apr 6, 2020
@github-actions
Copy link

This PR is marked as stale because it has been open 90 days with no activity.

@github-actions github-actions bot added the stale Stale issues that haven't been updated for a long time. label Oct 20, 2020
@Be-ing Be-ing changed the base branch from master to main October 23, 2020 23:54
@Be-ing
Copy link
Contributor

Be-ing commented Dec 15, 2020

Superceeded by #3446

@Be-ing Be-ing closed this Dec 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale Stale issues that haven't been updated for a long time.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants