Getting Noticed.

SMC uses the Java Bean event notification and .Net event raising features to inform listeners when an SMC-generated finite state machine changes state. The following sample code demonstrates how to use this feature in Java, C#,, Groovy and Scala.

Java Sample

SMC uses Java Beans package for state change notification. statemap.FSMContext defines the addStateChangeListener and removeStateChangeListener methods. Because the SMC-generated FSMContext subclass is privately contained within an application class, it will be necessary to expose the add, remove methods by adding these methods to the application class.

Note: Because applications use multiple state machines and a state change handler may register with multiple FSMs, I have added the methods FSMContext.getName() and FSMContext.setName(String). This name should be set and used to distinguish between FSMs.

import java.beans.PropertyChangeListener; public class AppClass {
//--------------------------------------------------------------- // Member methods. //
... public void addStateChangeListener(PropertyChangeListener listener) { _fsm.addStateChangeListener(listener); return; } public void removeStateChangeListener(PropertyChangeListener listener) { _fsm.removeStateChangeListener(listener); return; }
//--------------------------------------------------------------- // Member data. //
... private final AppClassContext _fsm; }
// end of class AppClass

Implement the java.beans.PropertyChangeListener interface and pass that implementation to AppClass.addStateChangeListener. When the AppClass finite state machine changes state, the listener receives a java.beans.PropertyChangeEvent containing:

import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import statemap.FSMContext; import statemap.State; public class StateChangeListener implements PropertyChangeListener {
//--------------------------------------------------------------- // Member methods. //
... public void propertyChange(PropertyChangeEvent event) { FSMContext fsm = (FSMContext) event.getSource(); String propertyName = event.getPropertyName(); State previousStatus = (State) event.getOldValue(); State newState = (State) event.getNewValue();
// Handle the state change event.
System.out.println( "FSM " + fsm.getName() + " went from " + previousState + " to " + newState + "."); return; } }
// end of class StateChangeListener

Register the StateChangeListener with the FSM as follows:

StateChangeListener listener = new StateChangeListener(); AppClass appInstance = new AppClass(); appInstance.addStateChangeListener(listener);
Note: Groovy and Scala also use Java Bean event notification.

C# Sample

.Net events required listeners to register an event directly with the event-raising object. For SMC, the finite state machine class FSMContext does the event raising. But the context class should be kept private within the application class. The following code shows how to add and remove state change listeners indirectly, leaving the FSM inaccessible.

The StateChangeEventArgs data methods are:

Note: Because applications use multiple state machines and a state change handler may register with multiple FSMs, I have added the property FSMContext.Name. This name is placed into StateChangeEventArgs to allow ready identification of which FSM changed state. The default state name is "FSMContext".

use System; use statemap; public class AppClass { .... public void AddStateChangeHandler(StateChangeEventHandler handler) { _fsm.StateChange += handler; return; } public void RemoveStateChangeHandler(StateChangeEventHandler handler) { _fsm.StateChange -= handler; return; } }

If a class wishes to receive state change events, then it must implement a method with the following signature. Note: the method does not have to be named StateChanged.

use System; use statemap; public class StateChangeHandler { public void StateChanged(object sender, StateChangeEventArgs args) {
//Handle the state change event.
Console.WriteLine("FSM " + args.FSMName() + " " + args.TransitionType() + " transition from " + args.PreviousState() + " to " + args.NewState() + "."); return; } }

Register the state change handler instance with the FSM as follows:

StateChangeHandler handler = new StateChangeHandler(); AppClass appInstance = new AppClass(); appInstance.AddStateChangeHandler(new StateChangeEventHandler(handler.StateChange));

VB.Net Sample

State change event handlers register indirectly via these application class methods (which you must add to your code).

Public Class AppClass ... Public Sub AddStateChangeHandler(handler As statemap.StateChangeEventHandler) AddHandler _fsm.StateChange, handler End Sub Public Sub RemoveStateChangeHandler(handler As statemap.StateChangeEventHandler) RemoveHandler _fsm.StateChange, handler End Sub End Class

If a class wishes to receive state change events, then it must implement a method with the following signature.

See the C# sample for more about StateChangeEventArgs.

Imports System Imports statemap Public Class StateChangeHandler ... Public Sub StateChange(sender As Object, e As StateChangeEventArgs) Console.Write("FSM ") Console.Write(e.FSMName()) Console.Write(" ") Console.Write(e.TransitionType()) Console.Write(" transition from ") Console.Write(e.PreviousState()) Console.Write(" to ") Console.Write(e.NewState()) Console.WriteLine(".") End Sub End Class

Register the state change handler with the FSM as follows:

Dim handler As StateChangeHandler = new StateChangeHandler() Dim appInstance As AppClass = new AppClass() appInstance.addStateChangeHandler(AddressOf handler.StateChange)