From 426ec1f9897122706f4c298e76d32c72089ebf4a Mon Sep 17 00:00:00 2001
From: Tobia Tesan
Date: Mon, 10 Jul 2017 14:51:21 +0200
Subject: CMD: Add --recursive option for adding & detection
New semantics is as follows:
[-p
] --add adds all games in or
working dir
[-p ] --detect enumerates dectected games in
with their ids
[-p ] --game --add adds just game if found
in and not already added
[-p ] --recursive --add adds all games in and
subdirs if not already added
[-p ] --recursive --game --add
adds just game if found
in or its subdirs and
not already added
[-p ] --recursive --detect enumerates games in
and subdirs
[-p ] --auto-detect launches the first game
found in
[-p ] --recursive --auto-detect
displays error message
The reason for the displaying an error message when attempting to do
autodetection on a whole tree is mainly one of UX, IMO it *might* get
confusing on a sufficiently large/deep tree.
The relevant if() can be removed safely if it's concluded that's not the
case.
---
base/commandLine.cpp | 84 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 60 insertions(+), 24 deletions(-)
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 7bb6998fcc..17be537b93 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -72,13 +72,15 @@ static const char HELP_STRING[] =
" -a, --add Add all games from current or specified directory.\n"
" If --game=ID is passed only the game with id ID is added. See also --detect\n"
" Use --path=PATH before -a, --add to specify a directory.\n"
- " --game=ID In combination with --add, only adds the game with id ID. See also --detect\n"
- " --detect Display a list of games with their ID from current or specified directory\n"
- " without adding it to the config. Use --path=PATH before --detect\n"
- " to specify a directory.\n"
+ " --detect Display a list of games with their ID from current or\n"
+ " specified directory without adding it to the config.\n"
+ " Use --path=PATH before --detect to specify a directory.\n"
+ " --game=ID In combination with --add or --detect only adds or attempts to\n"
+ " detect the game with id ID.\n"
" --auto-detect Display a list of games from current or specified directory\n"
" and start the first one. Use --path=PATH before --auto-detect\n"
" to specify a directory.\n"
+ " --recursive In combination with --add or --detect recurse down all subdirectories\n"
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
" --console Enable the console window (default:enabled)\n"
#endif
@@ -604,6 +606,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
DO_LONG_OPTION("game")
END_OPTION
+ DO_LONG_OPTION_BOOL("recursive")
+ END_OPTION
+
DO_LONG_OPTION("themepath")
Common::FSNode path(option);
if (!path.exists()) {
@@ -813,14 +818,10 @@ static GameList getGameList(Common::FSNode dir) {
// detect Games
GameList candidates(EngineMan.detectGames(files));
- if (candidates.empty()) {
- printf("ScummVM could not find any game in %s\n", dir.getPath().c_str());
- } else {
- Common::String dataPath = dir.getPath();
- // add game data path
- for (GameList::iterator v = candidates.begin(); v != candidates.end(); ++v) {
- (*v)["path"] = dataPath;
- }
+ Common::String dataPath = dir.getPath();
+ // add game data path
+ for (GameList::iterator v = candidates.begin(); v != candidates.end(); ++v) {
+ (*v)["path"] = dataPath;
}
return candidates;
}
@@ -851,15 +852,38 @@ static bool addGameToConf(const GameDescriptor &gd) {
return true;
}
+static GameList recListGames(Common::FSNode dir, bool recursive) {
+ GameList list = getGameList(dir);
+
+ if (recursive) {
+ Common::FSList files;
+ dir.getChildren(files, Common::FSNode::kListDirectoriesOnly);
+ for (Common::FSList::const_iterator file = files.begin(); file != files.end(); ++file) {
+ GameList rec = recListGames(*file, recursive);
+ for (GameList::const_iterator game = rec.begin(); game != rec.end(); ++game)
+ list.push_back(*game);
+ }
+ }
+
+ return list;
+}
+
/** Display all games in the given directory, return ID of first detected game */
-static Common::String detectGames(Common::String path) {
+static Common::String detectGames(Common::String path, Common::String recursiveOptStr) {
if (path.empty())
path = ".";
+ bool recursive = (recursiveOptStr == "true");
//Current directory
Common::FSNode dir(path);
- GameList candidates = getGameList(dir);
- if (candidates.empty())
+ GameList candidates = recListGames(dir, recursive);
+
+ if (candidates.empty()) {
+ printf("ScummVM could not find any game in %s\n", dir.getPath().c_str());
+ if (!recursive) {
+ printf("Consider using --recursive to search inside subdirectories\n");
+ }
return Common::String();
+ }
// Print all the candidate found
printf("ID Description\n");
@@ -871,7 +895,7 @@ static Common::String detectGames(Common::String path) {
return candidates[0].gameid();
}
-static int recAddGames(Common::FSNode dir, Common::String game, bool recursive=true) {
+static int recAddGames(Common::FSNode dir, Common::String game, bool recursive) {
int count = 0;
GameList list = getGameList(dir);
for (GameList::iterator v = list.begin(); v != list.end(); ++v) {
@@ -890,7 +914,7 @@ static int recAddGames(Common::FSNode dir, Common::String game, bool recursive=t
Common::FSList files;
if (dir.getChildren(files, Common::FSNode::kListDirectoriesOnly)) {
for (Common::FSList::const_iterator file = files.begin(); file != files.end(); ++file) {
- count += recAddGames(*file, game);
+ count += recAddGames(*file, game, recursive);
}
}
}
@@ -898,13 +922,17 @@ static int recAddGames(Common::FSNode dir, Common::String game, bool recursive=t
return count;
}
-static bool addGames(Common::String path, Common::String game) {
+static bool addGames(Common::String path, Common::String game, Common::String recursiveOptStr) {
if (path.empty())
path = ".";
+ bool recursive = (recursiveOptStr == "true");
//Current directory
Common::FSNode dir(path);
- int added = recAddGames(dir, game);
+ int added = recAddGames(dir, game, recursive);
printf("Added %d games\n", added);
+ if (added == 0 && recursive == false) {
+ printf("Consider using --recursive to search inside subdirectories\n");
+ }
ConfMan.flushToDisk();
return true;
}
@@ -1138,15 +1166,23 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
// If auto-detects fails (returns an empty ID) return true to close ScummVM.
// If we get a non-empty ID, we store it in command so that it gets processed together with the
// other command line options below.
- command = detectGames(settings["path"]);
- if (command.empty())
+ if (settings["recursive"] == "true") {
+ printf("Autodetection not supported with --recursive; are you sure you didn't want --detect?\n");
return true;
+ // There is not a particularly good technical reason for this.
+ // From an UX point of view, however, it might get confusing.
+ // Consider removing this if consensus says otherwise.
+ } else {
+ command = detectGames(settings["path"], settings["recursive"]);
+ if (command.empty())
+ return true;
+ }
} else if (command == "detect") {
- // Ignore the return value of detectGame.
- detectGames(settings["path"]);
+ detectGames(settings["path"], settings["recursive"]);
return true;
} else if (command == "add") {
- return (addGames(settings["path"], settings["game"]) > 0);
+ addGames(settings["path"], settings["game"], settings["recursive"]);
+ return true;
}
#ifdef DETECTOR_TESTING_HACK
else if (command == "test-detector") {
--
cgit v1.2.3