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
|
|
|
|
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()
|
2024-05-17 03:37:15 +00:00
|
|
|
if currentState == r.dest {
|
|
|
|
return nil
|
|
|
|
}
|
2024-05-17 00:28:49 +00:00
|
|
|
if currentState == r.source || r.source == "*" {
|
2024-04-04 20:08:50 +00:00
|
|
|
res := m.ChangeState(r.dest)
|
|
|
|
if res == currentState {
|
|
|
|
r.Notify(EXITSTATEEVENT, currentState, r.dest)
|
|
|
|
r.Notify(ENTERSTATEEVENT, currentState, r.dest)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
}
|