Fix remaining feedback loops

This commit is contained in:
Dean Herbert
2021-03-16 18:14:29 +09:00
parent e3bed4c97d
commit 932745e5c4

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
@ -80,7 +79,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
aspectRatio.BindValueChanged(aspect => aspectRatio.BindValueChanged(aspect =>
{ {
forceAspectRatio(aspect.NewValue); aspectRatioApplication?.Cancel();
aspectRatioApplication = Schedule(() => forceAspectRatio(aspect.NewValue));
}); });
((IBindable<Size>)tabletSize).BindTo(tabletHandler.TabletSize); ((IBindable<Size>)tabletSize).BindTo(tabletHandler.TabletSize);
@ -102,31 +102,44 @@ namespace osu.Game.Overlays.Settings.Sections.Input
}, true); }, true);
} }
private float curentAspectRatio => (float)sizeX.Value / sizeY.Value;
private void applyAspectRatio(ValueChangedEvent<Size> sizeChanged) private void applyAspectRatio(ValueChangedEvent<Size> sizeChanged)
{ {
float proposedAspectRatio = (float)sizeX.Value / sizeY.Value; float proposedAspectRatio = curentAspectRatio;
if (!aspectLock.Value) try
{ {
aspectRatio.Value = proposedAspectRatio; if (!aspectLock.Value)
{
// aspect ratio was in a valid range.
if (proposedAspectRatio >= aspectRatio.MinValue && proposedAspectRatio <= aspectRatio.MaxValue)
{
updateAspectRatio();
return;
}
}
// aspect ratio was in a valid range. if (sizeChanged.NewValue.Width != sizeChanged.OldValue.Width)
if (proposedAspectRatio >= aspectRatio.MinValue && proposedAspectRatio <= aspectRatio.MaxValue) {
return; areaSize.Value = new Size(areaSize.Value.Width, (int)(areaSize.Value.Width / aspectRatio.Value));
}
else
{
areaSize.Value = new Size((int)(areaSize.Value.Height * aspectRatio.Value), areaSize.Value.Height);
}
} }
finally
if (sizeChanged.NewValue.Width != sizeChanged.OldValue.Width)
{ {
areaSize.Value = new Size(areaSize.Value.Width, (int)(areaSize.Value.Width / aspectRatio.Value)); // cancel any event which may have fired while updating variables as a result of aspect ratio limitations.
} // this avoids a potential feedback loop.
else aspectRatioApplication?.Cancel();
{
areaSize.Value = new Size((int)(areaSize.Value.Height * aspectRatio.Value), areaSize.Value.Height);
} }
}
// cancel any event which may have fired while updating variables as a result of aspect ratio limitations. private void updateAspectRatio()
// this avoids a potential feedback loop. {
aspectRatioApplication?.Cancel(); aspectRatio.Value = curentAspectRatio;
} }
private void updateDisplay() private void updateDisplay()
@ -204,6 +217,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
else else
sizeX.Value = (int)(sizeY.Value * aspectRatio); sizeX.Value = (int)(sizeY.Value * aspectRatio);
updateAspectRatio();
aspectRatioApplication?.Cancel(); aspectRatioApplication?.Cancel();
aspectLock.Value = true; aspectLock.Value = true;
} }