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. oracle函数 SUM([distinct|all]x)

    [功能]统计数据表选中行x列的合计值. [参数]all表示对所有的值求合计值,distinct只对不同的值求合计值,默认为all 如果有参数distinct或all,需有空格与x(列)隔开. [参数] ...

  2. QT自定义窗口

    qt 中允许自定义窗口控件,使之满足特殊要求, (1)可以修改其显示,自行绘制 (2)可以动态显示 (3)可以添加事件,支持鼠标和键盘操作 自定义控件可以直接在QtDesigner里使用,可以直接加到 ...

  3. This cache store does not support tagging.

    用户权限管理系统 https://github.com/Zizaco/entrust 再添加角色的时候... 报了一个错.. BadMethodCallException in Repository. ...

  4. mysql查询包含逗号的数据,并逗号拆分为多行展现

    在做系统开发的时候,有可能是由于之前的遗留问题,导致在数据入库的时候,将多个数据以逗号分隔的实行,存储在一条数据中,例如: ID VALUE 1 yang,zheng,song 2 zhao,qian ...

  5. 洛谷P2820 局域网

    #include<bits/stdc++.h> using namespace std; ; ; int n,k,sum,tot; struct node{ int cnt,fa; }f[ ...

  6. iptables SNAT与伪装

    Source NAT(SNAT)的主要應用,是让同一內部網路上的多部主机,可共用同一条Internet实体连線.直接与Internet相连的闸道器,可使用SNAT(搭配连線追蹤)来来改写內部网络与In ...

  7. Codeforces Round #577 (Div 2)

    A. Important Exam 水题 #include<iostream> #include<string.h> #include<algorithm> #in ...

  8. elasticsearch-倒排索引原理

    倒排索引 Elasticsearch 使用一种称为 倒排索引 的结构,它适用于快速的全文搜索.一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表. 例如,假设我们有两个 ...

  9. Javassist指引(一)

    目录 原文链接 1. 读写字节码 1.1概述 Javassist是一个Java字节码类库.Java的字节码是包含Java类与接口,并按照一定的顺序存在class文件中. Javassist.CtCla ...

  10. linux scull 函数open 方法

    open 方法提供给驱动来做任何的初始化来准备后续的操作. 在大部分驱动中, open 应当 进行下面的工作: 检查设备特定的错误(例如设备没准备好, 或者类似的硬件错误 如果它第一次打开, 初始化设 ...