Cocos2d-x ValueMap

Cocos2d-x ValueMap

声明:本文分析的是cocos2d-x-3.13的代码

Value类

Cocos中的Value类可以存放各种基本类型如int、bool、string、float等等。Value类采用联合体实现,支持的数据类型有byte、int、unsigned、float、double、bool、string、vector、ValueMap、ValueMapIntKey。对于对象类型string、vector、ValueMap、ValueMapIntKey,Value类只存放指针,减少联合体的大小。以下时Value类的联合体定义:

   union

   {

       unsigned char byteVal;

       int intVal;

       unsigned int unsignedVal;

       float floatVal;

       double doubleVal;

       bool boolVal;

       std::string *strVal;

       ValueVector *vectorVal;

       ValueMap *mapVal;

       ValueMapIntKey *intKeyMapVal;

}_field;

 

Value类重载了所以类型的构造函数和operator=,这样Value可以直接通过等于号,或者构造函数赋值任何支持的类型。

 

Value类也重载了关系运算符==和!=。

 

Value类提供了每中类型的XXX asXXX()成员函数,该函数可以实现数据类型的内部转换,如Value当前类型为int,通过asString可以返回一个int数值转换后的字符穿,但Value的类型依然为int。

 

预定义Value容器

typedef std::vector<ValueValueVector;

typedef std::unordered_map<std::stringValueValueMap;

typedef std::unordered_map<intValueValueMapIntKey;

 

ValueMap类型

ValueMap实际的类型如下:

typedef std::unordered_map<std::stringValueValueMap;

是一个哈希表的Map,Key为string类型,值为Value类型。

这种类型非常适合存放键值对,可以存放一个key为字符串,值可以为任意类型(Value类所支持的类型),包括ValueMap类型。例如:

   ValueMap vm;

   vm.insert(make_pair(std::string("first"),Value(10)));

   vm.insert(make_pair(std::string("second"),Value("abc")));

   vm.insert(make_pair(std::string("third"),Value(vm)));

   ValueVector vv;

   vv.push_back(Value(1));vv.push_back(Value(2));vv.push_back(Value(3));

   vm.insert(make_pair(std::string("fourth"),Value(vv)));

 

ValueMap序列化存储

保存

Cocos中的FileUtils支持将ValueMap转换为相应的XML文件保存,通过以下函数保存。

bool FileUtils::writeValueMapToFile(const ValueMap&dict,const std::string&fullPath)

例如:

   ValueMap vm;

   vm.insert(make_pair(std::string("first"),Value(10)));

   vm.insert(make_pair(std::string("second"),Value("abc")));

   vm.insert(make_pair(std::string("third"),Value(vm)));

   ValueVector vv;

   vv.push_back(Value(1));vv.push_back(Value(2));vv.push_back(Value(3));

   vm.insert(make_pair(std::string("fourth"),Value(vv)));

 

   FileUtils::getInstance()->writeValueMapToFile(vm,path+"ValueMap.plist");

结果ValueMap.plist文件内容:

 

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC"-//Apple//DTD PLIST 1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
<plistversion="1.0">
   <dict>
        <key>fourth</key>
        <array>
            <integer>1</integer>
            <integer>2</integer>
            <integer>3</integer>
        </array>
        <key>first</key>
        <integer>10</integer>
        <key>second</key>
        <string>abc</string>
        <key>third</key>
        <dict>
            <key>first</key>
            <integer>10</integer>
            <key>second</key>
            <string>abc</string>
        </dict>
   </dict>
</plist>
 

 

 

 

根节点为plist,ValueMap对象对应dict节点,数组对应array节点,其他类型对应相应节点。

 

读取

Cocos中的FileUtils也支持从特定格式的XML文件读取并返回ValueMap对象,通过以下函数读取。

ValueMap FileUtils::getValueMapFromFile(const std::stringfilename)

 

例如读取上个例子保存的ValueMap.plist文件:

ValueMap vm2 =FileUtils::getInstance()->getValueMapFromFile(path+"ValueMap.plist");

CCLOG("%s,%s",vm2["first"].asString().c_str(),vm2["second"].asString().c_str());

结果:

10, abc

 

FileUtils对ValueMap的支持

写入ValueMap文件

CCFileUtils.cpp文件中有三个生成XML文档节点的函数

static tinyxml2::XMLElement*generateElementForDict(const ValueMap&dicttinyxml2::XMLDocument *doc)

static tinyxml2::XMLElement*generateElementForArray(const ValueVector&arraytinyxml2::XMLDocument *pDoc)

static tinyxml2::XMLElement*generateElementForObject(const Value&valuetinyxml2::XMLDocument *doc)

Cocos使用tinyxml2来解析XML文档。

这个三个函数分别是生成ValueMap节点,数组节点和一般数据类型节点。

保存ValueMap函数
bool FileUtils::writeValueMapToFile(const ValueMap&dict,const std::string&fullPath)

会调用这三个函数生成相应的XML文档对象,然后保存XML文件。

读取ValueMap文件

CCFileUtils.cpp文件实现了以下类读取并转换XML文件。

class DictMakerpublic SAXDelegator

SAXDelegator接口是用来遍历XML文档,有以下三个函数:

class CC_DLL SAXDelegator

{

public:

virtual ~SAXDelegator(){}

//开始访问节点时调用

virtual void startElement(void *ctx,const char*name,const char **atts) = 0;

//结束访问节点时调用

virtual void endElement(void *ctx,const char *name)= 0;

//访问节点文本内容时调用

   virtual void textHandler(void *ctx,const char*s,int len)= 0;

};

以下函数实现了对XML文件的读取并转换成ValueMap对象

Value Map DictMaker::dictionaryWithContentsOfFile(const std::stringfileName)

 

函数FileUtils::getValueMapFromFile只是简单调用DictMaker::dictionaryWithContentsOfFile

ValueMap FileUtils::getValueMapFromFile(const std::string &filename)

{

   const std::string fullPath=fullPathForFilename(filename);

   DictMaker tMaker;

   return tMaker.dictionaryWithContentsOfFile(fullPath);

}

 

扩展

 

1.      通过TexPacker将小图打包成为大图生成的配置文件就是一个plist的XML文件,文件格式就是按照ValueMap格式进行存储的。读取plist后便会生成一个ValueMap对象。

2.      AnimationCache加载动画使用的Animation配置文件也时一个ValueMap文件,且有两中格式,一种是简单配置,一种是复杂配置。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值