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
}
}