File: js.h

package info (click to toggle)
minitube 3.9.3-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 8,600 kB
  • sloc: cpp: 19,800; xml: 68; sh: 18; makefile: 11
file content (107 lines) | stat: -rw-r--r-- 3,068 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#ifndef JS_H
#define JS_H

#include <QtQml>

#include "jsnamfactory.h"
#include "jsresult.h"

class JSTimer : public QTimer {
    Q_OBJECT

public:
    static auto &getTimers() {
        static QHash<uint, JSTimer *> timers;
        return timers;
    }

    auto getId() const { return id; }

    // This should be static but cannot bind static functions to QJSEngine
    Q_INVOKABLE void clearTimeout(QJSValue id) {
        // qDebug() << "Clearing timer" << id.toString();
        auto timer = getTimers().take(id.toUInt());
        if (timer) {
            timer->stop();
            timer->deleteLater();
        } else
            qDebug() << "Unknown id" << id.toUInt();
        return;
    }
    // This should be static but cannot bind static functions to QJSEngine
    Q_INVOKABLE QJSValue setTimeout(QJSValue callback, QJSValue delayTime, QJSValue args) {
        qDebug() << callback.toString() << delayTime.toInt() << args.toString();

        QJSValueList valueArgs;
        if (args.isArray()) {
            const int argsLength = args.property("length").toInt();
            for (int i = 0; i < argsLength; ++i) {
                auto arg = args.property(i);
                qDebug() << "Adding arg" << arg.toString();
                valueArgs << arg;
            }
        }

        auto timer = new JSTimer();
        timer->setInterval(delayTime.toInt());
        connect(timer, &JSTimer::timeout, this, [callback, valueArgs]() mutable {
            qDebug() << "Calling" << callback.toString();
            if (!callback.isCallable()) qDebug() << callback.toString() << "is not callable";
            auto value = callback.call(valueArgs);
            if (value.isError()) {
                qWarning() << "Error" << value.toString();
                qDebug() << value.property("stack").toString().splitRef('\n');
            }
        });
        timer->start();
        return timer->getId();
    }

    Q_INVOKABLE JSTimer(QObject *parent = nullptr) : QTimer(parent) {
        setTimerType(Qt::PreciseTimer);
        setSingleShot(true);
        // avoid 0
        static uint counter = 1;
        id = counter++;
        connect(this, &JSTimer::destroyed, this, [id = id] { getTimers().remove(id); });
        connect(this, &JSTimer::timeout, this, &QTimer::deleteLater);
        getTimers().insert(id, this);
    }

private:
    uint id;
};

class JS : public QObject {
    Q_OBJECT

public:
    static JS &instance();

    explicit JS(QObject *parent = nullptr);
    JSNAMFactory &getNamFactory() { return namFactory; };

    void initialize(const QUrl &url);
    bool checkError(const QJSValue &value);

    bool isInitialized();
    QQmlEngine &getEngine() { return *engine; }

    JSResult &callFunction(JSResult *result, const QString &name, const QJSValueList &args);
    void resetNAM();

signals:
    void initialized();
    void initFailed(QString message);

private:
    void initialize();

    QQmlEngine *engine;
    JSNAMFactory namFactory;
    bool initializing = false;
    bool ready = false;
    QUrl url;
};

#endif // JS_H