mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-27 20:21:24 +08:00
Searching for sanity.
This commit is contained in:
parent
0a90565ba1
commit
3c57c03952
@ -67,20 +67,24 @@ public class AnimationStateTest {
|
||||
add(actual("start", entry));
|
||||
}
|
||||
|
||||
public void event (TrackEntry entry, Event event) {
|
||||
add(actual("event " + event.getString(), entry));
|
||||
}
|
||||
|
||||
public void interrupt (TrackEntry entry) {
|
||||
add(actual("interrupt", entry));
|
||||
}
|
||||
|
||||
public void end (TrackEntry entry) {
|
||||
add(actual("end", entry));
|
||||
}
|
||||
|
||||
public void dispose (TrackEntry entry) {
|
||||
add(actual("dispose", entry));
|
||||
}
|
||||
|
||||
public void complete (TrackEntry entry) {
|
||||
add(actual("complete", entry));
|
||||
}
|
||||
|
||||
public void end (TrackEntry entry) {
|
||||
add(actual("end", entry));
|
||||
public void event (TrackEntry entry, Event event) {
|
||||
add(actual("event " + event.getString(), entry));
|
||||
}
|
||||
|
||||
private void add (Result result) {
|
||||
@ -119,20 +123,36 @@ public class AnimationStateTest {
|
||||
expect(0, "event 14", 0.5f, 0.5f), //
|
||||
expect(0, "event 30", 1, 1), //
|
||||
expect(0, "complete", 1, 1), //
|
||||
expect(0, "end", 1, 1.1f) //
|
||||
expect(0, "end", 1, 1.1f), //
|
||||
expect(0, "dispose", 1, 1.1f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false);
|
||||
run(0.1f, 1000, null);
|
||||
|
||||
setup("1/60 time step", // 2
|
||||
setup("1/60 time step, dispose queued", // 2
|
||||
expect(0, "start", 0, 0), //
|
||||
expect(0, "interrupt", 0, 0), //
|
||||
expect(0, "end", 0, 0), //
|
||||
expect(0, "dispose", 0, 0), //
|
||||
expect(1, "dispose", 0, 0), //
|
||||
expect(0, "dispose", 0, 0), //
|
||||
expect(1, "dispose", 0, 0), //
|
||||
|
||||
// First 2 set/addAnimation calls are done.
|
||||
|
||||
expect(0, "start", 0, 0), //
|
||||
expect(0, "event 0", 0, 0), //
|
||||
expect(0, "event 14", 0.467f, 0.467f), //
|
||||
expect(0, "event 30", 1, 1), //
|
||||
expect(0, "complete", 1, 1), //
|
||||
expect(0, "end", 1, 1.017f) //
|
||||
expect(0, "end", 1, 1.017f), //
|
||||
expect(0, "dispose", 1, 1.017f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false);
|
||||
state.addAnimation(0, "events2", false, 0);
|
||||
state.addAnimation(0, "events1", false, 0);
|
||||
state.addAnimation(0, "events2", false, 0);
|
||||
state.setAnimation(0, "events1", false);
|
||||
run(1 / 60f, 1000, null);
|
||||
|
||||
setup("30 time step", // 3
|
||||
@ -141,7 +161,8 @@ public class AnimationStateTest {
|
||||
expect(0, "event 14", 30, 30), //
|
||||
expect(0, "event 30", 30, 30), //
|
||||
expect(0, "complete", 30, 30), //
|
||||
expect(0, "end", 30, 60) //
|
||||
expect(0, "end", 30, 60), //
|
||||
expect(0, "dispose", 30, 60) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false);
|
||||
run(30, 1000, null);
|
||||
@ -152,7 +173,8 @@ public class AnimationStateTest {
|
||||
expect(0, "event 14", 1, 1), //
|
||||
expect(0, "event 30", 1, 1), //
|
||||
expect(0, "complete", 1, 1), //
|
||||
expect(0, "end", 1, 2) //
|
||||
expect(0, "end", 1, 2), //
|
||||
expect(0, "dispose", 1, 2) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false);
|
||||
run(1, 1.01f, null);
|
||||
@ -171,6 +193,7 @@ public class AnimationStateTest {
|
||||
expect(1, "event 0", 0.1f, 1.1f), //
|
||||
|
||||
expect(0, "end", 1.1f, 1.2f), //
|
||||
expect(0, "dispose", 1.1f, 1.2f), //
|
||||
|
||||
expect(1, "event 14", 0.5f, 1.5f), //
|
||||
expect(1, "event 30", 1, 2), //
|
||||
@ -183,11 +206,13 @@ public class AnimationStateTest {
|
||||
expect(0, "event 0", 0.1f, 2.1f), //
|
||||
|
||||
expect(1, "end", 1.1f, 2.2f), //
|
||||
expect(1, "dispose", 1.1f, 2.2f), //
|
||||
|
||||
expect(0, "event 14", 0.5f, 2.5f), //
|
||||
expect(0, "event 30", 1, 3), //
|
||||
expect(0, "complete", 1, 3), //
|
||||
expect(0, "end", 1, 3.1f) //
|
||||
expect(0, "end", 1, 3.1f), //
|
||||
expect(0, "dispose", 1, 3.1f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false);
|
||||
state.addAnimation(0, "events2", false, 0);
|
||||
@ -206,11 +231,13 @@ public class AnimationStateTest {
|
||||
expect(1, "event 0", 0.1f, 0.6f), //
|
||||
|
||||
expect(0, "end", 0.6f, 0.7f), //
|
||||
expect(0, "dispose", 0.6f, 0.7f), //
|
||||
|
||||
expect(1, "event 14", 0.5f, 1.0f), //
|
||||
expect(1, "event 30", 1, 1.5f), //
|
||||
expect(1, "complete", 1, 1.5f), //
|
||||
expect(1, "end", 1, 1.6f) //
|
||||
expect(1, "end", 1, 1.6f), //
|
||||
expect(1, "dispose", 1, 1.6f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false);
|
||||
state.addAnimation(0, "events2", false, 0.5f);
|
||||
@ -230,10 +257,12 @@ public class AnimationStateTest {
|
||||
expect(1, "event 14", 0.5f, 1.4f), //
|
||||
|
||||
expect(0, "end", 1.6f, 1.7f), //
|
||||
expect(0, "dispose", 1.6f, 1.7f), //
|
||||
|
||||
expect(1, "event 30", 1, 1.9f), //
|
||||
expect(1, "complete", 1, 1.9f), //
|
||||
expect(1, "end", 1, 2) //
|
||||
expect(1, "end", 1, 2), //
|
||||
expect(1, "dispose", 1, 2) //
|
||||
);
|
||||
stateData.setMix("events1", "events2", 0.7f);
|
||||
state.setAnimation(0, "events1", true);
|
||||
@ -253,10 +282,12 @@ public class AnimationStateTest {
|
||||
|
||||
expect(0, "complete", 1, 1), //
|
||||
expect(0, "end", 1.1f, 1.2f), //
|
||||
expect(0, "dispose", 1.1f, 1.2f), //
|
||||
|
||||
expect(1, "event 30", 1, 1.4f), //
|
||||
expect(1, "complete", 1, 1.4f), //
|
||||
expect(1, "end", 1, 1.5f) //
|
||||
expect(1, "end", 1, 1.5f), //
|
||||
expect(1, "dispose", 1, 1.5f) //
|
||||
);
|
||||
stateData.setDefaultMix(0.7f);
|
||||
state.setAnimation(0, "events1", false);
|
||||
@ -277,10 +308,12 @@ public class AnimationStateTest {
|
||||
|
||||
expect(0, "complete", 1, 1), //
|
||||
expect(0, "end", 1.1f, 1.2f), //
|
||||
expect(0, "dispose", 1.1f, 1.2f), //
|
||||
|
||||
expect(1, "event 30", 1, 1.4f), //
|
||||
expect(1, "complete", 1, 1.4f), //
|
||||
expect(1, "end", 1, 1.5f) //
|
||||
expect(1, "end", 1, 1.5f), //
|
||||
expect(1, "dispose", 1, 1.5f) //
|
||||
);
|
||||
stateData.setMix("events1", "events2", 0.7f);
|
||||
state.setAnimation(0, "events1", false).setEventThreshold(0.5f);
|
||||
@ -305,10 +338,12 @@ public class AnimationStateTest {
|
||||
expect(1, "event 14", 0.5f, 1.3f), //
|
||||
|
||||
expect(0, "end", 1.5f, 1.6f), //
|
||||
expect(0, "dispose", 1.5f, 1.6f), //
|
||||
|
||||
expect(1, "event 30", 1, 1.8f), //
|
||||
expect(1, "complete", 1, 1.8f), //
|
||||
expect(1, "end", 1, 1.9f) //
|
||||
expect(1, "end", 1, 1.9f), //
|
||||
expect(1, "dispose", 1, 1.9f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", true).setEventThreshold(1);
|
||||
state.addAnimation(0, "events2", false, 0.8f).setMixDuration(0.7f);
|
||||
@ -351,11 +386,13 @@ public class AnimationStateTest {
|
||||
expect(1, "event 0", 0.1f, 2.1f), //
|
||||
|
||||
expect(0, "end", 2.1f, 2.2f), //
|
||||
expect(0, "dispose", 2.1f, 2.2f), //
|
||||
|
||||
expect(1, "event 14", 0.5f, 2.5f), //
|
||||
expect(1, "event 30", 1, 3), //
|
||||
expect(1, "complete", 1, 3), //
|
||||
expect(1, "end", 1, 3.1f) //
|
||||
expect(1, "end", 1, 3.1f), //
|
||||
expect(1, "dispose", 1, 3.1f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false);
|
||||
state.addAnimation(0, "events2", false, 2);
|
||||
@ -380,11 +417,13 @@ public class AnimationStateTest {
|
||||
expect(1, "event 0", 0.1f, 2.1f), //
|
||||
|
||||
expect(0, "end", 2.1f, 2.2f), //
|
||||
expect(0, "dispose", 2.1f, 2.2f), //
|
||||
|
||||
expect(1, "event 14", 0.5f, 2.5f), //
|
||||
expect(1, "event 30", 1, 3), //
|
||||
expect(1, "complete", 1, 3), //
|
||||
expect(1, "end", 1, 3.1f) //
|
||||
expect(1, "end", 1, 3.1f), //
|
||||
expect(1, "dispose", 1, 3.1f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", true);
|
||||
run(0.1f, 6, new TestListener() {
|
||||
@ -399,7 +438,8 @@ public class AnimationStateTest {
|
||||
expect(0, "event 14", 0.5f, 0.5f), //
|
||||
expect(0, "event 30", 1, 1), //
|
||||
expect(0, "complete", 1, 1), //
|
||||
expect(0, "end", 1, 1.1f) //
|
||||
expect(0, "end", 1, 1.1f), //
|
||||
expect(0, "dispose", 1, 1.1f) //
|
||||
);
|
||||
state.addAnimation(0, "events1", false, 0);
|
||||
run(0.1f, 1.9f, null);
|
||||
@ -410,7 +450,8 @@ public class AnimationStateTest {
|
||||
expect(0, "event 14", 0.5f, 0.5f), //
|
||||
expect(0, "event 30", 1, 1), //
|
||||
expect(0, "complete", 1, 1), //
|
||||
expect(0, "end", 9f, 9.1f) //
|
||||
expect(0, "end", 9f, 9.1f), //
|
||||
expect(0, "dispose", 9f, 9.1f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false).setTrackEnd(9);
|
||||
run(0.1f, 10, null);
|
||||
@ -447,7 +488,8 @@ public class AnimationStateTest {
|
||||
expect(0, "start", 0, 0), //
|
||||
expect(0, "event 14", 0.3f, 0.3f), //
|
||||
expect(0, "complete", 0.6f, 0.6f), //
|
||||
expect(0, "end", 1, 1.1f) //
|
||||
expect(0, "end", 1, 1.1f), //
|
||||
expect(0, "dispose", 1, 1.1f) //
|
||||
);
|
||||
entry = state.setAnimation(0, "events1", false);
|
||||
entry.setAnimationStart(0.2f);
|
||||
@ -472,10 +514,12 @@ public class AnimationStateTest {
|
||||
expect(1, "event 14", 0.5f, 1.2f), //
|
||||
|
||||
expect(0, "end", 1.4f, 1.5f), //
|
||||
expect(0, "dispose", 1.4f, 1.5f), //
|
||||
|
||||
expect(1, "event 30", 1, 1.7f), //
|
||||
expect(1, "complete", 1, 1.7f), //
|
||||
expect(1, "end", 1, 1.8f) //
|
||||
expect(1, "end", 1, 1.8f), //
|
||||
expect(1, "dispose", 1, 1.8f) //
|
||||
);
|
||||
entry = state.setAnimation(0, "events1", true);
|
||||
entry.setAnimationStart(0.2f);
|
||||
@ -489,20 +533,24 @@ public class AnimationStateTest {
|
||||
expect(0, "start", 0, 0), //
|
||||
expect(0, "event 0", 0, 0), //
|
||||
expect(0, "event 14", 0.5f, 0.5f), //
|
||||
expect(0, "event 30", 1, 1), //
|
||||
expect(0, "complete", 1, 1), //
|
||||
expect(0, "event 0", 1, 1), //
|
||||
|
||||
expect(1, "start", 0.1f, 1), //
|
||||
expect(1, "start", 0, 1), //
|
||||
|
||||
expect(0, "interrupt", 1, 1), //
|
||||
expect(0, "complete", 1, 1), //
|
||||
|
||||
expect(1, "event 0", 0.1f, 1), //
|
||||
expect(1, "event 14", 0.5f, 1.4f), //
|
||||
expect(1, "event 0", 0.1f, 1.1f), //
|
||||
expect(1, "event 14", 0.5f, 1.5f), //
|
||||
|
||||
expect(0, "end", 1.6f, 1.7f), //
|
||||
expect(0, "end", 1.7f, 1.8f), //
|
||||
expect(0, "dispose", 1.7f, 1.8f), //
|
||||
|
||||
expect(1, "event 30", 1, 1.9f), //
|
||||
expect(1, "complete", 1, 1.9f), //
|
||||
expect(1, "end", 1, 2) //
|
||||
expect(1, "event 30", 1, 2), //
|
||||
expect(1, "complete", 1, 2), //
|
||||
expect(1, "end", 1, 2.1f), //
|
||||
expect(1, "dispose", 1, 2.1f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", true);
|
||||
run(0.1f, 1000, new TestListener() {
|
||||
@ -513,37 +561,39 @@ public class AnimationStateTest {
|
||||
|
||||
setup("setAnimation twice", // 21
|
||||
expect(0, "start", 0, 0), //
|
||||
expect(0, "interrupt", 0, 0), //
|
||||
expect(0, "end", 0, 0), //
|
||||
expect(0, "dispose", 0, 0), //
|
||||
|
||||
expect(1, "start", 0, 0), //
|
||||
|
||||
expect(0, "interrupt", 0, 0), //
|
||||
|
||||
expect(1, "event 0", 0, 0), //
|
||||
|
||||
expect(0, "end", 0.1f, 0.2f), //
|
||||
|
||||
expect(1, "event 14", 0.5f, 0.5f), //
|
||||
|
||||
expect(0, "start", 0.1f, 0.8f), //
|
||||
// First 2 setAnimation calls are done.
|
||||
|
||||
expect(0, "start", 0, 0.8f), //
|
||||
|
||||
expect(1, "interrupt", 0.8f, 0.8f), //
|
||||
|
||||
expect(0, "event 0", 0.1f, 0.8f), //
|
||||
expect(0, "interrupt", 0, 0.8f), //
|
||||
expect(0, "end", 0, 0.8f), //
|
||||
expect(0, "dispose", 0, 0.8f), //
|
||||
|
||||
expect(1, "end", 0.8f, 0.9f), //
|
||||
|
||||
expect(0, "event 14", 0.5f, 1.2f), //
|
||||
expect(0, "event 30", 1, 1.7f), //
|
||||
expect(0, "complete", 1, 1.7f), //
|
||||
expect(0, "end", 1, 1.8f) //
|
||||
expect(1, "start", 0, 0.8f), //
|
||||
expect(1, "event 0", 0.1f, 0.9f), //
|
||||
expect(1, "event 14", 0.5f, 1.3f), //
|
||||
expect(1, "event 30", 1, 1.8f), //
|
||||
expect(1, "complete", 1, 1.8f), //
|
||||
expect(1, "end", 1, 1.9f), //
|
||||
expect(1, "dispose", 1, 1.9f) //
|
||||
);
|
||||
state.setAnimation(0, "events1", false); // First should be ignored.
|
||||
state.setAnimation(0, "events2", false);
|
||||
run(0.1f, 1000, new TestListener() {
|
||||
public void frame (float time) {
|
||||
if (MathUtils.isEqual(time, 0.8f)) {
|
||||
state.setAnimation(0, "events2", false); // First should be ignored.
|
||||
state.setAnimation(0, "events1", false);
|
||||
state.setAnimation(0, "events1", false); // First should be ignored.
|
||||
state.setAnimation(0, "events2", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -554,7 +604,8 @@ public class AnimationStateTest {
|
||||
expect(0, "event 14", 0.5f, 5.5f), //
|
||||
expect(0, "event 30", 1, 6), //
|
||||
expect(0, "complete", 1, 6), //
|
||||
expect(0, "end", 1, 6.1f) //
|
||||
expect(0, "end", 1, 6.1f), //
|
||||
expect(0, "dispose", 1, 6.1f) //
|
||||
);
|
||||
state.addAnimation(0, "events1", false, 5);
|
||||
run(0.1f, 10, null);
|
||||
@ -569,23 +620,41 @@ public class AnimationStateTest {
|
||||
state.addAnimation(3, "events2", false, 0);
|
||||
}
|
||||
|
||||
public void event (TrackEntry entry, Event event) {
|
||||
if (entry.getTrackIndex() != 2) state.setAnimation(2, "events2", false);
|
||||
}
|
||||
|
||||
public void end (TrackEntry entry) {
|
||||
if (entry.getAnimation().getName().equals("events1")) state.setAnimation(0, "events2", false);
|
||||
}
|
||||
|
||||
public void dispose (TrackEntry entry) {
|
||||
if (entry.getAnimation().getName().equals("events1")) state.setAnimation(1, "events2", false);
|
||||
}
|
||||
|
||||
public void complete (TrackEntry entry) {
|
||||
if (entry.getAnimation().getName().equals("events1")) state.setAnimation(1, "events2", false);
|
||||
}
|
||||
|
||||
public void event (TrackEntry entry, Event event) {
|
||||
if (entry.getTrackIndex() != 2) state.setAnimation(2, "events2", false);
|
||||
}
|
||||
});
|
||||
state.addAnimation(0, "events1", false, 0);
|
||||
state.addAnimation(0, "events2", false, 0);
|
||||
state.setAnimation(1, "events2", false);
|
||||
run(0.1f, 10, null);
|
||||
|
||||
setup("clearTrack", // 24
|
||||
expect(0, "start", 0, 0), //
|
||||
expect(0, "event 0", 0, 0), //
|
||||
expect(0, "event 14", 0.5f, 0.5f), //
|
||||
expect(0, "end", 0.7f, 0.7f), //
|
||||
expect(0, "dispose", 0.7f, 0.7f) //
|
||||
);
|
||||
state.addAnimation(0, "events1", false, 0);
|
||||
run(0.1f, 10, new TestListener() {
|
||||
public void frame (float time) {
|
||||
if (MathUtils.isEqual(time, 0.7f)) state.clearTrack(0);
|
||||
}
|
||||
});
|
||||
|
||||
System.out.println("AnimationState tests passed.");
|
||||
}
|
||||
|
||||
@ -608,7 +677,6 @@ public class AnimationStateTest {
|
||||
state.apply(skeleton);
|
||||
while (time < endTime) {
|
||||
time += incr;
|
||||
if (listener != null) listener.frame(time);
|
||||
skeleton.update(incr);
|
||||
state.update(incr);
|
||||
|
||||
@ -627,6 +695,8 @@ public class AnimationStateTest {
|
||||
state.apply(skeleton);
|
||||
state.apply(skeleton);
|
||||
if (expected.size > 0) state.addListener(stateListener);
|
||||
|
||||
if (listener != null) listener.frame(time);
|
||||
}
|
||||
// Expecting more than actual is a failure.
|
||||
for (int i = actual.size, n = expected.size; i < n; i++) {
|
||||
|
||||
@ -83,26 +83,31 @@ public class SimpleTest2 extends ApplicationAdapter {
|
||||
state = new AnimationState(stateData); // Holds the animation state for a skeleton (current animation, time, etc).
|
||||
state.setTimeScale(0.3f); // Slow all animations down to 30% speed.
|
||||
state.addListener(new AnimationStateListener() {
|
||||
public void event (TrackEntry entry, Event event) {
|
||||
System.out
|
||||
.println(entry.getTrackIndex() + " event: " + entry + ", " + event.getData().getName() + ", " + event.getInt());
|
||||
}
|
||||
|
||||
public void complete (TrackEntry entry) {
|
||||
System.out.println(entry.getTrackIndex() + " complete: " + entry);
|
||||
public void start (TrackEntry entry) {
|
||||
System.out.println(entry.getTrackIndex() + " start: " + entry);
|
||||
}
|
||||
|
||||
public void interrupt (TrackEntry entry) {
|
||||
System.out.println(entry.getTrackIndex() + " interrupt: " + entry);
|
||||
}
|
||||
|
||||
public void start (TrackEntry entry) {
|
||||
System.out.println(entry.getTrackIndex() + " start: " + entry);
|
||||
}
|
||||
|
||||
public void end (TrackEntry entry) {
|
||||
System.out.println(entry.getTrackIndex() + " end: " + entry);
|
||||
}
|
||||
|
||||
public void dispose (TrackEntry entry) {
|
||||
System.out.println(entry.getTrackIndex() + " dispose: " + entry);
|
||||
}
|
||||
|
||||
public void complete (TrackEntry entry) {
|
||||
System.out.println(entry.getTrackIndex() + " complete: " + entry);
|
||||
}
|
||||
|
||||
public void event (TrackEntry entry, Event event) {
|
||||
System.out
|
||||
.println(entry.getTrackIndex() + " event: " + entry + ", " + event.getData().getName() + ", " + event.getInt());
|
||||
}
|
||||
});
|
||||
|
||||
// Set animation on track 0.
|
||||
|
||||
@ -103,18 +103,18 @@ public class AnimationState {
|
||||
// Should we get rid of the track end time?
|
||||
// Or default it to MAX_VALUE even for non-looping animations?
|
||||
// Or reset the skeleton before clearing? Note only apply() has a skeleton.
|
||||
freeAll(current.next);
|
||||
queue.end(current);
|
||||
if (mixingFrom != null) queue.end(mixingFrom);
|
||||
tracks.set(i, null);
|
||||
queue.end(current);
|
||||
disposeNext(current);
|
||||
if (mixingFrom != null) queue.end(mixingFrom);
|
||||
continue;
|
||||
}
|
||||
|
||||
current.trackTime += currentDelta;
|
||||
if (mixingFrom != null) {
|
||||
if (current.mixTime >= current.mixDuration && current.mixTime > 0) {
|
||||
queue.end(mixingFrom);
|
||||
current.mixingFrom = null;
|
||||
queue.end(mixingFrom);
|
||||
animationsChanged = true;
|
||||
} else {
|
||||
mixingFrom.animationLast = mixingFrom.nextAnimationLast;
|
||||
@ -237,9 +237,12 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
public void clearTracks () {
|
||||
for (int i = 0, n = tracks.size; i < n; i++)
|
||||
clearTrack(i);
|
||||
for (int i = 0, n = tracks.size; i < n; i++) {
|
||||
TrackEntry current = tracks.get(i);
|
||||
if (current != null) clearTrack(current);
|
||||
}
|
||||
tracks.clear();
|
||||
queue.drain();
|
||||
}
|
||||
|
||||
// BOZO - This leaves the skeleton in the last pose, with no easy way of resetting.
|
||||
@ -247,22 +250,32 @@ public class AnimationState {
|
||||
if (trackIndex >= tracks.size) return;
|
||||
TrackEntry current = tracks.get(trackIndex);
|
||||
if (current == null) return;
|
||||
freeAll(current.next);
|
||||
|
||||
queue.end(current);
|
||||
if (current.mixingFrom != null) queue.end(current.mixingFrom);
|
||||
clearTrack(current);
|
||||
queue.drain();
|
||||
}
|
||||
|
||||
tracks.set(trackIndex, null);
|
||||
private void clearTrack (TrackEntry current) {
|
||||
queue.end(current);
|
||||
|
||||
disposeNext(current);
|
||||
|
||||
TrackEntry mixingFrom = current.mixingFrom;
|
||||
if (mixingFrom != null) {
|
||||
current.mixingFrom = null;
|
||||
queue.end(mixingFrom);
|
||||
}
|
||||
|
||||
tracks.set(current.trackIndex, null);
|
||||
}
|
||||
|
||||
/** @param entry May be null. */
|
||||
private void freeAll (TrackEntry entry) {
|
||||
while (entry != null) {
|
||||
TrackEntry next = entry.next;
|
||||
trackEntryPool.free(entry);
|
||||
entry = next;
|
||||
private void disposeNext (TrackEntry entry) {
|
||||
TrackEntry next = entry.next;
|
||||
while (next != null) {
|
||||
queue.dispose(next);
|
||||
next = next.next;
|
||||
}
|
||||
entry.next = null;
|
||||
}
|
||||
|
||||
private TrackEntry expandToIndex (int index) {
|
||||
@ -285,7 +298,7 @@ public class AnimationState {
|
||||
queue.interrupt(current);
|
||||
|
||||
// If a mix is in progress, mix from the closest animation.
|
||||
if (mixingFrom != null && current.mixTime / current.mixDuration < 0.5f) {
|
||||
if (mixingFrom != null && (current.mixDuration == 0 || current.mixTime / current.mixDuration < 0.5f)) {
|
||||
entry.mixingFrom = mixingFrom;
|
||||
mixingFrom = current;
|
||||
} else
|
||||
@ -347,28 +360,26 @@ public class AnimationState {
|
||||
return setAnimation(trackIndex, animation, loop);
|
||||
}
|
||||
|
||||
/** Sets the current animation for a track. If the track is empty, the new animation is made the current animation immediately.
|
||||
* Otherwise, any queued animations are discarded and the new animation is queued to become the current animation the next time
|
||||
* {@link #update(float)} is called.
|
||||
/** Sets the current animation for a track, discarding any queued animations.
|
||||
* @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||
* after {@link AnimationStateListener#end(TrackEntry)}. */
|
||||
public TrackEntry setAnimation (int trackIndex, Animation animation, boolean loop) {
|
||||
if (animation == null) throw new IllegalArgumentException("animation cannot be null.");
|
||||
TrackEntry current = expandToIndex(trackIndex);
|
||||
TrackEntry entry = trackEntry(trackIndex, animation, loop, current);
|
||||
if (current == null) {
|
||||
setCurrent(trackIndex, entry);
|
||||
queue.drain();
|
||||
} else {
|
||||
freeAll(current.next);
|
||||
if (current.nextTrackLast == -1) { // If current was never applied, replace it.
|
||||
setCurrent(trackIndex, entry);
|
||||
queue.drain();
|
||||
} else {
|
||||
current.next = entry;
|
||||
entry.delay = current.nextTrackLast;
|
||||
}
|
||||
if (current != null) {
|
||||
if (current.nextTrackLast == -1) {
|
||||
// Don't mix from an entry that was never applied.
|
||||
tracks.set(trackIndex, null);
|
||||
queue.interrupt(current);
|
||||
queue.end(current);
|
||||
disposeNext(current);
|
||||
current = null;
|
||||
} else
|
||||
disposeNext(current);
|
||||
}
|
||||
TrackEntry entry = trackEntry(trackIndex, animation, loop, current);
|
||||
setCurrent(trackIndex, entry);
|
||||
queue.drain();
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -696,11 +707,6 @@ public class AnimationState {
|
||||
return next;
|
||||
}
|
||||
|
||||
/** @param next May be null. */
|
||||
public void setNext (TrackEntry next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
/** Returns true if at least one loop has been completed. */
|
||||
public boolean isComplete () {
|
||||
return trackTime >= animationEnd - animationStart;
|
||||
@ -719,7 +725,7 @@ public class AnimationState {
|
||||
/** Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
|
||||
* {@link AnimationStateData} based on the animation before this animation (if any).
|
||||
* <p>
|
||||
* The mix duration must be set before this track entry becomes the current track entry. */
|
||||
* The mix duration must be set before the next time the animation state is updated. */
|
||||
public float getMixDuration () {
|
||||
return mixDuration;
|
||||
}
|
||||
@ -740,7 +746,7 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
static private class EventQueue {
|
||||
static private final int START = 0, EVENT = 1, COMPLETE = 2, INTERRUPT = 3, END = 4;
|
||||
static private final int START = 0, EVENT = 1, COMPLETE = 2, INTERRUPT = 3, END = 4, DISPOSE = 5;
|
||||
|
||||
private final Array<AnimationStateListener> listeners;
|
||||
private final Pool<TrackEntry> trackEntryPool;
|
||||
@ -779,6 +785,11 @@ public class AnimationState {
|
||||
eventTypes.add(END);
|
||||
}
|
||||
|
||||
public void dispose (TrackEntry entry) {
|
||||
objects.add(entry);
|
||||
eventTypes.add(DISPOSE);
|
||||
}
|
||||
|
||||
public void drain () {
|
||||
if (draining) return; // Not reentrant.
|
||||
draining = true;
|
||||
@ -810,6 +821,11 @@ public class AnimationState {
|
||||
if (entry.listener != null) entry.listener.end(entry);
|
||||
for (int i = 0; i < listeners.size; i++)
|
||||
listeners.get(i).end(entry);
|
||||
// Fall through.
|
||||
case DISPOSE:
|
||||
if (entry.listener != null) entry.listener.end(entry);
|
||||
for (int i = 0; i < listeners.size; i++)
|
||||
listeners.get(i).dispose(entry);
|
||||
trackEntryPool.free(entry);
|
||||
break;
|
||||
default:
|
||||
@ -830,31 +846,28 @@ public class AnimationState {
|
||||
}
|
||||
|
||||
static public interface AnimationStateListener {
|
||||
/** Invoked just after this animation is set as the current animation. */
|
||||
/** Invoked just after this entry is set as the current entry. */
|
||||
public void start (TrackEntry entry);
|
||||
|
||||
/** Invoked just after another animation is set as the current animation. The animation may continue being applied if there
|
||||
* is a mix duration. */
|
||||
/** Invoked just after another entry is set to replace this entry as the current entry. This entry may continue being
|
||||
* applied for mixing. */
|
||||
public void interrupt (TrackEntry entry);
|
||||
|
||||
/** Invoked when this animation will no longer be applied. After this method returns, no references to the track entry
|
||||
* should be kept because it may be reused. */
|
||||
/** Invoked just before this entry will no longer be the current entry and will never be applied again. */
|
||||
public void end (TrackEntry entry);
|
||||
|
||||
/** Invoked every time this animation completes a loop. */
|
||||
/** Invoked just before this track entry will be disposed. References to the entry should not be kept after dispose is
|
||||
* called, as it may be destroyed or reused. */
|
||||
public void dispose (TrackEntry entry);
|
||||
|
||||
/** Invoked every time this entry's animation completes a loop. */
|
||||
public void complete (TrackEntry entry);
|
||||
|
||||
/** Invoked when this animation triggers an event. */
|
||||
/** Invoked when this entry's animation triggers an event. */
|
||||
public void event (TrackEntry entry, Event event);
|
||||
}
|
||||
|
||||
static public abstract class AnimationStateAdapter implements AnimationStateListener {
|
||||
public void event (TrackEntry entry, Event event) {
|
||||
}
|
||||
|
||||
public void complete (TrackEntry entry) {
|
||||
}
|
||||
|
||||
public void start (TrackEntry entry) {
|
||||
}
|
||||
|
||||
@ -863,5 +876,14 @@ public class AnimationState {
|
||||
|
||||
public void end (TrackEntry entry) {
|
||||
}
|
||||
|
||||
public void dispose (TrackEntry entry) {
|
||||
}
|
||||
|
||||
public void event (TrackEntry entry, Event event) {
|
||||
}
|
||||
|
||||
public void complete (TrackEntry entry) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user