Classes of State Machine Application


I use state machines and SMC for several classes of application.

High-Level Application Policies for GUIs

One of the goals of the graphical revolution in the 1980s, was to create stateless interfaces for humans to use. At that time, computer interfaces were dominated by textual approaches using hierarchical menus. It was easy to get lost in the menu structure, losing track of what state the screen was in. GUIs helped mitigate that problem by minimizing the number of state changes that the screen went through. In modern GUIs, a great deal of work is put into keeping common features on the screen at all times and making sure that the user does not get confused by hidden states.

It is ironic, then, that the code that implements these "stateless" GUIs is strongly state driven. In such GUIs, the code must figure out which menu items and buttons to gray out, which subwindows should appear, which tab should be activated, where the focus ought to be put, and so on. All these decisions are decisions about the state of the interface.

I learned a long time ago that controlling these factors is a nightmare unless you organize them into a single control structure. That control structure is best characterized as an FSM. Since those days, I have been writing almost all my GUIs using FSMs generated by SMC or its predecessors.

Consider the state machine in Listing 36-15. This machine controls the GUI for the login portion of an application. On getting a start event, the machine puts up a login screen. Once the user presses the Enter key, the machine checks the password. If the password is good, the machine goes to the loggedIn state and starts the user process (not shown). If the password is bad, the machine displays a screen so informing the user. The user can try again by clicking the OK button but otherwise clicks the Cancel button. If a bad password is entered three times in a row (thirdBadPassword event), the machine locks the screen until the administrator password is entered.

Listing 36-15. login.sm

Initial init {   init   {     start logginIn displayLoginScreen   }   logginIn   {     enter checkingPassword checkPassword     cancel init clearScreen   }   checkingPassword   {     passwordGood loggedIn startUserProcess     passwordBad notifyingPasswordBad displayBadPasswordScreen     thirdBadPassword screenLocked displayLockScreen   }   notifyingPasswordBad   {     OK checkingPassword displayLoginScreen     cancel init clearScreen   }   screenLocked   {     enter checkingAdminPassword checkAdminPassword   }   checkingAdminPassword   {     passwordGood init clearScreen     passwordBad screenLocked displayLockScreen   } }

What we've done here is to capture the high-level policy of the application in a state machine. This high-level policy lives in one place and is easy to maintain. It vastly simplifies the rest of the code in the system, because that code is not mixed with the policy code.

Clearly, this approach can be used for interfaces other than GUIs. Indeed, I have used similar approaches for textual and machine/machine interfaces as well. But GUIs tend to be more complex than those others, so the need for them, and the volume of them, is greater.

GUI Interaction Controllers

Imagine that you want to allow your users to draw rectangles on the screen. The gestures they use are as follows. A user clicks the rectangle icon in the pallet window, positions the mouse in the canvas window at one corner of the rectangle, presses the mouse button, and drags the mouse toward the desired second corner. As the user drags, an animated image of the potential rectangle appears on the screen. The user manipulates the rectangle to the desired shape by continuing to hold the mouse button down while dragging the mouse. When the rectangle is right, the user releases the mouse button. The program then stops the animation and draws a fixed rectangle on the screen.

Of course, the user can abort this at any time by clicking a different pallet icon. If the user drags the mouse out of the canvas window, the animation disappears. If the mouse returns to the canvas window, the animation reappears.

Finally, having finished drawing a rectangle, the user can draw another one simply by clicking and dragging again in the canvas window. There is no need to click the rectangle icon in the pallet.

What I have described here is a FSM. The state transition diagram appears in Figure 36-5. The solid circle with the arrow denotes the starting state of the state machine.[4] The solid circle with the open circle around it is the final state of the machine.

[4] See Chapter 13, "State Diagrams."

Figure 36-5. Rectangle interaction state machine


GUI interactions are rife with FSMs. They are driven by the incoming events from the user. Those events cause changes in the state of the interaction.

Distributed Processing

Distributed processing is yet another situation in which the state of the system changes based on incoming events. For example, suppose that you had to transfer a large block of information from one node on a network to another. Suppose also that because network response time is precious, you need to chop up the block and send it as a group of small packets.

The state machine depicting this scenario is shown in Figure 36-6. It starts by requesting a transmission session, proceeds by sending each packet and waiting for an acknowledgment, and finishes by terminating the session.

Figure 36-6. Sending large block, using many packets





Agile Principles, Patterns, and Practices in C#
Agile Principles, Patterns, and Practices in C#
ISBN: 0131857258
EAN: 2147483647
Year: 2006
Pages: 272

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net