So now you have a list of states, the transitions and triggers you can start writing.
State Index Constants
Code:
CONST STATE_NONE = 0; STATE_INITIALISEMODEM = 1; STATE_BEGINWAITING = 2; STATE_WAITINGFORCALL = 3; STATE_CALLDETECTED = 4; STATE_CALLINPROGRESS = 5; STATE_ENDCALL = 6; STATE_CALLDISCONNECTED = 7;
Code:
state:=STATE_INITIALISEMODEM;
nextState:=STATE_NONE;
while (1=1) do
begin
case state of
STATE_INITIALISEMODEM : begin
modem.initialise;
nextState:=STATE_BEGINWAITING;
end;
STATE_BEGINWAITING : begin
modem.waitForCall;
nextState:=STATE_WAITINGFORCALL;
end;
STATE_WAITINGFORCALL : begin
if (modem.signalRingIndicator) then
begin
nextState:=STATE_CALLDETECTED;
end;
end;
STATE_CALLDETECTED : begin
modem.pickup;
nextState:=STATE_CALLINPROGRESS;
end;
STATE_CALLINPROGRESS : begin
if (not modem.signalCarrierDetect) then
begin
nextState:=STATE_CALLDISCONNECTED;
end
else
begin
if (modem.dataReady) then
begin
command:=modem.readString;
processCommand(command,quit);
if (quit) then
begin
nextState:=STATE_ENDCALL;
end;
end;
end;
end;
STATE_ENDCALL : begin
modem.hangUp;
nextState:=STATE_INITIALISEMODEM;
end;
STATE_CALLDISCONNECTED : begin
nextState:=STATE_INITIALISEMODEM;
end;
end;
if (nextState<>STATE_NONE) then
begin
state:=nextState;
nextState:=STATE_NONE;
end;
end;
Hopefully it's easy to see that we can optimise some of the states. There are some states which just perform simple operations and then move on... this is only possible because we aren't worrying about responses to our commands. For example, STATE_INITIALISEMODEM and STATE_BEGINWAITING can be combined into a single state and STATE_CALLDISCONNECTED could be dropped entirely by simply having the code move to STATE_INITIALISEMODEM instead of STATE_CALLDISCONNECTED.
And on the flipside, it is possible to split STATE_CALLINPROGRESS into two states. STATE_CALLINPROGRESS which would check the carrier detect signal and the data ready flag and a new state 'STATE_PROCESSINGCOMMAND' that simply read the command , processed it and then moved to either STATE_CALLINPROGRESS if the user didn't quit or STATE_ENDCALL if they did.
Whether you make these changes is ultimately a judgement call. Personally I would happy with just making the state reduction optimisations highlighted first. I don't feel STATE_CALLINPROGRESS is too complex, but much more logic and flow in there and I would probably split it into a number of simpler states.
If you are confident that you won't compromise the machine, you can make these sorts of optimisations during the design. If not, then leave the optimising until you've got the code.


Menu
Categories
Content Tags







vBulletin Message