forked from Real-Serious-Games/C-Sharp-Promise
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPromiseTimer.cs
More file actions
162 lines (138 loc) · 4.62 KB
/
PromiseTimer.cs
File metadata and controls
162 lines (138 loc) · 4.62 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
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RSG
{
/// <summary>
/// A class that wraps a pending promise with it's predicate and time data
/// </summary>
internal class PredicateWait
{
/// <summary>
/// Predicate for resolving the promise
/// </summary>
public Func<TimeData, bool> predicate;
/// <summary>
/// The time the promise was started
/// </summary>
public float timeStarted;
/// <summary>
/// The pending promise which is an interface for a promise that can be rejected or resolved.
/// </summary>
public IPendingPromise pendingPromise;
/// <summary>
/// The time data specific to this pending promise. Includes elapsed time and delta time.
/// </summary>
public TimeData timeData;
}
/// <summary>
/// Time data specific to a particular pending promise.
/// </summary>
public struct TimeData
{
/// <summary>
/// The amount of time that has elapsed since the pending promise started running
/// </summary>
public float elapsedTime;
/// <summary>
/// The amount of time since the last time the pending promise was updated.
/// </summary>
public float deltaTime;
}
public interface IPromiseTimer
{
/// <summary>
/// Resolve the returned promise once the time has elapsed
/// </summary>
IPromise WaitFor(float seconds);
/// <summary>
/// Resolve the returned promise once the predicate evaluates to true
/// </summary>
IPromise WaitUntil(Func<TimeData, bool> predicate);
/// <summary>
/// Resolve the returned promise once the predicate evaluates to false
/// </summary>
IPromise WaitWhile(Func<TimeData, bool> predicate);
/// <summary>
/// Update all pending promises. Must be called for the promises to progress and resolve at all.
/// </summary>
void Update(float deltaTime);
}
public class PromiseTimer : IPromiseTimer
{
/// <summary>
/// The current running total for time that this PromiseTimer has run for
/// </summary>
private float curTime;
/// <summary>
/// Currently pending promises
/// </summary>
private List<PredicateWait> waiting = new List<PredicateWait>();
/// <summary>
/// Resolve the returned promise once the time has elapsed
/// </summary>
public IPromise WaitFor(float seconds)
{
return WaitUntil(t => t.elapsedTime >= seconds);
}
/// <summary>
/// Resolve the returned promise once the predicate evaluates to false
/// </summary>
public IPromise WaitWhile(Func<TimeData, bool> predicate)
{
return WaitUntil(t => !predicate(t));
}
/// <summary>
/// Resolve the returned promise once the predicate evalutes to true
/// </summary>
public IPromise WaitUntil(Func<TimeData, bool> predicate)
{
var promise = new Promise();
var wait = new PredicateWait()
{
timeStarted = curTime,
pendingPromise = promise,
timeData = new TimeData(),
predicate = predicate
};
waiting.Add(wait);
return promise;
}
/// <summary>
/// Update all pending promises. Must be called for the promises to progress and resolve at all.
/// </summary>
public void Update(float deltaTime)
{
curTime += deltaTime;
int i = 0;
while (i < waiting.Count)
{
var wait = waiting[i];
var newElapsedTime = curTime - wait.timeStarted;
wait.timeData.deltaTime = newElapsedTime - wait.timeData.elapsedTime;
wait.timeData.elapsedTime = newElapsedTime;
bool result;
try
{
result = wait.predicate(wait.timeData);
}
catch (Exception ex)
{
wait.pendingPromise.Reject(ex);
waiting.RemoveAt(i);
continue;
}
if (result)
{
wait.pendingPromise.Resolve();
waiting.RemoveAt(i);
}
else
{
i++;
}
}
}
}
}