This commit introduces a complete statistics tracking and visualization system for the Oche Companion darts app, addressing multiple race condition issues and enhancing user experience with audio/vibration feedback controls. MAJOR FEATURES: Statistics & Database (Breaking Changes) - Upgraded Room database from v10 to v12 with destructive migration - Added hit distribution map (Map<String, Integer>) to Statistics entity - Implemented HitDistributionConverter with Gson for Map<->JSON persistence - Registered TypeConverter at database level for automatic conversion - Expanded Statistics entity to track: * Scoring milestones (60+, 100+, 140+, 180) * First 9 darts average (starting consistency metric) * Checkout statistics (successful finishes, highest checkout) * Double-out attempt tracking (success/miss rates) * Hit distribution for heat map visualization * Matches played counter GameActivity Enhancements - Added DartHit inner class to track baseValue and multiplier per dart - Implemented parallel tracking with mCurrentTurnDartHits list - Created recordTurnHitsToStatistics() for hit distribution updates - Added trackDoubleAttempt() for double-out success/failure recording - Added incrementMatchesPlayed() called on match completion - Fixed checkout value calculation (final dart, not full turn score) - Fixed bust tracking (addMissedDarts instead of saveDartsThrown) - Renamed Statistics getters/setters for consistency: * dartsThrown -> totalDartsThrown * overallPointsMade -> totalPoints * doubleOutsTargeted -> totalDartsAtDouble CRITICAL BUG FIXES: Race Condition Resolution - Fixed list clearing race: Pass copies (new ArrayList<>) to background threads - Fixed database race: Added per-player synchronization locks (mPlayerStatsLocks HashMap) - Implemented double synchronized block pattern: 1. synchronized(mPlayerStatsLocks) to get/create player lock 2. synchronized(lock) to protect entire READ-MODIFY-WRITE operation - Allows concurrent updates for different players while preventing data corruption User Feedback System - Added audio/vibration feedback toggle preferences - Implemented SharedPreferences reading in onResume() - Added conditional checks (mIsAudioEnabled, mIsVibrationEnabled) throughout - Created preference UI with toggle buttons and dynamic icons - Added Day/Night auto mode with mutual exclusion logic Visualization Components - Created HeatmapView custom view extending View - Implements dartboard rendering with Canvas path calculations - Color interpolation from cold (faded) to hot (volt green) - Splits board into concentric rings: doubles, outer singles, triples, inner singles - Added TestActivity for heatmap development/debugging - Added navigation from MainMenuActivity title click to TestActivity UI/UX Improvements - Added vector drawables for audio/vibration states (on/off) - Enhanced preferences screen with categorized sections - Improved settings fragment with preference interaction logic - Added Gson dependency (v2.13.2) for JSON serialization Code Quality - Added comprehensive JavaDoc to all new Statistics methods - Made all method parameters final for immutability - Added detailed logging for statistics operations - Improved error handling with try-catch blocks in background threads TECHNICAL NOTES: - Database migration is DESTRUCTIVE (all data lost on schema change) - Per-player locks enable parallel statistics updates across players - Hit distribution keys use format: "t20", "d16", "s5", "sb", "db" - Heatmap normalizes weights against max hits for consistent coloring - Statistics now tracks 15+ distinct performance metrics TESTING RECOMMENDATIONS: - Verify hit distribution persists correctly across matches - Test concurrent multi-player statistics updates - Confirm checkout values reflect final dart, not turn total - Validate milestone counters increment accurately - Test heatmap visualization with varied hit patterns
36 lines
1.6 KiB
TOML
36 lines
1.6 KiB
TOML
[versions]
|
|
agp = "9.0.0"
|
|
junit = "4.13.2"
|
|
junitVersion = "1.3.0"
|
|
espressoCore = "3.7.0"
|
|
appcompat = "1.7.1"
|
|
material = "1.13.0"
|
|
activity = "1.12.2"
|
|
constraintlayout = "2.2.1"
|
|
glide = "5.0.5"
|
|
room = "2.8.4"
|
|
preferences = "1.2.1"
|
|
preference = "1.2.1"
|
|
konfetti = "2.0.5"
|
|
gson = "2.13.2"
|
|
|
|
|
|
[libraries]
|
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
|
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
|
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
|
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
|
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
|
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
|
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
|
glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide"}
|
|
room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room"}
|
|
room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room"}
|
|
preferences = { group = "androidx.preference", name="preference-ktx", version.ref="preferences" }
|
|
preference = { group = "androidx.preference", name = "preference", version.ref = "preference" }
|
|
konfetti = { group = "nl.dionsegijn", name = "konfetti-xml", version.ref = "konfetti" }
|
|
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
|
|
|
|
[plugins]
|
|
android-application = { id = "com.android.application", version.ref = "agp" }
|