/* * GDevelop Core * Copyright 2008-2015 Florian Rival (Florian.Rival@gmail.com). All rights reserved. * This project is released under the MIT License. */ #include "GDCore/Project/Variable.h" #include "GDCore/String.h" #include #include "GDCore/Serialization/SerializerElement.h" #include "GDCore/TinyXml/tinyxml.h" using namespace std; namespace gd { /** * Get value as a double */ double Variable::GetValue() const { if (!isNumber) { stringstream ss; ss << str; ss >> value; isNumber = true; } return value; } const gd::String & Variable::GetString() const { if (isNumber) { stringstream s; s << (value); str = s.str(); isNumber = false; } return str; } bool Variable::HasChild(const gd::String & name) const { return isStructure && children.find(name) != children.end(); } /** * \brief Return the child with the specified name. * * If the variable is not a structure or has not * the specified child, an empty variable is returned. */ Variable & Variable::GetChild(const gd::String & name) { std::map::iterator it = children.find(name); if ( it != children.end() ) return it->second; isStructure = true; Variable newEmptyVariable; children[name] = newEmptyVariable; return children[name]; } /** * \brief Return the child with the specified name. * * If the variable is not a structure or has not * the specified child, an empty variable is returned. */ const Variable & Variable::GetChild(const gd::String & name) const { std::map::iterator it = children.find(name); if ( it != children.end() ) return it->second; isStructure = true; Variable newEmptyVariable; children[name] = newEmptyVariable; return children[name]; } /** * \brief Remove the child with the specified name. * * If the variable is not a structure or has not * the specified child, nothing is done. */ void Variable::RemoveChild(const gd::String & name) { if ( !isStructure ) return; children.erase(name); } void Variable::SerializeTo(SerializerElement & element) const { if (!isStructure) element.SetAttribute("value", GetString()); else { SerializerElement & childrenElement = element.AddChild("children"); childrenElement.ConsiderAsArrayOf("variable"); for (std::map::iterator i = children.begin(); i != children.end(); ++i) { SerializerElement & variableElement = childrenElement.AddChild("variable"); variableElement.SetAttribute("name", i->first); i->second.SerializeTo(variableElement); } } } void Variable::UnserializeFrom(const SerializerElement & element) { isStructure = element.HasChild("children", "Children"); if (isStructure) { const SerializerElement & childrenElement = element.GetChild("children", 0, "Children"); childrenElement.ConsiderAsArrayOf("variable", "Variable"); for (int i = 0; i < childrenElement.GetChildrenCount(); ++i) { const SerializerElement & childElement = childrenElement.GetChild(i); gd::String name = childElement.GetStringAttribute("name", "", "Name"); gd::Variable childVariable; childVariable.UnserializeFrom(childElement); children[name] = childVariable; } } else SetString(element.GetStringAttribute("value", "", "Value")); } void Variable::SaveToXml(TiXmlElement * element) const { if (!element) return; if ( !isStructure ) element->SetAttribute("Value", GetString().c_str()); else { TiXmlElement * childrenElem = new TiXmlElement( "Children" ); element->LinkEndChild( childrenElem ); for (std::map::iterator i = children.begin(); i != children.end(); ++i) { TiXmlElement * variable = new TiXmlElement( "Variable" ); childrenElem->LinkEndChild( variable ); variable->SetAttribute("Name", i->first.c_str()); i->second.SaveToXml(variable); } } } void Variable::LoadFromXml(const TiXmlElement * element) { if (!element) return; isStructure = element->FirstChildElement("Children") != NULL; if ( isStructure ) { const TiXmlElement * child = element->FirstChildElement("Children")->FirstChildElement(); while ( child ) { gd::String name = child->Attribute("Name") ? child->Attribute("Name") : ""; gd::Variable childVariable; childVariable.LoadFromXml(child); children[name] = childVariable; child = child->NextSiblingElement(); } } else if (element->Attribute("Value")) SetString(element->Attribute("Value")); } }