* Ships with unresolvable like_ships references are now removed as intended.

* Filtering out ships without roles or models now happens after like_ships relationships are applied, so incomplete ships can be used as templates. Added is_template property to explicitly exclude ships at this stage without error messages.

PAGroove_Stations now works properly.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@1674 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2008-06-04 19:23:10 +00:00
parent a95a581ac9
commit 9c9c4b53a0
2 changed files with 33 additions and 23 deletions

View File

@ -58,13 +58,13 @@ static NSString * const kOOLogDataCacheRemovedOld = @"dataCache.removedOld";
static NSString * const kCacheKeyVersion = @"CFBundleVersion"; // Legacy name
static NSString * const kCacheKeyEndianTag = @"endian tag";
static NSString * const kCacheKeyFormatVersion = @"format version";
static NSString * const kCacheKeyCaches = @"_caches";
static NSString * const kCacheKeyCaches = @"caches";
enum
{
kEndianTagValue = 0x12345678UL,
kFormatVersionValue = 18
kFormatVersionValue = 19
};
@ -600,7 +600,7 @@ static OOCacheManager *sSingleton = nil;
/* Construct the path for the cache file, which is:
~/Library/Caches/org.aegidian.oolite/Data Cache.plist
In addition to generally being the right place to put _caches,
In addition to generally being the right place to put caches,
~/Library/Caches has the particular advantage of not being indexed by
Spotlight or, in future, backed up by Time Machine.
*/

View File

@ -76,7 +76,7 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
- (NSDictionary *) mergeShip:(NSDictionary *)child withParent:(NSDictionary *)parent;
- (BOOL) loadAndMergeShipyard:(NSMutableDictionary *)ioData;
- (BOOL) loadAndApplyShipDataOverrides:(NSMutableDictionary *)ioData;
- (BOOL) isValidShipEntry:(NSDictionary *)shipEntry name:(NSString *)name;
- (BOOL) removeUnusableEntries:(NSMutableDictionary *)ioData;
- (void) mergeShipRoles:(NSString *)roles forShipKey:(NSString *)shipKey intoProbabilityMap:(NSMutableDictionary *)probabilitySets;
@end
@ -228,11 +228,12 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
cache:NO] mutableCopy] autorelease];
if (result == nil) return;
// Clean out any non-dictionaries.
for (enumerator = [result keyEnumerator]; (key = [enumerator nextObject]); )
// Clean out any non-dictionaries. (Iterates over a copy of keys since it mutates the dictionary.)
for (enumerator = [[result allKeys] objectEnumerator]; (key = [enumerator nextObject]); )
{
if (![self isValidShipEntry:[result objectForKey:key] name:key])
if (![[result objectForKey:key] isKindOfClass:[NSDictionary class]])
{
OOLog(@"shipData.load.badEntry", @"***** ERROR: the shipdata.plist entry \"%@\" is not a dictionary, ignoring.", key);
[result removeObjectForKey:key];
}
}
@ -243,6 +244,9 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
// Apply patches.
if (![self loadAndApplyShipDataOverrides:result]) return;
// Clean out templates and invalid entries.
if (![self removeUnusableEntries:result]) return;
// Add shipyard entries into shipdata entries.
if (![self loadAndMergeShipyard:result]) return;
@ -386,7 +390,7 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
count = lastCount = [remainingLikeShips count];
while (count != 0)
{
for (enumerator = [remainingLikeShips objectEnumerator]; (key = [enumerator nextObject]); )
for (enumerator = [[[remainingLikeShips copy] autorelease] objectEnumerator]; (key = [enumerator nextObject]); )
{
// Look up like_ship entry
shipEntry = [ioData objectForKey:key];
@ -407,8 +411,12 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
count = [remainingLikeShips count];
if (count == lastCount)
{
// Fail: we couldn't resolve all like_ship entries.
// Fail: we couldn't resolve all like_ship entries. Remove unresolved ones.
OOLog(@"shipData.merge.failed", @"***** ERROR: one or more shipdata.plist entries have like_ship references that cannot be resolved: %@", remainingLikeShips);
for (enumerator = [remainingLikeShips objectEnumerator]; (key = [enumerator nextObject]); )
{
[ioData removeObjectForKey:key];
}
break;
}
lastCount = count;
@ -535,27 +543,29 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
}
- (BOOL) isValidShipEntry:(NSDictionary *)shipEntry name:(NSString *)name
- (BOOL) removeUnusableEntries:(NSMutableDictionary *)ioData
{
// Quick checks for obvious problems. Not complete validation, just basic sanity checking.
if (![shipEntry isKindOfClass:[NSDictionary class]])
NSEnumerator *shipKeyEnum = nil;
NSString *shipKey = nil;
NSDictionary *shipEntry = nil;
// Clean out invalid entries and templates. (Iterates over a copy of keys since it mutates the dictionary.)
for (shipKeyEnum = [[ioData allKeys] objectEnumerator]; (shipKey = [shipKeyEnum nextObject]); )
{
OOLog(@"shipData.load.badEntry", @"***** ERROR: the shipdata.plist entry \"%@\" is not a dictionary, ignoring.", name);
return NO;
}
if ([shipEntry stringForKey:@"like_ship"] == nil) // Keys may be inherited, so we only check "root" ships.
{
if ([[shipEntry stringForKey:@"roles"] length] == 0)
shipEntry = [ioData objectForKey:shipKey];
if ([shipEntry boolForKey:@"is_template"]) [ioData removeObjectForKey:shipKey];
else if ([[shipEntry stringForKey:@"roles"] length] == 0)
{
OOLog(@"shipData.load.error", @"***** ERROR: the shipdata.plist entry \"%@\" specifies no %@, ignoring.", name, @"roles");
return NO;
OOLog(@"shipData.load.error", @"***** ERROR: the shipdata.plist entry \"%@\" specifies no %@, ignoring.", shipKey, @"roles");
[ioData removeObjectForKey:shipKey];
}
if ([[shipEntry stringForKey:@"model"] length] == 0)
else if ([[shipEntry stringForKey:@"model"] length] == 0)
{
OOLog(@"shipData.load.error", @"***** ERROR: the shipdata.plist entry \"%@\" specifies no %@, ignoring.", name, @"model");
return NO;
OOLog(@"shipData.load.error", @"***** ERROR: the shipdata.plist entry \"%@\" specifies no %@, ignoring.", shipKey, @"model");
[ioData removeObjectForKey:shipKey];
}
}
return YES;
}