"Go" collaboration in unity-encapsulation with promise (i)

Source: Internet
Author: User

Original: http://gad.qq.com/program/translateview/7170767

Translator: Chen Jingfeng (Nunu) revision: Wang Lei (future future)

Each unity developer should be very familiar with the collaboration program. For many unity developers, a synergistic program is a way to write a large number of asynchronous and deferred tasks. If you don't care about speed, there are very, very many special methods that can be paused and resumed at any desired time. In practice, they can create hallucinations of a concurrency function (although they are not thread-independent!). However, there are some problems with the collaboration program, and many programmers will stumble upon the use of a collaborative program. Let's take a closer look at these questions.

The internal mechanism of the cooperative program

So what's going on inside the unity Synergy program? How does the Unity collaboration program work? We don't have direct access to Unity's source code, but we can collect evidence from the manuals, and with the knowledge of C # we can more or less assume how they work. Let's try to streamline this sample code:

123456789 StartCoroutine(TestCoroutine());//…IEnumerator TestCoroutine(){    Debug.Log("Hello there!");    yield return newWaitForSeconds(2);    Debug.Log("Hello from future!");}

You don't need any special talent, it's easy to see that this code will print "Hello there!" in the terminal section. and print out "Hello from future!" after 2 seconds “。 But how does it do that? To understand a synergistic program, you must first look at the signature of the function--more precisely, the return type of the function. IEnumerator as a method of iterating over a set. It controls the execution of the next object from the execution of an object to the sequence.

To do this, it declares two very important member variables: The current property, which refers to the element currently being accessed by the enumerator (or, in other words, the cursor), and the MoveNext () function. It calculates the new current value while moving to the next element. It also has a reset () function, which is responsible for setting the enumerator to its initial position, but we skip this part.

Now because IEnumerator is just an interface, it does not explicitly specify the current type (except that we know nothing about an object). We can do anything we want to calculate the next object. The MoveNext () function will only do the work, and we will return to Fasle when we have accessed the last element of the sequence.

Iterator module

If it is in a pure C # environment, we can easily "implement" this interface within a special iterator module. In practice, the C # compiler transforms the iterator module into a state machine. Here are some functions that return a IEnumerator type and use the yield return statement to return a value (yes, it could be multiple values).

The call causes the MoveNext () function to simply return true, and to save the current position to the present variable, no matter where you return from. If you want to stop the enumerator, you can simply call yield break, which will ensure that the MoveNext () function returns false and terminates the entire sequence (it can be imagined as a break in a loop). Here is an example of how to do this:

1234567891011121314151617181920212223242526272829303132333435363738394041 using System;using System.Collections.Generic; class TestIEnumerator{    static readonly string inEnumerator = "####";      static IEnumerator GetTexts()    {        Console.WriteLine(inEnumerator + "First line of GetTexts()" + inEnumerator);         Console.WriteLine(inEnumerator + "Just before the first yield" + inEnumerator);        yield return "First returned text";        Console.WriteLine(inEnumerator + "Just after the first yield" + inEnumerator);         Console.WriteLine(inEnumerator + "Just before the second yield" + inEnumerator);        int b = 2;        int a = 5 + b;        yield return "Second returned text - " + a;        Console.WriteLine(inEnumerator + "Just after the second yield" + inEnumerator);    }     static void Main()    {        Console.WriteLine("Calling GetTexts()");        IEnumerator iterator = GetTexts();        Console.WriteLine("Calling MoveNext()...\n");        bool returnedValue = iterator.MoveNext();        Console.WriteLine("\nReturned value = {0}; Current = {1}", returnedValue, iterator.Current);         Console.WriteLine("Calling MoveNext() again...\n");        returnedValue = iterator.MoveNext();        Console.WriteLine("\nReturned value = {0}; Current = {1}", returnedValue, iterator.Current);         Console.WriteLine("Calling MoveNext() again...\n");        returnedValue = iterator.MoveNext();        Console.WriteLine("\nReturned value = {0} - stopping", returnedValue);          Console.ReadKey();    }}

Compile this program on your own computer and you will get the following output:

The following example uses the generic interface IEnumerator, but as described earlier, you can use the regular IEnumerator interface, where your current variable can be any type. This is exactly what unity requires for a collaborative program.

So, keep this in mind, and we have a clearer understanding of what unity is doing with the collaborative program. The Startcoroutine function adds a synergistic program to a container. Unity iterates through each of the Startcoroutine and executes the MoveNext () functions of these co-programs, and these functions continue to perform the work they interrupted before. As shown in the example above, it evaluates the value of the expression between the yield return statement and returns a value. If it returns false, it is clearly telling unity to abort the co-program (it just finished). If it returns true, it checks the current property (remember, this is a non-generic interface!) and see if there is a familiar type. Remember the first example of Waitforseconds ()? Unity sees this function and then pauses the co-program for two seconds. In fact, it is actually inherited from the Yieldinstruction base type, and you have the following unity-recognizable types:

1) Waitforendforframe: After all the cameras and GUIs have been rendered, the co-program will continue at the end of this frame.

2) Waitforfixedupdate: Waits for the next function to be updated at a fixed frame rate.

3) Coroutine type itself, this is a message that you can use after the collaboration program.

4) Customyieldinstruction: This is the introduction used to write your own custom yield statement-just inherit this class and overwrite the Keepwaiting property.

So where's the focus? Needless to say, with these simple types you can easily write time-based game logic and various asynchronous events. You can show a UI notification in a few seconds after just a few lines of code without using any dirty timers. Not only that, you can even return the Unitywebrequest.send () function and pause your function until you get an HTTP response. You might ask, "What's the problem?" First, you cannot easily return a value from a synergistic program. The function signature needs to return IEnumerator to keep track of when and how to recover your method. Second, there is no exception handling at the level of the collaboration program. You can't be in try ... The yield statement is used inside the catch block. Basically you try to use try ... in every Non-yield statement inside the collaboration program. Catch block. But what if there are multiple expressions that are isolated by multiple yield statements? Or you want to put the orchestration on the stack one after the other. But what if the top-most collaborative program encounters a run-time exception, how do I communicate along the pipeline to the following co-program? Fortunately, there is a solution to this problem. In the next section we will see Promise, which initially appeared in JavaScript. Please read this section here.

"Go" collaboration in unity-encapsulation with promise (i)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.