On Reflection.

SMC v. 4.3.0 introduces the -reflect command line option for the Java, C#, Perl, PHP, Python, Ruby, Tcl and VB.Net programming languages. This option tells SMC to generate for each state class either a getTransitions method or a Transitions property for C# and VB.Net. In both cases the method/property returns the state's defined transitions as a map. The map key is a transition name with an integer value.

SMC v. 6.0.1 adds the ability to retrieve a list of all states in the finite state machine.

The method definitions are:

The transition's associated integer value is limited to:

  1. The transition is undefined in the current state.
  2. The transition is defined in the current state.
  3. The transitions is defined in the default state.

This allows an application to discover which transitions a state supports.

Note: the returned transition names map includes the Default transition.

This feature is most useful for user interface developers who need to activate and deactivate features based on the current state. The user's actions are limited to the current state's transitions.

Reminder: You cannot call getState() while in a transition because the state is not set. If need to determine which state you just left while in transition. call getPreviousState().

Java Sample

import java.util.Iterator; import java.util.Map; public void processEvent(EventObject event) {
// Transform this event into a FSM transition:
if (event instanceof OpenEvent) { _fsm.openFile((OpenEvent) event); } else if ... { }
// Now figure out what features are active // and inactive based on the current state's returned transition map.
Map<String, Integer> transitions = (_fsm.getState()).getTransitions(); String transition; int status; for (Map.Entry<String, Integer> entry: transitions.entrySet()) { transition = entry.getKey(); status = (entry.getValue()).intValue();
// Ignore the Default transition.
if (transitions.equals("Default") == true) {
// no-op
}
// 0 - transition is undefined. // 1 - transition is explicity defined in the state. // 2 - transition is defined in Default state.
else if (status == 0) {
// Deactivate feature.
} else if (status == 1) {
// Activate feature.
} else {
// Do something else for default definitions.
} } }

C# Sample

using System.Collections.Generic; public void processEvent(Object event) {
// Transform this event into a FSM transition:
if (event is OpenEvent) { _fsm.openFile(event); } else if ...
// Now figure out what features are active // and inactive based on the returned transition map.
IDictionary<string, int> transitions = (_fsm.getState()).Transitions; int status; foreach (string name in transitions.Keys) { status = transitions[name];
// Ignore the Default transition.
if (name == "Default") {
// no-op
}
// 0 - transition is undefined. // 1 - transition is explicity defined in the state. // 2 - transition is defined in Default state.
else if (status == 0) {
// Deactivate feature.
} else if (status == 1) {
// Activate feature.
} else {
// Do something else for default definitions.
} } }

Tcl Sample

Using System.Collections public method ProcessEvent{event} {
# Transform this event into a FSM transition:
if {$event = "open"} { _fsm.Open() } elseif {...} { ... }
# Now figure out what features are active # and inactive based on the returned transition map.
foreach {name status} [[_fsm getState] transitions] {
# Ignore the Default transition. # 0 - transition is undefined. # 1 - transition is explicity defined in the state. # 2 - transition is defined in Default state.
if {$name = "Default"} {
# no-op
} elseif {$status = 0} {
# Deactivate feature.
} elseif {$status = 1} {
# Activate feature.
} else {
# Do something else for default definitions.
} } }