<commit_before>/*
 *
 * NodeRippleLikeBlockchainExplorer
 *
 * Created by El Khalil Bellakrid on 09/01/2019.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Ledger
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include "NodeRippleLikeBlockchainExplorer.h"
#include <api/RippleConfigurationDefaults.hpp>
#include <api/Configuration.hpp>
#include <rapidjson/document.h>
#include <wallet/currencies.hpp>

namespace ledger {
    namespace core {
        NodeRippleLikeBlockchainExplorer::NodeRippleLikeBlockchainExplorer(
                const std::shared_ptr<api::ExecutionContext> &context,
                const std::shared_ptr<HttpClient> &http,
                const api::RippleLikeNetworkParameters &parameters,
                const std::shared_ptr<api::DynamicObject> &configuration) :
                DedicatedContext(context),
                RippleLikeBlockchainExplorer(configuration, {api::Configuration::BLOCKCHAIN_EXPLORER_API_ENDPOINT}) {
            _http = http;
            _parameters = parameters;
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getBalance(const std::vector<RippleLikeKeychain::Address> &addresses) {
            auto size = addresses.size();
            if (size != 1) {
                throw make_exception(api::ErrorCode::INVALID_ARGUMENT,
                                     "Can only get balance of 1 address from Ripple Node, but got {} addresses", addresses.size());
            }
            std::string addressesStr = addresses[0]->toBase58();
            return getAccountInfo(addressesStr, "Balance", BigInt::ZERO, FieldTypes::StringType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getSequence(const std::string &address) {
            return getAccountInfo(address, "Sequence", BigInt::ZERO, FieldTypes::NumberType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getFees() {
            return getServerInfo("base_fee_xrp", FieldTypes::NumberType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getBaseReserve() {
            return getServerInfo("reserve_base_xrp", FieldTypes::StringType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getLedgerSequence() {
            return getServerInfo("seq", FieldTypes::StringType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getServerInfo(const std::string &field, FieldTypes type) {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("server_info");
            auto requestBody = bodyRequest.getString();
            bool parseNumberAsString = type == FieldTypes::StringType;
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .json(parseNumberAsString).mapPtr<BigInt>(getContext(), [field, type](const HttpRequest::JsonResult &result) {
                        auto &json = *std::get<1>(result);
                        //Is there a result field ?
                        if (!json.IsObject() || !json.HasMember("result") ||
                            !json["result"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                 "Failed to get base reserve from network, no (or malformed) field \"result\" in response");
                        }

                        //Is there an info field ?
                        auto resultObj = json["result"].GetObject();
                        if (!resultObj.HasMember("info") || !resultObj["info"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                 "Failed to get base reserve from network, no (or malformed) field \"info\" in response");
                        }

                        //Is there a validated_ledger field ?
                        auto infoObj = resultObj["info"].GetObject();
                        if (!infoObj.HasMember("validated_ledger") || !infoObj["validated_ledger"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                 "Failed to get base reserve from network, no (or malformed) field \"validated_ledger\" in response");
                        }

                        switch (type) {
                            case FieldTypes::StringType: {
                                //Is there a reserve_base_xrp field ?
                                auto reserveObj = infoObj["validated_ledger"].GetObject();
                                if (!reserveObj.HasMember(field.c_str()) || !reserveObj[field.c_str()].IsString()) {
                                    throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                         fmt::format("Failed to get {} from network, no (or malformed) field \"{}\" in response", field, field));
                                }

                                auto value = reserveObj[field.c_str()].GetString();
                                return std::make_shared<BigInt>(value);
                            }
                            case FieldTypes::NumberType: {
                                //Is there a reserve_base_xrp field ?
                                auto reserveObj = infoObj["validated_ledger"].GetObject();
                                if (!reserveObj.HasMember(field.c_str()) || !reserveObj[field.c_str()].IsDouble()) {
                                    throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                         fmt::format("Failed to get {} from network, no (or malformed) field \"{}\" in response <<<", field, field));
                                }

                                auto value = reserveObj[field.c_str()].GetDouble();
                                return std::make_shared<BigInt>(static_cast<unsigned int>(value * pow(10, currencies::RIPPLE.units[1].numberOfDecimal)));
                            }
                        }

                        throw make_exception(api::ErrorCode::INVALID_ARGUMENT, "Failed to get {} which has an unkown field type", field);
                    });
        }

        Future<String>
        NodeRippleLikeBlockchainExplorer::pushLedgerApiTransaction(const std::vector<uint8_t> &transaction) {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("submit");
            bodyRequest.pushParameter("tx_blob", hex::toString(transaction));
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .json().template map<String>(getExplorerContext(), [](const HttpRequest::JsonResult &result) -> String {
                        auto &json = *std::get<1>(result);
                        if (!json.IsObject() || !json.HasMember("result") ||
                            !json["result"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to broadcast transaction, no (or malformed) field \"result\" in response");
                        }
                        //Is there an tx_json field ?
                        auto resultObj = json["result"].GetObject();
                        if (!resultObj.HasMember("tx_json") || !resultObj["tx_json"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to broadcast transaction, no (or malformed) field \"tx_json\" in response");
                        }

                        //Is there an hash field ?
                        auto jsonObj = resultObj["tx_json"].GetObject();
                        if (!jsonObj.HasMember("hash") || !jsonObj["hash"].IsString()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to broadcast transaction, no (or malformed) field \"hash\" in response");
                        }
                        return jsonObj["hash"].GetString();
                    });
        }

        Future<void *> NodeRippleLikeBlockchainExplorer::startSession() {
            return Future<void *>::successful(new std::string("", 0));
        }

        Future<Unit> NodeRippleLikeBlockchainExplorer::killSession(void *session) {
            return Future<Unit>::successful(unit);
        }

        Future<Bytes> NodeRippleLikeBlockchainExplorer::getRawTransaction(const String &transactionHash) {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("tx");
            bodyRequest.pushParameter("trasnaction", transactionHash);
            bodyRequest.pushParameter("binary", "true");
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .json().template map<Bytes>(getExplorerContext(), [](const HttpRequest::JsonResult &result) -> Bytes {
                        auto &json = *std::get<1>(result);
                        if (!json.IsObject() || !json.HasMember("result") ||
                            !json["result"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get raw transaction, no (or malformed) field \"result\" in response");
                        }
                        //Is there a tx field ?
                        auto resultObj = json["result"].GetObject();
                        if (!resultObj.HasMember("tx") || !resultObj["tx"].IsString()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get raw transaction, no (or malformed) field \"tx\" in response");
                        }
                        return Bytes(hex::toByteArray(std::string(resultObj["tx"].GetString(), resultObj["tx"].GetStringLength())));
                    });
        }

        Future<String> NodeRippleLikeBlockchainExplorer::pushTransaction(const std::vector<uint8_t> &transaction) {
            return pushLedgerApiTransaction(transaction);
        }

        FuturePtr<RippleLikeBlockchainExplorer::TransactionsBulk>
        NodeRippleLikeBlockchainExplorer::getTransactions(const std::vector<std::string> &addresses,
                                                          Option<std::string> fromBlockHash,
                                                          Option<void *> session) {
            if (addresses.size() != 1) {
                throw make_exception(api::ErrorCode::INVALID_ARGUMENT,
                                     "Can only get transactions for 1 address from Ripple Node, but got {} addresses", addresses.size());
            }
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("account_tx");
            bodyRequest.pushParameter("account", addresses[0]);
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .template json<TransactionsBulk, Exception>(
                            LedgerApiParser<TransactionsBulk, RippleLikeTransactionsBulkParser>())
                    .template mapPtr<TransactionsBulk>(getExplorerContext(), [fromBlockHash](
                            const Either<Exception, std::shared_ptr<TransactionsBulk>> &result) {
                        if (result.isLeft()) {
                            if (fromBlockHash.isEmpty()) {
                                throw result.getLeft();
                            } else {
                                throw make_exception(api::ErrorCode::BLOCK_NOT_FOUND,
                                                     "Unable to find block with hash {}", fromBlockHash.getValue());
                            }
                        } else {
                            return result.getRight();
                        }
                    });
        }

        FuturePtr<Block> NodeRippleLikeBlockchainExplorer::getCurrentBlock() const {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("ledger");
            bodyRequest.pushParameter("ledger_index", std::string("validated"));
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .template json<Block, Exception>(LedgerApiParser<Block, RippleLikeBlockParser>())
                    .template mapPtr<Block>(getExplorerContext(),
                                                   [](const Either<Exception, std::shared_ptr<Block>> &result) {
                                                       if (result.isLeft()) {
                                                           throw result.getLeft();
                                                       } else {
                                                           return result.getRight();
                                                       }
                                                   });
        }

        FuturePtr<RippleLikeBlockchainExplorerTransaction>
        NodeRippleLikeBlockchainExplorer::getTransactionByHash(const String &transactionHash) const {
            return getLedgerApiTransactionByHash(transactionHash);
        }

        Future<int64_t> NodeRippleLikeBlockchainExplorer::getTimestamp() const {
            return getLedgerApiTimestamp();
        }

        std::shared_ptr<api::ExecutionContext> NodeRippleLikeBlockchainExplorer::getExplorerContext() const {
            return _executionContext;
        }

        api::RippleLikeNetworkParameters NodeRippleLikeBlockchainExplorer::getNetworkParameters() const {
            return _parameters;
        }

        std::string NodeRippleLikeBlockchainExplorer::getExplorerVersion() const {
            return "";
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getAccountInfo(const std::string &address,
                                                         const std::string &key,
                                                         const BigInt &defaultValue,
                                                         FieldTypes type) {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("account_info");
            bodyRequest.pushParameter("account", address);
            bodyRequest.pushParameter("ledger_index", std::string("validated"));
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .json().mapPtr<BigInt>(getContext(), [address, key, type, defaultValue](const HttpRequest::JsonResult &result) {
                        auto &json = *std::get<1>(result);
                        //Is there a result field ?
                        if (!json.IsObject() || !json.HasMember("result") ||
                            !json["result"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get {} for {}, no (or malformed) field \"result\" in response",
                                                 key, address);
                        }

                        //Is there an account_data field ?
                        auto resultObj = json["result"].GetObject();
                        if (!resultObj.HasMember("account_data") || !resultObj["account_data"].IsObject()) {
                            // Case of account not found (not activated yet)
                            return std::make_shared<BigInt>(defaultValue);
                        }

                        //Is there an field with key name ?
                        auto accountObj = resultObj["account_data"].GetObject();
                        switch(type) {
                            case FieldTypes::NumberType : {
                                if (!accountObj.HasMember(key.c_str()) || !accountObj[key.c_str()].IsUint64()) {
                                    throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get {} for {}, no (or malformed) field \"{}\" in response",
                                                         key, address, key);
                                }

                                auto balance = accountObj[key.c_str()].GetUint64();
                                return std::make_shared<BigInt>((int64_t)balance);
                            }
                            case FieldTypes::StringType : {
                                if (!accountObj.HasMember(key.c_str()) || !accountObj[key.c_str()].IsString()) {
                                    throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get {} for {}, no (or malformed) field \"{}\" in response",
                                                         key, address, key);
                                }

                                auto balance = accountObj[key.c_str()].GetString();
                                return std::make_shared<BigInt>(balance);
                            }
                        }

                        throw make_exception(api::ErrorCode::INVALID_ARGUMENT, "Failed to get {} which has an unkown field type",
                                             key);
                    });
        }
    }
}
<commit_msg>Throw exception if Ripple node does not return tesSUCCESS on broadcasting a txn<commit_after>/*
 *
 * NodeRippleLikeBlockchainExplorer
 *
 * Created by El Khalil Bellakrid on 09/01/2019.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Ledger
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include "NodeRippleLikeBlockchainExplorer.h"
#include <api/RippleConfigurationDefaults.hpp>
#include <api/Configuration.hpp>
#include <rapidjson/document.h>
#include <wallet/currencies.hpp>

namespace ledger {
    namespace core {
        NodeRippleLikeBlockchainExplorer::NodeRippleLikeBlockchainExplorer(
                const std::shared_ptr<api::ExecutionContext> &context,
                const std::shared_ptr<HttpClient> &http,
                const api::RippleLikeNetworkParameters &parameters,
                const std::shared_ptr<api::DynamicObject> &configuration) :
                DedicatedContext(context),
                RippleLikeBlockchainExplorer(configuration, {api::Configuration::BLOCKCHAIN_EXPLORER_API_ENDPOINT}) {
            _http = http;
            _parameters = parameters;
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getBalance(const std::vector<RippleLikeKeychain::Address> &addresses) {
            auto size = addresses.size();
            if (size != 1) {
                throw make_exception(api::ErrorCode::INVALID_ARGUMENT,
                                     "Can only get balance of 1 address from Ripple Node, but got {} addresses", addresses.size());
            }
            std::string addressesStr = addresses[0]->toBase58();
            return getAccountInfo(addressesStr, "Balance", BigInt::ZERO, FieldTypes::StringType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getSequence(const std::string &address) {
            return getAccountInfo(address, "Sequence", BigInt::ZERO, FieldTypes::NumberType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getFees() {
            return getServerInfo("base_fee_xrp", FieldTypes::NumberType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getBaseReserve() {
            return getServerInfo("reserve_base_xrp", FieldTypes::StringType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getLedgerSequence() {
            return getServerInfo("seq", FieldTypes::StringType);
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getServerInfo(const std::string &field, FieldTypes type) {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("server_info");
            auto requestBody = bodyRequest.getString();
            bool parseNumberAsString = type == FieldTypes::StringType;
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .json(parseNumberAsString).mapPtr<BigInt>(getContext(), [field, type](const HttpRequest::JsonResult &result) {
                        auto &json = *std::get<1>(result);
                        //Is there a result field ?
                        if (!json.IsObject() || !json.HasMember("result") ||
                            !json["result"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                 "Failed to get base reserve from network, no (or malformed) field \"result\" in response");
                        }

                        //Is there an info field ?
                        auto resultObj = json["result"].GetObject();
                        if (!resultObj.HasMember("info") || !resultObj["info"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                 "Failed to get base reserve from network, no (or malformed) field \"info\" in response");
                        }

                        //Is there a validated_ledger field ?
                        auto infoObj = resultObj["info"].GetObject();
                        if (!infoObj.HasMember("validated_ledger") || !infoObj["validated_ledger"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                 "Failed to get base reserve from network, no (or malformed) field \"validated_ledger\" in response");
                        }

                        switch (type) {
                            case FieldTypes::StringType: {
                                //Is there a reserve_base_xrp field ?
                                auto reserveObj = infoObj["validated_ledger"].GetObject();
                                if (!reserveObj.HasMember(field.c_str()) || !reserveObj[field.c_str()].IsString()) {
                                    throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                         fmt::format("Failed to get {} from network, no (or malformed) field \"{}\" in response", field, field));
                                }

                                auto value = reserveObj[field.c_str()].GetString();
                                return std::make_shared<BigInt>(value);
                            }
                            case FieldTypes::NumberType: {
                                //Is there a reserve_base_xrp field ?
                                auto reserveObj = infoObj["validated_ledger"].GetObject();
                                if (!reserveObj.HasMember(field.c_str()) || !reserveObj[field.c_str()].IsDouble()) {
                                    throw make_exception(api::ErrorCode::HTTP_ERROR,
                                                         fmt::format("Failed to get {} from network, no (or malformed) field \"{}\" in response <<<", field, field));
                                }

                                auto value = reserveObj[field.c_str()].GetDouble();
                                return std::make_shared<BigInt>(static_cast<unsigned int>(value * pow(10, currencies::RIPPLE.units[1].numberOfDecimal)));
                            }
                        }

                        throw make_exception(api::ErrorCode::INVALID_ARGUMENT, "Failed to get {} which has an unkown field type", field);
                    });
        }

        Future<String>
        NodeRippleLikeBlockchainExplorer::pushLedgerApiTransaction(const std::vector<uint8_t> &transaction) {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("submit");
            bodyRequest.pushParameter("tx_blob", hex::toString(transaction));
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .json().template map<String>(getExplorerContext(), [](const HttpRequest::JsonResult &result) -> String {
                        auto &json = *std::get<1>(result);
                        if (!json.IsObject() || !json.HasMember("result") ||
                            !json["result"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to broadcast transaction, no (or malformed) field \"result\" in response");
                        }

                        auto resultObj = json["result"].GetObject();

                        if (resultObj.HasMember("engine_result") && resultObj["engine_result"] == "tesSUCCESS") {
                          // Check presence of tx_json field
                          if (!resultObj.HasMember("tx_json") || !resultObj["tx_json"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to broadcast transaction, no (or malformed) field \"tx_json\" in response");
                          }
                          auto txnObj = resultObj["tx_json"].GetObject();

                          // Check presence of hash field
                          if (!txnObj.HasMember("hash") || !txnObj["hash"].IsString()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to broadcast transaction, no (or malformed) field \"hash\" in response");
                          }

                          return txnObj["hash"].GetString();
                        }

                        throw make_exception(api::ErrorCode::HTTP_ERROR,
                                             "Failed to broadcast transaction: {}",
                                             resultObj["engine_result"].GetString());
                    });
        }

        Future<void *> NodeRippleLikeBlockchainExplorer::startSession() {
            return Future<void *>::successful(new std::string("", 0));
        }

        Future<Unit> NodeRippleLikeBlockchainExplorer::killSession(void *session) {
            return Future<Unit>::successful(unit);
        }

        Future<Bytes> NodeRippleLikeBlockchainExplorer::getRawTransaction(const String &transactionHash) {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("tx");
            bodyRequest.pushParameter("trasnaction", transactionHash);
            bodyRequest.pushParameter("binary", "true");
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .json().template map<Bytes>(getExplorerContext(), [](const HttpRequest::JsonResult &result) -> Bytes {
                        auto &json = *std::get<1>(result);
                        if (!json.IsObject() || !json.HasMember("result") ||
                            !json["result"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get raw transaction, no (or malformed) field \"result\" in response");
                        }
                        //Is there a tx field ?
                        auto resultObj = json["result"].GetObject();
                        if (!resultObj.HasMember("tx") || !resultObj["tx"].IsString()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get raw transaction, no (or malformed) field \"tx\" in response");
                        }
                        return Bytes(hex::toByteArray(std::string(resultObj["tx"].GetString(), resultObj["tx"].GetStringLength())));
                    });
        }

        Future<String> NodeRippleLikeBlockchainExplorer::pushTransaction(const std::vector<uint8_t> &transaction) {
            return pushLedgerApiTransaction(transaction);
        }

        FuturePtr<RippleLikeBlockchainExplorer::TransactionsBulk>
        NodeRippleLikeBlockchainExplorer::getTransactions(const std::vector<std::string> &addresses,
                                                          Option<std::string> fromBlockHash,
                                                          Option<void *> session) {
            if (addresses.size() != 1) {
                throw make_exception(api::ErrorCode::INVALID_ARGUMENT,
                                     "Can only get transactions for 1 address from Ripple Node, but got {} addresses", addresses.size());
            }
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("account_tx");
            bodyRequest.pushParameter("account", addresses[0]);
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .template json<TransactionsBulk, Exception>(
                            LedgerApiParser<TransactionsBulk, RippleLikeTransactionsBulkParser>())
                    .template mapPtr<TransactionsBulk>(getExplorerContext(), [fromBlockHash](
                            const Either<Exception, std::shared_ptr<TransactionsBulk>> &result) {
                        if (result.isLeft()) {
                            if (fromBlockHash.isEmpty()) {
                                throw result.getLeft();
                            } else {
                                throw make_exception(api::ErrorCode::BLOCK_NOT_FOUND,
                                                     "Unable to find block with hash {}", fromBlockHash.getValue());
                            }
                        } else {
                            return result.getRight();
                        }
                    });
        }

        FuturePtr<Block> NodeRippleLikeBlockchainExplorer::getCurrentBlock() const {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("ledger");
            bodyRequest.pushParameter("ledger_index", std::string("validated"));
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .template json<Block, Exception>(LedgerApiParser<Block, RippleLikeBlockParser>())
                    .template mapPtr<Block>(getExplorerContext(),
                                                   [](const Either<Exception, std::shared_ptr<Block>> &result) {
                                                       if (result.isLeft()) {
                                                           throw result.getLeft();
                                                       } else {
                                                           return result.getRight();
                                                       }
                                                   });
        }

        FuturePtr<RippleLikeBlockchainExplorerTransaction>
        NodeRippleLikeBlockchainExplorer::getTransactionByHash(const String &transactionHash) const {
            return getLedgerApiTransactionByHash(transactionHash);
        }

        Future<int64_t> NodeRippleLikeBlockchainExplorer::getTimestamp() const {
            return getLedgerApiTimestamp();
        }

        std::shared_ptr<api::ExecutionContext> NodeRippleLikeBlockchainExplorer::getExplorerContext() const {
            return _executionContext;
        }

        api::RippleLikeNetworkParameters NodeRippleLikeBlockchainExplorer::getNetworkParameters() const {
            return _parameters;
        }

        std::string NodeRippleLikeBlockchainExplorer::getExplorerVersion() const {
            return "";
        }

        Future<std::shared_ptr<BigInt>>
        NodeRippleLikeBlockchainExplorer::getAccountInfo(const std::string &address,
                                                         const std::string &key,
                                                         const BigInt &defaultValue,
                                                         FieldTypes type) {
            NodeRippleLikeBodyRequest bodyRequest;
            bodyRequest.setMethod("account_info");
            bodyRequest.pushParameter("account", address);
            bodyRequest.pushParameter("ledger_index", std::string("validated"));
            auto requestBody = bodyRequest.getString();
            std::unordered_map<std::string, std::string> headers{{"Content-Type", "application/json"}};
            return _http->POST("", std::vector<uint8_t>(requestBody.begin(), requestBody.end()), headers)
                    .json().mapPtr<BigInt>(getContext(), [address, key, type, defaultValue](const HttpRequest::JsonResult &result) {
                        auto &json = *std::get<1>(result);
                        //Is there a result field ?
                        if (!json.IsObject() || !json.HasMember("result") ||
                            !json["result"].IsObject()) {
                            throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get {} for {}, no (or malformed) field \"result\" in response",
                                                 key, address);
                        }

                        //Is there an account_data field ?
                        auto resultObj = json["result"].GetObject();
                        if (!resultObj.HasMember("account_data") || !resultObj["account_data"].IsObject()) {
                            // Case of account not found (not activated yet)
                            return std::make_shared<BigInt>(defaultValue);
                        }

                        //Is there an field with key name ?
                        auto accountObj = resultObj["account_data"].GetObject();
                        switch(type) {
                            case FieldTypes::NumberType : {
                                if (!accountObj.HasMember(key.c_str()) || !accountObj[key.c_str()].IsUint64()) {
                                    throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get {} for {}, no (or malformed) field \"{}\" in response",
                                                         key, address, key);
                                }

                                auto balance = accountObj[key.c_str()].GetUint64();
                                return std::make_shared<BigInt>((int64_t)balance);
                            }
                            case FieldTypes::StringType : {
                                if (!accountObj.HasMember(key.c_str()) || !accountObj[key.c_str()].IsString()) {
                                    throw make_exception(api::ErrorCode::HTTP_ERROR, "Failed to get {} for {}, no (or malformed) field \"{}\" in response",
                                                         key, address, key);
                                }

                                auto balance = accountObj[key.c_str()].GetString();
                                return std::make_shared<BigInt>(balance);
                            }
                        }

                        throw make_exception(api::ErrorCode::INVALID_ARGUMENT, "Failed to get {} which has an unkown field type",
                                             key);
                    });
        }
    }
}
<|endoftext|>


<commit_before>#include "version.h"

namespace thewizardplusplus {
namespace language_do {
namespace utils {

const std::string VERSION_STRING = "v0.2";

}
}
}
<commit_msg>Update version.<commit_after>#include "version.h"

namespace thewizardplusplus {
namespace language_do {
namespace utils {

const std::string VERSION_STRING = "v0.1.1";

}
}
}
<|endoftext|>


<commit_before><commit_msg>Fixing a breakage in the GTK toolkit build that my last check-in caused.<commit_after><|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "savefmtdialog.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QInputDialog>
#include <QApplication>
#include <QStyle>
#include <iostream>

using namespace Vipster;

MainWindow::MainWindow(QWidget *parent):
    QMainWindow{parent},
    ui{new Ui::MainWindow}
{
    ui->setupUi(this);
    connect(ui->actionAbout_Qt,SIGNAL(triggered()),qApp,SLOT(aboutQt()));
    newMol();
    setupUI();
}

MainWindow::MainWindow(std::vector<IO::Data> &&d, QWidget *parent):
    QMainWindow{parent},
    ui{new Ui::MainWindow}
{
    ui->setupUi(this);
    connect(ui->actionAbout_Qt,SIGNAL(triggered()),qApp,SLOT(aboutQt()));
    for(auto&& mol: d){
        newData(std::move(mol));
    }
    setupUI();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setupUI()
{
    ui->firstStepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward));
    ui->preStepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSeekBackward));
    ui->playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
    ui->nextStepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSeekForward));
    ui->lastStepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipForward));
    // setup left dock-area
    tabifyDockWidget(ui->molDock, ui->paramDock);
    ui->molDock->raise();
#ifdef Q_OS_MACOS
    setDockOptions(dockOptions()^VerticalTabs);
#endif
    // fill in menu-options
    ui->menuPWScf->removeAction(ui->actionParamDummy); // qtcreator only creates menu when actions are provided
    auto pwi_range = Vipster::params.equal_range(IOFmt::PWI);
    for(auto it=pwi_range.first; it!=pwi_range.second; ++it){
        ui->menuPWScf->addAction(QString::fromStdString(it->second->name),
                                 this, &MainWindow::loadParam);
    }
}

void MainWindow::updateWidgets(Change change)
{
    if((change & (Change::atoms | Change::cell)) != 0) {
        ui->openGLWidget->setStep(curStep);
    }
    ui->molWidget->updateWidget(change);
    ui->paramWidget->updateWidget(change);
}

void MainWindow::setFmt(int i, bool apply, bool scale)
{
    fmt = static_cast<AtomFmt>(i);
    if(apply){
        curStep->setFmt(fmt, scale);
        updateWidgets(stepChanged);
    }else{
        updateWidgets(Change::fmt);
    }
}

AtomFmt MainWindow::getFmt()
{
    return fmt;
}

void MainWindow::setMol(int i)
{
    curMol = &molecules.at(i);
    uint steps = curMol->getNstep();
    //Step-control
    ui->stepLabel->setText(QString::number(steps));
    QSignalBlocker boxBlocker(ui->stepEdit);
    QSignalBlocker slideBlocker(ui->stepSlider);
    ui->stepEdit->setMaximum(steps);
    ui->stepEdit->setValue(steps);
    ui->stepSlider->setMaximum(steps);
    ui->stepSlider->setValue(steps);
    if(steps == 1){
        ui->stepEdit->setDisabled(true);
        ui->stepSlider->setDisabled(true);
    }else{
        ui->stepEdit->setEnabled(true);
        ui->stepSlider->setEnabled(true);
    }
    setStep(static_cast<int>(steps));
    updateWidgets(molChanged);
}

void MainWindow::setStep(int i)
{
    curStep = &curMol->getStep(static_cast<size_t>(i-1));
    fmt = curStep->getFmt();
    //Handle control-buttons
    if(i == 1){
        ui->preStepButton->setDisabled(true);
        ui->firstStepButton->setDisabled(true);
    }else{
        ui->preStepButton->setEnabled(true);
        ui->firstStepButton->setEnabled(true);
    }
    if(i == static_cast<int>(curMol->getNstep())){
        ui->nextStepButton->setDisabled(true);
        ui->lastStepButton->setDisabled(true);
    }else{
        ui->nextStepButton->setEnabled(true);
        ui->lastStepButton->setEnabled(true);
    }
    //Update child widgets
    updateWidgets(stepChanged);
}

void MainWindow::setParam(int i)
{
    curParam = params.at(static_cast<size_t>(i)).second.get();
    updateWidgets(Change::param);
}

void MainWindow::stepBut(QAbstractButton* but)
{
    if(but == ui->firstStepButton){
        setStep(1);
    }else if(but == ui->lastStepButton){
        setStep(static_cast<int>(curMol->getNstep()));
    }else if(but == ui->playButton){
        //TODO
    }
}

void MainWindow::editAtoms()
{
    const QObject *sender = QObject::sender();
    if ( sender == ui->actionNew_Atom){
        curStep->newAtom();
    }
    //TODO when selection stuff is implemented
//    }else if ( sender == ui->actionDelete_Atom_s){
//        curMol->curStep().delAtom();
//    }
    updateWidgets(Change::atoms);
}

void MainWindow::newMol()
{
    molecules.emplace_back();
    ui->molWidget->registerMol(molecules.back().getName());
}

void MainWindow::newData(IO::Data &&d)
{
    molecules.push_back(std::move(d.mol));
    ui->molWidget->registerMol(molecules.back().getName());
    if(d.param){
        params.push_back({d.fmt, std::move(d.param)});
        ui->paramWidget->registerParam(d.fmt, params.back().second->name);
    }
}

void MainWindow::loadMol()
{
    // File dialog
    QStringList files;
    QFileDialog fileDiag{this};
    fileDiag.setDirectory(path);
    fileDiag.setFileMode(QFileDialog::ExistingFiles);
    // Format dialog
    QStringList formats{};
    for(auto &iop: IOPlugins){
        formats << QString::fromStdString(iop.second->name);
    }
    QString fmt_s;
    IOFmt fmt;
    bool got_fmt{false};
    if(fileDiag.exec() != 0){
        files = fileDiag.selectedFiles();
        path = fileDiag.directory();
        if(files.count() != 0){
            fmt_s = QInputDialog::getItem(this, "Select format", "Format:",
                                          formats, 0, false, &got_fmt);
            if(got_fmt){
                fmt = static_cast<IOFmt>(formats.indexOf(fmt_s));
                for(auto &file: files){
                    newData(readFile(file.toStdString(), fmt));
                }
            }
        }
    }
}

void MainWindow::saveMol()
{
    QFileDialog fileDiag{this};
    fileDiag.setDirectory(path);
    fileDiag.setAcceptMode(QFileDialog::AcceptSave);
    if(fileDiag.exec() != 0){
        auto target = fileDiag.selectedFiles()[0].toStdString();
        path = fileDiag.directory();
        SaveFmtDialog sfd{this};
        if(sfd.exec() != 0){
            writeFile(target, sfd.fmt, *curMol, sfd.param, sfd.config);
        }
    }
}

void MainWindow::loadParam()
{
    auto* s = static_cast<QAction*>(sender());
    auto* p = static_cast<QMenu*>(s->parent());
    std::cout <
title().toStdString() << std::endl;
    IOFmt fmt = [&](){
        if(p->title() == "&PWScf"){
            return IOFmt::PWI;
        }
        throw Error("Invalid parameter set");
    }();
    auto range = Vipster::params.equal_range(fmt);
    for(auto it=range.first; it!=range.second; ++it){
        if (it->second->name.c_str() == s->text()){
            params.push_back({fmt, it->second->copy()});
            ui->paramWidget->registerParam(fmt, params.back().second->name);
            return;
        }
    }
}

void MainWindow::about()
{
    QMessageBox::about(this,QString("About Vipster"),
    QString("
Vipster
"
            "
"
            "©Sebastian Gsänger, 2018"
            "
"
            "Homepage"
            "
"
            "Source"
            "
"
            "
"
            "This program is provided under the GPLv3."
            "
"
            "It uses"
            "JSON for Modern C++, "
            "Catch2 and "
            "pybind11."
            "
"));
}

BaseWidget::BaseWidget()
{
    for(auto *w: qApp->topLevelWidgets()){
        if(auto *t = qobject_cast<MainWindow*>(w)){
            master = t;
            return;
        }
    }
    throw Error("Could not determine MainWindow-instance.");
}

void BaseWidget::triggerUpdate(Change change)
{
    updateTriggered = true;
    master->updateWidgets(change);
}
<commit_msg>removed debug-remains<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "savefmtdialog.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QInputDialog>
#include <QApplication>
#include <QStyle>

using namespace Vipster;

MainWindow::MainWindow(QWidget *parent):
    QMainWindow{parent},
    ui{new Ui::MainWindow}
{
    ui->setupUi(this);
    connect(ui->actionAbout_Qt,SIGNAL(triggered()),qApp,SLOT(aboutQt()));
    newMol();
    setupUI();
}

MainWindow::MainWindow(std::vector<IO::Data> &&d, QWidget *parent):
    QMainWindow{parent},
    ui{new Ui::MainWindow}
{
    ui->setupUi(this);
    connect(ui->actionAbout_Qt,SIGNAL(triggered()),qApp,SLOT(aboutQt()));
    for(auto&& mol: d){
        newData(std::move(mol));
    }
    setupUI();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setupUI()
{
    ui->firstStepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward));
    ui->preStepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSeekBackward));
    ui->playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
    ui->nextStepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSeekForward));
    ui->lastStepButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipForward));
    // setup left dock-area
    tabifyDockWidget(ui->molDock, ui->paramDock);
    ui->molDock->raise();
#ifdef Q_OS_MACOS
    setDockOptions(dockOptions()^VerticalTabs);
#endif
    // fill in menu-options
    ui->menuPWScf->removeAction(ui->actionParamDummy); // qtcreator only creates menu when actions are provided
    auto pwi_range = Vipster::params.equal_range(IOFmt::PWI);
    for(auto it=pwi_range.first; it!=pwi_range.second; ++it){
        ui->menuPWScf->addAction(QString::fromStdString(it->second->name),
                                 this, &MainWindow::loadParam);
    }
}

void MainWindow::updateWidgets(Change change)
{
    if((change & (Change::atoms | Change::cell)) != 0) {
        ui->openGLWidget->setStep(curStep);
    }
    ui->molWidget->updateWidget(change);
    ui->paramWidget->updateWidget(change);
}

void MainWindow::setFmt(int i, bool apply, bool scale)
{
    fmt = static_cast<AtomFmt>(i);
    if(apply){
        curStep->setFmt(fmt, scale);
        updateWidgets(stepChanged);
    }else{
        updateWidgets(Change::fmt);
    }
}

AtomFmt MainWindow::getFmt()
{
    return fmt;
}

void MainWindow::setMol(int i)
{
    curMol = &molecules.at(i);
    uint steps = curMol->getNstep();
    //Step-control
    ui->stepLabel->setText(QString::number(steps));
    QSignalBlocker boxBlocker(ui->stepEdit);
    QSignalBlocker slideBlocker(ui->stepSlider);
    ui->stepEdit->setMaximum(steps);
    ui->stepEdit->setValue(steps);
    ui->stepSlider->setMaximum(steps);
    ui->stepSlider->setValue(steps);
    if(steps == 1){
        ui->stepEdit->setDisabled(true);
        ui->stepSlider->setDisabled(true);
    }else{
        ui->stepEdit->setEnabled(true);
        ui->stepSlider->setEnabled(true);
    }
    setStep(static_cast<int>(steps));
    updateWidgets(molChanged);
}

void MainWindow::setStep(int i)
{
    curStep = &curMol->getStep(static_cast<size_t>(i-1));
    fmt = curStep->getFmt();
    //Handle control-buttons
    if(i == 1){
        ui->preStepButton->setDisabled(true);
        ui->firstStepButton->setDisabled(true);
    }else{
        ui->preStepButton->setEnabled(true);
        ui->firstStepButton->setEnabled(true);
    }
    if(i == static_cast<int>(curMol->getNstep())){
        ui->nextStepButton->setDisabled(true);
        ui->lastStepButton->setDisabled(true);
    }else{
        ui->nextStepButton->setEnabled(true);
        ui->lastStepButton->setEnabled(true);
    }
    //Update child widgets
    updateWidgets(stepChanged);
}

void MainWindow::setParam(int i)
{
    curParam = params.at(static_cast<size_t>(i)).second.get();
    updateWidgets(Change::param);
}

void MainWindow::stepBut(QAbstractButton* but)
{
    if(but == ui->firstStepButton){
        setStep(1);
    }else if(but == ui->lastStepButton){
        setStep(static_cast<int>(curMol->getNstep()));
    }else if(but == ui->playButton){
        //TODO
    }
}

void MainWindow::editAtoms()
{
    const QObject *sender = QObject::sender();
    if ( sender == ui->actionNew_Atom){
        curStep->newAtom();
    }
    //TODO when selection stuff is implemented
//    }else if ( sender == ui->actionDelete_Atom_s){
//        curMol->curStep().delAtom();
//    }
    updateWidgets(Change::atoms);
}

void MainWindow::newMol()
{
    molecules.emplace_back();
    ui->molWidget->registerMol(molecules.back().getName());
}

void MainWindow::newData(IO::Data &&d)
{
    molecules.push_back(std::move(d.mol));
    ui->molWidget->registerMol(molecules.back().getName());
    if(d.param){
        params.push_back({d.fmt, std::move(d.param)});
        ui->paramWidget->registerParam(d.fmt, params.back().second->name);
    }
}

void MainWindow::loadMol()
{
    // File dialog
    QStringList files;
    QFileDialog fileDiag{this};
    fileDiag.setDirectory(path);
    fileDiag.setFileMode(QFileDialog::ExistingFiles);
    // Format dialog
    QStringList formats{};
    for(auto &iop: IOPlugins){
        formats << QString::fromStdString(iop.second->name);
    }
    QString fmt_s;
    IOFmt fmt;
    bool got_fmt{false};
    if(fileDiag.exec() != 0){
        files = fileDiag.selectedFiles();
        path = fileDiag.directory();
        if(files.count() != 0){
            fmt_s = QInputDialog::getItem(this, "Select format", "Format:",
                                          formats, 0, false, &got_fmt);
            if(got_fmt){
                fmt = static_cast<IOFmt>(formats.indexOf(fmt_s));
                for(auto &file: files){
                    newData(readFile(file.toStdString(), fmt));
                }
            }
        }
    }
}

void MainWindow::saveMol()
{
    QFileDialog fileDiag{this};
    fileDiag.setDirectory(path);
    fileDiag.setAcceptMode(QFileDialog::AcceptSave);
    if(fileDiag.exec() != 0){
        auto target = fileDiag.selectedFiles()[0].toStdString();
        path = fileDiag.directory();
        SaveFmtDialog sfd{this};
        if(sfd.exec() != 0){
            writeFile(target, sfd.fmt, *curMol, sfd.param, sfd.config);
        }
    }
}

void MainWindow::loadParam()
{
    auto* s = static_cast<QAction*>(sender());
    auto* p = static_cast<QMenu*>(s->parent());
    IOFmt fmt = [&](){
        if(p->title() == "&PWScf"){
            return IOFmt::PWI;
        }
        throw Error("Invalid parameter set");
    }();
    auto range = Vipster::params.equal_range(fmt);
    for(auto it=range.first; it!=range.second; ++it){
        if (it->second->name.c_str() == s->text()){
            params.push_back({fmt, it->second->copy()});
            ui->paramWidget->registerParam(fmt, params.back().second->name);
            return;
        }
    }
}

void MainWindow::about()
{
    QMessageBox::about(this,QString("About Vipster"),
    QString("
Vipster
"
            "
"
            "©Sebastian Gsänger, 2018"
            "
"
            "Homepage"
            "
"
            "Source"
            "
"
            "
"
            "This program is provided under the GPLv3."
            "
"
            "It uses"
            "JSON for Modern C++, "
            "Catch2 and "
            "pybind11."
            "
"));
}

BaseWidget::BaseWidget()
{
    for(auto *w: qApp->topLevelWidgets()){
        if(auto *t = qobject_cast<MainWindow*>(w)){
            master = t;
            return;
        }
    }
    throw Error("Could not determine MainWindow-instance.");
}

void BaseWidget::triggerUpdate(Change change)
{
    updateTriggered = true;
    master->updateWidgets(change);
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkRegularStepGradientDescentOptimizerTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

#include <itkRegularStepGradientDescentOptimizer.h>
#include <itkPoint.h>
#include <itkCovariantVector.h>

/**
 *  The objectif function is the quadratic form:
 *
 *  1/2 x^T A x - b^T x
 *
 *  Where A is a matrix and b is a vector
 *  The system in this example is:
 *
 *     | 3  2 ||x|   | 2|   |0|
 *     | 2  6 ||y| + |-8| = |0|
 *
 *
 *   the solution is the vector | 2 -2 |
 *
 */
