Skip to content

Instantly share code, notes, and snippets.

@kobakoto-jy
Created January 27, 2022 14:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kobakoto-jy/7bf2a47f4399dad26e5b1100a2b6df3e to your computer and use it in GitHub Desktop.
Save kobakoto-jy/7bf2a47f4399dad26e5b1100a2b6df3e to your computer and use it in GitHub Desktop.
IEnumratorをある程度同時実行しつつ、全部完了するまで待機してくれる感じの奴
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 指定した数だけ同時実行するコルーチンのキュークラス;
/// 実行されるコルーチンはtargetBehaviourを使って生成され;
/// exeCoroutineにパスワードと共に登録する;
/// コルーチンは役目を終えたら;
/// 自らexeCoroutineに登録してるパスワードから自身を停止状態であると教える;
/// </summary>
public class ParallelCoroutineQueue
{
public class KeyCoroutine
{
/// <summary>
/// 登録コルーチン;
/// </summary>
public Coroutine ExeCoroutine { get; set; }
/// <summary>
/// パスワード;
/// </summary>
public string Key { get; set; }
/// <summary>
/// 実行中;
/// </summary>
public bool IsRunning { get; set; }
}
#region DECLARATION
/// <summary>
/// 同時実行の制限値;
/// </summary>
public int ParallelLength { get; set; } = 5;
private Queue<IEnumerator> entryEnumerators = new Queue<IEnumerator>();
private List<KeyCoroutine> exeCoroutine = new List<KeyCoroutine>();
private MonoBehaviour targetBehaviour = null;
#endregion // DECLARATION;
#region FUNCTION
/// <summary>
/// IEnumeratorの追加;
/// </summary>
/// <param name="enumerator"></param>
public void Add(IEnumerator enumerator)
{
entryEnumerators.Enqueue(enumerator);
}
/// <summary>
/// 追加したIEnumerator達を実行していく;
/// 全部実行したら終了になる;
/// </summary>
/// <param name="mb"></param>
/// <returns></returns>
public IEnumerator WaitForCoroutine(MonoBehaviour mb)
{
targetBehaviour = mb;
do
{
for (int i = 0; i < exeCoroutine.Count; ++i)
{
yield return exeCoroutine[i];
}
exeCoroutine.RemoveAll(item => !item.IsRunning);
while (entryEnumerators.Count != 0 && exeCoroutine.Count < ParallelLength)
{
AddExeCoroutine();
}
} while (entryEnumerators.Count != 0 || exeCoroutine.Count != 0);
}
private IEnumerator ExeCoroutine(IEnumerator enumerator, string path)
{
yield return enumerator;
ComplateExeCheckPath(path);
}
private void AddExeCoroutine()
{
// 10桁のパスワードを作る;
var key = Guid.NewGuid().ToString("N").Substring(0, 10);
var coroutine = targetBehaviour.StartCoroutine(ExeCoroutine(entryEnumerators.Dequeue(), key));
exeCoroutine.Add(new KeyCoroutine()
{
ExeCoroutine = coroutine,
Key = key,
IsRunning = true,
});
}
private void ComplateExeCheckPath(string key)
{
for(int i = 0; i < exeCoroutine.Count; ++i)
{
if(exeCoroutine[i].Key == key)
{
exeCoroutine[i].IsRunning = false;
return;
}
}
}
#endregion // FUNCTION;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment