Skip to content

Commit e15130d

Browse files
committed
Basic stats counting
1 parent 7b57d01 commit e15130d

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

neothesia/src/scene/playing_scene/midi_player.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,13 @@ pub enum MidiEventSource {
196196

197197
type NoteId = u8;
198198

199+
#[derive(Debug, Default)]
200+
struct NoteStats {
201+
notes_missed: usize,
202+
notes_hit: usize,
203+
wrong_notes: usize,
204+
}
205+
199206
#[derive(Debug)]
200207
struct NotePress {
201208
timestamp: Instant,
@@ -212,6 +219,8 @@ pub struct PlayAlong {
212219
user_pressed_recently: HashMap<NoteId, NotePress>,
213220
/// File notes that had NoteOn event, but no NoteOff yet
214221
in_proggres_file_notes: HashSet<NoteId>,
222+
223+
stats: NoteStats,
215224
}
216225

217226
impl PlayAlong {
@@ -221,6 +230,7 @@ impl PlayAlong {
221230
required_notes: Default::default(),
222231
user_pressed_recently: Default::default(),
223232
in_proggres_file_notes: Default::default(),
233+
stats: NoteStats::default(),
224234
}
225235
}
226236

@@ -229,20 +239,41 @@ impl PlayAlong {
229239
let now = Instant::now();
230240
let threshold = Duration::from_millis(500);
231241

242+
// Track the count of items before retain
243+
let count_before = self.user_pressed_recently.len();
244+
232245
// Retain only the items that are within the threshold
233246
self.user_pressed_recently
234247
.retain(|_, item| now.duration_since(item.timestamp) <= threshold);
248+
249+
self.stats.wrong_notes += count_before - self.user_pressed_recently.len();
235250
}
236251

237252
fn user_press_key(&mut self, note_id: u8, active: bool) {
238253
let timestamp = Instant::now();
239254

240255
if active {
241256
// Check if note has already been played by a file
242-
if self.required_notes.remove(&note_id).is_none() {
257+
if let Some(required_press) = self.required_notes.remove(&note_id) {
258+
// 160 to forgive touching the bottom
259+
let threshold = Duration::from_millis(160);
260+
261+
if timestamp.duration_since(required_press.timestamp) > threshold {
262+
self.stats.notes_missed += 1
263+
} else {
264+
self.stats.notes_hit += 1
265+
}
266+
} else {
243267
// This note was not played by file yet, place it in recents
244-
self.user_pressed_recently
245-
.insert(note_id, NotePress { timestamp });
268+
let got_replaced = self
269+
.user_pressed_recently
270+
.insert(note_id, NotePress { timestamp })
271+
.is_some();
272+
273+
if got_replaced {
274+
// TODO: This is not right, this may be to_early note, rather than wrong
275+
self.stats.wrong_notes += 1
276+
}
246277
}
247278
}
248279
}
@@ -251,7 +282,9 @@ impl PlayAlong {
251282
let timestamp = Instant::now();
252283
if active {
253284
// Check if note got pressed earlier 500ms (user_pressed_recently)
254-
if self.user_pressed_recently.remove(&note_id).is_none() {
285+
if self.user_pressed_recently.remove(&note_id).is_some() {
286+
self.stats.notes_hit += 1
287+
} else {
255288
// Player never pressed that note, let it reach required_notes
256289

257290
// Ignore overlapping notes

0 commit comments

Comments
 (0)