Listing 1: Client class FSM

//----------- 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