Add `enum` to snap method as alternative to mutliple nested invocations

This commit is contained in:
Dean Herbert 2022-05-12 15:23:41 +09:00
parent 5f2d9bf04c
commit c0abce918f
10 changed files with 62 additions and 67 deletions

View File

@ -6,6 +6,7 @@
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
@ -89,15 +90,19 @@ protected override IEnumerable<TernaryButton> CreateTernaryButtons() => base.Cre
new TernaryButton(distanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Ruler })
});
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition)
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All)
{
var result = base.FindSnappedPositionAndTime(screenSpacePosition);
var result = base.FindSnappedPositionAndTime(screenSpacePosition, snapType);
result.ScreenSpacePosition.X = screenSpacePosition.X;
if (distanceSnapGrid.IsPresent && distanceSnapGrid.GetSnappedPosition(result.ScreenSpacePosition) is SnapResult snapResult &&
Vector2.Distance(snapResult.ScreenSpacePosition, result.ScreenSpacePosition) < distance_snap_radius)
if (snapType.HasFlagFast(SnapType.Grids))
{
result = snapResult;
if (distanceSnapGrid.IsPresent && distanceSnapGrid.GetSnappedPosition(result.ScreenSpacePosition) is SnapResult snapResult &&
Vector2.Distance(snapResult.ScreenSpacePosition, result.ScreenSpacePosition) < distance_snap_radius)
{
result = snapResult;
}
}
return result;

View File

@ -97,12 +97,7 @@ public Drawable Child
set => InternalChild = value;
}
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition)
{
throw new System.NotImplementedException();
}
public override SnapResult FindSnappedPosition(Vector2 screenSpacePosition)
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All)
{
throw new System.NotImplementedException();
}

View File

@ -56,9 +56,9 @@ protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnl
protected override Playfield PlayfieldAtScreenSpacePosition(Vector2 screenSpacePosition) =>
Playfield.GetColumnByPosition(screenSpacePosition);
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition)
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All)
{
var result = base.FindSnappedPositionAndTime(screenSpacePosition);
var result = base.FindSnappedPositionAndTime(screenSpacePosition, snapType);
switch (ScrollingInfo.Direction.Value)
{

View File

@ -7,6 +7,7 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@ -123,33 +124,27 @@ protected override void Update()
}
}
public override SnapResult FindSnappedPosition(Vector2 screenSpacePosition)
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All)
{
if (snapToVisibleBlueprints(screenSpacePosition, out var snapResult))
if (snapType.HasFlagFast(SnapType.NearbyObjects) && snapToVisibleBlueprints(screenSpacePosition, out var snapResult))
return snapResult;
return new SnapResult(screenSpacePosition, null);
}
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition)
{
var positionSnap = FindSnappedPosition(screenSpacePosition);
if (positionSnap.ScreenSpacePosition != screenSpacePosition)
return positionSnap;
if (distanceSnapToggle.Value == TernaryState.True && distanceSnapGrid != null)
if (snapType.HasFlagFast(SnapType.Grids))
{
(Vector2 pos, double time) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(screenSpacePosition));
return new SnapResult(distanceSnapGrid.ToScreenSpace(pos), time, PlayfieldAtScreenSpacePosition(screenSpacePosition));
if (distanceSnapToggle.Value == TernaryState.True && distanceSnapGrid != null)
{
(Vector2 pos, double time) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(screenSpacePosition));
return new SnapResult(distanceSnapGrid.ToScreenSpace(pos), time, PlayfieldAtScreenSpacePosition(screenSpacePosition));
}
if (rectangularGridSnapToggle.Value == TernaryState.True)
{
Vector2 pos = rectangularPositionSnapGrid.GetSnappedPosition(rectangularPositionSnapGrid.ToLocalSpace(screenSpacePosition));
return new SnapResult(rectangularPositionSnapGrid.ToScreenSpace(pos), null, PlayfieldAtScreenSpacePosition(screenSpacePosition));
}
}
if (rectangularGridSnapToggle.Value == TernaryState.True)
{
Vector2 pos = rectangularPositionSnapGrid.GetSnappedPosition(rectangularPositionSnapGrid.ToLocalSpace(screenSpacePosition));
return new SnapResult(rectangularPositionSnapGrid.ToScreenSpace(pos), null, PlayfieldAtScreenSpacePosition(screenSpacePosition));
}
return base.FindSnappedPositionAndTime(screenSpacePosition);
return base.FindSnappedPositionAndTime(screenSpacePosition, snapType);
}
private bool snapToVisibleBlueprints(Vector2 screenSpacePosition, out SnapResult snapResult)

View File

@ -185,10 +185,7 @@ public override (Vector2 position, double time) GetSnappedPosition(Vector2 scree
private class SnapProvider : IDistanceSnapProvider
{
public SnapResult FindSnappedPosition(Vector2 screenSpacePosition) =>
new SnapResult(screenSpacePosition, null);
public SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition) => new SnapResult(screenSpacePosition, 0);
public SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.Grids) => new SnapResult(screenSpacePosition, 0);
public Bindable<double> DistanceSpacingMultiplier { get; } = new BindableDouble(1);

