# HG changeset patch # User IBBoard # Date 1238258247 0 # Node ID b49372dd8afa80e12a05bdcc7b0a8bf3ce929224 # Parent 85f2b9c3609c32f1f656fae298db5d48cb26430d Re #50 - Complete loading of XML files * Load base points * Check category exists when loaded Re #10 - Refactor source code for readability * Rearrange some methods * Move storing "extra data" in to a method diff -r 85f2b9c3609c -r b49372dd8afa api/Factories/Xml/WarFoundryXmlFactory.cs --- a/api/Factories/Xml/WarFoundryXmlFactory.cs Thu Mar 26 20:49:42 2009 +0000 +++ b/api/Factories/Xml/WarFoundryXmlFactory.cs Sat Mar 28 16:37:27 2009 +0000 @@ -91,22 +91,23 @@ GameSystem system = WarFoundryLoader.GetDefault().GetGameSystem(systemID); string raceID = elem.GetAttribute("race"); Race race = WarFoundryLoader.GetDefault().GetRace(system, raceID); - string pointsString = elem.GetAttribute("maxPoints"); - int points = 0; - - try - { - points = int.Parse(pointsString); - } - catch(FormatException) - { - throw new FormatException("Attribute 'maxPoints' of army '"+name+"' was not a valid number"); - } - + int points = GetIntValueFromAttribute(elem, "maxPoints"); Army army = new Army(race, name, points, file); - extraData[army] = elem.OwnerDocument; + StoreExtraData(army, elem); return army; } + + private void StoreExtraData(WarFoundryStagedLoadingObject wfObject, XmlElement elem) + { + extraData[wfObject] = elem.OwnerDocument; + } + + public XmlDocument GetExtraData(IWarFoundryObject obj) + { + XmlDocument extra = null; + extraData.TryGetValue(obj, out extra); + return extra; + } protected override Stream GetGameSystemDataStream (ZipFile file) { @@ -125,7 +126,7 @@ string id = elem.GetAttribute("id"); string name = elem.GetAttribute("name"); GameSystem system = new GameSystem(id, name, this); - extraData[system] = elem.OwnerDocument; + StoreExtraData(system, elem); return system; } @@ -148,128 +149,8 @@ string systemID = elem.GetAttribute("system"); string name = elem.GetAttribute("name"); Race race = new Race(id, subid, name, systemID, this); - extraData[race] = elem.OwnerDocument; + StoreExtraData(race, elem); return race; - } - - public override void CompleteLoading(IWarFoundryStagedLoadObject obj) - { - LogNotifier.DebugFormat(GetType(), "Complete loading of {0} with ID {1}", obj.GetType().Name, obj.ID); - - if (obj is GameSystem) - { - CompleteLoading((GameSystem)obj); - } - else if (obj is Race) - { - CompleteLoading((Race)obj); - } - } - - public XmlNode GetExtraData(IWarFoundryObject obj) - { - XmlDocument extra = null; - extraData.TryGetValue(obj, out extra); - XmlNode node = null; - - if (extra !=null) - { - node = extra.LastChild; - } - - return node; - } - - public void CompleteLoading(GameSystem system) - { - if (system.IsFullyLoaded) - { - LogNotifier.DebugFormat(GetType(), "Object of type GameSystem with ID {0} is already fully loaded", system.ID); - return; - } - - if (system.IsLoading) - { - LogNotifier.WarnFormat(GetType(), "Object of type GameSystem with ID {0} is already being loaded", system.ID); - return; - } - - system.SetAsLoading(); - - XmlNode elem = GetExtraData(system); - LoadCategoriesForSystem(system, elem); - XmlNodeList nodeList = SelectNodes(elem, "/system:system/system:sysStatsList"); - XmlNode statsElem = nodeList.Item(0); - string defaultStatsID = ((XmlElement)statsElem).GetAttribute("defaultStats"); - LoadSystemStatsForSystem(system, elem); - system.StandardSystemStatsID = defaultStatsID; - LogNotifier.DebugFormat(GetType(), "Completed loading of GameSystem with ID {0}", system.ID); - LogNotifier.DebugFormat(GetType(), "GameSystem with ID {0} default stats: {1}", system.ID, system.StandardSystemStatsID); - system.SetAsFullyLoaded(); - } - - private void LoadCategoriesForSystem(GameSystem system, XmlNode elem) - { - WarFoundryObject tempObj; - - foreach (XmlElement cat in SelectNodes(elem, "/system:system/system:categories/cat:cat")) - { - tempObj = CreateObjectFromElement(cat); - - if (tempObj is Category) - { - system.AddCategory((Category)tempObj); - } - else - { - LogNotifier.WarnFormat(GetType(), "Object for string {0} was not of type Category", cat.OuterXml); - } - } - } - - public void CompleteLoading(Race race) - { - if (race.IsFullyLoaded) - { - LogNotifier.DebugFormat(GetType(), "Object of type Race with ID {0} is already fully loaded", race.ID); - return; - } - - if (race.IsLoading) - { - LogNotifier.WarnFormat(GetType(), "Object of type Race with ID {0} is already being loaded", race.ID); - return; - } - - race.SetAsLoading(); - - XmlNode elem = GetExtraData(race); - - foreach (XmlElement node in SelectNodes(elem, "/race:race/race:units/race:unit")) - { - UnitType type = CreateUnitTypeFromElement(node, race, race.GameSystem); - race.AddUnitType(type); - } - - foreach (XmlElement node in SelectNodes(elem, "/race:race/race:categories/cat:cat")) - { - race.AddCategory(CreateCategoryFromElement(node)); - } - - foreach (XmlElement node in SelectNodes(elem, "/race:race/race:equipment/cat:equipmentItem")) - { - EquipmentItem item = CreateEquipmentItemFromElement(node, race); - race.AddEquipmentItem(item); - } - - foreach (XmlElement node in SelectNodes(elem, "/race:race/race:abilities/cat:ability")) - { - Ability ability = CreateAbilityFromElement(node, race); - race.AddAbility(ability); - } - - race.SetAsFullyLoaded(); - LogNotifier.DebugFormat(GetType(), "Completed loading of Race with ID {0}", race.ID); } protected XmlDocument CreateXmlDocumentFromStream(Stream stream) @@ -290,7 +171,7 @@ return doc; } - /// + /// /// Lazy-getter for XML reader settings. May throw a if there is a problem with the translation schema. /// /// @@ -319,6 +200,11 @@ return settings; } + private void ValidationEventMethod(object sender, ValidationEventArgs e) + { + throw new InvalidDataException("Problem validating against schema for WarFoundry data: " + e.Exception.Message, e.Exception); + } + private void AddSchemaToCache(XmlSchemaSet cache, string xmlNamespace, string schemaLocation) { try @@ -359,39 +245,9 @@ return element.SelectNodes(xpathQuery, GetNamespaceManager()); } - private void ValidationEventMethod(object sender, ValidationEventArgs e) - { - throw new InvalidDataException("Problem validating against schema for WarFoundry data: " + e.Exception.Message, e.Exception); - } - - private WarFoundryObject CreateObjectFromElement(XmlElement elem) + private XmlNode SelectSingleNode(XmlNode element, string xpathQuery) { - WarFoundryObject obj = null; - LogNotifier.DebugFormat(GetType(), "Create object for <{0}>", elem.Name); - - if (elem.LocalName.Equals(WarFoundryXmlElementName.CATEGORY_ELEMENT.Value)) - { - LogNotifier.Debug(GetType(), "Create Category"); - obj = CreateCategoryFromElement(elem); - } - else - { - LogNotifier.Debug(GetType(), "No match"); - } - - return obj; - } - - private Category CreateCategoryFromElement(XmlElement elem) - { - string id = elem.GetAttribute("id"); - string name = elem.GetAttribute("name"); - Category cat = new Category(id, name); - cat.MaximumPercentage = GetIntValueFromAttribute(elem, "maxPercentage"); - cat.MinimumPercentage = GetIntValueFromAttribute(elem, "minPercentage"); - cat.MaximumPoints = GetIntValueFromAttribute(elem, "maxPoints"); - cat.MinimumPoints = GetIntValueFromAttribute(elem, "minPoints"); - return cat; + return element.SelectSingleNode(xpathQuery, GetNamespaceManager()); } private int GetIntValueFromAttribute(XmlElement elem, string attributeName) @@ -429,6 +285,145 @@ return doubleVal; } + + public override void CompleteLoading(IWarFoundryStagedLoadObject obj) + { + LogNotifier.DebugFormat(GetType(), "Complete loading of {0} with ID {1}", obj.GetType().Name, obj.ID); + + if (obj is GameSystem) + { + CompleteLoading((GameSystem)obj); + } + else if (obj is Race) + { + CompleteLoading((Race)obj); + } + else if (obj is Army) + { + CompleteLoading((Army) obj); + } + } + + public void CompleteLoading(GameSystem system) + { + if (system.IsFullyLoaded) + { + LogNotifier.DebugFormat(GetType(), "Object of type GameSystem with ID {0} is already fully loaded", system.ID); + return; + } + + if (system.IsLoading) + { + LogNotifier.WarnFormat(GetType(), "Object of type GameSystem with ID {0} is already being loaded", system.ID); + return; + } + + system.SetAsLoading(); + + XmlDocument extraData = GetExtraData(system); + LoadCategoriesForSystem(system, extraData); + XmlElement statsElem = SelectSingleNode(extraData, "/system:system/system:sysStatsList"); + string defaultStatsID = statsElem.GetAttribute("defaultStats"); + LoadSystemStatsForSystem(system, extraData); + system.StandardSystemStatsID = defaultStatsID; + LogNotifier.DebugFormat(GetType(), "Completed loading of GameSystem with ID {0}", system.ID); + LogNotifier.DebugFormat(GetType(), "GameSystem with ID {0} default stats: {1}", system.ID, system.StandardSystemStatsID); + system.SetAsFullyLoaded(); + } + + private void LoadCategoriesForSystem(GameSystem system, XmlNode elem) + { + WarFoundryObject tempObj; + + foreach (XmlElement cat in SelectNodes(elem, "/system:system/system:categories/cat:cat")) + { + tempObj = CreateObjectFromElement(cat); + + if (tempObj is Category) + { + system.AddCategory((Category)tempObj); + } + else + { + LogNotifier.WarnFormat(GetType(), "Object for string {0} was not of type Category", cat.OuterXml); + } + } + } + + public void CompleteLoading(Race race) + { + if (race.IsFullyLoaded) + { + LogNotifier.DebugFormat(GetType(), "Object of type Race with ID {0} is already fully loaded", race.ID); + return; + } + + if (race.IsLoading) + { + LogNotifier.WarnFormat(GetType(), "Object of type Race with ID {0} is already being loaded", race.ID); + return; + } + + race.SetAsLoading(); + + XmlDocument extraData = GetExtraData(race); + + foreach (XmlElement node in SelectNodes(extraData, "/race:race/race:units/race:unit")) + { + UnitType type = CreateUnitTypeFromElement(node, race, race.GameSystem); + race.AddUnitType(type); + } + + foreach (XmlElement node in SelectNodes(extraData, "/race:race/race:categories/cat:cat")) + { + race.AddCategory(CreateCategoryFromElement(node)); + } + + foreach (XmlElement node in SelectNodes(extraData, "/race:race/race:equipment/cat:equipmentItem")) + { + EquipmentItem item = CreateEquipmentItemFromElement(node, race); + race.AddEquipmentItem(item); + } + + foreach (XmlElement node in SelectNodes(extraData, "/race:race/race:abilities/cat:ability")) + { + Ability ability = CreateAbilityFromElement(node, race); + race.AddAbility(ability); + } + + race.SetAsFullyLoaded(); + LogNotifier.DebugFormat(GetType(), "Completed loading of Race with ID {0}", race.ID); + } + + private WarFoundryObject CreateObjectFromElement(XmlElement elem) + { + WarFoundryObject obj = null; + LogNotifier.DebugFormat(GetType(), "Create object for <{0}>", elem.Name); + + if (elem.LocalName.Equals(WarFoundryXmlElementName.CATEGORY_ELEMENT.Value)) + { + LogNotifier.Debug(GetType(), "Create Category"); + obj = CreateCategoryFromElement(elem); + } + else + { + LogNotifier.Debug(GetType(), "No match"); + } + + return obj; + } + + private Category CreateCategoryFromElement(XmlElement elem) + { + string id = elem.GetAttribute("id"); + string name = elem.GetAttribute("name"); + Category cat = new Category(id, name); + cat.MaximumPercentage = GetIntValueFromAttribute(elem, "maxPercentage"); + cat.MinimumPercentage = GetIntValueFromAttribute(elem, "minPercentage"); + cat.MaximumPoints = GetIntValueFromAttribute(elem, "maxPoints"); + cat.MinimumPoints = GetIntValueFromAttribute(elem, "minPoints"); + return cat; + } private UnitType CreateUnitTypeFromElement(XmlElement elem, Race parentRace, GameSystem system) { @@ -439,14 +434,20 @@ type.MinNumber = GetIntValueFromAttribute(elem, "minNum"); type.MaxSize = GetIntValueFromAttribute(elem, "maxSize"); type.MinSize = GetIntValueFromAttribute(elem, "minSize"); - //TODO: Add base size + type.BaseSize = GetIntValueFromAttribute(elem, "baseSize"); type.CostPerTrooper = GetIntValueFromAttribute(elem, "points"); type.BaseUnitCost = GetIntValueFromAttribute(elem, "unitPoints"); string mainCatID = elem.GetAttribute("cat"); - type.MainCategory = parentRace.GetCategory(mainCatID); - XmlNodeList nodes = SelectNodes(elem, "/race:race/race:units/race:unit/race:stats"); - XmlNode node = nodes.Item(0); - type.UnitStats = ParseUnitStats((XmlElement)node, system); + Category cat = parentRace.GetCategory(mainCatID); + + if (cat == null) + { + throw new InvalidDataException(String.Format("Attribute 'cat' of UnitType {0} (value: {1}) did not reference a valid category", id, mainCatID)); + } + + type.MainCategory = cat; + XmlElement statsElement = SelectSingleNodes(elem, "/race:race/race:units/race:unit/race:stats"); + type.UnitStats = ParseUnitStats(statsElement, system); //TODO: Add unit requirements LogNotifier.Debug(GetType(), "Loaded "+type.Name); return type;