class CostFunction : public itk::LightObject
{
public:

  typedef CostFunction Self;
  typedef itk::LightObject  Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  itkNewMacro( Self );

  enum { SpaceDimension=2 };

  typedef itk::Point<  double, SpaceDimension >          ParametersType;

  typedef itk::CovariantVector< double, SpaceDimension > DerivativeType;

  typedef double MeasureType ;

  CostFunction()
  {
  }

  const ParametersType & GetParameters(void) const
  {
    return m_Parameters;
  }

  const MeasureType & GetValue( const ParametersType & parameters ) const
  {

    m_Parameters = parameters;

    double x = m_Parameters[0];
    double y = m_Parameters[1];

    std::cout << "GetValue( " ;
    std::cout << x << " ";
    std::cout << y << ") = ";

    double val = 0.5*(3*x*x+4*x*y+6*y*y) - 2*x + 8*y;

    std::cout << val << std::endl;
    return m_Measure;

  }

  const DerivativeType & GetDerivative(
             const ParametersType & parameters ) const
  {

    m_Parameters = parameters;

    double x = m_Parameters[0];
    double y = m_Parameters[1];

    std::cout << "GetDerivative( " ;
    std::cout << x << " ";
    std::cout << y << ") = ";

    m_Derivative[0] = 3 * x + 2 * y -2;
    m_Derivative[1] = 2 * x + 6 * y +8;

    std::cout << m_Derivative << std::endl;

    return m_Derivative;
  }

private:

