Skip to content

Commit 60bd8cb

Browse files
johnny9shaavan
andcommitted
qml: introduce ChainModel
The ChainModel is responsible for managing the block information that the gui components need to show. In this case, the ChainModel will provide a list of ratios for the block times of the last 12 hours to be rendered on the block clock's dial. Co-authored-by: shaavan <[email protected]>
1 parent eb945ac commit 60bd8cb

File tree

4 files changed

+157
-0
lines changed

4 files changed

+157
-0
lines changed

src/Makefile.qt.include

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ QT_FORMS_UI = \
3636

3737
QT_MOC_CPP = \
3838
qml/moc_appmode.cpp \
39+
qml/moc_chainmodel.cpp \
3940
qml/moc_nodemodel.cpp \
4041
qml/moc_options_model.cpp \
4142
qt/moc_addressbookpage.cpp \
@@ -111,6 +112,7 @@ QT_QRC_LOCALE = qt/bitcoin_locale.qrc
111112
BITCOIN_QT_H = \
112113
qml/appmode.h \
113114
qml/bitcoin.h \
115+
qml/chainmodel.h \
114116
qml/imageprovider.h \
115117
qml/nodemodel.h \
116118
qml/options_model.h \
@@ -291,6 +293,7 @@ BITCOIN_QT_WALLET_CPP = \
291293

292294
BITCOIN_QML_BASE_CPP = \
293295
qml/bitcoin.cpp \
296+
qml/chainmodel.cpp \
294297
qml/imageprovider.cpp \
295298
qml/nodemodel.cpp \
296299
qml/options_model.cpp \

src/qml/bitcoin.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66

77
#include <chainparams.h>
88
#include <init.h>
9+
#include <interfaces/chain.h>
910
#include <interfaces/init.h>
1011
#include <interfaces/node.h>
1112
#include <logging.h>
1213
#include <node/interface_ui.h>
1314
#include <noui.h>
1415
#include <qml/appmode.h>
16+
#include <qml/chainmodel.h>
1517
#include <qml/imageprovider.h>
1618
#include <qml/nodemodel.h>
1719
#include <qml/options_model.h>
@@ -155,6 +157,7 @@ int QmlGuiMain(int argc, char* argv[])
155157
GUIUtil::LogQtInfo();
156158

157159
std::unique_ptr<interfaces::Node> node = init->makeNode();
160+
std::unique_ptr<interfaces::Chain> chain = init->makeChain();
158161
if (!node->baseInitialize()) {
159162
// A dialog with detailed error will have been shown by InitError().
160163
return EXIT_FAILURE;
@@ -170,6 +173,11 @@ int QmlGuiMain(int argc, char* argv[])
170173
QObject::connect(&init_executor, &InitExecutor::shutdownResult, qGuiApp, &QGuiApplication::quit, Qt::QueuedConnection);
171174
// QObject::connect(&init_executor, &InitExecutor::runawayException, &node_model, &NodeModel::handleRunawayException);
172175

176+
ChainModel chain_model{*chain};
177+
178+
QObject::connect(&node_model, &NodeModel::setTimeRatioList, &chain_model, &ChainModel::setTimeRatioList);
179+
QObject::connect(&node_model, &NodeModel::setTimeRatioListInitial, &chain_model, &ChainModel::setTimeRatioListInitial);
180+
173181
qGuiApp->setQuitOnLastWindowClosed(false);
174182
QObject::connect(qGuiApp, &QGuiApplication::lastWindowClosed, [&] {
175183
node->startShutdown();
@@ -185,6 +193,7 @@ int QmlGuiMain(int argc, char* argv[])
185193
engine.addImageProvider(QStringLiteral("images"), new ImageProvider{network_style.data()});
186194

187195
engine.rootContext()->setContextProperty("nodeModel", &node_model);
196+
engine.rootContext()->setContextProperty("chainModel", &chain_model);
188197

189198
OptionsQmlModel options_model{*node};
190199
engine.rootContext()->setContextProperty("optionsModel", &options_model);

src/qml/chainmodel.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <qml/chainmodel.h>
6+
7+
#include <QDateTime>
8+
#include <QThread>
9+
#include <QTime>
10+
#include <interfaces/chain.h>
11+
12+
ChainModel::ChainModel(interfaces::Chain& chain)
13+
: m_chain{chain}
14+
{
15+
QTimer* timer = new QTimer();
16+
connect(timer, &QTimer::timeout, this, &ChainModel::setCurrentTimeRatio);
17+
timer->start(1000);
18+
19+
QThread* timer_thread = new QThread;
20+
timer->moveToThread(timer_thread);
21+
timer_thread->start();
22+
}
23+
24+
void ChainModel::setTimeRatioList(int new_time)
25+
{
26+
if (m_time_ratio_list.isEmpty()) {
27+
setTimeRatioListInitial();
28+
}
29+
int time_at_meridian = timestampAtMeridian();
30+
31+
if (new_time < time_at_meridian) {
32+
return;
33+
}
34+
m_time_ratio_list.push_back(double(new_time - time_at_meridian) / SECS_IN_12_HOURS);
35+
36+
Q_EMIT timeRatioListChanged();
37+
}
38+
39+
int ChainModel::timestampAtMeridian()
40+
{
41+
int secs_since_meridian = (QTime::currentTime().msecsSinceStartOfDay() / 1000) % SECS_IN_12_HOURS;
42+
int current_timestamp = QDateTime::currentSecsSinceEpoch();
43+
44+
return current_timestamp - secs_since_meridian;
45+
}
46+
47+
void ChainModel::setTimeRatioListInitial()
48+
{
49+
int time_at_meridian = timestampAtMeridian();
50+
m_time_ratio_list.clear();
51+
/* m_time_ratio_list[0] = current_time_ratio
52+
* m_time_ratio_list[1] = 0
53+
* These two positions remain fixed for these
54+
* values in m_time_ratio_list */
55+
m_time_ratio_list.push_back(double(QDateTime::currentSecsSinceEpoch() - time_at_meridian) / SECS_IN_12_HOURS);
56+
m_time_ratio_list.push_back(0);
57+
58+
int first_block_height;
59+
int active_chain_height = m_chain.getHeight().value();
60+
bool success = m_chain.findFirstBlockWithTimeAndHeight(/*min_time=*/time_at_meridian, /*min_height=*/0, interfaces::FoundBlock().height(first_block_height));
61+
62+
if (!success) {
63+
Q_EMIT timeRatioListChanged();
64+
return;
65+
}
66+
67+
for (int height = first_block_height; height < active_chain_height + 1; height++) {
68+
m_time_ratio_list.push_back(double(m_chain.getBlockTime(height) - time_at_meridian) / SECS_IN_12_HOURS);
69+
}
70+
71+
Q_EMIT timeRatioListChanged();
72+
}
73+
74+
void ChainModel::setCurrentTimeRatio()
75+
{
76+
int secs_since_meridian = (QTime::currentTime().msecsSinceStartOfDay() / 1000) % SECS_IN_12_HOURS;
77+
double current_time_ratio = double(secs_since_meridian) / SECS_IN_12_HOURS;
78+
79+
if (current_time_ratio < m_time_ratio_list[0].toDouble()) { // That means time has crossed a meridian
80+
m_time_ratio_list.clear();
81+
}
82+
83+
if (m_time_ratio_list.isEmpty()) {
84+
m_time_ratio_list.push_back(current_time_ratio);
85+
m_time_ratio_list.push_back(0);
86+
} else {
87+
m_time_ratio_list[0] = current_time_ratio;
88+
}
89+
90+
Q_EMIT timeRatioListChanged();
91+
}

src/qml/chainmodel.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_QML_CHAINMODEL_H
6+
#define BITCOIN_QML_CHAINMODEL_H
7+
8+
#include <interfaces/chain.h>
9+
10+
#include <QObject>
11+
#include <QTimer>
12+
#include <QVariant>
13+
14+
namespace interfaces {
15+
class FoundBlock;
16+
class Chain;
17+
} // namespace interfaces
18+
19+
static const int SECS_IN_12_HOURS = 43200;
20+
21+
class ChainModel : public QObject
22+
{
23+
Q_OBJECT
24+
Q_PROPERTY(QVariantList timeRatioList READ timeRatioList NOTIFY timeRatioListChanged)
25+
26+
public:
27+
explicit ChainModel(interfaces::Chain& chain);
28+
29+
QVariantList timeRatioList() const { return m_time_ratio_list; };
30+
31+
int timestampAtMeridian();
32+
33+
void setCurrentTimeRatio();
34+
35+
public Q_SLOTS:
36+
void setTimeRatioList(int new_time);
37+
void setTimeRatioListInitial();
38+
39+
Q_SIGNALS:
40+
void timeRatioListChanged();
41+
42+
private:
43+
/* time_ratio: Ratio between the time at which an event
44+
* happened and 12 hours. So, for example, if a block is
45+
* found at 4 am or pm, the time_ratio would be 0.3.
46+
* The m_time_ratio_list stores the time ratio value for
47+
* the current_time and the time at which the blocks in
48+
* the last 12 hours were mined. */
49+
QVariantList m_time_ratio_list{0.0};
50+
51+
interfaces::Chain& m_chain;
52+
};
53+
54+
#endif // BITCOIN_QML_CHAINMODEL_H

0 commit comments

Comments
 (0)