Esempio n. 1
0
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 "";
}
Esempio n. 2
0
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 "";
}