Move DrawableHitObject state management to base class

This commit is contained in:
Dean Herbert 2019-07-22 15:05:56 +09:00
parent 8327452fe1
commit 91f86adb66
3 changed files with 75 additions and 66 deletions

View File

@ -3,12 +3,10 @@
using System;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
@ -60,14 +58,6 @@ protected override void CheckForResult(bool userTriggered, double timeOffset)
ApplyResult(r => r.Type = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss);
}
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
if (HitObject is IHasComboInformation combo)
AccentColour.Value = skin.GetValue<SkinConfiguration, Color4?>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
}
protected override void UpdateState(ArmedState state)
{
using (BeginAbsoluteSequence(HitObject.StartTime - HitObject.TimePreempt))

View File

@ -1,15 +1,10 @@
// 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;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
using osuTK.Graphics;
using osu.Game.Graphics.Containers;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
@ -39,49 +34,11 @@ protected DrawableOsuHitObject(OsuHitObject hitObject)
protected override void ClearInternal(bool disposeChildren = true) => shakeContainer.Clear(disposeChildren);
protected override bool RemoveInternal(Drawable drawable) => shakeContainer.Remove(drawable);
protected override bool UseTransformStateManagement => true;
protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt;
protected sealed override void UpdateState(ArmedState state)
{
double transformTime = HitObject.StartTime - HitObject.TimePreempt;
base.ApplyTransformsAt(transformTime, true);
base.ClearTransformsAfter(transformTime, true);
using (BeginAbsoluteSequence(transformTime, true))
{
UpdatePreemptState();
var judgementOffset = Math.Min(HitObject.HitWindows.HalfWindowFor(HitResult.Miss), Result?.TimeOffset ?? 0);
using (BeginDelayedSequence(HitObject.TimePreempt + judgementOffset, true))
UpdateCurrentState(state);
}
}
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
if (HitObject is IHasComboInformation combo)
AccentColour.Value = skin.GetValue<SkinConfiguration, Color4?>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
}
protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadeIn);
protected virtual void UpdateCurrentState(ArmedState state)
{
}
// Todo: At some point we need to move these to DrawableHitObject after ensuring that all other Rulesets apply
// transforms in the same way and don't rely on them not being cleared
public override void ClearTransformsAfter(double time, bool propagateChildren = false, string targetMember = null)
{
}
public override void ApplyTransformsAt(double time, bool propagateChildren = false)
{
}
protected override void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadeIn);
private OsuInputManager osuActionInputManager;
internal OsuInputManager OsuActionInputManager => osuActionInputManager ?? (osuActionInputManager = GetContainingInputManager() as OsuInputManager);

View File

@ -79,10 +79,12 @@ public abstract class DrawableHitObject : SkinReloadableDrawable
public override bool RemoveCompletedTransforms => false;
protected override bool RequiresChildrenUpdate => true;
public override bool IsPresent => base.IsPresent || (State.Value == ArmedState.Idle && Clock?.CurrentTime >= LifetimeStart);
public override bool IsPresent => base.IsPresent || (state.Value == ArmedState.Idle && Clock?.CurrentTime >= LifetimeStart);
public readonly Bindable<ArmedState> State = new Bindable<ArmedState>();
private readonly Bindable<ArmedState> state = new Bindable<ArmedState>();
protected DrawableHitObject(HitObject hitObject)
{
HitObject = hitObject;
@ -122,21 +124,81 @@ protected override void LoadComplete()
{
base.LoadComplete();
State.ValueChanged += armed =>
state.BindValueChanged(armed =>
{
UpdateState(armed.NewValue);
updateState(armed.NewValue);
// apply any custom state overrides
ApplyCustomUpdateState?.Invoke(this, armed.NewValue);
if (armed.NewValue == ArmedState.Hit)
PlaySamples();
};
State.TriggerChange();
}, true);
}
protected abstract void UpdateState(ArmedState state);
protected virtual bool UseTransformStateManagement => false;
private void updateState(ArmedState state)
{
if (UseTransformStateManagement)
{
double transformTime = HitObject.StartTime - InitialLifetimeOffset;
base.ApplyTransformsAt(transformTime, true);
base.ClearTransformsAfter(transformTime, true);
using (BeginAbsoluteSequence(transformTime, true))
{
UpdatePreemptState();
var judgementOffset = Math.Min(HitObject.HitWindows?.HalfWindowFor(HitResult.Miss) ?? double.MaxValue, Result?.TimeOffset ?? 0);
using (BeginDelayedSequence(InitialLifetimeOffset + judgementOffset, true))
{
UpdateCurrentState(state);
State.Value = state;
}
}
}
else
{
State.Value = state;
}
UpdateState(state);
}
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
{
base.SkinChanged(skin, allowFallback);
if (HitObject is IHasComboInformation combo)
AccentColour.Value = skin.GetValue<SkinConfiguration, Color4?>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
}
protected virtual void UpdatePreemptState()
{
}
protected virtual void UpdateCurrentState(ArmedState state)
{
}
public override void ClearTransformsAfter(double time, bool propagateChildren = false, string targetMember = null)
{
if (!UseTransformStateManagement)
base.ClearTransformsAfter(time, propagateChildren, targetMember);
}
public override void ApplyTransformsAt(double time, bool propagateChildren = false)
{
if (!UseTransformStateManagement)
base.ApplyTransformsAt(time, propagateChildren);
}
protected virtual void UpdateState(ArmedState state)
{
}
/// <summary>
/// Bind to apply a custom state which can override the default implementation.
@ -163,7 +225,7 @@ protected override void Update()
Result.TimeOffset = 0;
Result.Type = HitResult.None;
State.Value = ArmedState.Idle;
state.Value = ArmedState.Idle;
}
}
}
@ -243,11 +305,11 @@ protected void ApplyResult(Action<JudgementResult> application)
break;
case HitResult.Miss:
State.Value = ArmedState.Miss;
state.Value = ArmedState.Miss;
break;
default:
State.Value = ArmedState.Hit;
state.Value = ArmedState.Hit;
break;
}