Object | +---DFSM
The DFSM class implements a (simple) finite state machine. The state machine is built by creating a number of transitions for every state. After the state machine is built, the processing is started by using the 'start' method. From that moment on, events can be fed to the state machine by calling 'feed'. This method returns the current state. With the method 'try' an event can be tested for the state machine, without changing the internal state of the machine. There is one assumption: events are ints.
#include <stdio.h> #include "ofc/DFSM.h" enum { INSERT_CARD, ENTER_PIN, REFUSE_PIN, ENTER_AMOUNT, ACCEPT_MONEY, REMOVE_CARD }; int main(int argc, char *argv[]) { DFSM *fsm = [DFSM new]; DFSMState *waitCard = [DFSMState new]; // State: wait for card DFSMState *waitPin = [DFSMState new]; // State: wait for pin DFSMState *waitAmount = [DFSMState new]; // State: wait for choice amount money DFSMState *waitAccept = [DFSMState new]; // State: wait for acceptance money DFSMState *waitRemoval = [DFSMState new]; // State: wait for removal card DBitArray *events = [DBitArray alloc]; // the events bit array [events init :INSERT_CARD :REMOVE_CARD]; // Init the events bit array // Setup the state machine [events reset]; [events set :INSERT_CARD]; [fsm transition :waitCard :[events copy] :waitPin]; [events reset]; [events set :ENTER_PIN]; [fsm transition :waitPin :[events copy] :waitAmount]; [events reset]; [events set :REFUSE_PIN]; [fsm transition :waitPin :[events copy] :waitRemoval]; [events reset]; [events set :ENTER_AMOUNT]; [fsm transition :waitAmount :[events copy] :waitAccept]; [events reset]; [events set :ACCEPT_MONEY]; [fsm transition :waitAccept :[events copy] :waitRemoval]; [events reset]; [events set :REMOVE_CARD]; [fsm transition :waitRemoval :[events copy] :waitCard]; // Start using the state machine [fsm start :waitCard]; // Feed the state machine with events if ([fsm feed :INSERT_CARD] != nil) printf("Event INSERT_CARD accepted.\n"); else printf("Event INSERT_CARD was not allowed in the current state.\n"); // Try an event in the current state printf("Event: ENTER_PIN is %s accaptable in the current state.\n", ([fsm try :ENTER_PIN] != nil ? "" : "not")); if ([fsm feed :REFUSE_PIN] == waitRemoval) printf("Event REFUSE_PIN accepted and fsm is moved to waitRemoval.\n"); else printf("Event REFUSE_PIN not accepted.\n"); [fsm free]; // Cleanup fsm, states and transations [events free]; return 0; }