File tree Expand file tree Collapse file tree 4 files changed +73
-7
lines changed
Expand file tree Collapse file tree 4 files changed +73
-7
lines changed Original file line number Diff line number Diff line change @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
88## [ Unreleased]
99
10+ ### Added
11+
12+ - OnStateChanged method
13+
1014## [ 0.1.0] - 2025-04-23
1115
1216### Added
Original file line number Diff line number Diff line change 11namespace TJC . StateMachine . Tests . Mocks
22{
3- internal class RevolverMock ( )
4- : StateMachineBase < RevolverStates > ( RevolverStates . Loaded )
3+ internal class RevolverMock ( ) : StateMachineBase < RevolverStates > ( RevolverStates . Loaded )
54 {
65 public int BulletsLoaded { get ; private set ; } = 6 ;
76
7+ internal uint StateChanges = 0 ;
8+
89 public bool TryShoot ( )
910 {
1011 switch ( State )
@@ -17,7 +18,9 @@ public bool TryShoot()
1718 State = RevolverStates . Empty ;
1819 return true ;
1920 default :
20- throw new InvalidOperationException ( $ "Unknown State [{ State } ] for method { nameof ( TryShoot ) } ") ;
21+ throw new InvalidOperationException (
22+ $ "Unknown State [{ State } ] for method { nameof ( TryShoot ) } "
23+ ) ;
2124 }
2225 }
2326
@@ -26,5 +29,10 @@ public void Reload()
2629 BulletsLoaded = 6 ;
2730 State = RevolverStates . Loaded ;
2831 }
32+
33+ protected override void OnStateChanged ( )
34+ {
35+ StateChanges ++ ;
36+ }
2937 }
30- }
38+ }
Original file line number Diff line number Diff line change @@ -57,5 +57,40 @@ public void EnsureReloadingResetsBulletsTo6()
5757 revolver . Reload ( ) ;
5858 Assert . AreEqual ( 6 , revolver . BulletsLoaded ) ;
5959 }
60+
61+ [ TestMethod ]
62+ public void EnsureEmptyingChangesStateAndReloadingChangesStateAgain ( )
63+ {
64+ var revolver = new RevolverMock ( ) ;
65+
66+ Assert . AreEqual < uint > ( 0 , revolver . StateChanges ) ;
67+
68+ revolver . TryShoot ( ) ;
69+ revolver . TryShoot ( ) ;
70+ revolver . TryShoot ( ) ;
71+ revolver . TryShoot ( ) ;
72+ revolver . TryShoot ( ) ;
73+ revolver . TryShoot ( ) ;
74+
75+ Assert . AreEqual < uint > ( 1 , revolver . StateChanges ) ;
76+
77+ revolver . Reload ( ) ;
78+
79+ Assert . AreEqual < uint > ( 2 , revolver . StateChanges ) ;
80+ }
81+
82+ [ TestMethod ]
83+ public void EnsureReloadingMultipleTimesDoesNotChangeState ( )
84+ {
85+ var revolver = new RevolverMock ( ) ;
86+
87+ Assert . AreEqual < uint > ( 0 , revolver . StateChanges ) ;
88+
89+ revolver . Reload ( ) ;
90+ revolver . Reload ( ) ;
91+ revolver . Reload ( ) ;
92+
93+ Assert . AreEqual < uint > ( 0 , revolver . StateChanges ) ;
94+ }
6095 }
6196}
Original file line number Diff line number Diff line change 55 /// </summary>
66 /// <typeparam name="T">State Type.</typeparam>
77 /// <param name="initialState">Initial State of the State Machine.</param>
8- public class StateMachineBase < T > ( T initialState )
8+ public abstract class StateMachineBase < T > ( T initialState )
99 {
10+ private T _state = initialState ;
11+
1012 /// <summary>
1113 /// State of the state machine.
1214 /// </summary>
13- protected T State { get ; set ; } = initialState ;
15+ protected T State
16+ {
17+ get => _state ;
18+ set
19+ {
20+ if ( Equals ( _state , value ) )
21+ return ;
22+ _state = value ;
23+ OnStateChanged ( ) ;
24+ }
25+ }
26+
27+ /// <summary>
28+ /// Called on state change.
29+ /// Can be used to add tracing & debugging.
30+ /// Should not be used to notify of state changes externally.
31+ /// </summary>
32+ protected abstract void OnStateChanged ( ) ;
1433 }
15- }
34+ }
You can’t perform that action at this time.
0 commit comments