zoukankan      html  css  js  c++  java
  • 蓝图编译器概述(翻译)

    本文依据官方文档翻译而来,注意官方版本的文档较旧(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类。

  • 相关阅读:
    201521044091《Java程序设计》第7周学习总结
    201521044091《java程序设计》第四次总结
    201521044091 《java程序设计》第八周学习总结
    201521044091 《Java程序设计》第5周学习总结
    201521044091 《Java程序设计》第2周学习总结
    201521044091 《Java程序设计》第3周学习总结
    MySQL设置字符集CHARACTER SET
    Create My MySQL configuration by Percona
    How to use jQuery to manipulate Cookies
    How to use OpenXml to import xml data to Sql server
  • 原文地址:https://www.cnblogs.com/ghl_carmack/p/5804737.html
Copyright © 2011-2022 走看看