Merge branch 'thread-safety-refactoring'

This commit is contained in:
Leon Styhre 2022-01-05 10:34:42 +01:00
commit 8644a414d8
73 changed files with 463 additions and 535 deletions

View file

@ -43,12 +43,8 @@ std::string myCollectionsName = "collections";
#define LAST_PLAYED_MAX 50 #define LAST_PLAYED_MAX 50
// Handles the getting, initialization, deinitialization, CollectionSystemsManager::CollectionSystemsManager() noexcept
// saving and deletion of a CollectionSystemsManager instance. : mWindow(Window::getInstance())
CollectionSystemsManager* CollectionSystemsManager::sInstance = nullptr;
CollectionSystemsManager::CollectionSystemsManager(Window* window)
: mWindow(window)
{ {
// clang-format off // clang-format off
CollectionSystemDecl systemDecls[] = { CollectionSystemDecl systemDecls[] = {
@ -90,49 +86,35 @@ CollectionSystemsManager::CollectionSystemsManager(Window* window)
mCustomCollectionsBundle = nullptr; mCustomCollectionsBundle = nullptr;
} }
CollectionSystemsManager::~CollectionSystemsManager() CollectionSystemsManager* CollectionSystemsManager::getInstance()
{ {
assert(sInstance == this); static CollectionSystemsManager instance;
return &instance;
// Don't attempt to remove any collections if no systems exist.
if (SystemData::sSystemVector.size() > 0)
removeCollectionsFromDisplayedSystems();
// Delete all custom collections.
for (std::map<std::string, CollectionSystemData, stringComparator>::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);
} }
void CollectionSystemsManager::deinit() void CollectionSystemsManager::deinit()
{ {
if (sInstance) // Don't attempt to remove any collections if no systems exist.
delete sInstance; if (SystemData::sSystemVector.size() > 0) {
removeCollectionsFromDisplayedSystems();
// Delete all custom collections.
for (std::map<std::string, CollectionSystemData, stringComparator>::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) void CollectionSystemsManager::saveCustomCollection(SystemData* sys)
@ -283,7 +265,7 @@ void CollectionSystemsManager::updateSystemsList()
for (auto sysIt = SystemData::sSystemVector.cbegin(); // Line break. for (auto sysIt = SystemData::sSystemVector.cbegin(); // Line break.
sysIt != SystemData::sSystemVector.cend(); ++sysIt) { sysIt != SystemData::sSystemVector.cend(); ++sysIt) {
if ((*sysIt)->isCollection()) 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. // 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. // Found it, and we are removing it.
if (name == "favorites" && file->metadata.get("favorite") == "false") { if (name == "favorites" && file->metadata.get("favorite") == "false") {
// Need to check if it is still marked as favorite, if not remove it. // Need to check if it is still marked as favorite, if not remove it.
ViewController::get()->getGameListView(curSys).get()->remove(collectionEntry, ViewController::getInstance()->getGameListView(curSys).get()->remove(
false); collectionEntry, false);
} }
else if (name == "recent" && file->metadata.get("lastplayed") == "0") { else if (name == "recent" && file->metadata.get("lastplayed") == "0") {
// If lastplayed is set to 0 it means the entry has been cleared, and the // If lastplayed is set to 0 it means the entry has been cleared, and the
// game should therefore be removed. // game should therefore be removed.
ViewController::get()->getGameListView(curSys).get()->remove(collectionEntry, ViewController::getInstance()->getGameListView(curSys).get()->remove(
false); collectionEntry, false);
ViewController::get()->onFileChanged(rootFolder, true); ViewController::getInstance()->onFileChanged(rootFolder, true);
} }
else if (curSys->isCollection() && !file->getCountAsGame()) { else if (curSys->isCollection() && !file->getCountAsGame()) {
// If the countasgame flag has been set to false, then remove the game. // If the countasgame flag has been set to false, then remove the game.
if (curSys->isGroupedCustomCollection()) { if (curSys->isGroupedCustomCollection()) {
ViewController::get() ViewController::getInstance()
->getGameListView(curSys->getRootFolder()->getParent()->getSystem()) ->getGameListView(curSys->getRootFolder()->getParent()->getSystem())
.get() .get()
->remove(collectionEntry, false); ->remove(collectionEntry, false);
@ -393,8 +375,8 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection
4000); 4000);
} }
else { else {
ViewController::get()->getGameListView(curSys).get()->remove(collectionEntry, ViewController::getInstance()->getGameListView(curSys).get()->remove(
false); collectionEntry, false);
} }
rootFolder->sort(rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()), rootFolder->sort(rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()),
mFavoritesSorting); mFavoritesSorting);
@ -402,7 +384,7 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection
else { else {
// Re-index with new metadata. // Re-index with new metadata.
fileIndex->addToIndex(collectionEntry); fileIndex->addToIndex(collectionEntry);
ViewController::get()->onFileChanged(collectionEntry, true); ViewController::getInstance()->onFileChanged(collectionEntry, true);
} }
} }
else { else {
@ -421,7 +403,8 @@ void CollectionSystemsManager::updateCollectionSystem(FileData* file, Collection
CollectionFileData* newGame = new CollectionFileData(file, curSys); CollectionFileData* newGame = new CollectionFileData(file, curSys);
rootFolder->addChild(newGame); rootFolder->addChild(newGame);
fileIndex->addToIndex(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") { if (name == "recent") {
trimCollectionCount(rootFolder, LAST_PLAYED_MAX); 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 // 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 // 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 // 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(); auto nTime = Utils::Time::now();
if (nTime - Utils::Time::stringToTime(file->metadata.get("lastplayed")) < 2) { if (nTime - Utils::Time::stringToTime(file->metadata.get("lastplayed")) < 2) {
// Select the first row of the gamelist (the game just played). // Select the first row of the gamelist (the game just played).
IGameListView* gameList = IGameListView* gameList = ViewController::getInstance()
ViewController::get()->getGameListView(getSystemToView(sysData.system)).get(); ->getGameListView(getSystemToView(sysData.system))
.get();
gameList->setCursor(gameList->getFirstEntry()); gameList->setCursor(gameList->getFirstEntry());
} }
} }
else { else {
ViewController::get()->onFileChanged(rootFolder, true); ViewController::getInstance()->onFileChanged(rootFolder, true);
// For custom collections, update either the actual system or its parent depending // For custom collections, update either the actual system or its parent depending
// on whether the collection is grouped or not. // on whether the collection is grouped or not.
if (sysData.decl.isCustom) { if (sysData.decl.isCustom) {
if (rootFolder->getSystem()->isGroupedCustomCollection()) if (rootFolder->getSystem()->isGroupedCustomCollection())
ViewController::get()->onFileChanged(rootFolder->getParent(), true); ViewController::getInstance()->onFileChanged(rootFolder->getParent(), true);
else else
ViewController::get()->onFileChanged(rootFolder, true); ViewController::getInstance()->onFileChanged(rootFolder, true);
} }
} }
} }
@ -505,7 +489,7 @@ void CollectionSystemsManager::deleteCollectionFiles(FileData* file)
if (found) { if (found) {
FileData* collectionEntry = children.at(key); FileData* collectionEntry = children.at(key);
SystemData* systemViewToUpdate = getSystemToView(sysDataIt->second.system); SystemData* systemViewToUpdate = getSystemToView(sysDataIt->second.system);
ViewController::get() ViewController::getInstance()
->getGameListView(systemViewToUpdate) ->getGameListView(systemViewToUpdate)
.get() .get()
->remove(collectionEntry, false); ->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. // Remove all tick marks from the games that are part of the collection.
for (auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it) { for (auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it) {
ViewController::get()->getGameListView((*it))->onFileChanged( ViewController::getInstance()->getGameListView((*it))->onFileChanged(
ViewController::get()->getGameListView((*it))->getCursor(), false); ViewController::getInstance()->getGameListView((*it))->getCursor(), false);
} }
mEditingCollectionSystemData->system->onMetaDataSavePoint(); mEditingCollectionSystemData->system->onMetaDataSavePoint();
@ -686,14 +670,14 @@ const bool CollectionSystemsManager::toggleGameInCollection(FileData* file)
// If we found it, we need to remove it. // If we found it, we need to remove it.
FileData* collectionEntry = children.at(key); FileData* collectionEntry = children.at(key);
fileIndex->removeFromIndex(collectionEntry); fileIndex->removeFromIndex(collectionEntry);
ViewController::get() ViewController::getInstance()
->getGameListView(systemViewToUpdate) ->getGameListView(systemViewToUpdate)
.get() .get()
->remove(collectionEntry, false); ->remove(collectionEntry, false);
systemViewToUpdate->getRootFolder()->sort( systemViewToUpdate->getRootFolder()->sort(
rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()), rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()),
Settings::getInstance()->getBool("FavFirstCustom")); Settings::getInstance()->getBool("FavFirstCustom"));
ViewController::get()->reloadGameListView(systemViewToUpdate); ViewController::getInstance()->reloadGameListView(systemViewToUpdate);
updateCollectionFolderMetadata(systemViewToUpdate); updateCollectionFolderMetadata(systemViewToUpdate);
} }
@ -705,7 +689,8 @@ const bool CollectionSystemsManager::toggleGameInCollection(FileData* file)
systemViewToUpdate->getRootFolder()->sort( systemViewToUpdate->getRootFolder()->sort(
rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()), rootFolder->getSortTypeFromString(rootFolder->getSortTypeString()),
Settings::getInstance()->getBool("FavFirstCustom")); Settings::getInstance()->getBool("FavFirstCustom"));
ViewController::get()->onFileChanged(systemViewToUpdate->getRootFolder(), true); ViewController::getInstance()->onFileChanged(systemViewToUpdate->getRootFolder(),
true);
fileIndex->addToIndex(newGame); fileIndex->addToIndex(newGame);
// Add to bundle index as well, if needed. // Add to bundle index as well, if needed.
@ -732,7 +717,7 @@ const bool CollectionSystemsManager::toggleGameInCollection(FileData* file)
file->getSourceFileData()->getSystem()->onMetaDataSavePoint(); file->getSourceFileData()->getSystem()->onMetaDataSavePoint();
refreshCollectionSystems(file->getSourceFileData()); refreshCollectionSystems(file->getSourceFileData());
if (mAutoCollectionSystemsData["favorites"].isEnabled) if (mAutoCollectionSystemsData["favorites"].isEnabled)
ViewController::get()->reloadGameListView( ViewController::getInstance()->reloadGameListView(
mAutoCollectionSystemsData["favorites"].system); mAutoCollectionSystemsData["favorites"].system);
} }
if (adding) { 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 // 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 // (where the custom collection deletions are initiated), as there seems to be some random
// issue with accessing mWindow via the lambda expression. // 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(); delete mWindow->peekGui();
if (collectionEntry != mCustomCollectionSystemsData.end()) { if (collectionEntry != mCustomCollectionSystemsData.end()) {
CollectionSystemsManager::get()->loadEnabledListFromSettings(); CollectionSystemsManager::getInstance()->loadEnabledListFromSettings();
CollectionSystemsManager::get()->updateSystemsList(); CollectionSystemsManager::getInstance()->updateSystemsList();
ViewController::get()->removeGameListView(collectionEntry->second.system); ViewController::getInstance()->removeGameListView(collectionEntry->second.system);
ViewController::get()->reloadAll(); ViewController::getInstance()->reloadAll();
delete collectionEntry->second.system; delete collectionEntry->second.system;
mCustomCollectionSystemsData.erase(collectionName); 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 // 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 // and then point to this, and for collections with games in them we select the first
// entry. // entry.
auto autoView = ViewController::get()->getGameListView(autoSystem->system).get(); auto autoView =
ViewController::getInstance()->getGameListView(autoSystem->system).get();
if (autoSystem->system->getRootFolder()->getChildren().size() == 0) { if (autoSystem->system->getRootFolder()->getChildren().size() == 0) {
autoView->addPlaceholder(autoSystem->system->getRootFolder()); autoView->addPlaceholder(autoSystem->system->getRootFolder());
autoView->setCursor(autoView->getLastEntry()); autoView->setCursor(autoView->getLastEntry());
@ -1054,7 +1040,8 @@ void CollectionSystemsManager::repopulateCollection(SystemData* sysData)
customSystem->isPopulated = false; customSystem->isPopulated = false;
populateCustomCollection(customSystem); populateCustomCollection(customSystem);
auto autoView = ViewController::get()->getGameListView(customSystem->system).get(); auto autoView =
ViewController::getInstance()->getGameListView(customSystem->system).get();
autoView->setCursor( autoView->setCursor(
customSystem->system->getRootFolder()->getChildrenRecursive().front()); customSystem->system->getRootFolder()->getChildrenRecursive().front());
autoView->setCursor(autoView->getFirstEntry()); autoView->setCursor(autoView->getFirstEntry());
@ -1173,12 +1160,13 @@ void CollectionSystemsManager::populateAutoCollection(CollectionSystemData* sysD
if (rootFolder->getName() == "recent" && !rootFolder->getChildrenRecursive().empty()) { if (rootFolder->getName() == "recent" && !rootFolder->getChildrenRecursive().empty()) {
// The following is needed to avoid a crash when repopulating the system as the previous // The following is needed to avoid a crash when repopulating the system as the previous
// cursor pointer may point to a random memory address. // 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( recentGamelist->setCursor(
rootFolder->getSystem()->getRootFolder()->getChildrenRecursive().front()); rootFolder->getSystem()->getRootFolder()->getChildrenRecursive().front());
recentGamelist->setCursor(recentGamelist->getFirstEntry()); recentGamelist->setCursor(recentGamelist->getFirstEntry());
if (rootFolder->getChildren().size() > 0) if (rootFolder->getChildren().size() > 0)
ViewController::get() ViewController::getInstance()
->getGameListView(rootFolder->getSystem()) ->getGameListView(rootFolder->getSystem())
.get() .get()
->onFileChanged(rootFolder->getChildren().front(), false); ->onFileChanged(rootFolder->getChildren().front(), false);
@ -1267,7 +1255,7 @@ void CollectionSystemsManager::removeCollectionsFromDisplayedSystems()
// Clear index. // Clear index.
mCustomCollectionsBundle->getIndex()->resetIndex(); mCustomCollectionsBundle->getIndex()->resetIndex();
// Remove view so it's re-created as needed. // Remove view so it's re-created as needed.
ViewController::get()->removeGameListView(mCustomCollectionsBundle); ViewController::getInstance()->removeGameListView(mCustomCollectionsBundle);
} }
void CollectionSystemsManager::addEnabledCollectionsToDisplayedSystems( void CollectionSystemsManager::addEnabledCollectionsToDisplayedSystems(
@ -1299,7 +1287,7 @@ void CollectionSystemsManager::addEnabledCollectionsToDisplayedSystems(
Settings::getInstance()->getBool("FavFirstCustom")); Settings::getInstance()->getBool("FavFirstCustom"));
// Jump to the first row of the game list, assuming it's not empty. // Jump to the first row of the game list, assuming it's not empty.
IGameListView* gameList = IGameListView* gameList =
ViewController::get()->getGameListView((it->second.system)).get(); ViewController::getInstance()->getGameListView((it->second.system)).get();
if (!gameList->getCursor()->isPlaceHolder()) { if (!gameList->getCursor()->isPlaceHolder()) {
gameList->setCursor(gameList->getFirstEntry()); gameList->setCursor(gameList->getFirstEntry());
} }
@ -1453,7 +1441,7 @@ void CollectionSystemsManager::trimCollectionCount(FileData* rootFolder, int lim
while (static_cast<int>(rootFolder->getChildrenListToDisplay().size()) > limit) { while (static_cast<int>(rootFolder->getChildrenListToDisplay().size()) > limit) {
CollectionFileData* gameToRemove = CollectionFileData* gameToRemove =
(CollectionFileData*)rootFolder->getChildrenListToDisplay().back(); (CollectionFileData*)rootFolder->getChildrenListToDisplay().back();
ViewController::get()->getGameListView(curSys).get()->remove(gameToRemove, false); ViewController::getInstance()->getGameListView(curSys).get()->remove(gameToRemove, false);
} }
} }

View file

@ -72,14 +72,12 @@ struct stringComparator {
class CollectionSystemsManager class CollectionSystemsManager
{ {
public: public:
CollectionSystemsManager(Window* window); static CollectionSystemsManager* getInstance();
~CollectionSystemsManager();
static CollectionSystemsManager* get();
static void init(Window* window);
static void deinit();
void saveCustomCollection(SystemData* sys); 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: // Functions to load all collections into memory, and enable the active ones:
// Load all collection systems. // Load all collection systems.
void loadCollectionSystems(); void loadCollectionSystems();
@ -137,7 +135,8 @@ public:
const std::string& getEditingCollection() const { return mEditingCollection; } const std::string& getEditingCollection() const { return mEditingCollection; }
private: private:
static CollectionSystemsManager* sInstance; CollectionSystemsManager() noexcept;
SystemEnvironmentData* mCollectionEnvData; SystemEnvironmentData* mCollectionEnvData;
std::map<std::string, CollectionSystemDecl, stringComparator> mCollectionSystemDeclsIndex; std::map<std::string, CollectionSystemDecl, stringComparator> mCollectionSystemDeclsIndex;
std::map<std::string, CollectionSystemData, stringComparator> mAutoCollectionSystemsData; std::map<std::string, CollectionSystemData, stringComparator> mAutoCollectionSystemsData;

View file

@ -1166,7 +1166,7 @@ void FileData::launchGame(Window* window)
gameToUpdate->metadata.get("lastplayed")); gameToUpdate->metadata.get("lastplayed"));
} }
CollectionSystemsManager::get()->refreshCollectionSystems(gameToUpdate); CollectionSystemsManager::getInstance()->refreshCollectionSystems(gameToUpdate);
gameToUpdate->mSystem->onMetaDataSavePoint(); gameToUpdate->mSystem->onMetaDataSavePoint();
} }

View file

@ -12,8 +12,8 @@
#include "components/VideoFFmpegComponent.h" #include "components/VideoFFmpegComponent.h"
#include "views/ViewController.h" #include "views/ViewController.h"
MediaViewer::MediaViewer(Window* window) MediaViewer::MediaViewer()
: mWindow(window) : mWindow(Window::getInstance())
, mVideo(nullptr) , mVideo(nullptr)
, mImage(nullptr) , mImage(nullptr)
{ {
@ -45,7 +45,7 @@ bool MediaViewer::startMediaViewer(FileData* game)
initiateViewer(); initiateViewer();
if (mHasVideo) if (mHasVideo)
ViewController::get()->onPauseVideo(); ViewController::getInstance()->onPauseVideo();
if (mHasVideo || mHasImages) if (mHasVideo || mHasImages)
return true; return true;
@ -56,7 +56,7 @@ bool MediaViewer::startMediaViewer(FileData* game)
void MediaViewer::stopMediaViewer() void MediaViewer::stopMediaViewer()
{ {
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND); NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
ViewController::get()->onStopVideo(); ViewController::getInstance()->onStopVideo();
if (mVideo) { if (mVideo) {
delete mVideo; delete mVideo;
@ -255,7 +255,7 @@ void MediaViewer::playVideo()
return; return;
mDisplayingImage = false; mDisplayingImage = false;
ViewController::get()->onStopVideo(); ViewController::getInstance()->onStopVideo();
mVideo = new VideoFFmpegComponent(mWindow); mVideo = new VideoFFmpegComponent(mWindow);
mVideo->topWindow(true); mVideo->topWindow(true);

View file

@ -17,7 +17,7 @@
class MediaViewer : public Window::MediaViewer class MediaViewer : public Window::MediaViewer
{ {
public: public:
MediaViewer(Window* window); MediaViewer();
virtual ~MediaViewer(); virtual ~MediaViewer();
virtual bool startMediaViewer(FileData* game) override; virtual bool startMediaViewer(FileData* game) override;

View file

@ -51,14 +51,14 @@ void FindRules::loadFindRules()
} }
else { else {
#if defined(_WIN64) #if defined(_WIN64)
path = ResourceManager::getInstance()->getResourcePath( path = ResourceManager::getInstance().getResourcePath(":/systems/windows/es_find_rules.xml",
":/systems/windows/es_find_rules.xml", false); false);
#elif defined(__APPLE__) #elif defined(__APPLE__)
path = ResourceManager::getInstance()->getResourcePath(":/systems/macos/es_find_rules.xml", path = ResourceManager::getInstance().getResourcePath(":/systems/macos/es_find_rules.xml",
false); false);
#else #else
path = ResourceManager::getInstance()->getResourcePath(":/systems/unix/es_find_rules.xml", path = ResourceManager::getInstance().getResourcePath(":/systems/unix/es_find_rules.xml",
false); false);
#endif #endif
} }
@ -659,7 +659,7 @@ bool SystemData::loadConfig()
// Don't load any collections if there are no systems available. // Don't load any collections if there are no systems available.
if (sSystemVector.size() > 0) if (sSystemVector.size() > 0)
CollectionSystemsManager::get()->loadCollectionSystems(); CollectionSystemsManager::getInstance()->loadCollectionSystems();
return false; return false;
} }
@ -718,12 +718,11 @@ std::vector<std::string> SystemData::getConfigPath(bool legacyWarning)
} }
#if defined(_WIN64) #if defined(_WIN64)
path = path = ResourceManager::getInstance().getResourcePath(":/systems/windows/es_systems.xml", true);
ResourceManager::getInstance()->getResourcePath(":/systems/windows/es_systems.xml", true);
#elif defined(__APPLE__) #elif defined(__APPLE__)
path = ResourceManager::getInstance()->getResourcePath(":/systems/macos/es_systems.xml", true); path = ResourceManager::getInstance().getResourcePath(":/systems/macos/es_systems.xml", true);
#else #else
path = ResourceManager::getInstance()->getResourcePath(":/systems/unix/es_systems.xml", true); path = ResourceManager::getInstance().getResourcePath(":/systems/unix/es_systems.xml", true);
#endif #endif
paths.push_back(path); paths.push_back(path);
@ -1128,7 +1127,7 @@ FileData* SystemData::getRandomGame(const FileData* currentGame)
gameList = mRootFolder->getParent()->getChildrenListToDisplay(); gameList = mRootFolder->getParent()->getChildrenListToDisplay();
} }
else { else {
gameList = ViewController::get() gameList = ViewController::getInstance()
->getGameListView(mRootFolder->getSystem()) ->getGameListView(mRootFolder->getSystem())
.get() .get()
->getCursor() ->getCursor()
@ -1211,10 +1210,10 @@ void SystemData::sortSystem(bool reloadGamelist, bool jumpToFirstRow)
favoritesSorting); favoritesSorting);
if (reloadGamelist) if (reloadGamelist)
ViewController::get()->reloadGameListView(this, false); ViewController::getInstance()->reloadGameListView(this, false);
if (jumpToFirstRow) { if (jumpToFirstRow) {
IGameListView* gameList = ViewController::get()->getGameListView(this).get(); IGameListView* gameList = ViewController::getInstance()->getGameListView(this).get();
gameList->setCursor(gameList->getFirstEntry()); gameList->setCursor(gameList->getFirstEntry());
} }
} }

