<commit_before>#include "snapshot.h"
#include "ui_snapshot.h"
#include "consts.h"
#include "preferences.h"
#include <QTimer>
#include <QSound>
#include <QSpinBox>

Snapshot::PlaybackBtn::PlaybackBtn(QWidget *parent) : QToolButton(parent)
{
    setPlay();
}

void Snapshot::PlaybackBtn::setPlay()
{
    this->setIcon(QIcon(":/icons/play.png"));
    this->setText(tr("Playback All Snapshots"));
}

void Snapshot::PlaybackBtn::setPause()
{
    this->setIcon(QIcon(":/icons/pause.png"));
    this->setText(tr("Stop All Playback"));
}

Snapshot::InfoLbl::InfoLbl(QWidget *parent) : QLabel(parent)
{
    setText(stSetup);
}

void Snapshot::InfoLbl::setText(Snapshot::state state)
{
    switch (state)
    {
        case stSetup:
            setText(tr("Add the universes you want to capture, then press Snapshot to capture a look"));
            break;
        case stCountDown5:
            Q_FALLTHROUGH();
        case stCountDown4:
            Q_FALLTHROUGH();
        case stCountDown3:
            Q_FALLTHROUGH();
        case stCountDown2:
            Q_FALLTHROUGH();
        case stCountDown1:
            setText(tr("Capturing snapshot in..."));
            break;
        case stReadyPlayback:
            Q_FALLTHROUGH();
        case stReplay:
            setText(tr("Press Play to playback snapshot"));
            break;
        case stPlayback:
            setText(tr("Replaying Data"));
            break;
    }
}

Snapshot::Snapshot(int firstUniverse, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Snapshot),
    m_countdown(new QTimer(this)),
    m_camera(new QSound(":/sound/camera.wav", this)),
    m_beep(new QSound(":/sound/beep.wav", this)),
    m_firstUniverse(firstUniverse)
{
    ui->setupUi(this);

    m_cid = CID::CreateCid();

    connect(m_countdown, SIGNAL(timeout()), this, SLOT(counterTick()));

    setState(stSetup);
}

Snapshot::~Snapshot()
{
    stopSnapshot();
    delete ui;
}

Snapshot::state& operator++(Snapshot::state& s) // Prefix
{
    switch (s)
    {
        case Snapshot::state::stCountDown5: return s = Snapshot::state::stCountDown4;
        case Snapshot::state::stCountDown4: return s = Snapshot::state::stCountDown3;
        case Snapshot::state::stCountDown3: return s = Snapshot::state::stCountDown2;
        case Snapshot::state::stCountDown2: return s = Snapshot::state::stCountDown1;
        case Snapshot::state::stCountDown1: return s = Snapshot::state::stReadyPlayback;
        default: return s;
    }
}

void Snapshot::on_btnAddRow_clicked()
{
    int row = ui->tableWidget->rowCount();
    ui->tableWidget->setRowCount(row + 1);

    auto universe = m_snapshots.isEmpty() ? m_firstUniverse : m_snapshots.last()->getUniverse() + 1;
    auto name = Preferences::getInstance()->GetDefaultTransmitName().append(tr(" - Snapshot"));
    clsSnapshot* snap = new clsSnapshot(universe, m_cid, name, this);

    snap->getBtnPlayback()->setAutoRaise(true);
    connect(snap, SIGNAL(senderStarted()), this, SLOT(senderStarted()));
    connect(snap, SIGNAL(senderStopped()), this, SLOT(senderStopped()));
    connect(snap, SIGNAL(senderTimedOut()), this, SLOT(senderTimedOut()));
    connect(snap, &clsSnapshot::snapshotTaken, [this]() { ui->btnPlay->setEnabled(true); });
    connect(snap, SIGNAL(snapshotMatches()), this, SLOT(snapshotMatches()));
    connect(snap, SIGNAL(snapshotDiffers()), this, SLOT(snapshotDiffers()));
    ui->tableWidget->setCellWidget(row, COL_BUTTON, snap->getBtnPlayback());
    ui->tableWidget->setCellWidget(row, COL_UNIVERSE, snap->getSbUniverse());
    ui->tableWidget->setCellWidget(row, COL_PRIORITY, snap->getSbPriority());

    setState(stSetup);

    m_snapshots.append(snap);
}

void Snapshot::on_btnRemoveRow_clicked()
{
    // Get selected rows
    QList<int> rows;
    for(auto selection: ui->tableWidget->selectionModel()->selectedRows())
    {
        rows << selection.row();
    }

    // Sort backwards
    std::sort(rows.rbegin(), rows.rend());

    // Remove from bottom
    for(auto row: rows)
    {
        for(auto snap: m_snapshots)
        {

           if (snap->getBtnPlayback() == ui->tableWidget->cellWidget(row, COL_BUTTON))
           {
               ui->tableWidget->removeRow(row);
               m_snapshots.removeOne(snap);
               snap->deleteLater();
               break;
           }
        }
    }
    ui->tableWidget->clearSelection();
    ui->btnSnapshot->setEnabled(ui->tableWidget->rowCount()>0);
    setState(stSetup);
}

void Snapshot::setState(state s)
{
    // Info Label Text
    ui->lbInfo->setText(s);

    // Play Button Text and Icon
    btnPlay_update();

    switch(s)
    {
    case stSetup:
        ui->btnPlay->setEnabled(false);
        ui->btnSnapshot->setEnabled(ui->tableWidget->rowCount()>0);
        ui->lbTimer->hide();
        ui->btnAddRow->setEnabled(true);
        on_tableWidget_itemSelectionChanged();

        for(auto snap: m_snapshots)
        {
            snap->getSbUniverse()->setEnabled(true);
            snap->getSbPriority()->setEnabled(true);
            if (snap->hasData())
                ui->btnPlay->setEnabled(true);
        }
        break;
    case stCountDown5:
        Q_FALLTHROUGH();
    case stCountDown4:
        Q_FALLTHROUGH();
    case stCountDown3:
        Q_FALLTHROUGH();
    case stCountDown2:
        Q_FALLTHROUGH();
    case stCountDown1:
        ui->btnAddRow->setEnabled(false);
        ui->btnRemoveRow->setEnabled(false);
        ui->btnSnapshot->setEnabled(false);
        ui->lbTimer->setText(QString::number(1+stCountDown1 - s));
        ui->lbTimer->show();
        m_beep->play();
        for(auto snap: m_snapshots)
        {
            snap->getSbUniverse()->setEnabled(false);
            snap->getSbPriority()->setEnabled(false);
        }
        m_countdown->start(1000);
        break;
    case stReadyPlayback:
        m_camera->play();
        saveSnapshot();
        Q_FALLTHROUGH();
    case stReplay:
        ui->btnPlay->setEnabled(true);
        ui->btnSnapshot->setEnabled(true);
        ui->lbTimer->hide();
        ui->btnAddRow->setEnabled(true);
        on_tableWidget_itemSelectionChanged();
        break;
    case stPlayback:
        ui->btnPlay->setEnabled(true);
        ui->btnSnapshot->setEnabled(false);
        ui->lbTimer->hide();
        ui->btnAddRow->setEnabled(false);
        ui->btnRemoveRow->setEnabled(false);
        for(auto snap: m_snapshots)
        {
            snap->getSbUniverse()->setEnabled(false);
            snap->getSbPriority()->setEnabled(false);
        }
        break;
    }
    m_state = s;
}

void Snapshot::counterTick()
{
    if(m_state != stReadyPlayback)
        setState(++m_state);
    else
        m_countdown->stop();
}

void Snapshot::on_btnSnapshot_pressed()
{
    setState(stCountDown5);
}

void Snapshot::btnPlay_update(bool updateState)
{
    bool displayPause = false;
    for(auto snap: m_snapshots)
        if (snap->isPlaying())
            displayPause = true;
    if (displayPause)
    {
        ui->btnPlay->setPause();
        if (updateState && m_state != stPlayback)
            setState(stPlayback);
    }
    else
    {
        ui->btnPlay->setPlay();
        if (updateState && m_state != stReplay)
            setState(stReplay);
    }
}

void Snapshot::on_btnPlay_pressed()
{
    if(m_state!=stPlayback)
    {
        playSnapshot();
        setState(stPlayback);
    }
    else
    {
        stopSnapshot();
        setState(stReplay);
    }
}

void Snapshot::saveSnapshot()
{
    for(auto snap: m_snapshots)
        snap->takeSnapshot();
}

void Snapshot::playSnapshot()
{
    for(auto snap: m_snapshots)
        snap->playSnapshot();
}

void Snapshot::stopSnapshot()
{
    for(auto snap: m_snapshots)
        snap->stopSnapshot();
}

void Snapshot::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);

    int width = (ui->tableWidget->width() - 30) / 2;
    ui->tableWidget->setColumnWidth(0, 30);
    ui->tableWidget->setColumnWidth(1, width - 3);
}

void Snapshot::senderTimedOut()
{
    senderStopped();
}

void Snapshot::senderStarted()
{
//    clsSnapshot *snap = dynamic_cast<clsSnapshot *>(sender());
//    if (!snap) return;
    btnPlay_update(true);
}

void Snapshot::senderStopped()
{
//    clsSnapshot *snap = dynamic_cast<clsSnapshot *>(sender());
//    if (!snap) return;
    btnPlay_update(true);
}

void Snapshot::on_tableWidget_itemSelectionChanged()
{
    if (
            (m_state == stReadyPlayback) ||
            (m_state == stReplay) ||
            (m_state == stSetup)
        )
        ui->btnRemoveRow->setEnabled(!ui->tableWidget->selectionModel()->selectedRows().isEmpty());
    else
       ui->btnRemoveRow->setEnabled(false);
}
<commit_msg>XP Build fix<commit_after>#include "snapshot.h"
#include "ui_snapshot.h"
#include "qt56.h"
#include "consts.h"
#include "preferences.h"
#include <QTimer>
#include <QSound>
#include <QSpinBox>

Snapshot::PlaybackBtn::PlaybackBtn(QWidget *parent) : QToolButton(parent)
{
    setPlay();
}

void Snapshot::PlaybackBtn::setPlay()
{
    this->setIcon(QIcon(":/icons/play.png"));
    this->setText(tr("Playback All Snapshots"));
}

void Snapshot::PlaybackBtn::setPause()
{
    this->setIcon(QIcon(":/icons/pause.png"));
    this->setText(tr("Stop All Playback"));
}

Snapshot::InfoLbl::InfoLbl(QWidget *parent) : QLabel(parent)
{
    setText(stSetup);
}

void Snapshot::InfoLbl::setText(Snapshot::state state)
{
    switch (state)
    {
        case stSetup:
            setText(tr("Add the universes you want to capture, then press Snapshot to capture a look"));
            break;
        case stCountDown5:
            Q_FALLTHROUGH();
        case stCountDown4:
            Q_FALLTHROUGH();
        case stCountDown3:
            Q_FALLTHROUGH();
        case stCountDown2:
            Q_FALLTHROUGH();
        case stCountDown1:
            setText(tr("Capturing snapshot in..."));
            break;
        case stReadyPlayback:
            Q_FALLTHROUGH();
        case stReplay:
            setText(tr("Press Play to playback snapshot"));
            break;
        case stPlayback:
            setText(tr("Replaying Data"));
            break;
    }
}

Snapshot::Snapshot(int firstUniverse, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Snapshot),
    m_countdown(new QTimer(this)),
    m_camera(new QSound(":/sound/camera.wav", this)),
    m_beep(new QSound(":/sound/beep.wav", this)),
    m_firstUniverse(firstUniverse)
{
    ui->setupUi(this);

    m_cid = CID::CreateCid();

    connect(m_countdown, SIGNAL(timeout()), this, SLOT(counterTick()));

    setState(stSetup);
}

Snapshot::~Snapshot()
{
    stopSnapshot();
    delete ui;
}

Snapshot::state& operator++(Snapshot::state& s) // Prefix
{
    switch (s)
    {
        case Snapshot::state::stCountDown5: return s = Snapshot::state::stCountDown4;
        case Snapshot::state::stCountDown4: return s = Snapshot::state::stCountDown3;
        case Snapshot::state::stCountDown3: return s = Snapshot::state::stCountDown2;
        case Snapshot::state::stCountDown2: return s = Snapshot::state::stCountDown1;
        case Snapshot::state::stCountDown1: return s = Snapshot::state::stReadyPlayback;
        default: return s;
    }
}

void Snapshot::on_btnAddRow_clicked()
{
    int row = ui->tableWidget->rowCount();
    ui->tableWidget->setRowCount(row + 1);

    auto universe = m_snapshots.isEmpty() ? m_firstUniverse : m_snapshots.last()->getUniverse() + 1;
    auto name = Preferences::getInstance()->GetDefaultTransmitName().append(tr(" - Snapshot"));
    clsSnapshot* snap = new clsSnapshot(universe, m_cid, name, this);

    snap->getBtnPlayback()->setAutoRaise(true);
    connect(snap, SIGNAL(senderStarted()), this, SLOT(senderStarted()));
    connect(snap, SIGNAL(senderStopped()), this, SLOT(senderStopped()));
    connect(snap, SIGNAL(senderTimedOut()), this, SLOT(senderTimedOut()));
    connect(snap, &clsSnapshot::snapshotTaken, [this]() { ui->btnPlay->setEnabled(true); });
    connect(snap, SIGNAL(snapshotMatches()), this, SLOT(snapshotMatches()));
    connect(snap, SIGNAL(snapshotDiffers()), this, SLOT(snapshotDiffers()));
    ui->tableWidget->setCellWidget(row, COL_BUTTON, snap->getBtnPlayback());
    ui->tableWidget->setCellWidget(row, COL_UNIVERSE, snap->getSbUniverse());
    ui->tableWidget->setCellWidget(row, COL_PRIORITY, snap->getSbPriority());

    setState(stSetup);

    m_snapshots.append(snap);
}

void Snapshot::on_btnRemoveRow_clicked()
{
    // Get selected rows
    QList<int> rows;
    for(auto selection: ui->tableWidget->selectionModel()->selectedRows())
    {
        rows << selection.row();
    }

    // Sort backwards
    std::sort(rows.rbegin(), rows.rend());

    // Remove from bottom
    for(auto row: rows)
    {
        for(auto snap: m_snapshots)
        {

           if (snap->getBtnPlayback() == ui->tableWidget->cellWidget(row, COL_BUTTON))
           {
               ui->tableWidget->removeRow(row);
               m_snapshots.removeOne(snap);
               snap->deleteLater();
               break;
           }
        }
    }
    ui->tableWidget->clearSelection();
    ui->btnSnapshot->setEnabled(ui->tableWidget->rowCount()>0);
    setState(stSetup);
}

void Snapshot::setState(state s)
{
    // Info Label Text
    ui->lbInfo->setText(s);

    // Play Button Text and Icon
    btnPlay_update();

    switch(s)
    {
    case stSetup:
        ui->btnPlay->setEnabled(false);
        ui->btnSnapshot->setEnabled(ui->tableWidget->rowCount()>0);
        ui->lbTimer->hide();
        ui->btnAddRow->setEnabled(true);
        on_tableWidget_itemSelectionChanged();

        for(auto snap: m_snapshots)
        {
            snap->getSbUniverse()->setEnabled(true);
            snap->getSbPriority()->setEnabled(true);
            if (snap->hasData())
                ui->btnPlay->setEnabled(true);
        }
        break;
    case stCountDown5:
        Q_FALLTHROUGH();
    case stCountDown4:
        Q_FALLTHROUGH();
    case stCountDown3:
        Q_FALLTHROUGH();
    case stCountDown2:
        Q_FALLTHROUGH();
    case stCountDown1:
        ui->btnAddRow->setEnabled(false);
        ui->btnRemoveRow->setEnabled(false);
        ui->btnSnapshot->setEnabled(false);
        ui->lbTimer->setText(QString::number(1+stCountDown1 - s));
        ui->lbTimer->show();
        m_beep->play();
        for(auto snap: m_snapshots)
        {
            snap->getSbUniverse()->setEnabled(false);
            snap->getSbPriority()->setEnabled(false);
        }
        m_countdown->start(1000);
        break;
    case stReadyPlayback:
        m_camera->play();
        saveSnapshot();
        Q_FALLTHROUGH();
    case stReplay:
        ui->btnPlay->setEnabled(true);
        ui->btnSnapshot->setEnabled(true);
        ui->lbTimer->hide();
        ui->btnAddRow->setEnabled(true);
        on_tableWidget_itemSelectionChanged();
        break;
    case stPlayback:
        ui->btnPlay->setEnabled(true);
        ui->btnSnapshot->setEnabled(false);
        ui->lbTimer->hide();
        ui->btnAddRow->setEnabled(false);
        ui->btnRemoveRow->setEnabled(false);
        for(auto snap: m_snapshots)
        {
            snap->getSbUniverse()->setEnabled(false);
            snap->getSbPriority()->setEnabled(false);
        }
        break;
    }
    m_state = s;
}

void Snapshot::counterTick()
{
    if(m_state != stReadyPlayback)
        setState(++m_state);
    else
        m_countdown->stop();
}

void Snapshot::on_btnSnapshot_pressed()
{
    setState(stCountDown5);
}

void Snapshot::btnPlay_update(bool updateState)
{
    bool displayPause = false;
    for(auto snap: m_snapshots)
        if (snap->isPlaying())
            displayPause = true;
    if (displayPause)
    {
        ui->btnPlay->setPause();
        if (updateState && m_state != stPlayback)
            setState(stPlayback);
    }
    else
    {
        ui->btnPlay->setPlay();
        if (updateState && m_state != stReplay)
            setState(stReplay);
    }
}

void Snapshot::on_btnPlay_pressed()
{
    if(m_state!=stPlayback)
    {
        playSnapshot();
        setState(stPlayback);
    }
    else
    {
        stopSnapshot();
        setState(stReplay);
    }
}

void Snapshot::saveSnapshot()
{
    for(auto snap: m_snapshots)
        snap->takeSnapshot();
}

void Snapshot::playSnapshot()
{
    for(auto snap: m_snapshots)
        snap->playSnapshot();
}

void Snapshot::stopSnapshot()
{
    for(auto snap: m_snapshots)
        snap->stopSnapshot();
}

void Snapshot::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);

    int width = (ui->tableWidget->width() - 30) / 2;
    ui->tableWidget->setColumnWidth(0, 30);
    ui->tableWidget->setColumnWidth(1, width - 3);
}

void Snapshot::senderTimedOut()
{
    senderStopped();
}

void Snapshot::senderStarted()
{
//    clsSnapshot *snap = dynamic_cast<clsSnapshot *>(sender());
//    if (!snap) return;
    btnPlay_update(true);
}

void Snapshot::senderStopped()
{
//    clsSnapshot *snap = dynamic_cast<clsSnapshot *>(sender());
//    if (!snap) return;
    btnPlay_update(true);
}

void Snapshot::on_tableWidget_itemSelectionChanged()
{
    if (
            (m_state == stReadyPlayback) ||
            (m_state == stReplay) ||
            (m_state == stSetup)
        )
        ui->btnRemoveRow->setEnabled(!ui->tableWidget->selectionModel()->selectedRows().isEmpty());
    else
       ui->btnRemoveRow->setEnabled(false);
}
<|endoftext|>


<commit_before>
#define NOMINMAX

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

#include <string>
#include <map>
#include <vector>
#include <iterator>
#include <limits>
#include <algorithm>

#include "SPCFile.h"

#define APP_NAME    "spcpoint"
#define APP_VER     "[2015-04-09]"
#define APP_URL     "http://github.com/loveemu/spcpoint"

static void usage(const char * progname)
{
	printf("%s %s\n", APP_NAME, APP_VER);
	printf("<%s>\n", APP_URL);
	printf("\n");
	printf("Usage: `%s [-tf] [-variable=value ...] spc-file(s)`\n", progname);
	printf("\n");
}

int main(int argc, char *argv[])
{
	if (argc == 1) {
		usage(argv[0]);
		return EXIT_FAILURE;
	}

	std::map<std::string, std::string> opt_tags;

	int argi = 1;
	while (argi < argc && argv[argi][0] == '-')
	{
		char * p_equal = strchr(argv[argi], '=');

		if (p_equal != NULL) {
			// tag option
			std::string name(argv[argi], 1, p_equal - argv[argi] - 1);
			std::string value(p_equal + 1);
			opt_tags[name] = value;
		}
		else {
			// regular option
			if (strcmp(argv[argi], "--help") == 0) {
				usage(argv[0]);
				return EXIT_FAILURE;
			}
			else {
				fprintf(stderr, "Error: Unknown option \"%s\"\n", argv[argi]);
				return EXIT_FAILURE;
			}
		}

		argi++;
	}

	int argnum = argc - argi;
	if (argnum == 0) {
		fprintf(stderr, "Error: No input files\n");
		return EXIT_FAILURE;
	}

	int num_errors = 0;
	for (; argi < argc; argi++) {
		SPCFile * spc = SPCFile::Load(argv[argi]);
		if (spc == NULL) {
			continue;
		}

#ifdef _DEBUG
		printf("Current tags:\n");
		printf("\n");
		printf("```\n");

		std::map<std::string, std::string> tags = spc->ExportPSFTag(true);
		for (auto itr = tags.begin(); itr != tags.end(); ++itr) {
			const std::string & name = (*itr).first;
			const std::string & value = (*itr).second;
			printf("%s=%s\n", name.c_str(), value.c_str());
		}

		printf("```\n");
		printf("\n");
#endif

		spc->ImportPSFTag(opt_tags);
		spc->Save(argv[argi]);

		delete spc;
	}

	return EXIT_SUCCESS;
}
<commit_msg>Add `-tf` implementation<commit_after>
#define NOMINMAX

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

