From 0ab75f8996c01d27972a2cac4e86d72fa6939f3e Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Wed, 3 Aug 2016 19:09:59 +0100 Subject: [PATCH 1/2] Add eclipse files to .gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 063da9dcf..0686c4180 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,8 @@ CMakeCache.txt CMakeFiles cmake_install.cmake Makefile + +# Eclipse +.cproject +.project +.settings/ From 454a18f9ec0ba6ff83d565914d1c87c03dd0f5be Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Tue, 9 Aug 2016 21:26:30 +0100 Subject: [PATCH 2/2] Trust the gamelist by not checking whether files exist and also improve the algorithm for parsing the gamelist. --- es-app/src/FileData.cpp | 15 ++++++++++----- es-app/src/FileData.h | 5 ++++- es-app/src/Gamelist.cpp | 35 ++++++++++++++++++++--------------- es-app/src/SystemData.cpp | 4 ++-- es-core/src/Util.cpp | 14 ++++++++++++++ es-core/src/Util.h | 1 + 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index f9f28185b..0b151b6e2 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -56,8 +56,7 @@ FileData::~FileData() if(mParent) mParent->removeChild(this); - while(mChildren.size()) - delete mChildren.back(); + mChildren.clear(); } std::string FileData::getDisplayName() const @@ -107,15 +106,20 @@ void FileData::addChild(FileData* file) assert(mType == FOLDER); assert(file->getParent() == NULL); - mChildren.push_back(file); - file->mParent = this; + const std::string key = file->getPath().filename().string(); + if (mChildrenByFilename.find(key) == mChildrenByFilename.end()) + { + mChildrenByFilename[key] = file; + mChildren.push_back(file); + file->mParent = this; + } } void FileData::removeChild(FileData* file) { assert(mType == FOLDER); assert(file->getParent() == this); - + mChildrenByFilename.erase(file->getPath().filename().string()); for(auto it = mChildren.begin(); it != mChildren.end(); it++) { if(*it == file) @@ -127,6 +131,7 @@ void FileData::removeChild(FileData* file) // File somehow wasn't in our children. assert(false); + } void FileData::sort(ComparisonFunction& comparator, bool ascending) diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index 99fba0671..f21ca8f9d 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -1,7 +1,8 @@ #pragma once -#include +#include #include +#include #include #include "MetaData.h" @@ -39,6 +40,7 @@ public: inline FileType getType() const { return mType; } inline const boost::filesystem::path& getPath() const { return mPath; } inline FileData* getParent() const { return mParent; } + inline const std::unordered_map& getChildrenByFilename() const { return mChildrenByFilename; } inline const std::vector& getChildren() const { return mChildren; } inline SystemData* getSystem() const { return mSystem; } @@ -76,5 +78,6 @@ private: boost::filesystem::path mPath; SystemData* mSystem; FileData* mParent; + std::unordered_map mChildrenByFilename; std::vector mChildren; }; diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index 9caeda354..8f3db352d 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -8,13 +8,21 @@ namespace fs = boost::filesystem; -FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type) +FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& path, FileType type, bool trustGamelist) { // first, verify that path is within the system's root folder FileData* root = system->getRootFolder(); - + + fs::path relative; bool contains = false; - fs::path relative = removeCommonPath(path, root->getPath(), contains); + if (trustGamelist) + { + relative = removeCommonPathUsingStrings(path, root->getPath(), contains); + } + else + { + relative = removeCommonPath(path, root->getPath(), contains); + } if(!contains) { LOG(LogError) << "File path \"" << path << "\" is outside system path \"" << system->getStartPath() << "\""; @@ -26,16 +34,12 @@ FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& pa bool found = false; while(path_it != relative.end()) { - const std::vector& children = treeNode->getChildren(); - found = false; - for(auto child_it = children.begin(); child_it != children.end(); child_it++) - { - if((*child_it)->getPath().filename() == *path_it) - { - treeNode = *child_it; - found = true; - break; - } + const std::unordered_map& children = treeNode->getChildrenByFilename(); + + std::string key = path_it->string(); + found = children.find(key) != children.end(); + if (found) { + treeNode = children.at(key); } // this is the end @@ -79,6 +83,7 @@ FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& pa void parseGamelist(SystemData* system) { + bool trustGamelist = Settings::getInstance()->getBool("ParseGamelistOnly"); std::string xmlpath = system->getGamelistPath(false); if(!boost::filesystem::exists(xmlpath)) @@ -114,13 +119,13 @@ void parseGamelist(SystemData* system) { fs::path path = resolvePath(fileNode.child("path").text().get(), relativeTo, false); - if(!boost::filesystem::exists(path)) + if(!trustGamelist && !boost::filesystem::exists(path)) { LOG(LogWarning) << "File \"" << path << "\" does not exist! Ignoring."; continue; } - FileData* file = findOrCreateFile(system, path, type); + FileData* file = findOrCreateFile(system, path, type, trustGamelist); if(!file) { LOG(LogError) << "Error finding/creating FileData for \"" << path << "\", skipping."; diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 95345ed63..cb46f1c47 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -198,7 +198,7 @@ void SystemData::populateFolder(FileData* folder) populateFolder(newFolder); //ignore folders that do not contain games - if(newFolder->getChildren().size() == 0) + if(newFolder->getChildrenByFilename().size() == 0) delete newFolder; else folder->addChild(newFolder); @@ -311,7 +311,7 @@ bool SystemData::loadConfig() path = genericPath.generic_string(); SystemData* newSys = new SystemData(name, fullname, path, extensions, cmd, platformIds, themeFolder); - if(newSys->getRootFolder()->getChildren().size() == 0) + if(newSys->getRootFolder()->getChildrenByFilename().size() == 0) { LOG(LogWarning) << "System \"" << name << "\" has no games! Ignoring it."; delete newSys; diff --git a/es-core/src/Util.cpp b/es-core/src/Util.cpp index 8c7dc0c92..80560a2ba 100644 --- a/es-core/src/Util.cpp +++ b/es-core/src/Util.cpp @@ -100,6 +100,20 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo return path; } +fs::path removeCommonPathUsingStrings(const fs::path& path, const fs::path& relativeTo, bool& contains) +{ + std::string pathStr = path.c_str(); + std::string relativeToStr = relativeTo.c_str(); + if (pathStr.find_first_of(relativeToStr) == 0) { + contains = true; + return pathStr.substr(relativeToStr.size() + 1); + } + else { + contains = false; + return path; + } +} + // example: removeCommonPath("/home/pi/roms/nes/foo/bar.nes", "/home/pi/roms/nes/") returns "foo/bar.nes" fs::path removeCommonPath(const fs::path& path, const fs::path& relativeTo, bool& contains) { diff --git a/es-core/src/Util.h b/es-core/src/Util.h index 5bf2a1275..507ceecfd 100644 --- a/es-core/src/Util.h +++ b/es-core/src/Util.h @@ -19,6 +19,7 @@ float round(float num); std::string getCanonicalPath(const std::string& str); +boost::filesystem::path removeCommonPathUsingStrings(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains); // example: removeCommonPath("/home/pi/roms/nes/foo/bar.nes", "/home/pi/roms/nes/") returns "foo/bar.nes" boost::filesystem::path removeCommonPath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains);