gen_view_code.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #!/usr/bin/python
  2. import os
  3. from xml.dom import minidom
  4. from gen_view_code.class_type import class_type
  5. class class_member:
  6. def __init__(self, name, ct):
  7. self.name = name
  8. self.class_type = ct
  9. def get_plain_actors(root, res):
  10. for node in root.childNodes:
  11. if node.nodeType == node.TEXT_NODE:
  12. continue
  13. res.append(node)
  14. get_plain_actors(node, res)
  15. def save_if_changed(name, content):
  16. try:
  17. with open(name, "r") as rd:
  18. data = rd.read()
  19. if data == content:
  20. return
  21. except IOError:
  22. pass
  23. with open(name, "w") as rd:
  24. rd.write(content)
  25. mp_actor = class_type("spActor", "Actor", "Actor.h")
  26. mp_button = class_type("spButton", "Button", "Button.h")
  27. mp_text = class_type("spTextField", "TextField", "TextField.h")
  28. mp_bar = class_type("spProgressBar", "ProgressBar", "ProgressBar.h")
  29. mp_clip = class_type("spClipRectActor", "ClipRectActor", "ClipRectActor.h")
  30. mp_sprite = class_type("spSprite", "Sprite", "Sprite.h")
  31. mp_sliding = class_type("spSlidingActor", "SlidingActor", "SlidingActor.h")
  32. mp_color = class_type("spColorRectSprite", "ColorRectSprite", "ColorRectSprite.h")
  33. mp_box9sprite = class_type("spBox9Sprite", "Box9Sprite", "Box9Sprite.h")
  34. mp_view = class_type("spView", "View", "View.h")
  35. def_mappings = (mp_bar,
  36. mp_clip,
  37. mp_button,
  38. mp_text,
  39. mp_actor,
  40. mp_sprite,
  41. mp_sliding,
  42. mp_color,
  43. mp_box9sprite)
  44. def get_mapping(lst, name):
  45. for m in lst:
  46. if m.className == name:
  47. return m
  48. return None
  49. user_mp = None
  50. def find_mapping(name, classes):
  51. if user_mp:
  52. mp = get_mapping(user_mp, name)
  53. if mp:
  54. return mp
  55. mp = get_mapping(def_mappings, name)
  56. if mp:
  57. return mp
  58. mp = get_mapping(classes, name)
  59. if mp:
  60. return mp
  61. return None
  62. def gen_classes(nodes, ct, classes):
  63. classes.add(ct)
  64. for child in nodes:
  65. class_mapping = mp_actor
  66. member = child.attrib["member"]
  67. res_id = ""
  68. if "id" in child.attrib:
  69. res_id = child.attrib["id"]
  70. if not res_id:
  71. res_id = os.path.splitext(child.attrib["file"])[0]
  72. class_mapping = mp_sprite
  73. if "ref" in child.attrib:
  74. class_mapping = mp_sprite
  75. try:
  76. #print res_id
  77. class_name = child.attrib["class"]
  78. class_mapping = find_mapping(class_name, classes)
  79. if not class_mapping:
  80. if class_name.endswith("<"):
  81. class_name = class_name.rstrip("<")
  82. class_mapping = class_type(class_name, "sp" + class_name, class_name, class_name + ".h", ns = "", member = res_id, parent = mp_sprite, generated=True)
  83. gen_classes(nodes, class_mapping, classes)
  84. elif class_name.startswith(">"):
  85. return
  86. else:
  87. class_mapping = class_type(class_name, "sp" + class_name, class_name, class_name + ".h", ns = "")
  88. except KeyError:
  89. pass
  90. classes.add(class_mapping)
  91. index = child.attrib["order"]
  92. ct.members.append(class_member(member, class_mapping, res_id))
  93. def gen2(xml_res_file, dest_folder, mappings):
  94. global user_mp
  95. user_mp = mappings
  96. import os
  97. from sets import Set
  98. from jinja2 import Environment, FileSystemLoader
  99. if not os.path.exists(dest_folder):
  100. os.makedirs(dest_folder)
  101. xml_res_file = os.path.normpath(xml_res_file)
  102. xml_res_file = xml_res_file.replace("\\", "/")
  103. from os import path
  104. doc = minidom.parse(xml_res_file)
  105. root = doc.documentElement
  106. folder = os.path.split(__file__)[0] + "/gen_view_code/templates"
  107. env = Environment(trim_blocks = True, lstrip_blocks = True, loader = FileSystemLoader(folder))
  108. class_h_template = env.get_template("class.h")
  109. class_cpp_template = env.get_template("class.cpp")
  110. import StringIO
  111. classes_node = root.getElementsByTagName("class")[0]
  112. classes = Set()
  113. for class_node in classes_node.childNodes:
  114. if class_node.nodeType == class_node.TEXT_NODE:
  115. continue
  116. res = []
  117. get_plain_actors(class_node, res)
  118. class_name = class_node.getAttribute("class")
  119. local_classes = Set()
  120. parent = find_mapping(class_node.nodeName, classes)
  121. custom_class = class_type("sp" + class_name, class_name, class_name + ".h", ns = "", member = "", parent = parent, generated=True)
  122. classes.add(custom_class)
  123. local_classes.add(custom_class)
  124. header = StringIO.StringIO()
  125. cpp = StringIO.StringIO()
  126. for node in res:
  127. name = node.getAttribute("name")
  128. ct = find_mapping(node.nodeName, classes)
  129. custom_class.members.append(class_member(name, ct))
  130. classes.add(ct)
  131. local_classes.add(ct)
  132. cls = list(local_classes)
  133. q = 0
  134. cls.sort(cmp = lambda a, b: cmp(b.ns, a.ns) or cmp(b.primary, a.primary) or cmp(a.className, b.className))
  135. includes = [inc for inc in cls if inc.header]
  136. args = {"types":cls,
  137. "ct":custom_class,
  138. "includes":includes}
  139. header.write(env.get_template("header.h").render(**args))
  140. cpp.write(env.get_template("header.cpp").render(**args))
  141. args = {"ct":custom_class,
  142. "xml":xml_res_file,
  143. "members":custom_class.members}
  144. header.write(class_h_template.render(**args))
  145. cpp.write(class_cpp_template.render(**args))
  146. header_name = class_name + ".h"
  147. cpp_name = class_name + ".cpp"
  148. gen_code = class_node.getAttribute("gencode")
  149. if gen_code == "false":
  150. continue
  151. save_if_changed(dest_folder + header_name, header.getvalue())
  152. save_if_changed(dest_folder + cpp_name, cpp.getvalue())
  153. if __name__ == "__main__":
  154. import argparse
  155. parser = argparse.ArgumentParser(description="generates h/cpp files from oxygine xml")
  156. parser.add_argument("xml", help = "xml file to process")
  157. parser.add_argument("-d", "--dest", help = "destination folder for generated classes", default = ".")
  158. """
  159. parser.add_argument("-mw", "--max_width", help = "max atlas width", type=int, default = 2048)
  160. parser.add_argument("-mh", "--max_height", help = "max atlas height", type=int, default = 2048)
  161. parser.add_argument("-s", "--scale", help = "scale factor", type=float, default = 1.0)
  162. parser.add_argument("-r", "--resize", help = "downscale/upscale by scale factor", action="store_true", default = False)
  163. parser.add_argument("-us", "--upscale", help = "allow upscale. good option for very HD displays with texture compression", action="store_true", default = False)
  164. parser.add_argument("-c", "--compression", help = "type of images compression. default is pure rgba8888 packed to png",
  165. choices = ["pvrtc", "etc1", "no"], default = "")
  166. parser.add_argument("-np", "--nopng", help = "store images without packing to png",
  167. action="store_true", default = False)
  168. parser.add_argument("-q", "--quality", help = "select quality to compressed textures",
  169. choices = ["default", "fast", "best"], default = "default")
  170. parser.add_argument("-d", "--dither", help = "added dithering to compressed textures (pvr option)", action="store_true", default = False)
  171. #parser.add_argument("--android_sdk", help = "path to android sdk", default = "")
  172. parser.add_argument("-debug", "--debug", help = "debug mode", action="store_true", default = False)
  173. parser.add_argument("-w", "--warnings", help = "show warnings", action="store_true", default = False)
  174. parser.add_argument("-v", "--verbosity", help = "verbosity level. 1 - only errors, 2 - normal. Default value is 2", type=int, default = 2)
  175. parser.add_argument("--md5", help = "generates md5 lists for some special files", type=bool, default = False)
  176. gen2(".", "test.xml", "./", "Qwe", None)
  177. """
  178. args = parser.parse_args()
  179. gen2(args.xml, args.dest + "/", None)