<commit_before>/**
    avrdude front-end, widget.cpp

    @author Fay Zheng <fay2003hiend@gmail.com>
    @version 1.0 March 03 2017
*/

#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QDir>
#include <QMessageBox>
#include <QTimer>
#include <QProcess>
#include <QSettings>
#include <QDesktopServices>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>

ZProcess::ZProcess(QObject *parent)
    : QProcess(parent)
{
    connect(this, SIGNAL(readyReadStandardOutput()), SLOT(slot_read_stdout()));
    connect(this, SIGNAL(readyReadStandardError()), SLOT(slot_read_stderr()));
}

void ZProcess::slot_read_stdout()
{
    std_out_data.append(readAllStandardOutput());
}

void ZProcess::slot_read_stderr()
{
    std_err_data.append(readAllStandardError());
}

int ZProcess::execute(const QString &command)
{
    start(command, QProcess::ReadOnly);

    if (!waitForStarted())
    {
        return -1;
    }

    if (!waitForFinished())
    {
        return -2;
    }

    return exitCode();
}

bool extract_asset(const QString& path_r, const QString& path_w)
{
    if (QFile::exists(path_w))
    {
        return true;
    }

    QFile fr(path_r);
    QFile fw(path_w);
    bool ret = false;

    if (fr.open(QIODevice::ReadOnly)) {
        if(fw.open(QIODevice::WriteOnly))
        {
            fw.write(fr.readAll());
            fw.close();
            ret = true;
        }
        fr.close();
    }
    return ret;
}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle(windowTitle() + tr(" -- Fay Zheng <fay2003hiend@gmail.com>"));

    connect(ui->pushButton_calc, SIGNAL(clicked(bool)), SLOT(slot_calc()));
    connect(ui->pushButton_cmd, SIGNAL(clicked(bool)), SLOT(slot_cmd()));
    connect(ui->pushButton_read, SIGNAL(clicked(bool)), SLOT(slot_read()));

    connect(ui->checkBox_do_fuse, SIGNAL(toggled(bool)), SLOT(slot_do_fuse(bool)));
    connect(ui->checkBox_hfuse, SIGNAL(toggled(bool)), SLOT(slot_hfuse(bool)));
    connect(ui->checkBox_efuse, SIGNAL(toggled(bool)), SLOT(slot_efuse(bool)));

    QTimer::singleShot(10, this, SLOT(slot_init()));
}

void Widget::dragEnterEvent(QDragEnterEvent *event)
{
    if(event->mimeData()->hasUrls()) {
        event->acceptProposedAction();
    }
}

void Widget::do_cmd(const QString &path)
{
    QString fuses;
    QString update;
    fromUI();

    if(do_fuse)
    {
        fuses = QString(" -U lfuse:w:0x%1:m").arg(last_lfuse);

        if (has_hfuse)
        {
            fuses += QString("-U hfuse:w:0x%1:m").arg(last_hfuse);
        }
        if (has_efuse)
        {
            fuses += QString("-U efuse:w:0x%1:m").arg(last_efuse);
        }
    }

    if (!path.isEmpty()) {
        update = QString(" -U flash:w:\"%1\":i").arg(path);
    }
    QString ret = QString("avrdude.exe -s -C avrdude.conf -c %1 -p %2 ")
            .arg(last_programmer, last_device)
            + fuses
            + update
            + " " + last_arguments;

    if (QMessageBox::question(this, tr("Execute"), ret,
                              QMessageBox::Yes, QMessageBox::No)
            == QMessageBox::Yes) {
        ZProcess p;
        p.execute(ret);
        ui->textBrowser->append("----");
        ui->textBrowser->append(p.std_out_data);
        ui->textBrowser->append("----");
        ui->textBrowser->append(p.std_err_data);
    }
}

void Widget::dropEvent(QDropEvent *event)
{
    QUrl url = event->mimeData()->urls().at(0);
    QString path = QDir::toNativeSeparators(url.toLocalFile());
    if(!path.endsWith(".hex")) {
        event->ignore();
        return;
    }

    last_path = path;
    do_cmd(path);
}

void Widget::slot_do_fuse(bool checked)
{
    ui->widget_fuse->setEnabled(checked);
}

void Widget::slot_hfuse(bool checked)
{
    ui->lineEdit_hfuse->setEnabled(checked);
}

void Widget::slot_efuse(bool checked)
{
    ui->lineEdit_efuse->setEnabled(checked);
}

#define SAVE_STR(x) conf.setValue(#x, x)
#define SAVE_BOOL(x) conf.setValue(#x, x)

Widget::~Widget()
{
    fromUI();
    QSettings conf("Qavrdude.ini", QSettings::IniFormat);
    SAVE_STR(last_programmer);
    SAVE_STR(last_device);
    SAVE_STR(last_arguments);
    SAVE_STR(last_hfuse);
    SAVE_STR(last_lfuse);
    SAVE_STR(last_efuse);
    SAVE_BOOL(do_fuse);
    SAVE_BOOL(has_hfuse);
    SAVE_BOOL(has_efuse);
    conf.sync();

    delete ui;
}

void Widget::fromUI()
{
    last_programmer = ui->comboBox_programmer->currentText();
    last_device = ui->comboBox_device->currentText();
    last_arguments = ui->lineEdit_arguments->text();

    last_hfuse = ui->lineEdit_hfuse->text().toLower();
    last_lfuse = ui->lineEdit_lfuse->text().toLower();
    last_efuse = ui->lineEdit_efuse->text().toLower();

    do_fuse = ui->checkBox_do_fuse->isChecked();
    has_hfuse = ui->checkBox_hfuse->isChecked();
    has_efuse = ui->checkBox_efuse->isChecked();
}

void Widget::toUI()
{
    ui->lineEdit_arguments->setText(last_arguments);
    ui->lineEdit_hfuse->setText(last_hfuse);
    ui->lineEdit_lfuse->setText(last_lfuse);
    ui->lineEdit_efuse->setText(last_efuse);

    ui->checkBox_do_fuse->setChecked(do_fuse);
    ui->widget_fuse->setEnabled(do_fuse);

    ui->checkBox_hfuse->setChecked(has_hfuse);
    ui->lineEdit_hfuse->setEnabled(has_hfuse);

    ui->checkBox_efuse->setChecked(has_efuse);
    ui->lineEdit_efuse->setEnabled(has_efuse);
}

bool Widget::fill_combobox(const QString &prog, QComboBox *box, const QString& matching_d)
{
    ZProcess p;
    if (p.execute(prog) < 0)
    {
        return false;
    }

    QList<QByteArray> lines = p.std_err_data.split('\n');
    QString str, key, value;
    int i = 0;
    int found = -1;
    int n;
    foreach(const QByteArray& line, lines)
    {
        str = QString::fromLocal8Bit(line);
        if ((n = str.indexOf(" = ")) == -1)
        {
            continue;
        }

        key = str.left(n).simplified();
        value = str.mid(n+3).simplified();

        box->addItem(QString("%1 - %2").arg(key, value), key);
        if (found == -1 && key == matching_d)
        {
            found = i;
            box->setCurrentIndex(i);
        }
        ++i;
    }
    return true;
}

#define READ_STR(x) x = conf.value(#x).toString()
#define READ_BOOL(x) x = conf.value(#x).toBool()

void Widget::slot_init()
{
    if (!extract_asset(":/bin/avrdude.exe", "avrdude.exe")
            || !extract_asset(":/bin/avrdude.conf", "avrdude.conf"))
    {
        QMessageBox::warning(this, tr("Error"),
                             tr("avrdude binaries can't be extracted!"),
                             QMessageBox::Ok);
        qApp->quit();
    }

    QSettings conf("Qavrdude.ini", QSettings::IniFormat);
    READ_STR(last_programmer);
    READ_STR(last_device);
    READ_STR(last_arguments);
    READ_STR(last_hfuse);
    READ_STR(last_lfuse);
    READ_STR(last_efuse);
    READ_BOOL(do_fuse);
    READ_BOOL(has_efuse);

    fill_combobox("avrdude.exe -c?", ui->comboBox_programmer, last_programmer);
    fill_combobox("avrdude.exe -p?", ui->comboBox_device, last_device);
    toUI();

    this->setAcceptDrops(true);
}

void Widget::slot_read()
{
    ZProcess p;
    last_programmer = ui->comboBox_programmer->currentText();
    last_device = ui->comboBox_device->currentText();
    last_arguments = ui->lineEdit_arguments->text();

    p.execute(QString("avrdude.exe -s -C avrdude.conf -c %1 -p %2 ")
              .arg(last_programmer, last_device)
              + last_arguments);
    ui->textBrowser->append(p.std_out_data);
    ui->textBrowser->append("--------------");
    ui->textBrowser->append(p.std_err_data);

    QString str = QString::fromLocal8Bit(p.std_err_data);
    int n;
    QRegExp expr("Fuses OK \\(E:[0-9A-F][0-9A-F], H:[0-9A-F][0-9A-F], L:[0-9A-F][0-9A-F]\\)");
    if ((n = str.indexOf(expr)) != -1)
    {
        ui->lineEdit_efuse->setText(str.mid(n + 12, 2));
        ui->lineEdit_hfuse->setText(str.mid(n + 18, 2));
        ui->lineEdit_lfuse->setText(str.mid(n + 24, 2));
    }
}

void Widget::slot_cmd()
{
    do_cmd(last_path);
}

void Widget::slot_calc()
{
    QDesktopServices::openUrl(QUrl("http://www.engbedded.com/fusecalc/"));
}
<commit_msg>fix argument for h and e fuse<commit_after>/**
    avrdude front-end, widget.cpp

    @author Fay Zheng <fay2003hiend@gmail.com>
    @version 1.0 March 03 2017
*/

#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QDir>
#include <QMessageBox>
#include <QTimer>
#include <QProcess>
#include <QSettings>
#include <QDesktopServices>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>

ZProcess::ZProcess(QObject *parent)
    : QProcess(parent)
{
    connect(this, SIGNAL(readyReadStandardOutput()), SLOT(slot_read_stdout()));
    connect(this, SIGNAL(readyReadStandardError()), SLOT(slot_read_stderr()));
}

void ZProcess::slot_read_stdout()
{
    std_out_data.append(readAllStandardOutput());
}

void ZProcess::slot_read_stderr()
{
    std_err_data.append(readAllStandardError());
}

int ZProcess::execute(const QString &command)
{
    start(command, QProcess::ReadOnly);

    if (!waitForStarted())
    {
        return -1;
    }

    if (!waitForFinished())
    {
        return -2;
    }

    return exitCode();
}

