起因

因为工作需要,所以需要使用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("//\n")
file_obj.write("// " + o_f + ".cpp\n")
file_obj.write("// CsdAnalysls\n")
file_obj.write("//\n")
file_obj.write("// Created by CsdAnalysls on " + time.strftime(ISOTIMEFORMAT, time.localtime() ) + ".\n")
file_obj.write("//\n")
file_obj.write("//\n")
file_obj.write("\n")
file_obj.write("#include \"" + o_f + ".hpp\"\n")
file_obj.write("#include \"SceneRegister.hpp\"\n")
file_obj.write("#include \"InlineFunc.h\"\n")
file_obj.write("\n")
file_obj.write("namespace\n")
file_obj.write("{\n")
file_obj.write(" SceneRegister<" + o_f + "> reg(#SceneIds id#);\n")
file_obj.write("}\n")
file_obj.write("\n")
file_obj.write("" + o_f + "::" + o_f + "()\n")
file_obj.write("{\n")
file_obj.write(" \n")
file_obj.write("}\n")
file_obj.write("\n")
file_obj.write("" + o_f + "::~" + o_f + "()\n")
file_obj.write("{\n")
file_obj.write(" \n")
file_obj.write("}\n")
file_obj.write("\n")
file_obj.write("bool " + o_f + "::init()\n")
file_obj.write("{\n")
file_obj.write(" bool success = false;\n")
file_obj.write(" \n")
file_obj.write(" do {\n")
file_obj.write(" if(!Scene::init())\n")
file_obj.write(" {\n")
file_obj.write(" break;\n")
file_obj.write(" }\n")
file_obj.write(" \n") datas = analysis_file_cpp(file_name)
for data in datas:
file_obj.write(" " + data + "\n") file_obj.write(" \n")
file_obj.write(" success = true;\n")
file_obj.write(" } while (0);\n")
file_obj.write(" \n")
file_obj.write(" return success;\n")
file_obj.write("}\n")
file_obj.write("\n")
file_obj.write("void " + o_f + "::onButtonClick(cocos2d::Ref * sender)\n")
file_obj.write("{\n")
file_obj.write("}\n")
file_obj.write("\n")
file_obj.write("\n") file_obj.close() file_obj = open(h_f, "w") file_obj.write("//\n")
file_obj.write("// " + o_f + ".hpp\n")
file_obj.write("// CsdAnalysls\n")
file_obj.write("//\n")
file_obj.write("// Created by CsdAnalysls on " + time.strftime(ISOTIMEFORMAT, time.localtime() ) + ".\n")
file_obj.write("//\n")
file_obj.write("//\n")
file_obj.write("\n")
file_obj.write("#ifndef " + o_f + "_hpp\n")
file_obj.write("#define " + o_f + "_hpp\n")
file_obj.write("\n")
file_obj.write("#include <stdio.h>\n")
file_obj.write("#include \"BaseScene.hpp\"\n")
file_obj.write("#include \"ui/CocosGUI.h\"\n")
file_obj.write("#include \"editor-support/cocostudio/CocoStudio.h\"\n")
file_obj.write("#include \"cocostudio/WidgetCallBackHandlerProtocol.h\"\n")
file_obj.write("\n")
file_obj.write("class " + o_f + " : public BaseScene\n")
file_obj.write("{ \n")
file_obj.write("public:\n")
file_obj.write(" " + o_f + "();\n")
file_obj.write(" virtual ~" + o_f + "();\n")
file_obj.write(" \n")
file_obj.write(" CREATE_FUNC(" + o_f + ");\n")
file_obj.write(" \n")
file_obj.write(" virtual bool init();\n")
file_obj.write(" virtual void onButtonClick(cocos2d::Ref * sender);\n")
file_obj.write("protected:\n") datas = analysis_file_h(file_name)
for data in datas:
file_obj.write(" " + data + "\n") file_obj.write("};\n")
file_obj.write("\n")
file_obj.write("#endif /* " + o_f + "_hpp */\n")
file_obj.write("\n") 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 "\n\ncode in " + csd_name + ".h\n"
datas = analysis_file_h(file_name)
for data in datas:
print data print "\n\ncode in " + csd_name + ".cpp\n"
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)

好了,没了

