1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-12 06:47:25 +08:00
osu-lazer/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointLifetimeEntry.cs
2021-10-27 13:04:41 +09:00

105 lines
3.0 KiB
C#

// 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 enable
using System;
using System.Diagnostics;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Performance;
using osu.Game.Rulesets.Objects;
using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
public class FollowPointLifetimeEntry : LifetimeEntry
{
public event Action? Invalidated;
public readonly OsuHitObject Start;
public FollowPointLifetimeEntry(OsuHitObject start)
{
Start = start;
LifetimeStart = Start.StartTime;
}
private OsuHitObject? end;
public OsuHitObject? End
{
get => end;
set
{
UnbindEvents();
end = value;
bindEvents();
refreshLifetimes();
}
}
private bool wasBound;
private void bindEvents()
{
UnbindEvents();
if (End == null)
return;
// Note: Positions are bound for instantaneous feedback from positional changes from the editor, before ApplyDefaults() is called on hitobjects.
Start.DefaultsApplied += onDefaultsApplied;
Start.PositionBindable.ValueChanged += onPositionChanged;
End.DefaultsApplied += onDefaultsApplied;
End.PositionBindable.ValueChanged += onPositionChanged;
wasBound = true;
}
public void UnbindEvents()
{
if (!wasBound)
return;
Debug.Assert(End != null);
Start.DefaultsApplied -= onDefaultsApplied;
Start.PositionBindable.ValueChanged -= onPositionChanged;
End.DefaultsApplied -= onDefaultsApplied;
End.PositionBindable.ValueChanged -= onPositionChanged;
wasBound = false;
}
private void onDefaultsApplied(HitObject obj) => refreshLifetimes();
private void onPositionChanged(ValueChangedEvent<Vector2> obj) => refreshLifetimes();
private void refreshLifetimes()
{
if (End == null || End.NewCombo || Start is Spinner || End is Spinner)
{
LifetimeEnd = LifetimeStart;
return;
}
Vector2 startPosition = Start.StackedEndPosition;
Vector2 endPosition = End.StackedPosition;
Vector2 distanceVector = endPosition - startPosition;
// The lifetime start will match the fade-in time of the first follow point.
float fraction = (int)(FollowPointConnection.SPACING * 1.5) / distanceVector.Length;
FollowPointConnection.GetFadeTimes(Start, End, fraction, out double fadeInTime, out _);
LifetimeStart = fadeInTime;
LifetimeEnd = double.MaxValue; // This will be set by the connection.
Invalidated?.Invoke();
}
}
}