From 80319893c23aa8486757cf6a32b617e314043639 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 14 Jul 2015 17:30:15 -0400 Subject: [PATCH] updating UI for asset supprot --- programs/cli_wallet/main.cpp | 2 + programs/light_client/ClientDataModel.cpp | 134 +++++++++++++++++++++- programs/light_client/ClientDataModel.hpp | 73 +++++++----- programs/light_client/qml/main.qml | 46 ++++++-- 4 files changed, 213 insertions(+), 42 deletions(-) diff --git a/programs/cli_wallet/main.cpp b/programs/cli_wallet/main.cpp index c98e51bc..f0cf6da2 100644 --- a/programs/cli_wallet/main.cpp +++ b/programs/cli_wallet/main.cpp @@ -134,10 +134,12 @@ int main( int argc, char** argv ) wdata.ws_password = options.at("server-rpc-password").as(); fc::http::websocket_client client; + idump((wdata.ws_server)); auto con = client.connect( wdata.ws_server ); auto apic = std::make_shared(*con); auto remote_api = apic->get_remote_api< login_api >(1); + edump((wdata.ws_user)(wdata.ws_password) ); FC_ASSERT( remote_api->login( wdata.ws_user, wdata.ws_password ) ); auto wapiptr = std::make_shared(remote_api); diff --git a/programs/light_client/ClientDataModel.cpp b/programs/light_client/ClientDataModel.cpp index 6b45b9e4..260161ab 100644 --- a/programs/light_client/ClientDataModel.cpp +++ b/programs/light_client/ClientDataModel.cpp @@ -10,6 +10,130 @@ using namespace graphene::app; ChainDataModel::ChainDataModel( fc::thread& t, QObject* parent ) :QObject(parent),m_thread(&t){} + +Asset* ChainDataModel::getAsset(qint64 id) +{ + auto& by_id_idx = m_assets.get<::by_id>(); + auto itr = by_id_idx.find(id); + if( itr == by_id_idx.end() ) + { + auto tmp = new Asset; + tmp->id = id; --m_account_query_num; + tmp->symbol = QString::number( --m_account_query_num); + auto result = m_assets.insert( tmp ); + assert( result.second ); + + /** execute in app thread */ + m_thread->async( [this,id](){ + try { + ilog( "look up symbol.." ); + auto result = m_db_api->get_assets( {asset_id_type(id)} ); + wdump((result)); + + /** execute in main */ + Q_EMIT queueExecute( [this,result,id](){ + wlog( "process result" ); + auto& by_id_idx = this->m_assets.get<::by_id>(); + auto itr = by_id_idx.find(id); + assert( itr != by_id_idx.end() ); + + if( result.size() == 0 || !result.front() ) + { + elog( "delete later" ); + (*itr)->deleteLater(); + by_id_idx.erase( itr ); + } + else + { + by_id_idx.modify( itr, + [=]( Asset* a ){ + a->setProperty("symbol", QString::fromStdString(result.front()->symbol) ); + a->setProperty("precision", result.front()->precision ); + } + ); + } + }); + } + catch ( const fc::exception& e ) + { + Q_EMIT exceptionThrown( QString::fromStdString(e.to_string()) ); + } + }); + return *result.first; + } + return *itr; +} + +Asset* ChainDataModel::getAsset(QString symbol) +{ + auto& by_symbol_idx = m_assets.get(); + auto itr = by_symbol_idx.find(symbol); + if( itr == by_symbol_idx.end() ) + { + auto tmp = new Asset; + tmp->id = --m_account_query_num; + tmp->symbol = symbol; + auto result = m_assets.insert( tmp ); + assert( result.second ); + + /** execute in app thread */ + m_thread->async( [this,symbol](){ + try { + ilog( "look up symbol.." ); + auto result = m_db_api->lookup_asset_symbols( {symbol.toStdString()} ); + /** execute in main */ + Q_EMIT queueExecute( [this,result,symbol](){ + wlog( "process result" ); + auto& by_symbol_idx = this->m_assets.get(); + auto itr = by_symbol_idx.find(symbol); + assert( itr != by_symbol_idx.end() ); + + if( result.size() == 0 || !result.front() ) + { + elog( "delete later" ); + (*itr)->deleteLater(); + by_symbol_idx.erase( itr ); + } + else + { + by_symbol_idx.modify( itr, + [=]( Asset* a ){ + a->setProperty("id", result.front()->id.instance() ); + a->setProperty("precision", result.front()->precision ); + } + ); + } + }); + } + catch ( const fc::exception& e ) + { + Q_EMIT exceptionThrown( QString::fromStdString(e.to_string()) ); + } + }); + return *result.first; + } + return *itr; +} + + + + + + + + + + + + + + + + + + + + Account* ChainDataModel::getAccount(qint64 id) { auto& by_id_idx = m_accounts.get<::by_id>(); @@ -80,19 +204,19 @@ Account* ChainDataModel::getAccount(QString name) /** execute in main */ Q_EMIT queueExecute( [this,result,name](){ wlog( "process result" ); - auto& by_name_idx = this->m_accounts.get(); - auto itr = by_name_idx.find(name); - assert( itr != by_name_idx.end() ); + auto& by_symbol_idx = this->m_accounts.get(); + auto itr = by_symbol_idx.find(name); + assert( itr != by_symbol_idx.end() ); if( result.size() == 0 || !result.front() ) { elog( "delete later" ); (*itr)->deleteLater(); - by_name_idx.erase( itr ); + by_symbol_idx.erase( itr ); } else { - by_name_idx.modify( itr, + by_symbol_idx.modify( itr, [=]( Account* a ){ a->setProperty("id", result.front()->id.instance() ); } diff --git a/programs/light_client/ClientDataModel.hpp b/programs/light_client/ClientDataModel.hpp index dd258e4c..dd588a0d 100644 --- a/programs/light_client/ClientDataModel.hpp +++ b/programs/light_client/ClientDataModel.hpp @@ -19,67 +19,79 @@ using namespace boost::multi_index; Q_DECLARE_METATYPE(std::function) +class GrapheneObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(qint64 id MEMBER id NOTIFY idChanged) -class Asset : public QObject { + public: + qint64 id; + + Q_SIGNALS: + void idChanged(); +}; + + +class Asset : public GrapheneObject { Q_OBJECT Q_PROPERTY(QString symbol MEMBER symbol) - Q_PROPERTY(qint64 id MEMBER id) - Q_PROPERTY(quint8 precision MEMBER precision) + Q_PROPERTY(quint32 precision MEMBER precision) - QString symbol; - qint64 id; - quint8 precision; + public: + QString symbol; + quint32 precision; + + + Q_SIGNALS: + void symbolChanged(); }; -class Balance : public QObject { +struct by_id; +struct by_symbol_name; +typedef multi_index_container< + Asset*, + indexed_by< + hashed_unique< tag, member >, + ordered_unique< tag, member > + > +> asset_multi_index_type; + +class Balance : public GrapheneObject { Q_OBJECT Q_PROPERTY(Asset* type MEMBER type) Q_PROPERTY(qint64 amount MEMBER amount) - Q_PROPERTY(qint64 id MEMBER id) Asset* type; qint64 amount; - qint64 id; }; -class Account : public QObject { +class Account : public GrapheneObject { Q_OBJECT Q_PROPERTY(QString name MEMBER name NOTIFY nameChanged) - Q_PROPERTY(qint64 id MEMBER id NOTIFY idChanged) Q_PROPERTY(QQmlListProperty balances READ balances) QList m_balances; -public: - // Account(QObject* parent = nullptr) - // : QObject(parent){} + public: + const QString& getName()const { return name; } - const QString& getName()const { return name; } - qint64 getId()const { return id; } + QQmlListProperty balances(); - QQmlListProperty balances(); + QString name; - QString name; - qint64 id; - -signals: - void nameChanged(); - void idChanged(); + Q_SIGNALS: + void nameChanged(); }; -struct by_id; struct by_account_name; -/** - * @ingroup object_index - */ typedef multi_index_container< Account*, indexed_by< - hashed_unique< tag, const_mem_fun >, - ordered_unique< tag, const_mem_fun > + hashed_unique< tag, member >, + ordered_unique< tag, member > > > account_multi_index_type; @@ -92,6 +104,8 @@ class ChainDataModel : public QObject { public: Q_INVOKABLE Account* getAccount(qint64 id); Q_INVOKABLE Account* getAccount(QString name); + Q_INVOKABLE Asset* getAsset(qint64 id); + Q_INVOKABLE Asset* getAsset(QString symbol); ChainDataModel(){} ChainDataModel( fc::thread& t, QObject* parent = nullptr ); @@ -109,6 +123,7 @@ private: qint64 m_account_query_num = -1; account_multi_index_type m_accounts; + asset_multi_index_type m_assets; }; diff --git a/programs/light_client/qml/main.qml b/programs/light_client/qml/main.qml index ef5f0c84..127bb1d1 100644 --- a/programs/light_client/qml/main.qml +++ b/programs/light_client/qml/main.qml @@ -75,24 +75,24 @@ ApplicationWindow { else { console.log("Waiting for result...") - acct.idChanged.connect(function(loadedAcct) { + acct.idChanged.connect(function() { console.log( "ID CHANGED" ); - console.log(JSON.stringify(loadedAcct)) + console.log(JSON.stringify(acct)) }) } } } TextField { - id: idField - onAccepted: lookupIdButton.clicked() + id: accountIdField + onAccepted: lookupAccountIdButton.clicked() focus: true } Button { - id: lookupIdButton - text: "Lookup ID" + id: lookupAccountIdButton + text: "Lookup Account ID" onClicked: { - var acct = app.model.getAccount(parseInt(idField.text)) + var acct = app.model.getAccount(parseInt(accountIdField.text)) console.log(JSON.stringify(acct)) // @disable-check M126 if (acct == null) @@ -105,7 +105,37 @@ ApplicationWindow { else { console.log("Waiting for result...") - acct.nameChanged.connect(function(loadedAcct) { + acct.nameChanged.connect(function() { + console.log( "NAME CHANGED" ); + console.log(JSON.stringify(acct)) + }) + } + } + } + + TextField { + id: assetIdField + onAccepted: lookupassetIdButton.clicked() + focus: true + } + Button { + id: lookupassetIdButton + text: "Lookup Asset ID" + onClicked: { + var acct = app.model.getAsset(parseInt(assetIdField.text)) + console.log(JSON.stringify(acct)) + // @disable-check M126 + if (acct == null) + console.log("Got back null asset") + else if ( !(parseInt(acct.name) <= 0) ) + { + console.log("NAME ALREADY SET" ); + console.log(JSON.stringify(acct)) + } + else + { + console.log("Waiting for result...") + acct.nameChanged.connect(function() { console.log( "NAME CHANGED" ); console.log(JSON.stringify(acct)) })