Cleanups + xmldoc rewordings/improvements.

This commit is contained in:
smoogipooo
2017-06-12 15:20:34 +09:00
parent 419682b740
commit ba8014bbd9
9 changed files with 108 additions and 66 deletions

View File

@ -7,8 +7,17 @@ using osu.Game.Rulesets.Timing;
namespace osu.Game.Rulesets.Mania.Mods namespace osu.Game.Rulesets.Mania.Mods
{ {
/// <summary>
/// A type of mod which generates speed adjustments that scroll the hit objects and bar lines.
/// </summary>
internal interface IGenerateSpeedAdjustments internal interface IGenerateSpeedAdjustments
{ {
/// <summary>
/// Applies this mod to a hit renderer.
/// </summary>
/// <param name="hitRenderer">The hit renderer to apply to.</param>
/// <param name="hitObjectTimingChanges">The per-column list of speed adjustments for hit objects.</param>
/// <param name="barlineTimingChanges">The list of speed adjustments for bar lines.</param>
void ApplyToHitRenderer(ManiaHitRenderer hitRenderer, ref List<SpeedAdjustmentContainer>[] hitObjectTimingChanges, ref List<SpeedAdjustmentContainer> barlineTimingChanges); void ApplyToHitRenderer(ManiaHitRenderer hitRenderer, ref List<SpeedAdjustmentContainer>[] hitObjectTimingChanges, ref List<SpeedAdjustmentContainer> barlineTimingChanges);
} }
} }

View File

@ -7,7 +7,6 @@ using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Mania.Timing;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.Timing;
using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables;
@ -23,21 +22,21 @@ namespace osu.Game.Rulesets.Mania.Mods
public void ApplyToHitRenderer(ManiaHitRenderer hitRenderer, ref List<SpeedAdjustmentContainer>[] hitObjectTimingChanges, ref List<SpeedAdjustmentContainer> barlineTimingChanges) public void ApplyToHitRenderer(ManiaHitRenderer hitRenderer, ref List<SpeedAdjustmentContainer>[] hitObjectTimingChanges, ref List<SpeedAdjustmentContainer> barlineTimingChanges)
{ {
foreach (HitObject obj in hitRenderer.Objects) // We have to generate one speed adjustment per hit object for gravity
foreach (ManiaHitObject obj in hitRenderer.Objects)
{ {
var maniaObject = obj as ManiaHitObject;
if (maniaObject == null)
continue;
MultiplierControlPoint controlPoint = hitRenderer.CreateControlPointAt(obj.StartTime); MultiplierControlPoint controlPoint = hitRenderer.CreateControlPointAt(obj.StartTime);
// Beat length has too large of an effect for gravity, so we'll force it to a constant value for now
controlPoint.TimingPoint.BeatLength = 1000; controlPoint.TimingPoint.BeatLength = 1000;
hitObjectTimingChanges[maniaObject.Column].Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity)); hitObjectTimingChanges[obj.Column].Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity));
} }
// Like with hit objects, we need to generate one speed adjustment per bar line
foreach (DrawableBarLine barLine in hitRenderer.BarLines) foreach (DrawableBarLine barLine in hitRenderer.BarLines)
{ {
var controlPoint = hitRenderer.CreateControlPointAt(barLine.HitObject.StartTime); var controlPoint = hitRenderer.CreateControlPointAt(barLine.HitObject.StartTime);
// Beat length has too large of an effect for gravity, so we'll force it to a constant value for now
controlPoint.TimingPoint.BeatLength = 1000; controlPoint.TimingPoint.BeatLength = 1000;
barlineTimingChanges.Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity)); barlineTimingChanges.Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity));

View File

@ -6,21 +6,24 @@ using osu.Game.Rulesets.Timing;
namespace osu.Game.Rulesets.Mania.Timing namespace osu.Game.Rulesets.Mania.Timing
{ {
/// <summary>
/// A <see cref="DrawableTimingSection"/> which scrolls relative to the control point start time.
/// </summary>
internal class BasicScrollingDrawableTimingSection : DrawableTimingSection internal class BasicScrollingDrawableTimingSection : DrawableTimingSection
{ {
private readonly MultiplierControlPoint timingSection; private readonly MultiplierControlPoint controlPoint;
public BasicScrollingDrawableTimingSection(MultiplierControlPoint timingSection) public BasicScrollingDrawableTimingSection(MultiplierControlPoint controlPoint)
: base(Axes.Y) : base(Axes.Y)
{ {
this.timingSection = timingSection; this.controlPoint = controlPoint;
} }
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();
Y = (float)(timingSection.StartTime - Time.Current); Y = (float)(controlPoint.StartTime - Time.Current);
} }
} }
} }

View File

@ -6,14 +6,17 @@ using osu.Game.Rulesets.Timing;
namespace osu.Game.Rulesets.Mania.Timing namespace osu.Game.Rulesets.Mania.Timing
{ {
/// <summary>
/// A <see cref="DrawableTimingSection"/> that emulates a form of gravity where hit objects speed up over time.
/// </summary>
internal class GravityScrollingDrawableTimingSection : DrawableTimingSection internal class GravityScrollingDrawableTimingSection : DrawableTimingSection
{ {
private readonly MultiplierControlPoint timingSection; private readonly MultiplierControlPoint controlPoint;
public GravityScrollingDrawableTimingSection(MultiplierControlPoint timingSection) public GravityScrollingDrawableTimingSection(MultiplierControlPoint controlPoint)
: base(Axes.Y) : base(Axes.Y)
{ {
this.timingSection = timingSection; this.controlPoint = controlPoint;
} }
protected override void UpdateAfterChildren() protected override void UpdateAfterChildren()
@ -21,9 +24,9 @@ namespace osu.Game.Rulesets.Mania.Timing
base.UpdateAfterChildren(); base.UpdateAfterChildren();
// The gravity-adjusted start position // The gravity-adjusted start position
float startPos = (float)computeGravityTime(timingSection.StartTime); float startPos = (float)computeGravityTime(controlPoint.StartTime);
// The gravity-adjusted end position // The gravity-adjusted end position
float endPos = (float)computeGravityTime(timingSection.StartTime + RelativeChildSize.Y); float endPos = (float)computeGravityTime(controlPoint.StartTime + RelativeChildSize.Y);
Y = startPos; Y = startPos;
Height = endPos - startPos; Height = endPos - startPos;

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Caching; using osu.Framework.Caching;
@ -24,19 +23,21 @@ namespace osu.Game.Rulesets.Timing
/// </para> /// </para>
/// ///
/// <para> /// <para>
/// This container will auto-size to the total size of its children along the desired auto-sizing axes such that the reasulting size /// This container will auto-size to the total duration of the contained hit objects along the desired auto-sizing axes such that the resulting size
/// of this container will also be a time value. /// of this container will be a value representing the total duration of all contained hit objects.
/// </para> /// </para>
/// ///
/// <para> /// <para>
/// This container is and must always be relatively-sized and positioned to its such that the parent can utilise /// This container is and must always be relatively-sized and positioned to its such that the parent can utilise <see cref="Container{T}.RelativeChildSize"/>
/// <see cref="Container{T}.RelativeChildSize"/> and <see cref="Container{T}.RelativeChildOffset"/> to apply further time offsets /// and <see cref="Container{T}.RelativeChildOffset"/> to apply further time offsets to this collection of hit objects.
/// to this collection of hit objects.
/// </para> /// </para>
/// </summary> /// </summary>
public abstract class DrawableTimingSection : Container<DrawableHitObject> public abstract class DrawableTimingSection : Container<DrawableHitObject>
{ {
private readonly BindableDouble visibleTimeRange = new BindableDouble(); private readonly BindableDouble visibleTimeRange = new BindableDouble();
/// <summary>
/// Gets or sets the range of time that is visible by the length of this container.
/// </summary>
public BindableDouble VisibleTimeRange public BindableDouble VisibleTimeRange
{ {
get { return visibleTimeRange; } get { return visibleTimeRange; }
@ -57,18 +58,8 @@ namespace osu.Game.Rulesets.Timing
{ {
this.autoSizingAxes = autoSizingAxes; this.autoSizingAxes = autoSizingAxes;
RelativeSizeAxes = Axes.Both;
RelativePositionAxes = Axes.Both; RelativePositionAxes = Axes.Both;
// We need a default size since RelativeSizeAxes is overridden
Size = Vector2.One;
}
public override Axes AutoSizeAxes { set { throw new InvalidOperationException($"{nameof(DrawableTimingSection)} must always be relatively-sized."); } }
public override Axes RelativeSizeAxes
{
get { return Axes.Both; }
set { throw new InvalidOperationException($"{nameof(DrawableTimingSection)} must always be relatively-sized."); }
} }
public override void InvalidateFromChild(Invalidation invalidation) public override void InvalidateFromChild(Invalidation invalidation)

View File

@ -10,27 +10,46 @@ namespace osu.Game.Rulesets.Timing
public class MultiplierControlPoint : IJsonSerializable, IComparable<MultiplierControlPoint> public class MultiplierControlPoint : IJsonSerializable, IComparable<MultiplierControlPoint>
{ {
/// <summary> /// <summary>
/// The time in milliseconds at which this control point starts. /// The time in milliseconds at which this <see cref="MultiplierControlPoint"/> starts.
/// </summary> /// </summary>
public readonly double StartTime; public readonly double StartTime;
/// <summary> /// <summary>
/// The multiplier which this control point provides. /// The multiplier which this <see cref="MultiplierControlPoint"/> provides.
/// </summary> /// </summary>
public double Multiplier => 1000 / TimingPoint.BeatLength / DifficultyPoint.SpeedMultiplier; public double Multiplier => 1000 / TimingPoint.BeatLength / DifficultyPoint.SpeedMultiplier;
/// <summary>
/// The <see cref="TimingControlPoint"/> that provides the timing information for this <see cref="MultiplierControlPoint"/>.
/// </summary>
public TimingControlPoint TimingPoint = new TimingControlPoint(); public TimingControlPoint TimingPoint = new TimingControlPoint();
/// <summary>
/// The <see cref="DifficultyControlPoint"/> that provides additional difficulty information for this <see cref="MultiplierControlPoint"/>.
/// </summary>
public DifficultyControlPoint DifficultyPoint = new DifficultyControlPoint(); public DifficultyControlPoint DifficultyPoint = new DifficultyControlPoint();
/// <summary>
/// Creates a <see cref="MultiplierControlPoint"/>. This is required for JSON serialization
/// </summary>
public MultiplierControlPoint() public MultiplierControlPoint()
{ {
} }
/// <summary>
/// Creates a <see cref="MultiplierControlPoint"/>.
/// </summary>
/// <param name="startTime">The start time of this <see cref="MultiplierControlPoint"/>.</param>
public MultiplierControlPoint(double startTime) public MultiplierControlPoint(double startTime)
{ {
StartTime = startTime; StartTime = startTime;
} }
/// <summary>
/// Creates a <see cref="MultiplierControlPoint"/> by copying another <see cref="MultiplierControlPoint"/>.
/// </summary>
/// <param name="startTime">The start time of this <see cref="MultiplierControlPoint"/>.</param>
/// <param name="other">The <see cref="MultiplierControlPoint"/> to copy.</param>
public MultiplierControlPoint(double startTime, MultiplierControlPoint other) public MultiplierControlPoint(double startTime, MultiplierControlPoint other)
: this(startTime) : this(startTime)
{ {

View File

@ -15,14 +15,16 @@ namespace osu.Game.Rulesets.Timing
/// A collection of <see cref="SpeedAdjustmentContainer"/>s. /// A collection of <see cref="SpeedAdjustmentContainer"/>s.
/// ///
/// <para> /// <para>
/// This container provides <see cref="VisibleTimeRange"/> for the <see cref="SpeedAdjustmentContainer"/>s. /// This container redirects any <see cref="DrawableHitObject"/>'s added to it to the <see cref="SpeedAdjustmentContainer"/>
/// which provides the speed adjustment active at the start time of the hit object. Furthermore, this container provides the
/// necessary <see cref="VisibleTimeRange"/> for the contained <see cref="SpeedAdjustmentContainer"/>s.
/// </para> /// </para>
/// </summary> /// </summary>
public class SpeedAdjustmentCollection : Container<SpeedAdjustmentContainer> public class SpeedAdjustmentCollection : Container<SpeedAdjustmentContainer>
{ {
private readonly BindableDouble visibleTimeRange = new BindableDouble(); private readonly BindableDouble visibleTimeRange = new BindableDouble();
/// <summary> /// <summary>
/// The amount of time visible by span of this container. /// Gets or sets the range of time that is visible by the length of this container.
/// For example, only hit objects with start time less than or equal to 1000 will be visible with <see cref="VisibleTimeRange"/> = 1000. /// For example, only hit objects with start time less than or equal to 1000 will be visible with <see cref="VisibleTimeRange"/> = 1000.
/// </summary> /// </summary>
public Bindable<double> VisibleTimeRange public Bindable<double> VisibleTimeRange
@ -32,15 +34,16 @@ namespace osu.Game.Rulesets.Timing
} }
/// <summary> /// <summary>
/// Adds a hit object to the most applicable timing section in this container. /// Adds a hit object to the <see cref="SpeedAdjustmentContainer"/> which provides the speed adjustment
/// active at the start time of the hit object.
/// </summary> /// </summary>
/// <param name="hitObject">The hit object to add.</param> /// <param name="hitObject">The hit object to add.</param>
public void Add(DrawableHitObject hitObject) public void Add(DrawableHitObject hitObject)
{ {
var target = timingSectionFor(hitObject); var target = adjustmentContainerFor(hitObject);
if (target == null) if (target == null)
throw new ArgumentException("No timing section could be found that can contain the hit object.", nameof(hitObject)); throw new ArgumentException("No speed adjustment could be found that can contain the hit object.", nameof(hitObject));
target.Add(hitObject); target.Add(hitObject);
} }
@ -51,33 +54,34 @@ namespace osu.Game.Rulesets.Timing
base.Add(speedAdjustment); base.Add(speedAdjustment);
} }
protected override IComparer<Drawable> DepthComparer => new TimingSectionReverseStartTimeComparer(); protected override IComparer<Drawable> DepthComparer => new SpeedAdjustmentContainerReverseStartTimeComparer();
/// <summary> /// <summary>
/// Finds the most applicable timing section that can contain a hit object. If the hit object occurs before the first (time-wise) /// Finds the <see cref="SpeedAdjustmentContainer"/> which provides the speed adjustment active at the start time
/// timing section, then the timing section returned is the first (time-wise) timing section. /// of a hit object. If there is no <see cref="SpeedAdjustmentContainer"/> active at the start time of the hit object,
/// then the first (time-wise) speed adjustment is returned.
/// </summary> /// </summary>
/// <param name="hitObject">The hit object to contain.</param> /// <param name="hitObject">The hit object to find the active <see cref="SpeedAdjustmentContainer"/> for.</param>
/// <returns>The last (time-wise) timing section which can contain <paramref name="hitObject"/>. Null if no timing section exists.</returns> /// <returns>The <see cref="SpeedAdjustmentContainer"/> active at <paramref name="hitObject"/>'s start time. Null if there are no speed adjustments.</returns>
private SpeedAdjustmentContainer timingSectionFor(DrawableHitObject hitObject) => Children.FirstOrDefault(c => c.CanContain(hitObject)) ?? Children.LastOrDefault(); private SpeedAdjustmentContainer adjustmentContainerFor(DrawableHitObject hitObject) => Children.FirstOrDefault(c => c.CanContain(hitObject)) ?? Children.LastOrDefault();
/// <summary> /// <summary>
/// Compares two timing sections by their start time, falling back to creation order if their start time is equal. /// Compares two speed adjustment containers by their control point start time, falling back to creation order
/// This will compare the two timing sections in reverse order. // if their control point start time is equal. This will compare the two speed adjustment containers in reverse order.
/// </summary> /// </summary>
private class TimingSectionReverseStartTimeComparer : ReverseCreationOrderDepthComparer private class SpeedAdjustmentContainerReverseStartTimeComparer : ReverseCreationOrderDepthComparer
{ {
public override int Compare(Drawable x, Drawable y) public override int Compare(Drawable x, Drawable y)
{ {
var timingChangeX = x as SpeedAdjustmentContainer; var speedAdjustmentX = x as SpeedAdjustmentContainer;
var timingChangeY = y as SpeedAdjustmentContainer; var speedAdjustmentY = y as SpeedAdjustmentContainer;
// If either of the two drawables are not hit objects, fall back to the base comparer // If either of the two drawables are not hit objects, fall back to the base comparer
if (timingChangeX?.MultiplierControlPoint == null || timingChangeY?.MultiplierControlPoint == null) if (speedAdjustmentX?.MultiplierControlPoint == null || speedAdjustmentY?.MultiplierControlPoint == null)
return base.Compare(x, y); return base.Compare(x, y);
// Compare by start time // Compare by start time
int i = timingChangeY.MultiplierControlPoint.StartTime.CompareTo(timingChangeX.MultiplierControlPoint.StartTime); int i = speedAdjustmentY.MultiplierControlPoint.StartTime.CompareTo(speedAdjustmentX.MultiplierControlPoint.StartTime);
return i != 0 ? i : base.Compare(x, y); return i != 0 ? i : base.Compare(x, y);
} }

View File

@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -12,18 +11,29 @@ using OpenTK;
namespace osu.Game.Rulesets.Timing namespace osu.Game.Rulesets.Timing
{ {
/// <summary> /// <summary>
/// A container for hit objects which applies applies the speed adjustments defined by the <see cref="Timing.MultiplierControlPoint"/> properties /// A container for hit objects which applies applies the speed adjustments defined by the properties of a <see cref="Timing.MultiplierControlPoint"/>
/// to its <see cref="Container{T}.Content"/> to affect the <see cref="DrawableTimingSection"/> scroll speed. /// to affect the scroll speed of the contained <see cref="DrawableTimingSection"/>.
///
/// <para>
/// This container must always be relatively-sized to its parent to provide the speed adjustments. This container will provide the speed adjustments
/// by modifying its size while maintaining a constant <see cref="Container{T}.RelativeChildSize"/> for its children
/// </para>
/// </summary> /// </summary>
public abstract class SpeedAdjustmentContainer : Container<DrawableHitObject> public abstract class SpeedAdjustmentContainer : Container<DrawableHitObject>
{ {
private readonly Bindable<double> visibleTimeRange = new Bindable<double>(); private readonly Bindable<double> visibleTimeRange = new Bindable<double>();
/// <summary>
/// Gets or sets the range of time that is visible by the length of this container.
/// </summary>
public Bindable<double> VisibleTimeRange public Bindable<double> VisibleTimeRange
{ {
get { return visibleTimeRange; } get { return visibleTimeRange; }
set { visibleTimeRange.BindTo(value); } set { visibleTimeRange.BindTo(value); }
} }
/// <summary>
/// The <see cref="MultiplierControlPoint"/> which provides the speed adjustments for this container.
/// </summary>
public readonly MultiplierControlPoint MultiplierControlPoint; public readonly MultiplierControlPoint MultiplierControlPoint;
protected override Container<DrawableHitObject> Content => content; protected override Container<DrawableHitObject> Content => content;
@ -34,12 +44,14 @@ namespace osu.Game.Rulesets.Timing
/// <summary> /// <summary>
/// Creates a new <see cref="SpeedAdjustmentContainer"/>. /// Creates a new <see cref="SpeedAdjustmentContainer"/>.
/// </summary> /// </summary>
/// <param name="multiplierControlPoint">The multiplier control point that provides the speed adjustments for this container.</param> /// <param name="multiplierControlPoint">The <see cref="MultiplierControlPoint"/> which provides the speed adjustments for this container.</param>
/// <param name="scrollingAxes">The axes through which this drawable timing section scrolls through.</param> /// <param name="scrollingAxes">The axes through which the content of this container should scroll through.</param>
protected SpeedAdjustmentContainer(MultiplierControlPoint multiplierControlPoint, Axes scrollingAxes) protected SpeedAdjustmentContainer(MultiplierControlPoint multiplierControlPoint, Axes scrollingAxes)
{ {
this.scrollingAxes = scrollingAxes; this.scrollingAxes = scrollingAxes;
RelativeSizeAxes = Axes.Both;
MultiplierControlPoint = multiplierControlPoint; MultiplierControlPoint = multiplierControlPoint;
} }
@ -54,12 +66,6 @@ namespace osu.Game.Rulesets.Timing
AddInternal(content = timingSection); AddInternal(content = timingSection);
} }
public override Axes RelativeSizeAxes
{
get { return Axes.Both; }
set { throw new InvalidOperationException($"{nameof(SpeedAdjustmentContainer)} must always be relatively-sized."); }
}
protected override void Update() protected override void Update()
{ {
float multiplier = (float)MultiplierControlPoint.Multiplier; float multiplier = (float)MultiplierControlPoint.Multiplier;
@ -77,7 +83,7 @@ namespace osu.Game.Rulesets.Timing
/// <summary> /// <summary>
/// Creates the container which handles the movement of a collection of hit objects. /// Creates the container which handles the movement of a collection of hit objects.
/// </summary> /// </summary>
/// <returns>The drawable timing section.</returns> /// <returns>The <see cref="DrawableTimingSection"/>.</returns>
protected abstract DrawableTimingSection CreateTimingSection(); protected abstract DrawableTimingSection CreateTimingSection();
} }
} }

View File

@ -120,6 +120,11 @@ namespace osu.Game.Rulesets.UI
/// </summary> /// </summary>
public Beatmap<TObject> Beatmap; public Beatmap<TObject> Beatmap;
/// <summary>
/// All the converted hit objects contained by this hit renderer.
/// </summary>
public override IEnumerable<HitObject> Objects => Beatmap.HitObjects;
/// <summary> /// <summary>
/// The mods which are to be applied. /// The mods which are to be applied.
/// </summary> /// </summary>
@ -206,7 +211,10 @@ namespace osu.Game.Rulesets.UI
public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor; public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor;
public override IEnumerable<HitObject> Objects => Beatmap.HitObjects; /// <summary>
/// All the converted hit objects contained by this hit renderer.
/// </summary>
public new IEnumerable<TObject> Objects => Beatmap.HitObjects;
protected override bool AllObjectsJudged => drawableObjects.All(h => h.Judged); protected override bool AllObjectsJudged => drawableObjects.All(h => h.Judged);