<commit_before>#include <qcustomplot.h>
#include <iostream>
#include "settingswidget.h"
#include "ui_settingswidget.h"

SettingsWidget::SettingsWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::SettingsWidget) {
    ui->setupUi(this);

}

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

SettingsWidget::SettingsWidget(Fan *fan, QWidget *parent) :
        QWidget(parent),
        ui(new Ui::SettingsWidget) {
    ui->setupUi(this);

    setWindowTitle(fan->monitorPath);

    initFanCurveGraph();
    deadZone = fanCurve.deadZone() * 100;
    initSettingsGraph();

    connect(customPlot, &QCustomPlot::mousePress, this, &SettingsWidget::dragPointFlag);
    connect(customPlot, &QCustomPlot::mouseMove, this, &SettingsWidget::dragPoint);
    connect(customPlot, &QCustomPlot::mouseRelease, [this]() {
        dragFlag = false;
        if (current)
            current->setBrush(QBrush(defaultColor));
        customPlot->replot();
    });
    connect(ui->pushButton_addPoint, &QPushButton::clicked, this, &SettingsWidget::addPoint);
    connect(ui->cancel, &QPushButton::clicked, [this]() {
        close();
    });
    connect(ui->pushButton_auto, &QPushButton::clicked, this, &SettingsWidget::setGraphToAuto);

}

void SettingsWidget::addPoint() {
    double x, y;
    x = ((*pointsX)[1] + (*pointsX)[2]) / 2;
    y = ((*pointsY)[1] + (*pointsY)[2]) / 2;
    pointsX->insert(2, 1, x);
    pointsY->insert(2, 1, y);

    pointsMarks->insert(2, 1, new PlotPoint(customPlot));
    (*pointsMarks)[2]->moveCenter((*pointsX)[2], (*pointsY)[2]);
    (*pointsMarks)[2]->setBrush(QBrush(defaultColor));

    customPlot->graph(0)->setData(*pointsX, *pointsY);
    customPlot->replot();
}

void SettingsWidget::dragPointFlag(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        QMouseEvent *e = event;
        if (!dragFlag) {
            for (int i = 0; i < (*pointsMarks).size(); ++i) {
                if ((*pointsMarks)[i]->selectTest(event->localPos(), false) < 10) {
                    current = (*pointsMarks)[i];
                    current->setBrush(QBrush(dragColor));
                    customPlot->replot();
                    dragFlag = true;
                    (*currentState).setIndex(i);
                    //TODO Check point mark center position collision.
                }
            }
        }
    }
}

void SettingsWidget::dragPoint(QMouseEvent *event) {
    if (dragFlag) {
        double x, y, checkX, checkY, leftX = 0, rightX = 100;
        int i = (*currentState).index();
        checkX = customPlot->xAxis->pixelToCoord(event->localPos().x());
        checkY = customPlot->yAxis->pixelToCoord(event->localPos().y());

        if (i > 1) {
            leftX = (*pointsX)[i - 1];
        }
        if (i < (*pointsX).size() - 1) {
            rightX = (*pointsX)[i + 1];
        }
        if (i == 0 || i == 1) {
            leftX = 0;
            rightX = (*pointsX)[2];
        }

        if (checkX > leftX && checkX < rightX) {
            x = customPlot->xAxis->pixelToCoord(event->localPos().x());
        }

        if (i == (*pointsX).size() - 1) {
            y = 100;
        } else if (i == 0) {
            y = 0;
        } else if (i == 1 && deadZone > 1) {
            y = deadZone;
        } else if (checkY >= 0 && checkY <= 100) {
            y = customPlot->yAxis->pixelToCoord(event->localPos().y());
        }
        cPos = QPointF(x, y);
        (*pointsX).replace(i, cPos.x());
        (*pointsY).replace(i, cPos.y());
        current->moveCenter(cPos.x(), cPos.y());
        if (deadZone > 1) {
            if (i == 0) {
                (*pointsX).replace(1, cPos.x() + 0.001);
                (*pointsMarks)[1]->moveCenter(cPos.x() + 0.001, (*pointsY)[1]);

            }
            if (i == 1) {
                (*pointsX).replace(0, cPos.x() - 0.001);
                (*pointsMarks)[0]->moveCenter(cPos.x() - 0.001, (*pointsY)[0]);
            }
        }

        customPlot->graph(0)->setData(*pointsX, *pointsY);
        customPlot->replot();
    }
}

void SettingsWidget::setGraphToAuto() {

    delete pointsX;
    delete pointsY;
    for (int j = 0; j < (*pointsMarks).size(); ++j) {
        delete (*pointsMarks)[j];
    }
    delete pointsMarks;

    initSettingsCommonCode();
    customPlot->replot();
}

void SettingsWidget::initSettingsGraph() {
    customPlot = ui->controlCurveEdit;
    currentState = new PlotPoint(customPlot);
    initSettingsCommonCode();
}

void SettingsWidget::initFanCurveGraph() {
    QCustomPlot *customPlot = ui->fanCurveDisplay;

    std::fstream config("curve_outtake.conf", std::ios::in);
    fanCurve.load(config);
    config.close();

    rpmP = new QVector<double>(256);
    x = new QVector<double>(256);
    for (int i = 0; i < 256; ++i) {
        (*rpmP)[i] = fanCurve.rpmFromPwm(i);
        (*x)[i] = i;
    }

    customPlot->addGraph();
    customPlot->graph(0)->setData(*x, *rpmP);
    customPlot->xAxis->setLabel("PWM");
    customPlot->yAxis->setLabel("RPM");
    customPlot->rescaleAxes();

    customPlot->xAxis->setBasePen(QPen(Qt::white, 1));
    customPlot->yAxis->setBasePen(QPen(Qt::white, 1));
    customPlot->xAxis->setTickPen(QPen(Qt::white, 1));
    customPlot->yAxis->setTickPen(QPen(Qt::white, 1));
    customPlot->xAxis->setSubTickPen(QPen(Qt::white, 1));
    customPlot->yAxis->setSubTickPen(QPen(Qt::white, 1));
    customPlot->xAxis->setTickLabelColor(Qt::white);
    customPlot->yAxis->setTickLabelColor(Qt::white);
    customPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridVisible(true);
    customPlot->yAxis->grid()->setSubGridVisible(true);
    customPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
    customPlot->yAxis->grid()->setZeroLinePen(Qt::NoPen);
    customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    QLinearGradient plotGradient;
    plotGradient.setStart(0, 0);
    plotGradient.setFinalStop(0, 350);
    plotGradient.setColorAt(0, QColor(80, 80, 80));
    plotGradient.setColorAt(1, QColor(50, 50, 50));
    customPlot->setBackground(plotGradient);
    QLinearGradient axisRectGradient;
    axisRectGradient.setStart(0, 0);
    axisRectGradient.setFinalStop(0, 350);
    axisRectGradient.setColorAt(0, QColor(80, 80, 80));
    axisRectGradient.setColorAt(1, QColor(30, 30, 30));
    customPlot->axisRect()->setBackground(axisRectGradient);

}

void SettingsWidget::initSettingsCommonCode() {
    pointsX = new QVector<double>(4);
    pointsY = new QVector<double>(4);
    pointsMarks = new QVector<PlotPoint *>(4);

    (*pointsX)[0] = 20;
    (*pointsX)[1] = 20.001;
    (*pointsX)[2] = 60;
    (*pointsX)[3] = 100;

    (*pointsY)[0] = 0;
    (*pointsY)[1] = deadZone > 1 ? deadZone : 20;
    (*pointsY)[2] = 50;
    (*pointsY)[3] = 100;

    customPlot->addGraph();
    customPlot->graph(0)->setData(*pointsX, *pointsY);
    customPlot->graph(0)->setPen(QPen(QBrush(QColor(graphColor)), 3));

    for (int i = 0; i < (*pointsX).size(); ++i) {
        (*pointsMarks)[i] = new PlotPoint(customPlot);
        (*pointsMarks)[i]->moveCenter((*pointsX)[i], (*pointsY)[i]);
        (*pointsMarks)[i]->setBrush(QBrush(defaultColor));
    }

    customPlot->xAxis->setLabel("°C");
    customPlot->xAxis->setLabelColor(Qt::white);
    customPlot->xAxis->setRange(0, 100);
    customPlot->yAxis->setLabel("%");
    customPlot->yAxis->setLabelColor(Qt::white);
    customPlot->yAxis->setRange(0, 100);

    customPlot->xAxis->setBasePen(QPen(Qt::white, 1));
    customPlot->yAxis->setBasePen(QPen(Qt::white, 1));
    customPlot->xAxis->setTickPen(QPen(Qt::white, 1));
    customPlot->yAxis->setTickPen(QPen(Qt::white, 1));
    customPlot->xAxis->setSubTickPen(QPen(Qt::white, 1));
    customPlot->yAxis->setSubTickPen(QPen(Qt::white, 1));
    customPlot->xAxis->setTickLabelColor(Qt::white);
    customPlot->yAxis->setTickLabelColor(Qt::white);
    customPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridVisible(true);
    customPlot->yAxis->grid()->setSubGridVisible(true);
    customPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
    customPlot->yAxis->grid()->setZeroLinePen(Qt::NoPen);
    customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    QLinearGradient plotGradient;
    plotGradient.setStart(0, 0);
    plotGradient.setFinalStop(0, 350);
    plotGradient.setColorAt(0, QColor(80, 80, 80));
    plotGradient.setColorAt(1, QColor(50, 50, 50));
    customPlot->setBackground(plotGradient);
    QLinearGradient axisRectGradient;
    axisRectGradient.setStart(0, 0);
    axisRectGradient.setFinalStop(0, 350);
    axisRectGradient.setColorAt(0, QColor(80, 80, 80));
    axisRectGradient.setColorAt(1, QColor(30, 30, 30));
    customPlot->axisRect()->setBackground(axisRectGradient);
}

<commit_msg>button FanTest<commit_after>#include <qcustomplot.h>
#include <iostream>
#include "settingswidget.h"
#include "ui_settingswidget.h"

SettingsWidget::SettingsWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::SettingsWidget) {
    ui->setupUi(this);

}

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

SettingsWidget::SettingsWidget(Fan *fan, QWidget *parent) :
        QWidget(parent),
        ui(new Ui::SettingsWidget) {
    ui->setupUi(this);

    setWindowTitle(fan->monitorPath);

    initFanCurveGraph();
    deadZone = fanCurve.deadZone() * 100;
    initSettingsGraph();

    connect(customPlot, &QCustomPlot::mousePress, this, &SettingsWidget::dragPointFlag);
    connect(customPlot, &QCustomPlot::mouseMove, this, &SettingsWidget::dragPoint);
    connect(customPlot, &QCustomPlot::mouseRelease, [this]() {
        dragFlag = false;
        if (current)
            current->setBrush(QBrush(defaultColor));
        customPlot->replot();
    });
    connect(ui->pushButton_addPoint, &QPushButton::clicked, this, &SettingsWidget::addPoint);
    connect(ui->cancel, &QPushButton::clicked, [this]() {
        close();
    });
    connect(ui->pushButton_auto, &QPushButton::clicked, this, &SettingsWidget::setGraphToAuto);

}

