NodeLoaderLibrary是用来存储节点加载器类型的类,通过registerDefaultNodeLoaders()可以注册所有默认类型的加载器

在CocosBuilder的使用手册中:

1、如果要使用自定义的加载器

//创建一个默认的节点加载器库对象
CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary(); //使用自己的节点加载器,第一个参数是节点加载器的名字,第二个参数是节点加载器的加载函数
ccNodeLoaderLibrary->registerCCNodeLoader("HelloCocosBuilderLayer", HelloCocosBuilderLayerLoader::loader());

我们来看一看第一个方法中中做了什么操作:

NodeLoaderLibrary * NodeLoaderLibrary::newDefaultNodeLoaderLibrary() {
//先是调用了librayr方法,但进去之后发现只是一行宏定义
//CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(NodeLoaderLibrary, library);
//再调到这个方法中,发现这是一个类似于create()的方法,用来创建NodeLoaderLibrary对象
//并将这个对象加入到内存自动管理中
NodeLoaderLibrary * ccNodeLoaderLibrary = NodeLoaderLibrary::library();
//给创建的对象注册一堆默认的节点加载器,放在下面一段代码中了
ccNodeLoaderLibrary->registerDefaultNodeLoaders();
//最后返回带了各种加载器的节点加载库对象
return ccNodeLoaderLibrary;
}
void NodeLoaderLibrary::registerDefaultNodeLoaders() {
this->registerNodeLoader("CCNode", NodeLoader::loader());
this->registerNodeLoader("CCLayer", LayerLoader::loader());
this->registerNodeLoader("CCLayerColor", LayerColorLoader::loader());
this->registerNodeLoader("CCLayerGradient", LayerGradientLoader::loader());
this->registerNodeLoader("CCSprite", SpriteLoader::loader());
this->registerNodeLoader("CCLabelBMFont", LabelBMFontLoader::loader());
this->registerNodeLoader("CCLabelTTF", LabelTTFLoader::loader());
this->registerNodeLoader("CCScale9Sprite", Scale9SpriteLoader::loader());
this->registerNodeLoader("CCScrollView", ScrollViewLoader::loader());
this->registerNodeLoader("CCBFile", CCBFileLoader::loader());
this->registerNodeLoader("CCMenu", MenuLoader::loader());
this->registerNodeLoader("CCMenuItemImage", MenuItemImageLoader::loader());
this->registerNodeLoader("CCControlButton", ControlButtonLoader::loader());
this->registerNodeLoader("CCParticleSystemQuad", ParticleSystemQuadLoader::loader());
}

再看看第二个方法:

void NodeLoaderLibrary::registerNodeLoader(const char * pClassName, NodeLoader * pNodeLoader) {
//先将加载器hold住
pNodeLoader->retain();
//将加载器以(加载器名,加载器)的格式存储在_nodeLoaders中
//_nodeLoaders是一张map,在.h文件中可以看到如下的定义,存储了所有的加载器
//typedef std::map<std::string, NodeLoader *> NodeLoaderMap;
this->_nodeLoaders.insert(NodeLoaderMapEntry(pClassName, pNodeLoader));
}

2、如果不使用自定义的加载器,只需要一行代码就可以创建默认的加载器对象了

 CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary();

以上是创建加载器的对象的方法

如果需要加载ccbi文件,那么需要知道ccbi文件中的根节点是什么类型的对象,以及想要返回的值类型,选择合适的类型来定义加载ccbi文件,如下使用了粒子系统来定义加载的ccbi文件

CCParticleSystem* myParticles = (CCParticleSystem*) ccbReader->readNodeGraphFromFile("MyParticleSystem.ccbi");

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

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

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

