summaryrefslogtreecommitdiffstats
path: root/libcommuni/src/util/irclagtimer.cpp
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2014-10-06 15:03:54 +0200
committerMarkus Mittendrein <git@maxmitti.tk>2014-10-06 15:03:54 +0200
commit529f38bd8878b6b1bea2b5457031ce936aab8d80 (patch)
tree1193caefcad12f6a36f818048e4547e60add4398 /libcommuni/src/util/irclagtimer.cpp
parent3b58b5536935adff242928ed9f30e1c0262fbd7c (diff)
downloadmanager-529f38bd8878b6b1bea2b5457031ce936aab8d80.tar.gz
manager-529f38bd8878b6b1bea2b5457031ce936aab8d80.zip
addedd communi
Diffstat (limited to 'libcommuni/src/util/irclagtimer.cpp')
-rw-r--r--libcommuni/src/util/irclagtimer.cpp243
1 files changed, 243 insertions, 0 deletions
diff --git a/libcommuni/src/util/irclagtimer.cpp b/libcommuni/src/util/irclagtimer.cpp
new file mode 100644
index 0000000..b1612f7
--- /dev/null
+++ b/libcommuni/src/util/irclagtimer.cpp
@@ -0,0 +1,243 @@
+/*
+ Copyright (C) 2008-2014 The Communi Project
+
+ You may use this file under the terms of BSD license as follows:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "irclagtimer.h"
+#include "irclagtimer_p.h"
+#include "ircconnection.h"
+#include "ircmessage.h"
+#include "irccommand.h"
+#include <QDateTime>
+
+IRC_BEGIN_NAMESPACE
+
+static const int DEFAULT_INTERVAL = 60;
+
+/*!
+ \file irclagtimer.h
+ \brief \#include &lt;IrcLagTimer&gt;
+ */
+
+/*!
+ \class IrcLagTimer irclagtimer.h <IrcLagTimer>
+ \ingroup util
+ \brief Provides a timer for measuring lag.
+
+ \note IrcLagTimer relies on functionality introduced in Qt 4.7.0, and is
+ therefore not functional when built against earlier versions of Qt.
+ */
+
+/*!
+ \fn void IrcLagTimer::lagChanged(qint64 lag)
+
+ This signal is emitted when the \a lag has changed.
+ */
+
+#ifndef IRC_DOXYGEN
+IrcLagTimerPrivate::IrcLagTimerPrivate() : q_ptr(0), connection(0), interval(DEFAULT_INTERVAL), lag(-1)
+{
+}
+
+bool IrcLagTimerPrivate::messageFilter(IrcMessage* msg)
+{
+ if (msg->type() == IrcMessage::Pong)
+ return processPongReply(static_cast<IrcPongMessage*>(msg));
+ return false;
+}
+
+bool IrcLagTimerPrivate::processPongReply(IrcPongMessage* msg)
+{
+#if QT_VERSION >= 0x040700
+ // TODO: configurable format?
+ if (msg->argument().startsWith("communi/")) {
+ bool ok = false;
+ qint64 timestamp = msg->argument().mid(8).toLongLong(&ok);
+ if (ok) {
+ updateLag(QDateTime::currentMSecsSinceEpoch() - timestamp);
+ return true;
+ }
+ }
+#endif // QT_VERSION
+ return false;
+}
+
+void IrcLagTimerPrivate::_irc_connected()
+{
+#if QT_VERSION >= 0x040700
+ if (interval > 0)
+ timer.start();
+#endif // QT_VERSION
+}
+
+void IrcLagTimerPrivate::_irc_pingServer()
+{
+#if QT_VERSION >= 0x040700
+ // TODO: configurable format?
+ QString argument = QString("communi/%1").arg(QDateTime::currentMSecsSinceEpoch());
+ IrcCommand* cmd = IrcCommand::createPing(argument);
+ connection->sendCommand(cmd);
+#endif // QT_VERSION
+}
+
+void IrcLagTimerPrivate::_irc_disconnected()
+{
+#if QT_VERSION >= 0x040700
+ updateLag(-1);
+ if (timer.isActive())
+ timer.stop();
+#endif // QT_VERSION
+}
+
+void IrcLagTimerPrivate::updateTimer()
+{
+#if QT_VERSION >= 0x040700
+ if (connection && interval > 0) {
+ timer.setInterval(interval * 1000);
+ if (!timer.isActive() && connection->isConnected())
+ timer.start();
+ } else {
+ if (timer.isActive())
+ timer.stop();
+ updateLag(-1);
+ }
+#endif // QT_VERSION
+}
+
+void IrcLagTimerPrivate::updateLag(qint64 value)
+{
+ Q_Q(IrcLagTimer);
+ if (lag != value) {
+ lag = qMax(-1ll, value);
+ emit q->lagChanged(lag);
+ }
+}
+#endif // IRC_DOXYGEN
+
+/*!
+ Constructs a new lag timer with \a parent.
+
+ \note If \a parent is an instance of IrcConnection, it will be
+ automatically assigned to \ref IrcLagTimer::connection "connection".
+ */
+IrcLagTimer::IrcLagTimer(QObject* parent) : QObject(parent), d_ptr(new IrcLagTimerPrivate)
+{
+ Q_D(IrcLagTimer);
+ d->q_ptr = this;
+ connect(&d->timer, SIGNAL(timeout()), this, SLOT(_irc_pingServer()));
+ setConnection(qobject_cast<IrcConnection*>(parent));
+}
+
+/*!
+ Destructs the lag timer.
+ */
+IrcLagTimer::~IrcLagTimer()
+{
+}
+
+/*!
+ This property holds the associated connection.
+
+ \par Access functions:
+ \li IrcConnection* <b>connection</b>() const
+ \li void <b>setConnection</b>(IrcConnection* connection)
+ */
+IrcConnection* IrcLagTimer::connection() const
+{
+ Q_D(const IrcLagTimer);
+ return d->connection;
+}
+
+void IrcLagTimer::setConnection(IrcConnection* connection)
+{
+ Q_D(IrcLagTimer);
+ if (d->connection != connection) {
+ if (d->connection) {
+ d->connection->removeMessageFilter(d);
+ disconnect(d->connection, SIGNAL(connected()), this, SLOT(_irc_connected()));
+ disconnect(d->connection, SIGNAL(disconnected()), this, SLOT(_irc_disconnected()));
+ }
+ d->connection = connection;
+ if (connection) {
+ connection->installMessageFilter(d);
+ connect(connection, SIGNAL(connected()), this, SLOT(_irc_connected()));
+ connect(connection, SIGNAL(disconnected()), this, SLOT(_irc_disconnected()));
+ }
+ d->updateLag(-1);
+ d->updateTimer();
+ }
+}
+
+/*!
+ This property holds the current lag in milliseconds.
+
+ The value is \c -1 when
+ \li the connection is not connected,
+ \li the lag has not yet been measured,
+ \li the lag timer is disabled (interval <= 0s), or
+ \li the Qt version is too old (4.7.0 or later is required).
+
+ \par Access function:
+ \li qint64 <b>lag</b>() const
+
+ \par Notifier signal:
+ \li void <b>lagChanged</b>(qint64 lag)
+ */
+qint64 IrcLagTimer::lag() const
+{
+ Q_D(const IrcLagTimer);
+ return d->lag;
+}
+
+/*!
+ This property holds the lag measurement interval in seconds.
+
+ The default value is \c 60 seconds. A value equal to or
+ less than \c 0 seconds disables the lag measurement.
+
+ \par Access functions:
+ \li int <b>interval</b>() const
+ \li void <b>setInterval</b>(int seconds)
+ */
+int IrcLagTimer::interval() const
+{
+ Q_D(const IrcLagTimer);
+ return d->interval;
+}
+
+void IrcLagTimer::setInterval(int seconds)
+{
+ Q_D(IrcLagTimer);
+ if (d->interval != seconds) {
+ d->interval = seconds;
+ d->updateTimer();
+ }
+}
+
+#include "moc_irclagtimer.cpp"
+#include "moc_irclagtimer_p.cpp"
+
+IRC_END_NAMESPACE