Function: coroutine implementation - take WaitForSeconds as an example
/// <summary>
/// 功能:协程Coroutine实现——以WaitForSeconds举例
/// </summary>
public class MyCoroutine : MonoBehaviour
{
void Start()
{
CoroutineManager.Instance.StartCoroutine(MyWaitForSecond(2f));
StartCoroutine(WaitForSecond(2f));
}
void Update()
{
CoroutineManager.Instance.UpdateCoroutine();
}
public interface IWait
{
bool Tick();
}
IEnumerator WaitForSecond(float time)
{
Debug.Log("WaitForSecondsStart: "+Time.realtimeSinceStartup);
yield return new WaitForSeconds(time);
Debug.Log("WaitForSecondEnd: "+Time.realtimeSinceStartup);
}
IEnumerator MyWaitForSecond(float time)
{
Debug.Log("MyWaitForSecondsStart: "+Time.realtimeSinceStartup);
yield return new MyWaitForSeconds(time);
Debug.Log("MyWaitForSecondEnd: "+Time.realtimeSinceStartup);
}
public class MyWaitForSeconds : IWait
{
float _seconds = 0f;
public MyWaitForSeconds(float seconds)
{
this._seconds = seconds;
}
public bool Tick()
{
_seconds -= Time.deltaTime;
return _seconds <= 0;
}
}
public class MyWaitForFrames : IWait
{
private int _frames = 0;
public MyWaitForFrames(int frames)
{
this._frames = frames;
}
public bool Tick()
{
_frames--;
return _frames <= 0;
}
}
public class CoroutineManager
{
private static CoroutineManager _instance = null;
public static CoroutineManager Instance
{
get
{
if(_instance == null)
{
_instance = new CoroutineManager();
}
return _instance;
}
}
private void Start() {
_instance = this;
}
private LinkedList<IEnumerator> coroutineList = new LinkedList<IEnumerator>();
public void StartCoroutine(IEnumerator ie)
{
coroutineList.AddLast(ie);
}
public void StopCoroutine(IEnumerator ie)
{
try
{
coroutineList.Remove(ie);
}
catch(Exception e) {Debug.Log(e.ToString());}
}
public void UpdateCoroutine()
{
var node = coroutineList.First;
while(node != null)
{
IEnumerator ie = node.Value;
bool ret = true;
if(ie.Current is IWait)
{
IWait wait = (IWait)ie.Current;
if(wait.Tick())
{
ret = ie.MoveNext();
}
}
else
{
ret = ie.MoveNext();
}
if(!ret)
{
coroutineList.Remove(node);
}
node = node.Next;
}
}
}
}