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:静水逐风)

Unity协程(Coroutine)管理类——TaskManager工具分享的更多相关文章

  1. Unity协程Coroutine使用总结和一些坑

    原文摘自 Unity协程Coroutine使用总结和一些坑 MonoBehavior关于协程提供了下面几个接口: 可以使用函数或者函数名字符串来启动一个协程,同时可以用函数,函数名字符串,和Corou ...

  2. unity协程coroutine浅析

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.序言 在unity的游戏开发中,对于异步操作,有一个避免不了的操作: 协程,以前一直理解的懵懵懂懂,最近认真充电了一下 ...

  3. Unity 协程Coroutine综合测试

    using UnityEngine; using System.Collections; using System.Text; public class rotCube : MonoBehaviour ...

  4. Unity 协程(Coroutine)原理与用法详解

    前言: 协程在Unity中是一个很重要的概念,我们知道,在使用Unity进行游戏开发时,一般(注意是一般)不考虑多线程,那么如何处理一些在主任务之外的需求呢,Unity给我们提供了协程这种方式 为啥在 ...

  5. Unity协程(Coroutine)原理深入剖析

    Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 其实协程并没有那么复杂,网上很多地方都说是多 ...

  6. Unity协程(Coroutine)原理深入剖析(转载)

    记得去年6月份刚开始实习的时候,当时要我写网络层的结构,用到了协程,当时有点懵,完全不知道Unity协程的执行机制是怎么样的,只是知道函数的返回值是IEnumerator类型,函数中使用yield r ...

  7. Unity协程(Coroutine)原理深入剖析再续

    Unity协程(Coroutine)原理深入剖析再续 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 前面已经介绍过对协程(Coroutine ...

  8. 【转】Unity协程(Coroutine)原理深入剖析

    Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 记得去年6月份刚开始实习的时候,当时要我写网 ...

  9. Unity怎样在Editor下运行协程(coroutine)

    在处理Unity5新的AssetBundle的时候,我有一个需求,须要在Editor下(比方一个menuitem的处理函数中,游戏没有执行.也没有MonoBehaviour)载入AssetBundle ...

随机推荐

  1. python import eventlet包时提示ImportError: cannot import name eventlet

    root@zte-desktop:/home/ubuntu/python-threads# cat eventlet.py #!/usr/bin python import eventlet from ...

  2. windows 下的定时任务

    linux 下的定时任务是crontab 以前都是linux的定时任务,这次在windows做了定时任务,简单记录一下 windows 2008下的定时任务配置: 控制面板->管理工具-> ...

  3. linux下oracle 10g的sqlplus无法使用

    问题如标题所示. 解决办法, 1,root用户登录,建立软连接 cd / cd /usr/bin ln -s /home/oracle/product/10.2.0/db_1/bin/sqlplus ...

  4. 《C与指针》第三章练习

    本章问题 1.What is the range for characters and the various integer types on your machine? (在你的机器上,字符型和整 ...

  5. ajax 中$.each(json,function(index,item){ }); 中的2个参数表示什么意思?

    $.each(json,function(index,item)里面的index代表当前循环到第几个索引,item表示遍历后的当前对象,比如json数据为:[{"name":&qu ...

  6. poj3592 强连通+记忆化搜索

    题意:有一片 n*m 的矿地,每一格有矿.或这传送门.或者挡路岩石.除了岩石不能走以外,其他的格子都能够向右或向下走,走到一个非岩石的格子.对于每一个矿点,经过它就能得到它的所有矿石,而对于每一个传送 ...

  7. poj3114 强连通+最短路

    题意:有 n 个城市,城市之间能够通过邮件或者电子邮件传递消息,已知 m 条邮件线路,每条线路代表 A 能送邮件到 B,并且花费 V 时间,如果几个城市之间能够相互邮件送达,那么他们就在同一个国家内, ...

  8. 《统计推断(Statistical Inference)》读书笔记——第1章 概率论

    第一章介绍了基本的概率论知识,以下是这一章的思维导图

  9. .NET垃圾回收:非托管资源,IDispose和析构函数的结合

    http://blog.jobbole.com/85436/ 原文出处: 田小计划   欢迎分享原创到伯乐头条 前面一篇文章介绍了垃圾回收的基本工作原理,垃圾回收器并不是可以管理内存中的所有资源.对于 ...

  10. activiti自定义流程之整合(六):获取我的申请任务

    流程启动后,流程节点便进入到了任务相关的部分.可以看到我之前的做法是在启动节点就绑定了form表单,启动时就填写相关的数据.实际上在之前我的做法是不对开始节点做任何操作,知道任务节点的时候再填写相关的 ...