// Copyright 2024 Matthew Rich . 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}) } }