view API/Factories/Xml/WarFoundryXmlGameSystemFactory.cs @ 450:8811737baebf

Fixes #352: Test/fix cyclic references in unit types * Tell the Race it has a new UnitType earlier to resolve load loops * Update example data file to one that uses all requirements, but caused cyclic issues
author IBBoard <dev@ibboard.co.uk>
date Sun, 22 Jan 2012 19:17:06 +0000
parents e50682387d63
children
line wrap: on
line source

//  This file (WarFoundryXmlGameSystemFactory.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 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;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using ICSharpCode.SharpZipLib.Zip;
using IBBoard.Xml;
using IBBoard.WarFoundry.API.Objects;

namespace IBBoard.WarFoundry.API.Factories.Xml
{
	/// <summary>
	/// A sub-factory specifically for loading GameSystems from WarFoundry XML files
	/// </summary>
	public class WarFoundryXmlGameSystemFactory
	{	
		private Dictionary<GameSystem, XmlDocument> extraData = new Dictionary<GameSystem, XmlDocument>();
		private WarFoundryXmlFactory mainFactory;
		
		public WarFoundryXmlGameSystemFactory(WarFoundryXmlFactory factory)
		{
			this.mainFactory = factory;
		}
		
		private void StoreExtraData(GameSystem wfObject, XmlElement elem)
		{
			extraData[wfObject] = elem.OwnerDocument;
		}
	
		private XmlDocument GetExtraData(GameSystem obj)
		{
			XmlDocument extra = null;
			extraData.TryGetValue(obj, out extra);			
			return extra;
		}
		
		public GameSystem CreateSystemFromElement(ZipFile file, XmlElement elem)
		{
			string id = elem.GetAttribute("id");
			string name = elem.GetAttribute("name");
			GameSystem system = new GameSystem(id, name, mainFactory);
            system.SystemArmyDefaultSize =  XmlTools.GetIntValueFromAttribute (elem, "defaultArmySize");
            system.SystemPtsAbbrevSingle = elem.GetAttribute ("defaultPtsAbbreviationSingular");
            system.SystemPtsAbbrevPlural = elem.GetAttribute ("defaultPtsAbbreviationPlural");
            system.SystemPtsNameSingle = elem.GetAttribute ("defaultPtsNameSingular");
            system.SystemPtsNamePlural = elem.GetAttribute ("defaultPtsNamePlural");
			StoreExtraData(system, elem);
			return system;
		}		
		
		public void CompleteLoading(GameSystem system)
		{
			if (!WarFoundryXmlFactoryUtils.CanCompleteLoading(system))
			{
				return;
			}
			
			system.SetAsLoading();			
			XmlDocument extraData = GetExtraData(system);
			LoadCategoriesForSystem(system, extraData);
			XmlElement statsElem = WarFoundryXmlFactoryUtils.SelectSingleElement(extraData, "/system:system/system:sysStatsList");
			string defaultStatsID = statsElem.GetAttribute("defaultStats");
			LoadSystemStatsForSystem(system, extraData);
			system.StandardSystemStatsID = defaultStatsID;
			XmlElement systemElement = WarFoundryXmlFactoryUtils.SelectSingleElement(extraData, "/system:system");
			system.WarnOnError = XmlTools.GetBoolValueFromAttribute(systemElement, "warn");
			system.AllowAllies = XmlTools.GetBoolValueFromAttribute(systemElement, "allowAllies");
			system.SetAsFullyLoaded();
		}

		
		private void LoadCategoriesForSystem(GameSystem system, XmlNode elem)
		{
			foreach (XmlElement cat in WarFoundryXmlFactoryUtils.SelectNodes(elem, "/system:system/system:categories/cat:cat"))
			{
				system.AddCategory(CategoryLoader.CreateFromElement(cat));
			}
		}	
		
		private void LoadSystemStatsForSystem(GameSystem system, XmlNode elem)
		{
			foreach (XmlElement stats in WarFoundryXmlFactoryUtils.SelectNodes(elem, "/system:system/system:sysStatsList/system:sysStats"))
			{
				SystemStats sysStats = CreateSystemStatsFromElement(stats);
				system.AddSystemStats(sysStats);
			}
		}
		
		private SystemStats CreateSystemStatsFromElement(XmlElement elem)
		{
			SystemStats sysStats = new SystemStats(elem.GetAttribute("id"));
			
			foreach (XmlElement slot in WarFoundryXmlFactoryUtils.SelectNodes(elem, "system:sysStat"))
			{
				sysStats.AddStatSlot(slot.GetAttribute("name"));
			}

			return sysStats;
		}	
	}
}