Merge pull request #78 from verybadsoldier/only_save_gamelist_diffs

Instant Shutdown by only writing changes to gamelist.xml
This commit is contained in:
Jools Wills 2016-12-20 17:58:32 +00:00 committed by GitHub
commit 74d1bb4ca1
3 changed files with 36 additions and 12 deletions

View file

@ -139,6 +139,8 @@ void parseGamelist(SystemData* system)
//make sure name gets set if one didn't exist //make sure name gets set if one didn't exist
if(file->metadata.get("name").empty()) if(file->metadata.get("name").empty())
file->metadata.set("name", defaultName); file->metadata.set("name", defaultName);
file->metadata.resetChangedFlag();
} }
} }
} }
@ -207,20 +209,24 @@ void updateGamelist(SystemData* system)
FileData* rootFolder = system->getRootFolder(); FileData* rootFolder = system->getRootFolder();
if (rootFolder != nullptr) if (rootFolder != nullptr)
{ {
int numUpdated = 0;
//get only files, no folders //get only files, no folders
std::vector<FileData*> files = rootFolder->getFilesRecursive(GAME | FOLDER); std::vector<FileData*> files = rootFolder->getFilesRecursive(GAME | FOLDER);
//iterate through all files, checking if they're already in the XML //iterate through all files, checking if they're already in the XML
std::vector<FileData*>::const_iterator fit = files.cbegin(); for(std::vector<FileData*>::const_iterator fit = files.cbegin(); fit != files.cend(); ++fit)
while(fit != files.cend())
{ {
const char* tag = ((*fit)->getType() == GAME) ? "game" : "folder"; const char* tag = ((*fit)->getType() == GAME) ? "game" : "folder";
// check if current file has metadata, if no, skip it as it wont be in the gamelist anyway. // check if current file has metadata, if no, skip it as it wont be in the gamelist anyway.
if ((*fit)->metadata.isDefault()) { if ((*fit)->metadata.isDefault()) {
++fit;
continue; continue;
} }
// do not touch if it wasn't changed anyway
if (!(*fit)->metadata.wasChanged())
continue;
// check if the file already exists in the XML // check if the file already exists in the XML
// if it does, remove it before adding // if it does, remove it before adding
for(pugi::xml_node fileNode = root.child(tag); fileNode; fileNode = fileNode.next_sibling(tag)) for(pugi::xml_node fileNode = root.child(tag); fileNode; fileNode = fileNode.next_sibling(tag))
@ -244,19 +250,22 @@ void updateGamelist(SystemData* system)
// it was either removed or never existed to begin with; either way, we can add it now // it was either removed or never existed to begin with; either way, we can add it now
addFileDataNode(root, *fit, tag, system); addFileDataNode(root, *fit, tag, system);
++numUpdated;
++fit;
} }
//now write the file //now write the file
if (numUpdated > 0) {
//make sure the folders leading up to this path exist (or the write will fail) //make sure the folders leading up to this path exist (or the write will fail)
boost::filesystem::path xmlWritePath(system->getGamelistPath(true)); boost::filesystem::path xmlWritePath(system->getGamelistPath(true));
boost::filesystem::create_directories(xmlWritePath.parent_path()); boost::filesystem::create_directories(xmlWritePath.parent_path());
LOG(LogInfo) << "Added/Updated " << numUpdated << " entities in '" << xmlReadPath << "'";
if (!doc.save_file(xmlWritePath.c_str())) { if (!doc.save_file(xmlWritePath.c_str())) {
LOG(LogError) << "Error saving gamelist.xml to \"" << xmlWritePath << "\" (for system " << system->getName() << ")!"; LOG(LogError) << "Error saving gamelist.xml to \"" << xmlWritePath << "\" (for system " << system->getName() << ")!";
} }
}
}else{ }else{
LOG(LogError) << "Found no root folder for system \"" << system->getName() << "\"!"; LOG(LogError) << "Found no root folder for system \"" << system->getName() << "\"!";
} }

View file

@ -49,7 +49,7 @@ const std::vector<MetaDataDecl>& getMDDByType(MetaDataListType type)
MetaDataList::MetaDataList(MetaDataListType type) MetaDataList::MetaDataList(MetaDataListType type)
: mType(type) : mType(type), mWasChanged(false)
{ {
const std::vector<MetaDataDecl>& mdd = getMDD(); const std::vector<MetaDataDecl>& mdd = getMDD();
for(auto iter = mdd.begin(); iter != mdd.end(); iter++) for(auto iter = mdd.begin(); iter != mdd.end(); iter++)
@ -110,11 +110,12 @@ void MetaDataList::appendToXML(pugi::xml_node parent, bool ignoreDefaults, const
void MetaDataList::set(const std::string& key, const std::string& value) void MetaDataList::set(const std::string& key, const std::string& value)
{ {
mMap[key] = value; mMap[key] = value;
mWasChanged = true;
} }
void MetaDataList::setTime(const std::string& key, const boost::posix_time::ptime& time) void MetaDataList::setTime(const std::string& key, const boost::posix_time::ptime& time)
{ {
mMap[key] = boost::posix_time::to_iso_string(time); set(key, boost::posix_time::to_iso_string(time));
} }
const std::string& MetaDataList::get(const std::string& key) const const std::string& MetaDataList::get(const std::string& key) const
@ -147,3 +148,13 @@ bool MetaDataList::isDefault()
return true; return true;
} }
bool MetaDataList::wasChanged() const
{
return mWasChanged;
}
void MetaDataList::resetChangedFlag()
{
mWasChanged = false;
}

View file

@ -58,10 +58,14 @@ public:
bool isDefault(); bool isDefault();
bool wasChanged() const;
void resetChangedFlag();
inline MetaDataListType getType() const { return mType; } inline MetaDataListType getType() const { return mType; }
inline const std::vector<MetaDataDecl>& getMDD() const { return getMDDByType(getType()); } inline const std::vector<MetaDataDecl>& getMDD() const { return getMDDByType(getType()); }
private: private:
MetaDataListType mType; MetaDataListType mType;
std::map<std::string, std::string> mMap; std::map<std::string, std::string> mMap;
bool mWasChanged;
}; };