UE5的Control Flows
在Gameplay开发过程中,常常会碰到一些流程非常复杂,由很多个子逻辑复合而成的业务,就比如最常见的客户端登录流程,可能要分这几步:要先走账号授权,访问平台SDK的API,等待回调取得对应token,再和游戏服务器建立连接,连接后将获取到的用户id和token发给游戏服务器,等待服务器校验成功后返回给客户端才算成功登录。中间会有好几个子步骤,每个步骤都可能是异步的回调。虽然流程看起来很线性,但当我们在实现时,会发现事情没这么简单。每一步都需要根据上一步的结果来决定下一步怎么做,过程中连接失败了怎么办,鉴权失败了怎么办,超时了怎么办?中间有非常多的异常逻辑要处理,最终的业务看似线性但实际是一个网。而且整个过程可能会因为策划需求变更,平台SDK更新,服务器重构等各种原因进行多次变更,每次修改流程,就要把业务的这张“网”重新编织一遍,“网”上的某个链路出现问题,就会导致整个系统出现瘫痪,无穷无尽的开发工作量就是这样出现的。经验丰富的开发者在写这些业务时,可能会考虑使用状态机,把这张网梳理成多个状态,在重构时只要调整状态机之间的关系即可,但业务在不符合状态机的运行模式时,强行套用可能会让业务变得更加抽象,当业务规模庞大时不但不能减轻业务开发人员的重构负担,反而会加重理解成本。
ControlFlows是UE5新增的一个插件,针对上述这种流程式的业务模型,封装了一套通用的类状态机但更简化的流程控制框架。就拿上述登录流程来说,如果使用ControlFlows这个插件来实现,可以让整个流程简化成几个子业务函数和一个整体的流程配置,当需要修改流程时不用改每一步的子业务函数,只修改对应的流程配置即可。插件本身的实现对引擎的新功能没有依赖,所以理论上手动移植到UE4上应该也会比较容易。
ControlFlow的使用
Lyra工程中的启动登录流程使用了ControlFlow,就以Lyra中的示例作为说明:
上图可以看到,首先创建一个ControlFlow的对象,然后调用QueueStep添加流程。整个登录流程分为了4步:
- 等待初始化
- 显示PressStart按钮
- 尝试加入请求的Session
- 显示主界面
每一步QueueStep后面都有一个函数作为参数。我们先看某一步的内部代码
可以看到内部,在业务执行完的时候,需要ContinueFlow,或者CancelFlow。这样就可以让多个步骤的Flow依次执行下去,或者中途结束。
其实这就是ControlFlows框架的全部了,就是这么简单。你可能会疑惑,使用ControlFlows和自己直接写一堆子业务的函数,并在每个子业务的回调函数内部调用下一个子业务有什么区别?其实本质是一样的,但使用ControlFlows有一个好处,就是当业务流程发生改变,但每一个子业务没有变化时,不用修改子业务本身,只需要修改下面这几行,可能简单调整一下顺序就搞定了。不用深入到每个子业务的回调中去调整下一个业务是什么,因为子业务内部启动下一个子业务的代码永远是ContinueFlow这个函数。
再说回QueueStep。看源码可以得知,QueueStep是一个模板函数,可以根据不同的参数特化成不同的实现,本质上类似Delegate的模式。这里直接看注释最清楚
可以看到QueueStep会根据参数情况,来决定调用QueueFunction,QueueWait,QueueControlFlow,QueueControlFlowBranch等函数,所以业务只需要使用一个QueueStep即可。
这里可以看到除了支持简单的任务外,还支持分支QueueBranch和循环QueueLoop。这两种模式都要求先提供一个判断函数来决定执行哪个分支或者循环是否结束,就像写if条件判断或者while循环一样,看源码内部有支持多线程的打算,但是没有实现,所以目前来说还只是单线程模式,和delegate一样,回调支持绑定UObject,所以建议只在GameThread上使用。
如下是分支的写法,创建两个分支,1和2,返回值就是决定执行哪个分支,这里写死了2,实际可以根据业务情况动态决定执行哪个branch
循环写法也类似,这里就不详细说明了。
有时候会遇到没法在QueueStep提供的函数内部决定是否ContinueFlow,或者无法在内部使用lambda回调。Lyra的做法是将参数SubFlow保存下来,在真正的回调结束后,用保存的SubFlow智能指针继续ContinueFlow
ControlFlow的创建,获取,销毁
可以看到默认要求填入OwningObject,这里支持两种对象,一种是UObject,一种是继承了SharedFromThis的智能指针。因为ControlFlow内部大量的Delegate,这样可以让ControlFlow在关联的对象生命周期内安全的运行。
每次执行ControlFlow不需要重新创建,直接复用原有的即可,只要FlowId相同。上面可以看到也支持FindOrCreate接口,FindOrCreate创建的Flow是Persistent的。而重复创建相同FlowId内部会报错,如果Flow创建时是Persistent的,即使Flow已经执行完成重复创建也会报错,这是需要注意的。
内部有4个全局的静态容器,保存了整个进程内所有的Flows,内部也会通过Ticker在游戏的每一帧检查执行完的Flow并删除。
ControlFlow本身也支持绑定一个FTrackedActivity,可以实时监控当前状态,也可以用于进度条展示等功能。比如我们在做资源加载时如果使用了ControlFlow,就可以额外使用FTrackedActivity来为当前UI提供相关的展示文字。
相关文章
- Jgit的使用笔记
- 利用Github Action实现Tornadofx/JavaFx打包
- 叹息!GitHub Trending 即将成为历史!
- 微软软了?开源社区讨论炸锅,GitHub CEO 亲自来答
- GitHub Trending 列表频现重复项,前后端都没去重?
- Photoshop Elements 2021版本软件安装教程(mac+windows全版本都有)
- (ps全版本)Photoshop 2020的安装与破解教程(mac+windows全版本都有)
- (ps全版本)Photoshop cc2018的安装与破解教程(mac+windows全版本,包括2023
- 环境搭建:Oracle GoldenGate 大数据迁移到 Redshift/Flat file/Flume/Kafka测试流程
- 每个开发人员都要掌握的:最小 Linux 基础课
- 来撸羊毛了!Windows 环境下 Hexo 博客搭建,并部署到 GitHub Pages
- 超实用!手把手入门 MongoDB:这些坑点请一定远离
- 【GitHub日报】22-10-09 zustand、neovim、webtorrent、express 等4款App今日上新
- 【GitHub日报】22-10-10 brew、minio、vite、seaweedfs、dbeaver 等8款App今日上新
- 【GitHub日报】22-10-11 cobra、grafana、vue、ToolJet、redwood 等13款App今日上新
- Photoshop 2018 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2017 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2020 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2023 资源免费下载(mac+windows全版本都有,包括最新的2023)
- 最新版本Photoshop CC2018软件安装教程(mac+windows全版本都有,包括2023