summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Sterna <tomek@xiaoka.com>2015-09-22 09:40:13 +0200
committerTomasz Sterna <tomek@xiaoka.com>2015-09-22 09:40:13 +0200
commit1c798b3a50ad86ba4f04056158ac39000cf9f56a (patch)
treec72a0e446cb075ade41dd199a3d6822fa153e139
parente2c1fb71995cd799e83b7644140750454a3b5900 (diff)
parent8123900781037703d54730a6032b09745c69007f (diff)
Merge pull request #90 from abranson/master
Support JS timers
-rw-r--r--daemon/jskitmanager.cpp8
-rw-r--r--daemon/jskitobjects.cpp64
-rw-r--r--daemon/jskitobjects.h11
3 files changed, 81 insertions, 2 deletions
diff --git a/daemon/jskitmanager.cpp b/daemon/jskitmanager.cpp
index 2da1986..a24ab10 100644
--- a/daemon/jskitmanager.cpp
+++ b/daemon/jskitmanager.cpp
@@ -155,8 +155,12 @@ void JSKitManager::startJsApp()
// Shims for compatibility...
QJSValue result = _engine->evaluate(
- "function XMLHttpRequest() { return Pebble.createXMLHttpRequest(); }\n"
- );
+ "function XMLHttpRequest() { return Pebble.createXMLHttpRequest(); }\n\
+ function setInterval(func, time) { return Pebble.setInterval(func, time); }\n\
+ function clearInterval(id) { Pebble.clearInterval(id); }\n\
+ function setTimeout(func, time) { return Pebble.setTimeout(func, time); }\n\
+ function clearTimeout(id) { Pebble.clearTimeout(id); }\n\
+ ");
Q_ASSERT(!result.isError());
// Polyfills...
diff --git a/daemon/jskitobjects.cpp b/daemon/jskitobjects.cpp
index 01a7e20..d9ef02f 100644
--- a/daemon/jskitobjects.cpp
+++ b/daemon/jskitobjects.cpp
@@ -4,6 +4,7 @@
#include <QAuthenticator>
#include <QBuffer>
#include <QDir>
+#include <QTimerEvent>
#include <QCryptographicHash>
#include <limits>
#include "jskitobjects.h"
@@ -38,6 +39,69 @@ void JSKitPebble::removeEventListener(const QString &type, QJSValue function)
}
}
+int JSKitPebble::setInterval(QJSValue expression, int delay)
+{
+ qCDebug(l) << "Setting interval for " << delay << "ms: " << expression.toString();
+ if (expression.isString() || expression.isCallable()) {
+ int timerId = startTimer(delay);
+ _intervals.insert(timerId, expression);
+ qCDebug(l) << "Timer id: " << timerId;
+ return timerId;
+ }
+ return -1;
+}
+
+void JSKitPebble::clearInterval(int timerId)
+{
+ qCDebug(l) << "Killing interval " << timerId ;
+ killTimer(timerId);
+ _intervals.remove(timerId);
+}
+
+int JSKitPebble::setTimeout(QJSValue expression, int delay)
+{
+ qCDebug(l) << "Setting timeout for " << delay << "ms: " << expression.toString();
+ if (expression.isString() || expression.isCallable()) {
+ int timerId = startTimer(delay);
+ _timeouts.insert(timerId, expression);
+ return timerId;
+ }
+ return -1;
+}
+
+void JSKitPebble::clearTimeout(int timerId)
+{
+ qCDebug(l) << "Killing timeout " << timerId ;
+ killTimer(timerId);
+ _timeouts.remove(timerId);
+}
+
+void JSKitPebble::timerEvent(QTimerEvent *event)
+{
+ int id = event->timerId();
+ QJSValue expression; // find in either intervals or timeouts
+ if (_intervals.contains(id))
+ expression = _intervals.value(id);
+ else if (_timeouts.contains(id)) {
+ expression = _timeouts.value(id);
+ killTimer(id); // timeouts don't repeat
+ }
+ else {
+ qCWarning(l) << "Unknown timer event";
+ killTimer(id); // interval nor timeout exist. kill the timer
+ return;
+ }
+
+ if (expression.isCallable()) { // call it if it's a function
+ QJSValue result = expression.call().toString();
+ qCDebug(l) << "Timer function result: " << result.toString();
+ }
+ else { // otherwise evaluate it
+ QJSValue result = _mgr->engine()->evaluate(expression.toString());
+ qCDebug(l) << "Timer expression result: " << result.toString();
+ }
+}
+
uint JSKitPebble::sendAppMessage(QJSValue message, QJSValue callbackForAck, QJSValue callbackForNack)
{
QVariantMap data = message.toVariant().toMap();
diff --git a/daemon/jskitobjects.h b/daemon/jskitobjects.h
index 43e1c30..9f5308f 100644
--- a/daemon/jskitobjects.h
+++ b/daemon/jskitobjects.h
@@ -19,6 +19,12 @@ public:
Q_INVOKABLE void addEventListener(const QString &type, QJSValue function);
Q_INVOKABLE void removeEventListener(const QString &type, QJSValue function);
+ Q_INVOKABLE int setInterval(QJSValue expression, int delay);
+ Q_INVOKABLE void clearInterval(int timerId);
+
+ Q_INVOKABLE int setTimeout(QJSValue expression, int delay);
+ Q_INVOKABLE void clearTimeout(int timerId);
+
Q_INVOKABLE uint sendAppMessage(QJSValue message, QJSValue callbackForAck = QJSValue(), QJSValue callbackForNack = QJSValue());
Q_INVOKABLE void showSimpleNotificationOnPebble(const QString &title, const QString &body);
@@ -32,6 +38,9 @@ public:
void invokeCallbacks(const QString &type, const QJSValueList &args = QJSValueList());
+protected:
+ void timerEvent(QTimerEvent *event);
+
private:
QJSValue buildAckEventObject(uint transaction, const QString &message = QString()) const;
@@ -39,6 +48,8 @@ private:
AppInfo _appInfo;
JSKitManager *_mgr;
QHash<QString, QList<QJSValue>> _callbacks;
+ QHash<int, QJSValue> _intervals;
+ QHash<int, QJSValue> _timeouts;
};
class JSKitConsole : public QObject