Collections are now properly initialized when enabled.

This commit is contained in:
Leon Styhre 2021-01-01 17:18:04 +01:00
parent 09a67eee19
commit fe4e94a827
3 changed files with 128 additions and 2 deletions

View file

@ -935,6 +935,74 @@ void CollectionSystemsManager::reactivateCustomCollectionEntry(FileData* game)
}
}
void CollectionSystemsManager::repopulateCollection(SystemData* sysData)
{
for (auto it = mAutoCollectionSystemsData.cbegin();
it != mAutoCollectionSystemsData.cend(); it++) {
if ((*it).second.system == sysData) {
LOG(LogDebug) << "CollectionSystemsManager::repopulateCollection(): "
"Repopulating auto collection '" << it->first << "'.";
CollectionSystemData* autoSystem = &mAutoCollectionSystemsData[it->first];
std::vector<FileData*> systemEntries =
autoSystem->system->getRootFolder()->getFilesRecursive(true, true, false);
if (systemEntries.empty())
return;
// Delete all children from the system and remove them from the index too.
for (FileData* entry : systemEntries) {
autoSystem->system->getIndex()->removeFromIndex(entry);
autoSystem->system->getRootFolder()->removeChild(entry);
delete entry;
}
// Flag the collection as not populated so it gets repopulated.
autoSystem->isPopulated = false;
populateAutoCollection(autoSystem);
// The cursor value is now pointing to some random memory address so we need to set
// it to something valid, as done here by selecting the first child. This does however
// not mean it's the first row of the gamelist, so we follow up with selecting the
// first entry after that. If doing this second step without the first step we would
// crash the application as it would try to access the old (now invalid) pointer.
auto autoView = ViewController::get()->getGameListView(autoSystem->system).get();
autoView->setCursor(autoSystem->system->getRootFolder()->
getChildrenRecursive().front());
autoView->setCursor(autoView->getFirstEntry());
}
}
for (auto it = mCustomCollectionSystemsData.cbegin();
it != mCustomCollectionSystemsData.cend(); it++) {
if ((*it).second.system == sysData) {
LOG(LogDebug) << "CollectionSystemsManager::repopulateCollection(): "
"Repopulating custom collection '" << it->first << "'.";
CollectionSystemData* customSystem = &mCustomCollectionSystemsData[it->first];
std::vector<FileData*> systemEntries =
customSystem->system->getRootFolder()->getFilesRecursive(true, true, false);
if (systemEntries.empty())
return;
for (FileData* entry : systemEntries) {
customSystem->system->getIndex()->removeFromIndex(entry);
customSystem->system->getRootFolder()->removeChild(entry);
delete entry;
}
customSystem->isPopulated = false;
populateCustomCollection(customSystem);
auto autoView = ViewController::get()->getGameListView(customSystem->system).get();
autoView->setCursor(customSystem->system->getRootFolder()->
getChildrenRecursive().front());
autoView->setCursor(autoView->getFirstEntry());
}
}
}
void CollectionSystemsManager::initAutoCollectionSystems()
{
for (std::map<std::string, CollectionSystemDecl, stringComparator>::const_iterator
@ -1038,6 +1106,13 @@ void CollectionSystemsManager::populateAutoCollection(CollectionSystemData* sysD
// collection was trimmed down to 50 items. If we don't do this, the game count will
// not be correct as it would include all the games prior to trimming.
if (rootFolder->getName() == "recent") {
// The following is needed to avoid a crash when repopulating the system as the previous
// cursor pointer may point to a random memory address.
auto recentGamelist = ViewController::get()->getGameListView(rootFolder->getSystem()).get();
recentGamelist->setCursor(rootFolder->getSystem()->getRootFolder()->
getChildrenRecursive().front());
recentGamelist->setCursor(recentGamelist->getFirstEntry());
ViewController::get()->getGameListView(rootFolder->getSystem()).get()->
onFileChanged(rootFolder->getChildren().front(), false);
}

View file

@ -112,6 +112,9 @@ public:
// Reactivate a game in all custom collections where it has an entry in the configuration file.
void reactivateCustomCollectionEntry(FileData* game);
// Repopulate the collection, which is basically a forced update of its complete content.
void repopulateCollection(SystemData* sysData);
inline std::map<std::string, CollectionSystemData, stringComparator>
getAutoCollectionSystems() { return mAutoCollectionSystemsData; };
inline std::map<std::string, CollectionSystemData, stringComparator>

View file

@ -14,6 +14,7 @@
#include "guis/GuiMsgBox.h"
#include "guis/GuiSettings.h"
#include "guis/GuiTextEditPopup.h"
#include "utils/StringUtil.h"
#include "views/ViewController.h"
#include "CollectionSystemsManager.h"
@ -49,7 +50,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(
collection_systems_auto->add(it->second.decl.longName, it->second.decl.name,
it->second.isEnabled);
addWithLabel("AUTOMATIC GAME COLLECTIONS", collection_systems_auto);
addSaveFunc([this] {
addSaveFunc([this, autoSystems] {
std::string autoSystemsSelected =
Utils::String::vectorToCommaString(collection_systems_auto->getSelectedObjects(), true);
std::string autoSystemsConfig = Settings::getInstance()->getString("CollectionSystemsAuto");
@ -57,6 +58,29 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(
if (CollectionSystemsManager::get()->isEditing())
CollectionSystemsManager::get()->exitEditMode();
Settings::getInstance()->setString("CollectionSystemsAuto", autoSystemsSelected);
// Check if any systems have been enabled, and if so repopulate them, which results in
// a complete initialization of their content. This is necessary as collections aren't
// updated while they are disabled.
std::vector<std::string> addedAutoSystems;
if (autoSystemsConfig == "") {
addedAutoSystems = Utils::String::delimitedStringToVector(autoSystemsSelected, ",");
}
else if (autoSystemsSelected != "") {
std::vector<std::string> selectedVector =
Utils::String::delimitedStringToVector(autoSystemsSelected, ",");
std::vector<std::string> configuredVector =
Utils::String::delimitedStringToVector(autoSystemsConfig, ",");
for (std::string system : selectedVector) {
if (std::find(configuredVector.begin(), configuredVector.end(), system) ==
configuredVector.end())
addedAutoSystems.push_back(system);
}
}
if (!addedAutoSystems.empty()) {
for (std::string system : addedAutoSystems)
CollectionSystemsManager::get()->
repopulateCollection(autoSystems.find(system)->second.system);
}
setNeedsSaving();
setNeedsReloading();
setNeedsCollectionsUpdate();
@ -76,7 +100,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(
collection_systems_custom->add(it->second.decl.longName, it->second.decl.name,
it->second.isEnabled);
addWithLabel("CUSTOM GAME COLLECTIONS", collection_systems_custom);
addSaveFunc([this] {
addSaveFunc([this, customSystems] {
if (!mDeletedCustomCollection) {
std::string customSystemsSelected = Utils::String::vectorToCommaString(
collection_systems_custom->getSelectedObjects(), true);
@ -87,6 +111,30 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(
CollectionSystemsManager::get()->exitEditMode();
Settings::getInstance()->setString("CollectionSystemsCustom",
customSystemsSelected);
// Check if any systems have been enabled, and if so repopulate them, which
// results in a complete initialization of their content. This is necessary as
// collections aren't updated while they are disabled.
std::vector<std::string> addedCustomSystems;
if (customSystemsConfig == "") {
addedCustomSystems =
Utils::String::delimitedStringToVector(customSystemsSelected, ",");
}
else if (customSystemsSelected != "") {
std::vector<std::string> selectedVector =
Utils::String::delimitedStringToVector(customSystemsSelected, ",");
std::vector<std::string> configuredVector =
Utils::String::delimitedStringToVector(customSystemsConfig, ",");
for (std::string system : selectedVector) {
if (std::find(configuredVector.begin(), configuredVector.end(), system) ==
configuredVector.end())
addedCustomSystems.push_back(system);
}
}
if (!addedCustomSystems.empty()) {
for (std::string system : addedCustomSystems)
CollectionSystemsManager::get()->
repopulateCollection(customSystems.find(system)->second.system);
}
setNeedsSaving();
setNeedsReloading();
setNeedsCollectionsUpdate();