FluentState 1.2.0

Suggested Alternatives

StateEngine

dotnet add package FluentState --version 1.2.0                
NuGet\Install-Package FluentState -Version 1.2.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FluentState" Version="1.2.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FluentState --version 1.2.0                
#r "nuget: FluentState, 1.2.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install FluentState as a Cake Addin
#addin nuget:?package=FluentState&version=1.2.0

// Install FluentState as a Cake Tool
#tool nuget:?package=FluentState&version=1.2.0                

FluentState

Getting Started

/**
 * Uses the default StateMachine builder to easily build a state machine.
 */

enum State
{
    STATE_1,
    STATE_2,
    STATE_3,
}

enum Stimulus
{
    STIM_1,
    STIM_2,
    STIM_3,
}

var stateMachine = new StateMachineBuilder<State, Stimulus>(State.STATE_1)
    // Global enter action across all states
    .WithEnterAction((toState, fromState, reason) => { /* Custom Action Here */ })
    // Global leave action across all states
    .WithLeaveAction((toState, fromState, reason) => { /* Custom Action Here */ })
    // Start building a specific state
    .WithState(State.STATE_1)
        // This action is applied any time STATE_1 is entered, regardless of the previous state and stimulus
        .WithEnterAction((toState, fromState, reason) => { /* Custom Action Here */})
        // Define the transitions
        .CanTransitionTo(State.STATE_2, Stimulus.STIM_2)
        // This action will only trigger when going to STATE_3 from STATE_1 because of STIM_3
        .CanTransitionTo(State.STATE_3, Stimulus.STIM_3, (toState, fromState, reason) => { /* Custom Action Here */})
        .Build()

// Start working the state machine
stateMachine.Post(STIM_2);
)

AsyncStateMachine

var asyncStateMachine = new AsyncStateMachineBuilder<State, Stimulus>(State.Idle)
    /* Build state machine just like above */
    .Build();

// Start working the state machine
await asyncStateMachine.Post(STIM_2);

// STIM_2 will be processed in due time, continue with other logic
/* Other logic */

// Now wait for the state machine to be idle, which implies STIM_2 was processed
await asyncStateMachine.AwaitIdleAsync();

// Dispose to clean up the thread
// If it's important for all stimuli in the queue to be processed prior to cleanup, you must
// call AwaitIdleAsync(), else everything in the queue will be ignored on Dispose()
asyncStateMachine.Dispose();

Serialization

using FluentState.Persistence;

// Type converters for the state and stimulus need to be provided.
// Typically, these are simple integers or enums so the implementation is easy
public class StateTypeConverter : ITypeSerializer<State>
{
    public State? Convert(string stateString)
    {
        if (Enum.TryParse(stateString, out State state))
        {
            return state;
        }
        return null;
    }
    public string Convert(State state)
    {
        return state.ToString();
    }
}
public class StimulusTypeConverter : ITypeSerializer<Stimulus>
{
    // Idential to StateTypeConverter
}
var serializer = new DefaultJsonSerializer(new StateTypeSerializer(), new StimulusTypeSerializer());

await serializer.Save(stateMachine, "pathToFile.json");
await serializer.Load(stateMachine, "pathToOtherFile.json");

Using History

var stateMachine = ...

foreach(var historyItem in stateMachine.History)
{
    // Use the historyItem
}

// Enable/disable history
stateMachine.History.Enabled = false;

// Set history as bounded or unbounded
stateMachine.History.MakeBounded(100);
stateMachine.History.MakeUnbounded()
Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net5.0-windows7.0 is compatible.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net6.0-windows7.0 is compatible.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 is compatible. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Added ability to define state machines in config files,  See IConfigLoader and JsonConfigLoader