avishayt / stateswitch

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Actions Status

stateswitch

Overview

A simple and clear way to create and represent state machine.

sm := stateswitch.NewStateMachine()

sm.AddTransition(stateswitch.TransitionRule{
    TransitionType:   TransitionTypeSetHwInfo,
    SourceStates:     stateswitch.States{StateDiscovering, StateKnown, StateInsufficient},
    DestinationState: StateKnown,
    Condition:        th.IsSufficient,
    Transition:       th.SetHwInfo,
    PostTransition:   th.PostSetHwInfo,
})

sm.AddTransition(stateswitch.TransitionRule{
    TransitionType:   TransitionTypeSetHwInfo,
    SourceStates:     stateswitch.States{StateDiscovering, StateKnown, StateInsufficient},
    DestinationState: StateInsufficient,
    Condition:        th.IsInsufficient,
    Transition:       th.SetHwInfo,
    PostTransition:   th.PostSetHwInfo,
})

sm.AddTransition(stateswitch.TransitionRule{
    TransitionType:   TransitionTypeRegister,
    SourceStates:     stateswitch.States{""},
    DestinationState: StateDiscovering,
    Condition:        nil,
    Transition:       nil,
    PostTransition:   th.RegisterNew,
})

sm.AddTransition(stateswitch.TransitionRule{
    TransitionType:   TransitionTypeRegister,
    SourceStates:     stateswitch.States{StateDiscovering, StateKnown, StateInsufficient},
    DestinationState: StateDiscovering,
    Condition:        nil,
    Transition:       nil,
    PostTransition:   th.RegisterAgain,
})

Usage

First your state object need to implement the state interface:

type StateSwitch interface {
	// State return current state
	State() State
	// SetState set a new state
	SetState(state State) error
}

Then you need to create state machine

sm := stateswitch.NewStateMachine()

Add transitions with the expected behavior

sm.AddTransition(stateswitch.TransitionRule{
    TransitionType:   TransitionTypeSetHwInfo,
    SourceStates:     stateswitch.States{StateDiscovering, StateKnown, StateInsufficient},
    DestinationState: StateInsufficient,
    Condition:        th.IsInsufficient,
    Transition:       th.SetHwInfo,
    PostTransition:   th.PostSetHwInfo,
})

TransitionRule define the behavior that will be selected for your object by transition type, source state and conditions that you define. The first transition that will satisfy those requirements will be activated. Condtion, Transition PostTranstion are all optional, the transition may only change the state.

Since Condtion represent boolean entity, stateswitch provides means to create a combination of these entities from basic boolean operations: Not,And, Or. For example, rule with complex condition:

sm.AddTransition(stateswitch.TransitionRule{
    TransitionType:   TransitionTypeSetHwInfo,
    SourceStates:     stateswitch.States{StateDiscovering, StateKnown, StateInsufficient},
    DestinationState: StatePending,
    Condition:        And(th.IsConnected, th.HasInventory, Not(th.RoleDefined)),
    Transition:       th.SetHwInfo,
    PostTransition:   th.PostSetHwInfo,
})

Run transition by type, state machine will select the right one for you.

h.sm.Run(TransitionTypeSetHwInfo, &stateHost{host: host}, &TransitionArgsSetHwInfo{hwInfo: hw})

for more details and full examples take a look at the examples section.

Examples

Example can be found here

About


Languages

Language:Go 99.0%Language:Makefile 1.0%