ES-DE/es-app/src/FileFilterIndex.cpp

650 lines
24 KiB
C++
Raw Normal View History

// SPDX-License-Identifier: MIT
2020-06-22 15:27:53 +00:00
//
// EmulationStation Desktop Edition
2020-06-22 15:27:53 +00:00
// FileFilterIndex.cpp
//
// Gamelist filters.
//
#include "FileFilterIndex.h"
2017-11-01 22:21:10 +00:00
#include "FileData.h"
#include "Log.h"
#include "Settings.h"
#include "utils/StringUtil.h"
#include "views/UIModeController.h"
#include "views/ViewController.h"
2017-11-01 22:21:10 +00:00
#include <cmath>
#define UNKNOWN_LABEL "UNKNOWN"
#define INCLUDE_UNKNOWN false;
FileFilterIndex::FileFilterIndex()
: mFilterByText(false)
, mTextRemoveSystem(false)
, mFilterByFavorites(false)
, mFilterByGenre(false)
, mFilterByPlayers(false)
, mFilterByDeveloper(false)
, mFilterByPublisher(false)
, mFilterByRatings(false)
, mFilterByKidGame(false)
, mFilterByCompleted(false)
, mFilterByBroken(false)
, mFilterByHidden(false)
, mFilterByAltemulator(false)
{
2020-06-22 15:27:53 +00:00
clearAllFilters();
// clang-format off
2020-06-22 15:27:53 +00:00
FilterDataDecl filterDecls[] = {
//type //allKeys //filteredBy //filteredKeys //primaryKey //hasSecondaryKey //secondaryKey //menuLabel
{FAVORITES_FILTER, &mFavoritesIndexAllKeys, &mFilterByFavorites, &mFavoritesIndexFilteredKeys, "favorite", false, "", "FAVORITES"},
{GENRE_FILTER, &mGenreIndexAllKeys, &mFilterByGenre, &mGenreIndexFilteredKeys, "genre", true, "genre", "GENRE"},
{PLAYER_FILTER, &mPlayersIndexAllKeys, &mFilterByPlayers, &mPlayersIndexFilteredKeys, "players", false, "", "PLAYERS"},
{DEVELOPER_FILTER, &mDeveloperIndexAllKeys, &mFilterByDeveloper, &mDeveloperIndexFilteredKeys, "developer", false, "", "DEVELOPER"},
{PUBLISHER_FILTER, &mPublisherIndexAllKeys, &mFilterByPublisher, &mPublisherIndexFilteredKeys, "publisher", false, "", "PUBLISHER"},
{RATINGS_FILTER, &mRatingsIndexAllKeys, &mFilterByRatings, &mRatingsIndexFilteredKeys, "rating", false, "", "RATING"},
{KIDGAME_FILTER, &mKidGameIndexAllKeys, &mFilterByKidGame, &mKidGameIndexFilteredKeys, "kidgame", false, "", "KIDGAME"},
{COMPLETED_FILTER, &mCompletedIndexAllKeys, &mFilterByCompleted, &mCompletedIndexFilteredKeys, "completed", false, "", "COMPLETED"},
{BROKEN_FILTER, &mBrokenIndexAllKeys, &mFilterByBroken, &mBrokenIndexFilteredKeys, "broken", false, "", "BROKEN"},
{HIDDEN_FILTER, &mHiddenIndexAllKeys, &mFilterByHidden, &mHiddenIndexFilteredKeys, "hidden", false, "", "HIDDEN"},
{ALTEMULATOR_FILTER, &mAltemulatorIndexAllKeys, &mFilterByAltemulator, &mAltemulatorIndexFilteredKeys, "altemulator", false, "", "ALTERNATIVE EMULATOR"}
2020-06-22 15:27:53 +00:00
};
// clang-format on
2020-06-22 15:27:53 +00:00
filterDataDecl = std::vector<FilterDataDecl>(
filterDecls, filterDecls + sizeof(filterDecls) / sizeof(filterDecls[0]));
}
FileFilterIndex::~FileFilterIndex()
{
// Reset the index when destroyed.
2020-06-22 15:27:53 +00:00
resetIndex();
}
void FileFilterIndex::importIndex(FileFilterIndex* indexToImport)
{
2020-06-22 15:27:53 +00:00
struct IndexImportStructure {
std::map<std::string, int>* destinationIndex;
std::map<std::string, int>* sourceIndex;
};
IndexImportStructure indexStructDecls[] = {
{&mFavoritesIndexAllKeys, &(indexToImport->mFavoritesIndexAllKeys)},
{&mGenreIndexAllKeys, &(indexToImport->mGenreIndexAllKeys)},
{&mPlayersIndexAllKeys, &(indexToImport->mPlayersIndexAllKeys)},
{&mDeveloperIndexAllKeys, &(indexToImport->mDeveloperIndexAllKeys)},
{&mPublisherIndexAllKeys, &(indexToImport->mPublisherIndexAllKeys)},
{&mRatingsIndexAllKeys, &(indexToImport->mRatingsIndexAllKeys)},
{&mKidGameIndexAllKeys, &(indexToImport->mKidGameIndexAllKeys)},
{&mCompletedIndexAllKeys, &(indexToImport->mCompletedIndexAllKeys)},
{&mBrokenIndexAllKeys, &(indexToImport->mBrokenIndexAllKeys)},
{&mHiddenIndexAllKeys, &(indexToImport->mHiddenIndexAllKeys)},
{&mAltemulatorIndexAllKeys, &(indexToImport->mAltemulatorIndexAllKeys)},
2020-06-22 15:27:53 +00:00
};
std::vector<IndexImportStructure> indexImportDecl = std::vector<IndexImportStructure>(
indexStructDecls,
indexStructDecls + sizeof(indexStructDecls) / sizeof(indexStructDecls[0]));
2020-06-22 15:27:53 +00:00
for (std::vector<IndexImportStructure>::const_iterator indexesIt = indexImportDecl.cbegin();
indexesIt != indexImportDecl.cend(); indexesIt++) {
2020-06-22 15:27:53 +00:00
for (std::map<std::string, int>::const_iterator sourceIt =
(*indexesIt).sourceIndex->cbegin();
sourceIt != (*indexesIt).sourceIndex->cend(); sourceIt++) {
2020-06-22 15:27:53 +00:00
if ((*indexesIt).destinationIndex->find((*sourceIt).first) ==
(*indexesIt).destinationIndex->cend()) {
2020-06-22 15:27:53 +00:00
// Entry doesn't exist.
(*((*indexesIt).destinationIndex))[(*sourceIt).first] = (*sourceIt).second;
}
else {
2020-06-22 15:27:53 +00:00
(*((*indexesIt).destinationIndex))[(*sourceIt).first] += (*sourceIt).second;
}
2020-06-22 15:27:53 +00:00
}
}
}
2020-06-22 15:27:53 +00:00
void FileFilterIndex::resetIndex()
{
2020-06-22 15:27:53 +00:00
clearAllFilters();
2020-11-08 15:47:51 +00:00
clearIndex(mFavoritesIndexAllKeys);
clearIndex(mGenreIndexAllKeys);
clearIndex(mPlayersIndexAllKeys);
clearIndex(mDeveloperIndexAllKeys);
clearIndex(mPublisherIndexAllKeys);
2020-11-08 15:47:51 +00:00
clearIndex(mRatingsIndexAllKeys);
clearIndex(mKidGameIndexAllKeys);
clearIndex(mCompletedIndexAllKeys);
clearIndex(mBrokenIndexAllKeys);
clearIndex(mHiddenIndexAllKeys);
clearIndex(mAltemulatorIndexAllKeys);
}
2020-06-22 15:27:53 +00:00
std::string FileFilterIndex::getIndexableKey(FileData* game,
FilterIndexType type,
bool getSecondary)
{
2020-06-22 15:27:53 +00:00
std::string key = "";
switch (type) {
case FAVORITES_FILTER: {
if (game->getType() != GAME)
return "FALSE";
key = Utils::String::toUpper(game->metadata.get("favorite"));
break;
}
2020-06-22 15:27:53 +00:00
case GENRE_FILTER: {
key = Utils::String::toUpper(game->metadata.get("genre"));
if (getSecondary && !key.empty()) {
std::istringstream f(key);
std::string newKey;
getline(f, newKey, '/');
if (!newKey.empty() && newKey != key)
key = newKey;
else
key = std::string();
}
break;
}
case PLAYER_FILTER: {
if (getSecondary)
break;
key = Utils::String::toUpper(game->metadata.get("players"));
2020-06-22 15:27:53 +00:00
break;
}
case DEVELOPER_FILTER: {
key = Utils::String::toUpper(game->metadata.get("developer"));
break;
}
case PUBLISHER_FILTER: {
2020-06-22 15:27:53 +00:00
key = Utils::String::toUpper(game->metadata.get("publisher"));
break;
}
case RATINGS_FILTER: {
int ratingNumber = 0;
if (!getSecondary) {
std::string ratingString = game->metadata.get("rating");
if (!ratingString.empty()) {
try {
// Round up fractional values such as 0.75 to 0.8.
// These values should only exist if a third party application has
// been used for scraping the ratings, or if the gamelist.xml file
// has been manually edited.
ratingNumber =
static_cast<int>((ceilf(stof(ratingString) / 0.1f) / 10.0f) * 5.0f);
2020-06-22 15:27:53 +00:00
if (ratingNumber < 0)
ratingNumber = 0;
if (ratingNumber == 5)
key = "5 STARS";
else
key = std::to_string(ratingNumber) + " - " +
std::to_string(ratingNumber) + ".5 STARS";
2020-06-22 15:27:53 +00:00
}
catch (int e) {
LOG(LogError) << "Error parsing Rating (invalid value, exception nr.): "
<< ratingString << ", " << e;
2020-06-22 15:27:53 +00:00
}
}
}
break;
}
case KIDGAME_FILTER: {
2020-06-22 15:27:53 +00:00
if (game->getType() != GAME)
return "FALSE";
key = Utils::String::toUpper(game->metadata.get("kidgame"));
2020-06-22 15:27:53 +00:00
break;
}
case COMPLETED_FILTER: {
2020-06-22 15:27:53 +00:00
if (game->getType() != GAME)
return "FALSE";
key = Utils::String::toUpper(game->metadata.get("completed"));
2020-06-22 15:27:53 +00:00
break;
}
case BROKEN_FILTER: {
2020-06-22 15:27:53 +00:00
if (game->getType() != GAME)
return "FALSE";
key = Utils::String::toUpper(game->metadata.get("broken"));
break;
}
case HIDDEN_FILTER: {
if (game->getType() != GAME)
return "FALSE";
key = Utils::String::toUpper(game->metadata.get("hidden"));
2020-06-22 15:27:53 +00:00
break;
}
case ALTEMULATOR_FILTER: {
if (getSecondary)
break;
key = Utils::String::toUpper(game->metadata.get("altemulator"));
break;
}
default:
break;
2020-06-22 15:27:53 +00:00
}
key = Utils::String::trim(key);
// Add a dummy value in case there is no metadata defined so we can filter based on this.
if ((type == GENRE_FILTER || type == PLAYER_FILTER || type == DEVELOPER_FILTER ||
type == PUBLISHER_FILTER) &&
Utils::String::toUpper(key) == UNKNOWN_LABEL)
key = ViewController::CROSSEDCIRCLE_CHAR + " UNKNOWN";
else if (type == ALTEMULATOR_FILTER && key.empty())
key = ViewController::CROSSEDCIRCLE_CHAR + " NONE DEFINED";
else if (key.empty() || (type == RATINGS_FILTER && key == "0 STARS"))
2020-06-22 15:27:53 +00:00
key = UNKNOWN_LABEL;
2020-06-22 15:27:53 +00:00
return key;
}
void FileFilterIndex::addToIndex(FileData* game)
{
manageFavoritesEntryInIndex(game);
2020-06-22 15:27:53 +00:00
manageGenreEntryInIndex(game);
managePlayerEntryInIndex(game);
manageDeveloperEntryInIndex(game);
managePublisherEntryInIndex(game);
2020-06-22 15:27:53 +00:00
manageRatingsEntryInIndex(game);
manageKidGameEntryInIndex(game);
manageCompletedEntryInIndex(game);
manageBrokenEntryInIndex(game);
manageHiddenEntryInIndex(game);
manageAltemulatorEntryInIndex(game);
}
void FileFilterIndex::removeFromIndex(FileData* game)
{
manageFavoritesEntryInIndex(game, true);
2020-06-22 15:27:53 +00:00
manageGenreEntryInIndex(game, true);
managePlayerEntryInIndex(game, true);
manageDeveloperEntryInIndex(game, true);
managePublisherEntryInIndex(game, true);
2020-06-22 15:27:53 +00:00
manageRatingsEntryInIndex(game, true);
manageKidGameEntryInIndex(game, true);
manageCompletedEntryInIndex(game, true);
manageBrokenEntryInIndex(game, true);
manageHiddenEntryInIndex(game, true);
manageAltemulatorEntryInIndex(game, true);
}
void FileFilterIndex::setFilter(FilterIndexType type, std::vector<std::string>* values)
{
2020-06-22 15:27:53 +00:00
// Test if it exists before setting.
if (type == NONE) {
clearAllFilters();
}
else {
for (std::vector<FilterDataDecl>::const_iterator it = filterDataDecl.cbegin();
it != filterDataDecl.cend(); it++) {
2020-06-22 15:27:53 +00:00
if ((*it).type == type) {
FilterDataDecl filterData = (*it);
*(filterData.filteredByRef) = values->size() > 0;
filterData.currentFilteredKeys->clear();
for (std::vector<std::string>::const_iterator vit = values->cbegin();
vit != values->cend(); vit++) {
// Check if it exists.
2020-06-22 15:27:53 +00:00
if (filterData.allIndexKeys->find(*vit) != filterData.allIndexKeys->cend()) {
filterData.currentFilteredKeys->push_back(std::string(*vit));
}
}
}
}
}
return;
}
void FileFilterIndex::setTextFilter(std::string textFilter)
{
mTextFilter = textFilter;
if (textFilter == "")
mFilterByText = false;
else
mFilterByText = true;
}
void FileFilterIndex::clearAllFilters()
{
2020-06-22 15:27:53 +00:00
for (std::vector<FilterDataDecl>::const_iterator it = filterDataDecl.cbegin();
it != filterDataDecl.cend(); it++) {
2020-06-22 15:27:53 +00:00
FilterDataDecl filterData = (*it);
*(filterData.filteredByRef) = false;
filterData.currentFilteredKeys->clear();
}
setTextFilter("");
2020-06-22 15:27:53 +00:00
return;
}
void FileFilterIndex::resetFilters()
{
2020-06-22 15:27:53 +00:00
clearAllFilters();
setKidModeFilters();
}
void FileFilterIndex::setKidModeFilters()
{
if (UIModeController::getInstance()->isUIModeKid()) {
mFilterByKidGame = true;
std::vector<std::string> val = {"TRUE"};
setFilter(KIDGAME_FILTER, &val);
2020-06-22 15:27:53 +00:00
}
}
void FileFilterIndex::debugPrintIndexes()
{
2020-06-22 15:27:53 +00:00
LOG(LogInfo) << "Printing Indexes...";
for (auto x : mFavoritesIndexAllKeys) {
LOG(LogInfo) << "Favorites Index: " << x.first << ": " << x.second;
2020-06-22 15:27:53 +00:00
}
for (auto x : mGenreIndexAllKeys) {
2020-06-22 15:27:53 +00:00
LOG(LogInfo) << "Genre Index: " << x.first << ": " << x.second;
}
for (auto x : mPlayersIndexAllKeys) {
LOG(LogInfo) << "Multiplayer Index: " << x.first << ": " << x.second;
2020-06-22 15:27:53 +00:00
}
for (auto x : mDeveloperIndexAllKeys) {
LOG(LogInfo) << "PubDev Index: " << x.first << ": " << x.second;
}
for (auto x : mPublisherIndexAllKeys) {
2020-06-22 15:27:53 +00:00
LOG(LogInfo) << "PubDev Index: " << x.first << ": " << x.second;
}
for (auto x : mRatingsIndexAllKeys) {
LOG(LogInfo) << "Ratings Index: " << x.first << ": " << x.second;
2020-06-22 15:27:53 +00:00
}
2020-11-08 15:47:51 +00:00
for (auto x : mKidGameIndexAllKeys) {
2020-06-22 15:27:53 +00:00
LOG(LogInfo) << "KidGames Index: " << x.first << ": " << x.second;
}
2020-11-08 15:47:51 +00:00
for (auto x : mCompletedIndexAllKeys) {
LOG(LogInfo) << "Completed Index: " << x.first << ": " << x.second;
}
2020-11-08 15:47:51 +00:00
for (auto x : mBrokenIndexAllKeys) {
LOG(LogInfo) << "Broken Index: " << x.first << ": " << x.second;
}
2020-11-08 15:47:51 +00:00
for (auto x : mHiddenIndexAllKeys) {
LOG(LogInfo) << "Hidden Index: " << x.first << ": " << x.second;
}
for (auto x : mAltemulatorIndexAllKeys) {
LOG(LogInfo) << "Altemulator Index: " << x.first << ": " << x.second;
}
}
bool FileFilterIndex::showFile(FileData* game)
{
2020-06-22 15:27:53 +00:00
// If folder, needs further inspection - i.e. see if folder contains at least one element
// that should be shown.
if (game->getType() == FOLDER) {
std::vector<FileData*> children = game->getChildren();
// Iterate through all of the children, until there's a match.
for (std::vector<FileData*>::const_iterator it = children.cbegin(); it != children.cend();
it++) {
2020-06-22 15:27:53 +00:00
if (showFile(*it))
return true;
}
return false;
}
bool nameMatch = false;
2020-06-22 15:27:53 +00:00
bool keepGoing = false;
// Name filters take precedence over all other filters, so if there is no match for
// the game name, then always return false. If we're in a collection system and the option
// to show the system name has been enabled, then exclude the system name that is encapsulated
// in [] from the search string.
if (mTextFilter != "" && mTextRemoveSystem &&
!(Utils::String::toUpper(game->getName().substr(0, game->getName().find_last_of("[")))
.find(mTextFilter) != std::string::npos)) {
return false;
}
else if (mTextFilter != "" &&
!(Utils::String::toUpper(game->getName()).find(mTextFilter) != std::string::npos)) {
return false;
}
if (mTextFilter != "")
nameMatch = true;
2020-06-22 15:27:53 +00:00
for (std::vector<FilterDataDecl>::const_iterator it = filterDataDecl.cbegin();
it != filterDataDecl.cend(); it++) {
2020-06-22 15:27:53 +00:00
FilterDataDecl filterData = (*it);
if (filterData.primaryKey == "kidgame" && UIModeController::getInstance()->isUIModeKid()) {
return (getIndexableKey(game, filterData.type, false) != "FALSE");
}
else if (*(filterData.filteredByRef)) {
2020-06-22 15:27:53 +00:00
// Try to find a match.
std::string key = getIndexableKey(game, filterData.type, false);
keepGoing = isKeyBeingFilteredBy(key, filterData.type);
// If we didn't find a match, try for secondary keys - i.e.
// publisher and dev, or first genre.
if (!keepGoing) {
if (!filterData.hasSecondaryKey)
return false;
std::string secKey = getIndexableKey(game, filterData.type, true);
if (secKey != UNKNOWN_LABEL)
keepGoing = isKeyBeingFilteredBy(secKey, filterData.type);
}
// If still nothing, then it's not a match.
if (!keepGoing)
return false;
}
}
// If there is a match for the game name, but not for any other filters, then return
// true as it means that the name filter is the only applied filter.
if (!keepGoing && nameMatch)
return true;
else
return keepGoing;
}
bool FileFilterIndex::isFiltered()
{
if (UIModeController::getInstance()->isUIModeKid()) {
return (mFilterByText || mFilterByFavorites || mFilterByGenre || mFilterByPlayers ||
mFilterByDeveloper || mFilterByPublisher || mFilterByRatings ||
mFilterByCompleted || mFilterByBroken || mFilterByHidden || mFilterByAltemulator);
}
else {
return (mFilterByText || mFilterByFavorites || mFilterByGenre || mFilterByPlayers ||
mFilterByDeveloper || mFilterByPublisher || mFilterByRatings || mFilterByKidGame ||
mFilterByCompleted || mFilterByBroken || mFilterByHidden | mFilterByAltemulator);
}
}
bool FileFilterIndex::isKeyBeingFilteredBy(std::string key, FilterIndexType type)
{
const FilterIndexType filterTypes[11] = {FAVORITES_FILTER, GENRE_FILTER, PLAYER_FILTER,
DEVELOPER_FILTER, PUBLISHER_FILTER, RATINGS_FILTER,
KIDGAME_FILTER, COMPLETED_FILTER, BROKEN_FILTER,
HIDDEN_FILTER, ALTEMULATOR_FILTER};
std::vector<std::string> filterKeysList[11] = {
mFavoritesIndexFilteredKeys, mGenreIndexFilteredKeys, mPlayersIndexFilteredKeys,
mDeveloperIndexFilteredKeys, mPublisherIndexFilteredKeys, mRatingsIndexFilteredKeys,
mKidGameIndexFilteredKeys, mCompletedIndexFilteredKeys, mBrokenIndexFilteredKeys,
mHiddenIndexFilteredKeys, mAltemulatorIndexFilteredKeys};
for (int i = 0; i < 11; i++) {
2020-06-22 15:27:53 +00:00
if (filterTypes[i] == type) {
for (std::vector<std::string>::const_iterator it = filterKeysList[i].cbegin();
it != filterKeysList[i].cend(); it++) {
2020-06-22 15:27:53 +00:00
if (key == (*it))
return true;
}
return false;
}
}
return false;
}
void FileFilterIndex::manageFavoritesEntryInIndex(FileData* game, bool remove)
{
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, FAVORITES_FILTER, false);
if (!includeUnknown && key == UNKNOWN_LABEL)
return;
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mFavoritesIndexAllKeys, key, remove);
}
void FileFilterIndex::manageGenreEntryInIndex(FileData* game, bool remove)
{
2020-06-22 15:27:53 +00:00
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, GENRE_FILTER, false);
2020-06-22 15:27:53 +00:00
if (!includeUnknown && (key == UNKNOWN_LABEL || key == "BIOS"))
return;
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mGenreIndexAllKeys, key, remove);
2020-06-22 15:27:53 +00:00
key = getIndexableKey(game, GENRE_FILTER, true);
if (!includeUnknown && key == UNKNOWN_LABEL)
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mGenreIndexAllKeys, key, remove);
}
void FileFilterIndex::managePlayerEntryInIndex(FileData* game, bool remove)
{
2020-06-22 15:27:53 +00:00
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, PLAYER_FILTER, false);
2020-06-22 15:27:53 +00:00
if (!includeUnknown && key == UNKNOWN_LABEL)
return;
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mPlayersIndexAllKeys, key, remove);
}
void FileFilterIndex::manageDeveloperEntryInIndex(FileData* game, bool remove)
{
2020-06-22 15:27:53 +00:00
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, DEVELOPER_FILTER, false);
if (!includeUnknown && key == UNKNOWN_LABEL)
return;
manageIndexEntry(&mDeveloperIndexAllKeys, key, remove);
2020-06-22 15:27:53 +00:00
key = getIndexableKey(game, DEVELOPER_FILTER, true);
if (!includeUnknown && key == UNKNOWN_LABEL)
manageIndexEntry(&mDeveloperIndexAllKeys, key, remove);
}
2020-06-22 15:27:53 +00:00
void FileFilterIndex::managePublisherEntryInIndex(FileData* game, bool remove)
{
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, PUBLISHER_FILTER, false);
2020-06-22 15:27:53 +00:00
if (!includeUnknown && key == UNKNOWN_LABEL)
2020-06-22 15:27:53 +00:00
return;
manageIndexEntry(&mPublisherIndexAllKeys, key, remove);
key = getIndexableKey(game, PUBLISHER_FILTER, true);
if (!includeUnknown && key == UNKNOWN_LABEL)
manageIndexEntry(&mPublisherIndexAllKeys, key, remove);
}
void FileFilterIndex::manageRatingsEntryInIndex(FileData* game, bool remove)
{
2020-06-22 15:27:53 +00:00
std::string key = getIndexableKey(game, RATINGS_FILTER, false);
2020-06-22 15:27:53 +00:00
// Flag for including unknowns.
bool includeUnknown = INCLUDE_UNKNOWN;
2020-06-22 15:27:53 +00:00
if (!includeUnknown && key == UNKNOWN_LABEL)
// No valid rating info found.
return;
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mRatingsIndexAllKeys, key, remove);
}
void FileFilterIndex::manageKidGameEntryInIndex(FileData* game, bool remove)
{
2020-06-22 15:27:53 +00:00
// Flag for including unknowns.
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, KIDGAME_FILTER, false);
2020-06-22 15:27:53 +00:00
if (!includeUnknown && key == UNKNOWN_LABEL)
// No valid kidgame info found.
2020-06-22 15:27:53 +00:00
return;
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mKidGameIndexAllKeys, key, remove);
}
void FileFilterIndex::manageCompletedEntryInIndex(FileData* game, bool remove)
{
2020-06-22 15:27:53 +00:00
// Flag for including unknowns.
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, COMPLETED_FILTER, false);
2020-06-22 15:27:53 +00:00
if (!includeUnknown && key == UNKNOWN_LABEL)
// No valid completed info found.
2020-06-22 15:27:53 +00:00
return;
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mCompletedIndexAllKeys, key, remove);
}
void FileFilterIndex::manageBrokenEntryInIndex(FileData* game, bool remove)
{
2020-06-22 15:27:53 +00:00
// Flag for including unknowns.
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, BROKEN_FILTER, false);
2020-06-22 15:27:53 +00:00
if (!includeUnknown && key == UNKNOWN_LABEL)
// No valid broken info found.
2020-06-22 15:27:53 +00:00
return;
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mBrokenIndexAllKeys, key, remove);
}
void FileFilterIndex::manageHiddenEntryInIndex(FileData* game, bool remove)
{
// Flag for including unknowns.
bool includeUnknown = INCLUDE_UNKNOWN;
std::string key = getIndexableKey(game, HIDDEN_FILTER, false);
if (!includeUnknown && key == UNKNOWN_LABEL)
// No valid hidden info found.
return;
2020-11-08 15:47:51 +00:00
manageIndexEntry(&mHiddenIndexAllKeys, key, remove);
}
void FileFilterIndex::manageAltemulatorEntryInIndex(FileData* game, bool remove)
{
std::string key = getIndexableKey(game, ALTEMULATOR_FILTER, false);
manageIndexEntry(&mAltemulatorIndexAllKeys, key, remove);
}
2020-06-22 15:27:53 +00:00
void FileFilterIndex::manageIndexEntry(std::map<std::string, int>* index,
std::string key,
bool remove)
2020-06-22 15:27:53 +00:00
{
bool includeUnknown = INCLUDE_UNKNOWN;
if (!includeUnknown && key == UNKNOWN_LABEL)
return;
if (remove) {
// Removing entry.
if (index->find(key) == index->cend()) {
// Disabled for now as this could happen because default values are assigned as
// filters, for example 'FALSE' for favorites and kidgames for non-game entries.
// LOG(LogDebug) << "Couldn't find entry in index! " << key;
2020-06-22 15:27:53 +00:00
}
else {
(index->at(key))--;
if (index->at(key) <= 0) {
index->erase(key);
}
}
}
else {
// Adding entry.
if (index->find(key) == index->cend())
(*index)[key] = 1;
else
(index->at(key))++;
}
}