View File

@ -7,6 +7,7 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.EnumExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
@ -361,20 +362,23 @@ public void EndPlacement(HitObject hitObject, bool commit)
/// <returns>The most relevant <see cref="Playfield"/>.</returns>
protected virtual Playfield PlayfieldAtScreenSpacePosition(Vector2 screenSpacePosition) => drawableRulesetWrapper.Playfield;
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition)
public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All)
{
var playfield = PlayfieldAtScreenSpacePosition(screenSpacePosition);
double? targetTime = null;
if (playfield is ScrollingPlayfield scrollingPlayfield)
if (snapType.HasFlagFast(SnapType.Grids))
{
targetTime = scrollingPlayfield.TimeAtScreenSpacePosition(screenSpacePosition);
if (playfield is ScrollingPlayfield scrollingPlayfield)
{
targetTime = scrollingPlayfield.TimeAtScreenSpacePosition(screenSpacePosition);
// apply beat snapping
targetTime = BeatSnapProvider.SnapTime(targetTime.Value);
// apply beat snapping
targetTime = BeatSnapProvider.SnapTime(targetTime.Value);
// convert back to screen space
screenSpacePosition = scrollingPlayfield.ScreenSpacePositionAtTime(targetTime.Value);
// convert back to screen space
screenSpacePosition = scrollingPlayfield.ScreenSpacePositionAtTime(targetTime.Value);
}
}
return new SnapResult(screenSpacePosition, targetTime, playfield);
@ -414,10 +418,7 @@ protected HitObjectComposer()
#region IPositionSnapProvider
public abstract SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition);
public virtual SnapResult FindSnappedPosition(Vector2 screenSpacePosition) =>
new SnapResult(screenSpacePosition, null);
public abstract SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All);
#endregion
}

View File

@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Edit
{
/// <summary>
/// A snap provider which given a proposed position for a hit object, potentially offers a more correct position and time value inferred from the context of the beatmap.
/// Provided values are inferred in an isolated context, without consideration of other nearby hit objects.
/// </summary>
[Cached]
public interface IPositionSnapProvider
@ -16,18 +15,9 @@ public interface IPositionSnapProvider
/// <summary>
/// Given a position, find a valid time and position snap.
/// </summary>
/// <remarks>
/// This call should be equivalent to running <see cref="FindSnappedPosition"/> with any additional logic that can be performed without the time immutability restriction.
/// </remarks>
/// <param name="screenSpacePosition">The screen-space position to be snapped.</param>
/// <param name="snapType">The type of snapping to apply.</param>
/// <returns>The time and position post-snapping.</returns>
SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition);
/// <summary>
/// Given a position, find a valid position snap, without changing the time value.
/// </summary>
/// <param name="screenSpacePosition">The screen-space position to be snapped.</param>
/// <returns>The position post-snapping. Time will always be null.</returns>
SnapResult FindSnappedPosition(Vector2 screenSpacePosition);
SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All);
}
}

View File

@ -0,0 +1,15 @@
// 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.
using System;
namespace osu.Game.Rulesets.Edit
{
[Flags]
public enum SnapType
{
NearbyObjects = 0,
Grids = 1,
All = NearbyObjects | Grids,
}
}

View File

@ -486,7 +486,7 @@ private bool moveCurrentSelection(DragEvent e)
Vector2 originalPosition = movementBlueprintOriginalPositions[i];
var testPosition = originalPosition + distanceTravelled;
var positionalResult = snapProvider.FindSnappedPosition(testPosition);
var positionalResult = snapProvider.FindSnappedPositionAndTime(testPosition, SnapType.NearbyObjects);
if (positionalResult.ScreenSpacePosition == testPosition) continue;
@ -505,7 +505,7 @@ private bool moveCurrentSelection(DragEvent e)
Vector2 movePosition = movementBlueprintOriginalPositions.First() + distanceTravelled;
// Retrieve a snapped position.
var result = snapProvider?.FindSnappedPositionAndTime(movePosition);
var result = snapProvider?.FindSnappedPositionAndTime(movePosition, ~SnapType.NearbyObjects);
if (result == null)
{

View File

@ -303,10 +303,7 @@ private void endUserDrag()
/// </summary>
public double VisibleRange => track.Length / Zoom;
public SnapResult FindSnappedPosition(Vector2 screenSpacePosition) =>
new SnapResult(screenSpacePosition, null);
public SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition) =>
public SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All) =>
new SnapResult(screenSpacePosition, beatSnapProvider.SnapTime(getTimeFromPosition(Content.ToLocalSpace(screenSpacePosition))));
private double getTimeFromPosition(Vector2 localPosition) =>