<commit_before>#include <errno.h>
#include <math.h>
#include <QCloseEvent>
#include <QDateTime>
#include <QMessageBox>

#include "mainwindow.h"
#include "ui_mainwindow.h"

const char MainWindow::pol_pm[] =
        "+ -";
const char MainWindow::pol_mp[] =
        "- +";

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

    QObject::connect(&configUI, SIGNAL(accepted()), this, SLOT(show()));

    currentTimer.setInterval(currentDwell);
    currentTimer.setSingleShot(false);
    QObject::connect(&currentTimer, SIGNAL(timeout()), this,
                     SLOT(on_currentTimer_timeout()));
}

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

void MainWindow::closeDevs()
{
    currentTimer.stop();
    ui->sweppingLabel->setEnabled(false);
    csvFile.close();
    ps622Hack.close();
    pwrPolSwitch.close();
    sdp_close(&sdp);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (configUI.isHidden() && configUI.result() == QDialog::Accepted) {
        closeDevs();
        event->ignore();
        hide();
        configUI.show();

        return;
    }

    QMainWindow::closeEvent(event);
}

void MainWindow::on_coilCurrDoubleSpinBox_valueChanged(double )
{
    ui->sweppingLabel->setEnabled(true);
}

void MainWindow::on_coilPolCrossCheckBox_toggled(bool checked)
{
    ui->sweppingLabel->setEnabled(true);

    if (checked)
        ui->polarityLabel->setText(pol_mp);
    else
        ui->polarityLabel->setText(pol_pm);
}

void MainWindow::on_coilPowerCheckBox_toggled(bool)
{
    ui->sweppingLabel->setEnabled(true);
}

void MainWindow::on_currentTimer_timeout()
{
    sdp_va_data_t va_data;

    // tweak coil current
    while (ui->sweppingLabel->isEnabled()) {
        /** Curent trought coil */
        double wantI, procI;
        /** Coil power state, on/off */
        bool wantCoilPower, procCoilPower;
        /** Coil power switch state direct/cross */
        PwrPolSwitch::state_t wantCoilSwitchState, procCoilSwitchState;

        /* Get all values necesary for process decisions. */
        // wanted values
        if (ui->coilPolCrossCheckBox->isChecked())
            wantCoilSwitchState = PwrPolSwitch::cross;
        else
            wantCoilSwitchState = PwrPolSwitch::direct;

        wantCoilPower = ui->coilPowerCheckBox->isChecked();

        if (wantCoilPower) {
            wantI = ui->coilCurrDoubleSpinBox->value();
            if (wantCoilSwitchState == PwrPolSwitch::cross)
                wantI = -wantI;
        }
        else
            wantI = 0;

        // proc values
        procCoilSwitchState = pwrPolSwitch.polarity();

        sdp_lcd_info_t lcd_info;
        sdp_get_lcd_info(&sdp, &lcd_info); // TODO check
        procCoilPower = lcd_info.output;
        procI = lcd_info.set_A;
        if (procCoilSwitchState == PwrPolSwitch::cross)
            procI = -procI;

        ui->plainTextEdit->appendPlainText(QString("procI: %1, procCoilSwitchState: %2, procCoilPower: %3").arg(procI).arg(procCoilSwitchState).arg(procCoilPower));
        ui->plainTextEdit->appendPlainText(QString("wantI: %1, wantCoilSwitchState: %2, wantCoilPower: %3\n").arg(wantI).arg(wantCoilSwitchState).arg(wantCoilPower));

        /* process decision */
        // Target reach, finish job
        if (fabs(procI - wantI) < currentSlope) {
            ui->sweppingLabel->setEnabled(false);
            if (!wantCoilPower && procI <= currentSlope && procCoilPower)
                sdp_set_output(&sdp, 0); // TODO check

            break;
        }

        // Need switch polarity?
        if (procCoilSwitchState != wantCoilSwitchState) {
            // Is polarity switch posible? (power is off)
            if (!procCoilPower) {
                pwrPolSwitch.setPolarity(wantCoilSwitchState); // TODO check
                break;
            }

            // Is posible power-off in order to swich polarity?
            if (fabs(procI) < currentSlope) {
                sdp_set_output(&sdp, 0);
                break;
            }

            // set current near to zero before polarity switching
        }

        // want current but power is off -> set power on at current 0.0 A
        if (procCoilPower != wantCoilPower && wantCoilPower) {
            sdp_set_curr(&sdp, 0.0);
            sdp_set_output(&sdp, 1);
            break;
        }

        // power is on, but current neet to be adjusted, do one step
        if (procI > wantI)
            procI -= currentSlope;
        else
            procI += currentSlope;

        sdp_set_curr(&sdp, fabs(procI));

        break;
    }

    if (sdp_get_va_data(&sdp, &va_data) < 0) {
        // TODO
        close();
        return;
    }

    ui->coilCurrMeasDoubleSpinBox->setValue(va_data.curr);
    ui->coilVoltMeasDoubleSpinBox->setValue(va_data.volt);
}

void MainWindow::on_measurePushButton_clicked()
{
    QString line("%1,%2,%3,%4,%5\r\n");
    QString s;
    int row;

    row = ui->dataTableWidget->rowCount();
    ui->dataTableWidget->insertRow(row);

    s = QDateTime::currentDateTime().toString("yyyy-MM-dd mm:ss");
    ui->dataTableWidget->setItem(row, 3, new QTableWidgetItem(s));
    line = line.arg(s);

    s = ui->coilCurrMeasDoubleSpinBox->text().replace(",", ".");
    ui->dataTableWidget->setItem(row, 0, new QTableWidgetItem(s));
    line = line.arg(s);

    s = ui->coilVoltMeasDoubleSpinBox->text().replace(",", ".");
    line = line.arg(s);

    s = ui->coilCurrDoubleSpinBox->text().replace(",", ".");
    line = line.arg(s);

    s = ui->sampleCurrDoubleSpinBox->text().replace(",", ".");
    ui->dataTableWidget->setItem(row, 1, new QTableWidgetItem(s));
    line = line.arg(s);

    // TODO: inset hall U

    csvFile.write(line.toLocal8Bit());

}

void MainWindow::on_sampleCurrDoubleSpinBox_valueChanged(double value)
{
    ps622Hack.setCurrent(value);
}

void MainWindow::on_samplePolCrossCheckBox_toggled(bool )
{

}

void MainWindow::on_samplePowerCheckBox_toggled(bool checked)
{
    ps622Hack.setOutput(checked);
}

bool MainWindow::openDevs()
{
    QString csvHeader("Time, coil curr. meas. [A],"
                      "coil volt. meas. [V],"
                      " coil curr want. [A],"
                      " sample curr. want. [A],"
                      " sample hall [V]\r\n");
    QString err_text, err_title;
    QString s;
    int err;

    s = settings.value(ConfigUI::cfg_powerSupplyPort).toString();
    err = sdp_open(&sdp, s.toLocal8Bit().constData(), SDP_DEV_ADDR_MIN);
    if (err < 0)
        goto sdp_err0;

    /* Set value limit in current input spin  box. */
    sdp_va_t limits;
    err = sdp_get_va_maximums(&sdp, &limits);
    if (err < 0)
        goto sdp_err;
    ui->coilCurrDoubleSpinBox->setMaximum(limits.curr);

    /* Set actual current as wanted value, avoiding anny jumps. */
    sdp_va_data_t va_data;
    err = sdp_get_va_data(&sdp, &va_data);
    if (err < 0)
        goto sdp_err;
    err = sdp_set_curr(&sdp, va_data.curr);
    if (err < 0)
        goto sdp_err;
    /* Set voltage to maximum, Hall is current driven. */
    err = sdp_set_volt_limit(&sdp, va_data.volt);
    if (err < 0)
        goto sdp_err;
    err = sdp_set_volt(&sdp, va_data.volt);
    if (err < 0)
        goto sdp_err;

    sdp_lcd_info_t lcd_info;
    sdp_get_lcd_info(&sdp, &lcd_info); // TODO check
    if (err < 0)
        goto sdp_err;
    ui->coilPowerCheckBox->setChecked(lcd_info.output);

    s = settings.value(ConfigUI::cfg_polSwitchPort).toString();
    if (!pwrPolSwitch.open(s.toLocal8Bit().constData())) {
        err = errno;
        goto mag_pwr_switch_err;
    }

    bool cross;
    cross = (pwrPolSwitch.polarity() == PwrPolSwitch::cross);
    ui->coilPolCrossCheckBox->setChecked(cross);

    s = settings.value(ConfigUI::cfg_samplePSPort).toString();
    if (!ps622Hack.open(s.toLocal8Bit().constData()))
    {
        err = errno;
        goto sample_pwr_err;
    }

    ui->sampleCurrDoubleSpinBox->setValue(ps622Hack.current());
    ui->samplePowerCheckBox->setChecked(ps622Hack.output());

    s= settings.value(ConfigUI::cfg_fileName).toString();
    csvFile.setFileName(s);
    if (!csvFile.open(QFile::WriteOnly | QFile::Truncate))
        goto file_err;

    csvFile.write(csvHeader.toLocal8Bit());
    /* TODO ... */

    ui->sweppingLabel->setEnabled(true);
    currentTimer.start();

    return true;

file_err:
    ps622Hack.close();
    if (err_title.isEmpty()) {
        err_title = QString::fromLocal8Bit(
                    "Failed to open output file");
        err_text = csvFile.errorString();
    }

sample_pwr_err:
    pwrPolSwitch.close();
    if (err_title.isEmpty()) {
        err_title = QString::fromLocal8Bit(
                    "Failed to open sample power supply (Keithaly 6220)");
        err_text = QString::fromLocal8Bit(strerror(err));
    }

mag_pwr_switch_err:
    if (err_title.isEmpty()) {
        err_title = QString::fromLocal8Bit(
                    "Failed to open power supply switch");
        err_text = QString::fromLocal8Bit(strerror(err));
    }

sdp_err:
    sdp_close(&sdp);

sdp_err0:
    if (err_title.isEmpty()) {
        err_title = QString::fromLocal8Bit(
                    "Failed to open Manson SDP power supply");
        err_text = QString::fromLocal8Bit(sdp_strerror(err));
    }

    err_text = QString("%1:\n\n%2").arg(err_title).arg(err_text);
    QMessageBox::critical(this, err_title, err_text);
    statusBar()->showMessage(err_title);

    return false;
}

void MainWindow::show()
{
    if (!openDevs()) {
        configUI.show();

        return;
    }

    QWidget::show();
}

void MainWindow::startApp()
{
    configUI.show();
}

void MainWindow::updateCurrent()
{
    double current;

    current = ui->coilCurrDoubleSpinBox->value();
    if (ui->coilPolCrossCheckBox->isChecked())
        current = -current;

    sdp_set_curr(&sdp, current);

    /* TODO */
}
<commit_msg>Fix voltage limits set to max instead of actual value<commit_after>#include <errno.h>
#include <math.h>
#include <QCloseEvent>
#include <QDateTime>
#include <QMessageBox>

#include "mainwindow.h"
#include "ui_mainwindow.h"

const char MainWindow::pol_pm[] =
        "+ -";
const char MainWindow::pol_mp[] =
        "- +";

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

    QObject::connect(&configUI, SIGNAL(accepted()), this, SLOT(show()));

    currentTimer.setInterval(currentDwell);
    currentTimer.setSingleShot(false);
    QObject::connect(&currentTimer, SIGNAL(timeout()), this,
                     SLOT(on_currentTimer_timeout()));
}

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

void MainWindow::closeDevs()
{
    currentTimer.stop();
    ui->sweppingLabel->setEnabled(false);
    csvFile.close();
    ps622Hack.close();
    pwrPolSwitch.close();
    sdp_close(&sdp);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (configUI.isHidden() && configUI.result() == QDialog::Accepted) {
        closeDevs();
        event->ignore();
        hide();
        configUI.show();

        return;
    }

    QMainWindow::closeEvent(event);
}

void MainWindow::on_coilCurrDoubleSpinBox_valueChanged(double )
{
    ui->sweppingLabel->setEnabled(true);
}

void MainWindow::on_coilPolCrossCheckBox_toggled(bool checked)
{
    ui->sweppingLabel->setEnabled(true);

    if (checked)
        ui->polarityLabel->setText(pol_mp);
    else
        ui->polarityLabel->setText(pol_pm);
}

void MainWindow::on_coilPowerCheckBox_toggled(bool)
{
    ui->sweppingLabel->setEnabled(true);
}

void MainWindow::on_currentTimer_timeout()
{
    sdp_va_data_t va_data;

    // tweak coil current
    while (ui->sweppingLabel->isEnabled()) {
        /** Curent trought coil */
        double wantI, procI;
        /** Coil power state, on/off */
        bool wantCoilPower, procCoilPower;
        /** Coil power switch state direct/cross */
        PwrPolSwitch::state_t wantCoilSwitchState, procCoilSwitchState;

        /* Get all values necesary for process decisions. */
        // wanted values
        if (ui->coilPolCrossCheckBox->isChecked())
            wantCoilSwitchState = PwrPolSwitch::cross;
        else
            wantCoilSwitchState = PwrPolSwitch::direct;

        wantCoilPower = ui->coilPowerCheckBox->isChecked();

        if (wantCoilPower) {
            wantI = ui->coilCurrDoubleSpinBox->value();
            if (wantCoilSwitchState == PwrPolSwitch::cross)
                wantI = -wantI;
        }
        else
            wantI = 0;

        // proc values
        procCoilSwitchState = pwrPolSwitch.polarity();

        sdp_lcd_info_t lcd_info;
        sdp_get_lcd_info(&sdp, &lcd_info); // TODO check
        procCoilPower = lcd_info.output;
        procI = lcd_info.set_A;
        if (procCoilSwitchState == PwrPolSwitch::cross)
            procI = -procI;

        ui->plainTextEdit->appendPlainText(QString("procI: %1, procCoilSwitchState: %2, procCoilPower: %3").arg(procI).arg(procCoilSwitchState).arg(procCoilPower));
        ui->plainTextEdit->appendPlainText(QString("wantI: %1, wantCoilSwitchState: %2, wantCoilPower: %3\n").arg(wantI).arg(wantCoilSwitchState).arg(wantCoilPower));

        /* process decision */
        // Target reach, finish job
        if (fabs(procI - wantI) < currentSlope) {
            ui->sweppingLabel->setEnabled(false);
            if (!wantCoilPower && procI <= currentSlope && procCoilPower)
                sdp_set_output(&sdp, 0); // TODO check

            break;
        }

        // Need switch polarity?
        if (procCoilSwitchState != wantCoilSwitchState) {
            // Is polarity switch posible? (power is off)
            if (!procCoilPower) {
                pwrPolSwitch.setPolarity(wantCoilSwitchState); // TODO check
                break;
            }

            // Is posible power-off in order to swich polarity?
            if (fabs(procI) < currentSlope) {
                sdp_set_output(&sdp, 0);
                break;
            }

            // set current near to zero before polarity switching
        }

        // want current but power is off -> set power on at current 0.0 A
        if (procCoilPower != wantCoilPower && wantCoilPower) {
            sdp_set_curr(&sdp, 0.0);
            sdp_set_output(&sdp, 1);
            break;
        }

        // power is on, but current neet to be adjusted, do one step
        if (procI > wantI)
            procI -= currentSlope;
        else
            procI += currentSlope;

        sdp_set_curr(&sdp, fabs(procI));

        break;
    }

    if (sdp_get_va_data(&sdp, &va_data) < 0) {
        // TODO
        close();
        return;
    }

    ui->coilCurrMeasDoubleSpinBox->setValue(va_data.curr);
    ui->coilVoltMeasDoubleSpinBox->setValue(va_data.volt);
}

void MainWindow::on_measurePushButton_clicked()
{
    QString line("%1,%2,%3,%4,%5\r\n");
    QString s;
    int row;

    row = ui->dataTableWidget->rowCount();
    ui->dataTableWidget->insertRow(row);

    s = QDateTime::currentDateTime().toString("yyyy-MM-dd mm:ss");
    ui->dataTableWidget->setItem(row, 3, new QTableWidgetItem(s));
    line = line.arg(s);

    s = ui->coilCurrMeasDoubleSpinBox->text().replace(",", ".");
    ui->dataTableWidget->setItem(row, 0, new QTableWidgetItem(s));
    line = line.arg(s);

    s = ui->coilVoltMeasDoubleSpinBox->text().replace(",", ".");
    line = line.arg(s);

    s = ui->coilCurrDoubleSpinBox->text().replace(",", ".");
    line = line.arg(s);

    s = ui->sampleCurrDoubleSpinBox->text().replace(",", ".");
    ui->dataTableWidget->setItem(row, 1, new QTableWidgetItem(s));
    line = line.arg(s);

    // TODO: inset hall U

    csvFile.write(line.toLocal8Bit());

}

void MainWindow::on_sampleCurrDoubleSpinBox_valueChanged(double value)
{
    ps622Hack.setCurrent(value);
}

void MainWindow::on_samplePolCrossCheckBox_toggled(bool )
{

}

void MainWindow::on_samplePowerCheckBox_toggled(bool checked)
{
    ps622Hack.setOutput(checked);
}

bool MainWindow::openDevs()
{
    QString csvHeader("Time, coil curr. meas. [A],"
                      "coil volt. meas. [V],"
                      " coil curr want. [A],"
                      " sample curr. want. [A],"
                      " sample hall [V]\r\n");
    QString err_text, err_title;
    QString s;
    int err;

    s = settings.value(ConfigUI::cfg_powerSupplyPort).toString();
    err = sdp_open(&sdp, s.toLocal8Bit().constData(), SDP_DEV_ADDR_MIN);
    if (err < 0)
        goto sdp_err0;

    /* Set value limit in current input spin  box. */
    sdp_va_t limits;
    err = sdp_get_va_maximums(&sdp, &limits);
    if (err < 0)
        goto sdp_err;
    ui->coilCurrDoubleSpinBox->setMaximum(limits.curr);

    /* Set actual current as wanted value, avoiding anny jumps. */
    sdp_va_data_t va_data;
    err = sdp_get_va_data(&sdp, &va_data);
    if (err < 0)
        goto sdp_err;
    err = sdp_set_curr(&sdp, va_data.curr);
    if (err < 0)
        goto sdp_err;
    ui->coilCurrDoubleSpinBox->setValue(va_data.curr);

    /* Set voltage to maximum, Hall is current driven. */
    err = sdp_set_volt_limit(&sdp, limits.volt);
    if (err < 0)
        goto sdp_err;
    err = sdp_set_volt(&sdp, limits.volt);
    if (err < 0)
        goto sdp_err;

    sdp_lcd_info_t lcd_info;
    sdp_get_lcd_info(&sdp, &lcd_info); // TODO check
    if (err < 0)
        goto sdp_err;
    ui->coilPowerCheckBox->setChecked(lcd_info.output);

    s = settings.value(ConfigUI::cfg_polSwitchPort).toString();
    if (!pwrPolSwitch.open(s.toLocal8Bit().constData())) {
        err = errno;
        goto mag_pwr_switch_err;
    }

    bool cross;
    cross = (pwrPolSwitch.polarity() == PwrPolSwitch::cross);
    ui->coilPolCrossCheckBox->setChecked(cross);

    s = settings.value(ConfigUI::cfg_samplePSPort).toString();
    if (!ps622Hack.open(s.toLocal8Bit().constData()))
    {
        err = errno;
        goto sample_pwr_err;
    }

    ui->sampleCurrDoubleSpinBox->setValue(ps622Hack.current());
    ui->samplePowerCheckBox->setChecked(ps622Hack.output());

    s= settings.value(ConfigUI::cfg_fileName).toString();
    csvFile.setFileName(s);
    if (!csvFile.open(QFile::WriteOnly | QFile::Truncate))
        goto file_err;

    csvFile.write(csvHeader.toLocal8Bit());
    /* TODO ... */

    ui->sweppingLabel->setEnabled(true);
    currentTimer.start();

    return true;

file_err:
    ps622Hack.close();
    if (err_title.isEmpty()) {
        err_title = QString::fromLocal8Bit(
                    "Failed to open output file");
        err_text = csvFile.errorString();
    }

sample_pwr_err:
    pwrPolSwitch.close();
    if (err_title.isEmpty()) {
        err_title = QString::fromLocal8Bit(
                    "Failed to open sample power supply (Keithaly 6220)");
        err_text = QString::fromLocal8Bit(strerror(err));
    }

mag_pwr_switch_err:
    if (err_title.isEmpty()) {
        err_title = QString::fromLocal8Bit(
                    "Failed to open power supply switch");
        err_text = QString::fromLocal8Bit(strerror(err));
    }

sdp_err:
    sdp_close(&sdp);

sdp_err0:
    if (err_title.isEmpty()) {
        err_title = QString::fromLocal8Bit(
                    "Failed to open Manson SDP power supply");
        err_text = QString::fromLocal8Bit(sdp_strerror(err));
    }

    err_text = QString("%1:\n\n%2").arg(err_title).arg(err_text);
    QMessageBox::critical(this, err_title, err_text);
    statusBar()->showMessage(err_title);

    return false;
}

void MainWindow::show()
{
    if (!openDevs()) {
        configUI.show();

        return;
    }

    QWidget::show();
}

void MainWindow::startApp()
{
    configUI.show();
}

void MainWindow::updateCurrent()
{
    double current;

    current = ui->coilCurrDoubleSpinBox->value();
    if (ui->coilPolCrossCheckBox->isChecked())
        current = -current;

    sdp_set_curr(&sdp, current);

    /* TODO */
}
<|endoftext|>


<commit_before>// Simulating Group Dynamics in Crowds of Pedestrians (SGDiCoP)
// Author: Sven Wehner <mail@svenwehner.de>
//
// Forked from: PedSim's demo application (version 2.2).
// (http://pedsim.silmaril.org/)
// Copyright text:
// 		pedsim - A microscopic pedestrian simulation system.
// 		Copyright (c) 2003 - 2012 by Christian Gloor

// Includes
#include "mainwindow.h"
// → SGDiCoP
#include "sgdicop.h"
#include "controlwidget.h"
#include "loggingwidget.h"
#include "editorwidget.h"
#include "scenarioview.h"
#include "scenarioelement.h"
// → Qt
#include <QCloseEvent>
#include <QFileDialog>
#include <QGraphicsScene>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>

