[cpp] Fix SPINE_USE_STD_FUNCTION listeners

Closes #2918
This commit is contained in:
Mario Zechner 2026-03-14 16:12:09 +01:00
parent 000a1882b9
commit e665976598
2 changed files with 56 additions and 13 deletions

View File

@ -308,7 +308,11 @@ namespace spine {
float getTrackComplete();
#ifdef SPINE_USE_STD_FUNCTION
void setListener(AnimationStateListener listener);
#else
void setListener(AnimationStateListener listener, void *userData = NULL);
#endif
void setListener(AnimationStateListenerObject *listener);
@ -353,7 +357,9 @@ namespace spine {
Array<TrackEntry *> _timelineHoldMix;
Array<float> _timelinesRotation;
AnimationStateListener _listener;
#ifndef SPINE_USE_STD_FUNCTION
void *_listenerUserData;
#endif
AnimationStateListenerObject *_listenerObject;
AnimationState *_state;
@ -523,7 +529,11 @@ namespace spine {
void setTimeScale(float inValue);
/// Adds a listener to receive events for all track entries.
#ifdef SPINE_USE_STD_FUNCTION
void setListener(AnimationStateListener listener);
#else
void setListener(AnimationStateListener listener, void *userData = NULL);
#endif
/// Adds a listener to receive events for all track entries.
void setListener(AnimationStateListenerObject *listener);
@ -559,7 +569,9 @@ namespace spine {
bool _animationsChanged;
AnimationStateListener _listener;
#ifndef SPINE_USE_STD_FUNCTION
void *_listenerUserData;
#endif
AnimationStateListenerObject *_listenerObject;
int _unkeyedState;

View File

@ -46,6 +46,18 @@
using namespace spine;
#ifdef SPINE_USE_STD_FUNCTION
void dummyOnAnimationEventFunc(AnimationState *state, spine::EventType type, TrackEntry *entry, Event *event) {
SP_UNUSED(state);
SP_UNUSED(type);
SP_UNUSED(entry);
SP_UNUSED(event);
}
#define SP_ANIMATION_LISTENER_USER_DATA_CTOR
#define SP_ANIMATION_LISTENER_CLEAR_USER_DATA()
#define SP_INVOKE_ANIMATION_LISTENER(listener, state, type, entry, event, userData) listener(&state, type, entry, event)
#else
void dummyOnAnimationEventFunc(AnimationState *state, spine::EventType type, TrackEntry *entry, Event *event, void *userData) {
SP_UNUSED(state);
SP_UNUSED(type);
@ -54,12 +66,17 @@ void dummyOnAnimationEventFunc(AnimationState *state, spine::EventType type, Tra
SP_UNUSED(userData);
}
#define SP_ANIMATION_LISTENER_USER_DATA_CTOR _listenerUserData(NULL),
#define SP_ANIMATION_LISTENER_CLEAR_USER_DATA() _listenerUserData = NULL
#define SP_INVOKE_ANIMATION_LISTENER(listener, state, type, entry, event, userData) listener(&state, type, entry, event, userData)
#endif
TrackEntry::TrackEntry()
: _animation(NULL), _previous(NULL), _next(NULL), _mixingFrom(NULL), _mixingTo(0), _trackIndex(0), _loop(false), _holdPrevious(false),
_reverse(false), _shortestRotation(false), _eventThreshold(0), _mixAttachmentThreshold(0), _alphaAttachmentThreshold(0),
_mixDrawOrderThreshold(0), _animationStart(0), _animationEnd(0), _animationLast(0), _nextAnimationLast(0), _delay(0), _trackTime(0),
_trackLast(0), _nextTrackLast(0), _trackEnd(0), _timeScale(1.0f), _alpha(0), _mixTime(0), _mixDuration(0), _interruptAlpha(0), _totalAlpha(0),
_mixBlend(MixBlend_Replace), _listener(dummyOnAnimationEventFunc), _listenerUserData(NULL), _listenerObject(NULL), _state(NULL) {
_mixBlend(MixBlend_Replace), _listener(dummyOnAnimationEventFunc), SP_ANIMATION_LISTENER_USER_DATA_CTOR _listenerObject(NULL), _state(NULL) {
}
TrackEntry::~TrackEntry() {
@ -278,15 +295,22 @@ void TrackEntry::resetRotationDirections() {
_timelinesRotation.clear();
}
#ifdef SPINE_USE_STD_FUNCTION
void TrackEntry::setListener(AnimationStateListener inValue) {
_listener = inValue;
_listenerObject = NULL;
}
#else
void TrackEntry::setListener(AnimationStateListener inValue, void *userData) {
_listener = inValue;
_listenerUserData = userData;
_listenerObject = NULL;
}
#endif
void TrackEntry::setListener(AnimationStateListenerObject *inValue) {
_listener = dummyOnAnimationEventFunc;
_listenerUserData = NULL;
SP_ANIMATION_LISTENER_CLEAR_USER_DATA();
_listenerObject = inValue;
}
@ -304,7 +328,7 @@ void TrackEntry::reset() {
_timelinesRotation.clear();
_listener = dummyOnAnimationEventFunc;
_listenerUserData = NULL;
SP_ANIMATION_LISTENER_CLEAR_USER_DATA();
_listenerObject = NULL;
}
@ -388,31 +412,31 @@ void EventQueue::drain() {
case EventType_Interrupt:
case EventType_Complete:
if (!trackEntry->_listenerObject)
trackEntry->_listener(&state, queueEntry._type, trackEntry, NULL, trackEntry->_listenerUserData);
SP_INVOKE_ANIMATION_LISTENER(trackEntry->_listener, state, queueEntry._type, trackEntry, NULL, trackEntry->_listenerUserData);
else
trackEntry->_listenerObject->callback(&state, queueEntry._type, trackEntry, NULL);
if (!state._listenerObject)
state._listener(&state, queueEntry._type, trackEntry, NULL, state._listenerUserData);
SP_INVOKE_ANIMATION_LISTENER(state._listener, state, queueEntry._type, trackEntry, NULL, state._listenerUserData);
else
state._listenerObject->callback(&state, queueEntry._type, trackEntry, NULL);
break;
case EventType_End:
if (!trackEntry->_listenerObject)
trackEntry->_listener(&state, queueEntry._type, trackEntry, NULL, trackEntry->_listenerUserData);
SP_INVOKE_ANIMATION_LISTENER(trackEntry->_listener, state, queueEntry._type, trackEntry, NULL, trackEntry->_listenerUserData);
else
trackEntry->_listenerObject->callback(&state, queueEntry._type, trackEntry, NULL);
if (!state._listenerObject)
state._listener(&state, queueEntry._type, trackEntry, NULL, state._listenerUserData);
SP_INVOKE_ANIMATION_LISTENER(state._listener, state, queueEntry._type, trackEntry, NULL, state._listenerUserData);
else
state._listenerObject->callback(&state, queueEntry._type, trackEntry, NULL);
/* Fall through. */
case EventType_Dispose:
if (!trackEntry->_listenerObject)
trackEntry->_listener(&state, EventType_Dispose, trackEntry, NULL, trackEntry->_listenerUserData);
SP_INVOKE_ANIMATION_LISTENER(trackEntry->_listener, state, EventType_Dispose, trackEntry, NULL, trackEntry->_listenerUserData);
else
trackEntry->_listenerObject->callback(&state, EventType_Dispose, trackEntry, NULL);
if (!state._listenerObject)
state._listener(&state, EventType_Dispose, trackEntry, NULL, state._listenerUserData);
SP_INVOKE_ANIMATION_LISTENER(state._listener, state, EventType_Dispose, trackEntry, NULL, state._listenerUserData);
else
state._listenerObject->callback(&state, EventType_Dispose, trackEntry, NULL);
@ -420,11 +444,11 @@ void EventQueue::drain() {
break;
case EventType_Event:
if (!trackEntry->_listenerObject)
trackEntry->_listener(&state, queueEntry._type, trackEntry, queueEntry._event, trackEntry->_listenerUserData);
SP_INVOKE_ANIMATION_LISTENER(trackEntry->_listener, state, queueEntry._type, trackEntry, queueEntry._event, trackEntry->_listenerUserData);
else
trackEntry->_listenerObject->callback(&state, queueEntry._type, trackEntry, queueEntry._event);
if (!state._listenerObject)
state._listener(&state, queueEntry._type, trackEntry, queueEntry._event, state._listenerUserData);
SP_INVOKE_ANIMATION_LISTENER(state._listener, state, queueEntry._type, trackEntry, queueEntry._event, state._listenerUserData);
else
state._listenerObject->callback(&state, queueEntry._type, trackEntry, queueEntry._event);
break;
@ -437,7 +461,7 @@ void EventQueue::drain() {
AnimationState::AnimationState(AnimationStateData &data)
: _data(&data), _queue(EventQueue::newEventQueue(*this)), _animationsChanged(false), _listener(dummyOnAnimationEventFunc),
_listenerUserData(NULL), _listenerObject(NULL), _unkeyedState(0), _timeScale(1), _manualTrackEntryDisposal(false) {
SP_ANIMATION_LISTENER_USER_DATA_CTOR _listenerObject(NULL), _unkeyedState(0), _timeScale(1), _manualTrackEntryDisposal(false) {
}
AnimationState::~AnimationState() {
@ -759,15 +783,22 @@ void AnimationState::setTimeScale(float inValue) {
_timeScale = inValue;
}
#ifdef SPINE_USE_STD_FUNCTION
void AnimationState::setListener(AnimationStateListener inValue) {
_listener = inValue;
_listenerObject = NULL;
}
#else
void AnimationState::setListener(AnimationStateListener inValue, void *userData) {
_listener = inValue;
_listenerUserData = userData;
_listenerObject = NULL;
}
#endif
void AnimationState::setListener(AnimationStateListenerObject *inValue) {
_listener = dummyOnAnimationEventFunc;
_listenerUserData = NULL;
SP_ANIMATION_LISTENER_CLEAR_USER_DATA();
_listenerObject = inValue;
}