diff --git a/src/omnicore/activation.cpp b/src/omnicore/activation.cpp index 08ec16f10..803c4de03 100644 --- a/src/omnicore/activation.cpp +++ b/src/omnicore/activation.cpp @@ -50,7 +50,7 @@ static void PendingActivationCompleted(const FeatureActivation& activation) { DeletePendingActivation(activation.featureId); vecCompletedActivations.push_back(activation); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); } /** @@ -70,7 +70,7 @@ void AddPendingActivation(uint16_t featureId, int activationBlock, uint32_t minC vecPendingActivations.push_back(featureActivation); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); } /** @@ -122,7 +122,7 @@ void ClearActivations() { vecPendingActivations.clear(); vecCompletedActivations.clear(); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); } /** diff --git a/src/omnicore/notifications.cpp b/src/omnicore/notifications.cpp index b71fb71ae..e7c2fde3b 100644 --- a/src/omnicore/notifications.cpp +++ b/src/omnicore/notifications.cpp @@ -36,7 +36,7 @@ void DeleteAlerts(const std::string& sender) PrintToLog("Removing deleted alert (from:%s type:%d expiry:%d message:%s)\n", alert.alert_sender, alert.alert_type, alert.alert_expiry, alert.alert_message); it = currentOmniAlerts.erase(it); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); } else { it++; } @@ -51,7 +51,7 @@ void DeleteAlerts(const std::string& sender) void ClearAlerts() { currentOmniAlerts.clear(); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); } /** @@ -148,7 +148,7 @@ bool CheckExpiredAlerts(unsigned int curBlock, uint64_t curTime) PrintToLog("Expiring alert (from %s: type:%d expiry:%d message:%s)\n", alert.alert_sender, alert.alert_type, alert.alert_expiry, alert.alert_message); it = currentOmniAlerts.erase(it); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); } else { it++; } @@ -158,7 +158,7 @@ bool CheckExpiredAlerts(unsigned int curBlock, uint64_t curTime) PrintToLog("Expiring alert (from %s: type:%d expiry:%d message:%s)\n", alert.alert_sender, alert.alert_type, alert.alert_expiry, alert.alert_message); it = currentOmniAlerts.erase(it); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); } else { it++; } @@ -168,7 +168,7 @@ bool CheckExpiredAlerts(unsigned int curBlock, uint64_t curTime) PrintToLog("Expiring alert (form: %s type:%d expiry:%d message:%s)\n", alert.alert_sender, alert.alert_type, alert.alert_expiry, alert.alert_message); it = currentOmniAlerts.erase(it); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); } else { it++; } @@ -177,7 +177,7 @@ bool CheckExpiredAlerts(unsigned int curBlock, uint64_t curTime) PrintToLog("Removing invalid alert (from:%s type:%d expiry:%d message:%s)\n", alert.alert_sender, alert.alert_type, alert.alert_expiry, alert.alert_message); it = currentOmniAlerts.erase(it); - //uiInterface.OmniStateChanged(); + uiInterface.OmniStateChanged(); break; } } diff --git a/src/omnicore/pending.cpp b/src/omnicore/pending.cpp index c98ad8869..a05b380f6 100644 --- a/src/omnicore/pending.cpp +++ b/src/omnicore/pending.cpp @@ -47,7 +47,7 @@ void PendingAdd(const uint256& txid, const std::string& sendingAddress, uint16_t } // after adding a transaction to pending the available balance may now be reduced, refresh wallet totals CheckWalletUpdate(true); // force an update since some outbound pending (eg MetaDEx cancel) may not change balances - //uiInterface.OmniPendingChanged(true); + uiInterface.OmniPendingChanged(true); } /** @@ -68,7 +68,7 @@ void PendingDelete(const uint256& txid) my_pending.erase(it); // if pending map is now empty following deletion, trigger a status change -// if (my_pending.empty()) uiInterface.OmniPendingChanged(false); + if (my_pending.empty()) uiInterface.OmniPendingChanged(false); } } diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 9530b63a2..8ca12ed56 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -33,7 +33,9 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : optionsModel(optionsModel), peerTableModel(0), banTableModel(0), - pollTimer(0) + pollTimer(0), + lockedOmniStateChanged(false), + lockedOmniBalanceChanged(false) { peerTableModel = new PeerTableModel(this); banTableModel = new BanTableModel(this); @@ -123,6 +125,48 @@ void ClientModel::updateNumConnections(int numConnections) Q_EMIT numConnectionsChanged(numConnections); } +void ClientModel::invalidateOmniState() +{ + Q_EMIT reinitOmniState(); +} + +void ClientModel::updateOmniState() +{ + lockedOmniStateChanged = false; + Q_EMIT refreshOmniState(); +} + +bool ClientModel::tryLockOmniStateChanged() +{ + if (lockedOmniStateChanged) { + return false; + } + + lockedOmniStateChanged = true; + return true; +} + +void ClientModel::updateOmniBalance() +{ + lockedOmniBalanceChanged = false; + Q_EMIT refreshOmniBalance(); +} + +bool ClientModel::tryLockOmniBalanceChanged() +{ + if (lockedOmniBalanceChanged) { + return false; + } + + lockedOmniBalanceChanged = true; + return true; +} + +void ClientModel::updateOmniPending(bool pending) +{ + Q_EMIT refreshOmniPending(pending); +} + void ClientModel::updateAlert() { Q_EMIT alertsChanged(getStatusBarWarnings()); @@ -196,6 +240,34 @@ void ClientModel::updateBanlist() } // Handlers for core signals +static void OmniStateInvalidated(ClientModel *clientmodel) +{ + // This will be triggered for if a reorg invalidates the state + QMetaObject::invokeMethod(clientmodel, "invalidateOmniState", Qt::QueuedConnection); +} + +static void OmniStateChanged(ClientModel *clientmodel) +{ + // This will be triggered for each block that contains Omni layer transactions + if (clientmodel->tryLockOmniStateChanged()) { + QMetaObject::invokeMethod(clientmodel, "updateOmniState", Qt::QueuedConnection); + } +} + +static void OmniBalanceChanged(ClientModel *clientmodel) +{ + // Triggered when a balance for a wallet address changes + if (clientmodel->tryLockOmniBalanceChanged()) { + QMetaObject::invokeMethod(clientmodel, "updateOmniBalance", Qt::QueuedConnection); + } +} + +static void OmniPendingChanged(ClientModel *clientmodel, bool pending) +{ + // Triggered when Omni pending map adds/removes transactions + QMetaObject::invokeMethod(clientmodel, "updateOmniPending", Qt::QueuedConnection, Q_ARG(bool, pending)); +} + static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress) { // emits signal "showProgress" @@ -255,6 +327,10 @@ void ClientModel::subscribeToCoreSignals() uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false)); uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true)); + uiInterface.OmniStateChanged.connect(boost::bind(OmniStateChanged, this)); + uiInterface.OmniPendingChanged.connect(boost::bind(OmniPendingChanged, this, _1)); + uiInterface.OmniBalanceChanged.connect(boost::bind(OmniBalanceChanged, this)); + uiInterface.OmniStateInvalidated.connect(boost::bind(OmniStateInvalidated, this)); } void ClientModel::unsubscribeFromCoreSignals() @@ -266,4 +342,8 @@ void ClientModel::unsubscribeFromCoreSignals() uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false)); uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true)); + uiInterface.OmniStateChanged.disconnect(boost::bind(OmniStateChanged, this)); + uiInterface.OmniPendingChanged.disconnect(boost::bind(OmniPendingChanged, this, _1)); + uiInterface.OmniBalanceChanged.disconnect(boost::bind(OmniBalanceChanged, this)); + uiInterface.OmniStateInvalidated.disconnect(boost::bind(OmniStateInvalidated, this)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 99fd574b9..8014c16fb 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -76,6 +76,9 @@ class ClientModel : public QObject QString formatClientStartupTime() const; QString dataDir() const; + bool tryLockOmniStateChanged(); + bool tryLockOmniBalanceChanged(); + private: OptionsModel *optionsModel; PeerTableModel *peerTableModel; @@ -86,12 +89,19 @@ class ClientModel : public QObject void subscribeToCoreSignals(); void unsubscribeFromCoreSignals(); + bool lockedOmniStateChanged; + bool lockedOmniBalanceChanged; + Q_SIGNALS: void numConnectionsChanged(int count); void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress, bool header); void mempoolSizeChanged(long count, size_t mempoolSizeInBytes); void alertsChanged(const QString &warnings); void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut); + void reinitOmniState(); + void refreshOmniState(); + void refreshOmniBalance(); + void refreshOmniPending(bool pending); //! Fired when a message should be reported to the user void message(const QString &title, const QString &message, unsigned int style); @@ -104,6 +114,10 @@ public Q_SLOTS: void updateNumConnections(int numConnections); void updateAlert(); void updateBanlist(); + void invalidateOmniState(); + void updateOmniState(); + void updateOmniBalance(); + void updateOmniPending(bool pending); }; #endif // BITCOIN_QT_CLIENTMODEL_H