VB.Net Library Tutorials

Step 1. Download the Fawdlstty.SMLite library via NuGet.

Step 2. Define two enumerated classes that represent all states and all triggers

Enum MyState
    Rest
    Ready
    Reading
    Writing
End Enum
Enum MyTrigger
    Run
    Close
    Read
    FinishRead
    Write
    FinishWrite
End Enum

Step 3. Define state machine builder, templates as two enumeration classes, and parameters as initial values

Dim _smb As SMLiteBuilder(Of MyState, MyTrigger) = New SMLiteBuilder(Of MyState, MyTrigger)()

Step 4. Rules that define a state machine, specifying what triggers are allowed to be fired for a specific state

With _smb.Configure(MyState.Rest)
    ' This method is fired if the state changes from another state to myState.rest state, not by the initial value specified when the state machine is initialized
    .OnEntry(Sub()
                 Console.WriteLine ("entry Rest")
             End Sub)

    ' This method is fired if the state changes from the myState.rest state to another state
    .OnLeave(Sub()
                 Console.WriteLine ("leave Rest")
             End Sub)

    ' If myTrigger.Run is triggered, change the status to MyState.ready
    .WhenChangeTo (MyTrigger.Run, MyState.Ready)

    ' If MyTrigger.Run is triggered, ignore it
    .WhenIgnore (MyTrigger.Close)

    ' If MyTrigger.read is triggered, the callback function is called and the state is adjusted to the return value
    .WhenFunc(MyTrigger.Read, Function(_state As MyState, _trigger As MyTrigger) As MyState
                                  Console.WriteLine ("call WhenFunc callback")
                                  Return MyState.Ready
                              End Function)

    ' If MyTrigger.FinishRead is fired, the callback function is called and the state is adjusted to the return value
    ' Note that an argument must be passed when firing, and the number and type must match exactly, otherwise an exception is thrown
    .WhenFunc(MyTrigger.FinishRead, Function(_state As MyState, _trigger As MyTrigger, _param_ As String) As MyState
                                        Console.WriteLine ($"call WhenFunc callback with param [{_param}]")
                                        Return MyState.Ready
                                    End Function)

    ' If MyTrigger.Write is fired, the callback function is called (triggering this method callback does not adjust the return value)
    .WhenAction(MyTrigger.Write, Sub(_state As MyState, _trigger As MyTrigger)
                                     Console.WriteLine ("call WhenAction callback")
                                 End Sub)

    ' If MyTrigger.FinishWrite is fired, the callback function is called (triggering this method callback does not adjust the return value)
    ' Note that an argument must be passed when firing, and the number and type must match exactly, otherwise an exception is thrown
    .WhenAction(MyTrigger.FinishWrite, Sub(_state As MyState, _trigger As MyTrigger, _param As String)
                                           Console.WriteLine ($"call WhenAction callback with param [{_param}]")
                                       End Sub)
End With

If you encounter the same trigger in the same state, you are allowed to define at most one way to handle it. The code above explains the defined trigger in detail.If a trigger is not defined but is encountered, the exception is thrown.

Step 5. Now let's get to the actual use of the state machine

' Build state machine
Dim _sm = _smb.Build(MyState.Rest)

' Get current status
Dim _state = _sm.State

' Determine whether an trigger is allowed to fire
Dim _allow = _sm.AllowTriggering(MyTrigger.Close)

' Fire an triggered
_sm.Triggering (MyTrigger.Run)

' Fires an trigger and passes in the specified parameters
_sm.Triggering (MyTrigger.Run, "hello")

' Forced to modify the current state, this code will not trigger OnEntry and OnLeave methods
_sm.State = MyState.Rest

Step 6. If you use asynchrony

Much like the above, the following is to specify the asynchronous trigger callback function

Dim _smb As SMLiteBuilderAsync(Of MyState, MyTrigger) = New SMLiteBuilderAsync(Of MyState, MyTrigger)()
With _smb.Configure(MyState.Rest)

    ' Same effect as onEntry, except this function specifies an asynchronous method and cannot be called at the same time as OnEntry
    .OnEntryAsync(Async Function() As Task
                      Await Task.Yield()
                      Console.WriteLine ("entry Ready")
                  End Function)

    ' This function specifies an asynchronous method and cannot be called at the same time as OnLeave
    .OnLeaveAsync(Async Function() As Task
                      Await Task.Yield()
                      Console.WriteLine ("leave Ready")
                  End Function)

    ' The effect is identical to WhenFunc, but this function specifies an asynchronous method
    .WhenFuncAsync(MyTrigger.Read, Async Function(_state As MyState, _trigger As MyTrigger, _token As CancellationToken) As Task(Of MyState)
                                       Await Task.Yield()
                                       Console.WriteLine ("call WhenFunc callback")
                                       Return MyState.Ready
                                   End Function)

    ' The effect is identical to WhenFunc, but this function specifies an asynchronous method
    .WhenFuncAsync(MyTrigger.FinishRead, Async Function(_state As MyState, _trigger As MyTrigger, _token As CancellationToken, _param As String) As Task(Of MyState)
                                             Await Task.Yield()
                                             Console.WriteLine ($"call WhenFunc callback with param [{_param}]")
                                             Return MyState.Ready
                                         End Function)

    ' The effect is identical to WhenAction, but this function specifies an asynchronous method
    .WhenActionAsync(MyTrigger.Write, Async Function(_state As MyState, _trigger As MyTrigger, _token As CancellationToken) As Task
                                          Await Task.Yield()
                                          Console.WriteLine ("call WhenAction callback")
                                      End Function)

    ' The effect is identical to WhenAction, but this function specifies an asynchronous method
    .WhenActionAsync(MyTrigger.FinishWrite, Async Function(_state As MyState, _trigger As MyTrigger, _token As CancellationToken, _p1 As String) As Task
                                                Await Task.Yield()
                                                Console.WriteLine ($"call WhenAction callback with param [{_param}]")
                                            End Function)
End With

Then there is the firing of an event:

' An event is fired asynchronously, passing in the specified parameters
Await _sm.TriggeringAsync (MyTrigger.Run, "hello")

' Limit the maximum execution time of an asynchronous task, timeout to cancel
Dim _source = new CancellationTokenSource (TimeSpan.FromSeconds (10))
Await _sm.TriggeringAsync (MyTrigger.Run, _source.Token, "hello")

Await asynchronously fired events will be returned after all functions have finished executing.In addition, it is important to note that synchronous and asynchronous should not be used together. If not used properly, it will easily lead to deadlock. The best practice is to use uniform synchronous or uniform asynchronous.

results matching ""

    No results matching ""