热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CocosStudio文件解析工具CsdAnalysis

起因因为工作需要,所以需要使用CocosStudio来制作界面动画什么的。做完了发现需要找里边对象的时候会有很长一串代码,感觉不是很爽。之前写OC代码的时候可以吧程序中的对象指针跟编辑器中的对象相对容

起因

因为工作需要,所以需要使用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(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 \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 if(sys.argv[i] == "-d"):
is_to_file = True
if i + 1 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)

 

好了,没了


推荐阅读
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 本文介绍了如何利用JavaScript或jQuery来判断网页中的文本框是否处于焦点状态,以及如何检测鼠标是否悬停在指定的HTML元素上。 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 本文介绍了如何在C#中启动一个应用程序,并通过枚举窗口来获取其主窗口句柄。当使用Process类启动程序时,我们通常只能获得进程的句柄,而主窗口句柄可能为0。因此,我们需要使用API函数和回调机制来准确获取主窗口句柄。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
author-avatar
936383130_54f13e
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有