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

    尊重他人的劳动,支持原创,转载请注明出处: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 :

    C#代码  收藏代码
    1. /// Simple, really.  There is no need to initialize or even refer to TaskManager.  
    2. /// When the first Task is created in an application, a "TaskManager" GameObject  
    3. /// will automatically be added to the scene root with the TaskManager component  
    4. /// attached.  This component will be responsible for dispatching all coroutines  
    5. /// behind the scenes.  
    6. ///  
    7. /// Task also provides an event that is triggered when the coroutine exits.  
    8.   
    9. using UnityEngine;  
    10. using System.Collections;  
    11.   
    12. /// A Task object represents a coroutine.  Tasks can be started, paused, and stopped.  
    13. /// It is an error to attempt to start a task that has been stopped or which has  
    14. /// naturally terminated.  
    15. public class Task  
    16. {  
    17.     /// Returns true if and only if the coroutine is running.  Paused tasks  
    18.     /// are considered to be running.  
    19.     public bool Running {  
    20.         get {  
    21.             return task.Running;  
    22.         }  
    23.     }  
    24.       
    25.     /// Returns true if and only if the coroutine is currently paused.  
    26.     public bool Paused {  
    27.         get {  
    28.             return task.Paused;  
    29.         }  
    30.     }  
    31.       
    32.     /// Delegate for termination subscribers.  manual is true if and only if  
    33.     /// the coroutine was stopped with an explicit call to Stop().  
    34.     public delegate void FinishedHandler(bool manual);  
    35.       
    36.     /// Termination event.  Triggered when the coroutine completes execution.  
    37.     public event FinishedHandler Finished;  
    38.   
    39.     /// Creates a new Task object for the given coroutine.  
    40.     ///  
    41.     /// If autoStart is true (default) the task is automatically started  
    42.     /// upon construction.  
    43.     public Task(IEnumerator c, bool autoStart = true)  
    44.     {  
    45.         task = TaskManager.CreateTask(c);  
    46.         task.Finished += TaskFinished;  
    47.         if(autoStart)  
    48.             Start();  
    49.     }  
    50.       
    51.     /// Begins execution of the coroutine  
    52.     public void Start()  
    53.     {  
    54.         task.Start();  
    55.     }  
    56.   
    57.     /// Discontinues execution of the coroutine at its next yield.  
    58.     public void Stop()  
    59.     {  
    60.         task.Stop();  
    61.     }  
    62.       
    63.     public void Pause()  
    64.     {  
    65.         task.Pause();  
    66.     }  
    67.       
    68.     public void Unpause()  
    69.     {  
    70.         task.Unpause();  
    71.     }  
    72.       
    73.     void TaskFinished(bool manual)  
    74.     {  
    75.         FinishedHandler handler = Finished;  
    76.         if(handler != null)  
    77.             handler(manual);  
    78.     }  
    79.       
    80.     TaskManager.TaskState task;  
    81. }  
    82.   
    83. class TaskManager : MonoBehaviour  
    84. {  
    85.     public class TaskState  
    86.     {  
    87.         public bool Running {  
    88.             get {  
    89.                 return running;  
    90.             }  
    91.         }  
    92.   
    93.         public bool Paused  {  
    94.             get {  
    95.                 return paused;  
    96.             }  
    97.         }  
    98.   
    99.         public delegate void FinishedHandler(bool manual);  
    100.         public event FinishedHandler Finished;  
    101.   
    102.         IEnumerator coroutine;  
    103.         bool running;  
    104.         bool paused;  
    105.         bool stopped;  
    106.           
    107.         public TaskState(IEnumerator c)  
    108.         {  
    109.             coroutine = c;  
    110.         }  
    111.           
    112.         public void Pause()  
    113.         {  
    114.             paused = true;  
    115.         }  
    116.           
    117.         public void Unpause()  
    118.         {  
    119.             paused = false;  
    120.         }  
    121.           
    122.         public void Start()  
    123.         {  
    124.             running = true;  
    125.             singleton.StartCoroutine(CallWrapper());  
    126.         }  
    127.           
    128.         public void Stop()  
    129.         {  
    130.             stopped = true;  
    131.             running = false;  
    132.         }  
    133.           
    134.         IEnumerator CallWrapper()  
    135.         {  
    136.             yield return null;  
    137.             IEnumerator e = coroutine;  
    138.             while(running) {  
    139.                 if(paused)  
    140.                     yield return null;  
    141.                 else {  
    142.                     if(e != null && e.MoveNext()) {  
    143.                         yield return e.Current;  
    144.                     }  
    145.                     else {  
    146.                         running = false;  
    147.                     }  
    148.                 }  
    149.             }  
    150.               
    151.             FinishedHandler handler = Finished;  
    152.             if(handler != null)  
    153.                 handler(stopped);  
    154.         }  
    155.     }  
    156.   
    157.     static TaskManager singleton;  
    158.   
    159.     public static TaskState CreateTask(IEnumerator coroutine)  
    160.     {  
    161.         if(singleton == null) {  
    162.             GameObject go = new GameObject("TaskManager");  
    163.             singleton = go.AddComponent<TaskManager>();  
    164.         }  
    165.         return new TaskState(coroutine);  
    166.     }  
    167. }  

       Usage Example:

    C#代码  收藏代码
    1. /// Example usage:  
    2. ///  
    3. /// ----------------------------------------------------------------------------  
    4. /// IEnumerator MyAwesomeTask()  
    5. /// {  
    6. ///     while(true) {  
    7. ///         Debug.Log("Logcat iz in ur consolez, spammin u wif messagez.");  
    8. ///         yield return null;  
    9. ////    }  
    10. /// }  
    11. ///  
    12. /// IEnumerator TaskKiller(float delay, Task t)  
    13. /// {  
    14. ///     yield return new WaitForSeconds(delay);  
    15. ///     t.Stop();  
    16. /// }  
    17. ///  
    18. /// void SomeCodeThatCouldBeAnywhereInTheUniverse()  
    19. /// {  
    20. ///     Task spam = new Task(MyAwesomeTask());  
    21. ///     new Task(TaskKiller(5, spam));  
    22. /// }  
    23. /// ----------------------------------------------------------------------------  

    小结:

           本文主要是分享我的收藏的一些“干货”,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:静水逐风)

  • 相关阅读:
    [牛客]十二桥问题 解题报告
    [NOIP2017 逛公园] 解题报告
    [JSOI2008]最小生成树计数 解题报告
    类欧几里得算法
    概率与期望题目列表
    [SCOI2008]配对 解题报告
    拦截导弹
    牛客网-约数的个数
    牛客网-成绩排名
    最大连续区间和的算法总结
  • 原文地址:https://www.cnblogs.com/harlan1009/p/4282306.html
Copyright © 2011-2022 走看看