package aurelienribon.tweenengine;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A TweenManager updates all your tweens and timelines at once.
* Its main interest is that it handles the tween/timeline life-cycles for you,
* as well as the pooling constraints (if object pooling is enabled).
* <p/>
*
* Just give it a bunch of tweens or timelines and call update() periodically,
* you don't need to care for anything else! Relax and enjoy your animations.
*
* @see Tween
* @see Timeline
* @author Aurelien Ribon | http://www.aurelienribon.com/
*/
public class TweenManager {
// -------------------------------------------------------------------------
// Static API
// -------------------------------------------------------------------------
/**
* Disables or enables the "auto remove" mode of any tween manager for a
* particular tween or timeline. This mode is activated by default. The
* interest of desactivating it is to prevent some tweens or timelines from
* being automatically removed from a manager once they are finished.
* Therefore, if you update a manager backwards, the tweens or timelines
* will be played again, even if they were finished.
*/
public static void setAutoRemove(BaseTween<?> object, boolean value) {
object.isAutoRemoveEnabled = value;
}
/**
* Disables or enables the "auto start" mode of any tween manager for a
* particular tween or timeline. This mode is activated by default. If it
* is not enabled, add a tween or timeline to any manager won't start it
* automatically, and you'll need to call .start() manually on your object.
*/
public static void setAutoStart(BaseTween<?> object, boolean value) {
object.isAutoStartEnabled = value;
}
// -------------------------------------------------------------------------
// Public API
// -------------------------------------------------------------------------
private final ArrayList<BaseTween<?>> objects = new ArrayList<BaseTween<?>>(20);
private boolean isPaused = false;
/**
* Adds a tween or timeline to the manager and starts or restarts it.
*
* @return The manager, for instruction chaining.
*/
public TweenManager add(BaseTween<?> object) {
if (!objects.contains(object)) objects.add(object);
if (object.isAutoStartEnabled) object.start();
return this;
}
/**
* Returns true if the manager contains any valid interpolation associated
* to the given target object.
*/
public boolean containsTarget(Object target) {
for (int i=0, n=objects.size(); i<n; i++) {
BaseTween<?> obj = objects.get(i);
if (obj.containsTarget(target)) return true;
}
return false;
}
/**
* Returns true if the manager contains any valid interpolation associated
* to the given target object and to the given tween type.
*/
public boolean containsTarget(Object target, int tweenType) {
for (int i=0, n=objects.size(); i<n; i++) {
BaseTween<?> obj = objects.get(i);
if (obj.containsTarget(target, tweenType)) return true;
}
return false;
}
/**
* Kills every managed tweens and timelines.
*/
public void killAll() {
for (int i=0, n=objects.size(); i<n; i++) {
BaseTween<?> obj = objects.get(i);
obj.kill();
}
}
/**
* Kills every tweens associated to the given target. Will also kill every
* timelines containing a tween associated to the given target.
*/
public void killTarget(Object target) {
for (int i=0, n=objects.size(); i<n; i++) {
BaseTween<?> obj = objects.get(i);
obj.killTarget(target);
}
}
/**
* Kills every tweens associated to the given target and tween type. Will
* also kill every timelines containing a tween associated to the given
* target and tween type.
*/
public void killTarget(Object target, int tweenType) {
for (int i=0, n=objects.size(); i<n; i++) {
BaseTween<?> obj = objects.get(i);
obj.killTarget(target, tweenType);
}
}
/**
* Increases the minimum capacity of the manager. Defaults to 20.
*/
public void ensureCapacity(int minCapacity) {
objects.ensureCapacity(minCapacity);
}
/**
* Pauses the manager. Further update calls won't have any effect.
*/
public void pause() {
isPaused = true;
}
/**
* Resumes the manager, if paused.
*/
public void resume() {
isPaused = false;
}
/**
* Updates every tweens with a delta time ang handles the tween life-cycles
* automatically. If a tween is finished, it will be removed from the
* manager. The delta time represents the elapsed time between now and the
* last update call. Each tween or timeline manages its local time, and adds
* this delta to its local time to update itself.
* <p/>
*
* Slow motion, fast motion and backward play can be easily achieved by
* tweaking this delta time. Multiply it by -1 to play the animation
* backward, or by 0.5 to play it twice slower than its normal speed.
*/
public void update(float delta) {
for (int i=objects.size()-1; i>=0; i--) {
BaseTween<?> obj = objects.get(i);
if (obj.isFinished() && obj.isAutoRemoveEnabled) {
objects.remove(i);
obj.free();
}
}
if (!isPaused) {
if (delta >= 0) {
for (int i=0, n=objects.size(); i<n; i++) objects.get(i).update(delta);
} else {
for (int i=objects.size()-1; i>=0; i--) objects.get(i).update(delta);
}
}
}
/**
* Gets the number of managed objects. An object may be a tween or a
* timeline. Note that a timeline only counts for 1 object, since it
* manages its children itself.
* <p/>
* To get the count of running tweens, see {@link #getRunningTweensCount()}.
*/
public int size() {
return objects.size();
}
/**
* Gets the number of running tweens. This number includes the tweens
* located inside timelines (and nested timelines).
* <p/>
* <b>Provided for debug purpose only.</b>
*/
public int getRunningTweensCount() {
return getTweensCount(objects);
}
/**
* Gets the number of running timelines. This number includes the timelines
* nested inside other timelines.
* <p/>
* <b>Provided for debug purpose only.</b>
*/
public int getRunningTimelinesCount() {
return getTimelinesCount(objects);
}
/**
* Gets an immutable list of every managed object.
* <p/>
* <b>Provided for debug purpose only.</b>
*/
public List<BaseTween<?>> getObjects() {
return Collections.unmodifiableList(objects);
}
// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------
private static int getTweensCount(List<BaseTween<?>> objs) {
int cnt = 0;
for (int i=0, n=objs.size(); i<n; i++) {
BaseTween<?> obj = objs.get(i);
if (obj instanceof Tween) cnt += 1;
else cnt += getTweensCount(((Timeline)obj).getChildren());
}
return cnt;
}
private static int getTimelinesCount(List<BaseTween<?>> objs) {
int cnt = 0;
for (int i=0, n=objs.size(); i<n; i++) {
BaseTween<?> obj = objs.get(i);
if (obj instanceof Timeline) {
cnt += 1 + getTimelinesCount(((Timeline)obj).getChildren());
}
}
return cnt;
}
}