funcNewFSM(initial string, events []EventDesc, callbacks map[string]Callback) *FSM { var f FSM f.current = initial f.transitions = make(map[eKey]string) f.callbacks = make(map[cKey]Callback)
// Build transition map and store sets of all events and states. allEvents := make(map[string]bool) allStates := make(map[string]bool) for _, e := range events { for _, src := range e.Src { f.transitions[eKey{e.Name, src}] = e.Dst allStates[src] = true allStates[e.Dst] = true } allEvents[e.Name] = true }
// Map all callbacks to events/states. for name, c := range callbacks { var target string var callbackType int
switch { case strings.HasPrefix(name, "before_"): target = strings.TrimPrefix(name, "before_") if target == "event" { target = "" callbackType = callbackBeforeEvent } elseif _, ok := allEvents[target]; ok { callbackType = callbackBeforeEvent } case strings.HasPrefix(name, "leave_"): target = strings.TrimPrefix(name, "leave_") if target == "state" { target = "" callbackType = callbackLeaveState } elseif _, ok := allStates[target]; ok { callbackType = callbackLeaveState } case strings.HasPrefix(name, "enter_"): target = strings.TrimPrefix(name, "enter_") if target == "state" { target = "" callbackType = callbackEnterState } elseif _, ok := allStates[target]; ok { callbackType = callbackEnterState } case strings.HasPrefix(name, "after_"): target = strings.TrimPrefix(name, "after_") if target == "event" { target = "" callbackType = callbackAfterEvent } elseif _, ok := allEvents[target]; ok { callbackType = callbackAfterEvent } default: target = name if _, ok := allStates[target]; ok { callbackType = callbackEnterState } elseif _, ok := allEvents[target]; ok { callbackType = callbackAfterEvent } }
if callbackType != callbackNone { f.callbacks[cKey{target, callbackType}] = c } }