Skip to content

Commit 7ead7e4

Browse files
authored
Fix spine callback issues (#18672)
* Fix spine issues: 1. Callbacks set via setTrackEndListener are not triggered. 2. The setEndListener callback interface cannot retrieve the animation name through the trackEntry parameter.
1 parent efd2ec5 commit 7ead7e4

File tree

6 files changed

+63
-30
lines changed

6 files changed

+63
-30
lines changed

native/cocos/editor-support/spine-creator-support/SkeletonAnimation.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,15 @@ struct TrackEntryListeners {
4646
};
4747

4848
void animationCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
49-
(static_cast<SkeletonAnimation *>(state->getRendererObject()))->cacheAnimationEvent(entry, type, event);
49+
auto *skeletonAnimation = static_cast<SkeletonAnimation *>(state->getRendererObject());
50+
skeletonAnimation->cacheAnimationEvent(entry, type, event);
51+
if (type == EventType::EventType_Dispose) {
52+
/**
53+
* In the official implementation of Spine's AnimationState class, the animationCallback is invoked after the trackEntryCallback.
54+
* After the AnimationState completes the EventType_Dispose callback, the TrackEntry will be reclaimed, so this event must be dispatched immediately.
55+
*/
56+
skeletonAnimation->dispatchEvents();
57+
}
5058
}
5159

5260
void trackEntryCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {

native/cocos/editor-support/spine-wasm/spine-skeleton-instance.cpp

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ static void animationCallback(AnimationState *state, EventType type, TrackEntry
2626
info.eventType = type;
2727
info.event = event;
2828
instance->animationEvents.add(info);
29+
30+
if (type == spine::EventType::EventType_Dispose) {
31+
/**
32+
* In the official implementation of Spine's AnimationState class, the animationCallback is invoked after the trackEntryCallback.
33+
* After the AnimationState completes the EventType_Dispose callback, the TrackEntry will be reclaimed, so this event must be dispatched immediately.
34+
*/
35+
instance->dispatchEvents();
36+
}
2937
}
3038
}
3139

@@ -37,12 +45,6 @@ static void trackEntryCallback(AnimationState *state, EventType type, TrackEntry
3745
info.eventType = type;
3846
info.event = event;
3947
instance->trackEvents.add(info);
40-
41-
if (type == EventType_Dispose) {
42-
if (entry->getRendererObject()) {
43-
entry->setRendererObject(nullptr);
44-
}
45-
}
4648
}
4749
}
4850

@@ -135,20 +137,7 @@ void SpineSkeletonInstance::updateAnimation(float dltTime) {
135137
_skeleton->update(dltTime);
136138
_animState->update(dltTime);
137139
_animState->apply(*_skeleton);
138-
//Cache animation events then call back to JS.
139-
auto vecAnimationEvents = animationEvents;
140-
animationEvents.clear();
141-
//Cache track events then call back to JS.
142-
auto vecTrackEvents = trackEvents;
143-
trackEvents.clear();
144-
for (int i = 0; i < vecAnimationEvents.size(); i++) {
145-
auto& info = vecAnimationEvents[i];
146-
onAnimationStateEvent(info.entry, info.eventType, info.event);
147-
}
148-
for (int i = 0; i < vecTrackEvents.size(); i++) {
149-
auto& info = vecTrackEvents[i];
150-
onTrackEntryEvent(info.entry, info.eventType, info.event);
151-
}
140+
dispatchEvents();
152141
}
153142

154143
SpineModel *SpineSkeletonInstance::updateRenderData() {
@@ -522,6 +511,7 @@ void SpineSkeletonInstance::onTrackEntryEvent(TrackEntry *entry, EventType type,
522511
SpineWasmUtil::s_currentEvent = event;
523512
spineTrackListenerCallback();
524513
if (type == EventType_Dispose) {
514+
entry->setRendererObject(nullptr);
525515
_trackListenerSet.remove(entry);
526516
}
527517
}
@@ -678,4 +668,27 @@ void SpineSkeletonInstance::setSlotTexture(const spine::String &slotName, const
678668
attachmentVertices->_textureUUID = textureUuid;
679669
}
680670
}
671+
}
672+
673+
void SpineSkeletonInstance::dispatchEvents() {
674+
spine::Vector<SpineEventInfo> vecAnimationEvents;
675+
spine::Vector<SpineEventInfo> vecTrackEvents;
676+
if (animationEvents.size() > 0) {
677+
//Cache animation events then call back to JS.
678+
vecAnimationEvents.addAll(animationEvents);
679+
animationEvents.clear();
680+
}
681+
if (trackEvents.size() > 0) {
682+
//Cache track events then call back to JS.
683+
vecTrackEvents.addAll(trackEvents);
684+
trackEvents.clear();
685+
}
686+
for (int i = 0; i < vecAnimationEvents.size(); i++) {
687+
auto& info = vecAnimationEvents[i];
688+
onAnimationStateEvent(info.entry, info.eventType, info.event);
689+
}
690+
for (int i = 0; i < vecTrackEvents.size(); i++) {
691+
auto& info = vecTrackEvents[i];
692+
onTrackEntryEvent(info.entry, info.eventType, info.event);
693+
}
681694
}

native/cocos/editor-support/spine-wasm/spine-skeleton-instance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class SpineSkeletonInstance {
7676
// Used internal for cache event
7777
spine::Vector<SpineEventInfo> animationEvents;
7878
spine::Vector<SpineEventInfo> trackEvents;
79+
// Used internal for dispatch event
80+
void dispatchEvents();
7981
private:
8082
void collectMeshData();
8183

native/cocos/editor-support/spine/3.8/spine/Vector.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ class SP_API Vector : public SpineObject {
117117
}
118118
}
119119

120-
void addAll(Vector<T> &inValue) {
120+
void addAll(const Vector<T> &inValue) {
121121
ensureCapacity(this->size() + inValue.size());
122122
for (size_t i = 0; i < inValue.size(); i++) {
123123
add(inValue[i]);
124124
}
125125
}
126126

127-
void clearAndAddAll(Vector<T> &inValue) {
127+
void clearAndAddAll(const Vector<T> &inValue) {
128128
this->clear();
129129
this->addAll(inValue);
130130
}
@@ -199,6 +199,13 @@ class SP_API Vector : public SpineObject {
199199
return _buffer;
200200
}
201201

202+
Vector &operator=(const Vector &inVector) {
203+
if (this != &inVector) {
204+
clearAndAddAll(inVector);
205+
}
206+
return *this;
207+
}
208+
202209
private:
203210
size_t _size;
204211
size_t _capacity;
@@ -227,8 +234,6 @@ class SP_API Vector : public SpineObject {
227234
inline void destroy(T *buffer) {
228235
buffer->~T();
229236
}
230-
231-
// Vector &operator=(const Vector &inVector) {};
232237
};
233238
} // namespace spine
234239

native/cocos/editor-support/spine/4.2/spine/Vector.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,14 @@ namespace spine {
116116
}
117117
}
118118

119-
inline void addAll(Vector<T> &inValue) {
119+
void addAll(const Vector<T> &inValue) {
120120
ensureCapacity(this->size() + inValue.size());
121121
for (size_t i = 0; i < inValue.size(); i++) {
122122
add(inValue[i]);
123123
}
124124
}
125125

126-
inline void clearAndAddAll(Vector<T> &inValue) {
126+
void clearAndAddAll(const Vector<T> &inValue) {
127127
this->clear();
128128
this->addAll(inValue);
129129
}
@@ -194,6 +194,13 @@ namespace spine {
194194
return !(lhs == rhs);
195195
}
196196

197+
Vector &operator=(const Vector &inVector) {
198+
if (this != &inVector) {
199+
clearAndAddAll(inVector);
200+
}
201+
return *this;
202+
}
203+
197204
inline T *buffer() {
198205
return _buffer;
199206
}
@@ -226,8 +233,6 @@ namespace spine {
226233
inline void destroy(T *buffer) {
227234
buffer->~T();
228235
}
229-
230-
// Vector &operator=(const Vector &inVector) {};
231236
};
232237
}
233238

native/external-config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
"type": "github",
44
"owner": "cocos",
55
"name": "cocos-engine-external",
6-
"checkout": "v3.8.7-7"
6+
"checkout": "v3.8.7-9"
77
}
88
}

0 commit comments

Comments
 (0)