<commit_before>/*
 *
 * ERC20LikeAccount
 *
 * Created by El Khalil Bellakrid on 26/08/2018.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 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 "ERC20LikeAccount.h"
#include <math/BigInt.h>
#include <api_impl/BigIntImpl.hpp>
#include <api/Amount.hpp>
#include <api/OperationType.hpp>
#include <bytes/RLP/RLPStringEncoder.h>
#include <utils/hex.h>
#include <math/BigInt.h>
#include <api/Address.hpp>
#include "erc20Tokens.h"
#include <wallet/common/OperationQuery.h>
#include <soci.h>
#include <database/soci-date.h>
#include <database/query/ConditionQueryFilter.h>
using namespace soci;

namespace ledger {
    namespace core {
        ERC20LikeAccount::ERC20LikeAccount(const std::string &accountUid,
                                           const api::ERC20Token &erc20Token,
                                           const std::string &accountAddress,
                                           const api::Currency &parentCurrency,
                                           const std::shared_ptr<EthereumLikeAccount> &parentAccount):
                                            _accountUid(accountUid),
                                            _token(erc20Token),
                                            _accountAddress(accountAddress),
                                            _parentCurrency(parentCurrency),
                                            _account(parentAccount)

        {}

        api::ERC20Token ERC20LikeAccount::getToken() {
            return _token;
        }

        std::string ERC20LikeAccount::getAddress() {

            return _accountAddress;
        }

        std::shared_ptr<api::BigInt> ERC20LikeAccount::getBalance() {
            auto result = BigInt::ZERO;
            auto operations = getOperations();
            for (auto &op : operations) {
                if (op->getOperationType() == api::OperationType::RECEIVE) {
                    result = result + BigInt(op->getValue()->toString(10));
                } else if (op->getOperationType() == api::OperationType::SEND){
                    result = result - BigInt(op->getValue()->toString(10));
                }

            }
            return std::make_shared<api::BigIntImpl>(result);
        }

        std::vector<std::shared_ptr<api::ERC20LikeOperation>>
        ERC20LikeAccount::getOperations() {
            auto localAccount = _account.lock();
            soci::session sql (localAccount->getWallet()->getDatabase()->getPool());
            soci::rowset<soci::row> rows = (sql.prepare << "SELECT op.uid, op.ethereum_operation_uid, op.account_uid,"
                    " op.type, op.hash, op.nonce, op.value,"
                    " op.date, op.sender, op.receiver, op.input_data,"
                    " op.gas_price, op.gas_limit, op.gas_used, op.status"
                    " FROM erc20_operations AS op"
                    " WHERE op.account_uid = :account_uid", soci::use(_accountUid));
            std::vector<std::shared_ptr<api::ERC20LikeOperation>> result;
            for (auto& row : rows) {
                auto op = std::make_shared<ERC20LikeOperation>();
                op->setOperationUid(row.get<std::string>(0));
                op->setETHOperationUid(row.get<std::string>(1));
                op->setOperationType(api::from_string<api::OperationType>(row.get<std::string>(3)));
                op->setHash(row.get<std::string>(4));
                op->setNonce(BigInt::fromHex(row.get<std::string>(5)));
                op->setValue(BigInt::fromHex(row.get<std::string>(6)));
                op->setTime(DateUtils::fromJSON(row.get<std::string>(7)));
                op->setSender(row.get<std::string>(8));
                op->setReceiver(row.get<std::string>(9));
                if (row.get_indicator(10) != soci::i_null) {
                    auto data = row.get<std::string>(10);
                    auto dataArray = hex::toByteArray(data);
                    op->setData(dataArray);
                }

                op->setGasPrice(BigInt::fromHex(row.get<std::string>(11)));
                op->setGasLimit(BigInt::fromHex(row.get<std::string>(12)));
                op->setUsedGas(BigInt::fromHex(row.get<std::string>(13)));
                auto status = row.get<int32_t>(14);
                op->setStatus(status);
                result.emplace_back(op);
            }
            return result;
        }

        std::vector<uint8_t> ERC20LikeAccount::getTransferToAddressData(const std::shared_ptr<api::BigInt> &amount,
                                                                        const std::string & address) {
            if (! api::Address::isValid(address, _parentCurrency)) {
                throw Exception(api::ErrorCode::INVALID_EIP55_FORMAT, "Invalid address : Invalid EIP55 format");
            }
            auto balance = getBalance();
            if ( amount->compare(balance) > 0) {
                throw Exception(api::ErrorCode::NOT_ENOUGH_FUNDS, "Cannot gather enough funds.");
            }

            BytesWriter writer;
            writer.writeByteArray(hex::toByteArray(erc20Tokens::ERC20MethodsID.at("transfer")));

            auto toUint256Format = [=](const std::string &hexInput) -> std::string {
                if (hexInput.size() > 64) {
                    throw Exception(api::ErrorCode::INVALID_ARGUMENT, "Invalid argument passed to toUint256Format");
                }
                auto hexOutput = hexInput;
                while (hexOutput.size() != 64) {
                    hexOutput = "00" + hexOutput;
                }

                return hexOutput;
            };

            writer.writeByteArray(hex::toByteArray(toUint256Format(address.substr(2,address.size() - 2))));

            BigInt bigAmount(amount->toString(10));
            writer.writeByteArray(hex::toByteArray(toUint256Format(bigAmount.toHexString())));

            return writer.toByteArray();
        }

        void ERC20LikeAccount::putOperation(soci::session &sql, const std::shared_ptr<ERC20LikeOperation> &operation, bool newOperation) {
            if (newOperation) {
                auto erc20OpUid = operation->getOperationUid();
                auto ethOpUid = operation->getETHOperationUid();
                auto hash = operation->getHash();
                auto receiver = operation->getReceiver();
                auto sender = operation->getSender();
                auto data = hex::toString(operation->getData());
                auto status = operation->getStatus();
                sql << "INSERT INTO erc20_operations VALUES("
                        ":uid, :eth_op_uid, :accout_uid, :op_type, :hash, :nonce, :value, :date, :sender,"
                        ":receiver, :data, :gas_price, :gas_limit, :gas_used, :status"
                        ")"
                        , use(erc20OpUid), use(ethOpUid)
                        , use(_accountUid), use(api::to_string(operation->getOperationType())), use(hash)
                        , use(operation->getNonce()->toString(16)), use(operation->getValue()->toString(16)), use(operation->getTime())
                        , use(sender), use(receiver), use(data)
                        , use(operation->getGasPrice()->toString(16)), use(operation->getGasLimit()->toString(16)), use(operation->getUsedGas()->toString(16))
                        , use(status);
            }
        }

        std::shared_ptr<api::OperationQuery> ERC20LikeAccount::queryOperations() {
            auto localAccount = _account.lock();
            auto accountUid = localAccount->getAccountUid();
            auto filter = std::make_shared<ConditionQueryFilter<std::string>>("uid", "IS NOT NULL", "", "e");
            filter->op_and(std::make_shared<ConditionQueryFilter<std::string>>("account_uid", "=", accountUid, "o"));
            auto query = std::make_shared<ERC20OperationQuery>(
                    filter,
                    localAccount->getWallet()->getDatabase(),
                    localAccount->getWallet()->getContext(),
                    localAccount->getWallet()->getMainExecutionContext()
            );
            query->registerAccount(localAccount);
            return query;
        }

    }
}<commit_msg>Fix filter on erc20 operations<commit_after>/*
 *
 * ERC20LikeAccount
 *
 * Created by El Khalil Bellakrid on 26/08/2018.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 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 "ERC20LikeAccount.h"
#include <math/BigInt.h>
#include <api_impl/BigIntImpl.hpp>
#include <api/Amount.hpp>
#include <api/OperationType.hpp>
#include <bytes/RLP/RLPStringEncoder.h>
#include <utils/hex.h>
#include <math/BigInt.h>
#include <api/Address.hpp>
#include "erc20Tokens.h"
#include <wallet/common/OperationQuery.h>
#include <soci.h>
#include <database/soci-date.h>
#include <database/query/ConditionQueryFilter.h>
using namespace soci;

namespace ledger {
    namespace core {
        ERC20LikeAccount::ERC20LikeAccount(const std::string &accountUid,
                                           const api::ERC20Token &erc20Token,
                                           const std::string &accountAddress,
                                           const api::Currency &parentCurrency,
                                           const std::shared_ptr<EthereumLikeAccount> &parentAccount):
                                            _accountUid(accountUid),
                                            _token(erc20Token),
                                            _accountAddress(accountAddress),
                                            _parentCurrency(parentCurrency),
                                            _account(parentAccount)

        {}

        api::ERC20Token ERC20LikeAccount::getToken() {
            return _token;
        }

        std::string ERC20LikeAccount::getAddress() {

            return _accountAddress;
        }

        std::shared_ptr<api::BigInt> ERC20LikeAccount::getBalance() {
            auto result = BigInt::ZERO;
            auto operations = getOperations();
            for (auto &op : operations) {
                if (op->getOperationType() == api::OperationType::RECEIVE) {
                    result = result + BigInt(op->getValue()->toString(10));
                } else if (op->getOperationType() == api::OperationType::SEND){
                    result = result - BigInt(op->getValue()->toString(10));
                }

            }
            return std::make_shared<api::BigIntImpl>(result);
        }

        std::vector<std::shared_ptr<api::ERC20LikeOperation>>
        ERC20LikeAccount::getOperations() {
            auto localAccount = _account.lock();
            soci::session sql (localAccount->getWallet()->getDatabase()->getPool());
            soci::rowset<soci::row> rows = (sql.prepare << "SELECT op.uid, op.ethereum_operation_uid, op.account_uid,"
                    " op.type, op.hash, op.nonce, op.value,"
                    " op.date, op.sender, op.receiver, op.input_data,"
                    " op.gas_price, op.gas_limit, op.gas_used, op.status"
                    " FROM erc20_operations AS op"
                    " WHERE op.account_uid = :account_uid", soci::use(_accountUid));
            std::vector<std::shared_ptr<api::ERC20LikeOperation>> result;
            for (auto& row : rows) {
                auto op = std::make_shared<ERC20LikeOperation>();
                op->setOperationUid(row.get<std::string>(0));
                op->setETHOperationUid(row.get<std::string>(1));
                op->setOperationType(api::from_string<api::OperationType>(row.get<std::string>(3)));
                op->setHash(row.get<std::string>(4));
                op->setNonce(BigInt::fromHex(row.get<std::string>(5)));
                op->setValue(BigInt::fromHex(row.get<std::string>(6)));
                op->setTime(DateUtils::fromJSON(row.get<std::string>(7)));
                op->setSender(row.get<std::string>(8));
                op->setReceiver(row.get<std::string>(9));
                if (row.get_indicator(10) != soci::i_null) {
                    auto data = row.get<std::string>(10);
                    auto dataArray = hex::toByteArray(data);
                    op->setData(dataArray);
                }

                op->setGasPrice(BigInt::fromHex(row.get<std::string>(11)));
                op->setGasLimit(BigInt::fromHex(row.get<std::string>(12)));
                op->setUsedGas(BigInt::fromHex(row.get<std::string>(13)));
                auto status = row.get<int32_t>(14);
                op->setStatus(status);
                result.emplace_back(op);
            }
            return result;
        }

        std::vector<uint8_t> ERC20LikeAccount::getTransferToAddressData(const std::shared_ptr<api::BigInt> &amount,
                                                                        const std::string & address) {
            if (! api::Address::isValid(address, _parentCurrency)) {
                throw Exception(api::ErrorCode::INVALID_EIP55_FORMAT, "Invalid address : Invalid EIP55 format");
            }
            auto balance = getBalance();
            if ( amount->compare(balance) > 0) {
                throw Exception(api::ErrorCode::NOT_ENOUGH_FUNDS, "Cannot gather enough funds.");
            }

            BytesWriter writer;
            writer.writeByteArray(hex::toByteArray(erc20Tokens::ERC20MethodsID.at("transfer")));

            auto toUint256Format = [=](const std::string &hexInput) -> std::string {
                if (hexInput.size() > 64) {
                    throw Exception(api::ErrorCode::INVALID_ARGUMENT, "Invalid argument passed to toUint256Format");
                }
                auto hexOutput = hexInput;
                while (hexOutput.size() != 64) {
                    hexOutput = "00" + hexOutput;
                }

                return hexOutput;
            };

            writer.writeByteArray(hex::toByteArray(toUint256Format(address.substr(2,address.size() - 2))));

            BigInt bigAmount(amount->toString(10));
            writer.writeByteArray(hex::toByteArray(toUint256Format(bigAmount.toHexString())));

            return writer.toByteArray();
        }

        void ERC20LikeAccount::putOperation(soci::session &sql, const std::shared_ptr<ERC20LikeOperation> &operation, bool newOperation) {
            if (newOperation) {
                auto erc20OpUid = operation->getOperationUid();
                auto ethOpUid = operation->getETHOperationUid();
                auto hash = operation->getHash();
                auto receiver = operation->getReceiver();
                auto sender = operation->getSender();
                auto data = hex::toString(operation->getData());
                auto status = operation->getStatus();
                sql << "INSERT INTO erc20_operations VALUES("
                        ":uid, :eth_op_uid, :accout_uid, :op_type, :hash, :nonce, :value, :date, :sender,"
                        ":receiver, :data, :gas_price, :gas_limit, :gas_used, :status"
                        ")"
                        , use(erc20OpUid), use(ethOpUid)
                        , use(_accountUid), use(api::to_string(operation->getOperationType())), use(hash)
                        , use(operation->getNonce()->toString(16)), use(operation->getValue()->toString(16)), use(operation->getTime())
                        , use(sender), use(receiver), use(data)
                        , use(operation->getGasPrice()->toString(16)), use(operation->getGasLimit()->toString(16)), use(operation->getUsedGas()->toString(16))
                        , use(status);
            }
        }

        std::shared_ptr<api::OperationQuery> ERC20LikeAccount::queryOperations() {
            auto localAccount = _account.lock();
            auto accountUid = localAccount->getAccountUid();
            auto filter = std::make_shared<ConditionQueryFilter<std::string>>("account_uid", "=", _accountUid, "e");
            auto query = std::make_shared<ERC20OperationQuery>(
                    filter,
                    localAccount->getWallet()->getDatabase(),
                    localAccount->getWallet()->getContext(),
                    localAccount->getWallet()->getMainExecutionContext()
            );
            query->registerAccount(localAccount);
            return query;
        }

    }
}<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// File ExtractCriticalLayer.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// 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.
//
// Description: Extract location of critical layer from streak file
//
///////////////////////////////////////////////////////////////////////////////

#include <cstdio>
#include <cstdlib>

#include <MultiRegions/ExpList.h>
#include <MultiRegions/ExpList2D.h>

void Computestreakpositions(MultiRegions::ExpListSharedPtr &streak,
                            Array<OneD, NekDouble> &xc,
                            Array<OneD, NekDouble> &yc,
                            NekDouble cr);

int main(int argc, char *argv[])
{
    int i,j;
    NekDouble cr = 0;

    if(argc !=3)
    {
        fprintf(stderr,"Usage: ./ExtractCriticalLayer  meshfile fieldfile  \n");
        exit(1);
    }

    //------------------------------------------------------------
    // Create Session file.
    LibUtilities::SessionReaderSharedPtr vSession
        = LibUtilities::SessionReader::CreateInstance(argc, argv);
    //-----------------------------------------------------------

    //-------------------------------------------------------------
    // Read in mesh from input file
    string meshfile(argv[argc-2]);
    SpatialDomains::MeshGraphSharedPtr graphShPt = SpatialDomains::MeshGraph::Read(meshfile);
    //------------------------------------------------------------

    //-------------------------------------------------------------
    // Define Streak Expansion
    MultiRegions::ExpListSharedPtr streak;

    streak = MemoryManager<MultiRegions::ExpList2D>
        ::AllocateSharedPtr(vSession,graphShPt);

    //---------------------------------------------------------------

    //----------------------------------------------
    // Import field file.
    string fieldfile(argv[argc-1]);
    vector<SpatialDomains::FieldDefinitionsSharedPtr> fielddef;
    vector<vector<NekDouble> > fielddata;
    graphShPt->Import(fieldfile,fielddef,fielddata);
    //----------------------------------------------

    //----------------------------------------------
    // Copy data from field file
    string  streak_field("w");
    for(unsigned int i = 0; i < fielddata.size(); ++i)
    {
        streak->ExtractDataToCoeffs(fielddef [i],
                                    fielddata[i],
                                    streak_field);
    }
    //----------------------------------------------

    int npts;
    vSession->LoadParameter("NoCriticalLayerPts",npts,30);
    Array<OneD, NekDouble> x_c(npts);
    Array<OneD, NekDouble> y_c(npts);
    NekDouble xc, yc;

    Computestreakpositions(streak,x_c, y_c,cr);

    cout << "# x_c y_c" << endl;
    for(i = 0; i < npts; ++i)
    {
        fprintf(stdout,"%12.10lf %12.10lf \n",x_c[i],y_c[i]);
        //cout << x_c[i] << " " << y_c[i] << endl;
    }
}

void Computestreakpositions(MultiRegions::ExpListSharedPtr &streak,
                            Array<OneD, NekDouble> &xc,
                            Array<OneD, NekDouble> &yc,
                            NekDouble cr)
{
    int i;
    int npts = xc.num_elements();

    int nq = streak->GetTotPoints();
    Array<OneD, NekDouble> derstreak(nq);
    Array<OneD, NekDouble> x(nq);
    Array<OneD, NekDouble> y(nq);
    streak->GetCoords(x,y);

    streak->BwdTrans(streak->GetCoeffs(),streak->UpdatePhys());
    streak->PhysDeriv(MultiRegions::eY, streak->GetPhys(), derstreak);

    // set intiial xc to be equispaced over mesh and yc to be zero
    NekDouble x_max = Vmath::Vmax(nq,x,1);
    NekDouble x_min = Vmath::Vmin(nq,x,1);

    for(i = 0; i < npts; ++i)
    {
        xc[i]  = x_min + (x_max - x_min)*i/((NekDouble)(npts-1));
        yc[i] = 0.0;
    }

    int elmtid, offset,cnt;
    NekDouble U,dU;
    NekDouble F;
    NekDouble ConvTol  = 1e-9;
    NekDouble CoordTol = 1e-5;
    int maxiter = 100;
    Array<OneD, NekDouble> coord(2);

    // Do Newton iteration on y direction
    cerr << "[";
    for(int e=0; e<npts; e++)
    {
        coord[0] = xc[e];
        coord[1] = yc[e];

        if(!(e%10))
        {
            cerr << ".";
        }

        F = 1000;
        cnt = 0;
        while((abs(F)> ConvTol)&&(cnt < maxiter))
        {
            elmtid = streak->GetExpIndex(coord,CoordTol);
            offset = streak->GetPhys_Offset(elmtid);

            U  = streak->GetExp(elmtid)->PhysEvaluate(coord, streak->GetPhys() + offset);
            dU = streak->GetExp(elmtid)->PhysEvaluate(coord, derstreak + offset);

            coord[1] = coord[1] - (U-cr)/dU;

            F = U-cr;
            cnt++;
        }
        ASSERTL0(cnt < maxiter, "Failed to converge Newton iteration");

        yc[e] = coord[1];
    }
    cerr << "]" << endl;
}
<commit_msg>Update version<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// File ExtractCriticalLayer.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// 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.
//
// Description: Extract location of critical layer from streak file
//
///////////////////////////////////////////////////////////////////////////////

#include <cstdio>
#include <cstdlib>

#include <MultiRegions/ExpList.h>
#include <MultiRegions/ExpList2D.h>

void Computestreakpositions(MultiRegions::ExpListSharedPtr &streak,
                            Array<OneD, NekDouble> &xc,
                            Array<OneD, NekDouble> &yc,
                            NekDouble cr);

int main(int argc, char *argv[])
{
    int i,j;
    NekDouble cr = 0;

    if(argc !=3)
    {
        fprintf(stderr,"Usage: ./ExtractCriticalLayer  meshfile fieldfile  \n");
        exit(1);
    }

    //------------------------------------------------------------
    // Create Session file.
    LibUtilities::SessionReaderSharedPtr vSession
        = LibUtilities::SessionReader::CreateInstance(argc, argv);
    //-----------------------------------------------------------

    //-------------------------------------------------------------
    // Read in mesh from input file
    string meshfile(argv[argc-2]);
    SpatialDomains::MeshGraphSharedPtr graphShPt = SpatialDomains::MeshGraph::Read(meshfile);
    //------------------------------------------------------------

    //-------------------------------------------------------------
    // Define Streak Expansion
    MultiRegions::ExpListSharedPtr streak;

    streak = MemoryManager<MultiRegions::ExpList2D>
        ::AllocateSharedPtr(vSession,graphShPt);

    //---------------------------------------------------------------

    //----------------------------------------------
    // Import field file.
    string fieldfile(argv[argc-1]);
    vector<SpatialDomains::FieldDefinitionsSharedPtr> fielddef;
    vector<vector<NekDouble> > fielddata;
    graphShPt->Import(fieldfile,fielddef,fielddata);
    //----------------------------------------------

    //----------------------------------------------
    // Copy data from field file
    string  streak_field("w");
    for(unsigned int i = 0; i < fielddata.size(); ++i)
    {
        streak->ExtractDataToCoeffs(fielddef [i],
                                    fielddata[i],
                                    streak_field);
    }
    //----------------------------------------------

    int npts;
    vSession->LoadParameter("NoCriticalLayerPts",npts,30);
    Array<OneD, NekDouble> x_c(npts);
    Array<OneD, NekDouble> y_c(npts);
    NekDouble xc, yc;

    Computestreakpositions(streak,x_c, y_c,cr);

    cout << "# x_c y_c" << endl;
    for(i = 0; i < npts; ++i)
    {
        fprintf(stdout,"%12.10lf %12.10lf \n",x_c[i],y_c[i]);
        //cout << x_c[i] << " " << y_c[i] << endl;
    }

}

void Computestreakpositions(MultiRegions::ExpListSharedPtr &streak,
                            Array<OneD, NekDouble> &xc,
                            Array<OneD, NekDouble> &yc,
                            NekDouble cr)
{
    int i;
    int npts = xc.num_elements();

    int nq = streak->GetTotPoints();
    Array<OneD, NekDouble> derstreak(nq);
    Array<OneD, NekDouble> x(nq);
    Array<OneD, NekDouble> y(nq);
    streak->GetCoords(x,y);

    streak->BwdTrans(streak->GetCoeffs(),streak->UpdatePhys());
    streak->PhysDeriv(MultiRegions::eY, streak->GetPhys(), derstreak);

    // set intiial xc to be equispaced over mesh and yc to be zero
    NekDouble x_max = Vmath::Vmax(nq,x,1);
    NekDouble x_min = Vmath::Vmin(nq,x,1);

    for(i = 0; i < npts; ++i)
    {
        xc[i]  = x_min + (x_max - x_min)*i/((NekDouble)(npts-1));
        yc[i] = 0.0;
    }

    int elmtid, offset,cnt;
    NekDouble U,dU;
    NekDouble F;
    NekDouble ConvTol  = 1e-9;
    NekDouble CoordTol = 1e-5;
    int maxiter = 100;
    Array<OneD, NekDouble> coord(2);

    // Do Newton iteration on y direction
    cerr << "[";
    for(int e=0; e<npts; e++)
    {
        coord[0] = xc[e];
        coord[1] = yc[e];

        if(!(e%10))
        {
            cerr << ".";
        }

        F = 1000;
        cnt = 0;
        while((abs(F)> ConvTol)&&(cnt < maxiter))
        {
            elmtid = streak->GetExpIndex(coord,CoordTol);
            offset = streak->GetPhys_Offset(elmtid);

            U  = streak->GetExp(elmtid)->PhysEvaluate(coord, streak->GetPhys() + offset);
            dU = streak->GetExp(elmtid)->PhysEvaluate(coord, derstreak + offset);

            coord[1] = coord[1] - (U-cr)/dU;

            F = U-cr;
            cnt++;
        }
        ASSERTL0(cnt < maxiter, "Failed to converge Newton iteration");

        yc[e] = coord[1];
    }
    cerr << "]" << endl;

    // output to interface file
    FILE *fp = fopen("interfacedat.geo","w");

    NekDouble y_max = Vmath::Vmax(nq,y,1);
    NekDouble y_min = Vmath::Vmin(nq,y,1);

    cnt = 1;
    fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
            cnt++,x_min,y_min);
    fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
            cnt++,x_max,y_min);
    fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
            cnt++,x_max,y_max);
    fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
            cnt++,x_min,y_max);

    for(i = 0; i < npts; ++i)
    {
        fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0};  \n",
                cnt++,xc[i],yc[i]);
    }

    fclose(fp);

    // output to interface_up file as bend of vertical shift and 45 degrees shift
    fp = fopen("interfacedat_up.geo","w");

    NekDouble trans = 0.1;
    NekDouble nx,ny,norm;

    fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0};  \n",cnt++,xc[0],yc[0]+trans);

    for(i = 1; i < npts-1; ++i)
    {
        norm = sqrt((xc[i+1]-xc[i-1])*(xc[i+1]-xc[i-1])+(yc[i+1]-yc[i-1])*(yc[i+1]-yc[i-1]));
        nx = (yc[i-1]-yc[i+1])/norm;
        ny = (xc[i+1]-xc[i-1])/norm;

        fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0};  \n",
                cnt++,xc[i]+nx*trans,yc[i]+ny*trans);
    }

    fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0};  \n",cnt++,xc[npts-1],yc[npts-1]+trans);

    // output to interface_up file as bend of vertical shift and 45 degrees shift
    fp = fopen("interfacedat_dn.geo","w");

    trans = -trans;

    fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0};  \n",cnt++,xc[0],yc[0]+trans);

    for(i = 1; i < npts-1; ++i)
    {
        norm = sqrt((xc[i+1]-xc[i-1])*(xc[i+1]-xc[i-1])+(yc[i+1]-yc[i-1])*(yc[i+1]-yc[i-1]));
        nx = (yc[i-1]-yc[i+1])/norm;
        ny = (xc[i+1]-xc[i-1])/norm;

        fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0};  \n",
                cnt++,xc[i]+nx*trans,yc[i]+ny*trans);
    }

    fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0};  \n",cnt++,xc[npts-1],yc[npts-1]+trans);

}
<|endoftext|>


<commit_before>//===-- ExternalMethods.cpp - Implement External Methods ------------------===//
//
//  This file contains both code to deal with invoking "external" methods, but
//  also contains code that implements "exported" external methods.
//
//  External methods in LLI are implemented by dlopen'ing the lli executable and
//  using dlsym to look op the methods that we want to invoke.  If a method is
//  found, then the arguments are mangled and passed in to the function call.
//
//===----------------------------------------------------------------------===//

#include "Interpreter.h"
#include "llvm/DerivedTypes.h"
#include <map>
#include <dlfcn.h>
#include <link.h>
#include <math.h>
#include <stdio.h>

typedef GenericValue (*ExFunc)(MethodType *, const vector<GenericValue> &);
static map<const Method *, ExFunc> Functions;
static map<string, ExFunc> FuncNames;

static Interpreter *TheInterpreter;

// getCurrentExecutablePath() - Return the directory that the lli executable
// lives in.
//
string Interpreter::getCurrentExecutablePath() const {
  Dl_info Info;
  if (dladdr(&TheInterpreter, &Info) == 0) return "";

  string LinkAddr(Info.dli_fname);
  unsigned SlashPos = LinkAddr.rfind('/');
  if (SlashPos != string::npos)
    LinkAddr.resize(SlashPos);    // Trim the executable name off...

  return LinkAddr;
}

static char getTypeID(const Type *Ty) {
  switch (Ty->getPrimitiveID()) {
  case Type::VoidTyID:    return 'V';
  case Type::BoolTyID:    return 'o';
  case Type::UByteTyID:   return 'B';
  case Type::SByteTyID:   return 'b';
  case Type::UShortTyID:  return 'S';
  case Type::ShortTyID:   return 's';
  case Type::UIntTyID:    return 'I';
  case Type::IntTyID:     return 'i';
  case Type::ULongTyID:   return 'L';
  case Type::LongTyID:    return 'l';
  case Type::FloatTyID:   return 'F';
  case Type::DoubleTyID:  return 'D';
  case Type::PointerTyID: return 'P';
  case Type::MethodTyID:  return 'M';
  case Type::StructTyID:  return 'T';
  case Type::ArrayTyID:   return 'A';
  case Type::OpaqueTyID:  return 'O';
  default: return 'U';
  }
}

static ExFunc lookupMethod(const Method *M) {
  // Function not found, look it up... start by figuring out what the
  // composite function name should be.
  string ExtName = "lle_";
  const MethodType *MT = M->getMethodType();
  for (unsigned i = 0; const Type *Ty = MT->getContainedType(i); ++i)
    ExtName += getTypeID(Ty);
  ExtName += "_" + M->getName();

  //cout << "Tried: '" << ExtName << "'\n";
  ExFunc FnPtr = FuncNames[ExtName];
  if (FnPtr == 0)
    FnPtr = (ExFunc)dlsym(RTLD_DEFAULT, ExtName.c_str());
  if (FnPtr == 0)
    FnPtr = FuncNames["lle_X_"+M->getName()];
  if (FnPtr == 0)  // Try calling a generic function... if it exists...
    FnPtr = (ExFunc)dlsym(RTLD_DEFAULT, ("lle_X_"+M->getName()).c_str());
  if (FnPtr != 0)
    Functions.insert(make_pair(M, FnPtr));  // Cache for later
  return FnPtr;
}

GenericValue Interpreter::callExternalMethod(Method *M,
                                         const vector<GenericValue> &ArgVals) {
  TheInterpreter = this;

  // Do a lookup to see if the method is in our cache... this should just be a
  // defered annotation!
  map<const Method *, ExFunc>::iterator FI = Functions.find(M);
  ExFunc Fn = (FI == Functions.end()) ? lookupMethod(M) : FI->second;
  if (Fn == 0) {
    cout << "Tried to execute an unknown external method: "
	 << M->getType()->getDescription() << " " << M->getName() << endl;
    return GenericValue();
  }

  // TODO: FIXME when types are not const!
  GenericValue Result = Fn(const_cast<MethodType*>(M->getMethodType()),ArgVals);
  return Result;
}

//===----------------------------------------------------------------------===//
//  Methods "exported" to the running application...
//
extern "C" {  // Don't add C++ manglings to llvm mangling :)

// Implement void printstr([ubyte {x N}] *)
GenericValue lle_VP_printstr(MethodType *M, const vector<GenericValue> &ArgVal){
  assert(ArgVal.size() == 1 && "printstr only takes one argument!");
  cout << (char*)ArgVal[0].PointerVal;
  return GenericValue();
}

// Implement 'void print(X)' for every type...
GenericValue lle_X_print(MethodType *M, const vector<GenericValue> &ArgVals) {
  assert(ArgVals.size() == 1 && "generic print only takes one argument!");

  Interpreter::print(M->getParamTypes()[0], ArgVals[0]);
  return GenericValue();
}

// Implement 'void printVal(X)' for every type...
GenericValue lle_X_printVal(MethodType *M, const vector<GenericValue> &ArgVal) {
  assert(ArgVal.size() == 1 && "generic print only takes one argument!");

  // Specialize print([ubyte {x N} ] *) and print(sbyte *)
  if (PointerType *PTy = dyn_cast<PointerType>(M->getParamTypes()[0].get()))
    if (PTy->getValueType() == Type::SByteTy ||
        isa<ArrayType>(PTy->getValueType())) {
      return lle_VP_printstr(M, ArgVal);
    }

  Interpreter::printValue(M->getParamTypes()[0], ArgVal[0]);
  return GenericValue();
}

// Implement 'void printString(X)'
// Argument must be [ubyte {x N} ] * or sbyte *
GenericValue lle_X_printString(MethodType *M, const vector<GenericValue> &ArgVal) {
  assert(ArgVal.size() == 1 && "generic print only takes one argument!");
  return lle_VP_printstr(M, ArgVal);
}

// Implement 'void print<TYPE>(X)' for each primitive type or pointer type
#define PRINT_TYPE_FUNC(TYPENAME,TYPEID) \
  GenericValue lle_X_print##TYPENAME(MethodType *M,\
                                     const vector<GenericValue> &ArgVal) {\
    assert(ArgVal.size() == 1 && "generic print only takes one argument!");\
    assert(M->getParamTypes()[0].get()->getPrimitiveID() == Type::##TYPEID);\
    Interpreter::printValue(M->getParamTypes()[0], ArgVal[0]);\
    return GenericValue();\
  }

PRINT_TYPE_FUNC(SByte,   SByteTyID)
PRINT_TYPE_FUNC(UByte,   UByteTyID)
PRINT_TYPE_FUNC(Short,   ShortTyID)
PRINT_TYPE_FUNC(UShort,  UShortTyID)
PRINT_TYPE_FUNC(Int,     IntTyID)
PRINT_TYPE_FUNC(UInt,    UIntTyID)
PRINT_TYPE_FUNC(Long,    LongTyID)
PRINT_TYPE_FUNC(ULong,   ULongTyID)
PRINT_TYPE_FUNC(Float,   FloatTyID)
PRINT_TYPE_FUNC(Double,  DoubleTyID)
PRINT_TYPE_FUNC(Pointer, PointerTyID)

// void "putchar"(sbyte)
GenericValue lle_Vb_putchar(MethodType *M, const vector<GenericValue> &Args) {
  cout << Args[0].SByteVal;
  return GenericValue();
}

// int "putchar"(int)
GenericValue lle_ii_putchar(MethodType *M, const vector<GenericValue> &Args) {
  cout << ((char)Args[0].IntVal) << flush;
  return Args[0];
}

// void "putchar"(ubyte)
GenericValue lle_VB_putchar(MethodType *M, const vector<GenericValue> &Args) {
  cout << Args[0].SByteVal << flush;
  return Args[0];
}

// void "__main"()
GenericValue lle_V___main(MethodType *M, const vector<GenericValue> &Args) {
  return GenericValue();
}

// void "exit"(int)
GenericValue lle_X_exit(MethodType *M, const vector<GenericValue> &Args) {
  TheInterpreter->exitCalled(Args[0]);
  return GenericValue();
}

// void *malloc(uint)
GenericValue lle_X_malloc(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1 && "Malloc expects one argument!");
  GenericValue GV;
  GV.PointerVal = (PointerTy)malloc(Args[0].UIntVal);
  return GV;
}

// void free(void *)
GenericValue lle_X_free(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1);
  free((void*)Args[0].PointerVal);
  return GenericValue();
}

// double pow(double, double)
GenericValue lle_X_pow(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 2);
  GenericValue GV;
  GV.DoubleVal = pow(Args[0].DoubleVal, Args[1].DoubleVal);
  return GV;
}

// double sqrt(double)
GenericValue lle_X_sqrt(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1);
  GenericValue GV;
  GV.DoubleVal = sqrt(Args[0].DoubleVal);
  return GV;
}

// double log(double)
GenericValue lle_X_log(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1);
  GenericValue GV;
  GV.DoubleVal = log(Args[0].DoubleVal);
  return GV;
}

// double drand48()
GenericValue lle_X_drand48(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 0);
  GenericValue GV;
  GV.DoubleVal = drand48();
  return GV;
}

// int printf(sbyte *, ...) - a very rough implementation to make output useful.
GenericValue lle_X_printf(MethodType *M, const vector<GenericValue> &Args) {
  const char *FmtStr = (const char *)Args[0].PointerVal;
  unsigned ArgNo = 1;

  // printf should return # chars printed.  This is completely incorrect, but
  // close enough for now.
  GenericValue GV; GV.IntVal = strlen(FmtStr);
  while (1) {
    switch (*FmtStr) {
    case 0: return GV;             // Null terminator...
    default:                       // Normal nonspecial character
      cout << *FmtStr++;
      break;
    case '\\': {                   // Handle escape codes
      char Buffer[3];
      Buffer[0] = *FmtStr++;
      Buffer[1] = *FmtStr++;
      Buffer[2] = 0;
      cout << Buffer;
      break;
    }
    case '%': {                    // Handle format specifiers
      char FmtBuf[100] = "", Buffer[1000] = "";
      char *FB = FmtBuf;
      *FB++ = *FmtStr++;
      char Last = *FB++ = *FmtStr++;
      unsigned HowLong = 0;
      while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' &&
             Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' &&
             Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' &&
             Last != 'p' && Last != 's' && Last != '%') {
        if (Last == 'l' || Last == 'L') HowLong++;  // Keep track of l's
        Last = *FB++ = *FmtStr++;
      }
      *FB = 0;

      switch (Last) {
      case '%':
        sprintf(Buffer, FmtBuf); break;
      case 'c':
        sprintf(Buffer, FmtBuf, Args[ArgNo++].SByteVal); break;
      case 'd': case 'i':
      case 'u': case 'o':
      case 'x': case 'X':
        if (HowLong == 2)
          sprintf(Buffer, FmtBuf, Args[ArgNo++].ULongVal);
        else
          sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal); break;
      case 'e': case 'E': case 'g': case 'G': case 'f':
        sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break;
      case 'p':
        sprintf(Buffer, FmtBuf, (void*)Args[ArgNo++].PointerVal); break;
      case 's':
        sprintf(Buffer, FmtBuf, (char*)Args[ArgNo++].PointerVal); break;
      default:  cout << "<unknown printf code '" << *FmtStr << "'!>";
        ArgNo++; break;
      }
      cout << Buffer;
      }
      break;
    }
  }
}

} // End extern "C"

void Interpreter::initializeExternalMethods() {
  FuncNames["lle_VP_printstr"] = lle_VP_printstr;
  FuncNames["lle_X_print"] = lle_X_print;
  FuncNames["lle_X_printVal"] = lle_X_printVal;
  FuncNames["lle_X_printString"] = lle_X_printString;
  FuncNames["lle_X_printUByte"] = lle_X_printUByte;
  FuncNames["lle_X_printSByte"] = lle_X_printSByte;
  FuncNames["lle_X_printUShort"] = lle_X_printUShort;
  FuncNames["lle_X_printShort"] = lle_X_printShort;
  FuncNames["lle_X_printInt"] = lle_X_printInt;
  FuncNames["lle_X_printUInt"] = lle_X_printUInt;
  FuncNames["lle_X_printLong"] = lle_X_printLong;
  FuncNames["lle_X_printULong"] = lle_X_printULong;
  FuncNames["lle_X_printFloat"] = lle_X_printFloat;
  FuncNames["lle_X_printDouble"] = lle_X_printDouble;
  FuncNames["lle_X_printPointer"] = lle_X_printPointer;
  FuncNames["lle_Vb_putchar"]     = lle_Vb_putchar;
  FuncNames["lle_ii_putchar"]     = lle_ii_putchar;
  FuncNames["lle_VB_putchar"]     = lle_VB_putchar;
  FuncNames["lle_V___main"]       = lle_V___main;
  FuncNames["lle_X_exit"]         = lle_X_exit;
  FuncNames["lle_X_malloc"]       = lle_X_malloc;
  FuncNames["lle_X_free"]         = lle_X_free;
  FuncNames["lle_X_pow"]          = lle_X_pow;
  FuncNames["lle_X_sqrt"]         = lle_X_sqrt;
  FuncNames["lle_X_printf"]       = lle_X_printf;
}
<commit_msg>Implement some more rand functions for em3d benchmark<commit_after>//===-- ExternalMethods.cpp - Implement External Methods ------------------===//
//
//  This file contains both code to deal with invoking "external" methods, but
//  also contains code that implements "exported" external methods.
//
//  External methods in LLI are implemented by dlopen'ing the lli executable and
//  using dlsym to look op the methods that we want to invoke.  If a method is
//  found, then the arguments are mangled and passed in to the function call.
//
//===----------------------------------------------------------------------===//

#include "Interpreter.h"
#include "llvm/DerivedTypes.h"
#include <map>
#include <dlfcn.h>
#include <link.h>
#include <math.h>
#include <stdio.h>

typedef GenericValue (*ExFunc)(MethodType *, const vector<GenericValue> &);
static map<const Method *, ExFunc> Functions;
static map<string, ExFunc> FuncNames;

static Interpreter *TheInterpreter;

// getCurrentExecutablePath() - Return the directory that the lli executable
// lives in.
//
string Interpreter::getCurrentExecutablePath() const {
  Dl_info Info;
  if (dladdr(&TheInterpreter, &Info) == 0) return "";

  string LinkAddr(Info.dli_fname);
  unsigned SlashPos = LinkAddr.rfind('/');
  if (SlashPos != string::npos)
    LinkAddr.resize(SlashPos);    // Trim the executable name off...

  return LinkAddr;
}

static char getTypeID(const Type *Ty) {
  switch (Ty->getPrimitiveID()) {
  case Type::VoidTyID:    return 'V';
  case Type::BoolTyID:    return 'o';
  case Type::UByteTyID:   return 'B';
  case Type::SByteTyID:   return 'b';
  case Type::UShortTyID:  return 'S';
  case Type::ShortTyID:   return 's';
  case Type::UIntTyID:    return 'I';
  case Type::IntTyID:     return 'i';
  case Type::ULongTyID:   return 'L';
  case Type::LongTyID:    return 'l';
  case Type::FloatTyID:   return 'F';
  case Type::DoubleTyID:  return 'D';
  case Type::PointerTyID: return 'P';
  case Type::MethodTyID:  return 'M';
  case Type::StructTyID:  return 'T';
  case Type::ArrayTyID:   return 'A';
  case Type::OpaqueTyID:  return 'O';
  default: return 'U';
  }
}

static ExFunc lookupMethod(const Method *M) {
  // Function not found, look it up... start by figuring out what the
  // composite function name should be.
  string ExtName = "lle_";
  const MethodType *MT = M->getMethodType();
  for (unsigned i = 0; const Type *Ty = MT->getContainedType(i); ++i)
    ExtName += getTypeID(Ty);
  ExtName += "_" + M->getName();

  //cout << "Tried: '" << ExtName << "'\n";
  ExFunc FnPtr = FuncNames[ExtName];
  if (FnPtr == 0)
    FnPtr = (ExFunc)dlsym(RTLD_DEFAULT, ExtName.c_str());
  if (FnPtr == 0)
    FnPtr = FuncNames["lle_X_"+M->getName()];
  if (FnPtr == 0)  // Try calling a generic function... if it exists...
    FnPtr = (ExFunc)dlsym(RTLD_DEFAULT, ("lle_X_"+M->getName()).c_str());
  if (FnPtr != 0)
    Functions.insert(make_pair(M, FnPtr));  // Cache for later
  return FnPtr;
}

GenericValue Interpreter::callExternalMethod(Method *M,
                                         const vector<GenericValue> &ArgVals) {
  TheInterpreter = this;

  // Do a lookup to see if the method is in our cache... this should just be a
  // defered annotation!
  map<const Method *, ExFunc>::iterator FI = Functions.find(M);
  ExFunc Fn = (FI == Functions.end()) ? lookupMethod(M) : FI->second;
  if (Fn == 0) {
    cout << "Tried to execute an unknown external method: "
	 << M->getType()->getDescription() << " " << M->getName() << endl;
    return GenericValue();
  }

  // TODO: FIXME when types are not const!
  GenericValue Result = Fn(const_cast<MethodType*>(M->getMethodType()),ArgVals);
  return Result;
}

//===----------------------------------------------------------------------===//
//  Methods "exported" to the running application...
//
extern "C" {  // Don't add C++ manglings to llvm mangling :)

// Implement void printstr([ubyte {x N}] *)
GenericValue lle_VP_printstr(MethodType *M, const vector<GenericValue> &ArgVal){
  assert(ArgVal.size() == 1 && "printstr only takes one argument!");
  cout << (char*)ArgVal[0].PointerVal;
  return GenericValue();
}

// Implement 'void print(X)' for every type...
GenericValue lle_X_print(MethodType *M, const vector<GenericValue> &ArgVals) {
  assert(ArgVals.size() == 1 && "generic print only takes one argument!");

  Interpreter::print(M->getParamTypes()[0], ArgVals[0]);
  return GenericValue();
}

// Implement 'void printVal(X)' for every type...
GenericValue lle_X_printVal(MethodType *M, const vector<GenericValue> &ArgVal) {
  assert(ArgVal.size() == 1 && "generic print only takes one argument!");

  // Specialize print([ubyte {x N} ] *) and print(sbyte *)
  if (PointerType *PTy = dyn_cast<PointerType>(M->getParamTypes()[0].get()))
    if (PTy->getValueType() == Type::SByteTy ||
        isa<ArrayType>(PTy->getValueType())) {
      return lle_VP_printstr(M, ArgVal);
    }

  Interpreter::printValue(M->getParamTypes()[0], ArgVal[0]);
  return GenericValue();
}

// Implement 'void printString(X)'
// Argument must be [ubyte {x N} ] * or sbyte *
GenericValue lle_X_printString(MethodType *M, const vector<GenericValue> &ArgVal) {
  assert(ArgVal.size() == 1 && "generic print only takes one argument!");
  return lle_VP_printstr(M, ArgVal);
}

// Implement 'void print<TYPE>(X)' for each primitive type or pointer type
#define PRINT_TYPE_FUNC(TYPENAME,TYPEID) \
  GenericValue lle_X_print##TYPENAME(MethodType *M,\
                                     const vector<GenericValue> &ArgVal) {\
    assert(ArgVal.size() == 1 && "generic print only takes one argument!");\
    assert(M->getParamTypes()[0].get()->getPrimitiveID() == Type::##TYPEID);\
    Interpreter::printValue(M->getParamTypes()[0], ArgVal[0]);\
    return GenericValue();\
  }

PRINT_TYPE_FUNC(SByte,   SByteTyID)
PRINT_TYPE_FUNC(UByte,   UByteTyID)
PRINT_TYPE_FUNC(Short,   ShortTyID)
PRINT_TYPE_FUNC(UShort,  UShortTyID)
PRINT_TYPE_FUNC(Int,     IntTyID)
PRINT_TYPE_FUNC(UInt,    UIntTyID)
PRINT_TYPE_FUNC(Long,    LongTyID)
PRINT_TYPE_FUNC(ULong,   ULongTyID)
PRINT_TYPE_FUNC(Float,   FloatTyID)
PRINT_TYPE_FUNC(Double,  DoubleTyID)
PRINT_TYPE_FUNC(Pointer, PointerTyID)

// void "putchar"(sbyte)
GenericValue lle_Vb_putchar(MethodType *M, const vector<GenericValue> &Args) {
  cout << Args[0].SByteVal;
  return GenericValue();
}

// int "putchar"(int)
GenericValue lle_ii_putchar(MethodType *M, const vector<GenericValue> &Args) {
  cout << ((char)Args[0].IntVal) << flush;
  return Args[0];
}

// void "putchar"(ubyte)
GenericValue lle_VB_putchar(MethodType *M, const vector<GenericValue> &Args) {
  cout << Args[0].SByteVal << flush;
  return Args[0];
}

// void "__main"()
GenericValue lle_V___main(MethodType *M, const vector<GenericValue> &Args) {
  return GenericValue();
}

// void "exit"(int)
GenericValue lle_X_exit(MethodType *M, const vector<GenericValue> &Args) {
  TheInterpreter->exitCalled(Args[0]);
  return GenericValue();
}

// void *malloc(uint)
GenericValue lle_X_malloc(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1 && "Malloc expects one argument!");
  GenericValue GV;
  GV.PointerVal = (PointerTy)malloc(Args[0].UIntVal);
  return GV;
}

// void free(void *)
GenericValue lle_X_free(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1);
  free((void*)Args[0].PointerVal);
  return GenericValue();
}

// double pow(double, double)
GenericValue lle_X_pow(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 2);
  GenericValue GV;
  GV.DoubleVal = pow(Args[0].DoubleVal, Args[1].DoubleVal);
  return GV;
}

// double sqrt(double)
GenericValue lle_X_sqrt(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1);
  GenericValue GV;
  GV.DoubleVal = sqrt(Args[0].DoubleVal);
  return GV;
}

// double log(double)
GenericValue lle_X_log(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1);
  GenericValue GV;
  GV.DoubleVal = log(Args[0].DoubleVal);
  return GV;
}

// double drand48()
GenericValue lle_X_drand48(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 0);
  GenericValue GV;
  GV.DoubleVal = drand48();
  return GV;
}

// long lrand48()
GenericValue lle_X_lrand48(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 0);
  GenericValue GV;
  GV.IntVal = lrand48();
  return GV;
}

// void srand48(long)
GenericValue lle_X_srand48(MethodType *M, const vector<GenericValue> &Args) {
  assert(Args.size() == 1);
  srand48(Args[0].IntVal);
  return GenericValue();
}

// int printf(sbyte *, ...) - a very rough implementation to make output useful.
GenericValue lle_X_printf(MethodType *M, const vector<GenericValue> &Args) {
  const char *FmtStr = (const char *)Args[0].PointerVal;
  unsigned ArgNo = 1;

  // printf should return # chars printed.  This is completely incorrect, but
  // close enough for now.
  GenericValue GV; GV.IntVal = strlen(FmtStr);
  while (1) {
    switch (*FmtStr) {
    case 0: return GV;             // Null terminator...
    default:                       // Normal nonspecial character
      cout << *FmtStr++;
      break;
    case '\\': {                   // Handle escape codes
      char Buffer[3];
      Buffer[0] = *FmtStr++;
      Buffer[1] = *FmtStr++;
      Buffer[2] = 0;
      cout << Buffer;
      break;
    }
    case '%': {                    // Handle format specifiers
      char FmtBuf[100] = "", Buffer[1000] = "";
      char *FB = FmtBuf;
      *FB++ = *FmtStr++;
      char Last = *FB++ = *FmtStr++;
      unsigned HowLong = 0;
      while (Last != 'c' && Last != 'd' && Last != 'i' && Last != 'u' &&
             Last != 'o' && Last != 'x' && Last != 'X' && Last != 'e' &&
             Last != 'E' && Last != 'g' && Last != 'G' && Last != 'f' &&
             Last != 'p' && Last != 's' && Last != '%') {
        if (Last == 'l' || Last == 'L') HowLong++;  // Keep track of l's
        Last = *FB++ = *FmtStr++;
      }
      *FB = 0;

      switch (Last) {
      case '%':
        sprintf(Buffer, FmtBuf); break;
      case 'c':
        sprintf(Buffer, FmtBuf, Args[ArgNo++].SByteVal); break;
      case 'd': case 'i':
      case 'u': case 'o':
      case 'x': case 'X':
        if (HowLong == 2)
          sprintf(Buffer, FmtBuf, Args[ArgNo++].ULongVal);
        else
          sprintf(Buffer, FmtBuf, Args[ArgNo++].IntVal); break;
      case 'e': case 'E': case 'g': case 'G': case 'f':
        sprintf(Buffer, FmtBuf, Args[ArgNo++].DoubleVal); break;
      case 'p':
        sprintf(Buffer, FmtBuf, (void*)Args[ArgNo++].PointerVal); break;
      case 's':
        sprintf(Buffer, FmtBuf, (char*)Args[ArgNo++].PointerVal); break;
      default:  cout << "<unknown printf code '" << *FmtStr << "'!>";
        ArgNo++; break;
      }
      cout << Buffer;
      }
      break;
    }
  }
}

} // End extern "C"

void Interpreter::initializeExternalMethods() {
  FuncNames["lle_VP_printstr"] = lle_VP_printstr;
  FuncNames["lle_X_print"] = lle_X_print;
  FuncNames["lle_X_printVal"] = lle_X_printVal;
  FuncNames["lle_X_printString"] = lle_X_printString;
  FuncNames["lle_X_printUByte"] = lle_X_printUByte;
  FuncNames["lle_X_printSByte"] = lle_X_printSByte;
  FuncNames["lle_X_printUShort"] = lle_X_printUShort;
  FuncNames["lle_X_printShort"] = lle_X_printShort;
  FuncNames["lle_X_printInt"] = lle_X_printInt;
  FuncNames["lle_X_printUInt"] = lle_X_printUInt;
  FuncNames["lle_X_printLong"] = lle_X_printLong;
  FuncNames["lle_X_printULong"] = lle_X_printULong;
  FuncNames["lle_X_printFloat"] = lle_X_printFloat;
  FuncNames["lle_X_printDouble"] = lle_X_printDouble;
  FuncNames["lle_X_printPointer"] = lle_X_printPointer;
  FuncNames["lle_Vb_putchar"]     = lle_Vb_putchar;
  FuncNames["lle_ii_putchar"]     = lle_ii_putchar;
  FuncNames["lle_VB_putchar"]     = lle_VB_putchar;
  FuncNames["lle_V___main"]       = lle_V___main;
  FuncNames["lle_X_exit"]         = lle_X_exit;
  FuncNames["lle_X_malloc"]       = lle_X_malloc;
  FuncNames["lle_X_free"]         = lle_X_free;
  FuncNames["lle_X_pow"]          = lle_X_pow;
  FuncNames["lle_X_log"]          = lle_X_log;
  FuncNames["lle_X_drand48"]      = lle_X_drand48;
  FuncNames["lle_X_srand48"]      = lle_X_srand48;
  FuncNames["lle_X_lrand48"]      = lle_X_lrand48;
  FuncNames["lle_X_sqrt"]         = lle_X_sqrt;
  FuncNames["lle_X_printf"]       = lle_X_printf;
}
<|endoftext|>


<commit_before>// Copyright (C) 2014 Oliver Schulz <oschulz@mpp.mpg.de>

// This is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "RootIO.h"

#include <stdexcept>

#include <TDataType.h>

#include "format.h"
#include "TypeReflection.h"

using namespace std;

namespace dbrx {

char RootIO::getTypeSymbol(const std::type_info& typeInfo) {
	if      (typeInfo == typeid(Bool_t))    return 'O';
	else if (typeInfo == typeid(Char_t))    return 'B';
	else if (typeInfo == typeid(UChar_t))   return 'b';
	else if (typeInfo == typeid(Short_t))   return 'S';
	else if (typeInfo == typeid(UShort_t))  return 's';
	else if (typeInfo == typeid(Int_t))     return 'I';
	else if (typeInfo == typeid(UInt_t))    return 'i';
	else if (typeInfo == typeid(Long64_t))  return 'L';
	else if (typeInfo == typeid(ULong64_t)) return 'l';
	else if (typeInfo == typeid(Double_t))  return 'D';
	else if (typeInfo == typeid(Float_t))   return 'F';
	else if (typeInfo == typeid(char*))     return 'C';
	else throw invalid_argument("No ROOT type symbol equivalent for type_info \"%s\""_format(typeInfo.name()));
}

void RootIO::inputValueFrom(WritableValue& value, TTree *tree, const TString& branchName) {
	const char* bName = branchName.Data();

	// Result of SetBranchAddress is not a reliable check for existence of the
	// branch (problem only with TChain?), so check with GetBranch first:
	if (tree->GetBranch(bName)) {
		tree->SetBranchStatus(bName, true);

		EDataType dataType = TDataType::GetType(value.typeInfo());
		Int_t result = -1;
		if (dataType == kNoType_t) { // Unknown type
			throw invalid_argument("Cannot set branch address for kNoType_t");
		} else if (dataType == EDataType::kOther_t) { // Object type
			const TClass *cl = TypeReflection(value.typeInfo()).getTClass();
			result = tree->SetBranchAddress(branchName, value.untypedPPtr(), nullptr, const_cast<TClass*>(cl), dataType, true);
		} else { // Primitive type
			if (value.empty()) value.setToDefault();
			result = tree->SetBranchAddress(branchName, value.untypedPtr(), nullptr, nullptr, dataType, false);
		}
		if (result < 0) throw runtime_error("Failed to set branch address");

		tree->AddBranchToCache(bName);
	}
	else throw runtime_error("Branch not found");
}

void RootIO::outputValueTo(Value& value, TTree *tree, const TString& branchName, Int_t bufsize, Int_t splitlevel) {
	if (! value.valid()) throw invalid_argument("Cannot output invalid value object to branch");
	const char* bName = branchName.Data();
	EDataType dataType = TDataType::GetType(value.typeInfo());

	TBranch* branch = nullptr;
	if (dataType == kNoType_t) { // Unknown type
		throw invalid_argument("Cannot create branch for kNoType_t");
	} else if (dataType == EDataType::kOther_t) { // Object type
		const TClass *cl = TypeReflection(value.typeInfo()).getTClass();
		branch = tree->Branch(bName, cl->GetName(), const_cast<void**>(value.untypedPPtr()), bufsize, splitlevel);
	} else { // Primitive type
		char typeSymbol = getTypeSymbol(value.typeInfo());
		if (value.empty()) throw invalid_argument("Cannot output empty value object of primitive type to branch");
		string formatString("%s/%c"_format(bName, typeSymbol));
		branch = tree->Branch(bName, const_cast<void*>(value.untypedPtr()), formatString.c_str(), bufsize);
	}
	if (branch == nullptr) throw runtime_error("Failed to create branch");
}

} // namespace dbrx
<commit_msg>Improved exception messages in RootIO::inputValueFrom()<commit_after>// Copyright (C) 2014 Oliver Schulz <oschulz@mpp.mpg.de>

// This is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include "RootIO.h"

#include <stdexcept>

#include <TDataType.h>

#include "format.h"
#include "TypeReflection.h"

using namespace std;

namespace dbrx {

char RootIO::getTypeSymbol(const std::type_info& typeInfo) {
	if      (typeInfo == typeid(Bool_t))    return 'O';
	else if (typeInfo == typeid(Char_t))    return 'B';
	else if (typeInfo == typeid(UChar_t))   return 'b';
	else if (typeInfo == typeid(Short_t))   return 'S';
	else if (typeInfo == typeid(UShort_t))  return 's';
	else if (typeInfo == typeid(Int_t))     return 'I';
	else if (typeInfo == typeid(UInt_t))    return 'i';
	else if (typeInfo == typeid(Long64_t))  return 'L';
	else if (typeInfo == typeid(ULong64_t)) return 'l';
	else if (typeInfo == typeid(Double_t))  return 'D';
	else if (typeInfo == typeid(Float_t))   return 'F';
	else if (typeInfo == typeid(char*))     return 'C';
	else throw invalid_argument("No ROOT type symbol equivalent for type_info \"%s\""_format(typeInfo.name()));
}

void RootIO::inputValueFrom(WritableValue& value, TTree *tree, const TString& branchName) {
	const char* bName = branchName.Data();

	// Result of SetBranchAddress is not a reliable check for existence of the
	// branch (problem only with TChain?), so check with GetBranch first:
	if (tree->GetBranch(bName)) {
		tree->SetBranchStatus(bName, true);

		EDataType dataType = TDataType::GetType(value.typeInfo());
		Int_t result = -1;
		if (dataType == kNoType_t) { // Unknown type
			throw invalid_argument("Cannot set branch address for kNoType_t");
		} else if (dataType == EDataType::kOther_t) { // Object type
			const TClass *cl = TypeReflection(value.typeInfo()).getTClass();
			result = tree->SetBranchAddress(branchName, value.untypedPPtr(), nullptr, const_cast<TClass*>(cl), dataType, true);
		} else { // Primitive type
			if (value.empty()) value.setToDefault();
			result = tree->SetBranchAddress(branchName, value.untypedPtr(), nullptr, nullptr, dataType, false);
		}
		if (result < 0) throw runtime_error("Failed to set branch address for branch \"%s\""_format(branchName));

		tree->AddBranchToCache(bName);
	}
	else throw runtime_error("Branch \"%s\" not found"_format(branchName));
}

void RootIO::outputValueTo(Value& value, TTree *tree, const TString& branchName, Int_t bufsize, Int_t splitlevel) {
	if (! value.valid()) throw invalid_argument("Cannot output invalid value object to branch");
	const char* bName = branchName.Data();
	EDataType dataType = TDataType::GetType(value.typeInfo());

	TBranch* branch = nullptr;
	if (dataType == kNoType_t) { // Unknown type
		throw invalid_argument("Cannot create branch for kNoType_t");
	} else if (dataType == EDataType::kOther_t) { // Object type
		const TClass *cl = TypeReflection(value.typeInfo()).getTClass();
		branch = tree->Branch(bName, cl->GetName(), const_cast<void**>(value.untypedPPtr()), bufsize, splitlevel);
	} else { // Primitive type
		char typeSymbol = getTypeSymbol(value.typeInfo());
		if (value.empty()) throw invalid_argument("Cannot output empty value object of primitive type to branch");
		string formatString("%s/%c"_format(bName, typeSymbol));
		branch = tree->Branch(bName, const_cast<void*>(value.untypedPtr()), formatString.c_str(), bufsize);
	}
	if (branch == nullptr) throw runtime_error("Failed to create branch");
}

} // namespace dbrx
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#include <BALL/VIEW/DIALOGS/raytraceableContourSurfaceDialog.h>

#include <QtGui/QPushButton>
#include <QtGui/qlineedit.h>
//#include <QtGui/qpushbutton.h>
#include <QtGui/QSlider>
#include <iostream>

namespace BALL
{
	namespace VIEW
	{

RaytraceableContourSurfaceDialog::RaytraceableContourSurfaceDialog(RaytraceableGrid* grid, QWidget* parent, const char* name, bool, Qt::WFlags fl )
	: QDialog(parent, fl),
		Ui_RaytraceableContourSurfaceDialogData(),
		ModularWidget(name),
		grid_(grid)
{
	std::cout << "Constructor RT_CS_Dialog " << std::endl;

	setupUi(this);
	//setINIFileSectionName("Raytracing");
	setObjectName(name);
	registerWidget(this);
	setObjectName(name);

	// signals and slots connections

	// Contour Threshold Range
	connect( OK_button, SIGNAL( clicked() ), this, SLOT( accept() ) );
	connect( cancel_button , SIGNAL( clicked() ), this, SLOT( reject() ) );
	connect( add_button, SIGNAL( clicked() ), this, SLOT( add() ) );
	connect( ContourSurfaceThresholdSlider, SIGNAL( valueChanged(int) ), this, SLOT( changedSliderThreshold(int) ) );
	connect( ContourSurfaceThresholdLineEdit, SIGNAL( editingFinished() ), this, SLOT( changedEditThreshold() ) );

	// Contour Threshold Range
	connect( autoRangeButton, SIGNAL( clicked() ), this, SLOT ( setDefaultRangeValues_() ) );
	connect( RangeLineEdit_min, SIGNAL( editingFinished() ), this, SLOT(changedRangeMin()) );
	connect( RangeLineEdit_max, SIGNAL( editingFinished() ), this, SLOT(changedRangeMax()) );
	connect( RangeLineEdit_steps, SIGNAL( editingFinished() ), this, SLOT(changedRangeSteps()) );

	OK_button->setEnabled(true);
	add_button->setEnabled(true);
	cancel_button->setEnabled(true);
	autoRangeButton->setEnabled(true);

	// initialize slider and editLine
	if (grid_ != 0)
	{
		setDefaultRangeValues_();
	}
	else
	{
		Log.error() << "The grid is not valid" << std::endl;
	}
}

RaytraceableContourSurfaceDialog::~RaytraceableContourSurfaceDialog()
{
	// TODO
}

void RaytraceableContourSurfaceDialog::setDefaultRangeValues_()
{
	//Log.info() << " setDefaultValues" << std::endl;
	min_ = grid_->getGridMinValue();
	max_ = grid_->getGridMaxValue();
	current_threshold_ = (min_+ max_)/2.;
	steps_ = 50;

	QString str = QString("%1").arg((double)current_threshold_, 0,'g',3);
	ContourSurfaceThresholdLineEdit->setText(str);

	ContourSurfaceThresholdSlider->setRange(0,steps_);
	ContourSurfaceThresholdSlider->setSliderPosition(steps_/2);
	str = QString("%1").arg((double)max_, 0, 'g', 3);
	RangeLineEdit_max->setText(str);
	str = QString("%1").arg((double)min_, 0, 'g', 3);
	RangeLineEdit_min->setText(str);
	str = QString("%1").arg((double)steps_, 0, 'g', 3);
	RangeLineEdit_steps->setText(str);

	str = QString("%1").arg((double)current_threshold_, 0, 'g', 3);
	ContourSurfaceThresholdLineEdit->setText(str);

}

void RaytraceableContourSurfaceDialog::add()
{
	//std::cout << " model reated- close()" << std::endl;
	//double new_threshold = 3.;
	//addModel_(new_threshold);
	addModel_(current_threshold_);
}

void RaytraceableContourSurfaceDialog::accept()
{
	//std::cout << "new model created - waiting()" << std::endl;
	// get the new threshold
	//double new_threshold = 3.;
	//addModel_(new_threshold);
	addModel_(current_threshold_);
	QDialog::accept();
}

void RaytraceableContourSurfaceDialog::reject()
{
//	std::cout << "no model reated- close()" << std::endl;
	QDialog::reject();
}

void RaytraceableContourSurfaceDialog::changedSliderThreshold(int sliderpos)
{
	//std::cout << "call slider changed! " << std::endl;
	current_threshold_ =  min_ + (float)((max_ - min_)/steps_) * (float)sliderpos;
	QString str = QString("%1").arg((double)current_threshold_, 0, 'g', 3);
	ContourSurfaceThresholdLineEdit->setText(str);
}

void RaytraceableContourSurfaceDialog::changedEditThreshold()
{
//	std::cout << "call edit th changed !" << std::endl;
	float new_threshold = getValue_(ContourSurfaceThresholdLineEdit);
	if (new_threshold > max_)
	{
		// ToDo: are there other restrictions??
		// ToDo: appropriate error/info message
		current_threshold_ = max_;
		QString str = QString("%1").arg((double)current_threshold_, 0,'g',3);
		ContourSurfaceThresholdLineEdit->setText(str);
	}
	else if(new_threshold < min_ )
	{
		current_threshold_ = min_;
		QString str = QString("%1").arg((double)current_threshold_, 0,'g',3);
		ContourSurfaceThresholdLineEdit->setText(str);
	}
	else
	{
		current_threshold_ = new_threshold;
	}

	// update the slider
	ContourSurfaceThresholdSlider->setSliderPosition((int) ((current_threshold_-min_)/(max_ - min_) * steps_));

}

void RaytraceableContourSurfaceDialog::addModel_(float threshold)
{
	// TODO: create a new model and add it to the representationlist
}

void  RaytraceableContourSurfaceDialog::changedRangeMin()
{
	//std::cout << "call min changed"  << std::endl;

	min_= getValue_(RangeLineEdit_min);
	if (current_threshold_ < min_)
	{
		current_threshold_ = min_;
		// update the value LineEdit
		QString str = QString("%1").arg((double)current_threshold_, 0, 'g', 3);
		ContourSurfaceThresholdLineEdit->setText(str);
	}
	// update the values slider
	ContourSurfaceThresholdSlider->setSliderPosition((int) ((current_threshold_-min_)/(max_ - min_) * steps_));

}

void  RaytraceableContourSurfaceDialog::changedRangeMax()
{
	//std::cout << "call max changed"  << std::endl;
	max_= getValue_(RangeLineEdit_max);
	if (current_threshold_ > max_)
	{
		current_threshold_ = max_;
		// update the value LineEdit
		QString str = QString("%1").arg((double)current_threshold_, 0, 'g', 3);
		ContourSurfaceThresholdLineEdit->setText(str);
	}

	// update the value slider
	ContourSurfaceThresholdSlider->setSliderPosition((int) ((current_threshold_-min_)/(max_ - min_) * steps_));

}

void  RaytraceableContourSurfaceDialog::changedRangeSteps()
{
	//std::cout << "call steps changed"  << std::endl;
	int new_steps = (int)getValue_(RangeLineEdit_steps);
	if (new_steps < 1)
	{
		steps_ = 1; //(int)(max_ - min_);
		QString str = QString("%1").arg((double)steps_, 0, 'g', 3);
		RangeLineEdit_steps->setText(str);
		// TO DO: appropriate error/info message??
	}
	else
	{
		steps_= new_steps;
	}
	// update the range and value slider
	ContourSurfaceThresholdSlider->setRange(0,(int)steps_);
	ContourSurfaceThresholdSlider->setSliderPosition((int) ((current_threshold_-min_)/(max_ - min_) * steps_));

}

float RaytraceableContourSurfaceDialog::getValue_(const QAbstractSlider* slider) const
{
	return(slider->value());
}

float RaytraceableContourSurfaceDialog::getValue_(const QLineEdit* edit) const
	throw(Exception::InvalidFormat)
{
	return (edit->text()).toFloat();
}

	} // VIEW and BALL namespace:
}
<commit_msg>Fixed a compile time warning in RaytraceableContourSurfaceDialog.<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#include <BALL/VIEW/DIALOGS/raytraceableContourSurfaceDialog.h>

#include <QtGui/QPushButton>
#include <QtGui/qlineedit.h>
//#include <QtGui/qpushbutton.h>
#include <QtGui/QSlider>
#include <iostream>

namespace BALL
{
	namespace VIEW
	{

RaytraceableContourSurfaceDialog::RaytraceableContourSurfaceDialog(RaytraceableGrid* grid, QWidget* parent, const char* name, bool, Qt::WFlags fl )
	: QDialog(parent, fl),
		Ui_RaytraceableContourSurfaceDialogData(),
		ModularWidget(name),
		grid_(grid)
{
	std::cout << "Constructor RT_CS_Dialog " << std::endl;

	setupUi(this);
	//setINIFileSectionName("Raytracing");
	setObjectName(name);
	registerWidget(this);
	setObjectName(name);

	// signals and slots connections

	// Contour Threshold Range
	connect( OK_button, SIGNAL( clicked() ), this, SLOT( accept() ) );
	connect( cancel_button , SIGNAL( clicked() ), this, SLOT( reject() ) );
	connect( add_button, SIGNAL( clicked() ), this, SLOT( add() ) );
	connect( ContourSurfaceThresholdSlider, SIGNAL( valueChanged(int) ), this, SLOT( changedSliderThreshold(int) ) );
	connect( ContourSurfaceThresholdLineEdit, SIGNAL( editingFinished() ), this, SLOT( changedEditThreshold() ) );

	// Contour Threshold Range
	connect( autoRangeButton, SIGNAL( clicked() ), this, SLOT ( setDefaultRangeValues_() ) );
	connect( RangeLineEdit_min, SIGNAL( editingFinished() ), this, SLOT(changedRangeMin()) );
	connect( RangeLineEdit_max, SIGNAL( editingFinished() ), this, SLOT(changedRangeMax()) );
	connect( RangeLineEdit_steps, SIGNAL( editingFinished() ), this, SLOT(changedRangeSteps()) );

	OK_button->setEnabled(true);
	add_button->setEnabled(true);
	cancel_button->setEnabled(true);
	autoRangeButton->setEnabled(true);

	// initialize slider and editLine
	if (grid_ != 0)
	{
		setDefaultRangeValues_();
	}
	else
	{
		Log.error() << "The grid is not valid" << std::endl;
	}
}

RaytraceableContourSurfaceDialog::~RaytraceableContourSurfaceDialog()
{
	// TODO
}

void RaytraceableContourSurfaceDialog::setDefaultRangeValues_()
{
	//Log.info() << " setDefaultValues" << std::endl;
	min_ = grid_->getGridMinValue();
	max_ = grid_->getGridMaxValue();
	current_threshold_ = (min_+ max_)/2.;
	steps_ = 50;

	QString str = QString("%1").arg((double)current_threshold_, 0,'g',3);
	ContourSurfaceThresholdLineEdit->setText(str);

	ContourSurfaceThresholdSlider->setRange(0,steps_);
	ContourSurfaceThresholdSlider->setSliderPosition(steps_/2);
	str = QString("%1").arg((double)max_, 0, 'g', 3);
	RangeLineEdit_max->setText(str);
	str = QString("%1").arg((double)min_, 0, 'g', 3);
	RangeLineEdit_min->setText(str);
	str = QString("%1").arg((double)steps_, 0, 'g', 3);
	RangeLineEdit_steps->setText(str);

	str = QString("%1").arg((double)current_threshold_, 0, 'g', 3);
	ContourSurfaceThresholdLineEdit->setText(str);

}

void RaytraceableContourSurfaceDialog::add()
{
	//std::cout << " model reated- close()" << std::endl;
	//double new_threshold = 3.;
	//addModel_(new_threshold);
	addModel_(current_threshold_);
}

void RaytraceableContourSurfaceDialog::accept()
{
	//std::cout << "new model created - waiting()" << std::endl;
	// get the new threshold
	//double new_threshold = 3.;
	//addModel_(new_threshold);
	addModel_(current_threshold_);
	QDialog::accept();
}

void RaytraceableContourSurfaceDialog::reject()
{
//	std::cout << "no model reated- close()" << std::endl;
	QDialog::reject();
}

void RaytraceableContourSurfaceDialog::changedSliderThreshold(int sliderpos)
{
	//std::cout << "call slider changed! " << std::endl;
	current_threshold_ =  min_ + (float)((max_ - min_)/steps_) * (float)sliderpos;
	QString str = QString("%1").arg((double)current_threshold_, 0, 'g', 3);
	ContourSurfaceThresholdLineEdit->setText(str);
}

void RaytraceableContourSurfaceDialog::changedEditThreshold()
{
//	std::cout << "call edit th changed !" << std::endl;
	float new_threshold = getValue_(ContourSurfaceThresholdLineEdit);
	if (new_threshold > max_)
	{
		// ToDo: are there other restrictions??
		// ToDo: appropriate error/info message
		current_threshold_ = max_;
		QString str = QString("%1").arg((double)current_threshold_, 0,'g',3);
		ContourSurfaceThresholdLineEdit->setText(str);
	}
	else if(new_threshold < min_ )
	{
		current_threshold_ = min_;
		QString str = QString("%1").arg((double)current_threshold_, 0,'g',3);
		ContourSurfaceThresholdLineEdit->setText(str);
	}
	else
	{
		current_threshold_ = new_threshold;
	}

	// update the slider
	ContourSurfaceThresholdSlider->setSliderPosition((int) ((current_threshold_-min_)/(max_ - min_) * steps_));

}

void RaytraceableContourSurfaceDialog::addModel_(float /*threshold*/)
{
	// TODO: create a new model and add it to the representationlist
}

void  RaytraceableContourSurfaceDialog::changedRangeMin()
{
	//std::cout << "call min changed"  << std::endl;

	min_= getValue_(RangeLineEdit_min);
	if (current_threshold_ < min_)
	{
		current_threshold_ = min_;
		// update the value LineEdit
		QString str = QString("%1").arg((double)current_threshold_, 0, 'g', 3);
		ContourSurfaceThresholdLineEdit->setText(str);
	}
	// update the values slider
	ContourSurfaceThresholdSlider->setSliderPosition((int) ((current_threshold_-min_)/(max_ - min_) * steps_));

}

void  RaytraceableContourSurfaceDialog::changedRangeMax()
{
	//std::cout << "call max changed"  << std::endl;
	max_= getValue_(RangeLineEdit_max);
	if (current_threshold_ > max_)
	{
		current_threshold_ = max_;
		// update the value LineEdit
		QString str = QString("%1").arg((double)current_threshold_, 0, 'g', 3);
		ContourSurfaceThresholdLineEdit->setText(str);
	}

	// update the value slider
	ContourSurfaceThresholdSlider->setSliderPosition((int) ((current_threshold_-min_)/(max_ - min_) * steps_));

}

void  RaytraceableContourSurfaceDialog::changedRangeSteps()
{
	//std::cout << "call steps changed"  << std::endl;
	int new_steps = (int)getValue_(RangeLineEdit_steps);
	if (new_steps < 1)
	{
		steps_ = 1; //(int)(max_ - min_);
		QString str = QString("%1").arg((double)steps_, 0, 'g', 3);
		RangeLineEdit_steps->setText(str);
		// TO DO: appropriate error/info message??
	}
	else
	{
		steps_= new_steps;
	}
	// update the range and value slider
	ContourSurfaceThresholdSlider->setRange(0,(int)steps_);
	ContourSurfaceThresholdSlider->setSliderPosition((int) ((current_threshold_-min_)/(max_ - min_) * steps_));

}

