Browse Source

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

See #1462.
NathanSweet 6 years ago
parent
commit
4812bac88d

+ 19 - 3
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java

@@ -37,6 +37,7 @@ import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.math.MathUtils;
 import com.badlogic.gdx.utils.Array;
 import com.badlogic.gdx.utils.FloatArray;
+import com.badlogic.gdx.utils.IntSet;
 
 import com.esotericsoftware.spine.attachments.Attachment;
 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. */
 public class Animation {
 	final String name;
-	final Array<Timeline> timelines;
+	Array<Timeline> timelines;
+	final IntSet timelineIDs = new IntSet();
 	float duration;
 
 	public Animation (String name, Array<Timeline> timelines, float duration) {
 		if (name == null) throw new IllegalArgumentException("name cannot be null.");
-		if (timelines == null) throw new IllegalArgumentException("timelines cannot be null.");
 		this.name = name;
-		this.timelines = timelines;
 		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 () {
 		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. */
 	public float getDuration () {
 		return duration;

+ 3 - 9
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java

@@ -37,6 +37,7 @@ import com.badlogic.gdx.utils.IntArray;
 import com.badlogic.gdx.utils.IntSet;
 import com.badlogic.gdx.utils.Pool;
 import com.badlogic.gdx.utils.Pool.Poolable;
+
 import com.esotericsoftware.spine.Animation.AttachmentTimeline;
 import com.esotericsoftware.spine.Animation.DrawOrderTimeline;
 import com.esotericsoftware.spine.Animation.EventTimeline;
@@ -745,11 +746,11 @@ public class AnimationState {
 			if (!propertyIDs.add(id))
 				timelineMode[i] = SUBSEQUENT;
 			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;
 			} else {
 				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) {
 						timelineMode[i] = HOLD_MIX;
 						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. */
 	public TrackEntry getCurrent (int trackIndex) {
 		if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0.");