-
Notifications
You must be signed in to change notification settings - Fork 459
Description
Consider the following scenario:
[Test]
public void TestPastTransformDoesntAffectOthers()
{
boxTest(box =>
{
box.Alpha = 0;
box.Scale = new Vector2(2);
box.RemoveCompletedTransforms = false;
});
// move forward to future point in time before adding transforms.
checkAtTime(interval * 4, _ => true);
AddStep("add transforms", () =>
{
using (box.BeginAbsoluteSequence(0))
{
box.FadeIn();
box.ScaleTo(1, interval * 4);
}
});
AddStep("change box scale", () => box.Scale = new Vector2(3));
AddStep("re-apply transforms", () =>
{
using (box.BeginAbsoluteSequence(0))
{
// fade-in is added here to test whether applying this transform would reset the state of the Scale property to the values of the previous transform.
box.FadeIn();
box.ScaleTo(1, interval * 4);
}
});
checkAtTime(0, box => box.Scale == new Vector2(3));
checkAtTime(interval * 4, box => box.Scale == new Vector2(1));
}This fails and ends up with unexpected values when rewinding to time = 0 due to two different reasons:
- When transforms are re-applied to a drawable with existing transforms, the first transform added will trigger a full update pass on the drawable, causing its current state to be lost and overwritten with the transforms currently existing.
- When a transform is applied on a certain property with a start time matching an existing transform, the previous one remains and rewinding would favour the previous transform. This is expected on a sequence-based use case (
drawable.FadeTo(0.5f).FadeTo(1, 200)), but it probably shouldn't happen on isolated cases (drawable.FadeTo(0.5f) ... drawable.FadeTo(0.25f)).
Opening this issue thread as it resulted in going back and fourth over resolving ppy/osu#20807 (see ppy/osu#20825). And given that there are existing logic for removing transforms that exist after an early new one, it would be expected that this would be implicitly handled without the consumer performing certain operations beforehand.
The alternative and simplest solution would be to clear all existing transforms before applying new ones, but if that's the path we want to go with rather than going through the issues here, then one would hope to be warned about with runtime exceptions (potentially a guard in BeginAbsoluteSequence(t) that throws when there are existing transforms after the specified time).