cocos / cocos-engine

Cocos simplifies game creation and distribution with Cocos Creator, a free, open-source, cross-platform game engine. Empowering millions of developers to create high-performance, engaging 2D/3D games and instant web entertainment.
https://www.cocos.com/en/creator
Other
8.25k stars 1.94k forks source link

[spine相关].SkeletonData资源的reset()方法需要添加对wasm的处理 #17430

Open finscn opened 3 months ago

finscn commented 3 months ago

Use Case

目前的 reset方法只是清空了 js端的 cache

    public reset (): void {
        this._skeletonCache = null;
        if (EDITOR_NOT_IN_PREVIEW) {
            this._skinsEnum = null;
            this._animsEnum = null;
        }
    }

但是执行此操作后, getRuntimeData 仍然会使用wasm中的缓存.


   public getRuntimeData (quiet?: boolean): spine.SkeletonData | null {
        if (this._skeletonCache) {
            return this._skeletonCache;
        }

        if (!(this.textures && this.textures.length > 0) && this.textureNames && this.textureNames.length > 0) {
            if (!quiet) {
                error(`${this.name} no textures found!`);
            }
            return null;
        }
        //
        //
        // 重点看这里
        const spData = spine.wasmUtil.querySpineSkeletonDataByUUID(this._uuid);
        if (spData) {
            this._skeletonCache = spData;

        //
        //

        } else if (this.skeletonJsonStr) {
            // ......
        } else {
           // ......
        }

        return this._skeletonCache;
    }

因为const spData = spine.wasmUtil.querySpineSkeletonDataByUUID(this._uuid);的存在, 导致 我reset后 使用的仍然是老数据.

所以 reset 里 应该调用 spine.wasmUtil.destroySpineSkeletonDataWithUUID()

Problem Description

.

Proposed Solution

No response

How it works

No response

Alternatives Considered

.

Additional Information

No response

finscn commented 3 months ago

我测试了一下, 直接 加上 destroySpineSkeletonDataWithUUID , 一开始 符合我的预期. 但是后续调用某些api时, 会出现 wasm端的错误.

跟踪了下, 有时候执行 this._instance!.initSkeleton(skeletonData)时会出错, 大意是 function 的 signal无效.

有时候执行 this._skeleton.setSkinByName(name)会报错, 内存越界 'Uncaught RuntimeError: memory access out of bounds',.

不知道是不是 wasm端有些调用还是使用了之前的数据或者内存地址, 但是内容已经被销毁导致的.

有点难办了