mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-28 21:34:12 +02:00
d2e0532b12
ElementPictureFactory caches the QPicture it builds for an element definition, keyed by that definition's uuid. Definitions saved before uuids were written do not have one, and every one of them presented the same null uuid. getPictures() spotted that and took an uncached path, so the drawing was rebuilt from the XML for every instance the project placed. Counted on the shipped examples: examples/m_000.qet 831 builds for 97 definitions examples/affuteuse_250h.qet 256 builds for 106 definitions examples/industrial.qet 65 builds, 553 cache hits (has uuids) 13 of the 23 example projects carry definitions without a uuid, so this is not a rare shape. Derive a key from the location when the definition has no uuid of its own. ElementsLocation::toString() qualifies an embedded path with the id of the project owning it, and QETApp hands out project ids from an ever-increasing counter and never reuses them, so the derived key cannot collide with an element of another project. Measured with callgrind, which counts instructions and so does not depend on what else the machine is doing, opening examples/affuteuse_250h.qet: 4,801,381,735 -> 4,285,411,908 instructions (-10.7 %) ElementPictureFactory::build 995 M -> 478 M ElementPictureFactory::getPictures 1289 M -> 774 M The halving of build() matches the counters independently: 106 definitions against 256 instances is 41 %, and the cost falls to 48 %. This also retires a latent aliasing bug rather than a measured one: build() inserted into m_primitives_H under the same null uuid for every definition lacking one, and getPrimitives() read back through that shared key. Its only caller is the image export dialog, which the command line does not reach, so no wrong output could be demonstrated here -- but the entries could only ever have belonged to whichever element was built last. --info stays byte identical on all 23 example projects, and the SVG export of affuteuse_250h.qet -- a project whose definitions all lack uuids -- is byte identical too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6MRq2Ach1ogvnGcbuqNLr
116 lines
3.5 KiB
C++
116 lines
3.5 KiB
C++
/*
|
|
Copyright 2006-2026 The QElectroTech Team
|
|
This file is part of QElectroTech.
|
|
|
|
QElectroTech is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
QElectroTech is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef ELEMENTPICTUREFACTORY_H
|
|
#define ELEMENTPICTUREFACTORY_H
|
|
|
|
#include <QMutex>
|
|
#include <QSharedPointer>
|
|
#include <QHash>
|
|
|
|
class ElementsLocation;
|
|
class QPicture;
|
|
class QUuid;
|
|
class QDomElement;
|
|
class QPainter;
|
|
class QGraphicsSimpleTextItem;
|
|
|
|
/**
|
|
@brief The ElementPictureFactory class
|
|
This class is singleton factory, use
|
|
to create and get the picture use by elements
|
|
*/
|
|
class ElementPictureFactory
|
|
{
|
|
public :
|
|
struct primitives
|
|
{
|
|
QList<QLineF> m_lines;
|
|
QList<QRectF> m_rectangles;
|
|
QList<QRectF> m_circles;
|
|
QList<QVector<QPointF>> m_polygons;
|
|
QList<QVector<qreal>> m_arcs;
|
|
QList<QGraphicsSimpleTextItem*> m_texts;
|
|
};
|
|
|
|
|
|
/**
|
|
@brief instance
|
|
@return The instance of the factory
|
|
*/
|
|
static ElementPictureFactory* instance()
|
|
{
|
|
static QMutex mutex;
|
|
if (!m_factory)
|
|
{
|
|
mutex.lock();
|
|
if (!m_factory) {
|
|
m_factory = new ElementPictureFactory();
|
|
}
|
|
mutex.unlock();
|
|
}
|
|
return m_factory;
|
|
}
|
|
|
|
/**
|
|
@brief dropInstance
|
|
Drop the instance of factory
|
|
*/
|
|
static void dropInstance()
|
|
{
|
|
static QMutex mutex;
|
|
if (m_factory)
|
|
{
|
|
mutex.lock();
|
|
delete m_factory;
|
|
m_factory = nullptr;
|
|
mutex.unlock();
|
|
}
|
|
}
|
|
|
|
void getPictures(const ElementsLocation &location, QPicture &picture, QPicture &low_picture);
|
|
QPixmap pixmap(const ElementsLocation &location);
|
|
ElementPictureFactory::primitives getPrimitives(const ElementsLocation &location);
|
|
|
|
private:
|
|
ElementPictureFactory() {}
|
|
ElementPictureFactory (const ElementPictureFactory &);
|
|
ElementPictureFactory operator= (const ElementPictureFactory &);
|
|
~ElementPictureFactory();
|
|
|
|
static QUuid cacheKey(const ElementsLocation &location);
|
|
bool build(const ElementsLocation &location, QPicture *picture=nullptr, QPicture *low_picture=nullptr);
|
|
void parseElement(const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseLine (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseRect (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseEllipse(const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseCircle (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseArc (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parsePolygon(const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseText (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parsePlcTable(const QDomElement &dom, const QDomElement &plc_data, QPainter &painter) const;
|
|
void setPainterStyle(const QDomElement &dom, QPainter &painter) const;
|
|
|
|
QHash<QUuid, QPicture> m_pictures_H;
|
|
QHash<QUuid, QPicture> m_low_pictures_H;
|
|
QHash<QUuid, QPixmap> m_pixmap_H;
|
|
QHash<QUuid, primitives> m_primitives_H;
|
|
static ElementPictureFactory* m_factory;
|
|
};
|
|
|
|
#endif // ELEMENTPICTUREFACTORY_H
|