using System.Collections.Generic; namespace ET { public static class ETTaskHelper { private class CoroutineBlocker { private int count; private List tcss = new List(); public CoroutineBlocker(int count) { this.count = count; } public async ETTask WaitAsync() { --this.count; if (this.count < 0) { return; } if (this.count == 0) { List t = this.tcss; this.tcss = null; foreach (ETTaskCompletionSource ttcs in t) { ttcs.SetResult(); } return; } ETTaskCompletionSource tcs = new ETTaskCompletionSource(); tcss.Add(tcs); await tcs.Task; } } public static async ETTask WaitAny(ETTask[] tasks) { if (tasks == null || tasks.Length == 0) { return; } CoroutineBlocker coroutineBlocker = new CoroutineBlocker(2); foreach (ETTask task in tasks) { RunOneTask(task).Coroutine(); } await coroutineBlocker.WaitAsync(); async ETVoid RunOneTask(ETTask task) { await task; await coroutineBlocker.WaitAsync(); } } public static async ETTask WaitAny(ETTask[] tasks) { if (tasks == null || tasks.Length == 0) { return; } CoroutineBlocker coroutineBlocker = new CoroutineBlocker(2); foreach (ETTask task in tasks) { RunOneTask(task).Coroutine(); } await coroutineBlocker.WaitAsync(); async ETVoid RunOneTask(ETTask task) { await task; await coroutineBlocker.WaitAsync(); } } public static async ETTask WaitAll(ETTask[] tasks) { if (tasks == null || tasks.Length == 0) { return; } CoroutineBlocker coroutineBlocker = new CoroutineBlocker(tasks.Length + 1); foreach (ETTask task in tasks) { RunOneTask(task).Coroutine(); } await coroutineBlocker.WaitAsync(); async ETVoid RunOneTask(ETTask task) { await task; await coroutineBlocker.WaitAsync(); } } public static async ETTask WaitAll(ETTask[] tasks) { if (tasks == null || tasks.Length == 0) { return; } CoroutineBlocker coroutineBlocker = new CoroutineBlocker(tasks.Length + 1); foreach (ETTask task in tasks) { RunOneTask(task).Coroutine(); } await coroutineBlocker.WaitAsync(); async ETVoid RunOneTask(ETTask task) { await task; await coroutineBlocker.WaitAsync(); } } public static async ETTask WaitAll(List tasks) { if (tasks == null || tasks.Count == 0) { return; } CoroutineBlocker coroutineBlocker = new CoroutineBlocker(tasks.Count + 1); foreach (ETTask task in tasks) { RunOneTask(task).Coroutine(); } await coroutineBlocker.WaitAsync(); async ETVoid RunOneTask(ETTask task) { await task; await coroutineBlocker.WaitAsync(); } } } }