-
Notifications
You must be signed in to change notification settings - Fork 1
/
NobleTimer.cs
101 lines (80 loc) · 2.56 KB
/
NobleTimer.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
using System;
using System.Timers;
using System.Diagnostics;
using System.Threading;
namespace NobleRobot {
public class Timer {
private System.Timers.Timer systemTimer;
private Stopwatch stopwatch;
public int totalTickCount;
public int currentTickCount;
public float tickDuration;
public double durationRemaining;
public bool isRunning;
public delegate void TimerEvent();
public event TimerEvent onTimerTick;
public event TimerEvent onTimerComplete;
private SynchronizationContext syncContext;
public Timer(float _tickDurationInMilliseconds, TimerEvent _onCompleteMethod = null, int _totalTickCount = 1, TimerEvent _onTickMethod = null, bool startUponCreation = false){
systemTimer = new System.Timers.Timer();
stopwatch = new Stopwatch();
currentTickCount = 0;
totalTickCount = _totalTickCount;
systemTimer.Interval = durationRemaining = tickDuration = _tickDurationInMilliseconds;
systemTimer.Elapsed += onTick;
// Move operations to the main thread (required for certain Unity APIs).
//
syncContext = SynchronizationContext.Current;
syncContext.Send(state =>{
if (_onCompleteMethod != null){ onTimerComplete += _onCompleteMethod; }
if (_onTickMethod != null){ onTimerTick += _onTickMethod; }
}, null);
// Saves the user a timer.start() call, if they choose.
//
if (startUponCreation){
start();
}
}
private void onTick(object source, ElapsedEventArgs elapsedEventArguments){
currentTickCount++;
if (currentTickCount < totalTickCount){
// Calls user-set method (Internal timer resets automatically).
syncContext.Send(state =>{ onTimerTick.Invoke(); }, null);
} else {
// Calls user-set method, also stops internal timer (which is normally set to repeat).
syncContext.Send(state =>{ onTimerComplete.Invoke(); }, null);
stop();
}
}
public void start(){
systemTimer.Start();
stopwatch.Start();
isRunning = true;
}
public void pause(){
// Stop things.
systemTimer.Stop();
stopwatch.Stop();
isRunning = false;
// Set new interval based on remaining time.
systemTimer.Interval = durationRemaining = tickDuration - stopwatch.Elapsed.TotalMilliseconds;
}
public void stop(){
systemTimer.Stop();
stopwatch.Stop();
stopwatch.Reset();
isRunning = false;
currentTickCount = 0;
systemTimer.Interval = durationRemaining = tickDuration;
}
public void destroy(){
systemTimer.Close();
systemTimer.Dispose();
systemTimer = null;
stopwatch = null;
syncContext = null;
onTimerComplete = null;
onTimerTick = null;
}
}
}