View file

@ -91,7 +91,7 @@ public:
mEnvData->mPlatformIds.cend(); mEnvData->mPlatformIds.cend();
} }
const std::shared_ptr<ThemeData>& getTheme() const { return mTheme; } const std::shared_ptr<ThemeData> getTheme() const { return mTheme; }
std::string getGamelistPath(bool forWrite) const; std::string getGamelistPath(bool forWrite) const;
std::string getThemePath() const; std::string getThemePath() const;

View file

@ -29,8 +29,8 @@
#define FADE_TIME 300 #define FADE_TIME 300
SystemScreensaver::SystemScreensaver(Window* window) SystemScreensaver::SystemScreensaver()
: mWindow(window) : mWindow(Window::getInstance())
, mState(STATE_INACTIVE) , mState(STATE_INACTIVE)
, mImageScreensaver(nullptr) , mImageScreensaver(nullptr)
, mVideoScreensaver(nullptr) , mVideoScreensaver(nullptr)
@ -209,12 +209,12 @@ void SystemScreensaver::launchGame()
{ {
if (mCurrentGame != nullptr) { if (mCurrentGame != nullptr) {
// Launching game // Launching game
ViewController::get()->triggerGameLaunch(mCurrentGame); ViewController::getInstance()->triggerGameLaunch(mCurrentGame);
ViewController::get()->goToGameList(mCurrentGame->getSystem()); ViewController::getInstance()->goToGameList(mCurrentGame->getSystem());
IGameListView* view = IGameListView* view =
ViewController::get()->getGameListView(mCurrentGame->getSystem()).get(); ViewController::getInstance()->getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame); view->setCursor(mCurrentGame);
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
} }
} }
@ -222,11 +222,11 @@ void SystemScreensaver::goToGame()
{ {
if (mCurrentGame != nullptr) { if (mCurrentGame != nullptr) {
// Go to the game in the gamelist view, but don't launch it. // 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 = IGameListView* view =
ViewController::get()->getGameListView(mCurrentGame->getSystem()).get(); ViewController::getInstance()->getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame); view->setCursor(mCurrentGame);
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
} }
} }

View file

@ -19,7 +19,7 @@ class VideoComponent;
class SystemScreensaver : public Window::Screensaver class SystemScreensaver : public Window::Screensaver
{ {
public: public:
SystemScreensaver(Window* window); SystemScreensaver();
virtual ~SystemScreensaver(); virtual ~SystemScreensaver();
virtual bool allowSleep() virtual bool allowSleep()

View file

@ -20,8 +20,6 @@ std::string VolumeControl::mixerName = "Master";
std::string VolumeControl::mixerCard = "default"; std::string VolumeControl::mixerCard = "default";
#endif #endif
VolumeControl* VolumeControl::sInstance = nullptr;
VolumeControl::VolumeControl() VolumeControl::VolumeControl()
#if defined(__linux__) #if defined(__linux__)
: mixerIndex(0) : mixerIndex(0)
@ -44,23 +42,6 @@ VolumeControl::~VolumeControl()
#endif #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() void VolumeControl::init()
{ {
// Initialize audio mixer interface. // Initialize audio mixer interface.

View file

@ -27,17 +27,12 @@ public:
VolumeControl(); VolumeControl();
~VolumeControl(); ~VolumeControl();
static VolumeControl* getInstance();
void deleteInstance();
void init(); void init();
void deinit(); void deinit();
int getVolume() const; int getVolume() const;
void setVolume(int volume); void setVolume(int volume);
static VolumeControl* sInstance;
#if defined(__linux__) #if defined(__linux__)
static std::string mixerName; static std::string mixerName;
static std::string mixerCard; static std::string mixerCard;

View file

@ -252,6 +252,6 @@ std::vector<HelpPrompt> GuiAlternativeEmulators::getHelpPrompts()
HelpStyle GuiAlternativeEmulators::getHelpStyle() HelpStyle GuiAlternativeEmulators::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -25,18 +25,19 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
, mDeletedCustomCollection(false) , mDeletedCustomCollection(false)
{ {
// Finish editing custom collection. // Finish editing custom collection.
if (CollectionSystemsManager::get()->isEditing()) { if (CollectionSystemsManager::getInstance()->isEditing()) {
ComponentListRow row; ComponentListRow row;
row.addElement(std::make_shared<TextComponent>( row.addElement(
mWindow, std::make_shared<TextComponent>(
"FINISH EDITING '" + mWindow,
Utils::String::toUpper( "FINISH EDITING '" +
CollectionSystemsManager::get()->getEditingCollection()) + Utils::String::toUpper(
"' COLLECTION", CollectionSystemsManager::getInstance()->getEditingCollection()) +
Font::get(FONT_SIZE_MEDIUM), 0x777777FF), "' COLLECTION",
true); Font::get(FONT_SIZE_MEDIUM), 0x777777FF),
true);
row.makeAcceptInputHandler([this] { row.makeAcceptInputHandler([this] {
CollectionSystemsManager::get()->exitEditMode(); CollectionSystemsManager::getInstance()->exitEditMode();
mWindow->invalidateCachedBackground(); mWindow->invalidateCachedBackground();
delete this; delete this;
}); });
@ -47,7 +48,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
collection_systems_auto = std::make_shared<OptionListComponent<std::string>>( collection_systems_auto = std::make_shared<OptionListComponent<std::string>>(
mWindow, getHelpStyle(), "SELECT COLLECTIONS", true); mWindow, getHelpStyle(), "SELECT COLLECTIONS", true);
std::map<std::string, CollectionSystemData, stringComparator> autoSystems = std::map<std::string, CollectionSystemData, stringComparator> autoSystems =
CollectionSystemsManager::get()->getAutoCollectionSystems(); CollectionSystemsManager::getInstance()->getAutoCollectionSystems();
// Add automatic systems. // Add automatic systems.
for (std::map<std::string, CollectionSystemData, stringComparator>::const_iterator it = for (std::map<std::string, CollectionSystemData, stringComparator>::const_iterator it =
autoSystems.cbegin(); autoSystems.cbegin();
@ -60,8 +61,8 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
collection_systems_auto->getSelectedObjects(), ",", true); collection_systems_auto->getSelectedObjects(), ",", true);
std::string autoSystemsConfig = Settings::getInstance()->getString("CollectionSystemsAuto"); std::string autoSystemsConfig = Settings::getInstance()->getString("CollectionSystemsAuto");
if (autoSystemsSelected != autoSystemsConfig) { if (autoSystemsSelected != autoSystemsConfig) {
if (CollectionSystemsManager::get()->isEditing()) if (CollectionSystemsManager::getInstance()->isEditing())
CollectionSystemsManager::get()->exitEditMode(); CollectionSystemsManager::getInstance()->exitEditMode();
Settings::getInstance()->setString("CollectionSystemsAuto", autoSystemsSelected); Settings::getInstance()->setString("CollectionSystemsAuto", autoSystemsSelected);
// Check if any systems have been enabled, and if so repopulate them, which results in // 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 // 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()) { if (!addedAutoSystems.empty()) {
for (std::string system : addedAutoSystems) for (std::string system : addedAutoSystems)
CollectionSystemsManager::get()->repopulateCollection( CollectionSystemsManager::getInstance()->repopulateCollection(
autoSystems.find(system)->second.system); autoSystems.find(system)->second.system);
} }
setNeedsSaving(); setNeedsSaving();
@ -96,7 +97,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
collection_systems_custom = std::make_shared<OptionListComponent<std::string>>( collection_systems_custom = std::make_shared<OptionListComponent<std::string>>(
mWindow, getHelpStyle(), "SELECT COLLECTIONS", true); mWindow, getHelpStyle(), "SELECT COLLECTIONS", true);
std::map<std::string, CollectionSystemData, stringComparator> customSystems = std::map<std::string, CollectionSystemData, stringComparator> customSystems =
CollectionSystemsManager::get()->getCustomCollectionSystems(); CollectionSystemsManager::getInstance()->getCustomCollectionSystems();
// Add custom systems. // Add custom systems.
for (std::map<std::string, CollectionSystemData, stringComparator>::const_iterator it = for (std::map<std::string, CollectionSystemData, stringComparator>::const_iterator it =
customSystems.cbegin(); customSystems.cbegin();
@ -112,8 +113,8 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
std::string customSystemsConfig = std::string customSystemsConfig =
Settings::getInstance()->getString("CollectionSystemsCustom"); Settings::getInstance()->getString("CollectionSystemsCustom");
if (customSystemsSelected != customSystemsConfig) { if (customSystemsSelected != customSystemsConfig) {
if (CollectionSystemsManager::get()->isEditing()) if (CollectionSystemsManager::getInstance()->isEditing())
CollectionSystemsManager::get()->exitEditMode(); CollectionSystemsManager::getInstance()->exitEditMode();
Settings::getInstance()->setString("CollectionSystemsCustom", Settings::getInstance()->setString("CollectionSystemsCustom",
customSystemsSelected); customSystemsSelected);
// Check if any systems have been enabled, and if so repopulate them, which // 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()) { if (!mAddedCustomCollection && !addedCustomSystems.empty()) {
for (std::string system : addedCustomSystems) for (std::string system : addedCustomSystems)
CollectionSystemsManager::get()->repopulateCollection( CollectionSystemsManager::getInstance()->repopulateCollection(
customSystems.find(system)->second.system); customSystems.find(system)->second.system);
} }
setNeedsSaving(); setNeedsSaving();
@ -159,7 +160,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
// Create custom collection from theme. // Create custom collection from theme.
std::vector<std::string> unusedFolders = std::vector<std::string> unusedFolders =
CollectionSystemsManager::get()->getUnusedSystemsFromTheme(); CollectionSystemsManager::getInstance()->getUnusedSystemsFromTheme();
if (unusedFolders.size() > 0) { if (unusedFolders.size() > 0) {
ComponentListRow row; ComponentListRow row;
auto themeCollection = auto themeCollection =
@ -259,8 +260,8 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
"ARE YOU SURE?", "ARE YOU SURE?",
"YES", "YES",
[this, name] { [this, name] {
if (CollectionSystemsManager::get()->isEditing()) if (CollectionSystemsManager::getInstance()->isEditing())
CollectionSystemsManager::get()->exitEditMode(); CollectionSystemsManager::getInstance()->exitEditMode();
mDeletedCustomCollection = true; mDeletedCustomCollection = true;
std::vector<std::string> selectedCustomCollections = std::vector<std::string> selectedCustomCollections =
collection_systems_custom->getSelectedObjects(); collection_systems_custom->getSelectedObjects();
@ -289,7 +290,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
setNeedsSaving(); setNeedsSaving();
setNeedsGoToStart(); setNeedsGoToStart();
} }
CollectionSystemsManager::get()->deleteCustomCollection(name); CollectionSystemsManager::getInstance()->deleteCustomCollection(name);
return true; return true;
}, },
"NO", [] { return false; })); "NO", [] { return false; }));
@ -349,8 +350,8 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
Settings::getInstance()->getBool("UseCustomCollectionsSystem")) { Settings::getInstance()->getBool("UseCustomCollectionsSystem")) {
Settings::getInstance()->setBool("UseCustomCollectionsSystem", Settings::getInstance()->setBool("UseCustomCollectionsSystem",
use_custom_collections_system->getState()); use_custom_collections_system->getState());
if (CollectionSystemsManager::get()->isEditing()) if (CollectionSystemsManager::getInstance()->isEditing())
CollectionSystemsManager::get()->exitEditMode(); CollectionSystemsManager::getInstance()->exitEditMode();
setNeedsSaving(); setNeedsSaving();
setNeedsCollectionsUpdate(); setNeedsCollectionsUpdate();
setNeedsReloading(); setNeedsReloading();
@ -378,14 +379,15 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
void GuiCollectionSystemsOptions::createCustomCollection(std::string inName) void GuiCollectionSystemsOptions::createCustomCollection(std::string inName)
{ {
if (CollectionSystemsManager::get()->isEditing()) if (CollectionSystemsManager::getInstance()->isEditing())
CollectionSystemsManager::get()->exitEditMode(); CollectionSystemsManager::getInstance()->exitEditMode();
std::string collectionName = CollectionSystemsManager::get()->getValidNewCollectionName(inName); std::string collectionName =
CollectionSystemsManager::getInstance()->getValidNewCollectionName(inName);
SystemData* newCollection = 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); collection_systems_custom->add(collectionName, collectionName, true);
mAddedCustomCollection = true; mAddedCustomCollection = true;
@ -397,7 +399,7 @@ void GuiCollectionSystemsOptions::createCustomCollection(std::string inName)
setNeedsGoToSystem(newCollection); setNeedsGoToSystem(newCollection);
Window* window = mWindow; Window* window = mWindow;
while (window->peekGui() && window->peekGui() != ViewController::get()) while (window->peekGui() && window->peekGui() != ViewController::getInstance())
delete window->peekGui(); delete window->peekGui();
CollectionSystemsManager::get()->setEditMode(collectionName); CollectionSystemsManager::getInstance()->setEditMode(collectionName);
} }

View file

@ -200,7 +200,7 @@ std::vector<HelpPrompt> GuiGameScraper::getHelpPrompts()
HelpStyle GuiGameScraper::getHelpStyle() HelpStyle GuiGameScraper::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -40,7 +40,7 @@ void GuiGamelistFilter::initializeMenu()
// If this is a collection and system names are shown per game, then let FileFilterIndex // 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. // 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")) if (Settings::getInstance()->getBool("CollectionShowSystemInfo"))
mFilterIndex->setTextRemoveSystem(true); mFilterIndex->setTextRemoveSystem(true);
else else
@ -262,6 +262,6 @@ std::vector<HelpPrompt> GuiGamelistFilter::getHelpPrompts()
HelpStyle GuiGamelistFilter::getHelpStyle() HelpStyle GuiGamelistFilter::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -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. // 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 && mSystem->getRootFolder()->getChildren().size() == 0 && !mIsCustomCollectionGroup &&
!mIsCustomCollection) { !mIsCustomCollection) {
row.elements.clear(); row.elements.clear();
@ -179,7 +179,7 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system)
if (UIModeController::getInstance()->isUIModeFull() && if (UIModeController::getInstance()->isUIModeFull() &&
(mIsCustomCollection || mIsCustomCollectionGroup)) { (mIsCustomCollection || mIsCustomCollectionGroup)) {
if (CollectionSystemsManager::get()->getEditingCollection() != customSystem) { if (CollectionSystemsManager::getInstance()->getEditingCollection() != customSystem) {
row.elements.clear(); row.elements.clear();
row.addElement(std::make_shared<TextComponent>(mWindow, row.addElement(std::make_shared<TextComponent>(mWindow,
"ADD/REMOVE GAMES TO THIS COLLECTION", "ADD/REMOVE GAMES TO THIS COLLECTION",
@ -191,16 +191,17 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system)
} }
if (UIModeController::getInstance()->isUIModeFull() && if (UIModeController::getInstance()->isUIModeFull() &&
CollectionSystemsManager::get()->isEditing()) { CollectionSystemsManager::getInstance()->isEditing()) {
row.elements.clear(); row.elements.clear();
row.addElement(std::make_shared<TextComponent>( row.addElement(
mWindow, std::make_shared<TextComponent>(
"FINISH EDITING '" + mWindow,
Utils::String::toUpper( "FINISH EDITING '" +
CollectionSystemsManager::get()->getEditingCollection()) + Utils::String::toUpper(
"' COLLECTION", CollectionSystemsManager::getInstance()->getEditingCollection()) +
Font::get(FONT_SIZE_MEDIUM), 0x777777FF), "' COLLECTION",
true); Font::get(FONT_SIZE_MEDIUM), 0x777777FF),
true);
row.makeAcceptInputHandler(std::bind(&GuiGamelistOptions::exitEditMode, this)); row.makeAcceptInputHandler(std::bind(&GuiGamelistOptions::exitEditMode, this));
mMenu.addRow(row); mMenu.addRow(row);
} }
@ -257,20 +258,20 @@ GuiGamelistOptions::~GuiGamelistOptions()
// This is required for the situation where scrolling started just before the menu // 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 // was openened. Without this, the scrolling would run until manually stopped after
// the menu has been closed. // the menu has been closed.
ViewController::get()->stopScrolling(); ViewController::getInstance()->stopScrolling();
if (mFiltersChanged) { if (mFiltersChanged) {
if (!mCustomCollectionSystem) { if (!mCustomCollectionSystem) {
ViewController::get()->reloadGameListView(mSystem); ViewController::getInstance()->reloadGameListView(mSystem);
} }
else { else {
if (!mFromPlaceholder) { if (!mFromPlaceholder) {
ViewController::get()->reloadGameListView(mSystem); ViewController::getInstance()->reloadGameListView(mSystem);
} }
else if (!mCustomCollectionSystem->getRootFolder() else if (!mCustomCollectionSystem->getRootFolder()
->getChildrenListToDisplay() ->getChildrenListToDisplay()
.empty()) { .empty()) {
ViewController::get()->reloadGameListView(mSystem); ViewController::getInstance()->reloadGameListView(mSystem);
getGamelist()->setCursor( getGamelist()->setCursor(
mCustomCollectionSystem->getRootFolder()->getChildrenListToDisplay().front()); mCustomCollectionSystem->getRootFolder()->getChildrenListToDisplay().front());
} }
@ -336,7 +337,8 @@ void GuiGamelistOptions::startEditMode()
std::string editingSystem = mSystem->getName(); std::string editingSystem = mSystem->getName();
// Need to check if we're editing the collections bundle, // Need to check if we're editing the collections bundle,
// as we will want to edit the selected collection within. // 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(); FileData* file = getGamelist()->getCursor();
// Do we have the cursor on a specific collection?. // Do we have the cursor on a specific collection?.
if (file->getType() == FOLDER) if (file->getType() == FOLDER)
@ -345,14 +347,14 @@ void GuiGamelistOptions::startEditMode()
// We are inside a specific collection. We want to edit that one. // We are inside a specific collection. We want to edit that one.
editingSystem = file->getSystem()->getName(); 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 // 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 // currently being edited. This is done cheaply using onFileChanged() which will trigger
// populateList(). // populateList().
for (auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it) { for (auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); ++it) {
ViewController::get()->getGameListView((*it))->onFileChanged( ViewController::getInstance()->getGameListView((*it))->onFileChanged(
ViewController::get()->getGameListView((*it))->getCursor(), false); ViewController::getInstance()->getGameListView((*it))->getCursor(), false);
} }
if (mSystem->getRootFolder()->getChildren().size() == 0) if (mSystem->getRootFolder()->getChildren().size() == 0)
@ -362,7 +364,7 @@ void GuiGamelistOptions::startEditMode()
void GuiGamelistOptions::exitEditMode() void GuiGamelistOptions::exitEditMode()
{ {
CollectionSystemsManager::get()->exitEditMode(); CollectionSystemsManager::getInstance()->exitEditMode();
if (mSystem->getRootFolder()->getChildren().size() == 0) if (mSystem->getRootFolder()->getChildren().size() == 0)
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND); NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
delete this; delete this;
@ -394,7 +396,7 @@ void GuiGamelistOptions::openMetaDataEd()
LOG(LogInfo) << "Deleting the media files and gamelist.xml entry for the file \"" LOG(LogInfo) << "Deleting the media files and gamelist.xml entry for the file \""
<< file->getFullPath() << "\""; << 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. // Manually reset all the metadata values, set the name to the actual file/folder name.
const std::vector<MetaDataDecl>& mdd = file->metadata.getMDD(); const std::vector<MetaDataDecl>& mdd = file->metadata.getMDD();
@ -420,7 +422,7 @@ void GuiGamelistOptions::openMetaDataEd()
// Update all collections where the game is present. // Update all collections where the game is present.
if (file->getType() == GAME) if (file->getType() == GAME)
CollectionSystemsManager::get()->refreshCollectionSystems(file, true); CollectionSystemsManager::getInstance()->refreshCollectionSystems(file, true);
file->getSystem()->sortSystem(); file->getSystem()->sortSystem();
// This delay reduces the likelyhood that the SVG rasterizer which is running in a // This delay reduces the likelyhood that the SVG rasterizer which is running in a
@ -440,11 +442,11 @@ void GuiGamelistOptions::openMetaDataEd()
deleteGameBtnFunc = [this, file] { deleteGameBtnFunc = [this, file] {
LOG(LogInfo) << "Deleting the game file \"" << file->getFullPath() LOG(LogInfo) << "Deleting the game file \"" << file->getFullPath()
<< "\", all its media files and its gamelist.xml entry."; << "\", 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::getInstance()->getGameListView(file->getSystem()).get()->removeMedia(file);
ViewController::get()->getGameListView(file->getSystem()).get()->remove(file, true); ViewController::getInstance()->getGameListView(file->getSystem()).get()->remove(file, true);
mSystem->getRootFolder()->sort(*mListSort->getSelected(), mFavoritesSorting); mSystem->getRootFolder()->sort(*mListSort->getSelected(), mFavoritesSorting);
ViewController::get()->reloadGameListView(mSystem); ViewController::getInstance()->reloadGameListView(mSystem);
mWindow->invalidateCachedBackground(); mWindow->invalidateCachedBackground();
}; };
@ -454,7 +456,8 @@ void GuiGamelistOptions::openMetaDataEd()
mWindow, &file->metadata, file->metadata.getMDD(FOLDER_METADATA), p, mWindow, &file->metadata, file->metadata.getMDD(FOLDER_METADATA), p,
Utils::FileSystem::getFileName(file->getPath()), Utils::FileSystem::getFileName(file->getPath()),
std::bind(&IGameListView::onFileChanged, std::bind(&IGameListView::onFileChanged,
ViewController::get()->getGameListView(file->getSystem()).get(), file, true), ViewController::getInstance()->getGameListView(file->getSystem()).get(), file,
true),
clearGameBtnFunc, deleteGameBtnFunc)); clearGameBtnFunc, deleteGameBtnFunc));
} }
else { else {
@ -462,7 +465,8 @@ void GuiGamelistOptions::openMetaDataEd()
mWindow, &file->metadata, file->metadata.getMDD(GAME_METADATA), p, mWindow, &file->metadata, file->metadata.getMDD(GAME_METADATA), p,
Utils::FileSystem::getFileName(file->getPath()), Utils::FileSystem::getFileName(file->getPath()),
std::bind(&IGameListView::onFileChanged, std::bind(&IGameListView::onFileChanged,
ViewController::get()->getGameListView(file->getSystem()).get(), file, true), ViewController::getInstance()->getGameListView(file->getSystem()).get(), file,
true),
clearGameBtnFunc, deleteGameBtnFunc)); clearGameBtnFunc, deleteGameBtnFunc));
} }
} }
@ -551,7 +555,7 @@ std::vector<HelpPrompt> GuiGamelistOptions::getHelpPrompts()
{ {
auto prompts = mMenu.getHelpPrompts(); auto prompts = mMenu.getHelpPrompts();
if (mSystem->getRootFolder()->getChildren().size() > 0 || mIsCustomCollectionGroup || if (mSystem->getRootFolder()->getChildren().size() > 0 || mIsCustomCollectionGroup ||
mIsCustomCollection || CollectionSystemsManager::get()->isEditing()) mIsCustomCollection || CollectionSystemsManager::getInstance()->isEditing())
prompts.push_back(HelpPrompt("a", "select")); prompts.push_back(HelpPrompt("a", "select"));
if (mSystem->getRootFolder()->getChildren().size() > 0 && mSystem->getName() != "recent") { if (mSystem->getRootFolder()->getChildren().size() > 0 && mSystem->getName() != "recent") {
prompts.push_back(HelpPrompt("b", "close (apply)")); prompts.push_back(HelpPrompt("b", "close (apply)"));
@ -566,5 +570,5 @@ std::vector<HelpPrompt> GuiGamelistOptions::getHelpPrompts()
IGameListView* GuiGamelistOptions::getGamelist() IGameListView* GuiGamelistOptions::getGamelist()
{ {
return ViewController::get()->getGameListView(mSystem).get(); return ViewController::getInstance()->getGameListView(mSystem).get();
} }

View file

@ -14,10 +14,10 @@
#include "components/TextComponent.h" #include "components/TextComponent.h"
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
GuiLaunchScreen::GuiLaunchScreen(Window* window) GuiLaunchScreen::GuiLaunchScreen()
: GuiComponent(window) : GuiComponent(Window::getInstance())
, mWindow(window) , mWindow(Window::getInstance())
, mBackground(window, ":/graphics/frame.svg") , mBackground(mWindow, ":/graphics/frame.svg")
, mGrid(nullptr) , mGrid(nullptr)
, mMarquee(nullptr) , mMarquee(nullptr)
{ {

View file

@ -21,7 +21,7 @@ class FileData;
class GuiLaunchScreen : public Window::GuiLaunchScreen, GuiComponent class GuiLaunchScreen : public Window::GuiLaunchScreen, GuiComponent
{ {
public: public:
GuiLaunchScreen(Window* window); GuiLaunchScreen();
virtual ~GuiLaunchScreen(); virtual ~GuiLaunchScreen();
virtual void displayLaunchScreen(FileData* game) override; virtual void displayLaunchScreen(FileData* game) override;

View file

@ -85,7 +85,7 @@ GuiMenu::~GuiMenu()
// This is required for the situation where scrolling started just before the menu // 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 // was openened. Without this, the scrolling would run until manually stopped after
// the menu has been closed. // the menu has been closed.
ViewController::get()->stopScrolling(); ViewController::getInstance()->stopScrolling();
} }
void GuiMenu::openScraperOptions() void GuiMenu::openScraperOptions()
@ -189,12 +189,12 @@ void GuiMenu::openUIOptions()
Scripting::fireEvent("theme-changed", theme_set->getSelected(), Scripting::fireEvent("theme-changed", theme_set->getSelected(),
Settings::getInstance()->getString("ThemeSet")); Settings::getInstance()->getString("ThemeSet"));
Settings::getInstance()->setString("ThemeSet", theme_set->getSelected()); Settings::getInstance()->setString("ThemeSet", theme_set->getSelected());
CollectionSystemsManager::get()->updateSystemsList(); CollectionSystemsManager::getInstance()->updateSystemsList();
mWindow->setChangedThemeSet(); mWindow->setChangedThemeSet();
// This is required so that the custom collection system does not disappear // 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 the user is editing a custom collection when switching theme sets.
if (CollectionSystemsManager::get()->isEditing()) { if (CollectionSystemsManager::getInstance()->isEditing()) {
CollectionSystemsManager::get()->exitEditMode(); CollectionSystemsManager::getInstance()->exitEditMode();
s->setNeedsCollectionsUpdate(); s->setNeedsCollectionsUpdate();
} }
s->setNeedsSaving(); s->setNeedsSaving();
@ -266,8 +266,9 @@ void GuiMenu::openUIOptions()
(*it)->sortSystem(); (*it)->sortSystem();
(*it)->getIndex()->resetFilters(); (*it)->getIndex()->resetFilters();
} }
ViewController::get()->reloadAll(); ViewController::getInstance()->reloadAll();
ViewController::get()->goToSystem(SystemData::sSystemVector.front(), false); ViewController::getInstance()->goToSystem(SystemData::sSystemVector.front(),
false);
mWindow->invalidateCachedBackground(); mWindow->invalidateCachedBackground();
}, },
"NO", nullptr)); "NO", nullptr));
@ -609,16 +610,22 @@ void GuiMenu::openSoundOptions()
// implemented for these operating systems. // implemented for these operating systems.
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
// System volume. // System volume.
auto system_volume = std::make_shared<SliderComponent>(mWindow, 0.f, 100.f, 1.f, "%"); // The reason to create the VolumeControl object every time instead of making it a singleton
system_volume->setValue(static_cast<float>(VolumeControl::getInstance()->getVolume())); // is that this is the easiest way to detect new default audio devices or changes to the
s->addWithLabel("SYSTEM VOLUME", system_volume); // audio volume done by the operating system. And we don't really need this object laying
s->addSaveFunc([system_volume] { // around anyway as it's only used here.
VolumeControl::getInstance()->setVolume( VolumeControl volumeControl;
static_cast<int>(std::round(system_volume->getValue()))); int currentVolume = volumeControl.getVolume();
// 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 auto systemVolume = std::make_shared<SliderComponent>(mWindow, 0.f, 100.f, 1.f, "%");
// audio devices or changes to the audio volume done by the operating system. systemVolume->setValue(static_cast<float>(currentVolume));
VolumeControl::getInstance()->deleteInstance(); 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<int>(systemVolume->getValue()) != currentVolume) {
VolumeControl volumeControl;
volumeControl.setVolume(static_cast<int>(std::round(systemVolume->getValue())));
}
}); });
#endif #endif
@ -822,7 +829,7 @@ void GuiMenu::openOtherOptions()
auto updateValMediaDir = [this](const std::string& newVal) { auto updateValMediaDir = [this](const std::string& newVal) {
Settings::getInstance()->setString("MediaDirectory", newVal); Settings::getInstance()->setString("MediaDirectory", newVal);
Settings::getInstance()->saveFile(); Settings::getInstance()->saveFile();
ViewController::get()->reloadAll(); ViewController::getInstance()->reloadAll();
mWindow->invalidateCachedBackground(); mWindow->invalidateCachedBackground();
}; };
rowMediaDir.makeAcceptInputHandler([this, titleMediaDir, mediaDirectoryStaticText, rowMediaDir.makeAcceptInputHandler([this, titleMediaDir, mediaDirectoryStaticText,
@ -1258,7 +1265,7 @@ void GuiMenu::close(bool closeAllWindows)
else { else {
Window* window = mWindow; Window* window = mWindow;
closeFunc = [window] { closeFunc = [window] {
while (window->peekGui() != ViewController::get()) while (window->peekGui() != ViewController::getInstance())
delete window->peekGui(); delete window->peekGui();
}; };
} }
@ -1292,6 +1299,6 @@ std::vector<HelpPrompt> GuiMenu::getHelpPrompts()
HelpStyle GuiMenu::getHelpStyle() HelpStyle GuiMenu::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -511,7 +511,7 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "SAVE", "save metadata", [&] { buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "SAVE", "save metadata", [&] {
save(); save();
ViewController::get()->onPauseVideo(); ViewController::getInstance()->onPauseVideo();
delete this; delete this;
})); }));
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "CANCEL", "cancel changes", buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "CANCEL", "cancel changes",
@ -689,7 +689,7 @@ void GuiMetaDataEd::save()
// Update disabled auto collections when hiding a game, as otherwise these could // Update disabled auto collections when hiding a game, as otherwise these could
// get invalid gamelist cursor positions. A cursor pointing to a removed game // get invalid gamelist cursor positions. A cursor pointing to a removed game
// would crash the application upon enabling the collections. // 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. // Remove the game from the index of all systems.
for (SystemData* sys : SystemData::sSystemVector) { for (SystemData* sys : SystemData::sSystemVector) {
std::vector<FileData*> children; std::vector<FileData*> children;
@ -698,7 +698,7 @@ void GuiMetaDataEd::save()
if (std::find(children.begin(), children.end(), hideGame) != children.end()) { if (std::find(children.begin(), children.end(), hideGame) != children.end()) {
sys->getIndex()->removeFromIndex(hideGame); sys->getIndex()->removeFromIndex(hideGame);
// Reload the gamelist as well as the view style may need to change. // 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 { else {
// Update all collections where the game is present. // 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 // If game counting was re-enabled for the game, then reactivate it in any custom collections
// where it may exist. // where it may exist.
if (setGameAsCounted) if (setGameAsCounted)
CollectionSystemsManager::get()->reactivateCustomCollectionEntry(mScraperParams.game); CollectionSystemsManager::getInstance()->reactivateCustomCollectionEntry(
mScraperParams.game);
mScraperParams.system->onMetaDataSavePoint(); mScraperParams.system->onMetaDataSavePoint();
@ -810,12 +811,12 @@ void GuiMetaDataEd::close()
// until the user scrolls up and down the gamelist. // until the user scrolls up and down the gamelist.
TextureResource::manualUnload(mScraperParams.game->getImagePath(), false); TextureResource::manualUnload(mScraperParams.game->getImagePath(), false);
TextureResource::manualUnload(mScraperParams.game->getMarqueePath(), 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. // Update all collections where the game is present.
CollectionSystemsManager::get()->refreshCollectionSystems(mScraperParams.game); CollectionSystemsManager::getInstance()->refreshCollectionSystems(mScraperParams.game);
mWindow->invalidateCachedBackground(); mWindow->invalidateCachedBackground();
} }
ViewController::get()->onPauseVideo(); ViewController::getInstance()->onPauseVideo();
delete this; delete this;
}; };
@ -866,6 +867,6 @@ std::vector<HelpPrompt> GuiMetaDataEd::getHelpPrompts()
HelpStyle GuiMetaDataEd::getHelpStyle() HelpStyle GuiMetaDataEd::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -198,7 +198,7 @@ GuiOfflineGenerator::~GuiOfflineGenerator()
mMiximageGenerator.reset(); mMiximageGenerator.reset();
if (mImagesGenerated > 0) if (mImagesGenerated > 0)
ViewController::get()->reloadAll(); ViewController::getInstance()->reloadAll();
} }
void GuiOfflineGenerator::onSizeChanged() void GuiOfflineGenerator::onSizeChanged()
@ -336,6 +336,6 @@ std::vector<HelpPrompt> GuiOfflineGenerator::getHelpPrompts()
HelpStyle GuiOfflineGenerator::getHelpStyle() HelpStyle GuiOfflineGenerator::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -1135,6 +1135,6 @@ std::vector<HelpPrompt> GuiScraperMenu::getHelpPrompts()
HelpStyle GuiScraperMenu::getHelpStyle() HelpStyle GuiScraperMenu::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -182,7 +182,7 @@ GuiScraperMulti::~GuiScraperMulti()
(*it)->sortSystem(); (*it)->sortSystem();
} }
} }
ViewController::get()->onPauseVideo(); ViewController::getInstance()->onPauseVideo();
} }
void GuiScraperMulti::onSizeChanged() void GuiScraperMulti::onSizeChanged()
@ -280,7 +280,7 @@ void GuiScraperMulti::acceptResult(const ScraperSearchResult& result)
mSearchQueue.pop(); mSearchQueue.pop();
++mCurrentGame; ++mCurrentGame;
++mTotalSuccessful; ++mTotalSuccessful;
CollectionSystemsManager::get()->refreshCollectionSystems(search.game); CollectionSystemsManager::getInstance()->refreshCollectionSystems(search.game);
doNextSearch(); doNextSearch();
} }
@ -324,6 +324,6 @@ std::vector<HelpPrompt> GuiScraperMulti::getHelpPrompts()
HelpStyle GuiScraperMulti::getHelpStyle() HelpStyle GuiScraperMulti::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -170,7 +170,7 @@ GuiScraperSearch::~GuiScraperSearch()
mMiximageGeneratorThread.join(); mMiximageGeneratorThread.join();
mMiximageGenerator.reset(); mMiximageGenerator.reset();
TextureResource::manualUnload(mLastSearch.game->getMiximagePath(), false); TextureResource::manualUnload(mLastSearch.game->getMiximagePath(), false);
ViewController::get()->onFileChanged(mLastSearch.game, true); ViewController::getInstance()->onFileChanged(mLastSearch.game, true);
} }
} }
@ -1017,6 +1017,6 @@ std::vector<HelpPrompt> GuiScraperSearch::getHelpPrompts()
HelpStyle GuiScraperSearch::getHelpStyle() HelpStyle GuiScraperSearch::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -98,7 +98,7 @@ public:
void onFocusGained() override { mGrid.onFocusGained(); } void onFocusGained() override { mGrid.onFocusGained(); }
void onFocusLost() override { mGrid.onFocusLost(); } void onFocusLost() override { mGrid.onFocusLost(); }
std::shared_ptr<ComponentList>& getResultList() { return mResultList; } std::shared_ptr<ComponentList> getResultList() { return mResultList; }
private: private:
void updateViewStyle(); void updateViewStyle();

View file

@ -66,8 +66,8 @@ void GuiSettings::save()
mWindow->reloadHelpPrompts(); mWindow->reloadHelpPrompts();
if (mNeedsCollectionsUpdate) { if (mNeedsCollectionsUpdate) {
CollectionSystemsManager::get()->loadEnabledListFromSettings(); CollectionSystemsManager::getInstance()->loadEnabledListFromSettings();
CollectionSystemsManager::get()->updateSystemsList(); CollectionSystemsManager::getInstance()->updateSystemsList();
} }
if (mNeedsSorting) { if (mNeedsSorting) {
@ -77,7 +77,7 @@ void GuiSettings::save()
(*it)->sortSystem(true); (*it)->sortSystem(true);
// Jump to the first row of the gamelist. // 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()); gameList->setCursor(gameList->getFirstEntry());
} }
} }
@ -94,38 +94,38 @@ void GuiSettings::save()
} }
if (mNeedsReloading) if (mNeedsReloading)
ViewController::get()->reloadAll(); ViewController::getInstance()->reloadAll();
if (mNeedsGoToStart) if (mNeedsGoToStart)
ViewController::get()->goToStart(true); ViewController::getInstance()->goToStart(true);
if (mNeedsGoToSystem) if (mNeedsGoToSystem)
ViewController::get()->goToSystem(mGoToSystem, false); ViewController::getInstance()->goToSystem(mGoToSystem, false);
if (mNeedsGoToGroupedCollections) { if (mNeedsGoToGroupedCollections) {
bool groupedSystemExists = false; bool groupedSystemExists = false;
for (SystemData* system : SystemData::sSystemVector) { for (SystemData* system : SystemData::sSystemVector) {
if (system->getThemeFolder() == "custom-collections") { if (system->getThemeFolder() == "custom-collections") {
ViewController::get()->goToSystem(system, false); ViewController::getInstance()->goToSystem(system, false);
groupedSystemExists = true; groupedSystemExists = true;
continue; continue;
} }
} }
if (!groupedSystemExists) if (!groupedSystemExists)
// No grouped custom collection system exists, so go to the first system instead. // 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) { 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 // 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 // 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 // these views can behave a bit strange during collection changes so it's better to be on
// the safe side. // the safe side.
if (state.getSystem()->isCollection() && if (state.getSystem()->isCollection() &&
state.getSystem()->getThemeFolder() != "custom-collections") { state.getSystem()->getThemeFolder() != "custom-collections") {
ViewController::get()->goToStart(false); ViewController::getInstance()->goToStart(false);
ViewController::get()->goToSystem(SystemData::sSystemVector.front(), false); ViewController::getInstance()->goToSystem(SystemData::sSystemVector.front(), false);
// We don't want to invalidate the cached background when there has been a collection // 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. // systen change as that may show a black screen in some circumstances.
return; return;
@ -134,7 +134,7 @@ void GuiSettings::save()
// system view). // system view).
if (std::find(SystemData::sSystemVector.begin(), SystemData::sSystemVector.end(), if (std::find(SystemData::sSystemVector.begin(), SystemData::sSystemVector.end(),
state.getSystem()) == SystemData::sSystemVector.end()) { state.getSystem()) == SystemData::sSystemVector.end()) {
ViewController::get()->goToStart(false); ViewController::getInstance()->goToStart(false);
return; return;
} }
} }
@ -237,7 +237,7 @@ bool GuiSettings::input(InputConfig* config, Input input)
HelpStyle GuiSettings::getHelpStyle() HelpStyle GuiSettings::getHelpStyle()
{ {
HelpStyle style = HelpStyle(); HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); style.applyTheme(ViewController::getInstance()->getState().getSystem()->getTheme(), "system");
return style; return style;
} }

View file

@ -528,24 +528,25 @@ int main(int argc, char* argv[])
} }
} }
Window window; Window* window = Window::getInstance();
SystemScreensaver screensaver(&window); ViewController::getInstance();
MediaViewer mediaViewer(&window); CollectionSystemsManager::getInstance();
GuiLaunchScreen guiLaunchScreen(&window); SystemScreensaver screensaver;
ViewController::init(&window); MediaViewer mediaViewer;
CollectionSystemsManager::init(&window); GuiLaunchScreen guiLaunchScreen;
window.pushGui(ViewController::get());
if (!window->init()) {
LOG(LogError) << "Window failed to initialize";
return 1;
}
window->pushGui(ViewController::getInstance());
bool splashScreen = Settings::getInstance()->getBool("SplashScreen"); bool splashScreen = Settings::getInstance()->getBool("SplashScreen");
bool splashScreenProgress = Settings::getInstance()->getBool("SplashScreenProgress"); bool splashScreenProgress = Settings::getInstance()->getBool("SplashScreenProgress");
SDL_Event event{}; SDL_Event event{};
if (!window.init()) { InputManager::getInstance().parseEvent(event, window);
LOG(LogError) << "Window failed to initialize";
return 1;
}
InputManager::getInstance()->parseEvent(event, &window);
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
return 1; return 1;
@ -571,7 +572,7 @@ int main(int argc, char* argv[])
std::string progressText = "Loading..."; std::string progressText = "Loading...";
if (splashScreenProgress) if (splashScreenProgress)
progressText = "Loading system config..."; progressText = "Loading system config...";
window.renderLoadingScreen(progressText); window->renderLoadingScreen(progressText);
} }
AudioManager::getInstance(); 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 // configure a different ROM directory as well as to generate the game systems
// directory structure. // directory structure.
if (loadSystemsStatus == INVALID_FILE) { if (loadSystemsStatus == INVALID_FILE) {
ViewController::get()->invalidSystemsFileDialog(); ViewController::getInstance()->invalidSystemsFileDialog();
} }
else if (loadSystemsStatus == NO_ROMS) { 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. // any command tag in es_systems.xml.
for (auto system : SystemData::sSystemVector) { for (auto system : SystemData::sSystemVector) {
if (system->getAlternativeEmulator().substr(0, 9) == "<INVALID>") { if (system->getAlternativeEmulator().substr(0, 9) == "<INVALID>") {
ViewController::get()->invalidAlternativeEmulatorDialog(); ViewController::getInstance()->invalidAlternativeEmulatorDialog();
break; 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. // 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. // This makes for no delays when accessing content, but a longer startup time.
ViewController::get()->preload(); ViewController::getInstance()->preload();
if (splashScreen && splashScreenProgress) 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. // Open the input configuration GUI if the flag to force this was passed from the command line.
if (!loadSystemsStatus) { if (!loadSystemsStatus) {
if (forceInputConfig) { if (forceInputConfig) {
window.pushGui(new GuiDetectDevice(&window, false, true, window->pushGui(new GuiDetectDevice(
[] { ViewController::get()->goToStart(true); })); window, false, true, [] { ViewController::getInstance()->goToStart(true); }));
} }
else { else {
ViewController::get()->goToStart(true); ViewController::getInstance()->goToStart(true);
} }
} }
@ -645,7 +646,7 @@ int main(int argc, char* argv[])
while (running) { while (running) {
if (SDL_PollEvent(&event)) { if (SDL_PollEvent(&event)) {
do { do {
InputManager::getInstance()->parseEvent(event, &window); InputManager::getInstance().parseEvent(event, window);
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
running = false; running = false;
@ -653,7 +654,7 @@ int main(int argc, char* argv[])
} while (SDL_PollEvent(&event)); } while (SDL_PollEvent(&event));
} }
if (window.isSleeping()) { if (window->isSleeping()) {
lastTime = SDL_GetTicks(); lastTime = SDL_GetTicks();
// This doesn't need to be accurate, we're just giving up // This doesn't need to be accurate, we're just giving up
// our CPU time until something wakes us up. // our CPU time until something wakes us up.
@ -669,18 +670,18 @@ int main(int argc, char* argv[])
if (deltaTime < 0) if (deltaTime < 0)
deltaTime = 1000; deltaTime = 1000;
window.update(deltaTime); window->update(deltaTime);
window.render(); window->render();
Renderer::swapBuffers(); Renderer::swapBuffers();
Log::flush(); Log::flush();
} }
while (window.peekGui() != ViewController::get()) while (window->peekGui() != ViewController::getInstance())
delete window.peekGui(); delete window->peekGui();
window.deinit(); window->deinit();
CollectionSystemsManager::deinit(); CollectionSystemsManager::getInstance()->deinit();
SystemData::deleteSystems(); SystemData::deleteSystems();
NavigationSounds::getInstance().deinit(); NavigationSounds::getInstance().deinit();

View file

@ -253,7 +253,7 @@ MDResolveHandle::MDResolveHandle(const ScraperSearchResult& result,
scrapeFiles.push_back(mediaFileInfo); scrapeFiles.push_back(mediaFileInfo);
#if defined(_WIN64) #if defined(_WIN64)
// Required due to the idiotic file locking that exists on this operating system. // Required due to the idiotic file locking that exists on this operating system.
ViewController::get()->onStopVideo(); ViewController::getInstance()->onStopVideo();
#endif #endif
} }

View file

@ -77,9 +77,9 @@ void SystemView::populate()
auto path = logoElem->get<std::string>("path"); auto path = logoElem->get<std::string>("path");
std::string defaultPath = std::string defaultPath =
logoElem->has("default") ? logoElem->get<std::string>("default") : ""; logoElem->has("default") ? logoElem->get<std::string>("default") : "";
if ((!path.empty() && ResourceManager::getInstance()->fileExists(path)) || if ((!path.empty() && ResourceManager::getInstance().fileExists(path)) ||
(!defaultPath.empty() && (!defaultPath.empty() &&
ResourceManager::getInstance()->fileExists(defaultPath))) { ResourceManager::getInstance().fileExists(defaultPath))) {
auto* logo = new ImageComponent(mWindow, false, false); auto* logo = new ImageComponent(mWindow, false, false);
logo->setMaxSize(glm::round(mCarousel.logoSize * mCarousel.logoScale)); logo->setMaxSize(glm::round(mCarousel.logoSize * mCarousel.logoScale));
logo->applyTheme(theme, "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR); logo->applyTheme(theme, "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR);
@ -101,9 +101,9 @@ void SystemView::populate()
auto path = logoElem->get<std::string>("path"); auto path = logoElem->get<std::string>("path");
std::string defaultPath = std::string defaultPath =
logoElem->has("default") ? logoElem->get<std::string>("default") : ""; logoElem->has("default") ? logoElem->get<std::string>("default") : "";
if ((!path.empty() && ResourceManager::getInstance()->fileExists(path)) || if ((!path.empty() && ResourceManager::getInstance().fileExists(path)) ||
(!defaultPath.empty() && (!defaultPath.empty() &&
ResourceManager::getInstance()->fileExists(defaultPath))) { ResourceManager::getInstance().fileExists(defaultPath))) {
auto* logo = new ImageComponent(mWindow, false, false); auto* logo = new ImageComponent(mWindow, false, false);
logo->applyTheme(theme, "system", "logoPlaceholderImage", ThemeFlags::ALL); logo->applyTheme(theme, "system", "logoPlaceholderImage", ThemeFlags::ALL);
if (!logoElem->has("size")) 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 && if (config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_r &&
SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug")) { SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug")) {
LOG(LogDebug) << "SystemView::input(): Reloading all"; LOG(LogDebug) << "SystemView::input(): Reloading all";
ViewController::get()->reloadAll(); ViewController::getInstance()->reloadAll();
return true; return true;
} }
@ -255,12 +255,12 @@ bool SystemView::input(InputConfig* config, Input input)
case VERTICAL: case VERTICAL:
case VERTICAL_WHEEL: case VERTICAL_WHEEL:
if (config->isMappedLike("up", input)) { if (config->isMappedLike("up", input)) {
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
listInput(-1); listInput(-1);
return true; return true;
} }
if (config->isMappedLike("down", input)) { if (config->isMappedLike("down", input)) {
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
listInput(1); listInput(1);
return true; return true;
} }
@ -269,12 +269,12 @@ bool SystemView::input(InputConfig* config, Input input)
case HORIZONTAL_WHEEL: case HORIZONTAL_WHEEL:
default: default:
if (config->isMappedLike("left", input)) { if (config->isMappedLike("left", input)) {
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
listInput(-1); listInput(-1);
return true; return true;
} }
if (config->isMappedLike("right", input)) { if (config->isMappedLike("right", input)) {
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
listInput(1); listInput(1);
return true; return true;
} }
@ -283,7 +283,7 @@ bool SystemView::input(InputConfig* config, Input input)
if (config->isMappedTo("a", input)) { if (config->isMappedTo("a", input)) {
stopScrolling(); stopScrolling();
ViewController::get()->goToGameList(getSelected()); ViewController::getInstance()->goToGameList(getSelected());
NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND); NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND);
return true; return true;
} }
@ -299,8 +299,8 @@ bool SystemView::input(InputConfig* config, Input input)
if (!UIModeController::getInstance()->isUIModeKid() && config->isMappedTo("back", input) && if (!UIModeController::getInstance()->isUIModeKid() && config->isMappedTo("back", input) &&
Settings::getInstance()->getBool("ScreensaverControls")) { Settings::getInstance()->getBool("ScreensaverControls")) {
if (!mWindow->isScreensaverActive()) { if (!mWindow->isScreensaverActive()) {
ViewController::get()->stopScrolling(); ViewController::getInstance()->stopScrolling();
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
mWindow->startScreensaver(); mWindow->startScreensaver();
mWindow->renderScreensaver(); mWindow->renderScreensaver();
} }

View file

@ -16,25 +16,7 @@
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
#include "views/ViewController.h" #include "views/ViewController.h"
UIModeController* UIModeController::sInstance = nullptr; UIModeController::UIModeController() noexcept
UIModeController* UIModeController::getInstance()
{
if (sInstance == nullptr)
sInstance = new UIModeController();
return sInstance;
}
void UIModeController::deinit()
{
if (sInstance) {
delete sInstance;
sInstance = nullptr;
}
}
UIModeController::UIModeController()
: mPassKeyCounter(0) : mPassKeyCounter(0)
{ {
mPassKeySequence = Settings::getInstance()->getString("UIMode_passkey"); mPassKeySequence = Settings::getInstance()->getString("UIMode_passkey");
@ -47,11 +29,17 @@ UIModeController::UIModeController()
} }
} }
UIModeController* UIModeController::getInstance()
{
static UIModeController instance;
return &instance;
}
void UIModeController::monitorUIMode() void UIModeController::monitorUIMode()
{ {
std::string uimode = Settings::getInstance()->getString("UIMode"); std::string uimode = Settings::getInstance()->getString("UIMode");
// UI mode was changed. // UI mode was changed.
if (uimode != mCurrentUIMode && !ViewController::get()->isCameraMoving()) { if (uimode != mCurrentUIMode && !ViewController::getInstance()->isCameraMoving()) {
mCurrentUIMode = uimode; mCurrentUIMode = uimode;
// Reset filters and sort gamelists (which will update the game counter). // Reset filters and sort gamelists (which will update the game counter).
for (auto it = SystemData::sSystemVector.cbegin(); // Line break. for (auto it = SystemData::sSystemVector.cbegin(); // Line break.
@ -63,7 +51,7 @@ void UIModeController::monitorUIMode()
customSystem->getSystem()->getIndex()->resetFilters(); customSystem->getSystem()->getIndex()->resetFilters();
} }
} }
ViewController::get()->ReloadAndGoToStart(); ViewController::getInstance()->ReloadAndGoToStart();
} }
} }

View file

@ -23,7 +23,6 @@ class UIModeController
{ {
public: public:
static UIModeController* getInstance(); static UIModeController* getInstance();
static void deinit();
// Monitor input for UI mode change, returns true (consumes input) when a UI mode // Monitor input for UI mode change, returns true (consumes input) when a UI mode
// change is triggered. // change is triggered.
@ -42,15 +41,14 @@ public:
void setCurrentUIMode(const std::string& mode) { mCurrentUIMode = mode; } void setCurrentUIMode(const std::string& mode) { mCurrentUIMode = mode; }
private: private:
UIModeController(); UIModeController() noexcept;
bool inputIsMatch(InputConfig* config, Input input); bool inputIsMatch(InputConfig* config, Input input);
bool isValidInput(InputConfig* config, Input input); bool isValidInput(InputConfig* config, Input input);
// Return UI mode to 'full'. // Return UI mode to 'full'.
void unlockUIMode(); void unlockUIMode();
static UIModeController* sInstance;
// Default passkeyseq = "uuddlrlrba", as defined in the setting 'UIMode_passkey'. // Default passkeyseq = "uuddlrlrba", as defined in the setting 'UIMode_passkey'.
std::string mPassKeySequence; std::string mPassKeySequence;

View file

@ -33,8 +33,6 @@
#include "views/gamelist/IGameListView.h" #include "views/gamelist/IGameListView.h"
#include "views/gamelist/VideoGameListView.h" #include "views/gamelist/VideoGameListView.h"
ViewController* ViewController::sInstance = nullptr;
#if defined(_MSC_VER) // MSVC compiler. #if defined(_MSC_VER) // MSVC compiler.
const std::string ViewController::CONTROLLER_CHAR = Utils::String::wideStringToString(L"\uf11b"); const std::string ViewController::CONTROLLER_CHAR = Utils::String::wideStringToString(L"\uf11b");
const std::string ViewController::CROSSEDCIRCLE_CHAR = Utils::String::wideStringToString(L"\uf05e"); 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"; const std::string ViewController::TICKMARK_CHAR = "\uf14a";
#endif #endif
ViewController* ViewController::get() ViewController* ViewController::getInstance()
{ {
assert(sInstance); static ViewController instance;
return sInstance; return &instance;
} }
void ViewController::init(Window* window) ViewController::ViewController() noexcept
{ : GuiComponent(Window::getInstance())
assert(!sInstance);
sInstance = new ViewController(window);
}
ViewController::ViewController(Window* window)
: GuiComponent(window)
, mNoGamesMessageBox(nullptr) , mNoGamesMessageBox(nullptr)
, mCurrentView(nullptr) , mCurrentView(nullptr)
, mPreviousView(nullptr) , mPreviousView(nullptr)
@ -88,13 +80,6 @@ ViewController::ViewController(Window* window)
mState.viewstyle = AUTOMATIC; mState.viewstyle = AUTOMATIC;
} }
ViewController::~ViewController()
{
assert(sInstance == this);
sInstance = nullptr;
UIModeController::deinit();
}
void ViewController::invalidSystemsFileDialog() void ViewController::invalidSystemsFileDialog()
{ {
std::string errorMessage = "COULDN'T PARSE THE SYSTEMS CONFIGURATION FILE.\n" std::string errorMessage = "COULDN'T PARSE THE SYSTEMS CONFIGURATION FILE.\n"

View file

@ -29,10 +29,7 @@ class SystemView;
class ViewController : public GuiComponent class ViewController : public GuiComponent
{ {
public: public:
static void init(Window* window); static ViewController* getInstance();
static ViewController* get();
virtual ~ViewController();
// These functions are called from main(). // These functions are called from main().
void invalidSystemsFileDialog(); void invalidSystemsFileDialog();
@ -131,8 +128,7 @@ public:
static const std::string TICKMARK_CHAR; static const std::string TICKMARK_CHAR;
private: private:
ViewController(Window* window); ViewController() noexcept;
static ViewController* sInstance;
void launch(FileData* game); void launch(FileData* game);

View file

@ -40,7 +40,7 @@ void BasicGameListView::onFileChanged(FileData* file, bool reloadGameList)
{ {
if (reloadGameList) { if (reloadGameList) {
// Might switch to a detailed view. // Might switch to a detailed view.
ViewController::get()->reloadGameListView(this); ViewController::getInstance()->reloadGameListView(this);
return; return;
} }
@ -55,8 +55,8 @@ void BasicGameListView::populateList(const std::vector<FileData*>& files, FileDa
std::string editingCollection; std::string editingCollection;
std::string inCollectionPrefix; std::string inCollectionPrefix;
if (CollectionSystemsManager::get()->isEditing()) { if (CollectionSystemsManager::getInstance()->isEditing()) {
editingCollection = CollectionSystemsManager::get()->getEditingCollection(); editingCollection = CollectionSystemsManager::getInstance()->getEditingCollection();
isEditing = true; isEditing = true;
} }
@ -78,7 +78,8 @@ void BasicGameListView::populateList(const std::vector<FileData*>& files, FileDa
// Add a leading tick mark icon to the game name if it's part of the custom collection // Add a leading tick mark icon to the game name if it's part of the custom collection
// currently being edited. // currently being edited.
if (isEditing && (*it)->getType() == GAME) { if (isEditing && (*it)->getType() == GAME) {
if (CollectionSystemsManager::get()->inCustomCollection(editingCollection, (*it))) { if (CollectionSystemsManager::getInstance()->inCustomCollection(editingCollection,
(*it))) {
if (Settings::getInstance()->getBool("SpecialCharsASCII")) if (Settings::getInstance()->getBool("SpecialCharsASCII"))
inCollectionPrefix = "! "; inCollectionPrefix = "! ";
else else
@ -161,7 +162,7 @@ void BasicGameListView::addPlaceholder(FileData* firstEntry)
void BasicGameListView::launch(FileData* game) void BasicGameListView::launch(FileData* game)
{ {
// This triggers ViewController to launch the game. // This triggers ViewController to launch the game.
ViewController::get()->triggerGameLaunch(game); ViewController::getInstance()->triggerGameLaunch(game);
} }
void BasicGameListView::remove(FileData* game, bool deleteFile) void BasicGameListView::remove(FileData* game, bool deleteFile)
@ -309,7 +310,7 @@ std::vector<HelpPrompt> BasicGameListView::getHelpPrompts()
prompts.push_back(HelpPrompt("left/right", "system")); prompts.push_back(HelpPrompt("left/right", "system"));
if (mRoot->getSystem()->getThemeFolder() == "custom-collections" && mCursorStack.empty() && 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")); prompts.push_back(HelpPrompt("a", "enter"));
else else
prompts.push_back(HelpPrompt("a", "launch")); prompts.push_back(HelpPrompt("a", "launch"));
@ -323,9 +324,9 @@ std::vector<HelpPrompt> BasicGameListView::getHelpPrompts()
prompts.push_back(HelpPrompt("thumbstickclick", "random")); prompts.push_back(HelpPrompt("thumbstickclick", "random"));
if (mRoot->getSystem()->getThemeFolder() == "custom-collections" && if (mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
!CollectionSystemsManager::get()->isEditing() && mCursorStack.empty() && !CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() &&
ViewController::get()->getState().viewing == ViewController::GAME_LIST && ViewController::getInstance()->getState().viewing == ViewController::GAME_LIST &&
ViewController::get()->getState().viewstyle != ViewController::BASIC) { ViewController::getInstance()->getState().viewstyle != ViewController::BASIC) {
prompts.push_back(HelpPrompt("y", "jump to game")); prompts.push_back(HelpPrompt("y", "jump to game"));
} }
else if (mRoot->getSystem()->isGameSystem() && else if (mRoot->getSystem()->isGameSystem() &&
@ -334,14 +335,14 @@ std::vector<HelpPrompt> BasicGameListView::getHelpPrompts()
!UIModeController::getInstance()->isUIModeKid() && !UIModeController::getInstance()->isUIModeKid() &&
!UIModeController::getInstance()->isUIModeKiosk() && !UIModeController::getInstance()->isUIModeKiosk() &&
(Settings::getInstance()->getBool("FavoritesAddButton") || (Settings::getInstance()->getBool("FavoritesAddButton") ||
CollectionSystemsManager::get()->isEditing())) { CollectionSystemsManager::getInstance()->isEditing())) {
std::string prompt = CollectionSystemsManager::get()->getEditingCollection(); std::string prompt = CollectionSystemsManager::getInstance()->getEditingCollection();
prompts.push_back(HelpPrompt("y", prompt)); prompts.push_back(HelpPrompt("y", prompt));
} }
else if (mRoot->getSystem()->isGameSystem() && else if (mRoot->getSystem()->isGameSystem() &&
mRoot->getSystem()->getThemeFolder() == "custom-collections" && mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
CollectionSystemsManager::get()->isEditing()) { CollectionSystemsManager::getInstance()->isEditing()) {
std::string prompt = CollectionSystemsManager::get()->getEditingCollection(); std::string prompt = CollectionSystemsManager::getInstance()->getEditingCollection();
prompts.push_back(HelpPrompt("y", prompt)); prompts.push_back(HelpPrompt("y", prompt));
} }
return prompts; return prompts;

View file

@ -338,8 +338,8 @@ void DetailedGameListView::updateInfoPanel()
// the first of these so that we can display its game media. // the first of these so that we can display its game media.
if (file->getSystem()->isCustomCollection() && if (file->getSystem()->isCustomCollection() &&
file->getPath() == file->getSystem()->getName()) { file->getPath() == file->getSystem()->getName()) {
mRandomGame = mRandomGame = CollectionSystemsManager::getInstance()->updateCollectionFolderMetadata(
CollectionSystemsManager::get()->updateCollectionFolderMetadata(file->getSystem()); file->getSystem());
if (mRandomGame) { if (mRandomGame) {
mThumbnail.setImage(mRandomGame->getThumbnailPath()); mThumbnail.setImage(mRandomGame->getThumbnailPath());
mMarquee.setImage(mRandomGame->getMarqueePath(), false, true); mMarquee.setImage(mRandomGame->getMarqueePath(), false, true);
@ -476,7 +476,7 @@ void DetailedGameListView::updateInfoPanel()
void DetailedGameListView::launch(FileData* game) void DetailedGameListView::launch(FileData* game)
{ {
ViewController::get()->triggerGameLaunch(game); ViewController::getInstance()->triggerGameLaunch(game);
} }
std::vector<TextComponent*> DetailedGameListView::getMDLabels() std::vector<TextComponent*> DetailedGameListView::getMDLabels()
@ -512,7 +512,7 @@ void DetailedGameListView::update(int deltaTime)
BasicGameListView::update(deltaTime); BasicGameListView::update(deltaTime);
mImage.update(deltaTime); mImage.update(deltaTime);
if (ViewController::get()->getGameLaunchTriggered() && mImage.isAnimationPlaying(0)) if (ViewController::getInstance()->getGameLaunchTriggered() && mImage.isAnimationPlaying(0))
mImage.finishAnimation(0); mImage.finishAnimation(0);
} }

View file

@ -130,7 +130,7 @@ void GridGameListView::onFileChanged(FileData* file, bool reloadGameList)
{ {
if (reloadGameList) { if (reloadGameList) {
// Might switch to a detailed view. // Might switch to a detailed view.
ViewController::get()->reloadGameListView(this); ViewController::getInstance()->reloadGameListView(this);
return; return;
} }
@ -519,7 +519,7 @@ void GridGameListView::addPlaceholder(FileData* firstEntry)
void GridGameListView::launch(FileData* game) void GridGameListView::launch(FileData* game)
{ {
// This triggers ViewController to launch the game. // This triggers ViewController to launch the game.
ViewController::get()->triggerGameLaunch(game); ViewController::getInstance()->triggerGameLaunch(game);
} }
void GridGameListView::remove(FileData* game, bool deleteFile) void GridGameListView::remove(FileData* game, bool deleteFile)
@ -687,7 +687,7 @@ std::vector<HelpPrompt> GridGameListView::getHelpPrompts()
prompts.push_back(HelpPrompt("up/down/left/right", "choose")); prompts.push_back(HelpPrompt("up/down/left/right", "choose"));
if (mRoot->getSystem()->getThemeFolder() == "custom-collections" && mCursorStack.empty() && 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")); prompts.push_back(HelpPrompt("a", "enter"));
else else
prompts.push_back(HelpPrompt("a", "launch")); prompts.push_back(HelpPrompt("a", "launch"));
@ -712,14 +712,14 @@ std::vector<HelpPrompt> GridGameListView::getHelpPrompts()
!UIModeController::getInstance()->isUIModeKid() && !UIModeController::getInstance()->isUIModeKid() &&
!UIModeController::getInstance()->isUIModeKiosk() && !UIModeController::getInstance()->isUIModeKiosk() &&
(Settings::getInstance()->getBool("FavoritesAddButton") || (Settings::getInstance()->getBool("FavoritesAddButton") ||
CollectionSystemsManager::get()->isEditing())) { CollectionSystemsManager::getInstance()->isEditing())) {
std::string prompt = CollectionSystemsManager::get()->getEditingCollection(); std::string prompt = CollectionSystemsManager::getInstance()->getEditingCollection();
prompts.push_back(HelpPrompt("y", prompt)); prompts.push_back(HelpPrompt("y", prompt));
} }
else if (mRoot->getSystem()->isGameSystem() && else if (mRoot->getSystem()->isGameSystem() &&
mRoot->getSystem()->getThemeFolder() == "custom-collections" && mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
CollectionSystemsManager::get()->isEditing()) { CollectionSystemsManager::getInstance()->isEditing()) {
std::string prompt = CollectionSystemsManager::get()->getEditingCollection(); std::string prompt = CollectionSystemsManager::getInstance()->getEditingCollection();
prompts.push_back(HelpPrompt("y", prompt)); prompts.push_back(HelpPrompt("y", prompt));
} }
return prompts; return prompts;

View file

@ -33,7 +33,7 @@ bool IGameListView::input(InputConfig* config, Input input)
// Select button opens GuiGamelistOptions. // Select button opens GuiGamelistOptions.
if (!UIModeController::getInstance()->isUIModeKid() && // Line break. if (!UIModeController::getInstance()->isUIModeKid() && // Line break.
config->isMappedTo("back", input) && input.value) { config->isMappedTo("back", input) && input.value) {
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
stopListScrolling(); stopListScrolling();
mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem())); mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem()));
return true; return true;
@ -45,7 +45,7 @@ bool IGameListView::input(InputConfig* config, Input input)
(SDL_GetModState() & (KMOD_LCTRL | KMOD_RCTRL)) && input.id == SDLK_r && (SDL_GetModState() & (KMOD_LCTRL | KMOD_RCTRL)) && input.id == SDLK_r &&
input.value != 0) { input.value != 0) {
LOG(LogDebug) << "IGameListView::input(): Reloading view"; LOG(LogDebug) << "IGameListView::input(): Reloading view";
ViewController::get()->reloadGameListView(this, true); ViewController::getInstance()->reloadGameListView(this, true);
return true; return true;
} }

View file

@ -30,7 +30,7 @@ public:
virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) = 0; virtual void onThemeChanged(const std::shared_ptr<ThemeData>& theme) = 0;
void setTheme(const std::shared_ptr<ThemeData>& theme); void setTheme(const std::shared_ptr<ThemeData>& theme);
const std::shared_ptr<ThemeData>& getTheme() const { return mTheme; } const std::shared_ptr<ThemeData> getTheme() const { return mTheme; }
virtual void preloadGamelist(){}; virtual void preloadGamelist(){};

View file

@ -106,14 +106,14 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
FileData* cursor = getCursor(); FileData* cursor = getCursor();
if (cursor->getType() == GAME) { if (cursor->getType() == GAME) {
onPauseVideo(); onPauseVideo();
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
stopListScrolling(); stopListScrolling();
launch(cursor); launch(cursor);
} }
else { else {
// It's a folder. // It's a folder.
if (cursor->getChildren().size() > 0) { if (cursor->getChildren().size() > 0) {
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND); NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND);
mCursorStack.push(cursor); mCursorStack.push(cursor);
populateList(cursor->getChildrenListToDisplay(), cursor); populateList(cursor->getChildrenListToDisplay(), cursor);
@ -147,7 +147,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
return true; return true;
} }
else if (config->isMappedTo("b", input)) { else if (config->isMappedTo("b", input)) {
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
if (mCursorStack.size()) { if (mCursorStack.size()) {
// Save the position to the cursor stack history. // Save the position to the cursor stack history.
mCursorStackHistory.push_back(getCursor()); mCursorStackHistory.push_back(getCursor());
@ -168,10 +168,10 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
SystemData* systemToView = getCursor()->getSystem(); SystemData* systemToView = getCursor()->getSystem();
if (systemToView->isCustomCollection() && if (systemToView->isCustomCollection() &&
systemToView->getRootFolder()->getParent()) systemToView->getRootFolder()->getParent())
ViewController::get()->goToSystemView( ViewController::getInstance()->goToSystemView(
systemToView->getRootFolder()->getParent()->getSystem(), true); systemToView->getRootFolder()->getParent()->getSystem(), true);
else else
ViewController::get()->goToSystemView(systemToView, true); ViewController::getInstance()->goToSystemView(systemToView, true);
} }
return true; return true;
@ -184,19 +184,20 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
else if (config->isMappedTo("x", input) && else if (config->isMappedTo("x", input) &&
mRoot->getSystem()->getThemeFolder() == "custom-collections" && mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
mCursorStack.empty() && mCursorStack.empty() &&
ViewController::get()->getState().viewing == ViewController::GAME_LIST) { ViewController::getInstance()->getState().viewing ==
ViewController::GAME_LIST) {
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND); NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
// Jump to the randomly selected game. // Jump to the randomly selected game.
if (mRandomGame) { if (mRandomGame) {
stopListScrolling(); stopListScrolling();
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
mWindow->startMediaViewer(mRandomGame); mWindow->startMediaViewer(mRandomGame);
return true; return true;
} }
} }
else if (mRoot->getSystem()->isGameSystem()) { else if (mRoot->getSystem()->isGameSystem()) {
stopListScrolling(); stopListScrolling();
ViewController::get()->cancelViewTransitions(); ViewController::getInstance()->cancelViewTransitions();
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND); NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
mWindow->startMediaViewer(getCursor()); mWindow->startMediaViewer(getCursor());
return true; return true;
@ -208,7 +209,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
onPauseVideo(); onPauseVideo();
onFocusLost(); onFocusLost();
stopListScrolling(); stopListScrolling();
ViewController::get()->goToNextGameList(); ViewController::getInstance()->goToNextGameList();
return true; return true;
} }
} }
@ -218,7 +219,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
onPauseVideo(); onPauseVideo();
onFocusLost(); onFocusLost();
stopListScrolling(); stopListScrolling();
ViewController::get()->goToPrevGameList(); ViewController::getInstance()->goToPrevGameList();
return true; return true;
} }
} }
@ -237,8 +238,8 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
} }
else if (config->isMappedTo("y", input) && else if (config->isMappedTo("y", input) &&
mRoot->getSystem()->getThemeFolder() == "custom-collections" && mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
!CollectionSystemsManager::get()->isEditing() && mCursorStack.empty() && !CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() &&
ViewController::get()->getState().viewing == ViewController::GAME_LIST) { ViewController::getInstance()->getState().viewing == ViewController::GAME_LIST) {
// Jump to the randomly selected game. // Jump to the randomly selected game.
if (mRandomGame) { if (mRandomGame) {
NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND); NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND);
@ -262,21 +263,21 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
} }
else if (config->isMappedTo("y", input) && else if (config->isMappedTo("y", input) &&
!Settings::getInstance()->getBool("FavoritesAddButton") && !Settings::getInstance()->getBool("FavoritesAddButton") &&
!CollectionSystemsManager::get()->isEditing()) { !CollectionSystemsManager::getInstance()->isEditing()) {
return true; return true;
} }
else if (config->isMappedTo("y", input) && else if (config->isMappedTo("y", input) &&
!UIModeController::getInstance()->isUIModeKid() && !UIModeController::getInstance()->isUIModeKid() &&
!UIModeController::getInstance()->isUIModeKiosk()) { !UIModeController::getInstance()->isUIModeKiosk()) {
// Notify the user if attempting to add a custom collection to a custom collection. // 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 && mRoot->getSystem()->isGameSystem() && getCursor()->getType() != PLACEHOLDER &&
getCursor()->getParent()->getPath() == "collections") { getCursor()->getParent()->getPath() == "collections") {
NavigationSounds::getInstance().playThemeNavigationSound(FAVORITESOUND); NavigationSounds::getInstance().playThemeNavigationSound(FAVORITESOUND);
mWindow->queueInfoPopup("CAN'T ADD CUSTOM COLLECTIONS TO CUSTOM COLLECTIONS", 4000); mWindow->queueInfoPopup("CAN'T ADD CUSTOM COLLECTIONS TO CUSTOM COLLECTIONS", 4000);
} }
// Notify the user if attempting to add a placeholder to a custom collection. // 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) { mRoot->getSystem()->isGameSystem() && getCursor()->getType() == PLACEHOLDER) {
NavigationSounds::getInstance().playThemeNavigationSound(FAVORITESOUND); NavigationSounds::getInstance().playThemeNavigationSound(FAVORITESOUND);
mWindow->queueInfoPopup("CAN'T ADD PLACEHOLDERS TO CUSTOM COLLECTIONS", 4000); mWindow->queueInfoPopup("CAN'T ADD PLACEHOLDERS TO CUSTOM COLLECTIONS", 4000);
@ -293,7 +294,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
bool favoritesSorting; bool favoritesSorting;
bool removedLastFavorite = false; bool removedLastFavorite = false;
bool selectLastEntry = false; bool selectLastEntry = false;
bool isEditing = CollectionSystemsManager::get()->isEditing(); bool isEditing = CollectionSystemsManager::getInstance()->isEditing();
bool foldersOnTop = Settings::getInstance()->getBool("FoldersOnTop"); bool foldersOnTop = Settings::getInstance()->getBool("FoldersOnTop");
// If the current list only contains folders, then treat it as if the folders // 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 // 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()), mRoot->getSortTypeFromString(mRoot->getSortTypeString()),
Settings::getInstance()->getBool("FavoritesFirst")); 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 // 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 // was unmarked. We couldn't do this earlier as we didn't have the list
// sorted yet. // sorted yet.
if (removedLastFavorite) { if (removedLastFavorite) {
ViewController::get() ViewController::getInstance()
->getGameListView(entryToUpdate->getSystem()) ->getGameListView(entryToUpdate->getSystem())
->setCursor(ViewController::get() ->setCursor(ViewController::getInstance()
->getGameListView(entryToUpdate->getSystem()) ->getGameListView(entryToUpdate->getSystem())
->getFirstEntry()); ->getFirstEntry());
} }
@ -439,17 +440,19 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
"AS GAMES TO CUSTOM COLLECTIONS", "AS GAMES TO CUSTOM COLLECTIONS",
4000); 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 // 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 // from ViewController instead of using the reference that existed before the
// destruction. Otherwise we get random crashes. // 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. // Jump to the first entry in the gamelist if the last favorite was unmarked.
if (foldersOnTop && removedLastFavorite && if (foldersOnTop && removedLastFavorite &&
!entryToUpdate->getSystem()->isCustomCollection()) { !entryToUpdate->getSystem()->isCustomCollection()) {
ViewController::get() ViewController::getInstance()
->getGameListView(entryToUpdate->getSystem()) ->getGameListView(entryToUpdate->getSystem())
->setCursor(ViewController::get() ->setCursor(ViewController::getInstance()
->getGameListView(entryToUpdate->getSystem()) ->getGameListView(entryToUpdate->getSystem())
->getFirstGameEntry()); ->getFirstGameEntry());
} }
@ -466,8 +469,9 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
if (isEditing) { if (isEditing) {
for (auto it = SystemData::sSystemVector.begin(); for (auto it = SystemData::sSystemVector.begin();
it != SystemData::sSystemVector.end(); ++it) { it != SystemData::sSystemVector.end(); ++it) {
ViewController::get()->getGameListView((*it))->onFileChanged( ViewController::getInstance()->getGameListView((*it))->onFileChanged(
ViewController::get()->getGameListView((*it))->getCursor(), false); ViewController::getInstance()->getGameListView((*it))->getCursor(),
false);
} }
} }
return true; return true;

View file

@ -349,8 +349,8 @@ void VideoGameListView::updateInfoPanel()
// the first of these so that we can display its game media. // the first of these so that we can display its game media.
if (file->getSystem()->isCustomCollection() && if (file->getSystem()->isCustomCollection() &&
file->getPath() == file->getSystem()->getName()) { file->getPath() == file->getSystem()->getName()) {
mRandomGame = mRandomGame = CollectionSystemsManager::getInstance()->updateCollectionFolderMetadata(
CollectionSystemsManager::get()->updateCollectionFolderMetadata(file->getSystem()); file->getSystem());
if (mRandomGame) { if (mRandomGame) {
mThumbnail.setImage(mRandomGame->getThumbnailPath()); mThumbnail.setImage(mRandomGame->getThumbnailPath());
mMarquee.setImage(mRandomGame->getMarqueePath(), false, true); 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<TextComponent*> VideoGameListView::getMDLabels() std::vector<TextComponent*> VideoGameListView::getMDLabels()
{ {
@ -542,7 +545,7 @@ void VideoGameListView::update(int deltaTime)
BasicGameListView::update(deltaTime); BasicGameListView::update(deltaTime);
mVideo->update(deltaTime); mVideo->update(deltaTime);
if (ViewController::get()->getGameLaunchTriggered() && mVideo->isAnimationPlaying(0)) if (ViewController::getInstance()->getGameLaunchTriggered() && mVideo->isAnimationPlaying(0))
mVideo->finishAnimation(0); mVideo->finishAnimation(0);
} }

View file

@ -14,7 +14,7 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
AudioManager::AudioManager() AudioManager::AudioManager() noexcept
{ {
// Init on construction. // Init on construction.
init(); init();
@ -119,6 +119,8 @@ void AudioManager::deinit()
SDL_CloseAudio(); SDL_CloseAudio();
SDL_QuitSubSystem(SDL_INIT_AUDIO); SDL_QuitSubSystem(SDL_INIT_AUDIO);
sAudioDevice = 0;
} }
void AudioManager::mixAudio(void* /*unused*/, Uint8* stream, int len) void AudioManager::mixAudio(void* /*unused*/, Uint8* stream, int len)

View file

@ -45,7 +45,7 @@ public:
inline static SDL_AudioSpec sAudioFormat; inline static SDL_AudioSpec sAudioFormat;
private: private:
AudioManager(); AudioManager() noexcept;
static void mixAudio(void* unused, Uint8* stream, int len); static void mixAudio(void* unused, Uint8* stream, int len);
static void mixAudio2(void* unused, Uint8* stream, int len); static void mixAudio2(void* unused, Uint8* stream, int len);

View file

@ -30,8 +30,6 @@ extern "C" {
extern int SDL_USER_CECBUTTONDOWN; extern int SDL_USER_CECBUTTONDOWN;
extern int SDL_USER_CECBUTTONUP; extern int SDL_USER_CECBUTTONUP;
CECInput* CECInput::sInstance = nullptr;
#if defined(HAVE_LIBCEC) #if defined(HAVE_LIBCEC)
static void onAlert(void* /*cbParam*/, static void onAlert(void* /*cbParam*/,
const CEC::libcec_alert type, const CEC::libcec_alert type,
@ -80,20 +78,6 @@ static void vchi_tv_and_cec_deinit()
#endif // _RPI_ #endif // _RPI_
#endif // HAVE_LIBCEC #endif // HAVE_LIBCEC
void CECInput::init()
{
if (!sInstance)
sInstance = new CECInput();
}
void CECInput::deinit()
{
if (sInstance) {
delete sInstance;
sInstance = nullptr;
}
}
CECInput::CECInput() CECInput::CECInput()
: mlibCEC(nullptr) : mlibCEC(nullptr)
{ {

View file

@ -19,18 +19,14 @@ namespace CEC
class CECInput class CECInput
{ {
public: public:
static void init(); CECInput();
static void deinit(); ~CECInput();
static std::string getAlertTypeString(const unsigned int _type); static std::string getAlertTypeString(const unsigned int _type);
static std::string getOpCodeString(const unsigned int _opCode); static std::string getOpCodeString(const unsigned int _opCode);
static std::string getKeyCodeString(const unsigned int _keyCode); static std::string getKeyCodeString(const unsigned int _keyCode);
private: private:
CECInput();
~CECInput();
static CECInput* sInstance;
CEC::ICECAdapter* mlibCEC; CEC::ICECAdapter* mlibCEC;
}; };

View file

@ -70,7 +70,7 @@ HttpReq::HttpReq(const std::string& url)
// these latter operating systems unless the bundled file is used. // these latter operating systems unless the bundled file is used.
curl_easy_setopt(mHandle, CURLOPT_CAINFO, curl_easy_setopt(mHandle, CURLOPT_CAINFO,
ResourceManager::getInstance() ResourceManager::getInstance()
->getResourcePath(":/certificates/curl-ca-bundle.crt") .getResourcePath(":/certificates/curl-ca-bundle.crt")
.c_str()); .c_str());
#endif #endif

View file

@ -10,7 +10,6 @@
#include "InputManager.h" #include "InputManager.h"
#include "CECInput.h"
#include "Log.h" #include "Log.h"
#include "Platform.h" #include "Platform.h"
#include "Scripting.h" #include "Scripting.h"
@ -32,9 +31,7 @@ int SDL_USER_CECBUTTONUP = -1;
static bool sAltDown = false; static bool sAltDown = false;
static bool sLguiDown = false; static bool sLguiDown = false;
InputManager* InputManager::sInstance = nullptr; InputManager::InputManager() noexcept
InputManager::InputManager()
: mKeyboardInputConfig(nullptr) : mKeyboardInputConfig(nullptr)
{ {
} }
@ -45,12 +42,10 @@ InputManager::~InputManager()
deinit(); deinit();
} }
InputManager* InputManager::getInstance() InputManager& InputManager::getInstance()
{ {
if (!sInstance) static InputManager instance;
sInstance = new InputManager(); return instance;
return sInstance;
} }
void InputManager::init() void InputManager::init()
@ -94,7 +89,7 @@ void InputManager::init()
Utils::FileSystem::getHomePath() + "/.emulationstation/" + "es_controller_mappings.cfg"; Utils::FileSystem::getHomePath() + "/.emulationstation/" + "es_controller_mappings.cfg";
if (!Utils::FileSystem::exists(mappingsFile)) if (!Utils::FileSystem::exists(mappingsFile))
mappingsFile = ResourceManager::getInstance()->getResourcePath( mappingsFile = ResourceManager::getInstance().getResourcePath(
":/controllers/es_controller_mappings.cfg"); ":/controllers/es_controller_mappings.cfg");
int controllerMappings = SDL_GameControllerAddMappingsFromFile(mappingsFile.c_str()); int controllerMappings = SDL_GameControllerAddMappingsFromFile(mappingsFile.c_str());
@ -116,7 +111,6 @@ void InputManager::init()
SDL_USER_CECBUTTONDOWN = SDL_RegisterEvents(2); SDL_USER_CECBUTTONDOWN = SDL_RegisterEvents(2);
SDL_USER_CECBUTTONUP = SDL_USER_CECBUTTONDOWN + 1; SDL_USER_CECBUTTONUP = SDL_USER_CECBUTTONDOWN + 1;
CECInput::init();
mCECInputConfig = std::make_unique<InputConfig>(DEVICE_CEC, "CEC", CEC_GUID_STRING); mCECInputConfig = std::make_unique<InputConfig>(DEVICE_CEC, "CEC", CEC_GUID_STRING);
loadInputConfig(mCECInputConfig.get()); loadInputConfig(mCECInputConfig.get());
} }
@ -138,15 +132,8 @@ void InputManager::deinit()
mKeyboardInputConfig.reset(); mKeyboardInputConfig.reset();
mCECInputConfig.reset(); mCECInputConfig.reset();
CECInput::deinit();
SDL_GameControllerEventState(SDL_DISABLE); SDL_GameControllerEventState(SDL_DISABLE);
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
if (sInstance) {
delete sInstance;
sInstance = nullptr;
}
} }
void InputManager::writeDeviceConfig(InputConfig* config) void InputManager::writeDeviceConfig(InputConfig* config)

View file

@ -11,6 +11,8 @@
#ifndef ES_CORE_INPUT_MANAGER_H #ifndef ES_CORE_INPUT_MANAGER_H
#define ES_CORE_INPUT_MANAGER_H #define ES_CORE_INPUT_MANAGER_H
#include "CECInput.h"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_joystick.h> #include <SDL2/SDL_joystick.h>
@ -25,9 +27,7 @@ union SDL_Event;
class InputManager class InputManager
{ {
public: public:
InputManager(); static InputManager& getInstance();
virtual ~InputManager();
static InputManager* getInstance();
void init(); void init();
void deinit(); void deinit();
@ -50,6 +50,9 @@ public:
int getNumJoysticks() { return static_cast<int>(mJoysticks.size()); } int getNumJoysticks() { return static_cast<int>(mJoysticks.size()); }
private: private:
InputManager() noexcept;
virtual ~InputManager();
bool initialized() const { return mKeyboardInputConfig != nullptr; } bool initialized() const { return mKeyboardInputConfig != nullptr; }
bool loadInputConfig(InputConfig* config); bool loadInputConfig(InputConfig* config);
@ -59,7 +62,8 @@ private:
void addControllerByDeviceIndex(Window* window, int deviceIndex); void addControllerByDeviceIndex(Window* window, int deviceIndex);
void removeControllerByJoystickID(Window* window, SDL_JoystickID joyID); void removeControllerByJoystickID(Window* window, SDL_JoystickID joyID);
static InputManager* sInstance; CECInput mCECInput;
static const int DEADZONE_TRIGGERS = 18000; static const int DEADZONE_TRIGGERS = 18000;
static const int DEADZONE_THUMBSTICKS = 23000; static const int DEADZONE_THUMBSTICKS = 23000;
bool mConfigFileExists; bool mConfigFileExists;

View file

@ -26,7 +26,7 @@ MameNames& MameNames::getInstance()
MameNames::MameNames() 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)) if (!Utils::FileSystem::exists(xmlpath))
return; return;
@ -54,7 +54,7 @@ MameNames::MameNames()
} }
// Read BIOS file. // Read BIOS file.
xmlpath = ResourceManager::getInstance()->getResourcePath(":/MAME/mamebioses.xml"); xmlpath = ResourceManager::getInstance().getResourcePath(":/MAME/mamebioses.xml");
if (!Utils::FileSystem::exists(xmlpath)) if (!Utils::FileSystem::exists(xmlpath))
return; return;
@ -80,7 +80,7 @@ MameNames::MameNames()
} }
// Read device file. // Read device file.
xmlpath = ResourceManager::getInstance()->getResourcePath(":/MAME/mamedevices.xml"); xmlpath = ResourceManager::getInstance().getResourcePath(":/MAME/mamedevices.xml");
if (!Utils::FileSystem::exists(xmlpath)) if (!Utils::FileSystem::exists(xmlpath))
return; return;

View file

@ -64,10 +64,10 @@ Settings::Settings()
loadFile(); loadFile();
} }
std::shared_ptr<Settings> Settings::getInstance() Settings* Settings::getInstance()
{ {
static std::shared_ptr<Settings> instance{new Settings()}; static Settings instance;
return instance; return &instance;
} }
void Settings::setDefaults() void Settings::setDefaults()

