• ‎CocosBuilder 学习笔记(1) CCBReader 解析 ccbi 文件流程


    1. 简介

    CocosBuilder是免费开源的Cocos2d UI编辑器。

    .ccb文件是CCB项目的原始文件。

    .ccbi文件是CCB项目发布后的生成的二进制文件。CCBReader可以快速通过该二进制文件,读取并设置CCB项目内容到引擎中。

    .ccb文件是用map键值对的形式,保存了项目中所有Node的信息。

    .ccbi文件是.ccb文件的精简,专门提供给CCBReader类进行解析。通过CCBReader,把项目中的Node和Node属性在引擎中新建Node并设置属性,从而把这些Node添加到Scene或Layer中。

    2. 解析之前

    NodeLoader

    Node加载器。用于解析ccbi文件中和当前node相关内容,并把解析到的内容设置到node上,这样就让node加载成功了。不同的类有不同的属性,所以Node类和每个Node子类都有对应的Loader。

    NodeLoaderLibrary

    加载器的库。有map类型成员_nodeLoaders,存储Node类名和对应的Node加载器。在创建库时,默认新建了多个自带的Node类的加载器。也可以自行向库中添加自定义的类名和对应的自定义的加载器。

    1. 首先创建库NodeLoaderLibrary,创建时为自带的Node和子类新建了加载器,并绑定加到库中。

    2. 新建一个自定义layer子类的加载器,layer子类名和加载器绑定到库中。

    3. 新建CCBRead对象,库作为CCBRead成员,绑定到其中。

    有了所有Node类的加载器,就能对之后解析到的Node类名新建对象、对属性和值进行设置了。

    接下来CCBReader开始解析.ccbi文件。

    3. 解析时

    通过.ccbi文件完整路径获取到文件二进制数据(Data类型)的指针。

    CCBReader执行readNodeGraphFromData方法进行解析,参数:.ccbi数据指针,this(调用解析方法时的场景、层),屏幕size。该方法最终会返回一个layer,项目中所有node都是layer的子节点。我们将返回的这个layer添加到场景即可。

    1. 解析文件头

    文件头结构:

    第0-3字节:ibcc

    .ccbi文件的标志。readHeader方法读取这四个字节,如果非ibcc说明非.ccbi文件,返回false停止继续读取。

    第4字节:二进制表示的十进制12

    版本号。readHeader方法在成功读取ibcc后,会读取该字节。为f时,如果经过运算后得出5,符合当前版本要求.ccbi文件版本为5,可以继续读取。

    第5字节:不为0时说明使用JS Controller,为0则不使用JS Controller

    通过是否为0得出bool值,作为 CCBReader _jsControlled 和 _animationManager->_jsControlled。

    至此,文件头读取完成,返回true。之后将继续读取后面的内容。

    2. 读取所有字符串,保存在CCBRead成员vector _stringCache中。

    3. 解析时间线Sequence。

    获取时间线Sequence总数,根据数量设置每个时间线。

    每个时间线需要设置duration(时间线长度,默认10秒)、name、Id、ChainedSequenceId(之后执行的时间线Id)。

    每个时间线的CallbackKeyframes不为空时,对每个keyframe设置time、value(callbackName callbackType),把keyframe加到时间线的SequenceProperty类型成员CallbackChannel的keyframes中。

    每个时间线的SoundKeyframes不为空时,对每个keyframe设置time、value(soundFile、pitch、pan、gain),把keyframe加到时间线的SequenceProperty类型成员SoundChannel的keyframes中。

    每个时间线最后被加到animationManager成员Vector sequences中。

    为animationManager设置成员autoPlaySequenceId。

    4. 解析node。

    执行readNodeGraph方法。

    1. 从stringCache中获取类名。

    2. 根据类名从库中找到对应的加载器。

    3. 通过加载器新建类名对应的node对象。

    4. 解析node相关的所有动画序列。

    AnimationManager成员map nodeSequences的结构如下图:

    容器nodeSequences存储了每个node和关联的多个seqProp,解析时要设置seqProp的name、type。每个seqProp的name加到CCBReader成员set animatedProps中。

    每个seqProp包含多个keyframe,读取并设置keyframe(time、easingType、easingOpt、value)。

    5. 解析node相关属性。

    需要node对应的加载器进行解析。执行加载器的parseProperties方法。

    1. 获取属性数量。

    2. 针对每个属性,获取属性类型、属性名、适用平台。

    3. 根据每个属性的类型,调用加载器不同的解析属性值的方法,获取属性值。

    4. 调用加载器的设置方法设置属性值。

    5. 如有子节点,对子节点递归调用readNodeGraph方法。

    对任何属性的解析,可概括为是先获取属性值,再进行设置。

    node中回调函数的解析

    以MenuItem为例,回调函数被视为属性,其PropertyType为BLOCK。

    属性值是结构体BlockData,包含回调函数、回调函数属于的对象(根节点Layer或CCBReader成员owner)。

    回调函数要求返回值void,参数Ref*,回调函数是属于Ref。

    MenuItem成员_callback被设为回调函数。

    以ControlButton为例,回调函数被视为属性,其PropertyType为BLOCK_CONTROL。

    属性值是结构体BlockControlData,包含回调函数、回调函数属于的对象target、触摸事件类型EventType。

    回调函数要求返回值void,参数Ref*和EventType,回调函数是属于Ref。

    设置时,是通过target、EventType、回调函数创建invocation,并加入该事件对应的容器(Control成员)中。

    至此,.ccbi文件所有内容都已被解析。

  • 相关阅读:
    快速模幂
    UPC-2249 曲线分割【递推】
    maven 服务器
    maven repo
    php-fpm sock
    mysql
    go 1
    xdebug
    centos
    win10 2503 2502
  • 原文地址:https://www.cnblogs.com/deepcho/p/cocosbuilder-ccbreader-read-node-graph.html
Copyright © 2020-2023  润新知