Fix follow points not updating on positional changes

This commit is contained in:
smoogipoo 2020-11-20 15:31:04 +09:00
parent c53a8fafe6
commit 33eea64cfc
2 changed files with 81 additions and 8 deletions

View File

@ -21,16 +21,33 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
public FollowPointRenderer.FollowPointLifetimeEntry Entry; public FollowPointRenderer.FollowPointLifetimeEntry Entry;
public DrawablePool<FollowPoint> Pool; public DrawablePool<FollowPoint> Pool;
protected override void FreeAfterUse()
{
base.FreeAfterUse();
ClearInternal(false);
}
protected override void PrepareForUse() protected override void PrepareForUse()
{ {
base.PrepareForUse(); base.PrepareForUse();
Entry.Invalidated += onEntryInvalidated;
refreshPoints();
}
protected override void FreeAfterUse()
{
base.FreeAfterUse();
Entry.Invalidated -= onEntryInvalidated;
// Return points to the pool.
ClearInternal(false);
Entry = null;
}
private void onEntryInvalidated() => refreshPoints();
private void refreshPoints()
{
ClearInternal(false);
OsuHitObject start = Entry.Start; OsuHitObject start = Entry.Start;
OsuHitObject end = Entry.End; OsuHitObject end = Entry.End;

View File

@ -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 System.Collections.Generic; using System.Collections.Generic;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
@ -117,7 +118,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
private void removeEntry(OsuHitObject hitObject) private void removeEntry(OsuHitObject hitObject)
{ {
int index = lifetimeEntries.FindIndex(e => e.Start == hitObject); int index = lifetimeEntries.FindIndex(e => e.Start == hitObject);
var entry = lifetimeEntries[index]; var entry = lifetimeEntries[index];
entry.UnbindEvents();
lifetimeEntries.RemoveAt(index); lifetimeEntries.RemoveAt(index);
lifetimeManager.RemoveEntry(entry); lifetimeManager.RemoveEntry(entry);
@ -161,14 +164,26 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
addEntry(hitObject); addEntry(hitObject);
} }
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
foreach (var entry in lifetimeEntries)
entry.UnbindEvents();
lifetimeEntries.Clear();
}
public class FollowPointLifetimeEntry : LifetimeEntry public class FollowPointLifetimeEntry : LifetimeEntry
{ {
public event Action Invalidated;
public readonly OsuHitObject Start; public readonly OsuHitObject Start;
public FollowPointLifetimeEntry(OsuHitObject start) public FollowPointLifetimeEntry(OsuHitObject start)
{ {
Start = start; Start = start;
LifetimeStart = Start.StartTime; LifetimeStart = Start.StartTime;
bindEvents();
} }
private OsuHitObject end; private OsuHitObject end;
@ -178,12 +193,51 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
get => end; get => end;
set set
{ {
UnbindEvents();
end = value; end = value;
computeLifetimes();
bindEvents();
refreshLifetimes();
} }
} }
private void computeLifetimes() private void bindEvents()
{
UnbindEvents();
// 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;
if (End != null)
{
End.DefaultsApplied += onDefaultsApplied;
End.PositionBindable.ValueChanged += onPositionChanged;
}
}
public void UnbindEvents()
{
if (Start != null)
{
Start.DefaultsApplied -= onDefaultsApplied;
Start.PositionBindable.ValueChanged -= onPositionChanged;
}
if (End != null)
{
End.DefaultsApplied -= onDefaultsApplied;
End.PositionBindable.ValueChanged -= onPositionChanged;
}
}
private void onDefaultsApplied(HitObject obj) => refreshLifetimes();
private void onPositionChanged(ValueChangedEvent<Vector2> obj) => refreshLifetimes();
private void refreshLifetimes()
{ {
if (end == null) if (end == null)
{ {
@ -203,6 +257,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
LifetimeStart = fadeInTime; LifetimeStart = fadeInTime;
LifetimeEnd = double.MaxValue; // This will be set by the connection. LifetimeEnd = double.MaxValue; // This will be set by the connection.
Invalidated?.Invoke();
} }
} }
} }