diff --git a/es-app/src/CollectionSystemsManager.cpp b/es-app/src/CollectionSystemsManager.cpp index 7f19be2d5..8757dd436 100644 --- a/es-app/src/CollectionSystemsManager.cpp +++ b/es-app/src/CollectionSystemsManager.cpp @@ -43,12 +43,8 @@ std::string myCollectionsName = "collections"; #define LAST_PLAYED_MAX 50 -// Handles the getting, initialization, deinitialization, -// saving and deletion of a CollectionSystemsManager instance. -CollectionSystemsManager* CollectionSystemsManager::sInstance = nullptr; - -CollectionSystemsManager::CollectionSystemsManager(Window* window) - : mWindow(window) +CollectionSystemsManager::CollectionSystemsManager() noexcept + : mWindow(Window::getInstance()) { // clang-format off CollectionSystemDecl systemDecls[] = { @@ -90,49 +86,35 @@ CollectionSystemsManager::CollectionSystemsManager(Window* window) mCustomCollectionsBundle = nullptr; } -CollectionSystemsManager::~CollectionSystemsManager() +CollectionSystemsManager* CollectionSystemsManager::getInstance() { - assert(sInstance == this); - - // Don't attempt to remove any collections if no systems exist. - if (SystemData::sSystemVector.size() > 0) - removeCollectionsFromDisplayedSystems(); - - // Delete all custom collections. - for (std::map::const_iterator it = - mCustomCollectionSystemsData.cbegin(); - it != mCustomCollectionSystemsData.cend(); ++it) - delete it->second.system; - - // Delete the custom collections bundle. - if (mCustomCollectionsBundle) - delete mCustomCollectionsBundle; - - // Delete the auto collections systems. - for (auto it = mAutoCollectionSystemsData.cbegin(); // Line break. - it != mAutoCollectionSystemsData.cend(); ++it) - delete (*it).second.system; - - delete mCollectionEnvData; - sInstance = nullptr; -} - -CollectionSystemsManager* CollectionSystemsManager::get() -{ - assert(sInstance); - return sInstance; -} - -void CollectionSystemsManager::init(Window* window) -{ - assert(!sInstance); - sInstance = new CollectionSystemsManager(window); + static CollectionSystemsManager instance; + return &instance; } void CollectionSystemsManager::deinit() { - if (sInstance) - delete sInstance; + // Don't attempt to remove any collections if no systems exist. + if (SystemData::sSystemVector.size() > 0) { + removeCollectionsFromDisplayedSystems(); + + // Delete all custom collections. + for (std::map::const_iterator it = + mCustomCollectionSystemsData.cbegin(); + it != mCustomCollectionSystemsData.cend(); ++it) + delete it->second.system; + + // Delete the custom collections bundle. + if (mCustomCollectionsBundle) + delete mCustomCollectionsBundle; + + // Delete the auto collections systems. + for (auto it = mAutoCollectionSystemsData.cbegin(); // Line break. + it != mAutoCollectionSystemsData.cend(); ++it) + delete (*it).second.system; + } + + delete mCollectionEnvData; } void CollectionSystemsManager::saveCustomCollection(SystemData* sys) @@ -283,7 +265,7 @@ void CollectionSystemsManager::updateSystemsList() for (auto sysIt = SystemData::sSystemVector.cbegin(); // Line break. sysIt != SystemData::sSystemVector.cend(); ++sysIt) { if ((*sysIt)->isCollection()) - ViewController::get()->getGameListView((*sysIt)); + ViewController::getInstance()->getGameListView((*sysIt)); } // If we were editing a custom collection, and it's no longer enabled, exit edit mode. @@ -363,20 +345,20 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection // Found it, and we are removing it. if (name == "favorites" && file->metadata.get("favorite") == "false") { // Need to check if it is still marked as favorite, if not remove it. - ViewController::get()->getGameListView(curSys).get()->remove(collectionEntry, - false); + ViewController::getInstance()->getGameListView(curSys).get()->remove( + collectionEntry, false); } else if (name == "recent" && file->metadata.get("lastplayed") == "0") { // If lastplayed is set to 0 it means the entry has been cleared, and the // game should therefore be removed. - ViewController::get()->getGameListView(curSys).get()->remove(collectionEntry, - false); - ViewController::get()->onFileChanged(rootFolder, true); + ViewController::getInstance()->getGameListView(curSys).get()->remove( + collectionEntry, false); + ViewController::getInstance()->onFileChanged(rootFolder, true); } else if (curSys->isCollection() && !file->getCountAsGame()) { // If the countasgame flag has been set to false, then remove the game. if (curSys->isGroupedCustomCollection()) { - ViewController::get() + ViewController::getInstance() ->getGameListView(curSys->getRootFolder()->getParent()->getSystem()) .get() ->remove(collectionEntry, false); @@ -393,8 +375,8 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection 4000); } else { - ViewController::get()->getGameListView(curSys).get()->remove(collectionEntry, - false); + ViewController::getInstance()->getGameListView(curSys).get()->remove( + collectionEntry, false); } rootFolder->sort(rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()), mFavoritesSorting); @@ -402,7 +384,7 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection else { // Re-index with new metadata. fileIndex->addToIndex(collectionEntry); - ViewController::get()->onFileChanged(collectionEntry, true); + ViewController::getInstance()->onFileChanged(collectionEntry, true); } } else { @@ -421,7 +403,8 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection CollectionFileData* newGame = new CollectionFileData(file, curSys); rootFolder->addChild(newGame); fileIndex->addToIndex(newGame); - ViewController::get()->getGameListView(curSys)->onFileChanged(newGame, true); + ViewController::getInstance()->getGameListView(curSys)->onFileChanged(newGame, + true); } } @@ -455,7 +438,7 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection if (name == "recent") { trimCollectionCount(rootFolder, LAST_PLAYED_MAX); - ViewController::get()->onFileChanged(rootFolder, false); + ViewController::getInstance()->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 @@ -466,20 +449,21 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection auto nTime = Utils::Time::now(); if (nTime - Utils::Time::stringToTime(file->metadata.get("lastplayed")) < 2) { // Select the first row of the gamelist (the game just played). - IGameListView* gameList = - ViewController::get()->getGameListView(getSystemToView(sysData.system)).get(); + IGameListView* gameList = ViewController::getInstance() + ->getGameListView(getSystemToView(sysData.system)) + .get(); gameList->setCursor(gameList->getFirstEntry()); } } else { - ViewController::get()->onFileChanged(rootFolder, true); + ViewController::getInstance()->onFileChanged(rootFolder, true); // For custom collections, update either the actual system or its parent depending // on whether the collection is grouped or not. if (sysData.decl.isCustom) { if (rootFolder->getSystem()->isGroupedCustomCollection()) - ViewController::get()->onFileChanged(rootFolder->getParent(), true); + ViewController::getInstance()->onFileChanged(rootFolder->getParent(), true); else - ViewController::get()->onFileChanged(rootFolder, true); + ViewController::getInstance()->onFileChanged(rootFolder, true); } } } @@ -505,7 +489,7 @@ void CollectionSystemsManager::deleteCollectionFiles(FileData* file) if (found) { FileData* collectionEntry = children.at(key); SystemData* systemViewToUpdate = getSystemToView(sysDataIt->second.system); - ViewController::get() + ViewController::getInstance() ->getGameListView(systemViewToUpdate) .get() ->remove(collectionEntry, false); @@ -640,8 +624,8 @@ void CollectionSystemsManager::exitEditMode(bool showPopup) // Remove all tick marks from the games that are part of the collection. for (auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it) { - ViewController::get()->getGameListView((*it))->onFileChanged( - ViewController::get()->getGameListView((*it))->getCursor(), false); + ViewController::getInstance()->getGameListView((*it))->onFileChanged( + ViewController::getInstance()->getGameListView((*it))->getCursor(), false); } mEditingCollectionSystemData->system->onMetaDataSavePoint(); @@ -686,14 +670,14 @@ const bool CollectionSystemsManager::toggleGameInCollection(FileData* file) // If we found it, we need to remove it. FileData* collectionEntry = children.at(key); fileIndex->removeFromIndex(collectionEntry); - ViewController::get() + ViewController::getInstance() ->getGameListView(systemViewToUpdate) .get() ->remove(collectionEntry, false); systemViewToUpdate->getRootFolder()->sort( rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()), Settings::getInstance()->getBool("FavFirstCustom")); - ViewController::get()->reloadGameListView(systemViewToUpdate); + ViewController::getInstance()->reloadGameListView(systemViewToUpdate); updateCollectionFolderMetadata(systemViewToUpdate); } @@ -705,7 +689,8 @@ const bool CollectionSystemsManager::toggleGameInCollection(FileData* file) systemViewToUpdate->getRootFolder()->sort( rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()), Settings::getInstance()->getBool("FavFirstCustom")); - ViewController::get()->onFileChanged(systemViewToUpdate->getRootFolder(), true); + ViewController::getInstance()->onFileChanged(systemViewToUpdate->getRootFolder(), + true); fileIndex->addToIndex(newGame); // Add to bundle index as well, if needed. @@ -732,7 +717,7 @@ const bool CollectionSystemsManager::toggleGameInCollection(FileData* file) file->getSourceFileData()->getSystem()->onMetaDataSavePoint(); refreshCollectionSystems(file->getSourceFileData()); if (mAutoCollectionSystemsData["favorites"].isEnabled) - ViewController::get()->reloadGameListView( + ViewController::getInstance()->reloadGameListView( mAutoCollectionSystemsData["favorites"].system); } if (adding) { @@ -923,15 +908,15 @@ void CollectionSystemsManager::deleteCustomCollection(const std::string& collect // The window deletion needs to be located here instead of in GuiCollectionSystemsOptions // (where the custom collection deletions are initiated), as there seems to be some random // issue with accessing mWindow via the lambda expression. - while (mWindow->peekGui() && mWindow->peekGui() != ViewController::get()) + while (mWindow->peekGui() && mWindow->peekGui() != ViewController::getInstance()) delete mWindow->peekGui(); if (collectionEntry != mCustomCollectionSystemsData.end()) { - CollectionSystemsManager::get()->loadEnabledListFromSettings(); - CollectionSystemsManager::get()->updateSystemsList(); + CollectionSystemsManager::getInstance()->loadEnabledListFromSettings(); + CollectionSystemsManager::getInstance()->updateSystemsList(); - ViewController::get()->removeGameListView(collectionEntry->second.system); - ViewController::get()->reloadAll(); + ViewController::getInstance()->removeGameListView(collectionEntry->second.system); + ViewController::getInstance()->reloadAll(); delete collectionEntry->second.system; mCustomCollectionSystemsData.erase(collectionName); @@ -1018,7 +1003,8 @@ void CollectionSystemsManager::repopulateCollection(SystemData* sysData) // it to something valid. For empty collections we need to first create a placeholder // and then point to this, and for collections with games in them we select the first // entry. - auto autoView = ViewController::get()->getGameListView(autoSystem->system).get(); + auto autoView = + ViewController::getInstance()->getGameListView(autoSystem->system).get(); if (autoSystem->system->getRootFolder()->getChildren().size() == 0) { autoView->addPlaceholder(autoSystem->system->getRootFolder()); autoView->setCursor(autoView->getLastEntry()); @@ -1054,7 +1040,8 @@ void CollectionSystemsManager::repopulateCollection(SystemData* sysData) customSystem->isPopulated = false; populateCustomCollection(customSystem); - auto autoView = ViewController::get()->getGameListView(customSystem->system).get(); + auto autoView = + ViewController::getInstance()->getGameListView(customSystem->system).get(); autoView->setCursor( customSystem->system->getRootFolder()->getChildrenRecursive().front()); autoView->setCursor(autoView->getFirstEntry()); @@ -1173,12 +1160,13 @@ void CollectionSystemsManager::populateAutoCollection(CollectionSystemData* sysD if (rootFolder->getName() == "recent" && !rootFolder->getChildrenRecursive().empty()) { // 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(); + auto recentGamelist = + ViewController::getInstance()->getGameListView(rootFolder->getSystem()).get(); recentGamelist->setCursor( rootFolder->getSystem()->getRootFolder()->getChildrenRecursive().front()); recentGamelist->setCursor(recentGamelist->getFirstEntry()); if (rootFolder->getChildren().size() > 0) - ViewController::get() + ViewController::getInstance() ->getGameListView(rootFolder->getSystem()) .get() ->onFileChanged(rootFolder->getChildren().front(), false); @@ -1267,7 +1255,7 @@ void CollectionSystemsManager::removeCollectionsFromDisplayedSystems() // Clear index. mCustomCollectionsBundle->getIndex()->resetIndex(); // Remove view so it's re-created as needed. - ViewController::get()->removeGameListView(mCustomCollectionsBundle); + ViewController::getInstance()->removeGameListView(mCustomCollectionsBundle); } void CollectionSystemsManager::addEnabledCollectionsToDisplayedSystems( @@ -1299,7 +1287,7 @@ void CollectionSystemsManager::addEnabledCollectionsToDisplayedSystems( Settings::getInstance()->getBool("FavFirstCustom")); // Jump to the first row of the game list, assuming it's not empty. IGameListView* gameList = - ViewController::get()->getGameListView((it->second.system)).get(); + ViewController::getInstance()->getGameListView((it->second.system)).get(); if (!gameList->getCursor()->isPlaceHolder()) { gameList->setCursor(gameList->getFirstEntry()); } @@ -1453,7 +1441,7 @@ void CollectionSystemsManager::trimCollectionCount(FileData* rootFolder, int lim while (static_cast(rootFolder->getChildrenListToDisplay().size()) > limit) { CollectionFileData* gameToRemove = (CollectionFileData*)rootFolder->getChildrenListToDisplay().back(); - ViewController::get()->getGameListView(curSys).get()->remove(gameToRemove, false); + ViewController::getInstance()->getGameListView(curSys).get()->remove(gameToRemove, false); } } diff --git a/es-app/src/CollectionSystemsManager.h b/es-app/src/CollectionSystemsManager.h index 48391a95a..b33f83c2e 100644 --- a/es-app/src/CollectionSystemsManager.h +++ b/es-app/src/CollectionSystemsManager.h @@ -72,14 +72,12 @@ struct stringComparator { class CollectionSystemsManager { public: - CollectionSystemsManager(Window* window); - ~CollectionSystemsManager(); - - static CollectionSystemsManager* get(); - static void init(Window* window); - static void deinit(); + static CollectionSystemsManager* getInstance(); void saveCustomCollection(SystemData* sys); + // Clean up all systems, called during application shutdown. + void deinit(); + // Functions to load all collections into memory, and enable the active ones: // Load all collection systems. void loadCollectionSystems(); @@ -137,7 +135,8 @@ public: const std::string& getEditingCollection() const { return mEditingCollection; } private: - static CollectionSystemsManager* sInstance; + CollectionSystemsManager() noexcept; + SystemEnvironmentData* mCollectionEnvData; std::map mCollectionSystemDeclsIndex; std::map mAutoCollectionSystemsData; diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 0e175e162..66e3cffdb 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -1166,7 +1166,7 @@ void FileData::launchGame(Window* window) gameToUpdate->metadata.get("lastplayed")); } - CollectionSystemsManager::get()->refreshCollectionSystems(gameToUpdate); + CollectionSystemsManager::getInstance()->refreshCollectionSystems(gameToUpdate); gameToUpdate->mSystem->onMetaDataSavePoint(); } diff --git a/es-app/src/MediaViewer.cpp b/es-app/src/MediaViewer.cpp index 4ba2c7be6..3013a0546 100644 --- a/es-app/src/MediaViewer.cpp +++ b/es-app/src/MediaViewer.cpp @@ -12,8 +12,8 @@ #include "components/VideoFFmpegComponent.h" #include "views/ViewController.h" -MediaViewer::MediaViewer(Window* window) - : mWindow(window) +MediaViewer::MediaViewer() + : mWindow(Window::getInstance()) , mVideo(nullptr) , mImage(nullptr) { @@ -45,7 +45,7 @@ bool MediaViewer::startMediaViewer(FileData* game) initiateViewer(); if (mHasVideo) - ViewController::get()->onPauseVideo(); + ViewController::getInstance()->onPauseVideo(); if (mHasVideo || mHasImages) return true; @@ -56,7 +56,7 @@ bool MediaViewer::startMediaViewer(FileData* game) void MediaViewer::stopMediaViewer() { NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND); - ViewController::get()->onStopVideo(); + ViewController::getInstance()->onStopVideo(); if (mVideo) { delete mVideo; @@ -255,7 +255,7 @@ void MediaViewer::playVideo() return; mDisplayingImage = false; - ViewController::get()->onStopVideo(); + ViewController::getInstance()->onStopVideo(); mVideo = new VideoFFmpegComponent(mWindow); mVideo->topWindow(true); diff --git a/es-app/src/MediaViewer.h b/es-app/src/MediaViewer.h index e84c696e0..a29d378ac 100644 --- a/es-app/src/MediaViewer.h +++ b/es-app/src/MediaViewer.h @@ -17,7 +17,7 @@ class MediaViewer : public Window::MediaViewer { public: - MediaViewer(Window* window); + MediaViewer(); virtual ~MediaViewer(); virtual bool startMediaViewer(FileData* game) override; diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index c67dc79b8..93dd56f9b 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -51,14 +51,14 @@ void FindRules::loadFindRules() } else { #if defined(_WIN64) - path = ResourceManager::getInstance()->getResourcePath( - ":/systems/windows/es_find_rules.xml", false); + path = ResourceManager::getInstance().getResourcePath(":/systems/windows/es_find_rules.xml", + false); #elif defined(__APPLE__) - path = ResourceManager::getInstance()->getResourcePath(":/systems/macos/es_find_rules.xml", - false); + path = ResourceManager::getInstance().getResourcePath(":/systems/macos/es_find_rules.xml", + false); #else - path = ResourceManager::getInstance()->getResourcePath(":/systems/unix/es_find_rules.xml", - false); + path = ResourceManager::getInstance().getResourcePath(":/systems/unix/es_find_rules.xml", + false); #endif } @@ -659,7 +659,7 @@ bool SystemData::loadConfig() // Don't load any collections if there are no systems available. if (sSystemVector.size() > 0) - CollectionSystemsManager::get()->loadCollectionSystems(); + CollectionSystemsManager::getInstance()->loadCollectionSystems(); return false; } @@ -718,12 +718,11 @@ std::vector SystemData::getConfigPath(bool legacyWarning) } #if defined(_WIN64) - path = - ResourceManager::getInstance()->getResourcePath(":/systems/windows/es_systems.xml", true); + path = ResourceManager::getInstance().getResourcePath(":/systems/windows/es_systems.xml", true); #elif defined(__APPLE__) - path = ResourceManager::getInstance()->getResourcePath(":/systems/macos/es_systems.xml", true); + path = ResourceManager::getInstance().getResourcePath(":/systems/macos/es_systems.xml", true); #else - path = ResourceManager::getInstance()->getResourcePath(":/systems/unix/es_systems.xml", true); + path = ResourceManager::getInstance().getResourcePath(":/systems/unix/es_systems.xml", true); #endif paths.push_back(path); @@ -1128,7 +1127,7 @@ FileData* SystemData::getRandomGame(const FileData* currentGame) gameList = mRootFolder->getParent()->getChildrenListToDisplay(); } else { - gameList = ViewController::get() + gameList = ViewController::getInstance() ->getGameListView(mRootFolder->getSystem()) .get() ->getCursor() @@ -1211,10 +1210,10 @@ void SystemData::sortSystem(bool reloadGamelist, bool jumpToFirstRow) favoritesSorting); if (reloadGamelist) - ViewController::get()->reloadGameListView(this, false); + ViewController::getInstance()->reloadGameListView(this, false); if (jumpToFirstRow) { - IGameListView* gameList = ViewController::get()->getGameListView(this).get(); + IGameListView* gameList = ViewController::getInstance()->getGameListView(this).get(); gameList->setCursor(gameList->getFirstEntry()); } } diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index f40ac14bc..990ff7ee6 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -91,7 +91,7 @@ public: mEnvData->mPlatformIds.cend(); } - const std::shared_ptr& getTheme() const { return mTheme; } + const std::shared_ptr getTheme() const { return mTheme; } std::string getGamelistPath(bool forWrite) const; std::string getThemePath() const; diff --git a/es-app/src/SystemScreensaver.cpp b/es-app/src/SystemScreensaver.cpp index 619bb0595..255ee802c 100644 --- a/es-app/src/SystemScreensaver.cpp +++ b/es-app/src/SystemScreensaver.cpp @@ -29,8 +29,8 @@ #define FADE_TIME 300 -SystemScreensaver::SystemScreensaver(Window* window) - : mWindow(window) +SystemScreensaver::SystemScreensaver() + : mWindow(Window::getInstance()) , mState(STATE_INACTIVE) , mImageScreensaver(nullptr) , mVideoScreensaver(nullptr) @@ -209,12 +209,12 @@ void SystemScreensaver::launchGame() { if (mCurrentGame != nullptr) { // Launching game - ViewController::get()->triggerGameLaunch(mCurrentGame); - ViewController::get()->goToGameList(mCurrentGame->getSystem()); + ViewController::getInstance()->triggerGameLaunch(mCurrentGame); + ViewController::getInstance()->goToGameList(mCurrentGame->getSystem()); IGameListView* view = - ViewController::get()->getGameListView(mCurrentGame->getSystem()).get(); + ViewController::getInstance()->getGameListView(mCurrentGame->getSystem()).get(); view->setCursor(mCurrentGame); - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); } } @@ -222,11 +222,11 @@ void SystemScreensaver::goToGame() { if (mCurrentGame != nullptr) { // Go to the game in the gamelist view, but don't launch it. - ViewController::get()->goToGameList(mCurrentGame->getSystem()); + ViewController::getInstance()->goToGameList(mCurrentGame->getSystem()); IGameListView* view = - ViewController::get()->getGameListView(mCurrentGame->getSystem()).get(); + ViewController::getInstance()->getGameListView(mCurrentGame->getSystem()).get(); view->setCursor(mCurrentGame); - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); } } diff --git a/es-app/src/SystemScreensaver.h b/es-app/src/SystemScreensaver.h index 087397f95..165dedfd2 100644 --- a/es-app/src/SystemScreensaver.h +++ b/es-app/src/SystemScreensaver.h @@ -19,7 +19,7 @@ class VideoComponent; class SystemScreensaver : public Window::Screensaver { public: - SystemScreensaver(Window* window); + SystemScreensaver(); virtual ~SystemScreensaver(); virtual bool allowSleep() diff --git a/es-app/src/VolumeControl.cpp b/es-app/src/VolumeControl.cpp index 2d865867d..5a072e350 100644 --- a/es-app/src/VolumeControl.cpp +++ b/es-app/src/VolumeControl.cpp @@ -20,8 +20,6 @@ std::string VolumeControl::mixerName = "Master"; std::string VolumeControl::mixerCard = "default"; #endif -VolumeControl* VolumeControl::sInstance = nullptr; - VolumeControl::VolumeControl() #if defined(__linux__) : mixerIndex(0) @@ -44,23 +42,6 @@ VolumeControl::~VolumeControl() #endif } -VolumeControl* VolumeControl::getInstance() -{ - // Check if a VolumeControl instance is already created, and if not then create it. - if (!sInstance) - sInstance = new VolumeControl(); - - return sInstance; -} - -void VolumeControl::deleteInstance() -{ - if (sInstance) { - delete sInstance; - sInstance = nullptr; - } -} - void VolumeControl::init() { // Initialize audio mixer interface. diff --git a/es-app/src/VolumeControl.h b/es-app/src/VolumeControl.h index 24cd416b5..8a002e569 100644 --- a/es-app/src/VolumeControl.h +++ b/es-app/src/VolumeControl.h @@ -27,17 +27,12 @@ public: VolumeControl(); ~VolumeControl(); - static VolumeControl* getInstance(); - void deleteInstance(); - void init(); void deinit(); int getVolume() const; void setVolume(int volume); - static VolumeControl* sInstance; - #if defined(__linux__) static std::string mixerName; static std::string mixerCard; diff --git a/es-app/src/guis/GuiAlternativeEmulators.cpp b/es-app/src/guis/GuiAlternativeEmulators.cpp index ed7934053..eb599239c 100644 --- a/es-app/src/guis/GuiAlternativeEmulators.cpp +++ b/es-app/src/guis/GuiAlternativeEmulators.cpp @@ -252,6 +252,6 @@ std::vector GuiAlternativeEmulators::getHelpPrompts() HelpStyle GuiAlternativeEmulators::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiCollectionSystemsOptions.cpp b/es-app/src/guis/GuiCollectionSystemsOptions.cpp index 6ada1030d..6aef1a9ef 100644 --- a/es-app/src/guis/GuiCollectionSystemsOptions.cpp +++ b/es-app/src/guis/GuiCollectionSystemsOptions.cpp @@ -25,18 +25,19 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st , mDeletedCustomCollection(false) { // Finish editing custom collection. - if (CollectionSystemsManager::get()->isEditing()) { + if (CollectionSystemsManager::getInstance()->isEditing()) { ComponentListRow row; - row.addElement(std::make_shared( - mWindow, - "FINISH EDITING '" + - Utils::String::toUpper( - CollectionSystemsManager::get()->getEditingCollection()) + - "' COLLECTION", - Font::get(FONT_SIZE_MEDIUM), 0x777777FF), - true); + row.addElement( + std::make_shared( + mWindow, + "FINISH EDITING '" + + Utils::String::toUpper( + CollectionSystemsManager::getInstance()->getEditingCollection()) + + "' COLLECTION", + Font::get(FONT_SIZE_MEDIUM), 0x777777FF), + true); row.makeAcceptInputHandler([this] { - CollectionSystemsManager::get()->exitEditMode(); + CollectionSystemsManager::getInstance()->exitEditMode(); mWindow->invalidateCachedBackground(); delete this; }); @@ -47,7 +48,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st collection_systems_auto = std::make_shared>( mWindow, getHelpStyle(), "SELECT COLLECTIONS", true); std::map autoSystems = - CollectionSystemsManager::get()->getAutoCollectionSystems(); + CollectionSystemsManager::getInstance()->getAutoCollectionSystems(); // Add automatic systems. for (std::map::const_iterator it = autoSystems.cbegin(); @@ -60,8 +61,8 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st collection_systems_auto->getSelectedObjects(), ",", true); std::string autoSystemsConfig = Settings::getInstance()->getString("CollectionSystemsAuto"); if (autoSystemsSelected != autoSystemsConfig) { - if (CollectionSystemsManager::get()->isEditing()) - CollectionSystemsManager::get()->exitEditMode(); + if (CollectionSystemsManager::getInstance()->isEditing()) + CollectionSystemsManager::getInstance()->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 @@ -83,7 +84,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st } if (!addedAutoSystems.empty()) { for (std::string system : addedAutoSystems) - CollectionSystemsManager::get()->repopulateCollection( + CollectionSystemsManager::getInstance()->repopulateCollection( autoSystems.find(system)->second.system); } setNeedsSaving(); @@ -96,7 +97,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st collection_systems_custom = std::make_shared>( mWindow, getHelpStyle(), "SELECT COLLECTIONS", true); std::map customSystems = - CollectionSystemsManager::get()->getCustomCollectionSystems(); + CollectionSystemsManager::getInstance()->getCustomCollectionSystems(); // Add custom systems. for (std::map::const_iterator it = customSystems.cbegin(); @@ -112,8 +113,8 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st std::string customSystemsConfig = Settings::getInstance()->getString("CollectionSystemsCustom"); if (customSystemsSelected != customSystemsConfig) { - if (CollectionSystemsManager::get()->isEditing()) - CollectionSystemsManager::get()->exitEditMode(); + if (CollectionSystemsManager::getInstance()->isEditing()) + CollectionSystemsManager::getInstance()->exitEditMode(); Settings::getInstance()->setString("CollectionSystemsCustom", customSystemsSelected); // Check if any systems have been enabled, and if so repopulate them, which @@ -137,7 +138,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st } if (!mAddedCustomCollection && !addedCustomSystems.empty()) { for (std::string system : addedCustomSystems) - CollectionSystemsManager::get()->repopulateCollection( + CollectionSystemsManager::getInstance()->repopulateCollection( customSystems.find(system)->second.system); } setNeedsSaving(); @@ -159,7 +160,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st // Create custom collection from theme. std::vector unusedFolders = - CollectionSystemsManager::get()->getUnusedSystemsFromTheme(); + CollectionSystemsManager::getInstance()->getUnusedSystemsFromTheme(); if (unusedFolders.size() > 0) { ComponentListRow row; auto themeCollection = @@ -259,8 +260,8 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st "ARE YOU SURE?", "YES", [this, name] { - if (CollectionSystemsManager::get()->isEditing()) - CollectionSystemsManager::get()->exitEditMode(); + if (CollectionSystemsManager::getInstance()->isEditing()) + CollectionSystemsManager::getInstance()->exitEditMode(); mDeletedCustomCollection = true; std::vector selectedCustomCollections = collection_systems_custom->getSelectedObjects(); @@ -289,7 +290,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st setNeedsSaving(); setNeedsGoToStart(); } - CollectionSystemsManager::get()->deleteCustomCollection(name); + CollectionSystemsManager::getInstance()->deleteCustomCollection(name); return true; }, "NO", [] { return false; })); @@ -349,8 +350,8 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st Settings::getInstance()->getBool("UseCustomCollectionsSystem")) { Settings::getInstance()->setBool("UseCustomCollectionsSystem", use_custom_collections_system->getState()); - if (CollectionSystemsManager::get()->isEditing()) - CollectionSystemsManager::get()->exitEditMode(); + if (CollectionSystemsManager::getInstance()->isEditing()) + CollectionSystemsManager::getInstance()->exitEditMode(); setNeedsSaving(); setNeedsCollectionsUpdate(); setNeedsReloading(); @@ -378,14 +379,15 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st void GuiCollectionSystemsOptions::createCustomCollection(std::string inName) { - if (CollectionSystemsManager::get()->isEditing()) - CollectionSystemsManager::get()->exitEditMode(); + if (CollectionSystemsManager::getInstance()->isEditing()) + CollectionSystemsManager::getInstance()->exitEditMode(); - std::string collectionName = CollectionSystemsManager::get()->getValidNewCollectionName(inName); + std::string collectionName = + CollectionSystemsManager::getInstance()->getValidNewCollectionName(inName); SystemData* newCollection = - CollectionSystemsManager::get()->addNewCustomCollection(collectionName); + CollectionSystemsManager::getInstance()->addNewCustomCollection(collectionName); - CollectionSystemsManager::get()->saveCustomCollection(newCollection); + CollectionSystemsManager::getInstance()->saveCustomCollection(newCollection); collection_systems_custom->add(collectionName, collectionName, true); mAddedCustomCollection = true; @@ -397,7 +399,7 @@ void GuiCollectionSystemsOptions::createCustomCollection(std::string inName) setNeedsGoToSystem(newCollection); Window* window = mWindow; - while (window->peekGui() && window->peekGui() != ViewController::get()) + while (window->peekGui() && window->peekGui() != ViewController::getInstance()) delete window->peekGui(); - CollectionSystemsManager::get()->setEditMode(collectionName); + CollectionSystemsManager::getInstance()->setEditMode(collectionName); } diff --git a/es-app/src/guis/GuiGameScraper.cpp b/es-app/src/guis/GuiGameScraper.cpp index 54e78d31f..329362df4 100644 --- a/es-app/src/guis/GuiGameScraper.cpp +++ b/es-app/src/guis/GuiGameScraper.cpp @@ -200,7 +200,7 @@ std::vector GuiGameScraper::getHelpPrompts() HelpStyle GuiGameScraper::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiGamelistFilter.cpp b/es-app/src/guis/GuiGamelistFilter.cpp index ded58fd5b..aca3b9617 100644 --- a/es-app/src/guis/GuiGamelistFilter.cpp +++ b/es-app/src/guis/GuiGamelistFilter.cpp @@ -40,7 +40,7 @@ void GuiGamelistFilter::initializeMenu() // If this is a collection and system names are shown per game, then let FileFilterIndex // know about this so the system names will not be included in game name text searches. - if (ViewController::get()->getState().getSystem()->isCollection()) { + if (ViewController::getInstance()->getState().getSystem()->isCollection()) { if (Settings::getInstance()->getBool("CollectionShowSystemInfo")) mFilterIndex->setTextRemoveSystem(true); else @@ -262,6 +262,6 @@ std::vector GuiGamelistFilter::getHelpPrompts() HelpStyle GuiGamelistFilter::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index a4ed3289c..1f7882b11 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -161,7 +161,7 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) } } // Add a dummy entry when applicable as the menu looks quite ugly if it's just blank. - else if (!CollectionSystemsManager::get()->isEditing() && + else if (!CollectionSystemsManager::getInstance()->isEditing() && mSystem->getRootFolder()->getChildren().size() == 0 && !mIsCustomCollectionGroup && !mIsCustomCollection) { row.elements.clear(); @@ -179,7 +179,7 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) if (UIModeController::getInstance()->isUIModeFull() && (mIsCustomCollection || mIsCustomCollectionGroup)) { - if (CollectionSystemsManager::get()->getEditingCollection() != customSystem) { + if (CollectionSystemsManager::getInstance()->getEditingCollection() != customSystem) { row.elements.clear(); row.addElement(std::make_shared(mWindow, "ADD/REMOVE GAMES TO THIS COLLECTION", @@ -191,16 +191,17 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) } if (UIModeController::getInstance()->isUIModeFull() && - CollectionSystemsManager::get()->isEditing()) { + CollectionSystemsManager::getInstance()->isEditing()) { row.elements.clear(); - row.addElement(std::make_shared( - mWindow, - "FINISH EDITING '" + - Utils::String::toUpper( - CollectionSystemsManager::get()->getEditingCollection()) + - "' COLLECTION", - Font::get(FONT_SIZE_MEDIUM), 0x777777FF), - true); + row.addElement( + std::make_shared( + mWindow, + "FINISH EDITING '" + + Utils::String::toUpper( + CollectionSystemsManager::getInstance()->getEditingCollection()) + + "' COLLECTION", + Font::get(FONT_SIZE_MEDIUM), 0x777777FF), + true); row.makeAcceptInputHandler(std::bind(&GuiGamelistOptions::exitEditMode, this)); mMenu.addRow(row); } @@ -257,20 +258,20 @@ GuiGamelistOptions::~GuiGamelistOptions() // This is required for the situation where scrolling started just before the menu // was openened. Without this, the scrolling would run until manually stopped after // the menu has been closed. - ViewController::get()->stopScrolling(); + ViewController::getInstance()->stopScrolling(); if (mFiltersChanged) { if (!mCustomCollectionSystem) { - ViewController::get()->reloadGameListView(mSystem); + ViewController::getInstance()->reloadGameListView(mSystem); } else { if (!mFromPlaceholder) { - ViewController::get()->reloadGameListView(mSystem); + ViewController::getInstance()->reloadGameListView(mSystem); } else if (!mCustomCollectionSystem->getRootFolder() ->getChildrenListToDisplay() .empty()) { - ViewController::get()->reloadGameListView(mSystem); + ViewController::getInstance()->reloadGameListView(mSystem); getGamelist()->setCursor( mCustomCollectionSystem->getRootFolder()->getChildrenListToDisplay().front()); } @@ -336,7 +337,8 @@ void GuiGamelistOptions::startEditMode() std::string editingSystem = mSystem->getName(); // Need to check if we're editing the collections bundle, // as we will want to edit the selected collection within. - if (editingSystem == CollectionSystemsManager::get()->getCustomCollectionsBundle()->getName()) { + if (editingSystem == + CollectionSystemsManager::getInstance()->getCustomCollectionsBundle()->getName()) { FileData* file = getGamelist()->getCursor(); // Do we have the cursor on a specific collection?. if (file->getType() == FOLDER) @@ -345,14 +347,14 @@ void GuiGamelistOptions::startEditMode() // We are inside a specific collection. We want to edit that one. editingSystem = file->getSystem()->getName(); } - CollectionSystemsManager::get()->setEditMode(editingSystem); + CollectionSystemsManager::getInstance()->setEditMode(editingSystem); // Display the indication icons which show what games are part of the custom collection // currently being edited. This is done cheaply using onFileChanged() which will trigger // populateList(). for (auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it) { - ViewController::get()->getGameListView((*it))->onFileChanged( - ViewController::get()->getGameListView((*it))->getCursor(), false); + ViewController::getInstance()->getGameListView((*it))->onFileChanged( + ViewController::getInstance()->getGameListView((*it))->getCursor(), false); } if (mSystem->getRootFolder()->getChildren().size() == 0) @@ -362,7 +364,7 @@ void GuiGamelistOptions::startEditMode() void GuiGamelistOptions::exitEditMode() { - CollectionSystemsManager::get()->exitEditMode(); + CollectionSystemsManager::getInstance()->exitEditMode(); if (mSystem->getRootFolder()->getChildren().size() == 0) NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND); delete this; @@ -394,7 +396,7 @@ void GuiGamelistOptions::openMetaDataEd() LOG(LogInfo) << "Deleting the media files and gamelist.xml entry for the file \"" << file->getFullPath() << "\""; } - ViewController::get()->getGameListView(file->getSystem()).get()->removeMedia(file); + ViewController::getInstance()->getGameListView(file->getSystem()).get()->removeMedia(file); // Manually reset all the metadata values, set the name to the actual file/folder name. const std::vector& mdd = file->metadata.getMDD(); @@ -420,7 +422,7 @@ void GuiGamelistOptions::openMetaDataEd() // Update all collections where the game is present. if (file->getType() == GAME) - CollectionSystemsManager::get()->refreshCollectionSystems(file, true); + CollectionSystemsManager::getInstance()->refreshCollectionSystems(file, true); file->getSystem()->sortSystem(); // This delay reduces the likelyhood that the SVG rasterizer which is running in a @@ -440,11 +442,11 @@ void GuiGamelistOptions::openMetaDataEd() deleteGameBtnFunc = [this, file] { LOG(LogInfo) << "Deleting the game file \"" << file->getFullPath() << "\", all its media files and its gamelist.xml entry."; - CollectionSystemsManager::get()->deleteCollectionFiles(file); - ViewController::get()->getGameListView(file->getSystem()).get()->removeMedia(file); - ViewController::get()->getGameListView(file->getSystem()).get()->remove(file, true); + CollectionSystemsManager::getInstance()->deleteCollectionFiles(file); + ViewController::getInstance()->getGameListView(file->getSystem()).get()->removeMedia(file); + ViewController::getInstance()->getGameListView(file->getSystem()).get()->remove(file, true); mSystem->getRootFolder()->sort(*mListSort->getSelected(), mFavoritesSorting); - ViewController::get()->reloadGameListView(mSystem); + ViewController::getInstance()->reloadGameListView(mSystem); mWindow->invalidateCachedBackground(); }; @@ -454,7 +456,8 @@ void GuiGamelistOptions::openMetaDataEd() mWindow, &file->metadata, file->metadata.getMDD(FOLDER_METADATA), p, Utils::FileSystem::getFileName(file->getPath()), std::bind(&IGameListView::onFileChanged, - ViewController::get()->getGameListView(file->getSystem()).get(), file, true), + ViewController::getInstance()->getGameListView(file->getSystem()).get(), file, + true), clearGameBtnFunc, deleteGameBtnFunc)); } else { @@ -462,7 +465,8 @@ void GuiGamelistOptions::openMetaDataEd() mWindow, &file->metadata, file->metadata.getMDD(GAME_METADATA), p, Utils::FileSystem::getFileName(file->getPath()), std::bind(&IGameListView::onFileChanged, - ViewController::get()->getGameListView(file->getSystem()).get(), file, true), + ViewController::getInstance()->getGameListView(file->getSystem()).get(), file, + true), clearGameBtnFunc, deleteGameBtnFunc)); } } @@ -551,7 +555,7 @@ std::vector GuiGamelistOptions::getHelpPrompts() { auto prompts = mMenu.getHelpPrompts(); if (mSystem->getRootFolder()->getChildren().size() > 0 || mIsCustomCollectionGroup || - mIsCustomCollection || CollectionSystemsManager::get()->isEditing()) + mIsCustomCollection || CollectionSystemsManager::getInstance()->isEditing()) prompts.push_back(HelpPrompt("a", "select")); if (mSystem->getRootFolder()->getChildren().size() > 0 && mSystem->getName() != "recent") { prompts.push_back(HelpPrompt("b", "close (apply)")); @@ -566,5 +570,5 @@ std::vector GuiGamelistOptions::getHelpPrompts() IGameListView* GuiGamelistOptions::getGamelist() { - return ViewController::get()->getGameListView(mSystem).get(); + return ViewController::getInstance()->getGameListView(mSystem).get(); } diff --git a/es-app/src/guis/GuiLaunchScreen.cpp b/es-app/src/guis/GuiLaunchScreen.cpp index 086f9d888..9b9acae88 100644 --- a/es-app/src/guis/GuiLaunchScreen.cpp +++ b/es-app/src/guis/GuiLaunchScreen.cpp @@ -14,10 +14,10 @@ #include "components/TextComponent.h" #include "utils/StringUtil.h" -GuiLaunchScreen::GuiLaunchScreen(Window* window) - : GuiComponent(window) - , mWindow(window) - , mBackground(window, ":/graphics/frame.svg") +GuiLaunchScreen::GuiLaunchScreen() + : GuiComponent(Window::getInstance()) + , mWindow(Window::getInstance()) + , mBackground(mWindow, ":/graphics/frame.svg") , mGrid(nullptr) , mMarquee(nullptr) { diff --git a/es-app/src/guis/GuiLaunchScreen.h b/es-app/src/guis/GuiLaunchScreen.h index c40d3c220..754f71ff1 100644 --- a/es-app/src/guis/GuiLaunchScreen.h +++ b/es-app/src/guis/GuiLaunchScreen.h @@ -21,7 +21,7 @@ class FileData; class GuiLaunchScreen : public Window::GuiLaunchScreen, GuiComponent { public: - GuiLaunchScreen(Window* window); + GuiLaunchScreen(); virtual ~GuiLaunchScreen(); virtual void displayLaunchScreen(FileData* game) override; diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index deb1d107f..117d6b3fb 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -85,7 +85,7 @@ GuiMenu::~GuiMenu() // This is required for the situation where scrolling started just before the menu // was openened. Without this, the scrolling would run until manually stopped after // the menu has been closed. - ViewController::get()->stopScrolling(); + ViewController::getInstance()->stopScrolling(); } void GuiMenu::openScraperOptions() @@ -189,12 +189,12 @@ void GuiMenu::openUIOptions() Scripting::fireEvent("theme-changed", theme_set->getSelected(), Settings::getInstance()->getString("ThemeSet")); Settings::getInstance()->setString("ThemeSet", theme_set->getSelected()); - CollectionSystemsManager::get()->updateSystemsList(); + CollectionSystemsManager::getInstance()->updateSystemsList(); mWindow->setChangedThemeSet(); // This is required so that the custom collection system does not disappear // if the user is editing a custom collection when switching theme sets. - if (CollectionSystemsManager::get()->isEditing()) { - CollectionSystemsManager::get()->exitEditMode(); + if (CollectionSystemsManager::getInstance()->isEditing()) { + CollectionSystemsManager::getInstance()->exitEditMode(); s->setNeedsCollectionsUpdate(); } s->setNeedsSaving(); @@ -266,8 +266,9 @@ void GuiMenu::openUIOptions() (*it)->sortSystem(); (*it)->getIndex()->resetFilters(); } - ViewController::get()->reloadAll(); - ViewController::get()->goToSystem(SystemData::sSystemVector.front(), false); + ViewController::getInstance()->reloadAll(); + ViewController::getInstance()->goToSystem(SystemData::sSystemVector.front(), + false); mWindow->invalidateCachedBackground(); }, "NO", nullptr)); @@ -609,16 +610,22 @@ void GuiMenu::openSoundOptions() // implemented for these operating systems. #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) // System volume. - auto system_volume = std::make_shared(mWindow, 0.f, 100.f, 1.f, "%"); - system_volume->setValue(static_cast(VolumeControl::getInstance()->getVolume())); - s->addWithLabel("SYSTEM VOLUME", system_volume); - s->addSaveFunc([system_volume] { - VolumeControl::getInstance()->setVolume( - static_cast(std::round(system_volume->getValue()))); - // Explicitly delete the VolumeControl instance so that it will reinitialize the - // next time the menu is entered. This is the easiest way to detect new default - // audio devices or changes to the audio volume done by the operating system. - VolumeControl::getInstance()->deleteInstance(); + // The reason to create the VolumeControl object every time instead of making it a singleton + // is that this is the easiest way to detect new default audio devices or changes to the + // audio volume done by the operating system. And we don't really need this object laying + // around anyway as it's only used here. + VolumeControl volumeControl; + int currentVolume = volumeControl.getVolume(); + + auto systemVolume = std::make_shared(mWindow, 0.f, 100.f, 1.f, "%"); + systemVolume->setValue(static_cast(currentVolume)); + s->addWithLabel("SYSTEM VOLUME", systemVolume); + s->addSaveFunc([systemVolume, currentVolume] { + // No need to create the VolumeControl object unless the volume has actually been changed. + if (static_cast(systemVolume->getValue()) != currentVolume) { + VolumeControl volumeControl; + volumeControl.setVolume(static_cast(std::round(systemVolume->getValue()))); + } }); #endif @@ -822,7 +829,7 @@ void GuiMenu::openOtherOptions() auto updateValMediaDir = [this](const std::string& newVal) { Settings::getInstance()->setString("MediaDirectory", newVal); Settings::getInstance()->saveFile(); - ViewController::get()->reloadAll(); + ViewController::getInstance()->reloadAll(); mWindow->invalidateCachedBackground(); }; rowMediaDir.makeAcceptInputHandler([this, titleMediaDir, mediaDirectoryStaticText, @@ -1258,7 +1265,7 @@ void GuiMenu::close(bool closeAllWindows) else { Window* window = mWindow; closeFunc = [window] { - while (window->peekGui() != ViewController::get()) + while (window->peekGui() != ViewController::getInstance()) delete window->peekGui(); }; } @@ -1292,6 +1299,6 @@ std::vector GuiMenu::getHelpPrompts() HelpStyle GuiMenu::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 4a4107499..5f342fee1 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -511,7 +511,7 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, buttons.push_back(std::make_shared(mWindow, "SAVE", "save metadata", [&] { save(); - ViewController::get()->onPauseVideo(); + ViewController::getInstance()->onPauseVideo(); delete this; })); buttons.push_back(std::make_shared(mWindow, "CANCEL", "cancel changes", @@ -689,7 +689,7 @@ void GuiMetaDataEd::save() // Update disabled auto collections when hiding a game, as otherwise these could // get invalid gamelist cursor positions. A cursor pointing to a removed game // would crash the application upon enabling the collections. - CollectionSystemsManager::get()->refreshCollectionSystems(hideGame, true); + CollectionSystemsManager::getInstance()->refreshCollectionSystems(hideGame, true); // Remove the game from the index of all systems. for (SystemData* sys : SystemData::sSystemVector) { std::vector children; @@ -698,7 +698,7 @@ void GuiMetaDataEd::save() if (std::find(children.begin(), children.end(), hideGame) != children.end()) { sys->getIndex()->removeFromIndex(hideGame); // Reload the gamelist as well as the view style may need to change. - ViewController::get()->reloadGameListView(sys); + ViewController::getInstance()->reloadGameListView(sys); } } } @@ -706,13 +706,14 @@ void GuiMetaDataEd::save() } else { // Update all collections where the game is present. - CollectionSystemsManager::get()->refreshCollectionSystems(mScraperParams.game); + CollectionSystemsManager::getInstance()->refreshCollectionSystems(mScraperParams.game); } // If game counting was re-enabled for the game, then reactivate it in any custom collections // where it may exist. if (setGameAsCounted) - CollectionSystemsManager::get()->reactivateCustomCollectionEntry(mScraperParams.game); + CollectionSystemsManager::getInstance()->reactivateCustomCollectionEntry( + mScraperParams.game); mScraperParams.system->onMetaDataSavePoint(); @@ -810,12 +811,12 @@ void GuiMetaDataEd::close() // until the user scrolls up and down the gamelist. TextureResource::manualUnload(mScraperParams.game->getImagePath(), false); TextureResource::manualUnload(mScraperParams.game->getMarqueePath(), false); - ViewController::get()->reloadGameListView(mScraperParams.system); + ViewController::getInstance()->reloadGameListView(mScraperParams.system); // Update all collections where the game is present. - CollectionSystemsManager::get()->refreshCollectionSystems(mScraperParams.game); + CollectionSystemsManager::getInstance()->refreshCollectionSystems(mScraperParams.game); mWindow->invalidateCachedBackground(); } - ViewController::get()->onPauseVideo(); + ViewController::getInstance()->onPauseVideo(); delete this; }; @@ -866,6 +867,6 @@ std::vector GuiMetaDataEd::getHelpPrompts() HelpStyle GuiMetaDataEd::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiOfflineGenerator.cpp b/es-app/src/guis/GuiOfflineGenerator.cpp index acd30b8b1..b46731528 100644 --- a/es-app/src/guis/GuiOfflineGenerator.cpp +++ b/es-app/src/guis/GuiOfflineGenerator.cpp @@ -198,7 +198,7 @@ GuiOfflineGenerator::~GuiOfflineGenerator() mMiximageGenerator.reset(); if (mImagesGenerated > 0) - ViewController::get()->reloadAll(); + ViewController::getInstance()->reloadAll(); } void GuiOfflineGenerator::onSizeChanged() @@ -336,6 +336,6 @@ std::vector GuiOfflineGenerator::getHelpPrompts() HelpStyle GuiOfflineGenerator::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiScraperMenu.cpp b/es-app/src/guis/GuiScraperMenu.cpp index 2df3ec7bb..cb817fc2a 100644 --- a/es-app/src/guis/GuiScraperMenu.cpp +++ b/es-app/src/guis/GuiScraperMenu.cpp @@ -1135,6 +1135,6 @@ std::vector GuiScraperMenu::getHelpPrompts() HelpStyle GuiScraperMenu::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiScraperMulti.cpp b/es-app/src/guis/GuiScraperMulti.cpp index d755a06be..7f7d42949 100644 --- a/es-app/src/guis/GuiScraperMulti.cpp +++ b/es-app/src/guis/GuiScraperMulti.cpp @@ -182,7 +182,7 @@ GuiScraperMulti::~GuiScraperMulti() (*it)->sortSystem(); } } - ViewController::get()->onPauseVideo(); + ViewController::getInstance()->onPauseVideo(); } void GuiScraperMulti::onSizeChanged() @@ -280,7 +280,7 @@ void GuiScraperMulti::acceptResult(const ScraperSearchResult& result) mSearchQueue.pop(); ++mCurrentGame; ++mTotalSuccessful; - CollectionSystemsManager::get()->refreshCollectionSystems(search.game); + CollectionSystemsManager::getInstance()->refreshCollectionSystems(search.game); doNextSearch(); } @@ -324,6 +324,6 @@ std::vector GuiScraperMulti::getHelpPrompts() HelpStyle GuiScraperMulti::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiScraperSearch.cpp b/es-app/src/guis/GuiScraperSearch.cpp index 05eeef9e3..9fb163166 100644 --- a/es-app/src/guis/GuiScraperSearch.cpp +++ b/es-app/src/guis/GuiScraperSearch.cpp @@ -170,7 +170,7 @@ GuiScraperSearch::~GuiScraperSearch() mMiximageGeneratorThread.join(); mMiximageGenerator.reset(); TextureResource::manualUnload(mLastSearch.game->getMiximagePath(), false); - ViewController::get()->onFileChanged(mLastSearch.game, true); + ViewController::getInstance()->onFileChanged(mLastSearch.game, true); } } @@ -1017,6 +1017,6 @@ std::vector GuiScraperSearch::getHelpPrompts() HelpStyle GuiScraperSearch::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/guis/GuiScraperSearch.h b/es-app/src/guis/GuiScraperSearch.h index 2df3ce320..490fee366 100644 --- a/es-app/src/guis/GuiScraperSearch.h +++ b/es-app/src/guis/GuiScraperSearch.h @@ -98,7 +98,7 @@ public: void onFocusGained() override { mGrid.onFocusGained(); } void onFocusLost() override { mGrid.onFocusLost(); } - std::shared_ptr& getResultList() { return mResultList; } + std::shared_ptr getResultList() { return mResultList; } private: void updateViewStyle(); diff --git a/es-app/src/guis/GuiSettings.cpp b/es-app/src/guis/GuiSettings.cpp index 7dc054878..31f90de9b 100644 --- a/es-app/src/guis/GuiSettings.cpp +++ b/es-app/src/guis/GuiSettings.cpp @@ -66,8 +66,8 @@ void GuiSettings::save() mWindow->reloadHelpPrompts(); if (mNeedsCollectionsUpdate) { - CollectionSystemsManager::get()->loadEnabledListFromSettings(); - CollectionSystemsManager::get()->updateSystemsList(); + CollectionSystemsManager::getInstance()->loadEnabledListFromSettings(); + CollectionSystemsManager::getInstance()->updateSystemsList(); } if (mNeedsSorting) { @@ -77,7 +77,7 @@ void GuiSettings::save() (*it)->sortSystem(true); // Jump to the first row of the gamelist. - IGameListView* gameList = ViewController::get()->getGameListView((*it)).get(); + IGameListView* gameList = ViewController::getInstance()->getGameListView((*it)).get(); gameList->setCursor(gameList->getFirstEntry()); } } @@ -94,38 +94,38 @@ void GuiSettings::save() } if (mNeedsReloading) - ViewController::get()->reloadAll(); + ViewController::getInstance()->reloadAll(); if (mNeedsGoToStart) - ViewController::get()->goToStart(true); + ViewController::getInstance()->goToStart(true); if (mNeedsGoToSystem) - ViewController::get()->goToSystem(mGoToSystem, false); + ViewController::getInstance()->goToSystem(mGoToSystem, false); if (mNeedsGoToGroupedCollections) { bool groupedSystemExists = false; for (SystemData* system : SystemData::sSystemVector) { if (system->getThemeFolder() == "custom-collections") { - ViewController::get()->goToSystem(system, false); + ViewController::getInstance()->goToSystem(system, false); groupedSystemExists = true; continue; } } if (!groupedSystemExists) // No grouped custom collection system exists, so go to the first system instead. - ViewController::get()->goToSystem(SystemData::sSystemVector.front(), false); + ViewController::getInstance()->goToSystem(SystemData::sSystemVector.front(), false); } if (mNeedsCollectionsUpdate) { - auto state = ViewController::get()->getState(); + auto state = ViewController::getInstance()->getState(); // If we're in any view other than the grouped custom collections, always jump to the // system view in case of any collection updates. This is overkill in some instances but // these views can behave a bit strange during collection changes so it's better to be on // the safe side. if (state.getSystem()->isCollection() && state.getSystem()->getThemeFolder() != "custom-collections") { - ViewController::get()->goToStart(false); - ViewController::get()->goToSystem(SystemData::sSystemVector.front(), false); + ViewController::getInstance()->goToStart(false); + ViewController::getInstance()->goToSystem(SystemData::sSystemVector.front(), false); // We don't want to invalidate the cached background when there has been a collection // systen change as that may show a black screen in some circumstances. return; @@ -134,7 +134,7 @@ void GuiSettings::save() // system view). if (std::find(SystemData::sSystemVector.begin(), SystemData::sSystemVector.end(), state.getSystem()) == SystemData::sSystemVector.end()) { - ViewController::get()->goToStart(false); + ViewController::getInstance()->goToStart(false); return; } } @@ -237,7 +237,7 @@ bool GuiSettings::input(InputConfig* config, Input input) HelpStyle GuiSettings::getHelpStyle() { HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system"); return style; } diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 37e8d6d0b..fc1430bf1 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -528,24 +528,25 @@ int main(int argc, char* argv[]) } } - Window window; - SystemScreensaver screensaver(&window); - MediaViewer mediaViewer(&window); - GuiLaunchScreen guiLaunchScreen(&window); - ViewController::init(&window); - CollectionSystemsManager::init(&window); - window.pushGui(ViewController::get()); + Window* window = Window::getInstance(); + ViewController::getInstance(); + CollectionSystemsManager::getInstance(); + SystemScreensaver screensaver; + MediaViewer mediaViewer; + GuiLaunchScreen guiLaunchScreen; + + if (!window->init()) { + LOG(LogError) << "Window failed to initialize"; + return 1; + } + + window->pushGui(ViewController::getInstance()); bool splashScreen = Settings::getInstance()->getBool("SplashScreen"); bool splashScreenProgress = Settings::getInstance()->getBool("SplashScreenProgress"); SDL_Event event{}; - if (!window.init()) { - LOG(LogError) << "Window failed to initialize"; - return 1; - } - - InputManager::getInstance()->parseEvent(event, &window); + InputManager::getInstance().parseEvent(event, window); if (event.type == SDL_QUIT) return 1; @@ -571,7 +572,7 @@ int main(int argc, char* argv[]) std::string progressText = "Loading..."; if (splashScreenProgress) progressText = "Loading system config..."; - window.renderLoadingScreen(progressText); + window->renderLoadingScreen(progressText); } AudioManager::getInstance(); @@ -584,10 +585,10 @@ int main(int argc, char* argv[]) // configure a different ROM directory as well as to generate the game systems // directory structure. if (loadSystemsStatus == INVALID_FILE) { - ViewController::get()->invalidSystemsFileDialog(); + ViewController::getInstance()->invalidSystemsFileDialog(); } else if (loadSystemsStatus == NO_ROMS) { - ViewController::get()->noGamesDialog(); + ViewController::getInstance()->noGamesDialog(); } } @@ -596,7 +597,7 @@ int main(int argc, char* argv[]) // any command tag in es_systems.xml. for (auto system : SystemData::sSystemVector) { if (system->getAlternativeEmulator().substr(0, 9) == "") { - ViewController::get()->invalidAlternativeEmulatorDialog(); + ViewController::getInstance()->invalidAlternativeEmulatorDialog(); break; } } @@ -606,19 +607,19 @@ int main(int argc, char* argv[]) // Preload what we can right away instead of waiting for the user to select it. // This makes for no delays when accessing content, but a longer startup time. - ViewController::get()->preload(); + ViewController::getInstance()->preload(); if (splashScreen && splashScreenProgress) - window.renderLoadingScreen("Done"); + window->renderLoadingScreen("Done"); // Open the input configuration GUI if the flag to force this was passed from the command line. if (!loadSystemsStatus) { if (forceInputConfig) { - window.pushGui(new GuiDetectDevice(&window, false, true, - [] { ViewController::get()->goToStart(true); })); + window->pushGui(new GuiDetectDevice( + window, false, true, [] { ViewController::getInstance()->goToStart(true); })); } else { - ViewController::get()->goToStart(true); + ViewController::getInstance()->goToStart(true); } } @@ -645,7 +646,7 @@ int main(int argc, char* argv[]) while (running) { if (SDL_PollEvent(&event)) { do { - InputManager::getInstance()->parseEvent(event, &window); + InputManager::getInstance().parseEvent(event, window); if (event.type == SDL_QUIT) running = false; @@ -653,7 +654,7 @@ int main(int argc, char* argv[]) } while (SDL_PollEvent(&event)); } - if (window.isSleeping()) { + if (window->isSleeping()) { lastTime = SDL_GetTicks(); // This doesn't need to be accurate, we're just giving up // our CPU time until something wakes us up. @@ -669,18 +670,18 @@ int main(int argc, char* argv[]) if (deltaTime < 0) deltaTime = 1000; - window.update(deltaTime); - window.render(); + window->update(deltaTime); + window->render(); Renderer::swapBuffers(); Log::flush(); } - while (window.peekGui() != ViewController::get()) - delete window.peekGui(); - window.deinit(); + while (window->peekGui() != ViewController::getInstance()) + delete window->peekGui(); + window->deinit(); - CollectionSystemsManager::deinit(); + CollectionSystemsManager::getInstance()->deinit(); SystemData::deleteSystems(); NavigationSounds::getInstance().deinit(); diff --git a/es-app/src/scrapers/Scraper.cpp b/es-app/src/scrapers/Scraper.cpp index 7d38179e4..98948883e 100644 --- a/es-app/src/scrapers/Scraper.cpp +++ b/es-app/src/scrapers/Scraper.cpp @@ -253,7 +253,7 @@ MDResolveHandle::MDResolveHandle(const ScraperSearchResult& result, scrapeFiles.push_back(mediaFileInfo); #if defined(_WIN64) // Required due to the idiotic file locking that exists on this operating system. - ViewController::get()->onStopVideo(); + ViewController::getInstance()->onStopVideo(); #endif } diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index b3114702a..029a4360b 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -77,9 +77,9 @@ void SystemView::populate() auto path = logoElem->get("path"); std::string defaultPath = logoElem->has("default") ? logoElem->get("default") : ""; - if ((!path.empty() && ResourceManager::getInstance()->fileExists(path)) || + if ((!path.empty() && ResourceManager::getInstance().fileExists(path)) || (!defaultPath.empty() && - ResourceManager::getInstance()->fileExists(defaultPath))) { + ResourceManager::getInstance().fileExists(defaultPath))) { auto* logo = new ImageComponent(mWindow, false, false); logo->setMaxSize(glm::round(mCarousel.logoSize * mCarousel.logoScale)); logo->applyTheme(theme, "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR); @@ -101,9 +101,9 @@ void SystemView::populate() auto path = logoElem->get("path"); std::string defaultPath = logoElem->has("default") ? logoElem->get("default") : ""; - if ((!path.empty() && ResourceManager::getInstance()->fileExists(path)) || + if ((!path.empty() && ResourceManager::getInstance().fileExists(path)) || (!defaultPath.empty() && - ResourceManager::getInstance()->fileExists(defaultPath))) { + ResourceManager::getInstance().fileExists(defaultPath))) { auto* logo = new ImageComponent(mWindow, false, false); logo->applyTheme(theme, "system", "logoPlaceholderImage", ThemeFlags::ALL); if (!logoElem->has("size")) @@ -247,7 +247,7 @@ bool SystemView::input(InputConfig* config, Input input) if (config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_r && SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug")) { LOG(LogDebug) << "SystemView::input(): Reloading all"; - ViewController::get()->reloadAll(); + ViewController::getInstance()->reloadAll(); return true; } @@ -255,12 +255,12 @@ bool SystemView::input(InputConfig* config, Input input) case VERTICAL: case VERTICAL_WHEEL: if (config->isMappedLike("up", input)) { - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); listInput(-1); return true; } if (config->isMappedLike("down", input)) { - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); listInput(1); return true; } @@ -269,12 +269,12 @@ bool SystemView::input(InputConfig* config, Input input) case HORIZONTAL_WHEEL: default: if (config->isMappedLike("left", input)) { - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); listInput(-1); return true; } if (config->isMappedLike("right", input)) { - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); listInput(1); return true; } @@ -283,7 +283,7 @@ bool SystemView::input(InputConfig* config, Input input) if (config->isMappedTo("a", input)) { stopScrolling(); - ViewController::get()->goToGameList(getSelected()); + ViewController::getInstance()->goToGameList(getSelected()); NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND); return true; } @@ -299,8 +299,8 @@ bool SystemView::input(InputConfig* config, Input input) if (!UIModeController::getInstance()->isUIModeKid() && config->isMappedTo("back", input) && Settings::getInstance()->getBool("ScreensaverControls")) { if (!mWindow->isScreensaverActive()) { - ViewController::get()->stopScrolling(); - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->stopScrolling(); + ViewController::getInstance()->cancelViewTransitions(); mWindow->startScreensaver(); mWindow->renderScreensaver(); } diff --git a/es-app/src/views/UIModeController.cpp b/es-app/src/views/UIModeController.cpp index 632ebd03d..7b32318fc 100644 --- a/es-app/src/views/UIModeController.cpp +++ b/es-app/src/views/UIModeController.cpp @@ -16,25 +16,7 @@ #include "utils/StringUtil.h" #include "views/ViewController.h" -UIModeController* UIModeController::sInstance = nullptr; - -UIModeController* UIModeController::getInstance() -{ - if (sInstance == nullptr) - sInstance = new UIModeController(); - - return sInstance; -} - -void UIModeController::deinit() -{ - if (sInstance) { - delete sInstance; - sInstance = nullptr; - } -} - -UIModeController::UIModeController() +UIModeController::UIModeController() noexcept : mPassKeyCounter(0) { mPassKeySequence = Settings::getInstance()->getString("UIMode_passkey"); @@ -47,11 +29,17 @@ UIModeController::UIModeController() } } +UIModeController* UIModeController::getInstance() +{ + static UIModeController instance; + return &instance; +} + void UIModeController::monitorUIMode() { std::string uimode = Settings::getInstance()->getString("UIMode"); // UI mode was changed. - if (uimode != mCurrentUIMode && !ViewController::get()->isCameraMoving()) { + if (uimode != mCurrentUIMode && !ViewController::getInstance()->isCameraMoving()) { mCurrentUIMode = uimode; // Reset filters and sort gamelists (which will update the game counter). for (auto it = SystemData::sSystemVector.cbegin(); // Line break. @@ -63,7 +51,7 @@ void UIModeController::monitorUIMode() customSystem->getSystem()->getIndex()->resetFilters(); } } - ViewController::get()->ReloadAndGoToStart(); + ViewController::getInstance()->ReloadAndGoToStart(); } } diff --git a/es-app/src/views/UIModeController.h b/es-app/src/views/UIModeController.h index 5fbc83721..7f04b8f8f 100644 --- a/es-app/src/views/UIModeController.h +++ b/es-app/src/views/UIModeController.h @@ -23,7 +23,6 @@ class UIModeController { public: static UIModeController* getInstance(); - static void deinit(); // Monitor input for UI mode change, returns true (consumes input) when a UI mode // change is triggered. @@ -42,15 +41,14 @@ public: void setCurrentUIMode(const std::string& mode) { mCurrentUIMode = mode; } private: - UIModeController(); + UIModeController() noexcept; + bool inputIsMatch(InputConfig* config, Input input); bool isValidInput(InputConfig* config, Input input); // Return UI mode to 'full'. void unlockUIMode(); - static UIModeController* sInstance; - // Default passkeyseq = "uuddlrlrba", as defined in the setting 'UIMode_passkey'. std::string mPassKeySequence; diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index c61ce96b1..5fa2e0f01 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -33,8 +33,6 @@ #include "views/gamelist/IGameListView.h" #include "views/gamelist/VideoGameListView.h" -ViewController* ViewController::sInstance = nullptr; - #if defined(_MSC_VER) // MSVC compiler. const std::string ViewController::CONTROLLER_CHAR = Utils::String::wideStringToString(L"\uf11b"); const std::string ViewController::CROSSEDCIRCLE_CHAR = Utils::String::wideStringToString(L"\uf05e"); @@ -57,20 +55,14 @@ const std::string ViewController::KEYBOARD_CHAR = "\uf11c"; const std::string ViewController::TICKMARK_CHAR = "\uf14a"; #endif -ViewController* ViewController::get() +ViewController* ViewController::getInstance() { - assert(sInstance); - return sInstance; + static ViewController instance; + return &instance; } -void ViewController::init(Window* window) -{ - assert(!sInstance); - sInstance = new ViewController(window); -} - -ViewController::ViewController(Window* window) - : GuiComponent(window) +ViewController::ViewController() noexcept + : GuiComponent(Window::getInstance()) , mNoGamesMessageBox(nullptr) , mCurrentView(nullptr) , mPreviousView(nullptr) @@ -88,13 +80,6 @@ ViewController::ViewController(Window* window) mState.viewstyle = AUTOMATIC; } -ViewController::~ViewController() -{ - assert(sInstance == this); - sInstance = nullptr; - UIModeController::deinit(); -} - void ViewController::invalidSystemsFileDialog() { std::string errorMessage = "COULDN'T PARSE THE SYSTEMS CONFIGURATION FILE.\n" diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h index 44438ac2d..29419c849 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -29,10 +29,7 @@ class SystemView; class ViewController : public GuiComponent { public: - static void init(Window* window); - static ViewController* get(); - - virtual ~ViewController(); + static ViewController* getInstance(); // These functions are called from main(). void invalidSystemsFileDialog(); @@ -131,8 +128,7 @@ public: static const std::string TICKMARK_CHAR; private: - ViewController(Window* window); - static ViewController* sInstance; + ViewController() noexcept; void launch(FileData* game); diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index 225506c1f..543676734 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -40,7 +40,7 @@ void BasicGameListView::onFileChanged(FileData* file, bool reloadGameList) { if (reloadGameList) { // Might switch to a detailed view. - ViewController::get()->reloadGameListView(this); + ViewController::getInstance()->reloadGameListView(this); return; } @@ -55,8 +55,8 @@ void BasicGameListView::populateList(const std::vector& files, FileDa std::string editingCollection; std::string inCollectionPrefix; - if (CollectionSystemsManager::get()->isEditing()) { - editingCollection = CollectionSystemsManager::get()->getEditingCollection(); + if (CollectionSystemsManager::getInstance()->isEditing()) { + editingCollection = CollectionSystemsManager::getInstance()->getEditingCollection(); isEditing = true; } @@ -78,7 +78,8 @@ void BasicGameListView::populateList(const std::vector& files, FileDa // Add a leading tick mark icon to the game name if it's part of the custom collection // currently being edited. if (isEditing && (*it)->getType() == GAME) { - if (CollectionSystemsManager::get()->inCustomCollection(editingCollection, (*it))) { + if (CollectionSystemsManager::getInstance()->inCustomCollection(editingCollection, + (*it))) { if (Settings::getInstance()->getBool("SpecialCharsASCII")) inCollectionPrefix = "! "; else @@ -161,7 +162,7 @@ void BasicGameListView::addPlaceholder(FileData* firstEntry) void BasicGameListView::launch(FileData* game) { // This triggers ViewController to launch the game. - ViewController::get()->triggerGameLaunch(game); + ViewController::getInstance()->triggerGameLaunch(game); } void BasicGameListView::remove(FileData* game, bool deleteFile) @@ -309,7 +310,7 @@ std::vector BasicGameListView::getHelpPrompts() prompts.push_back(HelpPrompt("left/right", "system")); if (mRoot->getSystem()->getThemeFolder() == "custom-collections" && mCursorStack.empty() && - ViewController::get()->getState().viewing == ViewController::GAME_LIST) + ViewController::getInstance()->getState().viewing == ViewController::GAME_LIST) prompts.push_back(HelpPrompt("a", "enter")); else prompts.push_back(HelpPrompt("a", "launch")); @@ -323,9 +324,9 @@ std::vector BasicGameListView::getHelpPrompts() prompts.push_back(HelpPrompt("thumbstickclick", "random")); if (mRoot->getSystem()->getThemeFolder() == "custom-collections" && - !CollectionSystemsManager::get()->isEditing() && mCursorStack.empty() && - ViewController::get()->getState().viewing == ViewController::GAME_LIST && - ViewController::get()->getState().viewstyle != ViewController::BASIC) { + !CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() && + ViewController::getInstance()->getState().viewing == ViewController::GAME_LIST && + ViewController::getInstance()->getState().viewstyle != ViewController::BASIC) { prompts.push_back(HelpPrompt("y", "jump to game")); } else if (mRoot->getSystem()->isGameSystem() && @@ -334,14 +335,14 @@ std::vector BasicGameListView::getHelpPrompts() !UIModeController::getInstance()->isUIModeKid() && !UIModeController::getInstance()->isUIModeKiosk() && (Settings::getInstance()->getBool("FavoritesAddButton") || - CollectionSystemsManager::get()->isEditing())) { - std::string prompt = CollectionSystemsManager::get()->getEditingCollection(); + CollectionSystemsManager::getInstance()->isEditing())) { + std::string prompt = CollectionSystemsManager::getInstance()->getEditingCollection(); prompts.push_back(HelpPrompt("y", prompt)); } else if (mRoot->getSystem()->isGameSystem() && mRoot->getSystem()->getThemeFolder() == "custom-collections" && - CollectionSystemsManager::get()->isEditing()) { - std::string prompt = CollectionSystemsManager::get()->getEditingCollection(); + CollectionSystemsManager::getInstance()->isEditing()) { + std::string prompt = CollectionSystemsManager::getInstance()->getEditingCollection(); prompts.push_back(HelpPrompt("y", prompt)); } return prompts; diff --git a/es-app/src/views/gamelist/DetailedGameListView.cpp b/es-app/src/views/gamelist/DetailedGameListView.cpp index 6e92af66a..8c83264fc 100644 --- a/es-app/src/views/gamelist/DetailedGameListView.cpp +++ b/es-app/src/views/gamelist/DetailedGameListView.cpp @@ -338,8 +338,8 @@ void DetailedGameListView::updateInfoPanel() // the first of these so that we can display its game media. if (file->getSystem()->isCustomCollection() && file->getPath() == file->getSystem()->getName()) { - mRandomGame = - CollectionSystemsManager::get()->updateCollectionFolderMetadata(file->getSystem()); + mRandomGame = CollectionSystemsManager::getInstance()->updateCollectionFolderMetadata( + file->getSystem()); if (mRandomGame) { mThumbnail.setImage(mRandomGame->getThumbnailPath()); mMarquee.setImage(mRandomGame->getMarqueePath(), false, true); @@ -476,7 +476,7 @@ void DetailedGameListView::updateInfoPanel() void DetailedGameListView::launch(FileData* game) { - ViewController::get()->triggerGameLaunch(game); + ViewController::getInstance()->triggerGameLaunch(game); } std::vector DetailedGameListView::getMDLabels() @@ -512,7 +512,7 @@ void DetailedGameListView::update(int deltaTime) BasicGameListView::update(deltaTime); mImage.update(deltaTime); - if (ViewController::get()->getGameLaunchTriggered() && mImage.isAnimationPlaying(0)) + if (ViewController::getInstance()->getGameLaunchTriggered() && mImage.isAnimationPlaying(0)) mImage.finishAnimation(0); } diff --git a/es-app/src/views/gamelist/GridGameListView.cpp b/es-app/src/views/gamelist/GridGameListView.cpp index 338969f47..335772cd6 100644 --- a/es-app/src/views/gamelist/GridGameListView.cpp +++ b/es-app/src/views/gamelist/GridGameListView.cpp @@ -130,7 +130,7 @@ void GridGameListView::onFileChanged(FileData* file, bool reloadGameList) { if (reloadGameList) { // Might switch to a detailed view. - ViewController::get()->reloadGameListView(this); + ViewController::getInstance()->reloadGameListView(this); return; } @@ -519,7 +519,7 @@ void GridGameListView::addPlaceholder(FileData* firstEntry) void GridGameListView::launch(FileData* game) { // This triggers ViewController to launch the game. - ViewController::get()->triggerGameLaunch(game); + ViewController::getInstance()->triggerGameLaunch(game); } void GridGameListView::remove(FileData* game, bool deleteFile) @@ -687,7 +687,7 @@ std::vector GridGameListView::getHelpPrompts() prompts.push_back(HelpPrompt("up/down/left/right", "choose")); if (mRoot->getSystem()->getThemeFolder() == "custom-collections" && mCursorStack.empty() && - ViewController::get()->getState().viewing == ViewController::GAME_LIST) + ViewController::getInstance()->getState().viewing == ViewController::GAME_LIST) prompts.push_back(HelpPrompt("a", "enter")); else prompts.push_back(HelpPrompt("a", "launch")); @@ -712,14 +712,14 @@ std::vector GridGameListView::getHelpPrompts() !UIModeController::getInstance()->isUIModeKid() && !UIModeController::getInstance()->isUIModeKiosk() && (Settings::getInstance()->getBool("FavoritesAddButton") || - CollectionSystemsManager::get()->isEditing())) { - std::string prompt = CollectionSystemsManager::get()->getEditingCollection(); + CollectionSystemsManager::getInstance()->isEditing())) { + std::string prompt = CollectionSystemsManager::getInstance()->getEditingCollection(); prompts.push_back(HelpPrompt("y", prompt)); } else if (mRoot->getSystem()->isGameSystem() && mRoot->getSystem()->getThemeFolder() == "custom-collections" && - CollectionSystemsManager::get()->isEditing()) { - std::string prompt = CollectionSystemsManager::get()->getEditingCollection(); + CollectionSystemsManager::getInstance()->isEditing()) { + std::string prompt = CollectionSystemsManager::getInstance()->getEditingCollection(); prompts.push_back(HelpPrompt("y", prompt)); } return prompts; diff --git a/es-app/src/views/gamelist/IGameListView.cpp b/es-app/src/views/gamelist/IGameListView.cpp index 1addc67a8..dcd86aaab 100644 --- a/es-app/src/views/gamelist/IGameListView.cpp +++ b/es-app/src/views/gamelist/IGameListView.cpp @@ -33,7 +33,7 @@ bool IGameListView::input(InputConfig* config, Input input) // Select button opens GuiGamelistOptions. if (!UIModeController::getInstance()->isUIModeKid() && // Line break. config->isMappedTo("back", input) && input.value) { - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); stopListScrolling(); mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem())); return true; @@ -45,7 +45,7 @@ bool IGameListView::input(InputConfig* config, Input input) (SDL_GetModState() & (KMOD_LCTRL | KMOD_RCTRL)) && input.id == SDLK_r && input.value != 0) { LOG(LogDebug) << "IGameListView::input(): Reloading view"; - ViewController::get()->reloadGameListView(this, true); + ViewController::getInstance()->reloadGameListView(this, true); return true; } diff --git a/es-app/src/views/gamelist/IGameListView.h b/es-app/src/views/gamelist/IGameListView.h index 212a062e9..9c31185d9 100644 --- a/es-app/src/views/gamelist/IGameListView.h +++ b/es-app/src/views/gamelist/IGameListView.h @@ -30,7 +30,7 @@ public: virtual void onThemeChanged(const std::shared_ptr& theme) = 0; void setTheme(const std::shared_ptr& theme); - const std::shared_ptr& getTheme() const { return mTheme; } + const std::shared_ptr getTheme() const { return mTheme; } virtual void preloadGamelist(){}; diff --git a/es-app/src/views/gamelist/ISimpleGameListView.cpp b/es-app/src/views/gamelist/ISimpleGameListView.cpp index e5a180531..66ddb9bc6 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.cpp +++ b/es-app/src/views/gamelist/ISimpleGameListView.cpp @@ -106,14 +106,14 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) FileData* cursor = getCursor(); if (cursor->getType() == GAME) { onPauseVideo(); - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); stopListScrolling(); launch(cursor); } else { // It's a folder. if (cursor->getChildren().size() > 0) { - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND); mCursorStack.push(cursor); populateList(cursor->getChildrenListToDisplay(), cursor); @@ -147,7 +147,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) return true; } else if (config->isMappedTo("b", input)) { - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); if (mCursorStack.size()) { // Save the position to the cursor stack history. mCursorStackHistory.push_back(getCursor()); @@ -168,10 +168,10 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) SystemData* systemToView = getCursor()->getSystem(); if (systemToView->isCustomCollection() && systemToView->getRootFolder()->getParent()) - ViewController::get()->goToSystemView( + ViewController::getInstance()->goToSystemView( systemToView->getRootFolder()->getParent()->getSystem(), true); else - ViewController::get()->goToSystemView(systemToView, true); + ViewController::getInstance()->goToSystemView(systemToView, true); } return true; @@ -184,19 +184,20 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) else if (config->isMappedTo("x", input) && mRoot->getSystem()->getThemeFolder() == "custom-collections" && mCursorStack.empty() && - ViewController::get()->getState().viewing == ViewController::GAME_LIST) { + ViewController::getInstance()->getState().viewing == + ViewController::GAME_LIST) { NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND); // Jump to the randomly selected game. if (mRandomGame) { stopListScrolling(); - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); mWindow->startMediaViewer(mRandomGame); return true; } } else if (mRoot->getSystem()->isGameSystem()) { stopListScrolling(); - ViewController::get()->cancelViewTransitions(); + ViewController::getInstance()->cancelViewTransitions(); NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND); mWindow->startMediaViewer(getCursor()); return true; @@ -208,7 +209,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) onPauseVideo(); onFocusLost(); stopListScrolling(); - ViewController::get()->goToNextGameList(); + ViewController::getInstance()->goToNextGameList(); return true; } } @@ -218,7 +219,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) onPauseVideo(); onFocusLost(); stopListScrolling(); - ViewController::get()->goToPrevGameList(); + ViewController::getInstance()->goToPrevGameList(); return true; } } @@ -237,8 +238,8 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) } else if (config->isMappedTo("y", input) && mRoot->getSystem()->getThemeFolder() == "custom-collections" && - !CollectionSystemsManager::get()->isEditing() && mCursorStack.empty() && - ViewController::get()->getState().viewing == ViewController::GAME_LIST) { + !CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() && + ViewController::getInstance()->getState().viewing == ViewController::GAME_LIST) { // Jump to the randomly selected game. if (mRandomGame) { NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND); @@ -262,21 +263,21 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) } else if (config->isMappedTo("y", input) && !Settings::getInstance()->getBool("FavoritesAddButton") && - !CollectionSystemsManager::get()->isEditing()) { + !CollectionSystemsManager::getInstance()->isEditing()) { return true; } else if (config->isMappedTo("y", input) && !UIModeController::getInstance()->isUIModeKid() && !UIModeController::getInstance()->isUIModeKiosk()) { // Notify the user if attempting to add a custom collection to a custom collection. - if (CollectionSystemsManager::get()->isEditing() && + if (CollectionSystemsManager::getInstance()->isEditing() && mRoot->getSystem()->isGameSystem() && getCursor()->getType() != PLACEHOLDER && getCursor()->getParent()->getPath() == "collections") { NavigationSounds::getInstance().playThemeNavigationSound(FAVORITESOUND); mWindow->queueInfoPopup("CAN'T ADD CUSTOM COLLECTIONS TO CUSTOM COLLECTIONS", 4000); } // Notify the user if attempting to add a placeholder to a custom collection. - if (CollectionSystemsManager::get()->isEditing() && + if (CollectionSystemsManager::getInstance()->isEditing() && mRoot->getSystem()->isGameSystem() && getCursor()->getType() == PLACEHOLDER) { NavigationSounds::getInstance().playThemeNavigationSound(FAVORITESOUND); mWindow->queueInfoPopup("CAN'T ADD PLACEHOLDERS TO CUSTOM COLLECTIONS", 4000); @@ -293,7 +294,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) bool favoritesSorting; bool removedLastFavorite = false; bool selectLastEntry = false; - bool isEditing = CollectionSystemsManager::get()->isEditing(); + bool isEditing = CollectionSystemsManager::getInstance()->isEditing(); bool foldersOnTop = Settings::getInstance()->getBool("FoldersOnTop"); // If the current list only contains folders, then treat it as if the folders // are not sorted on top, this way the logic should work exactly as for mixed @@ -420,15 +421,15 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) mRoot->getSortTypeFromString(mRoot->getSortTypeString()), Settings::getInstance()->getBool("FavoritesFirst")); - ViewController::get()->onFileChanged(getCursor(), false); + ViewController::getInstance()->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 // sorted yet. if (removedLastFavorite) { - ViewController::get() + ViewController::getInstance() ->getGameListView(entryToUpdate->getSystem()) - ->setCursor(ViewController::get() + ->setCursor(ViewController::getInstance() ->getGameListView(entryToUpdate->getSystem()) ->getFirstEntry()); } @@ -439,17 +440,19 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) "AS GAMES TO CUSTOM COLLECTIONS", 4000); } - else if (CollectionSystemsManager::get()->toggleGameInCollection(entryToUpdate)) { + else if (CollectionSystemsManager::getInstance()->toggleGameInCollection( + entryToUpdate)) { // As the toggling of the game destroyed this object, we need to get the view // from ViewController instead of using the reference that existed before the // destruction. Otherwise we get random crashes. - IGameListView* view = ViewController::get()->getGameListView(system).get(); + IGameListView* view = + ViewController::getInstance()->getGameListView(system).get(); // Jump to the first entry in the gamelist if the last favorite was unmarked. if (foldersOnTop && removedLastFavorite && !entryToUpdate->getSystem()->isCustomCollection()) { - ViewController::get() + ViewController::getInstance() ->getGameListView(entryToUpdate->getSystem()) - ->setCursor(ViewController::get() + ->setCursor(ViewController::getInstance() ->getGameListView(entryToUpdate->getSystem()) ->getFirstGameEntry()); } @@ -466,8 +469,9 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) if (isEditing) { for (auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it) { - ViewController::get()->getGameListView((*it))->onFileChanged( - ViewController::get()->getGameListView((*it))->getCursor(), false); + ViewController::getInstance()->getGameListView((*it))->onFileChanged( + ViewController::getInstance()->getGameListView((*it))->getCursor(), + false); } } return true; diff --git a/es-app/src/views/gamelist/VideoGameListView.cpp b/es-app/src/views/gamelist/VideoGameListView.cpp index e80f90691..e11b6093f 100644 --- a/es-app/src/views/gamelist/VideoGameListView.cpp +++ b/es-app/src/views/gamelist/VideoGameListView.cpp @@ -349,8 +349,8 @@ void VideoGameListView::updateInfoPanel() // the first of these so that we can display its game media. if (file->getSystem()->isCustomCollection() && file->getPath() == file->getSystem()->getName()) { - mRandomGame = - CollectionSystemsManager::get()->updateCollectionFolderMetadata(file->getSystem()); + mRandomGame = CollectionSystemsManager::getInstance()->updateCollectionFolderMetadata( + file->getSystem()); if (mRandomGame) { mThumbnail.setImage(mRandomGame->getThumbnailPath()); mMarquee.setImage(mRandomGame->getMarqueePath(), false, true); @@ -502,7 +502,10 @@ void VideoGameListView::updateInfoPanel() } } -void VideoGameListView::launch(FileData* game) { ViewController::get()->triggerGameLaunch(game); } +void VideoGameListView::launch(FileData* game) +{ + ViewController::getInstance()->triggerGameLaunch(game); +} std::vector VideoGameListView::getMDLabels() { @@ -542,7 +545,7 @@ void VideoGameListView::update(int deltaTime) BasicGameListView::update(deltaTime); mVideo->update(deltaTime); - if (ViewController::get()->getGameLaunchTriggered() && mVideo->isAnimationPlaying(0)) + if (ViewController::getInstance()->getGameLaunchTriggered() && mVideo->isAnimationPlaying(0)) mVideo->finishAnimation(0); } diff --git a/es-core/src/AudioManager.cpp b/es-core/src/AudioManager.cpp index e4004d04f..1d8dec2ac 100644 --- a/es-core/src/AudioManager.cpp +++ b/es-core/src/AudioManager.cpp @@ -14,7 +14,7 @@ #include -AudioManager::AudioManager() +AudioManager::AudioManager() noexcept { // Init on construction. init(); @@ -119,6 +119,8 @@ void AudioManager::deinit() SDL_CloseAudio(); SDL_QuitSubSystem(SDL_INIT_AUDIO); + + sAudioDevice = 0; } void AudioManager::mixAudio(void* /*unused*/, Uint8* stream, int len) diff --git a/es-core/src/AudioManager.h b/es-core/src/AudioManager.h index cca5b06a0..9a4bf86db 100644 --- a/es-core/src/AudioManager.h +++ b/es-core/src/AudioManager.h @@ -45,7 +45,7 @@ public: inline static SDL_AudioSpec sAudioFormat; private: - AudioManager(); + AudioManager() noexcept; static void mixAudio(void* unused, Uint8* stream, int len); static void mixAudio2(void* unused, Uint8* stream, int len); diff --git a/es-core/src/CECInput.cpp b/es-core/src/CECInput.cpp index d26474865..70dc87eca 100644 --- a/es-core/src/CECInput.cpp +++ b/es-core/src/CECInput.cpp @@ -30,8 +30,6 @@ extern "C" { extern int SDL_USER_CECBUTTONDOWN; extern int SDL_USER_CECBUTTONUP; -CECInput* CECInput::sInstance = nullptr; - #if defined(HAVE_LIBCEC) static void onAlert(void* /*cbParam*/, const CEC::libcec_alert type, @@ -80,20 +78,6 @@ static void vchi_tv_and_cec_deinit() #endif // _RPI_ #endif // HAVE_LIBCEC -void CECInput::init() -{ - if (!sInstance) - sInstance = new CECInput(); -} - -void CECInput::deinit() -{ - if (sInstance) { - delete sInstance; - sInstance = nullptr; - } -} - CECInput::CECInput() : mlibCEC(nullptr) { diff --git a/es-core/src/CECInput.h b/es-core/src/CECInput.h index 216e849e0..fbfaf3e3e 100644 --- a/es-core/src/CECInput.h +++ b/es-core/src/CECInput.h @@ -19,18 +19,14 @@ namespace CEC class CECInput { public: - static void init(); - static void deinit(); + CECInput(); + ~CECInput(); + static std::string getAlertTypeString(const unsigned int _type); static std::string getOpCodeString(const unsigned int _opCode); static std::string getKeyCodeString(const unsigned int _keyCode); private: - CECInput(); - ~CECInput(); - - static CECInput* sInstance; - CEC::ICECAdapter* mlibCEC; }; diff --git a/es-core/src/HttpReq.cpp b/es-core/src/HttpReq.cpp index 9c4ba55d8..ee84cd8cd 100644 --- a/es-core/src/HttpReq.cpp +++ b/es-core/src/HttpReq.cpp @@ -70,7 +70,7 @@ HttpReq::HttpReq(const std::string& url) // these latter operating systems unless the bundled file is used. curl_easy_setopt(mHandle, CURLOPT_CAINFO, ResourceManager::getInstance() - ->getResourcePath(":/certificates/curl-ca-bundle.crt") + .getResourcePath(":/certificates/curl-ca-bundle.crt") .c_str()); #endif diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index e1514c065..c77162479 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -10,7 +10,6 @@ #include "InputManager.h" -#include "CECInput.h" #include "Log.h" #include "Platform.h" #include "Scripting.h" @@ -32,9 +31,7 @@ int SDL_USER_CECBUTTONUP = -1; static bool sAltDown = false; static bool sLguiDown = false; -InputManager* InputManager::sInstance = nullptr; - -InputManager::InputManager() +InputManager::InputManager() noexcept : mKeyboardInputConfig(nullptr) { } @@ -45,12 +42,10 @@ InputManager::~InputManager() deinit(); } -InputManager* InputManager::getInstance() +InputManager& InputManager::getInstance() { - if (!sInstance) - sInstance = new InputManager(); - - return sInstance; + static InputManager instance; + return instance; } void InputManager::init() @@ -94,7 +89,7 @@ void InputManager::init() Utils::FileSystem::getHomePath() + "/.emulationstation/" + "es_controller_mappings.cfg"; if (!Utils::FileSystem::exists(mappingsFile)) - mappingsFile = ResourceManager::getInstance()->getResourcePath( + mappingsFile = ResourceManager::getInstance().getResourcePath( ":/controllers/es_controller_mappings.cfg"); int controllerMappings = SDL_GameControllerAddMappingsFromFile(mappingsFile.c_str()); @@ -116,7 +111,6 @@ void InputManager::init() SDL_USER_CECBUTTONDOWN = SDL_RegisterEvents(2); SDL_USER_CECBUTTONUP = SDL_USER_CECBUTTONDOWN + 1; - CECInput::init(); mCECInputConfig = std::make_unique(DEVICE_CEC, "CEC", CEC_GUID_STRING); loadInputConfig(mCECInputConfig.get()); } @@ -138,15 +132,8 @@ void InputManager::deinit() mKeyboardInputConfig.reset(); mCECInputConfig.reset(); - CECInput::deinit(); - SDL_GameControllerEventState(SDL_DISABLE); SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); - - if (sInstance) { - delete sInstance; - sInstance = nullptr; - } } void InputManager::writeDeviceConfig(InputConfig* config) diff --git a/es-core/src/InputManager.h b/es-core/src/InputManager.h index f8a19710f..20a4aa507 100644 --- a/es-core/src/InputManager.h +++ b/es-core/src/InputManager.h @@ -11,6 +11,8 @@ #ifndef ES_CORE_INPUT_MANAGER_H #define ES_CORE_INPUT_MANAGER_H +#include "CECInput.h" + #include #include @@ -25,9 +27,7 @@ union SDL_Event; class InputManager { public: - InputManager(); - virtual ~InputManager(); - static InputManager* getInstance(); + static InputManager& getInstance(); void init(); void deinit(); @@ -50,6 +50,9 @@ public: int getNumJoysticks() { return static_cast(mJoysticks.size()); } private: + InputManager() noexcept; + virtual ~InputManager(); + bool initialized() const { return mKeyboardInputConfig != nullptr; } bool loadInputConfig(InputConfig* config); @@ -59,7 +62,8 @@ private: void addControllerByDeviceIndex(Window* window, int deviceIndex); void removeControllerByJoystickID(Window* window, SDL_JoystickID joyID); - static InputManager* sInstance; + CECInput mCECInput; + static const int DEADZONE_TRIGGERS = 18000; static const int DEADZONE_THUMBSTICKS = 23000; bool mConfigFileExists; diff --git a/es-core/src/MameNames.cpp b/es-core/src/MameNames.cpp index 7672b30a0..173b3a323 100644 --- a/es-core/src/MameNames.cpp +++ b/es-core/src/MameNames.cpp @@ -26,7 +26,7 @@ MameNames& MameNames::getInstance() MameNames::MameNames() { - std::string xmlpath = ResourceManager::getInstance()->getResourcePath(":/MAME/mamenames.xml"); + std::string xmlpath = ResourceManager::getInstance().getResourcePath(":/MAME/mamenames.xml"); if (!Utils::FileSystem::exists(xmlpath)) return; @@ -54,7 +54,7 @@ MameNames::MameNames() } // Read BIOS file. - xmlpath = ResourceManager::getInstance()->getResourcePath(":/MAME/mamebioses.xml"); + xmlpath = ResourceManager::getInstance().getResourcePath(":/MAME/mamebioses.xml"); if (!Utils::FileSystem::exists(xmlpath)) return; @@ -80,7 +80,7 @@ MameNames::MameNames() } // Read device file. - xmlpath = ResourceManager::getInstance()->getResourcePath(":/MAME/mamedevices.xml"); + xmlpath = ResourceManager::getInstance().getResourcePath(":/MAME/mamedevices.xml"); if (!Utils::FileSystem::exists(xmlpath)) return; diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index fba4bcf5a..e4c27169d 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -64,10 +64,10 @@ Settings::Settings() loadFile(); } -std::shared_ptr Settings::getInstance() +Settings* Settings::getInstance() { - static std::shared_ptr instance{new Settings()}; - return instance; + static Settings instance; + return &instance; } void Settings::setDefaults() diff --git a/es-core/src/Settings.h b/es-core/src/Settings.h index d32b63ba6..9ded6f693 100644 --- a/es-core/src/Settings.h +++ b/es-core/src/Settings.h @@ -18,7 +18,7 @@ class Settings { public: - static std::shared_ptr getInstance(); + static Settings* getInstance(); void loadFile(); void saveFile(); diff --git a/es-core/src/Sound.cpp b/es-core/src/Sound.cpp index 0ece4f5c1..b3bbbe292 100644 --- a/es-core/src/Sound.cpp +++ b/es-core/src/Sound.cpp @@ -36,7 +36,7 @@ std::shared_ptr Sound::getFromTheme(ThemeData* const theme, if (theme == nullptr) { LOG(LogDebug) << "Sound::getFromTheme(): Using fallback sound file for \"" << element << "\""; - return get(ResourceManager::getInstance()->getResourcePath(":/sounds/" + element + ".wav")); + return get(ResourceManager::getInstance().getResourcePath(":/sounds/" + element + ".wav")); } LOG(LogDebug) << "Sound::getFromTheme(): Looking for tag "; @@ -44,7 +44,7 @@ std::shared_ptr Sound::getFromTheme(ThemeData* const theme, const ThemeData::ThemeElement* elem = theme->getElement(view, element, "sound"); if (!elem || !elem->has("path")) { LOG(LogDebug) << "Sound::getFromTheme(): Tag not found, using fallback sound file"; - return get(ResourceManager::getInstance()->getResourcePath(":/sounds/" + element + ".wav")); + return get(ResourceManager::getInstance().getResourcePath(":/sounds/" + element + ".wav")); } LOG(LogDebug) << "Sound::getFromTheme(): Tag found, ready to load theme sound file"; diff --git a/es-core/src/Sound.h b/es-core/src/Sound.h index 30f52e804..a93cb84e2 100644 --- a/es-core/src/Sound.h +++ b/es-core/src/Sound.h @@ -77,6 +77,7 @@ public: bool isPlayingThemeNavigationSound(NavigationSoundsID soundID); private: + NavigationSounds() noexcept {}; std::vector> mNavigationSounds; }; diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index ceb93d03e..ee57b2bdc 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -321,7 +321,7 @@ void ThemeData::parseIncludes(const pugi::xml_node& root) for (pugi::xml_node node = root.child("include"); node; node = node.next_sibling("include")) { std::string relPath = resolvePlaceholders(node.text().as_string()); std::string path = Utils::FileSystem::resolveRelativePath(relPath, mPaths.back(), true); - if (!ResourceManager::getInstance()->fileExists(path)) + if (!ResourceManager::getInstance().fileExists(path)) throw error << " -> \"" << relPath << "\" not found (resolved to \"" << path << "\")"; error << " -> \"" << relPath << "\""; @@ -512,7 +512,7 @@ void ThemeData::parseElement(const pugi::xml_node& root, } case PATH: { std::string path = Utils::FileSystem::resolveRelativePath(str, mPaths.back(), true); - if (!ResourceManager::getInstance()->fileExists(path)) { + if (!ResourceManager::getInstance().fileExists(path)) { std::stringstream ss; // "From theme yadda yadda, included file yadda yadda. LOG(LogWarning) << error.msg << ":"; @@ -607,7 +607,7 @@ const ThemeData::ThemeElement* ThemeData::getElement(const std::string& view, return &elemIt->second; } -const std::shared_ptr& ThemeData::getDefault() +const std::shared_ptr ThemeData::getDefault() { static std::shared_ptr theme = nullptr; if (theme == nullptr) { diff --git a/es-core/src/ThemeData.h b/es-core/src/ThemeData.h index 416c0d433..9bca793c3 100644 --- a/es-core/src/ThemeData.h +++ b/es-core/src/ThemeData.h @@ -199,7 +199,7 @@ public: const std::string& view, Window* window); - static const std::shared_ptr& getDefault(); + static const std::shared_ptr getDefault(); static std::map getThemeSets(); static std::string getThemeFromCurrentSet(const std::string& system); diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 2e4140122..5823d012e 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -24,7 +24,7 @@ #define CLOCK_BACKGROUND_CREATION false #endif -Window::Window() +Window::Window() noexcept : mScreensaver(nullptr) , mMediaViewer(nullptr) , mLaunchScreen(nullptr) @@ -48,9 +48,6 @@ Window::Window() , mTopScale(0.5) , mChangedThemeSet(false) { - mHelp = new HelpComponent(this); - mBackgroundOverlay = new ImageComponent(this); - mBackgroundOverlayOpacity = 0; } Window::~Window() @@ -67,6 +64,12 @@ Window::~Window() delete mHelp; } +Window* Window::getInstance() +{ + static Window instance; + return &instance; +} + void Window::pushGui(GuiComponent* gui) { if (mGuiStack.size() > 0) { @@ -109,9 +112,13 @@ bool Window::init() return false; } - InputManager::getInstance()->init(); + InputManager::getInstance().init(); - ResourceManager::getInstance()->reloadAll(); + ResourceManager::getInstance().reloadAll(); + + mHelp = new HelpComponent(this); + mBackgroundOverlay = new ImageComponent(this); + mBackgroundOverlayOpacity = 0; // Keep a reference to the default fonts, so they don't keep getting destroyed/recreated. if (mDefaultFonts.empty()) { @@ -147,8 +154,8 @@ void Window::deinit() mPostprocessedBackground.reset(); #endif - InputManager::getInstance()->deinit(); - ResourceManager::getInstance()->unloadAll(); + InputManager::getInstance().deinit(); + ResourceManager::getInstance().unloadAll(); Renderer::deinit(); } diff --git a/es-core/src/Window.h b/es-core/src/Window.h index 3ed856449..73485ba35 100644 --- a/es-core/src/Window.h +++ b/es-core/src/Window.h @@ -75,8 +75,7 @@ public: virtual void render(const glm::mat4& parentTrans) = 0; }; - Window(); - ~Window(); + static Window* getInstance(); void pushGui(GuiComponent* gui); void removeGui(GuiComponent* gui); @@ -147,6 +146,9 @@ public: bool getChangedThemeSet() { return mChangedThemeSet; } private: + Window() noexcept; + ~Window(); + void onSleep() { Scripting::fireEvent("sleep"); } void onWake() { Scripting::fireEvent("wake"); } diff --git a/es-core/src/components/AnimatedImageComponent.cpp b/es-core/src/components/AnimatedImageComponent.cpp index 7d08e30ca..0cba2673c 100644 --- a/es-core/src/components/AnimatedImageComponent.cpp +++ b/es-core/src/components/AnimatedImageComponent.cpp @@ -26,7 +26,7 @@ void AnimatedImageComponent::load(const AnimationDef* def) for (size_t i = 0; i < def->frameCount; ++i) { if (def->frames[i].path != "" && - !ResourceManager::getInstance()->fileExists(def->frames[i].path)) { + !ResourceManager::getInstance().fileExists(def->frames[i].path)) { LOG(LogError) << "Missing animation frame " << i << " (\"" << def->frames[i].path << "\")"; continue; diff --git a/es-core/src/components/HelpComponent.cpp b/es-core/src/components/HelpComponent.cpp index 3581b2d72..533ccad1a 100644 --- a/es-core/src/components/HelpComponent.cpp +++ b/es-core/src/components/HelpComponent.cpp @@ -269,7 +269,7 @@ std::shared_ptr HelpComponent::getIconTexture(const char* name) return nullptr; } - if (!ResourceManager::getInstance()->fileExists(pathLookup->second)) { + if (!ResourceManager::getInstance().fileExists(pathLookup->second)) { LOG(LogError) << "Couldn't load help icon \"" << name << "\" as the file \"" << pathLookup->second << "\" is missing"; return nullptr; diff --git a/es-core/src/components/ImageComponent.cpp b/es-core/src/components/ImageComponent.cpp index ec1d090f0..de0c0015e 100644 --- a/es-core/src/components/ImageComponent.cpp +++ b/es-core/src/components/ImageComponent.cpp @@ -140,8 +140,8 @@ void ImageComponent::setImage(const std::string& path, bool tile, bool linearMag mDynamic = false; } - if (path.empty() || !ResourceManager::getInstance()->fileExists(path)) { - if (mDefaultPath.empty() || !ResourceManager::getInstance()->fileExists(mDefaultPath)) + if (path.empty() || !ResourceManager::getInstance().fileExists(path)) { + if (mDefaultPath.empty() || !ResourceManager::getInstance().fileExists(mDefaultPath)) mTexture.reset(); else mTexture = diff --git a/es-core/src/components/ImageGridComponent.h b/es-core/src/components/ImageGridComponent.h index ee5bf8df2..40da603d1 100644 --- a/es-core/src/components/ImageGridComponent.h +++ b/es-core/src/components/ImageGridComponent.h @@ -327,7 +327,7 @@ void ImageGridComponent::applyTheme(const std::shared_ptr& theme, if (elem->has("gameImage")) { std::string path = elem->get("gameImage"); - if (!ResourceManager::getInstance()->fileExists(path)) { + if (!ResourceManager::getInstance().fileExists(path)) { LOG(LogWarning) << "Could not replace default game image, check path: " << path; } else { @@ -346,7 +346,7 @@ void ImageGridComponent::applyTheme(const std::shared_ptr& theme, if (elem->has("folderImage")) { std::string path = elem->get("folderImage"); - if (!ResourceManager::getInstance()->fileExists(path)) { + if (!ResourceManager::getInstance().fileExists(path)) { LOG(LogWarning) << "Could not replace default folder image, check path: " << path; } else { @@ -658,7 +658,7 @@ void ImageGridComponent::updateTileAtPos(int tilePos, std::string imagePath = mEntries.at(imgPos).data.texturePath; - if (ResourceManager::getInstance()->fileExists(imagePath)) + if (ResourceManager::getInstance().fileExists(imagePath)) tile->setImage(imagePath); else if (mEntries.at(imgPos).object->getType() == 2) tile->setImage(mDefaultFolderTexture); diff --git a/es-core/src/components/VideoComponent.cpp b/es-core/src/components/VideoComponent.cpp index 5e42a92dc..6a3f7977f 100644 --- a/es-core/src/components/VideoComponent.cpp +++ b/es-core/src/components/VideoComponent.cpp @@ -69,7 +69,7 @@ bool VideoComponent::setVideo(std::string path) mVideoPath = fullPath; // If the file exists then set the new video. - if (!fullPath.empty() && ResourceManager::getInstance()->fileExists(fullPath)) { + if (!fullPath.empty() && ResourceManager::getInstance().fileExists(fullPath)) { // Return true to show that we are going to attempt to play a video. return true; } diff --git a/es-core/src/components/VideoFFmpegComponent.cpp b/es-core/src/components/VideoFFmpegComponent.cpp index 45c04c8bf..1359e9ffe 100644 --- a/es-core/src/components/VideoFFmpegComponent.cpp +++ b/es-core/src/components/VideoFFmpegComponent.cpp @@ -1412,7 +1412,8 @@ void VideoFFmpegComponent::stopVideo() std::queue().swap(mAudioFrameQueue); // Clear the audio buffer. - AudioManager::getInstance().clearStream(); + if (AudioManager::sAudioDevice != 0) + AudioManager::getInstance().clearStream(); if (mFormatContext) { av_frame_free(&mVideoFrame); diff --git a/es-core/src/guis/GuiDetectDevice.cpp b/es-core/src/guis/GuiDetectDevice.cpp index b2f4b51b0..8c5f91f2b 100644 --- a/es-core/src/guis/GuiDetectDevice.cpp +++ b/es-core/src/guis/GuiDetectDevice.cpp @@ -43,7 +43,7 @@ GuiDetectDevice::GuiDetectDevice(Window* window, // Device info. std::stringstream deviceInfo; - int numDevices = InputManager::getInstance()->getNumJoysticks(); + int numDevices = InputManager::getInstance().getNumJoysticks(); if (numDevices > 0) deviceInfo << numDevices << " GAMEPAD" << (numDevices > 1 ? "S" : "") << " DETECTED"; @@ -148,7 +148,7 @@ void GuiDetectDevice::update(int deltaTime) // command line. if (!mForcedConfig && mFirstRun && Utils::FileSystem::exists(InputManager::getConfigPath()) && - InputManager::getInstance()->getNumConfiguredDevices() > 0) { + InputManager::getInstance().getNumConfiguredDevices() > 0) { if (mDoneCallback) mDoneCallback(); delete this; // Delete GUI element. diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index c0f7d89d0..df0d39894 100644 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -174,7 +174,7 @@ GuiInputConfig::GuiInputConfig(Window* window, // GUI buttons. std::vector> buttons; std::function okFunction = [this, okCallback] { - InputManager::getInstance()->writeDeviceConfig(mTargetConfig); // Save. + InputManager::getInstance().writeDeviceConfig(mTargetConfig); // Save. if (okCallback) okCallback(); delete this; diff --git a/es-core/src/renderers/Renderer.cpp b/es-core/src/renderers/Renderer.cpp index ab0174f65..721045408 100644 --- a/es-core/src/renderers/Renderer.cpp +++ b/es-core/src/renderers/Renderer.cpp @@ -44,7 +44,7 @@ namespace Renderer size_t width = 0; size_t height = 0; ResourceData resData = - ResourceManager::getInstance()->getFileData(":/graphics/window_icon_256.png"); + ResourceManager::getInstance().getFileData(":/graphics/window_icon_256.png"); std::vector rawData = ImageIO::loadFromMemoryRGBA32(resData.ptr.get(), resData.length, width, height); diff --git a/es-core/src/renderers/Shader_GL21.cpp b/es-core/src/renderers/Shader_GL21.cpp index f6a17a1fd..1e670639c 100644 --- a/es-core/src/renderers/Shader_GL21.cpp +++ b/es-core/src/renderers/Shader_GL21.cpp @@ -40,7 +40,7 @@ namespace Renderer std::string shaderCode; // This will load the entire GLSL source code into the string variable. - const ResourceData& shaderData = ResourceManager::getInstance()->getFileData(path); + const ResourceData& shaderData = ResourceManager::getInstance().getFileData(path); shaderCode.assign(reinterpret_cast(shaderData.ptr.get()), shaderData.length); // Define the GLSL version (version 120 = OpenGL 2.1). diff --git a/es-core/src/resources/Font.cpp b/es-core/src/resources/Font.cpp index fcd92c88e..1469aa711 100644 --- a/es-core/src/resources/Font.cpp +++ b/es-core/src/resources/Font.cpp @@ -128,7 +128,7 @@ std::shared_ptr Font::get(int size, const std::string& path) std::shared_ptr font = std::shared_ptr(new Font(def.second, def.first)); sFontMap[def] = std::weak_ptr(font); - ResourceManager::getInstance()->addReloadable(font); + ResourceManager::getInstance().addReloadable(font); return font; } @@ -243,25 +243,25 @@ std::vector getFallbackFontPaths() // Standard fonts, let's include them here for exception handling purposes even though that's // not really the correct location. (The application will crash if they are missing.) - ResourceManager::getInstance()->getResourcePath(":/fonts/Akrobat-Regular.ttf"); - ResourceManager::getInstance()->getResourcePath(":/fonts/Akrobat-SemiBold.ttf"); - ResourceManager::getInstance()->getResourcePath(":/fonts/Akrobat-Bold.ttf"); + ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-Regular.ttf"); + ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-SemiBold.ttf"); + ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-Bold.ttf"); // Vera sans Unicode. - fontPaths.push_back(ResourceManager::getInstance()->getResourcePath(":/fonts/DejaVuSans.ttf")); + fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/DejaVuSans.ttf")); // GNU FreeFont monospaced. - fontPaths.push_back(ResourceManager::getInstance()->getResourcePath(":/fonts/FreeMono.ttf")); + fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/FreeMono.ttf")); // Various languages, such as Japanese and Chinese. fontPaths.push_back( - ResourceManager::getInstance()->getResourcePath(":/fonts/DroidSansFallbackFull.ttf")); + ResourceManager::getInstance().getResourcePath(":/fonts/DroidSansFallbackFull.ttf")); // Korean. fontPaths.push_back( - ResourceManager::getInstance()->getResourcePath(":/fonts/NanumMyeongjo.ttf")); + ResourceManager::getInstance().getResourcePath(":/fonts/NanumMyeongjo.ttf")); // Font Awesome icon glyphs, used for various special symbols like stars, folders etc. fontPaths.push_back( - ResourceManager::getInstance()->getResourcePath(":/fonts/fontawesome-webfont.ttf")); + ResourceManager::getInstance().getResourcePath(":/fonts/fontawesome-webfont.ttf")); // This is only needed for some really rare special characters. - fontPaths.push_back(ResourceManager::getInstance()->getResourcePath(":/fonts/Ubuntu-C.ttf")); + fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/Ubuntu-C.ttf")); fontPaths.shrink_to_fit(); return fontPaths; @@ -281,7 +281,7 @@ FT_Face Font::getFaceForChar(unsigned int id) // i == 0 -> mPath // Otherwise, take from fallbackFonts. const std::string& path = (i == 0 ? mPath : fallbackFonts.at(i - 1)); - ResourceData data = ResourceManager::getInstance()->getFileData(path); + ResourceData data = ResourceManager::getInstance().getFileData(path); mFaceCache[i] = std::unique_ptr(new FontFace(std::move(data), mSize)); fit = mFaceCache.find(i); } diff --git a/es-core/src/resources/Font.h b/es-core/src/resources/Font.h index 50e830d22..481283bbe 100644 --- a/es-core/src/resources/Font.h +++ b/es-core/src/resources/Font.h @@ -90,8 +90,8 @@ public: float getHeight(float lineSpacing = 1.5f) const; float getLetterHeight(); - void reload(std::shared_ptr& rm) override { rebuildTextures(); } - void unload(std::shared_ptr& rm) override { unloadTextures(); } + void reload(ResourceManager& rm) override { rebuildTextures(); } + void unload(ResourceManager& rm) override { unloadTextures(); } int getSize() const { return mSize; } const std::string& getPath() const { return mPath; } diff --git a/es-core/src/resources/ResourceManager.cpp b/es-core/src/resources/ResourceManager.cpp index 5c9ad07d7..9a10cc18b 100644 --- a/es-core/src/resources/ResourceManager.cpp +++ b/es-core/src/resources/ResourceManager.cpp @@ -19,14 +19,10 @@ auto array_deleter = [](unsigned char* p) { delete[] p; }; -std::shared_ptr ResourceManager::sInstance = nullptr; - -std::shared_ptr& ResourceManager::getInstance() +ResourceManager& ResourceManager::getInstance() { - if (!sInstance) - sInstance = std::shared_ptr(new ResourceManager()); - - return sInstance; + static ResourceManager instance; + return instance; } std::string ResourceManager::getResourcePath(const std::string& path, bool terminateOnFailure) const @@ -145,7 +141,7 @@ void ResourceManager::unloadAll() auto iter = mReloadables.cbegin(); while (iter != mReloadables.cend()) { if (!iter->expired()) { - iter->lock()->unload(sInstance); + iter->lock()->unload(getInstance()); ++iter; } else { @@ -159,7 +155,7 @@ void ResourceManager::reloadAll() auto iter = mReloadables.cbegin(); while (iter != mReloadables.cend()) { if (!iter->expired()) { - iter->lock()->reload(sInstance); + iter->lock()->reload(getInstance()); ++iter; } else { diff --git a/es-core/src/resources/ResourceManager.h b/es-core/src/resources/ResourceManager.h index e668bff99..1f41e864a 100644 --- a/es-core/src/resources/ResourceManager.h +++ b/es-core/src/resources/ResourceManager.h @@ -28,14 +28,14 @@ class ResourceManager; class IReloadable { public: - virtual void unload(std::shared_ptr& rm) = 0; - virtual void reload(std::shared_ptr& rm) = 0; + virtual void unload(ResourceManager& rm) = 0; + virtual void reload(ResourceManager& rm) = 0; }; class ResourceManager { public: - static std::shared_ptr& getInstance(); + static ResourceManager& getInstance(); void addReloadable(std::weak_ptr reloadable); @@ -47,9 +47,8 @@ public: bool fileExists(const std::string& path) const; private: - ResourceManager() {} + ResourceManager() noexcept {} - static std::shared_ptr sInstance; std::list> mReloadables; ResourceData loadFile(const std::string& path) const; diff --git a/es-core/src/resources/TextureData.cpp b/es-core/src/resources/TextureData.cpp index 25c5ce6b6..3cbe001cc 100644 --- a/es-core/src/resources/TextureData.cpp +++ b/es-core/src/resources/TextureData.cpp @@ -179,8 +179,7 @@ bool TextureData::load() // Need to load. See if there is a file. if (!mPath.empty()) { - std::shared_ptr& rm = ResourceManager::getInstance(); - const ResourceData& data = rm->getFileData(mPath); + const ResourceData& data = ResourceManager::getInstance().getFileData(mPath); // Is it an SVG? if (Utils::String::toLower(mPath.substr(mPath.size() - 4, std::string::npos)) == ".svg") { mScalable = true; diff --git a/es-core/src/resources/TextureResource.cpp b/es-core/src/resources/TextureResource.cpp index bee1ba5df..8b8666415 100644 --- a/es-core/src/resources/TextureResource.cpp +++ b/es-core/src/resources/TextureResource.cpp @@ -148,14 +148,12 @@ std::shared_ptr TextureResource::get(const std::string& path, bool linearMagnify, bool forceRasterization) { - std::shared_ptr& rm = ResourceManager::getInstance(); - const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path); if (canonicalPath.empty()) { std::shared_ptr tex( new TextureResource("", tile, false, linearMagnify, forceRasterization)); // Make sure we get properly deinitialized even though we do nothing on reinitialization. - rm->addReloadable(tex); + ResourceManager::getInstance().addReloadable(tex); return tex; } @@ -182,7 +180,7 @@ std::shared_ptr TextureResource::get(const std::string& path, } // Add it to the reloadable list. - rm->addReloadable(tex); + ResourceManager::getInstance().addReloadable(tex); // Force load it if necessary. Note that it may get dumped from VRAM if we run low. if (forceLoad) { @@ -241,7 +239,7 @@ size_t TextureResource::getTotalTextureSize() return total; } -void TextureResource::unload(std::shared_ptr& /*rm*/) +void TextureResource::unload(ResourceManager& /*rm*/) { // Release the texture's resources. std::shared_ptr data; @@ -254,7 +252,7 @@ void TextureResource::unload(std::shared_ptr& /*rm*/) data->releaseRAM(); } -void TextureResource::reload(std::shared_ptr& /*rm*/) +void TextureResource::reload(ResourceManager& /*rm*/) { // For dynamically loaded textures the texture manager will load them on demand. // For manually loaded textures we have to reload them here. diff --git a/es-core/src/resources/TextureResource.h b/es-core/src/resources/TextureResource.h index b9f5646d8..1e2c39432 100644 --- a/es-core/src/resources/TextureResource.h +++ b/es-core/src/resources/TextureResource.h @@ -68,8 +68,8 @@ protected: bool dynamic, bool linearMagnify, bool forceRasterization); - virtual void unload(std::shared_ptr& rm); - virtual void reload(std::shared_ptr& rm); + virtual void unload(ResourceManager& rm); + virtual void reload(ResourceManager& rm); private: // mTextureData is used for textures that are not loaded from a file - these ones