float RaytraceableContourSurfaceDialog::getValue_(const QAbstractSlider* slider) const
{
	return(slider->value());
}

float RaytraceableContourSurfaceDialog::getValue_(const QLineEdit* edit) const
	throw(Exception::InvalidFormat)
{
	return (edit->text()).toFloat();
}

	} // VIEW and BALL namespace:
}
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2013 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/// \author James Hughes
/// \date   August 2013

#include "SRUtil.h"

#include "spire/src/Common.h"

namespace CPM_SPIRE_SCIRUN_NS {

size_t buildNormalRenderingForVBO(std::shared_ptr<std::vector<uint8_t>> vboData,
                                  size_t stride, float normalLength,
                                  std::vector<uint8_t>& out_vboData,
                                  std::vector<uint8_t>& out_iboData,
                                  size_t posOffset, size_t normOffset)
{
  uint8_t* rawData = &(*vboData)[0];

  // Figure out the size of out_vboData and out_iboData.
  size_t numInVertices = vboData->size() / stride;
  size_t outVBOSize = numInVertices * (sizeof(float) * 3 + sizeof(float) * 3) * 2;
  size_t outIBOSize = numInVertices * (sizeof(uint16_t) * 2);

  out_vboData.resize(outVBOSize);
  out_iboData.resize(outIBOSize);

  uint8_t* rawOutIBO = &out_iboData[0];
  uint8_t* rawOutVBO = &out_vboData[0];

  auto readFloat = [&rawData](size_t* offset) -> float {
    float ret = *reinterpret_cast<float*>(&rawData[*offset]);
    *offset += sizeof(float);
    return ret;
  };

  auto writeFloat = [](uint8_t* _rawData, size_t* offset, float data) {
    float* floatData = reinterpret_cast<float*>(&_rawData[*offset]);
    *floatData = data;
    *offset += sizeof(float);
  };

  auto writeUInt16 = [](uint8_t* _rawData, size_t* offset, uint16_t data) {
    uint16_t* uintData = reinterpret_cast<uint16_t*>(&_rawData[*offset]);
    *uintData = data;
    *offset += sizeof(uint16_t);
  };

  size_t outVboPos = 0;
  size_t outIboPos = 0;
  uint16_t iboIndex = 0;
  for (size_t inputVboPos = 0; inputVboPos + stride <= vboData->size();)
  {
    size_t inputOffset = inputVboPos + posOffset;
    spire::V3 position;
    position.x = readFloat(&inputOffset);
    position.y = readFloat(&inputOffset);
    position.z = readFloat(&inputOffset);

    inputOffset = inputVboPos + normOffset;
    spire::V3 normal;
    normal.x = readFloat(&inputOffset);
    normal.y = readFloat(&inputOffset);
    normal.z = readFloat(&inputOffset);

    inputVboPos += stride;

    spire::V3 distal = position + normal * normalLength;

    // Write VBO
    writeFloat(rawOutVBO, &outVboPos, position.x);
    writeFloat(rawOutVBO, &outVboPos, position.y);
    writeFloat(rawOutVBO, &outVboPos, position.z);

    writeFloat(rawOutVBO, &outVboPos, distal.x);
    writeFloat(rawOutVBO, &outVboPos, distal.y);
    writeFloat(rawOutVBO, &outVboPos, distal.z);

    // Write ibo (all unique).
    writeUInt16(rawOutIBO, &outIboPos, iboIndex); ++iboIndex;
    writeUInt16(rawOutIBO, &outIboPos, iboIndex); ++iboIndex;
  }

  return numInVertices;
}

} // namespace CPM_SPIRE_SCIRUN_NS

