开个新坑,学习的时候东西都在笔记上写着,但是本身就是抽时间学,所以时间一长就把前面的忘掉了。
从GameFrameWork框架源码开始看,每次如果我感觉前面的东西忘了就写篇文章复习XD。
GameFrameworkEntry.cs
首先它是一个静态类,目的是为了在任何地方都可以调用到。
第一个变量是负责存储GF框架所有模块的,GameFrameworkLinkedList类是GF框架封装的一个LinkedList类型,但是消耗低,之后看;GameFrameworkModule是游戏模块类,比如什么音效模块什么UI模块这些总的,或者自己实现的一些模块,都可以继承这个类型。
这个Update方法用来遍历刚刚 s_GameFrameworkModules 里存储的每一个模块,然后执行这个模块的更新方法。
至于两个参数,第一个参数是逻辑时间,假如游戏变速了,比如加快或者变慢,那么这个时间也会跟着变慢或者变快;第二个时间是真实流逝的时间,也就是加减速并不影响它的计时。
举个例子,比如五秒后玩家起飞,但是现在速度游戏速度调慢了1倍那么就需要真实时间的十秒,那么timescale的值越小,间隔就越小,第一个参数的值就越小,因为真实时间走一秒,假设原本间隔时间是0.02s,timescale缩小变慢后就成了0.01,对应的游戏间隔时间可能才算走一点点。
如果是第二个参数,如果还是五秒后玩家起飞,游戏速度又慢了1倍,但是这并不影响它的计时,也就是真实世界的五秒后起飞。传进来的参数是现实中五秒对应的每一帧的间隔值,也就是改变游戏速度完全不影响计时。
停止所有模块,先通过遍历GF框架链表的方式,执行每一个模块的关闭方法,执行结束后清理所有模块,清理缓存池等。
获取模块,获取的泛型类型必须是一个类。
先得到T的类型,泛型必须是接口,防止传入实现类,属于“约定优于配置”理念下的强制约束,接口固定对应的一个实现。
然后判断接口的命名空间开始的全名,StartsWith(“GameFramework.”, StringComparison.Ordinal):检查该完整名称是否以 “GameFramework.” 开头。StringComparison.Ordinal 表示使用字节级比较(区分大小写、最快),避免因区域性(Culture)导致的意外行为。
如果不以该前缀开头,则抛出 GameFrameworkException(框架自定义异常),并附带格式化错误信息,明确指出传入的类型不是合法的 Game Framework 模块。
然后通过拼接命名空间和类型名称,得到模块的名称,然后通过 Type.GetType(moduleName) 来得到对应的类型,如果没有得到报错,得到的话再调用下面这个GetModule方法传递Type类型得到GameFrameworkModule模块后父转子为T类型后返回。
interfaceType.Namespace:获取接口的命名空间,例如 “GameFramework.Resource”。
interfaceType.Name:获取接口的短名称(不含命名空间),例如 “IResourceManager”。
.Substring(1):从索引 1 开始截取,即去掉第一个字符。若接口名以 I 开头(约定),则得到 “ResourceManager”。
这也说明了GF框架中的一个约定,对于模块来说,需要遵守接口应该以大写I开头,比如IResourceManager,具体实现的是ResourceManager,这样才能通过GetModule方法来获取具体的模块。
这个是内部具体的获取模块的方法,其实就是遍历每一个s_GameFrameworkModules存的模块,因为GameFrameworkModule是class类型所以有object的方法,所以调用它的GetType获取类型来判断传入的Type类型的moduleType是否匹配,如果匹配就返回;如果没有,那么就调用 CreateModule方法 直接创建一个模块。
首先通过反射创建一个对应类型的实例,然后强转GameFrameworkModule,如果没转过来成null了,直接抛出异常不能创建这个模块;
如果转成功了,创建一个 LinkedListNode (它是一个链表节点类,节点对应的value的类型是GameFrameworkModule)让它先引用s_GameFrameworkModules所有模块的第一个,然后开始从头遍历(注意头部的Property是最大的,降序排列),直到这个新的模块的Priority优先级小于当前遍历中的模块的层级;
退出循环后,如果current为空也就是遍历到底了都没有比新模块优先级小的就把这个新模块放到最后,否则放到current对应模块的前面(因为break的时候没有执行current = current.Next 所以对应的current还是比当前模块小的那个)。