add recipe function to FSM

master
syneffort 11 months ago
parent 37e3db04c9
commit 0d42f94fb4
  1. 1
      DesignPattern/FSM/FSM.csproj
  2. 16
      DesignPattern/FSM/Program.cs
  3. 47
      DesignPattern/FSM/Recipes/Recipe.cs
  4. 18
      DesignPattern/FSM/States/IdleState.cs
  5. 10
      DesignPattern/FSM/States/PausedState.cs
  6. 46
      DesignPattern/FSM/States/RunningState.cs

@ -44,6 +44,7 @@
<ItemGroup>
<Compile Include="Machines\EquipmentEvent.cs" />
<Compile Include="Machines\EquipmentStateMachine.cs" />
<Compile Include="Recipes\Recipe.cs" />
<Compile Include="States\EmergencyStoppedState.cs" />
<Compile Include="States\IdleState.cs" />
<Compile Include="States\IEquipmentState.cs" />

@ -1,4 +1,5 @@
using FSM.Machines;
using FSM.Recipes;
using FSM.States;
using System;
using System.Collections.Generic;
@ -15,7 +16,18 @@ namespace FSM
{
PrintMessage("********** Start of the program **********");
IEquipmentState initialState = new IdleState();
IdleState initialState = new IdleState();
Recipe recipe = new Recipe("Main recipe",
new List<string>()
{
"MainRecipe_Step1",
"MainRecipe_Step2",
"MainRecipe_Step3",
"MainRecipe_Step4",
"MainRecipe_Step5",
});
initialState.SetRecipe(recipe);
var machine = new EquipmentStateMachine(initialState);
machine.OnHandleEvent -= machine_OnHandleEvent;
machine.OnHandleEvent += machine_OnHandleEvent;
@ -37,7 +49,7 @@ namespace FSM
foreach (EquipmentEvent evt in eventCommands)
{
machine.HandleEvent(evt);
Thread.Sleep(1000);
Thread.Sleep(10 * 1000);
}
PrintMessage("********** End of the program **********" + Environment.NewLine);

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FSM.Recipes
{
class Recipe
{
public string Name { get; private set; }
public List<string> Steps { get; private set; }
private int _currentStepIndex;
public int CurrentStepIndex { get { return _currentStepIndex; } }
public Recipe(string name, List<string> steps)
{
Name = name;
Steps = steps;
_currentStepIndex = 0;
}
public void Reset()
{
_currentStepIndex = 0;
}
public string GetCurrentStep()
{
if (_currentStepIndex < Steps.Count)
return Steps[_currentStepIndex];
return null;
}
public bool MoveToNextStep()
{
if (_currentStepIndex < Steps.Count - 1)
{
_currentStepIndex++;
return true;
}
return false;
}
}
}

@ -1,4 +1,5 @@
using FSM.Machines;
using FSM.Recipes;
using System;
using System.Collections.Generic;
using System.Linq;
@ -9,6 +10,8 @@ namespace FSM.States
{
class IdleState : IEquipmentState
{
private Recipe _currentRecipe;
public void Enter()
{
Console.WriteLine("Entering IdleState");
@ -19,13 +22,24 @@ namespace FSM.States
Console.WriteLine("Exiting IdleState");
}
public void SetRecipe(Recipe recipe)
{
_currentRecipe = recipe;
Console.WriteLine(string.Format("Recipe {0} set in IdleState", _currentRecipe.Name));
}
public bool HandleEvent(EquipmentEvent equipmentEvent, Machines.EquipmentStateMachine machine)
{
switch (equipmentEvent)
{
case EquipmentEvent.Start:
machine.SetState(new RunningState());
return true;
if (_currentRecipe != null)
{
machine.SetState(new RunningState(_currentRecipe));
return true;
}
Console.WriteLine("No recipe set. Unable to start.");
return false;
case EquipmentEvent.EmergencyStop:
machine.SetState(new EmergencyStoppedState());
return true;

@ -1,4 +1,5 @@
using FSM.Machines;
using FSM.Recipes;
using System;
using System.Collections.Generic;
using System.Linq;
@ -9,6 +10,13 @@ namespace FSM.States
{
class PausedState : IEquipmentState
{
private Recipe _currentRecipe;
public PausedState(Recipe recipe)
{
_currentRecipe = recipe;
}
public void Enter()
{
Console.WriteLine("Entering PausedState");
@ -24,7 +32,7 @@ namespace FSM.States
switch (equipmentEvent)
{
case EquipmentEvent.Resume:
machine.SetState(new RunningState());
machine.SetState(new RunningState(_currentRecipe));
return true;
case EquipmentEvent.Stop:
machine.SetState(new IdleState());

@ -1,22 +1,38 @@
using FSM.Machines;
using FSM.Recipes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace FSM.States
{
class RunningState : IEquipmentState
{
private Recipe _currentRecipe;
private Timer _timer;
public RunningState(Recipe recipe)
{
_currentRecipe = recipe;
_timer = new Timer(3000);
_timer.Elapsed += OnTimedEvent;
}
public void Enter()
{
Console.WriteLine("Entering RunningState");
Console.WriteLine(string.Format("Entering RunningState with recipe: {0}", _currentRecipe.Name));
ExecuteCurrentStep();
_timer.Start();
}
public void Exit()
{
Console.WriteLine("Exiting RunningState");
_timer.Stop();
}
public bool HandleEvent(EquipmentEvent equipmentEvent, Machines.EquipmentStateMachine machine)
@ -24,7 +40,7 @@ namespace FSM.States
switch (equipmentEvent)
{
case EquipmentEvent.Pause:
machine.SetState(new PausedState());
machine.SetState(new PausedState(_currentRecipe));
return true;
case EquipmentEvent.Stop:
machine.SetState(new IdleState());
@ -36,5 +52,31 @@ namespace FSM.States
return false;
}
}
private void ExecuteCurrentStep()
{
var step = _currentRecipe.GetCurrentStep();
if (string.IsNullOrEmpty(step))
{
Console.WriteLine("Recipe completed");
}
else
{
Console.WriteLine(string.Format("Execute step {0}: {1}", _currentRecipe.CurrentStepIndex + 1, step));
}
}
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
if (_currentRecipe.MoveToNextStep())
{
ExecuteCurrentStep();
}
else
{
Console.WriteLine("Recipe completed");
_timer.Stop();
}
}
}
}

Loading…
Cancel
Save