//加载ccb文件
Node* CCBReader::readNodeGraphFromFile(const char *pCCBFileName)
{
return this->readNodeGraphFromFile(pCCBFileName, nullptr);
} Node* CCBReader::readNodeGraphFromFile(const char* pCCBFileName, Ref* pOwner)
{
return this->readNodeGraphFromFile(pCCBFileName, pOwner, Director::getInstance()->getWinSize());
}
//最后都调用这个方法
Node* CCBReader::readNodeGraphFromFile(const char *pCCBFileName, Ref *pOwner, const Size &parentSize)
{
if (nullptr == pCCBFileName || strlen(pCCBFileName) == 0)
{
return nullptr;
} std::string strCCBFileName(pCCBFileName); //获取ccb文件的名字
std::string strSuffix(".ccb*i"); // 格式字符
// Add ccbi suffix
// 判断文件名没有.ccbi的后缀,如果没有就加上
if (!CCBReader::endsWith(strCCBFileName.c_str(), strSuffix.c_str()))
{
strCCBFileName += strSuffix;
}
//获取ccb文件的完整地址
std::string strPath = FileUtils::getInstance()->fullPathForFilename(strCCBFileName); //将ccb文件完整地址转型为Data
auto dataPtr = std::make_shared<Data>(FileUtils::getInstance()->getDataFromFile(strPath)); //调用readNodeGraphFromData,下面一段
Node *ret = this->readNodeGraphFromData(dataPtr, pOwner, parentSize); return ret;
}
Node* CCBReader::readNodeGraphFromDDData(std::shared_ptr<cocos2d::Data> data, Ref *pOwner, const Size &parentSize)
{
_data = data; //ccb完整路径
_bytes =_data->getBytes(); //将文件路径转换成char字符
_currentByte = 0;
_currentBit = 0;
_owner = pOwner; //跳转了几个函数没发现有什么用法,因为是Ref类型,猜测是可自定义参数
CC_SAFE_RETAIN(_owner); _animationManager->setRootContainerSize(parentSize);
_animationManager->_owner = _owner; //
Node *pNodeGraph = readFileWithCleanUp(true, std::make_shared<CCBAnimationManagerMap>()); //
if (pNodeGraph && _animationManager->getAutoPlaySequenceId() != -1)
{
// Auto play animations
_animationManager->runAnimationsForSequenceIdTweenDuration(_animationManager->getAutoPlaySequenceId(), 0);
} // Assign actionManagers to userObject
for (auto iter = _animationManagers->begin(); iter != _animationManagers->end(); ++iter)
{
Node* pNode = iter->first;
CCBAnimationManager* manager = iter->second; //
pNode->setUserObject(manager); //不使用
if (_jsControlled)
{
_nodesWithAnimationManagers.pushBack(pNode);
_animationManagersForNodes.pushBack(manager);
}
} return pNodeGraph;
}
Node* CCBReader::readFileWithCleanUp(bool bCleanUp, CCBAnimationManagerMapPtr am)
{
if (! readHeader())
{
return nullptr;
} if (! readStringCache())
{
return nullptr;
} if (! readSequences())
{
return nullptr;
} //
setAnimationManagers(am);
//
Node *pNode = readNodeGraph(nullptr);
//
_animationManagers->insert(pNode, _animationManager); if (bCleanUp)
{
cleanUpNodeGraph(pNode);
} return pNode;
} bool CCBReader::readStringCache() {
int numStrings = this->readInt(false); for(int i = 0; i < numStrings; i++) {
this->_stringCache.push_back(this->readUTF8());
} return true;
} bool CCBReader::readSequences()
{
auto& sequences = _animationManager->getSequences(); int numSeqs = readInt(false); for (int i = 0; i < numSeqs; i++)
{
CCBSequence *seq = new (std::nothrow) CCBSequence();
seq->autorelease(); seq->setDuration(readFloat());
seq->setName(readCachedString().c_str());
seq->setSequenceId(readInt(false));
seq->setChainedSequenceId(readInt(true)); if(!readCallbackKeyframesForSeq(seq)) return false;
if(!readSoundKeyframesForSeq(seq)) return false; sequences.pushBack(seq);
} _animationManager->setAutoPlaySequenceId(readInt(true));
return true;
}
//解析头部字节
bool CCBReader::readHeader()
{
/* If no bytes loaded, don't crash about it. */
if(this->_bytes == nullptr) {
return false;
} /* Read magic bytes */
int magicBytes = *((int*)(this->_bytes + this->_currentByte));
this->_currentByte += 4; if(CC_SWAP_INT32_BIG_TO_HOST(magicBytes) != (*reinterpret_cast<const int*>("ccbi"))) {
return false;
} /* Read version. */
int version = this->readInt(false);
if(version != CCB_VERSION) {
log("WARNING! Incompatible ccbi file version (file: %d reader: %d)", version, CCB_VERSION);
return false;
} // Read JS check
_jsControlled = this->readBool();
_animationManager->_jsControlled = _jsControlled; return true;
}

