-
Notifications
You must be signed in to change notification settings - Fork 0
/
CoroutineUtils.cs
147 lines (116 loc) · 3.33 KB
/
CoroutineUtils.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using Assets.Scripts.Services;
using System;
using System.Collections;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
public static class UnityExtensions
{
public static bool CheckColliderMask(this Collider other, LayerMask mask)
{
return (mask.value & (1 << other.transform.gameObject.layer)) > 0;
}
}
public static class CoroutineUtils
{
public static IEnumerator DoWithUpdate(float duration, Action<float> action, float startTime = 0f)
{
var elapsedTime = startTime / duration;
while (elapsedTime < duration)
{
action(elapsedTime / duration);
elapsedTime += Time.deltaTime;
yield return null;
}
action(1f);
}
public static IEnumerator WaitForRealTime(float delay)
{
while (true)
{
float pauseEndTime = Time.realtimeSinceStartup + delay;
while (Time.realtimeSinceStartup < pauseEndTime)
yield return 0;
break;
}
}
public static IEnumerator Then(this IEnumerator enumerator, Action action)
{
yield return enumerator;
action();
}
public static IEnumerator Then(this IEnumerator enumerator, IEnumerator enumerator2)
{
yield return enumerator;
yield return enumerator2;
}
public static Coroutine Start(this IEnumerator enumerator, MonoBehaviour holder = null)
{
if (holder != null)
return holder.StartCoroutine(enumerator);
return AsyncCoroutineRunnerService.Instance.StartCoroutine(enumerator);
}
public static void Immediate(this IEnumerator enumerator)
{
while (enumerator.MoveNext()) ;
}
}
public class DoInBackground : CustomYieldInstruction
{
public override bool keepWaiting => !isFinished;
private Thread thread;
private Action task;
private bool isFinished;
public DoInBackground(Action task)
{
this.task = task;
thread = new Thread(Work);
thread.Name = "bgThread" + thread.ManagedThreadId;
thread.IsBackground = true;
thread.Start(null);
}
private void Work(object args)
{
task.Invoke();
isFinished = true;
}
}
public class TaskYieldInstruction : CustomYieldInstruction
{
public Task Task { get; private set; }
public override bool keepWaiting
{
get
{
if (Task.Exception != null)
throw Task.Exception;
return !Task.IsCompleted;
}
}
public TaskYieldInstruction(Task task) =>
Task = task ?? throw new ArgumentNullException("task");
}
public class TaskYieldInstruction<T> : TaskYieldInstruction
{
public new Task<T> Task { get; private set; }
public T Result => Task.Result;
public TaskYieldInstruction(Task<T> task) : base(task)
{
Task = task;
}
}
public static class TaskYieldInstructionExtension
{
public static TaskYieldInstruction AsCoroutine(this Task task)
{
if (task == null)
throw new NullReferenceException();
return new TaskYieldInstruction(task);
}
public static TaskYieldInstruction<T> AsCoroutine<T>(this Task<T> task)
{
if (task == null)
throw new NullReferenceException();
return new TaskYieldInstruction<T>(task);
}
}