From e8a48302294d4d58c47c55942d94a84dead0f8b4 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Mon, 27 Aug 2018 16:15:18 +0200 Subject: [PATCH] ui: fixed crash that had a chance to occur when showing source files of cdb/cbp/sonargraph project --- src/lib/CMakeLists.txt | 1 + src/lib/utility/SingleValueCache.h | 48 ++++++++++++ .../QtProjectWizzardContentPath.cpp | 77 +++++++++++-------- .../QtProjectWizzardContentPath.h | 7 +- 4 files changed, 96 insertions(+), 37 deletions(-) create mode 100644 src/lib/utility/SingleValueCache.h diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 85b46525..302a6545 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -595,6 +595,7 @@ add_files( utility/ScopedFunctor.cpp utility/ScopedFunctor.h utility/ScopedSwitcher.h + utility/SingleValueCache.h utility/TimeStamp.cpp utility/TimeStamp.h utility/tracing.cpp diff --git a/src/lib/utility/SingleValueCache.h b/src/lib/utility/SingleValueCache.h new file mode 100644 index 00000000..9d968a39 --- /dev/null +++ b/src/lib/utility/SingleValueCache.h @@ -0,0 +1,48 @@ +#ifndef SINGLE_VALUE_CACHE_H +#define SINGLE_VALUE_CACHE_H + +#include + +template +class SingleValueCache +{ +public: + SingleValueCache(std::function calculator); + ValType getValue(); + void clear(); + +private: + std::function m_calculator; + ValType m_value; + bool m_hasValue; +}; + +template +SingleValueCache::SingleValueCache(std::function calculator) + : m_calculator(calculator) + , m_hasValue(false) +{ +} + +template +ValType SingleValueCache::getValue() +{ + if (!m_hasValue) + { + m_value = m_calculator(); + m_hasValue = true; + } + return m_value; +} + +template +void SingleValueCache::clear() +{ + if (m_hasValue) + { + m_value = ValType(); + m_hasValue = false; + } +} + +#endif // SINGLE_VALUE_CACHE_H diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.cpp index 3952cbe5..cc1db4e5 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.cpp @@ -128,6 +128,14 @@ QtProjectWizzardContentPathCDB::QtProjectWizzardContentPathCDB( ) : QtProjectWizzardContentPath(window) , m_settings(settings) + , m_filePaths([&]() + { + return utility::getAsRelativeIfShorter( + utility::toVector(SourceGroupCxxCdb(m_settings).getAllSourceFilePaths()), + m_settings->getProjectDirectoryPath() + ); + } + ) { setTitleString("Compilation Database (compile_commands.json)"); setHelpString( @@ -172,14 +180,11 @@ void QtProjectWizzardContentPathCDB::load() { m_picker->setText(QString::fromStdWString(m_settings->getCompilationDatabasePath().wstr())); - m_filePaths = utility::getAsRelativeIfShorter( - utility::toVector(SourceGroupCxxCdb(m_settings).getAllSourceFilePaths()), - m_settings->getProjectDirectoryPath() - ); + m_filePaths.clear(); if (m_fileCountLabel) { - m_fileCountLabel->setText("" + QString::number(m_filePaths.size()) + " source files were found in the compilation database."); + m_fileCountLabel->setText("" + QString::number(getFilePaths().size()) + " source files were found in the compilation database."); } } @@ -190,9 +195,7 @@ void QtProjectWizzardContentPathCDB::save() std::vector QtProjectWizzardContentPathCDB::getFilePaths() const { - const_cast(this)->load(); - - return m_filePaths; + return m_filePaths.getValue(); } QString QtProjectWizzardContentPathCDB::getFileNamesTitle() const @@ -235,6 +238,14 @@ QtProjectWizzardContentCodeblocksProjectPath::QtProjectWizzardContentCodeblocksP ) : QtProjectWizzardContentPath(window) , m_settings(settings) + , m_filePaths([&]() + { + return utility::getAsRelativeIfShorter( + utility::toVector(SourceGroupCxxCodeblocks(m_settings).getAllSourceFilePaths()), + m_settings->getProjectDirectoryPath() + ); + } + ) { setTitleString("Code::Blocks Project (.cbp)"); setHelpString( @@ -278,14 +289,11 @@ void QtProjectWizzardContentCodeblocksProjectPath::load() { m_picker->setText(QString::fromStdWString(m_settings->getCodeblocksProjectPath().wstr())); - m_filePaths = utility::getAsRelativeIfShorter( - utility::toVector(SourceGroupCxxCodeblocks(m_settings).getAllSourceFilePaths()), - m_settings->getProjectDirectoryPath() - ); + m_filePaths.clear(); if (m_fileCountLabel) { - m_fileCountLabel->setText("" + QString::number(m_filePaths.size()) + " source files were found in the Code::Blocks project."); + m_fileCountLabel->setText("" + QString::number(getFilePaths().size()) + " source files were found in the Code::Blocks project."); } } @@ -296,9 +304,7 @@ void QtProjectWizzardContentCodeblocksProjectPath::save() std::vector QtProjectWizzardContentCodeblocksProjectPath::getFilePaths() const { - const_cast(this)->load(); - - return m_filePaths; + return m_filePaths.getValue(); } QString QtProjectWizzardContentCodeblocksProjectPath::getFileNamesTitle() const @@ -346,6 +352,24 @@ QtProjectWizzardContentSonargraphProjectPath::QtProjectWizzardContentSonargraphP , m_settings(settings) , m_settingsCxxSonargraph(settingsCxxSonargraph) , m_settingsWithSonargraphProjectPath(settingsWithSonargraphProjectPath) + , m_filePaths([&]() + { + std::set allSourceFilePaths; + if (std::shared_ptr settings = std::dynamic_pointer_cast(m_settings)) + { + allSourceFilePaths = SourceGroupCxxSonargraph(settings).getAllSourceFilePaths(); + } + else if (std::shared_ptr settings = std::dynamic_pointer_cast(m_settings)) + { + allSourceFilePaths = SourceGroupJavaSonargraph(settings).getAllSourceFilePaths(); + } + + return utility::getAsRelativeIfShorter( + utility::toVector(allSourceFilePaths), + m_settings->getProjectDirectoryPath() + ); + } + ) { setTitleString("Sonargraph Project (system.sonargraph)"); setHelpString( @@ -389,24 +413,11 @@ void QtProjectWizzardContentSonargraphProjectPath::load() { m_picker->setText(QString::fromStdWString(m_settingsWithSonargraphProjectPath->getSonargraphProjectPath().wstr())); - std::set allSourceFilePaths; - if (std::shared_ptr settings = std::dynamic_pointer_cast(m_settings)) - { - allSourceFilePaths = SourceGroupCxxSonargraph(settings).getAllSourceFilePaths(); - } - else if (std::shared_ptr settings = std::dynamic_pointer_cast(m_settings)) - { - allSourceFilePaths = SourceGroupJavaSonargraph(settings).getAllSourceFilePaths(); - } - - m_filePaths = utility::getAsRelativeIfShorter( - utility::toVector(allSourceFilePaths), - m_settings->getProjectDirectoryPath() - ); + m_filePaths.clear(); if (m_fileCountLabel) { - m_fileCountLabel->setText("" + QString::number(m_filePaths.size()) + " source files were found in the Sonargraph project."); + m_fileCountLabel->setText("" + QString::number(getFilePaths().size()) + " source files were found in the Sonargraph project."); } } @@ -445,9 +456,7 @@ bool QtProjectWizzardContentSonargraphProjectPath::check() std::vector QtProjectWizzardContentSonargraphProjectPath::getFilePaths() const { - const_cast(this)->load(); - - return m_filePaths; + return m_filePaths.getValue(); } QString QtProjectWizzardContentSonargraphProjectPath::getFileNamesTitle() const diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.h index 489f39aa..97dc0d17 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPath.h @@ -4,6 +4,7 @@ #include #include "qt/window/project_wizzard/QtProjectWizzardContent.h" +#include "utility/SingleValueCache.h" class QCheckBox; class QComboBox; @@ -76,7 +77,7 @@ private: std::shared_ptr m_settings; QLabel* m_fileCountLabel; - std::vector m_filePaths; + mutable SingleValueCache> m_filePaths; }; @@ -108,7 +109,7 @@ private: std::shared_ptr m_settings; QLabel* m_fileCountLabel; - std::vector m_filePaths; + mutable SingleValueCache> m_filePaths; }; @@ -145,7 +146,7 @@ private: std::shared_ptr m_settingsCxxSonargraph; std::shared_ptr m_settingsWithSonargraphProjectPath; QLabel* m_fileCountLabel; - std::vector m_filePaths; + mutable SingleValueCache> m_filePaths; };