/
Scheduler.cs
127 lines (109 loc) · 3.63 KB
/
Scheduler.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
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class TimerMessage
{
public string message;
public float secondsBetween;
[HideInInspector]
public float nextTime;
[HideInInspector]
public GameObject gameObject;
};
public class Scheduler : MonoBehaviour
{
public TimerMessage[] messages;
private PriorityQueue<TimerMessage>priorityQueue;
private static int Comparison(TimerMessage a, TimerMessage b)
{
if (a.nextTime < b.nextTime) {
return -1;
} else if (a.nextTime > b.nextTime) {
return 1;
} else {
return 0;
}
}
static private Scheduler _instance = null;
static public Scheduler instance
{
get
{
return _instance;
}
}
void OnDestroy()
{
_instance = null;
}
void Awake()
{
if (_instance != null) { Debug.LogError("Instance should be null"); }
_instance = this;
priorityQueue = new PriorityQueue<TimerMessage>();
priorityQueue.comparator = Comparison;
for (int i = 0; i < messages.Length; i++) {
messages[i].gameObject = null;
messages[i].nextTime = Time.time + messages[i].secondsBetween;
priorityQueue.Add(messages[i]);
}
if (!priorityQueue.Empty()) {
// StartCoroutine (Schedule());
} else {
enabled = false;
}
}
public static void AddSchedule(float time, string message, bool repeat, GameObject obj = null)
{
TimerMessage msg = new TimerMessage();
msg.message = message;
msg.nextTime = Time.time + time;
msg.secondsBetween = (repeat ? time : 0.0f);
msg.gameObject = obj;
instance.priorityQueue.Add(msg);
instance.enabled = true;
}
public static void UpdateSchedule(float time, string message, GameObject obj = null)
{
TimerMessage msg =
instance.priorityQueue.Find((a) => a.message == message && a.gameObject == obj);
if (msg != null && msg.nextTime > 0) {
msg.nextTime = Time.time + time;
instance.priorityQueue.Update(msg);
} else {
AddSchedule(time, message, false, obj);
}
}
public static void CancelSchedule(string message, GameObject obj = null)
{
bool continueLoop = true;
while (continueLoop) {
continueLoop = instance.priorityQueue.Remove(
(a) => a.message == message && (obj == null || a.gameObject == obj));
}
if (instance.priorityQueue.Empty()) { instance.enabled = false; }
}
void Update()
{
if (Time.time > priorityQueue.Top.nextTime) {
// store these off so we can move the top level or remove it
GameObject obj = priorityQueue.Top.gameObject;
string message = priorityQueue.Top.message;
float secondsBetween = priorityQueue.Top.secondsBetween;
// move it before we call the message in case the message modifies the queue
if (priorityQueue.Top.secondsBetween > 0) {
priorityQueue.Top.nextTime = Time.time + priorityQueue.Top.secondsBetween;
priorityQueue.Update(priorityQueue.Top);
} else {
priorityQueue.Remove(priorityQueue.Top);
}
if (priorityQueue.Empty()) { enabled = false; }
if (obj) {
obj.SendMessage(message, secondsBetween);
} else {
Dispatcher.instance.Dispatch(message, secondsBetween);
}
}
}
}