-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRoutineScheduler.cs
129 lines (110 loc) · 2.79 KB
/
RoutineScheduler.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
namespace MadnessMicroactive;
/// <summary>
/// Routines are like Unity coroutines.<br></br>
/// These are <b>NOT</b> threads.<br></br>
/// They're not async or parallel, but instead ran on the main thread.
/// </summary>
public static class RoutineScheduler
{
private static readonly List<Routine> routines = new();
/// <summary>
/// Start a routine.
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
public static Routine Start(IEnumerator<IRoutineCommand> task)
{
var routine = new Routine
{
Task = task
};
routines.Add(routine);
return routine;
}
/// <summary>
/// Stop a routine.
/// </summary>
/// <param name="routine"></param>
public static void Stop(Routine routine)
{
routines.Remove(routine);
}
/// <summary>
/// Stop any and all routines.
/// </summary>
public static void StopAll()
{
routines.Clear();
}
/// <summary>
/// Is this routine running?
/// </summary>
/// <param name="routine"></param>
/// <returns></returns>
public static bool IsOngoing(Routine? routine)
{
return routine != null && routines.Contains(routine);
}
/// <summary>
/// Runs all the routines.
/// </summary>
/// <param name="dt"></param>
public static void StepRoutines(float dt)
{
for (int i = routines.Count - 1; i >= 0; i--)
{
if (routines.Count <= i)
continue;
var routine = routines[i];
var item = routine.Task;
if (item == null)
continue;
var cmd = item.Current;
if (cmd == null)
advance();
else if (cmd.CanAdvance(dt))
advance();
void advance()
{
if (!item.MoveNext())
routines.Remove(routine);
}
}
}
}
public class Routine
{
public IEnumerator<IRoutineCommand>? Task;
}
public interface IRoutineCommand
{
public bool CanAdvance(float deltaTime);
}
public struct RoutineDelay : IRoutineCommand
{
public float DelayInSeconds;
public float CurrentTime;
public RoutineDelay(float delayInSeconds)
{
DelayInSeconds = delayInSeconds;
CurrentTime = 0;
}
public bool CanAdvance(float dt)
{
CurrentTime += dt;
return CurrentTime >= DelayInSeconds;
}
}
public struct RoutineFrameDelay : IRoutineCommand
{
public bool CanAdvance(float dt) => true;
}
public struct RoutineWaitUntil : IRoutineCommand
{
public readonly Func<bool> Function;
public RoutineWaitUntil(Func<bool> function)
{
Function = function;
}
public bool CanAdvance(float dt) => Function();
}