mirror of
https://github.com/ppy/osu.git
synced 2024-11-14 15:57:24 +08:00
Refactor storyboard timeline to reduce GC / fix crashes (#7270)
Refactor storyboard timeline to reduce GC / fix crashes Co-authored-by: Dean Herbert <pe@ppy.sh>
This commit is contained in:
commit
fd7309551c
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Caching;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -12,27 +11,35 @@ namespace osu.Game.Storyboards
|
|||||||
public class CommandTimeline<T> : ICommandTimeline
|
public class CommandTimeline<T> : ICommandTimeline
|
||||||
{
|
{
|
||||||
private readonly List<TypedCommand> commands = new List<TypedCommand>();
|
private readonly List<TypedCommand> commands = new List<TypedCommand>();
|
||||||
|
|
||||||
public IEnumerable<TypedCommand> Commands => commands.OrderBy(c => c.StartTime);
|
public IEnumerable<TypedCommand> Commands => commands.OrderBy(c => c.StartTime);
|
||||||
|
|
||||||
public bool HasCommands => commands.Count > 0;
|
public bool HasCommands => commands.Count > 0;
|
||||||
|
|
||||||
private readonly Cached<double> startTimeBacking = new Cached<double>();
|
public double StartTime { get; private set; } = double.MaxValue;
|
||||||
public double StartTime => startTimeBacking.IsValid ? startTimeBacking : startTimeBacking.Value = HasCommands ? commands.Min(c => c.StartTime) : double.MinValue;
|
public double EndTime { get; private set; } = double.MinValue;
|
||||||
|
|
||||||
private readonly Cached<double> endTimeBacking = new Cached<double>();
|
public T StartValue { get; private set; }
|
||||||
public double EndTime => endTimeBacking.IsValid ? endTimeBacking : endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue;
|
public T EndValue { get; private set; }
|
||||||
|
|
||||||
public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default;
|
|
||||||
public T EndValue => HasCommands ? commands.OrderByDescending(c => c.EndTime).First().EndValue : default;
|
|
||||||
|
|
||||||
public void Add(Easing easing, double startTime, double endTime, T startValue, T endValue)
|
public void Add(Easing easing, double startTime, double endTime, T startValue, T endValue)
|
||||||
{
|
{
|
||||||
if (endTime < startTime)
|
if (endTime < startTime)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue, });
|
commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue });
|
||||||
|
|
||||||
startTimeBacking.Invalidate();
|
if (startTime < StartTime)
|
||||||
endTimeBacking.Invalidate();
|
{
|
||||||
|
StartValue = startValue;
|
||||||
|
StartTime = startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endTime > EndTime)
|
||||||
|
{
|
||||||
|
EndValue = endValue;
|
||||||
|
EndTime = endTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -25,28 +26,52 @@ namespace osu.Game.Storyboards
|
|||||||
public CommandTimeline<bool> FlipH = new CommandTimeline<bool>();
|
public CommandTimeline<bool> FlipH = new CommandTimeline<bool>();
|
||||||
public CommandTimeline<bool> FlipV = new CommandTimeline<bool>();
|
public CommandTimeline<bool> FlipV = new CommandTimeline<bool>();
|
||||||
|
|
||||||
|
private readonly ICommandTimeline[] timelines;
|
||||||
|
|
||||||
|
public CommandTimelineGroup()
|
||||||
|
{
|
||||||
|
timelines = new ICommandTimeline[]
|
||||||
|
{
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Scale,
|
||||||
|
VectorScale,
|
||||||
|
Rotation,
|
||||||
|
Colour,
|
||||||
|
Alpha,
|
||||||
|
BlendingParameters,
|
||||||
|
FlipH,
|
||||||
|
FlipV
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<ICommandTimeline> Timelines
|
public double CommandsStartTime
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return X;
|
double min = double.MaxValue;
|
||||||
yield return Y;
|
|
||||||
yield return Scale;
|
for (int i = 0; i < timelines.Length; i++)
|
||||||
yield return Rotation;
|
min = Math.Min(min, timelines[i].StartTime);
|
||||||
yield return Colour;
|
|
||||||
yield return Alpha;
|
return min;
|
||||||
yield return BlendingParameters;
|
|
||||||
yield return FlipH;
|
|
||||||
yield return FlipV;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public double CommandsStartTime => Timelines.Where(t => t.HasCommands).Min(t => t.StartTime);
|
public double CommandsEndTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
double max = double.MinValue;
|
||||||
|
|
||||||
[JsonIgnore]
|
for (int i = 0; i < timelines.Length; i++)
|
||||||
public double CommandsEndTime => Timelines.Where(t => t.HasCommands).Max(t => t.EndTime);
|
max = Math.Max(max, timelines[i].EndTime);
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public double CommandsDuration => CommandsEndTime - CommandsStartTime;
|
public double CommandsDuration => CommandsEndTime - CommandsStartTime;
|
||||||
@ -61,7 +86,19 @@ namespace osu.Game.Storyboards
|
|||||||
public double Duration => EndTime - StartTime;
|
public double Duration => EndTime - StartTime;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool HasCommands => Timelines.Any(t => t.HasCommands);
|
public bool HasCommands
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
for (int i = 0; i < timelines.Length; i++)
|
||||||
|
{
|
||||||
|
if (timelines[i].HasCommands)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual IEnumerable<CommandTimeline<T>.TypedCommand> GetCommands<T>(CommandTimelineSelector<T> timelineSelector, double offset = 0)
|
public virtual IEnumerable<CommandTimeline<T>.TypedCommand> GetCommands<T>(CommandTimelineSelector<T> timelineSelector, double offset = 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user