完整代码:
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
namespace GameLogic.CoroutinePipeline
{
/// <summary>
/// 运行协程的Mono
/// </summary>
public class CoroutineRunner : MonoBehaviour
{
public static CoroutineRunner Runner;
private void Awake()
{
gameObject.hideFlags = HideFlags.HideAndDontSave;
DontDestroyOnLoad(gameObject);
}
}
/// <summary>
/// 协程管线的管理类
/// </summary>
public static class PipelineManager
{
private static CoroutinePipeline mainPipeline;
private static Dictionary<int, CoroutinePipeline> pipelinePool = new Dictionary<int, CoroutinePipeline>();
/// <summary>
/// 初始化方法
/// </summary>
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Init()
{
CoroutineRunner.Runner = new GameObject("CoroutineRunner").AddComponent<CoroutineRunner>();
mainPipeline = new CoroutinePipeline(0, true);
pipelinePool.Add(0, mainPipeline);
mainPipeline.Play();
}
/// <summary>
/// 注销子管线
/// </summary>
/// <param name="index">管线索引</param>
public static void DestroyPipeline(int index)
{
if (pipelinePool.ContainsKey(index) && index != 0)
{
pipelinePool.Remove(index);
}
}
/// <summary>
/// 获得索引对应的管线
/// </summary>
/// <param name="index">管线索引</param>
/// <returns>索引对应的管线,若索引不存在返回主管线</returns>
public static CoroutinePipeline GetPipeline(int index = 0)
{
if (pipelinePool.ContainsKey(index))
{
return pipelinePool[index];
}
else
{
return mainPipeline;
}
}
/// <summary>
/// 创建新的子管线
/// </summary>
/// <param name="isSustained">是否为持续管线</param>
/// <returns></returns>
public static int CreatePipeline(bool isSustained = false)
{
int index = 1;
while (true)
{
if (!pipelinePool.ContainsKey(index))
{
pipelinePool.Add(index, new CoroutinePipeline(index, isSustained));
return index;
}
index++;
}
}
/// <summary>
/// 将协程注册至协程管线
/// </summary>
/// <param name="enumerator">需要注册的协程</param>
/// <param name="pipelineIndex">注册目标管线索引,默认为主管线</param>
public static void EnPipeline(this IEnumerator enumerator, int pipelineIndex = 0)
{
GetPipeline(pipelineIndex).EnPipeline(enumerator);
}
/// <summary>
/// 将协程注册至协程管线当前执行协程之后
/// </summary>
/// <param name="enumerator">需要注册的协程</param>
/// <param name="pipelineIndex">注册目标管线索引,默认为主管线</param>
public static void SyncInsertPipeline(this IEnumerator enumerator, int pipelineIndex = 0)
{
GetPipeline(pipelineIndex).SyncInsertPipeline(enumerator);
}
/// <summary>
/// 将协程注册至协程管线中第一个等于插入目标的协程之后
/// </summary>
/// <param name="enumerator">需要注册的协程</param>
/// <param name="target">插入目标</param>
/// <param name="pipelineIndex">注册目标管线索引,默认为主管线</param>
public static void AsyncInsertPipeline(this IEnumerator enumerator, IEnumerator target, int pipelineIndex = 0)
{
GetPipeline(pipelineIndex).AsyncInsertPipeline(enumerator, target);
}
/// <summary>
/// 将协程注册至索引对应的协程管线中最新的并行监听中,若没有将新建立一个监听
/// </summary>
/// <param name="enumerator">需要注册的协程</param>
/// <param name="pipelineIndex">注册目标管线索引,默认为主管线</param>
public static void EnParallelListener(this IEnumerator enumerator, int pipelineIndex = 0)
{
ParallelPipeline pipeline = GetPipeline(pipelineIndex).GetLastParallelPipeline();
if (pipeline != null)
{
enumerator.EnPipeline(pipeline.CreatePipeline());
}
else
{
pipeline = new ParallelPipeline(pipelineIndex);
pipeline.EnPipeline();
enumerator.EnPipeline(pipeline.CreatePipeline());
}
}
}
/// <summary>
/// 管线的并行监听类
/// </summary>
public class ParallelPipeline
{
private List<CoroutinePipeline> coroutines;
private CoroutinePipeline belongPipeline;
public ParallelPipeline()
{
coroutines = new List<CoroutinePipeline>();
this.belongPipeline = PipelineManager.GetPipeline();
}
public ParallelPipeline(List<CoroutinePipeline> coroutines)
{
coroutines = new List<CoroutinePipeline>(coroutines);
this.belongPipeline = PipelineManager.GetPipeline();
}
public ParallelPipeline(CoroutinePipeline belongPipeline)
{
coroutines = new List<CoroutinePipeline>();
this.belongPipeline = belongPipeline;
}
public ParallelPipeline(int belongPipelineIndex)
{
coroutines = new List<CoroutinePipeline>();
this.belongPipeline = PipelineManager.GetPipeline(belongPipelineIndex);
}
public ParallelPipeline(CoroutinePipeline belongPipeline, List<CoroutinePipeline> coroutines)
{
coroutines = new List<CoroutinePipeline>(coroutines);
this.belongPipeline = belongPipeline;
}
public ParallelPipeline(int belongPipelineIndex, List<CoroutinePipeline> coroutines)
{
coroutines = new List<CoroutinePipeline>(coroutines);
this.belongPipeline = PipelineManager.GetPipeline(belongPipelineIndex);
}
/// <summary>
/// 并行管线激活
/// </summary>
private void PipelineEnable()
{
foreach (var item in coroutines)
{
item.Play();
}
}
/// <summary>
/// 将并行管线注册至协程管线
/// </summary>
public void EnPipeline()
{
belongPipeline.EnParallelList(this);
ParallelPipelineWaiter().EnPipeline(belongPipeline.index);
}
/// <summary>
/// 将并行管线注册至协程管线当前执行协程之后
/// </summary>
public void SyncInsertPipeline()
{
belongPipeline.EnParallelList(this);
ParallelPipelineWaiter().SyncInsertPipeline(belongPipeline.index);
}
/// <summary>
/// 将并行管线注册至协程管线中第一个等于插入目标的协程之后
/// </summary>
/// <param name="target">插入目标</param>
public void AsyncInsertPipeline(IEnumerator target)
{
belongPipeline.EnParallelList(this);
ParallelPipelineWaiter().AsyncInsertPipeline(target, belongPipeline.index);
}
/// <summary>
/// 添加管线至此监听
/// </summary>
/// <param name="coroutine"></param>
public void AddPipeline(CoroutinePipeline coroutine)
{
coroutines.Add(coroutine);
}
/// <summary>
/// 创建管线并添加至此监听
/// </summary>
/// <returns>创建的管线索引</returns>
public int CreatePipeline()
{
int index = PipelineManager.CreatePipeline();
coroutines.Add(PipelineManager.GetPipeline(index));
return index;
}
/// <summary>
/// 封装的监听协程
/// </summary>
private IEnumerator ParallelPipelineWaiter()
{
PipelineEnable();
yield return ParallelHandle().AsIEnumerator();
}
private async Task ParallelHandle()
{
await Task.Run(() => Monitor());
}
public void Monitor()
{
try
{
while (true)
{
if (coroutines.Count == 0)
{
continue;
}
int i = 0;
foreach (var item in coroutines)
{
if (!item.isEnd)
{
continue;
}
i++;
}
if (i == coroutines.Count)
{
belongPipeline.DeParallelList(this);
return;
}
}
}
catch (System.Exception e)
{
Debug.LogError(e);
}
}
}
/// <summary>
/// 协程管线实例
/// </summary>
public class CoroutinePipeline
{
public bool isEnd = false;
private LinkedList<IEnumerator> coroutineLink = new LinkedList<IEnumerator>();
private LinkedListNode<IEnumerator> isPlayNode;
private List<ParallelPipeline> ParallelList = new List<ParallelPipeline>();
private Coroutine coroutine;
private bool isPause = true;
private bool isSustained;
public int index { private set; get; }
public CoroutinePipeline(int index, bool isSustained = false)
{
this.index = index;
this.isSustained = isSustained;
coroutine = CoroutineRunner.Runner.StartCoroutine(Coroutine());
}
public void EnParallelList(ParallelPipeline pipeline)
{
ParallelList.Add(pipeline);
}
public void DeParallelList(ParallelPipeline pipeline)
{
ParallelList.Remove(pipeline);
}
public ParallelPipeline GetLastParallelPipeline()
{
if (ParallelList.Count == 0)
{
return null;
}
else
{
return ParallelList[ParallelList.Count - 1];
}
}
/// <summary>
/// 将协程注册至协程管线
/// </summary>
/// <param name="enumerator">需要注册的协程</param>
public void EnPipeline(IEnumerator enumerator)
{
coroutineLink.AddLast(enumerator);
}
/// <summary>
/// 将协程注册至协程管线当前执行协程之后
/// </summary>
/// <param name="enumerator">需要注册的协程</param>
public void SyncInsertPipeline(IEnumerator enumerator)
{
if (isPlayNode == null)
{
coroutineLink.AddLast(enumerator);
}
else
{
coroutineLink.AddAfter(isPlayNode, enumerator);
}
}
/// <summary>
/// 将协程注册至协程管线中第一个等于插入目标的协程之后
/// </summary>
/// <param name="enumerator">需要注册的协程</param>
/// <param name="target">插入目标</param>
public void AsyncInsertPipeline(IEnumerator enumerator, IEnumerator target)
{
LinkedListNode<IEnumerator> node = coroutineLink.Find(target);
if (node == null)
{
coroutineLink.AddLast(enumerator);
}
else
{
coroutineLink.AddAfter(node, enumerator);
}
}
/// <summary>
/// 管线暂停
/// </summary>
public void Pause()
{
isPause = true;
}
/// <summary>
/// 管线播放
/// </summary>
public void Play()
{
isPause = false;
}
private IEnumerator Coroutine()
{
IEnumerator runingCoroutine = null;
bool IsDone = true;
while (!isEnd)
{
if (!isPause)
{
if (runingCoroutine == null && coroutineLink.Count != 0)
{
isPlayNode = coroutineLink.First;
runingCoroutine = isPlayNode.Value;
}
else if (coroutineLink.Count == 0)
{
yield return null;
}
if (runingCoroutine != null)
{
IsDone = !runingCoroutine.MoveNext();
if (!IsDone)
{
yield return runingCoroutine.Current;
}
else
{
coroutineLink.RemoveFirst();
if (!isSustained && coroutineLink.Count == 0)
{
isEnd = true;
}
IsDone = true;
runingCoroutine = null;
isPlayNode = null;
}
}
}
yield return null;
}
PipelineManager.DestroyPipeline(index);
CoroutineRunner.Runner.StopCoroutine(coroutine);
yield break;
}
}
}
769

被折叠的 条评论
为什么被折叠?



