forked from ppy/osu
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClicksPerSecondController.cs
More file actions
67 lines (49 loc) · 2.22 KB
/
Copy pathClicksPerSecondController.cs
File metadata and controls
67 lines (49 loc) · 2.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Rulesets.UI;
namespace osu.Game.Screens.Play.HUD.ClicksPerSecond
{
public partial class ClicksPerSecondController : Component
{
private readonly List<double> timestamps = new List<double>();
[Resolved]
private IGameplayClock gameplayClock { get; set; } = null!;
[Resolved]
private IFrameStableClock? frameStableClock { get; set; }
public int Value { get; private set; }
private IGameplayClock clock => frameStableClock ?? gameplayClock;
public ClicksPerSecondController()
{
RelativeSizeAxes = Axes.Both;
}
public void AddInputTimestamp() => timestamps.Add(clock.CurrentTime);
protected override void Update()
{
base.Update();
double latestValidTime = clock.CurrentTime;
double earliestTimeValid = latestValidTime - 1000 * gameplayClock.GetTrueGameplayRate();
// Timestamps are added in chronological order (from clock.CurrentTime),
// so we can use binary-search-style trimming instead of per-element RemoveAt.
// Trim future timestamps caused by rewinding (remove from the end in one batch).
// RemoveRange from the end is a single operation vs repeated RemoveAt calls.
int trimStart = timestamps.Count;
while (trimStart > 0 && timestamps[trimStart - 1] > latestValidTime)
trimStart--;
if (trimStart < timestamps.Count)
timestamps.RemoveRange(trimStart, timestamps.Count - trimStart);
// Count timestamps within the valid 1-second window.
// Since the list is in chronological order, scan backwards until we leave the window.
int count = 0;
for (int i = timestamps.Count - 1; i >= 0; i--)
{
if (timestamps[i] < earliestTimeValid)
break;
count++;
}
Value = count;
}
}
}