Implementation of coroutine - take WaitForSeconds as an example

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

Guess you like

Origin blog.csdn.net/weixin_51669718/article/details/128455790