Acme-FSM
view release on metacpan or search on metacpan
B<switch()> is invoked with no arguments
(B<switch()> of previous I<{state}> should have took care).
Whatever I<$item> could be returned is ignored.
Whatever I<$rule> could be returned is reported (at I<(basic trace)> level)
but otherwise ignored.
Then I<$action> is returned and state flow terminates.
=back
Supported I<$action>s (in alphabetical order):
=over
=item C<NEXT>
Drop whatever I<$item> at hands.
Request another.
If FST has such record:
somestate => { eturn => [ somestate => 'NEXT' ] }
then FSM will stay in C<somestate> as long as I<source()> callback returns
C<undef>.
Thus consuming all resources available.
No options provided to limit that consumption.
=item C<SAME>
Retains I<$item> uncoditionally.
That is, even if I<$item> isn't B<defined> it's kept anyway.
B<Beware>, if FST has such record:
somestate => { eturn => [ somestate => 'SAME' ] }
then FSM will cycle here forever.
That is, since I<source()> isn't queried for other I<$item>
(what's the purpose of this action is anyway)
there's no way to get out.
=item C<TSTL>
Check if I<$item> is B<defined>, then go as with C<SAME> or C<NEXT> otherwise.
That actually makes sense.
I<(note)> This action name is legacy of B<DMA::Misc::FSM>;
Possibly, that's C<TeST> something;
Someone can just speculate what C<L> could mean.
=back
=back
=cut
sub process {
my $self = shift @_;
my( $branch, $turn );
# XXX:202201072033:whynot: C<START> and C<CONTINUE> being handled specially is a side-effect of this extra sequence. Should be moved in the main loop with special handling. This results in there-be-dragons uncertainty.
$self->diag( 3, q|{%s}(%s): entering|, $self->state, $self->action );
$branch = $self->query_switch;
$turn = $self->turn( $self->state, $branch );
$self->diag( 5, q|{%s}(%s): switch returned: (%s)|, @$turn, $branch );
$self->state( $turn->[0] );
$self->action( $turn->[1] );
my( $item, $dump ) = $self->query_source;
$self->diag( 3, q|{%s}(%s): %s: going with|, @$turn, $dump );
# No one gets out of this loop without the state tables permission!
while ( 1 ) {
# We should never see an undefined state unless we've made a mistake.
# NOTE:202201072131:whynot: As a matter of fact, we don't now.
$self->verify( $self->fst( $self->state ),
$self->state, '', q|record|, q|HASH| );
( $branch, $item ) = $self->query_switch( $item );
$self->diag( 5, q|{%s}(%s): switch returned: (%s)|, @$turn, $branch );
$dump = $self->query_dumper( $item );
$turn = $self->turn( $self->state, $branch );
$self->diag( 3, q|{%s}(%s): %s: turning with|,
$turn->[0], $branch, $dump );
$self->state( $turn->[0] );
$self->action( $turn->[1] );
$self->diag( 5, q|{%s}(%s): going for|, @$turn );
$turn->[0] eq q|STOP| and last;
$turn->[0] eq q|BREAK| and last;
$turn->[1] eq q|SAME| and redo;
$turn->[1] eq q|NEXT| and next;
$turn->[1] eq q|TSTL| && defined $item and redo;
$turn->[1] eq q|TSTL| and next;
croak sprintf q|[process]: {%s}(%s): unknown action|, @$turn }
continue {
( $item, $dump ) = $self->query_source;
$self->diag( 5, q|{%s}(%s): %s: going with|, @$turn, $dump ) }
$self->diag( 3, q|{%s}(%s): leaving|, @$turn );
# XXX:20121231215139:whynot: Nothing to B<verify()>, leaving anyway.
$branch = $self->query_switch;
$self->diag( 5, q|{%s}(%s): switch returned: (%s)|, @$turn, $branch );
$self->diag( 3, q|{%s}(%s): changing state: (CONTINUE)|, @$turn )
->state( q|CONTINUE| ) if $turn->[0] eq q|BREAK|;
return $self->action }
=head1 METHODS AND STUFF
Access and utility methods to deal with various moves while doing The State
Flow.
These aren't forbidden for use from outside,
while being quite internal nevertheles.
=over
=cut
=item B<verify()>
( run in 0.334 second using v1.01-cache-2.11-cpan-7fcb06a456a )