Mercurial > repos > IBBoard.WarFoundry.API
changeset 265:6fe0cb1bf74f
Re #279: Create composite limit
* Change uses of "AbstractLimit" to "ILimit" as composites don't have a number themselves and can't extend AbstractLimit
* Refactor limit parsing code out into a separate class
* Use grouping to allow for re-use of limit types in schema
* Add min and max composite limits in schema
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 05 Jun 2010 15:36:04 +0000 |
parents | 68af2cd41e2f |
children | a3c1bf57fd3f |
files | IBBoard.WarFoundry.API.csproj api/Factories/Xml/WarFoundryXmlLimitParser.cs api/Factories/Xml/WarFoundryXmlRaceFactory.cs api/Objects/Unit.cs api/Objects/UnitEquipmentItem.cs api/Objects/UnitType.cs api/Util/UnitEquipmentUtil.cs schemas/warfoundry-core.xsd |
diffstat | 8 files changed, 150 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- a/IBBoard.WarFoundry.API.csproj Sat Jun 05 14:00:28 2010 +0000 +++ b/IBBoard.WarFoundry.API.csproj Sat Jun 05 15:36:04 2010 +0000 @@ -156,6 +156,7 @@ <Compile Include="api\AbstractWarFoundryLoader.cs" /> <Compile Include="api\DefaultWarFoundryLoader.cs" /> <Compile Include="api\Objects\UnitMemberType.cs" /> + <Compile Include="api\Factories\Xml\WarFoundryXmlLimitParser.cs" /> </ItemGroup> <ItemGroup> <Content Include="libs\ICSharpCode.SharpZipLib.dll" />
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/api/Factories/Xml/WarFoundryXmlLimitParser.cs Sat Jun 05 15:36:04 2010 +0000 @@ -0,0 +1,94 @@ +// This file (WarFoundryXmlLimitParser.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2010 IBBoard +// +// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license. +using System.Collections.Generic; +using System.Xml; +using IBBoard.Limits; +using IBBoard.Xml; + +namespace IBBoard.WarFoundry.API.Factories.Xml +{ + public class WarFoundryXmlLimitParser + { + public ILimit GetMinLimit(XmlElement elem) + { + XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "race:minLimit/*[1]"); + return GetLimitFromElement(limitElem); + } + + public ILimit GetMaxLimit(XmlElement equipSlot) + { + XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(equipSlot, "race:maxLimit/*[1]"); + return GetLimitFromElement(limitElem); + } + + public ILimit GetLimitFromElement(XmlElement limitElem) + { + ILimit limit = null; + + if (limitElem != null) + { + switch (limitElem.LocalName) + { + case "percentageLimit": + double limitPercent = XmlTools.GetDoubleValueFromAttribute(limitElem, "limit"); + bool roundUp = limitElem.GetAttribute("round").Equals("up"); + limit = new SimpleRoundedPercentageLimit(limitPercent, roundUp); + break; + case "sizeConstrainedLimit": + limit = new NumericSizeConstrainedLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); + break; + case "absoluteLimit": + limit = new AbsoluteNumericLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); + break; + case "unitSizeLimit": + limit = new SimpleRoundedPercentageLimit(100); + break; + case "compositeMaxLimit": + ICollection<ILimit> maxSubLimits = GetSubLimits(limitElem); + limit = new CompositeMaximumLimit(maxSubLimits); + break; + case "compositeMinLimit": + ICollection<ILimit> minSubLimits = GetSubLimits(limitElem); + limit = new CompositeMaximumLimit(minSubLimits); + break; + default: + //TODO: Warn of missing handler for when we've extended the limit list + break; + } + } + + return limit; + } + + private ICollection<ILimit> GetSubLimits(XmlElement limitElem) + { + System.Console.WriteLine("Getting sub limits"); + XmlNodeList subLimitNodes = GetSubLimitElements(limitElem); + ICollection<ILimit> limits = new List<ILimit>(); + + foreach (XmlNode node in subLimitNodes) + { + System.Console.WriteLine("Getting limit for "+node.LocalName); + if (node is XmlElement) + { + ILimit limit = GetLimitFromElement((XmlElement)node); + System.Console.WriteLine("Limit was "+(limit == null ? "null" : limit.GetType().Name)); + if (limit != null) + { + limits.Add(limit); + } + } + } + + return limits; + } + + private XmlNodeList GetSubLimitElements(XmlElement limitElem) + { + //"core:percentageLimit | core:sizeConstrainedLimit | core:absoluteLimit | core:unitSizeLimit | core:compositeMaxLimit | core:compositeMinLimit" + return WarFoundryXmlFactoryUtils.SelectNodes(limitElem, "core:absolueLimit"); + } + } +} +
--- a/api/Factories/Xml/WarFoundryXmlRaceFactory.cs Sat Jun 05 14:00:28 2010 +0000 +++ b/api/Factories/Xml/WarFoundryXmlRaceFactory.cs Sat Jun 05 15:36:04 2010 +0000 @@ -21,6 +21,7 @@ public class WarFoundryXmlRaceFactory : AbstractStagedLoadedSubFactory { private Dictionary<Race, XmlDocument> extraData = new Dictionary<Race, XmlDocument>(); + private WarFoundryXmlLimitParser limitParser = new WarFoundryXmlLimitParser(); public WarFoundryXmlRaceFactory(WarFoundryXmlFactory factory) : base (factory) { @@ -212,54 +213,26 @@ } } - private static void LoadEquipmentSlotForUnitType (UnitType type, XmlElement equipSlot) + private void LoadEquipmentSlotForUnitType(UnitType type, XmlElement equipSlot) { - string slotName = equipSlot.GetAttribute ("name"); - AbstractLimit limit = GetMaxLimit (equipSlot); + string slotName = equipSlot.GetAttribute("name"); + ILimit limit = GetMaxLimit(equipSlot); - if (limit!=null) + if (limit != null) { - type.AddEquipmentSlot (slotName, limit); + type.AddEquipmentSlot(slotName, limit); } } - - private static AbstractLimit GetMaxLimit (XmlElement equipSlot) - { - XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(equipSlot, "race:maxLimit/*[1]"); - return GetLimitFromElement(limitElem); - } - private static AbstractLimit GetLimitFromElement(XmlElement limitElem) + private ILimit GetMinLimit(XmlElement elem) { - AbstractLimit limit = null; - - if (limitElem != null) - { - switch (limitElem.LocalName) - { - case "percentageLimit": - double limitPercent = XmlTools.GetDoubleValueFromAttribute(limitElem, "limit"); - bool roundUp = limitElem.GetAttribute("round").Equals("up"); - limit = new SimpleRoundedPercentageLimit(limitPercent, roundUp); - break; - case "sizeConstrainedLimit": - limit = new NumericSizeConstrainedLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); - break; - case "absoluteLimit": - limit = new AbsoluteNumericLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); - break; - case "unitSizeLimit": - limit = new SimpleRoundedPercentageLimit(100); - break; - default: - //TODO: Warn of missing handler for when we've extended the limit list - break; - } - } - - return limit; + return limitParser.GetMinLimit(elem); } + private ILimit GetMaxLimit(XmlElement elem) + { + return limitParser.GetMaxLimit(elem); + } private void LoadEquipmentForUnitType(XmlElement elem, UnitType type) { @@ -311,7 +284,7 @@ } } - AbstractLimit limit = GetMaxLimit(equip); + ILimit limit = GetMaxLimit(equip); if (limit != null) { @@ -360,12 +333,6 @@ } } } - - private static AbstractLimit GetMinLimit(XmlElement elem) - { - XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(elem, "race:minLimit/*[1]"); - return GetLimitFromElement(limitElem); - } private void LoadAbilitiesForUnitType(XmlElement elem, UnitType type) {
--- a/api/Objects/Unit.cs Sat Jun 05 14:00:28 2010 +0000 +++ b/api/Objects/Unit.cs Sat Jun 05 15:36:04 2010 +0000 @@ -88,7 +88,7 @@ { if (CanEquipWithItem(unitEquip)) { - AbstractLimit minLimit = unitEquip.MinLimit; + ILimit minLimit = unitEquip.MinLimit; if (minLimit is IPercentageLimit) {
--- a/api/Objects/UnitEquipmentItem.cs Sat Jun 05 14:00:28 2010 +0000 +++ b/api/Objects/UnitEquipmentItem.cs Sat Jun 05 15:36:04 2010 +0000 @@ -22,8 +22,8 @@ private string[] mutexGroups; private UnitType unitType; private string slotName = ""; - private AbstractLimit minLimit; - private AbstractLimit maxLimit; + private ILimit minLimit; + private ILimit maxLimit; public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor) : this(equipmentItem, equipmentFor, new string[0]) @@ -131,11 +131,11 @@ /// <summary> /// Gets the Limit object for the minimum number of items that can be taken /// </summary> - public AbstractLimit MinLimit + public ILimit MinLimit { get { - AbstractLimit limit = minLimit; + ILimit limit = minLimit; if (limit == null) { @@ -163,11 +163,11 @@ /// <summary> /// Gets the Limit object for the maximum number of items that can be taken /// </summary> - public AbstractLimit MaxLimit + public ILimit MaxLimit { get { - AbstractLimit limit = maxLimit; + ILimit limit = maxLimit; if (limit == null) {
--- a/api/Objects/UnitType.cs Sat Jun 05 14:00:28 2010 +0000 +++ b/api/Objects/UnitType.cs Sat Jun 05 15:36:04 2010 +0000 @@ -32,7 +32,7 @@ private String notes = ""; private List<UnitType> containedTypes = new List<UnitType>(); private Dictionary<string, string> extraData = new Dictionary<string, string>(); - private Dictionary<string, AbstractLimit> slotLimits = new Dictionary<string, AbstractLimit>(); + private Dictionary<string, ILimit> slotLimits = new Dictionary<string, ILimit>(); private Dictionary<string, UnitMemberType> unitMemberTypes = new Dictionary<string, UnitMemberType>(); private List<Category> cats = new List<Category>(); @@ -593,7 +593,7 @@ } } - public void AddEquipmentSlot(string slotName, AbstractLimit slotLimit) + public void AddEquipmentSlot(string slotName, ILimit slotLimit) { slotLimits.Add(slotName, slotLimit); } @@ -608,9 +608,9 @@ /// </summary> /// <param name="slotName">The name of the equipment slot to get the limit for</param> /// <returns>The limit of the number of items allowed in a slot, or an infinite limit if the slot is the default one or has not been specified</returns> - public AbstractLimit GetEquipmentSlotLimit(string slotName) + public ILimit GetEquipmentSlotLimit(string slotName) { - AbstractLimit slotLimit = null; + ILimit slotLimit = null; if (HasEquipmentSlot(slotName)) {
--- a/api/Util/UnitEquipmentUtil.cs Sat Jun 05 14:00:28 2010 +0000 +++ b/api/Util/UnitEquipmentUtil.cs Sat Jun 05 15:36:04 2010 +0000 @@ -109,7 +109,7 @@ private static int GetEquipmentCountLimit (Unit unit, int currLimit, UnitEquipmentItem equip) { int newLimit = currLimit; - AbstractLimit limit = GetSlotLimitForItem(unit, equip); + ILimit limit = GetSlotLimitForItem(unit, equip); if (!(limit is UnlimitedLimit)) { @@ -120,7 +120,7 @@ return newLimit; } - private static AbstractLimit GetSlotLimitForItem(Unit unit, UnitEquipmentItem equip) + private static ILimit GetSlotLimitForItem(Unit unit, UnitEquipmentItem equip) { return unit.UnitType.GetEquipmentSlotLimit(equip.SlotName); } @@ -133,7 +133,7 @@ public static bool IsEquipmentRatioLimited(Unit unit, UnitEquipmentItem equip) { - AbstractLimit limit = GetSlotLimitForItem(unit, equip); + ILimit limit = GetSlotLimitForItem(unit, equip); return equip.IsRatioLimit && (limit is IPercentageLimit || limit is UnlimitedLimit); } @@ -147,10 +147,10 @@ return IBBMath.Percentage(number, unit.Size); } - private static double GetMinOfSlotLimitAndEquipmentLimit(UnitEquipmentItem equip, AbstractLimit equipLimit, Unit unit) + private static double GetMinOfSlotLimitAndEquipmentLimit(UnitEquipmentItem equip, ILimit equipLimit, Unit unit) { double limit = 0; - AbstractLimit slotLimit = GetSlotLimitForItem(unit, equip); + ILimit slotLimit = GetSlotLimitForItem(unit, equip); if (slotLimit is IPercentageLimit) {
--- a/schemas/warfoundry-core.xsd Sat Jun 05 14:00:28 2010 +0000 +++ b/schemas/warfoundry-core.xsd Sat Jun 05 15:36:04 2010 +0000 @@ -9,6 +9,13 @@ </xs:complexType> </xs:element> <xs:complexType name="limit"> + <xs:sequence> + <xs:group ref="limitElements" minOccurs="1" maxOccurs="1"/> + <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> + </xs:sequence> + <xs:anyAttribute processContents="lax"/> +</xs:complexType> +<xs:group name="limitElements"> <xs:choice> <xs:element name="percentageLimit"> <xs:complexType> @@ -46,10 +53,27 @@ <xs:anyAttribute processContents="lax"/> </xs:complexType> </xs:element> + <xs:element name="compositeMaxLimit"> + <xs:complexType> + <xs:sequence> + <xs:group ref="limitElements" minOccurs="1" maxOccurs="unbounded"/> + <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> + </xs:sequence> + <xs:anyAttribute processContents="lax"/> + </xs:complexType> + </xs:element> + <xs:element name="compositeMinLimit"> + <xs:complexType> + <xs:sequence> + <xs:group ref="limitElements" minOccurs="1" maxOccurs="unbounded"/> + <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> + </xs:sequence> + <xs:anyAttribute processContents="lax"/> + </xs:complexType> + </xs:element> <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/> </xs:choice> - <xs:anyAttribute processContents="lax"/> -</xs:complexType> +</xs:group> <xs:simpleType name="positiveOrInfiniteInteger"> <xs:union memberTypes="xs:positiveInteger infinity"/> </xs:simpleType>