mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-26 08:05: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)
|
if(mParent)
|
||||||
mParent->removeChild(this);
|
mParent->removeChild(this);
|
||||||
|
|
||||||
while(mChildren.size())
|
mChildren.clear();
|
||||||
delete mChildren.back();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FileData::getDisplayName() const
|
std::string FileData::getDisplayName() const
|
||||||
|
@ -107,15 +106,20 @@ void FileData::addChild(FileData* file)
|
||||||
assert(mType == FOLDER);
|
assert(mType == FOLDER);
|
||||||
assert(file->getParent() == NULL);
|
assert(file->getParent() == NULL);
|
||||||
|
|
||||||
mChildren.push_back(file);
|
const std::string key = file->getPath().filename().string();
|
||||||
file->mParent = this;
|
if (mChildrenByFilename.find(key) == mChildrenByFilename.end())
|
||||||
|
{
|
||||||
|
mChildrenByFilename[key] = file;
|
||||||
|
mChildren.push_back(file);
|
||||||
|
file->mParent = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileData::removeChild(FileData* file)
|
void FileData::removeChild(FileData* file)
|
||||||
{
|
{
|
||||||
assert(mType == FOLDER);
|
assert(mType == FOLDER);
|
||||||
assert(file->getParent() == this);
|
assert(file->getParent() == this);
|
||||||
|
mChildrenByFilename.erase(file->getPath().filename().string());
|
||||||
for(auto it = mChildren.begin(); it != mChildren.end(); it++)
|
for(auto it = mChildren.begin(); it != mChildren.end(); it++)
|
||||||
{
|
{
|
||||||
if(*it == file)
|
if(*it == file)
|
||||||
|
@ -127,6 +131,7 @@ void FileData::removeChild(FileData* file)
|
||||||
|
|
||||||
// File somehow wasn't in our children.
|
// File somehow wasn't in our children.
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileData::sort(ComparisonFunction& comparator, bool ascending)
|
void FileData::sort(ComparisonFunction& comparator, bool ascending)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include "MetaData.h"
|
#include "MetaData.h"
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ public:
|
||||||
inline FileType getType() const { return mType; }
|
inline FileType getType() const { return mType; }
|
||||||
inline const boost::filesystem::path& getPath() const { return mPath; }
|
inline const boost::filesystem::path& getPath() const { return mPath; }
|
||||||
inline FileData* getParent() const { return mParent; }
|
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 const std::vector<FileData*>& getChildren() const { return mChildren; }
|
||||||
inline SystemData* getSystem() const { return mSystem; }
|
inline SystemData* getSystem() const { return mSystem; }
|
||||||
|
|
||||||
|
@ -76,5 +78,6 @@ private:
|
||||||
boost::filesystem::path mPath;
|
boost::filesystem::path mPath;
|
||||||
SystemData* mSystem;
|
SystemData* mSystem;
|
||||||
FileData* mParent;
|
FileData* mParent;
|
||||||
|
std::unordered_map<std::string,FileData*> mChildrenByFilename;
|
||||||
std::vector<FileData*> mChildren;
|
std::vector<FileData*> mChildren;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,13 +8,21 @@
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
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
|
// first, verify that path is within the system's root folder
|
||||||
FileData* root = system->getRootFolder();
|
FileData* root = system->getRootFolder();
|
||||||
|
|
||||||
|
fs::path relative;
|
||||||
bool contains = false;
|
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)
|
if(!contains)
|
||||||
{
|
{
|
||||||
LOG(LogError) << "File path \"" << path << "\" is outside system path \"" << system->getStartPath() << "\"";
|
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;
|
bool found = false;
|
||||||
while(path_it != relative.end())
|
while(path_it != relative.end())
|
||||||
{
|
{
|
||||||
const std::vector<FileData*>& children = treeNode->getChildren();
|
const std::unordered_map<std::string, FileData*>& children = treeNode->getChildrenByFilename();
|
||||||
found = false;
|
|
||||||
for(auto child_it = children.begin(); child_it != children.end(); child_it++)
|
std::string key = path_it->string();
|
||||||
{
|
found = children.find(key) != children.end();
|
||||||
if((*child_it)->getPath().filename() == *path_it)
|
if (found) {
|
||||||
{
|
treeNode = children.at(key);
|
||||||
treeNode = *child_it;
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is the end
|
// this is the end
|
||||||
|
@ -79,6 +83,7 @@ FileData* findOrCreateFile(SystemData* system, const boost::filesystem::path& pa
|
||||||
|
|
||||||
void parseGamelist(SystemData* system)
|
void parseGamelist(SystemData* system)
|
||||||
{
|
{
|
||||||
|
bool trustGamelist = Settings::getInstance()->getBool("ParseGamelistOnly");
|
||||||
std::string xmlpath = system->getGamelistPath(false);
|
std::string xmlpath = system->getGamelistPath(false);
|
||||||
|
|
||||||
if(!boost::filesystem::exists(xmlpath))
|
if(!boost::filesystem::exists(xmlpath))
|
||||||
|
@ -114,13 +119,13 @@ void parseGamelist(SystemData* system)
|
||||||
{
|
{
|
||||||
fs::path path = resolvePath(fileNode.child("path").text().get(), relativeTo, false);
|
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.";
|
LOG(LogWarning) << "File \"" << path << "\" does not exist! Ignoring.";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileData* file = findOrCreateFile(system, path, type);
|
FileData* file = findOrCreateFile(system, path, type, trustGamelist);
|
||||||
if(!file)
|
if(!file)
|
||||||
{
|
{
|
||||||
LOG(LogError) << "Error finding/creating FileData for \"" << path << "\", skipping.";
|
LOG(LogError) << "Error finding/creating FileData for \"" << path << "\", skipping.";
|
||||||
|
|
|
@ -198,7 +198,7 @@ void SystemData::populateFolder(FileData* folder)
|
||||||
populateFolder(newFolder);
|
populateFolder(newFolder);
|
||||||
|
|
||||||
//ignore folders that do not contain games
|
//ignore folders that do not contain games
|
||||||
if(newFolder->getChildren().size() == 0)
|
if(newFolder->getChildrenByFilename().size() == 0)
|
||||||
delete newFolder;
|
delete newFolder;
|
||||||
else
|
else
|
||||||
folder->addChild(newFolder);
|
folder->addChild(newFolder);
|
||||||
|
@ -311,7 +311,7 @@ bool SystemData::loadConfig()
|
||||||
path = genericPath.generic_string();
|
path = genericPath.generic_string();
|
||||||
|
|
||||||
SystemData* newSys = new SystemData(name, fullname, path, extensions, cmd, platformIds, themeFolder);
|
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.";
|
LOG(LogWarning) << "System \"" << name << "\" has no games! Ignoring it.";
|
||||||
delete newSys;
|
delete newSys;
|
||||||
|
|
|
@ -100,6 +100,20 @@ fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allo
|
||||||
return path;
|
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"
|
// 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)
|
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);
|
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"
|
// 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);
|
boost::filesystem::path removeCommonPath(const boost::filesystem::path& path, const boost::filesystem::path& relativeTo, bool& contains);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue