diff --git a/DesignPatternGuru/DesignPatternGuru.sln b/DesignPatternGuru/DesignPatternGuru.sln index 333a235..223202d 100644 --- a/DesignPatternGuru/DesignPatternGuru.sln +++ b/DesignPatternGuru/DesignPatternGuru.sln @@ -47,6 +47,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Observer", "Observer\Observ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "State", "State\State.csproj", "{BE9AFB6B-3AD5-4F54-91FF-7829B0FBFBCD}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UsefulSamples", "UsefulSamples", "{7D7093A3-69ED-49A5-A6E2-D5732EB68559}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FiniteStateMachine", "FiniteStateMachine\FiniteStateMachine.csproj", "{51C2F1F3-B9FC-46D6-A6BD-6636010ABCD2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -129,6 +133,10 @@ Global {BE9AFB6B-3AD5-4F54-91FF-7829B0FBFBCD}.Debug|Any CPU.Build.0 = Debug|Any CPU {BE9AFB6B-3AD5-4F54-91FF-7829B0FBFBCD}.Release|Any CPU.ActiveCfg = Release|Any CPU {BE9AFB6B-3AD5-4F54-91FF-7829B0FBFBCD}.Release|Any CPU.Build.0 = Release|Any CPU + {51C2F1F3-B9FC-46D6-A6BD-6636010ABCD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51C2F1F3-B9FC-46D6-A6BD-6636010ABCD2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51C2F1F3-B9FC-46D6-A6BD-6636010ABCD2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51C2F1F3-B9FC-46D6-A6BD-6636010ABCD2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -153,6 +161,7 @@ Global {A6E39678-6214-4BD2-B616-A3350340E5AB} = {E3B8A482-1A9A-4B6E-8310-050A44C8E379} {EB189FAC-7C63-48BB-92D7-3C35A277EA1D} = {E3B8A482-1A9A-4B6E-8310-050A44C8E379} {BE9AFB6B-3AD5-4F54-91FF-7829B0FBFBCD} = {E3B8A482-1A9A-4B6E-8310-050A44C8E379} + {51C2F1F3-B9FC-46D6-A6BD-6636010ABCD2} = {7D7093A3-69ED-49A5-A6E2-D5732EB68559} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3E5A9C6B-2E8A-466E-B5E0-4379902EFFAC} diff --git a/DesignPatternGuru/FiniteStateMachine/Command.cs b/DesignPatternGuru/FiniteStateMachine/Command.cs new file mode 100644 index 0000000..468be5d --- /dev/null +++ b/DesignPatternGuru/FiniteStateMachine/Command.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FiniteStateMachine +{ + internal enum Command + { + Begin, + End, + Paused, + Resume, + Exit, + } +} diff --git a/DesignPatternGuru/FiniteStateMachine/FiniteStateMachine.csproj b/DesignPatternGuru/FiniteStateMachine/FiniteStateMachine.csproj new file mode 100644 index 0000000..74abf5c --- /dev/null +++ b/DesignPatternGuru/FiniteStateMachine/FiniteStateMachine.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/DesignPatternGuru/FiniteStateMachine/Info/StateMachine.png b/DesignPatternGuru/FiniteStateMachine/Info/StateMachine.png new file mode 100644 index 0000000..a8ad487 Binary files /dev/null and b/DesignPatternGuru/FiniteStateMachine/Info/StateMachine.png differ diff --git a/DesignPatternGuru/FiniteStateMachine/Process.cs b/DesignPatternGuru/FiniteStateMachine/Process.cs new file mode 100644 index 0000000..1223291 --- /dev/null +++ b/DesignPatternGuru/FiniteStateMachine/Process.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FiniteStateMachine +{ + internal class Process + { + private Dictionary _transitions; + + public ProcessState CurrentState { get; private set; } + + public Process() + { + CurrentState = ProcessState.Inactive; + + _transitions = new Dictionary() + { + { new StateTransition(ProcessState.Inactive, Command.Exit), ProcessState.Trminated }, + { new StateTransition(ProcessState.Inactive, Command.Begin), ProcessState.Active }, + { new StateTransition(ProcessState.Active, Command.End), ProcessState.Inactive }, + { new StateTransition(ProcessState.Active, Command.Paused), ProcessState.Paused }, + { new StateTransition(ProcessState.Paused, Command.End), ProcessState.Inactive }, + { new StateTransition (ProcessState.Paused, Command.Resume), ProcessState.Active }, + }; + } + + public ProcessState GetNext(Command command) + { + StateTransition transition = new StateTransition(CurrentState, command); + ProcessState nextState; + if (!_transitions.TryGetValue(transition, out nextState)) + throw new Exception($"Invalid transition: {CurrentState} → {nextState}"); + + return nextState; + } + + public ProcessState MoveNext(Command command) + { + CurrentState = GetNext(command); + return CurrentState; + } + } +} diff --git a/DesignPatternGuru/FiniteStateMachine/ProcessState.cs b/DesignPatternGuru/FiniteStateMachine/ProcessState.cs new file mode 100644 index 0000000..9f2f143 --- /dev/null +++ b/DesignPatternGuru/FiniteStateMachine/ProcessState.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FiniteStateMachine +{ + internal enum ProcessState + { + Inactive, + Active, + Paused, + Trminated, + } +} diff --git a/DesignPatternGuru/FiniteStateMachine/Program.cs b/DesignPatternGuru/FiniteStateMachine/Program.cs new file mode 100644 index 0000000..2875493 --- /dev/null +++ b/DesignPatternGuru/FiniteStateMachine/Program.cs @@ -0,0 +1,16 @@ +namespace FiniteStateMachine +{ + internal class Program + { + static void Main(string[] args) + { + Process p = new Process(); + + Console.WriteLine($"Current State: {p.CurrentState}"); + Console.WriteLine($"Command.Begin: {p.MoveNext(Command.Begin)}"); + Console.WriteLine($"Command.Pause: {p.MoveNext(Command.Paused)}"); + Console.WriteLine($"Command.End: {p.MoveNext(Command.End)}"); + Console.WriteLine($"Command.Exit: {p.MoveNext(Command.Exit)}"); + } + } +} \ No newline at end of file diff --git a/DesignPatternGuru/FiniteStateMachine/StateTransition.cs b/DesignPatternGuru/FiniteStateMachine/StateTransition.cs new file mode 100644 index 0000000..a0e041a --- /dev/null +++ b/DesignPatternGuru/FiniteStateMachine/StateTransition.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FiniteStateMachine +{ + internal class StateTransition + { + private readonly ProcessState CurrentState; + private readonly Command Command; + + public StateTransition(ProcessState currentState, Command command) + { + CurrentState = currentState; + Command = command; + } + + public override int GetHashCode() + { + return 17 + 31 * CurrentState.GetHashCode() + 31 * Command.GetHashCode(); + } + + public override bool Equals(object? obj) + { + StateTransition other = obj as StateTransition; + return other != null && this.CurrentState == other.CurrentState; + } + } +}