1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-06 10:22:54 +08:00

Move blueprint validity conditions to allow more correct external usage of EndPlacement

Until now, these were haphazardly enforce inline in blueprint
implementations. The only thing stopping complete breakage is that
`EndPlacement` wasn't called (too much) from outside the blueprint,
leaving them responsible for their own placement.

By moving this conditional out of the provided paramters to
`EndPlacement`, it allows more flexible usage of that method externally.
Coming in a future PR.
This commit is contained in:
Dean Herbert 2023-05-12 16:00:40 +09:00
parent 3e8711ed96
commit f443cfb93e
6 changed files with 26 additions and 7 deletions

View File

@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
private double placementStartTime; private double placementStartTime;
private double placementEndTime; private double placementEndTime;
protected override bool IsValidForPlacement => HitObject.Duration > 0;
public BananaShowerPlacementBlueprint() public BananaShowerPlacementBlueprint()
{ {
InternalChild = outline = new TimeSpanOutline(); InternalChild = outline = new TimeSpanOutline();
@ -49,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
case PlacementState.Active: case PlacementState.Active:
if (e.Button != MouseButton.Right) break; if (e.Button != MouseButton.Right) break;
EndPlacement(HitObject.Duration > 0); EndPlacement(true);
return true; return true;
} }

View File

@ -24,6 +24,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
private InputManager inputManager = null!; private InputManager inputManager = null!;
protected override bool IsValidForPlacement => HitObject.Duration > 0;
public JuiceStreamPlacementBlueprint() public JuiceStreamPlacementBlueprint()
{ {
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
@ -70,7 +72,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
return true; return true;
case MouseButton.Right: case MouseButton.Right:
EndPlacement(HitObject.Duration > 0); EndPlacement(true);
return true; return true;
} }

View File

@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
[Resolved] [Resolved]
private IScrollingInfo scrollingInfo { get; set; } private IScrollingInfo scrollingInfo { get; set; }
protected override bool IsValidForPlacement => HitObject.Duration > 0;
public HoldNotePlacementBlueprint() public HoldNotePlacementBlueprint()
: base(new HoldNote()) : base(new HoldNote())
{ {
@ -75,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
return; return;
base.OnMouseUp(e); base.OnMouseUp(e);
EndPlacement(HitObject.Duration > 0); EndPlacement(true);
} }
private double originalStartTime; private double originalStartTime;

View File

@ -41,6 +41,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
[Resolved(CanBeNull = true)] [Resolved(CanBeNull = true)]
private IDistanceSnapProvider snapProvider { get; set; } private IDistanceSnapProvider snapProvider { get; set; }
protected override bool IsValidForPlacement => HitObject.Path.HasValidLength;
public SliderPlacementBlueprint() public SliderPlacementBlueprint()
: base(new Slider()) : base(new Slider())
{ {
@ -150,7 +152,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
private void endCurve() private void endCurve()
{ {
updateSlider(); updateSlider();
EndPlacement(HitObject.Path.HasValidLength); EndPlacement(true);
} }
protected override void Update() protected override void Update()

View File

@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
private readonly IHasDuration spanPlacementObject; private readonly IHasDuration spanPlacementObject;
protected override bool IsValidForPlacement => spanPlacementObject.Duration > 0;
public TaikoSpanPlacementBlueprint(HitObject hitObject) public TaikoSpanPlacementBlueprint(HitObject hitObject)
: base(hitObject) : base(hitObject)
{ {
@ -73,7 +75,7 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
return; return;
base.OnMouseUp(e); base.OnMouseUp(e);
EndPlacement(spanPlacementObject.Duration > 0); EndPlacement(true);
} }
public override void UpdateTimeAndPosition(SnapResult result) public override void UpdateTimeAndPosition(SnapResult result)

View File

@ -47,6 +47,15 @@ namespace osu.Game.Rulesets.Edit
[Resolved] [Resolved]
private IPlacementHandler placementHandler { get; set; } private IPlacementHandler placementHandler { get; set; }
/// <summary>
/// Whether this blueprint is currently in a state that can be committed.
/// </summary>
/// <remarks>
/// Override this with any preconditions that should be double-checked on committing.
/// If <c>false</c> is returned and a commit is attempted, the blueprint will be destroyed instead.
/// </remarks>
protected virtual bool IsValidForPlacement => true;
protected PlacementBlueprint(HitObject hitObject) protected PlacementBlueprint(HitObject hitObject)
{ {
HitObject = hitObject; HitObject = hitObject;
@ -88,7 +97,7 @@ namespace osu.Game.Rulesets.Edit
/// Signals that the placement of <see cref="HitObject"/> has finished. /// Signals that the placement of <see cref="HitObject"/> has finished.
/// This will destroy this <see cref="PlacementBlueprint"/>, and add the HitObject.StartTime to the <see cref="Beatmap"/>. /// This will destroy this <see cref="PlacementBlueprint"/>, and add the HitObject.StartTime to the <see cref="Beatmap"/>.
/// </summary> /// </summary>
/// <param name="commit">Whether the object should be committed.</param> /// <param name="commit">Whether the object should be committed. Note that a commit may fail if <see cref="IsValidForPlacement"/> is <c>false</c>.</param>
public void EndPlacement(bool commit) public void EndPlacement(bool commit)
{ {
switch (PlacementActive) switch (PlacementActive)
@ -102,7 +111,7 @@ namespace osu.Game.Rulesets.Edit
break; break;
} }
placementHandler.EndPlacement(HitObject, commit); placementHandler.EndPlacement(HitObject, IsValidForPlacement && commit);
PlacementActive = PlacementState.Finished; PlacementActive = PlacementState.Finished;
} }