cocos2dx csb解析细节分析

560 阅读1分钟

csb的数据加密

FlatBuffers 是一个开源的、跨平台的、高效的、提供了多种语言接口的序列化工具库。

cocos2d-x\cocos\editor-support\cocostudio\CSParseBinary_generated.h

有时间再深入研究

运行逻辑分析

加载csb的代码

#include "cocostudio/CocoStudio.h"
Node* node = CSLoader::createNode("test.csb");
this->addChild(node);

内部逻辑分析:

  • 判断文件名后缀,是csb,进行解析
  • 将csb关联的plist加入到cache中
   auto textures = csparsebinary->textures();
    int textureSize = textures->size();
    for (int i = 0; i < textureSize; ++i)
    {
        // 参数是xxx.plist
        SpriteFrameCache::getInstance()->addSpriteFramesWithFile(textures->Get(i)->c_str());
    }
  • 序列化节点树

// 根据csb里面的名字,创建对应的NodeReader
Ref* ref = ObjectFactory::getInstance()->createObject(readername); 
NodeReaderProtocol* reader = dynamic_cast<NodeReaderProtocol*>(ref);
// 创建对应的node
reader->createNodeWithFlatBuffers();
 
 
// 具体的序列化node逻辑
Ref* ObjectFactory::createObject(const std::string &name)
{
    Ref *o = nullptr;
    do 
    {
        // _typeMap里面存储了序列化映射,通过name找到类的工厂单例
        const TInfo t = _typeMap[name];
        if (t._fun != nullptr)
        {
            o = t._fun();
        }else if (t._func != nullptr)
        {
            o = t._func();
        }
    } while (0);
   
    return o;
}

typedef cocos2d::Ref* (*Instance)(void);
typedef std::function<cocos2d::Ref* (void)> InstanceFunc;
struct CC_DLL TInfo
{
    TInfo(const std::string& type, Instance ins = nullptr);
    TInfo(const std::string& type, InstanceFunc ins = nullptr);
    TInfo(const TInfo &t);
    TInfo& operator= (const TInfo &t);
    std::string _class;
    Instance _fun;
    InstanceFunc _func;
};

ObjectFactory是个单例,在CCSGUIReader的构造函数中进行了类型的注册

#define CREATE_CLASS_WIDGET_READER_INFO(className) \
    cocos2d::ObjectFactory::TInfo(#className, &className::createInstance) 
    
#define IMPLEMENT_CLASS_NODE_READER_INFO(className) \
cocos2d::Ref* className::createInstance(void) \
{ \
return className::getInstance(); \
} \
cocos2d::ObjectFactory::TInfo className::__Type(#className, &className::createInstance); 

GUIReader::GUIReader():
m_strFilePath("")
{
    ObjectFactory* factoryCreate = ObjectFactory::getInstance();
    factoryCreate->registerType(CREATE_CLASS_WIDGET_READER_INFO(ButtonReader));
}

每种类型Reader都继承自NodeReaderProtocol

class NodeReaderProtocol{
    // 纯虚函数,生成最终的node
    virtual Node*  createNodeWithFlatBuffers(opts)=0;
    // 组装属性
    virtual void setPropsWithFlatBuffers()=0;
}


class SpriteReader : public cocos2d::Ref, public NodeReaderProtocol{
    Node* createNodeWithFlatBuffers(){
        Sprite* sprite = Sprite::create();
        setPropsWithFlatBuffers(sprite);
        return sprite;
    }
    void setPropsWithFlatBuffers(Sprite* sprite){
        string path;
        int resourceType;
        switch(resourceType):{
            // 普通的纹理
            case 0:{
                sprite->setTexture(path);
                break;
            }
            // plist合图
            case 1:{
                SpriteFrame* spriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName(path);
                sprite->setSpriteFrame(spriteFrame);
                break;
            }
        }
    }
}

Sprite接口调用堆栈

create(const std::string& filename)
    initWithFile(const std::string& filename)
        initWithTexture(Texture2D *texture, const Rect& rect, bool rotated)
            setTexture(Texture2D *texture)    
setTexture(const std::string &filename)
    setTexture(Texture2D *texture)     

setSpriteFrame(SpriteFrame *spriteFrame)
    setTexture(Texture2D *texture)    

setTexture是最终的归宿