From 5fa32387d5180957fbe43fc65afd6ae92655b58f Mon Sep 17 00:00:00 2001 From: yann300 Date: Sun, 18 Jan 2015 21:01:15 +0100 Subject: [PATCH 1/6] Ethereum QML types: #612 --- mix/AppContext.cpp | 1 + mix/ClientModel.cpp | 26 +++------ mix/ClientModel.h | 23 ++++---- mix/QBigInt.cpp | 59 +++++++++++++++++++ mix/QBigInt.h | 88 ++++++++++++++++++++++++++++ mix/QEther.cpp | 55 ++++++++++++++++++ mix/QEther.h | 86 +++++++++++++++++++++++++++ mix/qml.qrc | 2 + mix/qml/Ether.qml | 106 ++++++++++++++++++++++++++++++++++ mix/qml/EtherValue.qml | 12 ++++ mix/qml/StateDialog.qml | 28 +++++++-- mix/qml/StateList.qml | 7 ++- mix/qml/TransactionDialog.qml | 60 ++++++++++++++----- 13 files changed, 502 insertions(+), 51 deletions(-) create mode 100644 mix/QBigInt.cpp create mode 100644 mix/QBigInt.h create mode 100644 mix/QEther.cpp create mode 100644 mix/QEther.h create mode 100644 mix/qml/Ether.qml create mode 100644 mix/qml/EtherValue.qml diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index 4c8e61510..b7c8b100c 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -49,6 +49,7 @@ AppContext::AppContext(QQmlApplicationEngine* _engine) m_applicationEngine->rootContext()->setContextProperty("appContext", this); qmlRegisterType("org.ethereum.qml", 1, 0, "FileIo"); qmlRegisterSingletonType(QUrl("qrc:/qml/ProjectModel.qml"), "org.ethereum.qml.ProjectModel", 1, 0, "ProjectModel"); + qmlRegisterType("org.ethereum.qml.QEther", 1, 0, "QEther"); m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get()); m_applicationEngine->rootContext()->setContextProperty("fileIo", m_fileIo.get()); diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 14fcf9bfa..4b343297d 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -37,23 +37,11 @@ using namespace dev; using namespace dev::eth; using namespace dev::mix; -/// @todo Move this to QML -dev::u256 fromQString(QString const& _s) -{ - return dev::jsToU256(_s.toStdString()); -} - -/// @todo Move this to QML -QString toQString(dev::u256 _value) -{ - std::ostringstream s; - s << _value; - return QString::fromStdString(s.str()); -} - ClientModel::ClientModel(AppContext* _context): m_context(_context), m_running(false) { + qRegisterMetaType("QBigInt*"); + qRegisterMetaType("QEther*"); qRegisterMetaType("QVariableDefinition*"); qRegisterMetaType("QVariableDefinitionList*"); qRegisterMetaType>("QList"); @@ -74,7 +62,7 @@ void ClientModel::debugDeployment() void ClientModel::debugState(QVariantMap _state) { - u256 balance = fromQString(_state.value("balance").toString()); + u256 balance = (qvariant_cast(_state.value("balance")))->toU256Wei(); QVariantList transactions = _state.value("transactions").toList(); std::vector transactionSequence; @@ -84,14 +72,14 @@ void ClientModel::debugState(QVariantMap _state) QVariantMap transaction = t.toMap(); QString functionId = transaction.value("functionId").toString(); - u256 value = fromQString(transaction.value("value").toString()); - u256 gas = fromQString(transaction.value("gas").toString()); - u256 gasPrice = fromQString(transaction.value("gasPrice").toString()); + u256 gas = (qvariant_cast(_state.value("gas")))->toU256Wei(); + u256 value = (qvariant_cast(_state.value("value")))->toU256Wei(); + u256 gasPrice = (qvariant_cast(_state.value("gasPrice")))->toU256Wei(); QVariantMap params = transaction.value("parameters").toMap(); TransactionSettings transactionSettings(functionId, value, gas, gasPrice); for (auto p = params.cbegin(); p != params.cend(); ++p) - transactionSettings.parameterValues.insert(std::make_pair(p.key(), fromQString(p.value().toString()))); + transactionSettings.parameterValues.insert(std::make_pair(p.key(), (qvariant_cast(p.value()))->toU256Wei())); transactionSequence.push_back(transactionSettings); } diff --git a/mix/ClientModel.h b/mix/ClientModel.h index 509a5995b..a9450532e 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -1,18 +1,18 @@ /* - This file is part of cpp-ethereum. + This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . */ /** @file ClientModel.h * @author Yann yann@ethdev.com @@ -26,6 +26,7 @@ #include #include "DebuggingStateWrapper.h" #include "MixClient.h" +#include "QEther.h" using AssemblyDebuggerData = std::tuple, dev::mix::QQMLMap*>; diff --git a/mix/QBigInt.cpp b/mix/QBigInt.cpp new file mode 100644 index 000000000..9cfcf5783 --- /dev/null +++ b/mix/QBigInt.cpp @@ -0,0 +1,59 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file QBigInt.cpp + * @author Yann yann@ethdev.com + * @date 2015 + */ + +#include "boost/variant/multivisitors.hpp" +#include "boost/variant.hpp" +#include +#include "QBigInt.h" + +using namespace dev; +using namespace dev::mix; + +QString QBigInt::value() const +{ + std::ostringstream s; + s << m_internalValue; + return QString::fromStdString(s.str()); +} + +QBigInt* QBigInt::subtract(QBigInt* const& _value) const +{ + BigIntVariant toSubtract = _value->internalValue(); + return new QBigInt(boost::apply_visitor(mix::subtract(), m_internalValue, toSubtract)); +} + +QBigInt* QBigInt::add(QBigInt* const& _value) const +{ + BigIntVariant toAdd = _value->internalValue(); + return new QBigInt(boost::apply_visitor(mix::add(), m_internalValue, toAdd)); +} + +QBigInt* QBigInt::multiply(QBigInt* const& _value) const +{ + BigIntVariant toMultiply = _value->internalValue(); + return new QBigInt(boost::apply_visitor(mix::multiply(), m_internalValue, toMultiply)); +} + +QBigInt* QBigInt::divide(QBigInt* const& _value) const +{ + BigIntVariant toDivide = _value->internalValue(); + return new QBigInt(boost::apply_visitor(mix::divide(), m_internalValue, toDivide)); +} diff --git a/mix/QBigInt.h b/mix/QBigInt.h new file mode 100644 index 000000000..8de566856 --- /dev/null +++ b/mix/QBigInt.h @@ -0,0 +1,88 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file QBigInt.h + * @author Yann yann@ethdev.com + * @date 2015 + * Represent a big integer (u256, bigint, ...) to be used in QML. + */ + +#pragma once + +#include "boost/variant.hpp" +#include "boost/variant/multivisitors.hpp" +#include +#include +#include + +using namespace dev; + +namespace dev +{ +namespace mix +{ + +using BigIntVariant = boost::variant; + +struct add: public boost::static_visitor +{ + template + BigIntVariant operator()(T1 _value, T2 _otherValue) const { return _value + _otherValue; } +}; + +struct subtract: public boost::static_visitor +{ + template + BigIntVariant operator()(T1 _value, T2 _otherValue) const { return _value - _otherValue; } +}; + +struct multiply: public boost::static_visitor +{ + template + BigIntVariant operator()(T1 _value, T2 _otherValue) const { return _value * _otherValue; } +}; + +struct divide: public boost::static_visitor +{ + template + BigIntVariant operator()(T1 _value, T2 _otherValue) const { return _value / _otherValue; } +}; + +class QBigInt: public QObject +{ + Q_OBJECT + +public: + QBigInt(dev::u256 const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) {} + QBigInt(dev::bigint const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) {} + QBigInt(BigIntVariant const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value){} + ~QBigInt() {} + + BigIntVariant internalValue() { return m_internalValue; } + Q_INVOKABLE QString value() const; + Q_INVOKABLE QBigInt* subtract(QBigInt* const& _value) const; + Q_INVOKABLE QBigInt* add(QBigInt* const& _value) const; + Q_INVOKABLE QBigInt* multiply(QBigInt* const& _value) const; + Q_INVOKABLE QBigInt* divide(QBigInt* const& _value) const; + +protected: + BigIntVariant m_internalValue; +}; + +} +} + + diff --git a/mix/QEther.cpp b/mix/QEther.cpp new file mode 100644 index 000000000..6b8a15639 --- /dev/null +++ b/mix/QEther.cpp @@ -0,0 +1,55 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file QEther.cpp + * @author Yann yann@ethdev.com + * @date 2014 + */ + +#include +#include "QEther.h" + +using namespace dev::mix; + +QString QEther::format() const +{ + return QString::fromStdString(dev::eth::formatBalance(boost::get(toWei()->internalValue()))); +} + +QString QEther::unit() const +{ + QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); + const char* key = units.valueToKey(m_currentUnit); + return QString(key); +} + +void QEther::setUnit(QString const& _unit) +{ + QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); + m_currentUnit = static_cast(units.keysToValue(_unit.toStdString().c_str())); +} + +QBigInt* QEther::toWei() const +{ + QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); + const char* key = units.valueToKey(m_currentUnit); + for (std::pair rawUnit: dev::eth::units()) + { + if (rawUnit.second == QString(key).toStdString()) + return multiply(new QBigInt(rawUnit.first)); + } + return new QBigInt(dev::u256(0)); +} diff --git a/mix/QEther.h b/mix/QEther.h new file mode 100644 index 000000000..086a66c66 --- /dev/null +++ b/mix/QEther.h @@ -0,0 +1,86 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file QEther.h + * @author Yann yann@ethdev.com + * @date 2014 + * Represent an Ether value in QML (mapped to u256 in c++). + */ + +#pragma once + +#include +#include +#include "QBigInt.h" + +namespace dev +{ +namespace mix +{ + +class QEther: public QBigInt +{ + Q_OBJECT + Q_ENUMS(EtherUnit) + Q_PROPERTY(QString value READ value WRITE setValue NOTIFY valueChanged) + Q_PROPERTY(QString unit READ unit WRITE setUnit NOTIFY unitChanged) + +public: + enum EtherUnit + { + Uether, + Vether, + Dether, + Nether, + Yether, + Zether, + Eether, + Pether, + Tether, + Gether, + Mether, + grand, + ether, + finney, + szabo, + Gwei, + Mwei, + Kwei, + wei + }; + + QEther(QObject* _parent = 0): QBigInt(dev::u256(0), _parent), m_currentUnit(EtherUnit::ether) {} + QEther(dev::u256 _value, EtherUnit _unit, QObject* _parent = 0): QBigInt(_value, _parent), m_currentUnit(_unit) {} + ~QEther() {} + + Q_INVOKABLE QString format() const; + Q_INVOKABLE QBigInt* toWei() const; + Q_INVOKABLE void setValue(QString const& _value) { m_internalValue = dev::jsToU256(_value.toStdString()); } + Q_INVOKABLE QString unit() const; + Q_INVOKABLE void setUnit(QString const& _unit); + dev::u256 toU256Wei() { return boost::get(toWei()->internalValue()); } + +private: + EtherUnit m_currentUnit; + +signals: + void valueChanged(); + void unitChanged(); +}; + +} +} + diff --git a/mix/qml.qrc b/mix/qml.qrc index 344fcaa22..bc4568abf 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -40,5 +40,7 @@ qml/CodeEditorView.qml qml/js/ProjectModel.js qml/WebPreview.qml + qml/Ether.qml + qml/EtherValue.qml diff --git a/mix/qml/Ether.qml b/mix/qml/Ether.qml new file mode 100644 index 000000000..7df6369ad --- /dev/null +++ b/mix/qml/Ether.qml @@ -0,0 +1,106 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.1 + +Rectangle { + id: etherEdition + property bool displayFormattedValue; + property bool edit; + property variant value; + onValueChanged: update() + Component.onCompleted: update() + + function update() + { + etherValueEdit.text = value.value; + selectUnit(value.unit); + } + + function selectUnit(unit) + { + for(var i = 0; i < unitsModel.count; ++i) + { + if (unitsModel.get(i).text === unit) + { + units.currentIndex = i; + return; + } + } + } + + RowLayout + { + anchors.fill: parent; + id: row + width: 200 + height: parent.height + Rectangle + { + width : 200 + color: edit ? "blue" : "white" + TextField + { + onTextChanged: + { + value.setValue(text) + formattedValue.text = value.format(); + } + width: parent.width + readOnly: !edit + visible: edit + id: etherValueEdit; + } + } + + Rectangle + { + Layout.fillWidth: true + id: unitContainer + width: 20 + anchors.verticalCenter: parent.verticalCenter + ComboBox + { + id: units + onCurrentTextChanged: + { + value.setUnit(currentText); + formattedValue.text = value.format(); + } + model: ListModel { + id: unitsModel + ListElement { text: "wei"; } + ListElement { text: "Kwei"; } + ListElement { text: "Mwei"; } + ListElement { text: "Gwei"; } + ListElement { text: "szabo"; } + ListElement { text: "finney"; } + ListElement { text: "ether"; } + ListElement { text: "grand"; } + ListElement { text: "Mether"; } + ListElement { text: "Gether"; } + ListElement { text: "Tether"; } + ListElement { text: "Pether"; } + ListElement { text: "Eether"; } + ListElement { text: "Zether"; } + ListElement { text: "Yether"; } + ListElement { text: "Nether"; } + ListElement { text: "Dether"; } + ListElement { text: "Vether"; } + ListElement { text: "Uether"; } + } + } + Rectangle + { + anchors.verticalCenter: parent.verticalCenter + anchors.left: units.right + visible: displayFormattedValue + width: 20 + Text + { + id: formattedValue + } + } + } + } +} diff --git a/mix/qml/EtherValue.qml b/mix/qml/EtherValue.qml new file mode 100644 index 000000000..e1a838447 --- /dev/null +++ b/mix/qml/EtherValue.qml @@ -0,0 +1,12 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.1 +import org.ethereum.qml.QEther 1.0 + +QEther +{ + id: basicEther + value: "1000000" + unit: "ether" +} diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index cde7cb3ef..da24d457e 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -2,6 +2,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 +import org.ethereum.qml.QEther 1.0 Window { modality: Qt.WindowModal @@ -12,7 +13,7 @@ Window { visible: false property alias stateTitle: titleField.text - property alias stateBalance: balanceField.text + property alias stateBalance: balanceField.value property int stateIndex property var stateTransactions: [] signal accepted @@ -20,7 +21,7 @@ Window { function open(index, item) { stateIndex = index; stateTitle = item.title; - stateBalance = item.balance; + balanceField.value = item.balance; transactionsModel.clear(); stateTransactions = []; var transactions = item.transactions; @@ -66,9 +67,15 @@ Window { Label { text: qsTr("Balance") } - TextField { + Ether { id: balanceField + edit: true + displayFormattedValue: true Layout.fillWidth: true + value: QEther { + value: "100000" + unit: "ether" + } } Label { @@ -114,16 +121,25 @@ Window { transactionDialog.open(index, transactionsModel.get(index)); } + function ether(_value, _unit) + { + var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); + var ether = etherComponent.createObject(transactionsModel); + ether.setValue(_value); + ether.setUnit(_unit); + return ether; + } + function addTransaction() { // Set next id here to work around Qt bug // https://bugreports.qt-project.org/browse/QTBUG-41327 // Second call to signal handler would just edit the item that was just created, no harm done var item = { - value: "0", + value: ether("0", "ether"), functionId: "", - gas: "125000", - gasPrice: "100000" + gas: ether("125000", "ether"), + gasPrice: ether("100000", "ether") }; transactionDialog.open(transactionsModel.count, item); diff --git a/mix/qml/StateList.qml b/mix/qml/StateList.qml index 519e533d5..05537f3ad 100644 --- a/mix/qml/StateList.qml +++ b/mix/qml/StateList.qml @@ -4,6 +4,7 @@ import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import org.ethereum.qml.ProjectModel 1.0 +import org.ethereum.qml.QEther 1.0 Rectangle { color: "#ededed" @@ -67,9 +68,13 @@ Rectangle { id: stateListModel function addState() { + var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); + var ether = etherComponent.createObject(stateListModel); + ether.setValue("100000000000000000000000000"); + ether.setUnit("ether"); var item = { title: "", - balance: "100000000000000000000000000", + balance: ether, transactions: [] }; stateDialog.open(stateListModel.count, item); diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index 3a32e2af5..19727cd7d 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -2,6 +2,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 +import org.ethereum.qml.QEther 1.0 Window { modality: Qt.WindowModal @@ -11,9 +12,9 @@ Window { property int transactionIndex property alias transactionParams: paramsModel; - property alias gas: gasField.text; - property alias gasPrice: gasPriceField.text; - property alias transactionValue: valueField.text; + property alias gas: gasField.value; + property alias gasPrice: gasPriceField.value; + property alias transactionValue: valueField.value; property alias functionId: functionComboBox.currentText; property var itemParams; @@ -21,9 +22,9 @@ Window { function open(index, item) { transactionIndex = index; - gas = item.gas; - gasPrice = item.gasPrice; - transactionValue = item.value; + gasField.value = item.gas; + gasPriceField.value = item.gasPrice; + valueField.value = item.value; var functionId = item.functionId; itemParams = item.parameters !== undefined ? item.parameters : {}; functionsModel.clear(); @@ -53,7 +54,7 @@ Window { var parameters = func.parameters; for (var p = 0; p < parameters.length; p++) { var pname = parameters[p].name; - paramsModel.append({ name: pname, type: parameters[p].type, value: itemParams[pname] !== undefined ? itemParams[pname] : "" }); + paramsModel.append({ name: pname, type: parameters[p].type, value: itemParams[pname] !== undefined ? itemParams[pname].value() : "" }); } } } @@ -74,7 +75,11 @@ Window { } for (var p = 0; p < transactionDialog.transactionParams.count; p++) { var parameter = transactionDialog.transactionParams.get(p); - item.parameters[parameter.name] = parameter.value; + var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); + var param = etherComponent.createObject(stateListModel); + ether.setValue(parameter.value); + ether.setUnit("ether"); + item.parameters[parameter.name] = param; } return item; } @@ -107,25 +112,52 @@ Window { Label { text: qsTr("Value") } - TextField { - id: valueField + Rectangle + { Layout.fillWidth: true + Ether { + id: valueField + edit: true + displayFormattedValue: true + value: QEther { + value: "100000" + unit: "ether" + } + } } Label { text: qsTr("Gas") } - TextField { - id: gasField + Rectangle + { Layout.fillWidth: true + Ether { + id: gasField + edit: true + displayFormattedValue: true + value: QEther { + value: "100000" + unit: "ether" + } + } } Label { text: qsTr("Gas price") } - TextField { - id: gasPriceField + Rectangle + { Layout.fillWidth: true + Ether { + id: gasPriceField + edit: true + displayFormattedValue: true + value: QEther { + value: "100000" + unit: "ether" + } + } } Label { From 9c777a4d3cce37d5357794e00d2e3b88c8a179b1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 19 Jan 2015 16:05:43 +0100 Subject: [PATCH 2/6] - misc fixes. --- mix/AppContext.cpp | 2 +- mix/ClientModel.cpp | 6 +-- mix/DebuggingStateWrapper.cpp | 19 ++++----- mix/DebuggingStateWrapper.h | 15 ++++--- mix/MixClient.cpp | 22 +++++------ mix/MixClient.h | 22 +++++------ mix/QBigInt.h | 11 +++++- mix/QEther.cpp | 26 ++++++------- mix/QEther.h | 26 ++++++++----- mix/qml.qrc | 1 + mix/qml/BigIntValue.qml | 13 +++++++ mix/qml/Ether.qml | 73 ++++++++++++++++++++--------------- mix/qml/EtherValue.qml | 7 +++- mix/qml/StateDialog.qml | 13 +++---- mix/qml/StateList.qml | 4 +- mix/qml/TransactionDialog.qml | 20 ++-------- mix/qml/js/Debugger.js | 6 +-- 17 files changed, 153 insertions(+), 133 deletions(-) create mode 100644 mix/qml/BigIntValue.qml diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index b7c8b100c..8f7cda23f 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -50,9 +50,9 @@ AppContext::AppContext(QQmlApplicationEngine* _engine) qmlRegisterType("org.ethereum.qml", 1, 0, "FileIo"); qmlRegisterSingletonType(QUrl("qrc:/qml/ProjectModel.qml"), "org.ethereum.qml.ProjectModel", 1, 0, "ProjectModel"); qmlRegisterType("org.ethereum.qml.QEther", 1, 0, "QEther"); + qmlRegisterType("org.ethereum.qml.QBigInt", 1, 0, "QBigInt"); m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get()); m_applicationEngine->rootContext()->setContextProperty("fileIo", m_fileIo.get()); - } AppContext::~AppContext() diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 4b343297d..38395b1b5 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -72,9 +72,9 @@ void ClientModel::debugState(QVariantMap _state) QVariantMap transaction = t.toMap(); QString functionId = transaction.value("functionId").toString(); - u256 gas = (qvariant_cast(_state.value("gas")))->toU256Wei(); - u256 value = (qvariant_cast(_state.value("value")))->toU256Wei(); - u256 gasPrice = (qvariant_cast(_state.value("gasPrice")))->toU256Wei(); + u256 gas = (qvariant_cast(transaction.value("gas")))->toU256Wei(); + u256 value = (qvariant_cast(transaction.value("value")))->toU256Wei(); + u256 gasPrice = (qvariant_cast(transaction.value("gasPrice")))->toU256Wei(); QVariantMap params = transaction.value("parameters").toMap(); TransactionSettings transactionSettings(functionId, value, gas, gasPrice); diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 85179e84b..4030709bd 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -29,6 +29,7 @@ #include #include #include "DebuggingStateWrapper.h" +#include "QBigInt.h" using namespace dev; using namespace dev::eth; using namespace dev::mix; @@ -66,25 +67,19 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod return std::make_tuple(codeStr, QPointer(new QQMLMap(codeMapping))); } -QString DebuggingStateWrapper::gasCost() +QBigInt* DebuggingStateWrapper::gasCost() { - std::ostringstream ss; - ss << std::dec << m_state.gasCost; - return QString::fromStdString(ss.str()); + return new QBigInt(m_state.gasCost, this); } -QString DebuggingStateWrapper::gas() +QBigInt* DebuggingStateWrapper::gas() { - std::ostringstream ss; - ss << std::dec << m_state.gas; - return QString::fromStdString(ss.str()); + return new QBigInt(m_state.gas, this); } -QString DebuggingStateWrapper::newMemSize() +QBigInt* DebuggingStateWrapper::newMemSize() { - std::ostringstream ss; - ss << std::dec << m_state.newMemSize; - return QString::fromStdString(ss.str()); + return new QBigInt(m_state.newMemSize, this); } QStringList DebuggingStateWrapper::debugStack() diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index 010db9af7..0541f0afa 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -29,6 +29,7 @@ #include #include "QVariableDefinition.h" #include "MixClient.h" +#include "QBigInt.h" namespace dev { @@ -81,8 +82,8 @@ class DebuggingStateWrapper: public QObject Q_OBJECT Q_PROPERTY(int step READ step CONSTANT) Q_PROPERTY(int curPC READ curPC CONSTANT) - Q_PROPERTY(QString gasCost READ gasCost CONSTANT) - Q_PROPERTY(QString gas READ gas CONSTANT) + Q_PROPERTY(QBigInt* gasCost READ gasCost CONSTANT) + Q_PROPERTY(QBigInt* gas READ gas CONSTANT) Q_PROPERTY(QString instruction READ instruction CONSTANT) Q_PROPERTY(QStringList debugStack READ debugStack CONSTANT) Q_PROPERTY(QStringList debugStorage READ debugStorage CONSTANT) @@ -90,7 +91,7 @@ class DebuggingStateWrapper: public QObject Q_PROPERTY(QVariantList debugCallData READ debugCallData CONSTANT) Q_PROPERTY(QString headerInfo READ headerInfo CONSTANT) Q_PROPERTY(QString endOfDebug READ endOfDebug CONSTANT) - Q_PROPERTY(QString newMemSize READ newMemSize CONSTANT) + Q_PROPERTY(QBigInt* newMemSize READ newMemSize CONSTANT) Q_PROPERTY(QStringList levels READ levels CONSTANT) public: @@ -99,12 +100,10 @@ public: int step() { return (int)m_state.steps; } /// Get the proccessed code index. int curPC() { return (int)m_state.curPC; } - /// Get gas left. - QString gasLeft(); /// Get gas cost. - QString gasCost(); + QBigInt* gasCost(); /// Get gas used. - QString gas(); + QBigInt* gas(); /// Get stack. QStringList debugStack(); /// Get storage. @@ -118,7 +117,7 @@ public: /// get end of debug information. QString endOfDebug(); /// Get the new memory size. - QString newMemSize(); + QBigInt* newMemSize(); /// Get current instruction QString instruction(); /// Get all previous steps. diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index db272a3d0..dde6b7b89 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -1,18 +1,18 @@ /* - This file is part of cpp-ethereum. + This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . */ /** @file MixClient.cpp * @author Yann yann@ethdev.com diff --git a/mix/MixClient.h b/mix/MixClient.h index b7ba7fbf3..c22d845d7 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -1,18 +1,18 @@ /* - This file is part of cpp-ethereum. + This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . */ /** @file MixClient.h * @author Yann yann@ethdev.com diff --git a/mix/QBigInt.h b/mix/QBigInt.h index 8de566856..b305cd2db 100644 --- a/mix/QBigInt.h +++ b/mix/QBigInt.h @@ -17,7 +17,7 @@ /** @file QBigInt.h * @author Yann yann@ethdev.com * @date 2015 - * Represent a big integer (u256, bigint, ...) to be used in QML. + * Represent a big integer (u256, bigint) to be used in QML. */ #pragma once @@ -66,16 +66,25 @@ class QBigInt: public QObject Q_OBJECT public: + QBigInt(QObject* _parent = 0): QObject(_parent), m_internalValue(dev::u256(0)) {} QBigInt(dev::u256 const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) {} QBigInt(dev::bigint const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) {} QBigInt(BigIntVariant const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value){} ~QBigInt() {} + /// @returns the current used big integer. BigIntVariant internalValue() { return m_internalValue; } + /// @returns a string representation of the big integer used. Invokable from QML. Q_INVOKABLE QString value() const; + /// Set the value of the BigInteger used. Will use u256 type. Invokable from QML. + Q_INVOKABLE void setValue(QString const& _value) { m_internalValue = dev::jsToU256(_value.toStdString()); } + /// Subtract by @a _value. Invokable from QML. Q_INVOKABLE QBigInt* subtract(QBigInt* const& _value) const; + /// Add @a _value to the current big integer. Invokable from QML. Q_INVOKABLE QBigInt* add(QBigInt* const& _value) const; + /// Multiply by @a _value. Invokable from QML. Q_INVOKABLE QBigInt* multiply(QBigInt* const& _value) const; + /// divide by @a _value. Invokable from QML. Q_INVOKABLE QBigInt* divide(QBigInt* const& _value) const; protected: diff --git a/mix/QEther.cpp b/mix/QEther.cpp index 6b8a15639..46562d440 100644 --- a/mix/QEther.cpp +++ b/mix/QEther.cpp @@ -29,27 +29,27 @@ QString QEther::format() const return QString::fromStdString(dev::eth::formatBalance(boost::get(toWei()->internalValue()))); } -QString QEther::unit() const +QBigInt* QEther::toWei() const { QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); const char* key = units.valueToKey(m_currentUnit); - return QString(key); + for (std::pair rawUnit: dev::eth::units()) + { + if (rawUnit.second == QString(key).toLower().toStdString()) + return multiply(new QBigInt(rawUnit.first)); + } + return new QBigInt(dev::u256(0)); } void QEther::setUnit(QString const& _unit) { QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); - m_currentUnit = static_cast(units.keysToValue(_unit.toStdString().c_str())); -} - -QBigInt* QEther::toWei() const -{ - QMetaEnum units = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("EtherUnit")); - const char* key = units.valueToKey(m_currentUnit); - for (std::pair rawUnit: dev::eth::units()) + for (int k = 0; k < units.keyCount(); k++) { - if (rawUnit.second == QString(key).toStdString()) - return multiply(new QBigInt(rawUnit.first)); + if (QString(units.key(k)).toLower() == _unit) + { + m_currentUnit = static_cast(units.keysToValue(units.key(k))); + return; + } } - return new QBigInt(dev::u256(0)); } diff --git a/mix/QEther.h b/mix/QEther.h index 086a66c66..794ba2ba1 100644 --- a/mix/QEther.h +++ b/mix/QEther.h @@ -17,7 +17,7 @@ /** @file QEther.h * @author Yann yann@ethdev.com * @date 2014 - * Represent an Ether value in QML (mapped to u256 in c++). + * Represent an amount of Ether in QML (mapped to u256 in c++). */ #pragma once @@ -36,7 +36,7 @@ class QEther: public QBigInt Q_OBJECT Q_ENUMS(EtherUnit) Q_PROPERTY(QString value READ value WRITE setValue NOTIFY valueChanged) - Q_PROPERTY(QString unit READ unit WRITE setUnit NOTIFY unitChanged) + Q_PROPERTY(EtherUnit unit READ unit WRITE setUnit NOTIFY unitChanged) public: enum EtherUnit @@ -52,25 +52,31 @@ public: Tether, Gether, Mether, - grand, - ether, - finney, - szabo, + Grand, + Ether, + Finney, + Szabo, Gwei, Mwei, Kwei, - wei + Wei }; - QEther(QObject* _parent = 0): QBigInt(dev::u256(0), _parent), m_currentUnit(EtherUnit::ether) {} + QEther(QObject* _parent = 0): QBigInt(dev::u256(0), _parent), m_currentUnit(EtherUnit::Wei) {} QEther(dev::u256 _value, EtherUnit _unit, QObject* _parent = 0): QBigInt(_value, _parent), m_currentUnit(_unit) {} ~QEther() {} + /// @returns user-friendly string representation of the amount of ether. Invokable from QML. Q_INVOKABLE QString format() const; + /// @returns the current amount of Ether in Wei. Invokable from QML. Q_INVOKABLE QBigInt* toWei() const; - Q_INVOKABLE void setValue(QString const& _value) { m_internalValue = dev::jsToU256(_value.toStdString()); } - Q_INVOKABLE QString unit() const; + /// @returns the current unit used. Invokable from QML. + Q_INVOKABLE EtherUnit unit() const { return m_currentUnit; } + /// Set the unit to be used. Invokable from QML. + Q_INVOKABLE void setUnit(EtherUnit const& _unit) { m_currentUnit = _unit; } + /// Set the unit to be used. Invokable from QML. Q_INVOKABLE void setUnit(QString const& _unit); + /// @returns the u256 value of the current amount of Ether in Wei. dev::u256 toU256Wei() { return boost::get(toWei()->internalValue()); } private: diff --git a/mix/qml.qrc b/mix/qml.qrc index bc4568abf..169d1ebcb 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -42,5 +42,6 @@ qml/WebPreview.qml qml/Ether.qml qml/EtherValue.qml + qml/BigIntValue.qml diff --git a/mix/qml/BigIntValue.qml b/mix/qml/BigIntValue.qml new file mode 100644 index 000000000..5e3262516 --- /dev/null +++ b/mix/qml/BigIntValue.qml @@ -0,0 +1,13 @@ +/* + * Used to instanciate a QEther obj using Qt.createComponent function. +*/ +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.1 +import org.ethereum.qml.QBigInt 1.0 + +QBigInt +{ + id: bigInt +} diff --git a/mix/qml/Ether.qml b/mix/qml/Ether.qml index 7df6369ad..9eb9b63e0 100644 --- a/mix/qml/Ether.qml +++ b/mix/qml/Ether.qml @@ -1,3 +1,10 @@ +/* + * Display a row containing : + * - The amount of Ether. + * - The unit used. + * - User-friendly string representation of the amout of Ether (if displayFormattedValue == true). + * 'value' has to be a QEther obj. +*/ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 @@ -13,20 +20,16 @@ Rectangle { function update() { - etherValueEdit.text = value.value; - selectUnit(value.unit); + if (value !== undefined) + { + etherValueEdit.text = value.value; + selectUnit(value.unit); + } } function selectUnit(unit) { - for(var i = 0; i < unitsModel.count; ++i) - { - if (unitsModel.get(i).text === unit) - { - units.currentIndex = i; - return; - } - } + units.currentIndex = unit; } RowLayout @@ -43,8 +46,11 @@ Rectangle { { onTextChanged: { - value.setValue(text) - formattedValue.text = value.format(); + if (value !== undefined) + { + value.setValue(text) + formattedValue.text = value.format(); + } } width: parent.width readOnly: !edit @@ -64,30 +70,33 @@ Rectangle { id: units onCurrentTextChanged: { - value.setUnit(currentText); - formattedValue.text = value.format(); + if (value !== undefined) + { + value.setUnit(currentText); + formattedValue.text = value.format(); + } } model: ListModel { id: unitsModel - ListElement { text: "wei"; } - ListElement { text: "Kwei"; } - ListElement { text: "Mwei"; } - ListElement { text: "Gwei"; } - ListElement { text: "szabo"; } - ListElement { text: "finney"; } - ListElement { text: "ether"; } - ListElement { text: "grand"; } - ListElement { text: "Mether"; } - ListElement { text: "Gether"; } - ListElement { text: "Tether"; } - ListElement { text: "Pether"; } - ListElement { text: "Eether"; } - ListElement { text: "Zether"; } - ListElement { text: "Yether"; } - ListElement { text: "Nether"; } - ListElement { text: "Dether"; } - ListElement { text: "Vether"; } ListElement { text: "Uether"; } + ListElement { text: "Vether"; } + ListElement { text: "Dether"; } + ListElement { text: "Nether"; } + ListElement { text: "Yether"; } + ListElement { text: "Zether"; } + ListElement { text: "Eether"; } + ListElement { text: "Pether"; } + ListElement { text: "Tether"; } + ListElement { text: "Gether"; } + ListElement { text: "Mether"; } + ListElement { text: "grand"; } + ListElement { text: "ether"; } + ListElement { text: "finney"; } + ListElement { text: "szabo"; } + ListElement { text: "Gwei"; } + ListElement { text: "Mwei"; } + ListElement { text: "Kwei"; } + ListElement { text: "wei"; } } } Rectangle diff --git a/mix/qml/EtherValue.qml b/mix/qml/EtherValue.qml index e1a838447..1217aade5 100644 --- a/mix/qml/EtherValue.qml +++ b/mix/qml/EtherValue.qml @@ -1,3 +1,6 @@ +/* + * Used to instanciate a QEther obj using Qt.createComponent function. +*/ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 @@ -7,6 +10,6 @@ import org.ethereum.qml.QEther 1.0 QEther { id: basicEther - value: "1000000" - unit: "ether" + value: "100000000000" + unit: QEther.Wei } diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index da24d457e..55a4df14f 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -5,6 +5,7 @@ import QtQuick.Window 2.0 import org.ethereum.qml.QEther 1.0 Window { + id: modalStateDialog modality: Qt.WindowModal width:640 @@ -72,10 +73,6 @@ Window { edit: true displayFormattedValue: true Layout.fillWidth: true - value: QEther { - value: "100000" - unit: "ether" - } } Label { @@ -124,7 +121,7 @@ Window { function ether(_value, _unit) { var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); - var ether = etherComponent.createObject(transactionsModel); + var ether = etherComponent.createObject(modalStateDialog); ether.setValue(_value); ether.setUnit(_unit); return ether; @@ -136,10 +133,10 @@ Window { // https://bugreports.qt-project.org/browse/QTBUG-41327 // Second call to signal handler would just edit the item that was just created, no harm done var item = { - value: ether("0", "ether"), + value: ether("0", QEther.Wei), functionId: "", - gas: ether("125000", "ether"), - gasPrice: ether("100000", "ether") + gas: ether("125000", QEther.Wei), + gasPrice: ether("100000", QEther.Wei) }; transactionDialog.open(transactionsModel.count, item); diff --git a/mix/qml/StateList.qml b/mix/qml/StateList.qml index 05537f3ad..9cd53edbe 100644 --- a/mix/qml/StateList.qml +++ b/mix/qml/StateList.qml @@ -69,9 +69,9 @@ Rectangle { function addState() { var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); - var ether = etherComponent.createObject(stateListModel); + var ether = etherComponent.createObject(stateListContainer); ether.setValue("100000000000000000000000000"); - ether.setUnit("ether"); + ether.setUnit(QEther.Wei); var item = { title: "", balance: ether, diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index 19727cd7d..22995d66b 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -5,6 +5,7 @@ import QtQuick.Window 2.0 import org.ethereum.qml.QEther 1.0 Window { + id: modalTransactionDialog modality: Qt.WindowModal width:640 height:480 @@ -75,10 +76,9 @@ Window { } for (var p = 0; p < transactionDialog.transactionParams.count; p++) { var parameter = transactionDialog.transactionParams.get(p); - var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); - var param = etherComponent.createObject(stateListModel); - ether.setValue(parameter.value); - ether.setUnit("ether"); + var intComponent = Qt.createComponent("qrc:/qml/BigIntValue.qml"); + var param = intComponent.createObject(modalTransactionDialog); + param.setValue(parameter.value); item.parameters[parameter.name] = param; } return item; @@ -119,10 +119,6 @@ Window { id: valueField edit: true displayFormattedValue: true - value: QEther { - value: "100000" - unit: "ether" - } } } @@ -136,10 +132,6 @@ Window { id: gasField edit: true displayFormattedValue: true - value: QEther { - value: "100000" - unit: "ether" - } } } @@ -153,10 +145,6 @@ Window { id: gasPriceField edit: true displayFormattedValue: true - value: QEther { - value: "100000" - unit: "ether" - } } } diff --git a/mix/qml/js/Debugger.js b/mix/qml/js/Debugger.js index 43b15f27e..da3928105 100644 --- a/mix/qml/js/Debugger.js +++ b/mix/qml/js/Debugger.js @@ -65,9 +65,9 @@ function highlightSelection(index) function completeCtxInformation(state) { currentStep.update(state.step); - mem.update(state.newMemSize + " " + qsTr("words")); - stepCost.update(state.gasCost); - gasSpent.update(debugStates[0].gas - state.gas); + mem.update(state.newMemSize.value() + " " + qsTr("words")); + stepCost.update(state.gasCost.value()); + gasSpent.update(debugStates[0].gas.subtract(state.gas).value()); stack.listModel = state.debugStack; storage.listModel = state.debugStorage; From 5233166845b70e0fb2d11540f9ba71c92f137423 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 19 Jan 2015 16:18:14 +0100 Subject: [PATCH 3/6] - misc fixes. --- mix/QBigInt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mix/QBigInt.h b/mix/QBigInt.h index b305cd2db..6618c5e64 100644 --- a/mix/QBigInt.h +++ b/mix/QBigInt.h @@ -40,25 +40,25 @@ using BigIntVariant = boost::variant; struct add: public boost::static_visitor { template - BigIntVariant operator()(T1 _value, T2 _otherValue) const { return _value + _otherValue; } + BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value + _otherValue; } }; struct subtract: public boost::static_visitor { template - BigIntVariant operator()(T1 _value, T2 _otherValue) const { return _value - _otherValue; } + BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value - _otherValue; } }; struct multiply: public boost::static_visitor { template - BigIntVariant operator()(T1 _value, T2 _otherValue) const { return _value * _otherValue; } + BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value * _otherValue; } }; struct divide: public boost::static_visitor { template - BigIntVariant operator()(T1 _value, T2 _otherValue) const { return _value / _otherValue; } + BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value / _otherValue; } }; class QBigInt: public QObject From 5b6ea865669738dd2db00ac2d32d0ef51abc9d81 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 19 Jan 2015 16:39:32 +0100 Subject: [PATCH 4/6] - change ObjectOwnership to JavaScript. --- mix/DebuggingStateWrapper.cpp | 13 ++++++++++--- mix/QBigInt.cpp | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 4030709bd..778bb951a 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -69,17 +70,23 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod QBigInt* DebuggingStateWrapper::gasCost() { - return new QBigInt(m_state.gasCost, this); + QBigInt* re = new QBigInt(m_state.gasCost, this); + QQmlEngine::setObjectOwnership(re, QQmlEngine::JavaScriptOwnership); + return re; } QBigInt* DebuggingStateWrapper::gas() { - return new QBigInt(m_state.gas, this); + QBigInt* r = new QBigInt(m_state.gas, this); + QQmlEngine::setObjectOwnership(r, QQmlEngine::JavaScriptOwnership); + return r; } QBigInt* DebuggingStateWrapper::newMemSize() { - return new QBigInt(m_state.newMemSize, this); + QBigInt* r = new QBigInt(m_state.newMemSize, this); + QQmlEngine::setObjectOwnership(r, QQmlEngine::JavaScriptOwnership); + return r; } QStringList DebuggingStateWrapper::debugStack() diff --git a/mix/QBigInt.cpp b/mix/QBigInt.cpp index 9cfcf5783..191d20459 100644 --- a/mix/QBigInt.cpp +++ b/mix/QBigInt.cpp @@ -19,8 +19,8 @@ * @date 2015 */ -#include "boost/variant/multivisitors.hpp" -#include "boost/variant.hpp" +#include +#include #include #include "QBigInt.h" From 5c2884d407652a705cac69a603de2e0e5d336b59 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 19 Jan 2015 16:45:46 +0100 Subject: [PATCH 5/6] - changes in include ref (in *.h) --- mix/AppContext.cpp | 2 ++ mix/ClientModel.cpp | 3 ++- mix/ClientModel.h | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index 8f7cda23f..939829243 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -31,8 +31,10 @@ #include "FileIo.h" #include "ClientModel.h" #include "AppContext.h" +#include "QEther.h" #include + using namespace dev; using namespace dev::eth; using namespace dev::mix; diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 38395b1b5..eb61c8554 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -32,6 +32,7 @@ #include "ContractCallDataEncoder.h" #include "CodeModel.h" #include "ClientModel.h" +#include "QEther.h" using namespace dev; using namespace dev::eth; @@ -41,7 +42,7 @@ ClientModel::ClientModel(AppContext* _context): m_context(_context), m_running(false) { qRegisterMetaType("QBigInt*"); - qRegisterMetaType("QEther*"); + qRegisterMetaType("QEther*"); qRegisterMetaType("QVariableDefinition*"); qRegisterMetaType("QVariableDefinitionList*"); qRegisterMetaType>("QList"); diff --git a/mix/ClientModel.h b/mix/ClientModel.h index a9450532e..0e7f9c092 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -26,7 +26,6 @@ #include #include "DebuggingStateWrapper.h" #include "MixClient.h" -#include "QEther.h" using AssemblyDebuggerData = std::tuple, dev::mix::QQMLMap*>; From 92bdd6fd2fdf38349823297fc56681b22c224391 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 19 Jan 2015 17:56:10 +0100 Subject: [PATCH 6/6] - Add JavaScript ownership for QBigInt (declaration in constructors). --- mix/DebuggingStateWrapper.cpp | 12 +++--------- mix/QBigInt.h | 13 +++++++++---- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 778bb951a..69f5c2ee5 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -70,23 +70,17 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod QBigInt* DebuggingStateWrapper::gasCost() { - QBigInt* re = new QBigInt(m_state.gasCost, this); - QQmlEngine::setObjectOwnership(re, QQmlEngine::JavaScriptOwnership); - return re; + return new QBigInt(m_state.gasCost); } QBigInt* DebuggingStateWrapper::gas() { - QBigInt* r = new QBigInt(m_state.gas, this); - QQmlEngine::setObjectOwnership(r, QQmlEngine::JavaScriptOwnership); - return r; + return new QBigInt(m_state.gas); } QBigInt* DebuggingStateWrapper::newMemSize() { - QBigInt* r = new QBigInt(m_state.newMemSize, this); - QQmlEngine::setObjectOwnership(r, QQmlEngine::JavaScriptOwnership); - return r; + return new QBigInt(m_state.newMemSize); } QStringList DebuggingStateWrapper::debugStack() diff --git a/mix/QBigInt.h b/mix/QBigInt.h index 6618c5e64..842b86c7d 100644 --- a/mix/QBigInt.h +++ b/mix/QBigInt.h @@ -25,6 +25,7 @@ #include "boost/variant.hpp" #include "boost/variant/multivisitors.hpp" #include +#include #include #include @@ -61,15 +62,19 @@ struct divide: public boost::static_visitor BigIntVariant operator()(T1 const& _value, T2 const& _otherValue) const { return _value / _otherValue; } }; +/* + * Represent big integer like big int and u256 in QML. + * The ownership is set by default to Javascript. + */ class QBigInt: public QObject { Q_OBJECT public: - QBigInt(QObject* _parent = 0): QObject(_parent), m_internalValue(dev::u256(0)) {} - QBigInt(dev::u256 const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) {} - QBigInt(dev::bigint const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) {} - QBigInt(BigIntVariant const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value){} + QBigInt(QObject* _parent = 0): QObject(_parent), m_internalValue(dev::u256(0)) { QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); } + QBigInt(dev::u256 const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) { QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); } + QBigInt(dev::bigint const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value) { QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); } + QBigInt(BigIntVariant const& _value, QObject* _parent = 0): QObject(_parent), m_internalValue(_value){ QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); } ~QBigInt() {} /// @returns the current used big integer.