• CocosStudio文件解析工具CsdAnalysis


    起因

    因为工作需要,所以需要使用CocosStudio来制作界面动画什么的。做完了发现需要找里边对象的时候会有很长一串代码,感觉不是很爽。之前写OC代码的时候可以吧程序中的对象指针跟编辑器中的对象相对容易的结合起来。所以想要做一个类似的工具出来,解放自己的双手,更多的关注到业务逻辑里边。

    声明

    转载请详细注明出处:http://www.cnblogs.com/anxin1225/p/5099910.html

    先上图

     

    (自动生成的h文件)

    (自动生成的cpp文件)

    (命令行中输出局部关键代码)

    实现模式的选择

    - 批量生成:某一个目录下得所有csd文件都需要生成对应的类

    - 单一生成:针对某一个csd文件生成对应的类

    - 局部代码:在开发过程中,每一个csd文件都有可能修改,修改就代表需要变更我们的代码

    实现思路

    - csd文件实际上时一个Xml文件。解析一下就好。非常简单。。。没有啥实现过程

    再来讲讲咋用

    安装Python

    - Mac 自己带着

    - Window 我也不用,咱就不管了

    - 我设置这个只是告诉你要装,具体咋弄自己百度去

    - 我的版本号是2.7

    这是一个命令行程序

    参数说明

    - 解析目标(默认为当前目录)

    - 输出目录(默认为当前目录下的out_put目录,如果目录不存在将新建目录) 

    - -t 确认输出模式为输出到文件

    - -t 后的第一个参数 如果不是“-”开头,则会将此参数设置为输出目录

    - 不是跟在以“-”开头参数后的第一个参数则会被认为是解析目标

    使用场景常用命令

    第一次拿到美术资源时

    将目标目录中的文件全部解析到项目中(会覆盖项目文件,操作需谨慎)

    ython CsdAnalysis.py cocosstudio -d 项目中需要保存的位置

    项目中已经存在其他资源时

    将目标目录中的文件全部解析到当前目录

    ython CsdAnalysis.py cocosstudio -d

    文件已经建立需要局部更新

    将目标文件解析并且将关键代码输出到控制台

    ython CsdAnalysis.py cocosstudio/begin.csd

    相关的程序

    # -*- coding:utf-8 -*-
    
    from xml.dom import minidom
    import sys
    import os
    import time
    
    def get_attr_value(node, attrname):
         return node.getAttribute(attrname) if node else ''
    
    def get_csd_name(root_node):
        property_groups = root_node.getElementsByTagName("PropertyGroup") if root_node else ''
    
        csd_names = []
    
        for item in property_groups:
            csd_names.append(get_attr_value(item, "Name"))
    
        if csd_names.__len__() == 1:
            return csd_names[0]
        else:
            return ""
    
    def get_csd_animtion_list(node):
        animtion_name_list = []
    
        anim_list = node.getElementsByTagName("AnimationInfo")
    
        for item in anim_list:
            item_name = get_attr_value(item, "Name")
            animtion_name_list.append(item_name)
    
        return animtion_name_list
    
    def get_csd_root_objects(node):
        root_objects = []
    
        nodes = node.getElementsByTagName("AbstractNodeData")
        for item in nodes:
            item_name = get_attr_value(item, "Name")
            item_type = get_attr_value(item, "ctype")
    
            anim = {}
            anim["name"] = item_name
            anim["type"] = item_type
    
            root_objects.append(anim)
    
        return root_objects
    
    def get_csd_all_objects(node):
        all_objects = []
    
        object_items = node.getElementsByTagName("AbstractNodeData")
        for item in object_items:
            print get_csd_type_2_cpp(get_attr_value(item, "ctype")) + " " + get_attr_value(item, "Name")
    
        return all_objects
    
    def get_csd_type_2_cpp(type):
        type2cpp = {"GameNodeObjectData":"cocos2d::Node *",
                    "TextObjectData":"cocos2d::ui::Text *",
                    "ButtonObjectData":"cocos2d::ui::Button *",
                    "CheckBoxObjectData":"cocos2d::ui::CheckBox *",
                    "PanelObjectData":"cocos2d::ui::Layout *",
                    "TextFieldObjectData":"cocos2d::ui::TextField *",
                    "ListViewObjectData":"cocos2d::ui::ListView *",
                    "SpriteObjectData":"cocos2d::Sprite *"}
    
        if type2cpp.has_key(type):
            return type2cpp[type]
        else:
            return type
    
    def analysis_file_h(file_name):
        datas = []
    
        if file_name.endswith(".csd") and os.path.exists(file_name):
            doc = minidom.parse(file_name)
            root = doc.documentElement
    
            csd_name = get_csd_name(root)
            csd_anims = get_csd_animtion_list(root)
            all_items = get_csd_root_objects(root)
    
            datas.append("/**************** CsdAnalysis Start ****************/")
            datas.append("cocos2d::ui::Layout * _root_layout;")
            datas.append("cocostudio::timeline::ActionTimeline * _root_action;")
            datas.append("")
            for item in all_items:
                datas.append(get_csd_type_2_cpp(item["type"]) + " " + item["name"] + ";")
    
            datas.append("/**************** CsdAnalysis End ****************/")
        else:
            print file_name + " not find or not end with .csd"
    
        return datas
    
    def analysis_file_cpp(file_name):
        datas = []
    
        if file_name.endswith(".csd") and os.path.exists(file_name):
            doc = minidom.parse(file_name)
            root = doc.documentElement
    
            csd_name = get_csd_name(root)
            csd_anims = get_csd_animtion_list(root)
            all_items = get_csd_root_objects(root)
    
    
            o_f = os.path.splitext(os.path.split(file_name)[1])[0]
    
            datas.append("/**************** CsdAnalysis Start ****************/")
            datas.append("cocos2d::Data data = cocos2d::FileUtils::getInstance()->getDataFromFile("csb/" + o_f + ".csb");")
            datas.append("auto node = cocos2d::CSLoader::createNode(data);")
            datas.append("addChild(node);")
            datas.append("")
            datas.append("_root_action = cocos2d::CSLoader::createTimeline("csb/" + o_f  + ".csb");")
            datas.append("runAction(_root_action);")
    
            datas.append("_root_layout = static_cast<cocos2d::ui::Layout *>(node->getChildByName("panel_main"));")
    
            datas.append("")
    
            for item in all_items:
                datas.append(item["name"] + " = static_cast<" + get_csd_type_2_cpp(item["type"]) + ">(seekNodeByName(_root_layout, "" + item["name"] + ""));")
    
            datas.append("")
    
            for item in all_items:
                if item["type"] == "ButtonObjectData":
                    datas.append(item["name"] + "->addClickEventListener(CC_CALLBACK_1(" + o_f + "::onButtonClick, this));")
    
            datas.append("/**************** CsdAnalysis End ****************/")
    
            datas.append("")
    
            datas.append("/**************** CsdAnalysis Action Start ****************/")
    
            for item in csd_anims:
                datas.append("//_root_action->play("" + item + "", false);")
    
            datas.append("/**************** CsdAnalysis Action End ****************/")
    
        else:
            print file_name + " not find or not end with .csd"
    
        return datas
    
    def analysis_file_to_file(file_name, out_put_path):
        print "analysis " + file_name + " to " + out_put_path
        if os.path.exists(out_put_path) == False:
            dep_path = ""
            for path in os.path.split(out_put_path):
                if(dep_path == ""):
                    dep_path = path
                else:
                    dep_path += "/" + path
    
                if dep_path != "" and os.path.exists(dep_path) == False:
                    os.mkdir(dep_path)
    
        o_f = os.path.splitext(os.path.split(file_name)[1])[0]
        h_f = os.path.join(out_put_path, o_f + ".hpp")
        c_f = os.path.join(out_put_path, o_f + ".cpp")
    
        if file_name.endswith(".csd") == False or os.path.exists(file_name) == False:
            return
    
        ISOTIMEFORMAT='%Y/%m/%d'
    
        doc = minidom.parse(file_name)
        root = doc.documentElement
    
        csd_name = get_csd_name(root)
        csd_anims = get_csd_animtion_list(root)
        all_items = get_csd_root_objects(root)
    
        file_obj = open(c_f, "w")
    
        file_obj.write("//
    ")
        file_obj.write("//  " + o_f + ".cpp
    ")
        file_obj.write("//  CsdAnalysls
    ")
        file_obj.write("//
    ")
        file_obj.write("//  Created by CsdAnalysls on " + time.strftime(ISOTIMEFORMAT, time.localtime() ) + ".
    ")
        file_obj.write("//
    ")
        file_obj.write("//
    ")
        file_obj.write("
    ")
        file_obj.write("#include "" + o_f + ".hpp"
    ")
        file_obj.write("#include "SceneRegister.hpp"
    ")
        file_obj.write("#include "InlineFunc.h"
    ")
        file_obj.write("
    ")
        file_obj.write("namespace
    ")
        file_obj.write("{
    ")
        file_obj.write("    SceneRegister<" + o_f + "> reg(#SceneIds id#);
    ")
        file_obj.write("}
    ")
        file_obj.write("
    ")
        file_obj.write("" + o_f + "::" + o_f + "()
    ")
        file_obj.write("{
    ")
        file_obj.write("    
    ")
        file_obj.write("}
    ")
        file_obj.write("
    ")
        file_obj.write("" + o_f + "::~" + o_f + "()
    ")
        file_obj.write("{
    ")
        file_obj.write("    
    ")
        file_obj.write("}
    ")
        file_obj.write("
    ")
        file_obj.write("bool " + o_f + "::init()
    ")
        file_obj.write("{
    ")
        file_obj.write("    bool success = false;
    ")
        file_obj.write("    
    ")
        file_obj.write("    do {
    ")
        file_obj.write("        if(!Scene::init())
    ")
        file_obj.write("        {
    ")
        file_obj.write("            break;
    ")
        file_obj.write("        }
    ")
        file_obj.write("        
    ")
    
        datas = analysis_file_cpp(file_name)
        for data in datas:
            file_obj.write("        " + data + "
    ")
    
        file_obj.write("        
    ")
        file_obj.write("        success = true;
    ")
        file_obj.write("    } while (0);
    ")
        file_obj.write("    
    ")
        file_obj.write("    return success;
    ")
        file_obj.write("}
    ")
        file_obj.write("
    ")
        file_obj.write("void " + o_f + "::onButtonClick(cocos2d::Ref * sender)
    ")
        file_obj.write("{
    ")
        file_obj.write("}
    ")
        file_obj.write("
    ")
        file_obj.write("
    ")
    
        file_obj.close()
    
        file_obj = open(h_f, "w")
    
        file_obj.write("//
    ")
        file_obj.write("//  " + o_f + ".hpp
    ")
        file_obj.write("//  CsdAnalysls
    ")
        file_obj.write("//
    ")
        file_obj.write("//  Created by CsdAnalysls on " + time.strftime(ISOTIMEFORMAT, time.localtime() ) + ".
    ")
        file_obj.write("//
    ")
        file_obj.write("//
    ")
        file_obj.write("
    ")
        file_obj.write("#ifndef " + o_f + "_hpp
    ")
        file_obj.write("#define " + o_f + "_hpp
    ")
        file_obj.write("
    ")
        file_obj.write("#include <stdio.h>
    ")
        file_obj.write("#include "BaseScene.hpp"
    ")
        file_obj.write("#include "ui/CocosGUI.h"
    ")
        file_obj.write("#include "editor-support/cocostudio/CocoStudio.h"
    ")
        file_obj.write("#include "cocostudio/WidgetCallBackHandlerProtocol.h"
    ")
        file_obj.write("
    ")
        file_obj.write("class " + o_f + " : public BaseScene
    ")
        file_obj.write("{   
    ")
        file_obj.write("public:
    ")
        file_obj.write("    " + o_f + "();
    ")
        file_obj.write("    virtual ~" + o_f + "();
    ")
        file_obj.write("    
    ")
        file_obj.write("    CREATE_FUNC(" + o_f + ");
    ")
        file_obj.write("    
    ")
        file_obj.write("    virtual bool init();
    ")
        file_obj.write("    virtual void onButtonClick(cocos2d::Ref * sender);
    ")
        file_obj.write("protected:
    ")
    
        datas = analysis_file_h(file_name)
        for data in datas:
            file_obj.write("    " + data + "
    ")
    
        file_obj.write("};
    ")
        file_obj.write("
    ")
        file_obj.write("#endif /* " + o_f + "_hpp */
    ")
        file_obj.write("
    ")
    
        file_obj.close()
    
    
    def analysis_file_to_control(file_name):
        if file_name.endswith(".csd") and os.path.exists(file_name):
            doc = minidom.parse(file_name)
            root = doc.documentElement
    
            csd_name = get_csd_name(root)
            csd_anims = get_csd_animtion_list(root)
            all_items = get_csd_root_objects(root)
    
    
            print "
    
    code in " + csd_name + ".h
    "
            datas = analysis_file_h(file_name)
            for data in datas:
                print data
    
            print "
    
    code in " + csd_name + ".cpp
    "
            datas = analysis_file_cpp(file_name)
            for data in datas:
                print data
        else:
            print file_name + " not find or not end with .csd"
    
    def analysis_path_to_control(path_name):
        files = os.listdir(path_name)
        for item in files:
            file = os.path.join(path_name, item)
            if (os.path.isfile(file) and file.endswith(".csd")):
                analysis_file_to_control(file)
    
    
    def output_to_file(file_name, out_put_path):
        if file_name == "":
            print "not find file_name"
        elif os.path.isfile(file_name):
            analysis_file_to_file(file_name, out_put_path)
        elif os.path.isdir(file_name):
            for item in os.listdir(file_name):
                file = os.path.join(file_name, item)
                if (os.path.isfile(file) and file.endswith(".csd")):
                    analysis_file_to_file(file, out_put_path)
        else:
            print "not find " + file_name
    
    def output_to_control(file_name):
        if file_name == "":
            print "not find file_name"
        elif os.path.isfile(file_name):
            analysis_file_to_control(file_name)
        elif os.path.isdir(file_name):
            analysis_path_to_control(file_name)
        else:
            print "not find " + file_name
    
    if __name__  == "__main__":
    
        file_name = ""
    
        is_to_file = False
        to_file_path = "out_put"
    
        i = 1
        while i < len(sys.argv):
            if(sys.argv[i] == "-d"):
                is_to_file = True
                if i + 1 < len(sys.argv):
                    file_p = sys.argv[i + 1]
                    if file_p.startswith("-") == False:
                        to_file_path = file_p
                        i += 1
            elif file_name == "" and sys.argv[i].startswith("-") == False:
                file_name = sys.argv[i]
    
            i += 1
    
        if file_name == "":
            file_name = sys.path[0]
    
        # print "is_to_file = " + str(is_to_file)
        # print "file_name = " + file_name
        # print "to_file_path = " + to_file_path
    
        if(is_to_file):
            output_to_file(os.path.abspath(file_name),os.path.abspath(to_file_path))
        else:
            output_to_control(file_name)
    

    好了,没了

  • 相关阅读:
    hdu4549 M斐波那契数列(矩阵快速幂+费马小定理)
    E. 因数串(EOJ Monthly 2020.7 Sponsored by TuSimple)
    2019春总结作业
    大一下半年学期总结
    ball小游戏
    贪吃蛇
    链接远程仓库
    git自动上传脚本及基本代码
    模板 --游戏
    飞机小游戏
  • 原文地址:https://www.cnblogs.com/anxin1225/p/5099910.html
Copyright © 2020-2023  润新知