Skip to content

Conversation

@hebasto
Copy link
Member

@hebasto hebasto commented Apr 10, 2022

This PR:

  • is a pure refactoring with no behavior change
  • gets rid of QMetaObject::invokeMethod() "dynamic" calls, i.e., without compile-time checks of a called function name and its parameters
  • replaces std::binds with lambdas, making parameter permutation (including parameter omitting) explicit
  • makes code simpler, more concise, and easier to reason about

Additionally, debug messages have been unified.

@hebasto
Copy link
Member Author

hebasto commented Apr 10, 2022

Friendly ping @promag @ryanofsky

Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK.

m_handler_show_progress = m_node.handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2));
m_handler_show_progress = m_node.handleShowProgress(
[this](const std::string& title, int progress, [[maybe_unused]] bool resume_possible) {
Q_EMIT showProgress(QString::fromStdString(title), progress);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

508e2dc

This is fine because auto connection is used:

connect(_clientModel, &ClientModel::showProgress, this, &BitcoinGUI::showProgress);

m_handler_notify_num_connections_changed = m_node.handleNotifyNumConnectionsChanged(std::bind(NotifyNumConnectionsChanged, this, std::placeholders::_1));
m_handler_notify_num_connections_changed = m_node.handleNotifyNumConnectionsChanged(
[this](int new_num_connections) {
Q_EMIT numConnectionsChanged(new_num_connections);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

639563d

Also fine:

connect(_clientModel, &ClientModel::numConnectionsChanged, this, &BitcoinGUI::setNumConnections);

connect(model, &ClientModel::numConnectionsChanged, this, &RPCConsole::setNumConnections);

m_handler_banned_list_changed = m_node.handleBannedListChanged(
[this]() {
qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
banTableModel->refresh();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dd924e3

I think this is wrong because BanTableModel::refresh() needs to be called on the Qt main thread.

Maybe:

    GUIUtil::ObjectInvoke(banTableModel, [=] {
        banTableModel->refresh();
    });

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Fixed.

Copy link
Contributor

@shaavan shaavan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

To summarize, this PR is replacing the use of QMetaObject::invokeMethod(), std::bind, and std::placeholder with a more straightforward lambda function and direct Q_EMIT signals.

As per my understanding of the master branch’s implementation:

  • A function is used in which QMetaObject::invokeMethod(obj, member, conn_type, args) is used, which invoked the member signal or slot on the object, with the given args. Reference.
  • This function is then bounded (using std::bind) to “this” and placeholders if needed, which would be replaced by the required argument for the function. Reference.

In this PR’s implementation:

  • Instead of creating a function that would invokeMethod(), it directly creates it as a lambda function, where the argument values were earlier bounded (using std::bind).
  • It uses Q_EMIT to emit the respective signal immediately
  • All the Q_EMIT signals are bounded under a connect with Qt::ConnectionType as Qt::AutoConnection, which will ensure the signal is invoked correctly based on the receiver (if it is in the same thread or not). Reference.

However, as @promag mentioned, it is not the case with BanTableModel::refresh().

void BanTableModel::refresh()
{
    Q_EMIT layoutAboutToBeChanged();
    priv->refreshBanlist(m_node);
    Q_EMIT layoutChanged();
}

This function should be invoked under the main thread, but the emit signal it calls (layoutAboutToBeChanged()) is not bound by and connect. Hence, it would be directly emitted irrespective of the current thread. So this might probably cause some issues.

I hope my notes and understanding of this PR will help my fellow reviewers. In case any of my analyses are erroneous, please do correct me.

Testing result:

I successfully compiled this PR in Ubuntu 20.04 with Qt version 5.9.7.
I experimented with banning a few peers and sorting them (as BanTableModel::sort() uses refresh()) based on different categories, and I observed no discrepancy in the behavior.
Hence I observed no change in the behavior of GUI.

@hebasto
Copy link
Member Author

hebasto commented Apr 16, 2022

@shaavan

Thank you for your review.

I successfully compiled this PR in Ubuntu 20.04 with Qt version 5.9.7.

Want to update? :)

(bitcoin/bitcoin#24132)

@shaavan
Copy link
Contributor

shaavan commented Apr 16, 2022

Want to update? :)

Oops 😅! Let me do so now. And retest this PR ASAP!

@hebasto
Copy link
Member Author

hebasto commented Apr 16, 2022

Updated 78c4e90 -> bcbf982 (pr581.01 -> pr581.02, diff):

  • addressed @promag's comments
  • unified debug messages

Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK bcbf982

Copy link
Contributor

@w0xlt w0xlt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK bcbf982 on Ubuntu 21.10, Qt 5.15.2.

@hebasto hebasto merged commit 8c61374 into bitcoin-core:master May 20, 2022
@hebasto hebasto deleted the 220410-invoke branch May 20, 2022 10:09
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 28, 2022
@bitcoin-core bitcoin-core locked and limited conversation to collaborators May 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants