2017-12-07 03:23:40 -05:00

122 lines
3.4 KiB
C++
Executable File

//////////////////////////////////////////////////////////////////////
// filename: SpineEventMonitor.h
//
// purpose: Monitor spAnimationState Events
/////////////////////////////////////////////////////////////////////
#pragma once
#include <vector>
#include <string>
#include <spine/AnimationState.h>
using namespace Spine;
//////////////////////////////////////////////////////////////////////
// class: SpineEventMonitor
//
// purpose: Monitor spAnimationState Events and report when there
// are no more TrackEntry(s) waiting to play on track 0;
//
// Also allows for debug printing of Events to console.
/////////////////////////////////////////////////////////////////////
class SpineEventMonitor
{
public:
SpineEventMonitor(AnimationState* _pAnimationState = 0);
virtual ~SpineEventMonitor();
void RegisterListener(AnimationState* _pAnimationState);
void SetDebugLogging(bool val) { bLogging = val; }
bool GetDebugLogging() { return bLogging; }
virtual bool isAnimationPlaying();
protected:
static void spineAnimStateHandler(AnimationState* state, EventType type, TrackEntry* entry, Event* event);
virtual void OnSpineAnimationStateEvent(AnimationState* state, EventType type, TrackEntry* entry, Event* event);
protected:
AnimationState *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(AnimationState* state, EventType type, TrackEntry* trackEntry, Event* event);
std::string mAnimName;
int mEventType;
TrackEntry* mTrackEntry;
std::string mEventName;
};
typedef std::vector<InterruptEvent> InterruptEventStack;
public:
InterruptMonitor(AnimationState* _pAnimationState = 0);
~InterruptMonitor() {}
virtual bool isAnimationPlaying() override;
public:
InterruptMonitor& AddInterruptEvent(int theEventType);
InterruptMonitor& AddInterruptEvent(int theEventType, const std::string& theAnimationName);
InterruptMonitor& AddInterruptEvent(int theEventType, TrackEntry* theTrackEntry);
InterruptMonitor& AddInterruptEventTrigger(const std::string& theEventTriggerName);
protected:
virtual void OnSpineAnimationStateEvent(AnimationState* state, EventType type, TrackEntry* trackEntry, Event* 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 TrackEntry
.AddInterruptEvent(SP_ANIMATION_START); // Then, stop on any following START signal
*/