Acme-FSM

 view release on metacpan or  search on metacpan

lib/FSM.pm  view on Meta::CPAN

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 )