1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-23 00:37:18 +08:00

make SongProgress abstract

- move unrelated logic to `DefaultSongProgress`
- make `LegacySongProgress` inherit `SongProgress`
This commit is contained in:
Nitrous 2022-07-27 15:19:21 +08:00
parent a12676c25d
commit 37e642b0bd
No known key found for this signature in database
GPG Key ID: 85EC4A6AE8F69D64
8 changed files with 126 additions and 91 deletions

View File

@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[TestFixture]
public class TestSceneSongProgress : OsuTestScene
{
private SongProgress progress;
private DefaultSongProgress progress;
private TestSongProgressGraph graph;
private readonly Container progressContainer;
@ -62,7 +62,7 @@ namespace osu.Game.Tests.Visual.Gameplay
progress = null;
}
progressContainer.Add(progress = new SongProgress
progressContainer.Add(progress = new DefaultSongProgress
{
RelativeSizeAxes = Axes.X,
Anchor = Anchor.BottomLeft,

View File

@ -5,12 +5,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects;
@ -18,9 +15,9 @@ using osu.Game.Rulesets.UI;
using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Screens.Play
namespace osu.Game.Screens.Play.HUD
{
public class SongProgress : OverlayContainer, ISkinnableDrawable
public class DefaultSongProgress : SongProgress
{
public const float MAX_HEIGHT = info_height + bottom_bar_height + graph_height + handle_height;
@ -52,41 +49,13 @@ namespace osu.Game.Screens.Play
protected override bool BlockScrollInput => false;
private double firstHitTime => objects.First().StartTime;
//TODO: this isn't always correct (consider mania where a non-last object may last for longer than the last in the list).
private double lastHitTime => objects.Last().GetEndTime() + 1;
private IEnumerable<HitObject> objects;
public IEnumerable<HitObject> Objects
{
set
{
graph.Objects = objects = value;
info.StartTime = firstHitTime;
info.EndTime = lastHitTime;
bar.StartTime = firstHitTime;
bar.EndTime = lastHitTime;
}
}
[Resolved(canBeNull: true)]
private Player player { get; set; }
[Resolved]
private GameplayClock gameplayClock { get; set; }
[Resolved(canBeNull: true)]
private DrawableRuleset drawableRuleset { get; set; }
private IClock referenceClock;
public bool UsesFixedAnchor { get; set; }
public SongProgress()
public DefaultSongProgress()
{
RelativeSizeAxes = Axes.X;
Anchor = Anchor.BottomRight;
@ -127,9 +96,6 @@ namespace osu.Game.Screens.Play
{
if (player?.Configuration.AllowUserInteraction == true)
((IBindable<bool>)AllowSeeking).BindTo(drawableRuleset.HasReplayLoaded);
referenceClock = drawableRuleset.FrameStableClock;
Objects = drawableRuleset.Objects;
}
graph.FillColour = bar.FillColour = colours.BlueLighter;
@ -203,21 +169,24 @@ namespace osu.Game.Screens.Play
this.FadeOut(100);
}
protected override void UpdateObjects(IEnumerable<HitObject> objects)
{
graph.Objects = objects;
info.StartTime = FirstHitTime;
info.EndTime = LastHitTime;
bar.StartTime = FirstHitTime;
bar.EndTime = LastHitTime;
}
protected override void UpdateProgress(double progress, double time, bool isIntro)
{
bar.CurrentTime = time;
graph.Progress = (int)(graph.ColumnCount * progress);
}
protected override void Update()
{
base.Update();
if (objects == null)
return;
double gameplayTime = gameplayClock?.CurrentTime ?? Time.Current;
double frameStableTime = referenceClock?.CurrentTime ?? gameplayTime;
double progress = Math.Min(1, (frameStableTime - firstHitTime) / (lastHitTime - firstHitTime));
bar.CurrentTime = gameplayTime;
graph.Progress = (int)(graph.ColumnCount * progress);
Height = bottom_bar_height + graph_height + handle_size.Y + info_height - graph.Y;
}

View File

@ -0,0 +1,85 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;
using osu.Game.Skinning;
namespace osu.Game.Screens.Play.HUD
{
public abstract class SongProgress : OverlayContainer, ISkinnableDrawable
{
public bool UsesFixedAnchor { get; set; }
[Resolved]
private GameplayClock gameplayClock { get; set; }
[Resolved(canBeNull: true)]
private DrawableRuleset drawableRuleset { get; set; }
[Resolved(canBeNull: true)]
private IBindable<WorkingBeatmap> beatmap { get; set; }
private IClock referenceClock;
private IEnumerable<HitObject> objects;
public IEnumerable<HitObject> Objects
{
set => UpdateObjects(objects = value);
}
protected double FirstHitTime => objects.FirstOrDefault()?.StartTime ?? 0;
//TODO: this isn't always correct (consider mania where a non-last object may last for longer than the last in the list).
protected double LastHitTime => objects.LastOrDefault()?.GetEndTime() ?? 0;
protected double FirstEventTime { get; private set; }
protected abstract void UpdateProgress(double progress, double time, bool isIntro);
protected abstract void UpdateObjects(IEnumerable<HitObject> objects);
[BackgroundDependencyLoader]
private void load()
{
if (drawableRuleset != null)
{
Objects = drawableRuleset.Objects;
referenceClock = drawableRuleset.FrameStableClock;
}
if (beatmap != null)
{
FirstEventTime = beatmap.Value.Storyboard.EarliestEventTime ?? 0;
}
}
protected override void Update()
{
base.Update();
if (objects == null)
return;
double gameplayTime = gameplayClock?.CurrentTime ?? Time.Current;
double frameStableTime = referenceClock?.CurrentTime ?? gameplayTime;
if (frameStableTime < FirstHitTime)
{
UpdateProgress((frameStableTime - FirstEventTime) / (FirstHitTime - FirstEventTime), gameplayTime, true);
}
else
{
UpdateProgress((frameStableTime - FirstHitTime) / (LastHitTime - FirstHitTime), gameplayTime, false);
}
}
}
}

View File

@ -13,7 +13,7 @@ using osu.Framework.Graphics.UserInterface;
using osu.Framework.Utils;
using osu.Framework.Threading;
namespace osu.Game.Screens.Play
namespace osu.Game.Screens.Play.HUD
{
public class SongProgressBar : SliderBar<double>
{

View File

@ -8,7 +8,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Screens.Play
namespace osu.Game.Screens.Play.HUD
{
public class SongProgressGraph : SquareGraph
{

View File

@ -10,7 +10,7 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using System;
namespace osu.Game.Screens.Play
namespace osu.Game.Screens.Play.HUD
{
public class SongProgressInfo : Container
{

View File

@ -147,7 +147,7 @@ namespace osu.Game.Skinning
new DefaultScoreCounter(),
new DefaultAccuracyCounter(),
new DefaultHealthDisplay(),
new SongProgress(),
new DefaultSongProgress(),
new BarHitErrorMeter(),
new BarHitErrorMeter(),
new PerformancePointsCounter()

View File

@ -3,38 +3,20 @@
#nullable disable
using System;
using System.Linq;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.HUD;
using osuTK;
namespace osu.Game.Skinning
{
public class LegacySongProgress : CompositeDrawable, ISkinnableDrawable
public class LegacySongProgress : SongProgress
{
public bool UsesFixedAnchor { get; set; }
[Resolved]
private GameplayClock gameplayClock { get; set; }
[Resolved(canBeNull: true)]
private DrawableRuleset drawableRuleset { get; set; }
[Resolved(canBeNull: true)]
private IBindable<WorkingBeatmap> beatmap { get; set; }
private double lastHitTime;
private double firstHitTime;
private double firstEventTime;
private CircularProgress pie;
[BackgroundDependencyLoader]
@ -76,36 +58,35 @@ namespace osu.Game.Skinning
Size = new Vector2(3),
}
};
firstEventTime = beatmap?.Value.Storyboard.EarliestEventTime ?? 0;
if (drawableRuleset != null)
{
firstHitTime = drawableRuleset.Objects.First().StartTime;
//TODO: this isn't always correct (consider mania where a non-last object may last for longer than the last in the list).
lastHitTime = drawableRuleset.Objects.Last().GetEndTime() + 1;
}
}
protected override void Update()
protected override void PopIn()
{
base.Update();
}
double gameplayTime = gameplayClock?.CurrentTime ?? Time.Current;
protected override void PopOut()
{
}
if (gameplayTime < firstHitTime)
protected override void UpdateObjects(IEnumerable<HitObject> objects)
{
}
protected override void UpdateProgress(double progress, double time, bool isIntro)
{
if (isIntro)
{
pie.Scale = new Vector2(-1, 1);
pie.Anchor = Anchor.TopRight;
pie.Colour = new Colour4(199, 255, 47, 153);
pie.Current.Value = 1 - Math.Clamp((gameplayTime - firstEventTime) / (firstHitTime - firstEventTime), 0, 1);
pie.Current.Value = 1 - progress;
}
else
{
pie.Scale = new Vector2(1);
pie.Anchor = Anchor.TopLeft;
pie.Colour = new Colour4(255, 255, 255, 153);
pie.Current.Value = Math.Clamp((gameplayTime - firstHitTime) / (lastHitTime - firstHitTime), 0, 1);
pie.Current.Value = progress;
}
}
}