Skip to content

Commit

Permalink
fix setTrackxxxListener doesn't work on web platform
Browse files Browse the repository at this point in the history
(cherry picked from commit 9b90131d968185bd3d73c30f1a11960a9786fbde)
  • Loading branch information
bofeng-song committed Nov 16, 2023
1 parent 330b92a commit d6ae3e9
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 16 deletions.
16 changes: 8 additions & 8 deletions cocos/spine/skeleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1744,7 +1744,7 @@ export class Skeleton extends UIRenderer {
* @param listener @en Listener for registering callback functions. @zh 监听器对象,可注册回调方法。
*/
public setTrackStartListener (entry: spine.TrackEntry, listener: TrackListener): void {
TrackEntryListeners.getListeners(entry).start = listener;
TrackEntryListeners.getListeners(entry, this._instance).start = listener;
}

/**
Expand All @@ -1754,7 +1754,7 @@ export class Skeleton extends UIRenderer {
* @param listener @en Listener for registering callback functions. @zh 监听器对象,可注册回调方法。
*/
public setTrackInterruptListener (entry: spine.TrackEntry, listener: TrackListener): void {
TrackEntryListeners.getListeners(entry).interrupt = listener;
TrackEntryListeners.getListeners(entry, this._instance).interrupt = listener;
}

/**
Expand All @@ -1764,7 +1764,7 @@ export class Skeleton extends UIRenderer {
* @param listener @en Listener for registering callback functions. @zh 监听器对象,可注册回调方法。
*/
public setTrackEndListener (entry: spine.TrackEntry, listener: TrackListener): void {
TrackEntryListeners.getListeners(entry).end = listener;
TrackEntryListeners.getListeners(entry, this._instance).end = listener;
}

/**
Expand All @@ -1774,7 +1774,7 @@ export class Skeleton extends UIRenderer {
* @param listener @en Listener for registering callback functions. @zh 监听器对象,可注册回调方法。
*/
public setTrackDisposeListener (entry: spine.TrackEntry, listener: TrackListener): void {
TrackEntryListeners.getListeners(entry).dispose = listener;
TrackEntryListeners.getListeners(entry, this._instance).dispose = listener;
}

/**
Expand All @@ -1788,10 +1788,10 @@ export class Skeleton extends UIRenderer {
const loopCount = Math.floor(trackEntry.trackTime / trackEntry.animationEnd);
const listenerID = TrackEntryListeners.addListener(listener);
listener(trackEntry, loopCount);
this._instance.setListener(listenerID, spine.EventType.event);
this._listener!.event = listener;
// this._instance.setListener(listenerID, spine.EventType.event);
// this._listener!.event = listener;
};
TrackEntryListeners.getListeners(entry).complete = onComplete;
TrackEntryListeners.getListeners(entry, this._instance).complete = onComplete;
}

/**
Expand All @@ -1801,7 +1801,7 @@ export class Skeleton extends UIRenderer {
* @param listener @en Listener for registering callback functions. @zh 监听器对象,可注册回调方法。
*/
public setTrackEventListener (entry: spine.TrackEntry, listener: TrackListener|TrackListener2): void {
TrackEntryListeners.getListeners(entry).event = listener;
TrackEntryListeners.getListeners(entry, this._instance).event = listener;
}

/**
Expand Down
46 changes: 45 additions & 1 deletion cocos/spine/track-entry-listeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import spine from './lib/spine-core.js';

let _listener_ID = 0;
let _track_ID = 0;

type TrackListener = (x: spine.TrackEntry) => void;
type TrackListener2 = (x: spine.TrackEntry, ev: spine.Event) => void;
Expand All @@ -38,9 +39,12 @@ export class TrackEntryListeners {
complete?: ((entry: spine.TrackEntry) => void);
event?: ((entry: spine.TrackEntry, event: spine.Event) => void);

static getListeners (entry: spine.TrackEntry): spine.AnimationStateListener {
static getListeners (entry: spine.TrackEntry, instance: spine.SkeletonInstance): spine.AnimationStateListener {
if (!entry.listener) {
entry.listener = new TrackEntryListeners() as any;
const id = ++_track_ID;
instance.setTrackListener(id, entry);

Check failure on line 46 in cocos/spine/track-entry-listeners.ts

View workflow job for this annotation

GitHub Actions / npm_test

Property 'setTrackListener' does not exist on type 'SkeletonInstance'.
TrackEntryListeners._trackSet.set(id, entry);
}
return entry.listener;
}
Expand All @@ -54,13 +58,53 @@ export class TrackEntryListeners {
}
}

static emitTrackListener (id: number, entry: spine.TrackEntry, event: spine.Event, eventType: spine.EventType): void {
const curTrack = this._trackSet.get(id);
if (!curTrack) return;
// eslint-disable-next-line default-case
switch (eventType as number) {
case spine.EventType.start:
if (curTrack.listener.start) {
curTrack.listener.start(entry);
}
break;
case spine.EventType.interrupt:
if (curTrack.listener.interrupt) {
curTrack.listener.interrupt(entry);
}
break;
case spine.EventType.end:
if (curTrack.listener.end) {
curTrack.listener.end(entry);
}
break;
case spine.EventType.dispose:
if (curTrack.listener.dispose) {
curTrack.listener.dispose(entry);
}
this._trackSet.delete(id);
break;
case spine.EventType.complete:
if (curTrack.listener.complete) {
curTrack.listener.complete(entry);
}
break;
case spine.EventType.event:
if (curTrack.listener.event) {
curTrack.listener.event(entry, event);
}
break;
}
}

static addListener (listener: CommonTrackEntryListener): number {
const id = ++_listener_ID;
TrackEntryListeners._listenerSet.set(id, listener);
return id;
}

private static _listenerSet = new Map<number, CommonTrackEntryListener>();
private static _trackSet = new Map<number, spine.TrackEntry>();
}

globalThis.TrackEntryListeners = TrackEntryListeners;
9 changes: 9 additions & 0 deletions native/cocos/editor-support/spine-wasm/library_spine.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,14 @@ mergeInto(LibraryManager.library, {
var trackEntry = wasmUtil.getCurrentTrackEntry();
var event = wasmUtil.getCurrentEvent();
globalThis.TrackEntryListeners.emitListener(listenerID, trackEntry, event);
},

spineTrackListenerCallback: function() {
var wasmUtil = Module['SpineWasmUtil'];
var listenerID = wasmUtil.getCurrentListenerID();
var eventType = wasmUtil.getCurrentEventType();
var trackEntry = wasmUtil.getCurrentTrackEntry();
var event = wasmUtil.getCurrentEvent();
globalThis.TrackEntryListeners.emitTrackListener(listenerID, trackEntry, event, eventType.value);
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,24 @@ SlotMesh globalMesh(nullptr, nullptr, 0, 0);

extern "C" {
extern void spineListenerCallBackFromJS();
extern void spineTrackListenerCallback();
}
using namespace spine;

static void animationCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
SpineSkeletonInstance *instance = (SpineSkeletonInstance *)state->getRendererObject();
SpineSkeletonInstance *instance = (static_cast<SpineSkeletonInstance *>(state->getRendererObject()));
instance->onAnimationStateEvent(entry, type, event);
}

void trackEntryCallback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
(static_cast<SpineSkeletonInstance *>(state->getRendererObject()))->onTrackEntryEvent(entry, type, event);
if (type == EventType_Dispose) {
if (entry->getRendererObject()) {
entry->setRendererObject(nullptr);
}
}
}

SpineSkeletonInstance::SpineSkeletonInstance() {
_model = new SpineModel();
SpineSkeletonSystem::addSpineInstance(this);
Expand Down Expand Up @@ -420,6 +430,14 @@ void SpineSkeletonInstance::setListener(uint32_t listenerID, uint32_t type) {
}
}

void SpineSkeletonInstance::setTrackListener(uint32_t trackId, TrackEntry *entry) {
if (!entry->getRendererObject()) {
_trackListenerID = trackId;
entry->setRendererObject(this);
entry->setListener(trackEntryCallback);
}
}

void SpineSkeletonInstance::setUseTint(bool useTint) {
_userData.useTint = useTint;
}
Expand All @@ -428,6 +446,15 @@ void SpineSkeletonInstance::setDebugMode(bool debug) {
_userData.debugMode = debug;
}

void SpineSkeletonInstance::onTrackEntryEvent(TrackEntry *entry, EventType type, Event *event) {
if (!entry->getRendererObject()) return;
SpineWasmUtil::s_listenerID = _trackListenerID;
SpineWasmUtil::s_currentType = type;
SpineWasmUtil::s_currentEntry = entry;
SpineWasmUtil::s_currentEvent = event;
spineTrackListenerCallback();
}

void SpineSkeletonInstance::onAnimationStateEvent(TrackEntry *entry, EventType type, Event *event) {
SpineWasmUtil::s_currentType = type;
SpineWasmUtil::s_currentEntry = entry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@
#include "spine-model.h"
using namespace spine;

typedef std::function<void(TrackEntry *entry)> StartListener;
typedef std::function<void(TrackEntry *entry)> InterruptListener;
typedef std::function<void(TrackEntry *entry)> EndListener;
typedef std::function<void(TrackEntry *entry)> DisposeListener;
typedef std::function<void(TrackEntry *entry)> CompleteListener;
typedef std::function<void(TrackEntry *entry, Event *event)> EventListener;

enum DEBUG_SHAPE_TYPE {
DEBUG_REGION = 0,
Expand Down Expand Up @@ -58,7 +52,9 @@ class SpineSkeletonInstance {
AnimationState *getAnimationState();
void setMix(const std::string &from, const std::string &to, float duration);
void setListener(uint32_t listenerID, uint32_t type);
void setTrackListener(uint32_t trackId, TrackEntry *entry);
void onAnimationStateEvent(TrackEntry *entry, EventType type, Event *event);
void onTrackEntryEvent(TrackEntry *entry, EventType type, Event *event);
std::vector<SpineDebugShape> &getDebugShapes();
void resizeSlotRegion(const std::string &slotName, uint32_t width, uint32_t height, bool createNew = false);
void setSlotTexture(const std::string &slotName, uint32_t index);
Expand All @@ -83,6 +79,7 @@ class SpineSkeletonInstance {
uint32_t _disposeListenerID = 0;
uint32_t _completeListenerID = 0;
uint32_t _eventListenerID = 0;
uint32_t _trackListenerID = 0;
UserData _userData;
std::vector<SpineDebugShape> _debugShapes{};
std::map<Slot *, uint32_t> slotTextureSet{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,7 @@ EMSCRIPTEN_BINDINGS(spine) {
.function("getAnimationState", &SpineSkeletonInstance::getAnimationState, allow_raw_pointer<AnimationState>())
.function("setMix", &SpineSkeletonInstance::setMix)
.function("setListener", &SpineSkeletonInstance::setListener)
.function("setTrackListener", &SpineSkeletonInstance::setTrackListener, allow_raw_pointer<TrackEntry *>())
.function("setDebugMode", &SpineSkeletonInstance::setDebugMode)
.function("getDebugShapes", &SpineSkeletonInstance::getDebugShapes)
.function("resizeSlotRegion", &SpineSkeletonInstance::resizeSlotRegion)
Expand Down

0 comments on commit d6ae3e9

Please sign in to comment.