diff --git a/NEWS.md b/NEWS.md index 805fa5c5a..9e1aa0d9a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,7 +12,7 @@ OpenGL GLSL shader support has been added (not for the OpenGL ES renderer though A new default theme rbsimple-DE (based on Recalbox Multi) is bundled with the application and is part of the installation package/installer. However themes created for other EmulationStation ports should still work correctly. -Many bugs have been fixed, and numerous features that were only partially implemented or broken have been updated to a fully working state. +Many bugs have been fixed, and numerous features that were only partially implemented or broken have been updated to a fully working state. The application runs much faster as well due to lots of optimizations. ### Detailed list of changes @@ -25,6 +25,7 @@ Many bugs have been fixed, and numerous features that were only partially implem * In the metadata editor, any values updated by the single-game scraper or by the user are now highlighted using a different font color * Files or folders can now be flagged for exclusion when scraping with the multi-scraper, and for folders it can be set to apply recursively * Gamelist sorting is now working as expected and is persistent throughout the application session +* Overhaul of the game collection functionality including many bug fixes and optimizations * Game counting is now done during sorting instead of every time a system is selected. This should make the UI more responsive in case of large game libraries * Added a system view counter for favorite games in addition to the total number of games * Added support for jumping to the start and end of gamelists and menus using the controller trigger buttons (or equivalent keyboard mappings) @@ -89,6 +90,7 @@ Many bugs have been fixed, and numerous features that were only partially implem * Fixed an annoying gamelist issue that caused the game images and data to be updated and rendered up to six times every time the list was scrolled * VRAM statistics overlay was somewhat broken and incorrectly displayed numbers in megabytes instead of mebibytes * Not all input events were logged when running with debug logging activated +* Filters were not applied when leaving folders by using the back button * Editing long text entries made the cursor jump outside the editing field * Long game names would sometimes not scroll in the gamelist view * On Unix, adding a hidden folder with a game in it crashed the application on startup diff --git a/es-app/src/CollectionSystemManager.cpp b/es-app/src/CollectionSystemManager.cpp index de8e99c9a..0ccce2ddd 100644 --- a/es-app/src/CollectionSystemManager.cpp +++ b/es-app/src/CollectionSystemManager.cpp @@ -380,7 +380,7 @@ void CollectionSystemManager::updateCollectionSystem(FileData* file, CollectionS else { // Re-index with new metadata. fileIndex->addToIndex(collectionEntry); - ViewController::get()->onFileChanged(collectionEntry, FILE_METADATA_CHANGED); + ViewController::get()->onFileChanged(collectionEntry, false); } } else { @@ -398,7 +398,7 @@ void CollectionSystemManager::updateCollectionSystem(FileData* file, CollectionS rootFolder->addChild(newGame); fileIndex->addToIndex(newGame); ViewController::get()-> - getGameListView(curSys)->onFileChanged(newGame, FILE_METADATA_CHANGED); + getGameListView(curSys)->onFileChanged(newGame, false); } } @@ -424,7 +424,7 @@ void CollectionSystemManager::updateCollectionSystem(FileData* file, CollectionS if (name == "recent") { trimCollectionCount(rootFolder, LAST_PLAYED_MAX); - ViewController::get()->onFileChanged(rootFolder, FILE_METADATA_CHANGED); + ViewController::get()->onFileChanged(rootFolder, false); // This is a bit of a hack to prevent a jump to the first line of the gamelist // if an entry is manually adjusted from within the 'recent' gamelist, for example // by toggling a game as favorite. If the time since the last played timestamp is @@ -441,7 +441,7 @@ void CollectionSystemManager::updateCollectionSystem(FileData* file, CollectionS } } else { - ViewController::get()->onFileChanged(rootFolder, FILE_SORTED); + ViewController::get()->onFileChanged(rootFolder, false); // If it's a custom collection and the setting to group the collections is // enabled, we may have to update the parent instead. // However it may not necessarily be so if some collections are themed and @@ -450,11 +450,10 @@ void CollectionSystemManager::updateCollectionSystem(FileData* file, CollectionS Settings::getInstance()->getBool("UseCustomCollectionsSystem")) { // In case of a returned null pointer, we know there is no parent. if (rootFolder->getParent() == nullptr) { - ViewController::get()->onFileChanged(rootFolder, FILE_METADATA_CHANGED); + ViewController::get()->onFileChanged(rootFolder, false); } else { - ViewController::get()->onFileChanged( - rootFolder->getParent(), FILE_METADATA_CHANGED); + ViewController::get()->onFileChanged(rootFolder->getParent(), false); } } } @@ -682,8 +681,7 @@ bool CollectionSystemManager::toggleGameInCollection(FileData* file) systemViewToUpdate->getRootFolder()->sort(rootFolder->getSortTypeFromString( rootFolder->getSortTypeString()), Settings::getInstance()->getBool("FavFirstCustom")); - ViewController::get()->onFileChanged(systemViewToUpdate-> - getRootFolder(), FILE_SORTED); + ViewController::get()->onFileChanged(systemViewToUpdate->getRootFolder(), false); fileIndex->addToIndex(newGame); // Add to bundle index as well, if needed. diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index 943b2e0f0..ebac70105 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -26,13 +26,6 @@ enum FileType { PLACEHOLDER = 3 }; -enum FileChangeType { - FILE_ADDED, - FILE_METADATA_CHANGED, - FILE_REMOVED, - FILE_SORTED -}; - // Used for loading/saving gamelist.xml. const char* fileTypeToString(FileType type); FileType stringToFileType(const char* str); diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index e9ca5e4d6..94081edba 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -231,7 +231,7 @@ GuiGamelistOptions::~GuiGamelistOptions() root->setSortTypeString((*mListSort->getSelected()).description); // Notify that the root folder was sorted (refresh). - getGamelist()->onFileChanged(root, FILE_SORTED); + getGamelist()->onFileChanged(root, false); } // Has the user changed the letter using the quick selector? @@ -347,7 +347,7 @@ void GuiGamelistOptions::openMetaDataEd() file->metadata.getMDD(FOLDER_METADATA), p, Utils::FileSystem::getFileName(file->getPath()), std::bind( &IGameListView::onFileChanged, ViewController::get()->getGameListView( - file->getSystem()).get(), file, FILE_METADATA_CHANGED), + file->getSystem()).get(), file, true), clearGameBtnFunc, deleteGameBtnFunc)); } else { @@ -355,7 +355,7 @@ void GuiGamelistOptions::openMetaDataEd() file->metadata.getMDD(GAME_METADATA), p, Utils::FileSystem::getFileName(file->getPath()), std::bind( &IGameListView::onFileChanged, ViewController::get()->getGameListView( - file->getSystem()).get(), file, FILE_METADATA_CHANGED), + file->getSystem()).get(), file, true), clearGameBtnFunc, deleteGameBtnFunc)); } } diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index ebbecd2a0..680e890a4 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -286,11 +286,11 @@ void ViewController::playViewTransition() } } -void ViewController::onFileChanged(FileData* file, FileChangeType change) +void ViewController::onFileChanged(FileData* file, bool reloadGameList) { auto it = mGameListViews.find(file->getSystem()); if (it != mGameListViews.cend()) - it->second->onFileChanged(file, change); + it->second->onFileChanged(file, reloadGameList); } void ViewController::launch(FileData* game, Vector3f center) @@ -327,7 +327,7 @@ void ViewController::launch(FileData* game, Vector3f center) setAnimation(new LambdaAnimation([](float t){}, 1700), 0, [this, game] { while (NavigationSounds::getInstance()->isPlayingThemeNavigationSound(LAUNCHSOUND)); game->launchGame(mWindow); - onFileChanged(game, FILE_METADATA_CHANGED); + onFileChanged(game, true); // This is a workaround so that any key or button presses used for exiting the emulator // are not captured upon returning to ES. setAnimation(new LambdaAnimation([](float t){}, 1), 0, [this] { diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h index 0d4d2f508..1040780e6 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -58,7 +58,7 @@ public: void resetMovingCamera(); void stopScrolling(); - void onFileChanged(FileData* file, FileChangeType change); + void onFileChanged(FileData* file, bool reloadGameList); void launch(FileData* game, Vector3f centerCameraOn = Vector3f(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f, 0)); diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index d22ecb34e..82e08e104 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -38,15 +38,15 @@ void BasicGameListView::onThemeChanged(const std::shared_ptr& theme) sortChildren(); } -void BasicGameListView::onFileChanged(FileData* file, FileChangeType change) +void BasicGameListView::onFileChanged(FileData* file, bool reloadGameList) { - if (change == FILE_METADATA_CHANGED) { + if (reloadGameList) { // Might switch to a detailed view. ViewController::get()->reloadGameListView(this); return; } - ISimpleGameListView::onFileChanged(file, change); + ISimpleGameListView::onFileChanged(file, reloadGameList); } void BasicGameListView::populateList(const std::vector& files) @@ -203,7 +203,7 @@ void BasicGameListView::remove(FileData *game, bool deleteFile) if (deleteFile) { parent->sort(parent->getSortTypeFromString(parent->getSortTypeString()), Settings::getInstance()->getBool("FavoritesFirst")); - onFileChanged(parent, FILE_REMOVED); + onFileChanged(parent, false); } } diff --git a/es-app/src/views/gamelist/BasicGameListView.h b/es-app/src/views/gamelist/BasicGameListView.h index 8e6eefff7..b80377b03 100644 --- a/es-app/src/views/gamelist/BasicGameListView.h +++ b/es-app/src/views/gamelist/BasicGameListView.h @@ -18,7 +18,7 @@ public: BasicGameListView(Window* window, FileData* root); // Called when a FileData* is added, has its metadata changed, or is removed. - virtual void onFileChanged(FileData* file, FileChangeType change) override; + virtual void onFileChanged(FileData* file, bool reloadGameList) override; virtual void onThemeChanged(const std::shared_ptr& theme) override; diff --git a/es-app/src/views/gamelist/GridGameListView.cpp b/es-app/src/views/gamelist/GridGameListView.cpp index bdad319dd..cfc44e74f 100644 --- a/es-app/src/views/gamelist/GridGameListView.cpp +++ b/es-app/src/views/gamelist/GridGameListView.cpp @@ -547,7 +547,7 @@ void GridGameListView::remove(FileData *game, bool deleteFile) // Remove before repopulating (removes from parent), then update the view. delete game; - onFileChanged(parent, FILE_REMOVED); + onFileChanged(parent, false); } void GridGameListView::removeMedia(FileData *game) diff --git a/es-app/src/views/gamelist/IGameListView.h b/es-app/src/views/gamelist/IGameListView.h index d77088ae4..d1ab47bfd 100644 --- a/es-app/src/views/gamelist/IGameListView.h +++ b/es-app/src/views/gamelist/IGameListView.h @@ -30,11 +30,8 @@ public: virtual ~IGameListView() {} - // Called when a new file is added, a file is removed, a file's metadata changes, - // or a file's children are sorted. - // Note: FILE_SORTED is only reported for the topmost FileData, where the sort started. - // Since sorts are recursive, FileData's children probably changed too. - virtual void onFileChanged(FileData* file, FileChangeType change) = 0; + // Called when a FileData* is added, has its metadata changed, or is removed. + virtual void onFileChanged(FileData* file, bool reloadGameList) = 0; // Called whenever the theme changes. virtual void onThemeChanged(const std::shared_ptr& theme) = 0; diff --git a/es-app/src/views/gamelist/ISimpleGameListView.cpp b/es-app/src/views/gamelist/ISimpleGameListView.cpp index 61ec99c5a..dbe8c521c 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.cpp +++ b/es-app/src/views/gamelist/ISimpleGameListView.cpp @@ -82,7 +82,7 @@ void ISimpleGameListView::onThemeChanged(const std::shared_ptr& theme } } -void ISimpleGameListView::onFileChanged(FileData* /*file*/, FileChangeType /*change*/) +void ISimpleGameListView::onFileChanged(FileData* file, bool reloadGameList) { // We could be tricky here to be efficient; // but this shouldn't happen very often so we'll just always repopulate. @@ -283,11 +283,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) mRoot->getSortTypeFromString(mRoot->getSortTypeString()), Settings::getInstance()->getBool("FavoritesFirst")); - // This is actually a FILE_METADATA_CHANGED rather than a FILE_SORTED, - // but the former initiates a reload of the gamelist which takes quite - // some time and is not necessary at all when toggling the favorite - // flag for a folder. - ViewController::get()->onFileChanged(getCursor(), FILE_SORTED); + ViewController::get()->onFileChanged(getCursor(), false); // Always jump to the first entry in the gamelist if the last favorite // was unmarked. We couldn't do this earlier as we didn't have the list diff --git a/es-app/src/views/gamelist/ISimpleGameListView.h b/es-app/src/views/gamelist/ISimpleGameListView.h index 3b7bc7035..7be72d45a 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.h +++ b/es-app/src/views/gamelist/ISimpleGameListView.h @@ -21,11 +21,8 @@ public: ISimpleGameListView(Window* window, FileData* root); virtual ~ISimpleGameListView(); - // Called when a new file is added, a file is removed, a file's metadata changes, - // or a file's children are sorted. - // Note: FILE_SORTED is only reported for the topmost FileData, where the sort started. - // Since sorts are recursive, FileData's children probably changed too. - virtual void onFileChanged(FileData* file, FileChangeType change) override; + // Called when a FileData* is added, has its metadata changed, or is removed. + virtual void onFileChanged(FileData* file, bool reloadGameList) override; // Called whenever the theme changes. virtual void onThemeChanged(const std::shared_ptr& theme) override;