-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathProgressManager.cs
More file actions
91 lines (73 loc) · 2.87 KB
/
Copy pathProgressManager.cs
File metadata and controls
91 lines (73 loc) · 2.87 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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
namespace BlocklyNet.Scripting.Engine;
/// <summary>
/// Progress helper.
/// </summary>
public class ProgressManager
{
/// <summary>
/// Get current time - may be overwritten in test.
/// </summary>
internal Func<DateTime> Now = () => DateTime.UtcNow;
/// <summary>
/// Maximum time to finish estimation value.
/// </summary>
private static readonly TimeSpan MaximumRemainingSeconds = TimeSpan.FromDays(366);
/// <summary>
/// Latest progress seen.
/// </summary>
public ProgressDetails? Latest { get; private set; }
/// <summary>
/// Reset progress data.
/// </summary>
public void Reset()
{
Latest = null;
}
/// <summary>
/// Time of the progress with the smallest value.
/// </summary>
private DateTime _startTime;
/// <summary>
/// Progress with the smallest value.
/// </summary>
private double? _startProgress;
/// <summary>
/// Add a new progress.
/// </summary>
/// <param name="info">Progress data.</param>
/// <param name="progress">Progress value between 0 and 1.</param>
/// <param name="name">Optional name of the progress.</param>
/// <param name="addEstimation">Set to add time to finish estimation - if possible.</param>
/// <param name="noVisualisation">Set to hide progress from beeing shown.</param>
public void Update(object info, double? progress, string? name, bool? addEstimation, bool? noVisualisation)
{
// This is the very first.
if (Latest == null) _startProgress = null;
// Update as requested.
Latest = new() { Progress = progress ?? 0, Name = name, Info = info, NoVisualisation = noVisualisation };
// Can not estimate at all.
if (Latest.Progress < 0 || Latest.Progress > 1) return;
// Our very first progress - or a reset on backrunning progress.
var now = Now();
if (_startProgress == null || Latest.Progress < _startProgress)
{
// Remember first valid or minimum progress as a reference.
_startTime = now;
_startProgress = Latest.Progress;
return;
}
// No estimation requested.
if (addEstimation != true) return;
// Check for time expired so far - and respect some lower threshold.
var deltaTime = now - _startTime;
var deltaProgress = Latest.Progress - _startProgress;
if (deltaTime.TotalSeconds < 1 || deltaProgress < 0.01) return;
// Time to complete the full progress.
var totalEstimation = deltaTime / deltaProgress;
// Remaining time.
var remainingEstimation = (1 - Latest.Progress) * totalEstimation;
// Check for regular number - esp. overflow.
if (remainingEstimation < MaximumRemainingSeconds)
Latest.EstimatedRemainingSeconds = remainingEstimation.Value.TotalSeconds;
}
}