< prev index next >
modules/graphics/src/main/java/javafx/animation/SequentialTransition.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 352,363 ****
final int index = Arrays.binarySearch(startTimes, fromIndex, toIndex, ticks);
return (index < 0) ? -index - 2 : (index > 0) ? index - 1 : 0;
}
@Override
! void impl_sync(boolean forceSync) {
! super.impl_sync(forceSync);
if ((forceSync && childrenChanged) || (startTimes == null)) {
cachedChildren = getChildren().toArray(EMPTY_ANIMATION_ARRAY);
end = cachedChildren.length;
startTimes = new long[end + 1];
--- 352,363 ----
final int index = Arrays.binarySearch(startTimes, fromIndex, toIndex, ticks);
return (index < 0) ? -index - 2 : (index > 0) ? index - 1 : 0;
}
@Override
! void sync(boolean forceSync) {
! super.sync(forceSync);
if ((forceSync && childrenChanged) || (startTimes == null)) {
cachedChildren = getChildren().toArray(EMPTY_ANIMATION_ARRAY);
end = cachedChildren.length;
startTimes = new long[end + 1];
*** 392,474 ****
}
}
}
@Override
! void impl_start(boolean forceSync) {
! super.impl_start(forceSync);
toggledRate = false;
rateProperty().addListener(rateListener);
offsetTicks = 0L;
double curRate = getCurrentRate();
final long currentTicks = TickCalculation.fromDuration(getCurrentTime());
if (curRate < 0) {
jumpToEnd();
curIndex = end;
if (currentTicks < startTimes[end]) {
! impl_jumpTo(currentTicks, startTimes[end], false);
}
} else {
jumpToBefore();
curIndex = BEFORE;
if (currentTicks > 0) {
! impl_jumpTo(currentTicks, startTimes[end], false);
}
}
}
@Override
! void impl_pause() {
! super.impl_pause();
if ((curIndex != BEFORE) && (curIndex != end)) {
final Animation current = cachedChildren[curIndex];
if (current.getStatus() == Status.RUNNING) {
! current.impl_pause();
}
}
}
@Override
! void impl_resume() {
! super.impl_resume();
if ((curIndex != BEFORE) && (curIndex != end)) {
final Animation current = cachedChildren[curIndex];
if (current.getStatus() == Status.PAUSED) {
! current.impl_resume();
current.clipEnvelope.setRate(rates[curIndex] * Math.signum(getCurrentRate()));
}
}
}
@Override
! void impl_stop() {
! super.impl_stop();
if ((curIndex != BEFORE) && (curIndex != end)) {
final Animation current = cachedChildren[curIndex];
if (current.getStatus() != Status.STOPPED) {
! current.impl_stop();
}
}
if (childrenChanged) {
setCycleDuration(computeCycleDuration());
}
rateProperty().removeListener(rateListener);
}
private boolean startChild(Animation child, int index) {
final boolean forceSync = forceChildSync[index];
! if (child.impl_startable(forceSync)) {
child.clipEnvelope.setRate(rates[index] * Math.signum(getCurrentRate()));
! child.impl_start(forceSync);
forceChildSync[index] = false;
return true;
}
return false;
}
! @Override void impl_playTo(long currentTicks, long cycleTicks) {
! impl_setCurrentTicks(currentTicks);
final double frac = calculateFraction(currentTicks, cycleTicks);
final long newTicks = Math.max(0, Math.min(getCachedInterpolator().interpolate(0, cycleTicks, frac), cycleTicks));
final int newIndex = findNewIndex(newTicks);
final Animation current = ((curIndex == BEFORE) || (curIndex == end)) ? null : cachedChildren[curIndex];
if (toggledRate) {
--- 392,474 ----
}
}
}
@Override
! void doStart(boolean forceSync) {
! super.doStart(forceSync);
toggledRate = false;
rateProperty().addListener(rateListener);
offsetTicks = 0L;
double curRate = getCurrentRate();
final long currentTicks = TickCalculation.fromDuration(getCurrentTime());
if (curRate < 0) {
jumpToEnd();
curIndex = end;
if (currentTicks < startTimes[end]) {
! doJumpTo(currentTicks, startTimes[end], false);
}
} else {
jumpToBefore();
curIndex = BEFORE;
if (currentTicks > 0) {
! doJumpTo(currentTicks, startTimes[end], false);
}
}
}
@Override
! void doPause() {
! super.doPause();
if ((curIndex != BEFORE) && (curIndex != end)) {
final Animation current = cachedChildren[curIndex];
if (current.getStatus() == Status.RUNNING) {
! current.doPause();
}
}
}
@Override
! void doResume() {
! super.doResume();
if ((curIndex != BEFORE) && (curIndex != end)) {
final Animation current = cachedChildren[curIndex];
if (current.getStatus() == Status.PAUSED) {
! current.doResume();
current.clipEnvelope.setRate(rates[curIndex] * Math.signum(getCurrentRate()));
}
}
}
@Override
! void doStop() {
! super.doStop();
if ((curIndex != BEFORE) && (curIndex != end)) {
final Animation current = cachedChildren[curIndex];
if (current.getStatus() != Status.STOPPED) {
! current.doStop();
}
}
if (childrenChanged) {
setCycleDuration(computeCycleDuration());
}
rateProperty().removeListener(rateListener);
}
private boolean startChild(Animation child, int index) {
final boolean forceSync = forceChildSync[index];
! if (child.startable(forceSync)) {
child.clipEnvelope.setRate(rates[index] * Math.signum(getCurrentRate()));
! child.doStart(forceSync);
forceChildSync[index] = false;
return true;
}
return false;
}
! @Override void doPlayTo(long currentTicks, long cycleTicks) {
! setCurrentTicks(currentTicks);
final double frac = calculateFraction(currentTicks, cycleTicks);
final long newTicks = Math.max(0, Math.min(getCachedInterpolator().interpolate(0, cycleTicks, frac), cycleTicks));
final int newIndex = findNewIndex(newTicks);
final Animation current = ((curIndex == BEFORE) || (curIndex == end)) ? null : cachedChildren[curIndex];
if (toggledRate) {
*** 496,512 ****
oldTicks = newTicks;
return;
}
}
if (newTicks >= startTimes[curIndex+1]) {
! current.impl_timePulse(sub(durations[curIndex], offsetTicks));
if (newTicks == cycleTicks) {
curIndex = end;
}
} else {
final long localTicks = sub(newTicks - currentDelay, offsetTicks);
! current.impl_timePulse(localTicks);
}
}
} else { // getCurrentRate() < 0
final long currentDelay = add(startTimes[curIndex], delays[curIndex]);
if ((oldTicks >= startTimes[curIndex+1]) || ((oldTicks >= currentDelay) && (current.getStatus() == Status.STOPPED))){
--- 496,512 ----
oldTicks = newTicks;
return;
}
}
if (newTicks >= startTimes[curIndex+1]) {
! current.doTimePulse(sub(durations[curIndex], offsetTicks));
if (newTicks == cycleTicks) {
curIndex = end;
}
} else {
final long localTicks = sub(newTicks - currentDelay, offsetTicks);
! current.doTimePulse(localTicks);
}
}
} else { // getCurrentRate() < 0
final long currentDelay = add(startTimes[curIndex], delays[curIndex]);
if ((oldTicks >= startTimes[curIndex+1]) || ((oldTicks >= currentDelay) && (current.getStatus() == Status.STOPPED))){
*** 524,540 ****
oldTicks = newTicks;
return;
}
}
if (newTicks <= currentDelay) {
! current.impl_timePulse(sub(durations[curIndex], offsetTicks));
if (newTicks == 0) {
curIndex = BEFORE;
}
} else {
final long localTicks = sub(startTimes[curIndex + 1] - newTicks, offsetTicks);
! current.impl_timePulse(localTicks);
}
}
} else { // curIndex != newIndex
if (curIndex < newIndex) {
if (current != null) {
--- 524,540 ----
oldTicks = newTicks;
return;
}
}
if (newTicks <= currentDelay) {
! current.doTimePulse(sub(durations[curIndex], offsetTicks));
if (newTicks == 0) {
curIndex = BEFORE;
}
} else {
final long localTicks = sub(startTimes[curIndex + 1] - newTicks, offsetTicks);
! current.doTimePulse(localTicks);
}
}
} else { // curIndex != newIndex
if (curIndex < newIndex) {
if (current != null) {
*** 552,572 ****
}
}
}
}
if (current.getStatus() == Status.RUNNING) {
! current.impl_timePulse(sub(durations[curIndex], offsetTicks));
}
oldTicks = startTimes[curIndex + 1];
}
offsetTicks = 0;
curIndex++;
for (; curIndex < newIndex; curIndex++) {
final Animation animation = cachedChildren[curIndex];
animation.clipEnvelope.jumpTo(0);
if (startChild(animation, curIndex)) {
! animation.impl_timePulse(durations[curIndex]); // No need to subtract offsetTicks ( == 0)
} else {
final EventHandler<ActionEvent> handler = animation.getOnFinished();
if (handler != null) {
handler.handle(new ActionEvent(this, null));
}
--- 552,572 ----
}
}
}
}
if (current.getStatus() == Status.RUNNING) {
! current.doTimePulse(sub(durations[curIndex], offsetTicks));
}
oldTicks = startTimes[curIndex + 1];
}
offsetTicks = 0;
curIndex++;
for (; curIndex < newIndex; curIndex++) {
final Animation animation = cachedChildren[curIndex];
animation.clipEnvelope.jumpTo(0);
if (startChild(animation, curIndex)) {
! animation.doTimePulse(durations[curIndex]); // No need to subtract offsetTicks ( == 0)
} else {
final EventHandler<ActionEvent> handler = animation.getOnFinished();
if (handler != null) {
handler.handle(new ActionEvent(this, null));
}
*** 575,591 ****
}
final Animation newAnimation = cachedChildren[curIndex];
newAnimation.clipEnvelope.jumpTo(0);
if (startChild(newAnimation, curIndex)) {
if (newTicks >= startTimes[curIndex+1]) {
! newAnimation.impl_timePulse(durations[curIndex]); // No need to subtract offsetTicks ( == 0)
if (newTicks == cycleTicks) {
curIndex = end;
}
} else {
final long localTicks = sub(newTicks, add(startTimes[curIndex], delays[curIndex]));
! newAnimation.impl_timePulse(localTicks);
}
} else {
final EventHandler<ActionEvent> handler = newAnimation.getOnFinished();
if (handler != null) {
handler.handle(new ActionEvent(this, null));
--- 575,591 ----
}
final Animation newAnimation = cachedChildren[curIndex];
newAnimation.clipEnvelope.jumpTo(0);
if (startChild(newAnimation, curIndex)) {
if (newTicks >= startTimes[curIndex+1]) {
! newAnimation.doTimePulse(durations[curIndex]); // No need to subtract offsetTicks ( == 0)
if (newTicks == cycleTicks) {
curIndex = end;
}
} else {
final long localTicks = sub(newTicks, add(startTimes[curIndex], delays[curIndex]));
! newAnimation.doTimePulse(localTicks);
}
} else {
final EventHandler<ActionEvent> handler = newAnimation.getOnFinished();
if (handler != null) {
handler.handle(new ActionEvent(this, null));
*** 607,627 ****
}
}
}
}
if (current.getStatus() == Status.RUNNING) {
! current.impl_timePulse(sub(durations[curIndex], offsetTicks));
}
oldTicks = startTimes[curIndex];
}
offsetTicks = 0;
curIndex--;
for (; curIndex > newIndex; curIndex--) {
final Animation animation = cachedChildren[curIndex];
animation.clipEnvelope.jumpTo(Math.round(durations[curIndex] * rates[curIndex]));
if (startChild(animation, curIndex)) {
! animation.impl_timePulse(durations[curIndex]); // No need to subtract offsetTicks ( == 0)
} else {
final EventHandler<ActionEvent> handler = animation.getOnFinished();
if (handler != null) {
handler.handle(new ActionEvent(this, null));
}
--- 607,627 ----
}
}
}
}
if (current.getStatus() == Status.RUNNING) {
! current.doTimePulse(sub(durations[curIndex], offsetTicks));
}
oldTicks = startTimes[curIndex];
}
offsetTicks = 0;
curIndex--;
for (; curIndex > newIndex; curIndex--) {
final Animation animation = cachedChildren[curIndex];
animation.clipEnvelope.jumpTo(Math.round(durations[curIndex] * rates[curIndex]));
if (startChild(animation, curIndex)) {
! animation.doTimePulse(durations[curIndex]); // No need to subtract offsetTicks ( == 0)
} else {
final EventHandler<ActionEvent> handler = animation.getOnFinished();
if (handler != null) {
handler.handle(new ActionEvent(this, null));
}
*** 630,646 ****
}
final Animation newAnimation = cachedChildren[curIndex];
newAnimation.clipEnvelope.jumpTo(Math.round(durations[curIndex] * rates[curIndex]));
if (startChild(newAnimation, curIndex)) {
if (newTicks <= add(startTimes[curIndex], delays[curIndex])) {
! newAnimation.impl_timePulse(durations[curIndex]); // No need to subtract offsetTicks ( == 0)
if (newTicks == 0) {
curIndex = BEFORE;
}
} else {
final long localTicks = sub(startTimes[curIndex + 1], newTicks);
! newAnimation.impl_timePulse(localTicks);
}
} else {
final EventHandler<ActionEvent> handler = newAnimation.getOnFinished();
if (handler != null) {
handler.handle(new ActionEvent(this, null));
--- 630,646 ----
}
final Animation newAnimation = cachedChildren[curIndex];
newAnimation.clipEnvelope.jumpTo(Math.round(durations[curIndex] * rates[curIndex]));
if (startChild(newAnimation, curIndex)) {
if (newTicks <= add(startTimes[curIndex], delays[curIndex])) {
! newAnimation.doTimePulse(durations[curIndex]); // No need to subtract offsetTicks ( == 0)
if (newTicks == 0) {
curIndex = BEFORE;
}
} else {
final long localTicks = sub(startTimes[curIndex + 1], newTicks);
! newAnimation.doTimePulse(localTicks);
}
} else {
final EventHandler<ActionEvent> handler = newAnimation.getOnFinished();
if (handler != null) {
handler.handle(new ActionEvent(this, null));
*** 649,667 ****
}
}
oldTicks = newTicks;
}
! @Override void impl_jumpTo(long currentTicks, long cycleTicks, boolean forceJump) {
! impl_setCurrentTicks(currentTicks);
final Status status = getStatus();
if (status == Status.STOPPED && !forceJump) {
return;
}
! impl_sync(false);
final double frac = calculateFraction(currentTicks, cycleTicks);
final long newTicks = Math.max(0, Math.min(getCachedInterpolator().interpolate(0, cycleTicks, frac), cycleTicks));
final int oldIndex = curIndex;
curIndex = findNewIndex(newTicks);
final Animation newAnimation = cachedChildren[curIndex];
--- 649,667 ----
}
}
oldTicks = newTicks;
}
! @Override void doJumpTo(long currentTicks, long cycleTicks, boolean forceJump) {
! setCurrentTicks(currentTicks);
final Status status = getStatus();
if (status == Status.STOPPED && !forceJump) {
return;
}
! sync(false);
final double frac = calculateFraction(currentTicks, cycleTicks);
final long newTicks = Math.max(0, Math.min(getCachedInterpolator().interpolate(0, cycleTicks, frac), cycleTicks));
final int oldIndex = curIndex;
curIndex = findNewIndex(newTicks);
final Animation newAnimation = cachedChildren[curIndex];
*** 670,695 ****
if (curIndex != oldIndex) {
if (status != Status.STOPPED) {
if ((oldIndex != BEFORE) && (oldIndex != end)) {
final Animation oldChild = cachedChildren[oldIndex];
if (oldChild.getStatus() != Status.STOPPED) {
! cachedChildren[oldIndex].impl_stop();
}
}
if (curIndex < oldIndex) {
for (int i = oldIndex == end ? end - 1 : oldIndex; i > curIndex; --i) {
! cachedChildren[i].impl_jumpTo(0, durations[i], true);
}
} else { //curIndex > oldIndex as curIndex != oldIndex
for (int i = oldIndex == BEFORE? 0 : oldIndex; i < curIndex; ++i) {
! cachedChildren[i].impl_jumpTo(durations[i], durations[i], true);
}
}
if (newTicks >= currentDelay) {
startChild(newAnimation, curIndex);
if (status == Status.PAUSED) {
! newAnimation.impl_pause();
}
}
}
}
if (oldIndex == curIndex) {
--- 670,695 ----
if (curIndex != oldIndex) {
if (status != Status.STOPPED) {
if ((oldIndex != BEFORE) && (oldIndex != end)) {
final Animation oldChild = cachedChildren[oldIndex];
if (oldChild.getStatus() != Status.STOPPED) {
! cachedChildren[oldIndex].doStop();
}
}
if (curIndex < oldIndex) {
for (int i = oldIndex == end ? end - 1 : oldIndex; i > curIndex; --i) {
! cachedChildren[i].doJumpTo(0, durations[i], true);
}
} else { //curIndex > oldIndex as curIndex != oldIndex
for (int i = oldIndex == BEFORE? 0 : oldIndex; i < curIndex; ++i) {
! cachedChildren[i].doJumpTo(durations[i], durations[i], true);
}
}
if (newTicks >= currentDelay) {
startChild(newAnimation, curIndex);
if (status == Status.PAUSED) {
! newAnimation.doPause();
}
}
}
}
if (oldIndex == curIndex) {
*** 714,724 ****
}
private void jumpToEnd() {
for (int i = 0 ; i < end; ++i) {
if (forceChildSync[i]) {
! cachedChildren[i].impl_sync(true);
//NOTE: do not clean up forceChildSync[i] here. Another sync will be needed during the play
// The reason is we have 2 different use-cases for jumping (1)play from start, (2)play next cycle.
// and 2 different types of sub-transitions (A)"by" transitions that need to synchronize on
// the current state and move property by certain value and (B)"from-to" transitions that
// move from one point to another on each play/cycle. We can't query if transition is A or B.
--- 714,724 ----
}
private void jumpToEnd() {
for (int i = 0 ; i < end; ++i) {
if (forceChildSync[i]) {
! cachedChildren[i].sync(true);
//NOTE: do not clean up forceChildSync[i] here. Another sync will be needed during the play
// The reason is we have 2 different use-cases for jumping (1)play from start, (2)play next cycle.
// and 2 different types of sub-transitions (A)"by" transitions that need to synchronize on
// the current state and move property by certain value and (B)"from-to" transitions that
// move from one point to another on each play/cycle. We can't query if transition is A or B.
*** 729,751 ****
//
// Now the reason why we cannot clean forceChildSync[i] here is that while we need to sync here,
// there might be children of (A)-"by" type that operate on the same property, but fail to synchronize
// them when they start would mean they all would have the same value at the beginning.
}
! cachedChildren[i].impl_jumpTo(durations[i], durations[i], true);
}
}
private void jumpToBefore() {
for (int i = end - 1 ; i >= 0; --i) {
if (forceChildSync[i]) {
! cachedChildren[i].impl_sync(true);
//NOTE: do not clean up forceChildSync[i] here. Another sync will be needed during the play
// See explanation in jumpToEnd
}
! cachedChildren[i].impl_jumpTo(0, durations[i], true);
}
}
/**
* {@inheritDoc}
--- 729,751 ----
//
// Now the reason why we cannot clean forceChildSync[i] here is that while we need to sync here,
// there might be children of (A)-"by" type that operate on the same property, but fail to synchronize
// them when they start would mean they all would have the same value at the beginning.
}
! cachedChildren[i].doJumpTo(durations[i], durations[i], true);
}
}
private void jumpToBefore() {
for (int i = end - 1 ; i >= 0; --i) {
if (forceChildSync[i]) {
! cachedChildren[i].sync(true);
//NOTE: do not clean up forceChildSync[i] here. Another sync will be needed during the play
// See explanation in jumpToEnd
}
! cachedChildren[i].doJumpTo(0, durations[i], true);
}
}
/**
* {@inheritDoc}
< prev index next >