/** Returns a table mapping scene names to filenames */ static Table<std::string, std::string>& filenameTable() { static Table<std::string, std::string> filenameTable; if (filenameTable.size() == 0) { if (searchPaths.size() == 0) { setDefaultSearchPaths(); } // Create a table mapping scene names to filenames Array<std::string> filenameArray; FileSystem::ListSettings settings; settings.files = true; settings.directories = false; settings.includeParentPath = true; settings.recursive = true; for (int i = 0; i < searchPaths.size(); ++i) { FileSystem::list(FilePath::concat(searchPaths[i], "*.scn.any"), filenameArray, settings); FileSystem::list(FilePath::concat(searchPaths[i], "*.Scene.Any"), filenameArray, settings); } logLazyPrintf("Found scenes:\n"); for (int i = 0; i < filenameArray.size(); ++i) { Any a; std::string msg; try { a.load(filenameArray[i]); const std::string& name = a["name"].string(); alwaysAssertM(! filenameTable.containsKey(name), "Duplicate scene names in " + filenameArray[i] + " and " + filenameTable[name]); msg = format(" \"%s\" (%s)\n", name.c_str(), filenameArray[i].c_str()); filenameTable.set(name, filenameArray[i]); } catch (const ParseError& e) { msg = format(" <Parse error at %s:%d(%d): %s>\n", e.filename.c_str(), e.line, e.character, e.message.c_str()); } catch (...) { msg = format(" <Error while loading %s>\n", filenameArray[i].c_str()); } if (! msg.empty()) { logLazyPrintf("%s", msg.c_str()); debugPrintf("%s", msg.c_str()); } } logPrintf(""); } return filenameTable; }
std::string System::findDataFile (const std::string& full, bool errorIfNotFound) { // Places where specific files were most recently found. This is // used to cache seeking of common files. static Table<std::string, std::string> lastFound; // First check if the file exists as requested. This will go // through the FileSystemCache, so most calls do not touch disk. if (FileSystem::exists(full)) { return full; } // Now check where we previously found this file. std::string* last = lastFound.getPointer(full); if (last != NULL) { if (FileSystem::exists(*last)) { // Even if cwd has changed the file is still present. // We won't notice if it has been deleted, however. return *last; } else { // Remove this from the cache it is invalid lastFound.remove(full); } } // Places to look static Array<std::string> directoryArray; std::string initialAppDataDir(instance().m_appDataDir); const char* g3dPath = getenv("G3DDATA"); if (directoryArray.size() == 0) { // Initialize the directory array RealTime t0 = System::time(); Array<std::string> baseDirArray; baseDirArray.append(""); if (! initialAppDataDir.empty()) { baseDirArray.append(initialAppDataDir); } # ifdef G3D_WIN32 if (g3dPath == NULL) { // If running the demos under visual studio from the G3D.sln file, // this will locate the data directory. const char* paths[] = {"../data-files/", "../../data-files/", "../../../data-files/", NULL}; for (int i = 0; paths[i]; ++i) { if (FileSystem::exists(pathConcat(paths[i], "G3D-DATA-README.TXT"))) { g3dPath = paths[i]; break; } } } # endif if (g3dPath && (initialAppDataDir != g3dPath)) { baseDirArray.append(g3dPath); } static const std::string subdirs[] = {"font", "gui", "SuperShader", "cubemap", "icon", "material", "image", "md2", "md3", "ifs", "3ds", "sky", ""}; for (int j = 0; j < baseDirArray.size(); ++j) { std::string d = baseDirArray[j]; if ((d == "") || FileSystem::exists(d)) { directoryArray.append(d); for (int i = 0; ! subdirs[i].empty(); ++i) { const std::string& p = pathConcat(d, subdirs[i]); if (FileSystem::exists(p)) { directoryArray.append(p); } } } } logLazyPrintf("Initializing System::findDataFile took %fs\n", System::time() - t0); } for (int i = 0; i < directoryArray.size(); ++i) { const std::string& p = pathConcat(directoryArray[i], full); if (FileSystem::exists(p)) { lastFound.set(full, p); return p; } } if (errorIfNotFound) { // Generate an error message std::string locations; for (int i = 0; i < directoryArray.size(); ++i) { locations += "\'" + pathConcat(directoryArray[i], full) + "'\n"; } std::string msg = "Could not find '" + full + "'.\n\n"; msg += "cwd = \'" + FileSystem::currentDirectory() + "\'\n"; if (g3dPath) { msg += "G3DDATA = "; if (! FileSystem::exists(g3dPath)) { msg += "(illegal path!) "; } msg += std::string(g3dPath) + "\'\n"; } else { msg += "(G3DDATA environment variable is undefined)\n"; } msg += "GApp::Settings.dataDir = "; if (! FileSystem::exists(initialAppDataDir)) { msg += "(illegal path!) "; } msg += std::string(initialAppDataDir) + "\'\n"; msg += "\nLocations searched:\n" + locations; alwaysAssertM(false, msg); } // Not found return ""; }
std::string System::findDataFile (const std::string& full, bool errorIfNotFound) { // Places where specific files were most recently found. This is // used to cache seeking of common files. static Table<std::string, std::string> lastFound; // First check if the file exists as requested. This will go // through the FileSystemCache, so most calls do not touch disk. if (fileExists(full)) { return full; } // Now check where we previously found this file. std::string* last = lastFound.getPointer(full); if (last != NULL) { if (fileExists(*last)) { // Even if cwd has changed the file is still present. // We won't notice if it has been deleted, however. return *last; } else { // Remove this from the cache it is invalid lastFound.remove(full); } } // Places to look static Array<std::string> directoryArray; if (directoryArray.size() == 0) { // Initialize the directory array RealTime t0 = System::time(); Array<std::string> baseDirArray; std::string initialAppDataDir(instance().m_appDataDir); baseDirArray.append(""); if (! initialAppDataDir.empty()) { baseDirArray.append(initialAppDataDir); } const char* g3dPath = getenv("G3DDATA"); if (g3dPath && (initialAppDataDir != g3dPath)) { baseDirArray.append(g3dPath); } static const std::string subdirs[] = {"font", "gui", "SuperShader", "cubemap", "icon", "material", "image", "md2", "md3", "ifs", "3ds", "sky", ""}; for (int j = 0; j < baseDirArray.size(); ++j) { std::string d = baseDirArray[j]; if (fileExists(d)) { directoryArray.append(d); for (int i = 0; ! subdirs[i].empty(); ++i) { const std::string& p = pathConcat(d, subdirs[i]); if (fileExists(p)) { directoryArray.append(p); } } } } logLazyPrintf("Initializing System::findDataFile took %fs\n", System::time() - t0); } for (int i = 0; i < directoryArray.size(); ++i) { const std::string& p = pathConcat(directoryArray[i], full); if (fileExists(p)) { lastFound.set(full, p); return p; } } if (errorIfNotFound) { // Generate an error message std::string locations; for (int i = 0; i < directoryArray.size(); ++i) { locations += pathConcat(directoryArray[i], full) + "\n"; } alwaysAssertM(false, "Could not find '" + full + "' in:\n" + locations); } // Not found return ""; }