alinz / fsm.go

a finite state machine in Golang

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

fsm.go

fsm is a finite state machine implemented in Golang. This library was implemented as I needed a time base finite state machine to implement p2p network protocol.

Installation

Since this library only requires a single file, I would suggest copy that file and place it under internal/fsm folder for your project. However if you don't want that you can use go get and add it under your go.mod,

go get github.com/alinz/fsm.go

Usage

The best way to show the usage is by showing an example.

let's say we want to model a toggle button. There are 2 states a button can be at any time, on and off.

let's create a file call button.go under button folder

package button

import (
  "github.com/alinz/fsm.go"
)

const (
  EvtToggle = fsm.Event("toggle") // define a toggle event
)

const (
  _ fsm.State = iota // we always ignore the first one as State can't be zero
  On  // store 1
  Off // store 2
)

func NewFSM() (*fsm.Machine, error) {
  m, err := fsm.NewMachine(fsm.Config{
    // define the initial state of machine, which in this case it would be Off
    Initial: off,
    States: fsm.States{
      // define the first state which is On
      {
        Ref: On,
        // define list of all events and their corresponding states
        On: fsm.On{
        {
          // once this machine receives EvtToggle, it
          // switch to Off state
          Event: EvtToggle,
          Targets: fsm.Targets{
            {
              Target: Off,
            },
          },
        },
        },
      },
      // define the first state which is Off
      {
        Ref: Off,
        On: fsm.On{
          {
            // once this machine receives EvtToggle, it
            // switch to On state
            Event: EvtToggle,
            Targets: fsm.Targets{
              {
                Target: On,
              },
            },
          },
        },
      },
    },
  })

  return m, err
}

now in your main file,

package main

import (
  "github.com/alinz/fsm.go"

  "example.com/internal/button"
)

func main() {
  machine, err := button.NewFSM()
  if err != nil {
    panic(err)
  }

  fmt.Println(machine.State()) // should print out initial state which is Off

  // let's send an event
  err = machine.Send(button.EvtToggle)
  // Send function might return `fms.ErrNoop` if the given event doesn't change the state
  // of the system
  if err != nil && err != fsm.ErrNoop {
    panic(err)
  }

  fmt.Println(machine.State()) // should print out On state
}

For more examples, please look into fsm.test.go

About

a finite state machine in Golang

License:MIT License


Languages

Language:Go 100.0%