Mercurial > repos > IBDev-IBBoard.WarFoundry.API
annotate api/WarFoundryLoader.cs @ 8:613bc5eaac59
Re #9 - Make WarFoundry loading granular
* Remove specific staged loading classes
* Rework category loading for GameSystem and Race to make it use AddCategory(Category) method
* Promote staged loading from Native Factory to all Factories level
* Refactor XML Factory to use smaller methods
Also removed some commented code that isn't used any more
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sun, 04 Jan 2009 19:24:13 +0000 |
parents | b9346894319c |
children | 0770e5cbba7c |
rev | line source |
---|---|
0 | 1 // WarFoundryLoader.cs |
2 // | |
3 // Copyright (C) 2007 IBBoard | |
4 // | |
5 // This library is free software; you can redistribute it and/or | |
6 // modify it under the terms of the GNU Lesser General Public | |
7 // License version 2.1 of the License as published by the Free | |
8 // Software Foundation. | |
9 // | |
10 // This library is distributed in the hope that it will be useful, | |
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 // Lesser General Public License for more details. | |
14 // | |
15 // You should have received a copy of the GNU Lesser General Public | |
16 // License along with this library; if not, write to the Free Software | |
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 // | |
19 // | |
20 | |
21 using System; | |
22 using System.Collections.Generic; | |
23 using System.IO; | |
24 using IBBoard.Collections; | |
25 using IBBoard.IO; | |
26 using IBBoard.Logging; | |
27 using IBBoard.WarFoundry.API.Factories; | |
28 using IBBoard.WarFoundry.API.Objects; | |
29 using ICSharpCode.SharpZipLib.Zip; | |
30 | |
31 namespace IBBoard.WarFoundry.API | |
32 { | |
33 public class WarFoundryLoader | |
34 { | |
35 private static WarFoundryLoader loader; | |
36 | |
37 /// <summary> | |
38 /// Gets the default <see cref="WarFoundryLoader"/> used to load WarFoundry data files. | |
39 /// </summary> | |
40 /// <returns> | |
41 /// The default <see cref="WarFoundryLoader"/> | |
42 /// </returns> | |
43 public static WarFoundryLoader GetDefault() | |
44 { | |
45 if (loader == null) | |
46 { | |
47 loader = new WarFoundryLoader(); | |
48 } | |
49 | |
50 return loader; | |
51 } | |
52 | |
53 private ICollection<DirectoryInfo> directories; | |
54 private ICollection<INativeWarFoundryFactory> factories; | |
55 private ICollection<INonNativeWarFoundryFactory> nonNativeFactories; | |
56 private Dictionary<string, GameSystem> systemsTable; | |
57 private Dictionary<string, Dictionary<string, Dictionary<string, Race>>> racesTable; //Keys are: System, Race, SubRace | |
58 private Dictionary<IWarFoundryFactory, SimpleSet<IWarFoundryObject>> loadedObjects; | |
59 | |
60 protected WarFoundryLoader() | |
61 { | |
62 directories = new List<DirectoryInfo>(); | |
63 factories = new List<INativeWarFoundryFactory>(); | |
64 nonNativeFactories = new List<INonNativeWarFoundryFactory>(); | |
65 loadedObjects = new Dictionary<IWarFoundryFactory,SimpleSet<IWarFoundryObject>>(); | |
66 } | |
67 | |
68 /// <summary> | |
69 /// Adds a directory to the collection of directories that will be searched for WarFoundry data files. | |
70 /// </summary> | |
71 /// <param name="directory"> | |
72 /// The <see cref="DirectoryInfo"/> to add to the list for searching for data files | |
73 /// </param> | |
74 public void AddLoadDirectory(DirectoryInfo directory) | |
75 { | |
76 if (!directories.Contains(directory)) | |
77 { | |
78 directories.Add(directory); | |
79 } | |
80 } | |
81 | |
82 /// <summary> | |
83 /// Removes a directory from the collection of directories that will be searched for WarFoundry data files. | |
84 /// </summary> | |
85 /// <param name="directory"> | |
86 /// A <see cref="DirectoryInfo"/> | |
87 /// </param> | |
88 public void RemoveLoadDirectory(DirectoryInfo directory) | |
89 { | |
90 if (directories.Contains(directory)) | |
91 { | |
92 directories.Remove(directory); | |
93 } | |
94 } | |
95 | |
96 /// <summary> | |
97 /// Registers a <see cref="INativeWarFoundryFactory"/> as a factory that can parse native data files. | |
98 /// </summary> | |
99 /// <param name="factory"> | |
100 /// The <see cref="INativeWarFoundryFactory"/> to register to parse native data files. | |
101 /// </param> | |
102 public void RegisterFactory(INativeWarFoundryFactory factory) | |
103 { | |
104 if (!factories.Contains(factory)) | |
105 { | |
106 factories.Add(factory); | |
107 } | |
108 } | |
109 | |
110 /// <summary> | |
111 /// Unregisters a <see cref="INativeWarFoundryFactory"/> so that it will no longer be used to try to parse native data files. | |
112 /// </summary> | |
113 /// <param name="factory"> | |
114 /// The <see cref="INativeWarFoundryFactory"/> to remove from the collection of factories that are used to try to parse native data files. | |
115 /// </param> | |
116 public void UnregisterFactory(INativeWarFoundryFactory factory) | |
117 { | |
118 if (factories.Contains(factory)) | |
119 { | |
120 factories.Remove(factory); | |
121 } | |
122 } | |
123 | |
124 /// <summary> | |
125 /// Registers a <see cref="INonNativeWarFoundryFactory"/> so that it will be used to try to parse non-native data files from other applications. | |
126 /// </summary> | |
127 /// <param name="factory"> | |
128 /// The <see cref="INonNativeWarFoundryFactory"/> to register to parse non-native data files. | |
129 /// </param> | |
130 public void RegisterNonNativeFactory(INonNativeWarFoundryFactory factory) | |
131 { | |
132 if (!nonNativeFactories.Contains(factory)) | |
133 { | |
134 nonNativeFactories.Add(factory); | |
135 } | |
136 } | |
137 | |
138 /// <summary> | |
139 /// Unregisters a <see cref="INonNativeWarFoundryFactory"/> so that it will no longer be used to try to parse non-native data files from other applications. | |
140 /// </summary> | |
141 /// <param name="factory"> | |
142 /// The <see cref="INonNativeWarFoundryFactory"/> to remove from the collection of factories that are used to try to parse non-native data files. | |
143 /// </param> | |
144 public void UnregisterNonNativeFactory(INonNativeWarFoundryFactory factory) | |
145 { | |
146 if (nonNativeFactories.Contains(factory)) | |
147 { | |
148 nonNativeFactories.Remove(factory); | |
149 } | |
150 } | |
151 | |
152 /// <summary> | |
153 /// Loads all of the data files in the registered directories. | |
154 /// </summary> | |
155 public void LoadFiles() | |
156 { | |
157 LogNotifier.Debug(GetType(), "Load files"); | |
158 PrepareForFileLoad(); | |
159 | |
160 foreach (DirectoryInfo directory in directories) | |
161 { | |
5
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
162 if (directory.Exists) |
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
163 { |
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
164 LogNotifier.Debug(GetType(), "Load from "+directory.FullName); |
0 | 165 |
5
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
166 foreach (FileInfo file in directory.GetFiles()) |
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
167 { |
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
168 LoadFile(file); |
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
169 } |
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
170 } |
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
171 else |
0 | 172 { |
5
b9346894319c
Fixes #6 - Stop missing data folder being fatal
IBBoard <dev@ibboard.co.uk>
parents:
0
diff
changeset
|
173 LogNotifier.WarnFormat(GetType(), "Load for {0} failed because directory didn't exist", directory.FullName); |
0 | 174 } |
175 } | |
176 | |
177 ICollection<Race> races = new List<Race>(); | |
178 | |
179 foreach (SimpleSet<IWarFoundryObject> objs in loadedObjects.Values) | |
180 { | |
181 foreach (IWarFoundryObject obj in objs) | |
182 { | |
183 if (obj is Race) | |
184 { | |
185 races.Add((Race)obj); | |
186 } | |
187 else if (obj is GameSystem) | |
188 { | |
189 StoreGameSystem((GameSystem)obj); | |
190 } | |
191 } | |
192 } | |
193 | |
194 foreach (Race race in races) | |
195 { | |
196 StoreRace(race); | |
197 } | |
198 } | |
199 | |
200 protected void PrepareForFileLoad() | |
201 { | |
202 //Just set up blank dictionaries for now - may try different and more complex handling in future | |
203 systemsTable = new Dictionary<string,GameSystem>(); | |
204 racesTable = new Dictionary<string,Dictionary<string,Dictionary<string,Race>>>(); | |
205 } | |
206 | |
207 /// <summary> | |
208 /// Loads a single file through the registered WarFoundryFactories, if a factory exists that supports the file format. | |
209 /// </summary> | |
210 /// <param name="file"> | |
211 /// A <see cref="FileInfo"/> for the file to attempt to load | |
212 /// </param> | |
213 protected void LoadFile(FileInfo file) | |
214 { | |
215 bool handled = false; | |
216 | |
217 if (!handled) | |
218 { | |
219 ICollection<IWarFoundryObject> objs = null; | |
220 IWarFoundryFactory loadFactory = null; | |
221 | |
222 if (nonNativeFactories.Count > 0) | |
223 { | |
224 LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as a non-native file"); | |
225 | |
226 foreach (INonNativeWarFoundryFactory factory in nonNativeFactories) | |
227 { | |
228 LogNotifier.Debug(GetType(), "Load using "+factory.GetType().AssemblyQualifiedName+"? " + (factory.CanHandleFileFormat(file) ? "yes" : "no")); | |
229 | |
230 if (factory.CanHandleFileFormat(file)) | |
231 { | |
232 objs = factory.CreateObjectsFromFile(file); | |
233 | |
234 if (objs!=null) | |
235 { | |
236 loadFactory = factory; | |
237 break; | |
238 } | |
239 } | |
240 } | |
241 } | |
242 | |
243 if (objs == null) | |
244 { | |
245 LogNotifier.Debug(GetType(), "Attempting to load "+file.FullName+" as native file"); | |
246 | |
247 foreach (INativeWarFoundryFactory factory in factories) | |
248 { | |
249 if (factory.CanHandleFileFormat(file)) | |
250 { | |
251 objs = factory.CreateObjectsFromFile(file); | |
252 | |
253 if (objs!=null) | |
254 { | |
255 loadFactory = factory; | |
256 break; | |
257 } | |
258 } | |
259 } | |
260 } | |
261 | |
262 if (objs!=null) | |
263 { | |
264 AddLoadedObjects(objs, loadFactory); | |
265 } | |
266 } | |
267 } | |
268 | |
269 private void AddLoadedObjects(ICollection<IWarFoundryObject> loadedObjs, IWarFoundryFactory factory) | |
270 { | |
271 SimpleSet<IWarFoundryObject> objs; | |
272 loadedObjects.TryGetValue(factory, out objs); | |
273 | |
274 if (objs == null) | |
275 { | |
276 objs = new SimpleSet<IWarFoundryObject>(); | |
277 loadedObjects.Add(factory, objs); | |
278 } | |
279 | |
280 objs.AddRange(loadedObjs); | |
281 } | |
282 | |
283 private void AddLoadedObject(IWarFoundryObject obj, IWarFoundryFactory factory) | |
284 { | |
285 SimpleSet<IWarFoundryObject> objs; | |
286 loadedObjects.TryGetValue(factory, out objs); | |
287 | |
288 if (objs == null) | |
289 { | |
290 objs = new SimpleSet<IWarFoundryObject>(); | |
291 loadedObjects.Add(factory, objs); | |
292 } | |
293 | |
294 objs.Add(obj); | |
295 } | |
296 | |
297 protected virtual ZipFile MakeZipFile(FileInfo file) | |
298 { | |
299 return new ZipFile(file.FullName); | |
300 } | |
301 | |
302 protected void StoreGameSystem(GameSystem system) | |
303 { | |
304 string sysid = system.ID.ToLower(); | |
305 | |
306 if (systemsTable.ContainsKey(sysid)) | |
307 { | |
308 LogNotifier.WarnFormat(GetType(), "System {0} ({1}) has already been loaded. Duplicate file ({3}) discarded", system.Name, system.ID, system.SourceFile.FullName); | |
309 } | |
310 else | |
311 { | |
312 systemsTable.Add(sysid, (GameSystem)system); | |
313 } | |
314 } | |
315 | |
316 | |
317 /// <summary> | |
318 /// Stores a loaded <see cref="GameSystem"/> that has been generated outside the core loading structure. | |
319 /// | |
320 /// Note: Calls to this function should be made before calls to StoreRace(Race, IWarFoundryFactory). | |
321 /// </summary> | |
322 /// <param name="system"> | |
323 /// The <see cref="GameSystem"/> to register as loaded. | |
324 /// </param> | |
325 /// <param name="factory"> | |
326 /// The <see cref="IWarFoundryFactory"/> that created it. | |
327 /// </param> | |
328 public void StoreGameSystem(GameSystem system, IWarFoundryFactory factory) | |
329 { | |
330 AddLoadedObject(system, factory); | |
331 StoreGameSystem(system); | |
332 } | |
333 | |
334 protected void StoreRace(Race race) | |
335 { | |
336 Dictionary<string, Dictionary<string, Race>> systemRaces; | |
337 | |
338 if (race.GameSystem == null) | |
339 { | |
340 throw new InvalidOperationException("Race cannot have null game system. Game system should be loaded before race."); | |
341 } | |
342 | |
343 string systemID = race.GameSystem.ID.ToLower(); | |
344 racesTable.TryGetValue(systemID, out systemRaces); | |
345 | |
346 if (systemRaces==null) | |
347 { | |
348 systemRaces = new Dictionary<string,Dictionary<string,Race>>(); | |
349 racesTable.Add(systemID, systemRaces); | |
350 } | |
351 | |
352 Dictionary<string, Race> subRaces; | |
353 systemRaces.TryGetValue(race.ID.ToLower(), out subRaces); | |
354 | |
355 if (subRaces==null) | |
356 { | |
357 subRaces = new Dictionary<string,Race>(); | |
358 systemRaces.Add(race.ID.ToLower(), subRaces); | |
359 } | |
360 | |
361 if (subRaces.ContainsKey(race.SubID.ToLower())) | |
362 { | |
363 LogNotifier.WarnFormat(GetType(), "Race {0} ({1} - {2}) for system {3} ({4}) has already been loaded. Duplicate file ({5}) discarded", race.Name, race.ID, race.SubID, race.GameSystem.ID, race.GameSystem.Name, race.SourceFile.Name); | |
364 race = null; | |
365 } | |
366 else | |
367 { | |
368 subRaces.Add(race.SubID.ToLower(), race); | |
369 } | |
370 } | |
371 | |
372 /// <summary> | |
373 /// Stores a loaded <see cref="Race"/> that has been generated outside the core loading structure. | |
374 /// | |
375 /// Note: Calls to this function should ensure that the relevant <see cref="GameSystem"> has been created first. | |
376 /// </summary> | |
377 /// <param name="race"> | |
378 /// The <see cref="Race"/> to register as loaded. | |
379 /// </param> | |
380 /// <param name="factory"> | |
381 /// The <see cref="IWarFoundryFactory"/> that created it | |
382 /// </param> | |
383 public void StoreRace(Race race, IWarFoundryFactory factory) | |
384 { | |
385 AddLoadedObject(race, factory); | |
386 StoreRace(race); | |
387 } | |
388 | |
389 /// <summary> | |
390 /// Gets all <see cref="GameSystem"/>s that are currently available, determined by those that can be loaded with the current <see cref="IWarFoundryFactory"/>s. | |
391 /// </summary> | |
392 /// <returns> | |
393 /// An array of <see cref="GameSystem"/>s that are currently available. | |
394 /// </returns> | |
395 public GameSystem[] GetGameSystems() | |
396 { | |
397 if (systemsTable==null) | |
398 { | |
399 LoadFiles(); | |
400 } | |
401 | |
402 GameSystem[] systems = new GameSystem[systemsTable.Count]; | |
403 int iSys = 0; | |
404 | |
405 foreach (GameSystem sys in systemsTable.Values) | |
406 { | |
407 systems[iSys++] = sys; | |
408 } | |
409 | |
410 return systems; | |
411 } | |
412 | |
413 /// <summary> | |
414 /// Gets a single <see cref="GameSystem"/> with a given ID. | |
415 /// </summary> | |
416 /// <param name="systemID"> | |
417 /// The ID of the <see cref="GameSystem"/> to get, as a <see cref="System.String"/>. | |
418 /// </param> | |
419 /// <returns> | |
420 /// The <see cref="GameSystem"/> with the given ID, or <code>null</code> if one doesn't exist. | |
421 /// </returns> | |
422 public GameSystem GetGameSystem(string systemID) | |
423 { | |
424 if (systemsTable==null) | |
425 { | |
426 LoadFiles(); | |
427 } | |
428 | |
429 GameSystem system; | |
430 systemsTable.TryGetValue(systemID.ToLower(), out system); | |
431 return system; | |
432 } | |
433 | |
434 /// <summary> | |
435 /// Gets an array of the races for the specified <see cref="GameSystem"/>. | |
436 /// </summary> | |
437 /// <param name="system"> | |
438 /// The <see cref="GameSystem"/> to get the available races for. | |
439 /// </param> | |
440 /// <returns> | |
441 /// An array of <see cref="Race"/>s for the <see cref="GameSystem"/> | |
442 /// </returns> | |
443 public Race[] GetRaces(GameSystem system) | |
444 { | |
445 return GetRaces(system.ID); | |
446 } | |
447 | |
448 /// <summary> | |
449 /// Gets an array of the races for a game system by ID. | |
450 /// </summary> | |
451 /// <param name="systemID"> | |
452 /// The <see cref="System.String"/> ID of the game system to get races for | |
453 /// </param> | |
454 /// <returns> | |
455 /// An array of <see cref="Race"/>s for the specified game system | |
456 /// </returns> | |
457 public Race[] GetRaces(string systemID) | |
458 { | |
459 if (racesTable==null) | |
460 { | |
461 LoadFiles(); | |
462 } | |
463 | |
8
613bc5eaac59
Re #9 - Make WarFoundry loading granular
IBBoard <dev@ibboard.co.uk>
parents:
5
diff
changeset
|
464 systemID = systemID.ToLower(); |
0 | 465 Dictionary<string, Dictionary<string, Race>> system; |
466 racesTable.TryGetValue(systemID, out system); | |
467 | |
468 if (system==null) | |
469 { | |
470 return new Race[0]; | |
471 } | |
472 | |
473 int count = 0; | |
474 | |
475 foreach (Dictionary<string, Race> racesDict in system.Values) | |
476 { | |
477 count+= racesDict.Count; | |
478 } | |
479 | |
480 Race[] races = new Race[count]; | |
481 int i = 0; | |
482 | |
483 foreach (string raceID in system.Keys) | |
484 { | |
485 foreach (string raceSubId in system[raceID].Keys) | |
486 { | |
487 races[i++] = GetRace(systemID, raceID, raceSubId); | |
488 } | |
489 } | |
490 | |
491 return races; | |
492 } | |
493 | |
494 /// <summary> | |
495 /// Gets a single race for a given <see cref="GameSystem"/> by ID of the race. | |
496 /// </summary> | |
497 /// <param name="system"> | |
498 /// The <see cref="GameSystem"/> that the race is part of. | |
499 /// </param> | |
500 /// <param name="raceID"> | |
501 /// A <see cref="System.String"/> ID for the race to load. | |
502 /// </param> | |
503 /// <returns> | |
504 /// A <see cref="Race"/> with the specified ID from the <see cref="GameSystem"/>, or <code>null</code> if one doesn't exist. | |
505 /// </returns> | |
506 public Race GetRace(GameSystem system, string raceID) | |
507 { | |
508 return GetRace(system.ID, raceID); | |
509 } | |
510 | |
511 /// <summary> | |
512 /// Gets a single race for a given game system by ID of the game system and race. | |
513 /// </summary> | |
514 /// <param name="systemID"> | |
515 /// The <see cref="System.String"/> ID of the game system that the race is part of. | |
516 /// </param> | |
517 /// <param name="raceID"> | |
518 /// The <see cref="System.String"/> ID for the race to load. | |
519 /// </param> | |
520 /// <returns> | |
521 /// A <see cref="Race"/> with the specified ID from the game system with the specified ID, or <code>null</code> if there is no race or game system with those IDs. | |
522 /// </returns> | |
523 public Race GetRace(string systemID, string raceID) | |
524 { | |
525 return GetRace(systemID, raceID, ""); | |
526 } | |
527 | |
528 /// <summary> | |
529 /// Gets a single race for a given <see cref="GameSystem"/> by the race's ID and sub-race ID. | |
530 /// </summary> | |
531 /// <param name="system"> | |
532 /// The <see cref="GameSystem"/> that the race is part of. | |
533 /// </param> | |
534 /// <param name="raceID"> | |
535 /// The <see cref="System.String"/> ID for the race to load. | |
536 /// </param> | |
537 /// <param name="raceSubID"> | |
538 /// A <see cref="System.String"/> | |
539 /// </param> | |
540 /// <returns> | |
541 /// A <see cref="Race"/> | |
542 /// </returns> | |
543 public Race GetRace(GameSystem system, string raceID, string raceSubID) | |
544 { | |
545 return GetRace(system.ID, raceID, raceSubID); | |
546 } | |
547 | |
548 /// <summary> | |
549 /// Gets a single race for a given game system by the game system's ID and the race's ID and sub-race ID. | |
550 /// </summary> | |
551 /// <param name="systemID"> | |
552 /// The <see cref="System.String"/> ID of the game system that the race is part of. | |
553 /// </param> | |
554 /// <param name="raceID"> | |
555 /// The <see cref="System.String"/> ID for the race to load. | |
556 /// </param> | |
557 /// <param name="raceSubID"> | |
558 /// A <see cref="System.String"/> | |
559 /// </param> | |
560 /// <returns> | |
561 /// A <see cref="Race"/> | |
562 /// </returns> | |
563 public Race GetRace(string systemID, string raceID, string raceSubID) | |
564 { | |
565 if (racesTable==null) | |
566 { | |
567 LoadFiles(); | |
568 } | |
569 | |
570 Race race = null; | |
571 | |
572 systemID = systemID.ToLower(); | |
573 | |
574 Dictionary<string, Dictionary<string, Race>> races; | |
575 racesTable.TryGetValue(systemID, out races); | |
576 | |
577 if (races!=null) | |
578 { | |
579 Dictionary<string, Race> subraces; | |
580 races.TryGetValue(raceID, out subraces); | |
581 | |
582 if (subraces!=null) | |
583 { | |
584 subraces.TryGetValue(raceSubID, out race); | |
585 } | |
586 } | |
587 | |
588 return race; | |
589 } | |
590 | |
591 /// <summary> | |
592 /// Gets the IDs of all of the game systems currently available. | |
593 /// </summary> | |
594 /// <returns> | |
595 /// An array of <see cref="System.String"/>s representing the IDs of the game systems. | |
596 /// </returns> | |
597 public string[] GetGameSystemIDs() | |
598 { | |
599 if (systemsTable==null) | |
600 { | |
601 LoadFiles(); | |
602 } | |
603 | |
604 string[] keys = new string[systemsTable.Keys.Count]; | |
605 int i = 0; | |
606 | |
607 foreach (string key in systemsTable.Keys) | |
608 { | |
609 keys[i++] = key; | |
610 } | |
611 | |
612 return keys; | |
613 } | |
614 | |
615 /// <summary> | |
616 /// Gets the IDs of all of the races of a specified game system. | |
617 /// </summary> | |
618 /// <param name="system"> | |
619 /// The <see cref="GameSystem"/> to get the available races for. | |
620 /// </param> | |
621 /// <returns> | |
622 /// An array of <see cref="System.String"/>s representing the IDs of the races of the specified game system. | |
623 /// </returns> | |
624 public string[] GetSystemRaceIDs(GameSystem system) | |
625 { | |
626 return GetSystemRaceIDs(system.ID); | |
627 } | |
628 | |
629 /// <summary> | |
630 /// Gets the IDs of all of the races of a specified game system. | |
631 /// </summary> | |
632 /// <param name="systemID"> | |
633 /// The <see cref="System.String"/> ID of the game system to get the available races for. | |
634 /// </param> | |
635 /// <returns> | |
636 /// An array of <see cref="System.String"/>s representing the IDs of the races of the specified game system. | |
637 /// </returns> | |
638 public string[] GetSystemRaceIDs(string systemID) | |
639 { | |
640 if (racesTable == null) | |
641 { | |
642 LoadFiles(); | |
643 } | |
644 | |
645 Dictionary<string, Dictionary<string, Race>> races = racesTable[systemID.ToLower()]; | |
646 | |
647 if (races==null) | |
648 { | |
649 return new string[0]; | |
650 } | |
651 else | |
652 { | |
653 string[] keys = new string[races.Keys.Count]; | |
654 int i = 0; | |
655 | |
656 foreach (string key in races.Keys) | |
657 { | |
658 keys[i++] = key; | |
659 } | |
660 | |
661 return keys; | |
662 } | |
663 } | |
664 } | |
665 } |