bool extract_asset(const QString& path_r, const QString& path_w)
{
    if (QFile::exists(path_w))
    {
        return true;
    }

    QFile fr(path_r);
    QFile fw(path_w);
    bool ret = false;

    if (fr.open(QIODevice::ReadOnly)) {
        if(fw.open(QIODevice::WriteOnly))
        {
            fw.write(fr.readAll());
            fw.close();
            ret = true;
        }
        fr.close();
    }
    return ret;
}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle(windowTitle() + tr(" -- Fay Zheng <fay2003hiend@gmail.com>"));

    connect(ui->pushButton_calc, SIGNAL(clicked(bool)), SLOT(slot_calc()));
    connect(ui->pushButton_cmd, SIGNAL(clicked(bool)), SLOT(slot_cmd()));
    connect(ui->pushButton_read, SIGNAL(clicked(bool)), SLOT(slot_read()));

    connect(ui->checkBox_do_fuse, SIGNAL(toggled(bool)), SLOT(slot_do_fuse(bool)));
    connect(ui->checkBox_hfuse, SIGNAL(toggled(bool)), SLOT(slot_hfuse(bool)));
    connect(ui->checkBox_efuse, SIGNAL(toggled(bool)), SLOT(slot_efuse(bool)));

    QTimer::singleShot(10, this, SLOT(slot_init()));
}

void Widget::dragEnterEvent(QDragEnterEvent *event)
{
    if(event->mimeData()->hasUrls()) {
        event->acceptProposedAction();
    }
}

void Widget::do_cmd(const QString &path)
{
    QString fuses;
    QString update;
    fromUI();

    if(do_fuse)
    {
        fuses = QString(" -U lfuse:w:0x%1:m").arg(last_lfuse);

        if (has_hfuse)
        {
            fuses += QString(" -U hfuse:w:0x%1:m").arg(last_hfuse);
        }
        if (has_efuse)
        {
            fuses += QString(" -U efuse:w:0x%1:m").arg(last_efuse);
        }
    }

    if (!path.isEmpty()) {
        update = QString(" -U flash:w:\"%1\":i").arg(path);
    }
    QString ret = QString("avrdude.exe -s -C avrdude.conf -c %1 -p %2 ")
            .arg(last_programmer, last_device)
            + fuses
            + update
            + " " + last_arguments;

    if (QMessageBox::question(this, tr("Execute"), ret,
                              QMessageBox::Yes, QMessageBox::No)
            == QMessageBox::Yes) {
        ZProcess p;
        p.execute(ret);
        ui->textBrowser->append("----");
        ui->textBrowser->append(p.std_out_data);
        ui->textBrowser->append("----");
        ui->textBrowser->append(p.std_err_data);
    }
}

void Widget::dropEvent(QDropEvent *event)
{
    QUrl url = event->mimeData()->urls().at(0);
    QString path = QDir::toNativeSeparators(url.toLocalFile());
    if(!path.endsWith(".hex")) {
        event->ignore();
        return;
    }

    last_path = path;
    do_cmd(path);
}

void Widget::slot_do_fuse(bool checked)
{
    ui->widget_fuse->setEnabled(checked);
}

void Widget::slot_hfuse(bool checked)
{
    ui->lineEdit_hfuse->setEnabled(checked);
}

void Widget::slot_efuse(bool checked)
{
    ui->lineEdit_efuse->setEnabled(checked);
}

#define SAVE_STR(x) conf.setValue(#x, x)
#define SAVE_BOOL(x) conf.setValue(#x, x)

Widget::~Widget()
{
    fromUI();
    QSettings conf("Qavrdude.ini", QSettings::IniFormat);
    SAVE_STR(last_programmer);
    SAVE_STR(last_device);
    SAVE_STR(last_arguments);
    SAVE_STR(last_hfuse);
    SAVE_STR(last_lfuse);
    SAVE_STR(last_efuse);
    SAVE_BOOL(do_fuse);
    SAVE_BOOL(has_hfuse);
    SAVE_BOOL(has_efuse);
    conf.sync();

    delete ui;
}

void Widget::fromUI()
{
    last_programmer = ui->comboBox_programmer->currentText();
    last_device = ui->comboBox_device->currentText();
    last_arguments = ui->lineEdit_arguments->text();

    last_hfuse = ui->lineEdit_hfuse->text().toLower();
    last_lfuse = ui->lineEdit_lfuse->text().toLower();
    last_efuse = ui->lineEdit_efuse->text().toLower();

    do_fuse = ui->checkBox_do_fuse->isChecked();
    has_hfuse = ui->checkBox_hfuse->isChecked();
    has_efuse = ui->checkBox_efuse->isChecked();
}

void Widget::toUI()
{
    ui->lineEdit_arguments->setText(last_arguments);
    ui->lineEdit_hfuse->setText(last_hfuse);
    ui->lineEdit_lfuse->setText(last_lfuse);
    ui->lineEdit_efuse->setText(last_efuse);

    ui->checkBox_do_fuse->setChecked(do_fuse);
    ui->widget_fuse->setEnabled(do_fuse);

    ui->checkBox_hfuse->setChecked(has_hfuse);
    ui->lineEdit_hfuse->setEnabled(has_hfuse);

    ui->checkBox_efuse->setChecked(has_efuse);
    ui->lineEdit_efuse->setEnabled(has_efuse);
}

bool Widget::fill_combobox(const QString &prog, QComboBox *box, const QString& matching_d)
{
    ZProcess p;
    if (p.execute(prog) < 0)
    {
        return false;
    }

    QList<QByteArray> lines = p.std_err_data.split('\n');
    QString str, key, value;
    int i = 0;
    int found = -1;
    int n;
    foreach(const QByteArray& line, lines)
    {
        str = QString::fromLocal8Bit(line);
        if ((n = str.indexOf(" = ")) == -1)
        {
            continue;
        }

        key = str.left(n).simplified();
        value = str.mid(n+3).simplified();

        box->addItem(QString("%1 - %2").arg(key, value), key);
        if (found == -1 && key == matching_d)
        {
            found = i;
            box->setCurrentIndex(i);
        }
        ++i;
    }
    return true;
}

#define READ_STR(x) x = conf.value(#x).toString()
#define READ_BOOL(x) x = conf.value(#x).toBool()

void Widget::slot_init()
{
    if (!extract_asset(":/bin/avrdude.exe", "avrdude.exe")
            || !extract_asset(":/bin/avrdude.conf", "avrdude.conf"))
    {
        QMessageBox::warning(this, tr("Error"),
                             tr("avrdude binaries can't be extracted!"),
                             QMessageBox::Ok);
        qApp->quit();
    }

    QSettings conf("Qavrdude.ini", QSettings::IniFormat);
    READ_STR(last_programmer);
    READ_STR(last_device);
    READ_STR(last_arguments);
    READ_STR(last_hfuse);
    READ_STR(last_lfuse);
    READ_STR(last_efuse);
    READ_BOOL(do_fuse);
    READ_BOOL(has_efuse);

    fill_combobox("avrdude.exe -c?", ui->comboBox_programmer, last_programmer);
    fill_combobox("avrdude.exe -p?", ui->comboBox_device, last_device);
    toUI();

    this->setAcceptDrops(true);
}

void Widget::slot_read()
{
    ZProcess p;
    last_programmer = ui->comboBox_programmer->currentText();
    last_device = ui->comboBox_device->currentText();
    last_arguments = ui->lineEdit_arguments->text();

    p.execute(QString("avrdude.exe -s -C avrdude.conf -c %1 -p %2 ")
              .arg(last_programmer, last_device)
              + last_arguments);
    ui->textBrowser->append(p.std_out_data);
    ui->textBrowser->append("--------------");
    ui->textBrowser->append(p.std_err_data);

    QString str = QString::fromLocal8Bit(p.std_err_data);
    int n;
    QRegExp expr("Fuses OK \\(E:[0-9A-F][0-9A-F], H:[0-9A-F][0-9A-F], L:[0-9A-F][0-9A-F]\\)");
    if ((n = str.indexOf(expr)) != -1)
    {
        ui->lineEdit_efuse->setText(str.mid(n + 12, 2));
        ui->lineEdit_hfuse->setText(str.mid(n + 18, 2));
        ui->lineEdit_lfuse->setText(str.mid(n + 24, 2));
    }
}

void Widget::slot_cmd()
{
    do_cmd(last_path);
}

