//----------- FSM declaration ------------ #include "ABS_eventhandler.h" #include "list.h" typedef struct StructEvent { // event identifier int Id; // event parameters void *parameters; } STRUCT_EVENT; Makelista(STRUCT_EVENT); class FSM { private : typedef struct { int source_state; int destination_state; int event; int index; } TransitionType; TransitionType* myptrArrayTrans; // a pointer to the // array of transitions int myMaxNumTransitions; // max transitions supported int myCurrentState; // current state of the FSM // an event queue STRUCT_EVENTlista myList; ABSEventHandler* myptrHandler; // a pointer to the // abstract server class void insertInQueue(int inEvent, void *inParameters ); // Search using hash functions int hash(int inSourceState, int inEvent); int hash(int inEvent); public : // Constructor FSM(ABSEventHandler *inTrans, int inMaxNumTransitions, int inInitialState ); // Destructor ~FSM( void ); void defineTransition(int inSourceState, int inDestinationState, int inEvent, int inIndex); int control(int inEvent, void *inParameters = NULL ); void generateEvent(int inEvent, void *inParameters = NULL ); }; //----------- FSM definition ------------ #include <memory.h> #include <stdlib.h> #include "FSM.h" FSM::FSM(ABSEventHandler *inTrans, int inMaxNumTransitions, int inInitialState) { myptrHandler = inTrans; // Initialize the maximal number of transitions myMaxNumTransitions = inMaxNumTransitions; // Initialize the current state myCurrentState = inInitialState; // Initialize the array of transitions myptrArrayTrans = 0; myptrArrayTrans = new TransitionType[myMaxNumTransitions]; memset(myptrArrayTrans, -1, myMaxNumTransitions * sizeof(TransitionType)); } FSM::~FSM() { if ( myptrArrayTrans ) delete []myptrArrayTrans; } void FSM::insertInQueue(int inEvent, void *inParametros) // not shown int FSM::hash(int inSourceState, int inEvent) { int i = 0; int where = ((inEvent << 8) + inSourceState) % myMaxNumTransitions; // Look for the first available position while((myptrArrayTrans[(where + i)%myMaxNumTransitions].index != -1) && (i < myMaxNumTransitions)) i++; // Return negative value if the table is full if ( i >= myMaxNumTransitions ) return -1; else // Return free position?s index return ((where + i) % myMaxNumTransitions); } int FSM::hash( int inEvent ) { int i = 0; int where = ((inEvent << 8) + myCurrentState) % myMaxNumTransitions; // rest the same as above } int FSM::defineTransition(int inSourceState, int inDestinationState, int inEvent, int inIndex) { int index; // Search free position in the table of transitions index = hash(inSourceState, inEvent); if ( index != -1 ) { myptrArrayTrans[index].source_state = inSourceState; myptrArrayTrans[index].destination_state = inDestinationState; myptrArrayTrans[index].event = inEvent; myptrArrayTrans[index].index = inIndex; } return index; } int FSM::control( int inEvent, void *inParametros ) { int result = FALSE; int trans_num; StructEvent* anEvent = NULL; // Insert the received event in the queue insertInQueue(inEvent, inParametros); anEvent = myList.first(); while ( anEvent ) { // check if it is valid transition if ((trans_num = hash(anEvent->Id)) >= 0) { if (myptrArrayTrans[trans_num].index == -1) { // Missing transition - generate an internal error event generateEvent(INTERNAL_ERROR); } else { // Execute an event handler result = (myptrHandler->*myptrHandler-> functions[myptrArrayTrans[trans_num].index]) (anEvent->parameters); // Change the FSM's state myCurrentState = myptrArrayTrans[trans_num].destination_state; } } // Missing transition - generate an internal error event else { generateEvent(INTERNAL_ERROR); } // Remove the processed event myList.remove(anEvent); // pull the next event // from the queue anEvent = myList.next(); } return result; } void FSM::generateEvent(int inEvent, void *inParametros ) { insertInQueue(inEvent, inParametros); } //End of File