#ifndef SQLTransactionStateMachine_h
#define SQLTransactionStateMachine_h
#include "modules/webdatabase/SQLTransactionState.h"
#include "wtf/ThreadSafeRefCounted.h"
namespace WebCore {
template<typename T>
class SQLTransactionStateMachine {
public:
virtual ~SQLTransactionStateMachine() { }
protected:
SQLTransactionStateMachine();
typedef SQLTransactionState (T::* StateFunction)();
virtual StateFunction stateFunctionFor(SQLTransactionState) = 0;
void setStateToRequestedState();
void runStateMachine();
SQLTransactionState m_nextState;
SQLTransactionState m_requestedState;
#ifndef NDEBUG
static const int s_sizeOfStateAuditTrail = 20;
int m_nextStateAuditEntry;
SQLTransactionState m_stateAuditTrail[s_sizeOfStateAuditTrail];
#endif
};
#if !LOG_DISABLED
extern const char* nameForSQLTransactionState(SQLTransactionState);
#endif
template<typename T>
SQLTransactionStateMachine<T>::SQLTransactionStateMachine()
: m_nextState(SQLTransactionState::Idle)
, m_requestedState(SQLTransactionState::Idle)
#ifndef NDEBUG
, m_nextStateAuditEntry(0)
#endif
{
#ifndef NDEBUG
for (int i = 0; i < s_sizeOfStateAuditTrail; i++)
m_stateAuditTrail[i] = SQLTransactionState::NumberOfStates;
#endif
}
template<typename T>
void SQLTransactionStateMachine<T>::setStateToRequestedState()
{
ASSERT(m_nextState == SQLTransactionState::Idle);
ASSERT(m_requestedState != SQLTransactionState::Idle);
m_nextState = m_requestedState;
m_requestedState = SQLTransactionState::Idle;
}
template<typename T>
void SQLTransactionStateMachine<T>::runStateMachine()
{
ASSERT(SQLTransactionState::End < SQLTransactionState::Idle);
while (m_nextState > SQLTransactionState::Idle) {
ASSERT(m_nextState < SQLTransactionState::NumberOfStates);
StateFunction stateFunction = stateFunctionFor(m_nextState);
ASSERT(stateFunction);
#ifndef NDEBUG
m_stateAuditTrail[m_nextStateAuditEntry] = m_nextState;
m_nextStateAuditEntry = (m_nextStateAuditEntry + 1) % s_sizeOfStateAuditTrail;
#endif
m_nextState = (static_cast<T*>(this)->*stateFunction)();
}
}
}
#endif