Cocos2d-x ValueMap

来源:互联网 发布:oculus vr 软件下载 编辑:程序博客网 时间:2024/06/05 00:22

Cocos2d-x ValueMap

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

Value

Cocos中的Value类可以存放各种基本类型如intboolstringfloat等等。Value类采用联合体实现,支持的数据类型有byteintunsignedfloatdoubleboolstringvectorValueMapValueMapIntKey。对于对象类型stringvectorValueMapValueMapIntKeyValue类只存放指针,减少联合体的大小。以下时Value类的联合体定义:

   union

   {

       unsignedcharbyteVal;

       intintVal;

       unsignedintunsignedVal;

       floatfloatVal;

       doubledoubleVal;

       boolboolVal;

       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<Value> ValueVector;

typedef std::unordered_map<std::string, Value> ValueMap;

typedef std::unordered_map<int, Value> ValueMapIntKey;

 

ValueMap类型

ValueMap实际的类型如下:

typedef std::unordered_map<std::string, Value> ValueMap;

是一个哈希表的MapKeystring类型,值为Value类型。

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

   ValueMapvm;

   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)));

   ValueVectorvv;

   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)

例如:

   ValueMapvm;

   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)));

   ValueVectorvv;

   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> 

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

 

读取

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

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

 

例如读取上个例子保存的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

 

FileUtilsValueMap的支持

写入ValueMap文件

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

statictinyxml2::XMLElement*generateElementForDict(constValueMap&dict,tinyxml2::XMLDocument*doc)

statictinyxml2::XMLElement*generateElementForArray(constValueVector&array,tinyxml2::XMLDocument*pDoc)

statictinyxml2::XMLElement*generateElementForObject(constValue&value,tinyxml2::XMLDocument*doc)

Cocos使用tinyxml2来解析XML文档。

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

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

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

读取ValueMap文件

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

classDictMaker:publicSAXDelegator

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

classCC_DLLSAXDelegator

{

public:

virtual~SAXDelegator(){}

//开始访问节点时调用

virtualvoidstartElement(void *ctx,constchar*name,constchar**atts) = 0;

//结束访问节点时调用

virtualvoidendElement(void *ctx,constchar*name)= 0;

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

   virtualvoidtextHandler(void *ctx,constchar*s,intlen)= 0;

};

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

ValueMap DictMaker::dictionaryWithContentsOfFile(const std::string& fileName)

 

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

ValueMapFileUtils::getValueMapFromFile(conststd::string&filename)

{

   conststd::stringfullPath=fullPathForFilename(filename);

   DictMakertMaker;

   returntMaker.dictionaryWithContentsOfFile(fullPath);

}

 

扩展

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

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

 

1 0
原创粉丝点击