diff options
-rw-r--r-- | src/citra/emu_window/emu_window_sdl2.cpp | 4 | ||||
-rw-r--r-- | src/citra_qt/bootmanager.cpp | 4 | ||||
-rw-r--r-- | src/citra_qt/game_list.cpp | 48 | ||||
-rw-r--r-- | src/citra_qt/game_list.h | 4 | ||||
-rw-r--r-- | src/citra_qt/main.cpp | 3 | ||||
-rw-r--r-- | src/common/CMakeLists.txt | 23 | ||||
-rw-r--r-- | src/common/scm_rev.cpp.in | 2 | ||||
-rw-r--r-- | src/common/scm_rev.h | 1 |
8 files changed, 83 insertions, 6 deletions
diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp index 81a3abe3f..00d00905a 100644 --- a/src/citra/emu_window/emu_window_sdl2.cpp +++ b/src/citra/emu_window/emu_window_sdl2.cpp @@ -79,8 +79,8 @@ EmuWindow_SDL2::EmuWindow_SDL2() { SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); - std::string window_title = - Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); + std::string window_title = Common::StringFromFormat("Citra %s| %s-%s ", Common::g_build_name, + Common::g_scm_branch, Common::g_scm_desc); render_window = SDL_CreateWindow( window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, // x position diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 948db384d..69d18cf0c 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -101,8 +101,8 @@ private: GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) : QWidget(parent), child(nullptr), keyboard_id(0), emu_thread(emu_thread) { - std::string window_title = - Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); + std::string window_title = Common::StringFromFormat("Citra %s| %s-%s", Common::g_build_name, + Common::g_scm_branch, Common::g_scm_desc); setWindowTitle(QString::fromStdString(window_title)); keyboard_id = KeyMap::NewDeviceId(); diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp index 222c82b1c..db6f920ff 100644 --- a/src/citra_qt/game_list.cpp +++ b/src/citra_qt/game_list.cpp @@ -39,6 +39,7 @@ GameList::GameList(QWidget* parent) : QWidget{parent} { connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry); connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu); + connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); // We must register all custom types with the Qt Automoc system so that we are able to use it // with signals/slots. In this case, QList falls under the umbrells of custom types. @@ -103,6 +104,12 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) { item_model->removeRows(0, item_model->rowCount()); emit ShouldCancelWorker(); + + auto watch_dirs = watcher.directories(); + if (!watch_dirs.isEmpty()) { + watcher.removePaths(watch_dirs); + } + UpdateWatcherList(dir_path.toStdString(), deep_scan ? 256 : 0); GameListWorker* worker = new GameListWorker(dir_path, deep_scan); connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection); @@ -140,6 +147,45 @@ static bool HasSupportedFileExtension(const std::string& file_name) { return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); } +void GameList::RefreshGameDirectory() { + if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) { + LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list."); + PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); + } +} + +/** + * Adds the game list folder to the QFileSystemWatcher to check for updates. + * + * The file watcher will fire off an update to the game list when a change is detected in the game + * list folder. + * + * Notice: This method is run on the UI thread because QFileSystemWatcher is not thread safe and + * this function is fast enough to not stall the UI thread. If performance is an issue, it should + * be moved to another thread and properly locked to prevent concurrency issues. + * + * @param dir folder to check for changes in + * @param recursion 0 if recursion is disabled. Any positive number passed to this will add each + * directory recursively to the watcher and will update the file list if any of the folders + * change. The number determines how deep the recursion should traverse. + */ +void GameList::UpdateWatcherList(const std::string& dir, unsigned int recursion) { + const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory, + const std::string& virtual_name) -> bool { + std::string physical_name = directory + DIR_SEP + virtual_name; + + if (FileUtil::IsDirectory(physical_name)) { + UpdateWatcherList(physical_name, recursion - 1); + } + return true; + }; + + watcher.addPath(QString::fromStdString(dir)); + if (recursion > 0) { + FileUtil::ForeachDirectoryEntry(nullptr, dir, callback); + } +} + void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) { const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory, const std::string& virtual_name) -> bool { @@ -182,6 +228,6 @@ void GameListWorker::run() { } void GameListWorker::Cancel() { - disconnect(this, nullptr, nullptr, nullptr); + this->disconnect(); stop_processing = true; } diff --git a/src/citra_qt/game_list.h b/src/citra_qt/game_list.h index e6b7eea0b..b141fa3a5 100644 --- a/src/citra_qt/game_list.h +++ b/src/citra_qt/game_list.h @@ -4,6 +4,7 @@ #pragma once +#include <QFileSystemWatcher> #include <QModelIndex> #include <QSettings> #include <QStandardItem> @@ -46,8 +47,11 @@ private: void DonePopulating(); void PopupContextMenu(const QPoint& menu_location); + void UpdateWatcherList(const std::string& path, unsigned int recursion); + void RefreshGameDirectory(); QTreeView* tree_view = nullptr; QStandardItemModel* item_model = nullptr; GameListWorker* current_worker = nullptr; + QFileSystemWatcher watcher; }; diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 513da8001..7a80af890 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -69,7 +69,8 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { ConnectMenuEvents(); ConnectWidgetEvents(); - setWindowTitle(QString("Citra | %1-%2").arg(Common::g_scm_branch, Common::g_scm_desc)); + setWindowTitle(QString("Citra %1| %2-%3") + .arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc)); show(); game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 592911c2b..26c83efda 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,4 +1,27 @@ # Generate cpp with Git revision from template +# Also if this is a CI build, add the build name (ie: Nightly, Bleeding Edge) to the scm_rev file as well +set(REPO_NAME "") +if ($ENV{CI}) + if ($ENV{TRAVIS}) + set(BUILD_REPOSITORY $ENV{TRAVIS_REPO_SLUG}) + elseif($ENV{APPVEYOR}) + set(BUILD_REPOSITORY $ENV{APPVEYOR_REPO_NAME}) + endif() + # regex capture the string nightly or bleeding-edge into CMAKE_MATCH_1 + string(REGEX MATCH "citra-emu/citra-?(.*)" OUTVAR ${BUILD_REPOSITORY}) + if (${CMAKE_MATCH_COUNT} GREATER 0) + # capitalize the first letter of each word in the repo name. + string(REPLACE "-" ";" REPO_NAME_LIST ${CMAKE_MATCH_1}) + foreach(WORD ${REPO_NAME_LIST}) + string(SUBSTRING ${WORD} 0 1 FIRST_LETTER) + string(SUBSTRING ${WORD} 1 -1 REMAINDER) + string(TOUPPER ${FIRST_LETTER} FIRST_LETTER) + # this leaves a trailing space on the last word, but we actually want that + # because of how its styled in the title bar. + set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER} ") + endforeach() + endif() +endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp" @ONLY) set(SRCS diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in index 79b404bb8..0080db5d5 100644 --- a/src/common/scm_rev.cpp.in +++ b/src/common/scm_rev.cpp.in @@ -7,12 +7,14 @@ #define GIT_REV "@GIT_REV@" #define GIT_BRANCH "@GIT_BRANCH@" #define GIT_DESC "@GIT_DESC@" +#define BUILD_NAME "@REPO_NAME@" namespace Common { const char g_scm_rev[] = GIT_REV; const char g_scm_branch[] = GIT_BRANCH; const char g_scm_desc[] = GIT_DESC; +const char g_build_name[] = BUILD_NAME; } // namespace diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h index 0ef190afa..e22389803 100644 --- a/src/common/scm_rev.h +++ b/src/common/scm_rev.h @@ -9,5 +9,6 @@ namespace Common { extern const char g_scm_rev[]; extern const char g_scm_branch[]; extern const char g_scm_desc[]; +extern const char g_build_name[]; } // namespace |