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>