zoukankan      html  css  js  c++  java
  • Unity协程(Coroutine)管理类——TaskManager工具分享

    Unity协程(Coroutine)管理类——TaskManager工具分享

    By D.S.Qiu

    尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com

         

            在分享 vp_Timer 中提到,没有继承的MonoBehaviour,没有Update,InVoke 和StartCoroutine的机制,vp_Timer就是提供了InVoke的机制,而且还可以统一管理。本篇D.S.Qiu要分享的TaskManager就是一个协程 管理类。 TaskManager —— Unity3D Managed Coroutines with Start, Stop, Resume ,看着就觉得很强大,当然是对于我这种对协程理解不深的来说。下面贴出 The Motivation of the author:

              /// The motivation for this is twofold:

             ///

             /// 1. The existing coroutine API provides no means of stopping specific

            ///    coroutines; StopCoroutine only takes a string argument, and it stops

           ///    all coroutines started with that same string; there is no way to stop

           ///    coroutines which were started directly from an enumerator.  This is

           ///    not robust enough and is also probably pretty inefficient.

           ///

           /// 2. StartCoroutine and friends are MonoBehaviour methods.  This means

           ///    that in order to start a coroutine, a user typically must have some

          ///    component reference handy.  There are legitimate cases where such a

          ///    constraint is inconvenient.  This implementation hides that

          ///    constraint from the user.

           代码很简单,但却很解渴,Unity官方只听过了StopCoroutine(string methodName)或StopAllCoroutine() 这两个停止方法,从api就会觉得Unity的整体方法论还不完善,所以才会觉得TaskManager的难能可贵。由于源码简单,就不做解释了,See source for document :

    /// Simple, really.  There is no need to initialize or even refer to TaskManager.  
    /// When the first Task is created in an application, a "TaskManager" GameObject  
    /// will automatically be added to the scene root with the TaskManager component  
    /// attached.  This component will be responsible for dispatching all coroutines  
    /// behind the scenes.  
    ///  
    /// Task also provides an event that is triggered when the coroutine exits.  
      
    using UnityEngine;  
    using System.Collections;  
      
    /// A Task object represents a coroutine.  Tasks can be started, paused, and stopped.  
    /// It is an error to attempt to start a task that has been stopped or which has  
    /// naturally terminated.  
    public class Task  
    {  
        /// Returns true if and only if the coroutine is running.  Paused tasks  
        /// are considered to be running.  
        public bool Running {  
            get {  
                return task.Running;  
            }  
        }  
          
        /// Returns true if and only if the coroutine is currently paused.  
        public bool Paused {  
            get {  
                return task.Paused;  
            }  
        }  
          
        /// Delegate for termination subscribers.  manual is true if and only if  
        /// the coroutine was stopped with an explicit call to Stop().  
        public delegate void FinishedHandler(bool manual);  
          
        /// Termination event.  Triggered when the coroutine completes execution.  
        public event FinishedHandler Finished;  
      
        /// Creates a new Task object for the given coroutine.  
        ///  
        /// If autoStart is true (default) the task is automatically started  
        /// upon construction.  
        public Task(IEnumerator c, bool autoStart = true)  
        {  
            task = TaskManager.CreateTask(c);  
            task.Finished += TaskFinished;  
            if(autoStart)  
                Start();  
        }  
          
        /// Begins execution of the coroutine  
        public void Start()  
        {  
            task.Start();  
        }  
      
        /// Discontinues execution of the coroutine at its next yield.  
        public void Stop()  
        {  
            task.Stop();  
        }  
          
        public void Pause()  
        {  
            task.Pause();  
        }  
          
        public void Unpause()  
        {  
            task.Unpause();  
        }  
          
        void TaskFinished(bool manual)  
        {  
            FinishedHandler handler = Finished;  
            if(handler != null)  
                handler(manual);  
        }  
          
        TaskManager.TaskState task;  
    }  
      
    class TaskManager : MonoBehaviour  
    {  
        public class TaskState  
        {  
            public bool Running {  
                get {  
                    return running;  
                }  
            }  
      
            public bool Paused  {  
                get {  
                    return paused;  
                }  
            }  
      
            public delegate void FinishedHandler(bool manual);  
            public event FinishedHandler Finished;  
      
            IEnumerator coroutine;  
            bool running;  
            bool paused;  
            bool stopped;  
              
            public TaskState(IEnumerator c)  
            {  
                coroutine = c;  
            }  
              
            public void Pause()  
            {  
                paused = true;  
            }  
              
            public void Unpause()  
            {  
                paused = false;  
            }  
              
            public void Start()  
            {  
                running = true;  
                singleton.StartCoroutine(CallWrapper());  
            }  
              
            public void Stop()  
            {  
                stopped = true;  
                running = false;  
            }  
              
            IEnumerator CallWrapper()  
            {  
                yield return null;  
                IEnumerator e = coroutine;  
                while(running) {  
                    if(paused)  
                        yield return null;  
                    else {  
                        if(e != null && e.MoveNext()) {  
                            yield return e.Current;  
                        }  
                        else {  
                            running = false;  
                        }  
                    }  
                }  
                  
                FinishedHandler handler = Finished;  
                if(handler != null)  
                    handler(stopped);  
            }  
        }  
      
        static TaskManager singleton;  
      
        public static TaskState CreateTask(IEnumerator coroutine)  
        {  
            if(singleton == null) {  
                GameObject go = new GameObject("TaskManager");  
                singleton = go.AddComponent<TaskManager>();  
            }  
            return new TaskState(coroutine);  
        }  
    }  
    /// Example usage:  
    ///  
    /// ----------------------------------------------------------------------------  
    /// IEnumerator MyAwesomeTask()  
    /// {  
    ///     while(true) {  
    ///         Debug.Log("Logcat iz in ur consolez, spammin u wif messagez.");  
    ///         yield return null;  
    ////    }  
    /// }  
    ///  
    /// IEnumerator TaskKiller(float delay, Task t)  
    /// {  
    ///     yield return new WaitForSeconds(delay);  
    ///     t.Stop();  
    /// }  
    ///  
    /// void SomeCodeThatCouldBeAnywhereInTheUniverse()  
    /// {  
    ///     Task spam = new Task(MyAwesomeTask());  
    ///     new Task(TaskKiller(5, spam));  
    /// }  
    /// ----------------------------------------------------------------------------  

    小结:

           本文主要是分享我的收藏的一些“干货”,TaskManager 和 vp_Timer 在项目中发挥了很大的作用,D.S.Qiu 一再觉得强大的东西不都是复杂的,能够使用最简单的本质方法解决问题才是代码设计的追求。 文末附上了相关的链接以及TaskManager的代码。

           

            如果您对D.S.Qiu有任何建议或意见可以在文章后面评论,或者发邮件(gd.s.qiu@gmail.com)交流,您的鼓励和支持是我前进的动力,希望能有更多更好的分享。

           转载请在文首注明出处:http://dsqiu.iteye.com/blog/2022992

    更多精彩请关注D.S.Qiu的博客和微博(ID:静水逐风)

  • 相关阅读:
    Bootstrap开发框架视频整理
    在Bootstrap开发中解决Tab标签页切换图表显示问题
    在小程序中使用腾讯视频插件播放教程视频
    在小程序后端中转获取接口数据,绕过前端调用限制
    浅析Android恶意应用及其检测技术
    Android恶意软件特征及分类
    半监督学习分类——???
    强化学习的算法分类
    brew update 过慢的解决方法
    并查集模板——核心就是路径压缩
  • 原文地址:https://www.cnblogs.com/lihonglin2016/p/4989329.html
Copyright © 2011-2022 走看看