On Sep 15, 2009, at 6:42 PM, Chuck Hackett wrote:
>> From: Ned Konz
>> ....
>> I prefer the Quantum Platform package; it supports hierarchical state
>> machines, has an AVR port available, and skips the separate
>> representation of the state machine (i.e. it is not table based). So
>> its RAM footprint is very small.
>>
>> http://state-machine.com
>> ....
>
> In my current need, the SMs are table based and (possibly) changed
> at run
> time.
>
> I've noted it for future reference ... thanks.
Do you need:
- hierarchical states?
- Actions on transitions?
- Guards on transitions? (of course, this can be put in external code)
- Arbitrary code executed for actions, or could you call pre-
existing functions with arguments of your specification?
- "do" actions (periodically, while in a state)? Or could these be a
response to a timer event?
You might look at: Micah Martin's Statemachine framework for Ruby http://statemachine.rubyforge.org
and at http://blog.8thlight.com/articles/2006/11/17/understanding-statemachines-part-1-states-and-transitions
This can be installed (once you have Ruby installed) by just saying:
gem install statemachine
This will let you skip the yacc/lex stuff, and just use Ruby as the
interpreter and compiler.
The package provides:
- hierarchical state machine definition
- entry and exit actions for states
- default action for states
- states and events are just names
- actions are just names
The attached is an example of generation (in this case, it makes C
structure definitions, but it could easily make any binary format you
want).
It takes this source text:
$vending_machine = Statemachine.build do
trans :waiting, :dollar, :paid, :indicatePaid
trans :paid, :selection, :waiting, :vend
trans :waiting, :selection, :waiting
trans :paid, :dollar, :paid
end
$stateIds = { :root => 1, :waiting => 2, :paid => 3 }
$stateIds.default = 0
$eventIds = { :dollar => 1, :selection => 2 }
$eventIds.default = 0
$actionIds = { :indicatePaid => 1, :vend => 2 }
$actionIds.default = 0
and produces this C code (hypothetical structs for state and
transition):
struct state states[] = {
// state waiting, super root
{ .id = 2, .superstate = 1,
.entry_action = 0, .exit_action 0,
// transitions
.transitions = {
// transition on event selection from waiting to waiting (action=)
{ .event = 2, .destination_id = 2, .action = 0 },
// transition on event dollar from waiting to paid
(action=indicatePaid)
{ .event = 1, .destination_id = 3, .action = 1 },
}},
// state paid, super root
{ .id = 3, .superstate = 1,
.entry_action = 0, .exit_action 0,
// transitions
.transitions = {
// transition on event selection from paid to waiting (action=vend)
{ .event = 2, .destination_id = 2, .action = 2 },
// transition on event dollar from paid to paid (action=)
{ .event = 1, .destination_id = 3, .action = 0 },
}},
}
As you can see, all the representation of your state machine is here
(or could be, if I'd finished it).
All you would need to do is extend the state and statemachine classes
to be able to output whatever representation you wanted to execute
(like I did here with C code generation) and maybe add arguments to
actions (if needed).
----------
Ned Konz
[Non-text portions of this message have been removed]