<commit_msg>Ensure 'namespaces.h' is included in all cpp files.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2013 Scientific Computing and Imaging Institute,
   University of Utah.

   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.
*/

/// \author James Hughes
/// \date   August 2013

#include "namespaces.h"
#include "SRUtil.h"

#include "spire/src/Common.h"

namespace CPM_SPIRE_SCIRUN_NS {

size_t buildNormalRenderingForVBO(std::shared_ptr<std::vector<uint8_t>> vboData,
                                  size_t stride, float normalLength,
                                  std::vector<uint8_t>& out_vboData,
                                  std::vector<uint8_t>& out_iboData,
                                  size_t posOffset, size_t normOffset)
{
  uint8_t* rawData = &(*vboData)[0];

  // Figure out the size of out_vboData and out_iboData.
  size_t numInVertices = vboData->size() / stride;
  size_t outVBOSize = numInVertices * (sizeof(float) * 3 + sizeof(float) * 3) * 2;
  size_t outIBOSize = numInVertices * (sizeof(uint16_t) * 2);

  out_vboData.resize(outVBOSize);
  out_iboData.resize(outIBOSize);

  uint8_t* rawOutIBO = &out_iboData[0];
  uint8_t* rawOutVBO = &out_vboData[0];

  auto readFloat = [&rawData](size_t* offset) -> float {
    float ret = *reinterpret_cast<float*>(&rawData[*offset]);
    *offset += sizeof(float);
    return ret;
  };

  auto writeFloat = [](uint8_t* _rawData, size_t* offset, float data) {
    float* floatData = reinterpret_cast<float*>(&_rawData[*offset]);
    *floatData = data;
    *offset += sizeof(float);
  };

  auto writeUInt16 = [](uint8_t* _rawData, size_t* offset, uint16_t data) {
    uint16_t* uintData = reinterpret_cast<uint16_t*>(&_rawData[*offset]);
    *uintData = data;
    *offset += sizeof(uint16_t);
  };

  size_t outVboPos = 0;
  size_t outIboPos = 0;
  uint16_t iboIndex = 0;
  for (size_t inputVboPos = 0; inputVboPos + stride <= vboData->size();)
  {
    size_t inputOffset = inputVboPos + posOffset;
    spire::V3 position;
    position.x = readFloat(&inputOffset);
    position.y = readFloat(&inputOffset);
    position.z = readFloat(&inputOffset);

    inputOffset = inputVboPos + normOffset;
    spire::V3 normal;
    normal.x = readFloat(&inputOffset);
    normal.y = readFloat(&inputOffset);
    normal.z = readFloat(&inputOffset);

    inputVboPos += stride;

    spire::V3 distal = position + normal * normalLength;

    // Write VBO
    writeFloat(rawOutVBO, &outVboPos, position.x);
    writeFloat(rawOutVBO, &outVboPos, position.y);
    writeFloat(rawOutVBO, &outVboPos, position.z);

    writeFloat(rawOutVBO, &outVboPos, distal.x);
    writeFloat(rawOutVBO, &outVboPos, distal.y);
    writeFloat(rawOutVBO, &outVboPos, distal.z);

    // Write ibo (all unique).
    writeUInt16(rawOutIBO, &outIboPos, iboIndex); ++iboIndex;
    writeUInt16(rawOutIBO, &outIboPos, iboIndex); ++iboIndex;
  }

  return numInVertices;
}

} // namespace CPM_SPIRE_SCIRUN_NS

