-
Notifications
You must be signed in to change notification settings - Fork 0
/
RobustTimerFactory.cs
144 lines (120 loc) · 3.92 KB
/
RobustTimerFactory.cs
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using Xamarin.Forms;
namespace mtda.Framework
{
public enum TimerState
{
Stopped,
Running,
Paused
}
public interface IRobustTimer
{
TimeSpan Duration { get; }
TimeSpan Interval { get; }
TimerState State { get; }
void Start();
void Pause();
void Reset();
void SetInterval(TimeSpan interval);
void SetDuration(TimeSpan remainingTime);
}
public static class RobustTimerFactory
{
public static IRobustTimer Create(TimeSpan interval, TimeSpan timespan, Action<TimeSpan> onTick, Action onComplete = null)
{
return new RobustTimer(interval, timespan, TimerState.Stopped, onTick, onComplete);
}
public static IRobustTimer CreateAndPause(TimeSpan interval, TimeSpan timespan, Action<TimeSpan> onTick, Action onComplete = null)
{
return new RobustTimer(interval, timespan, TimerState.Paused, onTick, onComplete);
}
public static IRobustTimer CreateAndStartRunning(TimeSpan interval, TimeSpan timespan, Action<TimeSpan> onTick, Action onComplete = null)
{
var timer = new RobustTimer(interval, timespan, TimerState.Running, onTick, onComplete);
timer.Start();
return timer;
}
private class RobustTimer : IRobustTimer
{
private TimeSpan _originalDuration;
private TimeSpan _duration;
public TimeSpan Duration
{
get
{
return _duration;
}
}
private TimeSpan _interval;
public TimeSpan Interval
{
get
{
return _interval;
}
}
private TimerState _state;
public TimerState State
{
get { return _state; }
}
readonly Action<TimeSpan> _onTick;
readonly Action _onComplete;
public RobustTimer(TimeSpan interval, TimeSpan timespan, TimerState initialState, Action<TimeSpan> onTick, Action onComplete = null)
{
_interval = interval;
_duration = timespan;
_originalDuration = timespan;
_state = initialState;
_onTick = onTick;
_onComplete = onComplete;
}
public void Start()
{
_state = TimerState.Running;
RunTimer();
}
public void Pause()
{
_state = TimerState.Paused;
}
public void Reset()
{
_state = TimerState.Stopped;
_duration = _originalDuration;
}
public void SetInterval(TimeSpan interval)
{
_interval = interval;
}
public void SetDuration(TimeSpan remainingTime)
{
_duration = remainingTime;
_originalDuration = remainingTime;
}
private void RunTimer()
{
Device.StartTimer(_interval, () =>
{
if (_state != TimerState.Running)
{
return false;
}
// reduce the remaining time by the interval
_duration = _duration - _interval;
// if the timer has completed
if (_duration.TotalMilliseconds <= 0)
{
Reset();
_onComplete?.Invoke();
return false;
}
// fire the timer event
_onTick.Invoke(_duration);
return true;
});
}
}
}
}