From a1dd1a77c960b168e77e106f135e69e93d2e0994 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Tue, 3 Jul 2018 18:54:53 +0200 Subject: [PATCH] logic: allow the user to discard an aborted indexer run * keep old database on filesystem while indexing * migrate old ".coatiproject" settings to new ".srctrlprj" extension when loading project * send new errors in MessageErrorCountUpdate after injecting * recheck filepath exist() in FileSystem's remove, rename, copy and create functions * updated tasks to new "override" policy --- src/lib/Application.cpp | 65 ++++++-- src/lib/Application.h | 3 +- src/lib/CMakeLists.txt | 2 + .../component/controller/ErrorController.cpp | 22 ++- src/lib/component/view/DialogView.cpp | 3 +- src/lib/component/view/DialogView.h | 9 +- src/lib/data/TaskCleanStorage.h | 8 +- src/lib/data/TaskFinishParsing.cpp | 52 +++--- src/lib/data/TaskFinishParsing.h | 19 +-- src/lib/data/TaskInjectStorage.h | 8 +- src/lib/data/TaskMergeStorages.h | 8 +- .../data/TaskShowUnknownProgressDialog.cpp | 4 - src/lib/data/TaskShowUnknownProgressDialog.h | 10 +- src/lib/data/storage/PersistentStorage.cpp | 18 ++- src/lib/data/storage/PersistentStorage.h | 5 +- src/lib/project/Project.cpp | 151 ++++++++++++++---- src/lib/project/Project.h | 6 + src/lib/settings/ProjectSettings.cpp | 4 +- src/lib/utility/file/FileSystem.cpp | 14 +- .../MessageFilterErrorCountUpdate.h | 9 ++ .../type/error/MessageErrorCountUpdate.h | 9 +- src/lib/utility/scheduling/TaskDecorator.cpp | 4 - src/lib/utility/scheduling/TaskDecorator.h | 3 +- .../utility/scheduling/TaskDecoratorDelay.h | 10 +- .../utility/scheduling/TaskDecoratorRepeat.h | 8 +- src/lib/utility/scheduling/TaskFindValue.cpp | 26 +++ src/lib/utility/scheduling/TaskFindValue.h | 25 +++ src/lib/utility/scheduling/TaskGroup.cpp | 4 - src/lib/utility/scheduling/TaskGroup.h | 3 +- .../utility/scheduling/TaskGroupParallel.h | 12 +- .../utility/scheduling/TaskGroupSelector.cpp | 4 - .../utility/scheduling/TaskGroupSelector.h | 11 +- .../utility/scheduling/TaskGroupSequence.cpp | 4 - .../utility/scheduling/TaskGroupSequence.h | 11 +- src/lib/utility/scheduling/TaskLambda.cpp | 4 - src/lib/utility/scheduling/TaskLambda.h | 9 +- .../scheduling/TaskReturnSuccessWhile.h | 8 +- src/lib/utility/scheduling/TaskSetValue.h | 8 +- src/lib_gui/qt/view/QtDialogView.cpp | 32 +++- src/lib_gui/qt/view/QtDialogView.h | 22 +-- src/lib_gui/qt/window/QtIndexingDialog.cpp | 12 +- 41 files changed, 434 insertions(+), 215 deletions(-) create mode 100644 src/lib/utility/scheduling/TaskFindValue.cpp create mode 100644 src/lib/utility/scheduling/TaskFindValue.h diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index f4fdaf5a..f5acd394 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -1,5 +1,17 @@ #include "Application.h" +#include "component/controller/IDECommunicationController.h" +#include "component/NetworkFactory.h" +#include "component/view/DialogView.h" +#include "component/view/GraphViewStyle.h" +#include "component/view/MainView.h" +#include "component/view/ViewFactory.h" +#include "data/storage/StorageCache.h" +#include "LicenseChecker.h" +#include "settings/ApplicationSettings.h" +#include "settings/ProjectSettings.h" +#include "settings/ColorScheme.h" +#include "utility/file/FileSystem.h" #include "utility/interprocess/SharedMemoryGarbageCollector.h" #include "utility/logging/logging.h" #include "utility/logging/LogManager.h" @@ -16,18 +28,6 @@ #include "utility/utilityString.h" #include "utility/utilityUuid.h" #include "utility/Version.h" - -#include "component/controller/IDECommunicationController.h" -#include "component/NetworkFactory.h" -#include "component/view/DialogView.h" -#include "component/view/GraphViewStyle.h" -#include "component/view/MainView.h" -#include "component/view/ViewFactory.h" -#include "data/storage/StorageCache.h" -#include "LicenseChecker.h" -#include "settings/ApplicationSettings.h" -#include "settings/ProjectSettings.h" -#include "settings/ColorScheme.h" #include "UpdateChecker.h" std::shared_ptr Application::s_instance; @@ -85,6 +85,9 @@ std::shared_ptr Application::getInstance() void Application::destroyInstance() { + MessageQueue::getInstance()->stopMessageLoop(); + TaskScheduler::getInstance()->stopSchedulerLoop(); + s_instance.reset(); } @@ -126,9 +129,6 @@ Application::Application(bool withGUI) Application::~Application() { - MessageQueue::getInstance()->stopMessageLoop(); - TaskScheduler::getInstance()->stopSchedulerLoop(); - if (m_hasGUI) { m_mainView->saveLayout(); @@ -191,9 +191,12 @@ void Application::updateBookmarks(const std::vector>& m_mainView->updateBookmarksMenu(bookmarks); } -void Application::createAndLoadProject(const FilePath& projectSettingsFilePath) +void Application::createAndLoadProject(FilePath projectSettingsFilePath) { MessageStatus(L"Loading Project: " + projectSettingsFilePath.wstr(), false, true).dispatch(); + + projectSettingsFilePath = migrateProjectSettings(projectSettingsFilePath); + try { updateRecentProjects(projectSettingsFilePath); @@ -354,6 +357,36 @@ void Application::handleMessage(MessageWindowFocus* message) } } +FilePath Application::migrateProjectSettings(const FilePath& projectSettingsFilePath) const +{ + if (projectSettingsFilePath.extension() == L".coatiproject") + { + MessageStatus(L"Migrating deprecated project file extension \".coatiproject\" to new file extension \".srctrlprj\"").dispatch(); + const FilePath newSettingsPath = projectSettingsFilePath.replaceExtension(Project::PROJECT_FILE_EXTENSION); + { + FileSystem::rename(projectSettingsFilePath, newSettingsPath); + const FilePath oldDbPath = projectSettingsFilePath.replaceExtension(L"coatidb"); + if (oldDbPath.exists()) + { + FileSystem::rename(oldDbPath, oldDbPath.replaceExtension(L"srctrldb")); + } + } + { + ApplicationSettings* appSettings = ApplicationSettings::getInstance().get(); + std::vector recentProjects = appSettings->getRecentProjects(); + std::vector::iterator it = std::find(recentProjects.begin(), recentProjects.end(), projectSettingsFilePath); + if (it != recentProjects.end()) + { + recentProjects.erase(it); + } + appSettings->setRecentProjects(recentProjects); + appSettings->save(UserPaths::getAppSettingsPath()); + } + return newSettingsPath; + } + return projectSettingsFilePath; +} + void Application::startMessagingAndScheduling() { TaskScheduler::getInstance()->startSchedulerLoopThreaded(); diff --git a/src/lib/Application.h b/src/lib/Application.h index 293d6800..2315b687 100644 --- a/src/lib/Application.h +++ b/src/lib/Application.h @@ -47,7 +47,7 @@ public: const std::shared_ptr getCurrentProject(); - void createAndLoadProject(const FilePath& projectSettingsFilePath); + void createAndLoadProject(FilePath projectSettingsFilePath); void refreshProject(RefreshMode refreshMode); bool hasGUI(); @@ -74,6 +74,7 @@ private: virtual void handleMessage(MessageSwitchColorScheme* message); virtual void handleMessage(MessageWindowFocus* message); + FilePath migrateProjectSettings(const FilePath& projectSettingsFilePath) const; void startMessagingAndScheduling(); void updateRecentProjects(const FilePath& projectSettingsFilePath); diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 7d8a93b7..2f3e7a82 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -519,6 +519,8 @@ add_files( utility/scheduling/TaskDecoratorRepeat.h utility/scheduling/TaskDecoratorDelay.cpp utility/scheduling/TaskDecoratorDelay.h + utility/scheduling/TaskFindValue.cpp + utility/scheduling/TaskFindValue.h utility/scheduling/TaskGroup.cpp utility/scheduling/TaskGroup.h utility/scheduling/TaskGroupParallel.cpp diff --git a/src/lib/component/controller/ErrorController.cpp b/src/lib/component/controller/ErrorController.cpp index 18528c1f..68edafba 100644 --- a/src/lib/component/controller/ErrorController.cpp +++ b/src/lib/component/controller/ErrorController.cpp @@ -84,16 +84,22 @@ void ErrorController::handleMessage(MessageErrorCountUpdate* message) if (room > 0) { filter.limit = 0; - std::vector errors = m_storageAccess->getErrorsLimited(filter); - ErrorCountInfo errorCount(errors); + std::vector errors; - auto startIt = errors.begin() + m_errorCount; - errors = std::vector( - startIt, - (errors.size() < m_errorCount + room) ? errors.end() : startIt + room - ); + for (const ErrorInfo& error : message->newErrors) + { + if (filter.filter(error)) + { + errors.push_back(error); - getView()->addErrors(errors, errorCount, true); + if (room > 0 && errors.size() >= size_t(room)) + { + break; + } + } + } + + getView()->addErrors(errors, message->errorCount, true); getView()->showDockWidget(); m_errorCount += errors.size(); diff --git a/src/lib/component/view/DialogView.cpp b/src/lib/component/view/DialogView.cpp index 43069815..38fcd5ce 100644 --- a/src/lib/component/view/DialogView.cpp +++ b/src/lib/component/view/DialogView.cpp @@ -35,10 +35,11 @@ void DialogView::updateIndexingDialog( { } -void DialogView::finishedIndexingDialog( +DatabasePolicy DialogView::finishedIndexingDialog( size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo, bool interrupted) { + return DATABASE_POLICY_KEEP; // used in non-gui mode } void DialogView::hideDialogs(bool unblockUI) diff --git a/src/lib/component/view/DialogView.h b/src/lib/component/view/DialogView.h index 9d1a0c84..14bdc05a 100644 --- a/src/lib/component/view/DialogView.h +++ b/src/lib/component/view/DialogView.h @@ -10,6 +10,13 @@ class Project; class StorageAccess; +enum DatabasePolicy +{ + DATABASE_POLICY_KEEP, + DATABASE_POLICY_DISCARD, + DATABASE_POLICY_UNKNOWN +}; + class DialogView { public: @@ -26,7 +33,7 @@ public: Project* project, const std::vector& enabledModes, const RefreshInfo& info); virtual void updateIndexingDialog( size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const FilePath& sourcePath); - virtual void finishedIndexingDialog( + virtual DatabasePolicy finishedIndexingDialog( size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo, bool interrupted); diff --git a/src/lib/data/TaskCleanStorage.h b/src/lib/data/TaskCleanStorage.h index d03fec52..f23429cb 100644 --- a/src/lib/data/TaskCleanStorage.h +++ b/src/lib/data/TaskCleanStorage.h @@ -21,10 +21,10 @@ public: ); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; PersistentStorage* m_storage; std::vector m_filePaths; diff --git a/src/lib/data/TaskFinishParsing.cpp b/src/lib/data/TaskFinishParsing.cpp index 9dd9967e..ec3e56ed 100644 --- a/src/lib/data/TaskFinishParsing.cpp +++ b/src/lib/data/TaskFinishParsing.cpp @@ -10,17 +10,21 @@ #include "utility/utilityString.h" #include "Application.h" -TaskFinishParsing::TaskFinishParsing( - PersistentStorage* storage, - StorageAccess* storageAccess -) +TaskFinishParsing::TaskFinishParsing(std::shared_ptr storage) : m_storage(storage) - , m_storageAccess(storageAccess) { } -TaskFinishParsing::~TaskFinishParsing() +void TaskFinishParsing::terminate() { + Application* app = Application::getInstance().get(); + if (app) + { + app->getDialogView()->hideDialogs(); + } + + MessageStatus(L"An unknown exception was thrown during indexing.", true, false).dispatch(); + MessageFinishedParsing().dispatch(); } void TaskFinishParsing::doEnter(std::shared_ptr blackboard) @@ -36,12 +40,7 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr blackboa dialogView->showUnknownProgressDialog(L"Finish Indexing", L"Optimizing database"); m_storage->optimizeMemory(); - - dialogView->showUnknownProgressDialog(L"Finish Indexing", L"Building caches"); - m_storage->buildCaches(); - dialogView->hideUnknownProgressDialog(); - MessageFinishedParsing().dispatch(); float time = utility::duration(start); @@ -68,7 +67,7 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr blackboa bool interruptedIndexing = false; blackboard->get("interrupted_indexing", interruptedIndexing); - ErrorCountInfo errorInfo = m_storageAccess->getErrorCount(); + ErrorCountInfo errorInfo = m_storage->getErrorCount(); std::wstring status; status += L"Finished indexing: "; @@ -81,8 +80,8 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr blackboa } MessageStatus(status, false, false).dispatch(); - StorageStats stats = m_storageAccess->getStorageStats(); - dialogView->finishedIndexingDialog( + StorageStats stats = m_storage->getStorageStats(); + DatabasePolicy policy = dialogView->finishedIndexingDialog( indexedSourceFileCount, sourceFileCount, stats.completedFileCount, @@ -92,6 +91,19 @@ Task::TaskState TaskFinishParsing::doUpdate(std::shared_ptr blackboa interruptedIndexing ); + { + std::lock_guard lock(blackboard->getMutex()); + + if (policy == DATABASE_POLICY_KEEP) + { + blackboard->set("keep_database", true); + } + else if (policy == DATABASE_POLICY_DISCARD) + { + blackboard->set("discard_database", true); + } + } + return STATE_SUCCESS; } @@ -102,15 +114,3 @@ void TaskFinishParsing::doExit(std::shared_ptr blackboard) void TaskFinishParsing::doReset(std::shared_ptr blackboard) { } - -void TaskFinishParsing::terminate() -{ - Application* app = Application::getInstance().get(); - if (app) - { - app->getDialogView()->hideDialogs(); - } - - MessageStatus(L"An unknown exception was thrown during indexing.", true, false).dispatch(); - MessageFinishedParsing().dispatch(); -} diff --git a/src/lib/data/TaskFinishParsing.h b/src/lib/data/TaskFinishParsing.h index 177d1f07..e3f2baf4 100644 --- a/src/lib/data/TaskFinishParsing.h +++ b/src/lib/data/TaskFinishParsing.h @@ -14,22 +14,17 @@ class TaskFinishParsing : public Task { public: - TaskFinishParsing( - PersistentStorage* storage, - StorageAccess* storageAccess - ); + TaskFinishParsing(std::shared_ptr storage); - virtual ~TaskFinishParsing(); + void terminate() override; private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); - virtual void terminate(); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; - PersistentStorage* m_storage; - StorageAccess* m_storageAccess; + std::shared_ptr m_storage; }; #endif // TASK_FINISH_PARSING_H diff --git a/src/lib/data/TaskInjectStorage.h b/src/lib/data/TaskInjectStorage.h index 0f4bf413..ad76b1ec 100644 --- a/src/lib/data/TaskInjectStorage.h +++ b/src/lib/data/TaskInjectStorage.h @@ -18,10 +18,10 @@ public: ); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; std::shared_ptr m_storageProvider; std::shared_ptr m_target; diff --git a/src/lib/data/TaskMergeStorages.h b/src/lib/data/TaskMergeStorages.h index 8d191cea..04583017 100644 --- a/src/lib/data/TaskMergeStorages.h +++ b/src/lib/data/TaskMergeStorages.h @@ -16,10 +16,10 @@ public: ); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; std::shared_ptr m_storageProvider; }; diff --git a/src/lib/data/TaskShowUnknownProgressDialog.cpp b/src/lib/data/TaskShowUnknownProgressDialog.cpp index 3df27a31..084858ec 100644 --- a/src/lib/data/TaskShowUnknownProgressDialog.cpp +++ b/src/lib/data/TaskShowUnknownProgressDialog.cpp @@ -12,10 +12,6 @@ TaskShowUnknownProgressDialog::TaskShowUnknownProgressDialog( { } -TaskShowUnknownProgressDialog::~TaskShowUnknownProgressDialog() -{ -} - void TaskShowUnknownProgressDialog::doEnter(std::shared_ptr blackboard) { } diff --git a/src/lib/data/TaskShowUnknownProgressDialog.h b/src/lib/data/TaskShowUnknownProgressDialog.h index 52bfc79f..cdfab706 100644 --- a/src/lib/data/TaskShowUnknownProgressDialog.h +++ b/src/lib/data/TaskShowUnknownProgressDialog.h @@ -14,13 +14,11 @@ public: const std::wstring& message ); - virtual ~TaskShowUnknownProgressDialog(); - private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; const std::wstring m_title; const std::wstring m_message; diff --git a/src/lib/data/storage/PersistentStorage.cpp b/src/lib/data/storage/PersistentStorage.cpp index 1ac8213d..4a0e22f5 100644 --- a/src/lib/data/storage/PersistentStorage.cpp +++ b/src/lib/data/storage/PersistentStorage.cpp @@ -233,9 +233,12 @@ void PersistentStorage::finishInjection() { m_sqliteIndexStorage.commitTransaction(); - if (m_preInjectionErrorCount != m_sqliteIndexStorage.getErrorCount()) + std::vector errors = m_sqliteIndexStorage.getAll(); + if (m_preInjectionErrorCount < errors.size()) { - MessageErrorCountUpdate(getErrorCount()).dispatch(); + ErrorCountInfo errorCount(errors); + errors.erase(errors.begin(), errors.begin() + m_preInjectionErrorCount); + MessageErrorCountUpdate(errorCount, errors).dispatch(); } } @@ -244,11 +247,16 @@ void PersistentStorage::setMode(const SqliteIndexStorage::StorageModeType mode) m_sqliteIndexStorage.setMode(mode); } -FilePath PersistentStorage::getDbFilePath() const +FilePath PersistentStorage::getIndexDbFilePath() const { return m_sqliteIndexStorage.getDbFilePath(); } +FilePath PersistentStorage::getBookmarkDbFilePath() const +{ + return m_sqliteBookmarkStorage.getDbFilePath(); +} + bool PersistentStorage::isEmpty() const { return m_sqliteIndexStorage.isEmpty(); @@ -430,7 +438,7 @@ void PersistentStorage::optimizeMemory() m_sqliteIndexStorage.setTime(); m_sqliteIndexStorage.optimizeMemory(); - + m_sqliteBookmarkStorage.optimizeMemory(); } @@ -2758,7 +2766,7 @@ void PersistentStorage::buildSearchIndex() { TRACE(); - const FilePath dbPath = getDbFilePath(); + const FilePath dbPath = getIndexDbFilePath(); for (StorageNode& node : m_sqliteIndexStorage.getAll()) { diff --git a/src/lib/data/storage/PersistentStorage.h b/src/lib/data/storage/PersistentStorage.h index 007a1a72..c4925b41 100644 --- a/src/lib/data/storage/PersistentStorage.h +++ b/src/lib/data/storage/PersistentStorage.h @@ -47,7 +47,8 @@ public: void setMode(const SqliteIndexStorage::StorageModeType mode); - FilePath getDbFilePath() const; + FilePath getIndexDbFilePath() const; + FilePath getBookmarkDbFilePath() const; bool isEmpty() const; bool isIncompatible() const; @@ -190,7 +191,7 @@ private: void buildMemberEdgeIdOrderMap(); void buildHierarchyCache(); - int m_preInjectionErrorCount = 0; + size_t m_preInjectionErrorCount = 0; SearchIndex m_commandIndex; SearchIndex m_symbolIndex; diff --git a/src/lib/project/Project.cpp b/src/lib/project/Project.cpp index 04ee3b30..5fd0ef27 100644 --- a/src/lib/project/Project.cpp +++ b/src/lib/project/Project.cpp @@ -27,9 +27,11 @@ #include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageStatus.h" #include "utility/scheduling/TaskDecoratorRepeat.h" +#include "utility/scheduling/TaskFindValue.h" #include "utility/scheduling/TaskGroupSelector.h" #include "utility/scheduling/TaskGroupSequence.h" #include "utility/scheduling/TaskGroupParallel.h" +#include "utility/scheduling/TaskLambda.h" #include "utility/scheduling/TaskReturnSuccessWhile.h" #include "utility/scheduling/TaskSetValue.h" #include "utility/ScopedFunctor.h" @@ -38,6 +40,12 @@ #include "utility/utilityApp.h" #include "utility/utilityFile.h" #include "utility/utilityString.h" +#include "Application.h" + +const std::wstring Project::PROJECT_FILE_EXTENSION = L".srctrlprj"; +const std::wstring Project::BOOKMARK_DB_FILE_EXTENSION = L".srctrlbm"; +const std::wstring Project::INDEX_DB_FILE_EXTENSION = L".srctrldb"; +const std::wstring Project::TEMP_INDEX_DB_FILE_EXTENSION = L".srctrldb_tmp"; Project::Project(std::shared_ptr settings, StorageCache* storageCache, bool hasGUI) : m_settings(settings) @@ -76,22 +84,49 @@ void Project::setStateOutdated() void Project::load() { + m_storageCache->clear(); m_storageCache->setSubject(nullptr); - bool loadedSettings = m_settings->reload(); - - if (!loadedSettings) + if (!m_settings->reload()) { return; } const FilePath projectSettingsPath = m_settings->getFilePath(); - const std::wstring dbExtension = (projectSettingsPath.extension() == L".coatiproject" ? L"coatidb" : L"srctrldb"); - const FilePath dbPath = FilePath(projectSettingsPath).replaceExtension(dbExtension); - const FilePath bookmarkPath = FilePath(projectSettingsPath).replaceExtension(L"srctrlbm"); + { + const FilePath dbPath = projectSettingsPath.replaceExtension(INDEX_DB_FILE_EXTENSION); + const FilePath tempDbPath = projectSettingsPath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); + if (tempDbPath.exists()) + { + if (dbPath.exists()) + { + if (Application::getInstance()->getDialogView()->confirm( + "Sourcetrail has been closed unexpectedly while indexing this project. You can either choose to keep the data that has " + "already been indexed or discard that data and restore the state of your project before indexing?", { "Keep and Continue", "Discard and Restore" }) == 0) + { + LOG_INFO("Switching to temporary indexing data on user's decision"); + FileSystem::remove(dbPath); + FileSystem::rename(tempDbPath, dbPath); + } + else + { + LOG_INFO("Discarding temporary indexing data on user's decision"); + FileSystem::remove(tempDbPath); + } + } + else + { + LOG_INFO("Switching to temporary indexing data because no other persistent data was found"); + FileSystem::rename(tempDbPath, dbPath); + } + } + } - m_storage = std::make_shared(dbPath, bookmarkPath); + m_storage = std::make_shared( + projectSettingsPath.replaceExtension(INDEX_DB_FILE_EXTENSION), + projectSettingsPath.replaceExtension(BOOKMARK_DB_FILE_EXTENSION) + ); bool canLoad = false; @@ -233,10 +268,7 @@ void Project::refresh(RefreshMode refreshMode, DialogView* dialogView) if (question.size() && m_hasGUI) { - std::vector options = { "Yes", "No" }; - int result = dialogView->confirm(question, options); - - if (result == 1) + if (dialogView->confirm(question, { "Yes", "No" }) == 1) { return; } @@ -245,14 +277,10 @@ void Project::refresh(RefreshMode refreshMode, DialogView* dialogView) if (ApplicationSettings::getInstance()->getLoggingEnabled() && ApplicationSettings::getInstance()->getVerboseIndexerLoggingEnabled() && m_hasGUI) { - std::vector options = { "Yes", "No" }; - int result = dialogView->confirm( - "Warning: You are about to index your project with the \"verbose indexer logging\" setting " - "enabled. This will cause a significant slowdown in indexing performance. Do you want to proceed?", - options - ); - - if (result == 1) + if (dialogView->confirm( + "Warning: You are about to index your project with the \"verbose indexer logging\" setting " + "enabled. This will cause a significant slowdown in indexing performance. Do you want to proceed?", + { "Yes", "No" }) == 1) { return; } @@ -346,25 +374,33 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView) dialogView->showUnknownProgressDialog(L"Preparing Indexing", L"Setting up Indexers"); + m_storageCache->clear(); + m_storageCache->setSubject(m_storage.get()); + + const FilePath indexDbFilePath = m_storage->getIndexDbFilePath(); + const FilePath tempIndexDbFilePath = indexDbFilePath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); + + if (info.mode != REFRESH_ALL_FILES) + { + FileSystem::copyFile(indexDbFilePath, tempIndexDbFilePath); + } + + std::shared_ptr tempStorage = std::make_shared(tempIndexDbFilePath, m_storage->getBookmarkDbFilePath()); + tempStorage->setup(); + std::shared_ptr taskSequential = std::make_shared(); - if (info.mode == REFRESH_ALL_FILES) - { - m_storage->clear(); - } - else if (info.filesToClear.size() || info.nonIndexedFilesToClear.size()) + if (info.mode != REFRESH_ALL_FILES && (info.filesToClear.size() || info.nonIndexedFilesToClear.size())) { taskSequential->addTask(std::make_shared( - m_storage.get(), + tempStorage.get(), utility::toVector(utility::concat(info.filesToClear, info.nonIndexedFilesToClear)), info.mode == REFRESH_UPDATED_AND_INCOMPLETE_FILES )); } - m_storageCache->clear(); - - m_storage->setProjectSettingsText(TextAccess::createFromFile(getProjectSettingsFilePath())->getText()); - m_storage->updateVersion(); + tempStorage->setProjectSettingsText(TextAccess::createFromFile(getProjectSettingsFilePath())->getText()); + tempStorage->updateVersion(); std::shared_ptr indexerCommandList = std::make_shared(); for (const std::shared_ptr& sourceGroup : m_sourceGroups) @@ -402,7 +438,7 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView) taskSequential->addTask(std::make_shared>("indexed_source_file_count", 0)); taskSequential->addTask(std::make_shared>("indexer_count", 0)); - std::shared_ptr taskParserWrapper = std::make_shared(m_storage.get()); + std::shared_ptr taskParserWrapper = std::make_shared(tempStorage.get()); taskSequential->addTask(taskParserWrapper); std::shared_ptr taskParallelIndexing = std::make_shared(); @@ -443,7 +479,7 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView) // stopping when indexer count is zero, regardless wether there are still storages left to insert. std::make_shared>("indexer_count", TaskReturnSuccessWhile::CONDITION_GREATER_THAN, 0), std::make_shared()->addChildTasks( - std::make_shared(storageProvider, m_storage), + std::make_shared(storageProvider, tempStorage), // continuing when indexer count is greater than zero, even if there are no storages right now. std::make_shared>("indexer_count", TaskReturnSuccessWhile::CONDITION_GREATER_THAN, 0) ) @@ -459,7 +495,7 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView) // add task that injects the remaining intermediate storages into the persistent storage taskSequential->addTask( std::make_shared(TaskDecoratorRepeat::CONDITION_WHILE_SUCCESS, Task::STATE_SUCCESS)->addChildTask( - std::make_shared(storageProvider, m_storage) + std::make_shared(storageProvider, tempStorage) ) ); } @@ -468,12 +504,59 @@ void Project::buildIndex(const RefreshInfo& info, DialogView* dialogView) dialogView->hideUnknownProgressDialog(); } - taskSequential->addTask(std::make_shared(m_storage.get(), m_storageCache)); + taskSequential->addTask(std::make_shared(tempStorage)); + + + taskSequential->addTask(std::make_shared()->addChildTasks( + std::make_shared()->addChildTasks( + std::make_shared("keep_database"), + std::make_shared([this]() { + Task::dispatch(std::make_shared([this]() { + swapToTempStorage(); + m_state = PROJECT_STATE_LOADED; + })); + }) + ), + std::make_shared()->addChildTasks( + std::make_shared("discard_database"), + std::make_shared([this]() { + Task::dispatch(std::make_shared([this]() { + const FilePath tempIndexDbPath = m_storage->getIndexDbFilePath().replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); + if (tempIndexDbPath.exists()) + { + LOG_INFO("Discarding temporary indexing data"); + FileSystem::remove(tempIndexDbPath); + } + })); + }) + ) + )); + + taskSequential->addTask(std::make_shared([]() { + MessageFinishedParsing().dispatch(); + })); Task::dispatch(taskSequential); +} + +void Project::swapToTempStorage() +{ + LOG_INFO("Switching to temporary indexing data"); + const FilePath indexDbFilePath = m_storage->getIndexDbFilePath(); + const FilePath tempIndexDbFilePath = indexDbFilePath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); + const FilePath bookmarkDbFilePath = m_storage->getBookmarkDbFilePath(); + m_storage.reset(); + FileSystem::remove(indexDbFilePath); + FileSystem::rename(tempIndexDbFilePath, indexDbFilePath); + m_storage = std::make_shared(indexDbFilePath, bookmarkDbFilePath); + m_storage->setup(); + + //std::shared_ptr dialogView = Application::getInstance()->getDialogView(); + //dialogView->showUnknownProgressDialog(L"Finish Indexing", L"Building caches"); + m_storage->buildCaches(); + //dialogView->hideUnknownProgressDialog(); m_storageCache->setSubject(m_storage.get()); - m_state = PROJECT_STATE_LOADED; } bool Project::hasCxxSourceGroup() const diff --git a/src/lib/project/Project.h b/src/lib/project/Project.h index 1eac9624..7eac1d49 100644 --- a/src/lib/project/Project.h +++ b/src/lib/project/Project.h @@ -19,6 +19,11 @@ class StorageCache; class Project { public: + static const std::wstring PROJECT_FILE_EXTENSION; + static const std::wstring BOOKMARK_DB_FILE_EXTENSION; + static const std::wstring INDEX_DB_FILE_EXTENSION; + static const std::wstring TEMP_INDEX_DB_FILE_EXTENSION; + Project(std::shared_ptr settings, StorageCache* storageCache, bool hasGUI); virtual ~Project(); @@ -50,6 +55,7 @@ private: Project(const Project&); + void swapToTempStorage(); bool hasCxxSourceGroup() const; bool didFileChange(const FileInfo& info) const; diff --git a/src/lib/settings/ProjectSettings.cpp b/src/lib/settings/ProjectSettings.cpp index 6af7043f..d120663f 100644 --- a/src/lib/settings/ProjectSettings.cpp +++ b/src/lib/settings/ProjectSettings.cpp @@ -1,5 +1,6 @@ #include "settings/ProjectSettings.h" +#include "project/Project.h" #include "settings/migration/SettingsMigrationDeleteKey.h" #include "settings/migration/SettingsMigrationLambda.h" #include "settings/migration/SettingsMigrationMoveKey.h" @@ -17,7 +18,6 @@ #include "utility/utilityUuid.h" const size_t ProjectSettings::VERSION = 7; -const wchar_t PROJECT_FILE_EXTENSION[] = L".srctrlprj"; LanguageType ProjectSettings::getLanguageOfProject(const FilePath& filePath) { @@ -115,7 +115,7 @@ FilePath ProjectSettings::getProjectFilePath() const void ProjectSettings::setProjectFilePath(std::wstring projectName, const FilePath& projectFileLocation) { - setFilePath(projectFileLocation.getConcatenated(L"/" + projectName + PROJECT_FILE_EXTENSION)); + setFilePath(projectFileLocation.getConcatenated(L"/" + projectName + Project::PROJECT_FILE_EXTENSION)); } std::wstring ProjectSettings::getProjectName() const diff --git a/src/lib/utility/file/FileSystem.cpp b/src/lib/utility/file/FileSystem.cpp index b3598f54..6754e929 100644 --- a/src/lib/utility/file/FileSystem.cpp +++ b/src/lib/utility/file/FileSystem.cpp @@ -203,45 +203,51 @@ TimeStamp FileSystem::getLastWriteTime(const FilePath& filePath) bool FileSystem::remove(const FilePath& path) { - return boost::filesystem::remove(path.getPath()); + const bool ret = boost::filesystem::remove(path.getPath()); + path.recheckExists(); + return ret; } bool FileSystem::rename(const FilePath& from, const FilePath& to) { - if (!from.exists() || to.exists()) + if (!from.recheckExists() || to.recheckExists()) { return false; } boost::filesystem::rename(from.getPath(), to.getPath()); + to.recheckExists(); return true; } bool FileSystem::copyFile(const FilePath& from, const FilePath& to) { - if (!from.exists() || to.exists()) + if (!from.recheckExists() || to.recheckExists()) { return false; } boost::filesystem::copy_file(from.getPath(), to.getPath()); + to.recheckExists(); return true; } bool FileSystem::copy_directory(const FilePath& from, const FilePath& to) { - if (!from.exists() || to.exists()) + if (!from.recheckExists() || to.recheckExists()) { return false; } boost::filesystem::copy_directory(from.getPath(), to.getPath()); + to.recheckExists(); return true; } void FileSystem::createDirectory(const FilePath& path) { boost::filesystem::create_directories(path.str()); + path.recheckExists(); } std::vector FileSystem::getDirectSubDirectories(const FilePath& path) diff --git a/src/lib/utility/messaging/filter_types/MessageFilterErrorCountUpdate.h b/src/lib/utility/messaging/filter_types/MessageFilterErrorCountUpdate.h index b6af55a2..81cbc57f 100644 --- a/src/lib/utility/messaging/filter_types/MessageFilterErrorCountUpdate.h +++ b/src/lib/utility/messaging/filter_types/MessageFilterErrorCountUpdate.h @@ -21,6 +21,15 @@ class MessageFilterErrorCountUpdate { if ((*it)->getType() == MessageErrorCountUpdate::getStaticType()) { + MessageErrorCountUpdate* frontErrorsMessage = dynamic_cast(message); + MessageErrorCountUpdate* backErrorsMessage = dynamic_cast(it->get()); + + backErrorsMessage->newErrors.insert( + backErrorsMessage->newErrors.begin(), + frontErrorsMessage->newErrors.begin(), + frontErrorsMessage->newErrors.end() + ); + messageBuffer->pop_front(); return; } diff --git a/src/lib/utility/messaging/type/error/MessageErrorCountUpdate.h b/src/lib/utility/messaging/type/error/MessageErrorCountUpdate.h index 8dba840f..bcd53637 100644 --- a/src/lib/utility/messaging/type/error/MessageErrorCountUpdate.h +++ b/src/lib/utility/messaging/type/error/MessageErrorCountUpdate.h @@ -14,13 +14,20 @@ public: return "MessageErrorCountUpdate"; } - MessageErrorCountUpdate(const ErrorCountInfo& errorCount) + MessageErrorCountUpdate(const ErrorCountInfo& errorCount, const std::vector& newErrors) : errorCount(errorCount) + , newErrors(newErrors) { setSendAsTask(false); } + virtual void print(std::wostream& os) const + { + os << errorCount.total << '/' << errorCount.fatal << L" - " << newErrors.size() << L" new errors"; + } + const ErrorCountInfo errorCount; + std::vector newErrors; }; #endif // MESSAGE_ERROR_COUNT_UPDATE_H diff --git a/src/lib/utility/scheduling/TaskDecorator.cpp b/src/lib/utility/scheduling/TaskDecorator.cpp index 4878bf51..731b338e 100644 --- a/src/lib/utility/scheduling/TaskDecorator.cpp +++ b/src/lib/utility/scheduling/TaskDecorator.cpp @@ -6,10 +6,6 @@ TaskDecorator::TaskDecorator() { } -TaskDecorator::~TaskDecorator() -{ -} - std::shared_ptr TaskDecorator::addChildTask(std::shared_ptr child) { setTask(child); diff --git a/src/lib/utility/scheduling/TaskDecorator.h b/src/lib/utility/scheduling/TaskDecorator.h index a267a1f1..4d930a32 100644 --- a/src/lib/utility/scheduling/TaskDecorator.h +++ b/src/lib/utility/scheduling/TaskDecorator.h @@ -13,11 +13,10 @@ class TaskDecorator { public: TaskDecorator(); - virtual ~TaskDecorator(); std::shared_ptr addChildTask(std::shared_ptr child); virtual void setTask(std::shared_ptr task); - virtual void terminate(); + void terminate() override; protected: std::shared_ptr m_taskRunner; diff --git a/src/lib/utility/scheduling/TaskDecoratorDelay.h b/src/lib/utility/scheduling/TaskDecoratorDelay.h index 059d9621..10a4b35e 100644 --- a/src/lib/utility/scheduling/TaskDecoratorDelay.h +++ b/src/lib/utility/scheduling/TaskDecoratorDelay.h @@ -14,11 +14,11 @@ public: TaskDecoratorDelay(size_t delayMS); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); - virtual void doTerminate(); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; + void doTerminate() override; const size_t m_delayMS; diff --git a/src/lib/utility/scheduling/TaskDecoratorRepeat.h b/src/lib/utility/scheduling/TaskDecoratorRepeat.h index bda0668c..0753077f 100644 --- a/src/lib/utility/scheduling/TaskDecoratorRepeat.h +++ b/src/lib/utility/scheduling/TaskDecoratorRepeat.h @@ -18,10 +18,10 @@ public: TaskDecoratorRepeat(ConditionType condition, TaskState exitState); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; const ConditionType m_condition; const TaskState m_exitState; diff --git a/src/lib/utility/scheduling/TaskFindValue.cpp b/src/lib/utility/scheduling/TaskFindValue.cpp new file mode 100644 index 00000000..42a09a84 --- /dev/null +++ b/src/lib/utility/scheduling/TaskFindValue.cpp @@ -0,0 +1,26 @@ +#include "utility/scheduling/TaskFindValue.h" + +#include "utility/scheduling/Blackboard.h" + +TaskFindValue::TaskFindValue(const std::string& valueName) + : m_valueName(valueName) +{ +} + +void TaskFindValue::doEnter(std::shared_ptr blackboard) +{ +} + +Task::TaskState TaskFindValue::doUpdate(std::shared_ptr blackboard) +{ + std::lock_guard lock(blackboard->getMutex()); + return (blackboard->exists(m_valueName)) ? STATE_SUCCESS : STATE_FAILURE; +} + +void TaskFindValue::doExit(std::shared_ptr blackboard) +{ +} + +void TaskFindValue::doReset(std::shared_ptr blackboard) +{ +} diff --git a/src/lib/utility/scheduling/TaskFindValue.h b/src/lib/utility/scheduling/TaskFindValue.h new file mode 100644 index 00000000..3467fae3 --- /dev/null +++ b/src/lib/utility/scheduling/TaskFindValue.h @@ -0,0 +1,25 @@ +#ifndef TASK_FIND_VALUE_H +#define TASK_FIND_VALUE_H + +#include + +#include "utility/scheduling/Task.h" + +class Blackboard; + +class TaskFindValue: + public Task +{ +public: + TaskFindValue(const std::string& valueName); + +private: + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; + + const std::string m_valueName; +}; + +#endif // TASK_FIND_VALUE_H diff --git a/src/lib/utility/scheduling/TaskGroup.cpp b/src/lib/utility/scheduling/TaskGroup.cpp index 82828466..a9fb86ff 100644 --- a/src/lib/utility/scheduling/TaskGroup.cpp +++ b/src/lib/utility/scheduling/TaskGroup.cpp @@ -4,10 +4,6 @@ TaskGroup::TaskGroup() { } -TaskGroup::~TaskGroup() -{ -} - std::shared_ptr TaskGroup::addChildTasks(std::shared_ptr child1) { addTask(child1); diff --git a/src/lib/utility/scheduling/TaskGroup.h b/src/lib/utility/scheduling/TaskGroup.h index 776a8b19..5172ee6c 100644 --- a/src/lib/utility/scheduling/TaskGroup.h +++ b/src/lib/utility/scheduling/TaskGroup.h @@ -12,13 +12,12 @@ class TaskGroup { public: TaskGroup(); - virtual ~TaskGroup(); std::shared_ptr addChildTasks(std::shared_ptr child1); std::shared_ptr addChildTasks(std::shared_ptr child1, std::shared_ptr child2); std::shared_ptr addChildTasks(std::shared_ptr child1, std::shared_ptr child2, std::shared_ptr child3); virtual void addTask(std::shared_ptr task) = 0; - virtual void terminate(); + void terminate() override; private: virtual void doTerminate() = 0; diff --git a/src/lib/utility/scheduling/TaskGroupParallel.h b/src/lib/utility/scheduling/TaskGroupParallel.h index 98099fb3..67b49c20 100644 --- a/src/lib/utility/scheduling/TaskGroupParallel.h +++ b/src/lib/utility/scheduling/TaskGroupParallel.h @@ -15,7 +15,7 @@ public: TaskGroupParallel(); virtual ~TaskGroupParallel(); - virtual void addTask(std::shared_ptr task); + void addTask(std::shared_ptr task) override; private: struct TaskInfo @@ -29,11 +29,11 @@ private: volatile bool active; }; - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); - virtual void doTerminate(); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; + void doTerminate() override; void processTaskThreaded( std::shared_ptr taskInfo, diff --git a/src/lib/utility/scheduling/TaskGroupSelector.cpp b/src/lib/utility/scheduling/TaskGroupSelector.cpp index 3ee5537e..03f88b39 100644 --- a/src/lib/utility/scheduling/TaskGroupSelector.cpp +++ b/src/lib/utility/scheduling/TaskGroupSelector.cpp @@ -4,10 +4,6 @@ TaskGroupSelector::TaskGroupSelector() { } -TaskGroupSelector::~TaskGroupSelector() -{ -} - void TaskGroupSelector::addTask(std::shared_ptr task) { m_taskRunners.push_back(std::make_shared(task)); diff --git a/src/lib/utility/scheduling/TaskGroupSelector.h b/src/lib/utility/scheduling/TaskGroupSelector.h index 291f63e8..e372ebc4 100644 --- a/src/lib/utility/scheduling/TaskGroupSelector.h +++ b/src/lib/utility/scheduling/TaskGroupSelector.h @@ -9,16 +9,15 @@ class TaskGroupSelector { public: TaskGroupSelector(); - virtual ~TaskGroupSelector(); virtual void addTask(std::shared_ptr task); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); - virtual void doTerminate(); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; + void doTerminate() override; std::vector> m_taskRunners; int m_taskIndex; diff --git a/src/lib/utility/scheduling/TaskGroupSequence.cpp b/src/lib/utility/scheduling/TaskGroupSequence.cpp index 7d255678..e4722b0d 100644 --- a/src/lib/utility/scheduling/TaskGroupSequence.cpp +++ b/src/lib/utility/scheduling/TaskGroupSequence.cpp @@ -4,10 +4,6 @@ TaskGroupSequence::TaskGroupSequence() { } -TaskGroupSequence::~TaskGroupSequence() -{ -} - void TaskGroupSequence::addTask(std::shared_ptr task) { m_taskRunners.push_back(std::make_shared(task)); diff --git a/src/lib/utility/scheduling/TaskGroupSequence.h b/src/lib/utility/scheduling/TaskGroupSequence.h index 7701cae4..9a26510b 100644 --- a/src/lib/utility/scheduling/TaskGroupSequence.h +++ b/src/lib/utility/scheduling/TaskGroupSequence.h @@ -9,16 +9,15 @@ class TaskGroupSequence { public: TaskGroupSequence(); - virtual ~TaskGroupSequence(); virtual void addTask(std::shared_ptr task); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); - virtual void doTerminate(); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; + void doTerminate() override; std::vector> m_taskRunners; int m_taskIndex; diff --git a/src/lib/utility/scheduling/TaskLambda.cpp b/src/lib/utility/scheduling/TaskLambda.cpp index ebb0fe27..5939ea2e 100644 --- a/src/lib/utility/scheduling/TaskLambda.cpp +++ b/src/lib/utility/scheduling/TaskLambda.cpp @@ -5,10 +5,6 @@ TaskLambda::TaskLambda(std::function func) { } -TaskLambda::~TaskLambda() -{ -} - void TaskLambda::doEnter(std::shared_ptr blackboard) { } diff --git a/src/lib/utility/scheduling/TaskLambda.h b/src/lib/utility/scheduling/TaskLambda.h index 8c1b00a5..4cfc03fb 100644 --- a/src/lib/utility/scheduling/TaskLambda.h +++ b/src/lib/utility/scheduling/TaskLambda.h @@ -10,13 +10,12 @@ class TaskLambda { public: TaskLambda(std::function func); - virtual ~TaskLambda(); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; std::function m_func; }; diff --git a/src/lib/utility/scheduling/TaskReturnSuccessWhile.h b/src/lib/utility/scheduling/TaskReturnSuccessWhile.h index 74882f1b..15cebec0 100644 --- a/src/lib/utility/scheduling/TaskReturnSuccessWhile.h +++ b/src/lib/utility/scheduling/TaskReturnSuccessWhile.h @@ -18,10 +18,10 @@ public: TaskReturnSuccessWhile(const std::string& lhsValueName, ConditionType condition, T rhsValue); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; const std::string m_lhsValueName; const ConditionType m_condition; diff --git a/src/lib/utility/scheduling/TaskSetValue.h b/src/lib/utility/scheduling/TaskSetValue.h index 10487132..d4ee8a89 100644 --- a/src/lib/utility/scheduling/TaskSetValue.h +++ b/src/lib/utility/scheduling/TaskSetValue.h @@ -12,10 +12,10 @@ public: TaskSetValue(const std::string& valueName, T value); private: - virtual void doEnter(std::shared_ptr blackboard); - virtual TaskState doUpdate(std::shared_ptr blackboard); - virtual void doExit(std::shared_ptr blackboard); - virtual void doReset(std::shared_ptr blackboard); + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; const std::string m_valueName; const T m_value; diff --git a/src/lib_gui/qt/view/QtDialogView.cpp b/src/lib_gui/qt/view/QtDialogView.cpp index 4bf3d760..cc990c73 100644 --- a/src/lib_gui/qt/view/QtDialogView.cpp +++ b/src/lib_gui/qt/view/QtDialogView.cpp @@ -221,24 +221,50 @@ void QtDialogView::updateIndexingDialog( ); } -void QtDialogView::finishedIndexingDialog( +DatabasePolicy QtDialogView::finishedIndexingDialog( size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo, bool interrupted) { + DatabasePolicy policy = DATABASE_POLICY_UNKNOWN; + m_resultReady = false; m_onQtThread( - [=]() + [=, &policy]() { m_windowStack.clearWindows(); QtIndexingDialog* window = createWindow(); window->setupReport(indexedFileCount, totalIndexedFileCount, completedFileCount, totalFileCount, time, interrupted); window->updateErrorCount(errorInfo.total, errorInfo.fatal); + connect(window, &QtWindow::finished, + [this, &policy]() + { + setUIBlocked(false); + policy = DATABASE_POLICY_KEEP; + m_resultReady = true; + } + ); + connect(window, &QtWindow::canceled, + [this, &policy]() + { + setUIBlocked(false); + policy = DATABASE_POLICY_DISCARD; + m_resultReady = true; + } + ); - setUIBlocked(false); m_mainWindow->hideWindowsTaskbarProgress(); + setUIBlocked(true); } ); + + while (!m_resultReady) + { + const int SLEEP_TIME_MS = 25; + std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_MS)); + } + + return policy; } void QtDialogView::hideDialogs(bool unblockUI) diff --git a/src/lib_gui/qt/view/QtDialogView.h b/src/lib_gui/qt/view/QtDialogView.h index 256944b7..09fddebe 100644 --- a/src/lib_gui/qt/view/QtDialogView.h +++ b/src/lib_gui/qt/view/QtDialogView.h @@ -25,26 +25,26 @@ class QtDialogView public: QtDialogView(QtMainWindow* mainWindow, StorageAccess* storageAccess); - virtual ~QtDialogView(); + ~QtDialogView() override; - virtual void showUnknownProgressDialog(const std::wstring& title, const std::wstring& message) override; - virtual void hideUnknownProgressDialog() override; + void showUnknownProgressDialog(const std::wstring& title, const std::wstring& message) override; + void hideUnknownProgressDialog() override; - virtual void showProgressDialog(const std::wstring& title, const std::wstring& message, size_t progress) override; - virtual void hideProgressDialog() override; + void showProgressDialog(const std::wstring& title, const std::wstring& message, size_t progress) override; + void hideProgressDialog() override; - virtual void startIndexingDialog( + void startIndexingDialog( Project* project, const std::vector& enabledModes, const RefreshInfo& info) override; - virtual void updateIndexingDialog( + void updateIndexingDialog( size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const FilePath& sourcePath) override; - virtual void finishedIndexingDialog( + DatabasePolicy finishedIndexingDialog( size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo, bool interrupted) override; - virtual void hideDialogs(bool unblockUI = true) override; + void hideDialogs(bool unblockUI = true) override; - virtual int confirm(const std::string& message, const std::vector& options) override; - virtual int confirm(const std::wstring& message, const std::vector& options) override; + int confirm(const std::string& message, const std::vector& options) override; + int confirm(const std::wstring& message, const std::vector& options) override; void setParentWindow(QtWindow* window); diff --git a/src/lib_gui/qt/window/QtIndexingDialog.cpp b/src/lib_gui/qt/window/QtIndexingDialog.cpp index 811377b9..936c79d7 100644 --- a/src/lib_gui/qt/window/QtIndexingDialog.cpp +++ b/src/lib_gui/qt/window/QtIndexingDialog.cpp @@ -207,8 +207,16 @@ void QtIndexingDialog::setupReport( layout->addStretch(); addButtons(layout); - updateNextButton("OK"); - setCloseVisible(false); + if (interrupted) + { + updateNextButton("Keep"); + updateCloseButton("Discard"); + } + else + { + updateNextButton("OK"); + setCloseVisible(false); + } m_sizeHint = QSize(interrupted ? 400 : 430, 280);