[cocos2d-x]将ccb场景的plist文件转换为lua的table格式。
//仅仅是一个练手,无实质性作用
#include "stdafx.h"
enum ValueType
{
VT_NONE,
VT_VALUE, /* real integer true false */
VT_STRING,
VT_DICT,
VT_ARRAY,
};
class CBaseValue
{
public:
CBaseValue(ValueType vt)
: m_eType(vt)
{
}
virtual std:: string toString() = 0;
virtual ~CBaseValue()
{
}
protected:
ValueType m_eType;
};
class CValue : public CBaseValue
{
public:
CValue( const std:: string& value)
: CBaseValue(VT_VALUE)
, m_sValue(value)
{
}
std:: string toString()
{
return m_sValue;
}
protected:
std:: string m_sValue;
};
class CString : public CBaseValue
{
public:
CString( const std:: string& value)
: CBaseValue(VT_STRING)
, m_sValue("\"" + value + "\"")
{
}
std:: string toString()
{
return m_sValue;
}
protected:
std:: string m_sValue;
};
class CArray : public CBaseValue
{
public:
CArray( int depth = 0)
: CBaseValue(VT_ARRAY)
, m_nDepth(depth)
{
}
~CArray()
{
std::for_each(m_aValues.begin(), m_aValues.end(), [](CBaseValue* value)
{
delete value;
});
}
void add(CBaseValue* value)
{
m_aValues.push_back(value);
}
std:: string toString()
{
std:: string prefix(m_nDepth, '\t');
std:: string text = "{\n";
prefix.push_back('\t');
std::for_each(m_aValues.begin(), m_aValues.end(), [&](CBaseValue* value)
{
text += prefix + value->toString() + ",\n";
});
prefix.pop_back();
text += prefix + "}";
return text;
}
protected:
int m_nDepth;
std::vector<CBaseValue*> m_aValues;
};
class CDict : public CBaseValue
{
public:
CDict( int depth = 0)
: CBaseValue(VT_DICT)
, m_nDepth(depth)
{
}
~CDict()
{
std::for_each(m_mapValues.begin(), m_mapValues.end(), [](std::pair<std:: string, CBaseValue*> keyValue)
{
delete keyValue.second;
});
}
void add( const std:: string& key, CBaseValue* value)
{
m_mapValues.insert(std::make_pair(key, value));
}
std:: string toString()
{
std:: string prefix(m_nDepth, '\t');
std:: string text = "{\n";
prefix.push_back('\t');
std::for_each(m_mapValues.begin(), m_mapValues.end(), [&]( const std::pair<std:: string, CBaseValue*> keyValue)
{
text += prefix + keyValue.first + " = ";
text += keyValue.second->toString() + ",\n";
});
prefix.pop_back();
text += prefix + "}";
return text;
}
protected:
int m_nDepth;
std::map<std:: string, CBaseValue*> m_mapValues;
};
CArray* parseArray(pugi::xml_node& node, int depth = 0);
CDict* parseDict(pugi::xml_node& node, int depth = 0);
CBaseValue* parseValue(pugi::xml_node& node, int depth = 0)
{
std:: string name = node.name();
if (name == "real" || name == "integer")
{
return new CValue(node.text(). get());
}
else if (name == "true")
{
return new CValue("true");
}
else if (name == "false")
{
return new CValue("false");
}
else if (name == "string")
{
return new CString(node.text(). get());
}
else if (name == "array")
{
return parseArray(node, depth + 1);
}
else if (name == "dict")
{
return parseDict(node, depth + 1);
}
else
{
assert( false && "error type");
}
return NULL;
}
CArray* parseArray(pugi::xml_node& node, int depth)
{
CArray* array = new CArray(depth);
for (auto i = node.begin(); i != node.end(); )
{
/* value */
assert(i != node.end());
CBaseValue* value = parseValue(*i, depth);
++i;
array->add(value);
}
return array;
}
CDict* parseDict(pugi::xml_node& node, int depth)
{
CDict* dict = new CDict(depth);
for (auto i = node.begin(); i != node.end(); )
{
/* key */
assert(i->name() == std:: string("key"));
std:: string key = std:: string("[\"") + i->text().get() + "\"]";
++i;
/* value */
assert(i != node.end());
CBaseValue* value = parseValue(*i, depth);
++i;
dict->add(key, value);
}
return dict;
}
CDict* parseCCB( const std:: string& filename)
{
pugi::xml_document doc;
if (doc.load_file(filename.c_str()))
{
auto plist = doc.child("plist");
/* <plist> == <dict> */
if (plist)
{
return parseDict(plist.child("dict"));
}
}
return NULL;
}
bool ccbToLua( const std:: string& filename, std::ostream& os = std::cout)
{
CDict* dict = parseCCB(filename);
if (dict)
{
os << "return" << std::endl;
os << dict->toString() << std::endl;
delete dict;
}
return false;
}
int _tmain( int argc, _TCHAR* argv[])
{
std::ofstream os("test.out.lua");
ccbToLua("test.ccb", os);
os.close();
return 0;
}
enum ValueType
{
VT_NONE,
VT_VALUE, /* real integer true false */
VT_STRING,
VT_DICT,
VT_ARRAY,
};
class CBaseValue
{
public:
CBaseValue(ValueType vt)
: m_eType(vt)
{
}
virtual std:: string toString() = 0;
virtual ~CBaseValue()
{
}
protected:
ValueType m_eType;
};
class CValue : public CBaseValue
{
public:
CValue( const std:: string& value)
: CBaseValue(VT_VALUE)
, m_sValue(value)
{
}
std:: string toString()
{
return m_sValue;
}
protected:
std:: string m_sValue;
};
class CString : public CBaseValue
{
public:
CString( const std:: string& value)
: CBaseValue(VT_STRING)
, m_sValue("\"" + value + "\"")
{
}
std:: string toString()
{
return m_sValue;
}
protected:
std:: string m_sValue;
};
class CArray : public CBaseValue
{
public:
CArray( int depth = 0)
: CBaseValue(VT_ARRAY)
, m_nDepth(depth)
{
}
~CArray()
{
std::for_each(m_aValues.begin(), m_aValues.end(), [](CBaseValue* value)
{
delete value;
});
}
void add(CBaseValue* value)
{
m_aValues.push_back(value);
}
std:: string toString()
{
std:: string prefix(m_nDepth, '\t');
std:: string text = "{\n";
prefix.push_back('\t');
std::for_each(m_aValues.begin(), m_aValues.end(), [&](CBaseValue* value)
{
text += prefix + value->toString() + ",\n";
});
prefix.pop_back();
text += prefix + "}";
return text;
}
protected:
int m_nDepth;
std::vector<CBaseValue*> m_aValues;
};
class CDict : public CBaseValue
{
public:
CDict( int depth = 0)
: CBaseValue(VT_DICT)
, m_nDepth(depth)
{
}
~CDict()
{
std::for_each(m_mapValues.begin(), m_mapValues.end(), [](std::pair<std:: string, CBaseValue*> keyValue)
{
delete keyValue.second;
});
}
void add( const std:: string& key, CBaseValue* value)
{
m_mapValues.insert(std::make_pair(key, value));
}
std:: string toString()
{
std:: string prefix(m_nDepth, '\t');
std:: string text = "{\n";
prefix.push_back('\t');
std::for_each(m_mapValues.begin(), m_mapValues.end(), [&]( const std::pair<std:: string, CBaseValue*> keyValue)
{
text += prefix + keyValue.first + " = ";
text += keyValue.second->toString() + ",\n";
});
prefix.pop_back();
text += prefix + "}";
return text;
}
protected:
int m_nDepth;
std::map<std:: string, CBaseValue*> m_mapValues;
};
CArray* parseArray(pugi::xml_node& node, int depth = 0);
CDict* parseDict(pugi::xml_node& node, int depth = 0);
CBaseValue* parseValue(pugi::xml_node& node, int depth = 0)
{
std:: string name = node.name();
if (name == "real" || name == "integer")
{
return new CValue(node.text(). get());
}
else if (name == "true")
{
return new CValue("true");
}
else if (name == "false")
{
return new CValue("false");
}
else if (name == "string")
{
return new CString(node.text(). get());
}
else if (name == "array")
{
return parseArray(node, depth + 1);
}
else if (name == "dict")
{
return parseDict(node, depth + 1);
}
else
{
assert( false && "error type");
}
return NULL;
}
CArray* parseArray(pugi::xml_node& node, int depth)
{
CArray* array = new CArray(depth);
for (auto i = node.begin(); i != node.end(); )
{
/* value */
assert(i != node.end());
CBaseValue* value = parseValue(*i, depth);
++i;
array->add(value);
}
return array;
}
CDict* parseDict(pugi::xml_node& node, int depth)
{
CDict* dict = new CDict(depth);
for (auto i = node.begin(); i != node.end(); )
{
/* key */
assert(i->name() == std:: string("key"));
std:: string key = std:: string("[\"") + i->text().get() + "\"]";
++i;
/* value */
assert(i != node.end());
CBaseValue* value = parseValue(*i, depth);
++i;
dict->add(key, value);
}
return dict;
}
CDict* parseCCB( const std:: string& filename)
{
pugi::xml_document doc;
if (doc.load_file(filename.c_str()))
{
auto plist = doc.child("plist");
/* <plist> == <dict> */
if (plist)
{
return parseDict(plist.child("dict"));
}
}
return NULL;
}
bool ccbToLua( const std:: string& filename, std::ostream& os = std::cout)
{
CDict* dict = parseCCB(filename);
if (dict)
{
os << "return" << std::endl;
os << dict->toString() << std::endl;
delete dict;
}
return false;
}
int _tmain( int argc, _TCHAR* argv[])
{
std::ofstream os("test.out.lua");
ccbToLua("test.ccb", os);
os.close();
return 0;
}