Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/07/2011 in all areas

  1. There's been a lot of discussion about state machine patterns the last couple months. Admittedly a good part of it is because I'm so vocal in my dislike for the QSM, but Paul posted an excellent document recently and Justin and Norm pimped the JKI state machine and the TLB state machines respectively at NI Week. Last night I posted a broken example of an object-based state machine. This morning I was feeling guilty about it, so here's a version without the missing libraries. To reiterate from last night's post... ------------------------------ Here's a state machine for a Total Phase Beagle I2C monitor I recently put together using the pattern I described on Paul's other thread and Felix mentioned here. The benefit of having separate sections of code for entry, do/execution, exit, and transition actions can't (IMO) be overstated. It's way easier for me to understand and extend than any flavor of QSM. QSMs are further limited by the restriction of only performing entry actions and must repeatedly exit and reenter the same state. Notes: - Project code is available for LV 2009 or LV 2010. They are otherwise identical. - The project is dependent on the attached vip. Install it using VIPM before opening the project. - The attached vip is currently intended for LapDog developer use. Obviously you are free to use it, but it may not be compatible with future versions. It's an updated version of the library I posted here. (Please pay no mind to the really lame LapDog palette icon. I'm hoping someone comes up with something better.) - I replaced the original Beagle library with a ghost "BeagleApi" library. The vis in the ghost library are there simply for their connector panes--there's nothing in them. - There's not much documentation... I didn't expect to be sharing it yet. - The BeagleStateMachine class is the main public api. It contains the data required for the state machine to operate and shared accessors to that data for the state objects. - Each state is a separate class that derives from BaseState. - TestBeagleStateMachineLibrary is an example of how to use this state machine. Or you can build an Actor class around it. - The state diagram below is also on the bd of BeagleStateMachine:Execute. - If I ever get tempted to use a QSM again for anything non-trivial... please shoot me. The pain isn't worth it. [Edit 9-12] Uploaded a new copy of the 2010 version. The previous version was still attempting to link to a different MessageLibrary. lapdog_lib_message_library-0.7.0.1.vip BeagleStateMachine2009.zip BeagleStateMachine2010.zip
    1 point
  2. Just wanted to throw my $.02 behind Paul's comments. I've used a variation of the GoF State Machine pattern for several components and I'm quite liking it. (Is anyone surprised...?) One of the big problems I had with QSMs is that they don't really stay in any one 'state.' Even when there is no transition to another state the SM is exiting and re-entering the same state. Same thing, you say? Not when you start adding more strictly defined behaviors to your state machine. Every state in my SMs can define any of four different kinds of actions: 1. Entry Actions -- These are actions that are performed exactly once every time this state is entered from another state. 2. Execution Actions -- These are actions that are performed continuously while the SM remains in the current state. 3. Exit Actions -- These are actions that are performed exactly once just prior to this state exiting. 4. Transition Actions -- The are actions that are performed exactly once when this state exits and are unique for every 'current state-next state' combination. When looking at a state diagram, these actions are associated with the arrows. By recognizing these four different types of actions, it is much, much, easier for me to design and implement a state machine that does what I want it to do. I spend far less time fighting the implementation when trying to add an arbitrary new action. You can create a QSM that recognizes these four types of actions (my first experiments did) but I found it got pretty ugly pretty quickly and is error prone. Entry Actions and certain kinds of Execution Actions get particularly messy in a QSM. (Waiting actions do too.) I switched over to an object-based state machine and haven't looked back. I fully agree, and that is another major issue I have with the QSM. When you look at a state diagram the arrows not only define the transitions the SM does make, but also defines the transitions the SM is allowed to make. The SM defines and restricts it's own behavior; it doesn't depend on an external entity to know details about what states are "valid" to call from its current state. If there's no arrow, the SM simply won't transition from one to the other regardless of the command it received, because it's an invalid command. Leaving that responsibility to the external entity is error prone. QSMs allow far too much external control over the SM's internals. (In fact, I try to write my components in such a way that the SM client isn't even aware the implementation uses a state machine.)
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.