48 lines
1.1 KiB
Go
48 lines
1.1 KiB
Go
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||
|
|
||
|
package machine
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"errors"
|
||
|
)
|
||
|
|
||
|
type Transitioner interface {
|
||
|
Run(m Modeler) error
|
||
|
Subscribe(s Subscriber)
|
||
|
}
|
||
|
|
||
|
type Transition struct {
|
||
|
trigger string
|
||
|
source State
|
||
|
dest State
|
||
|
subscriptions []Subscriber
|
||
|
}
|
||
|
|
||
|
func NewTransition(trigger string, source State, dest State) Transitioner {
|
||
|
return &Transition{ trigger: trigger, source: source, dest: dest }
|
||
|
}
|
||
|
|
||
|
func (r *Transition) Run(m Modeler) error {
|
||
|
currentState := m.InspectState()
|
||
|
if currentState == r.source {
|
||
|
res := m.ChangeState(r.dest)
|
||
|
if res == currentState {
|
||
|
r.Notify(EXITSTATEEVENT, currentState, r.dest)
|
||
|
r.Notify(ENTERSTATEEVENT, currentState, r.dest)
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
return errors.New(fmt.Sprintf("Transition from %s to %s failed on model state %s", r.source, r.dest, currentState))
|
||
|
}
|
||
|
|
||
|
func (r *Transition) Subscribe(s Subscriber) {
|
||
|
r.subscriptions = append(r.subscriptions, s)
|
||
|
}
|
||
|
|
||
|
func (r *Transition) Notify(on Eventtype, source State, dest State) {
|
||
|
for _,s := range r.subscriptions {
|
||
|
s.Notify(&EventMessage{ on: on, source: source, dest: dest})
|
||
|
}
|
||
|
}
|