mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
Trust the gamelist by not checking whether files exist and also improve the algorithm for parsing the gamelist.
This commit is contained in:
parent
0ab75f8996
commit
454a18f9ec
|
@ -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);
|
||||
|
||||
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)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <boost/filesystem.hpp>
|
||||
#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<std::string, FileData*>& getChildrenByFilename() const { return mChildrenByFilename; }
|
||||
inline const std::vector<FileData*>& 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<std::string,FileData*> mChildrenByFilename;
|
||||
std::vector<FileData*> mChildren;
|
||||
};
|
||||
|
|
|
@ -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<FileData*>& 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<std::string, FileData*>& 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.";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue