Remove high-freq timer

This commit is contained in:
Alex Spataru 2021-12-21 01:41:04 -05:00
parent 24792e9686
commit 7dd8682379
7 changed files with 93 additions and 212 deletions

View File

@ -93,11 +93,8 @@ IO::Console::Console()
// Read received data automatically
const auto dm = &Manager::instance();
const auto te = &Misc::TimerEvents::instance();
connect(dm, &Manager::dataSent, this, &IO::Console::onDataSent);
connect(dm, &Manager::dataReceived, this, &IO::Console::onDataReceived);
connect(te, SIGNAL(highFreqTimeout()), this, SLOT(displayData()),
Qt::QueuedConnection);
}
/**
@ -294,11 +291,8 @@ void IO::Console::save()
*/
void IO::Console::clear()
{
m_dataBuffer.clear();
m_textBuffer.clear();
m_isStartingLine = true;
m_dataBuffer.reserve(1200 * 1000);
Q_EMIT dataReceived();
}
@ -539,17 +533,6 @@ void IO::Console::append(const QString &string, const bool addTimestamp)
Q_EMIT stringReceived(processedString);
}
/**
* Displays the given @a data in the console. @c QByteArray to ~@c QString conversion is
* done by the @c dataToString() function, which displays incoming data either in UTF-8
* or in hexadecimal mode.
*/
void IO::Console::displayData()
{
append(dataToString(m_dataBuffer), showTimestamp());
m_dataBuffer.clear();
}
/**
* Displays the given @a data in the console. @c QByteArray to ~@c QString conversion is
* done by the @c dataToString() function, which displays incoming data either in UTF-8
@ -562,12 +545,11 @@ void IO::Console::onDataSent(const QByteArray &data)
}
/**
* Adds the given @a data to the incoming data buffer, which is read later by the UI
* refresh functions (displayData())
* Displays the given @a data in the console
*/
void IO::Console::onDataReceived(const QByteArray &data)
{
m_dataBuffer.append(data);
append(dataToString(data), showTimestamp());
}
/**

View File

@ -149,7 +149,6 @@ public Q_SLOTS:
void append(const QString &str, const bool addTimestamp = false);
private Q_SLOTS:
void displayData();
void onDataSent(const QByteArray &data);
void addToHistory(const QString &command);
void onDataReceived(const QByteArray &data);
@ -175,8 +174,7 @@ private:
StringList m_lines;
StringList m_historyItems;
QString m_textBuffer;
QString m_printFont;
QByteArray m_dataBuffer;
QString m_textBuffer;
};
}

View File

@ -22,31 +22,13 @@
#include "TimerEvents.h"
#include <QtMath>
/**
* Converts the given @a hz to milliseconds
*/
static int HZ_TO_MS(const int hz)
{
const double rHz = hz;
const double uHz = 1000;
return qRound(uHz / rHz);
}
/**
* Constructor function
*/
Misc::TimerEvents::TimerEvents()
{
// Configure timeout intevals
m_timerLowFreq.setInterval(HZ_TO_MS(1));
m_timerHighFreq.setInterval(HZ_TO_MS(20));
// Configure signals/slots
m_timerLowFreq.setInterval(1000);
connect(&m_timerLowFreq, &QTimer::timeout, this, &Misc::TimerEvents::lowFreqTimeout);
connect(&m_timerHighFreq, &QTimer::timeout, this,
&Misc::TimerEvents::highFreqTimeout);
}
/**
@ -58,21 +40,12 @@ Misc::TimerEvents &Misc::TimerEvents::instance()
return *singleton;
}
/**
* Returns the target UI refresh frequency
*/
int Misc::TimerEvents::highFreqTimeoutHz() const
{
return HZ_TO_MS(m_timerHighFreq.interval());
}
/**
* Stops all the timers of this module
*/
void Misc::TimerEvents::stopTimers()
{
m_timerLowFreq.stop();
m_timerHighFreq.stop();
}
/**
@ -81,23 +54,4 @@ void Misc::TimerEvents::stopTimers()
void Misc::TimerEvents::startTimers()
{
m_timerLowFreq.start();
m_timerHighFreq.start();
}
/**
* Updates the target UI refresh frequency
*/
void Misc::TimerEvents::setHighFreqTimeout(const int hz)
{
if (hz > 0)
{
m_timerHighFreq.setInterval(HZ_TO_MS(hz));
Q_EMIT highFreqTimeoutChanged();
}
else
{
m_timerHighFreq.setInterval(HZ_TO_MS(1));
Q_EMIT highFreqTimeoutChanged();
}
}

View File

