diff options
Diffstat (limited to 'seriesmodel.cpp')
| -rw-r--r-- | seriesmodel.cpp | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/seriesmodel.cpp b/seriesmodel.cpp new file mode 100644 index 0000000..628cb60 --- /dev/null +++ b/seriesmodel.cpp @@ -0,0 +1,146 @@ +#include "seriesmodel.h" + +// cpp +// tbb +#ifdef __linux__ +#ifndef Q_MOC_RUN +#if defined(emit) +#undef emit +#include <execution> +#define emit // restore the macro definition of "emit", as it was defined in + // gtmetamacros.h +#else +#include <execution> +#endif // defined(emit) +#endif // Q_MOC_RUN +#endif + +SeriesModel::SeriesModel(QObject* parent) + : QAbstractTableModel(parent) +{ +} + +SeriesModel::SeriesModel(const SeriesModel& other) + : QAbstractTableModel() +{ + append(other.m_points); +} + +int SeriesModel::rowCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent); + return m_points.count(); +} + +int SeriesModel::columnCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent); + return 2; +} + +QVariant SeriesModel::data(const QModelIndex& modelIndex, int role) const +{ + if (!modelIndex.isValid()) + return QVariant(); + + if (modelIndex.row() < 0 || modelIndex.row() >= m_points.count()) + return QVariant(); + + if (role == Qt::DisplayRole) + { + if (modelIndex.column() == 0) + return m_points.at(modelIndex.row()).x(); + else if (modelIndex.column() == 1) + return m_points.at(modelIndex.row()).y(); + } + + return QVariant(); +} + +void SeriesModel::append(const QVector<QVector2D> points) +{ + QMutexLocker l(&m_mtx); + beginInsertRows( + QModelIndex(), + m_points.count(), + m_points.count() + points.count() - 1 + ); + + m_points << points; + endInsertRows(); + recalcLimits(); +} + +void SeriesModel::clear() +{ + QMutexLocker l(&m_mtx); + + if (m_points.isEmpty()) + return; + + beginRemoveRows(QModelIndex(), 0, m_points.count() - 1); + m_points.clear(); + endRemoveRows(); +} + +void SeriesModel::recalcLimits() +{ + // WARNING: not thread safe + m_minX = std::numeric_limits<float>::max(); + m_maxX = std::numeric_limits<float>::min(); + m_minY = std::numeric_limits<float>::max(); + m_maxY = std::numeric_limits<float>::min(); + +#ifdef __linux__ + const auto [minX, maxX] = std::minmax_element( + std::execution::par_unseq, + m_points.constBegin(), + m_points.constEnd(), + [](const auto& a, const auto& b) { return a.x() < b.x(); } + ); + + const auto [minY, maxY] = std::minmax_element( + std::execution::par_unseq, + m_points.constBegin(), + m_points.constEnd(), + [](const auto& a, const auto& b) { return a.y() < b.y(); } + ); + + float min = std::min(minX->x(), minY->y()); + float max = std::max(maxX->x(), maxY->y()); +#else + for (const auto& p : m_points) + { + if (p.x() < m_minX) + m_minX = p.x(); + + if (p.x() > m_maxX) + m_maxX = p.x(); + + if (p.y() < m_minY) + m_minY = p.y(); + + if (p.y() > m_maxY) + m_maxY = p.y(); + } + + float min = std::min(m_minX, m_minY); + float max = std::max(m_maxX, m_maxY); +#endif + + m_minX = min; + m_maxX = max; + m_minY = min; + m_maxY = max; + + emit minXChanged(); + emit maxXChanged(); + emit minYChanged(); + emit maxYChanged(); +} + +void SeriesModel::replace(const QVector<QVector2D> points) +{ + clear(); + append(points); +} |
