Acme-FSM
view release on metacpan or search on metacpan
The FST is just borrowed from source object during object construction.
Thus, in the synopsis, I<$bb3> and I<$bb2> use references to HASH
I<%$fst2>.
An idea behind this is to minimize memory footprint.
OTOH, maninpulations with one HASH are effectevely manipulations with FST of
any other copy-object that borrowed that FST.
IOW, anything behind FST HASH of class construction or options HASH of object
construction isa trailer and B<carp>ed.
Obviously, there's no trailer in class construction with list FST.
=cut
my @options = qw| diag_level namespace source dumper |;
sub connect {
my( $self, $opts ) = ( shift @_, shift @_ );
ref $opts eq q|HASH| or croak sprintf
q|[connect]: {options} HASH is required, got (%s) instead|, ref $opts;
my( $trailer, $leader );
if( ref $self eq '' ) {
$trailer = ref $_[0] eq q|HASH|;
$self = bless { _ => { fst => $trailer ? shift @_ : { @_ }}}, $self;
$leader = q|clean init with| }
else {
$trailer = @_;
$self = bless { _ => { %{$self->{_}} }}, ref $self;
$leader = q|stealing| }
$self->{_}{$_} = delete $opts->{$_} // $self->{_}{$_} foreach @options;
$self->{_}{diag_level} //= 1;
$self->diag( 3, q|%s (%i) items in FST|,
$leader, scalar keys %{$self->{_}{fst}} );
$self->carp( qq|($_): unknown option, ignored| ) foreach keys %$opts;
$self->carp( q|(source): unset| ) unless defined $self->{_}{source};
$trailer = ref $_[0] eq q|HASH| ? keys %{$_[0]} : @_ if $trailer;
$self->carp( qq|ignoring ($trailer) FST items in trailer| ) if $trailer;
$self->carp( q|FST has no {START} state| ) unless
exists $self->{_}{fst}{START};
$self->carp( q|FST has no {STOP} state| ) unless
exists $self->{_}{fst}{STOP};
@{$self->{_}}{qw| state action |} = qw| START VOID |;
return $self }
=head1 B<process()>
$bb = Acme::FSM->connect( { }, \%fst );
$rc = $bb->process;
This is heart, brains, liver, and so on of B<Acme::FSM>.
B<process()> is what does actual state flow.
That state flow is steered by records in I<%fst>.
Each record consists of:
=over
=item B<switch()> callback
This is some user supplied code that
always consumes whatever B<source()> callback returns (at some point in past),
(optionally) regurgitates said input,
and decides what I<[turn]> to go next.
Except when in special I<{state}> (see below) it's supplied with one argument:
I<$item>.
In special states I<$item> is missing.
B<switch()> returns two controls: I<$rule> and processed I<$item>.
What to do with returned I<$item> is determined by I<$action> (see below).
=item various I<[turn]>s
Each I<[turn]> spec is an ARRAY with two elements (trailing elements are
ignored).
First element is I<$state> to change to.
Second is I<$action> that sets what to do with I<$item> upon changing to named
I<$state>.
Here are known I<[turn]>s in order of logical treating decreasing.
=over
=item C<eturn>
That I<[turn]> will be choosen by FSM itself when I<$item> at hands is
C<undef>
(as returned by B<source()>).
I<switch()> isn't invoked -- I<$item> is void, there's nothing to call
I<switch()> with.
However, I<$action> may change I<$item>.
=item C<uturn>
That I<[turn]> will be choosen by FSM if I<$rule> is C<undef>
(as returned by B<switch()>).
Idea behind this is to give an FST an option to bailout.
In original B<DMA::FSM> that's not possible (except B<croak>ing, you know).
Also, see L<B<BUGS AND CAVEATS>|/Perl FALSE, undef, and uturn>.
=item C<tturn> and/or C<fturn>
If any (hence 'or') is present then I<$rule> returned by B<switch()> is
treated as Perl boolean, except C<undef> it's handled by C<uturn>.
That's how it is in original B<DMA::FSM>.
If B<switch()> always returns TRUE (or FALSE) then C<fturn> (or C<tturn>) can
be missing.
Also, see L<B<BUGS AND CAVEATS>|/tturn, fturn, and switch()>.
=item C<turns>
If neither C<tturn> nor C<fturn> is present then whatever I<$rule> would be
returned by B<switch()> is treated as string.
That string is supposed to be a key in I<%$turns>.
I<$rule> returned is forced to be string (so if you dare to return objects,
such objects should have C<""> overloaded).
Also, see L<B<BUGS AND CAEATS>|/Default For Turn Map>.
=back
I<$state> is treated as a key in FST hash, except when that's a special state.
Special states (in alphabetical order):
=over
=item C<BREAK>
( run in 1.169 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )