Skip to content

Commit

Permalink
Fix IllegalStateException in looped timing native animation
Browse files Browse the repository at this point in the history
Summary:
This PR fixes regression introduced in #17896 with IllegalStateException being thrown in FrameBasedAnimationDriver.

After investigating it seemed that the root cause was the code responsible for looping animations that was setting next frame time by adding the frame interval to the current time. In some circumstances the next frame would run earlier than that and as a result the calculated frame index was negative.

Here is the stacktrace as reported by axemclion https://github.com/facebook/react-native/pull/17896/files#r170007224
```
Caused by: java.lang.IllegalStateException: Calculated frame index should never be lower than 0
	at com.facebook.react.animated.FrameBasedAnimationDriver.runAnimationStep(FrameBasedAnimationDriver.java:60)
	at com.facebook.react.animated.NativeAnimatedNodesManager.runUpdates(NativeAnimatedNodesManager.java:444)
	at com.facebook.react.animated.NativeAnimatedModule$1.doFrameGuarded(NativeAnimatedModule.java:100)
	at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:29)
```

Run native animated tests suite. Run RNTester and scroll to the loop animation and see it working correctly

[ANDROID][BUGFIX][Animated] - Fix exception thrown by timing animation when looping
Closes #18061

Differential Revision: D7059335

Pulled By: hramos

fbshipit-source-id: b08dfd1398d028eeeabeb11863743666379da374
  • Loading branch information
kmagiera authored and facebook-github-bot committed Feb 22, 2018
1 parent cf0193f commit ef9d1fb
Showing 1 changed file with 5 additions and 2 deletions.
Expand Up @@ -52,7 +52,10 @@ public void resetConfig(ReadableMap config) {
public void runAnimationStep(long frameTimeNanos) {
if (mStartFrameTimeNanos < 0) {
mStartFrameTimeNanos = frameTimeNanos;
mFromValue = mAnimatedValue.mValue;
if (mCurrentLoop == 1) {
// initiate start value when animation runs for the first time
mFromValue = mAnimatedValue.mValue;
}
}
long timeFromStartMillis = (frameTimeNanos - mStartFrameTimeNanos) / 1000000;
int frameIndex = (int) Math.round(timeFromStartMillis / FRAME_TIME_MILLIS);
Expand All @@ -66,7 +69,7 @@ public void runAnimationStep(long frameTimeNanos) {
if (frameIndex >= mFrames.length - 1) {
nextValue = mToValue;
if (mIterations == -1 || mCurrentLoop < mIterations) { // looping animation, return to start
mStartFrameTimeNanos = frameTimeNanos + ((long) FRAME_TIME_MILLIS) * 1000000L;
mStartFrameTimeNanos = -1;
mCurrentLoop++;
} else { // animation has completed, no more frames left
mHasFinished = true;
Expand Down

0 comments on commit ef9d1fb

Please sign in to comment.