machine/transition.go

55 lines
1.3 KiB
Go
Raw Permalink Normal View History

2024-04-04 17:33:22 +00:00
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
2024-04-04 20:08:50 +00:00
2024-04-04 17:33:22 +00:00
package machine
import (
2024-04-04 20:08:50 +00:00
_ "errors"
"fmt"
2024-05-20 16:56:49 +00:00
"log/slog"
2024-04-04 17:33:22 +00:00
)
type Transitioner interface {
2024-04-04 20:08:50 +00:00
Run(m Modeler) error
Subscribe(s Subscriber)
2024-04-04 17:33:22 +00:00
}
type Transition struct {
2024-04-04 20:08:50 +00:00
trigger string
source []State
2024-04-04 20:08:50 +00:00
dest State
subscriptions []Subscriber
2024-04-04 17:33:22 +00:00
}
func NewTransition(trigger string, source []State, dest State) Transitioner {
2024-04-04 20:08:50 +00:00
return &Transition{trigger: trigger, source: source, dest: dest}
2024-04-04 17:33:22 +00:00
}
func (r *Transition) Run(m Modeler) error {
2024-05-20 16:59:55 +00:00
slog.Info("Transition.Run()", "transition", r, "model", m)
2024-04-04 20:08:50 +00:00
currentState := m.InspectState()
if currentState == r.dest {
return nil
}
for _, transitionSource := range r.source {
if currentState == transitionSource || transitionSource == "*" {
res := m.ChangeState(r.dest)
if res == currentState {
r.Notify(EXITSTATEEVENT, currentState, r.dest)
r.Notify(ENTERSTATEEVENT, currentState, r.dest)
return nil
}
2024-04-04 20:08:50 +00:00
}
}
return fmt.Errorf("Transition from %s to %s failed on model state %s", r.source, r.dest, currentState)
2024-04-04 17:33:22 +00:00
}
func (r *Transition) Subscribe(s Subscriber) {
2024-04-04 20:08:50 +00:00
r.subscriptions = append(r.subscriptions, s)
2024-04-04 17:33:22 +00:00
}
func (r *Transition) Notify(on Eventtype, source State, dest State) {
2024-04-04 20:08:50 +00:00
for _, s := range r.subscriptions {
2024-05-07 05:46:24 +00:00
s.Notify(&EventMessage{On: on, Source: source, Dest: dest})
2024-04-04 20:08:50 +00:00
}
2024-04-04 17:33:22 +00:00
}