@@ -54,8 +54,9 @@ internal sealed class SInputState : InputState
5454 /// <summary>The mouse state as of the last update, with overrides applied.</summary>
5555 public MouseState MouseState { get ; private set ; }
5656
57- /// <summary>The buttons which were pressed, held, or released as of the last update.</summary>
58- public IDictionary < SButton , SButtonState > ButtonStates { get ; private set ; } = new Dictionary < SButton , SButtonState > ( ) ;
57+ /// <summary>The buttons which were active (pressed, held, or newly released) as of the last update.</summary>
58+ /// <remarks>A released button is considered inactive if it's been released for two consecutive ticks, at which point it's no longer in this dictionary.</remarks>
59+ public Dictionary < SButton , SButtonState > ButtonStates { get ; } = [ ] ;
5960
6061 /// <summary>The cursor position on the screen adjusted for the zoom level.</summary>
6162 public ICursorPosition CursorPosition => this . CursorPositionImpl ;
@@ -96,10 +97,9 @@ public void TrueUpdate()
9697 Vector2 ? playerTilePos = Context . IsPlayerFree ? Game1 . player . Tile : null ;
9798
9899 pressedButtons . Clear ( ) ;
99- this . FillPressedButtons ( pressedButtons , keyboard , mouse , controller ) ;
100+ SInputState . FillPressedButtons ( pressedButtons , keyboard , mouse , controller ) ;
100101
101102 // apply overrides
102- bool hasOverrides = false ;
103103 if ( this . CustomPressedKeys . Count > 0 || this . CustomReleasedKeys . Count > 0 )
104104 {
105105 // reset overrides that no longer apply
@@ -108,31 +108,24 @@ public void TrueUpdate()
108108
109109 // apply overrides
110110 if ( this . ApplyOverrides ( this . CustomPressedKeys , this . CustomReleasedKeys , controller , keyboard , mouse ) )
111- hasOverrides = true ;
112-
113- // remove pressed keys
111+ {
112+ pressedButtons . Clear ( ) ;
113+ SInputState . FillPressedButtons ( pressedButtons , keyboard , mouse , controller ) ;
114+ }
114115 this . CustomPressedKeys . Clear ( ) ;
115116 }
116117
117- // get button states
118- if ( hasOverrides )
119- {
120- pressedButtons . Clear ( ) ;
121- this . FillPressedButtons ( pressedButtons , keyboard , mouse , controller ) ;
122- }
123- var activeButtons = this . DeriveStates ( this . ButtonStates , pressedButtons ) ;
124-
125118 // update
126119 this . HasNewOverrides = false ;
127120 this . ControllerState = controller . GetState ( ) ;
128121 this . KeyboardState = keyboard . GetState ( ) ;
129122 this . MouseState = mouse . GetState ( ) ;
130- this . ButtonStates = activeButtons ;
131123 if ( cursorAbsolutePos != this . CursorPositionImpl . AbsolutePixels || playerTilePos != this . LastPlayerTile )
132124 {
133125 this . LastPlayerTile = playerTilePos ;
134126 this . CursorPositionImpl = this . GetCursorPosition ( this . MouseState , cursorAbsolutePos , zoomMultiplier ) ;
135127 }
128+ SInputState . UpdateActiveStates ( this . ButtonStates , pressedButtons ) ;
136129 }
137130 catch ( InvalidOperationException )
138131 {
@@ -204,7 +197,7 @@ public void ApplyOverrides()
204197 /// <param name="button">The button to check.</param>
205198 public bool IsDown ( SButton button )
206199 {
207- return this . GetState ( this . ButtonStates , button ) . IsDown ( ) ;
200+ return SInputState . GetState ( this . ButtonStates , button ) . IsDown ( ) ;
208201 }
209202
210203 /// <summary>Get whether any of the given buttons were pressed or held.</summary>
@@ -218,7 +211,7 @@ public bool IsAnyDown(InputButton[] buttons)
218211 /// <param name="button">The button to check.</param>
219212 public SButtonState GetState ( SButton button )
220213 {
221- return this . GetState ( this . ButtonStates , button ) ;
214+ return SInputState . GetState ( this . ButtonStates , button ) ;
222215 }
223216
224217
@@ -255,9 +248,9 @@ private bool ApplyOverrides(ISet<SButton> pressed, ISet<SButton> released, GameP
255248 IDictionary < SButton , SButtonState > keyboardOverrides = new Dictionary < SButton , SButtonState > ( ) ;
256249 IDictionary < SButton , SButtonState > controllerOverrides = new Dictionary < SButton , SButtonState > ( ) ;
257250 IDictionary < SButton , SButtonState > mouseOverrides = new Dictionary < SButton , SButtonState > ( ) ;
258- foreach ( var button in pressed . Concat ( released ) )
251+ foreach ( SButton button in pressed . Concat ( released ) )
259252 {
260- var newState = this . DeriveState (
253+ SButtonState newState = SInputState . DeriveState (
261254 oldState : this . GetState ( button ) ,
262255 isDown : pressed . Contains ( button )
263256 ) ;
@@ -281,43 +274,46 @@ private bool ApplyOverrides(ISet<SButton> pressed, ISet<SButton> released, GameP
281274 return true ;
282275 }
283276
284- /// <summary>Get the state of all pressed or released buttons relative to their previous state .</summary>
285- /// <param name="previousStates ">The previous button states.</param>
277+ /// <summary>Update active button states based on the currently pressed buttons .</summary>
278+ /// <param name="buttonStates ">The button states from the previous update tick .</param>
286279 /// <param name="pressedButtons">The currently pressed buttons.</param>
287- private IDictionary < SButton , SButtonState > DeriveStates ( IDictionary < SButton , SButtonState > previousStates , HashSet < SButton > pressedButtons )
280+ private static void UpdateActiveStates ( Dictionary < SButton , SButtonState > buttonStates , HashSet < SButton > pressedButtons )
288281 {
289- IDictionary < SButton , SButtonState > activeButtons = new Dictionary < SButton , SButtonState > ( ) ;
290-
291- // handle pressed keys
292- foreach ( SButton button in pressedButtons )
293- activeButtons [ button ] = this . DeriveState ( this . GetState ( previousStates , button ) , isDown : true ) ;
294-
295- // handle released keys
296- foreach ( KeyValuePair < SButton , SButtonState > prev in previousStates )
282+ // update previously active keys
283+ foreach ( ( SButton button , SButtonState oldState ) in buttonStates )
297284 {
298- if ( prev . Value . IsDown ( ) )
299- activeButtons . TryAdd ( prev . Key , SButtonState . Released ) ;
285+ SButtonState newState = SInputState . DeriveState ( oldState , isDown : pressedButtons . Contains ( button ) ) ;
286+
287+ if ( oldState == SButtonState . Released && newState == SButtonState . Released )
288+ buttonStates . Remove ( button ) ;
289+ else if ( oldState != newState )
290+ buttonStates [ button ] = newState ;
300291 }
301292
302- return activeButtons ;
293+ // add newly pressed keys
294+ foreach ( SButton button in pressedButtons )
295+ buttonStates . TryAdd ( button , SButtonState . Pressed ) ;
303296 }
304297
305298 /// <summary>Get the state of a button relative to its previous state.</summary>
306299 /// <param name="oldState">The previous button state.</param>
307300 /// <param name="isDown">Whether the button is currently down.</param>
308- private SButtonState DeriveState ( SButtonState oldState , bool isDown )
301+ private static SButtonState DeriveState ( SButtonState oldState , bool isDown )
309302 {
310- if ( isDown && oldState . IsDown ( ) )
311- return SButtonState . Held ;
312303 if ( isDown )
313- return SButtonState . Pressed ;
304+ {
305+ return oldState . IsDown ( )
306+ ? SButtonState . Held
307+ : SButtonState . Pressed ;
308+ }
309+
314310 return SButtonState . Released ;
315311 }
316312
317313 /// <summary>Get the state of a button.</summary>
318314 /// <param name="activeButtons">The current button states to check.</param>
319315 /// <param name="button">The button to check.</param>
320- private SButtonState GetState ( IDictionary < SButton , SButtonState > activeButtons , SButton button )
316+ private static SButtonState GetState ( IDictionary < SButton , SButtonState > activeButtons , SButton button )
321317 {
322318 return activeButtons . TryGetValue ( button , out SButtonState state )
323319 ? state
@@ -330,7 +326,7 @@ private SButtonState GetState(IDictionary<SButton, SButtonState> activeButtons,
330326 /// <param name="mouse">The mouse state.</param>
331327 /// <param name="controller">The controller state.</param>
332328 /// <remarks>Thumbstick direction logic derived from <see cref="ButtonCollection"/>.</remarks>
333- private void FillPressedButtons ( HashSet < SButton > set , KeyboardStateBuilder keyboard , MouseStateBuilder mouse , GamePadStateBuilder controller )
329+ private static void FillPressedButtons ( HashSet < SButton > set , KeyboardStateBuilder keyboard , MouseStateBuilder mouse , GamePadStateBuilder controller )
334330 {
335331 keyboard . FillPressedButtons ( set ) ;
336332 mouse . FillPressedButtons ( set ) ;
0 commit comments