Mercurial > repos > IBBoard.WarFoundry.API
comparison api/AbstractWarFoundryLoader.cs @ 291:24e7b571f50f
Re #318: DefaultWarFoundryLoader throws null ref when loading individual files
* Fix quick fix so that it actually works and loads files - but it is still a quick-fix that needs double-checking
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Tue, 14 Dec 2010 20:17:07 +0000 |
parents | c035afa4a42c |
children | b24a78cfd314 |
comparison
equal
deleted
inserted
replaced
290:5ed39187b0e3 | 291:24e7b571f50f |
---|---|
20 { | 20 { |
21 private ICollection<DirectoryInfo> directories; | 21 private ICollection<DirectoryInfo> directories; |
22 private ICollection<INativeWarFoundryFactory> factories; | 22 private ICollection<INativeWarFoundryFactory> factories; |
23 private ICollection<INonNativeWarFoundryFactory> nonNativeFactories; | 23 private ICollection<INonNativeWarFoundryFactory> nonNativeFactories; |
24 private Dictionary<IWarFoundryFactory, SimpleSet<IWarFoundryObject>> loadedObjects; | 24 private Dictionary<IWarFoundryFactory, SimpleSet<IWarFoundryObject>> loadedObjects; |
25 | |
25 public delegate void FileLoadingCompleteDelegate(List<FileLoadFailure> failures); | 26 public delegate void FileLoadingCompleteDelegate(List<FileLoadFailure> failures); |
27 | |
26 public event MethodInvoker FileLoadingStarted; | 28 public event MethodInvoker FileLoadingStarted; |
29 | |
27 public event FileLoadingCompleteDelegate FileLoadingFinished; | 30 public event FileLoadingCompleteDelegate FileLoadingFinished; |
28 | 31 |
29 protected AbstractWarFoundryLoader() | 32 protected AbstractWarFoundryLoader() |
30 { | 33 { |
31 directories = new List<DirectoryInfo>(); | 34 directories = new List<DirectoryInfo>(); |
32 factories = new List<INativeWarFoundryFactory>(); | 35 factories = new List<INativeWarFoundryFactory>(); |
33 nonNativeFactories = new List<INonNativeWarFoundryFactory>(); | 36 nonNativeFactories = new List<INonNativeWarFoundryFactory>(); |
131 Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems = new Dictionary<FileInfo, IWarFoundryFactory>(); | 134 Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems = new Dictionary<FileInfo, IWarFoundryFactory>(); |
132 List<FileLoadFailure> failedLoads = FillLoadableFiles(loadableRaces, loadableGameSystems); | 135 List<FileLoadFailure> failedLoads = FillLoadableFiles(loadableRaces, loadableGameSystems); |
133 failedLoads.AddRange(LoadGameSystems(loadableGameSystems)); | 136 failedLoads.AddRange(LoadGameSystems(loadableGameSystems)); |
134 failedLoads.AddRange(LoadRaces(loadableRaces)); | 137 failedLoads.AddRange(LoadRaces(loadableRaces)); |
135 OnFileLoadingFinished(failedLoads); | 138 OnFileLoadingFinished(failedLoads); |
139 FinishFileLoad(); | |
136 return failedLoads; | 140 return failedLoads; |
137 } | 141 } |
138 | 142 |
139 private void OnFileLoadingFinished(List<FileLoadFailure> failures) | 143 private void OnFileLoadingFinished(List<FileLoadFailure> failures) |
140 { | 144 { |
141 if (FileLoadingFinished!=null) | 145 if (FileLoadingFinished != null) |
142 { | 146 { |
143 FileLoadingFinished(failures); | 147 FileLoadingFinished(failures); |
144 } | 148 } |
145 } | 149 } |
146 | 150 |
147 protected abstract void PrepareForFileLoad(); | 151 protected virtual void PrepareForFileLoad() |
152 { | |
153 //Do nothing special | |
154 } | |
155 | |
156 protected virtual void FinishFileLoad() | |
157 { | |
158 //Do nothing special | |
159 } | |
148 | 160 |
149 private List<FileLoadFailure> FillLoadableFiles(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems) | 161 private List<FileLoadFailure> FillLoadableFiles(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems) |
150 { | 162 { |
151 List<FileLoadFailure> fails = new List<FileLoadFailure>(); | 163 List<FileLoadFailure> fails = new List<FileLoadFailure>(); |
152 | 164 |
169 } | 181 } |
170 | 182 |
171 private List<FileLoadFailure> FillLoadableFilesForDirectory(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems, DirectoryInfo directory) | 183 private List<FileLoadFailure> FillLoadableFilesForDirectory(Dictionary<FileInfo, IWarFoundryFactory> loadableRaces, Dictionary<FileInfo, IWarFoundryFactory> loadableGameSystems, DirectoryInfo directory) |
172 { | 184 { |
173 List<FileLoadFailure> fails = new List<FileLoadFailure>(); | 185 List<FileLoadFailure> fails = new List<FileLoadFailure>(); |
174 LogNotifier.Debug(GetType(), "Load from "+directory.FullName); | 186 LogNotifier.Debug(GetType(), "Load from " + directory.FullName); |
175 | 187 |
176 foreach (FileInfo file in directory.GetFiles()) | 188 foreach (FileInfo file in directory.GetFiles()) |
177 { | 189 { |
178 IWarFoundryFactory factory = GetGameSystemLoadingFactoryForFile(file); | 190 IWarFoundryFactory factory = GetGameSystemLoadingFactoryForFile(file); |
179 | 191 |
183 } | 195 } |
184 else | 196 else |
185 { | 197 { |
186 factory = GetRaceLoadingFactoryForFile(file); | 198 factory = GetRaceLoadingFactoryForFile(file); |
187 | 199 |
188 if (factory!=null) | 200 if (factory != null) |
189 { | 201 { |
190 loadableRaces.Add(file, factory); | 202 loadableRaces.Add(file, factory); |
191 } | 203 } |
192 else | 204 else |
193 { | 205 { |
278 catch (Exception ex) | 290 catch (Exception ex) |
279 { | 291 { |
280 failure = new FileLoadFailure(file, null, ex.Message, null, ex); | 292 failure = new FileLoadFailure(file, null, ex.Message, null, ex); |
281 } | 293 } |
282 | 294 |
283 if (failure!=null) | 295 if (failure != null) |
284 { | 296 { |
285 fails.Add(failure); | 297 fails.Add(failure); |
286 LogNotifier.Warn(GetType(), failure.Message, failure.Exception); | 298 LogNotifier.Warn(GetType(), failure.Message, failure.Exception); |
287 } | 299 } |
288 } | 300 } |
310 catch (Exception ex) | 322 catch (Exception ex) |
311 { | 323 { |
312 failure = new FileLoadFailure(file, null, ex.Message, null, ex); | 324 failure = new FileLoadFailure(file, null, ex.Message, null, ex); |
313 } | 325 } |
314 | 326 |
315 if (failure!=null) | 327 if (failure != null) |
316 { | 328 { |
317 fails.Add(failure); | 329 fails.Add(failure); |
318 LogNotifier.Warn(GetType(), failure.Message, failure.Exception); | 330 LogNotifier.Warn(GetType(), failure.Message, failure.Exception); |
319 } | 331 } |
320 } | 332 } |
362 objs = LoadFileWithNativeFactories(file, out loadFactory); | 374 objs = LoadFileWithNativeFactories(file, out loadFactory); |
363 } | 375 } |
364 } | 376 } |
365 catch (InvalidFileException ex) | 377 catch (InvalidFileException ex) |
366 { | 378 { |
367 LogNotifier.Error(GetType(), file.FullName+" failed to load", ex); | 379 LogNotifier.Error(GetType(), file.FullName + " failed to load", ex); |
368 } | 380 } |
369 | 381 |
370 if (objs!=null) | 382 if (objs != null) |
371 { | 383 { |
372 AddLoadedObjects(objs, loadFactory); | 384 AddLoadedObjects(objs, loadFactory); |
373 } | 385 } |
374 else | 386 else |
375 { | 387 { |
376 objs = new List<IWarFoundryObject>(); | 388 objs = new List<IWarFoundryObject>(); |
377 } | 389 } |
378 | 390 |
379 return objs; | 391 return objs; |
380 } | 392 } |
381 | 393 |
382 private ICollection<IWarFoundryObject> LoadFileWithNonNativeFactories(FileInfo file, out IWarFoundryFactory loadFactory) | 394 private ICollection<IWarFoundryObject> LoadFileWithNonNativeFactories(FileInfo file, out IWarFoundryFactory loadFactory) |
383 { | 395 { |
384 ICollection<IWarFoundryObject> objs = null; | 396 ICollection<IWarFoundryObject> objs = null; |
385 loadFactory = null; | 397 loadFactory = null; |
386 | 398 |
387 if (nonNativeFactories.Count > 0) | 399 if (nonNativeFactories.Count > 0) |
388 { | 400 { |
389 LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as a non-native file"); | 401 LogNotifier.Debug(GetType(), "Attempting to load " + file.FullName + " as a non-native file"); |
390 | 402 |
391 foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) | 403 foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) |
392 { | 404 { |
393 bool canLoad = factory.CanHandleFileFormat(file); | 405 bool canLoad = factory.CanHandleFileFormat(file); |
394 LogNotifier.Debug(GetType(), "Load using "+factory.GetType().FullName+"? " + (canLoad ? "yes" : "no")); | 406 LogNotifier.Debug(GetType(), "Load using " + factory.GetType().FullName + "? " + (canLoad ? "yes" : "no")); |
395 | 407 |
396 if (canLoad) | 408 if (canLoad) |
397 { | 409 { |
398 objs = factory.CreateObjectsFromFile(file); | 410 objs = factory.CreateObjectsFromFile(file); |
399 | 411 |
400 if (objs!=null) | 412 if (objs != null) |
401 { | 413 { |
402 loadFactory = factory; | 414 loadFactory = factory; |
403 break; | 415 break; |
404 } | 416 } |
405 } | 417 } |
406 } | 418 } |
407 } | 419 } |
408 | 420 |
409 return objs; | 421 return objs; |
410 } | 422 } |
411 | 423 |
412 private ICollection<IWarFoundryObject> LoadFileWithNativeFactories(FileInfo file, out IWarFoundryFactory loadFactory) | 424 private ICollection<IWarFoundryObject> LoadFileWithNativeFactories(FileInfo file, out IWarFoundryFactory loadFactory) |
413 { | 425 { |
414 ICollection<IWarFoundryObject> objs = null; | 426 ICollection<IWarFoundryObject> objs = null; |
415 loadFactory = null; | 427 loadFactory = null; |
416 | 428 |
417 if (factories.Count > 0) | 429 if (factories.Count > 0) |
418 { | 430 { |
419 LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as native file"); | 431 LogNotifier.Debug(GetType(), "Attempting to load " + file.FullName + " as native file"); |
420 | 432 |
421 foreach (INativeWarFoundryFactory factory in factories) | 433 foreach (INativeWarFoundryFactory factory in factories) |
422 { | 434 { |
423 if (factory.CanHandleFileFormat(file)) | 435 if (factory.CanHandleFileFormat(file)) |
424 { | 436 { |
425 objs = factory.CreateObjectsFromFile(file); | 437 objs = factory.CreateObjectsFromFile(file); |
426 | 438 |
427 if (objs!=null) | 439 if (objs != null) |
428 { | 440 { |
429 loadFactory = factory; | 441 loadFactory = factory; |
430 break; | 442 break; |
431 } | 443 } |
432 } | 444 } |
433 } | 445 } |
434 } | 446 } |
435 | 447 |
436 return objs; | 448 return objs; |
437 } | 449 } |
438 | 450 |
439 private void AddLoadedObjects(ICollection<IWarFoundryObject> loadedObjs, IWarFoundryFactory factory) | 451 private void AddLoadedObjects(ICollection<IWarFoundryObject> loadedObjs, IWarFoundryFactory factory) |
440 { | 452 { |
441 SimpleSet<IWarFoundryObject> objs; | 453 SimpleSet<IWarFoundryObject> objs; |
442 loadedObjects.TryGetValue(factory, out objs); | 454 loadedObjects.TryGetValue(factory, out objs); |
443 | 455 |
463 { | 475 { |
464 StoreRace((Race)loadedObject); | 476 StoreRace((Race)loadedObject); |
465 } | 477 } |
466 } | 478 } |
467 } | 479 } |
468 | 480 |
469 protected void StoreGameSystem(GameSystem system) | 481 protected void StoreGameSystem(GameSystem system) |
470 { | 482 { |
471 GameSystem existingSystem = GetExistingSystemForSystem(system); | 483 GameSystem existingSystem = GetExistingSystemForSystem(system); |
472 | 484 |
473 if (existingSystem!=null) | 485 if (existingSystem != null) |
474 { | 486 { |
475 if (!system.Equals(existingSystem)) | 487 if (!system.Equals(existingSystem)) |
476 { | 488 { |
477 //TODO: Raise an event to say we got a different duplicate | 489 //TODO: Raise an event to say we got a different duplicate |
478 //We can't just fail, because failing is for completely unhandled files, not for objects in a file | 490 //We can't just fail, because failing is for completely unhandled files, not for objects in a file |
500 /// </summary> | 512 /// </summary> |
501 /// <param name="system"> | 513 /// <param name="system"> |
502 /// The loaded <see cref="GameSystem"/> to store | 514 /// The loaded <see cref="GameSystem"/> to store |
503 /// </param> | 515 /// </param> |
504 protected abstract void DoStoreGameSystem(GameSystem system); | 516 protected abstract void DoStoreGameSystem(GameSystem system); |
505 | 517 |
506 protected void StoreRace(Race race) | 518 protected void StoreRace(Race race) |
507 { | 519 { |
508 if (race.GameSystem == null) | 520 if (race.GameSystem == null) |
509 { | 521 { |
510 throw new InvalidOperationException("Race cannot have null game system. Game system should be loaded before race."); | 522 throw new InvalidOperationException("Race cannot have null game system. Game system should be loaded before race."); |
599 public virtual string[] GetGameSystemIDs() | 611 public virtual string[] GetGameSystemIDs() |
600 { | 612 { |
601 GameSystem[] systems = GetGameSystems(); | 613 GameSystem[] systems = GetGameSystems(); |
602 return GetWarFoundryObjectIDs(systems); | 614 return GetWarFoundryObjectIDs(systems); |
603 } | 615 } |
604 | 616 |
605 protected string[] GetWarFoundryObjectIDs(WarFoundryObject[] objs) | 617 protected string[] GetWarFoundryObjectIDs(WarFoundryObject[] objs) |
606 { | 618 { |
607 int objCount = objs.Length; | 619 int objCount = objs.Length; |
608 string[] keys = new string[objCount]; | 620 string[] keys = new string[objCount]; |
609 | 621 |
627 public virtual string[] GetSystemRaceIDs(GameSystem system) | 639 public virtual string[] GetSystemRaceIDs(GameSystem system) |
628 { | 640 { |
629 Race[] races = GetRaces(system); | 641 Race[] races = GetRaces(system); |
630 return GetWarFoundryObjectIDs(races); | 642 return GetWarFoundryObjectIDs(races); |
631 } | 643 } |
632 | 644 |
633 public Army LoadArmy(FileInfo file) | 645 public Army LoadArmy(FileInfo file) |
634 { | 646 { |
635 IWarFoundryFactory factory = GetArmyLoadingFactoryForFile(file); | 647 IWarFoundryFactory factory = GetArmyLoadingFactoryForFile(file); |
636 Army loadedArmy = null; | 648 Army loadedArmy = null; |
637 | 649 |
643 { | 655 { |
644 foreach (IWarFoundryObject systemCount in objs) | 656 foreach (IWarFoundryObject systemCount in objs) |
645 { | 657 { |
646 if (systemCount is Army) | 658 if (systemCount is Army) |
647 { | 659 { |
648 loadedArmy = (Army) systemCount; | 660 loadedArmy = (Army)systemCount; |
649 } | 661 } |
650 } | 662 } |
651 } | 663 } |
652 } | 664 } |
653 | 665 |