/
ConditionalTimer.ts
92 lines (79 loc) · 2.3 KB
/
ConditionalTimer.ts
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
import { IConditionalTimer, Condition, Action } from './IConditionalTimer';
import { Timer } from './Timer';
import { ITimer } from './ITimer';
/**
* A timer that performs an action over time based on the evaluation of a condition
*/
export class ConditionalTimer implements IConditionalTimer {
private timer: ITimer;
constructor(timer?: ITimer) {
this.timer = timer || new Timer(100);
}
/**
* Short hand for creating a new instance of ConditionalTimer
* @param interval
*/
public static Instance(interval?: number): ConditionalTimer {
return new ConditionalTimer(new Timer(interval));
}
/**
* Performs the given action one time after the condition evaluates to true
* @param action
* @param condition
*/
public async DoWhen(action: Action, condition: Condition): Promise<void> {
this.resetTimer();
return await new Promise<void>(async (resolve) => {
this.timer.Elapsed.push(() => {
if (condition()) {
action();
this.resetTimer();
resolve();
}
});
await this.timer.Start();
});
}
/**
* Performs the given action repeatedly until the condition evaluates to true
* @param action
* @param condition
*/
public async DoUntil(action: Action, condition: Condition): Promise<void> {
return this.getRepeatingConditionalTimer(action, condition);
}
/**
* Performs the given action repeatedly as long as the condition evaluates to true
* @param action
* @param condition
*/
public async DoWhile(action: Action, condition: Condition): Promise<void> {
return this.getRepeatingConditionalTimer(action, () => !condition());
}
/**
* Stops the underlying timer, preventing further execution
*/
public Stop(): void {
this.timer.Stop();
}
private async getRepeatingConditionalTimer(action: Action, condition: Condition): Promise<void> {
this.resetTimer();
return await new Promise<void>(async (resolve) => {
this.timer.Elapsed.push(() => {
action();
if (condition()) {
this.resetTimer();
resolve();
}
});
await this.timer.Start();
});
}
private resetTimer(): void {
if (this.timer.Enabled) {
this.Stop();
this.timer.AutoReset = true;
this.timer.Elapsed = [];
}
}
}