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

Merge pull request #13331 from ekrctb/pdwl-follow-point

Use general lifetime container for follow point container
This commit is contained in:
Dan Balasescu 2021-06-04 20:39:39 +09:00 committed by GitHub
commit fa7611f1e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 78 deletions

View File

@ -5,6 +5,7 @@ using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Pooling;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Pooling;
using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
@ -12,34 +13,29 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
/// <summary>
/// Visualises the <see cref="FollowPoint"/>s between two <see cref="DrawableOsuHitObject"/>s.
/// </summary>
public class FollowPointConnection : PoolableDrawable
public class FollowPointConnection : PoolableDrawableWithLifetime<FollowPointLifetimeEntry>
{
// Todo: These shouldn't be constants
public const int SPACING = 32;
public const double PREEMPT = 800;
public FollowPointLifetimeEntry Entry;
public DrawablePool<FollowPoint> Pool;
protected override void PrepareForUse()
protected override void OnApply(FollowPointLifetimeEntry entry)
{
base.PrepareForUse();
Entry.Invalidated += onEntryInvalidated;
base.OnApply(entry);
entry.Invalidated += onEntryInvalidated;
refreshPoints();
}
protected override void FreeAfterUse()
protected override void OnFree(FollowPointLifetimeEntry entry)
{
base.FreeAfterUse();
Entry.Invalidated -= onEntryInvalidated;
base.OnFree(entry);
entry.Invalidated -= onEntryInvalidated;
// Return points to the pool.
ClearInternal(false);
Entry = null;
}
private void onEntryInvalidated() => Scheduler.AddOnce(refreshPoints);
@ -48,8 +44,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
ClearInternal(false);
OsuHitObject start = Entry.Start;
OsuHitObject end = Entry.End;
var entry = Entry;
if (entry?.End == null) return;
OsuHitObject start = entry.Start;
OsuHitObject end = entry.End;
double startTime = start.GetEndTime();
@ -87,14 +86,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
fp.FadeIn(end.TimeFadeIn);
fp.ScaleTo(end.Scale, end.TimeFadeIn, Easing.Out);
fp.MoveTo(pointEndPosition, end.TimeFadeIn, Easing.Out);
fp.Delay(fadeOutTime - fadeInTime).FadeOut(end.TimeFadeIn);
fp.Delay(fadeOutTime - fadeInTime).FadeOut(end.TimeFadeIn).Expire();
finalTransformEndTime = fadeOutTime + end.TimeFadeIn;
finalTransformEndTime = fp.LifetimeEnd;
}
}
// todo: use Expire() on FollowPoints and take lifetime from them when https://github.com/ppy/osu-framework/issues/3300 is fixed.
Entry.LifetimeEnd = finalTransformEndTime;
entry.LifetimeEnd = finalTransformEndTime;
}
/// <summary>

View File

@ -1,6 +1,8 @@
// 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 osu.Framework.Bindables;
using osu.Framework.Graphics.Performance;
@ -11,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
public class FollowPointLifetimeEntry : LifetimeEntry
{
public event Action Invalidated;
public event Action? Invalidated;
public readonly OsuHitObject Start;
public FollowPointLifetimeEntry(OsuHitObject start)
@ -22,9 +24,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
bindEvents();
}
private OsuHitObject end;
private OsuHitObject? end;
public OsuHitObject End
public OsuHitObject? End
{
get => end;
set
@ -56,11 +58,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
public void UnbindEvents()
{
if (Start != null)
{
Start.DefaultsApplied -= onDefaultsApplied;
Start.PositionBindable.ValueChanged -= onPositionChanged;
}
Start.DefaultsApplied -= onDefaultsApplied;
Start.PositionBindable.ValueChanged -= onPositionChanged;
if (End != null)
{

View File

@ -6,43 +6,32 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Performance;
using osu.Framework.Graphics.Pooling;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Pooling;
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
/// <summary>
/// Visualises connections between <see cref="DrawableOsuHitObject"/>s.
/// </summary>
public class FollowPointRenderer : CompositeDrawable
public class FollowPointRenderer : PooledDrawableWithLifetimeContainer<FollowPointLifetimeEntry, FollowPointConnection>
{
public override bool RemoveCompletedTransforms => false;
public IReadOnlyList<FollowPointLifetimeEntry> Entries => lifetimeEntries;
public new IReadOnlyList<FollowPointLifetimeEntry> Entries => lifetimeEntries;
private DrawablePool<FollowPointConnection> connectionPool;
private DrawablePool<FollowPoint> pointPool;
private readonly List<FollowPointLifetimeEntry> lifetimeEntries = new List<FollowPointLifetimeEntry>();
private readonly Dictionary<LifetimeEntry, FollowPointConnection> connectionsInUse = new Dictionary<LifetimeEntry, FollowPointConnection>();
private readonly Dictionary<HitObject, IBindable> startTimeMap = new Dictionary<HitObject, IBindable>();
private readonly LifetimeEntryManager lifetimeManager = new LifetimeEntryManager();
public FollowPointRenderer()
{
lifetimeManager.EntryBecameAlive += onEntryBecameAlive;
lifetimeManager.EntryBecameDead += onEntryBecameDead;
}
[BackgroundDependencyLoader]
private void load()
{
InternalChildren = new Drawable[]
{
connectionPool = new DrawablePoolNoLifetime<FollowPointConnection>(1, 200),
pointPool = new DrawablePoolNoLifetime<FollowPoint>(50, 1000)
connectionPool = new DrawablePool<FollowPointConnection>(1, 200),
pointPool = new DrawablePool<FollowPoint>(50, 1000)
};
}
@ -107,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
previousEntry.End = newEntry.Start;
}
lifetimeManager.AddEntry(newEntry);
Add(newEntry);
}
private void removeEntry(OsuHitObject hitObject)
@ -118,7 +107,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
entry.UnbindEvents();
lifetimeEntries.RemoveAt(index);
lifetimeManager.RemoveEntry(entry);
Remove(entry);
if (index > 0)
{
@ -131,30 +120,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
}
}
protected override bool CheckChildrenLife()
protected override FollowPointConnection GetDrawable(FollowPointLifetimeEntry entry)
{
bool anyAliveChanged = base.CheckChildrenLife();
anyAliveChanged |= lifetimeManager.Update(Time.Current);
return anyAliveChanged;
}
private void onEntryBecameAlive(LifetimeEntry entry)
{
var connection = connectionPool.Get(c =>
{
c.Entry = (FollowPointLifetimeEntry)entry;
c.Pool = pointPool;
});
connectionsInUse[entry] = connection;
AddInternal(connection);
}
private void onEntryBecameDead(LifetimeEntry entry)
{
RemoveInternal(connectionsInUse[entry]);
connectionsInUse.Remove(entry);
var connection = connectionPool.Get();
connection.Pool = pointPool;
connection.Apply(entry);
return connection;
}
private void onStartTimeChanged(OsuHitObject hitObject)
@ -171,16 +142,5 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
entry.UnbindEvents();
lifetimeEntries.Clear();
}
private class DrawablePoolNoLifetime<T> : DrawablePool<T>
where T : PoolableDrawable, new()
{
public override bool RemoveWhenNotAlive => false;
public DrawablePoolNoLifetime(int initialSize, int? maximumSize = null)
: base(initialSize, maximumSize)
{
}
}
}
}