From 0d42f94fb424047c5ce1748e3fb3688c2c24b3ca Mon Sep 17 00:00:00 2001 From: syneffort Date: Tue, 28 May 2024 14:06:38 +0900 Subject: [PATCH] add recipe function to FSM --- DesignPattern/FSM/FSM.csproj | 1 + DesignPattern/FSM/Program.cs | 16 +++++++- DesignPattern/FSM/Recipes/Recipe.cs | 47 ++++++++++++++++++++++++ DesignPattern/FSM/States/IdleState.cs | 18 ++++++++- DesignPattern/FSM/States/PausedState.cs | 10 ++++- DesignPattern/FSM/States/RunningState.cs | 46 ++++++++++++++++++++++- 6 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 DesignPattern/FSM/Recipes/Recipe.cs diff --git a/DesignPattern/FSM/FSM.csproj b/DesignPattern/FSM/FSM.csproj index 459a5cd..1330518 100644 --- a/DesignPattern/FSM/FSM.csproj +++ b/DesignPattern/FSM/FSM.csproj @@ -44,6 +44,7 @@ + diff --git a/DesignPattern/FSM/Program.cs b/DesignPattern/FSM/Program.cs index dc7b685..810d2a6 100644 --- a/DesignPattern/FSM/Program.cs +++ b/DesignPattern/FSM/Program.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() + { + "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); diff --git a/DesignPattern/FSM/Recipes/Recipe.cs b/DesignPattern/FSM/Recipes/Recipe.cs new file mode 100644 index 0000000..39eb48d --- /dev/null +++ b/DesignPattern/FSM/Recipes/Recipe.cs @@ -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 Steps { get; private set; } + private int _currentStepIndex; + public int CurrentStepIndex { get { return _currentStepIndex; } } + + public Recipe(string name, List 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; + } + } +} diff --git a/DesignPattern/FSM/States/IdleState.cs b/DesignPattern/FSM/States/IdleState.cs index e1fca3d..1072348 100644 --- a/DesignPattern/FSM/States/IdleState.cs +++ b/DesignPattern/FSM/States/IdleState.cs @@ -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; diff --git a/DesignPattern/FSM/States/PausedState.cs b/DesignPattern/FSM/States/PausedState.cs index 9ce9056..19e33de 100644 --- a/DesignPattern/FSM/States/PausedState.cs +++ b/DesignPattern/FSM/States/PausedState.cs @@ -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()); diff --git a/DesignPattern/FSM/States/RunningState.cs b/DesignPattern/FSM/States/RunningState.cs index bed7447..edc98bc 100644 --- a/DesignPattern/FSM/States/RunningState.cs +++ b/DesignPattern/FSM/States/RunningState.cs @@ -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(); + } + } } }