void SettingsWidget::addPoint() {
    double x, y;
    x = ((*pointsX)[1] + (*pointsX)[2]) / 2;
    y = ((*pointsY)[1] + (*pointsY)[2]) / 2;
    pointsX->insert(2, 1, x);
    pointsY->insert(2, 1, y);

    pointsMarks->insert(2, 1, new PlotPoint(customPlot));
    (*pointsMarks)[2]->moveCenter((*pointsX)[2], (*pointsY)[2]);
    (*pointsMarks)[2]->setBrush(QBrush(defaultColor));

    customPlot->graph(0)->setData(*pointsX, *pointsY);
    customPlot->replot();
}

void SettingsWidget::dragPointFlag(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        QMouseEvent *e = event;
        if (!dragFlag) {
            for (int i = 0; i < (*pointsMarks).size(); ++i) {
                if ((*pointsMarks)[i]->selectTest(event->localPos(), false) < 10) {
                    current = (*pointsMarks)[i];
                    current->setBrush(QBrush(dragColor));
                    customPlot->replot();
                    dragFlag = true;
                    (*currentState).setIndex(i);
                    //TODO Check point mark center position collision.
                }
            }
        }
    }
}

void SettingsWidget::dragPoint(QMouseEvent *event) {
    if (dragFlag) {
        double x, y, checkX, checkY, leftX = 0, rightX = 100;
        int i = (*currentState).index();
        checkX = customPlot->xAxis->pixelToCoord(event->localPos().x());
        checkY = customPlot->yAxis->pixelToCoord(event->localPos().y());

        if (i > 1) {
            leftX = (*pointsX)[i - 1];
        }
        if (i < (*pointsX).size() - 1) {
            rightX = (*pointsX)[i + 1];
        }
        if (i == 0 || i == 1) {
            leftX = 0;
            rightX = (*pointsX)[2];
        }

        if (checkX > leftX && checkX < rightX) {
            x = customPlot->xAxis->pixelToCoord(event->localPos().x());
        }

        if (i == (*pointsX).size() - 1) {
            y = 100;
        } else if (i == 0) {
            y = 0;
        } else if (i == 1 && deadZone > 1) {
            y = deadZone;
        } else if (checkY >= 0 && checkY <= 100) {
            y = customPlot->yAxis->pixelToCoord(event->localPos().y());
        }
        cPos = QPointF(x, y);
        (*pointsX).replace(i, cPos.x());
        (*pointsY).replace(i, cPos.y());
        current->moveCenter(cPos.x(), cPos.y());
        if (deadZone > 1) {
            if (i == 0) {
                (*pointsX).replace(1, cPos.x() + 0.001);
                (*pointsMarks)[1]->moveCenter(cPos.x() + 0.001, (*pointsY)[1]);

            }
            if (i == 1) {
                (*pointsX).replace(0, cPos.x() - 0.001);
                (*pointsMarks)[0]->moveCenter(cPos.x() - 0.001, (*pointsY)[0]);
            }
        }

        customPlot->graph(0)->setData(*pointsX, *pointsY);
        customPlot->replot();
    }
}

void SettingsWidget::setGraphToAuto() {

    delete pointsX;
    delete pointsY;
    for (int j = 0; j < (*pointsMarks).size(); ++j) {
        delete (*pointsMarks)[j];
    }
    delete pointsMarks;

    initSettingsCommonCode();
    customPlot->replot();
}

void SettingsWidget::initSettingsGraph() {
    customPlot = ui->controlCurveEdit;
    currentState = new PlotPoint(customPlot);
    initSettingsCommonCode();
}

void SettingsWidget::initFanCurveGraph() {
    QCustomPlot *customPlot = ui->fanCurveDisplay;

    std::fstream config("curve_outtake.conf", std::ios::in);
    fanCurve.load(config);
    config.close();

    rpmP = new QVector<double>(256);
    x = new QVector<double>(256);
    for (int i = 0; i < 256; ++i) {
        (*rpmP)[i] = fanCurve.rpmFromPwm(i);
        (*x)[i] = i;
    }

    customPlot->addGraph();
    customPlot->graph(0)->setData(*x, *rpmP);
    customPlot->graph(0)->setPen(QPen(QBrush(QColor(graphColor)), 3));
    customPlot->xAxis->setLabel("PWM");
    customPlot->xAxis->setLabelColor(Qt::white);
    customPlot->yAxis->setLabel("RPM");
    customPlot->yAxis->setLabelColor(Qt::white);
    customPlot->rescaleAxes();

    customPlot->xAxis->setBasePen(QPen(Qt::white, 1));
    customPlot->yAxis->setBasePen(QPen(Qt::white, 1));
    customPlot->xAxis->setTickPen(QPen(Qt::white, 1));
    customPlot->yAxis->setTickPen(QPen(Qt::white, 1));
    customPlot->xAxis->setSubTickPen(QPen(Qt::white, 1));
    customPlot->yAxis->setSubTickPen(QPen(Qt::white, 1));
    customPlot->xAxis->setTickLabelColor(Qt::white);
    customPlot->yAxis->setTickLabelColor(Qt::white);
    customPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridVisible(true);
    customPlot->yAxis->grid()->setSubGridVisible(true);
    customPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
    customPlot->yAxis->grid()->setZeroLinePen(Qt::NoPen);
    customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    QLinearGradient plotGradient;
    plotGradient.setStart(0, 0);
    plotGradient.setFinalStop(0, 350);
    plotGradient.setColorAt(0, QColor(80, 80, 80));
    plotGradient.setColorAt(1, QColor(50, 50, 50));
    customPlot->setBackground(plotGradient);
    QLinearGradient axisRectGradient;
    axisRectGradient.setStart(0, 0);
    axisRectGradient.setFinalStop(0, 350);
    axisRectGradient.setColorAt(0, QColor(80, 80, 80));
    axisRectGradient.setColorAt(1, QColor(30, 30, 30));
    customPlot->axisRect()->setBackground(axisRectGradient);
}

void SettingsWidget::initSettingsCommonCode() {
    pointsX = new QVector<double>(4);
    pointsY = new QVector<double>(4);
    pointsMarks = new QVector<PlotPoint *>(4);

    (*pointsX)[0] = 20;
    (*pointsX)[1] = 20.001;
    (*pointsX)[2] = 60;
    (*pointsX)[3] = 100;

    (*pointsY)[0] = 0;
    (*pointsY)[1] = deadZone > 1 ? deadZone : 20;
    (*pointsY)[2] = 50;
    (*pointsY)[3] = 100;

    customPlot->addGraph();
    customPlot->graph(0)->setData(*pointsX, *pointsY);
    customPlot->graph(0)->setPen(QPen(QBrush(QColor(graphColor)), 3));

    for (int i = 0; i < (*pointsX).size(); ++i) {
        (*pointsMarks)[i] = new PlotPoint(customPlot);
        (*pointsMarks)[i]->moveCenter((*pointsX)[i], (*pointsY)[i]);
        (*pointsMarks)[i]->setBrush(QBrush(defaultColor));
    }

    customPlot->xAxis->setLabel("°C");
    customPlot->xAxis->setLabelColor(Qt::white);
    customPlot->xAxis->setRange(0, 100);
    customPlot->yAxis->setLabel("%");
    customPlot->yAxis->setLabelColor(Qt::white);
    customPlot->yAxis->setRange(0, 100);

    customPlot->xAxis->setBasePen(QPen(Qt::white, 1));
    customPlot->yAxis->setBasePen(QPen(Qt::white, 1));
    customPlot->xAxis->setTickPen(QPen(Qt::white, 1));
    customPlot->yAxis->setTickPen(QPen(Qt::white, 1));
    customPlot->xAxis->setSubTickPen(QPen(Qt::white, 1));
    customPlot->yAxis->setSubTickPen(QPen(Qt::white, 1));
    customPlot->xAxis->setTickLabelColor(Qt::white);
    customPlot->yAxis->setTickLabelColor(Qt::white);
    customPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    customPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    customPlot->xAxis->grid()->setSubGridVisible(true);
    customPlot->yAxis->grid()->setSubGridVisible(true);
    customPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
    customPlot->yAxis->grid()->setZeroLinePen(Qt::NoPen);
    customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    QLinearGradient plotGradient;
    plotGradient.setStart(0, 0);
    plotGradient.setFinalStop(0, 350);
    plotGradient.setColorAt(0, QColor(80, 80, 80));
    plotGradient.setColorAt(1, QColor(50, 50, 50));
    customPlot->setBackground(plotGradient);
    QLinearGradient axisRectGradient;
    axisRectGradient.setStart(0, 0);
    axisRectGradient.setFinalStop(0, 350);
    axisRectGradient.setColorAt(0, QColor(80, 80, 80));
    axisRectGradient.setColorAt(1, QColor(30, 30, 30));
    customPlot->axisRect()->setBackground(axisRectGradient);
}

<|endoftext|>


<commit_before>// (C) 2014 Arek Olek

#pragma once

#include <cstring>
#include <string>
#include <sstream>
#include <vector>

namespace opt_util {
  template <class Result>
  Result convert(const char* cstr) {
    throw "stub";
  }
  template <>
  int convert<int>(const char* cstr) {
    return atoi(cstr);
  }
  template <>
  float convert<float>(const char* cstr) {
    return atof(cstr);
  }
  template <>
  std::string convert<std::string>(const char* cstr) {
    return std::string(cstr);
  }
}

class options {
public:
  template <class Result = std::string>
  Result get(std::string name, Result def = Result()) {
    for(int i = 1; i < argc-1; ++i)
      if(strcmp(argv[i], name.c_str()) == 0)
        return opt_util::convert<Result>(argv[i+1]);
    return def;
  }
  template <class Result>
  std::vector<Result> getList(std::string name) {
    std::vector<Result> result;
    std::stringstream text(get(name));
    for(std::string token; std::getline(text, token, ',');)
      result.push_back(opt_util::convert<Result>(token.c_str()));
    return result;
  }
  options(int c, char** v) : argc(c), argv(v) { }
private:
  int argc;
  char** argv;
};
<commit_msg>default values for option list<commit_after>// (C) 2014 Arek Olek

#pragma once

#include <cstring>
#include <string>
#include <sstream>
#include <vector>

namespace opt_util {
  template <class Result>
  Result convert(const char* cstr) {
    throw "stub";
  }
  template <>
  int convert<int>(const char* cstr) {
    return atoi(cstr);
  }
  template <>
  float convert<float>(const char* cstr) {
    return atof(cstr);
  }
  template <>
  std::string convert<std::string>(const char* cstr) {
    return std::string(cstr);
  }
}

class options {
public:
  unsigned find(std::string const& name) const {
    for(int i = 1; i < argc-1; ++i)
      if(strcmp(argv[i], name.c_str()) == 0)
        return i + 1;
    return 0;
  }
  template <class Result = std::string>
  Result get(std::string name, Result def = Result()) {
    return find(name) ? opt_util::convert<Result>(argv[find(name)]) : def;
  }
  template <class Result>
  std::vector<Result> getList(std::string name, std::initializer_list<Result> def = {}) {
    std::vector<Result> result;
    std::stringstream text(get(name));
    for(std::string token; std::getline(text, token, ',');)
      result.push_back(opt_util::convert<Result>(token.c_str()));
    return find(name) ? result : def;
  }
  options(int c, char** v) : argc(c), argv(v) { }
private:
  int argc;
  char** argv;
};
<|endoftext|>


<commit_before>// Still just looking into possible choices for syntax but so far I like this one a lot. It's a bit more explicit then other solutions and
// offers more control then macros.

#include "Events.hpp"
#include "ScriptingManager.hpp"

namespace Testing {
	class TestingEventStuff {
	private:
		static Engine::Event testingEvent_method("testingEvent", "testingEvent_method", [] (Engine::ArgumentsRef args) {
			Engine::Logger::LogText("Testing", Engine::Logger::LogLevel_Log, "%s", args["Hello"]);
		});

		static Engine::ScriptMethod testingScript_method([] (Engine::ArgumentsRef args) {
			args.Assert(args[1]->IsString());
			testingEvent_method({
				{"Hello", "World"}
			});
		});
	};
}<commit_msg>Updated doc/newEventsAndScriptSyntax.cpp<commit_after>// Still just looking into possible choices for syntax but so far I like this one a lot. It's a bit more explicit then other solutions and
// offers more control then macros.

#include "Events.hpp"
#include "ScriptingManager.hpp"

namespace Testing {
	// It's not a requirement that the items exist inside a class but it makes origination and compartmentalization easier
	class TestingEventStuff {
	private:
		// The event is added to the events system as soon as the constructor is called
		static Engine::Event testingEvent_method("testingEvent", "testingEvent_method", [] (Engine::ArgumentsRef args) {
			Engine::Logger::Log("Testing", "%s", args["Hello"]); // A simplified syntax combined with printf style formatting
		});

		// The script method is not automatically added rather accepted as a script value which translates into a function using a
		// thin wrapper
		static Engine::ScriptMethod testingScript_method([] (Engine::ArgumentsRef args) {
			args.Assert(args[1]->IsString());
			// Event methods can be directly called as if they were methods thanks to the class identifying as a functor.
			testingEvent_method({
				{"Hello", "World"}
			});
		});
	};
}<|endoftext|>


<commit_before>#include "Mesh_OGL3.hpp"

Mesh::Mesh(void)
{
}

Mesh::~Mesh(void)
{
}

void Mesh::initBuffers()
{
	glGenVertexArrays(1, &vertexArrayObject);
	glGenBuffers(1, &vertexBuffer);
	glGenBuffers(1, &indexBuffer);

	glBindVertexArray(vertexArrayObject);

	glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*vertices.size(), (void*)&vertices[0], GL_STATIC_DRAW);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(glm::vec3)));
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(glm::vec3)*2));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*indices.size(), (void*)&indices[0], GL_STATIC_DRAW);

	glBindVertexArray(0);
}

void Mesh::draw()
{
	glBindVertexArray(vertexArrayObject);

	glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

	glBindVertexArray(0);
}

void Mesh::drawInstanced(GLsizei cnt)
{
	glBindVertexArray(vertexArrayObject);

	glDrawElementsInstanced(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0, cnt);

	glBindVertexArray(0);
}

void Mesh::addTransformAttribute(int attr, std::vector<glm::mat4>& _matrices)
{
	glBindVertexArray(vertexArrayObject);

	GLuint buffer;
	glGenBuffers(1, &buffer);
	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	glBufferData(GL_ARRAY_BUFFER, _matrices.size() * sizeof(glm::mat4), &_matrices[0], GL_STATIC_DRAW);

	GLsizei vec4Size = sizeof(glm::vec4);
	glEnableVertexAttribArray(attr);
	glVertexAttribPointer(attr, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)0);
	glEnableVertexAttribArray(attr+1);
	glVertexAttribPointer(attr+1, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(vec4Size));
	glEnableVertexAttribArray(attr+2);
	glVertexAttribPointer(attr+2, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(2 * vec4Size));
	glEnableVertexAttribArray(attr+3);
	glVertexAttribPointer(attr+3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(3 * vec4Size));

	glVertexAttribDivisor(attr+0, 1);
	glVertexAttribDivisor(attr+1, 1);
	glVertexAttribDivisor(attr+2, 1);
	glVertexAttribDivisor(attr+3, 1);

	glBindVertexArray(0);
}
<commit_msg>Adding missing Mesh destructor<commit_after>#include "Mesh_OGL3.hpp"

Mesh::Mesh(void)
{
}

Mesh::~Mesh(void)
{
	if (inited)
	{
		glDeleteVertexArrays(1, &vertexArrayObject);

		glDeleteBuffers(1, &vertexBuffer);
		glDeleteBuffers(1, &indexBuffer);
	}
}

void Mesh::initBuffers()
{
	glGenVertexArrays(1, &vertexArrayObject);
	glGenBuffers(1, &vertexBuffer);
	glGenBuffers(1, &indexBuffer);

	glBindVertexArray(vertexArrayObject);

	glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*vertices.size(), (void*)&vertices[0], GL_STATIC_DRAW);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(glm::vec3)));
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(glm::vec3)*2));

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*indices.size(), (void*)&indices[0], GL_STATIC_DRAW);

	glBindVertexArray(0);

	inited = true;
}

void Mesh::draw()
{
	glBindVertexArray(vertexArrayObject);

	glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);

	glBindVertexArray(0);
}

void Mesh::drawInstanced(GLsizei cnt)
{
	glBindVertexArray(vertexArrayObject);

	glDrawElementsInstanced(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0, cnt);

	glBindVertexArray(0);
}

void Mesh::addTransformAttribute(int attr, std::vector<glm::mat4>& _matrices)
{
	glBindVertexArray(vertexArrayObject);

	GLuint buffer;
	glGenBuffers(1, &buffer);
	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	glBufferData(GL_ARRAY_BUFFER, _matrices.size() * sizeof(glm::mat4), &_matrices[0], GL_STATIC_DRAW);

	GLsizei vec4Size = sizeof(glm::vec4);
	glEnableVertexAttribArray(attr);
	glVertexAttribPointer(attr, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)0);
	glEnableVertexAttribArray(attr+1);
	glVertexAttribPointer(attr+1, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(vec4Size));
	glEnableVertexAttribArray(attr+2);
	glVertexAttribPointer(attr+2, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(2 * vec4Size));
	glEnableVertexAttribArray(attr+3);
	glVertexAttribPointer(attr+3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(3 * vec4Size));

	glVertexAttribDivisor(attr+0, 1);
	glVertexAttribDivisor(attr+1, 1);
	glVertexAttribDivisor(attr+2, 1);
	glVertexAttribDivisor(attr+3, 1);

	glBindVertexArray(0);
}
<|endoftext|>


<commit_before><commit_msg>Improvements in Emscripten resize<commit_after><|endoftext|>


<commit_before>#include <MicroNMEA.h>

// Allow debugging/regression testing under normal g++ environment.
#ifdef MICRONMEA_DEBUG
#include <stdlib.h>
#include <iostream>
using namespace std;
#endif

static long exp10(uint8_t b)
{
	long r = 1;
	while (b--)
		r *= 10;
	return r;
}

static char toHex(uint8_t nibble)
{
	if (nibble >= 10)
		return nibble + 'A' - 10;
	else
		return nibble + '0';

}

const char* MicroNMEA::skipField(const char* s)
{
	if (s == nullptr)
		return nullptr;

	while (!isEndOfFields(*s)) {
		if (*s == ',') {
			// Check next character
			if (isEndOfFields(*++s))
				break;
			else
				return s;
		}
		++s;
	}
	return nullptr; // End of string or valid sentence
}

unsigned int MicroNMEA::parseUnsignedInt(const char *s, uint8_t len)
{
	int r = 0;
	while (len--)
		r = 10 * r + *s++ - '0';
	return r;
}

long MicroNMEA::parseFloat(const char* s, uint8_t log10Multiplier, const char** eptr)
{
	int8_t neg = 1;
	long r = 0;
	while (isspace(*s))
		++s;
	if (*s == '-') {
		neg = -1;
		++s;
	}
	else if (*s == '+')
		++s;

	while (isdigit(*s))
		r = 10*r + *s++ - '0';
	r *= exp10(log10Multiplier);

	if (*s == '.') {
		++s;
		long frac = 0;
		while (isdigit(*s) && log10Multiplier) {
			frac = 10 * frac + *s++ -'0';
			--log10Multiplier;
		}
		frac *= exp10(log10Multiplier);
		r += frac;
	}
	r *= neg; // Include effect of any minus sign

	if (eptr)
		*eptr = skipField(s);

	return r;
}

long MicroNMEA::parseDegreeMinute(const char* s, uint8_t degWidth,
								  const char **eptr)
{
	if (*s == ',') {
		if (eptr)
			*eptr = skipField(s);
		return 0;
	}
	long r = parseUnsignedInt(s, degWidth) * 1000000L;
	s += degWidth;
	r += parseFloat(s, 6, eptr) / 60;
	return r;
}

const char* MicroNMEA::parseField(const char* s, char *result, int len)
{
	if (s == nullptr)
		return nullptr;

	int i = 0;
	while (*s != ',' && !isEndOfFields(*s)) {
		if (result && i++ < len)
			*result++ = *s;
		++s;
	}
	if (result && i < len)
		*result = '\0'; // Terminate unless too long

	if (*s == ',')
		return ++s; // Location of start of next field
	else
		return nullptr; // End of string or valid sentence
}

const char* MicroNMEA::generateChecksum(const char* s, char* checksum)
{
	uint8_t c = 0;
	// Initial $ is omitted from checksum, if present ignore it.
	if (*s == '$')
		++s;

	while (*s != '\0' && *s != '*')
		c ^= *s++;

	if (checksum) {
		checksum[0] = toHex(c / 16);
		checksum[1] = toHex(c % 16);
	}
	return s;
}

bool MicroNMEA::testChecksum(const char* s)
{
	char checksum[2];
	const char* p = generateChecksum(s, checksum);
	return *p == '*' && p[1] == checksum[0] && p[2] == checksum[1];
}

#ifndef MICRONMEA_DEBUG
// When debugging in normal g++ environment ostream doesn't have a
// print member function. As sendSentence() isn't needed when
// debugging don't compile it.
Stream& MicroNMEA::sendSentence(Stream& s, const char* sentence)
{
	char checksum[3];
	generateChecksum(sentence, checksum);
	checksum[2] = '\0';
	s.print(sentence);
	s.print('*');
	s.print(checksum);
	s.print("\r\n");
	return s;
}
#endif

MicroNMEA::MicroNMEA(void) :
	_talkerID('\0'),
	_messageID{0},
	_badChecksumHandler(nullptr),
	_unknownSentenceHandler(nullptr)
{
	setBuffer(nullptr, 0);
	clear();
}

MicroNMEA::MicroNMEA(void* buf, uint8_t len) :
	_talkerID('\0'),
	_messageID{0},
	_badChecksumHandler(nullptr),
	_unknownSentenceHandler(nullptr)
{
	setBuffer(buf, len);
	clear();
}

void MicroNMEA::setBuffer(void* buf, uint8_t len)
{
	_bufferLen = len;
	_buffer = (char*)buf;
	_ptr = _buffer;
	if (_bufferLen) {
		*_ptr = '\0';
		_buffer[_bufferLen - 1] = '\0';
	}
}

void MicroNMEA::clear(void)
{
	_navSystem = '\0';
	_numSat = 0;
	_hdop = 255;
	_isValid = false;
	_latitude = 999000000L;
	_longitude = 999000000L;
	_altitude = _speed = _course = LONG_MIN;
	_altitudeValid = false;
	_year = _month = _day = 0;
	_hour = _minute = _second = 99;
	_hundredths = 0;
}

