Oolite 1.91.0.7745-260117-205bce7
Loading...
Searching...
No Matches
ResourceManager Class Reference

#include <ResourceManager.h>

Inheritance diagram for ResourceManager:
Collaboration diagram for ResourceManager:

Class Methods

(void) + reset
(void) + resetManifestKnowledgeForOXZManager
(NSArray *) + rootPaths
(NSArray *) + userRootPaths
(NSString *) + builtInPath
(NSArray *) + pathsWithAddOns
(NSArray *) + paths
(NSArray *) + maskUserNameInPathArray:
(NSString *) + maskUserName:inPath:
(NSString *) + useAddOns
(NSArray *) + OXPsWithMessagesFound
(void) + setUseAddOns:
(void) + addExternalPath:
(NSEnumerator *) + pathEnumerator
(NSEnumerator *) + reversePathEnumerator
(NSDictionary *) + manifestForIdentifier:
(BOOL) + checkVersionCompatibility:forOXP:
(BOOL) + manifestHasConflicts:logErrors:
(BOOL) + manifestHasMissingDependencies:logErrors:
(BOOL) + manifest:HasUnmetDependency:logErrors:
(BOOL) + matchVersions:withVersion:
(void) + handleEquipmentListMerging:forLookupIndex:
(void) + handleEquipmentOverrides:
(void) + handleStarNebulaListMerging:
(NSString *) + errors
(NSString *) + pathForFileNamed:inFolder:
(NSString *) + pathForFileNamed:inFolder:cache:
(BOOL) + corePlist:excludedAt:
(NSDictionary *) + dictionaryFromFilesNamed:inFolder:andMerge:
(NSDictionary *) + dictionaryFromFilesNamed:inFolder:mergeMode:cache:
(NSArray *) + arrayFromFilesNamed:inFolder:andMerge:
(NSArray *) + arrayFromFilesNamed:inFolder:andMerge:cache:
(NSDictionary *) + whitelistDictionary
(NSDictionary *) + shaderBindingTypesDictionary
(NSDictionary *) + logControlDictionary
(NSDictionary *) + roleCategoriesDictionary
(OOSystemDescriptionManager *) + systemDescriptionManager
(OOSound *) + ooSoundNamed:inFolder:
(OOMusic *) + ooMusicNamed:inFolder:
(NSString *) + stringFromFilesNamed:inFolder:
(NSString *) + stringFromFilesNamed:inFolder:cache:
(NSDictionary *) + loadScripts
(BOOL) + writeDiagnosticData:toFileNamed:
(BOOL) + writeDiagnosticString:toFileNamed:
(BOOL) + writeDiagnosticPList:toFileNamed:
(NSString *) + diagnosticFileLocation
(NSDictionary *) + materialDefaults
(void) + clearCaches
(void) + preloadFileLists [implementation]
(void) + preloadFileListFromOXZ:forFolders: [implementation]
(void) + preloadFileListFromFolder:forFolders: [implementation]
(void) + preloadFilePathFor:inFolder:atPath: [implementation]
(void) + checkOXPMessagesInPath: [implementation]
(void) + checkPotentialPath:path: [implementation]
(BOOL) + validateManifest:forOXP: [implementation]
(BOOL) + areRequirementsFulfilled:forOXP:andFile: [implementation]
(void) + filterSearchPathsForConflicts: [implementation]
(BOOL) + filterSearchPathsForRequirements: [implementation]
(void) + filterSearchPathsToExcludeScenarioOnlyPaths: [implementation]
(void) + filterSearchPathsByScenario: [implementation]
(BOOL) + manifestAllowedByScenario: [implementation]
(BOOL) + manifestAllowedByScenario:withIdentifier: [implementation]
(BOOL) + manifestAllowedByScenario:withTag: [implementation]
(void) + addErrorWithKey:param1:param2: [implementation]
(BOOL) + checkCacheUpToDateForPaths: [implementation]
(static NSString *) + LogClassKeyRoot [implementation]
(void) + mergeRoleCategories:intoDictionary: [implementation]
(id) + retrieveFileNamed:inFolder:cache:key:class:usePathCache: [implementation]
(BOOL) + directoryExists:create: [implementation]
(void) + logPaths [implementation]

Detailed Description

Definition at line 55 of file ResourceManager.h.

Method Documentation

◆ addErrorWithKey:param1:param2:

+ (void) addErrorWithKey: (NSString *) descriptionKey
param1: (id) param1
param2: (id) param2 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1133 of file ResourceManager.m.

1133 :(NSString *)descriptionKey param1:(id)param1 param2:(id)param2
1134{
1135 if (descriptionKey != nil)
1136 {
1137 if (sErrors == nil) sErrors = [[NSMutableArray alloc] init];
1138 [sErrors addObject:[NSArray arrayWithObjects:descriptionKey, param1 ?: (id)@"", param2 ?: (id)@"", nil]];
1139 }
1140}
return nil
static NSMutableArray * sErrors

References nil, and sErrors.

Referenced by checkPotentialPath:path:, manifest:HasUnmetDependency:logErrors:, manifestHasConflicts:logErrors:, and validateManifest:forOXP:.

Here is the caller graph for this function:

◆ addExternalPath:

+ (void) addExternalPath: (NSString *) fileName

Definition at line 546 of file ResourceManager.m.

546 :(NSString *)path
547{
548 if (sSearchPaths == nil) sSearchPaths = [[NSMutableArray alloc] init];
549 if (![sSearchPaths containsObject:path])
550 {
551 [sSearchPaths addObject:path];
552
553 if (sExternalPaths == nil) sExternalPaths = [[NSMutableArray alloc] init];
554 [sExternalPaths addObject:path];
555 }
556}
static NSMutableArray * sSearchPaths
static NSMutableArray * sExternalPaths

References nil, sExternalPaths, and sSearchPaths.

Referenced by GameController::applicationDidFinishLaunching:.

Here is the caller graph for this function:

◆ areRequirementsFulfilled:forOXP:andFile:

+ (BOOL) areRequirementsFulfilled: (NSDictionary*) requirements
forOXP: (NSString *) path
andFile: (NSString *) file 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 742 of file ResourceManager.m.

742 :(NSDictionary*)requirements forOXP:(NSString *)path andFile:(NSString *)file
743{
744 BOOL OK = YES;
745 NSString *requiredVersion = nil;
746 NSString *maxVersion = nil;
747 unsigned conditionsHandled = 0;
748 static NSArray *ooVersionComponents = nil;
749 NSArray *oxpVersionComponents = nil;
750
751 if (requirements == nil) return YES;
752
753 if (ooVersionComponents == nil)
754 {
755 ooVersionComponents = ComponentsFromVersionString([[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]);
756 [ooVersionComponents retain];
757 }
758
759 // Check "version" (minimum version)
760 if (OK)
761 {
762 // Not oo_stringForKey:, because we need to be able to complain about non-strings.
763 requiredVersion = [requirements objectForKey:@"version"];
764 if (requiredVersion != nil)
765 {
766 ++conditionsHandled;
767 if ([requiredVersion isKindOfClass:[NSString class]])
768 {
769 oxpVersionComponents = ComponentsFromVersionString(requiredVersion);
770 if (NSOrderedAscending == CompareVersions(ooVersionComponents, oxpVersionComponents)) OK = NO;
771 }
772 else
773 {
774 OOLog(@"requirements.wrongType", @"Expected %@ entry \"%@\" to be string, but got %@ in OXP %@.", file, @"version", [requirements class], [path lastPathComponent]);
775 OK = NO;
776 }
777 }
778 }
779
780 // Check "max_version" (minimum max_version)
781 if (OK)
782 {
783 // Not oo_stringForKey:, because we need to be able to complain about non-strings.
784 maxVersion = [requirements objectForKey:@"max_version"];
785 if (maxVersion != nil)
786 {
787 ++conditionsHandled;
788 if ([maxVersion isKindOfClass:[NSString class]])
789 {
790 oxpVersionComponents = ComponentsFromVersionString(maxVersion);
791 if (NSOrderedDescending == CompareVersions(ooVersionComponents, oxpVersionComponents)) OK = NO;
792 }
793 else
794 {
795 OOLog(@"requirements.wrongType", @"Expected %@ entry \"%@\" to be string, but got %@ in OXP %@.", file, @"max_version", [requirements class], [path lastPathComponent]);
796 OK = NO;
797 }
798 }
799 }
800
801 if (OK && conditionsHandled < [requirements count])
802 {
803 // There are unknown requirement keys - don't support. NOTE: this check was not made pre 1.69!
804 OOLog(@"requirements.unknown", @"requires.plist for OXP %@ contains unknown keys, rejecting.", [path lastPathComponent]);
805 OK = NO;
806 }
807
808 return OK;
809}
#define OOLog(class, format,...)
Definition OOLogging.h:88
unsigned count
NSArray * ComponentsFromVersionString(NSString *string)
NSComparisonResult CompareVersions(NSArray *version1, NSArray *version2)

References CompareVersions(), ComponentsFromVersionString(), count, nil, and OOLog.

Referenced by checkPotentialPath:path:, and checkVersionCompatibility:forOXP:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ arrayFromFilesNamed:inFolder:andMerge:

+ (NSArray *) arrayFromFilesNamed: (NSString *) fileName
inFolder: (NSString *) folderName
andMerge: (BOOL) mergeFiles 

Definition at line 1361 of file ResourceManager.m.

1361 :(NSString *)fileName inFolder:(NSString *)folderName andMerge:(BOOL) mergeFiles
1362{
1363 return [self arrayFromFilesNamed:fileName inFolder:folderName andMerge:mergeFiles cache:YES];
1364}

References arrayFromFilesNamed:inFolder:andMerge:cache:.

Referenced by OOProbabilisticTextureManager::initWithPListName:options:anisotropy:lodBias:seed:, Universe(OOPrivate)::loadScenarios, roleCategoriesDictionary, OODebugController::setUpLogMessageClassMenu, and Universe::setUpSettings.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ arrayFromFilesNamed:inFolder:andMerge:cache:

+ (NSArray *) arrayFromFilesNamed: (NSString *) fileName
inFolder: (NSString *) folderName
andMerge: (BOOL) mergeFiles
cache: (BOOL) useCache 

Definition at line 1367 of file ResourceManager.m.

1367 :(NSString *)fileName inFolder:(NSString *)folderName andMerge:(BOOL) mergeFiles cache:(BOOL)useCache
1368{
1369 id result = nil;
1370 NSMutableArray *results = nil;
1371 NSString *cacheKey = nil;
1372 OOCacheManager *cache = [OOCacheManager sharedCache];
1373 NSEnumerator *enumerator = nil;
1374 NSString *path = nil;
1375 NSString *arrayPath = nil;
1376 NSMutableArray *array = nil;
1377 NSArray *arrayNonEditable = nil;
1378
1379 if (fileName == nil) return nil;
1380
1381 if (useCache)
1382 {
1383 cacheKey = [NSString stringWithFormat:@"%@%@ merge:%@", (folderName != nil) ? [folderName stringByAppendingString:@"/"] : (NSString *)@"", fileName, mergeFiles ? @"yes" : @"no"];
1384 result = [cache objectForKey:cacheKey inCache:@"arrays"];
1385 if (result != nil) return result;
1386 }
1387
1388 if (!mergeFiles)
1389 {
1390 // Find "last" matching array
1391 for (enumerator = [ResourceManager reversePathEnumerator]; (path = [enumerator nextObject]); )
1392 {
1393 if (folderName != nil)
1394 {
1395 arrayPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1396 arrayNonEditable = OOArrayFromFile(arrayPath);
1397 if (arrayNonEditable != nil) break;
1398 }
1399 arrayPath = [path stringByAppendingPathComponent:fileName];
1400 arrayNonEditable = OOArrayFromFile(arrayPath);
1401 if (arrayNonEditable != nil) break;
1402 }
1403 result = arrayNonEditable;
1404 }
1405 else
1406 {
1407 // Find all matching arrays
1408 results = [NSMutableArray array];
1409 for (enumerator = [ResourceManager pathEnumerator]; (path = [enumerator nextObject]); )
1410 {
1411 if ([ResourceManager corePlist:fileName excludedAt:path])
1412 {
1413 continue;
1414 }
1415
1416 arrayPath = [path stringByAppendingPathComponent:fileName];
1417 array = [[OOArrayFromFile(arrayPath) mutableCopy] autorelease];
1418 if (array != nil) [results addObject:array];
1419
1420 // Special handling for arrays merging. Currently, only equipment.plist, nebulatextures.plist and
1421 // startextures.plist gets their objects merged.
1422 // A lookup index is required. For the equipment.plist items, this is the index corresponding to the
1423 // EQ_* string, which describes the role of an equipment item and is unique.
1424 // For nebula and star textures, this is the texture filename, although it can be overridden with a
1425 // "key" property
1426 if ([array count] != 0 && ([[fileName lowercaseString] isEqualToString:@"nebulatextures.plist"] ||
1427 [[fileName lowercaseString] isEqualToString:@"startextures.plist"]))
1428 [self handleStarNebulaListMerging:results];
1429
1430 if ([array count] != 0 && [[array objectAtIndex:0] isKindOfClass:[NSArray class]])
1431 {
1432 if ([[fileName lowercaseString] isEqualToString:@"equipment.plist"])
1433 [self handleEquipmentListMerging:results forLookupIndex:3]; // Index 3 is the role string (EQ_*).
1434 }
1435 if (folderName != nil)
1436 {
1437 arrayPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1438 array = [[OOArrayFromFile(arrayPath) mutableCopy] autorelease];
1439 if (array != nil) [results addObject:array];
1440
1441 if ([array count] != 0 && ([[fileName lowercaseString] isEqualToString:@"nebulatextures.plist"] ||
1442 [[fileName lowercaseString] isEqualToString:@"startextures.plist"]))
1443 [self handleStarNebulaListMerging:results];
1444
1445 if ([array count] != 0 && [[array objectAtIndex:0] isKindOfClass:[NSArray class]])
1446 {
1447 if ([[fileName lowercaseString] isEqualToString:@"equipment.plist"])
1448 [self handleEquipmentListMerging:results forLookupIndex:3]; // Index 3 is the role string (EQ_*).
1449 }
1450 }
1451 }
1452
1453 if ([results count] == 0) return nil;
1454
1455 // Merge result
1456 result = [NSMutableArray array];
1457
1458 for (enumerator = [results objectEnumerator]; (array = [enumerator nextObject]); )
1459 {
1460 [result addObjectsFromArray:array];
1461 }
1462 // if we're doing equipment.plist, do equipment overrides now, while the array is still mutable
1463 if ([[fileName lowercaseString] isEqualToString:@"equipment.plist"])
1464 {
1465 [self handleEquipmentOverrides:result];
1466 }
1467 result = [[result copy] autorelease]; // Make immutable
1468 }
1469
1470 if (useCache && result != nil) [cache setObject:result forKey:cacheKey inCache:@"arrays"];
1471
1472 return [NSArray arrayWithArray:result];
1473}
NSArray * OOArrayFromFile(NSString *path)
id objectForKey:inCache:(NSString *inKey,[inCache] NSString *inCacheKey)
OOCacheManager * sharedCache()
NSEnumerator * reversePathEnumerator()
NSEnumerator * pathEnumerator()

References count, handleEquipmentListMerging:forLookupIndex:, handleEquipmentOverrides:, handleStarNebulaListMerging:, nil, OOCacheManager::objectForKey:inCache:, OOArrayFromFile(), pathEnumerator, reversePathEnumerator, OOCacheManager::setObject:forKey:inCache:, and OOCacheManager::sharedCache.

Referenced by arrayFromFilesNamed:inFolder:andMerge:, OOShipRegistry(OODataLoader)::loadDemoShipConditions, and OOShipRegistry(OODataLoader)::loadDemoShips.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ builtInPath

+ (NSString *) builtInPath

Definition at line 205 of file ResourceManager.m.

206{
207#if OOLITE_WINDOWS
208 /* [[NSBundle mainBundle] resourcePath] causes complaints under Windows,
209 because we don't have a properly-built bundle.
210 */
211 return @"Resources";
212#else
213 return [[NSBundle mainBundle] resourcePath];
214#endif
215}

References builtInPath.

Referenced by builtInPath, corePlist:excludedAt:, Universe::descriptions, OOOXPVerifier(OOPrivate)::initWithPath:, LoadExplicitSettings(), logControlDictionary, pathsWithAddOns, rootPaths, shaderBindingTypesDictionary, and whitelistDictionary.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkCacheUpToDateForPaths:

+ (BOOL) checkCacheUpToDateForPaths: (NSArray *) searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1143 of file ResourceManager.m.

1143 :(NSArray *)searchPaths
1144{
1145 /* Check if caches are up to date.
1146 The strategy is to use a two-entry cache. One entry is an array
1147 containing the search paths, the other an array of modification dates
1148 (in the same order). If either fails to match the correct settings,
1149 we delete both.
1150 */
1151 OOCacheManager *cacheMgr = [OOCacheManager sharedCache];
1152 NSFileManager *fmgr = [NSFileManager defaultManager];
1153 BOOL upToDate = YES;
1154 id oldPaths = nil;
1155 NSMutableArray *modDates = nil;
1156 NSEnumerator *pathEnum = nil;
1157 NSString *path = nil;
1158 id modDate = nil;
1159
1160 if (EXPECT_NOT([[NSUserDefaults standardUserDefaults] boolForKey:@"always-flush-cache"]))
1161 {
1162 OOLog(kOOLogCacheExplicitFlush, @"%@", @"Cache explicitly flushed with always-flush-cache preference. Rebuilding from scratch.");
1163 upToDate = NO;
1164 }
1165 else if ([MyOpenGLView pollShiftKey])
1166 {
1167 OOLog(kOOLogCacheExplicitFlush, @"%@", @"Cache explicitly flushed with shift key. Rebuilding from scratch.");
1168 upToDate = NO;
1169 }
1170
1171 oldPaths = [cacheMgr objectForKey:kOOCacheKeySearchPaths inCache:kOOCacheSearchPathModDates];
1172 if (upToDate && ![oldPaths isEqual:searchPaths])
1173 {
1174 // OXPs added/removed
1175 if (oldPaths != nil) OOLog(kOOLogCacheStalePaths, @"%@", @"Cache is stale (search paths have changed). Rebuilding from scratch.");
1176 upToDate = NO;
1177 }
1178
1179 // Build modification date list. (We need this regardless of whether the search paths matched.)
1180
1181 modDates = [NSMutableArray arrayWithCapacity:[searchPaths count]];
1182 for (pathEnum = [searchPaths objectEnumerator]; (path = [pathEnum nextObject]); )
1183 {
1184 modDate = [[fmgr oo_fileAttributesAtPath:path traverseLink:YES] objectForKey:NSFileModificationDate];
1185 if (modDate != nil)
1186 {
1187 // Converts to double because I'm not sure the cache can deal with dates under GNUstep.
1188 modDate = [NSNumber numberWithDouble:[modDate timeIntervalSince1970]];
1189 [modDates addObject:modDate];
1190 }
1191 }
1192
1193 if (upToDate && ![[cacheMgr objectForKey:kOOCacheKeyModificationDates inCache:kOOCacheSearchPathModDates] isEqual:modDates])
1194 {
1195 OOLog(kOOLogCacheStaleDates, @"%@", @"Cache is stale (modification dates have changed). Rebuilding from scratch.");
1196 upToDate = NO;
1197 }
1198
1199 if (!upToDate)
1200 {
1201 [cacheMgr clearAllCaches];
1202 [cacheMgr setObject:searchPaths forKey:kOOCacheKeySearchPaths inCache:kOOCacheSearchPathModDates];
1203 [cacheMgr setObject:modDates forKey:kOOCacheKeyModificationDates inCache:kOOCacheSearchPathModDates];
1204 }
1205 else OOLog(kOOLogCacheUpToDate, @"%@", @"Data cache is up to date.");
1206
1207 return upToDate;
1208}
#define EXPECT_NOT(x)
static NSString *const kOOLogCacheUpToDate
static NSString *const kOOLogCacheStalePaths
static NSString *const kOOCacheSearchPathModDates
static NSString *const kOOLogCacheStaleDates
static NSString *const kOOLogCacheExplicitFlush
static NSString *const kOOCacheKeyModificationDates
void setObject:forKey:inCache:(id inElement,[forKey] NSString *inKey,[inCache] NSString *inCacheKey)

References OOCacheManager::clearAllCaches, EXPECT_NOT, kOOCacheKeyModificationDates, kOOCacheSearchPathModDates, kOOLogCacheExplicitFlush, kOOLogCacheStaleDates, kOOLogCacheStalePaths, kOOLogCacheUpToDate, nil, OOCacheManager::objectForKey:inCache:, OOLog, OOCacheManager::setObject:forKey:inCache:, and OOCacheManager::sharedCache.

Referenced by pathsWithAddOns, and setUseAddOns:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkOXPMessagesInPath:

+ (void) checkOXPMessagesInPath: (NSString *) path
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 583 of file ResourceManager.m.

583 :(NSString *)path
584{
585 NSArray *OXPMessageArray = OOArrayFromFile([path stringByAppendingPathComponent:@"OXPMessages.plist"]);
586
587 if ([OXPMessageArray count] > 0)
588 {
589 unsigned i;
590 for (i = 0; i < [OXPMessageArray count]; i++)
591 {
592 NSString *oxpMessage = [OXPMessageArray oo_stringAtIndex:i];
593 if (oxpMessage)
594 {
595 OOLog(@"oxp.message", @"%@: %@", path, oxpMessage);
596 }
597 }
598 if (sOXPsWithMessagesFound == nil) sOXPsWithMessagesFound = [[NSMutableArray alloc] init];
599 [sOXPsWithMessagesFound addObject:[path lastPathComponent]];
600 }
601}
static NSMutableArray * sOXPsWithMessagesFound

References count, nil, OOArrayFromFile(), OOLog, and sOXPsWithMessagesFound.

Referenced by pathsWithAddOns.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkPotentialPath:path:

+ (void) checkPotentialPath: (NSString *)
path: (NSMutableArray *) searchPaths 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 605 of file ResourceManager.m.

605 :(NSString *)path :(NSMutableArray *)searchPaths
606{
607 NSDictionary *requirements = nil;
608 NSDictionary *manifest = nil;
609 BOOL requirementsMet = YES;
610
611 if (![[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
612 {
613 // OXZ format ignores requires.plist
614 requirements = OODictionaryFromFile([path stringByAppendingPathComponent:@"requires.plist"]);
615 requirementsMet = [self areRequirementsFulfilled:requirements forOXP:path andFile:@"requires.plist"];
616 }
617 if (!requirementsMet)
618 {
619 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
620 OOLog(@"oxp.versionMismatch", @"OXP %@ is incompatible with version %@ of Oolite.", path, version);
621 [self addErrorWithKey:@"oxp-is-incompatible" param1:[path lastPathComponent] param2:version];
622 return;
623 }
624
625 manifest = OODictionaryFromFile([path stringByAppendingPathComponent:@"manifest.plist"]);
626 if (manifest == nil)
627 {
628 if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
629 {
630 OOLog(@"oxp.noManifest", @"OXZ %@ has no manifest.plist", path);
631 [self addErrorWithKey:@"oxz-lacks-manifest" param1:[path lastPathComponent] param2:nil];
632 return;
633 }
634 else
635 {
636 if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxp"])
637 {
638 OOStandardsError([NSString stringWithFormat:@"OXP %@ has no manifest.plist", path]);
639 if (OOEnforceStandards())
640 {
641 [self addErrorWithKey:@"oxp-lacks-manifest" param1:[path lastPathComponent] param2:nil];
642 return;
643 }
644 }
645 // make up a basic manifest in relaxed mode or for base folders
646 manifest = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"__oolite.tmp.%@",path],kOOManifestIdentifier,@"1",kOOManifestVersion,@"OXP without manifest",kOOManifestTitle,@"1",kOOManifestRequiredOoliteVersion,nil];
647 }
648 }
649
650 requirementsMet = [self validateManifest:manifest forOXP:path];
651
652
653 if (requirementsMet)
654 {
655 [searchPaths addObject:path];
656 }
657}
BOOL OOEnforceStandards(void)
void OOStandardsError(NSString *message)
NSDictionary * OODictionaryFromFile(NSString *path)

References addErrorWithKey:param1:param2:, areRequirementsFulfilled:forOXP:andFile:, nil, OODictionaryFromFile(), OOEnforceStandards(), OOLog, OOStandardsError(), and validateManifest:forOXP:.

Referenced by pathsWithAddOns.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ checkVersionCompatibility:forOXP:

+ (BOOL) checkVersionCompatibility: (NSDictionary *) manifest
forOXP: (NSString *) title 

Definition at line 726 of file ResourceManager.m.

726 :(NSDictionary *)manifest forOXP:(NSString *)title
727{
728 NSString *required = [manifest oo_stringForKey:kOOManifestRequiredOoliteVersion defaultValue:nil];
729 NSString *maxRequired = [manifest oo_stringForKey:kOOManifestMaximumOoliteVersion defaultValue:nil];
730 // ignore empty max version string rather than treating as "version 0"
731 if (maxRequired == nil || [maxRequired length] == 0)
732 {
733 return [self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", nil] forOXP:title andFile:@"manifest.plist"];
734 }
735 else
736 {
737 return [self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", maxRequired, @"max_version", nil] forOXP:title andFile:@"manifest.plist"];
738 }
739}

References areRequirementsFulfilled:forOXP:andFile:, and nil.

Referenced by validateManifest:forOXP:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clearCaches

+ (void) clearCaches

Definition at line 2268 of file ResourceManager.m.

2269{
2270 [sSoundCache release];
2271 sSoundCache = nil;
2272 [sStringCache release];
2273 sStringCache = nil;
2274}
static NSMutableDictionary * sSoundCache
static NSMutableDictionary * sStringCache

References clearCaches, nil, sSoundCache, and sStringCache.

Referenced by clearCaches, OOOXZManager::gui, and setUseAddOns:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ corePlist:excludedAt:

+ (BOOL) corePlist: (NSString *) fileName
excludedAt: (NSString *) path 

Definition at line 1219 of file ResourceManager.m.

1219 :(NSString *)fileName excludedAt:(NSString *)path
1220{
1221 if (![path isEqualToString:[self builtInPath]])
1222 {
1223 // non-core paths always okay
1224 return NO;
1225 }
1226 NSString *uaoBit = nil;
1227 foreach (uaoBit, sUseAddOnsParts)
1228 {
1229 if ([uaoBit hasPrefix:SCENARIO_OXP_DEFINITION_NOPLIST])
1230 {
1231 NSString *plist = [uaoBit substringFromIndex:[SCENARIO_OXP_DEFINITION_NOPLIST length]];
1232 if ([plist isEqualToString:fileName])
1233 {
1234 // this core plist file should not be loaded at all
1235 return YES;
1236 }
1237 }
1238 }
1239 // then not excluded
1240 return NO;
1241}
#define SCENARIO_OXP_DEFINITION_NOPLIST
static NSArray * sUseAddOnsParts
NSString * builtInPath()

References builtInPath, nil, SCENARIO_OXP_DEFINITION_NOPLIST, and sUseAddOnsParts.

Here is the call graph for this function:

◆ diagnosticFileLocation

+ (NSString *) diagnosticFileLocation

Definition at line 2244 of file ResourceManager.m.

2245{
2247}
NSString * OOLogHandlerGetLogBasePath(void)

References diagnosticFileLocation, and OOLogHandlerGetLogBasePath().

Referenced by diagnosticFileLocation, and writeDiagnosticData:toFileNamed:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dictionaryFromFilesNamed:inFolder:andMerge:

+ (NSDictionary *) dictionaryFromFilesNamed: (NSString *) fileName
inFolder: (NSString *) folderName
andMerge: (BOOL) mergeFiles 

◆ dictionaryFromFilesNamed:inFolder:mergeMode:cache:

+ (NSDictionary *) dictionaryFromFilesNamed: (NSString *) fileName
inFolder: (NSString *) folderName
mergeMode: (OOResourceMergeMode) mergeMode
cache: (BOOL) useCache 

Definition at line 1252 of file ResourceManager.m.

1252 :(NSString *)fileName
1253 inFolder:(NSString *)folderName
1254 mergeMode:(OOResourceMergeMode)mergeMode
1255 cache:(BOOL)cache
1256{
1257 id result = nil;
1258 NSMutableArray *results = nil;
1259 NSString *cacheKey = nil;
1260 NSString *mergeType = nil;
1261 OOCacheManager *cacheMgr = [OOCacheManager sharedCache];
1262 NSEnumerator *enumerator = nil;
1263 NSString *path = nil;
1264 NSString *dictPath = nil;
1265 NSDictionary *dict = nil;
1266
1267 if (fileName == nil) return nil;
1268
1269 switch (mergeMode)
1270 {
1271 case MERGE_NONE:
1272 mergeType = @"none";
1273 break;
1274
1275 case MERGE_BASIC:
1276 mergeType = @"basic";
1277 break;
1278
1279 case MERGE_SMART:
1280 mergeType = @"smart";
1281 break;
1282 }
1283 if (mergeType == nil)
1284 {
1285 OOLog(kOOLogParameterError, @"Unknown dictionary merge mode %u for %@. (This is an internal programming error, please report it.)", mergeMode, fileName);
1286 return nil;
1287 }
1288
1289 if (cache)
1290 {
1291
1292 if (folderName != nil)
1293 {
1294 cacheKey = [NSString stringWithFormat:@"%@/%@ merge:%@", folderName, fileName, mergeType];
1295 }
1296 else
1297 {
1298 cacheKey = [NSString stringWithFormat:@"%@ merge:%@", fileName, mergeType];
1299 }
1300 result = [cacheMgr objectForKey:cacheKey inCache:@"dictionaries"];
1301 if (result != nil) return result;
1302 }
1303
1304 if (mergeMode == MERGE_NONE)
1305 {
1306 // Find "last" matching dictionary
1307 for (enumerator = [ResourceManager reversePathEnumerator]; (path = [enumerator nextObject]); )
1308 {
1309 if (folderName != nil)
1310 {
1311 dictPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1312 dict = OODictionaryFromFile(dictPath);
1313 if (dict != nil) break;
1314 }
1315 dictPath = [path stringByAppendingPathComponent:fileName];
1316 dict = OODictionaryFromFile(dictPath);
1317 if (dict != nil) break;
1318 }
1319 result = dict;
1320 }
1321 else
1322 {
1323 // Find all matching dictionaries
1324 results = [NSMutableArray array];
1325 for (enumerator = [ResourceManager pathEnumerator]; (path = [enumerator nextObject]); )
1326 {
1327 if ([ResourceManager corePlist:fileName excludedAt:path])
1328 {
1329 continue;
1330 }
1331 dictPath = [path stringByAppendingPathComponent:fileName];
1332 dict = OODictionaryFromFile(dictPath);
1333 if (dict != nil) [results addObject:dict];
1334 if (folderName != nil)
1335 {
1336 dictPath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1337 dict = OODictionaryFromFile(dictPath);
1338 if (dict != nil) [results addObject:dict];
1339 }
1340 }
1341
1342 if ([results count] == 0) return nil;
1343
1344 // Merge result
1345 result = [NSMutableDictionary dictionary];
1346
1347 for (enumerator = [results objectEnumerator]; (dict = [enumerator nextObject]); )
1348 {
1349 if (mergeMode == MERGE_SMART) [result mergeEntriesFromDictionary:dict];
1350 else [result addEntriesFromDictionary:dict];
1351 }
1352 result = [[result copy] autorelease]; // Make immutable
1353 }
1354
1355 if (cache && result != nil) [cacheMgr setObject:result forKey:cacheKey inCache:@"dictionaries"];
1356
1357 return result;
1358}
NSString *const kOOLogParameterError
Definition OOLogging.m:647
OOResourceMergeMode
@ MERGE_SMART
@ MERGE_NONE
@ MERGE_BASIC

References count, kOOLogParameterError, MERGE_BASIC, MERGE_NONE, MERGE_SMART, nil, OOCacheManager::objectForKey:inCache:, OODictionaryFromFile(), OOLog, pathEnumerator, reversePathEnumerator, OOCacheManager::setObject:forKey:inCache:, and OOCacheManager::sharedCache.

Referenced by handleEquipmentOverrides:, OOCommodities::init, PlayerEntity(KeyMapper)::initCheckingDictionary, PlayerEntity(Controls)::initKeyConfigSettings, MyOpenGLView::initKeyMappingData, PlayerEntity(KeyMapperInternal)::keyboardDescription:, PlayerEntity(KeyMapper)::keyboardLayoutList, OOShipRegistry(OODataLoader)::loadAndApplyShipDataOverrides:, OOShipRegistry(OODataLoader)::loadAndMergeShipyard:, OOShipRegistry(OODataLoader)::loadShipData, OOInitDebugSupport(), and Universe::setUpSettings.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ directoryExists:create:

+ (BOOL) directoryExists: (NSString *) inPath
create: (BOOL) inCreate 
implementation

Definition at line 2218 of file ResourceManager.m.

2218 :(NSString *)inPath create:(BOOL)inCreate
2219{
2220 BOOL exists, directory;
2221 NSFileManager *fmgr = [NSFileManager defaultManager];
2222
2223 exists = [fmgr fileExistsAtPath:inPath isDirectory:&directory];
2224
2225 if (exists && !directory)
2226 {
2227 OOLog(@"resourceManager.write.buildPath.failed", @"Expected %@ to be a folder, but it is a file.", inPath);
2228 return NO;
2229 }
2230 if (!exists)
2231 {
2232 if (!inCreate) return NO;
2233 if (![fmgr oo_createDirectoryAtPath:inPath attributes:nil])
2234 {
2235 OOLog(@"resourceManager.write.buildPath.failed", @"Could not create folder %@.", inPath);
2236 return NO;
2237 }
2238 }
2239
2240 return YES;
2241}

References nil, and OOLog.

◆ errors

+ (NSString *) errors

Definition at line 133 of file ResourceManager.m.

134{
135 NSArray *error = nil;
136 NSUInteger i, count;
137 NSMutableArray *result = nil;
138 NSString *errStr = nil;
139
140 count = [sErrors count];
141 if (count == 0) return nil;
142
143 // Expand error messages. This is deferred for localizability.
144 result = [NSMutableArray arrayWithCapacity:count];
145 for (i = 0; i != count; ++i)
146 {
147 error = [sErrors objectAtIndex:i];
148 errStr = [UNIVERSE descriptionForKey:[error oo_stringAtIndex:0]];
149 if (errStr != nil)
150 {
151 errStr = [NSString stringWithFormat:errStr, [error objectAtIndex:1], [error objectAtIndex:2]];
152 [result addObject:errStr];
153 }
154 }
155
156 [sErrors release];
157 sErrors = nil;
158
159 return [result componentsJoinedByString:@"\n"];
160}

References count, errors, nil, and sErrors.

Referenced by errors, and PlayerEntity::setGuiToIntroFirstGo:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ filterSearchPathsByScenario:

+ (void) filterSearchPathsByScenario: (NSMutableArray *) searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1023 of file ResourceManager.m.

1023 :(NSMutableArray *)searchPaths
1024{
1025 NSDictionary *manifest = nil;
1026 NSString *identifier = nil;
1027 NSArray *identifiers = [sOXPManifests allKeys];
1028
1029 // take a copy because we'll mutate the original
1030 // foreach identified add-on
1031 foreach (identifier, identifiers)
1032 {
1033 manifest = [sOXPManifests objectForKey:identifier];
1034 if (manifest != nil)
1035 {
1036 if (![ResourceManager manifestAllowedByScenario:manifest])
1037 {
1038 // then we don't need this one
1039 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
1040 [sOXPManifests removeObjectForKey:identifier];
1041 }
1042 }
1043 }
1044}

References nil.

Referenced by pathsWithAddOns.

Here is the caller graph for this function:

◆ filterSearchPathsForConflicts:

+ (void) filterSearchPathsForConflicts: (NSMutableArray *) searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 848 of file ResourceManager.m.

848 :(NSMutableArray *)searchPaths
849{
850 NSDictionary *manifest = nil;
851 NSString *identifier = nil;
852 NSArray *identifiers = [sOXPManifests allKeys];
853
854 // take a copy because we'll mutate the original
855 // foreach identified add-on
856 foreach (identifier, identifiers)
857 {
858 manifest = [sOXPManifests objectForKey:identifier];
859 if (manifest != nil)
860 {
861 if ([self manifestHasConflicts:manifest logErrors:YES])
862 {
863 // then we have a conflict, so remove this path
864 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
865 [sOXPManifests removeObjectForKey:identifier];
866 }
867 }
868 }
869}

References nil.

Referenced by pathsWithAddOns.

Here is the caller graph for this function:

◆ filterSearchPathsForRequirements:

+ (BOOL) filterSearchPathsForRequirements: (NSMutableArray *) searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 941 of file ResourceManager.m.

941 :(NSMutableArray *)searchPaths
942{
943 NSDictionary *manifest = nil;
944 NSString *identifier = nil;
945 NSArray *identifiers = [sOXPManifests allKeys];
946
947 sAllMet = YES;
948
949 // take a copy because we'll mutate the original
950 // foreach identified add-on
951 foreach (identifier, identifiers)
952 {
953 manifest = [sOXPManifests objectForKey:identifier];
954 if (manifest != nil)
955 {
956 if ([self manifestHasMissingDependencies:manifest logErrors:YES])
957 {
958 // then we have a missing requirement, so remove this path
959 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
960 [sOXPManifests removeObjectForKey:identifier];
961 sAllMet = NO;
962 }
963 }
964 }
965
966 return sAllMet;
967}
static BOOL sAllMet

References nil, and sAllMet.

◆ filterSearchPathsToExcludeScenarioOnlyPaths:

+ (void) filterSearchPathsToExcludeScenarioOnlyPaths: (NSMutableArray *) searchPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 999 of file ResourceManager.m.

999 :(NSMutableArray *)searchPaths
1000{
1001 NSDictionary *manifest = nil;
1002 NSString *identifier = nil;
1003 NSArray *identifiers = [sOXPManifests allKeys];
1004
1005 // take a copy because we'll mutate the original
1006 // foreach identified add-on
1007 foreach (identifier, identifiers)
1008 {
1009 manifest = [sOXPManifests objectForKey:identifier];
1010 if (manifest != nil)
1011 {
1012 if ([[manifest oo_arrayForKey:kOOManifestTags] containsObject:kOOManifestTagScenarioOnly])
1013 {
1014 [searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
1015 [sOXPManifests removeObjectForKey:identifier];
1016 }
1017 }
1018 }
1019}
static NSString *const kOOManifestTags
static NSString *const kOOManifestTagScenarioOnly

References kOOManifestTags, kOOManifestTagScenarioOnly, and nil.

Referenced by pathsWithAddOns.

Here is the caller graph for this function:

◆ handleEquipmentListMerging:forLookupIndex:

+ (void) handleEquipmentListMerging: (NSMutableArray *) arrayToProcess
forLookupIndex: (unsigned) lookupIndex 

Definition at line 1479 of file ResourceManager.m.

1479 : (NSMutableArray *)arrayToProcess forLookupIndex:(unsigned)lookupIndex
1480{
1481 NSUInteger i,j,k;
1482 NSMutableArray *refArray = [arrayToProcess objectAtIndex:[arrayToProcess count] - 1];
1483
1484 // Any change to refArray will directly modify arrayToProcess.
1485
1486 for (i = 0; i < [refArray count]; i++)
1487 {
1488 for (j = 0; j < [arrayToProcess count] - 1; j++)
1489 {
1490 NSUInteger count = [[arrayToProcess oo_arrayAtIndex:j] count];
1491 if (count == 0) continue;
1492
1493 for (k=0; k < count; k++)
1494 {
1495 id processValue = [[[arrayToProcess oo_arrayAtIndex:j] oo_arrayAtIndex:k] oo_objectAtIndex:lookupIndex defaultValue:nil];
1496 id refValue = [[refArray oo_arrayAtIndex:i] oo_objectAtIndex:lookupIndex defaultValue:nil];
1497
1498 if ([processValue isEqual:refValue])
1499 {
1500 [[arrayToProcess objectAtIndex:j] replaceObjectAtIndex:k withObject:[refArray objectAtIndex:i]];
1501 [refArray removeObjectAtIndex:i];
1502 }
1503 }
1504 }
1505 }
1506 // arrayToProcess has been processed at this point. Any necessary merging has been done.
1507}

References count.

Referenced by arrayFromFilesNamed:inFolder:andMerge:cache:.

Here is the caller graph for this function:

◆ handleEquipmentOverrides:

+ (void) handleEquipmentOverrides: (NSMutableArray *) arrayToProcess

Definition at line 1514 of file ResourceManager.m.

1514 : (NSMutableArray *)arrayToProcess
1515{
1516 NSEnumerator *equipKeyEnum = nil;
1517 NSString *equipKey = nil;
1518 NSDictionary *overrides = nil;
1519 NSDictionary *overridesEntry = nil;
1520 int i;
1521
1522 overrides = [ResourceManager dictionaryFromFilesNamed:@"equipment-overrides.plist"
1523 inFolder:@"Config"
1524 mergeMode:MERGE_SMART
1525 cache:NO];
1526
1527 // cycle through all the equipment keys found in override files
1528 for (equipKeyEnum = [overrides keyEnumerator]; (equipKey = [equipKeyEnum nextObject]); )
1529 {
1530 overridesEntry = [overrides objectForKey:equipKey];
1531 // loop through our data array to find a match
1532 for (i = 0; i < [arrayToProcess count]; i++)
1533 {
1534 NSMutableArray *equipArray = [[[arrayToProcess objectAtIndex:i] mutableCopy] autorelease];
1535 id refValue = [equipArray oo_objectAtIndex:EQUIPMENT_KEY_INDEX defaultValue:nil];
1536 // does the overridden equipment item exist in the equipment array? if so, get working
1537 if ([equipKey isEqual:refValue])
1538 {
1539 NSEnumerator *infoKeyEnum = nil;
1540 NSString *infoKey;
1541 // cycle through all the properties found for this equipment key in the overrides file
1542 for (infoKeyEnum = [overridesEntry keyEnumerator]; (infoKey = [infoKeyEnum nextObject]); )
1543 {
1544 // special cases for the array items that don't have a direct keyname
1545 if ([infoKey isEqualToString:@"techlevel"])
1546 [equipArray replaceObjectAtIndex:EQUIPMENT_TECH_LEVEL_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1547 else if ([infoKey isEqualToString:@"price"])
1548 [equipArray replaceObjectAtIndex:EQUIPMENT_PRICE_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1549 else if ([infoKey isEqualToString:@"short_description"])
1550 [equipArray replaceObjectAtIndex:EQUIPMENT_SHORT_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1551 else if ([infoKey isEqualToString:@"name"])
1552 [equipArray replaceObjectAtIndex:EQUIPMENT_SHORT_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1553 else if ([infoKey isEqualToString:@"long_description"])
1554 [equipArray replaceObjectAtIndex:EQUIPMENT_LONG_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1555 else if ([infoKey isEqualToString:@"description"])
1556 [equipArray replaceObjectAtIndex:EQUIPMENT_LONG_DESC_INDEX withObject:[overridesEntry objectForKey:infoKey]];
1557 else
1558 {
1559 NSMutableDictionary *extra = nil;
1560 // for everything else
1561 // do we actually have an extras dictionary?
1562 if (![equipArray oo_dictionaryAtIndex:EQUIPMENT_EXTRA_INFO_INDEX])
1563 {
1564 // if not, create a blank one we can add to
1565 extra = [NSMutableDictionary dictionary];
1566 }
1567 else
1568 {
1569 extra = [[equipArray oo_dictionaryAtIndex:EQUIPMENT_EXTRA_INFO_INDEX] mutableCopy];
1570 }
1571 // special case for weapon_info && script_info, which are child dictionaries
1572 if ([infoKey isEqualToString:@"weapon_info"] || [infoKey isEqualToString:@"script_info"])
1573 {
1574 NSEnumerator *subEnum = nil;
1575 NSString *subKey;
1576 NSMutableDictionary *subInfo = nil;
1577 NSDictionary *subOverrides = nil;
1578 // do we actually have a weapon_info/script_info dictionary?
1579 if (![extra oo_dictionaryForKey:infoKey])
1580 {
1581 // if not, create a blank dictionary we can add to
1582 subInfo = [NSMutableDictionary dictionary];
1583 }
1584 else
1585 {
1586 subInfo = [[extra oo_dictionaryForKey:infoKey] mutableCopy];
1587 }
1588 subOverrides = [overridesEntry oo_dictionaryForKey:infoKey];
1589 // cycle through all the sub keys found in the overrides file for this equipment key item
1590 for (subEnum = [subOverrides keyEnumerator]; (subKey = [subEnum nextObject]); )
1591 {
1592 [subInfo setObject:[subOverrides objectForKey:subKey] forKey:subKey];
1593 }
1594 [extra setObject:[[subInfo copy] autorelease] forKey:infoKey];
1595 }
1596 else
1597 {
1598 // for all other keys in the extras dictionary
1599 [extra setObject:[overridesEntry objectForKey:infoKey] forKey:infoKey];
1600 }
1601 [equipArray replaceObjectAtIndex:EQUIPMENT_EXTRA_INFO_INDEX withObject:[[extra copy] autorelease]];
1602 }
1603 }
1604 [arrayToProcess replaceObjectAtIndex:i withObject:equipArray];
1605 }
1606 }
1607 }
1608}
@ EQUIPMENT_EXTRA_INFO_INDEX
Definition Universe.h:88
NSDictionary * dictionaryFromFilesNamed:inFolder:mergeMode:cache:(NSString *fileName,[inFolder] NSString *folderName,[mergeMode] OOResourceMergeMode mergeMode,[cache] BOOL useCache)

References dictionaryFromFilesNamed:inFolder:mergeMode:cache:, EQUIPMENT_EXTRA_INFO_INDEX, and nil.

Referenced by arrayFromFilesNamed:inFolder:andMerge:cache:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleStarNebulaListMerging:

+ (void) handleStarNebulaListMerging: (NSMutableArray *) arrayToProcess

Definition at line 1613 of file ResourceManager.m.

1613 : (NSMutableArray *)arrayToProcess
1614{
1615 NSUInteger i,j,k;
1616 NSMutableArray *refArray = [arrayToProcess objectAtIndex:[arrayToProcess count] - 1];
1617
1618 // Any change to refArray will directly modify arrayToProcess.
1619 for (i = 0; i < [refArray count]; i++)
1620 {
1621 for (j = 0; j < [arrayToProcess count] - 1; j++)
1622 {
1623 NSUInteger count = [[arrayToProcess oo_arrayAtIndex:j] count];
1624 if (count == 0) continue;
1625
1626 for (k = 0; k < count; k++)
1627 {
1628 id processValue = [[arrayToProcess oo_arrayAtIndex:j] oo_objectAtIndex:k defaultValue:nil];
1629 id refValue = [refArray oo_objectAtIndex:i defaultValue:nil];
1630 NSString *key1 = nil;
1631 NSString *key2 = nil;
1632
1633 if ([processValue isKindOfClass:[NSString class]])
1634 {
1635 key1 = processValue;
1636 }
1637 else if ([processValue isKindOfClass:[NSDictionary class]])
1638 {
1639 if (![processValue objectForKey:@"key"])
1640 {
1641 key1 = [processValue objectForKey:@"texture"];
1642 }
1643 else
1644 {
1645 key1 = [processValue objectForKey:@"key"];
1646 }
1647 }
1648 if (!key1) continue;
1649
1650 if ([refValue isKindOfClass:[NSString class]])
1651 {
1652 key2 = refValue;
1653 }
1654 else if ([refValue isKindOfClass:[NSDictionary class]])
1655 {
1656 if (![refValue objectForKey:@"key"])
1657 {
1658 key2 = [refValue objectForKey:@"texture"];
1659 }
1660 else
1661 {
1662 key2 = [refValue objectForKey:@"key"];
1663 }
1664 }
1665 if (!key2) continue;
1666
1667 if ([key1 isEqual:key2])
1668 {
1669 [[arrayToProcess objectAtIndex:j] replaceObjectAtIndex:k withObject:[refArray objectAtIndex:i]];
1670 [refArray removeObjectAtIndex:i];
1671 }
1672
1673 }
1674 }
1675 }
1676 // arrayToProcess has been processed at this point. Any necessary merging has been done.
1677}

References count, and nil.

Referenced by arrayFromFilesNamed:inFolder:andMerge:cache:.

Here is the caller graph for this function:

◆ loadScripts

+ (NSDictionary *) loadScripts

Definition at line 2088 of file ResourceManager.m.

2089{
2090 NSMutableDictionary *loadedScripts = nil;
2091 NSArray *results = nil;
2092 NSArray *paths = nil;
2093 NSEnumerator *pathEnum = nil;
2094 NSString *path = nil;
2095 NSEnumerator *scriptEnum = nil;
2096 OOScript *script = nil;
2097 NSString *name = nil;
2098 NSAutoreleasePool *pool = nil;
2099
2100 OOLog(@"script.load.world.begin", @"%@", @"Loading world scripts...");
2101
2102 loadedScripts = [NSMutableDictionary dictionary];
2104 for (pathEnum = [paths objectEnumerator]; (path = [pathEnum nextObject]); )
2105 {
2106 // excluding world-scripts.plist also excludes script.js / script.plist
2107 // though as those core files don't and won't exist this is not
2108 // a problem.
2109 if (![ResourceManager corePlist:@"world-scripts.plist" excludedAt:path])
2110 {
2111 pool = [[NSAutoreleasePool alloc] init];
2112
2113 @try
2114 {
2115 results = [OOScript worldScriptsAtPath:[path stringByAppendingPathComponent:@"Config"]];
2116 if (results == nil) results = [OOScript worldScriptsAtPath:path];
2117 if (results != nil)
2118 {
2119 for (scriptEnum = [results objectEnumerator]; (script = [scriptEnum nextObject]); )
2120 {
2121 name = [script name];
2122 if (name != nil) [loadedScripts setObject:script forKey:name];
2123 else OOLog(@"script.load.unnamed", @"Discarding anonymous script %@", script);
2124 }
2125 }
2126 }
2127 @catch (NSException *exception)
2128 {
2129 OOLog(@"script.load.exception", @"***** %s encountered exception %@ (%@) while trying to load script from %@ -- ignoring this location.", __PRETTY_FUNCTION__, [exception name], [exception reason], path);
2130 // Ignore exception and keep loading other scripts.
2131 }
2132
2133 [pool release];
2134 }
2135 }
2136
2137 if (OOLogWillDisplayMessagesInClass(@"script.load.world.listAll"))
2138 {
2139 NSUInteger count = [loadedScripts count];
2140 if (count != 0)
2141 {
2142 NSMutableArray *displayNames = nil;
2143 NSEnumerator *scriptEnum = nil;
2144 OOScript *script = nil;
2145 NSString *displayString = nil;
2146
2147 displayNames = [NSMutableArray arrayWithCapacity:count];
2148
2149 for (scriptEnum = [loadedScripts objectEnumerator]; (script = [scriptEnum nextObject]); )
2150 {
2151 [displayNames addObject:[script displayName]];
2152 }
2153
2154 displayString = [[displayNames sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@"\n "];
2155 OOLog(@"script.load.world.listAll", @"Loaded %llu world scripts:\n %@", count, displayString);
2156 }
2157 else
2158 {
2159 OOLog(@"script.load.world.listAll", @"%@", @"*** No world scripts loaded.");
2160 }
2161 }
2162
2163 return loadedScripts;
2164}
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
Definition OOLogging.m:144
NSString * name()
Definition OOScript.m:256
NSArray * worldScriptsAtPath:(NSString *path)
Definition OOScript.m:45
NSString * displayName()
Definition OOScript.m:277

References count, OOScript::displayName, loadScripts, OOScript::name, nil, OOLog, OOLogWillDisplayMessagesInClass(), paths, and OOScript::worldScriptsAtPath:.

Referenced by loadScripts, and PlayerEntity::setUpAndConfirmOK:saveGame:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LogClassKeyRoot

+ (NSString *) LogClassKeyRoot (NSString *) key
implementation

Definition at line 1698 of file ResourceManager.m.

1699{
1700 NSRange dot = [key rangeOfString:@"."];
1701 if (dot.location != NSNotFound)
1702 {
1703 return [key substringToIndex:dot.location];
1704 }
1705 else
1706 {
1707 return key;
1708 }
1709}

Referenced by logControlDictionary.

Here is the caller graph for this function:

◆ logControlDictionary

+ (NSDictionary *) logControlDictionary

Definition at line 1712 of file ResourceManager.m.

1713{
1714 // Load built-in copy of logcontrol.plist.
1715 NSString *path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"]
1716 stringByAppendingPathComponent:@"logcontrol.plist"];
1717 NSMutableDictionary *logControl = [NSMutableDictionary dictionaryWithDictionary:OODictionaryFromFile(path)];
1718 if (logControl == nil) logControl = [NSMutableDictionary dictionary];
1719
1720 // Build list of root log message classes that appear in the built-in list.
1721 NSMutableSet *coreRoots = [NSMutableSet set];
1722 NSString *key = nil;
1723 foreachkey(key, logControl)
1724 {
1725 [coreRoots addObject:LogClassKeyRoot(key)];
1726 }
1727
1728 NSArray *rootPaths = [self rootPaths];
1729 NSString *configPath = nil;
1730 NSDictionary *dict = nil;
1731
1732 // Look for logcontrol.plists inside OXPs (but not in root paths). These are not allowed to define keys in hierarchies used by the build-in one.
1733 NSEnumerator *pathEnum = [self pathEnumerator];
1734 while ((path = [pathEnum nextObject]))
1735 {
1736 if ([rootPaths containsObject:path]) continue;
1737
1738 configPath = [[path stringByAppendingPathComponent:@"Config"]
1739 stringByAppendingPathComponent:@"logcontrol.plist"];
1740 dict = OODictionaryFromFile(configPath);
1741 if (dict == nil)
1742 {
1743 configPath = [path stringByAppendingPathComponent:@"logcontrol.plist"];
1744 dict = OODictionaryFromFile(configPath);
1745 }
1746 foreachkey (key, dict)
1747 {
1748 if (![coreRoots containsObject:LogClassKeyRoot(key)])
1749 {
1750 [logControl setObject:[dict objectForKey:key] forKey:key];
1751 }
1752 }
1753 }
1754
1755 // Now, look for logcontrol.plists in root paths, i.e. not within OXPs. These are allowed to override the built-in copy.
1756 pathEnum = [rootPaths objectEnumerator];
1757 while ((path = [pathEnum nextObject]))
1758 {
1759 configPath = [[path stringByAppendingPathComponent:@"Config"]
1760 stringByAppendingPathComponent:@"logcontrol.plist"];
1761 dict = OODictionaryFromFile(configPath);
1762 if (dict == nil)
1763 {
1764 configPath = [path stringByAppendingPathComponent:@"logcontrol.plist"];
1765 dict = OODictionaryFromFile(configPath);
1766 }
1767 foreachkey (key, dict)
1768 {
1769 [logControl setObject:[dict objectForKey:key] forKey:key];
1770 }
1771 }
1772
1773 // Finally, look in preferences, which can override all of the above.
1774 dict = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"logging-enable"];
1775 if (dict != nil) [logControl addEntriesFromDictionary:dict];
1776
1777 return logControl;
1778}
#define foreachkey(VAR, DICT)
Definition OOCocoa.h:378
static NSString * LogClassKeyRoot(NSString *key)

References builtInPath, foreachkey, LogClassKeyRoot, logControlDictionary, nil, OODictionaryFromFile(), pathEnumerator, and rootPaths.

Referenced by LoadExplicitSettings(), and logControlDictionary.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ logPaths

+ (void) logPaths
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 2250 of file ResourceManager.m.

2251{
2252 NSMutableArray *displayPaths = nil;
2253 NSEnumerator *pathEnum = nil;
2254 NSString *path = nil;
2255
2256 // Prettify paths for logging.
2257 displayPaths = [NSMutableArray arrayWithCapacity:[sSearchPaths count]];
2258 for (pathEnum = [sSearchPaths objectEnumerator]; (path = [pathEnum nextObject]); )
2259 {
2260 [displayPaths addObject:[[path stringByStandardizingPath] stringByAbbreviatingWithTildeInPath]];
2261 }
2262
2263 OOLog(@"searchPaths.dumpAll", @"Resource paths: %@\n %@", sUseAddOns, [displayPaths componentsJoinedByString:@"\n "]);
2264
2265}
static NSString * sUseAddOns

References logPaths, nil, OOLog, sSearchPaths, and sUseAddOns.

Referenced by logPaths, and setUseAddOns:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ manifest:HasUnmetDependency:logErrors:

+ (BOOL) manifest: (NSDictionary *) manifest
HasUnmetDependency: (NSDictionary *) required
logErrors: (BOOL) logErrors 

Definition at line 894 of file ResourceManager.m.

894 :(NSDictionary *)manifest HasUnmetDependency:(NSDictionary *)required logErrors:(BOOL)logErrors
895{
896 NSString *requiredID = [required oo_stringForKey:kOOManifestRelationIdentifier];
897 NSMutableDictionary *requiredManifest = [sOXPManifests objectForKey:requiredID];
898 // if the other OXP is in the list
899 BOOL requirementsMet = NO;
900 if (requiredManifest != nil)
901 {
902 // then check versions
903 if ([self matchVersions:required withVersion:[requiredManifest oo_stringForKey:kOOManifestVersion]])
904 {
905 requirementsMet = YES;
906 /* Mark the requiredManifest as a dependency of the
907 * requiring manifest */
908 NSSet *reqby = [requiredManifest oo_setForKey:kOOManifestRequiredBy defaultValue:[NSSet set]];
909 NSUInteger reqbycount = [reqby count];
910 /* then add this manifest to its required set. This is
911 * done without checking if it's already there, because
912 * the list of nested requirements may have changed. */
913 reqby = [reqby setByAddingObject:[manifest oo_stringForKey:kOOManifestIdentifier]];
914 // *and* anything that requires this OXP to be installed
915 reqby = [reqby setByAddingObjectsFromSet:[manifest oo_setForKey:kOOManifestRequiredBy]];
916 if (reqbycount < [reqby count])
917 {
918 /* Then the set has increased in size. To handle
919 * potential cases with nested dependencies, need to
920 * re-run the requirement filter until all the sets
921 * stabilise. */
922 sAllMet = NO;
923 }
924 // and push back into the requiring manifest
925 [requiredManifest setObject:reqby forKey:kOOManifestRequiredBy];
926 }
927 }
928 if (!requirementsMet)
929 {
930 if (logErrors)
931 {
932 [self addErrorWithKey:@"oxp-required" param1:[manifest oo_stringForKey:kOOManifestTitle] param2:[required oo_stringForKey:kOOManifestRelationDescription defaultValue:[required oo_stringForKey:kOOManifestRelationIdentifier]]];
933 OOLog(@"oxp.requirementMissing",@"OXP %@ had unmet requirements and was removed from the loading list",[[manifest oo_stringForKey:kOOManifestFilePath] lastPathComponent]);
934 }
935 return YES;
936 }
937 return NO;
938}
static NSString *const kOOManifestVersion
static NSString *const kOOManifestFilePath

References addErrorWithKey:param1:param2:, count, kOOManifestFilePath, kOOManifestVersion, nil, OOLog, and sAllMet.

Here is the call graph for this function:

◆ manifestAllowedByScenario:

+ (BOOL) manifestAllowedByScenario: (NSDictionary *) manifest
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1047 of file ResourceManager.m.

1047 :(NSDictionary *)manifest
1048{
1049 /* Checks for a couple of "never happens" cases */
1050#ifndef NDEBUG
1051 // test string
1052 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_ALL])
1053 {
1054 OOLog(@"scenario.check", @"%@", @"Checked scenario allowances in all state - this is an internal error; please report this");
1055 return YES;
1056 }
1057 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_NONE])
1058 {
1059 OOLog(@"scenario.check", @"%@", @"Checked scenario allowances in none state - this is an internal error; please report this");
1060 return NO;
1061 }
1062#endif
1063 if ([[manifest oo_stringForKey:kOOManifestIdentifier] isEqualToString:@"org.oolite.oolite"])
1064 {
1065 // the core data is always allowed!
1066 return YES;
1067 }
1068
1069 NSString *uaoBit = nil;
1070 BOOL result = NO;
1071 foreach (uaoBit, sUseAddOnsParts)
1072 {
1073 if ([uaoBit hasPrefix:SCENARIO_OXP_DEFINITION_BYID])
1074 {
1075 result |= [ResourceManager manifestAllowedByScenario:manifest withIdentifier:[uaoBit substringFromIndex:[SCENARIO_OXP_DEFINITION_BYID length]]];
1076 }
1077 else if ([uaoBit hasPrefix:SCENARIO_OXP_DEFINITION_BYTAG])
1078 {
1079 result |= [ResourceManager manifestAllowedByScenario:manifest withTag:[uaoBit substringFromIndex:[SCENARIO_OXP_DEFINITION_BYTAG length]]];
1080 }
1081 }
1082 return result;
1083}
static NSString *const kOOManifestIdentifier
#define SCENARIO_OXP_DEFINITION_BYID
#define SCENARIO_OXP_DEFINITION_NONE
#define SCENARIO_OXP_DEFINITION_ALL
#define SCENARIO_OXP_DEFINITION_BYTAG
BOOL manifestAllowedByScenario:withTag:(NSDictionary *manifest, [withTag] NSString *tag)
BOOL manifestAllowedByScenario:withIdentifier:(NSDictionary *manifest, [withIdentifier] NSString *identifier)

References kOOManifestIdentifier, manifestAllowedByScenario:withIdentifier:, manifestAllowedByScenario:withTag:, nil, OOLog, SCENARIO_OXP_DEFINITION_ALL, SCENARIO_OXP_DEFINITION_BYID, SCENARIO_OXP_DEFINITION_BYTAG, SCENARIO_OXP_DEFINITION_NONE, sUseAddOns, and sUseAddOnsParts.

Here is the call graph for this function:

◆ manifestAllowedByScenario:withIdentifier:

+ (BOOL) manifestAllowedByScenario: (NSDictionary *) manifest
withIdentifier: (NSString *) identifier 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1086 of file ResourceManager.m.

1086 :(NSDictionary *)manifest withIdentifier:(NSString *)identifier
1087{
1088 if ([[manifest oo_stringForKey:kOOManifestIdentifier] isEqualToString:identifier])
1089 {
1090 // manifest has the identifier - easy
1091 return YES;
1092 }
1093 // manifest is also allowed if a manifest with that identifier
1094 // requires it to be installed
1095 if ([[manifest oo_setForKey:kOOManifestRequiredBy] containsObject:identifier])
1096 {
1097 return YES;
1098 }
1099 // otherwise, no
1100 return NO;
1101}
static NSString *const kOOManifestRequiredBy

References kOOManifestIdentifier, and kOOManifestRequiredBy.

Referenced by manifestAllowedByScenario:.

Here is the caller graph for this function:

◆ manifestAllowedByScenario:withTag:

+ (BOOL) manifestAllowedByScenario: (NSDictionary *) manifest
withTag: (NSString *) tag 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1104 of file ResourceManager.m.

1104 :(NSDictionary *)manifest withTag:(NSString *)tag
1105{
1106 if ([[manifest oo_arrayForKey:kOOManifestTags] containsObject:tag])
1107 {
1108 // manifest has the tag - easy
1109 return YES;
1110 }
1111 // manifest is also allowed if a manifest with that tag
1112 // requires it to be installed
1113 NSSet *reqby = [manifest oo_setForKey:kOOManifestRequiredBy];
1114 if (reqby != nil)
1115 {
1116 NSString *identifier = nil;
1117 foreach (identifier, reqby)
1118 {
1119 NSDictionary *reqManifest = [sOXPManifests oo_dictionaryForKey:identifier defaultValue:nil];
1120 // need to check for nil as this one may already have been ruled out
1121 if (reqManifest != nil && [[reqManifest oo_arrayForKey:kOOManifestTags] containsObject:tag])
1122 {
1123 return YES;
1124 }
1125 }
1126 }
1127 // otherwise, no
1128 return NO;
1129}

References kOOManifestTags, and nil.

Referenced by manifestAllowedByScenario:.

Here is the caller graph for this function:

◆ manifestForIdentifier:

+ (NSDictionary *) manifestForIdentifier: (NSString *) identifier

Definition at line 577 of file ResourceManager.m.

577 :(NSString *)identifier
578{
579 return [sOXPManifests objectForKey:identifier];
580}

Referenced by OOOXZManager(NSURLConnectionDataDelegate)::installableState:, and OOOXZManager::showInstallOptions.

Here is the caller graph for this function:

◆ manifestHasConflicts:logErrors:

+ (BOOL) manifestHasConflicts: (NSDictionary *) manifest
logErrors: (BOOL) logErrors 

Definition at line 812 of file ResourceManager.m.

812 :(NSDictionary *)manifest logErrors:(BOOL)logErrors
813{
814 NSDictionary *conflicting = nil;
815 NSDictionary *conflictManifest = nil;
816 NSString *conflictID = nil;
817 NSArray *conflicts = nil;
818
819 conflicts = [manifest oo_arrayForKey:kOOManifestConflictOXPs defaultValue:nil];
820 // if it has a non-empty conflict_oxps list
821 if (conflicts != nil && [conflicts count] > 0)
822 {
823 // iterate over that list
824 foreach (conflicting, conflicts)
825 {
826 conflictID = [conflicting oo_stringForKey:kOOManifestRelationIdentifier];
827 conflictManifest = [sOXPManifests objectForKey:conflictID];
828 // if the other OXP is in the list
829 if (conflictManifest != nil)
830 {
831 // then check versions
832 if ([self matchVersions:conflicting withVersion:[conflictManifest oo_stringForKey:kOOManifestVersion]])
833 {
834 if (logErrors)
835 {
836 [self addErrorWithKey:@"oxp-conflict" param1:[manifest oo_stringForKey:kOOManifestTitle] param2:[conflictManifest oo_stringForKey:kOOManifestTitle]];
837 OOLog(@"oxp.conflict",@"OXP %@ conflicts with %@ and was removed from the loading list",[[manifest oo_stringForKey:kOOManifestFilePath] lastPathComponent],[[conflictManifest oo_stringForKey:kOOManifestFilePath] lastPathComponent]);
838 }
839 return YES;
840 }
841 }
842 }
843 }
844 return NO;
845}

References addErrorWithKey:param1:param2:, count, kOOManifestFilePath, kOOManifestVersion, nil, and OOLog.

Here is the call graph for this function:

◆ manifestHasMissingDependencies:logErrors:

+ (BOOL) manifestHasMissingDependencies: (NSDictionary *) manifest
logErrors: (BOOL) logErrors 

Definition at line 872 of file ResourceManager.m.

872 :(NSDictionary *)manifest logErrors:(BOOL)logErrors
873{
874 NSDictionary *required = nil;
875 NSArray *requireds = nil;
876
877 requireds = [manifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
878 // if it has a non-empty required_oxps list
879 if (requireds != nil && [requireds count] > 0)
880 {
881 // iterate over that list
882 foreach (required, requireds)
883 {
884 if ([ResourceManager manifest:manifest HasUnmetDependency:required logErrors:logErrors])
885 {
886 return YES;
887 }
888 }
889 }
890 return NO;
891}

References count, and nil.

◆ maskUserName:inPath:

+ (NSString *) maskUserName: (NSString *) name
inPath: (NSString *) path 

Definition at line 489 of file ResourceManager.m.

489 :(NSString *)name inPath:(NSString *)path
490{
491 NSMutableString *result = [NSMutableString stringWithString:path];
492 if (result && name) [result replaceOccurrencesOfString:name withString:@"*"
493 options:NSLiteralSearch
494 range:NSMakeRange(0, [result length])
495 ];
496 return [NSString stringWithString:result];
497}

Referenced by maskUserNameInPathArray:.

Here is the caller graph for this function:

◆ maskUserNameInPathArray:

+ (NSArray *) maskUserNameInPathArray: (NSArray *) inputPathArray

Definition at line 469 of file ResourceManager.m.

469 :(NSArray *)inputPathArray
470{
471 NSString *path = nil;
472 NSMutableArray *maskedArray = [NSMutableArray arrayWithCapacity:[inputPathArray count]];
473 char *userNamePathEnvVar =
474#if OOLITE_WINDOWS
475 SDL_getenv("USERPROFILE");
476#else
477 SDL_getenv("HOME");
478#endif
479 NSString *userName = [[NSString stringWithFormat:@"%s", userNamePathEnvVar] lastPathComponent];
480 foreach (path, inputPathArray)
481 {
482 path = [self maskUserName:userName inPath:path];
483 [maskedArray addObject:path];
484 }
485 return maskedArray;
486}

References maskUserName:inPath:, and nil.

Referenced by OoliteGetProperty().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ matchVersions:withVersion:

+ (BOOL) matchVersions: (NSDictionary *) rangeDict
withVersion: (NSString *) version 

Definition at line 970 of file ResourceManager.m.

970 :(NSDictionary *)rangeDict withVersion:(NSString *)version
971{
972 NSString *minimum = [rangeDict oo_stringForKey:kOOManifestRelationVersion defaultValue:nil];
973 NSString *maximum = [rangeDict oo_stringForKey:kOOManifestRelationMaxVersion defaultValue:nil];
974 NSArray *isVersionComponents = ComponentsFromVersionString(version);
975 NSArray *reqVersionComponents = nil;
976 if (minimum != nil)
977 {
978 reqVersionComponents = ComponentsFromVersionString(minimum);
979 if (NSOrderedAscending == CompareVersions(isVersionComponents, reqVersionComponents))
980 {
981 // earlier than minimum version
982 return NO;
983 }
984 }
985 if (maximum != nil)
986 {
987 reqVersionComponents = ComponentsFromVersionString(maximum);
988 if (NSOrderedDescending == CompareVersions(isVersionComponents, reqVersionComponents))
989 {
990 // later than maximum version
991 return NO;
992 }
993 }
994 // either version was okay, or no version info so an unconditional match
995 return YES;
996}

References CompareVersions(), ComponentsFromVersionString(), and nil.

Here is the call graph for this function:

◆ materialDefaults

+ (NSDictionary *) materialDefaults

Definition at line 2212 of file ResourceManager.m.

2213{
2214 return [self dictionaryFromFilesNamed:@"material-defaults.plist" inFolder:@"Config" andMerge:YES];
2215}

References dictionaryFromFilesNamed:inFolder:andMerge:, and materialDefaults.

Referenced by materialDefaults, OODefaultShipShaderMacros(), OOMesh::placeholderMaterial, ShipSetMaterialsInternal(), and VisualEffectSetMaterialsInternal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mergeRoleCategories:intoDictionary:

+ (void) mergeRoleCategories: (NSDictionary *) catData
intoDictionary: (NSMutableDictionary *) categories 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 1818 of file ResourceManager.m.

1818 :(NSDictionary *)catData intoDictionary:(NSMutableDictionary *)categories
1819{
1820 NSMutableSet *contents = nil;
1821 NSArray *catDataEntry = nil;
1822 NSString *key;
1823 foreachkey(key, catData)
1824 {
1825 contents = [categories objectForKey:key];
1826 if (contents == nil)
1827 {
1828 contents = [NSMutableSet setWithCapacity:16];
1829 [categories setObject:contents forKey:key];
1830 }
1831 catDataEntry = [catData oo_arrayForKey:key];
1832 OOLog(@"shipData.load.roleCategories", @"Adding %ld entries for category %@", (unsigned long)[catDataEntry count], key);
1833 [contents addObjectsFromArray:catDataEntry];
1834 }
1835}

References count, foreachkey, nil, and OOLog.

Referenced by roleCategoriesDictionary.

Here is the caller graph for this function:

◆ ooMusicNamed:inFolder:

+ (OOMusic *) ooMusicNamed: (NSString *) fileName
inFolder: (NSString *) folderName 

Definition at line 2030 of file ResourceManager.m.

2030 :(NSString *)fileName inFolder:(NSString *)folderName
2031{
2032 return [self retrieveFileNamed:fileName
2033 inFolder:folderName
2034 cache:NULL // Don't cache music objects; minimizing latency isn't really important.
2035 key:[NSString stringWithFormat:@"OOMusic:%@:%@", folderName, fileName]
2036 class:[OOMusic class]
2037 usePathCache:YES];
2038}

References retrieveFileNamed:inFolder:cache:key:class:usePathCache:.

Referenced by OOMusicController::playMusicNamed:loop:gain:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ooSoundNamed:inFolder:

+ (OOSound *) ooSoundNamed: (NSString *) fileName
inFolder: (NSString *) folderName 

Definition at line 2041 of file ResourceManager.m.

2041 :(NSString *)fileName inFolder:(NSString *)folderName
2042{
2043 return [self retrieveFileNamed:fileName
2044 inFolder:folderName
2045 cache:&sSoundCache
2046 key:[NSString stringWithFormat:@"OOSound:%@:%@", folderName, fileName]
2047 class:[OOSound class]
2048 usePathCache:YES];
2049}

References retrieveFileNamed:inFolder:cache:key:class:usePathCache:.

Referenced by GetNamedSound(), Universe::PreloadOneSound, PlayerEntity(Sound)::setUpSound, and OOSound(OOCustomSounds)::soundWithCustomSoundKey:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OXPsWithMessagesFound

+ (NSArray *) OXPsWithMessagesFound

Definition at line 571 of file ResourceManager.m.

572{
573 return [[sOXPsWithMessagesFound copy] autorelease];
574}

References OXPsWithMessagesFound.

Referenced by OXPsWithMessagesFound, and PlayerEntity::setGuiToIntroFirstGo:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pathEnumerator

+ (NSEnumerator *) pathEnumerator

Definition at line 559 of file ResourceManager.m.

560{
561 return [[self paths] objectEnumerator];
562}

References pathEnumerator, and paths.

Referenced by arrayFromFilesNamed:inFolder:andMerge:cache:, dictionaryFromFilesNamed:inFolder:mergeMode:cache:, logControlDictionary, pathEnumerator, roleCategoriesDictionary, and systemDescriptionManager.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pathForFileNamed:inFolder:

+ (NSString *) pathForFileNamed: (NSString *) fileName
inFolder: (NSString *) folderName 

Definition at line 1935 of file ResourceManager.m.

1935 :(NSString *)fileName inFolder:(NSString *)folderName
1936{
1937 return [self pathForFileNamed:fileName inFolder:folderName cache:YES];
1938}

References pathForFileNamed:inFolder:cache:.

Referenced by OOScript::jsAIScriptFromFileNamed:properties:, OOScript::jsScriptFromFileNamed:properties:, OOTextureLoader::loaderWithTextureSpecifier:extraOptions:folder:, AI(OOPrivate)::loadStateMachine:jsName:, OOInitDebugSupport(), OOFileScannerVerifierStage::pathForFile:inFolder:referencedFrom:checkBuiltIn:, OOScript::scriptsFromFileNamed:, ShipEntity(AI)::setAITo:, OODebugMonitor(Private)::setUpDebugConsoleScript, PlayerEntity(LoadSave)::startScenario, and OOTexture::textureWithName:inFolder:options:anisotropy:lodBias:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pathForFileNamed:inFolder:cache:

+ (NSString *) pathForFileNamed: (NSString *) fileName
inFolder: (NSString *) folderName
cache: (BOOL) useCache 

Definition at line 1942 of file ResourceManager.m.

1942 :(NSString *)fileName inFolder:(NSString *)folderName cache:(BOOL)useCache
1943{
1944 NSString *result = nil;
1945 NSString *cacheKey = nil;
1946 OOCacheManager *cache = [OOCacheManager sharedCache];
1947 NSEnumerator *pathEnum = nil;
1948 NSString *path = nil;
1949 NSString *filePath = nil;
1950 NSFileManager *fmgr = nil;
1951
1952 if (fileName == nil) return nil;
1953
1954 if (cache)
1955 {
1956 if (folderName != nil) cacheKey = [NSString stringWithFormat:@"%@/%@", folderName, fileName];
1957 else cacheKey = fileName;
1958 result = [cache objectForKey:cacheKey inCache:@"resolved paths"];
1959 if (result != nil) return result;
1960 }
1961
1962 // Search for file
1963 fmgr = [NSFileManager defaultManager];
1964 // reverse object enumerator allows OXPs to override core
1965 for (pathEnum = [[ResourceManager paths] reverseObjectEnumerator]; (path = [pathEnum nextObject]); )
1966 {
1967 filePath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
1968 if ([fmgr oo_oxzFileExistsAtPath:filePath])
1969 {
1970 result = filePath;
1971 break;
1972 }
1973
1974 filePath = [path stringByAppendingPathComponent:fileName];
1975 if ([fmgr oo_oxzFileExistsAtPath:filePath])
1976 {
1977 result = filePath;
1978 break;
1979 }
1980 }
1981
1982 if (result != nil)
1983 {
1984 OOLog(@"resourceManager.foundFile", @"Found %@/%@ at %@", folderName, fileName, filePath);
1985 if (useCache)
1986 {
1987 [cache setObject:result forKey:cacheKey inCache:@"resolved paths"];
1988 }
1989 }
1990 return result;
1991}

References nil, OOCacheManager::objectForKey:inCache:, OOLog, paths, OOCacheManager::setObject:forKey:inCache:, and OOCacheManager::sharedCache.

Referenced by pathForFileNamed:inFolder:, retrieveFileNamed:inFolder:cache:key:class:usePathCache:, and stringFromFilesNamed:inFolder:cache:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ paths

+ (NSArray *) paths

Definition at line 459 of file ResourceManager.m.

460{
462 {
463 sSearchPaths = [[NSMutableArray alloc] init];
464 }
465 return [self pathsWithAddOns];
466}

References EXPECT_NOT, nil, paths, pathsWithAddOns, and sSearchPaths.

Referenced by loadScripts, OoliteGetProperty(), pathEnumerator, pathForFileNamed:inFolder:cache:, paths, preloadFileLists, OOOpenGLExtensionManager::reset, reversePathEnumerator, and setUseAddOns:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pathsWithAddOns

+ (NSArray *) pathsWithAddOns

Definition at line 218 of file ResourceManager.m.

219{
220 if ([sSearchPaths count] > 0) return sSearchPaths;
221
222 if (sUseAddOns == nil)
223 {
224 sUseAddOns = [[NSString alloc] initWithString:SCENARIO_OXP_DEFINITION_ALL];
225 sUseAddOnsParts = [[sUseAddOns componentsSeparatedByString:@";"] retain];
226 }
227
228 /* Handle special case of 'strict mode' efficiently */
229 // testing actual string
230 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_NONE])
231 {
232 return (NSArray *)[NSArray arrayWithObject:[self builtInPath]];
233 }
234
235 [sErrors release];
236 sErrors = nil;
237
238 NSFileManager *fmgr = [NSFileManager defaultManager];
239 NSArray *rootPaths = nil;
240 NSMutableArray *existingRootPaths = nil;
241 NSEnumerator *pathEnum = nil;
242 NSString *root = nil;
243 NSDirectoryEnumerator *dirEnum = nil;
244 NSString *subPath = nil;
245 NSString *path = nil;
246 BOOL isDirectory;
247
248 // Copy those root paths that actually exist to search paths.
249 rootPaths = [self rootPaths];
250 existingRootPaths = [NSMutableArray arrayWithCapacity:[rootPaths count]];
251 for (pathEnum = [rootPaths objectEnumerator]; (root = [pathEnum nextObject]); )
252 {
253 if ([fmgr fileExistsAtPath:root isDirectory:&isDirectory] && isDirectory)
254 {
255 [existingRootPaths addObject:root];
256 }
257 }
258
259 // validate default search paths
261 sSearchPaths = [NSMutableArray new];
262 foreach(path, existingRootPaths)
263 {
264 [self checkPotentialPath:path :sSearchPaths];
265 }
266
267 // Iterate over root paths.
268 for (pathEnum = [existingRootPaths objectEnumerator]; (root = [pathEnum nextObject]); )
269 {
270 // Iterate over each root path's contents.
271 if ([fmgr fileExistsAtPath:root isDirectory:&isDirectory] && isDirectory)
272 {
273 for (dirEnum = [fmgr enumeratorAtPath:root]; (subPath = [dirEnum nextObject]); )
274 {
275 // Check if it's a directory.
276 path = [root stringByAppendingPathComponent:subPath];
277 if ([fmgr fileExistsAtPath:path isDirectory:&isDirectory])
278 {
279 if (isDirectory)
280 {
281 // If it is, is it an OXP?.
282 if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxp"])
283 {
284 [self checkPotentialPath:path :sSearchPaths];
285 if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
286 }
287 else
288 {
289 // If not, don't search subdirectories.
290 [dirEnum skipDescendents];
291 }
292 }
293 else
294 {
295 // If not a directory, is it an OXZ?
296 if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
297 {
298 [self checkPotentialPath:path :sSearchPaths];
299 if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
300 }
301 }
302 }
303 }
304 }
305 }
306
307 for (pathEnum = [sExternalPaths objectEnumerator]; (path = [pathEnum nextObject]); )
308 {
309 [self checkPotentialPath:path :sSearchPaths];
310 if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
311 }
312
313 /* If a scenario restriction is *not* in place, remove
314 * scenario-only OXPs. */
315 // test string
316 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_ALL])
317 {
318 [self filterSearchPathsToExcludeScenarioOnlyPaths:sSearchPaths];
319 }
320
321 /* This is a conservative filter. It probably gets rid of more
322 * OXPs than it technically needs to in certain situations with
323 * dependency chains, but really any conflict here needs to be
324 * resolved by the user rather than Oolite. The point is to avoid
325 * loading OXPs which we shouldn't; if doing so takes out other
326 * OXPs which would have been safe, that's not important. */
327 [self filterSearchPathsForConflicts:sSearchPaths];
328
329 /* This one needs to be run repeatedly to be sure. Take the chain
330 * A depends on B depends on C. A and B are installed. A is
331 * checked first, and depends on B, which is thought to be
332 * okay. So A is kept. Then B is checked and removed. A must then
333 * be rechecked. This function therefore is run repeatedly until a
334 * run of it removes no further items.
335 *
336 * There may well be more elegant and efficient ways to do this
337 * but this is already fast enough for most purposes.
338 */
339 while (![self filterSearchPathsForRequirements:sSearchPaths]) {}
340
341 /* If a scenario restriction is in place, restrict OXPs to the
342 * ones valid for the scenario only. */
343 // test string
344 if (![sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_ALL])
345 {
346 [self filterSearchPathsByScenario:sSearchPaths];
347 }
348
349 [self checkCacheUpToDateForPaths:sSearchPaths];
350
351 return sSearchPaths;
352}
#define DESTROY(x)
Definition OOCocoa.h:85

References builtInPath, checkCacheUpToDateForPaths:, checkOXPMessagesInPath:, checkPotentialPath:path:, count, DESTROY, filterSearchPathsByScenario:, filterSearchPathsForConflicts:, filterSearchPathsToExcludeScenarioOnlyPaths:, nil, pathsWithAddOns, rootPaths, SCENARIO_OXP_DEFINITION_ALL, SCENARIO_OXP_DEFINITION_NONE, sErrors, sExternalPaths, sSearchPaths, sUseAddOns, and sUseAddOnsParts.

Referenced by paths, pathsWithAddOns, and resetManifestKnowledgeForOXZManager.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ preloadFileListFromFolder:forFolders:

+ (void) preloadFileListFromFolder: (NSString *) path
forFolders: (NSArray *) folders 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 424 of file ResourceManager.m.

424 :(NSString *)path forFolders:(NSArray *)folders
425{
426 NSFileManager *fmgr = [NSFileManager defaultManager];
427 NSString *subFolder = nil;
428 NSString *subFolderPath = nil;
429 NSArray *fileList = nil;
430 NSString *fileName = nil;
431
432 // search each subfolder for files
433 foreach (subFolder, folders)
434 {
435 subFolderPath = [path stringByAppendingPathComponent:subFolder];
436 fileList = [fmgr oo_directoryContentsAtPath:subFolderPath];
437 foreach (fileName, fileList)
438 {
439 [self preloadFilePathFor:fileName inFolder:subFolder atPath:[subFolderPath stringByAppendingPathComponent:fileName]];
440 }
441 }
442}

References nil, and preloadFilePathFor:inFolder:atPath:.

Referenced by preloadFileLists.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ preloadFileListFromOXZ:forFolders:

+ (void) preloadFileListFromOXZ: (NSString *) path
forFolders: (NSArray *) folders 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 377 of file ResourceManager.m.

377 :(NSString *)path forFolders:(NSArray *)folders
378{
379 unzFile uf = NULL;
380 const char* zipname = [path UTF8String];
381 char componentName[512];
382
383 if (zipname != NULL)
384 {
385 uf = unzOpen64(zipname);
386 }
387 if (uf == NULL)
388 {
389 OOLog(@"resourceManager.error",@"Could not open .oxz at %@ as zip file",path);
390 return;
391 }
392 if (unzGoToFirstFile(uf) == UNZ_OK)
393 {
394 do
395 {
397 componentName, 512,
398 NULL, 0,
399 NULL, 0);
400 NSString *zipEntry = [NSString stringWithUTF8String:componentName];
401 NSArray *pathBits = [zipEntry pathComponents];
402 if ([pathBits count] >= 2)
403 {
404 NSString *folder = [pathBits oo_stringAtIndex:0];
405 if ([folders containsObject:folder])
406 {
407 NSRange bitRange;
408 bitRange.location = 1;
409 bitRange.length = [pathBits count]-1;
410 NSString *file = [NSString pathWithComponents:[pathBits subarrayWithRange:bitRange]];
411 NSString *fullPath = [[path stringByAppendingPathComponent:folder] stringByAppendingPathComponent:file];
412
413 [self preloadFilePathFor:file inFolder:folder atPath:fullPath];
414 }
415 }
416
417 }
418 while (unzGoToNextFile(uf) == UNZ_OK);
419 }
420 unzClose(uf);
421}
int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition unzip.c:1130
int ZEXPORT unzGoToFirstFile(unzFile file)
Definition unzip.c:1184
unzFile ZEXPORT unzOpen64(const void *path)
Definition unzip.c:801
int ZEXPORT unzGoToNextFile(unzFile file)
Definition unzip.c:1205
int ZEXPORT unzClose(unzFile file)
Definition unzip.c:811
voidp unzFile
Definition unzip.h:70
#define UNZ_OK
Definition unzip.h:74

References count, OOLog, preloadFilePathFor:inFolder:atPath:, UNZ_OK, unzClose(), unzGetCurrentFileInfo64(), unzGoToFirstFile(), unzGoToNextFile(), and unzOpen64().

Referenced by preloadFileLists.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ preloadFileLists

+ (void) preloadFileLists
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 355 of file ResourceManager.m.

356{
357 NSString *path = nil;
358 NSEnumerator *pathEnum = nil;
359
360 // folders which may contain files to be cached
361 NSArray *folders = [NSArray arrayWithObjects:@"AIs",@"Images",@"Models",@"Music",@"Scenarios",@"Scripts",@"Shaders",@"Sounds",@"Textures",nil];
362
363 for (pathEnum = [[ResourceManager paths] reverseObjectEnumerator]; (path = [pathEnum nextObject]); )
364 {
365 if ([path hasSuffix:@".oxz"])
366 {
367 [self preloadFileListFromOXZ:path forFolders:folders];
368 }
369 else
370 {
371 [self preloadFileListFromFolder:path forFolders:folders];
372 }
373 }
374}

References nil, paths, preloadFileListFromFolder:forFolders:, preloadFileListFromOXZ:forFolders:, and preloadFileLists.

Referenced by preloadFileLists, and setUseAddOns:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ preloadFilePathFor:inFolder:atPath:

+ (void) preloadFilePathFor: (NSString *) fileName
inFolder: (NSString *) subFolder
atPath: (NSString *) path 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 445 of file ResourceManager.m.

445 :(NSString *)fileName inFolder:(NSString *)subFolder atPath:(NSString *)path
446{
447 OOCacheManager *cache = [OOCacheManager sharedCache];
448 NSString *cacheKey = [NSString stringWithFormat:@"%@/%@", subFolder, fileName];
449 NSString *result = [cache objectForKey:cacheKey inCache:@"resolved paths"];
450 // if nil, not found in another OXP already
451 if (result == nil)
452 {
453 OOLog(@"resourceManager.foundFile.preLoad", @"Found %@/%@ at %@", subFolder, fileName, path);
454 [cache setObject:path forKey:cacheKey inCache:@"resolved paths"];
455 }
456}

References nil, OOCacheManager::objectForKey:inCache:, OOLog, OOCacheManager::setObject:forKey:inCache:, and OOCacheManager::sharedCache.

Referenced by preloadFileListFromFolder:forFolders:, and preloadFileListFromOXZ:forFolders:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset

+ (void) reset

Definition at line 110 of file ResourceManager.m.

111{
112 sFirstRun = YES;
120}
static NSMutableDictionary * sOXPManifests
static BOOL sFirstRun

References DESTROY, reset, sErrors, sExternalPaths, sFirstRun, sOXPManifests, sOXPsWithMessagesFound, sSearchPaths, sUseAddOns, and sUseAddOnsParts.

Referenced by OOOXZManager::isRestarting, reset, and setUseAddOns:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resetManifestKnowledgeForOXZManager

+ (void) resetManifestKnowledgeForOXZManager

Definition at line 123 of file ResourceManager.m.

References DESTROY, pathsWithAddOns, resetManifestKnowledgeForOXZManager, sOXPManifests, sSearchPaths, sUseAddOns, and sUseAddOnsParts.

Referenced by OOOXZManager::managedOXZs, OOOXZManager(NSURLConnectionDataDelegate)::processDownloadedOXZ, and resetManifestKnowledgeForOXZManager.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ retrieveFileNamed:inFolder:cache:key:class:usePathCache:

+ (id) retrieveFileNamed: (NSString *) fileName
inFolder: (NSString *) folderName
cache: (NSMutableDictionary **) ioCache
key: (NSString *) key
class: (Class) class
usePathCache: (BOOL) useCache 
implementation

Definition at line 1996 of file ResourceManager.m.

1996 :(NSString *)fileName
1997 inFolder:(NSString *)folderName
1998 cache:(NSMutableDictionary **)ioCache
1999 key:(NSString *)key
2000 class:(Class)class
2001 usePathCache:(BOOL)useCache
2002{
2003 id result = nil;
2004 NSString *path = nil;
2005
2006 if (ioCache)
2007 {
2008 if (key == nil) key = [NSString stringWithFormat:@"%@:%@", folderName, fileName];
2009 if (*ioCache != nil)
2010 {
2011 // return the cached object, if any
2012 result = [*ioCache objectForKey:key];
2013 if (result) return result;
2014 }
2015 }
2016
2017 path = [self pathForFileNamed:fileName inFolder:folderName cache:useCache];
2018 if (path != nil) result = [[[class alloc] initWithContentsOfFile:path] autorelease];
2019
2020 if (result != nil && ioCache != NULL)
2021 {
2022 if (*ioCache == nil) *ioCache = [[NSMutableDictionary alloc] init];
2023 [*ioCache setObject:result forKey:key];
2024 }
2025
2026 return result;
2027}

References nil, and pathForFileNamed:inFolder:cache:.

Referenced by ooMusicNamed:inFolder:, and ooSoundNamed:inFolder:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reversePathEnumerator

+ (NSEnumerator *) reversePathEnumerator

Definition at line 565 of file ResourceManager.m.

566{
567 return [[self paths] reverseObjectEnumerator];
568}

References paths, and reversePathEnumerator.

Referenced by arrayFromFilesNamed:inFolder:andMerge:cache:, dictionaryFromFilesNamed:inFolder:mergeMode:cache:, and reversePathEnumerator.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ roleCategoriesDictionary

+ (NSDictionary *) roleCategoriesDictionary

Definition at line 1781 of file ResourceManager.m.

1782{
1783 NSMutableDictionary *roleCategories = [NSMutableDictionary dictionaryWithCapacity:16];
1784
1785 NSString *path = nil;
1786 NSString *configPath = nil;
1787 NSDictionary *categories = nil;
1788
1789 NSEnumerator *pathEnum = [self pathEnumerator];
1790 while ((path = [pathEnum nextObject]))
1791 {
1792 if ([ResourceManager corePlist:@"role-categories.plist" excludedAt:path])
1793 {
1794 continue;
1795 }
1796
1797 configPath = [[path stringByAppendingPathComponent:@"Config"]
1798 stringByAppendingPathComponent:@"role-categories.plist"];
1799 categories = OODictionaryFromFile(configPath);
1800 if (categories != nil)
1801 {
1802 [ResourceManager mergeRoleCategories:categories intoDictionary:roleCategories];
1803 }
1804 }
1805
1806 /* If the old pirate-victim-roles files exist, merge them in */
1807 NSArray *pirateVictims = [ResourceManager arrayFromFilesNamed:@"pirate-victim-roles.plist" inFolder:@"Config" andMerge:YES];
1808 if (OOEnforceStandards() && [pirateVictims count] > 0)
1809 {
1810 OOStandardsDeprecated(@"pirate-victim-roles.plist is still being used.");
1811 }
1812 [ResourceManager mergeRoleCategories:[NSDictionary dictionaryWithObject:pirateVictims forKey:@"oolite-pirate-victim"] intoDictionary:roleCategories];
1813
1814 return [[roleCategories copy] autorelease];
1815}
void OOStandardsDeprecated(NSString *message)
NSArray * arrayFromFilesNamed:inFolder:andMerge:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles)
void mergeRoleCategories:intoDictionary:(NSDictionary *catData, [intoDictionary] NSMutableDictionary *categories)

References arrayFromFilesNamed:inFolder:andMerge:, count, mergeRoleCategories:intoDictionary:, nil, OODictionaryFromFile(), OOEnforceStandards(), OOStandardsDeprecated(), pathEnumerator, and roleCategoriesDictionary.

Referenced by roleCategoriesDictionary, and Universe::setUpSettings.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rootPaths

+ (NSArray *) rootPaths

Definition at line 163 of file ResourceManager.m.

164{
165 static NSArray *sRootPaths = nil;
166 if (sRootPaths == nil) {
167 /* Built-in data, then managed OXZs, then manually installed ones,
168 * which may be useful for debugging/testing purposes. */
169 sRootPaths = [NSArray arrayWithObjects:[self builtInPath], [[OOOXZManager sharedManager] installPath], nil];
170 sRootPaths = [[sRootPaths arrayByAddingObjectsFromArray:[self userRootPaths]] retain];
171 }
172 return sRootPaths;
173}
NSString * installPath()
OOOXZManager * sharedManager()

References builtInPath, OOOXZManager::installPath, nil, rootPaths, OOOXZManager::sharedManager, and userRootPaths.

Referenced by logControlDictionary, pathsWithAddOns, and rootPaths.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setUseAddOns:

+ (void) setUseAddOns: (NSString *) useAddOns