  mutable ParametersType  m_Parameters;
  mutable MeasureType     m_Measure;
  mutable DerivativeType  m_Derivative;

};

int main()
{
  std::cout << "Conjugate Gradient Optimizer Test ";
  std::cout << std::endl << std::endl;

  typedef  itk::RegularStepGradientDescentOptimizer<
                                CostFunction >  OptimizerType;

  // Declaration of a itkOptimizer
  OptimizerType::Pointer  itkOptimizer = OptimizerType::New();

  // Declaration of the CostFunction adaptor
  CostFunction::Pointer costFunction = CostFunction::New();

  itkOptimizer->SetCostFunction( costFunction );

  typedef CostFunction::ParametersType    ParametersType;

  typedef OptimizerType::TransformType   TransformType;
  typedef TransformType::ParametersType  TransformParametersType;

  // We start not so far from  | 2 -2 |
  ParametersType  initialPosition;
  initialPosition[0] =  100;
  initialPosition[1] = -100;

  TransformParametersType parametersScale;
  parametersScale[0] = 1.0;
  parametersScale[1] = 1.0;

  itkOptimizer->SetMinimize();
  itkOptimizer->GetTransform()->SetScale( parametersScale );
  itkOptimizer->SetGradientMagnitudeTolerance( 1e-6 );
  itkOptimizer->SetMaximumStepLength( 30.0 );
  itkOptimizer->SetMinimumStepLength( 1e-6 );
  itkOptimizer->SetNumberOfIterations( 900 );

  itkOptimizer->SetInitialPosition( initialPosition );
  itkOptimizer->StartOptimization();

  ParametersType finalPosition;
  finalPosition = costFunction->GetParameters();
  std::cout << "Solution        = (";
  std::cout << finalPosition[0] << "," ;
  std::cout << finalPosition[1] << ")" << std::endl;

  //
  // check results to see if it is within range
  //
  bool pass = true;
  double trueParameters[2] = { 2, -2 };
  for( unsigned int j = 0; j < 2; j++ )
    {
    if( vnl_math_abs( finalPosition[j] - trueParameters[j] ) > 0.01 )
      pass = false;
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}

<commit_msg>SetMinimize()  converted to MinimizeOn()<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkRegularStepGradientDescentOptimizerTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

#include <itkRegularStepGradientDescentOptimizer.h>
#include <itkPoint.h>
#include <itkCovariantVector.h>

/**
 *  The objectif function is the quadratic form:
 *
 *  1/2 x^T A x - b^T x
 *
 *  Where A is a matrix and b is a vector
 *  The system in this example is:
 *
 *     | 3  2 ||x|   | 2|   |0|
 *     | 2  6 ||y| + |-8| = |0|
 *
 *
 *   the solution is the vector | 2 -2 |
 *
 */
class CostFunction : public itk::LightObject
{
public:

  typedef CostFunction Self;
  typedef itk::LightObject  Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  itkNewMacro( Self );

  enum { SpaceDimension=2 };

  typedef itk::Point<  double, SpaceDimension >          ParametersType;

  typedef itk::CovariantVector< double, SpaceDimension > DerivativeType;

  typedef double MeasureType ;

  CostFunction()
  {
  }

  const ParametersType & GetParameters(void) const
  {
    return m_Parameters;
  }

  const MeasureType & GetValue( const ParametersType & parameters ) const
  {

    m_Parameters = parameters;

    double x = m_Parameters[0];
    double y = m_Parameters[1];

    std::cout << "GetValue( " ;
    std::cout << x << " ";
    std::cout << y << ") = ";

    double val = 0.5*(3*x*x+4*x*y+6*y*y) - 2*x + 8*y;

    std::cout << val << std::endl;
    return m_Measure;

  }

  const DerivativeType & GetDerivative(
             const ParametersType & parameters ) const
  {

    m_Parameters = parameters;

    double x = m_Parameters[0];
    double y = m_Parameters[1];

    std::cout << "GetDerivative( " ;
    std::cout << x << " ";
    std::cout << y << ") = ";

    m_Derivative[0] = 3 * x + 2 * y -2;
    m_Derivative[1] = 2 * x + 6 * y +8;

    std::cout << m_Derivative << std::endl;

    return m_Derivative;
  }

private:

  mutable ParametersType  m_Parameters;
  mutable MeasureType     m_Measure;
  mutable DerivativeType  m_Derivative;

};

int main()
{
  std::cout << "Conjugate Gradient Optimizer Test ";
  std::cout << std::endl << std::endl;

  typedef  itk::RegularStepGradientDescentOptimizer<
                                CostFunction >  OptimizerType;

  // Declaration of a itkOptimizer
  OptimizerType::Pointer  itkOptimizer = OptimizerType::New();

  // Declaration of the CostFunction adaptor
  CostFunction::Pointer costFunction = CostFunction::New();

  itkOptimizer->SetCostFunction( costFunction );

  typedef CostFunction::ParametersType    ParametersType;

  typedef OptimizerType::TransformType   TransformType;
  typedef TransformType::ParametersType  TransformParametersType;

  // We start not so far from  | 2 -2 |
  ParametersType  initialPosition;
  initialPosition[0] =  100;
  initialPosition[1] = -100;

  TransformParametersType parametersScale;
  parametersScale[0] = 1.0;
  parametersScale[1] = 1.0;

  itkOptimizer->MinimizeOn();
  itkOptimizer->GetTransform()->SetScale( parametersScale );
  itkOptimizer->SetGradientMagnitudeTolerance( 1e-6 );
  itkOptimizer->SetMaximumStepLength( 30.0 );
  itkOptimizer->SetMinimumStepLength( 1e-6 );
  itkOptimizer->SetNumberOfIterations( 900 );

  itkOptimizer->SetInitialPosition( initialPosition );
  itkOptimizer->StartOptimization();

  ParametersType finalPosition;
  finalPosition = costFunction->GetParameters();
  std::cout << "Solution        = (";
  std::cout << finalPosition[0] << "," ;
  std::cout << finalPosition[1] << ")" << std::endl;

  //
  // check results to see if it is within range
  //
  bool pass = true;
  double trueParameters[2] = { 2, -2 };
  for( unsigned int j = 0; j < 2; j++ )
    {
    if( vnl_math_abs( finalPosition[j] - trueParameters[j] ) > 0.01 )
      pass = false;
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>/*    Copyright (c) 2010-2018, Delft University of Technology
 *    All rigths reserved
 *
 *    This file is part of the Tudat. Redistribution and use in source and
 *    binary forms, with or without modification, are permitted exclusively
 *    under the terms of the Modified BSD license. You should have received
 *    a copy of the license with this file. If not, please or visit:
 *    http://tudat.tudelft.nl/LICENSE.
 */

#include "Tudat/SimulationSetup/PropagationSetup/propagationOutputSettings.h"

namespace tudat
{

namespace propagators
{

//! Function to get a string representing a 'named identification' of a variable type
std::string getVariableName( const VariableType variableType )
{
    switch ( variableType )
    {
    case independentVariable:
        return "Independent variable ";
    case cpuTimeVariable:
        return "Cummulative computation time variable ";
    case stateVariable:
        return "Integrated state ";
    case dependentVariable:
        return "Dependent variable ";
    default:
        throw std::runtime_error( "Error, variable " +
                                  std::to_string( variableType ) +
                                  "not found when retrieving parameter name " );
    }
}

//! Function to get a string representing a 'named identification' of a variable
std::string getVariableId( const boost::shared_ptr< VariableSettings > variableSettings )
{
    boost::shared_ptr< SingleDependentVariableSaveSettings > singleDependentVariableSaveSettings =
            boost::dynamic_pointer_cast< SingleDependentVariableSaveSettings >( variableSettings );
    if ( singleDependentVariableSaveSettings )
    {
        return getDependentVariableId( singleDependentVariableSaveSettings );
    }
    else
    {
        return getVariableName( variableSettings->variableType_ );
    }
}

//! Function to get a string representing a 'named identification' of a dependent variable type
std::string getDependentVariableName( const PropagationDependentVariables propagationDependentVariables )
{
    std::string variableName = "";
    switch( propagationDependentVariables )
    {
    case mach_number_dependent_variable:
        variableName = "Mach number ";
        break;
    case altitude_dependent_variable:
        variableName = "Altitude ";
        break;
    case airspeed_dependent_variable:
        variableName = "Airspeed ";
        break;
    case local_density_dependent_variable:
        variableName = "Density ";
        break;
    case relative_speed_dependent_variable:
        variableName = "Relative speed ";
        break;
    case relative_position_dependent_variable:
        variableName = "Relative position ";
        break;
    case relative_distance_dependent_variable:
        variableName = "Relative distance ";
        break;
    case relative_velocity_dependent_variable:
        variableName = "Relative velocity ";
        break;
    case radiation_pressure_dependent_variable:
        variableName = "Radiation pressure ";
        break;
    case total_acceleration_norm_dependent_variable:
        variableName = "Total acceleration norm ";
        break;
    case single_acceleration_norm_dependent_variable:
        variableName = "Single acceleration norm of type ";
        break;
    case total_acceleration_dependent_variable:
        variableName = "Total acceleration in inertial frame ";
        break;
    case single_acceleration_dependent_variable:
        variableName = "Single acceleration in inertial frame of type ";
        break;
    case aerodynamic_force_coefficients_dependent_variable:
        variableName = "Aerodynamic force coefficients ";
        break;
    case aerodynamic_moment_coefficients_dependent_variable:
        variableName = "Aerodynamic moment coefficients ";
        break;
    case rotation_matrix_to_body_fixed_frame_variable:
        variableName = "Rotation matrix to body-fixed frame ";
        break;
    case intermediate_aerodynamic_rotation_matrix_variable:
        variableName = "Rotation matrix from ";
        break;
    case relative_body_aerodynamic_orientation_angle_variable:
        variableName = "Body orientation angle ";
        break;
    case body_fixed_airspeed_based_velocity_variable:
        variableName = "Airspeed-based velocity ";
        break;
    case body_fixed_groundspeed_based_velocity_variable:
        variableName = "Groundspeed-based velocity ";
        break;
    case total_aerodynamic_g_load_variable:
        variableName = "Aerodynamic g-load ";
        break;
    case stagnation_point_heat_flux_dependent_variable:
        variableName = "Stagnation-point heat flux ";
        break;
    case local_temperature_dependent_variable:
        variableName = "Local freestream temperature ";
        break;
    case geodetic_latitude_dependent_variable:
        variableName = "Geodetic latitude ";
        break;
    case control_surface_deflection_dependent_variable:
        variableName = "Control Surface Deflection ";
        break;
    case total_mass_rate_dependent_variables:
        variableName = "Body mass rate ";
        break;
    case lvlh_to_inertial_frame_rotation_dependent_variable:
        variableName = "LVLH to inertial frame rotation matrix ";
        break;
    case periapsis_altitude_dependent_variable:
        variableName = "Periapsis altitude ";
        break;
    case single_torque_dependent_variable:
        variableName = "Single torque in body-fixed frame of type ";
        break;
    case total_torque_dependent_variable:
        variableName = "Total torque in body-fixed frame ";
        break;
    case single_torque_norm_dependent_variable:
        variableName = "Single torque norm in body-fixed frame of type ";
        break;
    case total_torque_norm_dependent_variable:
        variableName = "Total torque norm in body-fixed frame ";
        break;
    case keplerian_state_dependent_variable:
        variableName = "Kepler elements  ";
        break;
    case modified_equinocial_state_dependent_variable:
        variableName = "Kepler elements  ";
        break;
    default:
        std::string errorMessage = "Error, dependent variable " +
                std::to_string( propagationDependentVariables ) +
                "not found when retrieving parameter name ";
        throw std::runtime_error( errorMessage );
    }
    return variableName;
}

//! Function to get a string representing a 'named identification' of a dependent variable
std::string getDependentVariableId(
        const boost::shared_ptr< SingleDependentVariableSaveSettings > dependentVariableSettings )
{
    std::string variableId = getDependentVariableName( dependentVariableSettings->dependentVariableType_ );

    if( ( dependentVariableSettings->dependentVariableType_ == single_acceleration_dependent_variable ) ||
            ( dependentVariableSettings->dependentVariableType_ == single_acceleration_norm_dependent_variable ) )
    {
        boost::shared_ptr< SingleAccelerationDependentVariableSaveSettings > accelerationDependentVariableSettings =
                boost::dynamic_pointer_cast< SingleAccelerationDependentVariableSaveSettings >( dependentVariableSettings );
        if( accelerationDependentVariableSettings == NULL )
        {
            throw std::runtime_error( "Error when getting dependent variable ID, input is inconsistent (acceleration type )" );
        }
        else
        {
            variableId += basic_astrodynamics::getAccelerationModelName(
                        accelerationDependentVariableSettings->accelerationModeType_ );
        }
    }
    else if( ( dependentVariableSettings->dependentVariableType_ == single_torque_dependent_variable ) ||
             ( dependentVariableSettings->dependentVariableType_ == single_torque_norm_dependent_variable ) )
    {
        boost::shared_ptr< SingleTorqueDependentVariableSaveSettings > torqueDependentVariableSettings =
                boost::dynamic_pointer_cast< SingleTorqueDependentVariableSaveSettings >( dependentVariableSettings );
        if( torqueDependentVariableSettings == NULL )
        {
            throw std::runtime_error( "Error when getting dependent variable ID, input is inconsistent (torque type )" );
        }
        else
        {
            variableId += basic_astrodynamics::getTorqueModelName(
                        torqueDependentVariableSettings->torqueModeType_ );
        }
    }
    else if( dependentVariableSettings->dependentVariableType_ == intermediate_aerodynamic_rotation_matrix_variable )
    {
        boost::shared_ptr< IntermediateAerodynamicRotationVariableSaveSettings > rotationDependentVariableSettings =
                boost::dynamic_pointer_cast< IntermediateAerodynamicRotationVariableSaveSettings >( dependentVariableSettings );
        if( rotationDependentVariableSettings == NULL )
        {
            throw std::runtime_error( "Error when getting dependent variable ID, input is inconsistent (rotation matrix)" );
        }
        else
        {
            variableId +=
                    reference_frames::getAerodynamicFrameName( rotationDependentVariableSettings->baseFrame_ ) + "to " +
                    reference_frames::getAerodynamicFrameName( rotationDependentVariableSettings->targetFrame_ );
        }
    }

    else if( dependentVariableSettings->dependentVariableType_ == relative_body_aerodynamic_orientation_angle_variable )
    {
        boost::shared_ptr< BodyAerodynamicAngleVariableSaveSettings > angleDependentVariableSettings =
                boost::dynamic_pointer_cast< BodyAerodynamicAngleVariableSaveSettings >( dependentVariableSettings );
        if( angleDependentVariableSettings == NULL )
        {
            throw std::runtime_error( "Error when getting dependent variable ID, input is inconsistent (angle)" );
        }
        else
        {
            variableId +=
                    reference_frames::getAerodynamicAngleName( angleDependentVariableSettings->angle_ );
        }
    }

    if( ( dependentVariableSettings->dependentVariableType_ == single_acceleration_dependent_variable ) ||
            ( dependentVariableSettings->dependentVariableType_ == single_acceleration_norm_dependent_variable )  )
    {
        variableId += ", acting on " + dependentVariableSettings->associatedBody_;
        if( dependentVariableSettings->secondaryBody_ != dependentVariableSettings->associatedBody_ )
        {
            variableId += ", exerted by " + dependentVariableSettings->secondaryBody_;
        }
    }
    else
    {
        variableId += "of " + dependentVariableSettings->associatedBody_;
        if( dependentVariableSettings->secondaryBody_ != "" )
        {
            variableId += " w.r.t. " + dependentVariableSettings->secondaryBody_;
        }

    }
    return variableId;
}

}

}
<commit_msg>Corrected error that can occur when saving MEE through JSON interface<commit_after>/*    Copyright (c) 2010-2018, Delft University of Technology
 *    All rigths reserved
 *
 *    This file is part of the Tudat. Redistribution and use in source and
 *    binary forms, with or without modification, are permitted exclusively
 *    under the terms of the Modified BSD license. You should have received
 *    a copy of the license with this file. If not, please or visit:
 *    http://tudat.tudelft.nl/LICENSE.
 */

#include "Tudat/SimulationSetup/PropagationSetup/propagationOutputSettings.h"

namespace tudat
{

namespace propagators
{

//! Function to get a string representing a 'named identification' of a variable type
std::string getVariableName( const VariableType variableType )
{
    switch ( variableType )
    {
    case independentVariable:
        return "Independent variable ";
    case cpuTimeVariable:
        return "Cummulative computation time variable ";
    case stateVariable:
        return "Integrated state ";
    case dependentVariable:
        return "Dependent variable ";
    default:
        throw std::runtime_error( "Error, variable " +
                                  std::to_string( variableType ) +
                                  "not found when retrieving parameter name " );
    }
}

//! Function to get a string representing a 'named identification' of a variable
std::string getVariableId( const boost::shared_ptr< VariableSettings > variableSettings )
{
    boost::shared_ptr< SingleDependentVariableSaveSettings > singleDependentVariableSaveSettings =
            boost::dynamic_pointer_cast< SingleDependentVariableSaveSettings >( variableSettings );
    if ( singleDependentVariableSaveSettings )
    {
        return getDependentVariableId( singleDependentVariableSaveSettings );
    }
    else
    {
        return getVariableName( variableSettings->variableType_ );
    }
}

//! Function to get a string representing a 'named identification' of a dependent variable type
std::string getDependentVariableName( const PropagationDependentVariables propagationDependentVariables )
{
    std::string variableName = "";
    switch( propagationDependentVariables )
    {
    case mach_number_dependent_variable:
        variableName = "Mach number ";
        break;
    case altitude_dependent_variable:
        variableName = "Altitude ";
        break;
    case airspeed_dependent_variable:
        variableName = "Airspeed ";
        break;
    case local_density_dependent_variable:
        variableName = "Density ";
        break;
    case relative_speed_dependent_variable:
        variableName = "Relative speed ";
        break;
    case relative_position_dependent_variable:
        variableName = "Relative position ";
        break;
    case relative_distance_dependent_variable:
        variableName = "Relative distance ";
        break;
    case relative_velocity_dependent_variable:
        variableName = "Relative velocity ";
        break;
    case radiation_pressure_dependent_variable:
        variableName = "Radiation pressure ";
        break;
    case total_acceleration_norm_dependent_variable:
        variableName = "Total acceleration norm ";
        break;
    case single_acceleration_norm_dependent_variable:
        variableName = "Single acceleration norm of type ";
        break;
    case total_acceleration_dependent_variable:
        variableName = "Total acceleration in inertial frame ";
        break;
    case single_acceleration_dependent_variable:
        variableName = "Single acceleration in inertial frame of type ";
        break;
    case aerodynamic_force_coefficients_dependent_variable:
        variableName = "Aerodynamic force coefficients ";
        break;
    case aerodynamic_moment_coefficients_dependent_variable:
        variableName = "Aerodynamic moment coefficients ";
        break;
    case rotation_matrix_to_body_fixed_frame_variable:
        variableName = "Rotation matrix to body-fixed frame ";
        break;
    case intermediate_aerodynamic_rotation_matrix_variable:
        variableName = "Rotation matrix from ";
        break;
    case relative_body_aerodynamic_orientation_angle_variable:
        variableName = "Body orientation angle ";
        break;
    case body_fixed_airspeed_based_velocity_variable:
        variableName = "Airspeed-based velocity ";
        break;
    case body_fixed_groundspeed_based_velocity_variable:
        variableName = "Groundspeed-based velocity ";
        break;
    case total_aerodynamic_g_load_variable:
        variableName = "Aerodynamic g-load ";
        break;
    case stagnation_point_heat_flux_dependent_variable:
        variableName = "Stagnation-point heat flux ";
        break;
    case local_temperature_dependent_variable:
        variableName = "Local freestream temperature ";
        break;
    case geodetic_latitude_dependent_variable:
        variableName = "Geodetic latitude ";
        break;
    case control_surface_deflection_dependent_variable:
        variableName = "Control Surface Deflection ";
        break;
    case total_mass_rate_dependent_variables:
        variableName = "Body mass rate ";
        break;
    case lvlh_to_inertial_frame_rotation_dependent_variable:
        variableName = "LVLH to inertial frame rotation matrix ";
        break;
    case periapsis_altitude_dependent_variable:
        variableName = "Periapsis altitude ";
        break;
    case single_torque_dependent_variable:
        variableName = "Single torque in body-fixed frame of type ";
        break;
    case total_torque_dependent_variable:
        variableName = "Total torque in body-fixed frame ";
        break;
    case single_torque_norm_dependent_variable:
        variableName = "Single torque norm in body-fixed frame of type ";
        break;
    case total_torque_norm_dependent_variable:
        variableName = "Total torque norm in body-fixed frame ";
        break;
    case keplerian_state_dependent_variable:
        variableName = "Kepler elements ";
        break;
    case modified_equinocial_state_dependent_variable:
        variableName = "Modified equinoctial elements ";
        break;
    default:
        std::string errorMessage = "Error, dependent variable " +
                std::to_string( propagationDependentVariables ) +
                "not found when retrieving parameter name ";
        throw std::runtime_error( errorMessage );
    }
    return variableName;
}

//! Function to get a string representing a 'named identification' of a dependent variable
std::string getDependentVariableId(
        const boost::shared_ptr< SingleDependentVariableSaveSettings > dependentVariableSettings )
{
    std::string variableId = getDependentVariableName( dependentVariableSettings->dependentVariableType_ );

    if( ( dependentVariableSettings->dependentVariableType_ == single_acceleration_dependent_variable ) ||
            ( dependentVariableSettings->dependentVariableType_ == single_acceleration_norm_dependent_variable ) )
    {
        boost::shared_ptr< SingleAccelerationDependentVariableSaveSettings > accelerationDependentVariableSettings =
                boost::dynamic_pointer_cast< SingleAccelerationDependentVariableSaveSettings >( dependentVariableSettings );
        if( accelerationDependentVariableSettings == NULL )
        {
            throw std::runtime_error( "Error when getting dependent variable ID, input is inconsistent (acceleration type )" );
        }
        else
        {
            variableId += basic_astrodynamics::getAccelerationModelName(
                        accelerationDependentVariableSettings->accelerationModeType_ );
        }
    }
    else if( ( dependentVariableSettings->dependentVariableType_ == single_torque_dependent_variable ) ||
             ( dependentVariableSettings->dependentVariableType_ == single_torque_norm_dependent_variable ) )
    {
        boost::shared_ptr< SingleTorqueDependentVariableSaveSettings > torqueDependentVariableSettings =
                boost::dynamic_pointer_cast< SingleTorqueDependentVariableSaveSettings >( dependentVariableSettings );
        if( torqueDependentVariableSettings == NULL )
        {
            throw std::runtime_error( "Error when getting dependent variable ID, input is inconsistent (torque type )" );
        }
        else
        {
            variableId += basic_astrodynamics::getTorqueModelName(
                        torqueDependentVariableSettings->torqueModeType_ );
        }
    }
    else if( dependentVariableSettings->dependentVariableType_ == intermediate_aerodynamic_rotation_matrix_variable )
    {
        boost::shared_ptr< IntermediateAerodynamicRotationVariableSaveSettings > rotationDependentVariableSettings =
                boost::dynamic_pointer_cast< IntermediateAerodynamicRotationVariableSaveSettings >( dependentVariableSettings );
        if( rotationDependentVariableSettings == NULL )
        {
            throw std::runtime_error( "Error when getting dependent variable ID, input is inconsistent (rotation matrix)" );
        }
        else
        {
            variableId +=
                    reference_frames::getAerodynamicFrameName( rotationDependentVariableSettings->baseFrame_ ) + "to " +
                    reference_frames::getAerodynamicFrameName( rotationDependentVariableSettings->targetFrame_ );
        }
    }

    else if( dependentVariableSettings->dependentVariableType_ == relative_body_aerodynamic_orientation_angle_variable )
    {
        boost::shared_ptr< BodyAerodynamicAngleVariableSaveSettings > angleDependentVariableSettings =
                boost::dynamic_pointer_cast< BodyAerodynamicAngleVariableSaveSettings >( dependentVariableSettings );
        if( angleDependentVariableSettings == NULL )
        {
            throw std::runtime_error( "Error when getting dependent variable ID, input is inconsistent (angle)" );
        }
        else
        {
            variableId +=
                    reference_frames::getAerodynamicAngleName( angleDependentVariableSettings->angle_ );
        }
    }

    if( ( dependentVariableSettings->dependentVariableType_ == single_acceleration_dependent_variable ) ||
            ( dependentVariableSettings->dependentVariableType_ == single_acceleration_norm_dependent_variable )  )
    {
        variableId += ", acting on " + dependentVariableSettings->associatedBody_;
        if( dependentVariableSettings->secondaryBody_ != dependentVariableSettings->associatedBody_ )
        {
            variableId += ", exerted by " + dependentVariableSettings->secondaryBody_;
        }
    }
    else
    {
        variableId += "of " + dependentVariableSettings->associatedBody_;
        if( dependentVariableSettings->secondaryBody_ != "" )
        {
            variableId += " w.r.t. " + dependentVariableSettings->secondaryBody_;
        }

    }
    return variableId;
}

}

}
<|endoftext|>


<commit_before>#include "codechecker.h"
#include "process.h"

CodeChecker::~CodeChecker()
{
    cancel();
}

void CodeChecker::connectSignals()
{
    connect(&p, &MznProcess::started, this, &CodeChecker::onStarted);
    connect(&p, &MznProcess::outputStdOut, this, &CodeChecker::onLine);
    connect(&p, &MznProcess::outputStdError, this, &CodeChecker::onLine);
    connect(&p, &MznProcess::finished, this, &CodeChecker::onFinished);
}

void CodeChecker::start(const QString& modelContents, SolverConfiguration& sc, const QString& wd)
{
    cancel();
    connectSignals();
    inRelevantError = false;
    curError = MiniZincError();
    mznErrors.clear();
    SolverConfiguration checkSc(sc.solverDefinition);
    checkSc.additionalData = sc.additionalData;
    checkSc.extraOptions = sc.extraOptions;
    QStringList args;
    args << "--model-check-only" << "-";
    input = modelContents;
    p.start(checkSc, args, wd);
}

void CodeChecker::cancel()
{
    p.disconnect();
    p.terminate();
}

void CodeChecker::onStarted()
{
    p.writeStdIn(input);
    p.closeStdIn();
}

void CodeChecker::onLine(const QString& l)
{
    QJsonParseError error;
    auto json = QJsonDocument::fromJson(l.toUtf8(), &error);
    if (json.isNull()) {
        return;
    }
    auto msg = json.object();
    if (msg["type"] != "error" && msg["type"] != "warning") {
        return;
    }
    if (!msg["location"].isObject()) {
        return;
    }
    auto loc = msg["location"].toObject();
    MiniZincError e;
    e.isWarning = msg["type"] == "warning";
    e.filename = loc["filename"].toString();
    e.first_line = loc["firstLine"].toInt();
    e.first_col = loc["firstColumn"].toInt();
    e.last_line = loc["lastLine"].toInt();
    e.last_col = loc["lastColumn"].toInt();
    e.msg = msg["message"].toString();
    mznErrors.push_back(e);
}

void CodeChecker::onFinished()
{
    emit finished(mznErrors);
}
<commit_msg>Ignore errors in other files during background code checking<commit_after>#include "codechecker.h"
#include "process.h"

CodeChecker::~CodeChecker()
{
    cancel();
}

void CodeChecker::connectSignals()
{
    connect(&p, &MznProcess::started, this, &CodeChecker::onStarted);
    connect(&p, &MznProcess::outputStdOut, this, &CodeChecker::onLine);
    connect(&p, &MznProcess::outputStdError, this, &CodeChecker::onLine);
    connect(&p, &MznProcess::finished, this, &CodeChecker::onFinished);
}

void CodeChecker::start(const QString& modelContents, SolverConfiguration& sc, const QString& wd)
{
    cancel();
    connectSignals();
    inRelevantError = false;
    curError = MiniZincError();
    mznErrors.clear();
    SolverConfiguration checkSc(sc.solverDefinition);
    checkSc.additionalData = sc.additionalData;
    checkSc.extraOptions = sc.extraOptions;
    QStringList args;
    args << "--model-check-only" << "-";
    input = modelContents;
    p.start(checkSc, args, wd);
}

void CodeChecker::cancel()
{
    p.disconnect();
    p.terminate();
}

void CodeChecker::onStarted()
{
    p.writeStdIn(input);
    p.closeStdIn();
}

void CodeChecker::onLine(const QString& l)
{
    QJsonParseError error;
    auto json = QJsonDocument::fromJson(l.toUtf8(), &error);
    if (json.isNull()) {
        return;
    }
    auto msg = json.object();
    if (msg["type"] != "error" && msg["type"] != "warning") {
        return;
    }
    if (!msg["location"].isObject()) {
        return;
    }
    auto loc = msg["location"].toObject();
    MiniZincError e;
    e.isWarning = msg["type"] == "warning";
    e.filename = loc["filename"].toString();
    e.first_line = loc["firstLine"].toInt();
    e.first_col = loc["firstColumn"].toInt();
    e.last_line = loc["lastLine"].toInt();
    e.last_col = loc["lastColumn"].toInt();
    e.msg = msg["message"].toString();
    if (e.filename == "stdin") {
        // Ignore errors that aren't from this file
        mznErrors.push_back(e);
    }
}

void CodeChecker::onFinished()
{
    emit finished(mznErrors);
}
<|endoftext|>


<commit_before>#include "Menus.hh"

//Escape_Menu Constructor
Escape_Menu::Escape_Menu()
{
	SelectedItemId = 1; //initially select the first one (aka "Yes")
	ValidatedItemId = 0; //No validated id
}
//Escape_Menu Destructor
Escape_Menu::~Escape_Menu()
{
}
//Blit the good menu surface in function of what the user wants to select with the keyboard
void Escape_Menu::Show_Menu(VideoSurface& Screen)
{
	if (SelectedItemId == 1) //we want to show Yes selected
	{
		Screen.blit(RGBSurface("data/LeaveMenu_YesSelected.png"), Point::Point(SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT/2 - 50) );
	}
	else if (SelectedItemId == 2) //we want to show No selected
	{
		Screen.blit(RGBSurface("data/LeaveMenu_NoSelected.png"), Point::Point(SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT/2 - 50) );
	}
}
//Managed validation on one item
bool Escape_Menu::Manage_Validation()
{
	if (ValidatedItemId == 0) //Do nothing but dont leave
	{ return false; }
	else if (ValidatedItemId == 1) //We have yes validated, the user wants to quit
	{
		// update _quitRequested to leave the mainloop
		return true;
	}
	else if (ValidatedItemId == 2) //We have no validated, the user wants to go back to the game
	{
		SelectedItemId = 1; //Reinit select item id
		ValidatedItemId = 0; //we leave the menu so no item is now validated
		GLOBAL_GAME_STATE = 3; //go back to normal game state
		return false;
	}
}
<commit_msg>P0 2D v0.01: removed the warning issue<commit_after>#include "Menus.hh"

//Escape_Menu Constructor
Escape_Menu::Escape_Menu()
{
	SelectedItemId = 1; //initially select the first one (aka "Yes")
	ValidatedItemId = 0; //No validated id
}
//Escape_Menu Destructor
Escape_Menu::~Escape_Menu()
{
}
//Blit the good menu surface in function of what the user wants to select with the keyboard
void Escape_Menu::Show_Menu(VideoSurface& Screen)
{
	if (SelectedItemId == 1) //we want to show Yes selected
	{
		Screen.blit(RGBSurface("data/LeaveMenu_YesSelected.png"), Point::Point(SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT/2 - 50) );
	}
	else if (SelectedItemId == 2) //we want to show No selected
	{
		Screen.blit(RGBSurface("data/LeaveMenu_NoSelected.png"), Point::Point(SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT/2 - 50) );
	}
}
//Managed validation on one item
bool Escape_Menu::Manage_Validation()
{
	if (ValidatedItemId == 1) //We have yes validated, the user wants to quit
	{
		// update _quitRequested to leave the mainloop
		return true;
	}
	else if (ValidatedItemId == 2) //We have no validated, the user wants to go back to the game
	{
		SelectedItemId = 1; //Reinit select item id
		ValidatedItemId = 0; //we leave the menu so no item is now validated
		GLOBAL_GAME_STATE = 3; //go back to normal game state
		return false;
	}
	else //ValidatedItemId == 0; do nothing but dont leave
	{
		return false;
	}

}
<|endoftext|>