From 42427f9a4ec2ec768d355729bbdd77f52ddb37b9 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 11 Jun 2008 06:22:02 +0000 Subject: Modified mass detector to not re-add already configured games (that is, if there is an existing entry with identical path, gameid, platform, language, then do not add a new one) svn-id: r32664 --- gui/launcher.cpp | 18 +++++++++--------- gui/massadd.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- gui/massadd.h | 10 ++++++++++ 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 92867562ad..2c1212b84a 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -572,8 +572,16 @@ void LauncherDialog::updateListing() { // Retrieve a list of all games defined in the config file _domains.clear(); const ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); - ConfigManager::DomainMap::const_iterator iter = domains.begin(); + ConfigManager::DomainMap::const_iterator iter; for (iter = domains.begin(); iter != domains.end(); ++iter) { +#ifdef __DS__ + // DS port uses an extra section called 'ds'. This prevents the section from being + // detected as a game. + if (iter->_key == "ds") { + continue; + } +#endif + String gameid(iter->_value.get("gameid")); String description(iter->_value.get("description")); @@ -585,14 +593,6 @@ void LauncherDialog::updateListing() { description = g.description(); } -#ifdef __DS__ - // DS port uses an extra section called 'ds'. This prevents the section from being - // detected as a game. - if (gameid == "ds") { - continue; - } -#endif - if (description.empty()) description = "Unknown (target " + iter->_key + ", gameid " + gameid + ")"; diff --git a/gui/massadd.cpp b/gui/massadd.cpp index b39b51f1fb..687d367516 100644 --- a/gui/massadd.cpp +++ b/gui/massadd.cpp @@ -24,6 +24,7 @@ #include "engines/metaengine.h" #include "common/events.h" +#include "common/config-manager.h" #include "gui/launcher.h" // For addGameToConf() #include "gui/massadd.h" @@ -87,6 +88,29 @@ MassAddDialog::MassAddDialog(const FilesystemNode &startDir) new ButtonWidget(this, "massadddialog_cancel", "Cancel", kCancelCmd, Common::ASCII_ESCAPE); + // Build a map from all configured game paths to the targets using them + const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); + Common::ConfigManager::DomainMap::const_iterator iter; + for (iter = domains.begin(); iter != domains.end(); ++iter) { + +#ifdef __DS__ + // DS port uses an extra section called 'ds'. This prevents the section from being + // detected as a game. + if (iter->_key == "ds") { + continue; + } +#endif + + Common::String path(iter->_value.get("path")); + // Remove trailing slash, so that "/foo" and "/foo/" match. + // This works around a bug in the POSIX FS code (and others?) + // where paths are not normalized (so FSNodes refering to identical + // FS objects may return different values in path()). + while (path != "/" && path.lastChar() == '/') + path.deleteLastChar(); + if (!path.empty()) + _pathToTargets[path].push_back(iter->_key); + } } @@ -136,9 +160,36 @@ void MassAddDialog::handleTickle() { // that either means the directory contains multiple games, or the detector // could not fully determine which game variant it was seeing. In either // case, let the user choose which entries he wants to keep. + // + // However, we only add games which are not already in the config file. for (GameList::const_iterator cand = candidates.begin(); cand != candidates.end(); ++cand) { GameDescriptor result = *cand; - result["path"] = dir.getPath(); + Common::String path = dir.getPath(); + + // Remove trailing slashes + while (path != "/" && path.lastChar() == '/') + path.deleteLastChar(); + + // Check for existing config entries for this path/gameid/lang/platform combination + if (_pathToTargets.contains(path)) { + bool duplicate = false; + const Common::StringList &targets = _pathToTargets[path]; + for (Common::StringList::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) { + // If the gameid, platform and language match -> skip it + Common::ConfigManager::Domain *dom = ConfMan.getDomain(*iter); + assert(dom); + + if ((*dom)["gameid"] == result["gameid"] && + (*dom)["platform"] == result["platform"] && + (*dom)["language"] == result["language"]) { + duplicate = true; + break; + } + } + if (duplicate) + break; // Skip duplicates + } + result["path"] = path; _games.push_back(result); } @@ -164,14 +215,14 @@ void MassAddDialog::handleTickle() { snprintf(buf, sizeof(buf), "Scan complete!"); _dirProgressText->setLabel(buf); - snprintf(buf, sizeof(buf), "Discovered %d games.", _games.size()); + snprintf(buf, sizeof(buf), "Discovered %d new games.", _games.size()); _gameProgressText->setLabel(buf); } else { snprintf(buf, sizeof(buf), "Scanned %d directories ...", _dirsScanned); _dirProgressText->setLabel(buf); - snprintf(buf, sizeof(buf), "Discovered %d games ...", _games.size()); + snprintf(buf, sizeof(buf), "Discovered %d new games ...", _games.size()); _gameProgressText->setLabel(buf); } diff --git a/gui/massadd.h b/gui/massadd.h index 29d24ca9a5..e0eff75c64 100644 --- a/gui/massadd.h +++ b/gui/massadd.h @@ -27,7 +27,10 @@ #include "gui/dialog.h" #include "common/fs.h" +#include "common/hashmap.h" #include "common/stack.h" +#include "common/str.h" +#include "common/hash-str.h" namespace GUI { @@ -45,6 +48,13 @@ private: Common::Stack _scanStack; GameList _games; + /** + * Map each path occuring in the config file to the target(s) using that path. + * Used to detect whether a potential new target is already present in the + * config manager. + */ + Common::HashMap _pathToTargets; + int _dirsScanned; Widget *_okButton; -- cgit v1.2.3