<commit_before>#include "masternodemanager.h"
#include "ui_masternodemanager.h"
#include "addeditadrenalinenode.h"
#include "adrenalinenodeconfigdialog.h"

#include "sync.h"
#include "clientmodel.h"
#include "walletmodel.h"
#include "activemasternode.h"
#include "masternodeconfig.h"
#include "masternodeman.h"
#include "masternode.h"
#include "walletdb.h"
#include "wallet.h"
#include "init.h"
#include "rpcserver.h"
#include <boost/lexical_cast.hpp>
#include <fstream>
using namespace json_spirit;
using namespace std;

#include <QAbstractItemDelegate>
#include <QClipboard>
#include <QPainter>
#include <QTimer>
#include <QDebug>
#include <QScrollArea>
#include <QScroller>
#include <QDateTime>
#include <QApplication>
#include <QClipboard>
#include <QMessageBox>
#include <QItemSelectionModel>

MasternodeManager::MasternodeManager(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MasternodeManager),
    clientModel(0),
    walletModel(0)
{
    ui->setupUi(this);

    ui->editButton->setEnabled(false);
    ui->startButton->setEnabled(false);

    int columnAddressWidth = 200;
    int columnProtocolWidth = 60;
    int columnStatusWidth = 80;
    int columnActiveWidth = 130;
    int columnLastSeenWidth = 130;

    ui->tableWidgetMasternodes->setColumnWidth(0, columnAddressWidth);
    ui->tableWidgetMasternodes->setColumnWidth(1, columnProtocolWidth);
    ui->tableWidgetMasternodes->setColumnWidth(2, columnStatusWidth);
    ui->tableWidgetMasternodes->setColumnWidth(3, columnActiveWidth);
    ui->tableWidgetMasternodes->setColumnWidth(4, columnLastSeenWidth);

    ui->tableWidgetMasternodes->setContextMenuPolicy(Qt::CustomContextMenu);
    QAction *copyAddressAction = new QAction(tr("Copy Address"), this);
    QAction *copyPubkeyAction = new QAction(tr("Copy Pubkey"), this);
    contextMenu = new QMenu();
    contextMenu->addAction(copyAddressAction);
    contextMenu->addAction(copyPubkeyAction);
    connect(ui->tableWidgetMasternodes, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));
    connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress()));
    connect(copyPubkeyAction, SIGNAL(triggered()), this, SLOT(copyPubkey()));

    ui->tableWidgetMasternodes->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    ui->tableWidget_2->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateNodeList()));
    if(!GetBoolArg("-reindexaddr", false))
        timer->start(30000);

    updateNodeList();
}

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

void MasternodeManager::on_tableWidget_2_itemSelectionChanged()
{
    if(ui->tableWidget_2->selectedItems().count() > 0)
    {
        ui->editButton->setEnabled(true);
        ui->startButton->setEnabled(true);
    }
}

void MasternodeManager::updateAdrenalineNode(QString alias, QString addr, QString privkey, QString txHash, QString txIndex, QString status)
{
    LOCK(cs_adrenaline);
    bool bFound = false;
    int nodeRow = 0;
    for(int i=0; i < ui->tableWidget_2->rowCount(); i++)
    {
        if(ui->tableWidget_2->item(i, 0)->text() == alias)
        {
            bFound = true;
            nodeRow = i;
            break;
        }
    }

    if(nodeRow == 0 && !bFound)
        ui->tableWidget_2->insertRow(0);

    QTableWidgetItem *aliasItem = new QTableWidgetItem(alias);
    QTableWidgetItem *addrItem = new QTableWidgetItem(addr);
    QTableWidgetItem *statusItem = new QTableWidgetItem(status);

    ui->tableWidget_2->setItem(nodeRow, 0, aliasItem);
    ui->tableWidget_2->setItem(nodeRow, 1, addrItem);
    ui->tableWidget_2->setItem(nodeRow, 2, statusItem);
}

static QString seconds_to_DHMS(quint32 duration)
{
  QString res;
  int seconds = (int) (duration % 60);
  duration /= 60;
  int minutes = (int) (duration % 60);
  duration /= 60;
  int hours = (int) (duration % 24);
  int days = (int) (duration / 24);
  if((hours == 0)&&(days == 0))
      return res.sprintf("%02dm:%02ds", minutes, seconds);
  if (days == 0)
      return res.sprintf("%02dh:%02dm:%02ds", hours, minutes, seconds);
  return res.sprintf("%dd %02dh:%02dm:%02ds", days, hours, minutes, seconds);
}

void MasternodeManager::updateNodeList()
{
    static int64_t nTimeListUpdated = GetTime();
    int64_t nSecondsToWait = nTimeListUpdated - GetTime() + 30;
    if (nSecondsToWait > 0) return;

    TRY_LOCK(cs_masternodes, lockMasternodes);
    if(!lockMasternodes) return;

    ui->countLabel->setText("Updating...");
    ui->tableWidgetMasternodes->setSortingEnabled(false);
    ui->tableWidgetMasternodes->clearContents();
    ui->tableWidgetMasternodes->setRowCount(0);
    std::vector<CMasternode> vMasternodes = mnodeman.GetFullMasternodeVector();

    BOOST_FOREACH(CMasternode& mn, vMasternodes)
    {

        // populate list
        // Address, Protocol, Status, Active Seconds, Last Seen, Pub Key
        QTableWidgetItem* addressItem = new QTableWidgetItem(QString::fromStdString(mn.addr.ToString()));
        QTableWidgetItem* protocolItem = new QTableWidgetItem(QString::number(mn.protocolVersion));
        QTableWidgetItem* statusItem = new QTableWidgetItem(QString::number(mn.IsEnabled()));
        QTableWidgetItem *activeSecondsItem = new QTableWidgetItem(seconds_to_DHMS((qint64)(mn.lastTimeSeen - mn.sigTime)));
        QTableWidgetItem *lastSeenItem = new QTableWidgetItem(QString::fromStdString(DateTimeStrFormat(mn.lastTimeSeen)));

        CScript pubkey;
        pubkey =GetScriptForDestination(mn.pubkey.GetID());
        CTxDestination address1;
        ExtractDestination(pubkey, address1);
        CCravecoinAddress address2(address1);
        QTableWidgetItem *pubkeyItem = new QTableWidgetItem(QString::fromStdString(address2.ToString()));

        ui->tableWidgetMasternodes->insertRow(0);
        ui->tableWidgetMasternodes->setItem(0, 0, addressItem);
        ui->tableWidgetMasternodes->setItem(0, 1, protocolItem);
        ui->tableWidgetMasternodes->setItem(0, 2, statusItem);
        ui->tableWidgetMasternodes->setItem(0, 3, activeSecondsItem);
        ui->tableWidgetMasternodes->setItem(0, 4, lastSeenItem);
        ui->tableWidgetMasternodes->setItem(0, 5, pubkeyItem);
    }

    ui->countLabel->setText(QString::number(ui->tableWidgetMasternodes->rowCount()));
    ui->tableWidgetMasternodes->setSortingEnabled(true);
}

void MasternodeManager::setClientModel(ClientModel *model)
{
    this->clientModel = model;
    if(model)
    {
    }
}

void MasternodeManager::setWalletModel(WalletModel *model)
{
    this->walletModel = model;
    if(model && model->getOptionsModel())
    {
    }

}

void MasternodeManager::on_createButton_clicked()
{
    AddEditAdrenalineNode* aenode = new AddEditAdrenalineNode();
    aenode->exec();
}

void MasternodeManager::on_startButton_clicked()
{
    // start the node
    QItemSelectionModel* selectionModel = ui->tableWidget_2->selectionModel();
    QModelIndexList selected = selectionModel->selectedRows();
    if(selected.count() == 0)
        return;

    QModelIndex index = selected.at(0);
    int r = index.row();
    std::string sAlias = ui->tableWidget_2->item(r, 0)->text().toStdString();

    if(pwalletMain->IsLocked()) {
    }

    std::string statusObj;
    statusObj += "Alias: " + sAlias;

    BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
        if(mne.getAlias() == sAlias) {
            std::string errorMessage;

            bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage);

            if(result) {
                statusObj += "
Successfully started masternode." ;
            } else {
                statusObj += "
Failed to start masternode.
Error: " + errorMessage;
            }
            break;
        }
    }
    statusObj += "";
    pwalletMain->Lock();

    QMessageBox msg;
    msg.setText(QString::fromStdString(statusObj));

    msg.exec();
}

void MasternodeManager::on_startAllButton_clicked()
{
    if(pwalletMain->IsLocked()) {
    }

    std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;

    int total = 0;
    int successful = 0;
    int fail = 0;
    std::string statusObj;

    BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
        total++;

        std::string errorMessage;

        bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage);

        if(result) {
            successful++;
        } else {
            fail++;
            statusObj += "\nFailed to start " + mne.getAlias() + ". Error: " + errorMessage;
        }
    }
    pwalletMain->Lock();

    std::string returnObj;
    returnObj = "Successfully started " + boost::lexical_cast<std::string>(successful) + " masternodes, failed to start " +
            boost::lexical_cast<std::string>(fail) + ", total " + boost::lexical_cast<std::string>(total);
    if (fail > 0)
        returnObj += statusObj;

    QMessageBox msg;
    msg.setText(QString::fromStdString(returnObj));
    msg.exec();
}

void MasternodeManager::on_UpdateButton_clicked()
{
    BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
        std::string errorMessage;

        std::vector<CMasternode> vMasternodes = mnodeman.GetFullMasternodeVector();
        if (errorMessage == ""){
            updateAdrenalineNode(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), QString::fromStdString(mne.getPrivKey()), QString::fromStdString(mne.getTxHash()),
                QString::fromStdString(mne.getOutputIndex()), QString::fromStdString("Not in the masternode list."));
        }
        else {
            updateAdrenalineNode(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), QString::fromStdString(mne.getPrivKey()), QString::fromStdString(mne.getTxHash()),
                QString::fromStdString(mne.getOutputIndex()), QString::fromStdString(errorMessage));
        }

        BOOST_FOREACH(CMasternode& mn, vMasternodes) {
            if (mn.addr.ToString().c_str() == mne.getIp()){
                updateAdrenalineNode(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), QString::fromStdString(mne.getPrivKey()), QString::fromStdString(mne.getTxHash()),
                QString::fromStdString(mne.getOutputIndex()), QString::fromStdString("Masternode is Running."));
            }
        }
    }
}

void MasternodeManager::showContextMenu(const QPoint& point)
{
    QTableWidgetItem* item = ui->tableWidgetMasternodes->itemAt(point);
    if (item) contextMenu->exec(QCursor::pos());
}

void MasternodeManager::copyAddress()
{
    std::string sData;
    int row;
    QItemSelectionModel* selectionModel = ui->tableWidgetMasternodes->selectionModel();
    QModelIndexList selectedRows = selectionModel->selectedRows();
    if(selectedRows.count() == 0)
        return;

    for (int i =0; i < selectedRows.count(); i++)
    {
        QModelIndex index = selectedRows.at(i);
        row = index.row();
        sData += ui->tableWidgetMasternodes->item(row, 0)->text().toStdString() + "\n";
    }

    QApplication::clipboard()->setText(QString::fromStdString(sData));
}

void MasternodeManager::copyPubkey()
{
    std::string sData;
    int row;
    QItemSelectionModel* selectionModel = ui->tableWidgetMasternodes->selectionModel();
    QModelIndexList selectedRows = selectionModel->selectedRows();
    if(selectedRows.count() == 0)
        return;

    for (int i =0; i < selectedRows.count(); i++)
    {
        QModelIndex index = selectedRows.at(i);
        row = index.row();
        sData += ui->tableWidgetMasternodes->item(row, 5)->text().toStdString() + "\n";
    }

    QApplication::clipboard()->setText(QString::fromStdString(sData));
}<commit_msg>Remove last "\n" at copy<commit_after>#include "masternodemanager.h"
#include "ui_masternodemanager.h"
#include "addeditadrenalinenode.h"
#include "adrenalinenodeconfigdialog.h"