CocosStudio文件解析工具CsdAnalysis的更多相关文章

  1. (转)AVI文件格式解析+AVI文件解析工具

    AVI文件解析工具下载地址:http://download.csdn.net/detail/zjq634359531/7556659 AVI(Audio Video Interleaved的缩写)是一 ...

  2. CSV文件解析工具

    package com.common.util; import java.io.BufferedReader; import java.io.FileInputStream; import java. ...

  3. 通过正则表达式实现简单xml文件解析

    这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...

  4. Golang Json文件解析为结构体工具-json2go

    代码地址如下:http://www.demodashi.com/demo/14946.html 概述 json2go是一个基于Golang开发的轻量json文件解析.转换命令行工具,目前支持转换输出到 ...

  5. HtmlParse:一款超轻量级的HTML文件解析和爬取工具

    HtmlParse 是一款基于windwos平台的HTML文档解析工具,可快速构建DOM树,从而轻松实现网页元素的爬取工作.DOM树就是一个HTML文档的节点树,每个节点由:标签(Tag).属性(At ...

  6. 文件处理工具 gif合成工具 文件后缀批量添加工具 文件夹搜索工具 重复文件查找工具 网页图片解析下载工具等

    以下都是一些简单的免费分享的工具,技术支持群:592132877,提供定制化服务开发. Gif动图合成工具 主要功能是扫描指定的文件夹里的所有zip文件,然后提取Zip文件中的图片,并合成一张gif图 ...

  7. 【微信】微信小程序 微信开发工具中新创建的json文件,编译报错VM1781:2 pages/module/module.json 文件解析错误 SyntaxError: Unexpected end of JSON input

    如果新创建报错:编译报错VM1781:2 pages/module/module.json 文件解析错误  SyntaxError: Unexpected end of JSON input 解决方法 ...

  8. Java XML解析工具 dom4j介绍及使用实例

    Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...

  9. phpcms V9 首页模板文件解析

    在了解了<phpcms V9 URL访问解析>之后,我们已经知道首页最终执行的是content模块下index控制器的init方法. 下面, 我们逐步分析过程如下: 第一.首页默认执行的是 ...

随机推荐

  1. window下搭建c开发环境(GNU环境的安装)

    一.在windows平台上安装GNU环境 windows操作系统不自带GNU环境,如果需要开发跨平台的C语言程序,那么需要给windows安装GNU环境 windows下的两款GNU环境:MinGW和 ...

  2. 在.NET Core中遭遇循环依赖问题"A circular dependency was detected"

    今天在将一个项目迁移至ASP.NET Core的过程中遭遇一个循环依赖问题,错误信息如下: A circular dependency was detected for the service of ...

  3. JSON and Microsoft Technologies(翻译)

    本文翻译CodeProject(链接)上的一篇文章,文章对JSON的概念以及它在微软一些技术中的应用起到了非常好的扫盲作用,总结得非常好,适合初学者. 目录 介绍 什么是JavaScript对象? 实 ...

  4. [开源]基于WPF实现的Gif图片分割器,提取GIf图片中的每一帧

    不知不觉又半个月没有更新博客了,今天终于抽出点时间,来分享一下前段时间的成果. 在网上,我们经常看到各种各样的图片,尤其是GIF图片的动态效果,让整个网站更加富有表现力!有时候,我们看到一些比较好看的 ...

  5. C#设计模式之工厂

    IronMan之工厂 前言 实用为主,学一些用得到的技术更能在如今的社会里保命. 虽然在日常的工作中设计模式不是经常的用到,但是呢,学习它只有好处没有坏处. 设计模式像是一种“标签”,它是代码编写者思 ...

  6. I/O重定向的原理和实现

    在Unix系统中,每个进程都有STDIN.STDOUT和STDERR这3种标准I/O,它们是程序最通用的输入输出方式.几乎所有语言都有相应的标准I/O函数,比如,C语言可以通过scanf从终端输入字符 ...

  7. 【VC++技术杂谈001】音频技术之调节音量及设置静音

    本文主要介绍如何使用混音器Mixer API函数实现系统音量调节,以及设置静音. 1.混音器的作用及结构 1.1混音器的作用 声卡(音频卡)是计算机进行声音处理的适配器,具有三个基本功能: (1)音乐 ...

  8. Html5 绘制五星红旗

    Html5+JavaScript 在Canvas上绘制五星红旗,具体思路如下图所示: 绘制思路在上图中已有说明,具体代码如下: <script type="text/javascrip ...

  9. C#设计模式-享元模式

    在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非常严重,然 ...

  10. 谈谈php里的IOC控制反转,DI依赖注入

    理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(In ...