Skip to content

Commit

Permalink
Allow To, From, Events, State to pull up existing states.
Browse files Browse the repository at this point in the history
  • Loading branch information
daegalus committed Jan 26, 2023
1 parent c88adec commit 10e6d4a
Showing 1 changed file with 34 additions and 4 deletions.
38 changes: 34 additions & 4 deletions transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Stater[T any] interface {
}

// New initialize a new StateMachine that hold states, events definitions
func New[T any](value T) *StateMachine[T] {
func New[T any](_ T) *StateMachine[T] {
return &StateMachine[T]{
states: map[string]*State[T]{},
events: map[string]*Event[T]{},
Expand All @@ -48,13 +48,19 @@ func (sm *StateMachine[T]) Initial(name string) *StateMachine[T] {

// State define a state
func (sm *StateMachine[T]) State(name string) *State[T] {
if _, ok := sm.states[name]; ok {
return sm.states[name]
}
state := &State[T]{Name: name}
sm.states[name] = state
return state
}

// Event define an event
func (sm *StateMachine[T]) Event(name string) *Event[T] {
if _, ok := sm.events[name]; ok {
return sm.events[name]
}
event := &Event[T]{Name: name}
sm.events[name] = event
return event
Expand Down Expand Up @@ -153,13 +159,20 @@ func (state *State[T]) Exit(fc func(value Stater[T]) error) *State[T] {
// Event contains Event information, including transition hooks
type Event[T any] struct {
Name string
transitions []*EventTransition[T]
transitions map[string]*EventTransition[T]
}

// To define EventTransition of go to a state
func (event *Event[T]) To(name string) *EventTransition[T] {
if event.transitions == nil {
event.transitions = map[string]*EventTransition[T]{}
}
if _, ok := event.transitions[name]; ok {
return event.transitions[name]
}

transition := &EventTransition[T]{to: name}
event.transitions = append(event.transitions, transition)
event.transitions[name] = transition
return transition
}

Expand All @@ -173,7 +186,8 @@ type EventTransition[T any] struct {

// From used to define from states
func (transition *EventTransition[T]) From(states ...string) *EventTransition[T] {
transition.froms = states
transition.froms = append(transition.froms, states...)
transition.froms = removeDuplicateValues(transition.froms)
return transition
}

Expand All @@ -188,3 +202,19 @@ func (transition *EventTransition[T]) After(fc func(value Stater[T]) error) *Eve
transition.afters = append(transition.afters, fc)
return transition
}

func removeDuplicateValues[T comparable](slice []T) []T {
keys := make(map[T]bool)
list := []T{}

// If the key(values of the slice) is not equal
// to the already present value in new slice (list)
// then we append it. else we jump on another element.
for _, entry := range slice {
if _, value := keys[entry]; !value {
keys[entry] = true
list = append(list, entry)
}
}
return list
}

0 comments on commit 10e6d4a

Please sign in to comment.