131 lines
3.6 KiB
C++
Executable File

//////////////////////////////////////////////////////////////////////
// filename: SpineEventMonitor.h
//
// purpose: Monitor spAnimationState Events
/////////////////////////////////////////////////////////////////////
#pragma once
#include <vector>
#include <string>
// forward declarations
typedef struct spAnimationState spAnimationState;
typedef struct spTrackEntry spTrackEntry;
typedef struct spEvent spEvent;
//////////////////////////////////////////////////////////////////////
// class: SpineEventMonitor
//
// purpose: Monitor spAnimationState Events and report when there
// are no more spTrackEntry(s) waiting to play on track 0;
//
// Also allows for debug printing of Events to console.
/////////////////////////////////////////////////////////////////////
class SpineEventMonitor {
public:
SpineEventMonitor(spAnimationState *_pAnimationState = 0);
virtual ~SpineEventMonitor();
void RegisterListener(spAnimationState *_pAnimationState);
void SetDebugLogging(bool val) { bLogging = val; }
bool GetDebugLogging() { return bLogging; }
virtual bool isAnimationPlaying();
protected:
static void spineAnimStateHandler(spAnimationState *state, int type, spTrackEntry *entry, spEvent *event);
virtual void
OnSpineAnimationStateEvent(spAnimationState *state, int type, spTrackEntry *trackEntry, spEvent *event);
protected:
spAnimationState *pAnimState;
bool bLogging;
};
//////////////////////////////////////////////////////////////////////
// class: InterruptMonitor
//
// purpose: Allows a programmer to interrupt/stop the updating
// of an animation based on a specific sequence of
// events generated by the animation.
/////////////////////////////////////////////////////////////////////
class InterruptMonitor : public SpineEventMonitor {
private:
struct InterruptEvent {
InterruptEvent() {
mEventType = -1; // invalid
mTrackEntry = 0;
}
bool matches(spAnimationState *state, int type, spTrackEntry *trackEntry, spEvent *event);
std::string mAnimName;
int mEventType;
spTrackEntry *mTrackEntry;
std::string mEventName;
};
typedef std::vector<InterruptEvent> InterruptEventStack;
public:
InterruptMonitor(spAnimationState *_pAnimationState = 0);
~InterruptMonitor() {}
virtual bool isAnimationPlaying() override;
public:
InterruptMonitor &AddInterruptEvent(int theEventType);
InterruptMonitor &AddInterruptEvent(int theEventType, const std::string &theAnimationName);
InterruptMonitor &AddInterruptEvent(int theEventType, spTrackEntry *theTrackEntry);
InterruptMonitor &AddInterruptEventTrigger(const std::string &theEventTriggerName);
protected:
virtual void
OnSpineAnimationStateEvent(spAnimationState *state, int type, spTrackEntry *trackEntry, spEvent *event) override;
virtual void OnMatchingComplete() {}
protected:
bool bForceInterrupt;
InterruptEventStack mEventStack; // must match these events in this order
size_t mEventStackCursor;
};
/*
EXAMPLE
=======
SpineEventMonitor eventMonitor(state);
eventMonitor.SetDebugLogging(true);
while(eventMonitor.isAnimationPlaying()){
// update...
}
EXAMPLE
=======
InterruptMonitor eventMonitor(state);
eventMonitor.SetDebugLogging(true);
// Interrupt the animation on this specific sequence of spEventType(s)
eventMonitor
.AddInterruptEvent(SP_ANIMATION_INTERRUPT, "jump") // First, wait for INTERRUPT signal on the 'jump' animation spTrackEntry
.AddInterruptEvent(SP_ANIMATION_START); // Then, stop on any following START signal
*/