diff --git a/es-app/src/CollectionSystemsManager.cpp b/es-app/src/CollectionSystemsManager.cpp index 7f19be2d5..02d74d588 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[] = { @@ -92,8 +88,6 @@ CollectionSystemsManager::CollectionSystemsManager(Window* window) CollectionSystemsManager::~CollectionSystemsManager() { - assert(sInstance == this); - // Don't attempt to remove any collections if no systems exist. if (SystemData::sSystemVector.size() > 0) removeCollectionsFromDisplayedSystems(); @@ -114,25 +108,12 @@ CollectionSystemsManager::~CollectionSystemsManager() delete (*it).second.system; delete mCollectionEnvData; - sInstance = nullptr; } -CollectionSystemsManager* CollectionSystemsManager::get() +CollectionSystemsManager* CollectionSystemsManager::getInstance() { - assert(sInstance); - return sInstance; -} - -void CollectionSystemsManager::init(Window* window) -{ - assert(!sInstance); - sInstance = new CollectionSystemsManager(window); -} - -void CollectionSystemsManager::deinit() -{ - if (sInstance) - delete sInstance; + static CollectionSystemsManager instance; + return &instance; } void CollectionSystemsManager::saveCustomCollection(SystemData* sys) @@ -927,8 +908,8 @@ void CollectionSystemsManager::deleteCustomCollection(const std::string& collect 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(); diff --git a/es-app/src/CollectionSystemsManager.h b/es-app/src/CollectionSystemsManager.h index 48391a95a..8739f5cb5 100644 --- a/es-app/src/CollectionSystemsManager.h +++ b/es-app/src/CollectionSystemsManager.h @@ -72,12 +72,7 @@ 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); // Functions to load all collections into memory, and enable the active ones: @@ -137,7 +132,9 @@ public: const std::string& getEditingCollection() const { return mEditingCollection; } private: - static CollectionSystemsManager* sInstance; + CollectionSystemsManager() noexcept; + ~CollectionSystemsManager(); + 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..4a7ae35c2 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) { 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..9e3589664 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); diff --git a/es-app/src/SystemScreensaver.cpp b/es-app/src/SystemScreensaver.cpp index 619bb0595..09c6c69aa 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) 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/GuiCollectionSystemsOptions.cpp b/es-app/src/guis/GuiCollectionSystemsOptions.cpp index 6ada1030d..a25a8eb0b 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; @@ -399,5 +401,5 @@ void GuiCollectionSystemsOptions::createCustomCollection(std::string inName) Window* window = mWindow; while (window->peekGui() && window->peekGui() != ViewController::get()) delete window->peekGui(); - CollectionSystemsManager::get()->setEditMode(collectionName); + CollectionSystemsManager::getInstance()->setEditMode(collectionName); } diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index a4ed3289c..bd6bdf2eb 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); } @@ -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,7 +347,7 @@ 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 @@ -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; @@ -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,7 +442,7 @@ 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); + CollectionSystemsManager::getInstance()->deleteCollectionFiles(file); ViewController::get()->getGameListView(file->getSystem()).get()->removeMedia(file); ViewController::get()->getGameListView(file->getSystem()).get()->remove(file, true); mSystem->getRootFolder()->sort(*mListSort->getSelected(), mFavoritesSorting); @@ -551,7 +553,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)")); 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..e8981263a 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -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(); @@ -609,16 +609,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 diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 4a4107499..8bfbe7d50 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -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; @@ -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(); @@ -812,7 +813,7 @@ void GuiMetaDataEd::close() TextureResource::manualUnload(mScraperParams.game->getMarqueePath(), false); ViewController::get()->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(); diff --git a/es-app/src/guis/GuiScraperMulti.cpp b/es-app/src/guis/GuiScraperMulti.cpp index d755a06be..d68704138 100644 --- a/es-app/src/guis/GuiScraperMulti.cpp +++ b/es-app/src/guis/GuiScraperMulti.cpp @@ -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(); } diff --git a/es-app/src/guis/GuiSettings.cpp b/es-app/src/guis/GuiSettings.cpp index 7dc054878..d28578def 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) { diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 37e8d6d0b..ea5fc9684 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -528,24 +528,27 @@ 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::get(); + CollectionSystemsManager::getInstance(); + + SystemScreensaver screensaver; + MediaViewer mediaViewer; + GuiLaunchScreen guiLaunchScreen; + + if (!window->init()) { + LOG(LogError) << "Window failed to initialize"; + return 1; + } + + window->pushGui(ViewController::get()); 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 +574,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(); @@ -609,13 +612,13 @@ int main(int argc, char* argv[]) ViewController::get()->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::get()->goToStart(true); })); } else { ViewController::get()->goToStart(true); @@ -645,7 +648,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 +656,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 +672,17 @@ 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::get()) + delete window->peekGui(); + window->deinit(); - CollectionSystemsManager::deinit(); SystemData::deleteSystems(); NavigationSounds::getInstance().deinit(); diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index b3114702a..f52c67890 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")) diff --git a/es-app/src/views/UIModeController.cpp b/es-app/src/views/UIModeController.cpp index 632ebd03d..968405b4d 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,6 +29,12 @@ UIModeController::UIModeController() } } +UIModeController* UIModeController::getInstance() +{ + static UIModeController instance; + return &instance; +} + void UIModeController::monitorUIMode() { std::string uimode = Settings::getInstance()->getString("UIMode"); 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..295fb5978 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"); @@ -59,18 +57,12 @@ const std::string ViewController::TICKMARK_CHAR = "\uf14a"; ViewController* ViewController::get() { - 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..53eb3601c 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -29,11 +29,8 @@ class SystemView; class ViewController : public GuiComponent { public: - static void init(Window* window); static ViewController* get(); - virtual ~ViewController(); - // These functions are called from main(). void invalidSystemsFileDialog(); void noGamesDialog(); @@ -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..f3eee0f1f 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -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 @@ -323,7 +324,7 @@ std::vector BasicGameListView::getHelpPrompts() prompts.push_back(HelpPrompt("thumbstickclick", "random")); if (mRoot->getSystem()->getThemeFolder() == "custom-collections" && - !CollectionSystemsManager::get()->isEditing() && mCursorStack.empty() && + !CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() && ViewController::get()->getState().viewing == ViewController::GAME_LIST && ViewController::get()->getState().viewstyle != ViewController::BASIC) { prompts.push_back(HelpPrompt("y", "jump to game")); @@ -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..855ccec9a 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); diff --git a/es-app/src/views/gamelist/GridGameListView.cpp b/es-app/src/views/gamelist/GridGameListView.cpp index 338969f47..ac14451ca 100644 --- a/es-app/src/views/gamelist/GridGameListView.cpp +++ b/es-app/src/views/gamelist/GridGameListView.cpp @@ -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/ISimpleGameListView.cpp b/es-app/src/views/gamelist/ISimpleGameListView.cpp index e5a180531..6e52707dd 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.cpp +++ b/es-app/src/views/gamelist/ISimpleGameListView.cpp @@ -237,7 +237,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input) } else if (config->isMappedTo("y", input) && mRoot->getSystem()->getThemeFolder() == "custom-collections" && - !CollectionSystemsManager::get()->isEditing() && mCursorStack.empty() && + !CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() && ViewController::get()->getState().viewing == ViewController::GAME_LIST) { // Jump to the randomly selected game. if (mRandomGame) { @@ -262,21 +262,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 +293,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 @@ -439,7 +439,8 @@ 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. diff --git a/es-app/src/views/gamelist/VideoGameListView.cpp b/es-app/src/views/gamelist/VideoGameListView.cpp index e80f90691..c3b81ba4e 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); diff --git a/es-core/src/AudioManager.cpp b/es-core/src/AudioManager.cpp index e4004d04f..a0d539bd3 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(); 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/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/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..87a6a8594 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 << ":"; 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/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