void Widget::slot_calc()
{
    QDesktopServices::openUrl(QUrl("http://www.engbedded.com/fusecalc/"));
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : B2.cpp
 * Author  : Kazune Takahashi
 * Created : 7/22/2019, 3:04:34 AM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

ll N, K;
ll C;
int A[200010];
ll a[60][200010];

int main()
{
  cin >> N >> K;
  C = N * K;
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < N; i++)
  {
    a[i][0] = -1;
  }
  vector<int> used(200010, -1);
  for (auto k = 0; k < 2; k++)
  {
    for (auto i = 0; i < N; i++)
    {
      if (used[A[i]] != -1)
      {
        a[0][used[A[i]]] = k * N + i - used[A[i]];
      }
      used[A[i]] = k * N + i;
    }
  }
#if DEBUG == 1
  for (auto i = 0; i < N; i++)
  {
    cerr << "a[0][" << i << "] = " << a[0][i] << endl;
  }
#endif
  for (auto k = 1; k < 60; k++)
  {
    for (auto i = 0; i < N; i++)
    {
      a[k][i] = a[k - 1][i] + a[k - 1][(a[k - 1][i] + 1) % N];
#if DEBUG == 1
      if (k < 5)
      {
        cerr << "a[" << k << "][" << i << "] = " << a[k][i] << endl;
      }
#endif
    }
  }
  ll sum = 0;
  int now = 0;
  while (true)
  {
    int ind = 0;
    for (auto k = 0; k < 60; k++)
    {
      if (a[k][now] + sum >= C)
      {
        ind = k - 1;
        break;
      }
    }
    if (ind == -1)
    {
      break;
    }
    sum += a[ind][now];
    now = (sum + 1) % N;
  }
#if DEBUG == 1
  cerr << "sum = " << sum << endl;
  cerr << "now = " << now << endl;
#endif
  deque<int> D;
  vector<bool> stacked(200010, false);
  for (auto i = now; i < N; i++)
  {
    if (!stacked[A[i]])
    {
      D.push_back(A[i]);
      stacked[A[i]] = true;
    }
    else
    {
      while (true)
      {
        int x = *D.rbegin();
        D.pop_back();
        stacked[x] = false;
        if (x == A[i])
        {
          break;
        }
      }
    }
  }
  for (auto i = 0u; i < D.size(); i++)
  {
    cout << D[i];
    if (i < D.size() - 1)
    {
      cout << " ";
    }
  }
  cout << endl;
}<commit_msg>tried B2.cpp to 'B'<commit_after>#define DEBUG 1
/**
 * File    : B2.cpp
 * Author  : Kazune Takahashi
 * Created : 7/22/2019, 3:04:34 AM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a)
  {
    mint b{a};
    return *this *= b.power(MOD - 2);
  }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 3000010;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

ll N, K;
ll C;
int A[200010];
ll a[60][200010];

int main()
{
  cin >> N >> K;
  C = N * K;
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < N; i++)
  {
    a[i][0] = -1;
  }
  vector<int> used(200010, -1);
  for (auto k = 0; k < 2; k++)
  {
    for (auto i = 0; i < N; i++)
    {
      if (used[A[i]] != -1)
      {
        a[0][used[A[i]]] = k * N + i - used[A[i]];
      }
      used[A[i]] = k * N + i;
    }
  }
#if DEBUG == 1
  for (auto i = 0; i < N; i++)
  {
    cerr << "a[0][" << i << "] = " << a[0][i] << endl;
  }
#endif
  for (auto k = 1; k < 60; k++)
  {
    for (auto i = 0; i < N; i++)
    {
      a[k][i] = a[k - 1][i] + a[k - 1][(a[k - 1][i] + 1) % N];
#if DEBUG == 1
      if (k < 5)
      {
        cerr << "a[" << k << "][" << i << "] = " << a[k][i] << endl;
      }
#endif
    }
  }
  ll sum = 0;
  int now = 0;
  while (true)
  {
    int ind = 0;
    for (auto k = 0; k < 60; k++)
    {
      if (a[k][now] + sum > C)
      {
        ind = k - 1;
        break;
      }
    }
    if (ind == -1)
    {
      break;
    }
    sum += a[ind][now];
    now = (sum + 1) % N;
  }
#if DEBUG == 1
  cerr << "sum = " << sum << endl;
  cerr << "now = " << now << endl;
#endif
  deque<int> D;
  vector<bool> stacked(200010, false);
  for (auto i = now; i < N; i++)
  {
    if (!stacked[A[i]])
    {
      D.push_back(A[i]);
      stacked[A[i]] = true;
    }
    else
    {
      while (true)
      {
        int x = *D.rbegin();
        D.pop_back();
        stacked[x] = false;
        if (x == A[i])
        {
          break;
        }
      }
    }
  }
  for (auto i = 0u; i < D.size(); i++)
  {
    cout << D[i];
    if (i < D.size() - 1)
    {
      cout << " ";
    }
  }
  cout << endl;
}<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : D2.cpp
 * Author  : Kazune Takahashi
 * Created : 11/13/2019, 7:24:07 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <boost/rational.hpp>
using boost::rational;
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{1000000007LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "0 1" << endl;
  exit(0);
}

using Info = tuple<ll, ll>;

int main()
{
  int N;
  cin >> N;
  vector<Info> V(N);
  ll A_sum{0LL};
  for (auto i = 0; i < N; i++)
  {
    ll A, B;
    cin >> A >> B;
    V[i] = Info(max(A, B), B);
    A_sum += A;
  }
  sort(V.rbegin(), V.rend());
  vector<ll> C_sum(N + 1);
  C_sum[0] = 0;
  for (auto i = 0; i < N; i++)
  {
    C_sum[i + 1] = C_sum[i] + get<0>(V[i]);
  }
  if (C_sum[N] == A_sum)
  {
    No();
  }
  rational<ll> ans{0, 1};
#if DEBUG == 1
  cerr << "A_sum = " << A_sum << endl;
#endif
  for (auto k = 0; k < N; k++)
  {
    ll B_k{get<1>(V[k])};
    ll ok{N}, ng{-1};
    ll tmp_sum{0};
    bool included{false};
    while (abs(ok - ng) > 1)
    {
      ll t{(ok + ng) / 2};
      ll tmp{C_sum[t]};
      if (k < t)
      {
        tmp -= B_k;
      }
      if (tmp + B_k >= A_sum)
      {
        ok = t;
        included = k < t;
        tmp_sum = tmp;
      }
      else
      {
        ng = t;
      }
    }
    rational<ll> r{A_sum - tmp_sum, B_k};
#if DEBUG == 1
    cerr << "k = " << k << ", B_k = " << B_k << ", tmp_sum = " << tmp_sum << ", r = " << r << endl;
#endif
    if (r < 0)
    {
      r = rational<ll>(0);
    }
    ll M{included ? ok - 1 : ok};
#if DEBUG == 1
    cerr << "ok = " << ok << ", included = " << included << ", M = " << M << ", r = " << r << endl;
#endif
    rational<ll> tmp_ans = (N - M - r) / N;
    ch_max(ans, tmp_ans);
  }
  cout << ans.numerator() << " " << ans.denominator() << endl;
}
<commit_msg>tried D2.cpp to 'D'<commit_after>#define DEBUG 1
/**
 * File    : D2.cpp
 * Author  : Kazune Takahashi
 * Created : 11/13/2019, 7:24:07 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <boost/rational.hpp>
using boost::rational;
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{1000000007LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "0 1" << endl;
  exit(0);
}

using Info = tuple<ll, ll>;

int main()
{
  int N;
  cin >> N;
  vector<Info> V(N);
  ll A_sum{0LL};
  for (auto i = 0; i < N; i++)
  {
    ll A, B;
    cin >> A >> B;
    V[i] = Info(max(A, B), B);
    A_sum += A;
  }
  sort(V.rbegin(), V.rend());
  vector<ll> C_sum(N + 1);
  C_sum[0] = 0;
  for (auto i = 0; i < N; i++)
  {
    C_sum[i + 1] = C_sum[i] + get<0>(V[i]);
  }
  if (C_sum[N] == A_sum)
  {
    No();
  }
  rational<ll> ans{0, 1};
#if DEBUG == 1
  cerr << "A_sum = " << A_sum << endl;
#endif
  for (auto k = 0; k < N; k++)
  {
    ll B_k{get<1>(V[k])};
    ll ok{N}, ng{-1};
    ll tmp_sum{0};
    bool included{false};
    while (abs(ok - ng) > 1)
    {
      ll t{(ok + ng) / 2};
      ll tmp{C_sum[t]};
      if (k < t)
      {
        tmp -= B_k;
      }
      if (tmp + B_k >= A_sum)
      {
        ok = t;
        included = k < t;
        tmp_sum = tmp;
      }
      else
      {
        ng = t;
      }
    }
    rational<ll> r{A_sum - tmp_sum, B_k};
#if DEBUG == 1
    cerr << "k = " << k << ", B_k = " << B_k << ", tmp_sum = " << tmp_sum << ", r = " << r << endl;
#endif
    ll M{included ? ok - 1 : ok};
#if DEBUG == 1
    cerr << "ok = " << ok << ", included = " << included << ", M = " << M << ", r = " << r << endl;
#endif
    if (r < 0)
    {
      continue;
    }
    rational<ll> tmp_ans = (N - M - r) / N;
    ch_max(ans, tmp_ans);
  }
  cout << ans.numerator() << " " << ans.denominator() << endl;
}
<|endoftext|>


<commit_before>#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iterator>
#include <tuple>
#include <regex>
#include <array>
#include <valarray>
#define all(v)begin(v),end(v)
#define dump(v)copy(all(v),ostream_iterator<decltype(*v.begin())>(cout,"\n"))
#define rg(i,a,b)for(int i=a,i##e=b;i<i##e;++i)
#define fr(i,n)for(int i=0,i##e=n;i<i##e;++i)
#define rf(i,n)for(int i=n-1;i>=0;--i)
#define ei(a,m)for(auto&a:m)if(int a##i=&a-&*begin(m)+1)if(--a##i,1)
#define sz(v)int(v.size())
#define sr(v)sort(all(v))
#define rs(v)sort(all(v),greater<int>())
#define rev(v)reverse(all(v))
#define eb emplace_back
#define stst stringstream
#define big numeric_limits<int>::max()
#define g(t,i)get<i>(t)
#define cb(v,w)copy(all(v),back_inserter(w))
#define uni(v)sort(all(v));v.erase(unique(all(v)),end(v))
#define vt(...)vector<tuple<__VA_ARGS__>>
#define smx(a,b)a=max(a,b)
#define smn(a,b)a=min(a,b)
#define words(w,q)vector<string>w;[&w](string&&s){stringstream u(s);string r;while(u>>r)w.eb(r);}(q);
#define digits(d,n,s)vector<int>d;[&d](int m){while(m)d.eb(m%s),m/=s;}(n);
typedef long long ll;
using namespace std;

struct MorselikeCode {
	string decrypt(vector <string> library, string message) {
		map<string, char> m;
		ei(a, library) {
			stst ss;
			char c;
			string s;
			ss >> c >> s;
			m[s] = c;
		}
		stst ss;
		ss << message;
		string s;
		string r;
		while (ss >> s) {
			cout << s << endl;
			r += m[s] == 0 ? '?' : m[s];
		}
		return r;
	}
};

// BEGIN KAWIGIEDIT TESTING
// Generated by KawigiEdit-pf 2.3.0
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cmath>
using namespace std;
bool KawigiEdit_RunTest(int testNum, vector <string> p0, string p1, bool hasAnswer, string p2) {
	cout << "Test " << testNum << ": [" << "{";
	for (int i = 0; int(p0.size()) > i; ++i) {
		if (i > 0) {
			cout << ",";
		}
		cout << "\"" << p0[i] << "\"";
	}
	cout << "}" << "," << "\"" << p1 << "\"";
	cout << "]" << endl;
	MorselikeCode *obj;
	string answer;
	obj = new MorselikeCode();
	clock_t startTime = clock();
	answer = obj->decrypt(p0, p1);
	clock_t endTime = clock();
	delete obj;
	bool res;
	res = true;
	cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
	if (hasAnswer) {
		cout << "Desired answer:" << endl;
		cout << "\t" << "\"" << p2 << "\"" << endl;
	}
	cout << "Your answer:" << endl;
	cout << "\t" << "\"" << answer << "\"" << endl;
	if (hasAnswer) {
		res = answer == p2;
	}
	if (!res) {
		cout << "DOESN'T MATCH!!!!" << endl;
	} else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
		cout << "FAIL the timeout" << endl;
		res = false;
	} else if (hasAnswer) {
		cout << "Match :-)" << endl;
	} else {
		cout << "OK, but is it right?" << endl;
	}
	cout << "" << endl;
	return res;
}
int main() {
	bool all_right;
	bool disabled;
	bool tests_disabled;
	all_right = true;
	tests_disabled = false;

	vector <string> p0;
	string p1;
	string p2;

	// ----- test 0 -----
	disabled = false;
	p0 = {"O ---","S ..."};
	p1 = "... --- ...";
	p2 = "SOS";
	all_right = (disabled || KawigiEdit_RunTest(0, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 1 -----
	disabled = false;
	p0 = {"O ---"};
	p1 = "... --- ...";
	p2 = "?O?";
	all_right = (disabled || KawigiEdit_RunTest(1, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 2 -----
	disabled = false;
	p0 = {"H -","E .","L --","L ..","O -."};
	p1 = "- . -- .. -.";
	p2 = "HELLO";
	all_right = (disabled || KawigiEdit_RunTest(2, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 3 -----
	disabled = false;
	p0 = {"H -.-.-.-.-.-.-.-.-.-.","I .-.-.-.-.-.-.-.-.-.-","K -.-.-.-.-.","E .-.-.-.-.-"};
	p1 = "-.-.-.-.-.-.-.-.-.-. .-.-.-.-.-.-.-.-.-.-";
	p2 = "HI";
	all_right = (disabled || KawigiEdit_RunTest(3, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 4 -----
	disabled = false;
	p0 = {"O ---","S ...","B -...","T -","R .-.","E .","N -.","X -..-","D -.."};
	p1 = "-... --- ... - --- -. .-. . -.. ... --- -..-";
	p2 = "BOSTONREDSOX";
	all_right = (disabled || KawigiEdit_RunTest(4, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 5 -----
	disabled = false;
	p0 = {"B -...","N -.","H ....","O --","Z --..","G ---","I ..","J .---"};
	p1 = "--- -- -... .- -. .- -. .-";
	p2 = "GOB?N?N?";
	all_right = (disabled || KawigiEdit_RunTest(5, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 6 -----
	disabled = false;
	p0 = {"A --","B -.","N ...-","I --..","F -.-.-."};
	p1 = "-. -- -.-.-. -.-.-. --- --.. ...- .-..--.";
	p2 = "BAFF?IN?";
	all_right = (disabled || KawigiEdit_RunTest(6, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	if (all_right) {
		if (tests_disabled) {
			cout << "You're a stud (but some test cases were disabled)!" << endl;
		} else {
			cout << "You're a stud (at least on given cases)!" << endl;
		}
	} else {
		cout << "Some of the test cases had errors." << endl;
	}
	return 0;
}
// END KAWIGIEDIT TESTING
<commit_msg>MorselikeCode<commit_after>#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iterator>
#include <tuple>
#include <regex>
#include <array>
#include <valarray>
#define all(v)begin(v),end(v)
#define dump(v)copy(all(v),ostream_iterator<decltype(*v.begin())>(cout,"\n"))
#define rg(i,a,b)for(int i=a,i##e=b;i<i##e;++i)
#define fr(i,n)for(int i=0,i##e=n;i<i##e;++i)
#define rf(i,n)for(int i=n-1;i>=0;--i)
#define ei(a,m)for(auto&a:m)if(int a##i=&a-&*begin(m)+1)if(--a##i,1)
#define sz(v)int(v.size())
#define sr(v)sort(all(v))
#define rs(v)sort(all(v),greater<int>())
#define rev(v)reverse(all(v))
#define eb emplace_back
#define stst stringstream
#define big numeric_limits<int>::max()
#define g(t,i)get<i>(t)
#define cb(v,w)copy(all(v),back_inserter(w))
#define uni(v)sort(all(v));v.erase(unique(all(v)),end(v))
#define vt(...)vector<tuple<__VA_ARGS__>>
#define smx(a,b)a=max(a,b)
#define smn(a,b)a=min(a,b)
#define words(w,q)vector<string>w;[&w](string&&s){stringstream u(s);string r;while(u>>r)w.eb(r);}(q);
#define digits(d,n,s)vector<int>d;[&d](int m){while(m)d.eb(m%s),m/=s;}(n);
typedef long long ll;
using namespace std;

struct MorselikeCode {
	string decrypt(vector <string> library, string message) {
		map<string, char> m;
		ei(a, library) {
			stst ss;
			char c;
			string s;
			ss >> c >> s;
			cout << s << endl;
			m[s] = c;
		}
		stst ss;
		ss << message;
		string s;
		string r;
		while (ss >> s) {
			r += m[s] == 0 ? '?' : m[s];
		}
		return r;
	}
};

// BEGIN KAWIGIEDIT TESTING
// Generated by KawigiEdit-pf 2.3.0
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cmath>
using namespace std;
bool KawigiEdit_RunTest(int testNum, vector <string> p0, string p1, bool hasAnswer, string p2) {
	cout << "Test " << testNum << ": [" << "{";
	for (int i = 0; int(p0.size()) > i; ++i) {
		if (i > 0) {
			cout << ",";
		}
		cout << "\"" << p0[i] << "\"";
	}
	cout << "}" << "," << "\"" << p1 << "\"";
	cout << "]" << endl;
	MorselikeCode *obj;
	string answer;
	obj = new MorselikeCode();
	clock_t startTime = clock();
	answer = obj->decrypt(p0, p1);
	clock_t endTime = clock();
	delete obj;
	bool res;
	res = true;
	cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
	if (hasAnswer) {
		cout << "Desired answer:" << endl;
		cout << "\t" << "\"" << p2 << "\"" << endl;
	}
	cout << "Your answer:" << endl;
	cout << "\t" << "\"" << answer << "\"" << endl;
	if (hasAnswer) {
		res = answer == p2;
	}
	if (!res) {
		cout << "DOESN'T MATCH!!!!" << endl;
	} else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
		cout << "FAIL the timeout" << endl;
		res = false;
	} else if (hasAnswer) {
		cout << "Match :-)" << endl;
	} else {
		cout << "OK, but is it right?" << endl;
	}
	cout << "" << endl;
	return res;
}
int main() {
	bool all_right;
	bool disabled;
	bool tests_disabled;
	all_right = true;
	tests_disabled = false;

	vector <string> p0;
	string p1;
	string p2;

	// ----- test 0 -----
	disabled = false;
	p0 = {"O ---","S ..."};
	p1 = "... --- ...";
	p2 = "SOS";
	all_right = (disabled || KawigiEdit_RunTest(0, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 1 -----
	disabled = false;
	p0 = {"O ---"};
	p1 = "... --- ...";
	p2 = "?O?";
	all_right = (disabled || KawigiEdit_RunTest(1, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 2 -----
	disabled = false;
	p0 = {"H -","E .","L --","L ..","O -."};
	p1 = "- . -- .. -.";
	p2 = "HELLO";
	all_right = (disabled || KawigiEdit_RunTest(2, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 3 -----
	disabled = false;
	p0 = {"H -.-.-.-.-.-.-.-.-.-.","I .-.-.-.-.-.-.-.-.-.-","K -.-.-.-.-.","E .-.-.-.-.-"};
	p1 = "-.-.-.-.-.-.-.-.-.-. .-.-.-.-.-.-.-.-.-.-";
	p2 = "HI";
	all_right = (disabled || KawigiEdit_RunTest(3, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 4 -----
	disabled = false;
	p0 = {"O ---","S ...","B -...","T -","R .-.","E .","N -.","X -..-","D -.."};
	p1 = "-... --- ... - --- -. .-. . -.. ... --- -..-";
	p2 = "BOSTONREDSOX";
	all_right = (disabled || KawigiEdit_RunTest(4, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 5 -----
	disabled = false;
	p0 = {"B -...","N -.","H ....","O --","Z --..","G ---","I ..","J .---"};
	p1 = "--- -- -... .- -. .- -. .-";
	p2 = "GOB?N?N?";
	all_right = (disabled || KawigiEdit_RunTest(5, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	// ----- test 6 -----
	disabled = false;
	p0 = {"A --","B -.","N ...-","I --..","F -.-.-."};
	p1 = "-. -- -.-.-. -.-.-. --- --.. ...- .-..--.";
	p2 = "BAFF?IN?";
	all_right = (disabled || KawigiEdit_RunTest(6, p0, p1, true, p2) ) && all_right;
	tests_disabled = tests_disabled || disabled;
	// ------------------

	if (all_right) {
		if (tests_disabled) {
			cout << "You're a stud (but some test cases were disabled)!" << endl;
		} else {
			cout << "You're a stud (at least on given cases)!" << endl;
		}
	} else {
		cout << "Some of the test cases had errors." << endl;
	}
	return 0;
}
// END KAWIGIEDIT TESTING
<|endoftext|>


<commit_before>#include "../dataStructure.h"
using namespace std;

//This is the data structure, where one can:
  //fetch entities by their type
  //insert entities
  //remove entities
  //get a list of elements with nearby x/y coordinates

//This data structure needs to know the level size in the game
//Width, height, hexRadius
Bin::Bin(const unsigned int width,
                 const unsigned int height,
                 const double hexRadius)
: width(width),
  height(height),
  hexRadius(hexRadius),

  //Initalize the x, then the y, of empty maps:
  hexes(ceil( (width+(hexRadius*0.5)) / (1.5*hexRadius)),
    vector<Hex*>( ceil((height+hexRadius) / (sqrt(3)*hexRadius)), nullptr )),
  hexCords(width, height, hexRadius)
  {
      //Populate hex grid:
      for (size_t col = 0; col < hexes.size(); col++)
        for (size_t row = 0; row < hexes[col].size(); row++)
            hexes[col][row] = new Hex(col, row, hexRadius);

      //Can only now initialize the hexCords with bins, since hexes now exist
      hexCords.populate(&hexes);
  }

//How else do we put things in this monstrosity?
void Bin::insert(Entity* const entity)
{
    if (entity->getX() >= width)
        entity->x = entity->x % width;

    if (entity->getY() >= height)
        entity->y = entity->y % height;

    //First Convert coordinates
    vector<unsigned int> cords = hexCords.hexOffsetCord(entity->getX(), entity->getY());

    Enticap* enticap = new Enticap(entity, hexes[cords[0]][cords[1]]);

    //byLocal (which in turn stores by type)
    //structure: [col][row][Hex*]
    hexes[cords[0]][cords[1]]->insert(entity, enticap);

    //byType
    //structure: <typeid.HashCode: <pointerToEntity:pointerToEnticap> >
    byTypeMap[typeid(*entity).hash_code()][entity] = enticap;

    //adjust the count
    ++entityCount;
}

//Delete an object
void Bin::remove(Entity* const entity)
{
    //First Convert Coordinates
    vector<unsigned int> cords = hexCords.hexOffsetCord(entity->getX(), entity->getY());

    //remove from byLocal
    hexes[cords[0]][cords[1]]->remove(entity);

    //remove from byType
    Enticap* enticapP = byTypeMap[typeid(*entity).hash_code()][entity];
    byTypeMap[typeid(*entity).hash_code()].erase(entity);
    delete enticapP; //Deletes the enticap and the entity

    //adjust the Count
    --entityCount;
}

//Add to removal list
void Bin::markForRemoval(Entity* const entity)
{
  removalList.push_back(entity);
}

//remove all entities marked for removal and clear removal list
void Bin::removeAll()
{
  for (Entity* const entity : removalList)
  {
    remove(entity);
  }
  removalList.clear();
}

//How to move an object in the dataStructure
void Bin::move(Entity* entity, unsigned int newX, unsigned int newY)
{
    //Adjust coordinates if needed
    if (newX >= width)
        newX = newX % width;

    if (newY >= height)
        newY = newY % height;

    //First Convert Coordinates
    vector<unsigned int> oldCords = hexCords.hexOffsetCord(entity->getX(), entity->getY());
    vector<unsigned int> newCords = hexCords.hexOffsetCord(newX, newY);

    //Switch Hexes
    hexes[oldCords[0]][oldCords[1]]->remove(entity);
    hexes[newCords[0]][newCords[1]]->insert(entity, byTypeMap[typeid(*entity).hash_code()][entity]);

    //Let the entity know it's been moved
    entity->x = newX;
    entity->y = newY;
}

//Update All Entities In The Structure
void Bin::updateEntities(unsigned int resolution)
{
  if (entityCount)
    for(Entity& entity : getAll())
        entity.update(resolution);
}

//Update All Hexes In The Structure
void Bin::updateHexes(unsigned int resolution)
{
  if (entityCount)
    for(Hex& hex : getAllHexes())
        hex.update(resolution);
}

Bin::~Bin()
{
    //Cycle through all Entities/Enticaps and delete them
    for(auto& outerPair : byTypeMap) //Every Different type
        for(auto& innerPair : outerPair.second) //Every single element
            delete innerPair.second; //Delete enticaps, since they delete the entity

    for(auto& col : hexes) //Every Different type
        for(Hex* hex : col) //Every single element
            delete hex;
    //All heap elements are deleted, now the deconstructor will remove pointers
}

//A few simple getters
unsigned int Bin::getWidth() const
{
    return width;
}
unsigned int Bin::getHeight() const
{
    return height;
}
unsigned long int Bin::count() const
{
    return entityCount;
}

#include "Enticap.cpp"

#include "pixToHex.cpp"

#include "HexInternals.cpp"
<commit_msg>Fix Empty byTypes<commit_after>#include "../dataStructure.h"
using namespace std;

//This is the data structure, where one can:
  //fetch entities by their type
  //insert entities
  //remove entities
  //get a list of elements with nearby x/y coordinates

//This data structure needs to know the level size in the game
//Width, height, hexRadius
Bin::Bin(const unsigned int width,
                 const unsigned int height,
                 const double hexRadius)
: width(width),
  height(height),
  hexRadius(hexRadius),

  //Initalize the x, then the y, of empty maps:
  hexes(ceil( (width+(hexRadius*0.5)) / (1.5*hexRadius)),
    vector<Hex*>( ceil((height+hexRadius) / (sqrt(3)*hexRadius)), nullptr )),
  hexCords(width, height, hexRadius)
  {
      //Populate hex grid:
      for (size_t col = 0; col < hexes.size(); col++)
        for (size_t row = 0; row < hexes[col].size(); row++)
            hexes[col][row] = new Hex(col, row, hexRadius);

      //Can only now initialize the hexCords with bins, since hexes now exist
      hexCords.populate(&hexes);
  }

//How else do we put things in this monstrosity?
void Bin::insert(Entity* const entity)
{
    if (entity->getX() >= width)
        entity->x = entity->x % width;

    if (entity->getY() >= height)
        entity->y = entity->y % height;

    //First Convert coordinates
    vector<unsigned int> cords = hexCords.hexOffsetCord(entity->getX(), entity->getY());

    Enticap* enticap = new Enticap(entity, hexes[cords[0]][cords[1]]);

    //byLocal (which in turn stores by type)
    //structure: [col][row][Hex*]
    hexes[cords[0]][cords[1]]->insert(entity, enticap);

    //byType
    //structure: <typeid.HashCode: <pointerToEntity:pointerToEnticap> >
    byTypeMap[typeid(*entity).hash_code()][entity] = enticap;

    //adjust the count
    ++entityCount;
}

//Delete an object
void Bin::remove(Entity* const entity)
{
    //First Convert Coordinates
    vector<unsigned int> cords = hexCords.hexOffsetCord(entity->getX(), entity->getY());

    //remove from byLocal
    hexes[cords[0]][cords[1]]->remove(entity);

    //remove from byType
    Enticap* enticapP = byTypeMap[typeid(*entity).hash_code()][entity];
    byTypeMap[typeid(*entity).hash_code()].erase(entity);
    delete enticapP; //Deletes the enticap and the entity

    //adjust the Count
    --entityCount;

    if (byTypeMap[typeid(*entity).hash_code()].size() == 0)
        byTypeMap.erase(typeid(*entity).hash_code());
}

//Add to removal list
void Bin::markForRemoval(Entity* const entity)
{
  removalList.push_back(entity);
}

//remove all entities marked for removal and clear removal list
void Bin::removeAll()
{
  for (Entity* const entity : removalList)
  {
    remove(entity);
  }
  removalList.clear();
}

//How to move an object in the dataStructure
void Bin::move(Entity* entity, unsigned int newX, unsigned int newY)
{
    //Adjust coordinates if needed
    if (newX >= width)
        newX = newX % width;

    if (newY >= height)
        newY = newY % height;

    //First Convert Coordinates
    vector<unsigned int> oldCords = hexCords.hexOffsetCord(entity->getX(), entity->getY());
    vector<unsigned int> newCords = hexCords.hexOffsetCord(newX, newY);

    //Switch Hexes
    hexes[oldCords[0]][oldCords[1]]->remove(entity);
    hexes[newCords[0]][newCords[1]]->insert(entity, byTypeMap[typeid(*entity).hash_code()][entity]);

    //Let the entity know it's been moved
    entity->x = newX;
    entity->y = newY;
}

//Update All Entities In The Structure
void Bin::updateEntities(unsigned int resolution)
{
  if (entityCount)
    for(Entity& entity : getAll())
        entity.update(resolution);
}

//Update All Hexes In The Structure
void Bin::updateHexes(unsigned int resolution)
{
  if (entityCount)
    for(Hex& hex : getAllHexes())
        hex.update(resolution);
}

Bin::~Bin()
{
    //Cycle through all Entities/Enticaps and delete them
    for(auto& outerPair : byTypeMap) //Every Different type
        for(auto& innerPair : outerPair.second) //Every single element
            delete innerPair.second; //Delete enticaps, since they delete the entity

    for(auto& col : hexes) //Every Different type
        for(Hex* hex : col) //Every single element
            delete hex;
    //All heap elements are deleted, now the deconstructor will remove pointers
}

//A few simple getters
unsigned int Bin::getWidth() const
{
    return width;
}
unsigned int Bin::getHeight() const
{
    return height;
}
unsigned long int Bin::count() const
{
    return entityCount;
}

#include "Enticap.cpp"

#include "pixToHex.cpp"

#include "HexInternals.cpp"
<|endoftext|>


<commit_before>/*
- Designer will publish:
http://docs.ros.org/indigo/api/trajectory_msgs/html/msg/JointTrajectory.html
- Designer will receive: (with root link as 0,0,0)
http://docs.ros.org/indigo/api/sensor_msgs/html/msg/JointState.html
*/
#include <cstdlib>
#include <string>
#include <ros/ros.h>
#include <lcm/lcm-cpp.hpp>

#include "lcmtypes/robotiqhand/command_t.hpp"
#include <trajectory_msgs/JointTrajectory.h>
#include <ipab_msgs/PlannerRequest.h>
#include <ipab_msgs/RobotiqCommand.h>
#include <std_srvs/Empty.h> // TODO: replace with Trigger once it's available

using namespace std;

class LCM2ROS{
  public:
    LCM2ROS(boost::shared_ptr<lcm::LCM> &lcm_, ros::NodeHandle &nh_);
    ~LCM2ROS() {}

  private:
    boost::shared_ptr<lcm::LCM> lcm_;
    ros::NodeHandle nh_;
    ros::NodeHandle* rosnode;

    ros::ServiceClient rosserviceclient_Emergency_Release_;

    void handCommandHandler(const lcm::ReceiveBuffer* rbuf, const std::string &channel, const robotiqhand::command_t* msg);
    ros::Publisher hand_command_pub_;
};

LCM2ROS::LCM2ROS(boost::shared_ptr<lcm::LCM> &lcm_, ros::NodeHandle &nh_): lcm_(lcm_),nh_(nh_) {
  lcm_->subscribe("ROBOTIQ_LEFT_COMMAND",&LCM2ROS::handCommandHandler, this);
  hand_command_pub_ = nh_.advertise<trajectory_msgs::JointTrajectory>("/sdh/command",10);

  rosserviceclient_Emergency_Release_ = nh_.serviceClient<std_srvs::Empty>("/gripper/sdh_controller/emergency_stop"); // TODO: change to trigger

  rosnode = new ros::NodeHandle();
}

void LCM2ROS::handCommandHandler(const lcm::ReceiveBuffer* rbuf, const std::string &channel, const robotiqhand::command_t* msg) {
  ROS_ERROR("LCM2ROS_SDH got hand command");

  // TODO: implement engaging on receiving this flag as true and have an auto-timeout to disengage

  // Check whether to perform an emergency release
  if (msg->emergency_release == 1) {
    std_srvs::Empty er_trigger; // TODO: temporary until std_srvs::Trigger is available
    if (rosserviceclient_Emergency_Release_.call(er_trigger)) {
      ROS_ERROR("Emergency release activated");
    } else {
      ROS_ERROR("Emergency release NOT activated");
    }
    return;
  }

  ipab_msgs::RobotiqCommand m;
  m.header.stamp= ros::Time().fromSec(msg->utime*1E-6);

  m.activate = (bool) msg->activate;
  m.emergency_release = (bool) msg->emergency_release;
  m.do_move = (bool) msg->do_move;

  m.mode = msg->mode;
  m.position = msg->position;
  m.force = msg->force;
  m.velocity = msg->velocity;

  m.ifc = (bool) msg->ifc;
  m.positionA = msg->positionA;
  m.positionB = msg->positionB;
  m.positionC = msg->positionC;

  m.isc = (bool) msg->isc;
  m.positionS = msg->positionS;

  hand_command_pub_.publish(m);

  // Check whether command is a movement
  if (msg->do_move == 1) {
    ROS_ERROR("Do move hand: %i", msg->do_move);

    // Command position, force, and velocity (TODO: only position implemented right now)
    // TODO

    // TODO: implement different modes
    /*switch(msg->mode) {
      // -1 - ignore (use previous mode)
      //  0 - basic (normal)
      //  1 - pinch
      //  2 - wide
      //  3 - scissor
    }*/

    // TODO: individual finger control and individual scissor control not yet implemented
    /*// Individual finger control
    // 1 - active
    // 0 - inactive
    int8_t ifc;
    int16_t positionA;
    int16_t positionB;
    int16_t positionC;

    // Indiviual scissor control
    // 1 - active
    // 0 - inactive
    int8_t isc;
    int16_t positionS;*/
  } else {
    ROS_WARN("Setting modes not supported - only basic mode supported!");
  }
}

int main(int argc,char** argv) {
  ros::init(argc,argv,"lcm2ros_sdh",ros::init_options::NoSigintHandler);
  boost::shared_ptr<lcm::LCM> lcm(new lcm::LCM);
  if(!lcm->good()){
    std::cerr <<"ERROR: lcm is not good()" <<std::endl;
  }
  ros::NodeHandle nh;

  LCM2ROS handlerObject(lcm, nh);
  cout << "\nlcm2ros_sdh translator ready\n";
  ROS_ERROR("LCM2ROS_SDH Translator Ready");

  while(0 == lcm->handle());
  return 0;
}
<commit_msg>LCM2ROS_SDH: Send ROBOTIQ_LEFT_COMMAND as /gripper/command in ROS<commit_after>/*
- Designer will publish:
http://docs.ros.org/indigo/api/trajectory_msgs/html/msg/JointTrajectory.html
- Designer will receive: (with root link as 0,0,0)
http://docs.ros.org/indigo/api/sensor_msgs/html/msg/JointState.html
*/
#include <cstdlib>
#include <string>
#include <ros/ros.h>
#include <lcm/lcm-cpp.hpp>

#include "lcmtypes/robotiqhand/command_t.hpp"
#include <trajectory_msgs/JointTrajectory.h>
#include <ipab_msgs/PlannerRequest.h>
#include <ipab_msgs/RobotiqCommand.h>
#include <std_srvs/Empty.h> // TODO: replace with Trigger once it's available

using namespace std;

class LCM2ROS{
  public:
    LCM2ROS(boost::shared_ptr<lcm::LCM> &lcm_, ros::NodeHandle &nh_);
    ~LCM2ROS() {}

  private:
    boost::shared_ptr<lcm::LCM> lcm_;
    ros::NodeHandle nh_;
    ros::NodeHandle* rosnode;

    ros::ServiceClient rosserviceclient_Emergency_Release_;

    void handCommandHandler(const lcm::ReceiveBuffer* rbuf, const std::string &channel, const robotiqhand::command_t* msg);
    ros::Publisher hand_command_pub_;
};

LCM2ROS::LCM2ROS(boost::shared_ptr<lcm::LCM> &lcm_, ros::NodeHandle &nh_): lcm_(lcm_),nh_(nh_) {
  lcm_->subscribe("ROBOTIQ_LEFT_COMMAND",&LCM2ROS::handCommandHandler, this);
  hand_command_pub_ = nh_.advertise<ipab_msgs::RobotiqCommand>("/gripper/ddapp_command",10);

  rosserviceclient_Emergency_Release_ = nh_.serviceClient<std_srvs::Empty>("/gripper/sdh_controller/emergency_stop"); // TODO: change to trigger

  rosnode = new ros::NodeHandle();
}

void LCM2ROS::handCommandHandler(const lcm::ReceiveBuffer* rbuf, const std::string &channel, const robotiqhand::command_t* msg) {
  ROS_ERROR("LCM2ROS_SDH got hand command");

  // TODO: implement engaging on receiving this flag as true and have an auto-timeout to disengage

  // Check whether to perform an emergency release
  if (msg->emergency_release == 1) {
    std_srvs::Empty er_trigger; // TODO: temporary until std_srvs::Trigger is available
    if (rosserviceclient_Emergency_Release_.call(er_trigger)) {
      ROS_ERROR("Emergency release activated");
    } else {
      ROS_ERROR("Emergency release NOT activated");
    }
    return;
  }

  ipab_msgs::RobotiqCommand m;
  m.header.stamp= ros::Time().fromSec(msg->utime*1E-6);

  m.activate = (bool) msg->activate;
  m.emergency_release = (bool) msg->emergency_release;
  m.do_move = (bool) msg->do_move;

  m.mode = msg->mode;
  m.position = msg->position;
  m.force = msg->force;
  m.velocity = msg->velocity;

  m.ifc = (bool) msg->ifc;
  m.positionA = msg->positionA;
  m.positionB = msg->positionB;
  m.positionC = msg->positionC;

  m.isc = (bool) msg->isc;
  m.positionS = msg->positionS;

  hand_command_pub_.publish(m);

  // TODO: Implement direct call of driver services
  /*if (msg->do_move == 1) {
    // Command position, force, and velocity (TODO: only position implemented right now)

    // TODO: implement different modes
    switch(msg->mode) {
      // -1 - ignore (use previous mode)
      //  0 - basic (normal)
      //  1 - pinch
      //  2 - wide
      //  3 - scissor
    }

    // TODO: individual finger control and individual scissor control not yet implemented
    // Individual finger control
    // 1 - active
    // 0 - inactive
    // int8_t ifc;
    // int16_t positionA;
    // int16_t positionB;
    // int16_t positionC;

    // Indiviual scissor control
    // 1 - active
    // 0 - inactive
    // int8_t isc;
    // int16_t positionS;
  } else {
    ROS_WARN("Setting modes not supported - only basic mode supported!");
  }*/
}