#include <string>
#include <map>
#include <vector>
#include <iterator>
#include <limits>
#include <algorithm>

#include "SPCFile.h"

#define APP_NAME    "spcpoint"
#define APP_VER     "[2015-04-09]"
#define APP_URL     "http://github.com/loveemu/spcpoint"

bool both_are_spaces(char lhs, char rhs)
{
	return (lhs == rhs) && (lhs == ' ');
}

void replace_all(std::string& str, const std::string& from, const std::string& to)
{
	std::string::size_type pos = 0;
	while (pos = str.find(from, pos), pos != std::string::npos) {
		str.replace(pos, from.length(), to);
		pos += to.length();
	}
}

static void usage(const char * progname)
{
	printf("%s %s\n", APP_NAME, APP_VER);
	printf("<%s>\n", APP_URL);
	printf("\n");
	printf("Usage: `%s [-tf] [-variable=value ...] spc-file(s)`\n", progname);
	printf("\n");
}

int main(int argc, char *argv[])
{
	if (argc == 1) {
		usage(argv[0]);
		return EXIT_FAILURE;
	}

	std::map<std::string, std::string> opt_tags;
	bool title_from_filename = false;

	int argi = 1;
	while (argi < argc && argv[argi][0] == '-')
	{
		char * p_equal = strchr(argv[argi], '=');

		if (p_equal != NULL) {
			// tag option
			std::string name(argv[argi], 1, p_equal - argv[argi] - 1);
			std::string value(p_equal + 1);
			opt_tags[name] = value;
		}
		else {
			// regular option
			if (strcmp(argv[argi], "--help") == 0) {
				usage(argv[0]);
				return EXIT_FAILURE;
			}
			else if (strcmp(argv[argi], "-tf") == 0) {
				title_from_filename = true;
			}
			else {
				fprintf(stderr, "Error: Unknown option \"%s\"\n", argv[argi]);
				return EXIT_FAILURE;
			}
		}

		argi++;
	}

	int argnum = argc - argi;
	if (argnum == 0) {
		fprintf(stderr, "Error: No input files\n");
		return EXIT_FAILURE;
	}

	int num_errors = 0;
	for (; argi < argc; argi++) {
		SPCFile * spc = SPCFile::Load(argv[argi]);
		if (spc == NULL) {
			continue;
		}

#ifdef _DEBUG
		printf("Current tags:\n");
		printf("\n");
		printf("```\n");

		std::map<std::string, std::string> tags = spc->ExportPSFTag(true);
		for (auto itr = tags.begin(); itr != tags.end(); ++itr) {
			const std::string & name = (*itr).first;
			const std::string & value = (*itr).second;
			printf("%s=%s\n", name.c_str(), value.c_str());
		}

		printf("```\n");
		printf("\n");
#endif

		std::map<std::string, std::string> psf_tags(opt_tags);
		if (title_from_filename) {
			std::string title(argv[argi]);

			// remove extension
			std::string::size_type offset_dot = title.find_last_of('.');
			if (offset_dot != std::string::npos) {
				title = title.substr(0, offset_dot);
			}

			// trim some beginning characters
			std::string::size_type offset_start = title.find_first_not_of(" _%0123456789-");
			if (offset_start != std::string::npos) {
				title = title.substr(offset_start);
			}

			// replace some other stuff
			replace_all(title, "%20", " ");
			replace_all(title, "_", " ");

			// replace multiple spaces with one space
			std::string::iterator new_end = std::unique(title.begin(), title.end(), both_are_spaces);
			title.erase(new_end, title.end());

			psf_tags["title"] = title;
			puts(title.c_str());
		}

		spc->ImportPSFTag(psf_tags);
		spc->Save(argv[argi]);

		delete spc;
	}

	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/clientmodel.h>

#include <qt/bantablemodel.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/peertablemodel.h>

#include <chain.h>
#include <chainparams.h>
#include <checkpoints.h>
#include <clientversion.h>
#include <validation.h>
#include <net.h>
#include <txmempool.h>
#include <ui_interface.h>
#include <util.h>
#include <warnings.h>

#include <stdint.h>

#include <QDebug>
#include <QTimer>

class CBlockIndex;

static int64_t nLastHeaderTipUpdateNotification = 0;
static int64_t nLastBlockTipUpdateNotification = 0;

ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) :
    QObject(parent),
    optionsModel(_optionsModel),
    peerTableModel(0),
    banTableModel(0),
    pollTimer(0)
{
    cachedBestHeaderHeight = -1;
    cachedBestHeaderTime = -1;
    peerTableModel = new PeerTableModel(this);
    banTableModel = new BanTableModel(this);
    pollTimer = new QTimer(this);
    connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
    pollTimer->start(MODEL_UPDATE_DELAY);

    versionOutDated = false;

    subscribeToCoreSignals();
}

ClientModel::~ClientModel()
{
    unsubscribeFromCoreSignals();
}

int ClientModel::getNumConnections(unsigned int flags) const
{
    CConnman::NumConnections connections = CConnman::CONNECTIONS_NONE;

    if(flags == CONNECTIONS_IN)
        connections = CConnman::CONNECTIONS_IN;
    else if (flags == CONNECTIONS_OUT)
        connections = CConnman::CONNECTIONS_OUT;
    else if (flags == CONNECTIONS_ALL)
        connections = CConnman::CONNECTIONS_ALL;

    if(g_connman)
         return g_connman->GetNodeCount(connections);
    return 0;
}

int ClientModel::getNumBlocks() const
{
    LOCK(cs_main);
    return chainActive.Height();
}

int ClientModel::getHeaderTipHeight() const
{
    if (cachedBestHeaderHeight == -1) {
        // make sure we initially populate the cache via a cs_main lock
        // otherwise we need to wait for a tip update
        LOCK(cs_main);
        if (pindexBestHeader) {
            cachedBestHeaderHeight = pindexBestHeader->nHeight;
            cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
        }
    }
    return cachedBestHeaderHeight;
}

int64_t ClientModel::getHeaderTipTime() const
{
    if (cachedBestHeaderTime == -1) {
        LOCK(cs_main);
        if (pindexBestHeader) {
            cachedBestHeaderHeight = pindexBestHeader->nHeight;
            cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
        }
    }
    return cachedBestHeaderTime;
}

quint64 ClientModel::getTotalBytesRecv() const
{
    if(!g_connman)
        return 0;
    return g_connman->GetTotalBytesRecv();
}

quint64 ClientModel::getTotalBytesSent() const
{
    if(!g_connman)
        return 0;
    return g_connman->GetTotalBytesSent();
}

QDateTime ClientModel::getLastBlockDate() const
{
    LOCK(cs_main);

    if (chainActive.Tip())
        return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());

    return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}

long ClientModel::getMempoolSize() const
{
    return mempool.size();
}

size_t ClientModel::getMempoolDynamicUsage() const
{
    return mempool.DynamicMemoryUsage();
}

double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const
{
    CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
    if (!tip)
    {
        LOCK(cs_main);
        tip = chainActive.Tip();
    }
    return GuessVerificationProgress(Params().TxData(), tip);
}

void ClientModel::updateTimer()
{
    // no locking required at this point
    // the following calls will acquire the required lock
    Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage());
    Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());

}

void ClientModel::updateNumConnections(int numConnections)
{
    Q_EMIT numConnectionsChanged(numConnections);
}

void ClientModel::updateNetworkActive(bool networkActive)
{
    Q_EMIT networkActiveChanged(networkActive);
}

void ClientModel::updateAlert()
{
    Q_EMIT alertsChanged(getStatusBarWarnings());
}

bool ClientModel::inInitialBlockDownload() const
{
    return IsInitialBlockDownload();
}

void ClientModel::updateBlockchainStatus(int status)
{
    Q_EMIT BlockchainStatusChanged(status);
}

enum BlockSource ClientModel::getBlockSource() const
{
    if (fReindex)
        return BLOCK_SOURCE_REINDEX;
    else if (fImporting)
        return BLOCK_SOURCE_DISK;
    else if (getNumConnections() > 0)
        return BLOCK_SOURCE_NETWORK;

    return BLOCK_SOURCE_NONE;
}

void ClientModel::setNetworkActive(bool active)
{
    if (g_connman) {
         g_connman->SetNetworkActive(active);
    }
}

bool ClientModel::getNetworkActive() const
{
    if (g_connman) {
        return g_connman->GetNetworkActive();
    }
    return false;
}

QString ClientModel::getStatusBarWarnings() const
{
    return QString::fromStdString(GetWarnings("gui"));
}

OptionsModel *ClientModel::getOptionsModel()
{
    return optionsModel;
}

PeerTableModel *ClientModel::getPeerTableModel()
{
    return peerTableModel;
}

BanTableModel *ClientModel::getBanTableModel()
{
    return banTableModel;
}

QString ClientModel::formatFullVersion() const
{
    return QString::fromStdString(FormatFullVersion());
}

QString ClientModel::formatSubVersion() const
{
    return QString::fromStdString(strSubVersion);
}

bool ClientModel::isReleaseVersion() const
{
    return CLIENT_VERSION_IS_RELEASE;
}

QString ClientModel::formatClientStartupTime() const
{
    return QDateTime::fromTime_t(GetStartupTime()).toString();
}

QString ClientModel::dataDir() const
{
    return GUIUtil::boostPathToQString(GetDataDir());
}

void ClientModel::updateBanlist()
{
    banTableModel->refresh();
}

// Handlers for core signals
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
{
    // emits signal "showProgress"
    QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
                              Q_ARG(QString, QString::fromStdString(title)),
                              Q_ARG(int, nProgress));
}

static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
{
    // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
    QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
                              Q_ARG(int, newNumConnections));
}

static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
{
    QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
                              Q_ARG(bool, networkActive));
}

static void NotifyAlertChanged(ClientModel *clientmodel)
{
    qDebug() << "NotifyAlertChanged";
    QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
}

static void NotifyBlockchainStatusChanged(ClientModel *clientmodel, int newStatus)
{
    qDebug() << "NotifyBlockchainStatusChanged: " + QString::number(newStatus);
    QMetaObject::invokeMethod(clientmodel, "updateBlockchainStatus", Qt::QueuedConnection,
                              Q_ARG(int, newStatus));
}

static void BannedListChanged(ClientModel *clientmodel)
{
    qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
    QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
}

static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader)
{
    // lock free async UI updates in case we have a new block tip
    // during initial sync, only update the UI if the last update
    // was > 250ms (MODEL_UPDATE_DELAY) ago
    int64_t now = 0;
    if (initialSync)
        now = GetTimeMillis();

    int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;

    if (fHeader) {
        // cache best headers time and height to reduce future cs_main locks
        clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
        clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
    }
    // if we are in-sync, update the UI regardless of last update time
    if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
        //pass an async signal to the UI thread
        QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
                                  Q_ARG(int, pIndex->nHeight),
                                  Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
                                  Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
                                  Q_ARG(bool, fHeader));
        nLastUpdateNotification = now;
    }
}

bool ClientModel::isNewVersionAvailable()
{
    //Connect to default tor node
    QNetworkProxy proxy;
    proxy.setType(QNetworkProxy::Socks5Proxy);
    proxy.setHostName("127.0.0.1");
    proxy.setPort(9081);

    QUrl url("https://deeponion.org/latestVersion.php");
    qInfo() << url.toString();
    QNetworkRequest request(url);
    QNetworkAccessManager nam;
    nam.setProxy(proxy);
    QNetworkReply * reply = nam.get(request);
    QTimer timer;
    timer.setSingleShot(true);
    timer.start(5000);

    while(timer.isActive()){
        qApp->processEvents();
        if(reply->isFinished()){
            timer.stop();

            QMessageBox Msgbox;
                Msgbox.setText(reply->readAll());
                Msgbox.exec();

            QByteArray response_data = reply->readAll();
            int ver = QString(response_data).toInt();
            if(ver == 0)
            {
                versionStatus = " - not available - ";
                reply->close();
                return false; //Empty response
            }
            if(isNewVersion(ver))
            {
                versionStatus = "outdated</>";
                versionOutDated = true;
            }
            else
            {
                versionStatus = "up to date</>";
                versionOutDated = false;
            }
            reply->close();
            return true;
        }
    }
    //Timeout
    versionStatus = " - not available - ";
    reply->close();
    return false;
}

bool ClientModel::isNewVersion(int ver)
{
   if(ver > CLIENT_VERSION)
       return true;
   else
       return false;
}

QString ClientModel::VersionStatus()
{
    return versionStatus;
}

bool ClientModel::VersionOutDated()
{
    return versionOutDated;
}

void ClientModel::subscribeToCoreSignals()
{
    // Connect signals to client
    uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
    uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
    uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, _1));
    uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));
    uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));
    uiInterface.NotifyBlockchainStatusChanged.connect(boost::bind(NotifyBlockchainStatusChanged, this, _1));
}

void ClientModel::unsubscribeFromCoreSignals()
{
    // Disconnect signals from client
    uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
    uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
    uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, _1));
    uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));
    uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));
    uiInterface.NotifyBlockchainStatusChanged.disconnect(boost::bind(NotifyBlockchainStatusChanged, this, _1));
}
<commit_msg>Revert "update v-check server url"<commit_after>// Copyright (c) 2011-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/clientmodel.h>

#include <qt/bantablemodel.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/peertablemodel.h>

#include <chain.h>
#include <chainparams.h>
#include <checkpoints.h>
#include <clientversion.h>
#include <validation.h>
#include <net.h>
#include <txmempool.h>
#include <ui_interface.h>
#include <util.h>
#include <warnings.h>

#include <stdint.h>

#include <QDebug>
#include <QTimer>

class CBlockIndex;

static int64_t nLastHeaderTipUpdateNotification = 0;
static int64_t nLastBlockTipUpdateNotification = 0;

ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) :
    QObject(parent),
    optionsModel(_optionsModel),
    peerTableModel(0),
    banTableModel(0),
    pollTimer(0)
{
    cachedBestHeaderHeight = -1;
    cachedBestHeaderTime = -1;
    peerTableModel = new PeerTableModel(this);
    banTableModel = new BanTableModel(this);
    pollTimer = new QTimer(this);
    connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
    pollTimer->start(MODEL_UPDATE_DELAY);

    versionOutDated = false;

    subscribeToCoreSignals();
}

ClientModel::~ClientModel()
{
    unsubscribeFromCoreSignals();
}

int ClientModel::getNumConnections(unsigned int flags) const
{
    CConnman::NumConnections connections = CConnman::CONNECTIONS_NONE;

    if(flags == CONNECTIONS_IN)
        connections = CConnman::CONNECTIONS_IN;
    else if (flags == CONNECTIONS_OUT)
        connections = CConnman::CONNECTIONS_OUT;
    else if (flags == CONNECTIONS_ALL)
        connections = CConnman::CONNECTIONS_ALL;

    if(g_connman)
         return g_connman->GetNodeCount(connections);
    return 0;
}

int ClientModel::getNumBlocks() const
{
    LOCK(cs_main);
    return chainActive.Height();
}

int ClientModel::getHeaderTipHeight() const
{
    if (cachedBestHeaderHeight == -1) {
        // make sure we initially populate the cache via a cs_main lock
        // otherwise we need to wait for a tip update
        LOCK(cs_main);
        if (pindexBestHeader) {
            cachedBestHeaderHeight = pindexBestHeader->nHeight;
            cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
        }
    }
    return cachedBestHeaderHeight;
}

int64_t ClientModel::getHeaderTipTime() const
{
    if (cachedBestHeaderTime == -1) {
        LOCK(cs_main);
        if (pindexBestHeader) {
            cachedBestHeaderHeight = pindexBestHeader->nHeight;
            cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
        }
    }
    return cachedBestHeaderTime;
}

quint64 ClientModel::getTotalBytesRecv() const
{
    if(!g_connman)
        return 0;
    return g_connman->GetTotalBytesRecv();
}

quint64 ClientModel::getTotalBytesSent() const
{
    if(!g_connman)
        return 0;
    return g_connman->GetTotalBytesSent();
}

QDateTime ClientModel::getLastBlockDate() const
{
    LOCK(cs_main);

    if (chainActive.Tip())
        return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());

    return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}

long ClientModel::getMempoolSize() const
{
    return mempool.size();
}

size_t ClientModel::getMempoolDynamicUsage() const
{
    return mempool.DynamicMemoryUsage();
}

double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const
{
    CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
    if (!tip)
    {
        LOCK(cs_main);
        tip = chainActive.Tip();
    }
    return GuessVerificationProgress(Params().TxData(), tip);
}

void ClientModel::updateTimer()
{
    // no locking required at this point
    // the following calls will acquire the required lock
    Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage());
    Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());

}

void ClientModel::updateNumConnections(int numConnections)
{
    Q_EMIT numConnectionsChanged(numConnections);
}

void ClientModel::updateNetworkActive(bool networkActive)
{
    Q_EMIT networkActiveChanged(networkActive);
}

void ClientModel::updateAlert()
{
    Q_EMIT alertsChanged(getStatusBarWarnings());
}

bool ClientModel::inInitialBlockDownload() const
{
    return IsInitialBlockDownload();
}

void ClientModel::updateBlockchainStatus(int status)
{
    Q_EMIT BlockchainStatusChanged(status);
}

enum BlockSource ClientModel::getBlockSource() const
{
    if (fReindex)
        return BLOCK_SOURCE_REINDEX;
    else if (fImporting)
        return BLOCK_SOURCE_DISK;
    else if (getNumConnections() > 0)
        return BLOCK_SOURCE_NETWORK;

    return BLOCK_SOURCE_NONE;
}

void ClientModel::setNetworkActive(bool active)
{
    if (g_connman) {
         g_connman->SetNetworkActive(active);
    }
}

bool ClientModel::getNetworkActive() const
{
    if (g_connman) {
        return g_connman->GetNetworkActive();
    }
    return false;
}

QString ClientModel::getStatusBarWarnings() const
{
    return QString::fromStdString(GetWarnings("gui"));
}

OptionsModel *ClientModel::getOptionsModel()
{
    return optionsModel;
}

PeerTableModel *ClientModel::getPeerTableModel()
{
    return peerTableModel;
}

BanTableModel *ClientModel::getBanTableModel()
{
    return banTableModel;
}

QString ClientModel::formatFullVersion() const
{
    return QString::fromStdString(FormatFullVersion());
}

QString ClientModel::formatSubVersion() const
{
    return QString::fromStdString(strSubVersion);
}

bool ClientModel::isReleaseVersion() const
{
    return CLIENT_VERSION_IS_RELEASE;
}

QString ClientModel::formatClientStartupTime() const
{
    return QDateTime::fromTime_t(GetStartupTime()).toString();
}

QString ClientModel::dataDir() const
{
    return GUIUtil::boostPathToQString(GetDataDir());
}

void ClientModel::updateBanlist()
{
    banTableModel->refresh();
}

// Handlers for core signals
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
{
    // emits signal "showProgress"
    QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
                              Q_ARG(QString, QString::fromStdString(title)),
                              Q_ARG(int, nProgress));
}

static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
{
    // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
    QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
                              Q_ARG(int, newNumConnections));
}

static void NotifyNetworkActiveChanged(ClientModel *clientmodel, bool networkActive)
{
    QMetaObject::invokeMethod(clientmodel, "updateNetworkActive", Qt::QueuedConnection,
                              Q_ARG(bool, networkActive));
}

static void NotifyAlertChanged(ClientModel *clientmodel)
{
    qDebug() << "NotifyAlertChanged";
    QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
}

static void NotifyBlockchainStatusChanged(ClientModel *clientmodel, int newStatus)
{
    qDebug() << "NotifyBlockchainStatusChanged: " + QString::number(newStatus);
    QMetaObject::invokeMethod(clientmodel, "updateBlockchainStatus", Qt::QueuedConnection,
                              Q_ARG(int, newStatus));
}

static void BannedListChanged(ClientModel *clientmodel)
{
    qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
    QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
}

static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex, bool fHeader)
{
    // lock free async UI updates in case we have a new block tip
    // during initial sync, only update the UI if the last update
    // was > 250ms (MODEL_UPDATE_DELAY) ago
    int64_t now = 0;
    if (initialSync)
        now = GetTimeMillis();

    int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;

    if (fHeader) {
        // cache best headers time and height to reduce future cs_main locks
        clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
        clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
    }
    // if we are in-sync, update the UI regardless of last update time
    if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
        //pass an async signal to the UI thread
        QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection,
                                  Q_ARG(int, pIndex->nHeight),
                                  Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
                                  Q_ARG(double, clientmodel->getVerificationProgress(pIndex)),
                                  Q_ARG(bool, fHeader));
        nLastUpdateNotification = now;
    }
}

bool ClientModel::isNewVersionAvailable()
{
    //Connect to default tor node
    QNetworkProxy proxy;
    proxy.setType(QNetworkProxy::Socks5Proxy);
    proxy.setHostName("127.0.0.1");
    proxy.setPort(9081);

    QUrl url("https://deeponion.org/latestVersion.php");
    qInfo() << url.toString();
    QNetworkRequest request(url);
    QNetworkAccessManager nam;
    nam.setProxy(proxy);
    QNetworkReply * reply = nam.get(request);
    QTimer timer;
    timer.setSingleShot(true);
    timer.start(5000);

    while(timer.isActive()){
        qApp->processEvents();
        if(reply->isFinished()){
            timer.stop();

        //    QMessageBox Msgbox;
        //        Msgbox.setText(reply->readAll());
        //        Msgbox.exec();

            QByteArray response_data = reply->readAll();
            int ver = QString(response_data).toInt();
            if(ver == 0)
            {
                versionStatus = " - not available - ";
                reply->close();
                return false; //Empty response
            }
            if(isNewVersion(ver))
            {
                versionStatus = "outdated</>";
                versionOutDated = true;
            }
            else
            {
                versionStatus = "up to date</>";
                versionOutDated = false;
            }
            reply->close();
            return true;
        }
    }
    //Timeout
    versionStatus = " - not available - ";
    reply->close();
    return false;
}

bool ClientModel::isNewVersion(int ver)
{
   if(ver > CLIENT_VERSION)
       return true;
   else
       return false;
}

QString ClientModel::VersionStatus()
{
    return versionStatus;
}

bool ClientModel::VersionOutDated()
{
    return versionOutDated;
}

void ClientModel::subscribeToCoreSignals()
{
    // Connect signals to client
    uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
    uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
    uiInterface.NotifyNetworkActiveChanged.connect(boost::bind(NotifyNetworkActiveChanged, this, _1));
    uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false));
    uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true));
    uiInterface.NotifyBlockchainStatusChanged.connect(boost::bind(NotifyBlockchainStatusChanged, this, _1));
}

void ClientModel::unsubscribeFromCoreSignals()
{
    // Disconnect signals from client
    uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
    uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
    uiInterface.NotifyNetworkActiveChanged.disconnect(boost::bind(NotifyNetworkActiveChanged, this, _1));
    uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false));
    uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true));
    uiInterface.NotifyBlockchainStatusChanged.disconnect(boost::bind(NotifyBlockchainStatusChanged, this, _1));
}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/walletframe.h>
#include <qt/walletmodel.h>

#include <qt/bitcoingui.h>
#include <qt/walletview.h>

#include <cassert>
#include <cstdio>

#include <QHBoxLayout>
#include <QLabel>

WalletFrame::WalletFrame(const PlatformStyle *_platformStyle, BitcoinGUI *_gui) :
    QFrame(_gui),
    gui(_gui),
    platformStyle(_platformStyle)
{
    // Leave HBox hook for adding a list view later
    QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
    setContentsMargins(0,0,0,0);
    walletStack = new QStackedWidget(this);
    walletFrameLayout->setContentsMargins(0,0,0,0);
    walletFrameLayout->addWidget(walletStack);

    QLabel *noWallet = new QLabel(tr("No wallet has been loaded."));
    noWallet->setAlignment(Qt::AlignCenter);
    walletStack->addWidget(noWallet);
}

WalletFrame::~WalletFrame()
{
}

void WalletFrame::setClientModel(ClientModel *_clientModel)
{
    this->clientModel = _clientModel;
}

bool WalletFrame::addWallet(WalletModel *walletModel)
{
    if (!gui || !clientModel || !walletModel) {
        return false;
    }

    const QString name = walletModel->getWalletName();
    if (mapWalletViews.count(name) > 0) {
        return false;
    }

    WalletView *walletView = new WalletView(platformStyle, this);
    walletView->setBitcoinGUI(gui);
    walletView->setClientModel(clientModel);
    walletView->setWalletModel(walletModel);
    walletView->showOutOfSyncWarning(bOutOfSync);

    WalletView* current_wallet_view = currentWalletView();
    if (current_wallet_view) {
        walletView->setCurrentIndex(current_wallet_view->currentIndex());
    } else {
        walletView->gotoOverviewPage();
    }

    walletStack->addWidget(walletView);
    mapWalletViews[name] = walletView;

    // Ensure a walletView is able to show the main window
    connect(walletView, SIGNAL(showNormalIfMinimized()), gui, SLOT(showNormalIfMinimized()));

    connect(walletView, SIGNAL(outOfSyncWarningClicked()), this, SLOT(outOfSyncWarningClicked()));

    return true;
}

bool WalletFrame::setCurrentWallet(const QString& name)
{
    if (mapWalletViews.count(name) == 0)
        return false;

    WalletView *walletView = mapWalletViews.value(name);
    walletStack->setCurrentWidget(walletView);
    assert(walletView);
    walletView->updateEncryptionStatus();
    return true;
}

bool WalletFrame::removeWallet(const QString &name)
{
    if (mapWalletViews.count(name) == 0)
        return false;

    WalletView *walletView = mapWalletViews.take(name);
    walletStack->removeWidget(walletView);
    return true;
}

void WalletFrame::removeAllWallets()
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        walletStack->removeWidget(i.value());
    mapWalletViews.clear();
}

bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)
{
    WalletView *walletView = currentWalletView();
    if (!walletView)
        return false;

    return walletView->handlePaymentRequest(recipient);
}

void WalletFrame::showOutOfSyncWarning(bool fShow)
{
    bOutOfSync = fShow;
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->showOutOfSyncWarning(fShow);
}

void WalletFrame::gotoOverviewPage()
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->gotoOverviewPage();
}

void WalletFrame::gotoHistoryPage()
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->gotoHistoryPage();
}

void WalletFrame::gotoReceiveCoinsPage()
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->gotoReceiveCoinsPage();
}

void WalletFrame::gotoSendCoinsPage(QString addr)
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->gotoSendCoinsPage(addr);
}

void WalletFrame::gotoSignMessageTab(QString addr)
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->gotoSignMessageTab(addr);
}

void WalletFrame::gotoVerifyMessageTab(QString addr)
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->gotoVerifyMessageTab(addr);
}

void WalletFrame::encryptWallet(bool status)
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->encryptWallet(status);
}

void WalletFrame::backupWallet()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->backupWallet();
}

void WalletFrame::changePassphrase()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->changePassphrase();
}

void WalletFrame::unlockWallet()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->unlockWallet();
}

void WalletFrame::usedSendingAddresses()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->usedSendingAddresses();
}

void WalletFrame::usedReceivingAddresses()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->usedReceivingAddresses();
}

WalletView *WalletFrame::currentWalletView()
{
    return qobject_cast<WalletView*>(walletStack->currentWidget());
}

void WalletFrame::outOfSyncWarningClicked()
{
    Q_EMIT requestedSyncWarningInfo();
}
<commit_msg>bugfix: Delete walletView in WalletFrame::removeWallet<commit_after>// Copyright (c) 2011-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/walletframe.h>
#include <qt/walletmodel.h>

#include <qt/bitcoingui.h>
#include <qt/walletview.h>

#include <cassert>
#include <cstdio>

#include <QHBoxLayout>
#include <QLabel>

WalletFrame::WalletFrame(const PlatformStyle *_platformStyle, BitcoinGUI *_gui) :
    QFrame(_gui),
    gui(_gui),
    platformStyle(_platformStyle)
{
    // Leave HBox hook for adding a list view later
    QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
    setContentsMargins(0,0,0,0);
    walletStack = new QStackedWidget(this);
    walletFrameLayout->setContentsMargins(0,0,0,0);
    walletFrameLayout->addWidget(walletStack);

    QLabel *noWallet = new QLabel(tr("No wallet has been loaded."));
    noWallet->setAlignment(Qt::AlignCenter);
    walletStack->addWidget(noWallet);
}

WalletFrame::~WalletFrame()
{
}

void WalletFrame::setClientModel(ClientModel *_clientModel)
{
    this->clientModel = _clientModel;
}

bool WalletFrame::addWallet(WalletModel *walletModel)
{
    if (!gui || !clientModel || !walletModel) {
        return false;
    }

    const QString name = walletModel->getWalletName();
    if (mapWalletViews.count(name) > 0) {
        return false;
    }

    WalletView *walletView = new WalletView(platformStyle, this);
    walletView->setBitcoinGUI(gui);
    walletView->setClientModel(clientModel);
    walletView->setWalletModel(walletModel);
    walletView->showOutOfSyncWarning(bOutOfSync);

    WalletView* current_wallet_view = currentWalletView();
    if (current_wallet_view) {
        walletView->setCurrentIndex(current_wallet_view->currentIndex());
    } else {
        walletView->gotoOverviewPage();
    }

    walletStack->addWidget(walletView);
    mapWalletViews[name] = walletView;

    // Ensure a walletView is able to show the main window
    connect(walletView, SIGNAL(showNormalIfMinimized()), gui, SLOT(showNormalIfMinimized()));

    connect(walletView, SIGNAL(outOfSyncWarningClicked()), this, SLOT(outOfSyncWarningClicked()));

    return true;
}

bool WalletFrame::setCurrentWallet(const QString& name)
{
    if (mapWalletViews.count(name) == 0)
        return false;

    WalletView *walletView = mapWalletViews.value(name);
    walletStack->setCurrentWidget(walletView);
    assert(walletView);
    walletView->updateEncryptionStatus();
    return true;
}

bool WalletFrame::removeWallet(const QString &name)
{
    if (mapWalletViews.count(name) == 0)
        return false;

    WalletView *walletView = mapWalletViews.take(name);
    walletStack->removeWidget(walletView);
    delete walletView;
    return true;
}

void WalletFrame::removeAllWallets()
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        walletStack->removeWidget(i.value());
    mapWalletViews.clear();
}

bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)
{
    WalletView *walletView = currentWalletView();
    if (!walletView)
        return false;

    return walletView->handlePaymentRequest(recipient);
}

void WalletFrame::showOutOfSyncWarning(bool fShow)
{
    bOutOfSync = fShow;
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->showOutOfSyncWarning(fShow);
}

void WalletFrame::gotoOverviewPage()
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->gotoOverviewPage();
}

void WalletFrame::gotoHistoryPage()
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->gotoHistoryPage();
}

void WalletFrame::gotoReceiveCoinsPage()
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->gotoReceiveCoinsPage();
}

void WalletFrame::gotoSendCoinsPage(QString addr)
{
    QMap<QString, WalletView*>::const_iterator i;
    for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
        i.value()->gotoSendCoinsPage(addr);
}

void WalletFrame::gotoSignMessageTab(QString addr)
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->gotoSignMessageTab(addr);
}

void WalletFrame::gotoVerifyMessageTab(QString addr)
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->gotoVerifyMessageTab(addr);
}

void WalletFrame::encryptWallet(bool status)
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->encryptWallet(status);
}

void WalletFrame::backupWallet()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->backupWallet();
}

void WalletFrame::changePassphrase()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->changePassphrase();
}

void WalletFrame::unlockWallet()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->unlockWallet();
}

void WalletFrame::usedSendingAddresses()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->usedSendingAddresses();
}

void WalletFrame::usedReceivingAddresses()
{
    WalletView *walletView = currentWalletView();
    if (walletView)
        walletView->usedReceivingAddresses();
}

WalletView *WalletFrame::currentWalletView()
{
    return qobject_cast<WalletView*>(walletStack->currentWidget());
}

void WalletFrame::outOfSyncWarningClicked()
{
    Q_EMIT requestedSyncWarningInfo();
}
<|endoftext|>


<commit_before>#include "rawtetrisboard.h"
#include "square.h"
#include "block.h"

