diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f9f346c83..8856d7175 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -84,10 +84,6 @@ using eth::g_logPost; using eth::g_logVerbosity; using eth::c_instructionInfo; -// Horrible global for the mainwindow. Needed for the QEthereums to find the Main window which acts as multiplexer for now. -// Can get rid of this once we've sorted out ITC for signalling & multiplexed querying. -Main* g_main = nullptr; - static void initUnits(QComboBox* _b) { for (auto n = (::uint)units().size(); n-- != 0; ) @@ -100,24 +96,9 @@ Main::Main(QWidget *parent) : QMainWindow(parent), ui(new Ui::Main) { - g_main = this; - setWindowFlags(Qt::Window); ui->setupUi(this); g_logPost = [=](std::string const& s, char const* c) { simpleDebugOut(s, c); ui->log->addItem(QString::fromStdString(s)); }; - m_client.reset(new Client("AlethZero")); - - m_refresh = new QTimer(this); - connect(m_refresh, SIGNAL(timeout()), SLOT(refresh())); - m_refresh->start(100); - m_refreshNetwork = new QTimer(this); - connect(m_refreshNetwork, SIGNAL(timeout()), SLOT(refreshNetwork())); - m_refreshNetwork->start(1000); - m_refreshMining = new QTimer(this); - connect(m_refreshMining, SIGNAL(timeout()), SLOT(refreshMining())); - m_refreshMining->start(200); - - connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); #if 0&Ð_DEBUG m_servers.append("192.168.0.10:30301"); @@ -147,7 +128,6 @@ Main::Main(QWidget *parent) : cerr << "Network protocol version: " << eth::c_protocolVersion << endl; ui->configDock->close(); - on_verbosity_valueChanged(); initUnits(ui->gasPriceUnits); initUnits(ui->valueUnits); @@ -160,27 +140,61 @@ Main::Main(QWidget *parent) : statusBar()->addPermanentWidget(ui->peerCount); statusBar()->addPermanentWidget(ui->mineStatus); statusBar()->addPermanentWidget(ui->blockCount); + + connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); + - connect(ui->webView, &QWebView::titleChanged, [=]() + m_client.reset(new Client("AlethZero")); + m_client->start(); + m_ethereum.reset(new QEthereum(this, this->m_client.get(), this->owned())); + + shared_ptr
qmain(this); + shared_ptrqeth(m_ethereum.get()); + connect(ui->webView, &QWebView::loadStarted, [qmain, qeth]() { - ui->tabWidget->setTabText(0, ui->webView->title()); - }); + Main::Main *self = qmain.get(); + QEthereum *eth = new QEthereum(self, self->m_client.get(), self->owned()); + connect(self, SIGNAL(changed()), eth, SIGNAL(changed())); + QWebFrame* f = self->ui->webView->page()->mainFrame(); + f->disconnect(SIGNAL(javaScriptWindowObjectCleared())); + connect(f, &QWebFrame::javaScriptWindowObjectCleared, [f, eth, self]() + { + f->disconnect(); + f->addToJavaScriptWindowObject("env", self, QWebFrame::QtOwnership); + f->addToJavaScriptWindowObject("eth", eth, QWebFrame::ScriptOwnership); + f->evaluateJavaScript("eth.watch = function(a, s, f) { eth.changed.connect(f ? f : s) }"); + f->evaluateJavaScript("eth.newBlock = function(f) { eth.changed.connect(f) }"); + + f->evaluateJavaScript("eth.create = function(s, v, c, g, p, f) { var v = eth.doCreate(s, v, c, g, p); if (f) f(v) }"); + f->evaluateJavaScript("eth.transact = function(s, v, t, d, g, p, f) { eth.doTransact(s, v, t, d, g, p); if (f) f() }"); + f->evaluateJavaScript("eth.transactions = function(a) { return JSON.parse(eth.getTransactions(JSON.stringify(a))); }"); + f->evaluateJavaScript("String.prototype.pad = function(l, r) { return eth.pad(this, l, r) }"); + f->evaluateJavaScript("String.prototype.bin = function() { return eth.toBinary(this) }"); + f->evaluateJavaScript("String.prototype.unbin = function(l) { return eth.fromBinary(this) }"); + f->evaluateJavaScript("String.prototype.unpad = function(l) { return eth.unpad(this) }"); + f->evaluateJavaScript("String.prototype.dec = function() { return eth.toDecimal(this) }"); + f->evaluateJavaScript("String.prototype.sha3 = function() { return eth.sha3(this) }"); + }); + }); + connect(ui->webView, &QWebView::loadFinished, [=]() { this->changed(); }); - - QWebFrame* f = ui->webView->page()->currentFrame(); - connect(f, &QWebFrame::javaScriptWindowObjectCleared, [=](){ - auto qe = new QEthereum(this, m_client.get(), owned()); - qe->setup(f); - f->addToJavaScriptWindowObject("env", this, QWebFrame::QtOwnership); + + connect(ui->webView, &QWebView::titleChanged, [=]() + { + ui->tabWidget->setTabText(0, ui->webView->title()); }); - + readSettings(); refresh(); + m_refresh = new QTimer(this); + connect(m_refresh, SIGNAL(timeout()), SLOT(refresh())); + m_refresh->start(100); + { QSettings s("ethereum", "alethzero"); if (s.value("splashMessage", true).toBool()) @@ -618,6 +632,23 @@ void Main::refreshBlockChain() void Main::refresh(bool _override) { + // 7/18, Alex: aggregating timers, prelude to better threading? + // Runs much faster on slower dual-core processors + static int interval = 100; + + // refresh mining every 200ms + if(interval / 100 % 2 == 0) + refreshMining(); + + // refresh peer list every 1000ms, reset counter + if(interval == 1000) + { + interval = 0; + refreshNetwork(); + } else + interval += 100; + + eth::ClientGuard g(m_client.get()); auto const& st = state(); @@ -625,7 +656,7 @@ void Main::refresh(bool _override) if (c || _override) { changed(); - + updateBlockCount(); auto acs = st.addresses(); @@ -1189,6 +1220,7 @@ void Main::on_killBlockchain_triggered() ui->net->setChecked(false); m_client.reset(); m_client.reset(new Client("AlethZero", Address(), string(), true)); + m_client->start(); readSettings(); } diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 4484cf70b..dc717a230 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -201,5 +201,5 @@ private: QList> m_consoleHistory; - QEthereum* m_ethereum; + std::unique_ptr m_ethereum; }; diff --git a/eth/main.cpp b/eth/main.cpp index 34361a7d3..3ab4c5837 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -292,6 +292,7 @@ int main(int argc, char** argv) if (!clientName.empty()) clientName += "/"; Client c("Ethereum(++)/" + clientName + "v" + eth::EthVersion + "/" ETH_QUOTED(ETH_BUILD_TYPE) "/" ETH_QUOTED(ETH_BUILD_PLATFORM), coinbase, dbPath); + c.start(); cout << credits(); cout << "Address: " << endl << toHex(us.address().asArray()) << endl; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 43d5735ba..36c63fd0d 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -63,7 +63,9 @@ Client::Client(std::string const& _clientVersion, Address _us, std::string const Defaults::setDBPath(_dbPath); m_vc.setOk(); m_changed = true; +} +void Client::start() { static const char* c_threadName = "eth"; m_work.reset(new thread([&](){ diff --git a/libethereum/Client.h b/libethereum/Client.h index acc0afe1b..cbfdcd6e5 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -130,6 +130,9 @@ public: /// Constructor. explicit Client(std::string const& _clientVersion, Address _us = Address(), std::string const& _dbPath = std::string(), bool _forceClean = false); + // Start client. Boost require threads are started outside constructor. + void start(); + /// Destructor. ~Client(); diff --git a/libqethereum/QEthereum.cpp b/libqethereum/QEthereum.cpp index df49ad999..981c8aa20 100644 --- a/libqethereum/QEthereum.cpp +++ b/libqethereum/QEthereum.cpp @@ -233,44 +233,17 @@ QString unpadded(QString _s) QEthereum::QEthereum(QObject* _p, Client* _c, QList _accounts): QObject(_p), m_client(_c), m_accounts(_accounts) { - connect(_p, SIGNAL(changed()), SIGNAL(changed())); + // required to prevent crash on osx when performing addto/evaluatejavascript calls + this->moveToThread(_p->thread()); } QEthereum::~QEthereum() { } -void QEthereum::setAccounts(QList _l) -{ - cnote << "WAS:"; - for (auto i: m_accounts) - cnote << i.sec(); - cnote << "NOW:"; - for (auto i: _l) - cnote << i.sec(); - m_accounts = _l; - changed(); -} - void QEthereum::setup(QWebFrame* _e) { - // disconnect - disconnect(SIGNAL(changed())); - _e->addToJavaScriptWindowObject("eth", this, QWebFrame::ScriptOwnership); -/* _e->addToJavaScriptWindowObject("u256", new U256Helper, QWebFrame::ScriptOwnership); - _e->addToJavaScriptWindowObject("key", new KeyHelper, QWebFrame::ScriptOwnership); - _e->addToJavaScriptWindowObject("bytes", new BytesHelper, QWebFrame::ScriptOwnership);*/ - _e->evaluateJavaScript("eth.newBlock = function(f) { eth.changed.connect(f) }"); - _e->evaluateJavaScript("eth.watch = function(a, s, f) { eth.changed.connect(f ? f : s) }"); - _e->evaluateJavaScript("eth.create = function(s, v, c, g, p, f) { var v = eth.doCreate(s, v, c, g, p); if (f) f(v) }"); - _e->evaluateJavaScript("eth.transact = function(s, v, t, d, g, p, f) { eth.doTransact(s, v, t, d, g, p); if (f) f() }"); - _e->evaluateJavaScript("eth.transactions = function(a) { return JSON.parse(eth.getTransactions(JSON.stringify(a))); }"); - _e->evaluateJavaScript("String.prototype.pad = function(l, r) { return eth.pad(this, l, r) }"); - _e->evaluateJavaScript("String.prototype.bin = function() { return eth.toBinary(this) }"); - _e->evaluateJavaScript("String.prototype.unbin = function(l) { return eth.fromBinary(this) }"); - _e->evaluateJavaScript("String.prototype.unpad = function(l) { return eth.unpad(this) }"); - _e->evaluateJavaScript("String.prototype.dec = function() { return eth.toDecimal(this) }"); - _e->evaluateJavaScript("String.prototype.sha3 = function() { return eth.sha3(this) }"); + // Alex: JS codes moved to mainwin until qtwebkit bugs are resolved (#245) } void QEthereum::teardown(QWebFrame*) diff --git a/libqethereum/QEthereum.h b/libqethereum/QEthereum.h index 488f9a261..ae0e051be 100644 --- a/libqethereum/QEthereum.h +++ b/libqethereum/QEthereum.h @@ -376,7 +376,7 @@ public: void setup(QWebFrame* _e); void teardown(QWebFrame* _e); - void setAccounts(QList _l); + void setAccounts(QList _l) { m_accounts = _l; this->changed(); } Q_INVOKABLE QString ethTest() const { return "Hello world!"; } Q_INVOKABLE QEthereum* self() { return this; } diff --git a/walleth/MainWin.cpp b/walleth/MainWin.cpp index cbd16c298..2c36d94fc 100644 --- a/walleth/MainWin.cpp +++ b/walleth/MainWin.cpp @@ -63,7 +63,8 @@ Main::Main(QWidget *parent) : g_qmlMain = this; m_client.reset(new Client("Walleth", Address(), eth::getDataDir() + "/Walleth")); - + m_client->start(); + g_qmlClient = m_client.get(); qRegisterMetaType("eth::u256");