MainWindow::MainWindow() {
	// create graphical representation
	graphicsscene = new QGraphicsScene();
	QColor backgroundColor = settings.value("Colors/Background", Qt::black).value<QColor>();
	graphicsscene->setBackgroundBrush(backgroundColor);
	graphicsscene->setItemIndexMethod(QGraphicsScene::NoIndex);

	graphicsView = new ScenarioView(this);
	graphicsView->setScene(graphicsscene);
	graphicsView->show();
	setCentralWidget(graphicsView);

	// add control widget to the GUI
	uicontrol = new ControlWidget(this);
	addDockWidget(Qt::LeftDockWidgetArea, uicontrol);

	// add logging widget to the GUI
	// uilogging = new LoggingWidget(this);
	// addDockWidget(Qt::BottomDockWidgetArea, uilogging);

	// add editor widget to the GUI
	uieditor = new EditorWidget(this);
	addDockWidget(Qt::RightDockWidgetArea, uieditor);
	uieditor->setVisible(false);

	createActions();
	loadIcons();
	createMenus();

	readSettings();
    setFocusPolicy(Qt::StrongFocus);

	// connect signals
	connect(uicontrol, SIGNAL(zoomin()), graphicsView, SLOT(zoomin()));
	connect(uicontrol, SIGNAL(zoomout()), graphicsView, SLOT(zoomout()));
	connect(&SGDICOP, SIGNAL(scenarioCreated()), this, SLOT(onScenarioCreated()));
	connect(&SGDICOP, SIGNAL(scenarioLoaded()), this, SLOT(onScenarioLoaded()));
}

QPointF MainWindow::getDefaultPosition() const {
	if(graphicsView == NULL)
		return QPointF();
	else
		return graphicsView->centerOfView();
}

QString MainWindow::showOpenScenarioDialog() {
	// open a file selector to choose the scene input file
	QSettings settings;
	QString recentInputFilename = settings.value("RecentInputFile").toString();
	QString sceneInputFilename = QFileDialog::getOpenFileName(
		this,
		tr("Open scenario file"),
		recentInputFilename,
		tr("SGDiCoP Scenario Files (*.xml *.scenario);;All (*)"));

	// aborted?
	if(!sceneInputFilename.isEmpty()) {
		// save selection as recent file
		settings.setValue("RecentInputFile", sceneInputFilename);
	}

	return sceneInputFilename;
}

void MainWindow::clearSelection(bool informUserIn) {
	// deselect elements
	foreach(ScenarioElement* element, selection)
		element->setSelected(false);

	selection.clear();

	// inform users
	if(informUserIn)
		emit selectionChanged();
}

void MainWindow::setSelection(ScenarioElement* elementIn) {
	clearSelection(false);
	selection.insert(elementIn);

	// select element
	elementIn->setSelected(true);

	// inform users
	emit selectionChanged();
}

void MainWindow::setSelection(const QSet<ScenarioElement*>& elementsIn) {
	clearSelection(false);
	selection = elementsIn;

	// select element
	foreach(ScenarioElement* element, selection)
		element->setSelected(true);

	// inform users
	emit selectionChanged();
}

const QSet<ScenarioElement*>& MainWindow::getSelection() const {
	return selection;
}

void MainWindow::addToSelection(ScenarioElement* elementIn) {
	selection.insert(elementIn);

	// select element
	elementIn->setSelected(true);

	// inform users
	emit selectionChanged();
}

bool MainWindow::removeFromSelection(ScenarioElement* elementIn) {
	bool found = selection.remove(elementIn);

	// deselect element
	elementIn->setSelected(false);

	// inform users, if selection really changed
	if(found)
		emit selectionChanged();

	return found;
}

void MainWindow::closeEvent(QCloseEvent* event) {
	// ask user whether he really wants to quit
	bool reallyQuit = verifyQuitting();
	if(reallyQuit == false) {
		event->ignore();
		return;
	}

	// quit
	SGDICOP.quit();
	event->accept();
}

bool MainWindow::verifyQuitting() {
	// popup if the window is minimized
	if(isMinimized())
		setWindowState(windowState() & ~Qt::WindowMinimized);

	QMessageBox::StandardButton buttonPressed = QMessageBox::question(this,
		tr("Quit?"),
		tr("Do you really want to quit this application?"),
		QMessageBox::Yes|QMessageBox::Cancel,
		QMessageBox::Cancel);

	return (buttonPressed == QMessageBox::Yes);
}

void MainWindow::about() {
	QMessageBox::about(
		this,
		tr("About Simulating Group Dynamics in Crowds of Pedestrians (SGDiCoP)"),
		tr("Simulating Group Dynamics in Crowds of Pedestrians (SGDiCoP) is a pedestrian simulation system "
			"with group dynamics in mind.
"
			"It is based on libpedsim, http://pedsim.silmaril.org/
"
			" Original Copyright: (c) 2003-2012 by Christian Gloor"
			" Additions: (c) 2013 by Sven Wehner (mail@svenwehner.de)"));
}

void MainWindow::createActions() {
	newAction = new QAction(tr("&New"), this);
	newAction->setShortcut(tr("Ctrl+N"));
	newAction->setStatusTip(tr("Create new scenario"));
	connect(newAction, SIGNAL(triggered()), this, SLOT(newScenario()));

	openAction = new QAction(tr("&Open"), this);
	openAction->setShortcut(tr("Ctrl+O"));
	openAction->setStatusTip(tr("Exit the application"));
	connect(openAction, SIGNAL(triggered()), this, SLOT(openScenario()));

	saveAction = new QAction(tr("&Save"), this);
	saveAction->setShortcut(tr("Ctrl+S"));
	saveAction->setStatusTip(tr("Exit the application"));
	connect(saveAction, SIGNAL(triggered()), this, SLOT(saveScenario()));

	exitAction = new QAction(tr("E&xit"), this);
	exitAction->setShortcut(tr("Ctrl+Q"));
	exitAction->setStatusTip(tr("Exit the application"));
	connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));

	aboutAction = new QAction(tr("&About"), this);
	aboutAction->setStatusTip(tr("Show the application's About box"));
	connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));

// 	zoominAction = new QAction(QIcon(":/images/zoomin.png"), tr("Zoom In"), this);
// 	zoominAction->setStatusTip(tr("Zoom In"));
// 	connect(zoominAction, SIGNAL(triggered()), this, SLOT(zoomin()));
//
// 	zoomoutAction = new QAction(QIcon(":/images/zoomout.png"), tr("Zoom Out"), this);
// 	zoomoutAction->setStatusTip(tr("Zoom Out"));
// 	connect(zoomoutAction, SIGNAL(triggered()), this, SLOT(zoomout()));
}

void MainWindow::createMenus() {
	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(newAction);
	fileMenu->addAction(openAction);
	fileMenu->addAction(saveAction);
	fileMenu->addSeparator();
	fileMenu->addAction(exitAction);

	viewMenu = menuBar()->addMenu(tr("&View"));
	viewMenu->addAction(uicontrol->toggleViewAction());
	// viewMenu->addAction(uilogging->toggleViewAction());
	viewMenu->addAction(uieditor->toggleViewAction());

	menuBar()->addSeparator();

	helpMenu = menuBar()->addMenu(tr("&Help"));
	helpMenu->addAction(aboutAction);
}

// void MainWindow::createToolBars() {
// 	//TODO: this isn't used
// // 	editToolBar = addToolBar(tr("Zoom"));
// // 	editToolBar->addAction(zoominAction);
// // 	editToolBar->addAction(zoomoutAction);
// }
//
//
// void MainWindow::createStatusBar() {
// 	//TODO: this isn't really /*necessary*/ → disabled
// 	statusBar()->showMessage(tr("Ready"));
// }

void MainWindow::loadIcons() {
	// File
	//  -> New
	QIcon newIcon = QIcon::fromTheme("document-new");
	if(!newIcon.isNull())
		newAction->setIcon(newIcon);
	//  -> Open
	QIcon openIcon = QIcon::fromTheme("document-open");
	if(!openIcon.isNull())
		openAction->setIcon(openIcon);
	//  -> Save Graph
	QIcon saveIcon = QIcon::fromTheme("document-save");
	if(!saveIcon.isNull())
		saveAction->setIcon(saveIcon);
	//  -> Quit
	QIcon quitIcon = QIcon::fromTheme("application-exit");
	if(!quitIcon.isNull())
		exitAction->setIcon(quitIcon);

	// Help
	//  -> About
	QIcon aboutIcon = QIcon::fromTheme("help-about");
	if(!aboutIcon.isNull())
		aboutAction->setIcon(aboutIcon);
}

void MainWindow::updateWindowTitle() {
	QString fileName = SGDICOP.scenarioFileName;
	QString title;
	if(fileName.isEmpty())
		title = tr("SGDiCoP - New Scenario");
	else
		title = tr("SGDiCoP - '%1'").arg(fileName);

	// apply new window title
	setWindowTitle(title);
}

void MainWindow::readSettings() {
	//TODO: default to maximize
	QPoint defaultPosition(0, 0);
	QSize defaultSize(1280, 800);

	// read settings
	QSettings settings;
	QPoint pos = settings.value("Window/Position", defaultPosition).toPoint();
	QSize size = settings.value("Window/Size", defaultSize).toSize();

	// apply settings
	resize(size);
	move(pos);
}

void MainWindow::writeSettings() {
	QSettings settings;
	settings.setValue("Window/Position", pos());
	settings.setValue("Window/Size", size());
}

void MainWindow::resizeEvent(QResizeEvent* event) {
	//write settings
	writeSettings();
}

bool MainWindow::newScenario() {
	// close previous scene
	return SGDICOP.newScene();
}

bool MainWindow::openScenario() {
	// open a file selector to choose the scene input file
	QString sceneInputFilename = showOpenScenarioDialog();

	// abort?
	if(sceneInputFilename.isEmpty())
		return false;

	// close previous scene
	SGDICOP.clearScene();

	// open scenario
	bool loadResult = SGDICOP.loadScene(sceneInputFilename);

	// inform the user
	if(loadResult)
		INFO_LOG("Successfully loaded scenario file '%1'", sceneInputFilename);
	else
		ERROR_LOG("Couldn't load scenario file '%1'", sceneInputFilename);

	return loadResult;
}

bool MainWindow::saveScenario() {
	QSettings settings;
	QString recentOutputFilename = settings.value("RecentOutputFile").toString();

	// if there hasn't been a previous output file name, use the current file name
	if(recentOutputFilename.isEmpty()) {
		QFileInfo fileInfo(SGDICOP.scenarioFileName);
		recentOutputFilename = fileInfo.canonicalFilePath();
	}

	// open a file selector to choose the graph output file
	QString sceneOutputFilename = QFileDialog::getSaveFileName(
		this,
		tr("Save scenario file"),
		recentOutputFilename,
		tr("Scenario Files (*.xml *.scenario);;All (*)"));

	// abort?
	if(sceneOutputFilename.isEmpty())
		return false;

	// save recent output file name
	settings.setValue("RecentOutputFile", sceneOutputFilename);

	// write scenario to file
	bool writeResult = SGDICOP.writeScene(sceneOutputFilename);

	return writeResult;
}

void MainWindow::enterEditMode() {
	// inform others
	// HACK: true=EditMode
	emit modeChanged(true);
}

void MainWindow::leaveEditMode() {
	// inform others
	// HACK: false=NormalMode
	emit modeChanged(false);
}

void MainWindow::onScenarioCreated() {
	updateWindowTitle();
}

void MainWindow::onScenarioLoaded() {
	updateWindowTitle();
}
<commit_msg>getting rid of nasty forced clicking<commit_after>// Simulating Group Dynamics in Crowds of Pedestrians (SGDiCoP)
// Author: Sven Wehner <mail@svenwehner.de>
//
// Forked from: PedSim's demo application (version 2.2).
// (http://pedsim.silmaril.org/)
// Copyright text:
// 		pedsim - A microscopic pedestrian simulation system.
// 		Copyright (c) 2003 - 2012 by Christian Gloor

// Includes
#include "mainwindow.h"
// → SGDiCoP
#include "sgdicop.h"
#include "controlwidget.h"
#include "loggingwidget.h"
#include "editorwidget.h"
#include "scenarioview.h"
#include "scenarioelement.h"
// → Qt
#include <QCloseEvent>
#include <QFileDialog>
#include <QGraphicsScene>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>

MainWindow::MainWindow() {
	// create graphical representation
	graphicsscene = new QGraphicsScene();
	QColor backgroundColor = settings.value("Colors/Background", Qt::black).value<QColor>();
	graphicsscene->setBackgroundBrush(backgroundColor);
	graphicsscene->setItemIndexMethod(QGraphicsScene::NoIndex);

	graphicsView = new ScenarioView(this);
	graphicsView->setScene(graphicsscene);
	graphicsView->show();
	setCentralWidget(graphicsView);

	// add control widget to the GUI
	uicontrol = new ControlWidget(this);
	addDockWidget(Qt::LeftDockWidgetArea, uicontrol);

	// add logging widget to the GUI
	// uilogging = new LoggingWidget(this);
	// addDockWidget(Qt::BottomDockWidgetArea, uilogging);

	// add editor widget to the GUI
	uieditor = new EditorWidget(this);
	addDockWidget(Qt::RightDockWidgetArea, uieditor);
	uieditor->setVisible(false);

	createActions();
	loadIcons();
	createMenus();

	readSettings();
    setFocusPolicy(Qt::StrongFocus);

	// connect signals
	connect(uicontrol, SIGNAL(zoomin()), graphicsView, SLOT(zoomin()));
	connect(uicontrol, SIGNAL(zoomout()), graphicsView, SLOT(zoomout()));
	connect(&SGDICOP, SIGNAL(scenarioCreated()), this, SLOT(onScenarioCreated()));
	connect(&SGDICOP, SIGNAL(scenarioLoaded()), this, SLOT(onScenarioLoaded()));
}

QPointF MainWindow::getDefaultPosition() const {
	if(graphicsView == NULL)
		return QPointF();
	else
		return graphicsView->centerOfView();
}

QString MainWindow::showOpenScenarioDialog() {
	// open a file selector to choose the scene input file
	QSettings settings;
	QString recentInputFilename = settings.value("RecentInputFile").toString();
	QString sceneInputFilename = QFileDialog::getOpenFileName(
		this,
		tr("Open scenario file"),
		recentInputFilename,
		tr("SGDiCoP Scenario Files (*.xml *.scenario);;All (*)"));

	// aborted?
	if(!sceneInputFilename.isEmpty()) {
		// save selection as recent file
		settings.setValue("RecentInputFile", sceneInputFilename);
	}

	return sceneInputFilename;
}

void MainWindow::clearSelection(bool informUserIn) {
	// deselect elements
	foreach(ScenarioElement* element, selection)
		element->setSelected(false);

	selection.clear();

	// inform users
	if(informUserIn)
		emit selectionChanged();
}

void MainWindow::setSelection(ScenarioElement* elementIn) {
	clearSelection(false);
	selection.insert(elementIn);

	// select element
	elementIn->setSelected(true);

	// inform users
	emit selectionChanged();
}

void MainWindow::setSelection(const QSet<ScenarioElement*>& elementsIn) {
	clearSelection(false);
	selection = elementsIn;

	// select element
	foreach(ScenarioElement* element, selection)
		element->setSelected(true);

	// inform users
	emit selectionChanged();
}

const QSet<ScenarioElement*>& MainWindow::getSelection() const {
	return selection;
}

void MainWindow::addToSelection(ScenarioElement* elementIn) {
	selection.insert(elementIn);

	// select element
	elementIn->setSelected(true);

	// inform users
	emit selectionChanged();
}

bool MainWindow::removeFromSelection(ScenarioElement* elementIn) {
	bool found = selection.remove(elementIn);

	// deselect element
	elementIn->setSelected(false);

	// inform users, if selection really changed
	if(found)
		emit selectionChanged();

	return found;
}

void MainWindow::closeEvent(QCloseEvent* event) {
	// ask user whether he really wants to quit
	bool reallyQuit = verifyQuitting();
	if(reallyQuit == false) {
		event->ignore();
		return;
	}

	// quit
	SGDICOP.quit();
	event->accept();
}

bool MainWindow::verifyQuitting() {
	// popup if the window is minimized
	if(isMinimized())
		setWindowState(windowState() & ~Qt::WindowMinimized);

	// QMessageBox::StandardButton buttonPressed = QMessageBox::question(this,
	// 	tr("Quit?"),
	// 	tr("Do you really want to quit this application?"),
	// 	QMessageBox::Yes|QMessageBox::Cancel,
	// 	QMessageBox::Cancel);

	// return (buttonPressed == QMessageBox::Yes);
	return true;
}

void MainWindow::about() {
	QMessageBox::about(
		this,
		tr("About Simulating Group Dynamics in Crowds of Pedestrians (SGDiCoP)"),
		tr("Simulating Group Dynamics in Crowds of Pedestrians (SGDiCoP) is a pedestrian simulation system "
			"with group dynamics in mind.
"
			"It is based on libpedsim, http://pedsim.silmaril.org/
"
			" Original Copyright: (c) 2003-2012 by Christian Gloor"
			" Additions: (c) 2013 by Sven Wehner (mail@svenwehner.de)"));
}

void MainWindow::createActions() {
	newAction = new QAction(tr("&New"), this);
	newAction->setShortcut(tr("Ctrl+N"));
	newAction->setStatusTip(tr("Create new scenario"));
	connect(newAction, SIGNAL(triggered()), this, SLOT(newScenario()));

	openAction = new QAction(tr("&Open"), this);
	openAction->setShortcut(tr("Ctrl+O"));
	openAction->setStatusTip(tr("Exit the application"));
	connect(openAction, SIGNAL(triggered()), this, SLOT(openScenario()));

	saveAction = new QAction(tr("&Save"), this);
	saveAction->setShortcut(tr("Ctrl+S"));
	saveAction->setStatusTip(tr("Exit the application"));
	connect(saveAction, SIGNAL(triggered()), this, SLOT(saveScenario()));

	exitAction = new QAction(tr("E&xit"), this);
	exitAction->setShortcut(tr("Ctrl+Q"));
	exitAction->setStatusTip(tr("Exit the application"));
	connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));

	aboutAction = new QAction(tr("&About"), this);
	aboutAction->setStatusTip(tr("Show the application's About box"));
	connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));

// 	zoominAction = new QAction(QIcon(":/images/zoomin.png"), tr("Zoom In"), this);
// 	zoominAction->setStatusTip(tr("Zoom In"));
// 	connect(zoominAction, SIGNAL(triggered()), this, SLOT(zoomin()));
//
// 	zoomoutAction = new QAction(QIcon(":/images/zoomout.png"), tr("Zoom Out"), this);
// 	zoomoutAction->setStatusTip(tr("Zoom Out"));
// 	connect(zoomoutAction, SIGNAL(triggered()), this, SLOT(zoomout()));
}

void MainWindow::createMenus() {
	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(newAction);
	fileMenu->addAction(openAction);
	fileMenu->addAction(saveAction);
	fileMenu->addSeparator();
	fileMenu->addAction(exitAction);

	viewMenu = menuBar()->addMenu(tr("&View"));
	viewMenu->addAction(uicontrol->toggleViewAction());
	// viewMenu->addAction(uilogging->toggleViewAction());
	viewMenu->addAction(uieditor->toggleViewAction());

	menuBar()->addSeparator();

	helpMenu = menuBar()->addMenu(tr("&Help"));
	helpMenu->addAction(aboutAction);
}

// void MainWindow::createToolBars() {
// 	//TODO: this isn't used
// // 	editToolBar = addToolBar(tr("Zoom"));
// // 	editToolBar->addAction(zoominAction);
// // 	editToolBar->addAction(zoomoutAction);
// }
//
//
// void MainWindow::createStatusBar() {
// 	//TODO: this isn't really /*necessary*/ → disabled
// 	statusBar()->showMessage(tr("Ready"));
// }

void MainWindow::loadIcons() {
	// File
	//  -> New
	QIcon newIcon = QIcon::fromTheme("document-new");
	if(!newIcon.isNull())
		newAction->setIcon(newIcon);
	//  -> Open
	QIcon openIcon = QIcon::fromTheme("document-open");
	if(!openIcon.isNull())
		openAction->setIcon(openIcon);
	//  -> Save Graph
	QIcon saveIcon = QIcon::fromTheme("document-save");
	if(!saveIcon.isNull())
		saveAction->setIcon(saveIcon);
	//  -> Quit
	QIcon quitIcon = QIcon::fromTheme("application-exit");
	if(!quitIcon.isNull())
		exitAction->setIcon(quitIcon);

	// Help
	//  -> About
	QIcon aboutIcon = QIcon::fromTheme("help-about");
	if(!aboutIcon.isNull())
		aboutAction->setIcon(aboutIcon);
}

void MainWindow::updateWindowTitle() {
	QString fileName = SGDICOP.scenarioFileName;
	QString title;
	if(fileName.isEmpty())
		title = tr("SGDiCoP - New Scenario");
	else
		title = tr("SGDiCoP - '%1'").arg(fileName);

	// apply new window title
	setWindowTitle(title);
}

void MainWindow::readSettings() {
	//TODO: default to maximize
	QPoint defaultPosition(0, 0);
	QSize defaultSize(1280, 800);

	// read settings
	QSettings settings;
	QPoint pos = settings.value("Window/Position", defaultPosition).toPoint();
	QSize size = settings.value("Window/Size", defaultSize).toSize();

	// apply settings
	resize(size);
	move(pos);
}

void MainWindow::writeSettings() {
	QSettings settings;
	settings.setValue("Window/Position", pos());
	settings.setValue("Window/Size", size());
}

void MainWindow::resizeEvent(QResizeEvent* event) {
	//write settings
	writeSettings();
}

bool MainWindow::newScenario() {
	// close previous scene
	return SGDICOP.newScene();
}

bool MainWindow::openScenario() {
	// open a file selector to choose the scene input file
	QString sceneInputFilename = showOpenScenarioDialog();

	// abort?
	if(sceneInputFilename.isEmpty())
		return false;

	// close previous scene
	SGDICOP.clearScene();

	// open scenario
	bool loadResult = SGDICOP.loadScene(sceneInputFilename);

	// inform the user
	if(loadResult)
		INFO_LOG("Successfully loaded scenario file '%1'", sceneInputFilename);
	else
		ERROR_LOG("Couldn't load scenario file '%1'", sceneInputFilename);

	return loadResult;
}

bool MainWindow::saveScenario() {
	QSettings settings;
	QString recentOutputFilename = settings.value("RecentOutputFile").toString();

	// if there hasn't been a previous output file name, use the current file name
	if(recentOutputFilename.isEmpty()) {
		QFileInfo fileInfo(SGDICOP.scenarioFileName);
		recentOutputFilename = fileInfo.canonicalFilePath();
	}

	// open a file selector to choose the graph output file
	QString sceneOutputFilename = QFileDialog::getSaveFileName(
		this,
		tr("Save scenario file"),
		recentOutputFilename,
		tr("Scenario Files (*.xml *.scenario);;All (*)"));

	// abort?
	if(sceneOutputFilename.isEmpty())
		return false;

	// save recent output file name
	settings.setValue("RecentOutputFile", sceneOutputFilename);

	// write scenario to file
	bool writeResult = SGDICOP.writeScene(sceneOutputFilename);

	return writeResult;
}

void MainWindow::enterEditMode() {
	// inform others
	// HACK: true=EditMode
	emit modeChanged(true);
}

void MainWindow::leaveEditMode() {
	// inform others
	// HACK: false=NormalMode
	emit modeChanged(false);
}

void MainWindow::onScenarioCreated() {
	updateWindowTitle();
}

void MainWindow::onScenarioLoaded() {
	updateWindowTitle();
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "config.h"

#include <model/qenvironement.h>
#include <gui/qenvironementeditor.h>
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    /*
    const bool loaded = QEnvironementInstance->loadEnvironementFromFile();
    if (!loaded) {
        qWarning() << "Error: we could not restore the last saved environement";
    }*/

    ui->setupUi(this);
    initUi();
    loadUi();
}

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

void MainWindow::initUi() {
    connect(ui->actionEnvironement, &QAction::triggered, [&](bool) {
        QEnvironementEditor editor;
        editor.exec();
    });

    connect(ui->actionOpen, &QAction::triggered, [&](bool) {
        const QString fileName = QFileDialog::getOpenFileName(this,
                tr("Open Environement File"), "", QString("Environement (*%1)").arg(ENVIRONEMENT_FORMAT));
        if (!fileName.isEmpty()) {
            if (!QEnvironementInstance->loadEnvironementFromFile(fileName)) {
                QMessageBox::information(this, tr("Unable to open file"), "The file is corrupted");
            }
        }
    });

    connect(ui->actionSave, &QAction::triggered, [&](bool) {
        QString fileName = QFileDialog::getSaveFileName(this,
                tr("Open Environement File"), "", QString("Environement (*%1)").arg(ENVIRONEMENT_FORMAT));

        if (!fileName.endsWith(ENVIRONEMENT_FORMAT))
            fileName += ENVIRONEMENT_FORMAT;

        if (!fileName.isEmpty()) {
            if (!QEnvironementInstance->saveEnvironementInFile(fileName)) {
                QMessageBox::information(this, tr("Unable to open file"), "The file is corrupted");
            }
        }
    });
}

void MainWindow::loadUi() {
    QSettings settings;
    settings.beginGroup("UI");
    restoreGeometry(settings.value("geometry", saveGeometry()).toByteArray());
    restoreState(settings.value("state", saveState()).toByteArray());
    ui->verticalSplitter->restoreState(
                settings.value("vSplitter", ui->verticalSplitter->saveState())
                .toByteArray());
    ui->horizontalSplitter->restoreState(
                settings.value("hSplitter", ui->horizontalSplitter->saveState())
                .toByteArray());
    settings.endGroup();
}

void MainWindow::saveUi() {
    QSettings settings;
    settings.beginGroup("UI");
    settings.setValue("geometry", saveGeometry());
    settings.setValue("state", saveState());
    settings.setValue("vSplitter", ui->verticalSplitter->saveState());
    settings.setValue("hSplitter", ui->horizontalSplitter->saveState());
    settings.endGroup();
    settings.sync();
}

void MainWindow::closeEvent(QCloseEvent *event) {
    if (!QEnvironementInstance->saveEnvironementInFile()) {
        qWarning() << "Error: could not save the current data model";
    }
    saveUi();
    QMainWindow::closeEvent(event);
}

<commit_msg>Invalidate beacons list when executing environementeditor<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "config.h"

#include <model/qenvironement.h>
#include <gui/qenvironementeditor.h>
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    /*
    const bool loaded = QEnvironementInstance->loadEnvironementFromFile();
    if (!loaded) {
        qWarning() << "Error: we could not restore the last saved environement";
    }*/

    ui->setupUi(this);
    initUi();
    loadUi();
}

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

void MainWindow::initUi() {
    connect(ui->actionEnvironement, &QAction::triggered, [&](bool) {
        QEnvironementEditor editor;
        editor.exec();
        ui->beaconsPanel->invalidate();
    });

    connect(ui->actionOpen, &QAction::triggered, [&](bool) {
        const QString fileName = QFileDialog::getOpenFileName(this,
                tr("Open Environement File"), "", QString("Environement (*%1)").arg(ENVIRONEMENT_FORMAT));
        if (!fileName.isEmpty()) {
            if (!QEnvironementInstance->loadEnvironementFromFile(fileName)) {
                QMessageBox::information(this, tr("Unable to open file"), "The file is corrupted");
            }
        }
    });

    connect(ui->actionSave, &QAction::triggered, [&](bool) {
        QString fileName = QFileDialog::getSaveFileName(this,
                tr("Open Environement File"), "", QString("Environement (*%1)").arg(ENVIRONEMENT_FORMAT));

        if (!fileName.endsWith(ENVIRONEMENT_FORMAT))
            fileName += ENVIRONEMENT_FORMAT;

        if (!fileName.isEmpty()) {
            if (!QEnvironementInstance->saveEnvironementInFile(fileName)) {
                QMessageBox::information(this, tr("Unable to open file"), "The file is corrupted");
            }
        }
    });
}

void MainWindow::loadUi() {
    QSettings settings;
    settings.beginGroup("UI");
    restoreGeometry(settings.value("geometry", saveGeometry()).toByteArray());
    restoreState(settings.value("state", saveState()).toByteArray());
    ui->verticalSplitter->restoreState(
                settings.value("vSplitter", ui->verticalSplitter->saveState())
                .toByteArray());
    ui->horizontalSplitter->restoreState(
                settings.value("hSplitter", ui->horizontalSplitter->saveState())
                .toByteArray());
    settings.endGroup();
}

void MainWindow::saveUi() {
    QSettings settings;
    settings.beginGroup("UI");
    settings.setValue("geometry", saveGeometry());
    settings.setValue("state", saveState());
    settings.setValue("vSplitter", ui->verticalSplitter->saveState());
    settings.setValue("hSplitter", ui->horizontalSplitter->saveState());
    settings.endGroup();
    settings.sync();
}

void MainWindow::closeEvent(QCloseEvent *event) {
    if (!QEnvironementInstance->saveEnvironementInFile()) {
        qWarning() << "Error: could not save the current data model";
    }
    saveUi();
    QMainWindow::closeEvent(event);
}

<|endoftext|>


<commit_before>#include <getopt.h>
#include "dlib/bam_util.h"

int usage(char **argv, int retcode=EXIT_FAILURE) {
    fprintf(stderr, "MASKRIPPER version %s.\n"
                    "Usage: maskripper <opts> in.bam out.bam\n"
                    "Flags:\n-m: Minimum trimmed read length. Default: 0.\n"
                    "-l: output compression level. Default: 6.\n"
                    "-S: output in sam format.\n"
                    "-s: perform single-end analyisis. This option results in imbalanced pairs on paired-end data.\n"
                    "Use - for stdin or stdout.\n", MASKRIPPER_VERSION);
    return retcode;
}
struct opts_t {
    uint8_t *data;
    uint32_t l_data:16;
    uint32_t m_data:16;
    uint32_t n_cigar:8;
    uint32_t min_trimmed_len:8;
    ~opts_t() {if(data) free(data);}
    void resize(uint32_t new_min) {
        if(new_min > m_data) {
            m_data = new_min;
            kroundup32(m_data);
            data = (uint8_t *)realloc(data, m_data * sizeof(uint8_t));
        }
    }
};

static int trim_ns(bam1_t *b, void *data) {
    // Currently passes all reads to keep balanced pairs. TODO: rewrite for pairs of reads and filter if both fail.
    opts_t *op((opts_t *)data);
    assert(bam_aux_get(b, "PV"));
    std::vector<uint8_t> aux(bam_get_aux(b), bam_get_aux(b) + bam_get_l_aux(b));
    int tmp;
    uint8_t *const seq(bam_get_seq(b));
    uint32_t *const cigar(bam_get_cigar(b));
    op->n_cigar = b->core.n_cigar;
    op->resize(b->l_data); // Make sure it's big enough to hold everything.
    memcpy(op->data, b->data, b->core.l_qname);

    // Get #Ns at the beginning
    for(tmp = 0; bam_seqi(seq, tmp) == dlib::htseq::HTS_N; ++tmp);
    const int n_start(tmp);

    if(tmp == b->core.l_qseq - 1) // all bases are N -- garbage read
         return 1; // Currently outputting to avoid

    // Get #Ns at the end
    for(tmp = b->core.l_qseq - 1; bam_seqi(seq, tmp) == dlib::htseq::HTS_N; --tmp);
    const int n_end(b->core.l_qseq - 1 - tmp);

    // Get new length for read
    const int final_len(b->core.l_qseq - n_end - n_start);
    if(final_len < op->min_trimmed_len) // Too short.
        return 1;

    if(n_end) {
        if((tmp = bam_cigar_oplen(cigar[b->core.n_cigar - 1]) - n_end) == 0) {
            LOG_DEBUG("Entire cigar operation is the softclip. Decrease the number of new cigar operations.\n");
            --op->n_cigar;
        } else {
            LOG_DEBUG("Updating second cigar operation in-place.\n");
            cigar[b->core.n_cigar - 1] = bam_cigar_gen(tmp, BAM_CSOFT_CLIP);
        }
    }

    // Get new n_cigar.
    if((tmp = bam_cigar_oplen(*cigar) - n_start) == 0) {
        --op->n_cigar;
        memcpy(op->data + b->core.l_qname, cigar + 1, op->n_cigar << 2); // << 2 for 4 bit per cigar op
    } else {
        if(n_start) *cigar = bam_cigar_gen(tmp, BAM_CSOFT_CLIP);
        memcpy(op->data + b->core.l_qname, cigar, op->n_cigar << 2);
    }
    uint8_t *opseq(op->data + b->core.l_qname + (op->n_cigar << 2)); // Pointer to the seq region of new data field.
    for(tmp = 0; tmp < final_len >> 1; ++tmp) {
        opseq[tmp] = (bam_seqi(seq, ((tmp << 1) + n_start)) << 4) | (bam_seqi(seq, (tmp << 1) + n_start + 1));
        assert(bam_seqi(opseq, tmp * 2) == bam_seqi(seq, (2 * tmp + n_start)));
        assert(bam_seqi(opseq, tmp * 2 + 1) == bam_seqi(seq, (2 * tmp + n_start + 1)));
    }
#if 0
    char tmpbuf[300];
    for(tmp = 0; tmp < final_len; ++tmp) {
        tmpbuf[tmp] = seq_nt16_str[bam_seqi(opseq, tmp)];
    }
    tmpbuf[tmp] = '\0';
    assert(strcmp(tmpbuf, "ANNCNNNGNNNNTNNNNCNNGGNNNNNNNNNCNNNNCNNNNNNNNAAAANNTNNNAAAAAAAAAAGAGAGAGGGAGAGAGACTATACACAGGCACCACCACATTTGGCTAATTTTT") == 0);
#endif

    // Copy in qual and all of aux.
    tmp = bam_get_l_aux(b);
    memcpy(opseq + ((final_len + 1) >> 1), bam_get_qual(b) + n_start, final_len + tmp);
    // Switch data strings
    std::swap(op->data, b->data);
    b->core.n_cigar = op->n_cigar;
    //b->l_data = b->core.l_qname + (op->n_cigar << 2) + ((final_len + 1) >> 1) + final_len + tmp;
    b->core.l_qseq = final_len;
    memcpy(bam_get_aux(b), aux.data(), aux.size());
    b->l_data = (bam_get_aux(b) - b->data) + aux.size();
    //trim_array_tags(b, n_start, n_end, final_len);
    if(n_end)
        bam_aux_append(b, "NE", 'i', sizeof(int), (uint8_t *)&n_end);
    if(n_start)
        bam_aux_append(b, "NS", 'i', sizeof(int), (uint8_t *)&n_start);
    const uint32_t *pvar = (uint32_t *)dlib::array_tag(b, "PV");
    tmp = b->core.flag & BAM_FREVERSE ? n_end: n_start;
    std::vector<uint32_t>pvals(pvar + tmp, pvar + final_len + tmp);
    const uint32_t *fvar = (uint32_t *)dlib::array_tag(b, "FA");
    std::vector<uint32_t>fvals(fvar + tmp, fvar + final_len + tmp);
    bam_aux_del(b, bam_aux_get(b, "PV"));
    bam_aux_del(b, bam_aux_get(b, "FA"));
    dlib::bam_aux_array_append(b, "PV", 'I', sizeof(uint32_t), final_len, (uint8_t *)pvals.data());
    dlib::bam_aux_array_append(b, "FA", 'I', sizeof(uint32_t), final_len, (uint8_t *)fvals.data());
    return 0;
}