#include "sync.h"
#include "clientmodel.h"
#include "walletmodel.h"
#include "activemasternode.h"
#include "masternodeconfig.h"
#include "masternodeman.h"
#include "masternode.h"
#include "walletdb.h"
#include "wallet.h"
#include "init.h"
#include "rpcserver.h"
#include <boost/lexical_cast.hpp>
#include <fstream>
using namespace json_spirit;
using namespace std;

#include <QAbstractItemDelegate>
#include <QClipboard>
#include <QPainter>
#include <QTimer>
#include <QDebug>
#include <QScrollArea>
#include <QScroller>
#include <QDateTime>
#include <QApplication>
#include <QClipboard>
#include <QMessageBox>
#include <QItemSelectionModel>

MasternodeManager::MasternodeManager(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MasternodeManager),
    clientModel(0),
    walletModel(0)
{
    ui->setupUi(this);

    ui->editButton->setEnabled(false);
    ui->startButton->setEnabled(false);

    int columnAddressWidth = 200;
    int columnProtocolWidth = 60;
    int columnStatusWidth = 80;
    int columnActiveWidth = 130;
    int columnLastSeenWidth = 130;

    ui->tableWidgetMasternodes->setColumnWidth(0, columnAddressWidth);
    ui->tableWidgetMasternodes->setColumnWidth(1, columnProtocolWidth);
    ui->tableWidgetMasternodes->setColumnWidth(2, columnStatusWidth);
    ui->tableWidgetMasternodes->setColumnWidth(3, columnActiveWidth);
    ui->tableWidgetMasternodes->setColumnWidth(4, columnLastSeenWidth);

    ui->tableWidgetMasternodes->setContextMenuPolicy(Qt::CustomContextMenu);
    QAction *copyAddressAction = new QAction(tr("Copy Address"), this);
    QAction *copyPubkeyAction = new QAction(tr("Copy Pubkey"), this);
    contextMenu = new QMenu();
    contextMenu->addAction(copyAddressAction);
    contextMenu->addAction(copyPubkeyAction);
    connect(ui->tableWidgetMasternodes, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));
    connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress()));
    connect(copyPubkeyAction, SIGNAL(triggered()), this, SLOT(copyPubkey()));

    ui->tableWidgetMasternodes->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    ui->tableWidget_2->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateNodeList()));
    if(!GetBoolArg("-reindexaddr", false))
        timer->start(30000);

    updateNodeList();
}

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

void MasternodeManager::on_tableWidget_2_itemSelectionChanged()
{
    if(ui->tableWidget_2->selectedItems().count() > 0)
    {
        ui->editButton->setEnabled(true);
        ui->startButton->setEnabled(true);
    }
}

void MasternodeManager::updateAdrenalineNode(QString alias, QString addr, QString privkey, QString txHash, QString txIndex, QString status)
{
    LOCK(cs_adrenaline);
    bool bFound = false;
    int nodeRow = 0;
    for(int i=0; i < ui->tableWidget_2->rowCount(); i++)
    {
        if(ui->tableWidget_2->item(i, 0)->text() == alias)
        {
            bFound = true;
            nodeRow = i;
            break;
        }
    }

    if(nodeRow == 0 && !bFound)
        ui->tableWidget_2->insertRow(0);

    QTableWidgetItem *aliasItem = new QTableWidgetItem(alias);
    QTableWidgetItem *addrItem = new QTableWidgetItem(addr);
    QTableWidgetItem *statusItem = new QTableWidgetItem(status);

    ui->tableWidget_2->setItem(nodeRow, 0, aliasItem);
    ui->tableWidget_2->setItem(nodeRow, 1, addrItem);
    ui->tableWidget_2->setItem(nodeRow, 2, statusItem);
}

static QString seconds_to_DHMS(quint32 duration)
{
  QString res;
  int seconds = (int) (duration % 60);
  duration /= 60;
  int minutes = (int) (duration % 60);
  duration /= 60;
  int hours = (int) (duration % 24);
  int days = (int) (duration / 24);
  if((hours == 0)&&(days == 0))
      return res.sprintf("%02dm:%02ds", minutes, seconds);
  if (days == 0)
      return res.sprintf("%02dh:%02dm:%02ds", hours, minutes, seconds);
  return res.sprintf("%dd %02dh:%02dm:%02ds", days, hours, minutes, seconds);
}

void MasternodeManager::updateNodeList()
{
    static int64_t nTimeListUpdated = GetTime();
    int64_t nSecondsToWait = nTimeListUpdated - GetTime() + 30;
    if (nSecondsToWait > 0) return;

    TRY_LOCK(cs_masternodes, lockMasternodes);
    if(!lockMasternodes) return;

    ui->countLabel->setText("Updating...");
    ui->tableWidgetMasternodes->setSortingEnabled(false);
    ui->tableWidgetMasternodes->clearContents();
    ui->tableWidgetMasternodes->setRowCount(0);
    std::vector<CMasternode> vMasternodes = mnodeman.GetFullMasternodeVector();

    BOOST_FOREACH(CMasternode& mn, vMasternodes)
    {

        // populate list
        // Address, Protocol, Status, Active Seconds, Last Seen, Pub Key
        QTableWidgetItem* addressItem = new QTableWidgetItem(QString::fromStdString(mn.addr.ToString()));
        QTableWidgetItem* protocolItem = new QTableWidgetItem(QString::number(mn.protocolVersion));
        QTableWidgetItem* statusItem = new QTableWidgetItem(QString::number(mn.IsEnabled()));
        QTableWidgetItem *activeSecondsItem = new QTableWidgetItem(seconds_to_DHMS((qint64)(mn.lastTimeSeen - mn.sigTime)));
        QTableWidgetItem *lastSeenItem = new QTableWidgetItem(QString::fromStdString(DateTimeStrFormat(mn.lastTimeSeen)));

        CScript pubkey;
        pubkey =GetScriptForDestination(mn.pubkey.GetID());
        CTxDestination address1;
        ExtractDestination(pubkey, address1);
        CCravecoinAddress address2(address1);
        QTableWidgetItem *pubkeyItem = new QTableWidgetItem(QString::fromStdString(address2.ToString()));

        ui->tableWidgetMasternodes->insertRow(0);
        ui->tableWidgetMasternodes->setItem(0, 0, addressItem);
        ui->tableWidgetMasternodes->setItem(0, 1, protocolItem);
        ui->tableWidgetMasternodes->setItem(0, 2, statusItem);
        ui->tableWidgetMasternodes->setItem(0, 3, activeSecondsItem);
        ui->tableWidgetMasternodes->setItem(0, 4, lastSeenItem);
        ui->tableWidgetMasternodes->setItem(0, 5, pubkeyItem);
    }

    ui->countLabel->setText(QString::number(ui->tableWidgetMasternodes->rowCount()));
    ui->tableWidgetMasternodes->setSortingEnabled(true);
}

void MasternodeManager::setClientModel(ClientModel *model)
{
    this->clientModel = model;
    if(model)
    {
    }
}

void MasternodeManager::setWalletModel(WalletModel *model)
{
    this->walletModel = model;
    if(model && model->getOptionsModel())
    {
    }

}

void MasternodeManager::on_createButton_clicked()
{
    AddEditAdrenalineNode* aenode = new AddEditAdrenalineNode();
    aenode->exec();
}

void MasternodeManager::on_startButton_clicked()
{
    // start the node
    QItemSelectionModel* selectionModel = ui->tableWidget_2->selectionModel();
    QModelIndexList selected = selectionModel->selectedRows();
    if(selected.count() == 0)
        return;

    QModelIndex index = selected.at(0);
    int r = index.row();
    std::string sAlias = ui->tableWidget_2->item(r, 0)->text().toStdString();

    if(pwalletMain->IsLocked()) {
    }

    std::string statusObj;
    statusObj += "Alias: " + sAlias;

    BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
        if(mne.getAlias() == sAlias) {
            std::string errorMessage;

            bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage);

            if(result) {
                statusObj += "
Successfully started masternode." ;
            } else {
                statusObj += "
Failed to start masternode.
Error: " + errorMessage;
            }
            break;
        }
    }
    statusObj += "";
    pwalletMain->Lock();

    QMessageBox msg;
    msg.setText(QString::fromStdString(statusObj));

    msg.exec();
}

void MasternodeManager::on_startAllButton_clicked()
{
    if(pwalletMain->IsLocked()) {
    }

    std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;

    int total = 0;
    int successful = 0;
    int fail = 0;
    std::string statusObj;

    BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
        total++;

        std::string errorMessage;

        bool result = activeMasternode.Register(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage);

        if(result) {
            successful++;
        } else {
            fail++;
            statusObj += "\nFailed to start " + mne.getAlias() + ". Error: " + errorMessage;
        }
    }
    pwalletMain->Lock();

    std::string returnObj;
    returnObj = "Successfully started " + boost::lexical_cast<std::string>(successful) + " masternodes, failed to start " +
            boost::lexical_cast<std::string>(fail) + ", total " + boost::lexical_cast<std::string>(total);
    if (fail > 0)
        returnObj += statusObj;

    QMessageBox msg;
    msg.setText(QString::fromStdString(returnObj));
    msg.exec();
}

void MasternodeManager::on_UpdateButton_clicked()
{
    BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
        std::string errorMessage;

        std::vector<CMasternode> vMasternodes = mnodeman.GetFullMasternodeVector();
        if (errorMessage == ""){
            updateAdrenalineNode(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), QString::fromStdString(mne.getPrivKey()), QString::fromStdString(mne.getTxHash()),
                QString::fromStdString(mne.getOutputIndex()), QString::fromStdString("Not in the masternode list."));
        }
        else {
            updateAdrenalineNode(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), QString::fromStdString(mne.getPrivKey()), QString::fromStdString(mne.getTxHash()),
                QString::fromStdString(mne.getOutputIndex()), QString::fromStdString(errorMessage));
        }

        BOOST_FOREACH(CMasternode& mn, vMasternodes) {
            if (mn.addr.ToString().c_str() == mne.getIp()){
                updateAdrenalineNode(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), QString::fromStdString(mne.getPrivKey()), QString::fromStdString(mne.getTxHash()),
                QString::fromStdString(mne.getOutputIndex()), QString::fromStdString("Masternode is Running."));
            }
        }
    }
}

void MasternodeManager::showContextMenu(const QPoint& point)
{
    QTableWidgetItem* item = ui->tableWidgetMasternodes->itemAt(point);
    if (item) contextMenu->exec(QCursor::pos());
}

void MasternodeManager::copyAddress()
{
    std::string sData;
    int row;
    QItemSelectionModel* selectionModel = ui->tableWidgetMasternodes->selectionModel();
    QModelIndexList selectedRows = selectionModel->selectedRows();
    if(selectedRows.count() == 0)
        return;

    for (int i = 0; i < selectedRows.count(); i++)
    {
        QModelIndex index = selectedRows.at(i);
        row = index.row();
        sData += ui->tableWidgetMasternodes->item(row, 0)->text().toStdString();
        if (i < selectedRows.count()-1)
            sData += "\n";
    }

    QApplication::clipboard()->setText(QString::fromStdString(sData));
}

void MasternodeManager::copyPubkey()
{
    std::string sData;
    int row;
    QItemSelectionModel* selectionModel = ui->tableWidgetMasternodes->selectionModel();
    QModelIndexList selectedRows = selectionModel->selectedRows();
    if(selectedRows.count() == 0)
        return;

    for (int i = 0; i < selectedRows.count(); i++)
    {
        QModelIndex index = selectedRows.at(i);
        row = index.row();
        sData += ui->tableWidgetMasternodes->item(row, 5)->text().toStdString();
        if (i < selectedRows.count()-1)
            sData += "\n";
    }

    QApplication::clipboard()->setText(QString::fromStdString(sData));
}<|endoftext|>


<commit_before>#include "text.h"
#include "font.h"
#include "sprite.h"

#include <SDL_ttf.h>

namespace mw {

	Text::Text() : characterSize_(0) {
		setText("");
	}

	Text::Text(std::string text, const Font& font) :
	    characterSize_((float) font.getCharacterSize()), font_(font) {

		setText(text);
	}

	Text::Text(std::string text, const Font& font, float characterSize) :
	    characterSize_(characterSize), font_(font) {

	    setText(text);
	}

	void Text::setText(std::string text) {
		// Text changed?
		if (text_ != text) {
		    // Try to load the text to a new texture.
            text_ = text;
			if (!loadTextToTexture(text)) {
			    // Texture loading failed.
			    texture_ = mw::Texture();
			}
		}
	}

	bool Text::loadTextToTexture(std::string str) {
	    // Font available?
		if (font_.getTtfFont()) {
			if (str.size() > 0) {
				SDL_Color color = {255, 255, 255, 255};
				SDL_Surface* surface = TTF_RenderUTF8_Blended(font_.getTtfFont(), str.c_str(), color);
				// No error?
				if (surface != 0) {
                    // Texture takes ownership of surface.
                    texture_ = Texture(surface, []() {
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                    });
                    return true;
				}
			}
		}
		return false;
	}

} // Namespace mw.
<commit_msg>Replaced TTF_RenderUTF8_Blended with TTF_RenderUTF8_Blended_Wrapped<commit_after>#include "text.h"
#include "font.h"
#include "sprite.h"

#include <SDL_ttf.h>

namespace mw {

	Text::Text() : characterSize_(0) {
		setText("");
	}

	Text::Text(std::string text, const Font& font) :
	    characterSize_((float) font.getCharacterSize()), font_(font) {

		setText(text);
	}

	Text::Text(std::string text, const Font& font, float characterSize) :
	    characterSize_(characterSize), font_(font) {

	    setText(text);
	}

	void Text::setText(std::string text) {
		// Text changed?
		if (text_ != text) {
		    // Try to load the text to a new texture.
            text_ = text;
			if (!loadTextToTexture(text)) {
			    // Texture loading failed.
			    texture_ = mw::Texture();
			}
		}
	}

	bool Text::loadTextToTexture(std::string str) {
	    // Font available?
		if (font_.getTtfFont()) {
			if (str.size() > 0) {
				SDL_Color color = {255, 255, 255, 255};
				SDL_Surface* surface = TTF_RenderUTF8_Blended_Wrapped(font_.getTtfFont(), str.c_str(), color, 500);

				// No error?
				if (surface != 0) {
                    // Texture takes ownership of surface.
                    texture_ = Texture(surface, []() {
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                    });
                    return true;
				}
			}
		}
		return false;
	}

} // Namespace mw.
<|endoftext|>


<commit_before>AliGenerator* CreatePythia8Gen( TString lTune          = "pp",
                               Float_t e_cms       = 13000.
                               );

AliGenerator* AddCustomMCGenPythia8243(   TString lTune          = "pp",
                                       Float_t e_cms       = 13000.

                                       ) {
    // Add Pythia 8 generator:
    //    -kProcess=0  MB generation
    //    -kProcess=1  Jet production, pthard generation
    //    - Color reconnection = ON/OFF
    //    - Set k factor, default = 1; range of possible values in xmldoc/CouplingsAndScales.xml

    gSystem->Load("liblhapdf");

    AliGenerator *genP  = NULL;
    genP                = CreatePythia8Gen(e_cms, tune, kCR, kF, kProcess, ptHardMin, ptHardMax,longlived);

    return genP;
}

AliGenerator* CreatePythia8Gen( Float_t e_cms,
                               Int_t tune,
                               Bool_t kCR,
                               Int_t kF,
                               Int_t kProcess,
                               Double_t ptHardMin,
                               Double_t ptHardMax,
                               Bool_t longlived
                               ) {

    gSystem->Load("libpythia6");
    gSystem->Load("libEGPythia6");
    gSystem->Load("libAliPythia6");
    gSystem->Load("libpythia8");
    gSystem->Load("libAliPythia8");
    gSystem->Setenv("PYTHIA8DATA", gSystem->ExpandPathName("$ALICE_ROOT/PYTHIA8/pythia8/xmldoc"));
    gSystem->Setenv("LHAPDF",      gSystem->ExpandPathName("$ALICE_ROOT/LHAPDF"));
    gSystem->Setenv("LHAPATH",     gSystem->ExpandPathName("$ALICE_ROOT/LHAPDF/PDFsets"));

    AliPythia8 *pythia = AliPythia8::Instance();            // For ROOT6 needs to be created before AliGenPythiaPlus object, otherwise ending in "illegal instruction"
    AliGenPythiaPlus* gener = new AliGenPythiaPlus(pythia);

    std::cout << "*****************************************************************" << std::endl;
    std::cout << " Desired PYTHIA configuration: "<< lTune.Data()<< std::endl;
    std::cout << "*****************************************************************" << std::endl;
    // set process (MB)
    gener->SetProcess(kPyMbDefault);

    //Centre of mass energy
    gener->SetEnergyCMS(e_cms); // in GeV

    //random seed based on time
    (AliPythia8::Instance())->ReadString("Beams:idA = 2212");
    (AliPythia8::Instance())->ReadString("Beams:idB = 2212");
    (AliPythia8::Instance())->ReadString("PhaseSpace:pTHatMax = -1.0"); //this should be fixed in the constructor
    (AliPythia8::Instance())->ReadString("Main:timesAllowErrors = 50000");

    if ( lTune.EqualTo("pp") ){
        // Specific settings go here
        // default: do nothing, Monash 2013 will do its thing
        (AliPythia8::Instance())->ReadString(Form("Tune:pp = %d",14));
    }
    if ( lTune.EqualTo("pp-experimental") ){
        // This is me testing a few things
        TRandom3 gRand3;
        gRand3.SetSeed(0);
        Float_t lRandpT0Ref = 2.0+(((Float_t)((Int_t)(10.*gRand3.Uniform())))/10.);
        (AliPythia8::Instance())->ReadString(Form("MultipartonInteractions:pT0Ref = %.2f",lRandpT0Ref));
        std::cout << " Random pT0Ref: "<< lRandpT0Ref << std::endl;
    }
    if ( lTune.EqualTo("pp-moreqcd") ){
        std::cout << " Setting pp-moreqcd parameters..." << std::endl;
        //Paper reference: https://arxiv.org/pdf/1505.01681.pdf ("mode 0")
        //===========================================================================
        (AliPythia8::Instance())->ReadString("StringPT:sigma = 0.335");
        (AliPythia8::Instance())->ReadString("StringZ:aLund = 0.36");
        (AliPythia8::Instance())->ReadString("StringZ:bLund = 0.56");
        (AliPythia8::Instance())->ReadString("StringFlav:probQQtoQ = 0.078");
        (AliPythia8::Instance())->ReadString("StringFlav:ProbStoUD = 0.2");
        (AliPythia8::Instance())->ReadString("StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("MultiPartonInteractions:pT0Ref = 2.12");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("BeamRemnants:remnantMode = 1");
        (AliPythia8::Instance())->ReadString("BeamRemnants:saturation = 5");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("ColourReconnection:mode = 1");
        (AliPythia8::Instance())->ReadString("ColourReconnection:allowDoubleJunRem = off");
        (AliPythia8::Instance())->ReadString("ColourReconnection:m0 = 2.9");
        (AliPythia8::Instance())->ReadString("ColourReconnection:allowJunctions = on");
        (AliPythia8::Instance())->ReadString("ColourReconnection:junctionCorrection = 1.43");
        (AliPythia8::Instance())->ReadString("ColourReconnection:timeDilationMode = 0");
        //===========================================================================
    }
    if ( lTune.EqualTo("pp-nocr") ){
        (AliPythia8::Instance())->ReadString("ColourReconnection:reconnect = off");
        (AliPythia8::Instance())->ReadString("PartonLevel:earlyResDec = off");
        (AliPythia8::Instance())->ReadString("MultipartonInteractions:pT0Ref = 2.30");
    }
    if ( lTune.EqualTo("pp-ropes") ){
        // This is a ropes setting acquired from Peter Christiansen on the Lund thing
        //===========================================================================
        (AliPythia8::Instance())->ReadString("MultiPartonInteractions:pT0Ref = 2.15");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("BeamRemnants:remnantMode = 1");
        (AliPythia8::Instance())->ReadString("BeamRemnants:saturation = 5");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("ColourReconnection:mode = 1");
        (AliPythia8::Instance())->ReadString("ColourReconnection:allowDoubleJunRem = off");
        (AliPythia8::Instance())->ReadString("ColourReconnection:m0 = 0.3");
        (AliPythia8::Instance())->ReadString("ColourReconnection:allowJunctions = on");
        (AliPythia8::Instance())->ReadString("ColourReconnection:junctionCorrection = 1.2");
        (AliPythia8::Instance())->ReadString("ColourReconnection:timeDilationMode = 2");
        (AliPythia8::Instance())->ReadString("ColourReconnection:timeDilationPar = 0.18");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("Ropewalk:RopeHadronization = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:doShoving = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:tInit = 1.5"); // Propagation time
        (AliPythia8::Instance())->ReadString("Ropewalk:deltat = 0.05");
        (AliPythia8::Instance())->ReadString("Ropewalk:tShove 0.1");
        (AliPythia8::Instance())->ReadString("Ropewalk:gAmplitude = 0."); // Set shoving strength to 0 explicitly
        (AliPythia8::Instance())->ReadString("Ropewalk:doFlavour = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:r0 = 0.5");
        (AliPythia8::Instance())->ReadString("Ropewalk:m0 = 0.2");
        (AliPythia8::Instance())->ReadString("Ropewalk:beta = 0.1");
        //===========================================================================
        // Enabling setting of vertex information.
        (AliPythia8::Instance())->ReadString("PartonVertex:setVertex = on");
        (AliPythia8::Instance())->ReadString("PartonVertex:protonRadius = 0.7");
        (AliPythia8::Instance())->ReadString("PartonVertex:emissionWidth = 0.1");
        //===========================================================================
    }
    if ( lTune.EqualTo("pp-shoving") ){
        // Enabling flavour ropes, setting model parameters.
        // The model is still untuned. These parameter values
        // are choosen for illustrative purposes.
        // This is a shoving setting acquired from Peter Christiansen on the Lund thing
        //===========================================================================
        (AliPythia8::Instance())->ReadString("Ropewalk:RopeHadronization = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:doShoving = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:doFlavour = off");
        (AliPythia8::Instance())->ReadString("Ropewalk:rCutOff = 10.0");
        (AliPythia8::Instance())->ReadString("Ropewalk:limitMom = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:pTcut = 2.0");
        (AliPythia8::Instance())->ReadString("Ropewalk:r0 = 0.41");
        (AliPythia8::Instance())->ReadString("Ropewalk:m0 = 0.2");
        (AliPythia8::Instance())->ReadString("Ropewalk:gAmplitude = 10.0");
        (AliPythia8::Instance())->ReadString("Ropewalk:gExponent = 1.0");
        (AliPythia8::Instance())->ReadString("Ropewalk:deltat = 0.1");
        (AliPythia8::Instance())->ReadString("Ropewalk:tShove = 1.");
        (AliPythia8::Instance())->ReadString("Ropewalk:deltay = 0.1");
        (AliPythia8::Instance())->ReadString("Ropewalk:tInit = 1.5");
        //===========================================================================
        // Enabling setting of vertex information.
        (AliPythia8::Instance())->ReadString("PartonVertex:setVertex = on");
        (AliPythia8::Instance())->ReadString("PartonVertex:protonRadius = 0.7");
        (AliPythia8::Instance())->ReadString("PartonVertex:emissionWidth = 0.1");
        //===========================================================================
    }

    (AliPythia8::Instance())->SetDecayLonglived();
    return gener;
}
<commit_msg>Fix bugs<commit_after>#include "AliPythia8.h"

AliGenerator* CreatePythia8Gen( TString lTune          = "pp",
                               Float_t e_cms       = 13000.
                               );

AliGenerator* AddCustomMCGenPythia8243(   TString lTune          = "pp",
                                       Float_t e_cms       = 13000.

                                       ) {
    // Add Pythia 8 generator:
    //    -kProcess=0  MB generation
    //    -kProcess=1  Jet production, pthard generation
    //    - Color reconnection = ON/OFF
    //    - Set k factor, default = 1; range of possible values in xmldoc/CouplingsAndScales.xml

    gSystem->Load("liblhapdf");

    AliGenerator *genP  = NULL;
    genP                = CreatePythia8Gen(lTune.Data(), e_cms;

    return genP;
}

AliGenerator* CreatePythia8Gen( TString lTune,
                               Float_t e_cms
                               ) {

    gSystem->Load("libpythia6");
    gSystem->Load("libEGPythia6");
    gSystem->Load("libAliPythia6");
    gSystem->Load("libpythia8");
    gSystem->Load("libAliPythia8");
    gSystem->Setenv("PYTHIA8DATA", gSystem->ExpandPathName("$ALICE_ROOT/PYTHIA8/pythia8/xmldoc"));
    gSystem->Setenv("LHAPDF",      gSystem->ExpandPathName("$ALICE_ROOT/LHAPDF"));
    gSystem->Setenv("LHAPATH",     gSystem->ExpandPathName("$ALICE_ROOT/LHAPDF/PDFsets"));

    AliPythia8 *pythia = AliPythia8::Instance();            // For ROOT6 needs to be created before AliGenPythiaPlus object, otherwise ending in "illegal instruction"
    AliGenPythiaPlus* gener = new AliGenPythiaPlus(pythia);

    std::cout << "*****************************************************************" << std::endl;
    std::cout << " Desired PYTHIA configuration: "<< lTune.Data()<< std::endl;
    std::cout << "*****************************************************************" << std::endl;
    // set process (MB)
    gener->SetProcess(kPyMbDefault);

    //Centre of mass energy
    gener->SetEnergyCMS(e_cms); // in GeV

    //random seed based on time
    (AliPythia8::Instance())->ReadString("Beams:idA = 2212");
    (AliPythia8::Instance())->ReadString("Beams:idB = 2212");
    (AliPythia8::Instance())->ReadString("PhaseSpace:pTHatMax = -1.0"); //this should be fixed in the constructor
    (AliPythia8::Instance())->ReadString("Main:timesAllowErrors = 50000");

    if ( lTune.EqualTo("pp") ){
        // Specific settings go here
        // default: do nothing, Monash 2013 will do its thing
        (AliPythia8::Instance())->ReadString(Form("Tune:pp = %d",14));
    }
    if ( lTune.EqualTo("pp-experimental") ){
        // This is me testing a few things
        TRandom3 gRand3;
        gRand3.SetSeed(0);
        Float_t lRandpT0Ref = 2.0+(((Float_t)((Int_t)(10.*gRand3.Uniform())))/10.);
        (AliPythia8::Instance())->ReadString(Form("MultipartonInteractions:pT0Ref = %.2f",lRandpT0Ref));
        std::cout << " Random pT0Ref: "<< lRandpT0Ref << std::endl;
    }
    if ( lTune.EqualTo("pp-moreqcd") ){
        std::cout << " Setting pp-moreqcd parameters..." << std::endl;
        //Paper reference: https://arxiv.org/pdf/1505.01681.pdf ("mode 0")
        //===========================================================================
        (AliPythia8::Instance())->ReadString("StringPT:sigma = 0.335");
        (AliPythia8::Instance())->ReadString("StringZ:aLund = 0.36");
        (AliPythia8::Instance())->ReadString("StringZ:bLund = 0.56");
        (AliPythia8::Instance())->ReadString("StringFlav:probQQtoQ = 0.078");
        (AliPythia8::Instance())->ReadString("StringFlav:ProbStoUD = 0.2");
        (AliPythia8::Instance())->ReadString("StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("MultiPartonInteractions:pT0Ref = 2.12");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("BeamRemnants:remnantMode = 1");
        (AliPythia8::Instance())->ReadString("BeamRemnants:saturation = 5");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("ColourReconnection:mode = 1");
        (AliPythia8::Instance())->ReadString("ColourReconnection:allowDoubleJunRem = off");
        (AliPythia8::Instance())->ReadString("ColourReconnection:m0 = 2.9");
        (AliPythia8::Instance())->ReadString("ColourReconnection:allowJunctions = on");
        (AliPythia8::Instance())->ReadString("ColourReconnection:junctionCorrection = 1.43");
        (AliPythia8::Instance())->ReadString("ColourReconnection:timeDilationMode = 0");
        //===========================================================================
    }
    if ( lTune.EqualTo("pp-nocr") ){
        (AliPythia8::Instance())->ReadString("ColourReconnection:reconnect = off");
        (AliPythia8::Instance())->ReadString("PartonLevel:earlyResDec = off");
        (AliPythia8::Instance())->ReadString("MultipartonInteractions:pT0Ref = 2.30");
    }
    if ( lTune.EqualTo("pp-ropes") ){
        // This is a ropes setting acquired from Peter Christiansen on the Lund thing
        //===========================================================================
        (AliPythia8::Instance())->ReadString("MultiPartonInteractions:pT0Ref = 2.15");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("BeamRemnants:remnantMode = 1");
        (AliPythia8::Instance())->ReadString("BeamRemnants:saturation = 5");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("ColourReconnection:mode = 1");
        (AliPythia8::Instance())->ReadString("ColourReconnection:allowDoubleJunRem = off");
        (AliPythia8::Instance())->ReadString("ColourReconnection:m0 = 0.3");
        (AliPythia8::Instance())->ReadString("ColourReconnection:allowJunctions = on");
        (AliPythia8::Instance())->ReadString("ColourReconnection:junctionCorrection = 1.2");
        (AliPythia8::Instance())->ReadString("ColourReconnection:timeDilationMode = 2");
        (AliPythia8::Instance())->ReadString("ColourReconnection:timeDilationPar = 0.18");
        //===========================================================================
        (AliPythia8::Instance())->ReadString("Ropewalk:RopeHadronization = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:doShoving = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:tInit = 1.5"); // Propagation time
        (AliPythia8::Instance())->ReadString("Ropewalk:deltat = 0.05");
        (AliPythia8::Instance())->ReadString("Ropewalk:tShove 0.1");
        (AliPythia8::Instance())->ReadString("Ropewalk:gAmplitude = 0."); // Set shoving strength to 0 explicitly
        (AliPythia8::Instance())->ReadString("Ropewalk:doFlavour = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:r0 = 0.5");
        (AliPythia8::Instance())->ReadString("Ropewalk:m0 = 0.2");
        (AliPythia8::Instance())->ReadString("Ropewalk:beta = 0.1");
        //===========================================================================
        // Enabling setting of vertex information.
        (AliPythia8::Instance())->ReadString("PartonVertex:setVertex = on");
        (AliPythia8::Instance())->ReadString("PartonVertex:protonRadius = 0.7");
        (AliPythia8::Instance())->ReadString("PartonVertex:emissionWidth = 0.1");
        //===========================================================================
    }
    if ( lTune.EqualTo("pp-shoving") ){
        // Enabling flavour ropes, setting model parameters.
        // The model is still untuned. These parameter values
        // are choosen for illustrative purposes.
        // This is a shoving setting acquired from Peter Christiansen on the Lund thing
        //===========================================================================
        (AliPythia8::Instance())->ReadString("Ropewalk:RopeHadronization = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:doShoving = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:doFlavour = off");
        (AliPythia8::Instance())->ReadString("Ropewalk:rCutOff = 10.0");
        (AliPythia8::Instance())->ReadString("Ropewalk:limitMom = on");
        (AliPythia8::Instance())->ReadString("Ropewalk:pTcut = 2.0");
        (AliPythia8::Instance())->ReadString("Ropewalk:r0 = 0.41");
        (AliPythia8::Instance())->ReadString("Ropewalk:m0 = 0.2");
        (AliPythia8::Instance())->ReadString("Ropewalk:gAmplitude = 10.0");
        (AliPythia8::Instance())->ReadString("Ropewalk:gExponent = 1.0");
        (AliPythia8::Instance())->ReadString("Ropewalk:deltat = 0.1");
        (AliPythia8::Instance())->ReadString("Ropewalk:tShove = 1.");
        (AliPythia8::Instance())->ReadString("Ropewalk:deltay = 0.1");
        (AliPythia8::Instance())->ReadString("Ropewalk:tInit = 1.5");
        //===========================================================================
        // Enabling setting of vertex information.
        (AliPythia8::Instance())->ReadString("PartonVertex:setVertex = on");
        (AliPythia8::Instance())->ReadString("PartonVertex:protonRadius = 0.7");
        (AliPythia8::Instance())->ReadString("PartonVertex:emissionWidth = 0.1");
        //===========================================================================
    }

    (AliPythia8::Instance())->SetDecayLonglived();
    return gener;
}
<|endoftext|>


<commit_before>/*
Invert a binary tree.

     4
   /   \
  2     7
 / \   / \
1   3 6   9
to
     4
   /   \
  7     2
 / \   / \
9   6 3   1
Trivia:
This problem was inspired by this original tweet by Max Howell:
Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.
*/

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
	TreeNode* invertTree(TreeNode* root) {
		if (root == NULL) {
			return root;
        }

		TreeNode *node = invertTree(root->left);
		root->left = invertTree(root->right);
		root->right = node;
    }
};
<commit_msg>task226 accepted<commit_after>/*
Invert a binary tree.

     4
   /   \
  2     7
 / \   / \
1   3 6   9
to
     4
   /   \
  7     2
 / \   / \
9   6 3   1
Trivia:
This problem was inspired by this original tweet by Max Howell:
Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.
*/

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
	TreeNode* invertTree(TreeNode* root) {
		if (root == NULL) {
			return root;
        }

		TreeNode *node = invertTree(root->left);
		root->left = invertTree(root->right);
		root->right = node;
	}
};
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

using namespace std;

template<typename T = int>
class TestCopy {
public:

    T val;

    TestCopy() {
        cout << "[CONSTR 1]" << endl;
        this->val = 0;
    }

    TestCopy(T val) {
        cout << "[CONSTR 2:" << val << "]" << endl;
        this->val = val;
    }

    TestCopy(const TestCopy &src) {
        cout << "[COPY]" << endl;
        this->val = src.val;
    }

    TestCopy(TestCopy &&src) {
        cout << "[MOVE]" << endl;
        this->val = std::move(src.val);
    }

    TestCopy &operator =(const TestCopy &src) {
        cout << "[OP=" << src.val << "]" << endl;
        this->val = src.val;
    }

    void ts() {
        cout << val << "===============" << endl;
    }

};

void runConstr() {

	TestCopy<> t1;
	TestCopy<> t2 {1};
	TestCopy<> t3 = t2;
	TestCopy<> t4 {t2};
	TestCopy<> t5 = TestCopy<>{5};
	TestCopy<> t6 = {6};
	TestCopy<> t7 = 7;

	t5.ts();
	t1 = t3;
	t1.ts();
	t1 = TestCopy<>{3};

	t3.ts();

	vector<TestCopy<>> tm;
    tm.push_back(TestCopy<>(99));
    tm[0].ts();

}
<commit_msg>header added<commit_after>//Sample provided by Thiago Massari Guedes
//April 2015
//http://www.simplycpp.com/

#include <iostream>
#include <vector>

using namespace std;

template<typename T = int>
class TestCopy {
public:

    T val;

    TestCopy() {
        cout << "[CONSTR 1]" << endl;
        this->val = 0;
    }

    TestCopy(T val) {
        cout << "[CONSTR 2:" << val << "]" << endl;
        this->val = val;
    }

    TestCopy(const TestCopy &src) {
        cout << "[COPY]" << endl;
        this->val = src.val;
    }

    TestCopy(TestCopy &&src) {
        cout << "[MOVE]" << endl;
        this->val = std::move(src.val);
    }

    TestCopy &operator =(const TestCopy &src) {
        cout << "[OP=" << src.val << "]" << endl;
        this->val = src.val;
    }

    void ts() {
        cout << val << "===============" << endl;
    }

};

void runConstr() {

	TestCopy<> t1;
	TestCopy<> t2 {1};
	TestCopy<> t3 = t2;
	TestCopy<> t4 {t2};
	TestCopy<> t5 = TestCopy<>{5};
	TestCopy<> t6 = {6};
	TestCopy<> t7 = 7;

	t5.ts();
	t1 = t3;
	t1.ts();
	t1 = TestCopy<>{3};

	t3.ts();

	vector<TestCopy<>> tm;
    tm.push_back(TestCopy<>(99));
    tm[0].ts();

}
<|endoftext|>


<commit_before>// Copyright (c) 2014-.... f0o / The Cryptocoin Revival Foundation
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "pulse.h"

/* Pulse(int64 value, int64 fee, int nHeight, unsigned int nBits) : int64 >= 0
   Returns value of proposed Block using algoritmic aproaches */
static int64 Pulse(int64 value, int64 fee, int nHeight, unsigned int nBits) {
	return value - GetBlockValue(nHeight, fee);
}

/* Pulse(int nHeight) ? true : false
   Returns true if nHeight is higher or equal to PULSE_HEIGHT */
static bool Pulse(int nHeight) {
	printf("Checking for Pulse on %u: ",nHeight);
	if( PulseI(nHeight) >= 0 ) {
		printf("True\n");
		return true;
	}
	printf("False\n");
	return false;
}

/* Pulse(CBlockIndex* prevBlock, CBlock* block) ? true : false
   Goes close to the top of CBlock::AcceptBlock
   Returns true if proposed Block matches constrains */
static bool Pulse(CBlockIndex* prevBlock, CBlock* block) {
	CBlockHeader blockHead = block->GetBlockHeader();
	CBlockIndex blockIndex = CBlockIndex(blockHead);
	CCoinsViewCache view(*pcoinsTip, true);
	int nHeight = prevBlock->nHeight+1;
	int rate = block->GetBlockTime() - prevBlock->GetBlockTime();
	int score = 0;
	int i = PulseI(nHeight);
	if( PULSE_RATE[i] > 0 && rate > PULSE_RATE[i] ) {
		return true;
	} else if( PULSE_MIN_RATE[i] > 0 && rate < PULSE_MIN_RATE[i] ) {
		return false;
	} else {
		if( PULSE_MIN_TX[i] > 0 && block->vtx.size() > PULSE_MIN_TX[i] ) {
			score++;
		}
		if( PULSE_MIN_VALUE[i] > 0 || PULSE_MIN_FEE[i] > 0 ) {
			int64 value = 0;
			int64 fee = 0;
			BOOST_FOREACH(const CTransaction& tx, block->vtx) {
				if( PULSE_MIN_FEE[i] > 0 && value > 0 ) {
					BOOST_FOREACH(const CTxIn txin, tx.vin)
						if( !view.HaveCoins(txin.prevout.hash) ) {
							return false;
						}
					fee += tx.GetValueIn(view) - tx.GetValueOut();
				}
				value += tx.GetValueOut();
			}
			value = Pulse(value, fee, nHeight, blockIndex.nBits);
			if( PULSE_FACTOR[i] == true ) {
				int64 bvalue = GetBlockValue(nHeight, 0, blockIndex.nBits);
				if( PULSE_MIN_VALUE[i] > 0 && value >= (PULSE_MIN_VALUE[i] * bvalue) ) {
					score++;
				}
				if( PULSE_MIN_FEE[i] > 0 && fee >= (PULSE_MIN_FEE[i] * bvalue) ) {
					score++;
				}
			} else {
				if( PULSE_MIN_VALUE[i] > 0 && value >= (PULSE_MIN_VALUE[i] * COIN) ) {
					score++;
				}
				if( PULSE_MIN_FEE[i] > 0 && fee >= (PULSE_MIN_FEE[i] * COIN) ) {
					score++;
				}
			}
		}
	}
	if( PULSE_EXPLICIT[i] ) {
		score++;
		if( PULSE_MIN_TX[i] > 0 )
			score--;
		if( PULSE_MIN_VALUE[i] > 0 )
			score--;
		if( PULSE_MIN_FEE[i] > 0 )
			score--;
	}
	if( score > 0 )
		return true;
	else
		return false;
}
<commit_msg>adjusted to match frycoin's getvalue<commit_after>// Copyright (c) 2014-.... f0o / The Cryptocoin Revival Foundation
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "main.h"
#include "pulse.h"

/* Pulse(int64 value, int64 fee, int nHeight, unsigned int nBits) : int64 >= 0
   Returns value of proposed Block using algoritmic aproaches */
static int64 Pulse(int64 value, int64 fee, int nHeight, unsigned int nBits) {
	return value - GetBlockValue(nHeight, fee);
}

/* Pulse(int nHeight) ? true : false
   Returns true if nHeight is higher or equal to PULSE_HEIGHT */
static bool Pulse(int nHeight) {
	printf("Checking for Pulse on %u: ",nHeight);
	if( PulseI(nHeight) >= 0 ) {
		printf("True\n");
		return true;
	}
	printf("False\n");
	return false;
}

/* Pulse(CBlockIndex* prevBlock, CBlock* block) ? true : false
   Goes close to the top of CBlock::AcceptBlock
   Returns true if proposed Block matches constrains */
static bool Pulse(CBlockIndex* prevBlock, CBlock* block) {
	CBlockHeader blockHead = block->GetBlockHeader();
	CBlockIndex blockIndex = CBlockIndex(blockHead);
	CCoinsViewCache view(*pcoinsTip, true);
	int nHeight = prevBlock->nHeight+1;
	int rate = block->GetBlockTime() - prevBlock->GetBlockTime();
	int score = 0;
	int i = PulseI(nHeight);
	if( PULSE_RATE[i] > 0 && rate > PULSE_RATE[i] ) {
		return true;
	} else if( PULSE_MIN_RATE[i] > 0 && rate < PULSE_MIN_RATE[i] ) {
		return false;
	} else {
		if( PULSE_MIN_TX[i] > 0 && block->vtx.size() > PULSE_MIN_TX[i] ) {
			score++;
		}
		if( PULSE_MIN_VALUE[i] > 0 || PULSE_MIN_FEE[i] > 0 ) {
			int64 value = 0;
			int64 fee = 0;
			BOOST_FOREACH(const CTransaction& tx, block->vtx) {
				if( PULSE_MIN_FEE[i] > 0 && value > 0 ) {
					BOOST_FOREACH(const CTxIn txin, tx.vin)
						if( !view.HaveCoins(txin.prevout.hash) ) {
							return false;
						}
					fee += tx.GetValueIn(view) - tx.GetValueOut();
				}
				value += tx.GetValueOut();
			}
			value = Pulse(value, fee, nHeight, blockIndex.nBits);
			if( PULSE_FACTOR[i] == true ) {
				int64 bvalue = GetBlockValue(nHeight, 0);
				if( PULSE_MIN_VALUE[i] > 0 && value >= (PULSE_MIN_VALUE[i] * bvalue) ) {
					score++;
				}
				if( PULSE_MIN_FEE[i] > 0 && fee >= (PULSE_MIN_FEE[i] * bvalue) ) {
					score++;
				}
			} else {
				if( PULSE_MIN_VALUE[i] > 0 && value >= (PULSE_MIN_VALUE[i] * COIN) ) {
					score++;
				}
				if( PULSE_MIN_FEE[i] > 0 && fee >= (PULSE_MIN_FEE[i] * COIN) ) {
					score++;
				}
			}
		}
	}
	if( PULSE_EXPLICIT[i] ) {
		score++;
		if( PULSE_MIN_TX[i] > 0 )
			score--;
		if( PULSE_MIN_VALUE[i] > 0 )
			score--;
		if( PULSE_MIN_FEE[i] > 0 )
			score--;
	}
	if( score > 0 )
		return true;
	else
		return false;
}
<|endoftext|>


<commit_before>#include <turbodbc_numpy/set_numpy_parameters.h>

#include <turbodbc_numpy/ndarrayobject.h>

#include <turbodbc/errors.h>
#include <turbodbc/make_description.h>
#include <turbodbc/type_code.h>
#include <turbodbc/time_helpers.h>

#include <iostream>
#include <algorithm>
#include <sstream>

#ifdef _WIN32
#include <windows.h>
#endif
#include <sql.h>

namespace turbodbc_numpy {

namespace {

    struct parameter_converter {
        parameter_converter(pybind11::array const & data, pybind11::array_t<bool> const & mask) :
            data(data),
            mask(mask)
        {}

        virtual void initialize(turbodbc::bound_parameter_set & parameters, std::size_t parameter_index) = 0;
        virtual void set_batch(turbodbc::parameter & parameter, std::size_t start, std::size_t elements) = 0;

        virtual ~parameter_converter() = default;

        pybind11::array const & data;
        pybind11::array_t<bool> const & mask;
    };

    template <typename Value>
    struct binary_converter : public parameter_converter {
        binary_converter(pybind11::array const & data, pybind11::array_t<bool> const & mask, turbodbc::type_code type) :
            parameter_converter(data, mask),
            type(type)
        {}

        void initialize(turbodbc::bound_parameter_set & parameters, std::size_t parameter_index) final
        {
            parameters.rebind(parameter_index, turbodbc::make_description(type, 0));
        }

        void set_batch(turbodbc::parameter & parameter, std::size_t start, std::size_t elements) final
        {
            auto data_ptr = data.unchecked<Value, 1>().data(0);
            auto & buffer = parameter.get_buffer();
            std::memcpy(buffer.data_pointer(), data_ptr + start, elements * sizeof(Value));
            if (mask.size() != 1) {
                auto const indicator = buffer.indicator_pointer();
                auto const mask_start = mask.unchecked<1>().data(start);
                for (std::size_t i = 0; i != elements; ++i) {
                    indicator[i] = (mask_start[i] == NPY_TRUE) ? SQL_NULL_DATA : sizeof(Value);
                }
            } else {
                intptr_t const sql_mask = (*mask.data() == NPY_TRUE) ? SQL_NULL_DATA : sizeof(Value);
                std::fill_n(buffer.indicator_pointer(), elements, sql_mask);
            }
        }
    private:
        turbodbc::type_code type;
    };

    struct timestamp_converter : public parameter_converter {
        timestamp_converter(pybind11::array const & data, pybind11::array_t<bool> const & mask) :
            parameter_converter(data, mask)
        {}

        void initialize(turbodbc::bound_parameter_set & parameters, std::size_t parameter_index) final
        {
            parameters.rebind(parameter_index, turbodbc::make_description(turbodbc::type_code::timestamp, 0));
        }

        void set_batch(turbodbc::parameter & parameter, std::size_t start, std::size_t elements) final
        {
            auto & buffer = parameter.get_buffer();
            auto const data_start = data.unchecked<std::int64_t, 1>().data(start);

            bool const uses_mask = (mask.size() != 1);
            if (uses_mask) {
                auto const mask_start = mask.unchecked<1>().data(start);
                for (std::size_t i = 0; i != elements; ++i) {
                    auto element = buffer[i];
                    if (mask_start[i] == NPY_TRUE) {
                        element.indicator = SQL_NULL_DATA;
                    } else {
                        turbodbc::microseconds_to_timestamp(data_start[i], element.data_pointer);
                        element.indicator = sizeof(SQL_TIMESTAMP_STRUCT);
                    }
                }
            } else {
                if (*mask.data() == NPY_TRUE) {
                    std::fill_n(buffer.indicator_pointer(), elements, static_cast<std::int64_t>(SQL_NULL_DATA));
                } else {
                    for (std::size_t i = 0; i != elements; ++i) {
                        auto element = buffer[i];
                        turbodbc::microseconds_to_timestamp(data_start[i], element.data_pointer);
                        element.indicator = sizeof(SQL_TIMESTAMP_STRUCT);
                    }
                }
            }
        }
    };

    struct date_converter : public parameter_converter {
        date_converter(pybind11::array const & data, pybind11::array_t<bool> const & mask) :
            parameter_converter(data, mask)
        {}

        void initialize(turbodbc::bound_parameter_set & parameters, std::size_t parameter_index) final
        {
            parameters.rebind(parameter_index, turbodbc::make_description(turbodbc::type_code::date, 0));
        }

        void set_batch(turbodbc::parameter & parameter, std::size_t start, std::size_t elements) final
        {
            auto & buffer = parameter.get_buffer();
            auto const data_start = data.unchecked<std::int64_t, 1>().data(start);

            bool const uses_mask = (mask.size() != 1);
            if (uses_mask) {
                auto const mask_start = mask.unchecked<1>().data(start);
                for (std::size_t i = 0; i != elements; ++i) {
                    auto element = buffer[i];
                    if (mask_start[i] == NPY_TRUE) {
                        element.indicator = SQL_NULL_DATA;
                    } else {
                        turbodbc::days_to_date(data_start[i], element.data_pointer);
                        element.indicator = sizeof(SQL_DATE_STRUCT);
                    }
                }
            } else {
                if (*mask.data() == NPY_TRUE) {
                    std::fill_n(buffer.indicator_pointer(), elements, static_cast<std::int64_t>(SQL_NULL_DATA));
                } else {
                    for (std::size_t i = 0; i != elements; ++i) {
                        auto element = buffer[i];
                        turbodbc::days_to_date(data_start[i], element.data_pointer);
                        element.indicator = sizeof(SQL_DATE_STRUCT);
                    }
                }
            }
        }
    };

    std::vector<std::unique_ptr<parameter_converter>> make_converters(std::vector<std::tuple<pybind11::array, pybind11::array_t<bool>, std::string>> const & columns)
    {
        std::vector<std::unique_ptr<parameter_converter>> converters;

        for (std::size_t i = 0; i != columns.size(); ++i) {
            auto const & data = std::get<0>(columns[i]);
            auto const & mask = std::get<1>(columns[i]);
            auto const & dtype = std::get<2>(columns[i]);
            if (dtype == "int64") {
               converters.emplace_back(new binary_converter<std::int64_t>(data, mask, turbodbc::type_code::integer));
            } else if (dtype == "float64") {
                converters.emplace_back(new binary_converter<double>(data, mask, turbodbc::type_code::floating_point));
            } else if (dtype == "datetime64[us]") {
                converters.emplace_back(new timestamp_converter(data, mask));
            } else if (dtype == "datetime64[D]") {
                converters.emplace_back(new date_converter(data, mask));
            } else {
                std::ostringstream message;
                message << "Unsupported NumPy dtype for column " << (i + 1) << " of " << columns.size();
                message << " (unsupported type: " << dtype << ")";
                throw turbodbc::interface_error(message.str());
            }
        }

        return converters;
    }

}

void set_numpy_parameters(turbodbc::bound_parameter_set & parameters, std::vector<std::tuple<pybind11::array, pybind11::array_t<bool>, std::string>> const & columns)
{
    if (parameters.number_of_parameters() != columns.size()) {
        throw turbodbc::interface_error("Number of passed columns is not equal to the number of parameters");
    }

    if (columns.size() == 0) {
        return;
    }

    auto converters = make_converters(columns);
    for (std::size_t i = 0; i != columns.size(); ++i) {
        converters[i]->initialize(parameters, i);
    }

    auto const total_sets = std::get<0>(columns.front()).size();

    for (std::size_t start = 0; start < total_sets; start += parameters.buffered_sets()) {
        auto const in_this_batch = std::min(parameters.buffered_sets(), total_sets - start);
        for (std::size_t i = 0; i != columns.size(); ++i) {
            converters[i]->set_batch(*parameters.get_parameters()[i], start, in_this_batch);
        }
        parameters.execute_batch(in_this_batch);
    }
}

}<commit_msg>Extract common code to datetime64 converter<commit_after>#include <turbodbc_numpy/set_numpy_parameters.h>

#include <turbodbc_numpy/ndarrayobject.h>

#include <turbodbc/errors.h>
#include <turbodbc/make_description.h>
#include <turbodbc/type_code.h>
#include <turbodbc/time_helpers.h>

#include <iostream>
#include <algorithm>
#include <sstream>

#ifdef _WIN32
#include <windows.h>
#endif
#include <sql.h>

namespace turbodbc_numpy {

namespace {

    struct parameter_converter {
        parameter_converter(pybind11::array const & data, pybind11::array_t<bool> const & mask) :
            data(data),
            mask(mask)
        {}

        virtual void initialize(turbodbc::bound_parameter_set & parameters, std::size_t parameter_index) = 0;
        virtual void set_batch(turbodbc::parameter & parameter, std::size_t start, std::size_t elements) = 0;

        virtual ~parameter_converter() = default;

        pybind11::array const & data;
        pybind11::array_t<bool> const & mask;
    };

    template <typename Value>
    struct binary_converter : public parameter_converter {
        binary_converter(pybind11::array const & data, pybind11::array_t<bool> const & mask, turbodbc::type_code type) :
            parameter_converter(data, mask),
            type(type)
        {}

        void initialize(turbodbc::bound_parameter_set & parameters, std::size_t parameter_index) final
        {
            parameters.rebind(parameter_index, turbodbc::make_description(type, 0));
        }

        void set_batch(turbodbc::parameter & parameter, std::size_t start, std::size_t elements) final
        {
            auto data_ptr = data.unchecked<Value, 1>().data(0);
            auto & buffer = parameter.get_buffer();
            std::memcpy(buffer.data_pointer(), data_ptr + start, elements * sizeof(Value));
            if (mask.size() != 1) {
                auto const indicator = buffer.indicator_pointer();
                auto const mask_start = mask.unchecked<1>().data(start);
                for (std::size_t i = 0; i != elements; ++i) {
                    indicator[i] = (mask_start[i] == NPY_TRUE) ? SQL_NULL_DATA : sizeof(Value);
                }
            } else {
                intptr_t const sql_mask = (*mask.data() == NPY_TRUE) ? SQL_NULL_DATA : sizeof(Value);
                std::fill_n(buffer.indicator_pointer(), elements, sql_mask);
            }
        }
    private:
        turbodbc::type_code type;
    };

    struct datetime64_converter : public parameter_converter {
        datetime64_converter(pybind11::array const & data,
                             pybind11::array_t<bool> const & mask,
                             turbodbc::type_code code,
                             std::intptr_t element_size) :
            parameter_converter(data, mask),
            code(code),
            element_size(element_size)
        {}

        void initialize(turbodbc::bound_parameter_set & parameters, std::size_t parameter_index) final
        {
            parameters.rebind(parameter_index, turbodbc::make_description(code, 0));
        }

        void set_batch(turbodbc::parameter & parameter, std::size_t start, std::size_t elements) final
        {
            auto & buffer = parameter.get_buffer();
            auto const data_start = data.unchecked<std::int64_t, 1>().data(start);

            bool const uses_mask = (mask.size() != 1);
            if (uses_mask) {
                auto const mask_start = mask.unchecked<1>().data(start);
                for (std::size_t i = 0; i != elements; ++i) {
                    auto element = buffer[i];
                    if (mask_start[i] == NPY_TRUE) {
                        element.indicator = SQL_NULL_DATA;
                    } else {
                        convert(data_start[i], element.data_pointer);
                        element.indicator = element_size;
                    }
                }
            } else {
                if (*mask.data() == NPY_TRUE) {
                    std::fill_n(buffer.indicator_pointer(), elements, static_cast<std::int64_t>(SQL_NULL_DATA));
                } else {
                    for (std::size_t i = 0; i != elements; ++i) {
                        auto element = buffer[i];
                        convert(data_start[i], element.data_pointer);
                        element.indicator = element_size;
                    }
                }
            }
        }

        virtual void convert(std::int64_t data, char * destination) = 0;

        turbodbc::type_code code;
        std::intptr_t element_size;
    };

    struct timestamp_converter : public datetime64_converter {
        timestamp_converter(pybind11::array const & data, pybind11::array_t<bool> const & mask) :
            datetime64_converter(data, mask, turbodbc::type_code::timestamp, sizeof(SQL_TIMESTAMP_STRUCT))
        {}

        virtual void convert(std::int64_t data, char * destination) {
            turbodbc::microseconds_to_timestamp(data, destination);
        }
    };

    struct date_converter : public datetime64_converter {
        date_converter(pybind11::array const & data, pybind11::array_t<bool> const & mask) :
            datetime64_converter(data, mask, turbodbc::type_code::date, sizeof(SQL_DATE_STRUCT))
        {}

        virtual void convert(std::int64_t data, char * destination) {
            turbodbc::days_to_date(data, destination);
        }
    };

    std::vector<std::unique_ptr<parameter_converter>> make_converters(std::vector<std::tuple<pybind11::array, pybind11::array_t<bool>, std::string>> const & columns)
    {
        std::vector<std::unique_ptr<parameter_converter>> converters;

        for (std::size_t i = 0; i != columns.size(); ++i) {
            auto const & data = std::get<0>(columns[i]);
            auto const & mask = std::get<1>(columns[i]);
            auto const & dtype = std::get<2>(columns[i]);
            if (dtype == "int64") {
               converters.emplace_back(new binary_converter<std::int64_t>(data, mask, turbodbc::type_code::integer));
            } else if (dtype == "float64") {
                converters.emplace_back(new binary_converter<double>(data, mask, turbodbc::type_code::floating_point));
            } else if (dtype == "datetime64[us]") {
                converters.emplace_back(new timestamp_converter(data, mask));
            } else if (dtype == "datetime64[D]") {
                converters.emplace_back(new date_converter(data, mask));
            } else {
                std::ostringstream message;
                message << "Unsupported NumPy dtype for column " << (i + 1) << " of " << columns.size();
                message << " (unsupported type: " << dtype << ")";
                throw turbodbc::interface_error(message.str());
            }
        }

        return converters;
    }

}

void set_numpy_parameters(turbodbc::bound_parameter_set & parameters, std::vector<std::tuple<pybind11::array, pybind11::array_t<bool>, std::string>> const & columns)
{
    if (parameters.number_of_parameters() != columns.size()) {
        throw turbodbc::interface_error("Number of passed columns is not equal to the number of parameters");
    }

    if (columns.size() == 0) {
        return;
    }

    auto converters = make_converters(columns);
    for (std::size_t i = 0; i != columns.size(); ++i) {
        converters[i]->initialize(parameters, i);
    }

    auto const total_sets = std::get<0>(columns.front()).size();

    for (std::size_t start = 0; start < total_sets; start += parameters.buffered_sets()) {
        auto const in_this_batch = std::min(parameters.buffered_sets(), total_sets - start);
        for (std::size_t i = 0; i != columns.size(); ++i) {
            converters[i]->set_batch(*parameters.get_parameters()[i], start, in_this_batch);
        }
        parameters.execute_batch(in_this_batch);
    }
}

}<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  animSequencer.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "animSequencer.h"
#include <float.h>
#include <math.h>

namespace Oryol {
namespace _priv {

//------------------------------------------------------------------------------
static void
checkValidateItem(animSequencer::item& item) {
    if (item.absStartTime >= item.absEndTime) {
        item.valid = false;
    }
}

//------------------------------------------------------------------------------
bool
animSequencer::add(double curTime, AnimJobId jobId, const AnimJob& job, float clipDuration) {
    if (this->items.Full()) {
        // no more free job slots
        return false;
    }

    // find insertion position
    double absStartTime = curTime + job.StartTime;
    int insertIndex;
    int numItems = this->items.Size();
    for (insertIndex = 0; insertIndex < numItems; insertIndex++) {
        const auto& curItem = this->items[insertIndex];
        if (!curItem.valid) {
            // skip invalid items
            continue;
        }
        else if (job.TrackIndex > curItem.trackIndex) {
            // skip items on smaller track indices
            continue;
        }
        else if ((job.TrackIndex==curItem.trackIndex) && (absStartTime>curItem.absStartTime)) {
            // skip items on same track with smaller start time
            continue;
        }
        else {
            // current item has higher track index, or is on same track
            // with higher or equal start time, insert the new job right before
            break;
        }
    }
    item newItem;
    newItem.id = jobId;
    newItem.valid = true;
    newItem.clipIndex = job.ClipIndex;
    newItem.trackIndex = job.TrackIndex;
    newItem.mixWeight = job.MixWeight;
    newItem.absStartTime = absStartTime;
    newItem.absFadeInTime = absStartTime + job.FadeIn;
    if (job.Duration > 0.0f) {
        if (job.DurationIsLoopCount) {
            newItem.absEndTime = absStartTime + job.Duration*clipDuration;
        }
        else {
            newItem.absEndTime = absStartTime + job.Duration;
        }
        newItem.absFadeOutTime = newItem.absEndTime - job.FadeOut;
    }
    else {
        // infinite duration
        newItem.absEndTime = DBL_MAX;
        newItem.absFadeOutTime = DBL_MAX;
    }
    this->items.Insert(insertIndex, newItem);

    // fix the start and end times for all jobs on the same
    // track that overlap with the new job, this may lead to
    // some jobs becoming infinitly short, these will no longer
    // take part in mixing, and will eventually be removed
    // when the play cursor passes over them
    numItems = this->items.Size();
    for (int i = 0; i < numItems; i++) {
        if (i == insertIndex) {
            // this is the item that was just inserted
            continue;
        }
        else {
            auto& curItem = this->items[i];
            if (curItem.valid && (newItem.trackIndex == curItem.trackIndex)) {
                // if before the new item, check overlap and trim the end if yes
                if ((i < insertIndex) && (curItem.absEndTime >= newItem.absFadeInTime)) {
                    curItem.absEndTime = newItem.absFadeInTime;
                    curItem.absFadeOutTime = newItem.absStartTime;
                }
                // if after the new item, check overlap and trim start if yes
                if ((i > insertIndex) && (curItem.absStartTime <= newItem.absFadeOutTime)) {
                    curItem.absStartTime = newItem.absFadeOutTime;
                    curItem.absFadeInTime = newItem.absEndTime;
                }
                // if both sides were clipped, it means the current item
                // is completely 'obscured' and needs to be removed
                // during the next 'garbage collection'
                checkValidateItem(curItem);
            }
        }
    }
    return true;
}

//------------------------------------------------------------------------------
static void
checkStopItem(double curTime, bool allowFadeOut, animSequencer::item& item) {
    if (curTime < item.absStartTime) {
        // the item is in the future, can mark it as invalid
        item.valid = false;
    }
    else if (curTime < item.absEndTime) {
        // the item overlaps curTime, clamp the end time
        if (allowFadeOut) {
            double fadeDuration = item.absEndTime - item.absFadeOutTime;
            item.absFadeOutTime = curTime;
            item.absEndTime = curTime + fadeDuration;
        }
        else {
            item.absFadeOutTime = curTime;
            item.absEndTime = curTime;
        }
        checkValidateItem(item);
    }
}

//------------------------------------------------------------------------------
void
animSequencer::stop(double curTime, AnimJobId jobId, bool allowFadeOut) {
    for (auto& curItem : this->items) {
        if (curItem.id == jobId) {
            checkStopItem(curTime, allowFadeOut, curItem);
            break;
        }
    }
}

//------------------------------------------------------------------------------
void
animSequencer::stopTrack(double curTime, int trackIndex, bool allowFadeOut) {
    for (auto& curItem : this->items) {
        if (curItem.trackIndex == trackIndex) {
            checkStopItem(curTime, allowFadeOut, curItem);
        }
    }
}

//------------------------------------------------------------------------------
void
animSequencer::stopAll(double curTime, bool allowFadeOut) {
    for (auto& curItem : this->items) {
        checkStopItem(curTime, allowFadeOut, curItem);
    }
}

//------------------------------------------------------------------------------
void
animSequencer::garbageCollect(double curTime) {
    // remove all invalid items, and items where absEndTime is < curTime
    for (int i = this->items.Size() - 1; i >= 0; i--) {
        const auto& item = this->items[i];
        if (!item.valid || (item.absEndTime < curTime)) {
            this->items.Erase(i);
        }
    }
}

//------------------------------------------------------------------------------
static float fadeWeight(float w0, float w1, double t, double t0, double t1) {
    // compute a fade-in or fade-out mixing weight
    double dt = t1 - t0;
    if ((dt > -0.000001) || (dt < 0.000001)) {
        return w0;  // just make sure we don't divide by zero
    }
    float rt = (float) ((t - t0) / (t1 - t0));
    if (rt < 0.0f) rt = 0.0f;
    else if (rt > 1.0f) rt = 1.0f;
    return w0 + rt*(w1-w0);
}

//------------------------------------------------------------------------------
static int clampKeyIndex(int keyIndex, int clipNumKeys) {
    // FIXME: handle clamp vs loop here
    o_assert_dbg(clipNumKeys > 0);
    keyIndex %= clipNumKeys;
    if (keyIndex < 0) {
        keyIndex += clipNumKeys;
    }
    return keyIndex;
}

//------------------------------------------------------------------------------
bool
animSequencer::eval(const AnimLibrary* lib, double curTime, float* sampleBuffer, int numSamples) {

    // for each item which crosses the current play time...
    float weightSum = 0.0f;
    int numProcessedItems = 0;
    for (const auto& item : this->items) {
        // if summed weight has reached 1.0 we can stop
        if (weightSum >= 1.0f) {
            break;
        }
        // skip current item if it isn't valid or doesn't cross the play cursor
        if (!item.valid || (item.absStartTime > curTime) || (item.absEndTime <= curTime)) {
            continue;
        }
        const AnimClip& clip = lib->Clips[item.clipIndex];

        // compute the mixing weight
        float weight = item.mixWeight;
        if (curTime < item.absFadeInTime) {
            weight = fadeWeight(0.0f, weight, curTime, item.absStartTime, item.absFadeInTime);
        }
        else if (curTime > item.absFadeOutTime) {
            weight = fadeWeight(weight, 0.0f, curTime, item.absFadeOutTime, item.absEndTime);
        }

        // compute sampling parameters
        int key0 = 0;
        int key1 = 0;
        float keyPos = 0.0f;
        if (clip.Length > 0) {
            o_assert_dbg(clip.KeyDuration > 0.0f);
            const float clipDuration = clip.KeyDuration * clip.Length;
            const float clipTime = curTime - item.absStartTime;
            key0 = clampKeyIndex((clipTime / clip.KeyDuration), clip.Length);
            key1 = clampKeyIndex(key0 + 1, clip.Length);
            // position between key0 and key1: 0..1
            keyPos = fmodf(fmodf(clipTime, clipDuration), clip.KeyDuration) / clip.KeyDuration;
        }

        // only sample, or sample and mix with previous track?
        const float* src0 = clip.Keys.Empty() ? nullptr : &(clip.Keys[key0 * clip.KeyStride]);
        const float* src1 = clip.Keys.Empty() ? nullptr : &(clip.Keys[key1 * clip.KeyStride]);
        float* dst = sampleBuffer;
        #if ORYOL_DEBUG
        const float* dstEnd = dst + numSamples;
        #endif
        float s0, s1, v0, v1;
        if (0 == numProcessedItems) {
            // first processed track, only need to sample, not mix with previous track
            for (const auto& curve : clip.Curves) {
                const int num = curve.NumValues;
                if (curve.Static) {
                    if (num >= 1) *dst++ = curve.StaticValue[0];
                    if (num >= 2) *dst++ = curve.StaticValue[1];
                    if (num >= 3) *dst++ = curve.StaticValue[2];
                    if (num >= 4) *dst++ = curve.StaticValue[3];
                }
                else {
                    // NOTE: simply use linear interpolation for quaternions,
                    // just assume they are close together
                    o_assert_dbg(src0 && src1);
                    if (num >= 1) { v0=*src0++; v1=*src1++; *dst++=v0+(v1-v0)*keyPos; }
                    if (num >= 2) { v0=*src0++; v1=*src1++; *dst++=v0+(v1-v0)*keyPos; }
                    if (num >= 3) { v0=*src0++; v1=*src1++; *dst++=v0+(v1-v0)*keyPos; }
                    if (num >= 4) { v0=*src0++; v1=*src1++; *dst++=v0+(v1-v0)*keyPos; }
                }
            }
        }
        else {
            // evaluate track and mix with previous sampling+mixing result
            // FIXME: may need to do proper quaternion slerp when mixing
            // rotation curves
            for (const auto& curve : clip.Curves) {
                const int num = curve.NumValues;
                if (curve.Static) {
                    if (num >= 1) { s0=*dst; s1=curve.StaticValue[0]; *dst++=s0+(s1-s0)*weight; }
                    if (num >= 2) { s0=*dst; s1=curve.StaticValue[1]; *dst++=s0+(s1-s0)*weight; }
                    if (num >= 3) { s0=*dst; s1=curve.StaticValue[2]; *dst++=s0+(s1-s0)*weight; }
                    if (num >= 4) { s0=*dst; s1=curve.StaticValue[2]; *dst++=s0+(s1-s0)*weight; }
                }
                else {
                    o_assert_dbg(src0 && src1);
                    if (num >= 1) {
                        v0 = *src0++; v1 = *src1++;
                        s0 = *dst; s1 = v0 + (v1 - v0) * keyPos;
                        *dst++ = s0 + (s1 - s0) * weight;
                    }
                    if (num >= 2) {
                        v0 = *src0++; v1 = *src1++;
                        s0 = *dst; s1 = v0 + (v1 - v0) * keyPos;
                        *dst++ = s0 + (s1 - s0) * weight;
                    }
                    if (num >= 3) {
                        v0 = *src0++; v1 = *src1++;
                        s0 = *dst; s1 = v0 + (v1 - v0) * keyPos;
                        *dst++ = s0 + (s1 - s0) * weight;
                    }
                    if (num >= 4) {
                        v0 = *src0++; v1 = *src1++;
                        s0 = *dst; s1 = v0 + (v1 - v0) * keyPos;
                        *dst++ = s0 + (s1 - s0) * weight;
                    }
                }
            }
        }
        o_assert_dbg(dst == dstEnd);
        #if ORYOL_DEBUG
        if (src0 && src1) {
            o_assert_dbg(src0 == (&(clip.Keys[key0 * clip.KeyStride]) + clip.KeyStride));
            o_assert_dbg(src1 == (&(clip.Keys[key1 * clip.KeyStride]) + clip.KeyStride));
        }
        #endif
        weightSum += weight;
    }
    return numProcessedItems > 0;
}

} // namespace _priv
} // namespace Oryol
<commit_msg>Fixed VS warnings<commit_after>//------------------------------------------------------------------------------
//  animSequencer.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "animSequencer.h"
#include <float.h>
#include <math.h>

namespace Oryol {
namespace _priv {

//------------------------------------------------------------------------------
static void
checkValidateItem(animSequencer::item& item) {
    if (item.absStartTime >= item.absEndTime) {
        item.valid = false;
    }
}

//------------------------------------------------------------------------------
bool
animSequencer::add(double curTime, AnimJobId jobId, const AnimJob& job, float clipDuration) {
    if (this->items.Full()) {
        // no more free job slots
        return false;
    }

    // find insertion position
    double absStartTime = curTime + job.StartTime;
    int insertIndex;
    int numItems = this->items.Size();
    for (insertIndex = 0; insertIndex < numItems; insertIndex++) {
        const auto& curItem = this->items[insertIndex];
        if (!curItem.valid) {
            // skip invalid items
            continue;
        }
        else if (job.TrackIndex > curItem.trackIndex) {
            // skip items on smaller track indices
            continue;
        }
        else if ((job.TrackIndex==curItem.trackIndex) && (absStartTime>curItem.absStartTime)) {
            // skip items on same track with smaller start time
            continue;
        }
        else {
            // current item has higher track index, or is on same track
            // with higher or equal start time, insert the new job right before
            break;
        }
    }
    item newItem;
    newItem.id = jobId;
    newItem.valid = true;
    newItem.clipIndex = job.ClipIndex;
    newItem.trackIndex = job.TrackIndex;
    newItem.mixWeight = job.MixWeight;
    newItem.absStartTime = absStartTime;
    newItem.absFadeInTime = absStartTime + job.FadeIn;
    if (job.Duration > 0.0f) {
        if (job.DurationIsLoopCount) {
            newItem.absEndTime = absStartTime + job.Duration*clipDuration;
        }
        else {
            newItem.absEndTime = absStartTime + job.Duration;
        }
        newItem.absFadeOutTime = newItem.absEndTime - job.FadeOut;
    }
    else {
        // infinite duration
        newItem.absEndTime = DBL_MAX;
        newItem.absFadeOutTime = DBL_MAX;
    }
    this->items.Insert(insertIndex, newItem);

    // fix the start and end times for all jobs on the same
    // track that overlap with the new job, this may lead to
    // some jobs becoming infinitly short, these will no longer
    // take part in mixing, and will eventually be removed
    // when the play cursor passes over them
    numItems = this->items.Size();
    for (int i = 0; i < numItems; i++) {
        if (i == insertIndex) {
            // this is the item that was just inserted
            continue;
        }
        else {
            auto& curItem = this->items[i];
            if (curItem.valid && (newItem.trackIndex == curItem.trackIndex)) {
                // if before the new item, check overlap and trim the end if yes
                if ((i < insertIndex) && (curItem.absEndTime >= newItem.absFadeInTime)) {
                    curItem.absEndTime = newItem.absFadeInTime;
                    curItem.absFadeOutTime = newItem.absStartTime;
                }
                // if after the new item, check overlap and trim start if yes
                if ((i > insertIndex) && (curItem.absStartTime <= newItem.absFadeOutTime)) {
                    curItem.absStartTime = newItem.absFadeOutTime;
                    curItem.absFadeInTime = newItem.absEndTime;
                }
                // if both sides were clipped, it means the current item
                // is completely 'obscured' and needs to be removed
                // during the next 'garbage collection'
                checkValidateItem(curItem);
            }
        }
    }
    return true;
}

//------------------------------------------------------------------------------
static void
checkStopItem(double curTime, bool allowFadeOut, animSequencer::item& item) {
    if (curTime < item.absStartTime) {
        // the item is in the future, can mark it as invalid
        item.valid = false;
    }
    else if (curTime < item.absEndTime) {
        // the item overlaps curTime, clamp the end time
        if (allowFadeOut) {
            double fadeDuration = item.absEndTime - item.absFadeOutTime;
            item.absFadeOutTime = curTime;
            item.absEndTime = curTime + fadeDuration;
        }
        else {
            item.absFadeOutTime = curTime;
            item.absEndTime = curTime;
        }
        checkValidateItem(item);
    }
}

//------------------------------------------------------------------------------
void
animSequencer::stop(double curTime, AnimJobId jobId, bool allowFadeOut) {
    for (auto& curItem : this->items) {
        if (curItem.id == jobId) {
            checkStopItem(curTime, allowFadeOut, curItem);
            break;
        }
    }
}

//------------------------------------------------------------------------------
void
animSequencer::stopTrack(double curTime, int trackIndex, bool allowFadeOut) {
    for (auto& curItem : this->items) {
        if (curItem.trackIndex == trackIndex) {
            checkStopItem(curTime, allowFadeOut, curItem);
        }
    }
}

//------------------------------------------------------------------------------
void
animSequencer::stopAll(double curTime, bool allowFadeOut) {
    for (auto& curItem : this->items) {
        checkStopItem(curTime, allowFadeOut, curItem);
    }
}

//------------------------------------------------------------------------------
void
animSequencer::garbageCollect(double curTime) {
    // remove all invalid items, and items where absEndTime is < curTime
    for (int i = this->items.Size() - 1; i >= 0; i--) {
        const auto& item = this->items[i];
        if (!item.valid || (item.absEndTime < curTime)) {
            this->items.Erase(i);
        }
    }
}

//------------------------------------------------------------------------------
static float fadeWeight(float w0, float w1, double t, double t0, double t1) {
    // compute a fade-in or fade-out mixing weight
    double dt = t1 - t0;
    if ((dt > -0.000001) || (dt < 0.000001)) {
        return w0;  // just make sure we don't divide by zero
    }
    float rt = (float) ((t - t0) / (t1 - t0));
    if (rt < 0.0f) rt = 0.0f;
    else if (rt > 1.0f) rt = 1.0f;
    return w0 + rt*(w1-w0);
}

//------------------------------------------------------------------------------
static int clampKeyIndex(int keyIndex, int clipNumKeys) {
    // FIXME: handle clamp vs loop here
    o_assert_dbg(clipNumKeys > 0);
    keyIndex %= clipNumKeys;
    if (keyIndex < 0) {
        keyIndex += clipNumKeys;
    }
    return keyIndex;
}

//------------------------------------------------------------------------------
bool
animSequencer::eval(const AnimLibrary* lib, double curTime, float* sampleBuffer, int numSamples) {

    // for each item which crosses the current play time...
    float weightSum = 0.0f;
    int numProcessedItems = 0;
    for (const auto& item : this->items) {
        // if summed weight has reached 1.0 we can stop
        if (weightSum >= 1.0f) {
            break;
        }
        // skip current item if it isn't valid or doesn't cross the play cursor
        if (!item.valid || (item.absStartTime > curTime) || (item.absEndTime <= curTime)) {
            continue;
        }
        const AnimClip& clip = lib->Clips[item.clipIndex];

        // compute the mixing weight
        float weight = item.mixWeight;
        if (curTime < item.absFadeInTime) {
            weight = fadeWeight(0.0f, weight, curTime, item.absStartTime, item.absFadeInTime);
        }
        else if (curTime > item.absFadeOutTime) {
            weight = fadeWeight(weight, 0.0f, curTime, item.absFadeOutTime, item.absEndTime);
        }

        // compute sampling parameters
        int key0 = 0;
        int key1 = 0;
        float keyPos = 0.0f;
        if (clip.Length > 0) {
            o_assert_dbg(clip.KeyDuration > 0.0f);
            const float clipDuration = clip.KeyDuration * clip.Length;
            const float clipTime = float(curTime - item.absStartTime);
            key0 = clampKeyIndex(int(clipTime / clip.KeyDuration), clip.Length);
            key1 = clampKeyIndex(key0 + 1, clip.Length);
            // position between key0 and key1: 0..1
            keyPos = fmodf(fmodf(clipTime, clipDuration), clip.KeyDuration) / clip.KeyDuration;
        }

        // only sample, or sample and mix with previous track?
        const float* src0 = clip.Keys.Empty() ? nullptr : &(clip.Keys[key0 * clip.KeyStride]);
        const float* src1 = clip.Keys.Empty() ? nullptr : &(clip.Keys[key1 * clip.KeyStride]);
        float* dst = sampleBuffer;
        #if ORYOL_DEBUG
        const float* dstEnd = dst + numSamples;
        #endif
        float s0, s1, v0, v1;
        if (0 == numProcessedItems) {
            // first processed track, only need to sample, not mix with previous track
            for (const auto& curve : clip.Curves) {
                const int num = curve.NumValues;
                if (curve.Static) {
                    if (num >= 1) *dst++ = curve.StaticValue[0];
                    if (num >= 2) *dst++ = curve.StaticValue[1];
                    if (num >= 3) *dst++ = curve.StaticValue[2];
                    if (num >= 4) *dst++ = curve.StaticValue[3];
                }
                else {
                    // NOTE: simply use linear interpolation for quaternions,
                    // just assume they are close together
                    o_assert_dbg(src0 && src1);
                    if (num >= 1) { v0=*src0++; v1=*src1++; *dst++=v0+(v1-v0)*keyPos; }
                    if (num >= 2) { v0=*src0++; v1=*src1++; *dst++=v0+(v1-v0)*keyPos; }
                    if (num >= 3) { v0=*src0++; v1=*src1++; *dst++=v0+(v1-v0)*keyPos; }
                    if (num >= 4) { v0=*src0++; v1=*src1++; *dst++=v0+(v1-v0)*keyPos; }
                }
            }
        }
        else {
            // evaluate track and mix with previous sampling+mixing result
            // FIXME: may need to do proper quaternion slerp when mixing
            // rotation curves
            for (const auto& curve : clip.Curves) {
                const int num = curve.NumValues;
                if (curve.Static) {
                    if (num >= 1) { s0=*dst; s1=curve.StaticValue[0]; *dst++=s0+(s1-s0)*weight; }
                    if (num >= 2) { s0=*dst; s1=curve.StaticValue[1]; *dst++=s0+(s1-s0)*weight; }
                    if (num >= 3) { s0=*dst; s1=curve.StaticValue[2]; *dst++=s0+(s1-s0)*weight; }
                    if (num >= 4) { s0=*dst; s1=curve.StaticValue[2]; *dst++=s0+(s1-s0)*weight; }
                }
                else {
                    o_assert_dbg(src0 && src1);
                    if (num >= 1) {
                        v0 = *src0++; v1 = *src1++;
                        s0 = *dst; s1 = v0 + (v1 - v0) * keyPos;
                        *dst++ = s0 + (s1 - s0) * weight;
                    }
                    if (num >= 2) {
                        v0 = *src0++; v1 = *src1++;
                        s0 = *dst; s1 = v0 + (v1 - v0) * keyPos;
                        *dst++ = s0 + (s1 - s0) * weight;
                    }
                    if (num >= 3) {
                        v0 = *src0++; v1 = *src1++;
                        s0 = *dst; s1 = v0 + (v1 - v0) * keyPos;
                        *dst++ = s0 + (s1 - s0) * weight;
                    }
                    if (num >= 4) {
                        v0 = *src0++; v1 = *src1++;
                        s0 = *dst; s1 = v0 + (v1 - v0) * keyPos;
                        *dst++ = s0 + (s1 - s0) * weight;
                    }
                }
            }
        }
        o_assert_dbg(dst == dstEnd);
        #if ORYOL_DEBUG
        if (src0 && src1) {
            o_assert_dbg(src0 == (&(clip.Keys[key0 * clip.KeyStride]) + clip.KeyStride));
            o_assert_dbg(src1 == (&(clip.Keys[key1 * clip.KeyStride]) + clip.KeyStride));
        }
        #endif
        weightSum += weight;
    }
    return numProcessedItems > 0;
}

} // namespace _priv
} // namespace Oryol
<|endoftext|>