#include "XmlElement.h" #include "../Exception.h" using namespace std; void xml::XmlElement::LoadElementCache() { TiXmlElement *el = 0; TiXmlElement *subel = 0; XmlTag * aTag = 0; Statsmap tmpStatsmap; Stringmap tmpStringmap; ResetCache(); // All elements have a mandatory component located at componet[0] Component * aComponent = new Component(); _components.push_back(aComponent); // Check Element type try { IdElementType(); } catch(Exception e) { e.PrintError(); exit(-1); } // Look at all the tags inside this Element block for(el = _tag->FirstChildElement(); el; el = el->NextSiblingElement()) { try { // Check if this tag is a basic tag all Elements have if(IdentifyBasic(el)) continue; // Next tag in the Element block // If no basic tag has been found this tag has to be a configurable Element tag aTag = IdentifyElementXml(el->ValueStr()); // int values if(aTag->GetType() == TAG_INT) { pair< Statsmap::iterator, bool > sucess = make_pair(tmpStatsmap.begin(), true); sucess = tmpStatsmap.insert(std::make_pair(el->ValueStr(), new StatisticalValue(atoi(el->GetText())))); if(!sucess.second) throw Exception("XmlElement::LoadElementCache","Failed to insert value, stat, \ probably duplicate tag: " + el->ValueStr()); } // string values else if(aTag->GetType() == TAG_STRING) { pair< Stringmap::iterator, bool > sucess = make_pair(tmpStringmap.begin(), true); sucess = tmpStringmap.insert(std::make_pair(el->ValueStr(), (std::string)el->GetText())); if(!sucess.second) throw Exception("XmlElement::LoadElementCache","Failed to insert value, string, \ probably duplicate tag: " + el->ValueStr()); } // Subtag that should load another component else if(aTag->GetType() == TAG_BASE) { TiXmlElement *tmpel = el; Statsmap tmpsubStatsmap; Stringmap tmpsubStringmap; // Save the old parent group XmlTag * tmpXmlTagGroup = _XmlTagGroup; // Set new group to look for tags _XmlTagGroup = aTag; // If tag is missing children then this is a file link, open new file and load from there instead if(!el->FirstChildElement()) { SubFile((std::string)el->GetText()); tmpel = _tag; } // Read all child tags an add values to there maps for(subel = tmpel->FirstChildElement(); subel; subel = subel->NextSiblingElement()) { // Load all tags inside subtag (the component) aTag = IdentifyElementXml(subel->ValueStr()); if(aTag->GetType() == TAG_INT) { pair< Statsmap::iterator, bool > sucess = make_pair(tmpsubStatsmap.begin(), true); sucess = tmpsubStatsmap.insert(std::make_pair(subel->ValueStr(), new StatisticalValue(atoi(subel->GetText())))); // Insert failed probebly duplicate tags if(!sucess.second) throw Exception("XmlElement::LoadElementCache","Failed to insert value, \ subtag stat, probably duplicate tag: " + subel->ValueStr()); } else if(aTag->GetType() == TAG_STRING) { pair< Stringmap::iterator, bool > sucess = make_pair(tmpsubStringmap.begin(), true); sucess = tmpsubStringmap.insert(std::make_pair(subel->ValueStr(), (std::string)subel->GetText())); if(!sucess.second) throw Exception("XmlElement::LoadElementCache","Failed to insert value, \ subtag string, probably duplicate tag: " + subel->ValueStr()); } } // if we have used an sub file we can close it now if(!el->FirstChildElement()) UnSubFile(); // All done maps have been fully loaded create component and add to map Component * aSubComp = new Component(tmpsubStatsmap,tmpsubStringmap); _components.push_back(aSubComp); // Restore tag group so parent can continue loading _XmlTagGroup = tmpXmlTagGroup; } } catch(Exception e) { e.PrintError(); exit(-1); } } // All tags for this element have been checked update the mantatory first component[0] _components[0]->AddStats(tmpStatsmap); _components[0]->AddStrings(tmpStringmap); // Everything is ready create new elemnt, base is later return when requested if(!_type.compare("unit")) { _unit = new Unit(_rowsize, _colsize, _views, _components); _unit->SetFaction(_faction); _unit->SetDirection(_direction); _base = _unit; } else if(!_type.compare("building")) { _build = new Building(_rowsize, _colsize, _views, _components); _build->SetFaction(_faction); _build->SetDirection(_direction); _base = _build; } else if(!_type.compare("sceneelement")) { _scene = new SceneElement(_rowsize, _colsize, _views, _components); _scene->SetDirection(_direction); _base = _scene; } else if(!_type.compare("terrainelement")) { _terra = new TerrainElement(_rowsize, _colsize, _views, _components); _terra->SetDirection(_direction); _base = _terra; } else throw Exception("XmlElement::LoadElementCache()","Unknown Element type: " + _type); } bool xml::XmlElement::NextElement() { _tag = _tag->NextSiblingElement(); // Continue loading while there are more Element in file if(_tag) { try { ResetCache(); LoadElementCache(); } catch(Exception e) { e.PrintError(); exit(-1); } return true; } return false; } void xml::XmlElement::IdElementType() { // Search in XmlTag map after any entry with value XmlTagmap::iterator it = _element_tags.find(_tag->ValueStr()); if(it != _element_tags.end()) { //found a known type, make element same type _type = _tag->ValueStr(); } else // No known type found throw Exception("XmlElement::IdElementType()","Unknown XML tag: " + _tag->ValueStr()); // If the tag does not have a child, then it is a path to a new XML file if(!_tag->FirstChildElement()) SubFile(_tag->GetText()); // Set _XmlTagGroup to found XmlTag from _element_tags, These tags will be used for this XML block _XmlTagGroup = (*it).second; } xml::XmlTag * xml::XmlElement::IdentifyElementXml(std::string ElXml) { // Check if this Element type has this specific tag XmlTag * aTag = _XmlTagGroup->GetSub(ElXml); if(!aTag) throw Exception("XmlElement::IdentifyElementXml","Unknown XML tag: " + ElXml); return aTag; }