fix save game state

1. HandleProcessThrowResult - Neuer Effect der bei IsGameOver den State sofort speichert
  2. HandleExecuteGameActionSuccess - Neuer Effect der bei IsGameOver den State sofort speichert

  Diese Effects laufen nach dem Reducer, daher ist der State bereits aktualisiert wenn gespeichert wird. Bei F5-Reload wird jetzt der finale Spielzustand geladen.
This commit is contained in:
beo3000 2026-01-11 10:42:38 +01:00
parent 60da0ce18b
commit 979cf14adf
1 changed files with 51 additions and 2 deletions

View File

@ -468,9 +468,10 @@ public class GameEffects
afterThrowState.PinsKnocked);
}
// If game is over, skip save (user must confirm end via UI)
// If game is over, don't start debounce timer - the ProcessThrowResultAction effect handles saving
if (isGameOver)
{
_saveDebounceTimer?.Dispose();
return;
}
@ -483,6 +484,30 @@ public class GameEffects
Timeout.Infinite);
}
/// <summary>
/// Handles ProcessThrowResultAction - saves game state immediately when game is over.
/// This effect runs after the reducer, so the state is already updated.
/// </summary>
[EffectMethod]
public async Task HandleProcessThrowResult(ProcessThrowResultAction action, IDispatcher dispatcher)
{
// Only save immediately if game is over
if (!action.IsGameOver) return;
var state = _gameState.Value;
if (!state.ActiveGameId.HasValue) return;
var success = await SaveCurrentStateAsync(state.ActiveGameId.Value);
if (success)
{
_logger.LogInformation("Game over state saved for game {GameId}", state.ActiveGameId.Value);
}
else
{
_logger.LogWarning("Failed to save game over state for game {GameId}", state.ActiveGameId.Value);
}
}
/// <summary>
/// Handles ExecuteGameActionAction - executes game-specific action via IGameLogicService.
/// </summary>
@ -538,7 +563,7 @@ public class GameEffects
dispatcher);
}
// If game is over, skip save (user must confirm end via UI)
// If game is over, skip debounce - the ExecuteGameActionSuccessAction effect handles saving
if (result.IsGameOver)
{
return;
@ -564,6 +589,30 @@ public class GameEffects
}
}
/// <summary>
/// Handles ExecuteGameActionSuccessAction - saves game state immediately when game is over.
/// This effect runs after the reducer, so the state is already updated.
/// </summary>
[EffectMethod]
public async Task HandleExecuteGameActionSuccess(ExecuteGameActionSuccessAction action, IDispatcher dispatcher)
{
// Only save immediately if game is over
if (!action.IsGameOver) return;
var state = _gameState.Value;
if (!state.ActiveGameId.HasValue) return;
var success = await SaveCurrentStateAsync(state.ActiveGameId.Value);
if (success)
{
_logger.LogInformation("Game over state saved (from action) for game {GameId}", state.ActiveGameId.Value);
}
else
{
_logger.LogWarning("Failed to save game over state (from action) for game {GameId}", state.ActiveGameId.Value);
}
}
private static ThrowPanelSnapshot CreateThrowPanelSnapshot(ThrowPanelState state)
{
return ThrowPanelSnapshot.FromPins(