From d85c3e99e79c652a706b7788993cb92eaa1f3ffc Mon Sep 17 00:00:00 2001 From: Collin Smith Date: Sun, 10 Mar 2019 15:17:51 -0700 Subject: [PATCH] Improved animation listener system Improved animation listener system Listeners now support passing desired frame (-1 for final frame) Listeners are lazily initialized --- core/src/com/riiablo/codec/Animation.java | 50 +++++++++++++------ .../com/riiablo/codec/excel/ItemEntry.java | 1 + core/src/com/riiablo/entity/ItemHolder.java | 6 +-- .../riiablo/screen/AudioUnpackerScreen.java | 4 +- .../riiablo/widget/CharacterCreateButton.java | 8 +-- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/core/src/com/riiablo/codec/Animation.java b/core/src/com/riiablo/codec/Animation.java index ec486586..19a670f4 100644 --- a/core/src/com/riiablo/codec/Animation.java +++ b/core/src/com/riiablo/codec/Animation.java @@ -10,15 +10,14 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.math.Affine2; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.scenes.scene2d.utils.BaseDrawable; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Bits; +import com.badlogic.gdx.utils.IntMap; import com.riiablo.Riiablo; import com.riiablo.codec.util.BBox; import com.riiablo.graphics.BlendMode; import com.riiablo.graphics.PaletteIndexedBatch; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; - public class Animation extends BaseDrawable { private static final String TAG = "Animation"; private static final int DEBUG_MODE = 1; // 0=off, 1=box, 2=layer box @@ -30,6 +29,8 @@ public class Animation extends BaseDrawable { private static final Color SHADOW_TINT = Riiablo.colors.modal75; private static final Affine2 SHADOW_TRANSFORM = new Affine2(); + private final IntMap> EMPTY_MAP = new IntMap<>(0); + private int numDirections; private int numFrames; private int direction; @@ -43,7 +44,7 @@ public class Animation extends BaseDrawable { private BBox box; private boolean highlighted; - private final Set ANIMATION_LISTENERS; + private IntMap> animationListeners; Animation() { this(0, 0, new Layer[NUM_LAYERS]); @@ -61,7 +62,7 @@ public class Animation extends BaseDrawable { frameDuration = FRAME_DURATION; box = new BBox(); - ANIMATION_LISTENERS = new CopyOnWriteArraySet<>(); + animationListeners = EMPTY_MAP; } public static Animation newAnimation(com.riiablo.codec.DC dc) { @@ -280,6 +281,7 @@ public class Animation extends BaseDrawable { public void act(float delta) { elapsedTime += delta; frame = getKeyFrameIndex(elapsedTime); + notifyListeners(frame); if (frame == numFrames - 1) notifyAnimationFinished(); } @@ -437,26 +439,44 @@ public class Animation extends BaseDrawable { } private void notifyAnimationFinished() { - for (AnimationListener l : ANIMATION_LISTENERS) { - l.onFinished(this); - } + if (animationListeners == EMPTY_MAP) return; + Array listeners = animationListeners.get(-1); + if (listeners == null) return; + for (AnimationListener l : listeners) l.onTrigger(this, -1); } - public boolean addAnimationListener(AnimationListener l) { + private void notifyListeners(int frame) { + if (animationListeners == EMPTY_MAP) return; + Array listeners = animationListeners.get(frame); + if (listeners == null) return; + for (AnimationListener l : listeners) l.onTrigger(this, frame); + } + + public boolean addAnimationListener(int frame, AnimationListener l) { Preconditions.checkArgument(l != null, "l cannot be null"); - return ANIMATION_LISTENERS.add(l); + if (animationListeners == EMPTY_MAP) animationListeners = new IntMap<>(1); + Array listeners = animationListeners.get(frame); + if (listeners == null) animationListeners.put(frame, listeners = new Array<>(1)); + listeners.add(l); + return true; } - public boolean removeAnimationListener(Object o) { - return o != null && ANIMATION_LISTENERS.remove(o); + public boolean removeAnimationListener(int frame, AnimationListener l) { + if (l == null || animationListeners == EMPTY_MAP) return false; + Array listeners = animationListeners.get(frame); + if (listeners == null) return false; + return listeners.removeValue(l, true); } - public boolean containsAnimationListener(Object o) { - return o != null && ANIMATION_LISTENERS.contains(o); + public boolean containsAnimationListener(int frame, AnimationListener l) { + if (l == null || animationListeners == EMPTY_MAP) return false; + Array listeners = animationListeners.get(frame); + if (listeners == null) return false; + return listeners.contains(l, true); } public interface AnimationListener { - void onFinished(Animation animation); + void onTrigger(Animation animation, int frame); } public static class Layer { diff --git a/core/src/com/riiablo/codec/excel/ItemEntry.java b/core/src/com/riiablo/codec/excel/ItemEntry.java index cbeda929..8ebbdd1f 100644 --- a/core/src/com/riiablo/codec/excel/ItemEntry.java +++ b/core/src/com/riiablo/codec/excel/ItemEntry.java @@ -26,6 +26,7 @@ public class ItemEntry extends Excel.Entry { @Column public int invwidth; @Column public int invheight; @Column public String dropsound; + @Column public int dropsfxframe; @Column public boolean stackable; @Column public boolean useable; @Column public String usesound; diff --git a/core/src/com/riiablo/entity/ItemHolder.java b/core/src/com/riiablo/entity/ItemHolder.java index 8fe3858f..4d598f9c 100644 --- a/core/src/com/riiablo/entity/ItemHolder.java +++ b/core/src/com/riiablo/entity/ItemHolder.java @@ -44,11 +44,11 @@ public class ItemHolder extends Entity { .build(); animation.setLooping(false); animation.updateBox(); - animation.addAnimationListener(new Animation.AnimationListener() { + animation.addAnimationListener(item.base.dropsfxframe, new Animation.AnimationListener() { @Override - public void onFinished(Animation animation) { + public void onTrigger(Animation animation, int frame) { Riiablo.audio.play(item.base.dropsound, true); - animation.removeAnimationListener(this); + animation.removeAnimationListener(frame, this); } }); diff --git a/core/src/com/riiablo/screen/AudioUnpackerScreen.java b/core/src/com/riiablo/screen/AudioUnpackerScreen.java index a1ab8acc..7ff70f60 100644 --- a/core/src/com/riiablo/screen/AudioUnpackerScreen.java +++ b/core/src/com/riiablo/screen/AudioUnpackerScreen.java @@ -59,9 +59,9 @@ public class AudioUnpackerScreen extends ScreenAdapter { Riiablo.assets.finishLoadingAsset(DownloadPatchBall2Descriptor); Animation DownloadPatchBall2 = Animation.newAnimation(Riiablo.assets.get(DownloadPatchBall2Descriptor)); DownloadPatchBall2.setFrameDuration(Float.MAX_VALUE); - DownloadPatchBall2.addAnimationListener(new Animation.AnimationListener() { + DownloadPatchBall2.addAnimationListener(-1, new Animation.AnimationListener() { @Override - public void onFinished(Animation animation) { + public void onTrigger(Animation animation, int frame) { Riiablo.client.setScreen(new SplashScreen()); } }); diff --git a/core/src/com/riiablo/widget/CharacterCreateButton.java b/core/src/com/riiablo/widget/CharacterCreateButton.java index 1d4911ac..6b1b8e6d 100644 --- a/core/src/com/riiablo/widget/CharacterCreateButton.java +++ b/core/src/com/riiablo/widget/CharacterCreateButton.java @@ -196,9 +196,9 @@ public class CharacterCreateButton extends Widget implements Disposable { } fw = builder.build(); fw.setLooping(false); - fw.addAnimationListener(new Animation.AnimationListener() { + fw.addAnimationListener(-1, new Animation.AnimationListener() { @Override - public void onFinished(Animation fw) { + public void onTrigger(Animation fw, int frame) { state = State.NU3; if (nu3 == null) { Riiablo.assets.finishLoadingAsset(nu3Desc); @@ -236,9 +236,9 @@ public class CharacterCreateButton extends Widget implements Disposable { } bw = builder.build(); bw.setLooping(false); - bw.addAnimationListener(new Animation.AnimationListener() { + bw.addAnimationListener(-1, new Animation.AnimationListener() { @Override - public void onFinished(Animation bw) { + public void onTrigger(Animation bw, int frame) { state = State.NU1; if (clickListener.isOver()) { assert nu2 != null;