bool MicroNMEA::process(char c)
{
	if (_buffer == nullptr || _bufferLen == 0)
		return false;
	if (c == '\0' || c == '\n' || c == '\r') {
		// Terminate buffer then reset pointer
		*_ptr = '\0';
		_ptr = _buffer;

		if (*_buffer == '$' && testChecksum(_buffer)) {
			// Valid message
			const char* data;
			if (_buffer[1] == 'G') {
				_talkerID = _buffer[2];
				data = parseField(&_buffer[3], &_messageID[0], sizeof(_messageID));
			}
			else {
				_talkerID = '\0';
				data = parseField(&_buffer[1], &_messageID[0], sizeof(_messageID));
			}

			if (strcmp(&_messageID[0], "GGA") == 0)
				return processGGA(data);
			else if (strcmp(&_messageID[0], "RMC") == 0)
				return processRMC(data);
			else if (_unknownSentenceHandler)
				(*_unknownSentenceHandler)(*this);
		}
		else {
			if (_badChecksumHandler && *_buffer != '\0') // don't send empty buffers as bad checksums!
				(*_badChecksumHandler)(*this);
		}
		// Return true for a complete, non-empty, sentence (even if not a valid one).
		return *_buffer != '\0'; //
	}
	else {
		*_ptr = c;
		if (_ptr < &_buffer[_bufferLen - 1])
			++_ptr;
	}

	return false;
}

const char* MicroNMEA::parseTime(const char* s)
{
	if (*s == ',')
		return skipField(s);
	_hour = parseUnsignedInt(s, 2);
	_minute = parseUnsignedInt(s + 2, 2);
	_second = parseUnsignedInt(s + 4, 2);
	_hundredths = parseUnsignedInt(s + 7, 2);
	return skipField(s + 9);
}

const char* MicroNMEA::parseDate(const char* s)
{
	if (*s == ',')
		return skipField(s);
	_day = parseUnsignedInt(s, 2);
	_month = parseUnsignedInt(s + 2, 2);
	_year = parseUnsignedInt(s + 4, 2) + 2000;
	return skipField(s + 6);
}

bool MicroNMEA::processGGA(const char *s)
{
	// If GxGSV messages are received _talker_ID can be changed after
	// other MicroNMEA sentences. Compatibility modes can set the talker ID
	// to indicate GPS regardless of actual navigation system used.
	_navSystem = _talkerID;

	s = parseTime(s);
	// ++s;
	_latitude = parseDegreeMinute(s, 2, &s);
	if (*s == ',')
		++s;
	else {
		if (*s == 'S')
			_latitude *= -1;
		s += 2; // Skip N/S and comma
	}
	_longitude = parseDegreeMinute(s, 3, &s);
	if (*s == ',')
		++s;
	else {
		if (*s == 'W')
			_longitude *= -1;
		s += 2; // Skip E/W and comma
	}
	_isValid = (*s >= '1' && *s <= '5');
	s += 2; // Skip position fix flag and comma
	_numSat = parseFloat(s, 0, &s);
	_hdop = parseFloat(s, 1, &s);
	_altitude = parseFloat(s, 3, &s);
	_altitudeValid = true;
	// That's all we care about
	return true;
}

bool MicroNMEA::processRMC(const char* s)
{
	// If GxGSV messages are received _talker_ID can be changed after
	// other MicroNMEA sentences. Compatibility modes can set the talker
	// ID to indicate GPS regardless of actual navigation system used.
	_navSystem = _talkerID;

	s = parseTime(s);
	_isValid = (*s == 'A');
	s += 2; // Skip validity and comma
	_latitude = parseDegreeMinute(s, 2, &s);
	if (*s == ',')
		++s;
	else {
		if (*s == 'S')
			_latitude *= -1;
		s += 2; // Skip N/S and comma
	}
	_longitude = parseDegreeMinute(s, 3, &s);
	if (*s == ',')
		++s;
	else {
		if (*s == 'W')
			_longitude *= -1;
		s += 2; // Skip E/W and comma
	}
	_speed = parseFloat(s, 3, &s);
	_course = parseFloat(s, 3, &s);
	s = parseDate(s);
	// That's all we care about
	return true;
}
<commit_msg>Give up parsing when bad input has been detected<commit_after>#include <MicroNMEA.h>

// Allow debugging/regression testing under normal g++ environment.
#ifdef MICRONMEA_DEBUG
#include <stdlib.h>
#include <iostream>
using namespace std;
#endif

static long exp10(uint8_t b)
{
	long r = 1;
	while (b--)
		r *= 10;
	return r;
}

static char toHex(uint8_t nibble)
{
	if (nibble >= 10)
		return nibble + 'A' - 10;
	else
		return nibble + '0';

}

const char* MicroNMEA::skipField(const char* s)
{
	if (s == nullptr)
		return nullptr;

	while (!isEndOfFields(*s)) {
		if (*s == ',') {
			// Check next character
			if (isEndOfFields(*++s))
				break;
			else
				return s;
		}
		++s;
	}
	return nullptr; // End of string or valid sentence
}

unsigned int MicroNMEA::parseUnsignedInt(const char *s, uint8_t len)
{
	int r = 0;
	while (len--)
		r = 10 * r + *s++ - '0';
	return r;
}

long MicroNMEA::parseFloat(const char* s, uint8_t log10Multiplier, const char** eptr)
{
	int8_t neg = 1;
	long r = 0;
	while (isspace(*s))
		++s;
	if (*s == '-') {
		neg = -1;
		++s;
	}
	else if (*s == '+')
		++s;

	while (isdigit(*s))
		r = 10*r + *s++ - '0';
	r *= exp10(log10Multiplier);

	if (*s == '.') {
		++s;
		long frac = 0;
		while (isdigit(*s) && log10Multiplier) {
			frac = 10 * frac + *s++ -'0';
			--log10Multiplier;
		}
		frac *= exp10(log10Multiplier);
		r += frac;
	}
	r *= neg; // Include effect of any minus sign

	if (eptr)
		*eptr = skipField(s);

	return r;
}

long MicroNMEA::parseDegreeMinute(const char* s, uint8_t degWidth,
								  const char **eptr)
{
	if (*s == ',') {
		if (eptr)
			*eptr = skipField(s);
		return 0;
	}
	long r = parseUnsignedInt(s, degWidth) * 1000000L;
	s += degWidth;
	r += parseFloat(s, 6, eptr) / 60;
	return r;
}

const char* MicroNMEA::parseField(const char* s, char *result, int len)
{
	if (s == nullptr)
		return nullptr;

	int i = 0;
	while (*s != ',' && !isEndOfFields(*s)) {
		if (result && i++ < len)
			*result++ = *s;
		++s;
	}
	if (result && i < len)
		*result = '\0'; // Terminate unless too long

	if (*s == ',')
		return ++s; // Location of start of next field
	else
		return nullptr; // End of string or valid sentence
}

const char* MicroNMEA::generateChecksum(const char* s, char* checksum)
{
	uint8_t c = 0;
	// Initial $ is omitted from checksum, if present ignore it.
	if (*s == '$')
		++s;

	while (*s != '\0' && *s != '*')
		c ^= *s++;

	if (checksum) {
		checksum[0] = toHex(c / 16);
		checksum[1] = toHex(c % 16);
	}
	return s;
}

bool MicroNMEA::testChecksum(const char* s)
{
	char checksum[2];
	const char* p = generateChecksum(s, checksum);
	return *p == '*' && p[1] == checksum[0] && p[2] == checksum[1];
}

#ifndef MICRONMEA_DEBUG
// When debugging in normal g++ environment ostream doesn't have a
// print member function. As sendSentence() isn't needed when
// debugging don't compile it.
Stream& MicroNMEA::sendSentence(Stream& s, const char* sentence)
{
	char checksum[3];
	generateChecksum(sentence, checksum);
	checksum[2] = '\0';
	s.print(sentence);
	s.print('*');
	s.print(checksum);
	s.print("\r\n");
	return s;
}
#endif

MicroNMEA::MicroNMEA(void) :
	_talkerID('\0'),
	_messageID{0},
	_badChecksumHandler(nullptr),
	_unknownSentenceHandler(nullptr)
{
	setBuffer(nullptr, 0);
	clear();
}

MicroNMEA::MicroNMEA(void* buf, uint8_t len) :
	_talkerID('\0'),
	_messageID{0},
	_badChecksumHandler(nullptr),
	_unknownSentenceHandler(nullptr)
{
	setBuffer(buf, len);
	clear();
}

void MicroNMEA::setBuffer(void* buf, uint8_t len)
{
	_bufferLen = len;
	_buffer = (char*)buf;
	_ptr = _buffer;
	if (_bufferLen) {
		*_ptr = '\0';
		_buffer[_bufferLen - 1] = '\0';
	}
}

void MicroNMEA::clear(void)
{
	_navSystem = '\0';
	_numSat = 0;
	_hdop = 255;
	_isValid = false;
	_latitude = 999000000L;
	_longitude = 999000000L;
	_altitude = _speed = _course = LONG_MIN;
	_altitudeValid = false;
	_year = _month = _day = 0;
	_hour = _minute = _second = 99;
	_hundredths = 0;
}

bool MicroNMEA::process(char c)
{
	if (_buffer == nullptr || _bufferLen == 0)
		return false;
	if (c == '\0' || c == '\n' || c == '\r') {
		// Terminate buffer then reset pointer
		*_ptr = '\0';
		_ptr = _buffer;

		if (*_buffer == '$' && testChecksum(_buffer)) {
			// Valid message
			const char* data;
			if (_buffer[1] == 'G') {
				_talkerID = _buffer[2];
				data = parseField(&_buffer[3], &_messageID[0], sizeof(_messageID));
			}
			else {
				_talkerID = '\0';
				data = parseField(&_buffer[1], &_messageID[0], sizeof(_messageID));
			}

			if (strcmp(&_messageID[0], "GGA") == 0)
				return processGGA(data);
			else if (strcmp(&_messageID[0], "RMC") == 0)
				return processRMC(data);
			else if (_unknownSentenceHandler)
				(*_unknownSentenceHandler)(*this);
		}
		else {
			if (_badChecksumHandler && *_buffer != '\0') // don't send empty buffers as bad checksums!
				(*_badChecksumHandler)(*this);
		}
		// Return true for a complete, non-empty, sentence (even if not a valid one).
		return *_buffer != '\0'; //
	}
	else {
		*_ptr = c;
		if (_ptr < &_buffer[_bufferLen - 1])
			++_ptr;
	}

	return false;
}

const char* MicroNMEA::parseTime(const char* s)
{
	if (*s == ',')
		return skipField(s);
	_hour = parseUnsignedInt(s, 2);
	_minute = parseUnsignedInt(s + 2, 2);
	_second = parseUnsignedInt(s + 4, 2);
	_hundredths = parseUnsignedInt(s + 7, 2);
	return skipField(s + 9);
}

const char* MicroNMEA::parseDate(const char* s)
{
	if (*s == ',')
		return skipField(s);
	_day = parseUnsignedInt(s, 2);
	_month = parseUnsignedInt(s + 2, 2);
	_year = parseUnsignedInt(s + 4, 2) + 2000;
	return skipField(s + 6);
}