<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2008 Sacha Schutz <istdasklar@free.fr>
 * Copyright (C) 2010 Kim Jung Nissen <jungnissen@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "gluonbuttons.h"

#include <QtCore/QMetaEnum>

using namespace GluonInput;

template<> GLUON_INPUT_EXPORT GluonButtons *GluonCore::Singleton<GluonButtons>::m_instance = 0;

GluonButtons::GluonButtons()
{
}

GluonButtons::~GluonButtons()
{
}

QString GluonButtons::buttonName(DeviceFlag deviceType, int code)
{
    return metaObject()->enumerator(metaObject()->indexOfEnumerator("Button")).valueToKey(code);
}

QString GluonButtons::axisName(DeviceFlag deviceType,int code)
{
    QString value = "";
    switch (deviceType) {
    case MouseDevice:
        value = metaObject()->enumerator(metaObject()->indexOfEnumerator("Relative")).valueToKey(code);
        return value != "" ? value : "Unknown";
        break;
    case JoystickDevice:
        value = metaObject()->enumerator(metaObject()->indexOfEnumerator("Absolute")).valueToKey(code);
        return value != "" ? value : "Unknown";
        break;
    default:
        return "Unknown";
    }
}

#include "gluonbuttons.moc"
<commit_msg>Refactor the function and the switch statement handling, it was a bit ugly.<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (C) 2008 Sacha Schutz <istdasklar@free.fr>
 * Copyright (C) 2010 Kim Jung Nissen <jungnissen@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "gluonbuttons.h"

#include <QtCore/QMetaEnum>

using namespace GluonInput;

template<> GLUON_INPUT_EXPORT GluonButtons *GluonCore::Singleton<GluonButtons>::m_instance = 0;

GluonButtons::GluonButtons()
{
}

GluonButtons::~GluonButtons()
{
}

QString GluonButtons::buttonName(DeviceFlag deviceType, int code)
{
    return metaObject()->enumerator(metaObject()->indexOfEnumerator("Button")).valueToKey(code);
}

QString GluonButtons::axisName(DeviceFlag deviceType,int code)
{
    QString value = "";
    switch (deviceType) {
    case MouseDevice:
        value = metaObject()->enumerator(metaObject()->indexOfEnumerator("Relative")).valueToKey(code);
        value != "" ? value : "Unknown";
        break;
    case JoystickDevice:
        value = metaObject()->enumerator(metaObject()->indexOfEnumerator("Absolute")).valueToKey(code);
        value != "" ? value : "Unknown";
        break;
    default:
        value = "Unknown";
        break;
    }
    return value;
}

#include "gluonbuttons.moc"
<|endoftext|>