fsa.pm 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #!/usr/bin/perl
  2. # Конечный автомат для телеграм-бота
  3. # Ю. Жиловец, 20.08.2024
  4. use Modern::Perl;
  5. use utf8;
  6. use Mojo::Base -strict, -signatures, -async_await;
  7. package fsa;
  8. sub new($class, $rules, $state, $notes={})
  9. {
  10. $notes->{_state} = $state;
  11. bless {rules=>$rules, notes=>$notes}, $class;
  12. }
  13. sub state($self, $new_state=undef)
  14. {
  15. if (defined($new_state))
  16. {
  17. die "Unknown state '$new_state" unless exists $self->{rules}->{$new_state};
  18. $self->note(_state => $new_state);
  19. }
  20. $self->{notes}->{_state};
  21. }
  22. sub note($self, $key, $val=undef)
  23. {
  24. if (defined $val)
  25. {
  26. $self->{notes}->{$key} = $val;
  27. }
  28. $self->{notes}->{$key};
  29. }
  30. sub notes($self)
  31. {
  32. $self->{notes};
  33. }
  34. sub delete_note($self, $key)
  35. {
  36. delete $self->{notes}->{$key};
  37. }
  38. async sub switch
  39. {
  40. my ($self, $line, @rest) = @_;
  41. my $state = $self->{notes}->{_state};
  42. my $rule = $self->{rules}->{$state};
  43. die "fsa::switch: no rule for '$state'" unless $rule;
  44. my $new_state = $rule->($self, $line, @rest);
  45. $new_state = await $new_state if ref $new_state && $new_state->can("then");
  46. $new_state ||= $self->{notes}->{_state};
  47. use Data::Dumper;
  48. say Dumper $new_state;
  49. die "fsa::switch: unknown new state '$new_state'" unless exists $self->{rules}->{$new_state};
  50. $self->note("_state", $new_state);
  51. $new_state;
  52. }
  53. 1;