bool MicroNMEA::processGGA(const char *s)
{
	// If GxGSV messages are received _talker_ID can be changed after
	// other MicroNMEA sentences. Compatibility modes can set the talker ID
	// to indicate GPS regardless of actual navigation system used.
	_navSystem = _talkerID;

	s = parseTime(s);
	if (s == nullptr)
		return false;
	// ++s;
	_latitude = parseDegreeMinute(s, 2, &s);
	if (s == nullptr)
		return false;
	if (*s == ',')
		++s;
	else {
		if (*s == 'S')
			_latitude *= -1;
		s += 2; // Skip N/S and comma
	}
	_longitude = parseDegreeMinute(s, 3, &s);
	if (s == nullptr)
		return false;
	if (*s == ',')
		++s;
	else {
		if (*s == 'W')
			_longitude *= -1;
		s += 2; // Skip E/W and comma
	}
	_isValid = (*s >= '1' && *s <= '5');
	s += 2; // Skip position fix flag and comma
	_numSat = parseFloat(s, 0, &s);
	if (s == nullptr)
		return false;
	_hdop = parseFloat(s, 1, &s);
	if (s == nullptr)
		return false;
	_altitude = parseFloat(s, 3, &s);
	if (s == nullptr)
		return false;
	_altitudeValid = true;
	// That's all we care about
	return true;
}

bool MicroNMEA::processRMC(const char* s)
{
	// If GxGSV messages are received _talker_ID can be changed after
	// other MicroNMEA sentences. Compatibility modes can set the talker
	// ID to indicate GPS regardless of actual navigation system used.
	_navSystem = _talkerID;

	s = parseTime(s);
	if (s == nullptr)
		return false;
	_isValid = (*s == 'A');
	s += 2; // Skip validity and comma
	_latitude = parseDegreeMinute(s, 2, &s);
	if (s == nullptr)
		return false;
	if (*s == ',')
		++s;
	else {
		if (*s == 'S')
			_latitude *= -1;
		s += 2; // Skip N/S and comma
	}
	_longitude = parseDegreeMinute(s, 3, &s);
	if (s == nullptr)
		return false;
	if (*s == ',')
		++s;
	else {
		if (*s == 'W')
			_longitude *= -1;
		s += 2; // Skip E/W and comma
	}
	_speed = parseFloat(s, 3, &s);
	if (s == nullptr)
		return false;
	_course = parseFloat(s, 3, &s);
	if (s == nullptr)
		return false;
	s = parseDate(s);
	// That's all we care about
	return true;
}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file MixClient.cpp
 * @author Arkadiy Paronyan arkadiy@ethdev.com
 * @date 2015
 * Ethereum IDE client.
 */

#include "MixClient.h"
#include <vector>
#include <utility>
#include <libdevcore/Exceptions.h>
#include <libethcore/ChainOperationParams.h>
#include <libethcore/BasicAuthority.h>
#include <libethereum/BlockChain.h>
#include <libethereum/Transaction.h>
#include <libethereum/Executive.h>
#include <libethereum/ExtVM.h>
#include <libethereum/BlockChain.h>
#include <libevm/VM.h>
#include "Exceptions.h"
using namespace std;
using namespace dev;
using namespace dev::eth;

namespace dev
{
namespace mix
{

u256 const c_mixGenesisDifficulty = 131072; //TODO: make it lower for Mix somehow

namespace
{
}

MixBlockChain::MixBlockChain(std::string const& _path, AccountMap const& _pre):
	BlockChain(createParams(_pre), _path, WithExisting::Kill)
{
}

ChainParams MixBlockChain::createParams(AccountMap const& _pre)
{
	ChainParams ret;
	ret.accountStartNonce = 0;
	ret.author = Address();
	ret.blockReward = 5000 * ether;
	ret.difficulty = 0;
	ret.gasLimit = 3141592;
	ret.gasUsed = 0;
	ret.genesisState = _pre;
	ret.maximumExtraDataSize = 1024;
	ret.parentHash = h256();
	ret.sealEngineName = "NoProof";
	ret.sealFields = 0;
	ret.timestamp = 0;
	return ret;
}

MixClient::MixClient(std::string const& _dbPath):
	m_preSeal(Block::Null),
	m_postSeal(Block::Null),
	m_dbPath(_dbPath)
{
	resetState(AccountMap());
}

MixClient::~MixClient()
{
}

void MixClient::resetState(std::unordered_map<Address, Account> const& _accounts, Secret const& _miner)
{
	WriteGuard l(x_state);
	Guard fl(x_filtersWatches);

	m_filters.clear();
	for (auto& i: m_specialFilters)
		i.second.clear();
	m_watches.clear();

	m_stateDB = OverlayDB();
	SecureTrieDB<Address, MemoryDB> accountState(&m_stateDB);
	accountState.init();
	dev::eth::commit(_accounts, accountState);

	m_bc.reset();
	m_bc.reset(new MixBlockChain(m_dbPath, _accounts));
	Block b(*m_bc, m_stateDB, BaseState::PreExisting, KeyPair(_miner).address());
	b.sync(bc());
	m_preSeal = b;
	m_postSeal = b;

	DEV_WRITE_GUARDED(x_executions)
		m_executions.clear();
}

Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas, Secret const& _secret)
{
	Transaction ret;
	if (_secret)
	{
		if (_t.isCreation())
			ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce(), _secret);
		else
			ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce(), _secret);
	}
	else
	{
		if (_t.isCreation())
			ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce());
		else
			ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce());
		ret.forceSender(_t.safeSender());
	}
	return ret;
}

// TODO: prototype changed - will need rejigging.
ExecutionResult MixClient::debugTransaction(Transaction const& _t, State const& _state, EnvInfo const& _envInfo, bool _call)
{
	State execState = _state;
	execState.addBalance(_t.sender(), _t.gas() * _t.gasPrice()); //give it enough balance for gas estimation
	eth::ExecutionResult er;
	Executive execution(execState, _envInfo);
	execution.setResultRecipient(er);

	ExecutionResult d;
	d.address = _t.receiveAddress();
	d.sender = _t.sender();
	d.value = _t.value();
	d.inputParameters = _t.data();
	d.executonIndex = m_executions.size();
	if (!_call)
		d.transactionIndex = m_postSeal.pending().size();

	try
	{
		execution.initialize(_t);
		execution.execute();
	}
	catch (Exception const& _e)
	{
		d.excepted = toTransactionException(_e);
		d.transactionData.push_back(_t.data());
		return d;
	}

	std::vector<MachineState> machineStates;
	std::vector<unsigned> levels;
	std::vector<MachineCode> codes;
	std::map<bytes const*, unsigned> codeIndexes;
	std::vector<bytes> data;
	std::map<bytesConstRef const*, unsigned> dataIndexes;
	bytes const* lastCode = nullptr;
	bytesConstRef const* lastData = nullptr;
	unsigned codeIndex = 0;
	unsigned dataIndex = 0;
	auto onOp = [&](uint64_t steps, Instruction inst, bigint newMemSize, bigint gasCost, bigint gas, void* voidVM, void const* voidExt)
	{
		VM& vm = *static_cast<VM*>(voidVM);
		ExtVM const& ext = *static_cast<ExtVM const*>(voidExt);
		if (lastCode == nullptr || lastCode != &ext.code)
		{
			auto const& iter = codeIndexes.find(&ext.code);
			if (iter != codeIndexes.end())
				codeIndex = iter->second;
			else
			{
				codeIndex = codes.size();
				codes.push_back(MachineCode({ext.myAddress, ext.code}));
				codeIndexes[&ext.code] = codeIndex;
			}
			lastCode = &ext.code;
		}

		if (lastData == nullptr || lastData != &ext.data)
		{
			auto const& iter = dataIndexes.find(&ext.data);
			if (iter != dataIndexes.end())
				dataIndex = iter->second;
			else
			{
				dataIndex = data.size();
				data.push_back(ext.data.toBytes());
				dataIndexes[&ext.data] = dataIndex;
			}
			lastData = &ext.data;
		}

		if (levels.size() < ext.depth)
			levels.push_back(machineStates.size() - 1);
		else
			levels.resize(ext.depth);

		machineStates.push_back(MachineState{
									steps,
									vm.curPC(),
									inst,
									newMemSize,
									static_cast<u256>(gas),
									vm.stack(),
									vm.memory(),
									gasCost,
									ext.state().storage(ext.myAddress),
									std::move(levels),
									codeIndex,
									dataIndex
								});
	};

	execution.go(onOp);
	execution.finalize();

	d.excepted = er.excepted;
	d.result = er;
	d.machineStates = machineStates;
	d.executionCode = std::move(codes);
	d.transactionData = std::move(data);
	d.gasUsed = er.gasUsed + er.gasRefunded + c_callStipend;
	if (_t.isCreation())
		d.contractAddress = right160(sha3(rlpList(_t.sender(), _t.nonce())));
	return d;
}

void MixClient::executeTransaction(Transaction const& _t, Block& _block, bool _call, bool _gasAuto, Secret const& _secret)
{
	Transaction t = _gasAuto ? replaceGas(_t, m_postSeal.gasLimitRemaining()) : _t;

	// do debugging run first
	EnvInfo envInfo(bc().info(), bc().lastHashes());
	ExecutionResult d = debugTransaction(t, _block.state(), envInfo, _call);

	// execute on a state
	if (!_call && d.excepted == TransactionException::None)
	{
		u256 useGas = min(d.gasUsed, _block.gasLimitRemaining());
		t = _gasAuto ? replaceGas(_t, useGas, _secret) : _t;
		eth::ExecutionResult const& er = _block.execute(envInfo.lastHashes(), t);
		if (t.isCreation() && _block.state().code(d.contractAddress).empty())
			BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment"));
		d.gasUsed = er.gasUsed + er.gasRefunded + er.gasForDeposit + c_callStipend;
		LocalisedLogEntries logs;
		TransactionReceipt const& tr = _block.receipt(_block.pending().size() - 1);

		LogEntries le = tr.log();
		if (le.size())
			for (unsigned j = 0; j < le.size(); ++j)
				logs.insert(logs.begin(), LocalisedLogEntry(le[j]));
		d.logs =  logs;
	}
	WriteGuard l(x_executions);
	m_executions.emplace_back(std::move(d));
}

std::unordered_map<u256, u256> MixClient::contractStorage(Address _contract)
{
	return m_preSeal.state().storage(_contract);
}

void MixClient::mine()
{
	WriteGuard l(x_state);
	NoProof sealer;
	m_postSeal.commitToSeal(bc());
	Notified<bytes> sealed;
	sealer.onSealGenerated([&](bytes const& sealedHeader){ sealed = sealedHeader; });
	sealer.generateSeal(m_postSeal.info());
	m_postSeal.sealBlock(sealed);
	bc().import(m_postSeal.blockData(), m_postSeal.state().db(), (ImportRequirements::Everything & ~ImportRequirements::ValidSeal) != 0);
	m_postSeal.sync(bc());
	m_preSeal = m_postSeal;
}

ExecutionResult MixClient::lastExecution() const
{
	ReadGuard l(x_executions);
	return m_executions.empty() ? ExecutionResult() : m_executions.back();
}

ExecutionResult MixClient::execution(unsigned _index) const
{
	ReadGuard l(x_executions);
	return m_executions.size() > _index ? m_executions.at(_index) : ExecutionResult();
}

Block MixClient::asOf(h256 const& _block) const
{
	ReadGuard l(x_state);
	Block ret(*m_bc, m_stateDB);
	ret.populateFromChain(bc(), _block);
	return ret;
}

pair<h256, Address> MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto)
{
	TransactionSkeleton ts = _ts;
	ts.from = toAddress(_secret);
	ts.nonce = postSeal().transactionsFrom(ts.from);
	if (ts.nonce == Invalid256)
		ts.nonce = max<u256>(postSeal().transactionsFrom(ts.from), m_tq.maxNonce(ts.from));
	if (ts.gasPrice == Invalid256)
		ts.gasPrice = gasBidPrice();
	if (ts.gas == Invalid256)
		ts.gas = min<u256>(gasLimitRemaining() / 5, balanceAt(ts.from) / ts.gasPrice);
	WriteGuard l(x_state);
	eth::Transaction t(ts, _secret);
	executeTransaction(t, m_postSeal, false, _gasAuto, _secret);
	return make_pair(t.sha3(), toAddress(ts.from, ts.nonce));
}

dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff)
{
	(void)_blockNumber;
	Block block = asOf(eth::PendingBlock);
	u256 n = block.transactionsFrom(_from);
	u256 gas = _gas == Invalid256 ? gasLimitRemaining() : _gas;
	u256 gasPrice = _gasPrice == Invalid256 ? gasBidPrice() : _gasPrice;
	Transaction t(_value, gasPrice, gas, _dest, _data, n);
	t.forceSender(_from);
	if (_ff == FudgeFactor::Lenient)
		block.mutableState().addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
	WriteGuard lw(x_state); //TODO: lock is required only for last execution state
	executeTransaction(t, block, true, _gasAuto);
	return lastExecution().result;
}

dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff)
{
	return call(_from, _value, _dest, _data, _gas, _gasPrice, _blockNumber, false, _ff);
}

dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff)
{
	(void)_blockNumber;
	u256 n;
	Block temp(Block::Null);
	{
		ReadGuard lr(x_state);
		temp = asOf(eth::PendingBlock);
		n = temp.transactionsFrom(_from);
	}
	Transaction t(_value, _gasPrice, _gas, _data, n);
	t.forceSender(_from);
	if (_ff == FudgeFactor::Lenient)
		temp.mutableState().addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
	WriteGuard lw(x_state); //TODO: lock is required only for last execution state
	executeTransaction(t, temp, true, false);
	return lastExecution().result;
}

eth::BlockHeader MixClient::blockInfo() const
{
	ReadGuard l(x_state);
	return BlockHeader(bc().block());
}

void MixClient::setAuthor(Address const& _us)
{
	WriteGuard l(x_state);
	m_postSeal.setAuthor(_us);
}

}
}
<commit_msg>Minor API change - must provide SealEngine to Executive now.<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file MixClient.cpp
 * @author Arkadiy Paronyan arkadiy@ethdev.com
 * @date 2015
 * Ethereum IDE client.
 */

#include "MixClient.h"
#include <vector>
#include <utility>
#include <libdevcore/Exceptions.h>
#include <libethcore/ChainOperationParams.h>
#include <libethcore/BasicAuthority.h>
#include <libethereum/BlockChain.h>
#include <libethereum/Transaction.h>
#include <libethereum/Executive.h>
#include <libethereum/ExtVM.h>
#include <libethereum/BlockChain.h>
#include <libevm/VM.h>
#include "Exceptions.h"
using namespace std;
using namespace dev;
using namespace dev::eth;

namespace dev
{
namespace mix
{

u256 const c_mixGenesisDifficulty = 131072; //TODO: make it lower for Mix somehow

namespace
{
}

MixBlockChain::MixBlockChain(std::string const& _path, AccountMap const& _pre):
	BlockChain(createParams(_pre), _path, WithExisting::Kill)
{
}

ChainParams MixBlockChain::createParams(AccountMap const& _pre)
{
	ChainParams ret;
	ret.accountStartNonce = 0;
	ret.author = Address();
	ret.blockReward = 5000 * ether;
	ret.difficulty = 0;
	ret.gasLimit = 3141592;
	ret.gasUsed = 0;
	ret.genesisState = _pre;
	ret.maximumExtraDataSize = 1024;
	ret.parentHash = h256();
	ret.sealEngineName = "NoProof";
	ret.sealFields = 0;
	ret.timestamp = 0;
	return ret;
}

MixClient::MixClient(std::string const& _dbPath):
	m_preSeal(Block::Null),
	m_postSeal(Block::Null),
	m_dbPath(_dbPath)
{
	resetState(AccountMap());
}

MixClient::~MixClient()
{
}

void MixClient::resetState(std::unordered_map<Address, Account> const& _accounts, Secret const& _miner)
{
	WriteGuard l(x_state);
	Guard fl(x_filtersWatches);

	m_filters.clear();
	for (auto& i: m_specialFilters)
		i.second.clear();
	m_watches.clear();

	m_stateDB = OverlayDB();
	SecureTrieDB<Address, MemoryDB> accountState(&m_stateDB);
	accountState.init();
	dev::eth::commit(_accounts, accountState);

	m_bc.reset();
	m_bc.reset(new MixBlockChain(m_dbPath, _accounts));
	Block b(*m_bc, m_stateDB, BaseState::PreExisting, KeyPair(_miner).address());
	b.sync(bc());
	m_preSeal = b;
	m_postSeal = b;

	DEV_WRITE_GUARDED(x_executions)
		m_executions.clear();
}

Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas, Secret const& _secret)
{
	Transaction ret;
	if (_secret)
	{
		if (_t.isCreation())
			ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce(), _secret);
		else
			ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce(), _secret);
	}
	else
	{
		if (_t.isCreation())
			ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce());
		else
			ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce());
		ret.forceSender(_t.safeSender());
	}
	return ret;
}

// TODO: prototype changed - will need rejigging.
ExecutionResult MixClient::debugTransaction(Transaction const& _t, State const& _state, EnvInfo const& _envInfo, bool _call)
{
	State execState = _state;
	execState.addBalance(_t.sender(), _t.gas() * _t.gasPrice()); //give it enough balance for gas estimation
	eth::ExecutionResult er;
	Executive execution(execState, _envInfo, m_bc->sealEngine());
	execution.setResultRecipient(er);

	ExecutionResult d;
	d.address = _t.receiveAddress();
	d.sender = _t.sender();
	d.value = _t.value();
	d.inputParameters = _t.data();
	d.executonIndex = m_executions.size();
	if (!_call)
		d.transactionIndex = m_postSeal.pending().size();

	try
	{
		execution.initialize(_t);
		execution.execute();
	}
	catch (Exception const& _e)
	{
		d.excepted = toTransactionException(_e);
		d.transactionData.push_back(_t.data());
		return d;
	}

	std::vector<MachineState> machineStates;
	std::vector<unsigned> levels;
	std::vector<MachineCode> codes;
	std::map<bytes const*, unsigned> codeIndexes;
	std::vector<bytes> data;
	std::map<bytesConstRef const*, unsigned> dataIndexes;
	bytes const* lastCode = nullptr;
	bytesConstRef const* lastData = nullptr;
	unsigned codeIndex = 0;
	unsigned dataIndex = 0;
	auto onOp = [&](uint64_t steps, Instruction inst, bigint newMemSize, bigint gasCost, bigint gas, void* voidVM, void const* voidExt)
	{
		VM& vm = *static_cast<VM*>(voidVM);
		ExtVM const& ext = *static_cast<ExtVM const*>(voidExt);
		if (lastCode == nullptr || lastCode != &ext.code)
		{
			auto const& iter = codeIndexes.find(&ext.code);
			if (iter != codeIndexes.end())
				codeIndex = iter->second;
			else
			{
				codeIndex = codes.size();
				codes.push_back(MachineCode({ext.myAddress, ext.code}));
				codeIndexes[&ext.code] = codeIndex;
			}
			lastCode = &ext.code;
		}

		if (lastData == nullptr || lastData != &ext.data)
		{
			auto const& iter = dataIndexes.find(&ext.data);
			if (iter != dataIndexes.end())
				dataIndex = iter->second;
			else
			{
				dataIndex = data.size();
				data.push_back(ext.data.toBytes());
				dataIndexes[&ext.data] = dataIndex;
			}
			lastData = &ext.data;
		}

		if (levels.size() < ext.depth)
			levels.push_back(machineStates.size() - 1);
		else
			levels.resize(ext.depth);

		machineStates.push_back(MachineState{
									steps,
									vm.curPC(),
									inst,
									newMemSize,
									static_cast<u256>(gas),
									vm.stack(),
									vm.memory(),
									gasCost,
									ext.state().storage(ext.myAddress),
									std::move(levels),
									codeIndex,
									dataIndex
								});
	};

	execution.go(onOp);
	execution.finalize();

	d.excepted = er.excepted;
	d.result = er;
	d.machineStates = machineStates;
	d.executionCode = std::move(codes);
	d.transactionData = std::move(data);
	d.gasUsed = er.gasUsed + er.gasRefunded + c_callStipend;
	if (_t.isCreation())
		d.contractAddress = right160(sha3(rlpList(_t.sender(), _t.nonce())));
	return d;
}

void MixClient::executeTransaction(Transaction const& _t, Block& _block, bool _call, bool _gasAuto, Secret const& _secret)
{
	Transaction t = _gasAuto ? replaceGas(_t, m_postSeal.gasLimitRemaining()) : _t;

	// do debugging run first
	EnvInfo envInfo(bc().info(), bc().lastHashes());
	ExecutionResult d = debugTransaction(t, _block.state(), envInfo, _call);

	// execute on a state
	if (!_call && d.excepted == TransactionException::None)
	{
		u256 useGas = min(d.gasUsed, _block.gasLimitRemaining());
		t = _gasAuto ? replaceGas(_t, useGas, _secret) : _t;
		eth::ExecutionResult const& er = _block.execute(envInfo.lastHashes(), t);
		if (t.isCreation() && _block.state().code(d.contractAddress).empty())
			BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment"));
		d.gasUsed = er.gasUsed + er.gasRefunded + er.gasForDeposit + c_callStipend;
		LocalisedLogEntries logs;
		TransactionReceipt const& tr = _block.receipt(_block.pending().size() - 1);

		LogEntries le = tr.log();
		if (le.size())
			for (unsigned j = 0; j < le.size(); ++j)
				logs.insert(logs.begin(), LocalisedLogEntry(le[j]));
		d.logs =  logs;
	}
	WriteGuard l(x_executions);
	m_executions.emplace_back(std::move(d));
}

std::unordered_map<u256, u256> MixClient::contractStorage(Address _contract)
{
	return m_preSeal.state().storage(_contract);
}

void MixClient::mine()
{
	WriteGuard l(x_state);
	NoProof sealer;
	m_postSeal.commitToSeal(bc());
	Notified<bytes> sealed;
	sealer.onSealGenerated([&](bytes const& sealedHeader){ sealed = sealedHeader; });
	sealer.generateSeal(m_postSeal.info());
	m_postSeal.sealBlock(sealed);
	bc().import(m_postSeal.blockData(), m_postSeal.state().db(), (ImportRequirements::Everything & ~ImportRequirements::ValidSeal) != 0);
	m_postSeal.sync(bc());
	m_preSeal = m_postSeal;
}

ExecutionResult MixClient::lastExecution() const
{
	ReadGuard l(x_executions);
	return m_executions.empty() ? ExecutionResult() : m_executions.back();
}

ExecutionResult MixClient::execution(unsigned _index) const
{
	ReadGuard l(x_executions);
	return m_executions.size() > _index ? m_executions.at(_index) : ExecutionResult();
}

Block MixClient::asOf(h256 const& _block) const
{
	ReadGuard l(x_state);
	Block ret(*m_bc, m_stateDB);
	ret.populateFromChain(bc(), _block);
	return ret;
}

pair<h256, Address> MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto)
{
	TransactionSkeleton ts = _ts;
	ts.from = toAddress(_secret);
	ts.nonce = postSeal().transactionsFrom(ts.from);
	if (ts.nonce == Invalid256)
		ts.nonce = max<u256>(postSeal().transactionsFrom(ts.from), m_tq.maxNonce(ts.from));
	if (ts.gasPrice == Invalid256)
		ts.gasPrice = gasBidPrice();
	if (ts.gas == Invalid256)
		ts.gas = min<u256>(gasLimitRemaining() / 5, balanceAt(ts.from) / ts.gasPrice);
	WriteGuard l(x_state);
	eth::Transaction t(ts, _secret);
	executeTransaction(t, m_postSeal, false, _gasAuto, _secret);
	return make_pair(t.sha3(), toAddress(ts.from, ts.nonce));
}

dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff)
{
	(void)_blockNumber;
	Block block = asOf(eth::PendingBlock);
	u256 n = block.transactionsFrom(_from);
	u256 gas = _gas == Invalid256 ? gasLimitRemaining() : _gas;
	u256 gasPrice = _gasPrice == Invalid256 ? gasBidPrice() : _gasPrice;
	Transaction t(_value, gasPrice, gas, _dest, _data, n);
	t.forceSender(_from);
	if (_ff == FudgeFactor::Lenient)
		block.mutableState().addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
	WriteGuard lw(x_state); //TODO: lock is required only for last execution state
	executeTransaction(t, block, true, _gasAuto);
	return lastExecution().result;
}

dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff)
{
	return call(_from, _value, _dest, _data, _gas, _gasPrice, _blockNumber, false, _ff);
}

dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff)
{
	(void)_blockNumber;
	u256 n;
	Block temp(Block::Null);
	{
		ReadGuard lr(x_state);
		temp = asOf(eth::PendingBlock);
		n = temp.transactionsFrom(_from);
	}
	Transaction t(_value, _gasPrice, _gas, _data, n);
	t.forceSender(_from);
	if (_ff == FudgeFactor::Lenient)
		temp.mutableState().addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
	WriteGuard lw(x_state); //TODO: lock is required only for last execution state
	executeTransaction(t, temp, true, false);
	return lastExecution().result;
}

eth::BlockHeader MixClient::blockInfo() const
{
	ReadGuard l(x_state);
	return BlockHeader(bc().block());
}

void MixClient::setAuthor(Address const& _us)
{
	WriteGuard l(x_state);
	m_postSeal.setAuthor(_us);
}

}
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <stan/prob/distributions/univariate/discrete/ordered_logistic.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions.hpp>
#include <stan/math/constants.hpp>

using Eigen::Matrix;
using Eigen::Dynamic;

typedef Eigen::Matrix<double,Eigen::Dynamic,1> vector_d;

vector_d
get_simplex(double lambda,
           const vector_d& c) {
  using stan::math::inv_logit;
  int K = c.size() + 1;
  vector_d theta(K);
  theta(0) = 1.0 - inv_logit(lambda - c(0));
  for (int k = 1; k < (K - 1); ++k)
    theta(k) = inv_logit(lambda - c(k - 1)) - inv_logit(lambda - c(k));
  theta(K-1) = inv_logit(lambda - c(K-2)); // - 0.0
  return theta;
}

TEST(ProbDistributions,ordered_logistic_vals) {
  using Eigen::Matrix;
  using Eigen::Dynamic;

  using stan::prob::ordered_logistic_log;
  using stan::math::inv_logit;

  int K = 5;
  Matrix<double,Dynamic,1> c(K-1);
  c << -1.7, -0.3, 1.2, 2.6;
  double lambda = 1.1;

  vector_d theta = get_simplex(lambda,c);

  double sum = 0.0;
  for (int k = 0; k < theta.size(); ++k)
    sum += theta(k);
  EXPECT_FLOAT_EQ(1.0,sum);

  for (int k = 0; k < K; ++k)
    EXPECT_FLOAT_EQ(log(theta(k)),ordered_logistic_log(k+1,lambda,c));

  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(6,lambda,c),std::domain_error);
}

TEST(ProbDistributions,ordered_logistic_vals_2) {
  using Eigen::Matrix;
  using Eigen::Dynamic;

  using stan::prob::ordered_logistic_log;
  using stan::math::inv_logit;

  int K = 3;
  Matrix<double,Dynamic,1> c(K-1);
  c << -0.2, 4;
  double lambda = -0.9;

  vector_d theta = get_simplex(lambda,c);

  double sum = 0.0;
  for (int k = 0; k < theta.size(); ++k)
    sum += theta(k);
  EXPECT_FLOAT_EQ(1.0,sum);

  for (int k = 0; k < K; ++k)
    EXPECT_FLOAT_EQ(log(theta(k)),ordered_logistic_log(k+1,lambda,c));

  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(4,lambda,c),std::domain_error);
}

TEST(ProbDistributions,ordered_logistic) {
  using stan::prob::ordered_logistic_log;
  int K = 4;
  Eigen::Matrix<double,Eigen::Dynamic,1> c(K-1);
  c << -0.3, 0.1, 1.2;
  double lambda = 0.5;
  EXPECT_THROW(ordered_logistic_log(-1,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(5,lambda,c),std::domain_error);
  for (int k = 1; k <= K; ++k)
    EXPECT_NO_THROW(ordered_logistic_log(k,lambda,c));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_zero; // init size zero
  EXPECT_EQ(0,c_zero.size());
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_zero),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> c_neg(1);
  c_neg << -13.7;
  EXPECT_NO_THROW(ordered_logistic_log(1,lambda,c_neg));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord(3);
  c_unord << 1.0, 0.4, 2.0;
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_unord),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord_2(3);
  c_unord_2 << 1.0, 2.0, 0.4;
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_unord_2),std::domain_error);

  double nan = std::numeric_limits<double>::quiet_NaN();
  double inf = std::numeric_limits<double>::infinity();

  EXPECT_THROW(ordered_logistic_log(1,nan,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(1,inf,c),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad(2);
  cbad << 0.2, inf;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad),std::domain_error);
  cbad[1] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad1(1);
  cbad1 <<  inf;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad1),std::domain_error);
  cbad1[0] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad1),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad3(3);
  cbad3 <<  0.5, inf, 1.0;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad3),std::domain_error);
  cbad3[1] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad3),std::domain_error);
}

void expect_nan(double x) {
  EXPECT_TRUE(std::isnan(x));
}

TEST(ProbDistributionOrderedLogistic, error_check) {
  boost::random::mt19937 rng;
  double inf = std::numeric_limits<double>::infinity();
  Eigen::VectorXd c(4);
  c << -2,
    2.0,
    5,
    10;
  EXPECT_NO_THROW(stan::prob::ordered_logistic_rng(4.0, c, rng));

  EXPECT_THROW(stan::prob::ordered_logistic_rng(stan::math::positive_infinity(),
                                                c, rng),
               std::domain_error);
  c << -inf,
    2.0,
    -5,
    inf;
  EXPECT_THROW(stan::prob::ordered_logistic_rng(4.0, c, rng),
               std::domain_error);

}

TEST(ProbDistributionOrderedLogistic, chiSquareGoodnessFitTest) {
  using stan::math::inv_logit;
  boost::random::mt19937 rng;
  int N = 10000;
  double eta = 1.0;
  Eigen::VectorXd theta(3);
  theta << -1.4,
    21.0,
    139.2;
  Eigen::VectorXd prob(4);
  prob(0) = 1 - inv_logit(eta - theta(0));
  prob(1) = inv_logit(eta - theta(0)) - inv_logit(eta - theta(1));
  prob(2) = inv_logit(eta - theta(1)) - inv_logit(eta - theta(2));
  prob(3) = inv_logit(eta - theta(2));
  int K = prob.rows();
  boost::math::chi_squared mydist(K-1);

  Eigen::VectorXd loc(prob.rows());
  for(int i = 0; i < prob.rows(); i++)
    loc(i) = 0;

  for(int i = 0; i < prob.rows(); i++) {
      for(int j = i; j < prob.rows(); j++)
  loc(j) += prob(i);
    }

  int count = 0;
  int bin [K];
  double expect [K];
  for(int i = 0 ; i < K; i++) {
    bin[i] = 0;
    expect[i] = N * prob(i);
  }

  while (count < N) {
    int a = stan::prob::ordered_logistic_rng(eta,theta,rng);
    bin[a - 1]++;
    count++;
   }

  double chi = 0;

  for(int j = 0; j < K; j++)
    chi += ((bin[j] - expect[j]) * (bin[j] - expect[j]) / expect[j]);

  EXPECT_TRUE(chi < quantile(complement(mydist, 1e-6)));
}

<commit_msg>change ordered_logistic_rng test case so it fails with current code<commit_after>#include <gtest/gtest.h>
#include <stan/prob/distributions/univariate/discrete/ordered_logistic.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions.hpp>
#include <stan/math/constants.hpp>

using Eigen::Matrix;
using Eigen::Dynamic;

typedef Eigen::Matrix<double,Eigen::Dynamic,1> vector_d;

vector_d
get_simplex(double lambda,
           const vector_d& c) {
  using stan::math::inv_logit;
  int K = c.size() + 1;
  vector_d theta(K);
  theta(0) = 1.0 - inv_logit(lambda - c(0));
  for (int k = 1; k < (K - 1); ++k)
    theta(k) = inv_logit(lambda - c(k - 1)) - inv_logit(lambda - c(k));
  theta(K-1) = inv_logit(lambda - c(K-2)); // - 0.0
  return theta;
}

TEST(ProbDistributions,ordered_logistic_vals) {
  using Eigen::Matrix;
  using Eigen::Dynamic;

  using stan::prob::ordered_logistic_log;
  using stan::math::inv_logit;

  int K = 5;
  Matrix<double,Dynamic,1> c(K-1);
  c << -1.7, -0.3, 1.2, 2.6;
  double lambda = 1.1;

  vector_d theta = get_simplex(lambda,c);

  double sum = 0.0;
  for (int k = 0; k < theta.size(); ++k)
    sum += theta(k);
  EXPECT_FLOAT_EQ(1.0,sum);

  for (int k = 0; k < K; ++k)
    EXPECT_FLOAT_EQ(log(theta(k)),ordered_logistic_log(k+1,lambda,c));

  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(6,lambda,c),std::domain_error);
}