Definition at line 506 of file ResourceManager.m.

506 :(NSString *)useAddOns
507{
508 if (sFirstRun || ![useAddOns isEqualToString:sUseAddOns])
509 {
510 [self reset];
511 sFirstRun = NO;
514 sUseAddOns = [useAddOns retain];
515 sUseAddOnsParts = [[sUseAddOns componentsSeparatedByString:@";"] retain];
516
519
520 OOCacheManager *cmgr = [OOCacheManager sharedCache];
521 /* only allow cache writes for the "all OXPs" default
522 *
523 * cache should be less necessary for restricted sets anyway */
524 // testing the actual string here
525 if ([sUseAddOns isEqualToString:SCENARIO_OXP_DEFINITION_ALL])
526 {
527 [cmgr reloadAllCaches];
528 [cmgr setAllowCacheWrites:YES];
529 }
530 else
531 {
532 [cmgr clearAllCaches];
533 [cmgr setAllowCacheWrites:NO];
534 }
535
536 [self checkCacheUpToDateForPaths:[self paths]];
537 [self logPaths];
538 /* preloading the file lists at this stage helps efficiency a
539 * lot when many OXZs are installed */
540 [self preloadFileLists];
541
542 }
543}
void OOHUDResetTextEngine(void)
void setAllowCacheWrites:(BOOL flag)
NSString * useAddOns()

