transition_callbacks.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "github.com/looplab/fsm"
  7. )
  8. func main() {
  9. var afterFinishCalled bool
  10. cbs := make(fsm.Callbacks)
  11. for _, name := range []string{
  12. // Events: before, after
  13. "run",
  14. "finish",
  15. "reset",
  16. // States: enter, leave
  17. "start",
  18. "end",
  19. "finished",
  20. } {
  21. for _, op := range []string{"before_", "after_", "leave_", "enter_"} {
  22. cbs[op+name] = func(ctx context.Context, event *fsm.Event) {
  23. log.Printf("%s", op+name)
  24. }
  25. }
  26. }
  27. cbs["enter_end"] = func(ctx context.Context, e *fsm.Event) {
  28. log.Println("enter end")
  29. if err := e.FSM.Event(ctx, "finish"); err != nil {
  30. fmt.Println(err)
  31. }
  32. }
  33. cbs["after_finish"] = func(ctx context.Context, e *fsm.Event) {
  34. log.Println("after finish")
  35. afterFinishCalled = true
  36. if e.Src != "end" {
  37. panic(fmt.Sprintf("source should have been 'end' but was '%s'", e.Src))
  38. }
  39. if err := e.FSM.Event(ctx, "reset"); err != nil {
  40. fmt.Println(err)
  41. }
  42. }
  43. machine := fsm.NewFSM(
  44. "start",
  45. fsm.Events{
  46. {Name: "run", Src: []string{"start"}, Dst: "end"},
  47. {Name: "finish", Src: []string{"end"}, Dst: "finished"},
  48. {Name: "reset", Src: []string{"end", "finished"}, Dst: "start"},
  49. },
  50. cbs,
  51. )
  52. if err := machine.Event(context.Background(), "run"); err != nil {
  53. panic(fmt.Sprintf("Error encountered when triggering the run event: %v", err))
  54. }
  55. if !afterFinishCalled {
  56. //panic(fmt.Sprintf("After finish callback should have run, current state: '%s'", machine.Current()))
  57. }
  58. currentState := machine.Current()
  59. if currentState != "start" {
  60. panic(fmt.Sprintf("expected state to be 'start', was '%s'", currentState))
  61. }
  62. fmt.Println("Successfully ran state machine.")
  63. //fmt.Println(fsm.VisualizeForMermaidWithGraphType(machine, fsm.StateDiagram))
  64. fmt.Println(fsm.VisualizeWithType(machine, fsm.GRAPHVIZ))
  65. }