cocos2d-x3.2 的UserDefault
来源:互联网 发布:ubuntu安装hp打印机 编辑:程序博客网 时间:2024/05/19 13:25
[cocos2dx笔记016]cocos2dx 3.2 的UserDefault
本文地址:http://www.cppblog.com/zdhsoft/archive/2014/09/03/208216.html
本文基于cocos2dx 3.2
cocos2dx 提供了一个基于xml的用户数据存贮类,给基于cocos2dx开发的用户数据存贮,这个类名就是UserDefault,在cocos2dx 2.x中是CCUserDefault。我的程序用的就是这个,但是最近老出错,于是分析源代码,发现了一个让我震惊的东西。经过分析,发现用UserDefault每读写一次数据,都会创建一个tinyxml对象,然后读取xml内容。如果是写数据,还是写入xml一次。下面是对应的代码:
读取key,所以各种读取key的操作,都是类似这样。
如果你用它存贮比较多的字段时,你就会现,你悲剧了。
幸好发现及时,这里不建议大家使用UserDefault做为你的数据存贮。
可以可以用自定义的方式文件读写
如可以通过标准的C读写 fopen,fwrite等或iostream也都可以,重点是读写的文件路径,会有所不同,下面是得到文件路径的例子
本文基于cocos2dx 3.2
cocos2dx 提供了一个基于xml的用户数据存贮类,给基于cocos2dx开发的用户数据存贮,这个类名就是UserDefault,在cocos2dx 2.x中是CCUserDefault。我的程序用的就是这个,但是最近老出错,于是分析源代码,发现了一个让我震惊的东西。经过分析,发现用UserDefault每读写一次数据,都会创建一个tinyxml对象,然后读取xml内容。如果是写数据,还是写入xml一次。下面是对应的代码:
读取key,所以各种读取key的操作,都是类似这样。
double UserDefault::getDoubleForKey(const char* pKey, double defaultValue)
{
const char* value = nullptr;
tinyxml2::XMLElement* rootNode;
tinyxml2::XMLDocument* doc;
tinyxml2::XMLElement* node;
node = getXMLNodeForKey(pKey, &rootNode, &doc);
// find the node
if (node && node->FirstChild())
{
value = (const char*)(node->FirstChild()->Value());
}
double ret = defaultValue;
if (value)
{
ret = utils::atof(value);
}
if (doc) delete doc;
return ret;
}
关于getXMLNodeForKey的实现{
const char* value = nullptr;
tinyxml2::XMLElement* rootNode;
tinyxml2::XMLDocument* doc;
tinyxml2::XMLElement* node;
node = getXMLNodeForKey(pKey, &rootNode, &doc);
// find the node
if (node && node->FirstChild())
{
value = (const char*)(node->FirstChild()->Value());
}
double ret = defaultValue;
if (value)
{
ret = utils::atof(value);
}
if (doc) delete doc;
return ret;
}
/**
* define the functions here because we don't want to
* export xmlNodePtr and other types in "CCUserDefault.h"
*/
static tinyxml2::XMLElement* getXMLNodeForKey(const char* pKey, tinyxml2::XMLElement** rootNode, tinyxml2::XMLDocument **doc)
{
tinyxml2::XMLElement* curNode = nullptr;
// check the key value
if (! pKey)
{
return nullptr;
}
do
{
tinyxml2::XMLDocument* xmlDoc = new tinyxml2::XMLDocument();
*doc = xmlDoc;
std::string xmlBuffer = FileUtils::getInstance()->getStringFromFile(UserDefault::getInstance()->getXMLFilePath());
if (xmlBuffer.empty())
{
CCLOG("can not read xml file");
break;
}
xmlDoc->Parse(xmlBuffer.c_str(), xmlBuffer.size());
// get root node
*rootNode = xmlDoc->RootElement();
if (nullptr == *rootNode)
{
CCLOG("read root node error");
break;
}
// find the node
curNode = (*rootNode)->FirstChildElement();
while (nullptr != curNode)
{
const char* nodeName = curNode->Value();
if (!strcmp(nodeName, pKey))
{
break;
}
curNode = curNode->NextSiblingElement();
}
} while (0);
return curNode;
}
关于setValueForKey的实现* define the functions here because we don't want to
* export xmlNodePtr and other types in "CCUserDefault.h"
*/
static tinyxml2::XMLElement* getXMLNodeForKey(const char* pKey, tinyxml2::XMLElement** rootNode, tinyxml2::XMLDocument **doc)
{
tinyxml2::XMLElement* curNode = nullptr;
// check the key value
if (! pKey)
{
return nullptr;
}
do
{
tinyxml2::XMLDocument* xmlDoc = new tinyxml2::XMLDocument();
*doc = xmlDoc;
std::string xmlBuffer = FileUtils::getInstance()->getStringFromFile(UserDefault::getInstance()->getXMLFilePath());
if (xmlBuffer.empty())
{
CCLOG("can not read xml file");
break;
}
xmlDoc->Parse(xmlBuffer.c_str(), xmlBuffer.size());
// get root node
*rootNode = xmlDoc->RootElement();
if (nullptr == *rootNode)
{
CCLOG("read root node error");
break;
}
// find the node
curNode = (*rootNode)->FirstChildElement();
while (nullptr != curNode)
{
const char* nodeName = curNode->Value();
if (!strcmp(nodeName, pKey))
{
break;
}
curNode = curNode->NextSiblingElement();
}
} while (0);
return curNode;
}
static void setValueForKey(const char* pKey, const char* pValue)
{
tinyxml2::XMLElement* rootNode;
tinyxml2::XMLDocument* doc;
tinyxml2::XMLElement* node;
// check the params
if (! pKey || ! pValue)
{
return;
}
// find the node
node = getXMLNodeForKey(pKey, &rootNode, &doc);
// if node exist, change the content
if (node)
{
if (node->FirstChild())
{
node->FirstChild()->SetValue(pValue);
}
else
{
tinyxml2::XMLText* content = doc->NewText(pValue);
node->LinkEndChild(content);
}
}
else
{
if (rootNode)
{
tinyxml2::XMLElement* tmpNode = doc->NewElement(pKey);//new tinyxml2::XMLElement(pKey);
rootNode->LinkEndChild(tmpNode);
tinyxml2::XMLText* content = doc->NewText(pValue);//new tinyxml2::XMLText(pValue);
tmpNode->LinkEndChild(content);
}
}
// save file and free doc
if (doc)
{
doc->SaveFile(UserDefault::getInstance()->getXMLFilePath().c_str());
delete doc;
}
}
它的flush方法也有惊人的发现:{
tinyxml2::XMLElement* rootNode;
tinyxml2::XMLDocument* doc;
tinyxml2::XMLElement* node;
// check the params
if (! pKey || ! pValue)
{
return;
}
// find the node
node = getXMLNodeForKey(pKey, &rootNode, &doc);
// if node exist, change the content
if (node)
{
if (node->FirstChild())
{
node->FirstChild()->SetValue(pValue);
}
else
{
tinyxml2::XMLText* content = doc->NewText(pValue);
node->LinkEndChild(content);
}
}
else
{
if (rootNode)
{
tinyxml2::XMLElement* tmpNode = doc->NewElement(pKey);//new tinyxml2::XMLElement(pKey);
rootNode->LinkEndChild(tmpNode);
tinyxml2::XMLText* content = doc->NewText(pValue);//new tinyxml2::XMLText(pValue);
tmpNode->LinkEndChild(content);
}
}
// save file and free doc
if (doc)
{
doc->SaveFile(UserDefault::getInstance()->getXMLFilePath().c_str());
delete doc;
}
}
void UserDefault::flush()
{
}
它是一个空函数,也就是说,你在写入数据的时候,会以为最后会通过flush才会写入数据,没想全错了!{
}
如果你用它存贮比较多的字段时,你就会现,你悲剧了。
幸好发现及时,这里不建议大家使用UserDefault做为你的数据存贮。
可以可以用自定义的方式文件读写
如可以通过标准的C读写 fopen,fwrite等或iostream也都可以,重点是读写的文件路径,会有所不同,下面是得到文件路径的例子
std::string strFullFileName = FileUtils::getInstance()->getWritablePath() + DATA_FILE_NAME;
最后:不要求写太高质量的代码,但也不要写的太低质量了
最后:不要求写太高质量的代码,但也不要写的太低质量了
0 0
- cocos2d-x3.2 的UserDefault
- Cocos2d-x3.2下Lua,UserDefault、Texture的使用
- Cocos2d-x3.2 UserDefault用户数据
- Cocos2d-x3.2 UserDefault用户数据 使用
- cocos2d UserDefault
- Cocos2d-x3.2 定时器的使用
- Cocos2d-x3.2 定时器的使用
- cocos2d-x3.2对CocoStudio的支持
- cocos2d-x3.2入门
- cocos2d-x3.2 scrollView
- Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程
- Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程
- Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程
- Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程
- Cocos2d-x3.2与OpenGL渲染总结Cocos2d-x3.2的渲染流程
- Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程
- Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程
- Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程
- 嵌入式linux中nRF24L01驱动(主控板tiny4412)
- 迭代器模式——解决问题的第三者
- 数据结构: 栈
- [从头学数学] 第77节 可能性
- 3.以普通表格型单表为模板定制模块:短信库维护
- cocos2d-x3.2 的UserDefault
- document.documentElement和document.body的 scrollHeight/scrollTop/clientHeight 以及判断滚动条是否已拉到页面最底部
- java实现逆波兰式四则运算
- 基于Android arm64 Linux got 调试_02
- 雷思海:500年的猴子,只说了一桩心事
- 3.定时任务处理
- NLP系列(5)_从朴素贝叶斯到N-gram语言模型
- 思维导图之《机器视觉知识体系》
- hdoj 2035人见人爱A^B