References checkCacheUpToDateForPaths:, OOCacheManager::clearAllCaches, clearCaches, DESTROY, logPaths, OOHUDResetTextEngine(), paths, preloadFileLists, OOCacheManager::reloadAllCaches, reset, SCENARIO_OXP_DEFINITION_ALL, OOCacheManager::setAllowCacheWrites:, sFirstRun, OOCacheManager::sharedCache, sUseAddOns, sUseAddOnsParts, and useAddOns.

Referenced by Universe::initWithGameView:, Universe::reinitAndShowDemo:, and OOOXPVerifier(OOPrivate)::run.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shaderBindingTypesDictionary

+ (NSDictionary *) shaderBindingTypesDictionary

Definition at line 1889 of file ResourceManager.m.

1890{
1892
1894 {
1895 NSAutoreleasePool *pool = [NSAutoreleasePool new];
1896
1897 NSString *path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"shader-uniform-bindings.plist"];
1898 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
1899 NSArray *keys = [dict allKeys];
1900
1901 // Resolve all $inherit keys.
1902 unsigned changeCount = 0;
1903 do {
1904 changeCount = 0;
1905 NSString *key = nil;
1906 foreach (key, keys)
1907 {
1908 NSDictionary *value = [dict oo_dictionaryForKey:key];
1909 NSString *inheritKey = [value oo_stringForKey:@"$w2"];
1910 if (inheritKey != nil)
1911 {
1912 changeCount++;
1913 NSMutableDictionary *mutableValue = [[value mutableCopy] autorelease];
1914 [mutableValue removeObjectForKey:@"$w3"];
1915 NSDictionary *inherited = [dict oo_dictionaryForKey:inheritKey];
1916 if (inherited != nil)
1917 {
1918 [mutableValue addEntriesFromDictionary:inherited];
1919 }
1920
1921 [dict setObject:[[mutableValue copy] autorelease] forKey:key];
1922 }
1923 }
1924 } while (changeCount != 0);
1925
1926 shaderBindingTypesDictionary = [dict copy];
1927
1928 [pool release];
1929 }
1930
1932}
NSDictionary * shaderBindingTypesDictionary()

References builtInPath, nil, and shaderBindingTypesDictionary.

Referenced by shaderBindingTypesDictionary, and OODefaultShaderSynthesizer::writeLightMaps.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stringFromFilesNamed:inFolder:

+ (NSString *) stringFromFilesNamed: (NSString *) fileName
inFolder: (NSString *) folderName 

Definition at line 2052 of file ResourceManager.m.

2052 :(NSString *)fileName inFolder:(NSString *)folderName
2053{
2054 return [self stringFromFilesNamed:fileName inFolder:folderName cache:YES];
2055}

References stringFromFilesNamed:inFolder:cache:.

Referenced by GetShaderSource().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ stringFromFilesNamed:inFolder:cache:

+ (NSString *) stringFromFilesNamed: (NSString *) fileName
inFolder: (NSString *) folderName
cache: (BOOL) useCache 

Definition at line 2058 of file ResourceManager.m.

2058 :(NSString *)fileName inFolder:(NSString *)folderName cache:(BOOL)useCache
2059{
2060 id result = nil;
2061 NSString *path = nil;
2062 NSString *key = nil;
2063
2064 if (useCache)
2065 {
2066 key = [NSString stringWithFormat:@"%@:%@", folderName, fileName];
2067 if (sStringCache != nil)
2068 {
2069 // return the cached object, if any
2070 result = [sStringCache objectForKey:key];
2071 if (result) return result;
2072 }
2073 }
2074
2075 path = [self pathForFileNamed:fileName inFolder:folderName cache:YES];
2076 if (path != nil) result = [NSString stringWithContentsOfUnicodeFile:path];
2077
2078 if (result != nil && useCache)
2079 {
2080 if (sStringCache == nil) sStringCache = [[NSMutableDictionary alloc] init];
2081 [sStringCache setObject:result forKey:key];
2082 }
2083
2084 return result;
2085}

