SpineEventMonitor.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "SpineEventMonitor.h"
  2. #include "spine/spine.h"
  3. #include "KString.h"
  4. #include "KMemory.h" // Last include
  5. SpineEventMonitor::SpineEventMonitor(spAnimationState *_pAnimationState /*= nullptr*/) {
  6. bLogging = false;
  7. RegisterListener(_pAnimationState);
  8. }
  9. SpineEventMonitor::~SpineEventMonitor() {
  10. pAnimState = 0;
  11. }
  12. void SpineEventMonitor::RegisterListener(spAnimationState *_pAnimationState) {
  13. if (_pAnimationState) {
  14. _pAnimationState->rendererObject = this;
  15. _pAnimationState->listener = (spAnimationStateListener) &SpineEventMonitor::spineAnimStateHandler;
  16. }
  17. pAnimState = _pAnimationState;
  18. }
  19. bool SpineEventMonitor::isAnimationPlaying() {
  20. if (pAnimState)
  21. return spAnimationState_getCurrent(pAnimState, 0) != 0;
  22. return false;
  23. }
  24. void SpineEventMonitor::spineAnimStateHandler(spAnimationState *state, int type, spTrackEntry *entry, spEvent *event) {
  25. if (state && state->rendererObject) {
  26. SpineEventMonitor *pEventMonitor = (SpineEventMonitor *) state->rendererObject;
  27. pEventMonitor->OnSpineAnimationStateEvent(state, type, entry, event);
  28. }
  29. }
  30. void SpineEventMonitor::OnSpineAnimationStateEvent(spAnimationState *state, int type, spTrackEntry *trackEntry,
  31. spEvent *event) {
  32. const char *eventName = 0;
  33. if (state == pAnimState) { // only monitor ours
  34. switch (type) {
  35. case SP_ANIMATION_START:
  36. eventName = "SP_ANIMATION_START";
  37. break;
  38. case SP_ANIMATION_INTERRUPT:
  39. eventName = "SP_ANIMATION_INTERRUPT";
  40. break;
  41. case SP_ANIMATION_END:
  42. eventName = "SP_ANIMATION_END";
  43. break;
  44. case SP_ANIMATION_COMPLETE:
  45. eventName = "SP_ANIMATION_COMPLETE";
  46. break;
  47. case SP_ANIMATION_DISPOSE:
  48. eventName = "SP_ANIMATION_DISPOSE";
  49. break;
  50. case SP_ANIMATION_EVENT:
  51. eventName = "SP_ANIMATION_EVENT";
  52. break;
  53. default:
  54. break;
  55. }
  56. if (bLogging && eventName && trackEntry && trackEntry->animation && trackEntry->animation->name)
  57. KOutputDebug(DEBUGLVL, "[%s : '%s']\n", eventName, trackEntry->animation->name);//*/
  58. }
  59. }
  60. InterruptMonitor::InterruptMonitor(spAnimationState *_pAnimationState) :
  61. SpineEventMonitor(_pAnimationState) {
  62. bForceInterrupt = false;
  63. mEventStackCursor = 0; // cursor used to track events
  64. }
  65. bool InterruptMonitor::isAnimationPlaying() {
  66. return !bForceInterrupt && SpineEventMonitor::isAnimationPlaying();
  67. }
  68. // Stops the animation on any occurance of the spEventType
  69. InterruptMonitor &InterruptMonitor::AddInterruptEvent(int theEventType) {
  70. InterruptEvent ev;
  71. ev.mEventType = theEventType;
  72. mEventStack.push_back(ev);
  73. return *this;
  74. }
  75. // Stops the animation when the [spEventType : 'animationName'] occurs
  76. InterruptMonitor &InterruptMonitor::AddInterruptEvent(int theEventType, const std::string &theAnimationName) {
  77. InterruptEvent ev;
  78. ev.mEventType = theEventType;
  79. ev.mAnimName = theAnimationName;
  80. mEventStack.push_back(ev);
  81. return *this;
  82. }
  83. // stops the first encounter of spEventType on the specified TrackEntry
  84. InterruptMonitor &InterruptMonitor::AddInterruptEvent(int theEventType, spTrackEntry *theTrackEntry) {
  85. InterruptEvent ev;
  86. ev.mEventType = theEventType;
  87. ev.mTrackEntry = theTrackEntry;
  88. mEventStack.push_back(ev);
  89. return *this;
  90. }
  91. // Stops on the first SP_ANIMATION_EVENT with the string payload of 'theEventTriggerName'
  92. InterruptMonitor &InterruptMonitor::AddInterruptEventTrigger(const std::string &theEventTriggerName) {
  93. InterruptEvent ev;
  94. ev.mEventType = SP_ANIMATION_EVENT;
  95. ev.mEventName = theEventTriggerName;
  96. mEventStack.push_back(ev);
  97. return *this;
  98. }
  99. void InterruptMonitor::OnSpineAnimationStateEvent(spAnimationState *state, int type, spTrackEntry *trackEntry,
  100. spEvent *event) {
  101. SpineEventMonitor::OnSpineAnimationStateEvent(state, type, trackEntry, event);
  102. if (mEventStackCursor < mEventStack.size()) {
  103. if (mEventStack[mEventStackCursor].matches(state, type, trackEntry, event))
  104. ++mEventStackCursor;
  105. if (mEventStackCursor >= mEventStack.size()) {
  106. bForceInterrupt = true;
  107. OnMatchingComplete();
  108. }
  109. }
  110. }
  111. inline bool
  112. InterruptMonitor::InterruptEvent::matches(spAnimationState *state, int type, spTrackEntry *trackEntry, spEvent *event) {
  113. // Must match spEventType {SP_ANIMATION_START, SP_ANIMATION_INTERRUPT, SP_ANIMATION_END, SP_ANIMATION_COMPLETE, SP_ANIMATION_DISPOSE, SP_ANIMATION_EVENT }
  114. if (mEventType == type) {
  115. // Looking for specific TrackEntry by pointer
  116. if (mTrackEntry != 0) {
  117. return mTrackEntry == trackEntry;
  118. }
  119. // looking for Animation Track by name
  120. if (!mAnimName.empty()) {
  121. if (trackEntry && trackEntry->animation && trackEntry->animation->name) {
  122. if (CompareNoCase(trackEntry->animation->name, mAnimName) == 0) {
  123. return true;
  124. }
  125. }
  126. return false;
  127. }
  128. // looking for Event String Text
  129. if (!mEventName.empty()) {
  130. if (event && event->stringValue) {
  131. return (CompareNoCase(event->stringValue, mEventName) == 0);
  132. }
  133. return false;
  134. }
  135. return true; // waiting for ANY spEventType that matches
  136. }
  137. return false;
  138. }