[libgdx] Store timeline ids inside set in Animation for O(1) lookup, added Animation#setTimelines.

See #1462.
This commit is contained in:
NathanSweet 2019-10-17 17:45:01 +02:00
parent 691c795fa0
commit 4812bac88d
2 changed files with 22 additions and 12 deletions

View File

@ -37,6 +37,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.FloatArray;
import com.badlogic.gdx.utils.IntSet;
import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.Attachment;
import com.esotericsoftware.spine.attachments.VertexAttachment; import com.esotericsoftware.spine.attachments.VertexAttachment;
@ -44,21 +45,36 @@ import com.esotericsoftware.spine.attachments.VertexAttachment;
/** A simple container for a list of timelines and a name. */ /** A simple container for a list of timelines and a name. */
public class Animation { public class Animation {
final String name; final String name;
final Array<Timeline> timelines; Array<Timeline> timelines;
final IntSet timelineIDs = new IntSet();
float duration; float duration;
public Animation (String name, Array<Timeline> timelines, float duration) { public Animation (String name, Array<Timeline> timelines, float duration) {
if (name == null) throw new IllegalArgumentException("name cannot be null."); if (name == null) throw new IllegalArgumentException("name cannot be null.");
if (timelines == null) throw new IllegalArgumentException("timelines cannot be null.");
this.name = name; this.name = name;
this.timelines = timelines;
this.duration = duration; this.duration = duration;
setTimelines(timelines);
} }
/** If the returned array or the timelines it contains are modified, {@link #setTimelines(Array)} must be called. */
public Array<Timeline> getTimelines () { public Array<Timeline> getTimelines () {
return timelines; return timelines;
} }
public void setTimelines (Array<Timeline> timelines) {
if (timelines == null) throw new IllegalArgumentException("timelines cannot be null.");
this.timelines = timelines;
timelineIDs.clear();
for (Timeline timeline : timelines)
timelineIDs.add(timeline.getPropertyId());
}
/** Return true if this animation contains a timeline with the specified property ID. **/
public boolean hasTimeline (int id) {
return timelineIDs.contains(id);
}
/** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */ /** The duration of the animation in seconds, which is the highest time of all keys in the timeline. */
public float getDuration () { public float getDuration () {
return duration; return duration;

View File

@ -37,6 +37,7 @@ import com.badlogic.gdx.utils.IntArray;
import com.badlogic.gdx.utils.IntSet; import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.Pool; import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.Pool.Poolable; import com.badlogic.gdx.utils.Pool.Poolable;
import com.esotericsoftware.spine.Animation.AttachmentTimeline; import com.esotericsoftware.spine.Animation.AttachmentTimeline;
import com.esotericsoftware.spine.Animation.DrawOrderTimeline; import com.esotericsoftware.spine.Animation.DrawOrderTimeline;
import com.esotericsoftware.spine.Animation.EventTimeline; import com.esotericsoftware.spine.Animation.EventTimeline;
@ -745,11 +746,11 @@ public class AnimationState {
if (!propertyIDs.add(id)) if (!propertyIDs.add(id))
timelineMode[i] = SUBSEQUENT; timelineMode[i] = SUBSEQUENT;
else if (to == null || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline else if (to == null || timeline instanceof AttachmentTimeline || timeline instanceof DrawOrderTimeline
|| timeline instanceof EventTimeline || !hasTimeline(to, id)) { || timeline instanceof EventTimeline || !to.animation.hasTimeline(id)) {
timelineMode[i] = FIRST; timelineMode[i] = FIRST;
} else { } else {
for (TrackEntry next = to.mixingTo; next != null; next = next.mixingTo) { for (TrackEntry next = to.mixingTo; next != null; next = next.mixingTo) {
if (hasTimeline(next, id)) continue; if (next.animation.hasTimeline(id)) continue;
if (next.mixDuration > 0) { if (next.mixDuration > 0) {
timelineMode[i] = HOLD_MIX; timelineMode[i] = HOLD_MIX;
timelineHoldMix[i] = next; timelineHoldMix[i] = next;
@ -776,13 +777,6 @@ public class AnimationState {
} }
} }
private boolean hasTimeline (TrackEntry entry, int id) {
Object[] timelines = entry.animation.timelines.items;
for (int i = 0, n = entry.animation.timelines.size; i < n; i++)
if (((Timeline)timelines[i]).getPropertyId() == id) return true;
return false;
}
/** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */
public TrackEntry getCurrent (int trackIndex) { public TrackEntry getCurrent (int trackIndex) {
if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0."); if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0.");