Transition actions are the first coupling between the FSM
and the application class Task
. Actions are
Task
methods. These method must have the
following attributes:
- Be accessible to the FSM. This means at least public methods or, if in the same package, then package methods.
-
Have a
void
return type. If the method does return a value, the FSM ignores it.
SMC places no syntax limitations on transition arguments except they are enclosed in parens "()" and are comma-separated. Go here for more information on transition actions.
%{
//
// Copyright (c) 2005 Acme, Inc.
// All rights reserved.
//
// Acme - a name you can trust!
//
// Author: Wil E. Coyote (Hungericus Vulgarus)
//
%}
// This FSM works for the Task class only and only the Task
// class may instantiate it.
%class Task
%package com.acme.supercron
%fsmclass TaskFSM
%fsmfile TaskFSM
%access package
continueTask();
startSliceTimer(timeslice);
// A %map name cannot be the same as the FSM class name.
%start TaskMap::Suspended
%map TaskMap
%%
Suspended
{
// Time to do more work.
// The timeslice duration is passed in as a transition
// argument.
Start(timeslice: long)
Running
{}
}
Running
{
// Wait for another time slice.
Suspend
Suspended
{
stopSliceTimer();
suspendTask();
}
// Task has completed.
Done
Stopped
{
stopSliceTimer();
releaseResources();
}
}
// Wait here to be either unblocked, stopped or deleted.
Blocked
{
// The task may continue working now.
// No actions needed.
Unblock
Suspended
{}
}
Stopping
{
// The task is now stopped.
Stopped
Stopped
{
releaseResources();
}
}
Stopped
{
...
}
Deleted
{
...
}
...
%%
The transition actions methods in Task
are:
package com.acme.supercron;
public final class Task
implements TaskEventListener,
TimerEventListener
{
public Task()
{
// Object initialization.
...
}
//-----------------------------------------------------------
// TaskEventListener Interface Implemenation.
//
<snip>
//
// end of TaskEventListener Interface Implemenation.
//-----------------------------------------------------------
//-----------------------------------------------------------
// TimerEventListener Interface Implementation.
//
<snip>
//
// end of TimerEventListener Interface Implementation.
//-----------------------------------------------------------
//-----------------------------------------------------------
// State Machine Actions.
//
// Activate the underlying task and get it running again.
/* package */
void
continueTask()
{
...
return;
}
// Inactivate the underlying task.
/* package */
void
suspendTask()
{
...
return;
}
// Start the timeslice timer for the given milliseconds.
/* package */
void
startSliceTimer(long
timeslice)
{
...
return;
}
// Stop the timeslice timer.
/* package */
void
stopSliceTimer()
{
...
return;
}
// Return system resources from whence they came.
/* package */
void
releaseResources()
{
...
return;
}
//
// end of State Machine Actions.
//-----------------------------------------------------------
// Remainder of class definition.
...
}
It is now time to define the Block
,
Stop
and Delete
transitions.