Non-linear transitions in timed frames cause the Player to break in the following frame

Issue #165 resolved
ThePaSch created an issue

Setting a non-linear transition (bézier, ease-in, ease-out) for a timed frame causes the div for the place display engine to end up with an invalid class name in the next frame, making all characters disappear from the screen and irreparably breaking the player until the trial is reloaded.

A trial in which this effect is demonstrated can be found here.

A pull request that fixes this issue has been submitted. I apologize for not catching this bug in initial testing.

Comments (9)

  1. ThePaSch reporter

    Further investigation has revealed that this is actually a bug that has always existed, but never really had any impact. The actual problem here is the setTimeout call in display_engine_global's setTransition function in correlation with timed frames - if that timed frame is slower than the default transition duration, which is 500ms, the next frame's setTransition call will go through before that timeout triggers and removes the transitioning property from the previous frame. When linear transitions were the only option, this didn't cause any problems, as the property to be removed was always 'transitioning-left', and setTransition would be called with a duration of 0 during the next non-transitioning frame, which would remove that class (and which is exactly what the timout callback does). The timeout would then trigger setTransition again, but since the class had already been removed by the next frame's calculations, it would obviously just do nothing.

    You can observe this effect by once more opening the trial linked in the description above and keeping a watch on the className of the place display container (found in divs with the ids and classes "screen-top" -> "display_engine_screen" -> "viewport" -> "display_engine_place") and setting a breakpoint in the setTransition function. In the trial's first linear transition, setTransition is called once, which causes the actual transition, and then again when the next frame is automatically displayed. In between those calls, you can see that the transitioning-left class remains on the place display container and is only removed after the second setTransition call, which races with the timeout callback and usually wins.

    Hence, the real cause of this bug is that the transition timeout is always set to 500ms, regardless of the fact that the frame it's set on may be timed and setTransition may be already called before the timeout itself triggers. The fix I've submitted is one that fixes the symptoms, while fixing the cause would require making sure that the player, upon displaying a frame, checks whether there is a timeout currently pending that will remove the transition, and if so, does not remove it while displaying the frame.

    This also means that there is fortunately a workaround for this bug - just change the wait time for frames with non-linear transitions to 501. This will make them work fine.

    I have updated the demonstration trial with two demonstrations, both effects of the same issue.

  2. Enthalpy

    We've received a new report of expanded trigger conditions for either this bug, or a related one. The reporter confirmed that removing the "ease out" command on an untimed frame restored the character display engine.

    I have a copy of the bugged trial data and will verify that pull request #52 also fixes the bug in this case.

  3. ThePaSch reporter

    Did that frame follow a timed frame, perchance? I was able to trigger the bug by putting a timed frame without a transition before an untimed frame with a transition - which is basically the opposite way around - and the result is exactly the same; the place display engine is left with an invalid identifier, which breaks it. In that case, the workaround (of using any time higher than 500ms) should still work for this particular occasion. It would also mean that pull request #52 definitely fixes it.

  4. Log in to comment