static int pe_trim_ns(bam1_t *b1, bam1_t *b2, void *aux)
{
    return trim_ns(b1, aux) && trim_ns(b2, aux);
}

int main(int argc, char *argv[]) {
    if(argc < 3)
        return usage(argv);

    if(strcmp(argv[1], "--help") == 0)
        return usage(argv, EXIT_SUCCESS);

    int c;
    int is_se{0};
    char out_mode[4] = "wb";
    opts_t opts{0};
    while((c = getopt(argc, argv, "m:l:h?sS")) > -1) {
        switch(c) {
        case 'm': opts.min_trimmed_len = (uint32_t)atoi(optarg); break;
        case 'l': out_mode[2] = atoi(optarg) % 10 + '0'; break;
        case 's': is_se = 1; break;
        case 'S': sprintf(out_mode, "w"); break;
        case 'h': case '?': return usage(argv, EXIT_SUCCESS);
        }
    }
    if(argc - 2 != optind)
        LOG_EXIT("Required: precisely two positional arguments (in bam, out bam).\n");

    LOG_DEBUG("ZOUNDS\n");
    // Actually this function. You can't really apply a null function....
    dlib::BamHandle inHandle(argv[optind]);
    dlib::BamHandle outHandle(argv[optind + 1], inHandle.header, out_mode);
    if(is_se) {
        dlib::abstract_single_iter(inHandle.fp, inHandle.header, outHandle.fp,
                                   &trim_ns, (void *)&opts);
    } else {
        dlib::abstract_pair_iter(inHandle.fp, inHandle.header, outHandle.fp, &pe_trim_ns, (void *)&opts);
    }
    return EXIT_SUCCESS;
}
<commit_msg>Fix an 'edge case'.<commit_after>#include <getopt.h>
#include "dlib/bam_util.h"

int usage(char **argv, int retcode=EXIT_FAILURE) {
    fprintf(stderr, "MASKRIPPER version %s.\n"
                    "Usage: maskripper <opts> in.bam out.bam\n"
                    "Flags:\n-m: Minimum trimmed read length. Default: 0.\n"
                    "-l: output compression level. Default: 6.\n"
                    "-S: output in sam format.\n"
                    "-s: perform single-end analyisis. This option results in imbalanced pairs on paired-end data.\n"
                    "Use - for stdin or stdout.\n", MASKRIPPER_VERSION);
    return retcode;
}
struct opts_t {
    uint8_t *data;
    uint32_t l_data:16;
    uint32_t m_data:16;
    uint32_t n_cigar:8;
    uint32_t min_trimmed_len:8;
    ~opts_t() {if(data) free(data);}
    void resize(uint32_t new_min) {
        if(new_min > m_data) {
            m_data = new_min;
            kroundup32(m_data);
            data = (uint8_t *)realloc(data, m_data * sizeof(uint8_t));
        }
    }
};

static int trim_ns(bam1_t *b, void *data) {
    opts_t *op((opts_t *)data);
    assert(bam_aux_get(b, "PV"));
    std::vector<uint8_t> aux(bam_get_aux(b), bam_get_aux(b) + bam_get_l_aux(b));
    int tmp;
    uint8_t *const seq(bam_get_seq(b));
    uint32_t *const cigar(bam_get_cigar(b));
    op->n_cigar = b->core.n_cigar;
    op->resize(b->l_data); // Make sure it's big enough to hold everything.
    memcpy(op->data, b->data, b->core.l_qname);

    // Get #Ns at the beginning
    for(tmp = 0; bam_seqi(seq, tmp) == dlib::htseq::HTS_N; ++tmp);
    const int n_start(tmp);

    if(tmp == b->core.l_qseq - 1) // all bases are N -- garbage read
         return 1; // Currently outputting to avoid

    // Get #Ns at the end
    for(tmp = b->core.l_qseq - 1; bam_seqi(seq, tmp) == dlib::htseq::HTS_N; --tmp);
    const int n_end(b->core.l_qseq - 1 - tmp);

    // Get new length for read
    const int final_len(b->core.l_qseq - n_end - n_start);
    if(final_len < op->min_trimmed_len) // Too short.
        return 1;

    if(n_end) {
        if((tmp = bam_cigar_oplen(cigar[b->core.n_cigar - 1]) - n_end) == 0) {
            LOG_DEBUG("Entire cigar operation is the softclip. Decrease the number of new cigar operations.\n");
            --op->n_cigar;
        } else {
            LOG_DEBUG("Updating second cigar operation in-place.\n");
            cigar[b->core.n_cigar - 1] = bam_cigar_gen(tmp, BAM_CSOFT_CLIP);
        }
    }

    // Get new n_cigar.
    if((tmp = bam_cigar_oplen(*cigar) - n_start) == 0) {
        --op->n_cigar;
        memcpy(op->data + b->core.l_qname, cigar + 1, op->n_cigar << 2); // << 2 for 4 bit per cigar op
    } else {
        if(n_start) *cigar = bam_cigar_gen(tmp, BAM_CSOFT_CLIP);
        memcpy(op->data + b->core.l_qname, cigar, op->n_cigar << 2);
    }
    uint8_t *opseq(op->data + b->core.l_qname + (op->n_cigar << 2)); // Pointer to the seq region of new data field.
    for(tmp = 0; tmp < final_len >> 1; ++tmp) {
        opseq[tmp] = (bam_seqi(seq, ((tmp << 1) + n_start)) << 4) | (bam_seqi(seq, (tmp << 1) + n_start + 1));
        assert(bam_seqi(opseq, tmp * 2) == bam_seqi(seq, (2 * tmp + n_start)));
        assert(bam_seqi(opseq, tmp * 2 + 1) == bam_seqi(seq, (2 * tmp + n_start + 1)));
    }
    if(final_len & 1)
        opseq[tmp] = (bam_seqi(seq, ((tmp << 1) + n_start)) << 4);
#if 0
    char tmpbuf[300];
    for(tmp = 0; tmp < final_len; ++tmp) {
        tmpbuf[tmp] = seq_nt16_str[bam_seqi(opseq, tmp)];
    }
    tmpbuf[tmp] = '\0';
    assert(strcmp(tmpbuf, "ANNCNNNGNNNNTNNNNCNNGGNNNNNNNNNCNNNNCNNNNNNNNAAAANNTNNNAAAAAAAAAAGAGAGAGGGAGAGAGACTATACACAGGCACCACCACATTTGGCTAATTTTT") == 0);
#endif

    // Copy in qual and all of aux.
    tmp = bam_get_l_aux(b);
    memcpy(opseq + ((final_len + 1) >> 1), bam_get_qual(b) + n_start, final_len + tmp);
    // Switch data strings
    std::swap(op->data, b->data);
    b->core.n_cigar = op->n_cigar;
    //b->l_data = b->core.l_qname + (op->n_cigar << 2) + ((final_len + 1) >> 1) + final_len + tmp;
    b->core.l_qseq = final_len;
    memcpy(bam_get_aux(b), aux.data(), aux.size());
    b->l_data = (bam_get_aux(b) - b->data) + aux.size();
    //trim_array_tags(b, n_start, n_end, final_len);
    if(n_end)
        bam_aux_append(b, "NE", 'i', sizeof(int), (uint8_t *)&n_end);
    if(n_start)
        bam_aux_append(b, "NS", 'i', sizeof(int), (uint8_t *)&n_start);
    const uint32_t *pvar = (uint32_t *)dlib::array_tag(b, "PV");
    tmp = b->core.flag & BAM_FREVERSE ? n_end: n_start;
    std::vector<uint32_t>pvals(pvar + tmp, pvar + final_len + tmp);
    const uint32_t *fvar = (uint32_t *)dlib::array_tag(b, "FA");
    std::vector<uint32_t>fvals(fvar + tmp, fvar + final_len + tmp);
    bam_aux_del(b, bam_aux_get(b, "PV"));
    bam_aux_del(b, bam_aux_get(b, "FA"));
    dlib::bam_aux_array_append(b, "PV", 'I', sizeof(uint32_t), final_len, (uint8_t *)pvals.data());
    dlib::bam_aux_array_append(b, "FA", 'I', sizeof(uint32_t), final_len, (uint8_t *)fvals.data());
    return 0;
}

static int pe_trim_ns(bam1_t *b1, bam1_t *b2, void *aux)
{
    return trim_ns(b1, aux) && trim_ns(b2, aux);
}

