l

成都手游码农一枚
随笔 - 32, 文章 - 0, 评论 - 117, 引用 - 0
数据加载中……

[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;
}

posted on 2013-07-01 23:55 l1989 阅读(1248) 评论(0)  编辑 收藏 引用 所属分类: C++游戏


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理