EMSm 1.4.0

EMSm is a simple, TDD-testable hierarchical state machine library for .Net, perfectly suitable for developing the behavior of your embedded systems.

Install-Package EMSm -Version 1.4.0
dotnet add package EMSm --version 1.4.0
<PackageReference Include="EMSm" Version="1.4.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add EMSm --version 1.4.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

EMSm-Logo

Build Status
NuGet Badge
License: MIT

A simple, TDD-testable hierarchical state machine for .Net

Changelog

  • v1.1.0: intial version.
  • v1.2.0: support of older .Net-Frameworks implemented.
  • v1.3.0: strong-name-signing implemented
  • v1.4.0: Fix: Exit()-Methods weren't executed during state-transitions via setting the state path.

Features

  • Entry-/Exit- Implementation.
  • Synchronous-/Asynchronous- Mode.
  • Perfect to realize the behavior of embedded systems.
  • UML-statechart-applicability.
  • Use of transitions-tables to define the hierarchical structure.
  • Great overview of all states because every state is represented with a separate class.
  • Each state is TDD-testable.
  • Full flexible due to state-logic-implementation in Do()-method.
  • Command-injection can be accomplished from any thread.
  • Variable-injection provides clarity and great testability.
  • States can be designed for reusability.
  • Supports Done-Flag-Pattern.
  • Current-state-restoring using state-paths.
  • Simple to learn :-).

Quick Start

StateChart

class InnerState1 : State
{
    private int counter;
 
    protected override void Entry()
    {
        /*Do some stuff here, which should run once
         a transition to this state occurs*/
        this.counter = 0;
        base.Entry();
    }
    protected override Enum Do()
    {
        /*This method is excuted on every RunCycle 
         as long as this state is the active one.
         Returns a transition for switching to another state*/
        if (this.counter++ >= 5)
            return Transitions.Transition1;
        return base.Do();
    }
    protected override void Exit()
    {
        /*Here you can do some cleanup,
         which run before a transition to
         another state happens*/
        base.Exit();
    }
}
class InnerState2 : State
{
    private int counter;
 
    protected override void Entry()
    {
        /*Do some stuff here, which should run once
         a transition to this state occurs*/
        this.counter = 0;
        base.Entry();
    }
    protected override Enum Do()
    {
        /*This method is excuted on every RunCycle 
         as long as this state is the active one.
         Returns a transition for switching to another state*/
        if (this.counter++ >= 99)
            return Transitions.Transition2;
        return base.Do();
    }
    protected override void Exit()
    {
        /*Here you can do some cleanup,
         which run before a transition to
         another state happens*/
        base.Exit();
    }
}
class OuterState : State
{
    public override TransitionsTable TransitionsTable
    {
        get => new TransitionsTable {
        //Initialtransition which should endup to InnerState 1
        new TransitionEntry{    
            Transition=Transitions.Initial,
            StateType=typeof(InnerState1),
            StateName="InnerState 1"},
        //Transition 1, which should endup to InnerState 2
        new TransitionEntry{
            Transition=Transitions.Transition1,
            StateType=typeof(InnerState2),
            StateName="Innerstate 2"},
        //Transition 2, which should endup to InnerState 1
        new TransitionEntry{
            Transition=Transitions.Transition2,
            StateType=typeof(InnerState1),
            StateName="Innerstate 1"},
        };
    }
 
    protected override void Entry()
    {
        /*Do some stuff here, which should run once
         a transition to this state occurs*/
        base.Entry();
    }
    protected override Enum Do()
    {
        /*This method is excuted on every RunCycle 
         if this state is the active one*/
        return base.Do();
    }
    protected override void Exit()
    {
        /*Here you can do some cleanup,
         which run before a transition to
         another state happens*/
        base.Exit();
    }
}

RunCycle:

OuterState outerState = new OuterState();
outerState.RunCycle();

StateChart-sync-async

Please visit https://www.eforge.net/EMSm for further documentation and tutorials

