2019-01-24 16:43:03 +08:00
// 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.
2018-04-13 17:19:50 +08:00
using osu.Framework.Graphics ;
2019-11-01 14:34:24 +08:00
using osu.Framework.Graphics.Containers ;
2018-04-13 17:19:50 +08:00
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
2019-11-01 14:34:24 +08:00
public class FollowPointRenderer : CompositeDrawable
2018-04-13 17:19:50 +08:00
{
/// <summary>
2019-11-01 14:39:23 +08:00
/// Adds the <see cref="FollowPoint"/>s around a <see cref="DrawableOsuHitObject"/>.
/// This includes <see cref="FollowPoint"/>s leading into <paramref name="hitObject"/>, and <see cref="FollowPoint"/>s exiting <paramref name="hitObject"/>.
2018-04-13 17:19:50 +08:00
/// </summary>
2019-11-01 14:39:23 +08:00
/// <param name="hitObject">The <see cref="DrawableOsuHitObject"/> to add <see cref="FollowPoint"/>s for.</param>
public void AddFollowPoints ( DrawableOsuHitObject hitObject )
2018-04-13 17:19:50 +08:00
{
2019-11-01 14:39:23 +08:00
var startGroup = new FollowPointGroup ( hitObject ) ;
AddInternal ( startGroup ) ;
// Groups are sorted by their start time when added, so the index can be used to post-process other surrounding groups
int startIndex = IndexOfInternal ( startGroup ) ;
if ( startIndex < InternalChildren . Count - 1 )
2018-04-13 17:19:50 +08:00
{
2019-11-01 14:39:23 +08:00
// h1 -> -> -> h2
// hitObject nextGroup
2019-02-27 20:07:17 +08:00
2019-11-01 14:39:23 +08:00
var nextGroup = ( FollowPointGroup ) InternalChildren [ startIndex + 1 ] ;
startGroup . End = nextGroup . Start ;
2018-04-13 17:19:50 +08:00
}
2019-02-27 20:07:17 +08:00
2019-11-01 14:39:23 +08:00
if ( startIndex > 0 )
2018-04-13 17:19:50 +08:00
{
2019-11-01 14:39:23 +08:00
// h1 -> -> -> h2
// prevGroup hitObject
2019-02-27 20:07:17 +08:00
2019-11-01 14:39:23 +08:00
var previousGroup = ( FollowPointGroup ) InternalChildren [ startIndex - 1 ] ;
previousGroup . End = startGroup . Start ;
2018-04-13 17:19:50 +08:00
}
}
2019-11-01 14:39:23 +08:00
/// <summary>
/// Removes the <see cref="FollowPoint"/>s around a <see cref="DrawableOsuHitObject"/>.
/// This includes <see cref="FollowPoint"/>s leading into <paramref name="hitObject"/>, and <see cref="FollowPoint"/>s exiting <paramref name="hitObject"/>.
/// </summary>
/// <param name="hitObject">The <see cref="DrawableOsuHitObject"/> to remove <see cref="FollowPoint"/>s for.</param>
public void RemoveFollowPoints ( DrawableOsuHitObject hitObject )
2018-04-13 17:19:50 +08:00
{
2019-11-01 14:39:23 +08:00
var groups = findGroups ( hitObject ) ;
// Regardless of the position of the hitobject in the beatmap, there will always be a group leading from the hitobject
RemoveInternal ( groups . start ) ;
if ( groups . end ! = null )
2018-04-13 17:19:50 +08:00
{
2019-11-01 14:39:23 +08:00
// When there were two groups referencing the same hitobject, merge them by updating the end group to point to the new end (the start group was already removed)
groups . end . End = groups . start . End ;
2018-04-13 17:19:50 +08:00
}
}
2019-11-01 14:39:23 +08:00
/// <summary>
/// Finds the <see cref="FollowPointGroup"/>s with <paramref name="hitObject"/> as the start and end <see cref="DrawableOsuHitObject"/>s.
/// </summary>
/// <param name="hitObject">The <see cref="DrawableOsuHitObject"/> to find the relevant <see cref="FollowPointGroup"/> of.</param>
/// <returns>A tuple containing the end group (the <see cref="FollowPointGroup"/> where <paramref name="hitObject"/> is the end of),
/// and the start group (the <see cref="FollowPointGroup"/> where <paramref name="hitObject"/> is the start of).</returns>
private ( FollowPointGroup start , FollowPointGroup end ) findGroups ( DrawableOsuHitObject hitObject )
2018-04-13 17:19:50 +08:00
{
2019-11-01 14:39:23 +08:00
// endGroup startGroup
// h1 -> -> -> -> -> h2 -> -> -> -> -> h3
// hitObject
2018-04-13 17:19:50 +08:00
2019-11-01 14:39:23 +08:00
FollowPointGroup startGroup = null ; // The group which the hitobject is the start in
FollowPointGroup endGroup = null ; // The group which the hitobject is the end in
2018-04-13 17:19:50 +08:00
2019-11-01 14:39:23 +08:00
int startIndex = 0 ;
2019-04-01 11:16:05 +08:00
2019-11-01 14:39:23 +08:00
for ( ; startIndex < InternalChildren . Count ; startIndex + + )
2018-04-13 17:19:50 +08:00
{
2019-11-01 14:39:23 +08:00
var group = ( FollowPointGroup ) InternalChildren [ startIndex ] ;
if ( group . Start = = hitObject )
2018-04-13 17:19:50 +08:00
{
2019-11-01 14:39:23 +08:00
startGroup = group ;
break ;
2018-04-13 17:19:50 +08:00
}
}
2019-11-01 14:39:23 +08:00
if ( startIndex > 0 )
endGroup = ( FollowPointGroup ) InternalChildren [ startIndex - 1 ] ;
return ( startGroup , endGroup ) ;
}
protected override int Compare ( Drawable x , Drawable y )
{
var groupX = ( FollowPointGroup ) x ;
var groupY = ( FollowPointGroup ) y ;
return groupX . Start . HitObject . StartTime . CompareTo ( groupY . Start . HitObject . StartTime ) ;
2018-04-13 17:19:50 +08:00
}
}
}