Performance optimization. Use threads to speed up preparing details for layout.

Addtionaly users will see nice progress bar.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2019-01-20 12:19:42 +02:00
parent 2cbeff76d4
commit 2ce17d5bee
3 changed files with 100 additions and 61 deletions

View File

@ -116,8 +116,45 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, autosavePrefix, (QLatin1String(".autosa
// String below need for getting translation for key Ctrl
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strQShortcut, (QLatin1String("QShortcut"))) // Context
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strCtrl, (QLatin1String("Ctrl"))) // String
//---------------------------------------------------------------------------------------------------------------------
QVector<DetailForLayout> SortDetailsForLayout(const QHash<quint32, VPiece> *allDetails,
const QString &nameRegex = QString())
{
QVector<DetailForLayout> details;
QHash<quint32, VPiece>::const_iterator i = allDetails->constBegin();
if (nameRegex.isEmpty())
{
while (i != allDetails->constEnd())
{
if (i.value().IsInLayout())
{
details.append(DetailForLayout(i.key(), i.value()));
}
++i;
}
}
else
{
QRegularExpression nameRe(nameRegex);
while (i != allDetails->constEnd())
{
if (nameRe.match(i.value().GetName()).hasMatch())
{
details.append(DetailForLayout(i.key(), i.value()));
}
++i;
}
}
return details;
}
} // anonymous namespace
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief MainWindow constructor.
@ -2579,7 +2616,7 @@ void MainWindow::ActionLayout(bool checked)
ui->actionDetails->setChecked(false);
ui->actionLayout->setChecked(true);
QHash<quint32, VPiece> details;
QVector<DetailForLayout> details;
if(not qApp->getOpeningPattern())
{
const QHash<quint32, VPiece> *allDetails = pattern->DataPieces();
@ -2593,15 +2630,7 @@ void MainWindow::ActionLayout(bool checked)
}
else
{
QHash<quint32, VPiece>::const_iterator i = allDetails->constBegin();
while (i != allDetails->constEnd())
{
if (i.value().IsInLayout())
{
details.insert(i.key(), i.value());
}
++i;
}
details = SortDetailsForLayout(allDetails);
if (details.count() == 0)
{
@ -4867,17 +4896,7 @@ void MainWindow::ExportLayoutAs()
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::ExportDetailsAs()
{
const QHash<quint32, VPiece> *allDetails = pattern->DataPieces();
QHash<quint32, VPiece>::const_iterator i = allDetails->constBegin();
QHash<quint32, VPiece> detailsInLayout;
while (i != allDetails->constEnd())
{
if (i.value().IsInLayout())
{
detailsInLayout.insert(i.key(), i.value());
}
++i;
}
QVector<DetailForLayout> detailsInLayout = SortDetailsForLayout(pattern->DataPieces());
if (detailsInLayout.count() == 0)
{
@ -5199,7 +5218,7 @@ void MainWindow::ZoomFirstShow()
//---------------------------------------------------------------------------------------------------------------------
bool MainWindow::DoExport(const VCommandLinePtr &expParams)
{
QHash<quint32, VPiece> details;
QVector<DetailForLayout> details;
if(not qApp->getOpeningPattern())
{
const QHash<quint32, VPiece> *allDetails = pattern->DataPieces();
@ -5211,32 +5230,7 @@ bool MainWindow::DoExport(const VCommandLinePtr &expParams)
}
else
{
const QString nameRegex = expParams->OptExportSuchDetails();
if (nameRegex.isEmpty())
{
QHash<quint32, VPiece>::const_iterator i = allDetails->constBegin();
while (i != allDetails->constEnd())
{
if (i.value().IsInLayout())
{
details.insert(i.key(), i.value());
}
++i;
}
}
else
{
const QRegularExpression nameRe(nameRegex);
QHash<quint32, VPiece>::const_iterator i = allDetails->constBegin();
while (i != allDetails->constEnd())
{
if (nameRe.match(i.value().GetName()).hasMatch())
{
details.insert(i.key(), i.value());
}
++i;
}
}
details = SortDetailsForLayout(allDetails, expParams->OptExportSuchDetails());
if (details.count() == 0)
{

View File

@ -60,6 +60,7 @@
#include <QPrintPreviewDialog>
#include <QPrintDialog>
#include <QPrinterInfo>
#include <QtConcurrent>
#if defined(Q_OS_WIN32) && QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
#include <QWinTaskbarButton>
@ -799,22 +800,50 @@ void MainWindowsNoGUI::PrintTiled()
}
//---------------------------------------------------------------------------------------------------------------------
QVector<VLayoutPiece> MainWindowsNoGUI::PrepareDetailsForLayout(const QHash<quint32, VPiece> &details)
QVector<VLayoutPiece> MainWindowsNoGUI::PrepareDetailsForLayout(const QVector<DetailForLayout> &details)
{
QVector<VLayoutPiece> listDetails;
if (not details.isEmpty())
if (details.isEmpty())
{
QHash<quint32, VPiece>::const_iterator i = details.constBegin();
while (i != details.constEnd())
{
VAbstractTool *tool = qobject_cast<VAbstractTool*>(VAbstractPattern::getTool(i.key()));
SCASSERT(tool != nullptr)
listDetails.append(VLayoutPiece::Create(i.value(), tool->getData()));
++i;
}
return QVector<VLayoutPiece>();
}
return listDetails;
std::function<VLayoutPiece (const DetailForLayout &data)> PrepareDetail = [](const DetailForLayout &data)
{
VAbstractTool *tool = qobject_cast<VAbstractTool*>(VAbstractPattern::getTool(data.id));
SCASSERT(tool != nullptr)
return VLayoutPiece::Create(data.piece, tool->getData());
};
QProgressDialog progress(tr("Preparing details for layout"), QString(), 0, details.size());
progress.setWindowModality(Qt::ApplicationModal);
QFutureWatcher<VLayoutPiece> futureWatcher;
QObject::connect(&futureWatcher, &QFutureWatcher<VLayoutPiece>::finished, &progress, &QProgressDialog::reset);
QObject::connect(&futureWatcher, &QFutureWatcher<VLayoutPiece>::progressRangeChanged, &progress,
&QProgressDialog::setRange);
QObject::connect(&futureWatcher, &QFutureWatcher<VLayoutPiece>::progressValueChanged, &progress,
&QProgressDialog::setValue);
futureWatcher.setFuture(QtConcurrent::mapped(details, PrepareDetail));
if (qApp->IsGUIMode())
{
progress.exec();
}
futureWatcher.waitForFinished();
QVector<VLayoutPiece> layautDetails;
layautDetails.resize(details.size());
const QFuture<VLayoutPiece> future = futureWatcher.future();
QFuture<VLayoutPiece>::const_iterator i;
for (i = future.constBegin(); i != future.constEnd(); ++i)
{
layautDetails.append(*i);
}
return layautDetails;
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -48,6 +48,22 @@ class QWinTaskbarButton;
class QWinTaskbarProgress;
#endif
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Weffc++")
struct DetailForLayout {
DetailForLayout() = default;
DetailForLayout(quint32 id, const VPiece &piece)
: id(id), piece(piece)
{}
quint32 id{NULL_ID};
VPiece piece;
};
QT_WARNING_POP
class MainWindowsNoGUI : public VAbstractMainWindow
{
Q_OBJECT
@ -103,7 +119,7 @@ protected:
QWinTaskbarProgress *m_taskbarProgress;
#endif
static QVector<VLayoutPiece> PrepareDetailsForLayout(const QHash<quint32, VPiece> &details);
static QVector<VLayoutPiece> PrepareDetailsForLayout(const QVector<DetailForLayout> &details);
void ExportData(const QVector<VLayoutPiece> &listDetails);