#include <vector>

RawTetrisBoard::RawTetrisBoard(int nbrRows, int nbrColumns,
	BlockType current, BlockType next) :
	gameboard_(nbrRows * nbrColumns, BlockType::EMPTY),
	next_(next),
	nbrRows_(nbrRows), nbrColumns_(nbrColumns),
	isGameOver_(false) {

	current_ = createBlock(current);
}

void RawTetrisBoard::update(Move move) {
	// Game over?
	if (isGameOver_ || collision(current_)) {
		if (!isGameOver_) {
			// Only called once when the game becomes game over.
			isGameOver_ = true;
			triggerEvent(GameEvent::GAME_OVER);
		}
	} else {
		Block block = current_;
		switch (move) {
			case Move::GAME_OVER:
				// Only called once when the game becomes game over.
				isGameOver_ = true;
				triggerEvent(GameEvent::GAME_OVER);
				break;
			case Move::LEFT:
				block.moveLeft();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_MOVES_BLOCK_LEFT);
				}
				break;
			case Move::RIGHT:
				block.moveRight();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_MOVES_BLOCK_RIGHT);
				}
				break;
			case Move::DOWN:
				block.moveDown();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_MOVES_BLOCK_DOWN);
				}
				break;
			case Move::ROTATE_RIGHT:
				block.rotateRight();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_ROTATES_BLOCK);
				}
				break;
			case Move::ROTATE_LEFT:
				block.rotateLeft();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_ROTATES_BLOCK);
				}
				break;
			case Move::DOWN_GRAVITY:
				block.moveDown();
				if (collision(block)) {
					// Collision detected, add squares to the gameboard.
					addBlockToBoard(current_);

					// Remove any filled row on the gameboard.
					int nbr = removeFilledRows(current_);

					// Add rows due to some external event.
					std::vector<BlockType> squares = addExternalRows();
					gameboard_.insert(gameboard_.begin(), squares.begin(), squares.end());
					gameboard_.resize(gameboard_.size() - squares.size(), BlockType::EMPTY);

					// Update the user controlled block.
					current_ = createBlock(next_);
					triggerEvent(GameEvent::CURRENT_BLOCK_UPDATED);

					switch (nbr) {
						case 1:
							triggerEvent(GameEvent::ONE_ROW_REMOVED);
							break;
						case 2:
							triggerEvent(GameEvent::TWO_ROW_REMOVED);
							break;
						case 3:
							triggerEvent(GameEvent::THREE_ROW_REMOVED);
							break;
						case 4:
							triggerEvent(GameEvent::FOUR_ROW_REMOVED);
							break;
					}
					triggerEvent(GameEvent::BLOCK_COLLISION);
				} else {
					current_ = block;
					triggerEvent(GameEvent::GRAVITY_MOVES_BLOCK);
				}
				break;
		}
	}
}

void RawTetrisBoard::updateNextBlock(BlockType nextBlock) {
	next_ = nextBlock;
	triggerEvent(GameEvent::NEXT_BLOCK_UPDATED);
}

void RawTetrisBoard::updateCurrentBlock(BlockType current) {
	current_ = createBlock(current);
	triggerEvent(GameEvent::CURRENT_BLOCK_UPDATED);
}

void RawTetrisBoard::updateRestart(BlockType current, BlockType next) {
	next_ = next;
	current_ = createBlock(current);
	clearBoard();
	triggerEvent(GameEvent::RESTARTED);
}

const std::vector<BlockType>& RawTetrisBoard::getBoardVector() const {
	return gameboard_;
}

void RawTetrisBoard::addBlockToBoard(const Block& block) {
	// All squares in the block is added to the gameboard.
	for (const Square& sq : block) {
		blockType(sq.row_, sq.column_) = sq.blockType_;
	}
}

Block RawTetrisBoard::createBlock(BlockType blockType) const {
	return Block(blockType, nbrRows_- 4, nbrColumns_ / 2 - 1); // 4 rows are the starting area.
}

bool RawTetrisBoard::collision(const Block& block) const {
	bool collision = false;

	for (const Square& sq : block) {
		if (getBlockType(sq.row_, sq.column_) != BlockType::EMPTY) {
			collision = true;
			break;
		}
	}

	return collision;
}

void RawTetrisBoard::clearBoard() {
	gameboard_.assign(gameboard_.size(), BlockType::EMPTY);
	isGameOver_ = false;
}

int RawTetrisBoard::removeFilledRows(const Block& block) {
	row1_ = -1;
	row2_ = -1;
	row3_ = -1;
	row4_ = -1;
	int row = block.getLowestRow();

	int nbr = 0; // Number of rows filled.
	const int nbrOfSquares = current_.nbrOfSquares();
	for (int i = 0; i < nbrOfSquares; ++i) {
		bool filled = true;
		if (row >= 0) {
			int index = row * nbrColumns_;
			for (int column = 0; column < nbrColumns_; ++column) {
				if (gameboard_[index + column] == BlockType::EMPTY) {
					filled = false;
				}
			}
		} else {
			filled = false;
		}
		if (filled) {
			moveRowsOneStepDown(row);
			// Which row was filled?
			switch (nbr) {
				case 0:
					row1_ = row + nbr;
					break;
				case 1:
					row2_ = row + nbr;;
					break;
				case 2:
					row3_ = row + nbr;;
					break;
				case 3:
					row4_ = row + nbr;;
					break;
			}
			++nbr;
		} else {
			++row;
		}
	}

	return nbr;
}

void RawTetrisBoard::moveRowsOneStepDown(int rowToRemove) {
	int indexStartOfRow = rowToRemove * nbrColumns_;
	// Erase the row to be removed.
	gameboard_.erase(gameboard_.begin() + indexStartOfRow, gameboard_.begin() + nbrColumns_);
	// Replace the row that was removed with a empty row at the top.
	gameboard_.insert(gameboard_.end(), nbrColumns_, BlockType::EMPTY);
}
<commit_msg>Bug fix! RawTetrisBoard used erase wrong.<commit_after>#include "rawtetrisboard.h"
#include "square.h"
#include "block.h"

#include <vector>

RawTetrisBoard::RawTetrisBoard(int nbrRows, int nbrColumns,
	BlockType current, BlockType next) :
	gameboard_(nbrRows * nbrColumns, BlockType::EMPTY),
	next_(next),
	nbrRows_(nbrRows), nbrColumns_(nbrColumns),
	isGameOver_(false) {

	current_ = createBlock(current);
}

void RawTetrisBoard::update(Move move) {
	// Game over?
	if (isGameOver_ || collision(current_)) {
		if (!isGameOver_) {
			// Only called once when the game becomes game over.
			isGameOver_ = true;
			triggerEvent(GameEvent::GAME_OVER);
		}
	} else {
		Block block = current_;
		switch (move) {
			case Move::GAME_OVER:
				// Only called once when the game becomes game over.
				isGameOver_ = true;
				triggerEvent(GameEvent::GAME_OVER);
				break;
			case Move::LEFT:
				block.moveLeft();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_MOVES_BLOCK_LEFT);
				}
				break;
			case Move::RIGHT:
				block.moveRight();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_MOVES_BLOCK_RIGHT);
				}
				break;
			case Move::DOWN:
				block.moveDown();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_MOVES_BLOCK_DOWN);
				}
				break;
			case Move::ROTATE_RIGHT:
				block.rotateRight();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_ROTATES_BLOCK);
				}
				break;
			case Move::ROTATE_LEFT:
				block.rotateLeft();
				if (!collision(block)) {
					current_ = block;
					triggerEvent(GameEvent::PLAYER_ROTATES_BLOCK);
				}
				break;
			case Move::DOWN_GRAVITY:
				block.moveDown();
				if (collision(block)) {
					// Collision detected, add squares to the gameboard.
					addBlockToBoard(current_);

					// Remove any filled row on the gameboard.
					int nbr = removeFilledRows(current_);

					// Add rows due to some external event.
					std::vector<BlockType> squares = addExternalRows();
					gameboard_.insert(gameboard_.begin(), squares.begin(), squares.end());
					gameboard_.resize(gameboard_.size() - squares.size(), BlockType::EMPTY);

					// Update the user controlled block.
					current_ = createBlock(next_);
					triggerEvent(GameEvent::CURRENT_BLOCK_UPDATED);

					switch (nbr) {
						case 1:
							triggerEvent(GameEvent::ONE_ROW_REMOVED);
							break;
						case 2:
							triggerEvent(GameEvent::TWO_ROW_REMOVED);
							break;
						case 3:
							triggerEvent(GameEvent::THREE_ROW_REMOVED);
							break;
						case 4:
							triggerEvent(GameEvent::FOUR_ROW_REMOVED);
							break;
					}
					triggerEvent(GameEvent::BLOCK_COLLISION);
				} else {
					current_ = block;
					triggerEvent(GameEvent::GRAVITY_MOVES_BLOCK);
				}
				break;
		}
	}
}

void RawTetrisBoard::updateNextBlock(BlockType nextBlock) {
	next_ = nextBlock;
	triggerEvent(GameEvent::NEXT_BLOCK_UPDATED);
}

void RawTetrisBoard::updateCurrentBlock(BlockType current) {
	current_ = createBlock(current);
	triggerEvent(GameEvent::CURRENT_BLOCK_UPDATED);
}

void RawTetrisBoard::updateRestart(BlockType current, BlockType next) {
	next_ = next;
	current_ = createBlock(current);
	clearBoard();
	triggerEvent(GameEvent::RESTARTED);
}

const std::vector<BlockType>& RawTetrisBoard::getBoardVector() const {
	return gameboard_;
}

void RawTetrisBoard::addBlockToBoard(const Block& block) {
	// All squares in the block is added to the gameboard.
	for (const Square& sq : block) {
		blockType(sq.row_, sq.column_) = sq.blockType_;
	}
}

Block RawTetrisBoard::createBlock(BlockType blockType) const {
	return Block(blockType, nbrRows_- 4, nbrColumns_ / 2 - 1); // 4 rows are the starting area.
}

bool RawTetrisBoard::collision(const Block& block) const {
	bool collision = false;

	for (const Square& sq : block) {
		if (getBlockType(sq.row_, sq.column_) != BlockType::EMPTY) {
			collision = true;
			break;
		}
	}

	return collision;
}

void RawTetrisBoard::clearBoard() {
	gameboard_.assign(gameboard_.size(), BlockType::EMPTY);
	isGameOver_ = false;
}

