feat: add pause/resume game functionality#203
Conversation
- Add paused state to GameState enum - Add pauseGame() and resumeGame() methods to GameLogic - Pause cancels timer and sets state to paused - Resume restores timer from paused state - Refactor dispose() to remain cleanup-only Co-Authored-By: Oz <oz-agent@warp.dev>
⚙️ CodePeel WalkthroughCommits: reviewing 📁 Files reviewed (1)lib/providers/
Overview
Key Changes
Risk Assessment
Changes
Review effort: ⬤◯◯◯◯ (1/5) Health score: 🟢 99/100 | Inline comments: 0 SummaryAdded pause/resume functionality with new paused game state Logic FlowsequenceDiagram
participant UI
participant GameLogic
UI->>GameLogic: pauseGame()
GameLogic->>GameLogic: cancel timer
GameLogic->>GameLogic: set state to paused
GameLogic->>UI: onStateChanged()
UI->>GameLogic: resumeGame()
alt GameState == paused
GameLogic->>GameLogic: set state to playing
GameLogic->>GameLogic: cancel existing timer
GameLogic->>GameLogic: create new periodic timer
GameLogic->>UI: onStateChanged()
loop every 100ms
GameLogic->>GameLogic: decrement timeRemaining
alt timeRemaining <= 0
GameLogic->>GameLogic: cancel timer
GameLogic->>GameLogic: set state to bust
end
GameLogic->>UI: onStateChanged()
end
else
GameLogic->>GameLogic: return early
end
ℹ️ Review coverage1 issues identified, 0 posted as inline comments. Some may have been consolidated or skipped due to line validation. |
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes. 💤 Files selected but had no reviewable changes (1)
⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthrough
ChangesPause/Resume Gameplay
Estimated code review effort🎯 2 (Simple) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/providers/game_logic.dart`:
- Around line 87-91: The `pauseGame()` and `resumeGame()` methods are
implemented in the `GameLogic` class but are not forwarded by the `GameProvider`
class, making them inaccessible to the UI layer. Add two forwarding methods to
the `GameProvider` class (in the range of lines 8-34 in
lib/providers/game_provider.dart): one method named `pauseGame()` that delegates
to `_gameLogic.pauseGame()` and another method named `resumeGame()` that
delegates to `_gameLogic.resumeGame()`. This will expose both pause and resume
functionality through the provider interface that the UI accesses.
- Around line 87-91: The pauseGame() method currently allows state transitions
to paused from any state, which creates invalid state transitions. Add a guard
condition at the start of the pauseGame() method to check if _gameState equals
GameState.playing, similar to how resumeGame() validates state. Only proceed
with canceling the timer, setting _gameState to GameState.paused, and calling
onStateChanged() if the current state is playing; otherwise, the method should
return early without making any state changes.
- Around line 93-106: The timer creation logic in the resumeGame() method
duplicates the identical timer setup code from the startGame() method, violating
the DRY principle. Extract the timer creation logic (the Timer.periodic call
that decrements _timeRemaining, checks for bust state, and calls onStateChanged)
into a private helper method (e.g., _startGameTimer()). Then replace the
duplicated timer initialization code in both resumeGame() and startGame() with
calls to this new helper method.
- Line 116: Add a missing case for GameState.paused in the switch statement in
main.dart (lines 51-60) that currently handles only home, playing, banked, and
bust states. When GameState.paused is encountered (which is set by the
pauseGame() method in GameProvider), render an appropriate pause screen UI
instead of leaving it unhandled. This will resolve the compilation error
triggered by Dart 3.4+ requiring exhaustive enum handling in switch statements
and provide the UI needed to display the paused game state that pauseGame() and
resumeGame() methods are managing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c2af4ba5-2ab0-4f54-9f0c-1ac50c5beb52
📒 Files selected for processing (1)
lib/providers/game_logic.dart
| void pauseGame() { | ||
| _timer?.cancel(); | ||
| _gameState = GameState.paused; | ||
| onStateChanged(); | ||
| } |
There was a problem hiding this comment.
Expose pauseGame() and resumeGame() in GameProvider for UI accessibility.
The new pauseGame() and resumeGame() methods are implemented in GameLogic but are not forwarded by GameProvider (lines 8-34 in lib/providers/game_provider.dart). Since the UI layer accesses game controls through GameProvider, these methods are currently unreachable, preventing the pause/resume feature from functioning end-to-end.
🔌 Proposed fix to forward methods in GameProvider
Add these forwarding methods to GameProvider in lib/providers/game_provider.dart:
void pauseGame() => _gameLogic.pauseGame();
void resumeGame() => _gameLogic.resumeGame();Also applies to: 93-106
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/providers/game_logic.dart` around lines 87 - 91, The `pauseGame()` and
`resumeGame()` methods are implemented in the `GameLogic` class but are not
forwarded by the `GameProvider` class, making them inaccessible to the UI layer.
Add two forwarding methods to the `GameProvider` class (in the range of lines
8-34 in lib/providers/game_provider.dart): one method named `pauseGame()` that
delegates to `_gameLogic.pauseGame()` and another method named `resumeGame()`
that delegates to `_gameLogic.resumeGame()`. This will expose both pause and
resume functionality through the provider interface that the UI accesses.
Add state guard to only allow pausing from playing state.
pauseGame() currently transitions to paused from any state without validation. This allows nonsensical transitions like pausing from home, banked, or bust states. Add a guard similar to resumeGame() to ensure pause only occurs when _gameState == GameState.playing.
🛡️ Proposed fix to add state guard
void pauseGame() {
+ if (_gameState != GameState.playing) return;
_timer?.cancel();
_gameState = GameState.paused;
onStateChanged();
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void pauseGame() { | |
| _timer?.cancel(); | |
| _gameState = GameState.paused; | |
| onStateChanged(); | |
| } | |
| void pauseGame() { | |
| if (_gameState != GameState.playing) return; | |
| _timer?.cancel(); | |
| _gameState = GameState.paused; | |
| onStateChanged(); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/providers/game_logic.dart` around lines 87 - 91, The pauseGame() method
currently allows state transitions to paused from any state, which creates
invalid state transitions. Add a guard condition at the start of the pauseGame()
method to check if _gameState equals GameState.playing, similar to how
resumeGame() validates state. Only proceed with canceling the timer, setting
_gameState to GameState.paused, and calling onStateChanged() if the current
state is playing; otherwise, the method should return early without making any
state changes.
| void resumeGame() { | ||
| if (_gameState != GameState.paused) return; | ||
| _gameState = GameState.playing; | ||
| _timer?.cancel(); | ||
| _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) { | ||
| _timeRemaining -= 0.1; | ||
| if (_timeRemaining <= 0) { | ||
| _timer?.cancel(); | ||
| _gameState = GameState.bust; | ||
| } | ||
| onStateChanged(); | ||
| }); | ||
| onStateChanged(); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Extract duplicated timer logic to reduce code duplication.
The timer creation logic in resumeGame() (lines 97-104) duplicates the identical logic from startGame() (lines 61-68). This violates the DRY principle and makes the code harder to maintain.
♻️ Proposed refactor to extract timer logic
+ void _startTimer() {
+ _timer?.cancel();
+ _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
+ _timeRemaining -= 0.1;
+ if (_timeRemaining <= 0) {
+ _timer?.cancel();
+ _gameState = GameState.bust;
+ }
+ onStateChanged();
+ });
+ }
+
void startGame() {
_currentScore = 0;
_timeRemaining = 10.0;
_gameState = GameState.playing;
_showOnboarding = false;
_saveOnboardingState();
- _timer?.cancel();
- _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
- _timeRemaining -= 0.1;
- if (_timeRemaining <= 0) {
- _timer?.cancel();
- _gameState = GameState.bust;
- }
- onStateChanged();
- });
+ _startTimer();
onStateChanged();
}
void resumeGame() {
if (_gameState != GameState.paused) return;
_gameState = GameState.playing;
- _timer?.cancel();
- _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
- _timeRemaining -= 0.1;
- if (_timeRemaining <= 0) {
- _timer?.cancel();
- _gameState = GameState.bust;
- }
- onStateChanged();
- });
+ _startTimer();
onStateChanged();
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void resumeGame() { | |
| if (_gameState != GameState.paused) return; | |
| _gameState = GameState.playing; | |
| _timer?.cancel(); | |
| _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) { | |
| _timeRemaining -= 0.1; | |
| if (_timeRemaining <= 0) { | |
| _timer?.cancel(); | |
| _gameState = GameState.bust; | |
| } | |
| onStateChanged(); | |
| }); | |
| onStateChanged(); | |
| } | |
| void _startTimer() { | |
| _timer?.cancel(); | |
| _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) { | |
| _timeRemaining -= 0.1; | |
| if (_timeRemaining <= 0) { | |
| _timer?.cancel(); | |
| _gameState = GameState.bust; | |
| } | |
| onStateChanged(); | |
| }); | |
| } | |
| void startGame() { | |
| _currentScore = 0; | |
| _timeRemaining = 10.0; | |
| _gameState = GameState.playing; | |
| _showOnboarding = false; | |
| _saveOnboardingState(); | |
| _startTimer(); | |
| onStateChanged(); | |
| } | |
| void resumeGame() { | |
| if (_gameState != GameState.paused) return; | |
| _gameState = GameState.playing; | |
| _startTimer(); | |
| onStateChanged(); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/providers/game_logic.dart` around lines 93 - 106, The timer creation
logic in the resumeGame() method duplicates the identical timer setup code from
the startGame() method, violating the DRY principle. Extract the timer creation
logic (the Timer.periodic call that decrements _timeRemaining, checks for bust
state, and calls onStateChanged) into a private helper method (e.g.,
_startGameTimer()). Then replace the duplicated timer initialization code in
both resumeGame() and startGame() with calls to this new helper method.
| enum GameState { | ||
| home, | ||
| playing, | ||
| paused, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check for switch statements over GameState that may be missing the paused case.
rg -nP -A15 'switch\s*\(\s*\w+\.gameState\s*\)' --type=dartRepository: hexivine/volt-rush
Length of output: 817
🏁 Script executed:
#!/bin/bash
# Check the GameState enum definition in game_logic.dart
echo "=== GameState enum definition ==="
rg -nA 30 'enum GameState' lib/providers/game_logic.dart --type=dart
echo -e "\n=== Check main.dart switch statement with more context ==="
sed -n '45,65p' lib/main.dart
echo -e "\n=== Search for all GameState switch statements ==="
rg -n 'switch.*gameState|case GameState\.' lib/main.dart --type=dart
echo -e "\n=== Check for other GameState references ==="
rg -n 'GameState\.' lib --type=dart | head -20Repository: hexivine/volt-rush
Length of output: 2130
🏁 Script executed:
#!/bin/bash
# Verify Dart version and check if this would trigger exhaustiveness check
echo "=== Check pubspec.yaml for Dart SDK version ==="
rg -A 5 "sdk:" pubspec.yaml
echo -e "\n=== Verify pauseGame() and resumeGame() exist in GameProvider ==="
rg -n 'void pauseGame|void resumeGame' lib/providers/game_logic.dart --type=dart -A 2Repository: hexivine/volt-rush
Length of output: 652
Add missing switch case for GameState.paused in main.dart.
The GameState enum includes a paused variant (line 116 in game_logic.dart), but the switch statement in main.dart (lines 51–60) only handles home, playing, banked, and bust. With Dart 3.4+, this non-exhaustive switch over an enum without a default case triggers a compilation error. Additionally, pauseGame() (line 87) and resumeGame() (line 93) in GameProvider set and check GameState.paused, but the UI has no screen to display when the game is paused.
Add a case for GameState.paused in the switch statement to render an appropriate pause screen.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@lib/providers/game_logic.dart` at line 116, Add a missing case for
GameState.paused in the switch statement in main.dart (lines 51-60) that
currently handles only home, playing, banked, and bust states. When
GameState.paused is encountered (which is set by the pauseGame() method in
GameProvider), render an appropriate pause screen UI instead of leaving it
unhandled. This will resolve the compilation error triggered by Dart 3.4+
requiring exhaustive enum handling in switch statements and provide the UI
needed to display the paused game state that pauseGame() and resumeGame()
methods are managing.
|
Auto-Fix PR Available CodePeel has generated fixes for this review: #204 |
⚙️ CodePeel WalkthroughCommits: reviewing 📁 Files reviewed (2)lib/providers/
Overview
Key Changes
Risk Assessment
Changes
Review effort: ⬤◯◯◯◯ (1/5) Health score: 🟢 100/100 | Inline comments: 0 SummaryAdded test_staging.txt file for staging environment testing. |
⚙️ CodePeel WalkthroughCommits: reviewing 📁 Files reviewed (2)lib/providers/
Overview
Key Changes
Risk Assessment
Changes
Review effort: ⬤◯◯◯◯ (1/5) Health score: 🟢 100/100 | Inline comments: 0 SummaryAdded a new binary file |
Summary
esumeGame() methods
Test plan
Co-Authored-By: Oz oz-agent@warp.dev
Summary by CodeRabbit