Files
GoldenCheetah/qwt/examples/oscilloscope/SignalData.cpp
Joachim Kohlhammer 49cf6340a4 Upgraded Qwt to 6.2 (branch: qwt-multiaxes) (#4427)
This commit is based on https://github.com/GoldenCheetah/GoldenCheetah/pull/3956
with the following additions / changes:
* Upgraded to the latest version of the multiaxes-branch, thus eliminating crashes of GoldenCheetah on startup
* Disabled the emitting of Layout Requests on geometry changes of QwtScaleWidget - without this, CPU utilization was up to 100% on one core
* Added the class SplineLookup, reusing small portions of code from Qwt 6.1
* Re-added the splines in WPrime and RideFile (resampling), using the new interface of QwtSpline
* Appveyor: qwt in cache-section now depends on qwt/qwtconfig.prin.in for refresh on version change
2024-01-06 18:59:55 -03:00

140 lines
2.9 KiB
C++

/*****************************************************************************
* Qwt Examples - Copyright (C) 2002 Uwe Rathmann
* This file may be used under the terms of the 3-clause BSD License
*****************************************************************************/
#include "SignalData.h"
#include <QVector>
#include <QMutex>
#include <QReadWriteLock>
class SignalData::PrivateData
{
public:
PrivateData()
: boundingRect( 1.0, 1.0, -2.0, -2.0 ) // invalid
{
values.reserve( 1000 );
}
inline void append( const QPointF& sample )
{
values.append( sample );
// adjust the bounding rectangle
if ( boundingRect.width() < 0 || boundingRect.height() < 0 )
{
boundingRect.setRect( sample.x(), sample.y(), 0.0, 0.0 );
}
else
{
boundingRect.setRight( sample.x() );
if ( sample.y() > boundingRect.bottom() )
boundingRect.setBottom( sample.y() );
if ( sample.y() < boundingRect.top() )
boundingRect.setTop( sample.y() );
}
}
QReadWriteLock lock;
QVector< QPointF > values;
QRectF boundingRect;
QMutex mutex; // protecting pendingValues
QVector< QPointF > pendingValues;
};
SignalData::SignalData()
{
m_data = new PrivateData();
}
SignalData::~SignalData()
{
delete m_data;
}
int SignalData::size() const
{
return m_data->values.size();
}
QPointF SignalData::value( int index ) const
{
return m_data->values[index];
}
QRectF SignalData::boundingRect() const
{
return m_data->boundingRect;
}
void SignalData::lock()
{
m_data->lock.lockForRead();
}
void SignalData::unlock()
{
m_data->lock.unlock();
}
void SignalData::append( const QPointF& sample )
{
m_data->mutex.lock();
m_data->pendingValues += sample;
const bool isLocked = m_data->lock.tryLockForWrite();
if ( isLocked )
{
const int numValues = m_data->pendingValues.size();
const QPointF* pendingValues = m_data->pendingValues.data();
for ( int i = 0; i < numValues; i++ )
m_data->append( pendingValues[i] );
m_data->pendingValues.clear();
m_data->lock.unlock();
}
m_data->mutex.unlock();
}
void SignalData::clearStaleValues( double limit )
{
m_data->lock.lockForWrite();
m_data->boundingRect = QRectF( 1.0, 1.0, -2.0, -2.0 ); // invalid
const QVector< QPointF > values = m_data->values;
m_data->values.clear();
m_data->values.reserve( values.size() );
int index;
for ( index = values.size() - 1; index >= 0; index-- )
{
if ( values[index].x() < limit )
break;
}
if ( index > 0 )
m_data->append( values[index++] );
while ( index < values.size() - 1 )
m_data->append( values[index++] );
m_data->lock.unlock();
}
SignalData& SignalData::instance()
{
static SignalData valueVector;
return valueVector;
}