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

Move beatmap track into MusicController #9792

Merged
merged 92 commits into from Sep 2, 2020

Conversation

smoogipoo
Copy link
Contributor

@smoogipoo smoogipoo commented Aug 6, 2020

I apologise for the size of this one. It's really hard to make such a change without touching almost every file in the game, which probably spells bad news for the reach of the (now) MusicController in general.
Going forward this can probably be fixed on a per-case basis by either passing down the track or caching it locally at overarching components, which is probably a good idea in general for component isolation. I've already done this for Player because it felt wrong to DI MusicController in GameplayClockContainer and FailAnimation.

The idea of this PR is to define a single owner for the beatmap's track. Specifically, the track which plays the sound and which is stored as an on-going reference.
The goal is to eventually be able to fade between tracks when changed in song select, which needs both the single owner idea and for the track to be able to be placed in the draw hierarchy - it needs to also become a DrawableTrack.

Changes of particular note

  • "Recycling" of working beatmap tracks has been removed. It is now handled by MusicController.
  • The "transferring" of working beatmaps has been removed. Both the track and texture stores are passed to new WorkingBeatmap instances by BeatmapManager and the disposal of the track store is now also handled by the BeatmapManager.
  • The cycling of tracks once one has complete has been moved from OsuGame to MusicController.
  • MusicController has been moved to OsuGameBase. It is now loaded as part of the async procedure but before the game's Loader. I haven't fully assessed the performance impact of this since it was previously in a loadComponentSingleFile() but it doesn't seem to have a noticeable impact when loading osu! from an external USB drive with ~1000 sets.
    • Another way this can be done is to move the track handling part into its own separate component, like a "TrackController" that is DI'd in by the MusicController.

Testing

Beyond the automated CI tests, I've also tested a whole bunch of scenarios, including:

  • Selecting multiplayer item with no local beatmap.
  • Selecting multiplayer item with a local beatmap.
  • Completing a beatmap import with the selected playlist item.
  • All the intros.
  • Track loops in song select.
  • Track doesn't loop in main menu.
  • Track loops in match subscreen.
  • Track doesn't change when another beatmap from the same set is selected.
  • Failing in gameplay.
  • Restarting in gameplay.
  • DT/NC/WU/WD mods applying at song select.
  • DT/NC/WU/WD mods applying in gameplay.
  • DT/NC/WU/WD mods applying after map is restarted.
  • DT/NC/WU/WD mods applying in multiplayer (match subscreen and gameplay).
  • Playing preview tracks to mute audio.
  • Changing track while a preview track is playing.

@bdach
Copy link
Collaborator

bdach commented Aug 6, 2020

Mostly out of curiosity, what is the end goal here? This seems like a pretty drastic change in direction.

@smoogipoo
Copy link
Contributor Author

smoogipoo commented Aug 7, 2020

The goal is to have a dedicated owner of the track, rather than it being referenced/potentially created by everything in the game. One immediate use for this is to fade between tracks at song select, which is a 2-liner now that MusicController can .Expire() and transform the new track.

@peppy
Copy link
Sponsor Member

peppy commented Aug 22, 2020

Are you talking about the ReadyButton usage with regards to multiplayer? or somewhere else?

@bdach
Copy link
Collaborator

bdach commented Aug 22, 2020

Yeah, that was the one.

@peppy
Copy link
Sponsor Member

peppy commented Aug 24, 2020

I've reverted that usage too. I thought it made sense to leave it as MusicController but looking at the code in the same method using gameBeatmap, revert does seem better.

@bdach
Copy link
Collaborator

bdach commented Aug 24, 2020

I don't think I have any issues left with this any more, and I've also briefly play-tested this branch and had nothing funny happen, so going to throw in a tentative approve. Should get a second pair of eyes on this before merging though (hi @smoogipoo)

bdach
bdach previously approved these changes Aug 24, 2020
Copy link
Contributor Author

@smoogipoo smoogipoo left a comment

Choose a reason for hiding this comment

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

As I mentioned in discord, I'm really not sure I like these.

Components that use both the beatmap and the track should outright crash if the track isn't loaded, rather than silently using the music controller's (wrong) track.

osu.Game/Graphics/Containers/BeatSyncedContainer.cs Outdated Show resolved Hide resolved
osu.Game/Overlays/Music/PlaylistOverlay.cs Outdated Show resolved Hide resolved
osu.Game/Overlays/NowPlayingOverlay.cs Show resolved Hide resolved
osu.Game/Screens/Menu/LogoVisualisation.cs Outdated Show resolved Hide resolved
osu.Game/Screens/Menu/MainMenu.cs Show resolved Hide resolved
osu.Game/Screens/Menu/OsuLogo.cs Show resolved Hide resolved
@smoogipoo
Copy link
Contributor Author

Seems like #9843 has broken this branch a bit. Since mods no longer preserve references, ModTimeRamp doesn't have the correct track set during gameplay...

@smoogipoo
Copy link
Contributor Author

I think this is ok, but would appreciate a second pass @peppy / @bdach , especially with my recent changes.

Comment on lines 634 to 636
Beatmap.Value.Track.ResetSpeedAdjustments();
foreach (var mod in Mods.Value.OfType<IApplicableToTrack>())
mod.ApplyToTrack(Beatmap.Value.Track);
Copy link
Collaborator

Choose a reason for hiding this comment

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

In the failing tests, doing this causes the adjustment to get re-applied twice because of this:

MusicController.AllowRateAdjustments = true;

Disabling this back again locally makes them pass, but this makes me quite uneasy... Maybe that true override is no longer necessary with the recent changes?

Copy link
Sponsor Member

Choose a reason for hiding this comment

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

i would hope it's not needed.. but also hope that it didn't break anything.

@peppy
Copy link
Sponsor Member

peppy commented Sep 2, 2020

@smoogipoo did you find the reason that was breaking things? kinda need some resolution there as it really shouldn't in my head.

@smoogipoo
Copy link
Contributor Author

I haven't, but I can imagine why. musicController.ResetTrackAdjustments() doesn't just reset the adjustments, it also adds the MC's own adjustments via mod.ApplyToTrack(). So Player does the same and the end result is that adjustments get applied twice.
Of note, MusicController.AllowRateAdjustments is false by default, and is only set to true by OsuGame when an OsuScreen wants it (pretty much everywhere except Editor, Player, MainMenu).

I'm not super confident about this code

@peppy
Copy link
Sponsor Member

peppy commented Sep 2, 2020

But player is also resetting?

image

@smoogipoo
Copy link
Contributor Author

That's correct, check the implementation of ResetTrackAdjustments:

public void ResetTrackAdjustments()
{
var track = current?.Track;
if (track == null)
return;
track.ResetSpeedAdjustments();
if (allowRateAdjustments)
{
foreach (var mod in mods.Value.OfType<IApplicableToTrack>())
mod.ApplyToTrack(track);
}
}

@peppy
Copy link
Sponsor Member

peppy commented Sep 2, 2020

ah......................... at very least let's add a mention to the xmldoc for ResetTrackAdjustments that the behaviour differs depending on AllowRateAdjustments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants