bbgo_origin/pkg/interact/command.go

90 lines
2.1 KiB
Go
Raw Permalink Normal View History

2022-01-13 14:15:05 +00:00
package interact
import "strconv"
// Command is a domain specific language syntax helper
// It's used for helping developer define the state and transition function
type Command struct {
// Name is the command name
Name string
2022-01-13 18:57:39 +00:00
// Desc is the command description
Desc string
2022-01-13 14:15:05 +00:00
// StateF is the command handler function
F interface{}
stateID int
states map[State]State
statesFunc map[State]interface{}
initState, lastState State
}
2022-01-13 18:57:39 +00:00
func NewCommand(name, desc string, f interface{}) *Command {
2022-01-13 14:15:05 +00:00
c := &Command{
Name: name,
2022-01-13 18:57:39 +00:00
Desc: desc,
2022-01-13 14:15:05 +00:00
F: f,
states: make(map[State]State),
statesFunc: make(map[State]interface{}),
initState: State(name + "_" + strconv.Itoa(0)),
}
return c.Next(f)
}
// Transit defines the state transition that is not related to the last defined state.
func (c *Command) Transit(state1, state2 State, f interface{}) *Command {
c.states[state1] = state2
c.statesFunc[state1] = f
return c
}
2022-01-13 16:17:41 +00:00
func (c *Command) NamedNext(n State, f interface{}) *Command {
2022-01-13 14:15:05 +00:00
var curState State
if c.lastState == "" {
curState = State(c.Name + "_" + strconv.Itoa(c.stateID))
} else {
curState = c.lastState
}
2022-01-13 16:17:41 +00:00
nextState := n
2022-01-13 14:15:05 +00:00
c.states[curState] = nextState
c.statesFunc[curState] = f
c.lastState = nextState
return c
}
2022-01-14 19:06:36 +00:00
func (c *Command) Cycle(f interface{}) *Command {
var curState State
if c.lastState == "" {
curState = State(c.Name + "_" + strconv.Itoa(c.stateID))
} else {
curState = c.lastState
}
nextState := curState
c.states[curState] = nextState
c.statesFunc[curState] = f
c.lastState = nextState
return c
}
2022-01-13 14:15:05 +00:00
// Next defines the next state with the transition function from the last defined state.
func (c *Command) Next(f interface{}) *Command {
var curState State
if c.lastState == "" {
curState = State(c.Name + "_" + strconv.Itoa(c.stateID))
} else {
curState = c.lastState
}
// generate the next state by the stateID
c.stateID++
nextState := State(c.Name + "_" + strconv.Itoa(c.stateID))
c.states[curState] = nextState
c.statesFunc[curState] = f
c.lastState = nextState
return c
}