using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using XericLibrary.Runtime.Type; namespace XericLibrary { /// /// 线性处理流程 /// public class ProgramFlowLinear : WeaklyObject { #region 委托事件 /// /// 恢复待执行事件列表 /// public event Action RecoveredCoroutineList; #endregion #region 字段属性 /// /// 设定是否循环处理所有协程 /// public bool LoopProgramFlow { get => loopProgramFlow; set { if(TargetEvent == null) loopProgramFlow = value; else Debug.LogError("不允许在协程运行中进行处理流程模式的切换"); } } /// /// 循环处理所有协程 /// private bool loopProgramFlow = true; /// /// 最大执行计数 /// public int MaxEmbeddedLoopCount = 100; /// /// 当前协程内执行流程计数 /// private int embeddedLoopCount = 0; /// /// 等待执行的协程 /// private LinkedList routines = new LinkedList(); /// /// 当前执行的协程 /// private Coroutine TargetEvent; /// /// 持久担保者 /// private MonoBehaviour assure; /// /// 第一次执行 /// private bool firstTime = true; #endregion /// /// 线性协程处理器,将一系列协程进行线性处理; /// /// 将添加协程的过程进行定义 /// 协程处理的担保脚本 /// 在定义完成后立即执行协程 /// 设定协程循环执行,如果不循环则需要手动调用start方法 public ProgramFlowLinear(Action recoveredListTodo, MonoBehaviour assure, bool executeImmediately = true, bool loopProgram = true) { RecoveredCoroutineList = recoveredListTodo; this.loopProgramFlow = loopProgram; firstTime = true; if(executeImmediately) StartCoroutine(); } #region 方法 /// /// 添加待处理协程 /// /// public void AddCoroutine(IEnumerator routine) { routines.AddLast(routine); } /// /// 协程!启动! /// public void StartCoroutine() { if(TargetEvent == null) { if(firstTime && routines.Count <= 0) RecoveredCoroutineList(); if(routines.Count <= 0) { Debug.LogError("协程步骤为空,可能是并非初始,或复位栈为空"); return; } TargetEvent = assure.StartCoroutine(routines.First.Value); routines.RemoveFirst(); firstTime = false; } } /// /// 执行下一个协程 /// public void NextCoroutine() { if(loopProgramFlow && routines.Count <= 0) RecoveredCoroutineList(); if(TargetEvent != null) TargetEvent = null; else Debug.LogError("执行的协程步骤来自初始?"); StartCoroutine(); } /// /// 尝试增加协程执行计数,当计数超越预设范围后将提示停止协程 /// public bool TryPromoteEmbedded() { if(++embeddedLoopCount > MaxEmbeddedLoopCount) { embeddedLoopCount = 0; return true; } return false; } #endregion } }