暂存

从零开始のcocos2dx生活(九)CCBReader的更多相关文章

  1. 从零开始のcocos2dx生活(七)ParticleSystem

    CCParticleSystem是用来设置粒子效果的类 1.粒子分为两种模式:重力模式 和 半径模式 重力模式独占属性: gravity 重力方向,Vec2类型,可以分别指定不同方向的重力大小 spe ...

  2. 从零开始のcocos2dx生活(二)Node

    节点 Node 文章目录 节点 Node 前言 变量初始化 创建一个节点对象 获取节点依赖的计数器 获取节点的描述(获取节点的Tag) 节点的局部层顺序值(LocalZOrder) 设置节点的Loca ...

  3. 从零开始のcocos2dx生活(十一)TableView

    目录 简述 主要变量 主要方法 setVerticalFillOrder reloadData cellAtIndex updateCellAtIndex insertCellAtIndex remo ...

  4. 从零开始のcocos2dx生活(十)ScrollView

    目录 简介 基础变量 ScrollViewDelegate Direction _dragging _container _touchMoved _bounceable _touchLength 方法 ...

  5. 从零开始のcocos2dx生活(八)ParticleSystemQuad

    https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/#_1 写的真的非常好-最近没时间拜读,只看 ...

  6. 从零开始のcocos2dx生活(六)EventDispatcher

    EventDispatcher可能是所有的里面比较不容易理解也不容易看的 我说自己的理解可能会误导到你们-[索了你们看不下去>< 我写了几乎所有的代码的注释,有的是废话跳过就好 主要的代码 ...

  7. 从零开始のcocos2dx生活(一)内存管理

    cocos中所有的对象都是继承自Ref基类,Ref的职责就是对对象进行引用计数管理 内存管理中最重要的是三个方法retain().release().autorelease() 在cocos中创建对象 ...

  8. 从零开始のcocos2dx生活(五)ActionEase

    文章目录 sineEaseIn sineEaseOut sineEaseInOut expoEaseIn expoEaseOut expoEaseInOut easeIn easeOut easeIn ...

  9. 从零开始のcocos2dx生活(四)ActionManager

    文章目录 初始化构造函数 析构函数 删除哈希元素 分配存放动作对象的空间 通过索引移除动作 暂停动作 恢复动作 暂停所有的动作 恢复所有的动作 添加动作 移除所有的动作 移除target中的所有动作 ...

随机推荐

  1. JVM问题诊断

    https://gitbook.cn/books/5d2d822f175a450263e945f9/index.html

  2. behavior planning——inputs to transition functions

    the answer is that we have to pass all  of the data into transition function except for the previous ...

  3. 云原生生态周报 Vol. 6 | KubeCon EU 特刊

    5 月 26日,2019 年第一个 KubeCon + CloudNativeCon 在巴塞罗那成功闭幕.本届 KubeCon 共吸引了超过 7700 名与会者,相较去年哥本哈根大会的 4300 余名 ...

  4. C#面向对象--练习题

    public class Program { //用户自定义:我们自己定义这种数据类型 public struct jiegouti// 结构体前面加上public, 可供外界访问 { public ...

  5. 基于jQuery+JSON的省市联动效果

    省市区联动下拉效果在WEB应用中使用非常广泛,尤其在一些会员信息系统.电商网站最为常见,开发者一般使用AJAX实现无刷新下拉联动. 本文将讲述利用jQuery插件,通过读取JSON数据,实现无刷新动态 ...

  6. ajax上传文件 基于jquery form表单上传文件

    <script src="/static/js/jquery.js"></script><script> $("#reg-btn&qu ...

  7. js实现点击隐藏图片

    方法一: 把图片的display设为none,触发点击事件时,display变为block <style> img { width: 400px;height: 300px; displa ...

  8. 【React】富文本编辑器 清空文本内容 获取HTML

    富文本编辑器  React  传入 import React,{Component } from 'react'; import { Card, Button, Table, Form, Select ...

  9. H3C 单路径网络中环路产生过程(3)

  10. css图片填充的几种方式

    当图片比例不固定时,想要让图片自适应,一般都会用background-size:cover/contain,但是这个只适用于背景图. img有个属性object-fit 属性值:object-fit: ...