diff --git a/native/cocos/editor-support/spine-creator-support/SkeletonAnimation.cpp b/native/cocos/editor-support/spine-creator-support/SkeletonAnimation.cpp index da8da068ea8..f7da60aef7a 100644 --- a/native/cocos/editor-support/spine-creator-support/SkeletonAnimation.cpp +++ b/native/cocos/editor-support/spine-creator-support/SkeletonAnimation.cpp @@ -46,7 +46,15 @@ struct TrackEntryListeners { }; void animationCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) { - (static_cast(state->getRendererObject()))->cacheAnimationEvent(entry, type, event); + auto *skeletonAnimation = static_cast(state->getRendererObject()); + skeletonAnimation->cacheAnimationEvent(entry, type, event); + if (type == EventType::EventType_Dispose) { + /** + * In the official implementation of Spine's AnimationState class, the animationCallback is invoked after the trackEntryCallback. + * After the AnimationState completes the EventType_Dispose callback, the TrackEntry will be reclaimed, so this event must be dispatched immediately. + */ + skeletonAnimation->dispatchEvents(); + } } void trackEntryCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) { diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp index b988b50e84b..a5923cd8040 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp @@ -26,6 +26,14 @@ static void animationCallback(AnimationState *state, EventType type, TrackEntry info.eventType = type; info.event = event; instance->animationEvents.add(info); + + if (type == spine::EventType::EventType_Dispose) { + /** + * In the official implementation of Spine's AnimationState class, the animationCallback is invoked after the trackEntryCallback. + * After the AnimationState completes the EventType_Dispose callback, the TrackEntry will be reclaimed, so this event must be dispatched immediately. + */ + instance->dispatchEvents(); + } } } @@ -37,12 +45,6 @@ static void trackEntryCallback(AnimationState *state, EventType type, TrackEntry info.eventType = type; info.event = event; instance->trackEvents.add(info); - - if (type == EventType_Dispose) { - if (entry->getRendererObject()) { - entry->setRendererObject(nullptr); - } - } } } @@ -135,20 +137,7 @@ void SpineSkeletonInstance::updateAnimation(float dltTime) { _skeleton->update(dltTime); _animState->update(dltTime); _animState->apply(*_skeleton); - //Cache animation events then call back to JS. - auto vecAnimationEvents = animationEvents; - animationEvents.clear(); - //Cache track events then call back to JS. - auto vecTrackEvents = trackEvents; - trackEvents.clear(); - for (int i = 0; i < vecAnimationEvents.size(); i++) { - auto& info = vecAnimationEvents[i]; - onAnimationStateEvent(info.entry, info.eventType, info.event); - } - for (int i = 0; i < vecTrackEvents.size(); i++) { - auto& info = vecTrackEvents[i]; - onTrackEntryEvent(info.entry, info.eventType, info.event); - } + dispatchEvents(); } SpineModel *SpineSkeletonInstance::updateRenderData() { @@ -522,6 +511,7 @@ void SpineSkeletonInstance::onTrackEntryEvent(TrackEntry *entry, EventType type, SpineWasmUtil::s_currentEvent = event; spineTrackListenerCallback(); if (type == EventType_Dispose) { + entry->setRendererObject(nullptr); _trackListenerSet.remove(entry); } } @@ -678,4 +668,27 @@ void SpineSkeletonInstance::setSlotTexture(const spine::String &slotName, const attachmentVertices->_textureUUID = textureUuid; } } +} + +void SpineSkeletonInstance::dispatchEvents() { + spine::Vector vecAnimationEvents; + spine::Vector vecTrackEvents; + if (animationEvents.size() > 0) { + //Cache animation events then call back to JS. + vecAnimationEvents.addAll(animationEvents); + animationEvents.clear(); + } + if (trackEvents.size() > 0) { + //Cache track events then call back to JS. + vecTrackEvents.addAll(trackEvents); + trackEvents.clear(); + } + for (int i = 0; i < vecAnimationEvents.size(); i++) { + auto& info = vecAnimationEvents[i]; + onAnimationStateEvent(info.entry, info.eventType, info.event); + } + for (int i = 0; i < vecTrackEvents.size(); i++) { + auto& info = vecTrackEvents[i]; + onTrackEntryEvent(info.entry, info.eventType, info.event); + } } \ No newline at end of file diff --git a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h index b9182caf84a..05162722f36 100644 --- a/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h +++ b/native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h @@ -76,6 +76,8 @@ class SpineSkeletonInstance { // Used internal for cache event spine::Vector animationEvents; spine::Vector trackEvents; + // Used internal for dispatch event + void dispatchEvents(); private: void collectMeshData(); diff --git a/native/cocos/editor-support/spine/3.8/spine/Vector.h b/native/cocos/editor-support/spine/3.8/spine/Vector.h index 5782a7937bc..5f485d2260c 100644 --- a/native/cocos/editor-support/spine/3.8/spine/Vector.h +++ b/native/cocos/editor-support/spine/3.8/spine/Vector.h @@ -117,14 +117,14 @@ class SP_API Vector : public SpineObject { } } - void addAll(Vector &inValue) { + void addAll(const Vector &inValue) { ensureCapacity(this->size() + inValue.size()); for (size_t i = 0; i < inValue.size(); i++) { add(inValue[i]); } } - void clearAndAddAll(Vector &inValue) { + void clearAndAddAll(const Vector &inValue) { this->clear(); this->addAll(inValue); } @@ -199,6 +199,13 @@ class SP_API Vector : public SpineObject { return _buffer; } + Vector &operator=(const Vector &inVector) { + if (this != &inVector) { + clearAndAddAll(inVector); + } + return *this; + } + private: size_t _size; size_t _capacity; @@ -227,8 +234,6 @@ class SP_API Vector : public SpineObject { inline void destroy(T *buffer) { buffer->~T(); } - - // Vector &operator=(const Vector &inVector) {}; }; } // namespace spine diff --git a/native/cocos/editor-support/spine/4.2/spine/Vector.h b/native/cocos/editor-support/spine/4.2/spine/Vector.h index 41a246c13fb..ffa356bea2b 100644 --- a/native/cocos/editor-support/spine/4.2/spine/Vector.h +++ b/native/cocos/editor-support/spine/4.2/spine/Vector.h @@ -116,14 +116,14 @@ namespace spine { } } - inline void addAll(Vector &inValue) { + void addAll(const Vector &inValue) { ensureCapacity(this->size() + inValue.size()); for (size_t i = 0; i < inValue.size(); i++) { add(inValue[i]); } } - inline void clearAndAddAll(Vector &inValue) { + void clearAndAddAll(const Vector &inValue) { this->clear(); this->addAll(inValue); } @@ -194,6 +194,13 @@ namespace spine { return !(lhs == rhs); } + Vector &operator=(const Vector &inVector) { + if (this != &inVector) { + clearAndAddAll(inVector); + } + return *this; + } + inline T *buffer() { return _buffer; } @@ -226,8 +233,6 @@ namespace spine { inline void destroy(T *buffer) { buffer->~T(); } - - // Vector &operator=(const Vector &inVector) {}; }; } diff --git a/native/external-config.json b/native/external-config.json index 72d3e9f3142..1ea1afa19ea 100644 --- a/native/external-config.json +++ b/native/external-config.json @@ -3,6 +3,6 @@ "type": "github", "owner": "cocos", "name": "cocos-engine-external", - "checkout": "v3.8.7-7" + "checkout": "v3.8.7-9" } } \ No newline at end of file