diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 3a2b50999..e18b23ab3 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -113,24 +113,27 @@ QString ClientModel::apiCall(QString const& _message) void ClientModel::mine() { - if (m_running) + if (m_running || m_mining) BOOST_THROW_EXCEPTION(ExecutionStateException()); - m_running = true; - emit runStarted(); - emit runStateChanged(); + m_mining = true; + emit miningStarted(); + emit miningStateChanged(); QtConcurrent::run([=]() { try { m_client->mine(); newBlock(); + m_mining = false; + emit miningComplete(); } catch (...) { + m_mining = false; std::cerr << boost::current_exception_diagnostic_information(); emit runFailed(QString::fromStdString(boost::current_exception_diagnostic_information())); } - m_running = false; + emit miningStateChanged(); }); } diff --git a/mix/ClientModel.h b/mix/ClientModel.h index 493290780..be264e108 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -114,6 +114,8 @@ public: ~ClientModel(); /// @returns true if currently executing contract code Q_PROPERTY(bool running MEMBER m_running NOTIFY runStateChanged) + /// @returns true if currently mining + Q_PROPERTY(bool mining MEMBER m_mining NOTIFY miningStateChanged) /// @returns address of the last executed contract Q_PROPERTY(QString contractAddress READ contractAddress NOTIFY contractAddressChanged) /// ethereum.js RPC request entry point @@ -144,6 +146,12 @@ signals: void runStarted(); /// Transaction execution completed successfully void runComplete(); + /// Mining has started + void miningStarted(); + /// Mined a new block + void miningComplete(); + /// Mining stopped or started + void miningStateChanged(); /// Transaction execution completed with error /// @param _message Error message void runFailed(QString const& _message); @@ -174,6 +182,7 @@ private: AppContext* m_context; std::atomic m_running; + std::atomic m_mining; std::unique_ptr m_client; std::unique_ptr m_rpcConnector; std::unique_ptr m_web3Server; diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 17e369a4e..512847a78 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -91,6 +91,7 @@ void MixClient::resetState(u256 _balance) m_state.sync(bc()); m_startState = m_state; m_pendingExecutions.clear(); + m_executions.clear(); } void MixClient::executeTransaction(Transaction const& _t, State& _state) @@ -215,7 +216,7 @@ ExecutionResult const& MixClient::execution(unsigned _block, unsigned _transacti { if (_block == bc().number() + 1) return m_pendingExecutions.at(_transaction); - return m_executions.at(_block).at(_transaction); + return m_executions.at(_block - 1).at(_transaction); } ExecutionResult const& MixClient::lastExecution() const diff --git a/mix/qml/DebugInfoList.qml b/mix/qml/DebugInfoList.qml index cad2a4c9e..1e16038e7 100644 --- a/mix/qml/DebugInfoList.qml +++ b/mix/qml/DebugInfoList.qml @@ -4,14 +4,19 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 ColumnLayout { + id: root property string title property variant listModel; property bool collapsible; + property bool enableSelection; + property real storedHeight; property Component itemDelegate + signal rowActivated(int index) spacing: 0 function collapse() { + storedHeight = childrenRect.height; storageContainer.state = "collapsed"; } @@ -32,7 +37,9 @@ ColumnLayout { Image { source: "qrc:/qml/img/opentriangleindicator.png" width: 15 + height: 15 sourceSize.width: 15 + sourceSize.height: 15 id: storageImgArrow } @@ -53,16 +60,20 @@ ColumnLayout { if (storageContainer.state == "collapsed") { storageContainer.state = ""; - storageContainer.parent.parent.height = storageContainer.parent.parent.Layout.maximumHeight; + storageContainer.parent.parent.height = storedHeight; } else + { + storedHeight = root.childrenRect.height; storageContainer.state = "collapsed"; + } } } } } Rectangle { + id: storageContainer border.width: 3 border.color: "#deddd9" Layout.fillWidth: true @@ -80,18 +91,23 @@ ColumnLayout { } } ] - id: storageContainer - ListView { + TableView { clip: true; + alternatingRowColors: false anchors.top: parent.top anchors.left: parent.left anchors.topMargin: 3 anchors.leftMargin: 3 width: parent.width - 3 height: parent.height - 6 - id: storageList model: listModel - delegate: itemDelegate + selectionMode: enableSelection ? SelectionMode.SingleSelection : SelectionMode.NoSelection + headerDelegate: null + itemDelegate: root.itemDelegate + TableViewColumn { + role: "modelData" + width: parent.width + } } } } diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index facf759a8..d7023f4b2 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -58,7 +58,7 @@ Rectangle { Settings { id: splitSettings property alias transactionLogHeight: transactionLog.height - property alias callStackHeight: callStack.height + property alias callStackHeight: callStackRect.height property alias storageHeightSettings: storageRect.height property alias memoryDumpHeightSettings: memoryRect.height property alias callDataHeightSettings: callDataRect.height @@ -154,18 +154,19 @@ Rectangle { id: statesLayout spacing: machineStates.sideMargin - RowLayout { + Rectangle { // step button + slider id: buttonRow - spacing: machineStates.sideMargin height: 27 Layout.fillWidth: true + color: "transparent" Rectangle { - height: parent.height + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left color: "transparent" - Layout.minimumWidth: stateListContainer.width - Layout.maximumWidth: stateListContainer.width + width: stateListContainer.width RowLayout { anchors.horizontalCenter: parent.horizontalCenter id: jumpButtons @@ -245,9 +246,11 @@ Rectangle { } Rectangle { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + width: debugInfoContainer.width color: "transparent" - Layout.fillWidth: true - height: parent.height Slider { id: statesSlider anchors.fill: parent @@ -324,47 +327,45 @@ Rectangle { Component { id: renderDelegate Item { - - Rectangle { - radius: 4 - anchors.fill: parent - color: "#4A90E2" - visible: styleData.selected; - } - - RowLayout { - id: wrapperItem - height: 20 - //width: parent.width - anchors.fill: parent - spacing: 5 - - - Text { - anchors.left: parent.left - anchors.leftMargin: 10 - width: 15 - color: "#b2b3ae" - text: styleData.value.split(' ')[0] - font.family: "monospace" - font.pointSize: 9 - wrapMode: Text.NoWrap - id: id + Rectangle { + radius: 4 + anchors.fill: parent + color: "#4A90E2" + visible: styleData.selected; } - Text { - anchors.left: id.right; - wrapMode: Text.NoWrap - color: styleData.selected ? "white" : "black" - font.family: "monospace" - text: styleData.value.replace(styleData.value.split(' ')[0], '') - font.pointSize: 9 + + RowLayout { + id: wrapperItem + anchors.fill: parent + spacing: 5 + + + Text { + anchors.left: parent.left + anchors.leftMargin: 10 + width: 15 + color: "#b2b3ae" + text: styleData.value.split(' ')[0] + font.family: "monospace" + font.pointSize: 9 + wrapMode: Text.NoWrap + id: id + } + Text { + anchors.left: id.right; + wrapMode: Text.NoWrap + color: styleData.selected ? "white" : "black" + font.family: "monospace" + text: styleData.value.replace(styleData.value.split(' ')[0], '') + font.pointSize: 9 + } } } - } } } Rectangle { + id: debugInfoContainer width: parent.width * 0.6 - machineStates.sideMargin anchors.top : parent.top anchors.bottom: parent.bottom @@ -409,7 +410,7 @@ Rectangle { title : qsTr("Stack") itemDelegate: Item { id: renderedItem - height: 25 + //height: 25 width: parent.width RowLayout { @@ -428,7 +429,7 @@ Rectangle { anchors.leftMargin: 5 font.family: "monospace" color: "#4a4a4a" - text: model.index; + text: styleData.row; font.pointSize: 9 } } @@ -439,7 +440,6 @@ Rectangle { Layout.fillWidth: true Layout.minimumWidth: 15 Layout.preferredWidth: 15 - Layout.maximumWidth: 60 Layout.minimumHeight: parent.height Text { anchors.left: parent.left @@ -447,7 +447,7 @@ Rectangle { font.family: "monospace" anchors.verticalCenter: parent.verticalCenter color: "#4a4a4a" - text: modelData + text: styleData.value font.pointSize: 9 } } @@ -477,16 +477,80 @@ Rectangle { { id: callStackRect; color: "transparent" - height: 120 - width: parent.width - Layout.minimumHeight: 120 - Layout.maximumHeight: 400 + Layout.minimumHeight: 25 + Layout.maximumHeight: 800 onHeightChanged: machineStates.updateHeight(); - CallStack { - anchors.fill: parent + DebugInfoList + { id: callStack - onFrameActivated: Debugger.displayFrame(index); + collapsible: true + anchors.fill: parent + title : qsTr("Call Stack") + enableSelection: true + onRowActivated: Debugger.displayFrame(index); + itemDelegate: + Item { + anchors.fill: parent + + Rectangle { + anchors.fill: parent + color: "#4A90E2" + visible: styleData.selected; + } + + RowLayout + { + id: row + anchors.fill: parent + Rectangle + { + color: "#f7f7f7" + Layout.fillWidth: true + Layout.minimumWidth: 30 + Layout.maximumWidth: 30 + Text { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + font.family: "monospace" + anchors.leftMargin: 5 + color: "#4a4a4a" + text: styleData.row; + font.pointSize: 9 + width: parent.width - 5 + elide: Text.ElideRight + } + } + Rectangle + { + color: "transparent" + Layout.fillWidth: true + Layout.minimumWidth: parent.width - 30 + Layout.maximumWidth: parent.width - 30 + Text { + anchors.leftMargin: 5 + width: parent.width - 5 + wrapMode: Text.Wrap + anchors.left: parent.left + font.family: "monospace" + anchors.verticalCenter: parent.verticalCenter + color: "#4a4a4a" + text: styleData.value; + elide: Text.ElideRight + font.pointSize: 9 + } + } + } + + Rectangle { + anchors.top: row.bottom + width: parent.width; + height: 1; + color: "#cccccc" + anchors.bottom: parent.bottom + } + } } + } Rectangle @@ -505,28 +569,24 @@ Rectangle { title : qsTr("Storage") itemDelegate: Item { - height: 27 - width: parent.width; + anchors.fill: parent RowLayout { id: row - width: parent.width - height: 26 + anchors.fill: parent Rectangle { color: "#f7f7f7" Layout.fillWidth: true Layout.minimumWidth: parent.width / 2 - Layout.preferredWidth: parent.width / 2 Layout.maximumWidth: parent.width / 2 - Layout.minimumHeight: parent.height Text { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left font.family: "monospace" anchors.leftMargin: 5 color: "#4a4a4a" - text: modelData.split('\t')[0]; + text: styleData.value.split('\t')[0]; font.pointSize: 9 width: parent.width - 5 elide: Text.ElideRight @@ -537,9 +597,7 @@ Rectangle { color: "transparent" Layout.fillWidth: true Layout.minimumWidth: parent.width / 2 - Layout.preferredWidth: parent.width / 2 Layout.maximumWidth: parent.width / 2 - Layout.minimumHeight: parent.height Text { anchors.leftMargin: 5 width: parent.width - 5 @@ -548,7 +606,7 @@ Rectangle { font.family: "monospace" anchors.verticalCenter: parent.verticalCenter color: "#4a4a4a" - text: modelData.split('\t')[1]; + text: styleData.value.split('\t')[1]; elide: Text.ElideRight font.pointSize: 9 } diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index e95a85fde..f4ddca84e 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -114,7 +114,8 @@ Item { onClientConnected: { //filter polling spam //TODO: do it properly - var log = _request.content.indexOf("eth_changed") < 0; + //var log = _request.content.indexOf("eth_changed") < 0; + var log = true; if (log) console.log(_request.content); var response = clientModel.apiCall(_request.content); diff --git a/mix/qml/js/Debugger.js b/mix/qml/js/Debugger.js index 96e7a54a2..872d0aa36 100644 --- a/mix/qml/js/Debugger.js +++ b/mix/qml/js/Debugger.js @@ -107,7 +107,7 @@ function select(stateIndex) callStackData.push(address); } callStackData.push(debugData.states[0].address); - callStack.model = callStackData; + callStack.listModel = callStackData; } function codeStr(stateIndex) diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index 4d501ffca..718dd4fa4 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -153,6 +153,7 @@ function doCloseProject() { console.log("closing project"); projectListModel.clear(); projectPath = ""; + currentDocumentId = ""; projectClosed(); } diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 49d00311f..41b7c50a4 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -88,7 +88,7 @@ ApplicationWindow { text: qsTr("Mine") shortcut: "Ctrl+M" onTriggered: clientModel.mine(); - enabled: codeModel.hasContract && !clientModel.running + enabled: codeModel.hasContract && !clientModel.running &&!clientModel.mining } Connections {