References nil, pathForFileNamed:inFolder:cache:, and sStringCache.

Referenced by OOMesh(Private)::loadData:scaleFactor:, and stringFromFilesNamed:inFolder:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ systemDescriptionManager

+ (OOSystemDescriptionManager *) systemDescriptionManager

Definition at line 1838 of file ResourceManager.m.

1839{
1840 OOLog(@"resourceManager.planetinfo.load", @"%@", @"Initialising manager");
1841 OOSystemDescriptionManager *manager = [[OOSystemDescriptionManager alloc] init];
1842
1843 NSString *path = nil;
1844 NSString *configPath = nil;
1845 NSDictionary *categories = nil;
1846 NSString *systemKey = nil;
1847
1848 NSEnumerator *pathEnum = [self pathEnumerator];
1849 while ((path = [pathEnum nextObject]))
1850 {
1851 if ([ResourceManager corePlist:@"planetinfo.plist" excludedAt:path])
1852 {
1853 continue;
1854 }
1855 configPath = [[path stringByAppendingPathComponent:@"Config"]
1856 stringByAppendingPathComponent:@"planetinfo.plist"];
1857 categories = OODictionaryFromFile(configPath);
1858 if (categories != nil)
1859 {
1860 foreachkey(systemKey,categories)
1861 {
1862 NSDictionary *values = [categories oo_dictionaryForKey:systemKey defaultValue:nil];
1863 if (values != nil)
1864 {
1865 if ([systemKey isEqualToString:PLANETINFO_UNIVERSAL_KEY])
1866 {
1867 [manager setUniversalProperties:values];
1868 }
1869 else if ([systemKey isEqualToString:PLANETINFO_INTERSTELLAR_KEY])
1870 {
1871 [manager setInterstellarProperties:values];
1872 }
1873 else
1874 {
1875 [manager setProperties:values forSystemKey:systemKey];
1876 }
1877 }
1878 }
1879 }
1880 }
1881 OOLog(@"resourceManager.planetinfo.load", @"%@", @"Caching routes");
1882 [manager buildRouteCache];
1883 OOLog(@"resourceManager.planetinfo.load", @"%@", @"Initialised manager");
1884 return [manager autorelease];
1885}
#define PLANETINFO_UNIVERSAL_KEY
Definition Universe.h:158
#define PLANETINFO_INTERSTELLAR_KEY
Definition Universe.h:159
void setUniversalProperties:(NSDictionary *properties)
void setProperties:forSystemKey:(NSDictionary *properties,[forSystemKey] NSString *key)
void setInterstellarProperties:(NSDictionary *properties)

References OOSystemDescriptionManager::buildRouteCache, foreachkey, nil, OODictionaryFromFile(), OOLog, pathEnumerator, PLANETINFO_INTERSTELLAR_KEY, PLANETINFO_UNIVERSAL_KEY, OOSystemDescriptionManager::setInterstellarProperties:, OOSystemDescriptionManager::setProperties:forSystemKey:, OOSystemDescriptionManager::setUniversalProperties:, and systemDescriptionManager.

Referenced by Universe::setUpSettings, and systemDescriptionManager.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ useAddOns

+ (NSString *) useAddOns

Definition at line 500 of file ResourceManager.m.

501{
502 return sUseAddOns;
503}

References sUseAddOns, and useAddOns.

Referenced by setUseAddOns:, useAddOns, and GameController::validateMenuItem:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ userRootPaths

+ (NSArray *) userRootPaths

Definition at line 176 of file ResourceManager.m.

177{
178 static NSArray *sUserRootPaths = nil;
179
180 if (sUserRootPaths == nil)
181 {
182 // the paths are now in order of preference as per yesterday's talk. -- Kaks 2010-05-05
183 NSArray *defaultAddOnsPaths = [NSArray arrayWithObjects:
184#if OOLITE_MAC_OS_X
185 [[[[NSHomeDirectory() stringByAppendingPathComponent:@"Library"]
186 stringByAppendingPathComponent:@"Application Support"]
187 stringByAppendingPathComponent:@"Oolite"]
188 stringByAppendingPathComponent:@"AddOns"],
189 [[[[NSBundle mainBundle] bundlePath]
190 stringByDeletingLastPathComponent]
191 stringByAppendingPathComponent:@"AddOns"],
192#endif
193#if !OOLITE_WINDOWS
194 @"AddOns",
195#endif
197 nil];
198 sUserRootPaths = [[[[OOOXZManager sharedManager] additionalAddOnsPaths] arrayByAddingObjectsFromArray:defaultAddOnsPaths] retain];
199 }
200 OOLog(@"searchPaths.debug",@"%@",sUserRootPaths);
201 return sUserRootPaths;
202}
NSString * extractAddOnsPath()
NSArray * additionalAddOnsPaths()

References OOOXZManager::additionalAddOnsPaths, OOOXZManager::extractAddOnsPath, nil, OOLog, OOOXZManager::sharedManager, and userRootPaths.

Referenced by OOOXZManager(NSURLConnectionDataDelegate)::extractionBasePathForIdentifier:andVersion:, rootPaths, GameController::showAddOnsAction:, and userRootPaths.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validateManifest:forOXP:

+ (BOOL) validateManifest: (NSDictionary*) manifest
forOXP: (NSString *) path 
implementation

Provided by category ResourceManager(OOPrivate).

Definition at line 660 of file ResourceManager.m.

660 :(NSDictionary*)manifest forOXP:(NSString *)path
661{
663 {
664 sOXPManifests = [[NSMutableDictionary alloc] initWithCapacity:32];
665 }
666
667 BOOL OK = YES;
668 NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier defaultValue:nil];
669 NSString *version = [manifest oo_stringForKey:kOOManifestVersion defaultValue:nil];
670 NSString *required = [manifest oo_stringForKey:kOOManifestRequiredOoliteVersion defaultValue:nil];
671 NSString *title = [manifest oo_stringForKey:kOOManifestTitle defaultValue:nil];
672
673 if (identifier == nil)
674 {
675 OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestIdentifier);
676 [self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestIdentifier];
677 OK = NO;
678 }
679 if (version == nil)
680 {
681 OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestVersion);
682 [self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestVersion];
683 OK = NO;
684 }
685 if (required == nil)
686 {
687 OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestRequiredOoliteVersion);
688 [self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestRequiredOoliteVersion];
689 OK = NO;
690 }
691 if (title == nil)
692 {
693 OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestTitle);
694 [self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestTitle];
695 OK = NO;
696 }
697 if (!OK)
698 {
699 return NO;
700 }
701 OK = [self checkVersionCompatibility:manifest forOXP:title];
702
703 if (!OK)
704 {
705 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
706 OOLog(@"oxp.versionMismatch", @"OXP %@ is incompatible with version %@ of Oolite.", path, version);
707 [self addErrorWithKey:@"oxp-is-incompatible" param1:[path lastPathComponent] param2:version];
708 return NO;
709 }
710
711 NSDictionary *duplicate = [sOXPManifests objectForKey:identifier];
712 if (duplicate != nil)
713 {
714 OOLog(@"oxp.duplicate", @"OXP %@ has the same identifier (%@) as %@ which has already been loaded.",path,identifier,[duplicate oo_stringForKey:kOOManifestFilePath]);
715 [self addErrorWithKey:@"oxp-manifest-duplicate" param1:path param2:[duplicate oo_stringForKey:kOOManifestFilePath]];
716 return NO;
717 }
718 NSMutableDictionary *mData = [NSMutableDictionary dictionaryWithDictionary:manifest];
719 [mData setObject:path forKey:kOOManifestFilePath];
720 // add an extra key
721 [sOXPManifests setObject:mData forKey:identifier];
722 return YES;
723}
static NSString *const kOOManifestRequiredOoliteVersion
static NSString *const kOOManifestTitle

References addErrorWithKey:param1:param2:, checkVersionCompatibility:forOXP:, EXPECT_NOT, kOOManifestFilePath, kOOManifestIdentifier, kOOManifestRequiredOoliteVersion, kOOManifestTitle, kOOManifestVersion, nil, OOLog, and sOXPManifests.

Referenced by checkPotentialPath:path:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ whitelistDictionary

+ (NSDictionary *) whitelistDictionary

Definition at line 1680 of file ResourceManager.m.

1681{
1682 static id whitelistDictionary = nil;
1683
1684 if (whitelistDictionary == nil)
1685 {
1686 NSString *path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"whitelist.plist"];
1687 whitelistDictionary = [NSDictionary dictionaryWithContentsOfFile:path];
1688 if (whitelistDictionary == nil) whitelistDictionary = [NSNull null];
1689
1690 [whitelistDictionary retain];
1691 }
1692
1693 if (whitelistDictionary == [NSNull null]) return nil;
1694 return whitelistDictionary;
1695}
NSDictionary * whitelistDictionary()

References builtInPath, nil, and whitelistDictionary.

Referenced by HeadUpDisplay::addDial:, AI(OOPrivate)::cleanActions:forHandler:state:stateMachine:, LookUpLegacySelector(), OOUniformBindingPermitted(), OOAIStateMachineVerifierStage::run, SanitizeActionMethod(), SanitizeQueryMethod(), and whitelistDictionary.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeDiagnosticData:toFileNamed:

+ (BOOL) writeDiagnosticData: (NSData *) data
toFileNamed: (NSString *) name 

Definition at line 2167 of file ResourceManager.m.

2167 :(NSData *)data toFileNamed:(NSString *)name
2168{
2169 if (data == nil || name == nil) return NO;
2170
2171 NSString *directory = [self diagnosticFileLocation];
2172 if (directory == nil) return NO;
2173
2174 NSArray *nameComponents = [name componentsSeparatedByString:@"/"];
2175 NSUInteger count = [nameComponents count];
2176 if (count > 1)
2177 {
2178 name = [nameComponents lastObject];
2179
2180 for (NSUInteger i = 0; i < count - 1; i++)
2181 {
2182 NSString *component = [nameComponents objectAtIndex:i];
2183 if ([component hasPrefix:@"."])
2184 {
2185 component = [@"!" stringByAppendingString:[component substringFromIndex:1]];
2186 }
2187 directory = [directory stringByAppendingPathComponent:component];
2188 [[NSFileManager defaultManager] oo_createDirectoryAtPath:directory attributes:nil];
2189 }
2190 }
2191
2192 return [data writeToFile:[directory stringByAppendingPathComponent:name] atomically:YES];
2193}

References count, diagnosticFileLocation, and nil.

Referenced by writeDiagnosticPList:toFileNamed:, and writeDiagnosticString:toFileNamed:.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ writeDiagnosticPList:toFileNamed:

+ (BOOL) writeDiagnosticPList: (id) plist
toFileNamed: (NSString *) name 

Definition at line 2202 of file ResourceManager.m.

2202 :(id)plist toFileNamed:(NSString *)name
2203{
2204 NSData *data = [plist oldSchoolPListFormatWithErrorDescription:NULL];
2205 if (data == nil) [NSPropertyListSerialization dataFromPropertyList:plist format:NSPropertyListXMLFormat_v1_0 errorDescription:NULL];
2206 if (data == nil) return NO;
2207
2208 return [self writeDiagnosticData:data toFileNamed:name];
2209}

References nil, and writeDiagnosticData:toFileNamed:.

Here is the call graph for this function:

◆ writeDiagnosticString:toFileNamed:

+ (BOOL) writeDiagnosticString: (NSString *) string
toFileNamed: (NSString *) name 

Definition at line 2196 of file ResourceManager.m.

2196 :(NSString *)string toFileNamed:(NSString *)name
2197{
2198 return [self writeDiagnosticData:[string dataUsingEncoding:NSUTF8StringEncoding] toFileNamed:name];
2199}

References writeDiagnosticData:toFileNamed:.

Referenced by OOOXPVerifier(OOPrivate)::dumpDebugGraphviz, and SVGDumpEnd().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: