#pragma once #include #include "../RenderAble.h" namespace YSG { void LIB_DECL startAllRenderThread(); class TimerThread; struct PlotPrivate; // 此锁用于锁住从mSet里第一个元素,到最后一个元素的渲染过程 用于时间同步 // mSet 里的元素修改前 加上此锁,可保证 所有的这个元素组数据同步 class LIB_DECL PrePareMutiDataMutex { public: SpinLock mRangeLock; QSet mSet; QVector mList; // lock,unlock都只在Plot渲染函数render里调用 一个线程,所以不用加锁 std::chrono::system_clock::time_point start; void lock(RenderAble* a) { if(mList.empty()) { mRangeLock.lock(); start = std::chrono::system_clock::now(); //qDebug() << "lock " << QTime::currentTime().toString("ss:zzz"); mList.reserve(mSet.size()); for(RenderAble* that : mSet) { mList.append(that); } } mList.removeOne(a); } void unlock() { if(mList.empty()) { //qDebug() << "unlock " << QTime::currentTime().toString("ss:zzz"); mRangeLock.unlock(); double duration = std::chrono::duration(std::chrono::system_clock::now() - start).count() * 1000; //qDebug() << "duration == " << duration; } } }; class PerformanceShower; class LIB_DECL Plot : public QWidget { Q_OBJECT public: bool usePerformanceShower(); void set_usePerformanceShower(bool use); void bindRenderThread(const QString& threadName); virtual void init() { initLayer(); } void render(); QColor backgroundColor(); bool mFirstResize = true, mFirstPrepareData = true; void setBackgroundColor(const QColor& color) const; struct Layer { QString mLayerName; QVector mRenderAbles; }; QString mObjectName; QList mLayerList; QString mDefaultLayerName; virtual void initLayer() { auto addLayer = [this](QString&& name) { auto layer = new Layer; layer->mLayerName = name; mLayerList.append(layer); mLayerMap[name] = layer; }; addLayer("background"); addLayer("plottable"); addLayer("axis"); addLayer("legend"); mDefaultLayerName = "plottable"; } bool isRendering(); void startRender(int refreshTimesPreSecond); void startRender() const; void pauseRender() const; QVector mMutiSpinLock; Plot(); ~Plot() override; PlotPrivate *d{}; private: QHash mLayerMap; bool event(QEvent* event) final; void paintEvent(QPaintEvent* event) final; friend class TimerThread; friend struct RenderAble; }; }