TEST(ProbDistributions,ordered_logistic_vals_2) {
  using Eigen::Matrix;
  using Eigen::Dynamic;

  using stan::prob::ordered_logistic_log;
  using stan::math::inv_logit;

  int K = 3;
  Matrix<double,Dynamic,1> c(K-1);
  c << -0.2, 4;
  double lambda = -0.9;

  vector_d theta = get_simplex(lambda,c);

  double sum = 0.0;
  for (int k = 0; k < theta.size(); ++k)
    sum += theta(k);
  EXPECT_FLOAT_EQ(1.0,sum);

  for (int k = 0; k < K; ++k)
    EXPECT_FLOAT_EQ(log(theta(k)),ordered_logistic_log(k+1,lambda,c));

  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(4,lambda,c),std::domain_error);
}

TEST(ProbDistributions,ordered_logistic) {
  using stan::prob::ordered_logistic_log;
  int K = 4;
  Eigen::Matrix<double,Eigen::Dynamic,1> c(K-1);
  c << -0.3, 0.1, 1.2;
  double lambda = 0.5;
  EXPECT_THROW(ordered_logistic_log(-1,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(0,lambda,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(5,lambda,c),std::domain_error);
  for (int k = 1; k <= K; ++k)
    EXPECT_NO_THROW(ordered_logistic_log(k,lambda,c));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_zero; // init size zero
  EXPECT_EQ(0,c_zero.size());
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_zero),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> c_neg(1);
  c_neg << -13.7;
  EXPECT_NO_THROW(ordered_logistic_log(1,lambda,c_neg));

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord(3);
  c_unord << 1.0, 0.4, 2.0;
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_unord),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> c_unord_2(3);
  c_unord_2 << 1.0, 2.0, 0.4;
  EXPECT_THROW(ordered_logistic_log(1,lambda,c_unord_2),std::domain_error);

  double nan = std::numeric_limits<double>::quiet_NaN();
  double inf = std::numeric_limits<double>::infinity();

  EXPECT_THROW(ordered_logistic_log(1,nan,c),std::domain_error);
  EXPECT_THROW(ordered_logistic_log(1,inf,c),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad(2);
  cbad << 0.2, inf;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad),std::domain_error);
  cbad[1] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad1(1);
  cbad1 <<  inf;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad1),std::domain_error);
  cbad1[0] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad1),std::domain_error);

  Eigen::Matrix<double,Eigen::Dynamic,1> cbad3(3);
  cbad3 <<  0.5, inf, 1.0;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad3),std::domain_error);
  cbad3[1] = nan;
  EXPECT_THROW(ordered_logistic_log(1,1.0,cbad3),std::domain_error);
}

void expect_nan(double x) {
  EXPECT_TRUE(std::isnan(x));
}

TEST(ProbDistributionOrderedLogistic, error_check) {
  boost::random::mt19937 rng;
  double inf = std::numeric_limits<double>::infinity();
  Eigen::VectorXd c(4);
  c << -2,
    2.0,
    5,
    10;
  EXPECT_NO_THROW(stan::prob::ordered_logistic_rng(4.0, c, rng));

  EXPECT_THROW(stan::prob::ordered_logistic_rng(stan::math::positive_infinity(),
                                                c, rng),
               std::domain_error);
  c << -inf,
    2.0,
    -5,
    inf;
  EXPECT_THROW(stan::prob::ordered_logistic_rng(4.0, c, rng),
               std::domain_error);

}

TEST(ProbDistributionOrderedLogistic, chiSquareGoodnessFitTest) {
  using stan::math::inv_logit;
  boost::random::mt19937 rng;
  int N = 10000;
  double eta = 1.0;
  Eigen::VectorXd theta(3);
  theta << -0.4,
    4.0,
    6.2;
  Eigen::VectorXd prob(4);
  prob(0) = 1 - inv_logit(eta - theta(0));
  prob(1) = inv_logit(eta - theta(0)) - inv_logit(eta - theta(1));
  prob(2) = inv_logit(eta - theta(1)) - inv_logit(eta - theta(2));
  prob(3) = inv_logit(eta - theta(2));
  int K = prob.rows();
  boost::math::chi_squared mydist(K-1);

  Eigen::VectorXd loc(prob.rows());
  for(int i = 0; i < prob.rows(); i++)
    loc(i) = 0;

  for(int i = 0; i < prob.rows(); i++) {
      for(int j = i; j < prob.rows(); j++)
  loc(j) += prob(i);
    }

  int count = 0;
  int bin [K];
  double expect [K];
  for(int i = 0 ; i < K; i++) {
    bin[i] = 0;
    expect[i] = N * prob(i);
  }

  while (count < N) {
    int a = stan::prob::ordered_logistic_rng(eta,theta,rng);
    bin[a - 1]++;
    count++;
   }

  double chi = 0;

  for(int j = 0; j < K; j++) {
    chi += ((bin[j] - expect[j]) * (bin[j] - expect[j]) / expect[j]);
    std::cout<<j<<" bin   "<<bin[j]<<std::endl;
    std::cout<<j<<" exp   "<<expect[j]<<std::endl;
  }
  EXPECT_TRUE(chi < quantile(complement(mydist, 1e-6)));
}

<|endoftext|>


<commit_before>//----------------------------  crash_10.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2005, 2006 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  crash_10.cc  ---------------------------

// a version of hp_hanging_node_02 that crashed at the time
// of writing the time

#include <base/logstream.h>
#include <grid/tria.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_constraints.h>
#include <grid/grid_generator.h>

#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>

#include <fe/fe_q.h>

#include <dofs/dof_tools.h>

#include <fe/hp_fe_values.h>
#include <base/quadrature_lib.h>

#include <base/function.h>
#include <numerics/vectors.h>
#include <numerics/matrices.h>

#include <lac/vector.h>
#include <lac/full_matrix.h>
#include <lac/sparse_matrix.h>
#include <lac/solver_cg.h>
#include <lac/precondition.h>

#include <numerics/data_out.h>
#include <fstream>
#include <iostream>

std::ofstream logfile("crash_10/output");

template <int dim>
void test ()
{
  Triangulation<dim>     triangulation;
  hp::FECollection<dim>              fe;
  hp::DoFHandler<dim>        dof_handler(triangulation);
  ConstraintMatrix     hanging_node_constraints;

  FE_Q<dim> fe_1 (1), fe_2 (2), fe_3 (3), fe_4 (4);

  fe.push_back (fe_1);
  fe.push_back (fe_2);
  fe.push_back (fe_3);
  fe.push_back (fe_4);

  GridGenerator::hyper_cube (triangulation, -1, 1);
  triangulation.refine_global (5-dim);
  deallog << "Number of active cells: "
	    << triangulation.n_active_cells()
	    << std::endl;
  deallog << "Total number of cells: "
	    << triangulation.n_cells()
	    << std::endl;

				   // Now to the p-Method. Assign
				   // random active_fe_indices to the
				   // different cells.
  typename hp::DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active (),
						     endc = dof_handler.end ();
  for (; cell != endc; ++cell)
    cell->set_active_fe_index (random() % 4);

  dof_handler.distribute_dofs (fe);
  DoFTools::make_hanging_node_constraints (dof_handler,
					   hanging_node_constraints);

  hanging_node_constraints.print (deallog.get_file_stream ());

  hanging_node_constraints.close ();
}

int main ()
{
  logfile.precision(2);

  deallog.attach(logfile);
  deallog.depth_console(0);
  deallog.threshold_double(1.e-10);

				   // this test depends on the right
				   // starting value of the random
				   // number generator. set it to the
				   // same value it has in
				   // hp_hanging_nodes_02
  for (unsigned int i=0; i<64; ++i)
    random ();
  test<3> ();

  return 0;
}
<commit_msg>Remove a bunch of include files that we don't need no more.<commit_after>//----------------------------  crash_10.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2005, 2006 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  crash_10.cc  ---------------------------

// a version of hp_hanging_node_02 that crashed at the time
// of writing the time

#include <base/logstream.h>
#include <grid/tria.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_constraints.h>
#include <grid/grid_generator.h>

#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_accessor.h>

#include <fe/fe_q.h>

#include <dofs/dof_tools.h>

#include <fstream>

std::ofstream logfile("crash_10/output");

template <int dim>
void test ()
{
  Triangulation<dim>     triangulation;
  hp::FECollection<dim>              fe;
  hp::DoFHandler<dim>        dof_handler(triangulation);
  ConstraintMatrix     hanging_node_constraints;

  FE_Q<dim> fe_1 (1), fe_2 (2), fe_3 (3), fe_4 (4);

  fe.push_back (fe_1);
  fe.push_back (fe_2);
  fe.push_back (fe_3);
  fe.push_back (fe_4);

  GridGenerator::hyper_cube (triangulation, -1, 1);
  triangulation.refine_global (5-dim);
  deallog << "Number of active cells: "
	    << triangulation.n_active_cells()
	    << std::endl;
  deallog << "Total number of cells: "
	    << triangulation.n_cells()
	    << std::endl;

				   // Now to the p-Method. Assign
				   // random active_fe_indices to the
				   // different cells.
  typename hp::DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active (),
						     endc = dof_handler.end ();
  for (; cell != endc; ++cell)
    cell->set_active_fe_index (random() % 4);

  dof_handler.distribute_dofs (fe);
  DoFTools::make_hanging_node_constraints (dof_handler,
					   hanging_node_constraints);

  hanging_node_constraints.print (deallog.get_file_stream ());

  hanging_node_constraints.close ();
}

int main ()
{
  logfile.precision(2);

  deallog.attach(logfile);
  deallog.depth_console(0);
  deallog.threshold_double(1.e-10);

				   // this test depends on the right
				   // starting value of the random
				   // number generator. set it to the
				   // same value it has in
				   // hp_hanging_nodes_02
  for (unsigned int i=0; i<64; ++i)
    random ();
  test<3> ();

  return 0;
}
<|endoftext|>


<commit_before>#include "NodeModel.hpp"

using namespace QtNodes;

NodeModel::NodeModel() {}

void NodeModel::setInData(std::shared_ptr<QtNodes::NodeData> nodeData,
                          QtNodes::PortIndex port) {
  Q_UNUSED(nodeData)
  Q_UNUSED(port)
}

std::shared_ptr<NodeData> NodeModel::outData(PortIndex port) {
  Q_UNUSED(port)
  std::shared_ptr<NodeData> ptr;
  return ptr;
}

SimpleNodeModel::SimpleNodeModel() {}

QString SimpleNodeModel::caption() const { return QStringLiteral(""); }

bool SimpleNodeModel::captionVisible() const { return false; }

QString AnonymousNodeModel::name() const { return QStringLiteral(""); }
<commit_msg>added missing constructor of AnonymousNodeModel<commit_after>#include "NodeModel.hpp"

using namespace QtNodes;

NodeModel::NodeModel() {}

void NodeModel::setInData(std::shared_ptr<QtNodes::NodeData> nodeData,
                          QtNodes::PortIndex port) {
  Q_UNUSED(nodeData)
  Q_UNUSED(port)
}

std::shared_ptr<NodeData> NodeModel::outData(PortIndex port) {
  Q_UNUSED(port)
  std::shared_ptr<NodeData> ptr;
  return ptr;
}

SimpleNodeModel::SimpleNodeModel() {}

QString SimpleNodeModel::caption() const { return QStringLiteral(""); }

bool SimpleNodeModel::captionVisible() const { return false; }

AnonymousNodeModel::AnonymousNodeModel(){}

QString AnonymousNodeModel::name() const { return QStringLiteral(""); }
<|endoftext|>