int main(int argc, char *argv[]) {
    if(argc < 3)
        return usage(argv);

    if(strcmp(argv[1], "--help") == 0)
        return usage(argv, EXIT_SUCCESS);

    int c;
    int is_se{0};
    char out_mode[4] = "wb";
    opts_t opts{0};
    while((c = getopt(argc, argv, "m:l:h?sS")) > -1) {
        switch(c) {
        case 'm': opts.min_trimmed_len = (uint32_t)atoi(optarg); break;
        case 'l': out_mode[2] = atoi(optarg) % 10 + '0'; break;
        case 's': is_se = 1; break;
        case 'S': sprintf(out_mode, "w"); break;
        case 'h': case '?': return usage(argv, EXIT_SUCCESS);
        }
    }
    if(argc - 2 != optind)
        LOG_EXIT("Required: precisely two positional arguments (in bam, out bam).\n");

    LOG_DEBUG("ZOUNDS\n");
    // Actually this function. You can't really apply a null function....
    dlib::BamHandle inHandle(argv[optind]);
    dlib::BamHandle outHandle(argv[optind + 1], inHandle.header, out_mode);
    if(is_se) {
        dlib::abstract_single_iter(inHandle.fp, inHandle.header, outHandle.fp,
                                   &trim_ns, (void *)&opts);
    } else {
        dlib::abstract_pair_iter(inHandle.fp, inHandle.header, outHandle.fp, &pe_trim_ns, (void *)&opts);
    }
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, Christian Menard
 * Copyright (c) 2015, Nils Asmussen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the FreeBSD Project.
 */

#ifndef __MEM_DTU_DTU_HH__
#define __MEM_DTU_DTU_HH__

#include "mem/dtu/base.hh"
#include "mem/dtu/regfile.hh"
#include "mem/dtu/noc_addr.hh"
#include "mem/dtu/pt_unit.hh"
#include "params/Dtu.hh"

class MessageUnit;
class MemoryUnit;
class XferUnit;

class Dtu : public BaseDtu
{
  public:

    enum MemoryFlags : uint8_t
    {
        READ                = (1 << 0),
        WRITE               = (1 << 1),
    };

    enum MessageFlags : uint8_t
    {
        REPLY_FLAG          = (1 << 0),
        GRANT_CREDITS_FLAG  = (1 << 1),
        REPLY_ENABLED       = (1 << 2),
        PAGEFAULT           = (1 << 3),
    };

    struct MessageHeader
    {
         // if bit 0 is set its a reply, if bit 1 is set we grant credits
        uint8_t flags;
        uint8_t senderCoreId;
        uint8_t senderEpId;
         // for a normal message this is the reply epId
        // for a reply this is the enpoint that receives credits
        uint8_t replyEpId;
        uint16_t length;

        // both should be large enough for pointers.
        uint64_t label;
        uint64_t replyLabel;
    } M5_ATTR_PACKED;

    enum class NocPacketType
    {
        MESSAGE,
        READ_REQ,
        WRITE_REQ,
        CACHE_MEM_REQ_FUNC,
        CACHE_MEM_REQ,
    };

    enum class TransferType
    {
        // we are reading stuff out of our local memory and send it
        LOCAL_READ,
        // we received the read resp. from somebody and write it to local mem
        LOCAL_WRITE,
        // we received something and write it to our local memory
        REMOTE_WRITE,
        // we should send something from our local memory to somebody else
        REMOTE_READ
    };

    enum class MemReqType
    {
        TRANSFER,
        HEADER,
        TRANSLATION
    };

    struct MemSenderState : public Packet::SenderState
    {
        Addr data;
        MasterID mid;
        MemReqType type;
    };

    struct NocSenderState : public Packet::SenderState
    {
        NocPacketType packetType;
    };

    struct InitSenderState : public Packet::SenderState
    {
    };

    enum class CommandOpcode
    {
        IDLE = 0,
        SEND = 1,
        REPLY = 2,
        READ = 3,
        WRITE = 4,
        INC_READ_PTR = 5,
        WAKEUP_CORE = 6,
    };

    struct Command
    {
        CommandOpcode opcode;
        unsigned epId;
    };

  public:

    static constexpr unsigned numCmdOpcodeBits = 3;

  public:

    Dtu(DtuParams* p);

    ~Dtu();

    RegFile &regs() { return regFile; }

    PacketPtr generateRequest(Addr addr, Addr size, MemCmd cmd);
    void freeRequest(PacketPtr pkt);

    void wakeupCore();

    void updateSuspendablePin();

    void forwardRequestToRegFile(PacketPtr pkt, bool isCpuRequest);

    void sendFunctionalMemRequest(PacketPtr pkt)
    {
        dcacheMasterPort.sendFunctional(pkt);
    }

    void scheduleFinishOp(Cycles delay)
    {
        schedule(finishCommandEvent, clockEdge(delay));
    }

    void scheduleCommand(Cycles delay)
    {
        schedule(executeCommandEvent, clockEdge(delay));
    }

    void sendMemRequest(PacketPtr pkt,
                        Addr data,
                        MemReqType type,
                        Cycles delay);

    void sendNocRequest(NocPacketType type,
                        PacketPtr pkt,
                        Cycles delay,
                        bool functional = false);

    void startTransfer(TransferType type,
                       NocAddr targetAddr,
                       Addr sourceAddr,
                       Addr size,
                       PacketPtr pkt = NULL,
                       MessageHeader* header = NULL,
                       Cycles delay = Cycles(0),
                       uint flags = 0);

    void startTranslate(Addr virt,
                        DtuTlb::Flag access,
                        PtUnit::Translation *trans);

    void handlePFResp(PacketPtr pkt);

    void printPacket(PacketPtr pkt) const;

  private:

    Command getCommand();

    void executeCommand();

    void finishCommand();

    void completeNocRequest(PacketPtr pkt) override;

    void completeMemRequest(PacketPtr pkt) override;

    void handleNocRequest(PacketPtr pkt) override;

    void handleCpuRequest(PacketPtr pkt) override;

    bool handleCacheMemRequest(PacketPtr pkt, bool functional) override;

    bool translate(PtUnit::Translation *trans,
                   PacketPtr pkt,
                   bool icache,
                   bool functional) override;

  private:

    const MasterID masterId;

    System *system;

    RegFile regFile;

    MessageUnit *msgUnit;

    MemoryUnit *memUnit;

    XferUnit *xferUnit;

    PtUnit *ptUnit;

    EventWrapper<Dtu, &Dtu::executeCommand> executeCommandEvent;

    EventWrapper<Dtu, &Dtu::finishCommand> finishCommandEvent;

    bool cmdInProgress;

  public:

    DtuTlb *tlb;

    unsigned memPe;
    Addr memOffset;
    Addr memSize;

    const bool atomicMode;

    const unsigned numEndpoints;

    const Addr maxNocPacketSize;

    const unsigned numCmdEpidBits;

    const size_t blockSize;

    const size_t bufCount;
    const size_t bufSize;

    const Cycles registerAccessLatency;

    const Cycles commandToNocRequestLatency;
    const Cycles startMsgTransferDelay;

    const Cycles transferToMemRequestLatency;
    const Cycles transferToNocLatency;
    const Cycles nocToTransferLatency;
};

#endif // __MEM_DTU_DTU_HH__
<commit_msg>DTU: only schedule the finished event, if a cmd was in progress.<commit_after>/*
 * Copyright (c) 2015, Christian Menard
 * Copyright (c) 2015, Nils Asmussen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the FreeBSD Project.
 */

#ifndef __MEM_DTU_DTU_HH__
#define __MEM_DTU_DTU_HH__

#include "mem/dtu/base.hh"
#include "mem/dtu/regfile.hh"
#include "mem/dtu/noc_addr.hh"
#include "mem/dtu/pt_unit.hh"
#include "params/Dtu.hh"

class MessageUnit;
class MemoryUnit;
class XferUnit;

class Dtu : public BaseDtu
{
  public:

    enum MemoryFlags : uint8_t
    {
        READ                = (1 << 0),
        WRITE               = (1 << 1),
    };

    enum MessageFlags : uint8_t
    {
        REPLY_FLAG          = (1 << 0),
        GRANT_CREDITS_FLAG  = (1 << 1),
        REPLY_ENABLED       = (1 << 2),
        PAGEFAULT           = (1 << 3),
    };

    struct MessageHeader
    {
         // if bit 0 is set its a reply, if bit 1 is set we grant credits
        uint8_t flags;
        uint8_t senderCoreId;
        uint8_t senderEpId;
         // for a normal message this is the reply epId
        // for a reply this is the enpoint that receives credits
        uint8_t replyEpId;
        uint16_t length;

        // both should be large enough for pointers.
        uint64_t label;
        uint64_t replyLabel;
    } M5_ATTR_PACKED;

    enum class NocPacketType
    {
        MESSAGE,
        READ_REQ,
        WRITE_REQ,
        CACHE_MEM_REQ_FUNC,
        CACHE_MEM_REQ,
    };

    enum class TransferType
    {
        // we are reading stuff out of our local memory and send it
        LOCAL_READ,
        // we received the read resp. from somebody and write it to local mem
        LOCAL_WRITE,
        // we received something and write it to our local memory
        REMOTE_WRITE,
        // we should send something from our local memory to somebody else
        REMOTE_READ
    };

    enum class MemReqType
    {
        TRANSFER,
        HEADER,
        TRANSLATION
    };

    struct MemSenderState : public Packet::SenderState
    {
        Addr data;
        MasterID mid;
        MemReqType type;
    };

    struct NocSenderState : public Packet::SenderState
    {
        NocPacketType packetType;
    };

    struct InitSenderState : public Packet::SenderState
    {
    };

    enum class CommandOpcode
    {
        IDLE = 0,
        SEND = 1,
        REPLY = 2,
        READ = 3,
        WRITE = 4,
        INC_READ_PTR = 5,
        WAKEUP_CORE = 6,
    };

    struct Command
    {
        CommandOpcode opcode;
        unsigned epId;
    };

  public:

    static constexpr unsigned numCmdOpcodeBits = 3;

  public:

    Dtu(DtuParams* p);

    ~Dtu();

    RegFile &regs() { return regFile; }

    PacketPtr generateRequest(Addr addr, Addr size, MemCmd cmd);
    void freeRequest(PacketPtr pkt);

    void wakeupCore();

    void updateSuspendablePin();

    void forwardRequestToRegFile(PacketPtr pkt, bool isCpuRequest);

    void sendFunctionalMemRequest(PacketPtr pkt)
    {
        dcacheMasterPort.sendFunctional(pkt);
    }

    void scheduleFinishOp(Cycles delay)
    {
        if (cmdInProgress)
            schedule(finishCommandEvent, clockEdge(delay));
    }

    void scheduleCommand(Cycles delay)
    {
        schedule(executeCommandEvent, clockEdge(delay));
    }

    void sendMemRequest(PacketPtr pkt,
                        Addr data,
                        MemReqType type,
                        Cycles delay);

    void sendNocRequest(NocPacketType type,
                        PacketPtr pkt,
                        Cycles delay,
                        bool functional = false);

    void startTransfer(TransferType type,
                       NocAddr targetAddr,
                       Addr sourceAddr,
                       Addr size,
                       PacketPtr pkt = NULL,
                       MessageHeader* header = NULL,
                       Cycles delay = Cycles(0),
                       uint flags = 0);

    void startTranslate(Addr virt,
                        DtuTlb::Flag access,
                        PtUnit::Translation *trans);

    void handlePFResp(PacketPtr pkt);

    void printPacket(PacketPtr pkt) const;

  private:

    Command getCommand();

    void executeCommand();

    void finishCommand();

    void completeNocRequest(PacketPtr pkt) override;

    void completeMemRequest(PacketPtr pkt) override;

    void handleNocRequest(PacketPtr pkt) override;

    void handleCpuRequest(PacketPtr pkt) override;

    bool handleCacheMemRequest(PacketPtr pkt, bool functional) override;

    bool translate(PtUnit::Translation *trans,
                   PacketPtr pkt,
                   bool icache,
                   bool functional) override;

  private:

    const MasterID masterId;

    System *system;

    RegFile regFile;

    MessageUnit *msgUnit;

    MemoryUnit *memUnit;

    XferUnit *xferUnit;

    PtUnit *ptUnit;

    EventWrapper<Dtu, &Dtu::executeCommand> executeCommandEvent;

    EventWrapper<Dtu, &Dtu::finishCommand> finishCommandEvent;

    bool cmdInProgress;

  public:

    DtuTlb *tlb;

    unsigned memPe;
    Addr memOffset;
    Addr memSize;

    const bool atomicMode;

    const unsigned numEndpoints;

    const Addr maxNocPacketSize;

    const unsigned numCmdEpidBits;

    const size_t blockSize;

    const size_t bufCount;
    const size_t bufSize;

    const Cycles registerAccessLatency;

    const Cycles commandToNocRequestLatency;
    const Cycles startMsgTransferDelay;

    const Cycles transferToMemRequestLatency;
    const Cycles transferToNocLatency;
    const Cycles nocToTransferLatency;
};

#endif // __MEM_DTU_DTU_HH__
<|endoftext|>


<commit_before>/**
 ** \file object/UVar.cc
 ** \brief Creation of the URBI object UVar.
 */

# include <object/uvar.hh>
# include <object/global.hh>
# include <object/list.hh>
# include <runner/call.hh>
# include <runner/runner.hh>

namespace object
{
  static inline void callNotify(runner::Runner& r, rObject self,
                                libport::Symbol notifyList)
  {
    rList l = self->slot_get(notifyList).unsafe_cast<List>();
    objects_type args;
    foreach(rObject& co, l->value_get())
      r.apply(self, co, SYMBOL(NOTIFY), args);
  }
  static rObject
  update_bounce(runner::Runner& r, objects_type args)
  {
    //called with self slotname slotval
    check_arg_count(args.size() - 1, 2);
    libport::intrusive_ptr<UVar> rvar
    =args.front()->slot_get(libport::Symbol(args[1]->as<String>()->value_get()))
      .unsafe_cast<UVar>();
    rvar->update_(r, args[2]);
    return void_class;
  }
  UVar::UVar()
  : Primitive( boost::bind(&UVar::accessor, this, _1))
  , looping_(false)
  , inChange_(false)
  , inAccess_(false)
  {
    protos_set(new List);
    proto_add(proto ? proto : Primitive::proto);
  }

  UVar::UVar(libport::intrusive_ptr<UVar>)
  : Primitive( boost::bind(&UVar::accessor, this, _1))
  , looping_(false)
  , inChange_(false)
  , inAccess_(false)
  {
    protos_set(new List);
    proto_add(proto ? proto : Primitive::proto);
  }
  void
  UVar::loopCheck(runner::Runner& r)
  {
    if (!looping_
        && !slot_get(SYMBOL(change))->as<List>()->value_get().empty()
        && !slot_get(SYMBOL(access))->as<List>()->value_get().empty() )
    {
      looping_ = true;
      while (true)
      {
        accessor(r);
        objects_type args;
        rObject period = urbi_call(r, global_class, SYMBOL(getPeriod), args);
        r.yield_until(libport::utime() +
          static_cast<libport::utime_t>(period->as<Float>()->value_get()
                                       * 1000000.0));
      }
    }
  }
  rObject
  UVar::update_(runner::Runner& r, rObject val)
  {
    slot_update(r, SYMBOL(val), val);
    if (is_true(slot_get(SYMBOL(owned))))
      callNotify(r, rObject(this), SYMBOL(changeOwned));
     else if (!inChange_)
     {
       inChange_ = true;
       callNotify(r, rObject(this), SYMBOL(change));
       inChange_ = false;
     }
   return val;
  }
  rObject
  UVar::accessor(runner::Runner& r)
  {
    if (this == proto.get())
      return this;
    if (!inAccess_)
    {
      inAccess_ = true;
      callNotify(r, rObject(this), SYMBOL(access));
      inAccess_ = false;
    }
    if (!is_true(slot_get(SYMBOL(owned))))
      return slot_get(SYMBOL(val));
    else
      return slot_get(SYMBOL(valsensor));
  }
  rObject
  UVar::writeOwned(runner::Runner& r, rObject newval)
  {
    slot_update(r, SYMBOL(valsensor), newval);
    callNotify(r, rObject(this), SYMBOL(change));
    return newval;
  }
  void
  UVar::initialize(CxxObject::Binder<UVar>& bind)
  {
    bind(SYMBOL(writeOwned), &UVar::writeOwned);
    bind(SYMBOL(update_), &UVar::update_);
    bind(SYMBOL(loopCheck), &UVar::loopCheck);
    bind(SYMBOL(accessor), &UVar::accessor);
    proto->slot_set(SYMBOL(update_bounce), new Primitive(&update_bounce));
  }
  rObject
  UVar::proto_make()
  {
    return new UVar();
  }
  URBI_CXX_OBJECT_REGISTER(UVar);
}
<commit_msg>Denottalify.<commit_after>/**
 ** \file object/UVar.cc
 ** \brief Creation of the URBI object UVar.
 */

# include <object/uvar.hh>
# include <object/global.hh>
# include <object/list.hh>
# include <runner/call.hh>
# include <runner/runner.hh>

namespace object
{
  static inline void callNotify(runner::Runner& r, rObject self,
                                libport::Symbol notifyList)
  {
    rList l = self->slot_get(notifyList).unsafe_cast<List>();
    objects_type args;
    foreach(rObject& co, l->value_get())
      r.apply(self, co, SYMBOL(NOTIFY), args);
  }

  static rObject
  update_bounce(runner::Runner& r, objects_type args)
  {
    //called with self slotname slotval
    check_arg_count(args.size() - 1, 2);
    libport::intrusive_ptr<UVar> rvar =
      args.front()
      ->slot_get(libport::Symbol(args[1]->as<String>()->value_get()))
      .unsafe_cast<UVar>();
    rvar->update_(r, args[2]);
    return void_class;
  }

  UVar::UVar()
    : Primitive( boost::bind(&UVar::accessor, this, _1))
    , looping_(false)
    , inChange_(false)
    , inAccess_(false)
  {
    protos_set(new List);
    proto_add(proto ? proto : Primitive::proto);
  }

  UVar::UVar(libport::intrusive_ptr<UVar>)
    : Primitive( boost::bind(&UVar::accessor, this, _1))
    , looping_(false)
    , inChange_(false)
    , inAccess_(false)
  {
    protos_set(new List);
    proto_add(proto ? proto : Primitive::proto);
  }

  void
  UVar::loopCheck(runner::Runner& r)
  {
    if (!looping_
        && !slot_get(SYMBOL(change))->as<List>()->value_get().empty()
        && !slot_get(SYMBOL(access))->as<List>()->value_get().empty())
    {
      looping_ = true;
      while (true)
      {
        accessor(r);
        objects_type args;
        rObject period = urbi_call(r, global_class, SYMBOL(getPeriod), args);
        r.yield_until(libport::utime() +
          static_cast<libport::utime_t>(period->as<Float>()->value_get()
                                       * 1000000.0));
      }
    }
  }

  rObject
  UVar::update_(runner::Runner& r, rObject val)
  {
    slot_update(r, SYMBOL(val), val);
    if (is_true(slot_get(SYMBOL(owned))))
      callNotify(r, rObject(this), SYMBOL(changeOwned));
     else if (!inChange_)
     {
       inChange_ = true;
       callNotify(r, rObject(this), SYMBOL(change));
       inChange_ = false;
     }
   return val;
  }

  rObject
  UVar::accessor(runner::Runner& r)
  {
    if (this == proto.get())
      return this;
    if (!inAccess_)
    {
      inAccess_ = true;
      callNotify(r, rObject(this), SYMBOL(access));
      inAccess_ = false;
    }
    if (!is_true(slot_get(SYMBOL(owned))))
      return slot_get(SYMBOL(val));
    else
      return slot_get(SYMBOL(valsensor));
  }

  rObject
  UVar::writeOwned(runner::Runner& r, rObject newval)
  {
    slot_update(r, SYMBOL(valsensor), newval);
    callNotify(r, rObject(this), SYMBOL(change));
    return newval;
  }

  void
  UVar::initialize(CxxObject::Binder<UVar>& bind)
  {
    bind(SYMBOL(writeOwned), &UVar::writeOwned);
    bind(SYMBOL(update_), &UVar::update_);
    bind(SYMBOL(loopCheck), &UVar::loopCheck);
    bind(SYMBOL(accessor), &UVar::accessor);
    proto->slot_set(SYMBOL(update_bounce), new Primitive(&update_bounce));
  }

  rObject
  UVar::proto_make()
  {
    return new UVar();
  }

  URBI_CXX_OBJECT_REGISTER(UVar);
}
<|endoftext|>


<commit_before>#include "include/object.h"

#include <cstring>

<commit_msg>No need for old object file<commit_after><|endoftext|>


<commit_before>#include "oniguruma.h"
#include "onig-result.h"
#include "unicode-utils.h"

OnigResult::OnigResult(OnigRegion* region, const string& searchString) : searchString_(searchString) {
  region_ = region;
}

OnigResult::~OnigResult() {
  onig_region_free(region_, 1);
}

int OnigResult::Count() {
  return region_->num_regs;
}

int OnigResult::LocationAt(int index) {
  int bytes = *(region_->beg + index);
  return UnicodeUtils::characters_in_bytes(searchString_.data(), bytes);
}

int OnigResult::LengthAt(int index) {
  int bytes = *(region_->end + index) - *(region_->beg + index);
  const char *search = searchString_.data() + *(region_->beg + index);
  return UnicodeUtils::characters_in_bytes(search, bytes);
}
<commit_msg>Only convert to characters when bytes > 0<commit_after>#include "oniguruma.h"
#include "onig-result.h"
#include "unicode-utils.h"

OnigResult::OnigResult(OnigRegion* region, const string& searchString) : searchString_(searchString) {
  region_ = region;
}

OnigResult::~OnigResult() {
  onig_region_free(region_, 1);
}

int OnigResult::Count() {
  return region_->num_regs;
}

int OnigResult::LocationAt(int index) {
  int bytes = *(region_->beg + index);
  if (bytes > 0)
    return UnicodeUtils::characters_in_bytes(searchString_.data(), bytes);
  else
    return 0;
}

int OnigResult::LengthAt(int index) {
  int bytes = *(region_->end + index) - *(region_->beg + index);
  if (bytes > 0) {
    const char *search = searchString_.data() + *(region_->beg + index);
    return UnicodeUtils::characters_in_bytes(search, bytes);
  } else
    return 0;
}
<|endoftext|>