初步重构
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include "Core/Base/RingBuffer.hpp"
|
||||
#include "../Axis/Frequent_Axis_p.h"
|
||||
#include "../Axis/Time_Axis_p.h"
|
||||
#include "../Renderable.h"
|
||||
#include "../base/Global.h"
|
||||
#include "../base/Performance_Shower_p.h"
|
||||
#include "../base/Plot.h"
|
||||
#include "../base/Plot_p.h"
|
||||
#include "Waterfall.h"
|
||||
namespace YSG {
|
||||
struct WaterFallData {
|
||||
int mTick;
|
||||
QVector<double> mFrequent;
|
||||
};
|
||||
struct Waterfall_Input_Data : Input_Data {
|
||||
std::list<WaterFallData> mDataList;
|
||||
void clear() override {
|
||||
mDataList.clear();
|
||||
}
|
||||
};
|
||||
struct Waterfall_Render_State : Render_State, Hover_Info_Render_State, WaterFall_Prop {};
|
||||
struct WaterFallRingBuffer {
|
||||
Psc::StreamRingBuffer_ST buffer;
|
||||
std::vector<std::uint8_t> recordBuffer;
|
||||
std::vector<std::uint8_t> snapshotBuffer;
|
||||
std::vector<double> rowBuffer;
|
||||
std::size_t recordByteSize{};
|
||||
std::size_t rowByteSize{};
|
||||
int rowCount{};
|
||||
int colCount{};
|
||||
int dataCount{};
|
||||
bool match(int col, int row) const {
|
||||
return colCount == col && rowCount == row && recordByteSize;
|
||||
}
|
||||
void resize(int col, int row) {
|
||||
colCount = col;
|
||||
rowCount = row;
|
||||
dataCount = 0;
|
||||
rowByteSize = sizeof(double) * colCount;
|
||||
recordByteSize = rowByteSize + sizeof(int);
|
||||
recordBuffer.resize(recordByteSize);
|
||||
snapshotBuffer.resize(recordByteSize * rowCount);
|
||||
rowBuffer.resize(colCount);
|
||||
buffer.init(recordByteSize * rowCount);
|
||||
}
|
||||
void push_data(const double* data, int tick) {
|
||||
if (dataCount == rowCount) {
|
||||
buffer.skip(recordByteSize);
|
||||
--dataCount;
|
||||
}
|
||||
std::memcpy(recordBuffer.data(), data, rowByteSize);
|
||||
std::memcpy(recordBuffer.data() + rowByteSize, &tick, sizeof(tick));
|
||||
buffer.write(recordBuffer.data(), recordByteSize);
|
||||
++dataCount;
|
||||
}
|
||||
int snapshot() {
|
||||
buffer.peek_best_effort(snapshotBuffer.data(), recordByteSize * dataCount);
|
||||
return dataCount;
|
||||
}
|
||||
const double* frequent_data(int row) {
|
||||
std::memcpy(rowBuffer.data(), snapshotBuffer.data() + row * recordByteSize, rowByteSize);
|
||||
return rowBuffer.data();
|
||||
}
|
||||
int tick(int row) const {
|
||||
int value;
|
||||
std::memcpy(&value, snapshotBuffer.data() + row * recordByteSize + rowByteSize, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
};
|
||||
struct Waterfall_Private : Typed_Render_Data<Waterfall, Waterfall_Render_State, Waterfall_Input_Data> {
|
||||
friend class Waterfall;
|
||||
WaterFallRingBuffer ringBuffer;
|
||||
QImage image;
|
||||
bool select_test(const QPointF& pos) override {
|
||||
return true;
|
||||
}
|
||||
void set_hover_state(const QPoint& pos, bool active) override {
|
||||
Render_Edit_Lease<Waterfall_Private, Waterfall_Render_State> edit(this);
|
||||
edit->hoverInfoPos = pos;
|
||||
edit->hoverInfoActive = active;
|
||||
}
|
||||
void prepare_data() override {
|
||||
sync_state_pipeline();
|
||||
Waterfall_Input_Data* data = render_input_data();
|
||||
const Waterfall_Render_State* s = render_state();
|
||||
int colCount = s->frequent_point_size, rowCount = s->time_axis->time_point_size();
|
||||
if (!ringBuffer.match(colCount, rowCount)) {
|
||||
ringBuffer.resize(colCount, rowCount);
|
||||
}
|
||||
for (WaterFallData& wd : data->mDataList) {
|
||||
QVector<double>& frequent_data = wd.mFrequent;
|
||||
if (frequent_data.size() != colCount) {
|
||||
qDebug() << "WaterFall 舍弃数据 colCount == " << colCount <<
|
||||
" dataSize == " << frequent_data.size() <<
|
||||
"s FrequentRectCount==" << s->frequent_point_size <<
|
||||
"sc FrequentRectCount==" << edit_state()->frequent_point_size;
|
||||
break;
|
||||
}
|
||||
ringBuffer.push_data(frequent_data.data(), wd.mTick);
|
||||
}
|
||||
clear_render_input();
|
||||
}
|
||||
void draw(QPainter* painter) override {
|
||||
Waterfall_Render_State* s = render_state();
|
||||
Performance_Shower* shower = q()->mPlot->d->mShower;
|
||||
if (shower) {
|
||||
shower->set_performance_line("FrequentRectCount", Performance_Line(QString("FrequentRectCount:%1 time_point_size: %2").arg(s->frequent_point_size).arg(s->time_axis->time_point_size())));
|
||||
}
|
||||
Abs_Axis* hAxis = s->frequent_axis;
|
||||
Time_Axis* vAxis = s->time_axis;
|
||||
Range hRange = s->frequent_range, vRange = s->time_axis->coord_range();
|
||||
Time_Ticker& maker = s->time_axis->d()->mTimeTicker;
|
||||
if (!maker.mStartCoordToEndCoord) {
|
||||
std::swap(vRange.lower, vRange.upper);
|
||||
}
|
||||
int colCount = s->frequent_point_size, rowCount = s->time_axis->time_point_size();
|
||||
if (image.width() != colCount || image.height() != rowCount) {
|
||||
image = QImage(colCount, rowCount, QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(q()->mPlot->background_color());
|
||||
Performance_Shower* shower = q()->mPlot->d->mShower;
|
||||
if (shower) {
|
||||
shower->set_performance_line("colCount, rowCount", Performance_Line(QString("colCount:%1, rowCount:%2").arg(colCount).arg(rowCount)));
|
||||
}
|
||||
}
|
||||
double valueStartCoord = s->power_range.lower;
|
||||
double rate = 256.0 / s->power_range.size();
|
||||
int bufferDataCount = ringBuffer.snapshot();
|
||||
QVector<QRgb>& mColorMap = Global::instance()->mColorMap;
|
||||
{
|
||||
Cacl c("waterfull setTime:%1 SRTT:%2 RTTVAR:%3", q()->mPlot->d->mShower);
|
||||
int startTick = (int)s->time_axis->start_coord();
|
||||
for (int row = 0; row < bufferDataCount; ++row) {
|
||||
int bufferRow = bufferDataCount - row - 1;
|
||||
auto list = ringBuffer.frequent_data(bufferRow);
|
||||
int tick = ringBuffer.tick(bufferRow);
|
||||
int tickOffset = tick - startTick;
|
||||
if (tickOffset < 0 || tickOffset >= rowCount) continue;
|
||||
QRgb* scanLine = reinterpret_cast<QRgb*>(image.scanLine(tickOffset));
|
||||
for (int col = 0; col < colCount; ++col) {
|
||||
int colorOffset = int((list[col] - valueStartCoord) * rate);
|
||||
if (colorOffset < 0 || colorOffset > 255) {
|
||||
qDebug() << "colorOffset:" << colorOffset << " value: " << list[col] << s->frequent_range;
|
||||
}
|
||||
scanLine[col] = mColorMap.at(clamp(colorOffset, 0, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
double x = hAxis->coord_to_pixel(hRange.lower, SRC::Render);
|
||||
double y = vAxis->coord_to_pixel(vRange.lower, SRC::Render);
|
||||
double w = hAxis->coord_to_pixel(hRange.upper, SRC::Render) - x;
|
||||
double h = vAxis->coord_to_pixel(vRange.upper, SRC::Render) - y;
|
||||
Range &&hAxisRange = hAxis->coord_range(), &&vAxisRange = vAxis->coord_range();
|
||||
double hr = ((hAxisRange.lower < hAxisRange.upper) ^ (hRange.lower < hRange.upper)) ? -1 : 1;
|
||||
double vr = ((vAxisRange.lower < vAxisRange.upper) ^ (vRange.lower < vRange.upper)) ? -1 : 1;
|
||||
painter->save();
|
||||
painter->scale(hr, vr);
|
||||
painter->drawImage(QRectF(hr * x, vr * y, hr * w, vr * h), image);
|
||||
painter->restore();
|
||||
if (q()->hover_ok(q())) {
|
||||
q()->draw_hover(painter, s->frequent_axis, s->time_axis);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user