package org.andengine.util.modifier; import java.util.Arrays; import org.andengine.util.modifier.IModifier.IModifierListener; /** * (c) 2010 Nicolas Gramlich * (c) 2011 Zynga Inc. * * @author Nicolas Gramlich * @since 11:21:22 - 03.09.2010 * @param <T> */ public class ParallelModifier<T> extends BaseModifier<T> implements IModifierListener<T> { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== private float mSecondsElapsed; private final float mDuration; private final IModifier<T>[] mModifiers; private boolean mFinishedCached; // =========================================================== // Constructors // =========================================================== public ParallelModifier(final IModifier<T> ... pModifiers) throws IllegalArgumentException { this(null, pModifiers); } public ParallelModifier(final IModifierListener<T> pModifierListener, final IModifier<T> ... pModifiers) throws IllegalArgumentException { super(pModifierListener); if(pModifiers.length == 0) { throw new IllegalArgumentException("pModifiers must not be empty!"); } BaseModifier.assertNoNullModifier(pModifiers); Arrays.sort(pModifiers, MODIFIER_COMPARATOR_DURATION_DESCENDING); this.mModifiers = pModifiers; final IModifier<T> modifierWithLongestDuration = pModifiers[0]; this.mDuration = modifierWithLongestDuration.getDuration(); modifierWithLongestDuration.addModifierListener(this); } @SuppressWarnings("unchecked") protected ParallelModifier(final ParallelModifier<T> pParallelModifier) throws DeepCopyNotSupportedException { final IModifier<T>[] otherModifiers = pParallelModifier.mModifiers; this.mModifiers = new IModifier[otherModifiers.length]; final IModifier<T>[] modifiers = this.mModifiers; for(int i = modifiers.length - 1; i >= 0; i--) { modifiers[i] = otherModifiers[i].deepCopy(); } final IModifier<T> modifierWithLongestDuration = modifiers[0]; this.mDuration = modifierWithLongestDuration.getDuration(); modifierWithLongestDuration.addModifierListener(this); } @Override public ParallelModifier<T> deepCopy() throws DeepCopyNotSupportedException{ return new ParallelModifier<T>(this); } // =========================================================== // Getter & Setter // =========================================================== // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== @Override public float getSecondsElapsed() { return this.mSecondsElapsed; } @Override public float getDuration() { return this.mDuration; } @Override public float onUpdate(final float pSecondsElapsed, final T pItem) { if(this.mFinished){ return 0; } else { float secondsElapsedRemaining = pSecondsElapsed; final IModifier<T>[] shapeModifiers = this.mModifiers; this.mFinishedCached = false; while(secondsElapsedRemaining > 0 && !this.mFinishedCached) { float secondsElapsedUsed = 0; for(int i = shapeModifiers.length - 1; i >= 0; i--) { secondsElapsedUsed = Math.max(secondsElapsedUsed, shapeModifiers[i].onUpdate(pSecondsElapsed, pItem)); } secondsElapsedRemaining -= secondsElapsedUsed; } this.mFinishedCached = false; final float secondsElapsedUsed = pSecondsElapsed - secondsElapsedRemaining; this.mSecondsElapsed += secondsElapsedUsed; return secondsElapsedUsed; } } @Override public void reset() { this.mFinished = false; this.mSecondsElapsed = 0; final IModifier<T>[] shapeModifiers = this.mModifiers; for(int i = shapeModifiers.length - 1; i >= 0; i--) { shapeModifiers[i].reset(); } } @Override public void onModifierStarted(final IModifier<T> pModifier, final T pItem) { this.onModifierStarted(pItem); } @Override public void onModifierFinished(final IModifier<T> pModifier, final T pItem) { this.mFinished = true; this.mFinishedCached = true; this.onModifierFinished(pItem); } // =========================================================== // Methods // =========================================================== // =========================================================== // Inner and Anonymous Classes // =========================================================== }