EMSm-Logo

Build Status
NuGet Badge
License: MIT

A simple, TDD-testable hierarchical state machine for .Net

Changelog

  • v1.1.0: intial version.
  • v1.2.0: support of older .Net-Frameworks implemented.
  • v1.3.0: strong-name-signing implemented
  • v1.4.0: Fix: Exit()-Methods weren't executed during state-transitions via setting the state path.

Features

  • Entry-/Exit- Implementation.
  • Synchronous-/Asynchronous- Mode.
  • Perfect to realize the behavior of embedded systems.
  • UML-statechart-applicability.
  • Use of transitions-tables to define the hierarchical structure.
  • Great overview of all states because every state is represented with a separate class.
  • Each state is TDD-testable.
  • Full flexible due to state-logic-implementation in Do()-method.
  • Command-injection can be accomplished from any thread.
  • Variable-injection provides clarity and great testability.
  • States can be designed for reusability.
  • Supports Done-Flag-Pattern.
  • Current-state-restoring using state-paths.
  • Simple to learn :-).

Quick Start

StateChart

class InnerState1 : State
{
    private int counter;
 
    protected override void Entry()
    {
        /*Do some stuff here, which should run once
         a transition to this state occurs*/
        this.counter = 0;
        base.Entry();
    }
    protected override Enum Do()
    {
        /*This method is excuted on every RunCycle 
         as long as this state is the active one.
         Returns a transition for switching to another state*/
        if (this.counter++ >= 5)
            return Transitions.Transition1;
        return base.Do();
    }
    protected override void Exit()
    {
        /*Here you can do some cleanup,
         which run before a transition to
         another state happens*/
        base.Exit();
    }
}
class InnerState2 : State
{
    private int counter;
 
    protected override void Entry()
    {
        /*Do some stuff here, which should run once
         a transition to this state occurs*/
        this.counter = 0;
        base.Entry();
    }
    protected override Enum Do()
    {
        /*This method is excuted on every RunCycle 
         as long as this state is the active one.
         Returns a transition for switching to another state*/
        if (this.counter++ >= 99)
            return Transitions.Transition2;
        return base.Do();
    }
    protected override void Exit()
    {
        /*Here you can do some cleanup,
         which run before a transition to
         another state happens*/
        base.Exit();
    }
}
class OuterState : State
{
    public override TransitionsTable TransitionsTable
    {
        get => new TransitionsTable {
        //Initialtransition which should endup to InnerState 1
        new TransitionEntry{    
            Transition=Transitions.Initial,
            StateType=typeof(InnerState1),
            StateName="InnerState 1"},
        //Transition 1, which should endup to InnerState 2
        new TransitionEntry{
            Transition=Transitions.Transition1,
            StateType=typeof(InnerState2),
            StateName="Innerstate 2"},
        //Transition 2, which should endup to InnerState 1
        new TransitionEntry{
            Transition=Transitions.Transition2,
            StateType=typeof(InnerState1),
            StateName="Innerstate 1"},
        };
    }
 
    protected override void Entry()
    {
        /*Do some stuff here, which should run once
         a transition to this state occurs*/
        base.Entry();
    }
    protected override Enum Do()
    {
        /*This method is excuted on every RunCycle 
         if this state is the active one*/
        return base.Do();
    }
    protected override void Exit()
    {
        /*Here you can do some cleanup,
         which run before a transition to
         another state happens*/
        base.Exit();
    }
}

RunCycle:

OuterState outerState = new OuterState();
outerState.RunCycle();

StateChart-sync-async

Please visit https://www.eforge.net/EMSm for further documentation and tutorials

  • .NETFramework 3.5

    • No dependencies.
  • .NETStandard 2.1

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
1.4.0 169 6/29/2020
1.3.0 94 5/24/2020
1.2.0 153 5/23/2020
1.1.0 159 12/10/2019
1.0.1-beta 170 9/19/2019
1.0.0-beta 210 9/16/2019