• 蓝图编译器概述(翻译)


    本文依据官方文档翻译而来,注意官方版本的文档较旧(UE 4 4.9),新版本的类名已经改变。本文是直接翻译而来,并没有做相应改动。

    蓝图,像常规的C++类一样,需要编译后才能在运行的时候使用。当你在蓝图编辑器中按下编译按钮时,那么编译器就会把蓝图资源的属性和图转换成类。

    术语

    FkismetCompilerContext

    执行编译工作的类。每一次编译都会生成一个新的实例。存储需要编译类的引用,蓝图等。

    FKismetFunctionContext

    持有编译一个函数的信息,比如相关图的引用,属性以及生成的UFunction。

    FNodeHandlingFunctor

    一个用来处理一类节点的帮助类。包含用于注册引脚连接的函数,并且生成编译语句。

    FKismetCompiledStatement

    编译中的工作单元。编译器会把节点转换成一系列的语句,然后编译器后端会把这些节点翻译成字节码操作。

    例子:变量赋值、无条件跳转(goto),调用(call)

    FKismetTerm

    图中的一个末端(字面量、常量、或者变量引用)。每一个数据引用接连都会跟它们中的一个连接。为了抓取变量或者中间值等你也可以在NodeHandlingFunctor中来创建你自己的项。

    编译过程

    编译蓝图的一个基本过程如下图所示:

    *仅适用于完全编译

    清理类

    类是就地编译的,这意味着同一个UBlueprintGeneratedClass被清除并且会重复得使用,因此指向这个类的指针不必修正。CleanAndSanitizeClass()把属性和函数从类中移动到一个临时包中的垃圾类中,然后清除类中的所有数据。

    创建类的属性

    编译器遍历蓝图的NewVariables数组以及其它地方(比如构建脚本等)来找到类需要的所有属性,然后通过函数CreateClassVariablesFromBlueprint()在UClass内创建UProperties。

    创建函数列表

    编译器通过处理事件图表、常规函数图表来创建函数列表,并且预编译这些函数。例如为每一个上下文调用PrecompileFunction()函数。

    处理事件图表

    事件图表的处理通过调用CreateAndProcessUberGraph()函数而进行。它把所有的事件图表拷贝到一个大的图表中去,这之后节点会被展开。然后为图表中的每一个事件节点创建一个函数的存根(stub),并且第一个事件节点都会生成一个对应 的FKismetFunctionContext。

    处理函数图表

    处理常规函数图表的过程是通过调用ProcessOneFunctionGraph()函数来完成的,它会复制每一个图表到一个临时的图表里面,在这个图表里节点被会展开。每一个函数图表都会创建一个FKismetFunctionContext。

    预编译函数

    函数的预编译是通过调用每一个上下文中的PrecompileFunction()。这个函数会做以下几步的操作:

    1. 安排执行并且计算数据依赖。
    2. 去除那此没有使用的或者不是一个数据依赖的节点。
    3. 在每一个存在的节点上运行RegisterNets()节点处理器。
    4. 为函数中的值创建FKismetTerms。
    5. 创建UFunction和相关的属性。

    绑定和链接类

    现在编译器已经知道类的所有UFunction和UProperty了,现在它可以调用绑定和链接类了,这个过程包括创建属性链,设置属性大小,函数映射等。在这个时候,它实际上只有一个类头,不包含最终的标记和元数据,也没有一个类默认对象(CDO)。

    编译函数

    接下来需要为剩下的节点生成FKismetCompiledState对象,通过节点处理器的Compile()函数调用AppendStatementForNode()完成。这个函数会为当前编译的函数创建FKismetTerm对象只要它们只用来局部使用。

    完成编译类

    为了完成编译这个类,在通过一些最终检查来确保所有事情都做好之前,编译器会定下来类的标记并且从父类继承标记和元数据。

    后端发出生成的代码

    后端把每个函数上下文中的语句集合转换成代码。有两个可以使用的后端。

    1. FKismetCompilerVMBackend 把FKCS转换成UnrealScript 虚拟机的字节码,然后就把这些字节码序列化到函数的脚本数组中。
    2. FKismetCppBackend 产生用于调试的像C++的代码。

    拷贝类默认对象属性

    使用一个特别的函数CopyPropertiesForUnrelatedObjects(),编译器会把类原来的CDO中的值拷贝到新的CDO。属性通过标记的序列化拷贝,因此只要名字一致,它们应该会被正确的转移。CDO的组件会被重新实际化并且在这个阶段修正。这个生成类的CDO是权威的(authoritative)。

    重新实际化

    由于类可能会改变了大小 或者属性被添加或移除,编译器需要重新实例化刚编译的类的所有对应。这个过程使用TObjectIterator来找到这个类的所有实例,生成一个新的然后使用CopyPropertitiesForUnrelatedObjects()函数来把旧的实例拷贝到新的实例里面去。

    要想了解更多的细节,查看FBlueprintCompileReinstancer类。

  • 相关阅读:
    骑士飞行棋 C#代码详解
    C#中的static静态变量的用法
    Break和Continue的一些注意事项
    枚举类型
    html 01-认识Web和Web标准
    css 17-CSS3的常见边框汇总
    css 16-浏览器的兼容性问题
    css 15-Sass入门
    css 14-CSS3属性详解:Web字体
    css 13-CSS3属性:Flex布局图文详解
  • 原文地址:https://www.cnblogs.com/ghl_carmack/p/5804737.html
Copyright © 2020-2023  润新知