Unity IFramework 框架学习笔记 2021 (三): CoroutineModule(协程模块)
CoroutineModule(协程模块)
附上IFramework 下载地址:IFramewrok
IFramework QQ交流群:782290296
上面所示的链接是IFramework的,这个框架是unity的,但是这个框架依赖于一个cs库。也就是说有很大一部分源码是需要另外下载的。而协程模块就是在cs库当中的。
附上CS_IFramework 下载地址:CS_IFramework
该协程模块并不是unity自带的协程,而是作者自己封装的一个协程模块,当然原理和unity的差不多,也是使用迭代器来实现的。
该模块主要有三个类:
1.CoroutineModule (协程模块)
2.Coroutine (协程类)
3.CoroutineInstruction(协程等待的基类)
其中最核心的就是协程类了。接下来我们一一讲解。
首先,还是从使用说起。向外部提供的api都封装在CoroutineModule(协程模块)当中,所以我们先看到CoroutineModule这个类。
首先看到他的继承关系,我们可以看到他继承了一个UpdateFrameworkModule。说明他是一个需要有每帧刷新函数的模块。而另一个接口,应该是为了规范和符合依赖倒置而实现的一个接口。当中的协程对象池,重写了一个CreateNew方法。这个方法应该是在对象池没有可以获取的对象时用来创建新对象的方法。继续往下看。
最重要的一个api。开启协程。开启一个协程,他需要传递一个迭代器类型的参数。其实这个跟unity的一样。我们在unity 当中也是自己声明一个返回值为迭代器类型的方法,再将方法当成参数传递到开启协程方法当中的。继续往下看。先去调用Get方法获取一个协程。我们进到Get方法看一下。
这里,将外部传递进来的迭代器封装成一个协程。并对协程相关属性进行初始化。然后返回出去。再回到上面,获取协程之后,调用协程的Start方法。所以,我们开始进Coroutine(协程类)里面去看。
我已经写上注释了。其中协程模块和迭代器都是刚才初始化的时候传递进来的,比较难理解的应该是这个嵌套的协程,我们下面会讲到,不急。直接看到start方法。
start方法中。将自身的更新函数添加到协程模块的更新函数当中。这样,自身的更新函数也会每帧去调用了。那我们看看自身的更新函数都做了什么。
这是上半部分。当嵌套协程为空时,执行里面的代码。(至于为什么为空才执行,后面再讲)。第二个判断,当迭代器的MoveNext返回false时,调用ComPelete函数。我们unity中的协程也是这样每帧去调用迭代器的MoveNext方法,为true则继续执行,为false则协程结束。如果不知道为什么的小伙伴得先去搜一下C#迭代器的资料了。这里就不解释了。当MoveNext函数返回false,说明迭代器结束了,那么去执行Compelete函数,我们看到ComPlete函数。
就是对自身属性进行一些清除操作,并标记为Done。继续回倒上面的代码。继续判断自身协程是否为Done,是则直接退出,没必要在继续执行了。继续判断迭代器的Current属性。那么这个Current属性其实指的就是咱们yield return 出去的那个值。那么这里分三种情况,第一种yield return 的是一个CoroutineInstruction类型的,这个类型就相当于我们unity协程当中的yield return waitsecond。相信大家都用过吧?就是等待的。第二种情况yield return 的是一个迭代器,第三种情况是yield return 一个Coroutine,那么这三种情况需要对其做特殊处理。因为这三种情况,我们需要做等待处理,举个例子,在协程里边,如果我们写一个yield return StartCoroutine().那么他是需要去等待新开启的协程执行完了再去继续执行下面的代码的。所以我们看这里做了什么特殊处理。他先去判断这个Current是什么,当他满足判断中的其中一个条件,他会去调用Finish函数,
函数很简单,当协程未结束,返回一个迭代器。再回到上面的代码,这个迭代器会传入协程模块中的Get方法,这个方法我们刚才已经讲过了。是将迭代器封装成一个协程,然后执行协程的start方法。那不就跟我们开启一个协程是一个意思的?然后再将这个协程赋值给_innerAction。这个是我们在协程中开启的,所以是嵌套的协程。然后我们在看到第一个判断。当_innerAction为空,在执行下面的代码,现在应该明白什么意思了吧?当_innerAction不为空,说明有嵌套的协程,那我们应该去执行嵌套的协程,等到嵌套的协程执行完了,我们在继续执行最外层的协程,这样就达到了一个等待的效果。最核心的地方就是这里了,这个_innerAction也是协程,他也是可以去嵌套的。一直执行,知道MoveNext返回false,则调用Complete函数重置一下,然后协程结束放入对象池。就结束了,大体是这么一个流程。但是有一个类我们还没讲,就是CoroutineInstruction。这是一个专门用来等待的类。我们进里面看下。
这是一个基类。声明一些相关属性,迭代器等。
在看到更新函数。
其实如果上面看明白了,这里应该很容易看懂,当这个类型的值被赋值到协程中的_innerAction,那么协程会一直先执行这里边的更新函数,而这里面的更新函数,是当迭代器的MoveNext返回false,则标记为Done,而迭代器是由InnerLogoc提供的,这个方法由子类实现。所以他具体的等待逻辑其实是由不同子类来进行实现的,我们随便看一个把,其他都大同小异。
看类名就知道了,WaitForFrames,等待多少帧。由外部传递帧数进来,然后一直刷新帧数,帧数到了就返回true,然后协程的Current属性就是true了,然后就标记为Done,最外层的协程就可以继续执行了。大致就是这样的一个实现协程的过程。
如果觉得不错的小伙伴,希望大家可以支持下,进来GitHub给颗小星星哦。IFramewrok