summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qtimer.h
blob: e77db27049d5892b7d160c3443555134c244f3dc (plain)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#ifndef QTIMER_H
#define QTIMER_H

#include <QtCore/qglobal.h>

#ifndef QT_NO_QOBJECT

#include <QtCore/qbasictimer.h> // conceptual inheritance
#include <QtCore/qobject.h>

#include <chrono>

QT_BEGIN_NAMESPACE

class QTimerPrivate;
class Q_CORE_EXPORT QTimer : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool singleShot READ isSingleShot WRITE setSingleShot BINDABLE bindableSingleShot)
    Q_PROPERTY(int interval READ interval WRITE setInterval BINDABLE bindableInterval)
    Q_PROPERTY(int remainingTime READ remainingTime)
    Q_PROPERTY(Qt::TimerType timerType READ timerType WRITE setTimerType BINDABLE bindableTimerType)
    Q_PROPERTY(bool active READ isActive STORED false BINDABLE bindableActive)
public:
    explicit QTimer(QObject *parent = nullptr);
    ~QTimer();

    bool isActive() const;
    QBindable<bool> bindableActive();
    int timerId() const;

    void setInterval(int msec);
    int interval() const;
    QBindable<int> bindableInterval();

    int remainingTime() const;

    void setTimerType(Qt::TimerType atype);
    Qt::TimerType timerType() const;
    QBindable<Qt::TimerType> bindableTimerType();

    void setSingleShot(bool singleShot);
    bool isSingleShot() const;
    QBindable<bool> bindableSingleShot();

    static void singleShot(int msec, const QObject *receiver, const char *member);
    static void singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member);

    // singleShot with context
    template <typename Duration, typename Functor>
    static inline void singleShot(Duration interval,
#ifdef Q_QDOC
                                  const QObject *receiver,
#else
                                  const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *receiver,
#endif

                                  Functor &&slot)
    {
        singleShot(interval, defaultTypeFor(interval), receiver, std::forward<Functor>(slot));
    }
    template <typename Duration, typename Functor>
    static inline void singleShot(Duration interval, Qt::TimerType timerType,
#ifdef Q_QDOC
                                  const QObject *receiver,
#else
                                  const typename QtPrivate::ContextTypeForFunctor<Functor>::ContextType *receiver,
#endif
                                  Functor &&slot)
    {
        using Prototype = void(*)();
        singleShotImpl(interval, timerType, receiver,
                       QtPrivate::makeCallableObject<Prototype>(std::forward<Functor>(slot)));
    }
    // singleShot without context
    template <typename Duration, typename Functor>
    static inline void singleShot(Duration interval, Functor &&slot)
    {
        singleShot(interval, defaultTypeFor(interval), nullptr, std::forward<Functor>(slot));
    }
    template <typename Duration, typename Functor>
    static inline void singleShot(Duration interval, Qt::TimerType timerType, Functor &&slot)
    {
        singleShot(interval, timerType, nullptr, std::forward<Functor>(slot));
    }

#ifdef Q_QDOC
    template <typename Functor>
    QMetaObject::Connection callOnTimeout(Functor &&slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
    template <typename Functor>
    QMetaObject::Connection callOnTimeout(const QObject *context, Functor &&slot, Qt::ConnectionType connectionType = Qt::AutoConnection);
#else
    template <typename ... Args>
    QMetaObject::Connection callOnTimeout(Args && ...args)
    {
        return QObject::connect(this, &QTimer::timeout, std::forward<Args>(args)... );
    }

#endif

public Q_SLOTS:
    void start(int msec);

    void start();
    void stop();

Q_SIGNALS:
    void timeout(QPrivateSignal);

public:
    void setInterval(std::chrono::milliseconds value)
    {
        setInterval(int(value.count()));
    }

    std::chrono::milliseconds intervalAsDuration() const
    {
        return std::chrono::milliseconds(interval());
    }

    std::chrono::milliseconds remainingTimeAsDuration() const
    {
        return std::chrono::milliseconds(remainingTime());
    }

    static void singleShot(std::chrono::milliseconds value, const QObject *receiver, const char *member)
    {
        singleShot(int(value.count()), receiver, member);
    }

    static void singleShot(std::chrono::milliseconds value, Qt::TimerType timerType, const QObject *receiver, const char *member)
    {
        singleShot(int(value.count()), timerType, receiver, member);
    }

    void start(std::chrono::milliseconds value)
    {
        start(int(value.count()));
    }

protected:
    void timerEvent(QTimerEvent *) override;

private:
    Q_DISABLE_COPY(QTimer)
    Q_DECLARE_PRIVATE(QTimer)

    inline int startTimer(int){ return -1;}
    inline void killTimer(int){}

    static constexpr Qt::TimerType defaultTypeFor(int msecs) noexcept
    { return msecs >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer; }
    static void singleShotImpl(int msec, Qt::TimerType timerType,
                               const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj);

    static Qt::TimerType defaultTypeFor(std::chrono::milliseconds interval)
    { return defaultTypeFor(int(interval.count())); }

    static void singleShotImpl(std::chrono::milliseconds interval, Qt::TimerType timerType,
                               const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj)
    {
        singleShotImpl(int(interval.count()),
                       timerType, receiver, slotObj);
    }
};

QT_END_NAMESPACE

#endif // QT_NO_QOBJECT

#endif // QTIMER_H