int main(int argc,char** argv) {
  ros::init(argc,argv,"lcm2ros_sdh",ros::init_options::NoSigintHandler);
  boost::shared_ptr<lcm::LCM> lcm(new lcm::LCM);
  if(!lcm->good()){
    std::cerr <<"ERROR: lcm is not good()" <<std::endl;
  }
  ros::NodeHandle nh;

  LCM2ROS handlerObject(lcm, nh);
  cout << "\nlcm2ros_sdh translator ready\n";
  ROS_ERROR("LCM2ROS_SDH Translator Ready");

  while(0 == lcm->handle());
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Vulkan
 *
 * Copyright (C) 2014 LunarG, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#include <assert.h>
#include <unordered_map>
#include "vk_dispatch_table_helper.h"
#include "vkLayer.h"
#include "layers_table.h"
static device_table_map tableMap;
static instance_table_map tableInstanceMap;

// Map lookup must be thread safe
VkLayerDispatchTable *device_dispatch_table(VkObject object)
{
//    VkLayerDispatchTable *pDisp  = *(VkLayerDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    device_table_map::const_iterator it = tableMap.find((void *) key);
    assert(it != tableMap.end() && "Not able to find device dispatch entry");
    return it->second;
}

VkLayerInstanceDispatchTable *instance_dispatch_table(VkObject object)
{
//    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
    if (it != tableInstanceMap.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
    assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
    return it->second;
}

void destroy_dispatch_table(device_table_map &map, dispatch_key key)
{
    device_table_map::const_iterator it = map.find((void *) key);
    if (it != map.end()) {
        fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
    } else {
        fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
        assert(it != map.end());
    }
    map.erase(key);
}

void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
{
    instance_table_map::const_iterator it = map.find((void *) key);
    if (it != map.end()) {
        fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
    } else {
        fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
        assert(it != map.end());
    }
    map.erase(key);
}

void destroy_device_dispatch_table(dispatch_key key)
{
    destroy_dispatch_table(tableMap, key);
}

void destroy_instance_dispatch_table(dispatch_key key)
{
    destroy_dispatch_table(tableInstanceMap, key);
}

VkLayerDispatchTable *get_dispatch_table(device_table_map &map, VkObject object)
{
//    VkLayerDispatchTable *pDisp  = *(VkLayerDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    device_table_map::const_iterator it = map.find((void *) key);
    if (it != map.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
    assert(it != map.end() && "Not able to find device dispatch entry");
    return it->second;
}

VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, VkObject object)
{
//    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    instance_table_map::const_iterator it = map.find((void *) key);
    if (it != map.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
    assert(it != map.end() && "Not able to find instance dispatch entry");
    return it->second;
}

/* Various dispatchable objects will use the same underlying dispatch table if they
 * are created from that "parent" object. Thus use pointer to dispatch table
 * as the key to these table maps.
 *    Instance -> PhysicalDevice
 *    Device -> CmdBuffer or Queue
 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
 * and a new key inserted into map */
VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
{
    VkLayerInstanceDispatchTable *pTable;
    assert(instancew);
    VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;

    std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
    if (it == tableInstanceMap.end())
    {
        pTable =  new VkLayerInstanceDispatchTable;
        map[(void *) *ppDisp] = pTable;
        fprintf(stderr, "New, Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, pTable);
        assert(map.size() <= 1 && "Instance dispatch table map has more than one entry");
    } else
    {
        fprintf(stderr, "Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, it->second);
        return it->second;
    }

    layer_init_instance_dispatch_table(pTable, instancew);

    return pTable;
}

VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
{
    return initInstanceTable(tableInstanceMap, instancew);
}

VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
{
    VkLayerDispatchTable *layer_device_table = NULL;
    assert(devw);
    VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
    VkLayerDispatchTable *base_device_table = *ppDisp;

    std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
    if (it == tableMap.end())
    {
        layer_device_table =  new VkLayerDispatchTable;
        map[(void *) base_device_table] = layer_device_table;
        fprintf(stderr, "New, Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, layer_device_table);
    } else
    {
        fprintf(stderr, "Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, it->second);
        return it->second;
    }

    layer_initialize_dispatch_table(layer_device_table, devw);

    return layer_device_table;
}

VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
{
    return initDeviceTable(tableMap, devw);
}
<commit_msg>layers: Ifdef out debug code<commit_after>/*
 * Vulkan
 *
 * Copyright (C) 2014 LunarG, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#include <assert.h>
#include <unordered_map>
#include "vk_dispatch_table_helper.h"
#include "vkLayer.h"
#include "layers_table.h"
static device_table_map tableMap;
static instance_table_map tableInstanceMap;

// Map lookup must be thread safe
VkLayerDispatchTable *device_dispatch_table(VkObject object)
{
//    VkLayerDispatchTable *pDisp  = *(VkLayerDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    device_table_map::const_iterator it = tableMap.find((void *) key);
    assert(it != tableMap.end() && "Not able to find device dispatch entry");
    return it->second;
}

VkLayerInstanceDispatchTable *instance_dispatch_table(VkObject object)
{
//    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != tableInstanceMap.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
    return it->second;
}

void destroy_dispatch_table(device_table_map &map, dispatch_key key)
{
    device_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
    } else {
        fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
        assert(it != map.end());
    }
#endif
    map.erase(key);
}

void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
{
    instance_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
    } else {
        fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
        assert(it != map.end());
    }
#endif
    map.erase(key);
}

void destroy_device_dispatch_table(dispatch_key key)
{
    destroy_dispatch_table(tableMap, key);
}

void destroy_instance_dispatch_table(dispatch_key key)
{
    destroy_dispatch_table(tableInstanceMap, key);
}

VkLayerDispatchTable *get_dispatch_table(device_table_map &map, VkObject object)
{
//    VkLayerDispatchTable *pDisp  = *(VkLayerDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    device_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != map.end() && "Not able to find device dispatch entry");
    return it->second;
}

VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, VkObject object)
{
//    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    instance_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != map.end() && "Not able to find instance dispatch entry");
    return it->second;
}

/* Various dispatchable objects will use the same underlying dispatch table if they
 * are created from that "parent" object. Thus use pointer to dispatch table
 * as the key to these table maps.
 *    Instance -> PhysicalDevice
 *    Device -> CmdBuffer or Queue
 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
 * and a new key inserted into map */
VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
{
    VkLayerInstanceDispatchTable *pTable;
    assert(instancew);
    VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;

    std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
    if (it == tableInstanceMap.end())
    {
        pTable =  new VkLayerInstanceDispatchTable;
        map[(void *) *ppDisp] = pTable;
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "New, Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, pTable);
#endif
        assert(map.size() <= 1 && "Instance dispatch table map has more than one entry");
    } else
    {
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, it->second);
#endif
        return it->second;
    }

    layer_init_instance_dispatch_table(pTable, instancew);

    return pTable;
}

VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
{
    return initInstanceTable(tableInstanceMap, instancew);
}

VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
{
    VkLayerDispatchTable *layer_device_table = NULL;
    assert(devw);
    VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
    VkLayerDispatchTable *base_device_table = *ppDisp;

    std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
    if (it == tableMap.end())
    {
        layer_device_table =  new VkLayerDispatchTable;
        map[(void *) base_device_table] = layer_device_table;
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "New, Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, layer_device_table);
#endif
    } else
    {
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, it->second);
#endif
        return it->second;
    }

    layer_initialize_dispatch_table(layer_device_table, devw);

    return layer_device_table;
}

VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
{
    return initDeviceTable(tableMap, devw);
}
<|endoftext|>


<commit_before>#include <audio/format/OGG.h>
#include <system/System.h>
#include <vorbis/vorbisfile.h>

namespace lime {

	typedef struct {

		unsigned char* data;
		ogg_int64_t size;
		ogg_int64_t pos;

	} OAL_OggMemoryFile;

	static size_t OAL_OggBufferRead (void* dest, size_t eltSize, size_t nelts, OAL_OggMemoryFile* src) {

		size_t len = eltSize * nelts;

		if ((src->pos + len) > src->size) {

			len = src->size - src->pos;

		}

		if (len > 0) {

			memcpy (dest, (src->data + src->pos), len);
			src->pos += len;

		}

		return len;

	}

	static int OAL_OggBufferSeek (OAL_OggMemoryFile* src, ogg_int64_t pos, int whence) {

		switch (whence) {

			case SEEK_CUR:

				src->pos += pos;
				break;

			case SEEK_END:

				src->pos = src->size - pos;
				break;

			case SEEK_SET:

				src->pos = pos;
				break;

			default:

				return -1;

		}

		if (src->pos < 0) {

			src->pos = 0;
			return -1;

		}

		if (src->pos > src->size) {

			return -1;

		}

		return 0;

	}

	static int OAL_OggBufferClose (OAL_OggMemoryFile* src) {

		return 0;

	}

	static long OAL_OggBufferTell (OAL_OggMemoryFile *src) {

		return src->pos;

	}

	static ov_callbacks OAL_CALLBACKS_BUFFER = {

		(size_t (*)(void *, size_t, size_t, void *)) OAL_OggBufferRead,
		(int (*)(void *, ogg_int64_t, int)) OAL_OggBufferSeek,
		(int (*)(void *)) OAL_OggBufferClose,
		(long (*)(void *)) OAL_OggBufferTell

	};

	bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) {

		OggVorbis_File oggFile;
		Bytes *data = NULL;
		OAL_OggMemoryFile fakeFile;

		if (resource->path) {

			FILE_HANDLE *file = lime::fopen (resource->path, "rb");

			if (!file) {

				return false;

			}

			if (file->isFile ()) {

				if (ov_open (file->getFile (), &oggFile, NULL, file->getLength ()) != 0) {

					lime::fclose (file);
					return false;

				}

			} else {

				lime::fclose (file);
				data = new Bytes (resource->path);

				fakeFile = { data->Data (), data->Length (), 0 };

				if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {

					delete data;
					return false;

				}

			}

		} else {

			fakeFile = { resource->data->Data (), resource->data->Length (), 0 };

			if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {

				return false;

			}

		}

		// 0 for Little-Endian, 1 for Big-Endian
		#ifdef HXCPP_BIG_ENDIAN
		#define BUFFER_READ_TYPE 1
		#else
		#define BUFFER_READ_TYPE 0
		#endif

		int bitStream;
		long bytes = 1;
		int totalBytes = 0;

		#define BUFFER_SIZE 4096

		vorbis_info *pInfo = ov_info (&oggFile, -1);

		if (pInfo == NULL) {

			//LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n");
			ov_clear (&oggFile);

			if (data) {

				delete data;

			}

			return false;

		}

		audioBuffer->channels = pInfo->channels;
		audioBuffer->sampleRate = pInfo->rate;

		audioBuffer->bitsPerSample = 16;

		int dataLength = ov_pcm_total (&oggFile, -1) * audioBuffer->channels * audioBuffer->bitsPerSample / 8;
		audioBuffer->data->Resize (dataLength);

		while (bytes > 0) {

			bytes = ov_read (&oggFile, (char *)audioBuffer->data->Data () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream);
			totalBytes += bytes;

		}

		if (dataLength != totalBytes) {

			audioBuffer->data->Resize (totalBytes);

		}

		ov_clear (&oggFile);

		#undef BUFFER_READ_TYPE

		if (data) {

			delete data;

		}

		return true;

	}

}<commit_msg>Compile fix<commit_after>#include <audio/format/OGG.h>
#include <system/System.h>
#include <vorbis/vorbisfile.h>

namespace lime {

	typedef struct {

		unsigned char* data;
		ogg_int64_t size;
		ogg_int64_t pos;

	} OAL_OggMemoryFile;

	static size_t OAL_OggBufferRead (void* dest, size_t eltSize, size_t nelts, OAL_OggMemoryFile* src) {

		size_t len = eltSize * nelts;

		if ((src->pos + len) > src->size) {

			len = src->size - src->pos;

		}

		if (len > 0) {

			memcpy (dest, (src->data + src->pos), len);
			src->pos += len;

		}

		return len;

	}

	static int OAL_OggBufferSeek (OAL_OggMemoryFile* src, ogg_int64_t pos, int whence) {

		switch (whence) {

			case SEEK_CUR:

				src->pos += pos;
				break;

			case SEEK_END:

				src->pos = src->size - pos;
				break;

			case SEEK_SET:

				src->pos = pos;
				break;

			default:

				return -1;

		}

		if (src->pos < 0) {

			src->pos = 0;
			return -1;

		}

		if (src->pos > src->size) {

			return -1;

		}

		return 0;

	}

	static int OAL_OggBufferClose (OAL_OggMemoryFile* src) {

		return 0;

	}

	static long OAL_OggBufferTell (OAL_OggMemoryFile *src) {

		return src->pos;

	}

	static ov_callbacks OAL_CALLBACKS_BUFFER = {

		(size_t (*)(void *, size_t, size_t, void *)) OAL_OggBufferRead,
		(int (*)(void *, ogg_int64_t, int)) OAL_OggBufferSeek,
		(int (*)(void *)) OAL_OggBufferClose,
		(long (*)(void *)) OAL_OggBufferTell

	};

	bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) {

		OggVorbis_File oggFile;
		Bytes *data = NULL;
		OAL_OggMemoryFile fakeFile;

		if (resource->path) {

			FILE_HANDLE *file = lime::fopen (resource->path, "rb");

			if (!file) {

				return false;

			}

			if (file->isFile ()) {

				if (ov_open (file->getFile (), &oggFile, NULL, file->getLength ()) != 0) {

					lime::fclose (file);
					return false;

				}

			} else {

				lime::fclose (file);
				data = new Bytes (resource->path);

				fakeFile = OAL_OggMemoryFile ();
				fakeFile.data = data->Data ();
				fakeFile.size = data->Length ();
				fakeFile.pos = 0;

				if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {

					delete data;
					return false;

				}

			}

		} else {

			fakeFile = OAL_OggMemoryFile ();
			fakeFile.data = resource->data->Data ();
			fakeFile.size = resource->data->Length ();
			fakeFile.pos = 0;

			if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {

				return false;

			}

		}

		// 0 for Little-Endian, 1 for Big-Endian
		#ifdef HXCPP_BIG_ENDIAN
		#define BUFFER_READ_TYPE 1
		#else
		#define BUFFER_READ_TYPE 0
		#endif

		int bitStream;
		long bytes = 1;
		int totalBytes = 0;

		#define BUFFER_SIZE 4096

		vorbis_info *pInfo = ov_info (&oggFile, -1);

		if (pInfo == NULL) {

			//LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n");
			ov_clear (&oggFile);

			if (data) {

				delete data;

			}

			return false;

		}

		audioBuffer->channels = pInfo->channels;
		audioBuffer->sampleRate = pInfo->rate;

		audioBuffer->bitsPerSample = 16;

		int dataLength = ov_pcm_total (&oggFile, -1) * audioBuffer->channels * audioBuffer->bitsPerSample / 8;
		audioBuffer->data->Resize (dataLength);

		while (bytes > 0) {

			bytes = ov_read (&oggFile, (char *)audioBuffer->data->Data () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream);
			totalBytes += bytes;

		}

		if (dataLength != totalBytes) {

			audioBuffer->data->Resize (totalBytes);

		}

		ov_clear (&oggFile);

		#undef BUFFER_READ_TYPE

		if (data) {

			delete data;

		}

		return true;

	}

}<|endoftext|>


<commit_before>#include "lightedimageitem.h"

#include <QSGGeometryNode>
#include <QQuickWindow>
#include <QSGSimpleMaterial>
#include <QSGTexture>
#include <array>

struct LightedImageMaterialState
{
    std::unique_ptr<QSGTexture> sourceImage;
    std::unique_ptr<QSGTexture> normalsImage;
    std::array<QVector3D, 10> lightVec;
};

class LightedImageMaterialShader : public QSGSimpleMaterialShader<LightedImageMaterialState>
{
    QSG_DECLARE_SIMPLE_SHADER(LightedImageMaterialShader, LightedImageMaterialState)
public:

    const char *vertexShader() const {
        return QT_STRINGIFY(
            attribute highp vec4 vertex;
            attribute highp vec2 tex;
            uniform highp mat4 qt_Matrix;
            varying highp vec2 qt_TexCoord0;

            void main() {
                qt_TexCoord0 = tex;
                gl_Position = qt_Matrix * vertex;
            }
        );
    }

    const char *fragmentShader() const {
        return QT_STRINGIFY(
            varying highp vec2 qt_TexCoord0;
            uniform highp float qt_Opacity;
            uniform sampler2D sourceImage;
            uniform sampler2D normalsImage;
            uniform highp vec3 lightVec[10];

            void main(void)
            {
                highp vec2 pixPos = qt_TexCoord0;
                highp vec4 pix = texture2D(sourceImage, pixPos.st);
                highp vec4 pix2 = texture2D(normalsImage, pixPos.st);
                highp vec3 normal = vec3(pix2.rg * 2.0 - 1.0, pix2.b);
                highp float diffuse = 0.66;

                for(int i = 0; i <= 10; ++i) {
                    highp float factor = step(0.01, lightVec[i].z);
                    highp vec3 relVec = lightVec[i];
                    relVec.xy -= pixPos;
                    diffuse = min(1.0, max(diffuse, factor * dot(normal, normalize(relVec))));
                }

                highp vec4 color = vec4(diffuse * pix.rgb, pix.a);
                gl_FragColor = color * qt_Opacity;
            }
        );
    }

    QList<QByteArray> attributes() const override {
        return QList<QByteArray>() << "vertex" << "tex";
    }

    void resolveUniforms() override {
        program()->bind();
        program()->setUniformValue("sourceImage", 0);
        program()->setUniformValue("normalsImage", 1);
    }

    void updateState(const LightedImageMaterialState *state, const LightedImageMaterialState *) override {
        glActiveTexture(GL_TEXTURE1);
        state->normalsImage->bind();
        glActiveTexture(GL_TEXTURE0);
        state->sourceImage->bind();
        program()->setUniformValueArray("lightVec", state->lightVec.data(), state->lightVec.size());
    }

};

LightedImageItem::LightedImageItem()
{
    setFlag(ItemHasContents);
}

QSGNode *LightedImageItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    auto node = static_cast<QSGGeometryNode *>(oldNode);
    if (!node) {
        node = new QSGGeometryNode;
        auto material = LightedImageMaterialShader::createMaterial();
        material->setFlag(QSGMaterial::Blending);
        // FIXME: Check for changed and move lower.
        material->state()->sourceImage.reset(window()->createTextureFromImage(QImage{ m_sourceImage }));
        material->state()->sourceImage->setHorizontalWrapMode(QSGTexture::Repeat);
        material->state()->sourceImage->setVerticalWrapMode(QSGTexture::Repeat);
        material->state()->normalsImage.reset(window()->createTextureFromImage(QImage{ m_normalsImage }));
        material->state()->normalsImage->setHorizontalWrapMode(QSGTexture::Repeat);
        material->state()->normalsImage->setVerticalWrapMode(QSGTexture::Repeat);
        node->setFlags(QSGNode::OwnsMaterial | QSGNode::OwnsGeometry);
        node->setMaterial(material);
        node->setGeometry(new QSGGeometry{ QSGGeometry::defaultAttributes_TexturedPoint2D(), 4 });
    }

    auto material = static_cast<QSGSimpleMaterial<LightedImageMaterialState>*>(node->material());
    unsigned i = 0;
    material->state()->lightVec = { };
    for (auto &item : m_lightSourceItems) {
        if (i >= material->state()->lightVec.size())
            break;
        if (item->property("lightWidth").toFloat() <= 0)
            continue;
        material->state()->lightVec[i] = QVector3D(mapFromItem(item, item->boundingRect().center()));
        material->state()->lightVec[i][0] *= m_hRepeat / width();
        material->state()->lightVec[i][1] *= m_vRepeat / height();
        material->state()->lightVec[i][2] = item->property("lightWidth").toFloat() * m_hRepeat / width();
        ++i;
    }

    QSGGeometry::updateTexturedRectGeometry(node->geometry(), boundingRect(), QRectF{ 0, 0, m_hRepeat, m_vRepeat });
    node->markDirty(QSGNode::DirtyGeometry);
    node->markDirty(QSGNode::DirtyMaterial);

    return node;
}
<commit_msg>Compile<commit_after>#include "lightedimageitem.h"

#include <QSGGeometryNode>
#include <QQuickWindow>
#include <QSGSimpleMaterial>
#include <QSGTexture>
#include <array>

#include <memory>

struct LightedImageMaterialState
{
    std::unique_ptr<QSGTexture> sourceImage;
    std::unique_ptr<QSGTexture> normalsImage;
    std::array<QVector3D, 10> lightVec;
};

class LightedImageMaterialShader : public QSGSimpleMaterialShader<LightedImageMaterialState>
{
    QSG_DECLARE_SIMPLE_SHADER(LightedImageMaterialShader, LightedImageMaterialState)
public:

    const char *vertexShader() const {
        return QT_STRINGIFY(
            attribute highp vec4 vertex;
            attribute highp vec2 tex;
            uniform highp mat4 qt_Matrix;
            varying highp vec2 qt_TexCoord0;

            void main() {
                qt_TexCoord0 = tex;
                gl_Position = qt_Matrix * vertex;
            }
        );
    }

    const char *fragmentShader() const {
        return QT_STRINGIFY(
            varying highp vec2 qt_TexCoord0;
            uniform highp float qt_Opacity;
            uniform sampler2D sourceImage;
            uniform sampler2D normalsImage;
            uniform highp vec3 lightVec[10];

            void main(void)
            {
                highp vec2 pixPos = qt_TexCoord0;
                highp vec4 pix = texture2D(sourceImage, pixPos.st);
                highp vec4 pix2 = texture2D(normalsImage, pixPos.st);
                highp vec3 normal = vec3(pix2.rg * 2.0 - 1.0, pix2.b);
                highp float diffuse = 0.66;

                for(int i = 0; i <= 10; ++i) {
                    highp float factor = step(0.01, lightVec[i].z);
                    highp vec3 relVec = lightVec[i];
                    relVec.xy -= pixPos;
                    diffuse = min(1.0, max(diffuse, factor * dot(normal, normalize(relVec))));
                }

                highp vec4 color = vec4(diffuse * pix.rgb, pix.a);
                gl_FragColor = color * qt_Opacity;
            }
        );
    }

    QList<QByteArray> attributes() const override {
        return QList<QByteArray>() << "vertex" << "tex";
    }

    void resolveUniforms() override {
        program()->bind();
        program()->setUniformValue("sourceImage", 0);
        program()->setUniformValue("normalsImage", 1);
    }

    void updateState(const LightedImageMaterialState *state, const LightedImageMaterialState *) override {
        glActiveTexture(GL_TEXTURE1);
        state->normalsImage->bind();
        glActiveTexture(GL_TEXTURE0);
        state->sourceImage->bind();
        program()->setUniformValueArray("lightVec", state->lightVec.data(), state->lightVec.size());
    }

};

LightedImageItem::LightedImageItem()
{
    setFlag(ItemHasContents);
}

QSGNode *LightedImageItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    auto node = static_cast<QSGGeometryNode *>(oldNode);
    if (!node) {
        node = new QSGGeometryNode;
        auto material = LightedImageMaterialShader::createMaterial();
        material->setFlag(QSGMaterial::Blending);
        // FIXME: Check for changed and move lower.
        material->state()->sourceImage.reset(window()->createTextureFromImage(QImage{ m_sourceImage }));
        material->state()->sourceImage->setHorizontalWrapMode(QSGTexture::Repeat);
        material->state()->sourceImage->setVerticalWrapMode(QSGTexture::Repeat);
        material->state()->normalsImage.reset(window()->createTextureFromImage(QImage{ m_normalsImage }));
        material->state()->normalsImage->setHorizontalWrapMode(QSGTexture::Repeat);
        material->state()->normalsImage->setVerticalWrapMode(QSGTexture::Repeat);
        node->setFlags(QSGNode::OwnsMaterial | QSGNode::OwnsGeometry);
        node->setMaterial(material);
        node->setGeometry(new QSGGeometry{ QSGGeometry::defaultAttributes_TexturedPoint2D(), 4 });
    }

    auto material = static_cast<QSGSimpleMaterial<LightedImageMaterialState>*>(node->material());
    unsigned i = 0;
    material->state()->lightVec = { };
    for (auto &item : m_lightSourceItems) {
        if (i >= material->state()->lightVec.size())
            break;
        if (item->property("lightWidth").toFloat() <= 0)
            continue;
        material->state()->lightVec[i] = QVector3D(mapFromItem(item, item->boundingRect().center()));
        material->state()->lightVec[i][0] *= m_hRepeat / width();
        material->state()->lightVec[i][1] *= m_vRepeat / height();
        material->state()->lightVec[i][2] = item->property("lightWidth").toFloat() * m_hRepeat / width();
        ++i;
    }

    QSGGeometry::updateTexturedRectGeometry(node->geometry(), boundingRect(), QRectF{ 0, 0, m_hRepeat, m_vRepeat });
    node->markDirty(QSGNode::DirtyGeometry);
    node->markDirty(QSGNode::DirtyMaterial);

    return node;
}
<|endoftext|>