Sun Guangdong 2014.7.19
Inadvertently, an article on Unity Wiki is about the introduction of your own writing process.
Think very well, so that you can better understand the mechanism of the implementation of the association and other characteristics. It's still good.
The original link address is as follows:
Http://wiki.unity3d.com/index.php?title=CoroutineScheduler
Project Address: http://download.csdn.net/detail/u010019717/8912069
Detailed content such as the following:
A simple co-scheduling program.
This cooperative scheduler agrees to fully control the execution mechanism of a set of cooperative programs. Reading the code will also help you understand how collaboration works behind the scenes. Understanding how a synergistic program builds on a. Net generator will allow you to join collaborative support to non-unity projects.
The synergy is able to yield until the next update "yield;" until the given number of updates has passed "yield anint;" Until a given second has passed "yield afloat;", or until another process has finished "yield scheduler. Startcoroutine (Coroutine ()); ". Startcoroutine (Coroutine ()); ".
Multiple scheduler instances are supported and can be very useful. Collaborative execution can be performed under a completely different scheduler instance (wait).
Do not use Unity's yieldinstruction class. Because we cannot access the internal data of the dispatch required by this class. Semantics semantics is slightly different from Unity's scheduler. For example, in Unity it is assumed that you start working together and it will execute on its first yield, but in the scheduler that you write, it will not execute until the next call to Updateallcoroutines. This feature agrees to start a co-process at any time, regardless of the code started.
At the same time ensure that the start-up of the co-program can only be performed at a specific time.
You should not rely on the update order between the same update orchestration execution.
For a deeper understanding and learn a lot about how the Synergy program is implemented.
Use:
Using unityengine;using system.collections;///<summary>///coroutineschedulertest.cs/////Port of the Javascript version from//http://www.unifycommunity.com/wiki/index.php?title=CoroutineScheduler/////Linked list Node type used by Coroutine Scheduler to track scheduling of coroutines./////BMBF researchproject http://playfm.htw-be rlin.de///playfm-serious Games dealt den it-gestützten wissenstransfer im Facility Management///gef?rdert durch das bmb+ F-programm Forschung an Fachhochschulen profuntfh//////<author>[email protected]</author>////// </summary>public class Testapi:monobehaviour {Coroutinescheduler Scheduler; Coroutinescheduler m_scheduler2;string requesturl = "http://www.my-server.com/cgi-bin/screenshot.pl"; void Start () { Scheduler = new Coroutinescheduler (); scheduler. Startcoroutine (Mycoroutine ()); m_scheduler2 = new Coroutinescheduler (); M_scheduler2. Startcoroutine (Test ());} IEnumerator Mycoroutine () {Debug.Log ("Mycoroutine:beginYield return 0;//wait for next UpdateDebug.Log ("Mycoroutine:next update;" + time.time), yield return 2;//wait for 2 Updates, same as yield; Yield;debug. Log ("Mycoroutine:after yield 2;" + time.time); yield return 3.5f;//wait for 3.5 secondsDebug.Log ("Mycoroutine:after 3. 5 seconds; "+ time.time);//You can also yield for a coroutine running on a completely different scheduler Instanceyield R Eturn Scheduler. Startcoroutine (Waitforme ());D Ebug. Log ("Mycoroutine:after waitforme () finished;" + Time.time);} IEnumerator Waitforme () {yield return 7.8f;//wait for 7.8 seconds before finishing}//Update is called once per void Upda Te () {Scheduler. Updateallcoroutines (Time.framecount, time.time);} IEnumerator Test () {//... set up Requestvar www = new unityengine.www (requesturl); yield return new Unitywwwyieldwrapper (WW W)//... loading complete do some stuff}}
CoroutineScheduler.cs
Using system.collections;using unityengine;///<summary>///coroutinescheduler.cs/////Port of the Javascript Version from//http://www.unifycommunity.com/wiki/index.php?title=coroutinescheduler/////Linked list node type used by Coroutine Scheduler to track scheduling of coroutines.///// /////BMBF Researchproject http://playfm.htw-berlin.de///playfm-serious Games dealt den it-gestützten Wissenstransfer im Facility Management///gef?rdert durch das Bmb+f-programm Forschung an Fachhochschulen profuntfh//////<author>[em ail protected]</author>////////A simple Coroutine Scheduler. Coroutines can yield until the next update///"yield;", until a given number of updates "yield anint", until a given///am Ount of seconds "yield afloat;", or until another coroutine has finished///"yield scheduler. Startcoroutine (Coroutine ()) ".//////Multiple scheduler instances is supported and can be very useful. a///Coroutine running under one scheduler can yield (wait) for a coroutine///running under a completely different schedu Ler instance./////Unity ' s yieldinstruction classes is not used because I cannot///access their internal data needeD for scheduling. Semantics is slightly///different from Unity ' s scheduler. For example, the Unity if you start a///coroutine it would run up-to-its first yield immediately, while in this///schedule R it would not run until the next time Updateallcoroutines be called.///This feature allows all code to start coroutines a T any time, while///making sure the started coroutines only run at specific times./////You should not depend on update Order between Coroutines running on the same///update. For example, Startcoroutine (A), Startcoroutine (B), Startcoroutine (c)///Where A, B, C and while (true) {print (a| b| C); Yield }, do not expect "ABC" or///"CBA" or any other specific ordering.///</summary>public class Coroutinescheduler:mo Nobehaviour{coroutinenode first = Null;int currentframe;float currenttime;/** * Starts a coroutine, the Coroutine does n OT run immediately but on the "next call" to Updateallcoroutines. The execution of a coroutine can * be paused on any pointUsing the yield statement. The yield return value * Specifies when the coroutine is resumed. */public coroutinenode startcoroutine (IEnumerator fiber) {//If function does not has a yield, fiber would be null and we NO-OPIF (Fiber = = null) {return null;} Create Coroutine node and run until we reach first yieldcoroutinenode coroutine = new Coroutinenode (fiber); Addcoroutine (coroutine); return coroutine;} /** * Stops All coroutines running in this behaviour. Use of the This method is * discouraged, think of a natural-in-your coroutines to-finish * on their own instead of being ing forcefully stopped before they finish. * If you need finer control over stopping coroutines you can use multiple * schedulers. */public void Stopallcoroutines () {first = null;} /** * Returns True if this scheduler have any coroutines. You can use the this to * check if all coroutines has finished or been stopped. */public bool Hascoroutines () {return first! = NULL;} /** * Runs all active CoroutinEs until their next yield. Caller must provide * the current frame and time. This allows is schedulers to run under * frame and time regimes other than the Unity ' s main game loop. */public void Updateallcoroutines (int frame, float time) {currentframe = Frame;currenttime = time; Coroutinenode coroutine = This.first;while (coroutine! = null) {//store listnext before Coroutine finishes and is removed From the Listcoroutinenode Listnext = coroutine.listnext;if (Coroutine.waitforframe > 0 && frame >= coroutin E.waitforframe) {coroutine.waitforframe =-1; Updatecoroutine (coroutine);} else if (Coroutine.waitfortime > 0.0f && time >= coroutine.waitfortime) {coroutine.waitfortime = -1.0f; Updatecoroutine (coroutine);} else if (coroutine.waitforcoroutine! = null && coroutine.waitForCoroutine.finished) { Coroutine.waitforcoroutine = null; Updatecoroutine (coroutine);} else if (coroutine.waitforunityobject! = null && coroutine.waitForUnityObject.finished)//lonewOlfwilliams{coroutine.waitforunityobject = null; Updatecoroutine (coroutine);} else if (coroutine.waitforframe = =-1 && coroutine.waitfortime = = -1.0f && Coroutine.waitforcorou Tine = = NULL && Coroutine.waitforunityobject = = null) {//initial updateupdatecoroutine (Coroutine);} Coroutine = Listnext;}} /** * Executes coroutine until next yield. If Coroutine has finished, the flags * it as finished and removes it from scheduler list. */private void Updatecoroutine (Coroutinenode coroutine) {IEnumerator fiber = coroutine.fiber;if ( Coroutine.fiber.MoveNext ()) {System.Object Yieldcommand = fiber. Current = = null? (System.Object) 1:fiber. Current;if (yieldcommand.gettype () = = typeof (int)) {coroutine.waitforframe = (int) Yieldcommand; Coroutine.waitforframe + = (int) currentframe;} else if (yieldcommand.gettype () = = typeof (float)) {coroutine.waitfortime = (float) Yieldcommand;coroutine.waitfortime + = (float) currenttime;} else if (yieldcommand.gettype () = = typeof (Coroutinenode)){coroutine.waitforcoroutine = (Coroutinenode) Yieldcommand;} else if (Yieldcommand is iyieldwrapper)//lonewolfwilliams{coroutine.waitforunityobject = Yieldcommand as IYieldWrapper ;} Else{throw New System.ArgumentException ("coroutinescheduler:unexpected coroutine yield type:" + yieldcommand.gettype ( ));//this is a alternative if you don't have access to the function passed to the couroutinescheduler-maybe it ' s Precompiled in a DLLs for Example-remember you'll have the add a case every time you add a wrapper://* var commandtype = Yieldcommand.gettype (); if (CommandType = = typeof (Unityengine.www)) {coroutine.waitforunityobject = new Unitywwwwrapper ( Yieldcommand as Unityengine.www); } else if (CommandType = = typeof (Unityengine.asyncoperation)) {coroutine.waitforunityobject = new UNITYASYNCOPWR Apper (Yieldcommand as Unityengine.asyncoperation); } else if (CommandType = = typeof (Unityengine.assetbundlerequest)) {CoroutiNe.waitforunityobject = new Unityassetbundlerequestwrapper (Yieldcommand as Unityengine.assetbundlerequest); } else {throw new System.ArgumentException ("coroutinescheduler:unexpected coroutine yield type:" + Yieldcomm and. GetType ()); } */}}else{//Coroutine finishedcoroutine.finished = true; Removecoroutine (Coroutine);}} private void Addcoroutine (Coroutinenode coroutine) {if (This.first! = null) {Coroutine.listnext = This.first; first.listprevious = Coroutine;} first = Coroutine;} private void Removecoroutine (Coroutinenode coroutine) {if (This.first = = coroutine) {//Remove Firstthis.first = Coroutine . Listnext;} else {//not Head of ListIf (coroutine.listnext! = null) {//Remove Betweencoroutine.listPrevious.listNext = Coroutine.lis tnext;coroutine.listnext.listprevious = coroutine.listprevious;} else if (coroutine.listprevious! = null) {//and Listnext is Nullcoroutine.listPrevious.listNext = null;//Remove Last}}co routine.listprevious = Null;coroutine.listnext =null;}} Class
CoroutineNode.cs
Using system.collections;using unityengine;///<summary>///coroutinenode.cs/////Port of the Javascript version From//http://www.unifycommunity.com/wiki/index.php?title=CoroutineScheduler/////Linked list node type used by Coroutine Scheduler to track scheduling of coroutines./////BMBF researchproject http://playfm.htw-berlin.de///Playfm -Serious games dealt den it-gestützten wissenstransfer im Facility Management///gef?rdert durch das Bmb+f-programm FORSC Hung an fachhochschulen profuntfh//////<author>[email protected]</author>//////</summary>public Class Coroutinenode{public Coroutinenode listprevious = null;public Coroutinenode listnext = null;public IEnumerator fibe r;public bool finished = false;public int waitforframe = -1;public float waitfortime = -1.0f;public Coroutinenode WaitForC Oroutine;public Iyieldwrapper Waitforunityobject; Lonewolfwilliamspublic Coroutinenode (IEnumerator _fiber) {this.fiber = _fiber;}}
IYieldWrapper.cs
/* * Gareth Williams * http://www.lonewolfwilliams.com */public interface Iyieldwrapper{bool finished {get;}}
Example Wrappers
Below is some examples of wrappers I has used, in fact they has almost identical signatures so a more generic implement Ation could probably be written ^_^
Unityasyncopwrapper
Using system;using system.collections.generic;using system.linq;using system.text;/** Gareth Williams* http ://www.lonewolfwilliams.com*/class unityasyncopwrapper:iyieldwrapper{private unityengine.asyncoperation m_ unityobject;public bool Finished{get{return m_unityobject.isdone;}} Public Unityasyncopwrapper (Unityengine.asyncoperation wraps) {m_unityobject = wraps;}}
Unitywwwyieldwrapper
Using system;using system.collections.generic;using system.linq;using system.text; /* * Gareth Williams * http://www.lonewolfwilliams.com */public class unitywwwyieldwrapper:iyieldwrapper{ private U Nityengine.www M_unityobject; public bool finished { get { return m_unityobject.isdone; } } Public Unitywwwyieldwrapper (Unityengine.www wraps) { m_unityobject = wraps; }}
??????
God and horses are clouds, unity in their own writing Coroutine routines code