Improve preparing history list.

Basically when we have cleared by garbage collector modeling objects Valentina will try to add them to list, because they still present in tool record list. Additionally this patch brings using multithreading support.
This commit is contained in:
Roman Telezhynskyi 2020-03-09 20:07:17 +02:00
parent dc2ebc8458
commit 9dd796cb8c
5 changed files with 181 additions and 116 deletions

View File

@ -40,7 +40,9 @@
#include "../vtools/tools/drawTools/toolpoint/toolsinglepoint/toolcut/vtoolcutarc.h" #include "../vtools/tools/drawTools/toolpoint/toolsinglepoint/toolcut/vtoolcutarc.h"
#include "../xml/vpattern.h" #include "../xml/vpattern.h"
#include "../vmisc/diagnostic.h" #include "../vmisc/diagnostic.h"
#include <QDebug> #include <QDebug>
#include <QtConcurrent>
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
@ -165,26 +167,30 @@ void DialogHistory::FillTable()
qint32 currentRow = -1; qint32 currentRow = -1;
qint32 count = 0; qint32 count = 0;
ui->tableWidget->setRowCount(history.size());//Make row count max possible number ui->tableWidget->setRowCount(history.size());//Make row count max possible number
for (qint32 i = 0; i< history.size(); ++i)
std::function<HistoryRecord (const VToolRecord &tool)> CreateRecord = [this](const VToolRecord &tool)
{ {
const VToolRecord tool = history.at(i); return Record(tool);
const QString historyRecord = Record(tool); };
if (not historyRecord.isEmpty())
QVector<HistoryRecord> historyRecords = QtConcurrent::blockingMapped(history, CreateRecord);
for (auto &record : historyRecords)
{
if (not record.description.isEmpty())
{ {
currentRow++; currentRow++;
{ {
QTableWidgetItem *item = new QTableWidgetItem(QString()); QTableWidgetItem *item = new QTableWidgetItem(QString());
item->setTextAlignment(Qt::AlignHCenter); item->setTextAlignment(Qt::AlignHCenter);
item->setData(Qt::UserRole, tool.getId()); item->setData(Qt::UserRole, record.id);
item->setFlags(item->flags() ^ Qt::ItemIsEditable); item->setFlags(item->flags() ^ Qt::ItemIsEditable);
ui->tableWidget->setItem(currentRow, 0, item); ui->tableWidget->setItem(currentRow, 0, item);
} }
QTableWidgetItem *item = new QTableWidgetItem(historyRecord); QTableWidgetItem *item = new QTableWidgetItem(record.description);
QFont font = item->font(); item->setFont(QFont("Times", 12, QFont::Bold));
font.setBold(true);
item->setFont(font);
item->setFlags(item->flags() ^ Qt::ItemIsEditable); item->setFlags(item->flags() ^ Qt::ItemIsEditable);
ui->tableWidget->setItem(currentRow, 1, item); ui->tableWidget->setItem(currentRow, 1, item);
++count; ++count;
@ -211,16 +217,20 @@ QT_WARNING_DISABLE_GCC("-Wswitch-default")
* @param tool record data * @param tool record data
* @return description * @return description
*/ */
QString DialogHistory::Record(const VToolRecord &tool) HistoryRecord DialogHistory::Record(const VToolRecord &tool) const
{ {
// This check helps to find missed tools in the switch // This check helps to find missed tools in the switch
Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were used in history."); Q_STATIC_ASSERT_X(static_cast<int>(Tool::LAST_ONE_DO_NOT_USE) == 55, "Not all tools were used in history.");
const QDomElement domElem = doc->elementById(tool.getId()); HistoryRecord record;
record.id = tool.getId();
bool updateCache = false;
const QDomElement domElem = doc->elementById(tool.getId(), QString(), updateCache);
if (domElem.isElement() == false) if (domElem.isElement() == false)
{ {
qDebug()<<"Can't find element by id"<<Q_FUNC_INFO; qDebug()<<"Can't find element by id" << record.id << Q_FUNC_INFO;
return QString(); return record;
} }
try try
{ {
@ -238,110 +248,130 @@ QString DialogHistory::Record(const VToolRecord &tool)
Q_UNREACHABLE(); //-V501 Q_UNREACHABLE(); //-V501
break; break;
case Tool::BasePoint: case Tool::BasePoint:
return tr("%1 - Base point").arg(PointName(tool.getId())); record.description = tr("%1 - Base point").arg(PointName(tool.getId()));
return record;
case Tool::EndLine: case Tool::EndLine:
return tr("%1_%2 - Line from point %1 to point %2") record.description = tr("%1_%2 - Line from point %1 to point %2")
.arg(PointName(AttrUInt(domElem, AttrBasePoint)), PointName(tool.getId())); .arg(PointName(AttrUInt(domElem, AttrBasePoint)), PointName(tool.getId()));
return record;
case Tool::Line: case Tool::Line:
return tr("%1_%2 - Line from point %1 to point %2") record.description = tr("%1_%2 - Line from point %1 to point %2")
.arg(PointName(AttrUInt(domElem, AttrFirstPoint)), .arg(PointName(AttrUInt(domElem, AttrFirstPoint)),
PointName(AttrUInt(domElem, AttrSecondPoint))); PointName(AttrUInt(domElem, AttrSecondPoint)));
return record;
case Tool::AlongLine: case Tool::AlongLine:
return tr("%3 - Point along line %1_%2") record.description = tr("%3 - Point along line %1_%2")
.arg(PointName(AttrUInt(domElem, AttrFirstPoint)), .arg(PointName(AttrUInt(domElem, AttrFirstPoint)),
PointName(AttrUInt(domElem, AttrSecondPoint)), PointName(tool.getId())); PointName(AttrUInt(domElem, AttrSecondPoint)), PointName(tool.getId()));
return record;
case Tool::ShoulderPoint: case Tool::ShoulderPoint:
return tr("%1 - Point of shoulder").arg(PointName(tool.getId())); record.description = tr("%1 - Point of shoulder").arg(PointName(tool.getId()));
return record;
case Tool::Normal: case Tool::Normal:
return tr("%3 - normal to line %1_%2") record.description = tr("%3 - normal to line %1_%2")
.arg(PointName(AttrUInt(domElem, AttrFirstPoint)), .arg(PointName(AttrUInt(domElem, AttrFirstPoint)),
PointName(AttrUInt(domElem, AttrSecondPoint)), PointName(tool.getId())); PointName(AttrUInt(domElem, AttrSecondPoint)), PointName(tool.getId()));
return record;
case Tool::Bisector: case Tool::Bisector:
return tr("%4 - bisector of angle %1_%2_%3") record.description = tr("%4 - bisector of angle %1_%2_%3")
.arg(PointName(AttrUInt(domElem, AttrFirstPoint)), .arg(PointName(AttrUInt(domElem, AttrFirstPoint)),
PointName(AttrUInt(domElem, AttrSecondPoint)), PointName(AttrUInt(domElem, AttrSecondPoint)),
PointName(AttrUInt(domElem, AttrThirdPoint)), PointName(tool.getId())); PointName(AttrUInt(domElem, AttrThirdPoint)), PointName(tool.getId()));
return record;
case Tool::LineIntersect: case Tool::LineIntersect:
return tr("%5 - intersection of lines %1_%2 and %3_%4") record.description = tr("%5 - intersection of lines %1_%2 and %3_%4")
.arg(PointName(AttrUInt(domElem, AttrP1Line1)), .arg(PointName(AttrUInt(domElem, AttrP1Line1)),
PointName(AttrUInt(domElem, AttrP2Line1)), PointName(AttrUInt(domElem, AttrP2Line1)),
PointName(AttrUInt(domElem, AttrP1Line2)), PointName(AttrUInt(domElem, AttrP1Line2)),
PointName(AttrUInt(domElem, AttrP2Line2)), PointName(AttrUInt(domElem, AttrP2Line2)),
PointName(tool.getId())); PointName(tool.getId()));
return record;
case Tool::Spline: case Tool::Spline:
{ {
const QSharedPointer<VSpline> spl = data->GeometricObject<VSpline>(tool.getId()); const QSharedPointer<VSpline> spl = data->GeometricObject<VSpline>(tool.getId());
SCASSERT(not spl.isNull()) SCASSERT(not spl.isNull())
return spl->NameForHistory(tr("Curve")); record.description = spl->NameForHistory(tr("Curve"));
return record;
} }
case Tool::CubicBezier: case Tool::CubicBezier:
{ {
const QSharedPointer<VCubicBezier> spl = data->GeometricObject<VCubicBezier>(tool.getId()); const QSharedPointer<VCubicBezier> spl = data->GeometricObject<VCubicBezier>(tool.getId());
SCASSERT(not spl.isNull()) SCASSERT(not spl.isNull())
return spl->NameForHistory(tr("Cubic bezier curve")); record.description = spl->NameForHistory(tr("Cubic bezier curve"));
return record;
} }
case Tool::Arc: case Tool::Arc:
{ {
const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(tool.getId()); const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(tool.getId());
SCASSERT(not arc.isNull()) SCASSERT(not arc.isNull())
return arc->NameForHistory(tr("Arc")); record.description = arc->NameForHistory(tr("Arc"));
return record;
} }
case Tool::ArcWithLength: case Tool::ArcWithLength:
{ {
const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(tool.getId()); const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(tool.getId());
SCASSERT(not arc.isNull()) SCASSERT(not arc.isNull())
return tr("%1 with length %2") record.description = tr("%1 with length %2")
.arg(arc->NameForHistory(tr("Arc"))) .arg(arc->NameForHistory(tr("Arc")))
.arg(arc->GetLength()); .arg(arc->GetLength());
return record;
} }
case Tool::SplinePath: case Tool::SplinePath:
{ {
const QSharedPointer<VSplinePath> splPath = data->GeometricObject<VSplinePath>(tool.getId()); const QSharedPointer<VSplinePath> splPath = data->GeometricObject<VSplinePath>(tool.getId());
SCASSERT(not splPath.isNull()) SCASSERT(not splPath.isNull())
return splPath->NameForHistory(tr("Spline path")); record.description = splPath->NameForHistory(tr("Spline path"));
return record;
} }
case Tool::CubicBezierPath: case Tool::CubicBezierPath:
{ {
const QSharedPointer<VCubicBezierPath> splPath = data->GeometricObject<VCubicBezierPath>(tool.getId()); const QSharedPointer<VCubicBezierPath> splPath = data->GeometricObject<VCubicBezierPath>(tool.getId());
SCASSERT(not splPath.isNull()) SCASSERT(not splPath.isNull())
return splPath->NameForHistory(tr("Cubic bezier curve path")); record.description = splPath->NameForHistory(tr("Cubic bezier curve path"));
return record;
} }
case Tool::PointOfContact: case Tool::PointOfContact:
return tr("%4 - point of contact of arc with the center in point %1 and line %2_%3") record.description = tr("%4 - point of contact of arc with the center in point %1 and line %2_%3")
.arg(PointName(AttrUInt(domElem, AttrCenter)), .arg(PointName(AttrUInt(domElem, AttrCenter)),
PointName(AttrUInt(domElem, AttrFirstPoint)), PointName(AttrUInt(domElem, AttrFirstPoint)),
PointName(AttrUInt(domElem, AttrSecondPoint)), PointName(AttrUInt(domElem, AttrSecondPoint)),
PointName(tool.getId())); PointName(tool.getId()));
return record;
case Tool::Height: case Tool::Height:
return tr("Point of perpendicular from point %1 to line %2_%3") record.description = tr("Point of perpendicular from point %1 to line %2_%3")
.arg(PointName(AttrUInt(domElem, AttrBasePoint)), .arg(PointName(AttrUInt(domElem, AttrBasePoint)),
PointName(AttrUInt(domElem, AttrP1Line)), PointName(AttrUInt(domElem, AttrP1Line)),
PointName(AttrUInt(domElem, AttrP2Line))); PointName(AttrUInt(domElem, AttrP2Line)));
return record;
case Tool::Triangle: case Tool::Triangle:
return tr("Triangle: axis %1_%2, points %3 and %4") record.description = tr("Triangle: axis %1_%2, points %3 and %4")
.arg(PointName(AttrUInt(domElem, AttrAxisP1)), .arg(PointName(AttrUInt(domElem, AttrAxisP1)),
PointName(AttrUInt(domElem, AttrAxisP2)), PointName(AttrUInt(domElem, AttrAxisP2)),
PointName(AttrUInt(domElem, AttrFirstPoint)), PointName(AttrUInt(domElem, AttrFirstPoint)),
PointName(AttrUInt(domElem, AttrSecondPoint))); PointName(AttrUInt(domElem, AttrSecondPoint)));
return record;
case Tool::PointOfIntersection: case Tool::PointOfIntersection:
return tr("%1 - point of intersection %2 and %3") record.description = tr("%1 - point of intersection %2 and %3")
.arg(PointName(tool.getId()), .arg(PointName(tool.getId()),
PointName(AttrUInt(domElem, AttrFirstPoint)), PointName(AttrUInt(domElem, AttrFirstPoint)),
PointName(AttrUInt(domElem, AttrSecondPoint))); PointName(AttrUInt(domElem, AttrSecondPoint)));
return record;
case Tool::CutArc: case Tool::CutArc:
{ {
const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(AttrUInt(domElem, AttrArc)); const QSharedPointer<VArc> arc = data->GeometricObject<VArc>(AttrUInt(domElem, AttrArc));
SCASSERT(not arc.isNull()) SCASSERT(not arc.isNull())
return tr("%1 - cut %2") record.description = tr("%1 - cut %2")
.arg(PointName(tool.getId()), arc->NameForHistory(tr("arc"))); .arg(PointName(tool.getId()), arc->NameForHistory(tr("arc")));
return record;
} }
case Tool::CutSpline: case Tool::CutSpline:
{ {
const quint32 splineId = AttrUInt(domElem, VToolCutSpline::AttrSpline); const quint32 splineId = AttrUInt(domElem, VToolCutSpline::AttrSpline);
const QSharedPointer<VAbstractCubicBezier> spl = data->GeometricObject<VAbstractCubicBezier>(splineId); const QSharedPointer<VAbstractCubicBezier> spl = data->GeometricObject<VAbstractCubicBezier>(splineId);
SCASSERT(not spl.isNull()) SCASSERT(not spl.isNull())
return tr("%1 - cut %2") record.description = tr("%1 - cut %2")
.arg(PointName(tool.getId()), spl->NameForHistory(tr("curve"))); .arg(PointName(tool.getId()), spl->NameForHistory(tr("curve")));
return record;
} }
case Tool::CutSplinePath: case Tool::CutSplinePath:
{ {
@ -349,56 +379,71 @@ QString DialogHistory::Record(const VToolRecord &tool)
const QSharedPointer<VAbstractCubicBezierPath> splPath = const QSharedPointer<VAbstractCubicBezierPath> splPath =
data->GeometricObject<VAbstractCubicBezierPath>(splinePathId); data->GeometricObject<VAbstractCubicBezierPath>(splinePathId);
SCASSERT(not splPath.isNull()) SCASSERT(not splPath.isNull())
return tr("%1 - cut %2") record.description = tr("%1 - cut %2")
.arg(PointName(tool.getId()), splPath->NameForHistory(tr("curve path"))); .arg(PointName(tool.getId()), splPath->NameForHistory(tr("curve path")));
return record;
} }
case Tool::LineIntersectAxis: case Tool::LineIntersectAxis:
return tr("%1 - point of intersection line %2_%3 and axis through point %4") record.description = tr("%1 - point of intersection line %2_%3 and axis through point %4")
.arg(PointName(tool.getId()), .arg(PointName(tool.getId()),
PointName(AttrUInt(domElem, AttrP1Line)), PointName(AttrUInt(domElem, AttrP1Line)),
PointName(AttrUInt(domElem, AttrP2Line)), PointName(AttrUInt(domElem, AttrP2Line)),
PointName(AttrUInt(domElem, AttrBasePoint))); PointName(AttrUInt(domElem, AttrBasePoint)));
return record;
case Tool::CurveIntersectAxis: case Tool::CurveIntersectAxis:
return tr("%1 - point of intersection curve and axis through point %2") record.description = tr("%1 - point of intersection curve and axis through point %2")
.arg(PointName(tool.getId()), PointName(AttrUInt(domElem, AttrBasePoint))); .arg(PointName(tool.getId()), PointName(AttrUInt(domElem, AttrBasePoint)));
return record;
case Tool::PointOfIntersectionArcs: case Tool::PointOfIntersectionArcs:
return tr("%1 - point of arcs intersection").arg(PointName(tool.getId())); record.description = tr("%1 - point of arcs intersection").arg(PointName(tool.getId()));
return record;
case Tool::PointOfIntersectionCircles: case Tool::PointOfIntersectionCircles:
return tr("%1 - point of circles intersection").arg(PointName(tool.getId())); record.description = tr("%1 - point of circles intersection").arg(PointName(tool.getId()));
return record;
case Tool::PointOfIntersectionCurves: case Tool::PointOfIntersectionCurves:
return tr("%1 - point of curves intersection").arg(PointName(tool.getId())); record.description = tr("%1 - point of curves intersection").arg(PointName(tool.getId()));
return record;
case Tool::PointFromCircleAndTangent: case Tool::PointFromCircleAndTangent:
return tr("%1 - point from circle and tangent").arg(PointName(tool.getId())); record.description = tr("%1 - point from circle and tangent").arg(PointName(tool.getId()));
return record;
case Tool::PointFromArcAndTangent: case Tool::PointFromArcAndTangent:
return tr("%1 - point from arc and tangent").arg(PointName(tool.getId())); record.description = tr("%1 - point from arc and tangent").arg(PointName(tool.getId()));
return record;
case Tool::TrueDarts: case Tool::TrueDarts:
return tr("Correction the dart %1_%2_%3") record.description = tr("Correction the dart %1_%2_%3")
.arg(PointName(AttrUInt(domElem, AttrDartP1)), .arg(PointName(AttrUInt(domElem, AttrDartP1)),
PointName(AttrUInt(domElem, AttrDartP2)), PointName(AttrUInt(domElem, AttrDartP2)),
PointName(AttrUInt(domElem, AttrDartP2))); PointName(AttrUInt(domElem, AttrDartP2)));
return record;
case Tool::EllipticalArc: case Tool::EllipticalArc:
{ {
const QSharedPointer<VEllipticalArc> elArc = data->GeometricObject<VEllipticalArc>(tool.getId()); const QSharedPointer<VEllipticalArc> elArc = data->GeometricObject<VEllipticalArc>(tool.getId());
SCASSERT(not elArc.isNull()) SCASSERT(not elArc.isNull())
return tr("%1 with length %2") record.description = tr("%1 with length %2")
.arg(elArc->NameForHistory(tr("Elliptical arc"))) .arg(elArc->NameForHistory(tr("Elliptical arc")))
.arg(elArc->GetLength()); .arg(elArc->GetLength());
return record;
} }
case Tool::Rotation: case Tool::Rotation:
return tr("Rotate objects around point %1. Suffix '%2'") record.description = tr("Rotate objects around point %1. Suffix '%2'")
.arg(PointName(AttrUInt(domElem, AttrCenter)), .arg(PointName(AttrUInt(domElem, AttrCenter)),
doc->GetParametrString(domElem, AttrSuffix, QString())); doc->GetParametrString(domElem, AttrSuffix, QString()));
return record;
case Tool::FlippingByLine: case Tool::FlippingByLine:
return tr("Flipping by line %1_%2. Suffix '%3'") record.description = tr("Flipping by line %1_%2. Suffix '%3'")
.arg(PointName(AttrUInt(domElem, AttrP1Line)), .arg(PointName(AttrUInt(domElem, AttrP1Line)),
PointName(AttrUInt(domElem, AttrP2Line)), PointName(AttrUInt(domElem, AttrP2Line)),
doc->GetParametrString(domElem, AttrSuffix, QString())); doc->GetParametrString(domElem, AttrSuffix, QString()));
return record;
case Tool::FlippingByAxis: case Tool::FlippingByAxis:
return tr("Flipping by axis through %1 point. Suffix '%2'") record.description = tr("Flipping by axis through %1 point. Suffix '%2'")
.arg(PointName(AttrUInt(domElem, AttrCenter)), .arg(PointName(AttrUInt(domElem, AttrCenter)),
doc->GetParametrString(domElem, AttrSuffix, QString())); doc->GetParametrString(domElem, AttrSuffix, QString()));
return record;
case Tool::Move: case Tool::Move:
return tr("Move objects. Suffix '%1'").arg(doc->GetParametrString(domElem, AttrSuffix, QString())); record.description = tr("Move objects. Suffix '%1'")
.arg(doc->GetParametrString(domElem, AttrSuffix, QString()));
return record;
//Because "history" not only show history of pattern, but help restore current data for each pattern's //Because "history" not only show history of pattern, but help restore current data for each pattern's
//piece, we need add record about details and nodes, but don't show them. //piece, we need add record about details and nodes, but don't show them.
case Tool::Piece: case Tool::Piece:
@ -414,16 +459,16 @@ QString DialogHistory::Record(const VToolRecord &tool)
case Tool::PlaceLabel: case Tool::PlaceLabel:
case Tool::InsertNode: case Tool::InsertNode:
case Tool::DuplicateDetail: case Tool::DuplicateDetail:
return QString(); return record;
} }
} }
catch (const VExceptionBadId &e) catch (const VExceptionBadId &e)
{ {
qDebug()<<e.ErrorMessage()<<Q_FUNC_INFO; qDebug()<<e.ErrorMessage()<<Q_FUNC_INFO;
return QString(); return record;
} }
qDebug()<<"Can't create history record for the tool."; qDebug()<<"Can't create history record for the tool" << record.id;
return QString(); return record;
} }
QT_WARNING_POP QT_WARNING_POP
@ -465,13 +510,13 @@ void DialogHistory::ShowPoint()
* @param pointId point if in data. * @param pointId point if in data.
* @return point name. * @return point name.
*/ */
QString DialogHistory::PointName(quint32 pointId) QString DialogHistory::PointName(quint32 pointId) const
{ {
return data->GeometricObject<VPointF>(pointId)->name(); return data->GeometricObject<VPointF>(pointId)->name();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
quint32 DialogHistory::AttrUInt(const QDomElement &domElement, const QString &name) quint32 DialogHistory::AttrUInt(const QDomElement &domElement, const QString &name) const
{ {
return doc->GetParametrUInt(domElement, name, QChar('0')); return doc->GetParametrUInt(domElement, name, QChar('0'));
} }

View File

@ -35,6 +35,12 @@
class VPattern; class VPattern;
struct HistoryRecord
{
QString description{};
quint32 id{NULL_ID};
};
namespace Ui namespace Ui
{ {
class DialogHistory; class DialogHistory;
@ -86,11 +92,11 @@ private:
qint32 cursorToolRecordRow; qint32 cursorToolRecordRow;
void FillTable(); void FillTable();
QString Record(const VToolRecord &tool); HistoryRecord Record(const VToolRecord &tool) const;
void InitialTable(); void InitialTable();
void ShowPoint(); void ShowPoint();
QString PointName(quint32 pointId); QString PointName(quint32 pointId) const;
quint32 AttrUInt(const QDomElement &domElement, const QString &name); quint32 AttrUInt(const QDomElement &domElement, const QString &name) const;
void RetranslateUi(); void RetranslateUi();
int CursorRow() const; int CursorRow() const;
}; };

View File

@ -3450,6 +3450,22 @@ void VPattern::GarbageCollector(bool commit)
{ {
modElement.removeChild(modNode); modElement.removeChild(modNode);
cleared = true; cleared = true;
// Clear history
try
{
vidtype id = GetParametrId(modNode);
auto record = std::find_if(history.begin(), history.end(),
[id](const VToolRecord &record) { return record.getId() == id; });
if (record != history.end())
{
history.erase(record);
}
}
catch(const VExceptionWrongId &)
{
// do nothing
}
} }
} }
} }

View File

@ -264,7 +264,7 @@ VDomDocument::~VDomDocument()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QDomElement VDomDocument::elementById(quint32 id, const QString &tagName) QDomElement VDomDocument::elementById(quint32 id, const QString &tagName, bool updateCache)
{ {
if (id == 0) if (id == 0)
{ {
@ -278,11 +278,12 @@ QDomElement VDomDocument::elementById(quint32 id, const QString &tagName)
{ {
return e; return e;
} }
m_elementIdCache.remove(id);
} }
// Cached missed if (updateCache)
RefreshElementIdCache(); { // Cached missed
RefreshElementIdCache();
}
if (tagName.isEmpty()) if (tagName.isEmpty())
{ {
@ -290,10 +291,8 @@ QDomElement VDomDocument::elementById(quint32 id, const QString &tagName)
QHash<quint32, QDomElement> tmpCache; QHash<quint32, QDomElement> tmpCache;
if (VDomDocument::find(tmpCache, this->documentElement(), id)) if (VDomDocument::find(tmpCache, this->documentElement(), id))
{ {
m_elementIdCache = tmpCache; return tmpCache.value(id);
return m_elementIdCache.value(id);
} }
m_elementIdCache = tmpCache;
} }
else else
{ {
@ -305,7 +304,6 @@ QDomElement VDomDocument::elementById(quint32 id, const QString &tagName)
{ {
const quint32 elementId = GetParametrUInt(domElement, AttrId, NULL_ID_STR); const quint32 elementId = GetParametrUInt(domElement, AttrId, NULL_ID_STR);
m_elementIdCache.insert(elementId, domElement);
if (elementId == id) if (elementId == id)
{ {
return domElement; return domElement;

View File

@ -96,7 +96,7 @@ public:
explicit VDomDocument(QObject *parent = nullptr); explicit VDomDocument(QObject *parent = nullptr);
virtual ~VDomDocument(); virtual ~VDomDocument();
QDomElement elementById(quint32 id, const QString &tagName = QString()); QDomElement elementById(quint32 id, const QString &tagName = QString(), bool updateCache=true);
template <typename T> template <typename T>
void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const; void SetAttribute(QDomElement &domElement, const QString &name, const T &value) const;