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. notepad++最有用的快捷键

    Ctrl+Tab  实现在多个打开的窗口间切换 Ctrl+Shift+Q 区块注释 Ctrl+K  行注释 Tab 缩进 Shift+Tab 删除缩进 先按住键盘上的“ctrl”键不放,然后滚动鼠标的 ...

  2. ListOfOpenSourcePrograms

    ListOfOpenSourcePrograms Contents Desktop Applications Communication Engineering Educational Financi ...

  3. uni-app获取当前位置

    uniapp获取当前城市: 官方api:uni.getLocation()获取当前的地理位置.速度. 在微信小程序中,当用户离开应用后,此接口无法调用,除非申请后台持续定位权限:当用户点击“显示在聊天 ...

  4. git init之后,没有.git后缀的文件

    git init之后,打开相关目录没有.git后缀的文件 尝试

  5. 4、安装supervisor

    1.安装 sudo apt-get install supervisor 2.如果报phthond2.7错误,则执行 easy_install supervisor 3.配置文件位置和配置文件例子 配 ...

  6. Android Studio(十一):代码混淆及打包apk

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

  7. linux中使用gbd进行单布调试

    在linux 中使用gdb命令行进行单步调试,将整个过程介绍如下: 1.在当前路径下新建文件夹main, 并进入文件夹,新建文件main.cpp mkdir main cd main touch ma ...

  8. P1109 桃花岛

    题目描述 不是任何人都可以进入桃花岛的,黄药师最讨厌象郭靖一样呆头呆脑的人.所以,他在桃花岛的唯一入口处修了一条小路,这条小路全部用正方形瓷砖铺设而成.有的瓷砖可以踩,我们认为是安全的,而有的瓷砖一踩 ...

  9. H3C 多路径网络中环路避免操作示例

  10. java 泛型接口和方法

    java5后,可以声明泛型接口,声明方式和声明泛型类是一样的. public interface IDAO<T>{} 泛型接口子类有两种方式: 直接在子类后申明泛型: 在子类实现的接口中给 ...