@ -42,16 +42,10 @@ class TimerEvents : public QObject
{
// clang-format off
Q_OBJECT
Q_PROPERTY(int highFreqTimeoutHz
READ highFreqTimeoutHz
WRITE setHighFreqTimeout
NOTIFY highFreqTimeoutChanged)
// clang-format on
Q_SIGNALS:
void lowFreqTimeout();
void highFreqTimeout();
void highFreqTimeoutChanged();
private:
explicit TimerEvents();
@ -62,15 +56,12 @@ private:
public:
static TimerEvents &instance();
int highFreqTimeoutHz() const;
public Q_SLOTS:
void stopTimers();
void startTimers();
void setHighFreqTimeout(const int hz);
private:
QTimer m_timerLowFreq;
QTimer m_timerHighFreq;
};
}

View File

@ -42,9 +42,8 @@ Plugins::Server::Server()
// Send processed data at 1 Hz
connect(&JSON::Generator::instance(), &JSON::Generator::jsonChanged,
this, &Plugins::Server::registerFrame);
connect(&Misc::TimerEvents::instance(), &Misc::TimerEvents::highFreqTimeout,
this, &Plugins::Server::sendProcessedData,
Qt::QueuedConnection);
connect(&Misc::TimerEvents::instance(), &Misc::TimerEvents::lowFreqTimeout,
this, &Plugins::Server::sendProcessedData);
// Send I/O "raw" data directly
connect(&IO::Manager::instance(), &IO::Manager::dataReceived,

View File

@ -41,26 +41,15 @@ UI::Dashboard::Dashboard()
: m_points(100)
, m_precision(2)
{
const auto cp = &CSV::Player::instance();
const auto io = &IO::Manager::instance();
const auto ge = &JSON::Generator::instance();
const auto te = &Misc::TimerEvents::instance();
// clang-format off
connect(cp, SIGNAL(openChanged()),
this, SLOT(resetData()),
Qt::QueuedConnection);
connect(te, SIGNAL(highFreqTimeout()),
this, SLOT(updateData()),
Qt::QueuedConnection);
connect(io, SIGNAL(connectedChanged()),
this, SLOT(resetData()),
Qt::QueuedConnection);
connect(ge, SIGNAL(jsonFileMapChanged()),
this, SLOT(resetData()),
Qt::QueuedConnection);
connect(ge, &JSON::Generator::jsonChanged,
connect(&CSV::Player::instance(), &CSV::Player::openChanged,
this, &UI::Dashboard::resetData);
connect(&IO::Manager::instance(), &IO::Manager::connectedChanged,
this, &UI::Dashboard::resetData);
connect(&JSON::Generator::instance(), &JSON::Generator::jsonChanged,
this, &UI::Dashboard::processLatestJSON);
connect(&JSON::Generator::instance(), &JSON::Generator::jsonFileMapChanged,
this, &UI::Dashboard::resetData);
// clang-format on
}
@ -626,7 +615,6 @@ void UI::Dashboard::setAccelerometerVisible(const int i, const bool v) { setVisi
void UI::Dashboard::resetData()
{
// Make latest frame invalid
m_jsonList.clear();
m_latestFrame.read(QJsonObject {});
// Clear plot data
@ -668,17 +656,89 @@ void UI::Dashboard::resetData()
}
/**
* Interprets the most recent JSON frame & signals the UI to regenerate itself.
* Regenerates the data displayed on the dashboard plots
*/
void UI::Dashboard::updateData()
void UI::Dashboard::updatePlots()
{
// Check if we have anything to read
if (m_jsonList.isEmpty())
return;
// Initialize arrays that contain pointers to the
// datasets that need to be plotted.
QVector<JSON::Dataset *> fftDatasets;
QVector<JSON::Dataset *> linearDatasets;
// Sort JSON list
JFI_SortList(&m_jsonList);
// Create list with datasets that need to be graphed
for (int i = 0; i < m_latestFrame.groupCount(); ++i)
{
const auto group = m_latestFrame.groups().at(i);
for (int j = 0; j < group->datasetCount(); ++j)
{
auto dataset = group->datasets().at(j);
if (dataset->fft())
fftDatasets.append(dataset);
if (dataset->graph())
linearDatasets.append(dataset);
}
}
// Check if we need to update dataset points
if (m_linearPlotValues.count() != linearDatasets.count())
{
m_linearPlotValues.clear();
for (int i = 0; i < linearDatasets.count(); ++i)
{
m_linearPlotValues.append(PlotData());
m_linearPlotValues.last().resize(points());
// clang-format off
std::fill(m_linearPlotValues.last().begin(),
m_linearPlotValues.last().end(),
0.0001);
// clang-format on
}
}
// Check if we need to update FFT dataset points
if (m_fftPlotValues.count() != fftDatasets.count())
{
m_fftPlotValues.clear();
for (int i = 0; i < fftDatasets.count(); ++i)
{
m_fftPlotValues.append(PlotData());
m_fftPlotValues.last().resize(fftDatasets[i]->fftSamples());
// clang-format off
std::fill(m_fftPlotValues.last().begin(),
m_fftPlotValues.last().end(),
0);
// clang-format on
}
}
// Append latest values to linear plot data
for (int i = 0; i < linearDatasets.count(); ++i)
{
auto data = m_linearPlotValues[i].data();
auto count = m_linearPlotValues[i].count();
memmove(data, data + 1, count * sizeof(double));
m_linearPlotValues[i][count - 1] = linearDatasets[i]->value().toDouble();
}
// Append latest values to FFT plot data
for (int i = 0; i < fftDatasets.count(); ++i)
{
auto data = m_fftPlotValues[i].data();
auto count = m_fftPlotValues[i].count();
memmove(data, data + 1, count * sizeof(double));
m_fftPlotValues[i][count - 1] = fftDatasets[i]->value().toDouble();
}
}
/**
* Regenerates the data displayed on the dashboard widgets
*/
void UI::Dashboard::processLatestJSON(const JFI_Object &frameInfo)
{
// Save widget count
const int barC = barCount();
const int fftC = fftCount();
@ -696,15 +756,12 @@ void UI::Dashboard::updateData()
const auto pTitle = title();
// Try to read latest frame for widget updating
if (!m_latestFrame.read(m_jsonList.last().jsonDocument.object()))
if (!m_latestFrame.read(frameInfo.jsonDocument.object()))
return;
// Regenerate plot data
updatePlots();
// Remove previous values from JSON list
m_jsonList.clear();
// Update widget vectors
m_fftWidgets = getFFTWidgets();
m_ledWidgets = getLEDWidgets();
@ -778,104 +835,6 @@ void UI::Dashboard::updateData()
Q_EMIT updated();
}
void UI::Dashboard::updatePlots()
{
// Initialize arrays that contain pointers to the
// datasets that need to be plotted.
QVector<JSON::Dataset *> fftDatasets;
QVector<JSON::Dataset *> linearDatasets;
// Register all plot values for each frame
for (int f = 0; f < m_jsonList.count(); ++f)
{
// Clear dataset & latest values list
fftDatasets.clear();
linearDatasets.clear();
// Get frame, abort if frame is invalid
JSON::Frame frame;
if (!frame.read(m_jsonList.at(f).jsonDocument.object()))
continue;
// Create list with datasets that need to be graphed
for (int i = 0; i < frame.groupCount(); ++i)
{
const auto group = frame.groups().at(i);
for (int j = 0; j < group->datasetCount(); ++j)
{
auto dataset = group->datasets().at(j);
if (dataset->fft())
fftDatasets.append(dataset);
if (dataset->graph())
linearDatasets.append(dataset);
}
}
// Check if we need to update dataset points
if (m_linearPlotValues.count() != linearDatasets.count())
{
m_linearPlotValues.clear();
for (int i = 0; i < linearDatasets.count(); ++i)
{
m_linearPlotValues.append(PlotData());
m_linearPlotValues.last().resize(points());
// clang-format off
std::fill(m_linearPlotValues.last().begin(),
m_linearPlotValues.last().end(),
0.0001);
// clang-format on
}
}
// Check if we need to update FFT dataset points
if (m_fftPlotValues.count() != fftDatasets.count())
{
m_fftPlotValues.clear();
for (int i = 0; i < fftDatasets.count(); ++i)
{
m_fftPlotValues.append(PlotData());
m_fftPlotValues.last().resize(fftDatasets[i]->fftSamples());
// clang-format off
std::fill(m_fftPlotValues.last().begin(),
m_fftPlotValues.last().end(),
0);
// clang-format on
}
}
// Append latest values to linear plot data
for (int i = 0; i < linearDatasets.count(); ++i)
{
auto data = m_linearPlotValues[i].data();
auto count = m_linearPlotValues[i].count();
memmove(data, data + 1, count * sizeof(double));
m_linearPlotValues[i][count - 1] = linearDatasets[i]->value().toDouble();
}
// Append latest values to FFT plot data
for (int i = 0; i < fftDatasets.count(); ++i)
{
auto data = m_fftPlotValues[i].data();
auto count = m_fftPlotValues[i].count();
memmove(data, data + 1, count * sizeof(double));
m_fftPlotValues[i][count - 1] = fftDatasets[i]->value().toDouble();
}
}
}
/**
* Registers the JSON frame to the list of JSON frame vectors, which is later used to
* update widgets & graphs
*/
void UI::Dashboard::processLatestJSON(const JFI_Object &frameInfo)
{
m_jsonList.append(frameInfo);
}
//----------------------------------------------------------------------------------------
// Widget utility functions
//----------------------------------------------------------------------------------------

View File

@ -264,7 +264,6 @@ public Q_SLOTS:
private Q_SLOTS:
void resetData();
void updateData();
void updatePlots();
void processLatestJSON(const JFI_Object &frameInfo);
@ -319,6 +318,5 @@ private:
QVector<JSON::Group *> m_accelerometerWidgets;
JSON::Frame m_latestFrame;
QVector<JFI_Object> m_jsonList;
};
}