| Graph-Easy-StateMachine documentation | view source | Contained in the Graph-Easy-StateMachine distribution. |
Graph::Easy::StateMachine - create a FSA framework from a Graph::Easy graph
Create state machine classes, also known as a FSA or a DFSA, from a state machine description in Graph::Easy's graph description language. States, and their methods, are available in derived classes that use it too.
use Graph::Easy::StateMachine;
my $graph = Graph::Easy->new( <<FSA );
[ BASE ] = EnterStateMachine =>
[ START ] => [ disconnected ]
= goodconnect => [ inprogress ]
= goodconnect => [ connected ]
= sentrequest => [ requestsent ]
= readresponse => [ haveresponse ]
= done => [ END ]
# Try pasting this into the form
# at http://bloodgate.com/graph-demo
[ disconnected ], [ inprogress ], [connected ] ,
[ requestsent ] , [ haveresponse ]
-- whoops --> [FAIL] -- LeaveStateMachine --> [BASE]
FSA
eval $graph->as_FSA( base => 'SelectableURLfetcher')
or die "FSA parser failure: $@";
Alternately, use the import method to eval the FSA for you.
package SelectableURLfetcher;
use Graph::Easy::StateMachine <<FSA;
[ BASE ] = EnterStateMachine =>
[ START ] => [ disconnected ]
= goodconnect => [ inprogress ]
= goodconnect => [ connected ]
= sentrequest => [ requestsent ]
= readresponse => [ haveresponse ]
= done => [ END ]
# Try pasting this into the form
# at http://bloodgate.com/graph-demo
[ disconnected ], [ inprogress ], [connected ] ,
[ requestsent ] , [ haveresponse ]
-- whoops --> [FAIL] -- LeaveStateMachine --> [BASE]
FSA
This module adds a new layout engine to Graph::Easy. The as_FSA layout engine produces evaluatable perl code implementing the graph as a set of namespaces each containing methods for all transitions to other states.
Absent a label on an edge from [A] to [B], state A's method to transition
to state B is called B.
Node names represent states, labeled edges are aliases for the enter methods.
In the example in the previous section, the
SelectableURLfetcher::disconnected::goodconnect method reblesses
a SelectableURLfetcher::disconnected object into the SelectableURLfetcher::inprogress
package, while the SelectableURLfetcher::inprogress::goodconnect method reblesses
an inprogress object into the connected state. That is, states are represented
by packages, and transitioning occurs by reblessing the object.
Graphs presented to as_FSA must have uniquely named edges.
[A] - next -> [B] [A] - next -> [C]
is a syntax error and will croak.
single inheritance from the base class and transition methods are all that gets defined. You have to set up your own convention for using them. Something like
for (@AsyncObjects) {
$_->OnEntry();
$_->${ $_->run ? \'HappyPath' : \'Problem' }()
}
As of version 0.06, state namespaces now inherit from the equivalent namespace in all parent classes.
When a base class of other derived classes has state machine classes
and methods
associated with it via this tool invoked by presenting the graphs on
the use line (yes, graphs. Transitions described in later graphs will
clobber transitions in earlier graphs.) derived classes may bring in
the state machines from their parent classes like so
package MyDerivedStatelyClass; use base MyParentStatelyClass; use Graph::Easy::StateMachine;
When the derived class has some variation in its state machine,
the variation is all that needs to be enumerated. When a parent
class has a state class, such as ExampleParent::UNVERIFIED, and
a child class uses this module, the resulting ExampleChild::UNVERIFIED
package will list ExampleParent::UNVERIFIED in its @ISA list,
so a method such as
sub ExampleParent::UNVERIFIED::isVerified{0}
will be available to objects in the ExampleChild::UNVERIFIED
state class.
This works by reevaluating all the graphs from the superclasses with regard to the the current package. No facility is made for state transitions between BASE classes.
as_FSA takes named parameters that control the produced source code.
Altering these is not supported when specifying graphs on the use line.
the base parameter specifies the name space prefix
for the state machine class system. When base is not specified, the current
package is used.
the BASESTATE parameter reserves a state to indicate transitioning to the
base package. When not specified, the default is BASE. While invalid transitions
will normally throw perl runtime "Can't locate object method" errors, attempts
to call invalid transition methods that are valid from the base state
throw "invalid transition" errors.
before adding the bit to as_FSA that enumerates all the methods that can be used to transition from the base state into the state machine, it would have been necessary to explicitly list all the entry methods to prevent inheritance from allowing them in all states.
package Acme::Bibbity::Bobbity::Boo;
use Graph::Easy::StateMachine <<FSA;
[BASE] - getwand -> [HAVEWAND]
[ PLAINDRELLA ] - domagic -> [FANCYDRELLA]
- domagic -> [ATBALL]
- midnight -> [REPUMPKINIZING]
[BASE] - BeDrella -> [PLAINDRELLA]
[PLAINDRELLA],[FANCYDRELLA] - getwand -> [ERROR]
...
FSA
in version 0.03, transitions from BASE are noted and all states
get their own set of methods that throw errors if they haven't
got an entry method. By entry method I mean a method that
transitions from BASE into a state class. In the example above,
getwand and BeDrella are entry methods.
writes the as_FSA method into Graph::Easy's name space.
Original version
switched from enter_X to the simpler X for the default transition method name
added invalid method error-throwers
inheritance
syntax check for ambiguous edges
added inheritance from existing state classes in parents
http://en.wikipedia.org/wiki/Finite_state_automata for theory. Also http://en.wikipedia.org/wiki/Automata-based_programming and http://en.wikipedia.org/wiki/Event-driven_programming
Graph::Easy for how to create your graph
Please use http://rt.cpan.org to report bugs and share patches
This tool is copyright (C) 2009 by David Nicol <davidnico@cpan.org>; The FSA source code generated with it is copyrightable by whoever wrote the graph.
| Graph-Easy-StateMachine documentation | view source | Contained in the Graph-Easy-StateMachine distribution. |