Paste P139

Masterwork From Distant Lands
ActivePublic

Authored by dkazakov on Nov 23 2017, 11:15 AM.
diff --git a/libs/global/kis_relaxed_timer.cpp b/libs/global/kis_relaxed_timer.cpp
index 00b3691..dfe3f4e 100644
--- a/libs/global/kis_relaxed_timer.cpp
+++ b/libs/global/kis_relaxed_timer.cpp
@@ -97,6 +97,7 @@ void KisRelaxedTimer::resync()
m_emitOnTimeTick = m_nextTimerTickSeqNo;
m_timer.start(m_interval, this);
m_tick.start();
+ m_numberOfRestarts++;
}
void KisRelaxedTimer::timerEvent(QTimerEvent *event)
diff --git a/libs/global/kis_relaxed_timer.h b/libs/global/kis_relaxed_timer.h
index 08ca7e7..20a0d7b 100644
--- a/libs/global/kis_relaxed_timer.h
+++ b/libs/global/kis_relaxed_timer.h
@@ -64,6 +64,8 @@ public:
int remainingTime() const;
+ int m_numberOfRestarts = 0;
+
Q_SIGNALS:
void timeout();
diff --git a/libs/global/kis_signal_compressor.cpp b/libs/global/kis_signal_compressor.cpp
index 90e5614..2c4dabb 100644
--- a/libs/global/kis_signal_compressor.cpp
+++ b/libs/global/kis_signal_compressor.cpp
@@ -47,6 +47,11 @@ void KisSignalCompressor::setDelay(int delay)
m_timer->setInterval(delay, 1, delay / 10);
}
+int KisSignalCompressor::numRestarts() const
+{
+ return m_timer->m_numberOfRestarts;
+}
+
void KisSignalCompressor::start()
{
Q_ASSERT(m_mode != UNDEFINED);
diff --git a/libs/global/kis_signal_compressor.h b/libs/global/kis_signal_compressor.h
index ff2ff7a..33f23eb 100644
--- a/libs/global/kis_signal_compressor.h
+++ b/libs/global/kis_signal_compressor.h
@@ -74,6 +74,8 @@ public:
void setMode(Mode mode);
void setDelay(int delay);
+ int numRestarts() const;
+
public Q_SLOTS:
void start();
void stop();
diff --git a/libs/global/tests/CMakeLists.txt b/libs/global/tests/CMakeLists.txt
index 3cc4776..717ae1b 100644
--- a/libs/global/tests/CMakeLists.txt
+++ b/libs/global/tests/CMakeLists.txt
@@ -6,3 +6,8 @@ macro_add_unittest_definitions()
ecm_add_test(KisSharedThreadPoolAdapterTest.cpp
TEST_NAME KisSharedThreadPoolAdapter
LINK_LIBRARIES kritaglobal Qt5::Test)
+
+ecm_add_test(KisSignalCompressorTest.cpp
+ TEST_NAME KisSignalCompressorTest
+ LINK_LIBRARIES kritaglobal Qt5::Test)
+
diff --git a/libs/global/tests/KisSignalCompressorTest.cpp b/libs/global/tests/KisSignalCompressorTest.cpp
new file mode 100644
index 0000000..3e9f8df
--- /dev/null
+++ b/libs/global/tests/KisSignalCompressorTest.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "KisSignalCompressorTest.h"
+
+#include <QTest>
+#include <QElapsedTimer>
+#include <QEventLoop>
+#include "kis_debug.h"
+
+
+#include <boost/accumulators/accumulators.hpp>
+#include <boost/accumulators/statistics/stats.hpp>
+#include <boost/accumulators/statistics/min.hpp>
+#include <boost/accumulators/statistics/max.hpp>
+#include <boost/accumulators/statistics/mean.hpp>
+#include <boost/accumulators/statistics/variance.hpp>
+
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/normal_distribution.hpp>
+
+using namespace boost::accumulators;
+
+class TimerTester : public QObject
+{
+ Q_OBJECT
+public:
+ TimerTester(int expectedPeriod, int tickPeriod, int tickVariance, int numEvents)
+ : m_timer(&m_eventLoop),
+ m_expectedPeriod(expectedPeriod),
+ m_desiredPeriod(tickPeriod),
+ m_desiredVariance(tickVariance),
+ m_desiredNumEvents(numEvents),
+ m_rnd(11), // manually crafted very random seed!
+ m_distribution(tickPeriod, tickVariance)
+ {
+ m_timer.setSingleShot(true);
+ connect(&m_timer, SIGNAL(timeout()), SLOT(timerTick()));
+ }
+
+ qreal periodMean() const {
+ return mean(m_accumulator);
+ }
+
+ qreal periodStandardDeviation() const {
+ return std::sqrt(lazy_variance(m_accumulator));
+ }
+
+ qreal periodMin() const {
+ return min(m_accumulator);
+ }
+
+ qreal periodMax() const {
+ return max(m_accumulator);
+ }
+
+ qreal positiveOffsetMean() const {
+ return mean(m_positiveOffsetAccumulator);
+ }
+
+ qreal positiveOffsetStandardDeviation() const {
+ return std::sqrt(lazy_variance(m_positiveOffsetAccumulator));
+ }
+
+ qreal positiveOffsetMax() const {
+ return max(m_positiveOffsetAccumulator);
+ }
+
+ qreal negativeOffsetMean() const {
+ return mean(m_negativeOffsetAccumulator);
+ }
+
+ qreal negativeOffsetStandardDeviation() const {
+ return std::sqrt(lazy_variance(m_negativeOffsetAccumulator));
+ }
+
+ qreal negativeOffsetMax() const {
+ return min(m_negativeOffsetAccumulator);
+ }
+
+ int realNumberOfTicks() const {
+ return m_realNumberOfTicks;
+ }
+
+ void start() {
+ m_timeSinceLastTick.start();
+ m_timer.start(m_distribution(m_rnd));
+
+ m_eventLoop.exec();
+ }
+
+ QEventLoop *eventLoop() {
+ return &m_eventLoop;
+ }
+
+public Q_SLOTS:
+ void externalTimerTicked() {
+ const qreal msecTime = m_timeSinceLastTick.nsecsElapsed() / 1000000.0;
+
+ //ENTER_FUNCTION() << ppVar(msecTime);
+
+ m_accumulator(msecTime);
+
+ m_positiveOffsetAccumulator(qMax(0.0, msecTime - qreal(m_expectedPeriod)));
+ m_negativeOffsetAccumulator(qMin(0.0, msecTime - qreal(m_expectedPeriod)));
+
+ m_timeSinceLastTick.restart();
+
+ if (int(count(m_accumulator)) >= m_desiredNumEvents) {
+ m_eventLoop.quit();
+ }
+ }
+
+Q_SIGNALS:
+ void sigStartExternalTimer();
+
+private Q_SLOTS:
+ void timerTick() {
+ emit sigStartExternalTimer();
+ m_timer.start(m_distribution(m_rnd));
+ m_realNumberOfTicks++;
+ }
+
+private:
+ QEventLoop m_eventLoop;
+ QTimer m_timer;
+ int m_expectedPeriod;
+ int m_desiredPeriod;
+ int m_desiredVariance;
+ int m_desiredNumEvents;
+ int m_realNumberOfTicks = 0;
+ QElapsedTimer m_timeSinceLastTick;
+ accumulator_set<qreal, stats<tag::mean, tag::lazy_variance, tag::min, tag::max> > m_accumulator;
+
+ accumulator_set<qreal, stats<tag::mean, tag::lazy_variance, tag::min> > m_negativeOffsetAccumulator;
+ accumulator_set<qreal, stats<tag::mean, tag::lazy_variance, tag::max> > m_positiveOffsetAccumulator;
+
+
+ boost::random::mt19937 m_rnd;
+ boost::random::normal_distribution<qreal> m_distribution;
+
+};
+
+#include <kis_signal_compressor.h>
+
+void KisSignalCompressorTest::test()
+{
+ const int compressorPeriod = 60;
+ const int tickPeriod = 30;
+
+
+ TimerTester tester(compressorPeriod, tickPeriod, 5, 200);
+
+ // noop testing
+ // connect(&tester, SIGNAL(sigStartExternalTimer()), &tester, SLOT(externalTimerTicked()));
+
+ KisSignalCompressor compressor(compressorPeriod, KisSignalCompressor::FIRST_ACTIVE, tester.eventLoop());
+ connect(&tester, SIGNAL(sigStartExternalTimer()), &compressor, SLOT(start()));
+ connect(&compressor, SIGNAL(timeout()), &tester, SLOT(externalTimerTicked()));
+ tester.start();
+
+ qDebug() << "Period: mean:" << tester.periodMean() <<
+ "st.dev.:" << tester.periodStandardDeviation() <<
+ "min/max:" << tester.periodMin() << tester.periodMax();
+
+ qDebug() << " +offset: mean:" << tester.positiveOffsetMean()
+ << "max:" << tester.positiveOffsetMax();
+
+ qDebug() << " -offset: mean:" << tester.negativeOffsetMean()
+ << "max:" << tester.negativeOffsetMax();
+
+ qDebug() << "Ticks:" << tester.realNumberOfTicks() << "Restarts:" << compressor.numRestarts() << qreal(compressor.numRestarts()) / tester.realNumberOfTicks();
+}
+
+QTEST_MAIN(KisSignalCompressorTest)
+
+#include "KisSignalCompressorTest.moc"
diff --git a/libs/global/tests/KisSignalCompressorTest.h b/libs/global/tests/KisSignalCompressorTest.h
new file mode 100644
index 0000000..4208388
--- /dev/null
+++ b/libs/global/tests/KisSignalCompressorTest.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KISSIGNALCOMPRESSORTEST_H
+#define KISSIGNALCOMPRESSORTEST_H
+
+#include <QtTest>
+
+class KisSignalCompressorTest : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void test();
+};
+
+#endif // KISSIGNALCOMPRESSORTEST_H
dkazakov edited the content of this paste. (Show Details)Nov 23 2017, 11:15 AM
dkazakov changed the title of this paste from untitled to Masterwork From Distant Lands.
dkazakov updated the paste's language from autodetect to autodetect.