View file

@ -18,7 +18,7 @@
class Settings class Settings
{ {
public: public:
static std::shared_ptr<Settings> getInstance(); static Settings* getInstance();
void loadFile(); void loadFile();
void saveFile(); void saveFile();

View file

@ -36,7 +36,7 @@ std::shared_ptr<Sound> Sound::getFromTheme(ThemeData* const theme,
if (theme == nullptr) { if (theme == nullptr) {
LOG(LogDebug) << "Sound::getFromTheme(): Using fallback sound file for \"" << element 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 <sound name=\"" << element << "\">"; LOG(LogDebug) << "Sound::getFromTheme(): Looking for tag <sound name=\"" << element << "\">";
@ -44,7 +44,7 @@ std::shared_ptr<Sound> Sound::getFromTheme(ThemeData* const theme,
const ThemeData::ThemeElement* elem = theme->getElement(view, element, "sound"); const ThemeData::ThemeElement* elem = theme->getElement(view, element, "sound");
if (!elem || !elem->has("path")) { if (!elem || !elem->has("path")) {
LOG(LogDebug) << "Sound::getFromTheme(): Tag not found, using fallback sound file"; 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"; LOG(LogDebug) << "Sound::getFromTheme(): Tag found, ready to load theme sound file";

View file

@ -77,6 +77,7 @@ public:
bool isPlayingThemeNavigationSound(NavigationSoundsID soundID); bool isPlayingThemeNavigationSound(NavigationSoundsID soundID);
private: private:
NavigationSounds() noexcept {};
std::vector<std::shared_ptr<Sound>> mNavigationSounds; std::vector<std::shared_ptr<Sound>> mNavigationSounds;
}; };

View file

@ -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")) { for (pugi::xml_node node = root.child("include"); node; node = node.next_sibling("include")) {
std::string relPath = resolvePlaceholders(node.text().as_string()); std::string relPath = resolvePlaceholders(node.text().as_string());
std::string path = Utils::FileSystem::resolveRelativePath(relPath, mPaths.back(), true); 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 << "\")"; throw error << " -> \"" << relPath << "\" not found (resolved to \"" << path << "\")";
error << " -> \"" << relPath << "\""; error << " -> \"" << relPath << "\"";
@ -512,7 +512,7 @@ void ThemeData::parseElement(const pugi::xml_node& root,
} }
case PATH: { case PATH: {
std::string path = Utils::FileSystem::resolveRelativePath(str, mPaths.back(), true); std::string path = Utils::FileSystem::resolveRelativePath(str, mPaths.back(), true);
if (!ResourceManager::getInstance()->fileExists(path)) { if (!ResourceManager::getInstance().fileExists(path)) {
std::stringstream ss; std::stringstream ss;
// "From theme yadda yadda, included file yadda yadda. // "From theme yadda yadda, included file yadda yadda.
LOG(LogWarning) << error.msg << ":"; LOG(LogWarning) << error.msg << ":";
@ -607,7 +607,7 @@ const ThemeData::ThemeElement* ThemeData::getElement(const std::string& view,
return &elemIt->second; return &elemIt->second;
} }
const std::shared_ptr<ThemeData>& ThemeData::getDefault() const std::shared_ptr<ThemeData> ThemeData::getDefault()
{ {
static std::shared_ptr<ThemeData> theme = nullptr; static std::shared_ptr<ThemeData> theme = nullptr;
if (theme == nullptr) { if (theme == nullptr) {

View file

@ -199,7 +199,7 @@ public:
const std::string& view, const std::string& view,
Window* window); Window* window);
static const std::shared_ptr<ThemeData>& getDefault(); static const std::shared_ptr<ThemeData> getDefault();
static std::map<std::string, ThemeSet> getThemeSets(); static std::map<std::string, ThemeSet> getThemeSets();
static std::string getThemeFromCurrentSet(const std::string& system); static std::string getThemeFromCurrentSet(const std::string& system);

View file

@ -24,7 +24,7 @@
#define CLOCK_BACKGROUND_CREATION false #define CLOCK_BACKGROUND_CREATION false
#endif #endif
Window::Window() Window::Window() noexcept
: mScreensaver(nullptr) : mScreensaver(nullptr)
, mMediaViewer(nullptr) , mMediaViewer(nullptr)
, mLaunchScreen(nullptr) , mLaunchScreen(nullptr)
@ -48,9 +48,6 @@ Window::Window()
, mTopScale(0.5) , mTopScale(0.5)
, mChangedThemeSet(false) , mChangedThemeSet(false)
{ {
mHelp = new HelpComponent(this);
mBackgroundOverlay = new ImageComponent(this);
mBackgroundOverlayOpacity = 0;
} }
Window::~Window() Window::~Window()
@ -67,6 +64,12 @@ Window::~Window()
delete mHelp; delete mHelp;
} }
Window* Window::getInstance()
{
static Window instance;
return &instance;
}
void Window::pushGui(GuiComponent* gui) void Window::pushGui(GuiComponent* gui)
{ {
if (mGuiStack.size() > 0) { if (mGuiStack.size() > 0) {
@ -109,9 +112,13 @@ bool Window::init()
return false; 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. // Keep a reference to the default fonts, so they don't keep getting destroyed/recreated.
if (mDefaultFonts.empty()) { if (mDefaultFonts.empty()) {
@ -147,8 +154,8 @@ void Window::deinit()
mPostprocessedBackground.reset(); mPostprocessedBackground.reset();
#endif #endif
InputManager::getInstance()->deinit(); InputManager::getInstance().deinit();
ResourceManager::getInstance()->unloadAll(); ResourceManager::getInstance().unloadAll();
Renderer::deinit(); Renderer::deinit();
} }

View file

@ -75,8 +75,7 @@ public:
virtual void render(const glm::mat4& parentTrans) = 0; virtual void render(const glm::mat4& parentTrans) = 0;
}; };
Window(); static Window* getInstance();
~Window();
void pushGui(GuiComponent* gui); void pushGui(GuiComponent* gui);
void removeGui(GuiComponent* gui); void removeGui(GuiComponent* gui);
@ -147,6 +146,9 @@ public:
bool getChangedThemeSet() { return mChangedThemeSet; } bool getChangedThemeSet() { return mChangedThemeSet; }
private: private:
Window() noexcept;
~Window();
void onSleep() { Scripting::fireEvent("sleep"); } void onSleep() { Scripting::fireEvent("sleep"); }
void onWake() { Scripting::fireEvent("wake"); } void onWake() { Scripting::fireEvent("wake"); }

View file

@ -26,7 +26,7 @@ void AnimatedImageComponent::load(const AnimationDef* def)
for (size_t i = 0; i < def->frameCount; ++i) { for (size_t i = 0; i < def->frameCount; ++i) {
if (def->frames[i].path != "" && 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 LOG(LogError) << "Missing animation frame " << i << " (\"" << def->frames[i].path
<< "\")"; << "\")";
continue; continue;

View file

@ -269,7 +269,7 @@ std::shared_ptr<TextureResource> HelpComponent::getIconTexture(const char* name)
return nullptr; 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 \"" LOG(LogError) << "Couldn't load help icon \"" << name << "\" as the file \""
<< pathLookup->second << "\" is missing"; << pathLookup->second << "\" is missing";
return nullptr; return nullptr;

View file

@ -140,8 +140,8 @@ void ImageComponent::setImage(const std::string& path, bool tile, bool linearMag
mDynamic = false; mDynamic = false;
} }
if (path.empty() || !ResourceManager::getInstance()->fileExists(path)) { if (path.empty() || !ResourceManager::getInstance().fileExists(path)) {
if (mDefaultPath.empty() || !ResourceManager::getInstance()->fileExists(mDefaultPath)) if (mDefaultPath.empty() || !ResourceManager::getInstance().fileExists(mDefaultPath))
mTexture.reset(); mTexture.reset();
else else
mTexture = mTexture =

View file

@ -327,7 +327,7 @@ void ImageGridComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (elem->has("gameImage")) { if (elem->has("gameImage")) {
std::string path = elem->get<std::string>("gameImage"); std::string path = elem->get<std::string>("gameImage");
if (!ResourceManager::getInstance()->fileExists(path)) { if (!ResourceManager::getInstance().fileExists(path)) {
LOG(LogWarning) << "Could not replace default game image, check path: " << path; LOG(LogWarning) << "Could not replace default game image, check path: " << path;
} }
else { else {
@ -346,7 +346,7 @@ void ImageGridComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (elem->has("folderImage")) { if (elem->has("folderImage")) {
std::string path = elem->get<std::string>("folderImage"); std::string path = elem->get<std::string>("folderImage");
if (!ResourceManager::getInstance()->fileExists(path)) { if (!ResourceManager::getInstance().fileExists(path)) {
LOG(LogWarning) << "Could not replace default folder image, check path: " << path; LOG(LogWarning) << "Could not replace default folder image, check path: " << path;
} }
else { else {
@ -658,7 +658,7 @@ void ImageGridComponent<T>::updateTileAtPos(int tilePos,
std::string imagePath = mEntries.at(imgPos).data.texturePath; std::string imagePath = mEntries.at(imgPos).data.texturePath;
if (ResourceManager::getInstance()->fileExists(imagePath)) if (ResourceManager::getInstance().fileExists(imagePath))
tile->setImage(imagePath); tile->setImage(imagePath);
else if (mEntries.at(imgPos).object->getType() == 2) else if (mEntries.at(imgPos).object->getType() == 2)
tile->setImage(mDefaultFolderTexture); tile->setImage(mDefaultFolderTexture);

View file

@ -69,7 +69,7 @@ bool VideoComponent::setVideo(std::string path)
mVideoPath = fullPath; mVideoPath = fullPath;
// If the file exists then set the new video. // 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 to show that we are going to attempt to play a video.
return true; return true;
} }

View file

@ -1412,7 +1412,8 @@ void VideoFFmpegComponent::stopVideo()
std::queue<AudioFrame>().swap(mAudioFrameQueue); std::queue<AudioFrame>().swap(mAudioFrameQueue);
// Clear the audio buffer. // Clear the audio buffer.
AudioManager::getInstance().clearStream(); if (AudioManager::sAudioDevice != 0)
AudioManager::getInstance().clearStream();
if (mFormatContext) { if (mFormatContext) {
av_frame_free(&mVideoFrame); av_frame_free(&mVideoFrame);

View file

@ -43,7 +43,7 @@ GuiDetectDevice::GuiDetectDevice(Window* window,
// Device info. // Device info.
std::stringstream deviceInfo; std::stringstream deviceInfo;
int numDevices = InputManager::getInstance()->getNumJoysticks(); int numDevices = InputManager::getInstance().getNumJoysticks();
if (numDevices > 0) if (numDevices > 0)
deviceInfo << numDevices << " GAMEPAD" << (numDevices > 1 ? "S" : "") << " DETECTED"; deviceInfo << numDevices << " GAMEPAD" << (numDevices > 1 ? "S" : "") << " DETECTED";
@ -148,7 +148,7 @@ void GuiDetectDevice::update(int deltaTime)
// command line. // command line.
if (!mForcedConfig && mFirstRun && if (!mForcedConfig && mFirstRun &&
Utils::FileSystem::exists(InputManager::getConfigPath()) && Utils::FileSystem::exists(InputManager::getConfigPath()) &&
InputManager::getInstance()->getNumConfiguredDevices() > 0) { InputManager::getInstance().getNumConfiguredDevices() > 0) {
if (mDoneCallback) if (mDoneCallback)
mDoneCallback(); mDoneCallback();
delete this; // Delete GUI element. delete this; // Delete GUI element.

View file

@ -174,7 +174,7 @@ GuiInputConfig::GuiInputConfig(Window* window,
// GUI buttons. // GUI buttons.
std::vector<std::shared_ptr<ButtonComponent>> buttons; std::vector<std::shared_ptr<ButtonComponent>> buttons;
std::function<void()> okFunction = [this, okCallback] { std::function<void()> okFunction = [this, okCallback] {
InputManager::getInstance()->writeDeviceConfig(mTargetConfig); // Save. InputManager::getInstance().writeDeviceConfig(mTargetConfig); // Save.
if (okCallback) if (okCallback)
okCallback(); okCallback();
delete this; delete this;

View file

@ -44,7 +44,7 @@ namespace Renderer
size_t width = 0; size_t width = 0;
size_t height = 0; size_t height = 0;
ResourceData resData = ResourceData resData =
ResourceManager::getInstance()->getFileData(":/graphics/window_icon_256.png"); ResourceManager::getInstance().getFileData(":/graphics/window_icon_256.png");
std::vector<unsigned char> rawData = std::vector<unsigned char> rawData =
ImageIO::loadFromMemoryRGBA32(resData.ptr.get(), resData.length, width, height); ImageIO::loadFromMemoryRGBA32(resData.ptr.get(), resData.length, width, height);

View file

@ -40,7 +40,7 @@ namespace Renderer
std::string shaderCode; std::string shaderCode;
// This will load the entire GLSL source code into the string variable. // 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<const char*>(shaderData.ptr.get()), shaderData.length); shaderCode.assign(reinterpret_cast<const char*>(shaderData.ptr.get()), shaderData.length);
// Define the GLSL version (version 120 = OpenGL 2.1). // Define the GLSL version (version 120 = OpenGL 2.1).

View file

@ -128,7 +128,7 @@ std::shared_ptr<Font> Font::get(int size, const std::string& path)
std::shared_ptr<Font> font = std::shared_ptr<Font>(new Font(def.second, def.first)); std::shared_ptr<Font> font = std::shared_ptr<Font>(new Font(def.second, def.first));
sFontMap[def] = std::weak_ptr<Font>(font); sFontMap[def] = std::weak_ptr<Font>(font);
ResourceManager::getInstance()->addReloadable(font); ResourceManager::getInstance().addReloadable(font);
return font; return font;
} }
@ -243,25 +243,25 @@ std::vector<std::string> getFallbackFontPaths()
// Standard fonts, let's include them here for exception handling purposes even though that's // 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.) // 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-Regular.ttf");
ResourceManager::getInstance()->getResourcePath(":/fonts/Akrobat-SemiBold.ttf"); ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-SemiBold.ttf");
ResourceManager::getInstance()->getResourcePath(":/fonts/Akrobat-Bold.ttf"); ResourceManager::getInstance().getResourcePath(":/fonts/Akrobat-Bold.ttf");
// Vera sans Unicode. // Vera sans Unicode.
fontPaths.push_back(ResourceManager::getInstance()->getResourcePath(":/fonts/DejaVuSans.ttf")); fontPaths.push_back(ResourceManager::getInstance().getResourcePath(":/fonts/DejaVuSans.ttf"));
// GNU FreeFont monospaced. // 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. // Various languages, such as Japanese and Chinese.
fontPaths.push_back( fontPaths.push_back(
ResourceManager::getInstance()->getResourcePath(":/fonts/DroidSansFallbackFull.ttf")); ResourceManager::getInstance().getResourcePath(":/fonts/DroidSansFallbackFull.ttf"));
// Korean. // Korean.
fontPaths.push_back( 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. // Font Awesome icon glyphs, used for various special symbols like stars, folders etc.
fontPaths.push_back( 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. // 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(); fontPaths.shrink_to_fit();
return fontPaths; return fontPaths;
@ -281,7 +281,7 @@ FT_Face Font::getFaceForChar(unsigned int id)
// i == 0 -> mPath // i == 0 -> mPath
// Otherwise, take from fallbackFonts. // Otherwise, take from fallbackFonts.
const std::string& path = (i == 0 ? mPath : fallbackFonts.at(i - 1)); 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<FontFace>(new FontFace(std::move(data), mSize)); mFaceCache[i] = std::unique_ptr<FontFace>(new FontFace(std::move(data), mSize));
fit = mFaceCache.find(i); fit = mFaceCache.find(i);
} }

View file

@ -90,8 +90,8 @@ public:
float getHeight(float lineSpacing = 1.5f) const; float getHeight(float lineSpacing = 1.5f) const;
float getLetterHeight(); float getLetterHeight();
void reload(std::shared_ptr<ResourceManager>& rm) override { rebuildTextures(); } void reload(ResourceManager& rm) override { rebuildTextures(); }
void unload(std::shared_ptr<ResourceManager>& rm) override { unloadTextures(); } void unload(ResourceManager& rm) override { unloadTextures(); }
int getSize() const { return mSize; } int getSize() const { return mSize; }
const std::string& getPath() const { return mPath; } const std::string& getPath() const { return mPath; }

View file

@ -19,14 +19,10 @@
auto array_deleter = [](unsigned char* p) { delete[] p; }; auto array_deleter = [](unsigned char* p) { delete[] p; };
std::shared_ptr<ResourceManager> ResourceManager::sInstance = nullptr; ResourceManager& ResourceManager::getInstance()
std::shared_ptr<ResourceManager>& ResourceManager::getInstance()
{ {
if (!sInstance) static ResourceManager instance;
sInstance = std::shared_ptr<ResourceManager>(new ResourceManager()); return instance;
return sInstance;
} }
std::string ResourceManager::getResourcePath(const std::string& path, bool terminateOnFailure) const std::string ResourceManager::getResourcePath(const std::string& path, bool terminateOnFailure) const
@ -145,7 +141,7 @@ void ResourceManager::unloadAll()
auto iter = mReloadables.cbegin(); auto iter = mReloadables.cbegin();
while (iter != mReloadables.cend()) { while (iter != mReloadables.cend()) {
if (!iter->expired()) { if (!iter->expired()) {
iter->lock()->unload(sInstance); iter->lock()->unload(getInstance());
++iter; ++iter;
} }
else { else {
@ -159,7 +155,7 @@ void ResourceManager::reloadAll()
auto iter = mReloadables.cbegin(); auto iter = mReloadables.cbegin();
while (iter != mReloadables.cend()) { while (iter != mReloadables.cend()) {
if (!iter->expired()) { if (!iter->expired()) {
iter->lock()->reload(sInstance); iter->lock()->reload(getInstance());
++iter; ++iter;
} }
else { else {

View file

@ -28,14 +28,14 @@ class ResourceManager;
class IReloadable class IReloadable
{ {
public: public:
virtual void unload(std::shared_ptr<ResourceManager>& rm) = 0; virtual void unload(ResourceManager& rm) = 0;
virtual void reload(std::shared_ptr<ResourceManager>& rm) = 0; virtual void reload(ResourceManager& rm) = 0;
}; };
class ResourceManager class ResourceManager
{ {
public: public:
static std::shared_ptr<ResourceManager>& getInstance(); static ResourceManager& getInstance();
void addReloadable(std::weak_ptr<IReloadable> reloadable); void addReloadable(std::weak_ptr<IReloadable> reloadable);
@ -47,9 +47,8 @@ public:
bool fileExists(const std::string& path) const; bool fileExists(const std::string& path) const;
private: private:
ResourceManager() {} ResourceManager() noexcept {}
static std::shared_ptr<ResourceManager> sInstance;
std::list<std::weak_ptr<IReloadable>> mReloadables; std::list<std::weak_ptr<IReloadable>> mReloadables;
ResourceData loadFile(const std::string& path) const; ResourceData loadFile(const std::string& path) const;

View file

@ -179,8 +179,7 @@ bool TextureData::load()
// Need to load. See if there is a file. // Need to load. See if there is a file.
if (!mPath.empty()) { if (!mPath.empty()) {
std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance(); const ResourceData& data = ResourceManager::getInstance().getFileData(mPath);
const ResourceData& data = rm->getFileData(mPath);
// Is it an SVG? // Is it an SVG?
if (Utils::String::toLower(mPath.substr(mPath.size() - 4, std::string::npos)) == ".svg") { if (Utils::String::toLower(mPath.substr(mPath.size() - 4, std::string::npos)) == ".svg") {
mScalable = true; mScalable = true;

View file

@ -148,14 +148,12 @@ std::shared_ptr<TextureResource> TextureResource::get(const std::string& path,
bool linearMagnify, bool linearMagnify,
bool forceRasterization) bool forceRasterization)
{ {
std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance();
const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path); const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path);
if (canonicalPath.empty()) { if (canonicalPath.empty()) {
std::shared_ptr<TextureResource> tex( std::shared_ptr<TextureResource> tex(
new TextureResource("", tile, false, linearMagnify, forceRasterization)); new TextureResource("", tile, false, linearMagnify, forceRasterization));
// Make sure we get properly deinitialized even though we do nothing on reinitialization. // Make sure we get properly deinitialized even though we do nothing on reinitialization.
rm->addReloadable(tex); ResourceManager::getInstance().addReloadable(tex);
return tex; return tex;
} }
@ -182,7 +180,7 @@ std::shared_ptr<TextureResource> TextureResource::get(const std::string& path,
} }
// Add it to the reloadable list. // 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. // Force load it if necessary. Note that it may get dumped from VRAM if we run low.
if (forceLoad) { if (forceLoad) {
@ -241,7 +239,7 @@ size_t TextureResource::getTotalTextureSize()
return total; return total;
} }
void TextureResource::unload(std::shared_ptr<ResourceManager>& /*rm*/) void TextureResource::unload(ResourceManager& /*rm*/)
{ {
// Release the texture's resources. // Release the texture's resources.
std::shared_ptr<TextureData> data; std::shared_ptr<TextureData> data;
@ -254,7 +252,7 @@ void TextureResource::unload(std::shared_ptr<ResourceManager>& /*rm*/)
data->releaseRAM(); data->releaseRAM();
} }
void TextureResource::reload(std::shared_ptr<ResourceManager>& /*rm*/) void TextureResource::reload(ResourceManager& /*rm*/)
{ {
// For dynamically loaded textures the texture manager will load them on demand. // For dynamically loaded textures the texture manager will load them on demand.
// For manually loaded textures we have to reload them here. // For manually loaded textures we have to reload them here.

View file

@ -68,8 +68,8 @@ protected:
bool dynamic, bool dynamic,
bool linearMagnify, bool linearMagnify,
bool forceRasterization); bool forceRasterization);
virtual void unload(std::shared_ptr<ResourceManager>& rm); virtual void unload(ResourceManager& rm);
virtual void reload(std::shared_ptr<ResourceManager>& rm); virtual void reload(ResourceManager& rm);
private: private:
// mTextureData is used for textures that are not loaded from a file - these ones // mTextureData is used for textures that are not loaded from a file - these ones