Runtimes for AS-3 have the bug for any Spine animation:
skeleton = new SkeletonAnimation(skeletonData, stateData);
addChild(skeleton);
skeleton.state.onComplete.add(function (entry:TrackEntry) : void {
trace("onComplete DISPATCHED EVEN AFTER removeChild(skeleton)");
});
skeleton.state.onEvent.add(function (entry:TrackEntry, event:Event) : void {
trace("onEvent DISPATCHED EVEN AFTER removeChild(skeleton)");
});
...
removeChild(skeleton);
ALL events continue dispatch after animation removal.
Garbage collector DONT remove animation instance, and FPS become lower.
Reason :
After removeChild of SkeletonSprite instance enterFrame method of removed instance continue called by system, because we need to call removeEventListener(Event.ENTER_FRAME, enterFrame) manually.
FIX :
public class SkeletonSprite extends Sprite {
static private var blendModes:Vector.<String> = new <String>[
BlendMode.NORMAL, BlendMode.ADD, BlendMode.MULTIPLY, BlendMode.SCREEN];
private var _skeleton:Skeleton;
public var timeScale:Number = 1;
private var lastTime:int;
private var wrappers:Dictionary = new Dictionary(true);
public function SkeletonSprite (skeletonData:SkeletonData) {
Bone.yDown = true;
_skeleton = new Skeleton(skeletonData);
_skeleton.updateWorldTransform();
// Move subscription to onAdd
// addEventListener(Event.ENTER_FRAME, enterFrame);
addEventListener(Event.ADDED_TO_STAGE, onAdd);
addEventListener(Event.REMOVED_FROM_STAGE, onRemove);
}
// protected to allow override in SkeletonAnimation
protected function onRemove(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, enterFrame);
}
// can be usefull
public function clearListeners(){
removeEventListener(Event.ADDED_TO_STAGE, onAdd);
removeEventListener(Event.REMOVED_FROM_STAGE, onRemove);
}
protected function onAdd(event:Event):void
{
// FIX from my previous post : http://ru.esotericsoftware.com/forum/Runtimes-spine-starling-spine-AS3-major-bug-not-crash-8038
lastTime = getTimer();
enterFrame(null);
addEventListener(Event.ENTER_FRAME, enterFrame);
}
Also we can clean state callbaks :
public class SkeletonAnimation extends SkeletonSprite {
public var state:AnimationState;
public function SkeletonAnimation (skeletonData:SkeletonData, stateData:AnimationStateData = null) {
super(skeletonData);
state = new AnimationState(stateData ? stateData : new AnimationStateData(skeletonData));
}
// This allow to clear callbacks after removeChild(skeleton)
override protected function onRemove(e:Event):void{
state.clearListeners();
state.clearListenerNotifications();
super.onRemove(e);
}
Best regards,
Michael
spb.mihail.gor@ gmail.com