Skip to content

Commit

Permalink
gui: Add WalletController
Browse files Browse the repository at this point in the history
  • Loading branch information
promag committed Jan 18, 2019
1 parent cefb399 commit 8fa271f
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Makefile.qt.include
Expand Up @@ -157,6 +157,7 @@ QT_MOC_CPP = \
qt/moc_transactiontablemodel.cpp \
qt/moc_transactionview.cpp \
qt/moc_utilitydialog.cpp \
qt/moc_walletcontroller.cpp \
qt/moc_walletframe.cpp \
qt/moc_walletmodel.cpp \
qt/moc_walletview.cpp
Expand Down Expand Up @@ -237,6 +238,7 @@ BITCOIN_QT_H = \
qt/transactiontablemodel.h \
qt/transactionview.h \
qt/utilitydialog.h \
qt/walletcontroller.h \
qt/walletframe.h \
qt/walletmodel.h \
qt/walletmodeltransaction.h \
Expand Down Expand Up @@ -350,6 +352,7 @@ BITCOIN_QT_WALLET_CPP = \
qt/transactionrecord.cpp \
qt/transactiontablemodel.cpp \
qt/transactionview.cpp \
qt/walletcontroller.cpp \
qt/walletframe.cpp \
qt/walletmodel.cpp \
qt/walletmodeltransaction.cpp \
Expand Down
95 changes: 95 additions & 0 deletions src/qt/walletcontroller.cpp
@@ -0,0 +1,95 @@
// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/walletcontroller.h>

#include <interfaces/handler.h>
#include <interfaces/node.h>

#include <algorithm>

#include <QMutexLocker>
#include <QThread>

WalletController::WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent)
: QObject(parent)
, m_node(node)
, m_platform_style(platform_style)
, m_options_model(options_model)
{
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
getOrCreateWallet(std::move(wallet));
});

for (std::unique_ptr<interfaces::Wallet>& wallet : m_node.getWallets()) {
getOrCreateWallet(std::move(wallet));
}
}

// Not using the default destructor because not all member types definitions are
// available in the header, just forward declared.
WalletController::~WalletController() {}

std::vector<WalletModel*> WalletController::getWallets() const
{
QMutexLocker locker(&m_mutex);
return m_wallets;
}

WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet)
{
QMutexLocker locker(&m_mutex);

// Return model instance if exists.
if (!m_wallets.empty()) {
std::string name = wallet->getWalletName();
for (WalletModel* wallet_model : m_wallets) {
if (wallet_model->wallet().getWalletName() == name) {
return wallet_model;
}
}
}

// Instantiate model and register it.
WalletModel* wallet_model = new WalletModel(std::move(wallet), m_node, m_platform_style, m_options_model, nullptr);
m_wallets.push_back(wallet_model);

connect(wallet_model, &WalletModel::unload, [this, wallet_model] {
removeAndDeleteWallet(wallet_model);
});

// Re-emit coinsSent signal from wallet model.
connect(wallet_model, &WalletModel::coinsSent, this, &WalletController::coinsSent);

// Notify walletAdded signal on the GUI thread.
if (QThread::currentThread() == thread()) {
addWallet(wallet_model);
} else {
// Handler callback runs in a different thread so fix wallet model thread affinity.
wallet_model->moveToThread(thread());
QMetaObject::invokeMethod(this, "addWallet", Qt::QueuedConnection, Q_ARG(WalletModel*, wallet_model));
}

return wallet_model;
}

void WalletController::addWallet(WalletModel* wallet_model)
{
// Take ownership of the wallet model and register it.
wallet_model->setParent(this);
Q_EMIT walletAdded(wallet_model);
}

void WalletController::removeAndDeleteWallet(WalletModel* wallet_model)
{
// Unregister wallet model.
{
QMutexLocker locker(&m_mutex);
m_wallets.erase(std::remove(m_wallets.begin(), m_wallets.end(), wallet_model));
}
Q_EMIT walletRemoved(wallet_model);
// Currently this can trigger the unload since the model can hold the last
// CWallet shared pointer.
delete wallet_model;
}
59 changes: 59 additions & 0 deletions src/qt/walletcontroller.h
@@ -0,0 +1,59 @@
// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_QT_WALLETCONTROLLER_H
#define BITCOIN_QT_WALLETCONTROLLER_H

#include <qt/walletmodel.h>
#include <sync.h>

#include <list>
#include <memory>
#include <vector>

#include <QMutex>

class OptionsModel;
class PlatformStyle;

namespace interfaces {
class Handler;
class Node;
} // namespace interfaces

/**
* Controller between interfaces::Node, WalletModel instances and the GUI.
*/
class WalletController : public QObject
{
Q_OBJECT

WalletModel* getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
void removeAndDeleteWallet(WalletModel* wallet_model);

public:
WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent);
~WalletController();

std::vector<WalletModel*> getWallets() const;

private Q_SLOTS:
void addWallet(WalletModel* wallet_model);

Q_SIGNALS:
void walletAdded(WalletModel* wallet_model);
void walletRemoved(WalletModel* wallet_model);

void coinsSent(WalletModel* wallet_model, SendCoinsRecipient recipient, QByteArray transaction);

private:
interfaces::Node& m_node;
const PlatformStyle* const m_platform_style;
OptionsModel* const m_options_model;
mutable QMutex m_mutex;
std::vector<WalletModel*> m_wallets;
std::unique_ptr<interfaces::Handler> m_handler_load_wallet;
};

#endif // BITCOIN_QT_WALLETCONTROLLER_H

0 comments on commit 8fa271f

Please sign in to comment.