int RawTetrisBoard::removeFilledRows(const Block& block) {
	row1_ = -1;
	row2_ = -1;
	row3_ = -1;
	row4_ = -1;
	int row = block.getLowestRow();

	int nbr = 0; // Number of rows filled.
	const int nbrOfSquares = current_.nbrOfSquares();
	for (int i = 0; i < nbrOfSquares; ++i) {
		bool filled = true;
		if (row >= 0) {
			int index = row * nbrColumns_;
			for (int column = 0; column < nbrColumns_; ++column) {
				if (gameboard_[index + column] == BlockType::EMPTY) {
					filled = false;
				}
			}
		} else {
			filled = false;
		}
		if (filled) {
			moveRowsOneStepDown(row);
			// Which row was filled?
			switch (nbr) {
				case 0:
					row1_ = row + nbr;
					break;
				case 1:
					row2_ = row + nbr;;
					break;
				case 2:
					row3_ = row + nbr;;
					break;
				case 3:
					row4_ = row + nbr;;
					break;
			}
			++nbr;
		} else {
			++row;
		}
	}

	return nbr;
}

void RawTetrisBoard::moveRowsOneStepDown(int rowToRemove) {
	int indexStartOfRow = rowToRemove * nbrColumns_;
	// Erase the row.
	gameboard_.erase(gameboard_.begin() + indexStartOfRow, gameboard_.begin() + indexStartOfRow + nbrColumns_);
	// Replace the removed row with an empty row at the top.
	gameboard_.insert(gameboard_.end(), nbrColumns_, BlockType::EMPTY);
}
<|endoftext|>


<commit_before>#define SPICA_BSSRDF_EXPORT
#include "bssrdf.h"

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

#include "renderer_constants.h"

namespace spica {

    // ------------------------------------------------------------
    // BSSRDF base class
    // ------------------------------------------------------------

    double BSSRDFBase::Ft(const Vector3D& normal, const Vector3D& in) const {
        const double nnt = kIorObject / kIorVaccum;
        const double ddn = in.dot(normal);
        const double cos2t = 1.0 - nnt * nnt * (1.0 - ddn * ddn);

        if (cos2t < 0.0) return 0.0;

        Vector3D refractDir = (in * nnt + normal * (ddn * nnt + sqrt(cos2t))).normalized();

        const double a = kIorObject - kIorVaccum;
        const double b = kIorObject + kIorVaccum;
        const double R0 = (a * a) / (b * b);

        const double c  = 1.0 - Vector3D::dot(refractDir, -normal);
        const double Re = R0 + (1.0 - R0) * pow(c, 5.0);
        return 1.0 - Re;
    }

    double BSSRDFBase::Fdr() const {
        if (_eta >= 1.0) {
            return -1.4399 / (_eta * _eta) + 0.7099 / _eta + 0.6681 + 0.0636 * _eta;
        } else {
            return -0.4399 + 0.7099 / _eta - 0.3319 / (_eta * _eta) + 0.0636 / (_eta * _eta * _eta);
        }
    }

    // ------------------------------------------------------------
    // BSSRDF with dipole approximation
    // ------------------------------------------------------------

    DipoleBSSRDF::DipoleBSSRDF(const Color& sigma_a,
                               const Color& sigmap_s, double eta)
        : BSSRDFBase(eta)
        , _A(0.0)
        , _sigmap_t()
        , _sigma_tr()
        , _alphap()
        , _zpos()
        , _zneg()
    {
        _A = (1.0 + Fdr()) / (1.0 - Fdr());
        _sigmap_t = sigma_a + sigmap_s;
        _sigma_tr = Color::sqrt(3.0 * sigma_a * _sigmap_t);
        _alphap = sigmap_s / _sigmap_t;
        _zpos = Color(1.0, 1.0, 1.0) / _sigmap_t;
        _zneg = _zpos * (1.0 + (4.0 / 3.0) * _A);
    }

    DipoleBSSRDF::DipoleBSSRDF(const DipoleBSSRDF& bssrdf)
        : BSSRDFBase()
        , _A(0.0)
        , _sigmap_t()
        , _sigma_tr()
        , _alphap()
        , _zpos()
        , _zneg()
    {
        this->operator=(bssrdf);
    }

    DipoleBSSRDF& DipoleBSSRDF::operator=(const DipoleBSSRDF& bssrdf) {
        BSSRDFBase::operator=(bssrdf);
        this->_A = bssrdf._A;
        this->_sigmap_t = bssrdf._sigmap_t;
        this->_sigma_tr = bssrdf._sigma_tr;
        this->_alphap = bssrdf._alphap;
        this->_zpos = bssrdf._zpos;
        this->_zneg = bssrdf._zneg;
        return *this;
    }

    BSSRDF DipoleBSSRDF::factory(const Color& sigma_a, const Color& sigmap_s, double eta) {
        return BSSRDF(new DipoleBSSRDF(sigma_a, sigmap_s, eta));
    }

    Color DipoleBSSRDF::operator()(const double d2) const {
        const Color dpos = Color::sqrt(d2 + _zpos * _zpos);
        const Color dneg = Color::sqrt(d2 + _zneg * _zneg);
        const Color dpos3 = dpos * dpos * dpos;
        const Color dneg3 = dneg * dneg * dneg;
        const Color posTerm = _zpos * (dpos * _sigma_tr + 1.0) * Color::exp(-_sigma_tr * dpos);
        const Color negTerm = _zneg * (dneg * _sigma_tr + 1.0) * Color::exp(-_sigma_tr * dneg);
        const Color Rd = ((_alphap * posTerm * dneg3 - negTerm * dpos3) / (4.0 * PI * _sigma_tr * dpos3 * dneg3));
        return Rd.clamp();
    }

    BSSRDFBase* DipoleBSSRDF::clone() const {
        return new DipoleBSSRDF(*this);
    }

    // ------------------------------------------------------------
    // BSSRDF with diffuse reflectance function
    // ------------------------------------------------------------

    DiffuseBSSRDF::DiffuseBSSRDF()
        : BSSRDFBase()
        , _distances()
        , _colors()
    {
    }

    DiffuseBSSRDF::DiffuseBSSRDF(const double eta, const std::vector<double>& distances, const std::vector<Color>& colors)
        : BSSRDFBase(eta)
        , _distances(distances)
        , _colors(colors)
    {
        Assertion(distances.size() == colors.size(), "Arrays for distances and colors must have the same length!!");
    }

    DiffuseBSSRDF::DiffuseBSSRDF(const DiffuseBSSRDF& bssrdf)
        : BSSRDFBase()
        , _distances()
        , _colors()
    {
        this->operator=(bssrdf);
    }

    DiffuseBSSRDF::DiffuseBSSRDF(DiffuseBSSRDF&& bssrdf)
        : BSSRDFBase()
        , _distances()
        , _colors()
    {
        this->operator=(std::move(bssrdf));
    }

    DiffuseBSSRDF& DiffuseBSSRDF::operator=(const DiffuseBSSRDF& bssrdf) {
        BSSRDFBase::operator=(bssrdf);
        this->_distances = bssrdf._distances;
        this->_colors = bssrdf._colors;
        return *this;
    }

    DiffuseBSSRDF& DiffuseBSSRDF::operator=(DiffuseBSSRDF&& bssrdf) {
        BSSRDFBase::operator=(std::move(bssrdf));
        this->_distances = std::move(bssrdf._distances);
        this->_colors = std::move(bssrdf._colors);
        return *this;
    }

    BSSRDF DiffuseBSSRDF::factory(const double eta, const std::vector<double>& distances, const std::vector<Color>& colors) {
        return std::move(BSSRDF(new DiffuseBSSRDF(eta, distances, colors)));
    }

    BSSRDF DiffuseBSSRDF::factory() const {
        return std::move(BSSRDF(new DiffuseBSSRDF(*this)));
    }

    Color DiffuseBSSRDF::operator()(const double d2) const {
        if (d2 < 0.0 || d2 > _distances[_distances.size() - 1]) return Color(0.0, 0.0, 0.0);
        const int idx = std::lower_bound(_distances.begin(), _distances.end(), d2) - _distances.begin();
        return _colors[idx];
    }

    BSSRDFBase* DiffuseBSSRDF::clone() const {
        return new DiffuseBSSRDF(*this);
    }

    int DiffuseBSSRDF::numIntervals() const {
        return static_cast<int>(_distances.size());
    }

    const std::vector<double>& DiffuseBSSRDF::distances() const {
        return _distances;
    }

    const std::vector<Color>& DiffuseBSSRDF::colors() const {
        return _colors;
    }

    DiffuseBSSRDF DiffuseBSSRDF::scaled(double sc) const {
        DiffuseBSSRDF ret(*this);
        for (size_t i = 0; i < ret._distances.size(); i++) {
            ret._distances[i] /= sc;
            ret._colors[i] /= (sc * sc);
        }
        return std::move(ret);
    }

    void DiffuseBSSRDF::save(const std::string& filename) const {
        std::ofstream ofs(filename.c_str(), std::ios::out | std::ios::binary);
        const int intervals = static_cast<int>(this->_distances.size());
        ofs.write((const char*)&intervals, sizeof(int));

        float ff[4];
        for (int i = 0; i < intervals; i++) {
            ff[0] = static_cast<float>(_distances[i]);
            ff[1] = static_cast<float>(_colors[i].red());
            ff[2] = static_cast<float>(_colors[i].green());
            ff[3] = static_cast<float>(_colors[i].blue());
            ofs.write((const char*)ff, sizeof(float) * 4);
        }

        ofs.close();
    }

    void DiffuseBSSRDF::load(const std::string& filename) {
        std::ifstream ifs(filename.c_str(), std::ios::in | std::ios::binary);
        Assertion(ifs.is_open(), "Faied to open file!!");

        int intervals;
        ifs.read((char*)&intervals, sizeof(int));

        _distances.resize(intervals);
        _colors.resize(intervals);

        float ff[4];
        for (int i = 0; i < intervals; i++) {
            ifs.read((char*)ff, sizeof(float) * 4);
            _distances[i] = ff[0];
            _colors[i] = spica::Color(ff[1], ff[2], ff[3]);
        }

        ifs.close();
    }

    // ------------------------------------------------------------
    // Abstract BSSRDF class
    // ------------------------------------------------------------

    BSSRDF::BSSRDF()
        : _ptr(NULL)
    {
    }

    BSSRDF::BSSRDF(const BSSRDF& bssrdf)
        : _ptr(NULL)
    {
        this->operator=(bssrdf);
    }

    BSSRDF::BSSRDF(BSSRDF&& bssrdf)
        : _ptr(NULL)
    {
        this->operator=(std::move(bssrdf));
    }

    BSSRDF::BSSRDF(const BSSRDFBase* ptr)
        : _ptr(ptr)
    {
    }

    BSSRDF::~BSSRDF() {
        delete _ptr;
    }

    BSSRDF& BSSRDF::operator=(const BSSRDF& bssrdf) {
        if (this == &bssrdf) {
            return *this;
        }

        delete _ptr;

        if (bssrdf._ptr == NULL) {
            _ptr = NULL;
        } else {
            _ptr = bssrdf._ptr->clone();
        }
        return *this;
    }

    BSSRDF& BSSRDF::operator=(BSSRDF&& bssrdf) {
        delete _ptr;

        this->_ptr = bssrdf._ptr;
        bssrdf._ptr = nullptr;
        return *this;
    }

    double BSSRDF::Ft(const Vector3D& normal, const Vector3D& in) const {
        nullCheck();
        return _ptr->Ft(normal, in);
    }

    double BSSRDF::Fdr() const {
        nullCheck();
        return _ptr->Fdr();
    }

    Color BSSRDF::operator()(const double dr) const {
        return _ptr->operator()(dr);
    }

    void BSSRDF::nullCheck() const {
        Assertion(_ptr != NULL, "BSSRDF does not have instance!!");
    }

}  // namespace spica
<commit_msg>Minor revision.<commit_after>#define SPICA_BSSRDF_EXPORT
#include "bssrdf.h"

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

#include "renderer_constants.h"

namespace spica {

    // ------------------------------------------------------------
    // BSSRDF base class
    // ------------------------------------------------------------

    double BSSRDFBase::Ft(const Vector3D& normal, const Vector3D& in) const {
        const double nnt = kIorObject / kIorVaccum;
        const double ddn = in.dot(normal);
        const double cos2t = 1.0 - nnt * nnt * (1.0 - ddn * ddn);

        if (cos2t < 0.0) return 0.0;

        Vector3D refractDir = (in * nnt + normal * (ddn * nnt + sqrt(cos2t))).normalized();

        const double a = kIorObject - kIorVaccum;
        const double b = kIorObject + kIorVaccum;
        const double R0 = (a * a) / (b * b);

        const double c  = 1.0 - Vector3D::dot(refractDir, -normal);
        const double Re = R0 + (1.0 - R0) * pow(c, 5.0);
        return 1.0 - Re;
    }

    double BSSRDFBase::Fdr() const {
        if (_eta >= 1.0) {
            return -1.4399 / (_eta * _eta) + 0.7099 / _eta + 0.6681 + 0.0636 * _eta;
        } else {
            return -0.4399 + 0.7099 / _eta - 0.3319 / (_eta * _eta) + 0.0636 / (_eta * _eta * _eta);
        }
    }

    // ------------------------------------------------------------
    // BSSRDF with dipole approximation
    // ------------------------------------------------------------

    DipoleBSSRDF::DipoleBSSRDF(const Color& sigma_a,
                               const Color& sigmap_s, double eta)
        : BSSRDFBase(eta)
        , _A(0.0)
        , _sigmap_t()
        , _sigma_tr()
        , _alphap()
        , _zpos()
        , _zneg()
    {
        _A = (1.0 + Fdr()) / (1.0 - Fdr());
        _sigmap_t = sigma_a + sigmap_s;
        _sigma_tr = Color::sqrt(3.0 * sigma_a * _sigmap_t);
        _alphap = sigmap_s / _sigmap_t;
        _zpos = Color(1.0, 1.0, 1.0) / _sigmap_t;
        _zneg = _zpos * (1.0 + (4.0 / 3.0) * _A);
    }

    DipoleBSSRDF::DipoleBSSRDF(const DipoleBSSRDF& bssrdf)
        : BSSRDFBase()
        , _A(0.0)
        , _sigmap_t()
        , _sigma_tr()
        , _alphap()
        , _zpos()
        , _zneg()
    {
        this->operator=(bssrdf);
    }

    DipoleBSSRDF& DipoleBSSRDF::operator=(const DipoleBSSRDF& bssrdf) {
        BSSRDFBase::operator=(bssrdf);
        this->_A = bssrdf._A;
        this->_sigmap_t = bssrdf._sigmap_t;
        this->_sigma_tr = bssrdf._sigma_tr;
        this->_alphap = bssrdf._alphap;
        this->_zpos = bssrdf._zpos;
        this->_zneg = bssrdf._zneg;
        return *this;
    }

    BSSRDF DipoleBSSRDF::factory(const Color& sigma_a, const Color& sigmap_s, double eta) {
        return BSSRDF(new DipoleBSSRDF(sigma_a, sigmap_s, eta));
    }

    Color DipoleBSSRDF::operator()(const double d2) const {
        const Color dpos = Color::sqrt(d2 + _zpos * _zpos);
        const Color dneg = Color::sqrt(d2 + _zneg * _zneg);
        const Color dpos3 = dpos * dpos * dpos;
        const Color dneg3 = dneg * dneg * dneg;
        const Color posTerm = _zpos * (dpos * _sigma_tr + 1.0) * Color::exp(-_sigma_tr * dpos);
        const Color negTerm = _zneg * (dneg * _sigma_tr + 1.0) * Color::exp(-_sigma_tr * dneg);
        const Color Rd = ((_alphap * posTerm * dneg3 - negTerm * dpos3) / (4.0 * PI * _sigma_tr * dpos3 * dneg3));
        return Rd.clamp();
    }

    BSSRDFBase* DipoleBSSRDF::clone() const {
        return new DipoleBSSRDF(*this);
    }

    // ------------------------------------------------------------
    // BSSRDF with diffuse reflectance function
    // ------------------------------------------------------------

    DiffuseBSSRDF::DiffuseBSSRDF()
        : BSSRDFBase()
        , _distances()
        , _colors()
    {
    }

    DiffuseBSSRDF::DiffuseBSSRDF(const double eta, const std::vector<double>& distances, const std::vector<Color>& colors)
        : BSSRDFBase(eta)
        , _distances(distances)
        , _colors(colors)
    {
        Assertion(distances.size() == colors.size(), "Arrays for distances and colors must have the same length!!");
    }

    DiffuseBSSRDF::DiffuseBSSRDF(const DiffuseBSSRDF& bssrdf)
        : BSSRDFBase()
        , _distances()
        , _colors()
    {
        this->operator=(bssrdf);
    }

    DiffuseBSSRDF::DiffuseBSSRDF(DiffuseBSSRDF&& bssrdf)
        : BSSRDFBase()
        , _distances()
        , _colors()
    {
        this->operator=(std::move(bssrdf));
    }

    DiffuseBSSRDF& DiffuseBSSRDF::operator=(const DiffuseBSSRDF& bssrdf) {
        BSSRDFBase::operator=(bssrdf);
        this->_distances = bssrdf._distances;
        this->_colors = bssrdf._colors;
        return *this;
    }

    DiffuseBSSRDF& DiffuseBSSRDF::operator=(DiffuseBSSRDF&& bssrdf) {
        BSSRDFBase::operator=(std::move(bssrdf));
        this->_distances = std::move(bssrdf._distances);
        this->_colors = std::move(bssrdf._colors);
        return *this;
    }

    BSSRDF DiffuseBSSRDF::factory(const double eta, const std::vector<double>& distances, const std::vector<Color>& colors) {
        return std::move(BSSRDF(new DiffuseBSSRDF(eta, distances, colors)));
    }

    BSSRDF DiffuseBSSRDF::factory() const {
        return std::move(BSSRDF(new DiffuseBSSRDF(*this)));
    }

    Color DiffuseBSSRDF::operator()(const double d2) const {
        if (d2 < 0.0 || d2 > _distances[_distances.size() - 1]) return Color(0.0, 0.0, 0.0);
        const int idx = std::lower_bound(_distances.begin(), _distances.end(), d2) - _distances.begin();
        return _colors[idx];
    }

    BSSRDFBase* DiffuseBSSRDF::clone() const {
        return new DiffuseBSSRDF(*this);
    }

    int DiffuseBSSRDF::numIntervals() const {
        return static_cast<int>(_distances.size());
    }

    const std::vector<double>& DiffuseBSSRDF::distances() const {
        return _distances;
    }

    const std::vector<Color>& DiffuseBSSRDF::colors() const {
        return _colors;
    }

    DiffuseBSSRDF DiffuseBSSRDF::scaled(double sc) const {
        DiffuseBSSRDF ret(*this);
        for (size_t i = 0; i < ret._distances.size(); i++) {
            ret._distances[i] /= sc;
            ret._colors[i] /= (sc * sc);
        }
        return std::move(ret);
    }

    void DiffuseBSSRDF::save(const std::string& filename) const {
        std::ofstream ofs(filename.c_str(), std::ios::out | std::ios::binary);
        const int intervals = static_cast<int>(this->_distances.size());
        ofs.write((const char*)&intervals, sizeof(int));

        float ff[4];
        for (int i = 0; i < intervals; i++) {
            ff[0] = static_cast<float>(_distances[i]);
            ff[1] = static_cast<float>(_colors[i].red());
            ff[2] = static_cast<float>(_colors[i].green());
            ff[3] = static_cast<float>(_colors[i].blue());
            ofs.write((const char*)ff, sizeof(float) * 4);
        }

        ofs.close();
    }

    void DiffuseBSSRDF::load(const std::string& filename) {
        std::ifstream ifs(filename.c_str(), std::ios::in | std::ios::binary);
        Assertion(ifs.is_open(), "Faied to open file!!");

        int intervals;
        ifs.read((char*)&intervals, sizeof(int));

        _distances.resize(intervals);
        _colors.resize(intervals);

        float ff[4];
        for (int i = 0; i < intervals; i++) {
            ifs.read((char*)ff, sizeof(float) * 4);
            _distances[i] = ff[0];
            _colors[i] = spica::Color(ff[1], ff[2], ff[3]);
        }

        ifs.close();
    }

    // ------------------------------------------------------------
    // Abstract BSSRDF class
    // ------------------------------------------------------------

    BSSRDF::BSSRDF()
        : _ptr(NULL)
    {
    }

    BSSRDF::BSSRDF(const BSSRDF& bssrdf)
        : _ptr(NULL)
    {
        this->operator=(bssrdf);
    }

    BSSRDF::BSSRDF(BSSRDF&& bssrdf)
        : _ptr(NULL)
    {
        this->operator=(std::move(bssrdf));
    }

    BSSRDF::BSSRDF(const BSSRDFBase* ptr)
        : _ptr(ptr)
    {
    }

    BSSRDF::~BSSRDF() {
        delete _ptr;
    }

    BSSRDF& BSSRDF::operator=(const BSSRDF& bssrdf) {
        if (this == &bssrdf) {
            return *this;
        }

        delete _ptr;

        if (bssrdf._ptr == NULL) {
            _ptr = NULL;
        } else {
            _ptr = bssrdf._ptr->clone();
        }
        return *this;
    }

    BSSRDF& BSSRDF::operator=(BSSRDF&& bssrdf) {
        delete _ptr;

        this->_ptr = bssrdf._ptr;
        bssrdf._ptr = nullptr;
        return *this;
    }

    double BSSRDF::Ft(const Vector3D& normal, const Vector3D& in) const {
        nullCheck();
        return _ptr->Ft(normal, in);
    }

    double BSSRDF::Fdr() const {
        nullCheck();
        return _ptr->Fdr();
    }

    Color BSSRDF::operator()(const double dr) const {
        return _ptr->operator()(dr);
    }

    void BSSRDF::nullCheck() const {
        Assertion(_ptr != NULL, "BSSRDF does not have instance!!");
    }

}  // namespace spica
<|endoftext|>