Mercurial > repos > IBDev-IBBoard.WarFoundry.API
changeset 14:0770e5cbba7c
Closes #21 - File loading in order
* Reworked LoadFiles to smaller methods for readability (also re #10) and structure
* Now determine expected load return before loading then load all "expected GameSystem" before "expected Race"
* Make "can load as race/game system/army" methods public in interface
Re #22 - Get errored file loading
* Created FileLoadFailure class and made LoadFiles return a list of them
Also
* Some code cleanup
* Change to DictionaryUtils calls
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sun, 25 Jan 2009 14:03:20 +0000 |
parents | ad8eaed12e66 |
children | 306558904c2a |
files | IBBoard.WarFoundry.API.mdp api/Factories/AbstractNativeWarFoundryFactory.cs api/Factories/AbstractNonNativeFileExtensionWarFoundryFactory.cs api/Factories/AbstractWarFoundryFactory.cs api/Factories/IWarFoundryFactory.cs api/FileLoadFailure.cs api/Objects/GameSystem.cs api/Objects/Race.cs api/WarFoundryLoader.cs |
diffstat | 9 files changed, 414 insertions(+), 258 deletions(-) [+] |
line wrap: on
line diff
--- a/IBBoard.WarFoundry.API.mdp Thu Jan 22 20:26:08 2009 +0000 +++ b/IBBoard.WarFoundry.API.mdp Sun Jan 25 14:03:20 2009 +0000 @@ -88,6 +88,7 @@ <File name="api/Objects/WarFoundryStagedLoadingObject.cs" subtype="Code" buildaction="Compile" /> <File name="api/Objects/IWarFoundryStagedLoadObject.cs" subtype="Code" buildaction="Compile" /> <File name="api/Objects/DuplicateItemException.cs" subtype="Code" buildaction="Compile" /> + <File name="api/FileLoadFailure.cs" subtype="Code" buildaction="Compile" /> </Contents> <References> <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
--- a/api/Factories/AbstractNativeWarFoundryFactory.cs Thu Jan 22 20:26:08 2009 +0000 +++ b/api/Factories/AbstractNativeWarFoundryFactory.cs Sun Jan 25 14:03:20 2009 +0000 @@ -58,39 +58,32 @@ } catch(ZipException) { - //Silently dispose - we don't support the file and our other methods should handle that + //Silently dispose as per spec for the method } return zip; } protected override bool CheckCanHandleFileFormat (ZipFile file) - { - bool canHandle = false; - - if (file!=null) - { - canHandle = CheckCanHandleAsSystem(file) || CheckCanHandleAsRace(file) || CheckCanHandleAsArmy(file); - } - - return canHandle; + { + return CheckCanHandleFileAsGameSystem(file) || CheckCanHandleFileAsRace(file) || CheckCanHandleFileAsArmy(file); } - protected bool CheckCanHandleAsSystem(ZipFile file) + protected override bool CheckCanHandleFileAsGameSystem(ZipFile file) { return file.ZipFileComment.StartsWith(SYSTEM_ZIP_IDENTIFIER) && CheckCanFindSystemFileContent(file); } protected abstract bool CheckCanFindSystemFileContent(ZipFile file); - protected bool CheckCanHandleAsRace(ZipFile file) + protected override bool CheckCanHandleFileAsRace(ZipFile file) { return file.ZipFileComment.StartsWith(RACE_ZIP_IDENTIFIER) && CheckCanFindRaceFileContent(file); } protected abstract bool CheckCanFindRaceFileContent(ZipFile file); - protected bool CheckCanHandleAsArmy(ZipFile file) + protected override bool CheckCanHandleFileAsArmy(ZipFile file) { return file.ZipFileComment.StartsWith(ARMY_ZIP_IDENTIFIER) && CheckCanFindArmyFileContent(file); } @@ -124,108 +117,10 @@ return objects; } - - -/* - public override bool CanHandleArmyFileFormat(FileInfo file) - { - bool canHandle = false; - - try - { - ZipFile zip = new ZipFile(file.FullName); - canHandle = zip.ZipFileComment.StartsWith(ARMY_ZIP_IDENTIFIER) && CanHandleArmyFileFormat(zip); - } - catch (ZipException) - { - //Not a valid zip file so we can't handle it - } - - return canHandle; - } - - public override bool CanHandleRaceFileFormat(FileInfo file) - { - bool canHandle = false; - - try - { - ZipFile zip = new ZipFile(file.FullName); - canHandle = zip.ZipFileComment.StartsWith(RACE_ZIP_IDENTIFIER) && CanHandleRaceFileFormat(zip); - } - catch (ZipException) - { - //Not a valid zip file so we can't handle it - } - - return canHandle; - } - - public override bool CanHandleSystemFileFormat(FileInfo file) - { - bool canHandle = false; - - try - { - ZipFile zip = new ZipFile(file.FullName); - canHandle = zip.ZipFileComment.StartsWith(SYSTEM_ZIP_IDENTIFIER) && CanHandleSystemFileFormat(zip); - } - catch (ZipException) - { - //Not a valid zip file so we can't handle it - } - - return canHandle; - } - - public abstract bool CanHandleArmyFileFormat(ZipFile file); - public abstract bool CanHandleRaceFileFormat(ZipFile file); - public abstract bool CanHandleSystemFileFormat(ZipFile file); - - public override Army CreateArmyFromFile (FileInfo file) - { - try - { - ZipFile zip = new ZipFile(file.FullName); - return CreateArmyFromFile(zip); - } - catch(ZipException ex) - { - throw new InvalidFileException(Translation.GetTranslation("InvalidArmyFileException", "Cannot get Army for file {0} as it was not a recognised Army file", file.Name), ex); - } - } - - public override Race CreateRaceFromFile (FileInfo file) - { - try - { - ZipFile zip = new ZipFile(file.FullName); - return CreateRaceFromFile(zip); - } - catch(ZipException ex) - { - throw new InvalidFileException(Translation.GetTranslation("InvalidRaceFileException", "Cannot get Race for file {0} as it was not a recognised Race file", file.Name), ex); - } - } - - public override GameSystem CreateGameSystemFromFile (FileInfo file) - { - try - { - ZipFile zip = new ZipFile(file.FullName); - return CreateGameSystemFromFile(zip); - } - catch(ZipException ex) - { - throw new InvalidFileException(Translation.GetTranslation("InvalidGameSystemFileException", "Cannot get Game System for file {0} as it was not a recognised Race file", file.Name), ex); - } - }*/ protected Army CreateArmyFromFile(ZipFile file) { - Army army = CreateArmyFromStream(file, GetArmyDataStream(file)); - //throw new InvalidFileException(Translation.GetTranslation("InvalidArmyFileException", "Cannot get Army for file {0} as it was not an Army file", file.Name)); - return army; + return CreateArmyFromStream(file, GetArmyDataStream(file)); } protected abstract Stream GetArmyDataStream(ZipFile file); @@ -235,9 +130,7 @@ { try { - Race race = CreateRaceFromStream(file, GetRaceDataStream(file)); - //throw new InvalidFileException(Translation.GetTranslation("InvalidRaceFileException", "Cannot get Race for file {0} as it was not a Race file", file.Name)); - return race; + return CreateRaceFromStream(file, GetRaceDataStream(file)); } catch (InvalidFileException ex) { @@ -250,9 +143,7 @@ protected GameSystem CreateGameSystemFromFile(ZipFile file) { - GameSystem system = CreateGameSystemFromStream(file, GetGameSystemDataStream(file)); - //throw new InvalidFileException(Translation.GetTranslation("InvalidGameSystemFileException", "Cannot get Game System for file {0} as it was not a Game System file", file.Name)); - return system; + return CreateGameSystemFromStream(file, GetGameSystemDataStream(file)); } protected abstract Stream GetGameSystemDataStream(ZipFile file);
--- a/api/Factories/AbstractNonNativeFileExtensionWarFoundryFactory.cs Thu Jan 22 20:26:08 2009 +0000 +++ b/api/Factories/AbstractNonNativeFileExtensionWarFoundryFactory.cs Sun Jan 25 14:03:20 2009 +0000 @@ -33,20 +33,20 @@ protected override bool CheckCanHandleFileFormat (FileInfo file) { - return IsArmyFile(file) || IsRaceFile(file) || IsSystemFile(file); + return CheckCanHandleFileAsArmy(file) || CheckCanHandleFileAsRace(file) || CheckCanHandleFileAsGameSystem(file); } - protected bool IsArmyFile(FileInfo file) + protected override bool CheckCanHandleFileAsArmy(FileInfo file) { return ArmyFileExtension!=null && file.Name.ToLower().EndsWith(ArmyFileExtension); } - protected bool IsRaceFile(FileInfo file) + protected override bool CheckCanHandleFileAsRace(FileInfo file) { return RaceFileExtension!=null && file.Name.ToLower().EndsWith(RaceFileExtension); } - protected bool IsSystemFile(FileInfo file) + protected override bool CheckCanHandleFileAsGameSystem(FileInfo file) { return GameSystemFileExtension!=null && file.Name.ToLower().EndsWith(GameSystemFileExtension); } @@ -54,8 +54,7 @@ protected override FileInfo GetFileAsSupportedType (FileInfo file) { return file; - } - + } protected abstract Army CreateArmyFromFile(FileInfo file); protected abstract Race CreateRaceFromFile(FileInfo file);
--- a/api/Factories/AbstractWarFoundryFactory.cs Thu Jan 22 20:26:08 2009 +0000 +++ b/api/Factories/AbstractWarFoundryFactory.cs Sun Jan 25 14:03:20 2009 +0000 @@ -34,7 +34,26 @@ public bool CanHandleFileFormat (FileInfo file) { - return CheckCanHandleFileFormat(GetFileAsSupportedType(file)); + FILE_TYPE typedFile = GetFileAsSupportedType(file); + return typedFile != null && CheckCanHandleFileFormat(typedFile); + } + + public bool CanHandleFileAsRace(FileInfo file) + { + FILE_TYPE typedFile = GetFileAsSupportedType(file); + return typedFile != null && CheckCanHandleFileAsRace(typedFile); + } + + public bool CanHandleFileAsGameSystem(FileInfo file) + { + FILE_TYPE typedFile = GetFileAsSupportedType(file); + return typedFile != null && CheckCanHandleFileAsGameSystem(typedFile); + } + + public bool CanHandleFileAsArmy(FileInfo file) + { + FILE_TYPE typedFile = GetFileAsSupportedType(file); + return typedFile != null && CheckCanHandleFileAsArmy(typedFile); } /// <summary> @@ -58,6 +77,40 @@ /// <code>true</code> if the factory thinks it can support the file, else <code>false</code> /// </returns> protected abstract bool CheckCanHandleFileFormat(FILE_TYPE file); + + /// <summary> + /// Checks whether the factory thinks it can load data from the file in its paramaterised type as a Race object. + /// </summary> + /// <param name="file"> + /// An object of the converted <see cref="FILE_TYPE"/> to check support for + /// </param> + /// <returns> + /// <code>true</code> if the factory thinks it can support the file as a Race, else <code>false</code> + /// </returns> + protected abstract bool CheckCanHandleFileAsRace(FILE_TYPE file); + + /// <summary> + /// Checks whether the factory thinks it can load data from the file in its paramaterised type as a GameSystem object. + /// </summary> + /// <param name="file"> + /// An object of the converted <see cref="FILE_TYPE"/> to check support for + /// </param> + /// <returns> + /// <code>true</code> if the factory thinks it can support the file as a GameSystem, else <code>false</code> + /// </returns> + protected abstract bool CheckCanHandleFileAsGameSystem(FILE_TYPE file); + + /// <summary> + /// Checks whether the factory thinks it can load data from the file in its paramaterised type as an Army object. + /// </summary> + /// <param name="file"> + /// An object of the converted <see cref="FILE_TYPE"/> to check support for + /// </param> + /// <returns> + /// <code>true</code> if the factory thinks it can support the file as a Army, else <code>false</code> + /// </returns> + protected abstract bool CheckCanHandleFileAsArmy(FILE_TYPE file); + public ICollection<IWarFoundryObject> CreateObjectsFromFile(FileInfo file) {
--- a/api/Factories/IWarFoundryFactory.cs Thu Jan 22 20:26:08 2009 +0000 +++ b/api/Factories/IWarFoundryFactory.cs Sun Jan 25 14:03:20 2009 +0000 @@ -44,7 +44,40 @@ /// <returns> /// <code>true</code> if the file appears to be supported for loading by this factory, else returns <code>false</code> /// </returns> - bool CanHandleFileFormat(FileInfo file); + bool CanHandleFileFormat(FileInfo file); + + /// <summary> + /// Checks if the factory thinks it can handle the supplied file as a Race. Checks can be performed on file extension or some basic check of file content, or some other method. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to check support for as a file containing Race information. + /// </param> + /// <returns> + /// <code>true</code> if the file appears to be supported for loading by this factory as a Race, else returns <code>false</code> + /// </returns> + bool CanHandleFileAsRace(FileInfo file); + + /// <summary> + /// Checks if the factory thinks it can handle the supplied file as a GameSystem. Checks can be performed on file extension or some basic check of file content, or some other method. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to check support for as a file containing GameSystem information. + /// </param> + /// <returns> + /// <code>true</code> if the file appears to be supported for loading by this factory as a GameSystem, else returns <code>false</code> + /// </returns> + bool CanHandleFileAsGameSystem(FileInfo file); + + /// <summary> + /// Checks if the factory thinks it can handle the supplied file as a Army. Checks can be performed on file extension or some basic check of file content, or some other method. + /// </summary> + /// <param name="file"> + /// A <see cref="FileInfo"/> for the file to check support for as a file containing Army information. + /// </param> + /// <returns> + /// <code>true</code> if the file appears to be supported for loading by this factory as a Army, else returns <code>false</code> + /// </returns> + bool CanHandleFileAsArmy(FileInfo file); /// <summary> /// Reads the data from the supplied file and returns it as a collection of loadable objects.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/api/FileLoadFailure.cs Sun Jan 25 14:03:20 2009 +0000 @@ -0,0 +1,68 @@ +// This file (FileLoadFailure.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 under the GNU LGPL license. Please see COPYING.LGPL for more information and the full license. + +using System; +using System.IO; +using IBBoard.Lang; +using IBBoard.WarFoundry.API.Factories; + +namespace IBBoard.WarFoundry.API +{ + public class FileLoadFailure + { + private FileInfo failedFile; + private IWarFoundryFactory loadingFactory; + private string defaultMessage; + private string messageTranslationID; + private string message; + + public FileLoadFailure(FileInfo file, string message) : this (file, message, "") + { + } + + public FileLoadFailure(FileInfo file, string message, string translationID) : this (file, null, message, "") + { + } + + public FileLoadFailure(FileInfo file, IWarFoundryFactory factory, string message) : this (file, factory, message, "") + { + } + + public FileLoadFailure(FileInfo file,IWarFoundryFactory factory, string message, string translationID) + { + failedFile = file; + loadingFactory = factory; + defaultMessage = message; + messageTranslationID = translationID; + } + + public FileInfo FailedFile + { + get + { + return failedFile; + } + } + + public string Message + { + get + { + if (message == null) + { + if (messageTranslationID == "") + { + message = String.Format(defaultMessage, FailedFile, loadingFactory); + } + else + { + message = Translation.GetTranslation(messageTranslationID, defaultMessage, failedFile, loadingFactory); + } + } + + return message; + } + } + } +}
--- a/api/Objects/GameSystem.cs Thu Jan 22 20:26:08 2009 +0000 +++ b/api/Objects/GameSystem.cs Sun Jan 25 14:03:20 2009 +0000 @@ -67,7 +67,7 @@ get { EnsureFullyLoaded(); - return DictionaryToArrayConverter.Convert<string, Category>(RawCategories); + return DictionaryUtils.ToArray<string, Category>(RawCategories); } }
--- a/api/Objects/Race.cs Thu Jan 22 20:26:08 2009 +0000 +++ b/api/Objects/Race.cs Sun Jan 25 14:03:20 2009 +0000 @@ -119,7 +119,7 @@ } else { - cats = DictionaryToArrayConverter.Convert<string, Category>(categories); + cats = DictionaryUtils.ToArray<string, Category>(categories); } return cats; @@ -192,7 +192,7 @@ } else { - unitTypesArray = DictionaryToArrayConverter.Convert<string, UnitType>(unitTypesDictionary); + unitTypesArray = DictionaryUtils.ToArray<string, UnitType>(unitTypesDictionary); } return unitTypesArray;
--- a/api/WarFoundryLoader.cs Thu Jan 22 20:26:08 2009 +0000 +++ b/api/WarFoundryLoader.cs Sun Jan 25 14:03:20 2009 +0000 @@ -152,49 +152,22 @@ /// <summary> /// Loads all of the data files in the registered directories. /// </summary> - public void LoadFiles() + /// <returns> + /// A <see cref="Dictionary"/> of files that failed to load mapped against the message that their failure returned + /// </returns> + public List<FileLoadFailure> LoadFiles() { LogNotifier.Debug(GetType(), "Load files"); PrepareForFileLoad(); - - foreach (DirectoryInfo directory in directories) - { - if (directory.Exists) - { - LogNotifier.Debug(GetType(), "Load from "+directory.FullName); - - foreach (FileInfo file in directory.GetFiles()) - { - LoadFile(file); - } - } - else - { - LogNotifier.WarnFormat(GetType(), "Load for {0} failed because directory didn't exist", directory.FullName); - } - } - - ICollection<Race> races = new List<Race>(); + Dictionary<FileInfo, IWarFoundryFactory> loadableRaces = new Dictionary<FileInfo, IWarFoundryFactory>(); + Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems = new Dictionary<FileInfo, IWarFoundryFactory>(); + List<FileLoadFailure> failedLoads = FillLoadableFiles(loadableRaces, loadableGameSystems); + failedLoads.AddRange(LoadGameSystems(loadableGameSystems)); + failedLoads.AddRange(LoadRaces(loadableRaces)); + + LogNotifier.Debug(GetType(), failedLoads.Count + " failed file loads"); - foreach (SimpleSet<IWarFoundryObject> objs in loadedObjects.Values) - { - foreach (IWarFoundryObject obj in objs) - { - if (obj is Race) - { - races.Add((Race)obj); - } - else if (obj is GameSystem) - { - StoreGameSystem((GameSystem)obj); - } - } - } - - foreach (Race race in races) - { - StoreRace(race); - } + return failedLoads; } protected void PrepareForFileLoad() @@ -203,6 +176,179 @@ systemsTable = new Dictionary<string,GameSystem>(); racesTable = new Dictionary<string,Dictionary<string,Dictionary<string,Race>>>(); } + + private List<FileLoadFailure> FillLoadableFiles(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems) + { + List<FileLoadFailure> fails = new List<FileLoadFailure>(); + + foreach (DirectoryInfo directory in directories) + { + if (directory.Exists) + { + List<FileLoadFailure> directoryFails = FillLoadableFilesForDirectory(loadableRaces, loadableGameSystems, directory); + fails.AddRange(directoryFails); + } + else + { + LogNotifier.WarnFormat(GetType(), "Load for {0} failed because directory didn't exist", directory.FullName); + } + } + + return fails; + } + + private List<FileLoadFailure> FillLoadableFilesForDirectory(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems, DirectoryInfo directory) + { + List<FileLoadFailure> fails = new List<FileLoadFailure>(); + LogNotifier.Debug(GetType(), "Load from "+directory.FullName); + + foreach (FileInfo file in directory.GetFiles()) + { + IWarFoundryFactory factory = GetGameSystemRaceLoadingFactoryForFile(file); + + if (factory != null) + { + loadableGameSystems.Add(file, factory); + } + else + { + factory = GetRaceLoadingFactoryForFile(file); + + if (factory!=null) + { + loadableRaces.Add(file, factory); + } + else + { + fails.Add(new FileLoadFailure(file, "FileNotHandled", "File not handled as a Race or Game System definition: {0}")); + } + } + } + + return fails; + } + + private IWarFoundryFactory GetGameSystemRaceLoadingFactoryForFile(FileInfo file) + { + IWarFoundryFactory loadingFactory = null; + + foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) + { + if (factory.CanHandleFileAsGameSystem(file)) + { + loadingFactory = factory; + break; + } + } + + if (loadingFactory == null) + { + foreach (INativeWarFoundryFactory factory in factories) + { + if (factory.CanHandleFileAsGameSystem(file)) + { + loadingFactory = factory; + break; + } + } + } + + return loadingFactory; + } + + private IWarFoundryFactory GetRaceLoadingFactoryForFile(FileInfo file) + { + IWarFoundryFactory loadingFactory = null; + + foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) + { + if (factory.CanHandleFileAsRace(file)) + { + loadingFactory = factory; + break; + } + } + + if (loadingFactory == null) + { + foreach (INativeWarFoundryFactory factory in factories) + { + if (factory.CanHandleFileAsRace(file)) + { + loadingFactory = factory; + break; + } + } + } + + return loadingFactory; + } + + private List<FileLoadFailure> LoadGameSystems(Dictionary<FileInfo, IWarFoundryFactory> gameSystemFiles) + { + List<FileLoadFailure> fails = new List<FileLoadFailure>(); + + + foreach (FileInfo file in gameSystemFiles.Keys) + { + try + { + bool loaded = LoadObject(file, gameSystemFiles[file]); + + if (!loaded) + { + fails.Add(new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as Race using {1}")); + } + } + catch (Exception ex) + { + fails.Add(new FileLoadFailure(file, ex.Message)); + } + } + + return fails; + } + + private List<FileLoadFailure> LoadRaces(Dictionary<FileInfo, IWarFoundryFactory> raceFiles) + { + List<FileLoadFailure> fails = new List<FileLoadFailure>(); + + foreach (FileInfo file in raceFiles.Keys) + { + try + { + bool loaded = LoadObject(file, raceFiles[file]); + + if (!loaded) + { + fails.Add(new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as Race using {1}")); + } + } + catch (Exception ex) + { + fails.Add(new FileLoadFailure(file, ex.Message)); + } + } + + return fails; + } + + private bool LoadObject(FileInfo file, IWarFoundryFactory factory) + { + bool loaded = false; + + LogNotifier.DebugFormat(GetType(), "Loading {0} using {1}", file.FullName, factory.GetType().Name); + ICollection<IWarFoundryObject> objects = factory.CreateObjectsFromFile(file); + + if (objects.Count > 0) + { + AddLoadedObjects(objects, factory); + loaded = true; + } + + return loaded; + } + /// <summary> /// Loads a single file through the registered WarFoundryFactories, if a factory exists that supports the file format. @@ -210,60 +356,66 @@ /// <param name="file"> /// A <see cref="FileInfo"/> for the file to attempt to load /// </param> - protected void LoadFile(FileInfo file) + /// <returns> + /// An ICollection of IWarFoundryObjects loaded from <code>file</code> + /// </returns> + public ICollection<IWarFoundryObject> LoadFile(FileInfo file) { - bool handled = false; + ICollection<IWarFoundryObject> objs = null; + IWarFoundryFactory loadFactory = null; - if (!handled) + if (nonNativeFactories.Count > 0) { - ICollection<IWarFoundryObject> objs = null; - IWarFoundryFactory loadFactory = null; + LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as a non-native file"); - if (nonNativeFactories.Count > 0) + foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) { - LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as a non-native file"); + bool canLoad = factory.CanHandleFileFormat(file); + LogNotifier.Debug(GetType(), "Load using "+factory.GetType().FullName+"? " + (canLoad ? "yes" : "no")); - foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) + if (canLoad) { - LogNotifier.Debug(GetType(), "Load using "+factory.GetType().AssemblyQualifiedName+"? " + (factory.CanHandleFileFormat(file) ? "yes" : "no")); + objs = factory.CreateObjectsFromFile(file); - if (factory.CanHandleFileFormat(file)) + if (objs!=null) { - objs = factory.CreateObjectsFromFile(file); - - if (objs!=null) - { - loadFactory = factory; - break; - } - } - } + loadFactory = factory; + break; + } + } } + } + + if (objs == null) + { + LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as native file"); - if (objs == null) + foreach (INativeWarFoundryFactory factory in factories) { - LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as native file"); - - foreach (INativeWarFoundryFactory factory in factories) + if (factory.CanHandleFileFormat(file)) { - if (factory.CanHandleFileFormat(file)) + objs = factory.CreateObjectsFromFile(file); + + if (objs!=null) { - objs = factory.CreateObjectsFromFile(file); - - if (objs!=null) - { - loadFactory = factory; - break; - } + loadFactory = factory; + break; } } } - - if (objs!=null) - { - AddLoadedObjects(objs, loadFactory); - } + } + + if (objs!=null) + { + AddLoadedObjects(objs, loadFactory); } + else + { + LogNotifier.Debug(GetType(), "Loading of "+file.FullName+" failed"); + objs = new List<IWarFoundryObject>(); + } + + return objs; } private void AddLoadedObjects(ICollection<IWarFoundryObject> loadedObjs, IWarFoundryFactory factory) @@ -278,20 +430,22 @@ } objs.AddRange(loadedObjs); + StoreObjects(loadedObjs); } - - private void AddLoadedObject(IWarFoundryObject obj, IWarFoundryFactory factory) + + private void StoreObjects(ICollection<IWarFoundryObject> loadedObjects) { - SimpleSet<IWarFoundryObject> objs; - loadedObjects.TryGetValue(factory, out objs); - - if (objs == null) + foreach (IWarFoundryObject loadedObject in loadedObjects) { - objs = new SimpleSet<IWarFoundryObject>(); - loadedObjects.Add(factory, objs); + if (loadedObject is GameSystem) + { + StoreGameSystem((GameSystem)loadedObject); + } + else if (loadedObject is Race) + { + StoreRace((Race)loadedObject); + } } - - objs.Add(obj); } protected virtual ZipFile MakeZipFile(FileInfo file) @@ -313,24 +467,6 @@ } } - - /// <summary> - /// Stores a loaded <see cref="GameSystem"/> that has been generated outside the core loading structure. - /// - /// Note: Calls to this function should be made before calls to StoreRace(Race, IWarFoundryFactory). - /// </summary> - /// <param name="system"> - /// The <see cref="GameSystem"/> to register as loaded. - /// </param> - /// <param name="factory"> - /// The <see cref="IWarFoundryFactory"/> that created it. - /// </param> - public void StoreGameSystem(GameSystem system, IWarFoundryFactory factory) - { - AddLoadedObject(system, factory); - StoreGameSystem(system); - } - protected void StoreRace(Race race) { Dictionary<string, Dictionary<string, Race>> systemRaces; @@ -370,23 +506,6 @@ } /// <summary> - /// Stores a loaded <see cref="Race"/> that has been generated outside the core loading structure. - /// - /// Note: Calls to this function should ensure that the relevant <see cref="GameSystem"> has been created first. - /// </summary> - /// <param name="race"> - /// The <see cref="Race"/> to register as loaded. - /// </param> - /// <param name="factory"> - /// The <see cref="IWarFoundryFactory"/> that created it - /// </param> - public void StoreRace(Race race, IWarFoundryFactory factory) - { - AddLoadedObject(race, factory); - StoreRace(race); - } - - /// <summary> /// Gets all <see cref="GameSystem"/>s that are currently available, determined by those that can be loaded with the current <see cref="IWarFoundryFactory"/>s. /// </summary> /// <returns> @@ -399,15 +518,7 @@ LoadFiles(); } - GameSystem[] systems = new GameSystem[systemsTable.Count]; - int iSys = 0; - - foreach (GameSystem sys in systemsTable.Values) - { - systems[iSys++] = sys; - } - - return systems; + return DictionaryUtils.ToArray<string, GameSystem>(systemsTable); } /// <summary>