Copyright (C) 2008 North State Software, LLC using System; using System.Collections.Generic; using System.Text; using System.Threading; using NorthStateFramework; namespace CommandProcessorExample { public class CommandProcessor : NSFStateMachine { #region Fields private Queue commandQueue = new Queue(); private Queue responseQueue = new Queue(); private NSFEvent responseTimeoutEvent; private NSFInitialState initialState; private NSFCompositeState waitForCommandState; private NSFCompositeState waitForResponseState; private NSFCompositeState errorState; #endregion Fields #region Constructors public CommandProcessor(String name, ThreadPriority priority) : base(name, new NSFEventThread(name, priority)) { // Events responseTimeoutEvent = new NSFEvent("ResponseTimeout", this, this); // Regions and States initialState = new NSFInitialState("Initial", this); waitForCommandState = new NSFCompositeState("WaitForCommand", this, null, null); waitForResponseState = new NSFCompositeState("WaitForResponse", this, waitForResponseEntryActions, waitForResponseExitActions); errorState = new NSFCompositeState("Error", this, errorEntryActions, null); // Transitions new NSFExternalTransition(initialState, waitForCommandState, null, null, null); new NSFExternalTransition(waitForCommandState, waitForResponseState, null, hasCommand, sendCommand); new NSFExternalTransition(waitForResponseState, waitForCommandState, null, hasResponse, handleResponse); new NSFExternalTransition(waitForResponseState, errorState, responseTimeoutEvent, null, null); } #endregion Constructors #region Methods public void addCommand(string newCommand) { commandQueue.Enqueue(newCommand); forceStateMachineEvaluation(); } public void addResponse(string newResponse) { responseQueue.Enqueue(newResponse); forceStateMachineEvaluation(); } private bool hasCommand(NSFState source, NSFStateEventArgs eventArgs) { return (commandQueue.Count != 0); } private bool hasResponse(NSFState source, NSFStateEventArgs eventArgs) { return (responseQueue.Count != 0); } private void sendCommand(NSFState source, NSFStateEventArgs eventArgs) { // Code to send the command goes here // ... // Log trace of command sent NSFTraceLog.logTrace(NSFTraceTags.messageSentTag, NSFTraceTags.sourceTag, this.Name, NSFTraceTags.messageTag, commandQueue.Dequeue()); } private void waitForResponseEntryActions(NSFState source, NSFStateEventArgs eventArgs) { // Schedule timeout event in 1000 mS, in case no response received responseTimeoutEvent.schedule(1000, 0); } private void waitForResponseExitActions(NSFState source, NSFStateEventArgs eventArgs) { // Unschedule the timeout event responseTimeoutEvent.unschedule(); } private void handleResponse(NSFState source, NSFStateEventArgs eventArgs) { // Code to handle the response goes here // ... // Log trace of command sent NSFTraceLog.logTrace(NSFTraceTags.messageReceivedTag, NSFTraceTags.sourceTag, this.Name, NSFTraceTags.messageTag, responseQueue.Dequeue()); } private void errorEntryActions(NSFState source, NSFStateEventArgs eventArgs) { // Code to handle the error goes here // ... } #endregion Methods } }