Advertisement
Guest User

xml deserializer

a guest
Nov 23rd, 2020
469
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. extends XMLParser
  2. class_name XmlDeserializer
  3.  
  4. export var tag_name : String setget , get_tag_name
  5. export var node_type: String setget, get_node_type_string
  6.  
  7. func get_tag_name():
  8.     if get_node_type() == XMLParser.NODE_TEXT:
  9.         return "[Text]"
  10.     return get_node_name()
  11.  
  12. var err = OK
  13. var current_file_name
  14. func read_start_element() -> String:
  15.     if is_empty() and get_node_type() == XMLParser.NODE_ELEMENT:
  16.         return ""
  17.     err = read()
  18.     while err == OK:
  19.         match get_node_type():
  20.             XMLParser.NODE_ELEMENT:
  21.                 return get_node_name()
  22.             XMLParser.NODE_ELEMENT_END:
  23.                 return ""
  24.             _:
  25.                 pass
  26.         err = read()
  27.     return ""
  28.  
  29. func skip():
  30.     if is_empty():
  31.         err = read()
  32.     else:
  33.         skip_section()
  34.  
  35. func attr(name) -> String:
  36.     return get_named_attribute_value(name)
  37.  
  38. func init_attribute(node, name, xml_name = null):
  39.     if not xml_name:
  40.         xml_name = name
  41.     var old_value = node.get_indexed(name)
  42.     var value = read_typed_value(typeof(old_value), xml_name)
  43.     assert(value != null)
  44.     node.set_indexed(name, value)
  45.  
  46. func read_typed_value(type, attribute):
  47.     var xml_val = get_named_attribute_value(attribute)
  48.     match type:
  49.         TYPE_BOOL:
  50.             return xml_val.to_lower() == "true"
  51.         TYPE_INT:
  52.             return xml_val.to_int()
  53.         TYPE_REAL:
  54.             return xml_val.to_float()
  55.         TYPE_STRING:
  56.             return xml_val.xml_unescape()
  57.         _:
  58.             if xml_val == "null":
  59.                 return null
  60.             else:
  61.                 error("Cannot initialize property: Unknown type: " + String(type))
  62.                 return null
  63.  
  64. func init_property(node, prop_name = null):
  65.     assert(get_node_type() == XMLParser.NODE_ELEMENT)
  66.     assert(get_node_name() == "property")
  67.     prop_name = Util.opt(prop_name, attr("name"))
  68.     var old_value = node.get_indexed(prop_name)
  69.     var value
  70.     if has_attribute("value"):
  71.         assert(old_value != null)
  72.         value = read_typed_value(typeof(old_value), "value")
  73.         assert(value != null)
  74.         skip()
  75.     else:
  76.         value = read_value()
  77.         assert(value != null)
  78.         skip()
  79.  
  80.     node.set(prop_name, value)
  81.  
  82. func read_value():
  83.     if not read_start_element() == "value":
  84.         error("Malformed property tag")
  85.         return null
  86.     var value = parse_value()
  87.     return value
  88.  
  89. func parse_value():
  90.     match attr("type"):
  91.         "Color":
  92.             var value = Color(attr("r").to_float(), attr("g").to_float(), attr("b").to_float(), attr("a").to_float())
  93.             skip()
  94.             return value
  95.         "Vector2":
  96.             var value = Vector2(attr("x").to_float(), attr("y").to_float())
  97.             skip()
  98.             return value
  99.         "Resource":
  100.             var value = load(attr("value"))
  101.             skip()
  102.             return value
  103.         "Rect2":
  104.             var value = Rect2(attr("x").to_float(), attr("y").to_float(), attr("w").to_float(), attr("h").to_float())
  105.             skip()
  106.             return value
  107.         "int":
  108.             var value = attr("value").to_int()
  109.             skip()
  110.             return value
  111.         "real":
  112.             var value = attr("value").to_float()
  113.             skip()
  114.             return value
  115.         "bool":
  116.             var value =  attr("value").to_lower() == "true"
  117.             skip()
  118.             return value
  119.         "string":
  120.             var value =  attr("value").xml_unescape()
  121.             skip()
  122.             return value
  123.         "Array":
  124.             var res =[]
  125.             var element = read_start_element()
  126.             while element == "value":
  127.                 res.append(parse_value())
  128.                 element = read_start_element()
  129.             return res
  130.  
  131. func read_text():
  132.     assert(get_node_type() == NODE_ELEMENT)
  133.     err = read()
  134.     var text = get_node_data()
  135.     err = read()
  136.     assert(get_node_type() == NODE_ELEMENT_END)
  137.     return text
  138.  
  139. func get_node_type_string():
  140.     match get_node_type():
  141.         NODE_NONE: return "NONE"
  142.         NODE_ELEMENT: return "ELEMENT"
  143.         NODE_ELEMENT_END: return "END_ELEMENT"
  144.         NODE_TEXT: return "TEXT"
  145.         NODE_COMMENT: return "COMMENT"
  146.         NODE_CDATA: return "CDATA"
  147.         NODE_UNKNOWN: return "UNKNOWN"
  148.  
  149.  
  150. func read_world(file_name):
  151.     current_file_name = file_name
  152.     err = open(file_name)
  153.     if err != OK:
  154.         return
  155.  
  156.     err = read()
  157.     var root = read_start_element()
  158.     if root != "save_game":
  159.         return null
  160.     if not read_start_element() == "world":
  161.         return null
  162.     var world = load("res://world.tscn").instance()
  163.     Debug.dump_tree(world)
  164.     world.deserialize(self)
  165.  
  166.     return world
  167.  
  168.  
  169. func deserialize_children(node: Object, prefix="deserialize_"):
  170.     if is_empty():
  171.         skip()
  172.         return
  173.     assert(get_node_type() == NODE_ELEMENT)
  174.     var tag = get_node_name()
  175.     var element = read_start_element()
  176.     while element:
  177.         node.call(prefix+element, self)
  178.         element = read_start_element()
  179.     assert(get_node_type() == NODE_ELEMENT_END and get_node_name() == tag or is_empty())
  180.  
  181. func trace(msg = ""):
  182.     print("%s:%d %s:%s %s" % [current_file_name, get_current_line(), get_node_type_string(), get_node_name(), msg])
  183.  
  184. func warning(text):
  185.     push_warning("%s(%d): %s" % [current_file_name, get_current_line(), text])
  186.  
  187. func error(text):
  188.     push_error("%s(%d): %s" % [current_file_name, get_current_line(), text])
  189.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement