pixijs / spine

Pixi.js plugin that enables Spine support.
Other
568 stars 217 forks source link

Spine destroy issue #316

Open ayangupta01 opened 5 years ago

ayangupta01 commented 5 years ago

Hi,

I have a requirement of using different spine for a view object. so everytime I create a new spine and then destroy and intend to create another spine with the same variable name. This throws error when I destroy the first one and try to create a new one.

Container.js:416 Uncaught TypeError: Cannot read property 'updateTransform' of null

My code is pretty simple. Here is a sample :

destroySymbol () { if (this.symbol) { TweenMax.killTweensOf(this.symbol); TweenMax.killTweensOf(this); this.removeChild(this.symbol); this.symbol.destroy(); this.symbol = null; } }

showAppearing(config, targetrow) { this.destroySymbol(); this.configData = config; this.rowNo = targetrow; this.currentRow = 0; this.symbol = UIUtil.getSpine(this.configData.spineName); this.symbol.on("onAnimComplete", this.onSpineAnimComplete.bind(this));

First time it creates fine but when the showAppearing is called second time and I call destroySymbol it throws the error even before creating the new spine.

Any help would be really appreciated.

ivanpopelyshev commented 5 years ago

Welcome to i dont know where spine is updated show!

Please open the devTools and screenshot the stracktrace where that error is happening.

Something is updating spine instance when its already later For example, you destroy it inside event and update is keep going.

Its general problem with all animated elements, in pixi and in other renderers/frameworks. You have to deal with it through debugging.

People added several IF's in pixi-spine to prevent that problem, but its not possible to solve it completely, it depends on case.

ayangupta01 commented 5 years ago

image

Here it is.

ivanpopelyshev commented 5 years ago

ok , two things: either you destroyed it from the same method (autoUpdateTransform) , either somehow that spine was added somewhere after death. Need more debugging.

As I said, its general error that many people stumble across, and it depends on your case.

ayangupta01 commented 5 years ago

thanks for your hint. I called the method with a settimeout of 0 and it worked fine.

ivanpopelyshev commented 5 years ago

Yeah, that's usually help , but its better if you track where to put extra "if" to stop update .

Look, we already had one such change: https://github.com/pixijs/pixi-spine/pull/273

ralficzek commented 1 year ago

Actually I just ran into the same issue and after reviewing the code I believe the SpineBase implementation could be improved to solve this. The current code calls local update method that in turn fires spine related events from state and then tries to call Container.updateTransform making it impossible to call destroy of that particular Spine instance on any spine event listener. Isn't that quite common scenario: listen for an event -> destroy the instance?

image

One simple option would be to wrap Container.updateTransform in an if like that:

autoUpdateTransform() {
        if (settings.GLOBAL_AUTO_UPDATE) {
            this.lastTime = this.lastTime || Date.now();
            const timeDelta = (Date.now() - this.lastTime) * 0.001;

            this.lastTime = Date.now();
            this.update(timeDelta);
        } else {
            this.lastTime = 0;
        }

        if (!this._destroyed) {
            Container.prototype.updateTransform.call(this);
        }
    }

Otherwise we have 2 options: