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

#include "adapters/joystickadapter.h"
#include "adapters/mapadapter.h"
#include "adapters/gpsadapter.h"
#include "adapters/joystickadapter.h"
#include "adapters/cameraadapter.h"
#include "adapters/imuadapter.h"

#include <hardware/sensors/gps/simulatedgps.h>
#include <hardware/sensors/gps/nmeacompatiblegps.h>
#include <hardware/sensors/camera/StereoPlayback.h>
#include <hardware/sensors/camera/Bumblebee2.h>
#include <hardware/sensors/IMU/Ardupilot.h>
#include <hardware/sensors/lidar/SimulatedLidar.h>
#include <hardware/sensors/lidar/lms200.h>

#include <QMdiSubWindow>
#include <QTextEdit>
#include "adapters/joystickadapter.h"
#include "adapters/lidaradapter.h"
#include "adapters/positiontrackeradapter.h"
#include <QDebug>
#include <QFileDialog>

#include <iostream>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    configTreeModel.populateModel();
    ui->configTree->setModel(configTreeModel.model());
    mdiArea = ui->mainDisplayArea;
    connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),
            this, SLOT(updateMenus()));
    windowMapper = new QSignalMapper(this);
    connect(windowMapper, SIGNAL(mapped(QWidget*)),
            this, SLOT(setActiveSubWindow(QWidget*)));

    checkIcon = QIcon(QString(":/images/Checkmark"));
    xIcon = QIcon(QString(":/images/Close"));

    connect(ui->hardwareStatusList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openHardwareView(QModelIndex)));

    Logger::setSatusBar(ui->statusBar);

    setupMenus();
    updateWindowMenu();

    _motorController = new MotorEncoderDriver2013;
    ui->hardwareStatusList->addItem("Motor Board");

    _joystick = new Joystick;
    ui->joystickButton->setEnabled(_joystick->isOpen());
    ui->hardwareStatusList->addItem("Joystick");

    ui->hardwareStatusList->addItem("Map");

    _joystickDriver = new JoystickDriver(&_joystick->onNewData);

//    _lidar = new SimulatedLidar();
    _lidar = new LMS200();
    ui->hardwareStatusList->addItem("LIDAR");
    ui->actionLMS_200->setChecked(true);

    //_stereoSource = new StereoPlayback((QDir::currentPath() + "/../../test_data/video/CompCourse_left0.mpeg").toStdString(),(QDir::currentPath() + "/../../test_data/video/CompCourse_right0.mpeg").toStdString(),20,"",false);
    _stereoSource = new Bumblebee2("/home/robojackets/igvc/software/src/hardware/sensors/camera/calib/out_camera_data.xml");
    ui->hardwareStatusList->addItem("Camera");

//    _GPS = new SimulatedGPS("");
    _GPS = new NMEACompatibleGPS("/dev/ttyGPS", 19200);
    ui->actionOutback_A321->setChecked(true);
    ui->hardwareStatusList->addItem("GPS");

    _IMU = new Ardupilot();
    ui->hardwareStatusList->addItem("IMU");

    _posTracker = new BasicPositionTracker;
    _GPS->onNewData += &_posTracker->LonNewGPS;
    _IMU->onNewData += &_posTracker->LonNewIMU;
    ui->hardwareStatusList->addItem("Position Tracker");

    _mapper = new MapBuilder(_lidar, _posTracker);

    updateHardwareStatusIcons();

    isRunning = false;
    isPaused = false;
    ui->stopButton->setVisible(false);
}

void MainWindow::setupMenus()
{
    connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(close()));
    connect(ui->menuWindow, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));
    connect(ui->actionClose_2, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow()));
    connect(ui->actionClose_All, SIGNAL(triggered()), mdiArea, SLOT(closeAllSubWindows()));
    connect(ui->actionCascade, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows()));
    connect(ui->actionTile, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows()));
}

MainWindow::~MainWindow()
{
    _GPS->onNewData -= &(_posTracker->LonNewGPS);
    _IMU->onNewData -= &(_posTracker->LonNewIMU);
    delete ui;
    delete _joystick;
    delete _posTracker;
    delete _GPS;
    delete _IMU;
    delete _stereoSource;
    delete _lidar;
}

void MainWindow::openHardwareView(QModelIndex index)
{
    QString labelText = ui->hardwareStatusList->item(index.row())->text();
    if(MDIWindow* window = findWindowWithTitle(labelText))
    {
        if(!window->isVisible())
            window->show();
    }
    else
    {
        using namespace std;
        MDIWindow *newWindow = new MDIWindow;
        newWindow->setWindowTitle(labelText);
        newWindow->setLayout(new QGridLayout);

        QWidget* adapter;

        if(labelText == "Joystick")
        {
            adapter = new JoystickAdapter(_joystick);
        }
        else if(labelText == "LIDAR")
        {
            adapter = new LidarAdapter(_lidar);
	}
        else if(labelText == "Map")
        {
            adapter = new MapAdapter(_mapper, _posTracker);
        }
        else if(labelText == "GPS")
        {
            adapter = new GPSAdapter(_GPS);
        }
        else if(labelText == "Camera")
        {
            adapter = new CameraAdapter(_stereoSource);
        }
        else if(labelText == "IMU")
        {
            adapter = new IMUAdapter(_IMU);
        }
        else if(labelText == "Position Tracker")
        {
            adapter = new PositionTrackerAdapter(_posTracker);
        }
        else
        {
            adapter = new QWidget();
        }

        newWindow->layout()->addWidget(adapter);

        mdiArea->addSubWindow(newWindow);
        newWindow->show();
    }

    updateWindowMenu();
}

void MainWindow::on_actionFullscreen_triggered()
{
    if(ui->actionFullscreen->isChecked())
        this->showFullScreen();
    else
        this->showNormal();
}

void MainWindow::updateMenus()
{
    bool hasMdiChild = (activeMdiChild() != 0);

    ui->actionTile->setEnabled(hasMdiChild);
    ui->actionCascade->setEnabled(hasMdiChild);
    ui->actionClose_2->setEnabled(hasMdiChild);
    ui->actionClose_All->setEnabled(hasMdiChild);
}

void MainWindow::updateWindowMenu()
{
    for(int i = ui->menuWindow->actions().size()-1; i > 5; i--)
    {
        ui->menuWindow->removeAction(ui->menuWindow->actions().at(i));
    }

    QList<QMdiSubWindow *> windows = mdiArea->subWindowList();

    for (int i = 0; i < windows.size(); ++i) {
        MDIWindow *child = qobject_cast<MDIWindow *>(windows.at(i)->widget());

        QString text = windows.at(i)->windowTitle();
        QAction *action  = ui->menuWindow->addAction(text);
        action->setCheckable(true);
        action ->setChecked(child == activeMdiChild());
        connect(action, SIGNAL(triggered()), windowMapper, SLOT(map()));
        windowMapper->setMapping(action, windows.at(i));
    }
}

MDIWindow* MainWindow::activeMdiChild()
{
    if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow())
        return qobject_cast<MDIWindow *>(activeSubWindow->widget());
    return 0;
}

void MainWindow::setActiveSubWindow(QWidget *window)
{
    if (!window)
        return;
    mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
}

MDIWindow* MainWindow::findWindowWithTitle(QString title)
{
    foreach(QMdiSubWindow *window, mdiArea->subWindowList())
    {
        MDIWindow *mdiChild = qobject_cast<MDIWindow*>(window->widget());
        if(mdiChild && mdiChild->windowTitle() == title)
            return mdiChild;
    }
    return 0;
}

void MainWindow::on_joystickButton_toggled(bool checked)
{
    this->setFocus();
    if(checked)
    {
        _motorController->setControlEvent(&_joystickDriver->controlEvent);
    }
    else
    {
        //TODO : Set motor controller to listen to intelligence events
        _motorController->setControlEvent(0);
    }
}

void MainWindow::on_playButton_clicked()
{
    if(isRunning)
    {
        if(isPaused)
        {
            ui->playButton->setIcon(QIcon(":/images/Pause"));
        }
        else
        {
            ui->playButton->setIcon(QIcon(":/images/Play"));
        }
        isPaused = !isPaused;
    }
    else
    {
        ui->playButton->setIcon(QIcon(":/images/Pause"));
        ui->stopButton->setVisible(true);
        isRunning = true;
    }
}

void MainWindow::on_stopButton_clicked()
{
    if(isRunning)
    {
        ui->playButton->setIcon(QIcon(":/images/Play"));
        ui->stopButton->setVisible(false);
        isRunning = false;
        isPaused = false;
    }
}

void MainWindow::on_actionStatus_Bar_toggled(bool checked)
{
    if(checked)
    {
        ui->statusBar->show();
        Logger::setSatusBar(ui->statusBar);
    }
    else
    {
        ui->statusBar->hide();
        Logger::setSatusBar(0);
    }
}

void MainWindow::on_saveConfigButton_clicked()
{
    ConfigManager::Instance().save();
}

void MainWindow::on_loadConfigButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Configuration File"), "", tr("XML Files(*.xml)"));
    ConfigManager::Instance().load(fileName.toStdString());
}

void MainWindow::on_actionHemisphere_A100_triggered()
{
    ui->actionSimulatedGPS->setChecked(false);
    ui->actionHemisphere_A100->setChecked(true);
    ui->actionOutback_A321->setChecked(false);
    _GPS = new NMEACompatibleGPS("/dev/ttyGPS", 4800);
    _GPS->onNewData += &(_posTracker->LonNewGPS);
    updateHardwareStatusIcons();
}

void MainWindow::on_actionSimulatedGPS_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Simulated GPS Data File"), "", tr("Text Files(*.txt)"));
    if(fileName.length() > 0)
    {
        ui->actionSimulatedGPS->setChecked(true);
        ui->actionHemisphere_A100->setChecked(false);
        ui->actionOutback_A321->setChecked(false);
        _GPS = new SimulatedGPS(fileName.toStdString());
        _GPS->onNewData += &(_posTracker->LonNewGPS);
        updateHardwareStatusIcons();
    }
}

void MainWindow::updateHardwareStatusIcons()
{
    ui->hardwareStatusList->findItems("GPS", Qt::MatchExactly).at(0)->setIcon(_GPS->isOpen() ? checkIcon : xIcon);
    ui->hardwareStatusList->findItems("Joystick", Qt::MatchExactly).at(0)->setIcon(_joystick->isOpen() ? checkIcon : xIcon);
    ui->hardwareStatusList->findItems("Motor Board", Qt::MatchExactly).at(0)->setIcon(_motorController->isOpen() ? checkIcon : xIcon);
    ui->hardwareStatusList->findItems("IMU", Qt::MatchExactly).at(0)->setIcon(_IMU->isWorking() ? checkIcon : xIcon);
    ui->hardwareStatusList->findItems("LIDAR", Qt::MatchExactly).at(0)->setIcon(_lidar->IsWorking() ? checkIcon : xIcon);
}

void MainWindow::on_actionClearLogs_triggered()
{
    Logger::Clear();
}

void MainWindow::closeEvent(QCloseEvent *e)
{
    mdiArea->closeAllSubWindows();
    std::cout << mdiArea->subWindowList().size() << std::endl;
    QMainWindow::closeEvent(e);
}

void MainWindow::on_actionOutback_A321_triggered()
{
    ui->actionSimulatedGPS->setChecked(false);
    ui->actionHemisphere_A100->setChecked(false);
    ui->actionOutback_A321->setChecked(true);
    _GPS = new NMEACompatibleGPS("/dev/ttyGPS", 19200);
    _GPS->onNewData += &(_posTracker->LonNewGPS);
    updateHardwareStatusIcons();
}

void MainWindow::on_actionSimulatedLidar_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Simulated Lidar Data File"), "", tr("Text Files(*.txt)"));
    if(fileName.length() > 0)
    {
        ui->actionLMS_200->setChecked(false);
        ui->actionSimulatedLidar->setChecked(true);
        SimulatedLidar *newDevice = new SimulatedLidar;
        newDevice->loadFile(fileName.toStdString().c_str());
        _mapper->ChangeLidar(newDevice);
        _mapper->Clear();
        _lidar = newDevice;
        updateHardwareStatusIcons();
    }
}

void MainWindow::on_actionLMS_200_triggered()
{
    ui->actionLMS_200->setChecked(true);
    ui->actionSimulatedLidar->setChecked(false);
    _lidar = new LMS200;
    _mapper->ChangeLidar(_lidar);
    _mapper->Clear();
    updateHardwareStatusIcons();
}
<commit_msg>Removes unnecessary printout on close.<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "adapters/joystickadapter.h"
#include "adapters/mapadapter.h"
#include "adapters/gpsadapter.h"
#include "adapters/joystickadapter.h"
#include "adapters/cameraadapter.h"
#include "adapters/imuadapter.h"

#include <hardware/sensors/gps/simulatedgps.h>
#include <hardware/sensors/gps/nmeacompatiblegps.h>
#include <hardware/sensors/camera/StereoPlayback.h>
#include <hardware/sensors/camera/Bumblebee2.h>
#include <hardware/sensors/IMU/Ardupilot.h>
#include <hardware/sensors/lidar/SimulatedLidar.h>
#include <hardware/sensors/lidar/lms200.h>

#include <QMdiSubWindow>
#include <QTextEdit>
#include "adapters/joystickadapter.h"
#include "adapters/lidaradapter.h"
#include "adapters/positiontrackeradapter.h"
#include <QDebug>
#include <QFileDialog>

#include <iostream>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    configTreeModel.populateModel();
    ui->configTree->setModel(configTreeModel.model());
    mdiArea = ui->mainDisplayArea;
    connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),
            this, SLOT(updateMenus()));
    windowMapper = new QSignalMapper(this);
    connect(windowMapper, SIGNAL(mapped(QWidget*)),
            this, SLOT(setActiveSubWindow(QWidget*)));

    checkIcon = QIcon(QString(":/images/Checkmark"));
    xIcon = QIcon(QString(":/images/Close"));

    connect(ui->hardwareStatusList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openHardwareView(QModelIndex)));

    Logger::setSatusBar(ui->statusBar);

    setupMenus();
    updateWindowMenu();

    _motorController = new MotorEncoderDriver2013;
    ui->hardwareStatusList->addItem("Motor Board");

    _joystick = new Joystick;
    ui->joystickButton->setEnabled(_joystick->isOpen());
    ui->hardwareStatusList->addItem("Joystick");

    ui->hardwareStatusList->addItem("Map");

    _joystickDriver = new JoystickDriver(&_joystick->onNewData);

//    _lidar = new SimulatedLidar();
    _lidar = new LMS200();
    ui->hardwareStatusList->addItem("LIDAR");
    ui->actionLMS_200->setChecked(true);

    //_stereoSource = new StereoPlayback((QDir::currentPath() + "/../../test_data/video/CompCourse_left0.mpeg").toStdString(),(QDir::currentPath() + "/../../test_data/video/CompCourse_right0.mpeg").toStdString(),20,"",false);
    _stereoSource = new Bumblebee2("/home/robojackets/igvc/software/src/hardware/sensors/camera/calib/out_camera_data.xml");
    ui->hardwareStatusList->addItem("Camera");

//    _GPS = new SimulatedGPS("");
    _GPS = new NMEACompatibleGPS("/dev/ttyGPS", 19200);
    ui->actionOutback_A321->setChecked(true);
    ui->hardwareStatusList->addItem("GPS");

    _IMU = new Ardupilot();
    ui->hardwareStatusList->addItem("IMU");

    _posTracker = new BasicPositionTracker;
    _GPS->onNewData += &_posTracker->LonNewGPS;
    _IMU->onNewData += &_posTracker->LonNewIMU;
    ui->hardwareStatusList->addItem("Position Tracker");

    _mapper = new MapBuilder(_lidar, _posTracker);

    updateHardwareStatusIcons();

    isRunning = false;
    isPaused = false;
    ui->stopButton->setVisible(false);
}

void MainWindow::setupMenus()
{
    connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(close()));
    connect(ui->menuWindow, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));
    connect(ui->actionClose_2, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow()));
    connect(ui->actionClose_All, SIGNAL(triggered()), mdiArea, SLOT(closeAllSubWindows()));
    connect(ui->actionCascade, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows()));
    connect(ui->actionTile, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows()));
}

MainWindow::~MainWindow()
{
    _GPS->onNewData -= &(_posTracker->LonNewGPS);
    _IMU->onNewData -= &(_posTracker->LonNewIMU);
    delete ui;
    delete _joystick;
    delete _posTracker;
    delete _GPS;
    delete _IMU;
    delete _stereoSource;
    delete _lidar;
}

void MainWindow::openHardwareView(QModelIndex index)
{
    QString labelText = ui->hardwareStatusList->item(index.row())->text();
    if(MDIWindow* window = findWindowWithTitle(labelText))
    {
        if(!window->isVisible())
            window->show();
    }
    else
    {
        using namespace std;
        MDIWindow *newWindow = new MDIWindow;
        newWindow->setWindowTitle(labelText);
        newWindow->setLayout(new QGridLayout);

        QWidget* adapter;

        if(labelText == "Joystick")
        {
            adapter = new JoystickAdapter(_joystick);
        }
        else if(labelText == "LIDAR")
        {
            adapter = new LidarAdapter(_lidar);
	}
        else if(labelText == "Map")
        {
            adapter = new MapAdapter(_mapper, _posTracker);
        }
        else if(labelText == "GPS")
        {
            adapter = new GPSAdapter(_GPS);
        }
        else if(labelText == "Camera")
        {
            adapter = new CameraAdapter(_stereoSource);
        }
        else if(labelText == "IMU")
        {
            adapter = new IMUAdapter(_IMU);
        }
        else if(labelText == "Position Tracker")
        {
            adapter = new PositionTrackerAdapter(_posTracker);
        }
        else
        {
            adapter = new QWidget();
        }

        newWindow->layout()->addWidget(adapter);

        mdiArea->addSubWindow(newWindow);
        newWindow->show();
    }

    updateWindowMenu();
}

void MainWindow::on_actionFullscreen_triggered()
{
    if(ui->actionFullscreen->isChecked())
        this->showFullScreen();
    else
        this->showNormal();
}

void MainWindow::updateMenus()
{
    bool hasMdiChild = (activeMdiChild() != 0);

    ui->actionTile->setEnabled(hasMdiChild);
    ui->actionCascade->setEnabled(hasMdiChild);
    ui->actionClose_2->setEnabled(hasMdiChild);
    ui->actionClose_All->setEnabled(hasMdiChild);
}

void MainWindow::updateWindowMenu()
{
    for(int i = ui->menuWindow->actions().size()-1; i > 5; i--)
    {
        ui->menuWindow->removeAction(ui->menuWindow->actions().at(i));
    }

    QList<QMdiSubWindow *> windows = mdiArea->subWindowList();

    for (int i = 0; i < windows.size(); ++i) {
        MDIWindow *child = qobject_cast<MDIWindow *>(windows.at(i)->widget());

        QString text = windows.at(i)->windowTitle();
        QAction *action  = ui->menuWindow->addAction(text);
        action->setCheckable(true);
        action ->setChecked(child == activeMdiChild());
        connect(action, SIGNAL(triggered()), windowMapper, SLOT(map()));
        windowMapper->setMapping(action, windows.at(i));
    }
}

MDIWindow* MainWindow::activeMdiChild()
{
    if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow())
        return qobject_cast<MDIWindow *>(activeSubWindow->widget());
    return 0;
}

void MainWindow::setActiveSubWindow(QWidget *window)
{
    if (!window)
        return;
    mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
}

MDIWindow* MainWindow::findWindowWithTitle(QString title)
{
    foreach(QMdiSubWindow *window, mdiArea->subWindowList())
    {
        MDIWindow *mdiChild = qobject_cast<MDIWindow*>(window->widget());
        if(mdiChild && mdiChild->windowTitle() == title)
            return mdiChild;
    }
    return 0;
}

void MainWindow::on_joystickButton_toggled(bool checked)
{
    this->setFocus();
    if(checked)
    {
        _motorController->setControlEvent(&_joystickDriver->controlEvent);
    }
    else
    {
        //TODO : Set motor controller to listen to intelligence events
        _motorController->setControlEvent(0);
    }
}

void MainWindow::on_playButton_clicked()
{
    if(isRunning)
    {
        if(isPaused)
        {
            ui->playButton->setIcon(QIcon(":/images/Pause"));
        }
        else
        {
            ui->playButton->setIcon(QIcon(":/images/Play"));
        }
        isPaused = !isPaused;
    }
    else
    {
        ui->playButton->setIcon(QIcon(":/images/Pause"));
        ui->stopButton->setVisible(true);
        isRunning = true;
    }
}

void MainWindow::on_stopButton_clicked()
{
    if(isRunning)
    {
        ui->playButton->setIcon(QIcon(":/images/Play"));
        ui->stopButton->setVisible(false);
        isRunning = false;
        isPaused = false;
    }
}

void MainWindow::on_actionStatus_Bar_toggled(bool checked)
{
    if(checked)
    {
        ui->statusBar->show();
        Logger::setSatusBar(ui->statusBar);
    }
    else
    {
        ui->statusBar->hide();
        Logger::setSatusBar(0);
    }
}

void MainWindow::on_saveConfigButton_clicked()
{
    ConfigManager::Instance().save();
}

void MainWindow::on_loadConfigButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Configuration File"), "", tr("XML Files(*.xml)"));
    ConfigManager::Instance().load(fileName.toStdString());
}

void MainWindow::on_actionHemisphere_A100_triggered()
{
    ui->actionSimulatedGPS->setChecked(false);
    ui->actionHemisphere_A100->setChecked(true);
    ui->actionOutback_A321->setChecked(false);
    _GPS = new NMEACompatibleGPS("/dev/ttyGPS", 4800);
    _GPS->onNewData += &(_posTracker->LonNewGPS);
    updateHardwareStatusIcons();
}

void MainWindow::on_actionSimulatedGPS_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Simulated GPS Data File"), "", tr("Text Files(*.txt)"));
    if(fileName.length() > 0)
    {
        ui->actionSimulatedGPS->setChecked(true);
        ui->actionHemisphere_A100->setChecked(false);
        ui->actionOutback_A321->setChecked(false);
        _GPS = new SimulatedGPS(fileName.toStdString());
        _GPS->onNewData += &(_posTracker->LonNewGPS);
        updateHardwareStatusIcons();
    }
}

void MainWindow::updateHardwareStatusIcons()
{
    ui->hardwareStatusList->findItems("GPS", Qt::MatchExactly).at(0)->setIcon(_GPS->isOpen() ? checkIcon : xIcon);
    ui->hardwareStatusList->findItems("Joystick", Qt::MatchExactly).at(0)->setIcon(_joystick->isOpen() ? checkIcon : xIcon);
    ui->hardwareStatusList->findItems("Motor Board", Qt::MatchExactly).at(0)->setIcon(_motorController->isOpen() ? checkIcon : xIcon);
    ui->hardwareStatusList->findItems("IMU", Qt::MatchExactly).at(0)->setIcon(_IMU->isWorking() ? checkIcon : xIcon);
    ui->hardwareStatusList->findItems("LIDAR", Qt::MatchExactly).at(0)->setIcon(_lidar->IsWorking() ? checkIcon : xIcon);
}

void MainWindow::on_actionClearLogs_triggered()
{
    Logger::Clear();
}

void MainWindow::closeEvent(QCloseEvent *e)
{
    mdiArea->closeAllSubWindows();
    QMainWindow::closeEvent(e);
}

void MainWindow::on_actionOutback_A321_triggered()
{
    ui->actionSimulatedGPS->setChecked(false);
    ui->actionHemisphere_A100->setChecked(false);
    ui->actionOutback_A321->setChecked(true);
    _GPS = new NMEACompatibleGPS("/dev/ttyGPS", 19200);
    _GPS->onNewData += &(_posTracker->LonNewGPS);
    updateHardwareStatusIcons();
}

void MainWindow::on_actionSimulatedLidar_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Simulated Lidar Data File"), "", tr("Text Files(*.txt)"));
    if(fileName.length() > 0)
    {
        ui->actionLMS_200->setChecked(false);
        ui->actionSimulatedLidar->setChecked(true);
        SimulatedLidar *newDevice = new SimulatedLidar;
        newDevice->loadFile(fileName.toStdString().c_str());
        _mapper->ChangeLidar(newDevice);
        _mapper->Clear();
        _lidar = newDevice;
        updateHardwareStatusIcons();
    }
}

void MainWindow::on_actionLMS_200_triggered()
{
    ui->actionLMS_200->setChecked(true);
    ui->actionSimulatedLidar->setChecked(false);
    _lidar = new LMS200;
    _mapper->ChangeLidar(_lidar);
    _mapper->Clear();
    updateHardwareStatusIcons();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#ifndef UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_SERVER_HPP_INCLUDED
#define UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_SERVER_HPP_INCLUDED

#include <uavcan/build_config.hpp>
#include <uavcan/node/subscriber.hpp>
#include <uavcan/node/publisher.hpp>
#include <uavcan/node/timer.hpp>
#include <uavcan/util/method_binder.hpp>
#include <uavcan/util/map.hpp>
// Types used by the server
#include <uavcan/protocol/dynamic_node_id/server/AppendEntries.hpp>
#include <uavcan/protocol/dynamic_node_id/server/RequestVote.hpp>
#include <uavcan/protocol/dynamic_node_id/server/Entry.hpp>
#include <uavcan/protocol/dynamic_node_id/server/Discovery.hpp>
#include <uavcan/protocol/dynamic_node_id/Allocation.hpp>
#include <uavcan/protocol/GetNodeInfo.hpp>
#include <uavcan/protocol/NodeStatus.hpp>

namespace uavcan
{
/**
 *
 */
class DynamicNodeIDAllocationServer
{
    /*
     * Public type definitions
     */
public:
    /**
     * This interface is used by the server to read and write stable storage.
     * The storage is represented as a key-value container, where keys and values are ASCII strings up to 32
     * characters long, not including the termination byte. Fixed block size allows for absolutely straightforward
     * and efficient implementation of storage backends, e.g. based on text files.
     */
    class IStorageBackend
    {
    public:
        /**
         * Maximum length of keys and values. One pair takes twice as much space.
         */
        enum { MaxStringLength = 32 };

        /**
         * It is guaranteed that the server will never require more than this number of key/value pairs.
         * Total storage space needed is (MaxKeyValuePairs * MaxStringLength * 2), not including storage overhead.
         */
        enum { MaxKeyValuePairs = 400 };

        /**
         * This type is used to exchange data chunks with the backend.
         * It doesn't use any dynamic memory; please refer to the Array<> class for details.
         */
        typedef Array<IntegerSpec<8, SignednessUnsigned, CastModeTruncate>, ArrayModeDynamic, MaxStringLength> String;

        /**
         * Read one value from the storage.
         * If such key does not exist, or if read failed, an empty string will be returned.
         * This method should not block for more than 50 ms.
         */
        virtual String get(const String& key) const = 0;

        /**
         * Create or update value for the given key.
         * This method should not block for more than 50 ms.
         * Failures will be ignored.
         */
        virtual void set(const String& key, const String& value) = 0;

        virtual ~IStorageBackend() { }
    };

private:
    /*
     * Callback type definitions
     */
    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const ReceivedDataStructure<protocol::dynamic_node_id::Allocation>&)>
        AllocationCallback;

    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const ReceivedDataStructure<protocol::NodeStatus>&)> NodeStatusCallback;

    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const protocol::dynamic_node_id::server::AppendEntries::Request&,
                              protocol::dynamic_node_id::server::AppendEntries::Response&)> AppendEntriesCallback;

    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const protocol::dynamic_node_id::server::RequestVote::Request&,
                              protocol::dynamic_node_id::server::RequestVote::Response&)> RequestVoteCallback;

    /*
     * Internal type definitions
     */
    typedef Map<NodeID, uint8_t> PendingGetNodeInfoAttemptsMap;

    typedef StorageType<protocol::dynamic_node_id::server::Entry::FieldTypes::term>::Type Term;

    /**
     * This class extends the storage backend interface with serialization/deserialization functionality.
     */
    class StorageMarshallingDecorator
    {
        IStorageBackend& storage_;

    public:
        StorageMarshallingDecorator(IStorageBackend& storage)
            : storage_(storage)
        {
            // Making sure that there will be no data loss during serialization.
            StaticAssert<(sizeof(Term) <= sizeof(uint32_t))>::check();
        }

        /**
         * Setters do the following:
         *  1. Serialize the value.
         *  2. Update the value on the backend.
         *  3. Read the value back from the backend; return false if read fails.
         *  4. Deserealize the newly read value.
         *  5. Update the argument with deserialized value.
         *  6. Return true.
         * The caller then is supposed to check whether the argument has the desired value.
         */
        bool setAndGetBack(const IStorageBackend::String& key, uint32_t& inout_value);
        bool setAndGetBack(const IStorageBackend::String& key,
                           protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id& inout_value);

        /**
         * Getters simply read and deserialize the value.
         */
        bool get(const IStorageBackend::String& key, uint32_t& out_value) const;
        bool get(const IStorageBackend::String& key,
                 protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id& out_value) const;
    };

    /**
     * Raft log.
     * This class transparently replicates its state to the storage backend, keeping the most recent state in memory.
     * Writes are slow, reads are instantaneous.
     */
    class Log
    {
    public:
        typedef uint8_t Index;

    private:
        enum { Capacity = NodeID::Max + 1 };

        IStorageBackend& storage_;
        protocol::dynamic_node_id::server::Entry entries_[Capacity];
        Index max_index_;             // Index zero always contains an empty entry

    public:
        Log(IStorageBackend& storage)
            : storage_(storage)
            , max_index_(0)
        { }

        /**
         * This method invokes storage IO.
         */
        int init();

        /**
         * This method invokes storage IO.
         */
        void append(const protocol::dynamic_node_id::server::Entry& entry);

        /**
         * This method invokes storage IO.
         */
        void removeEntriesWhereIndexGreaterOrEqual(Index index);

        /**
         * Returns nullptr if there's no such index.
         * This method does not use storage IO.
         */
        const protocol::dynamic_node_id::server::Entry* getEntryAtIndex(Index index) const;

        Index getMaxIndex() const { return max_index_; }

        bool isOtherLogUpToDate(Index other_last_index, Term other_last_term) const;
    };

    /**
     * This class is a convenient container for persistent state variables defined by Raft.
     * Writes are slow, reads are instantaneous.
     */
    class PersistentState
    {
        IStorageBackend& storage_;

        Term current_term_;
        NodeID voted_for_;
        Log log_;

    public:
        PersistentState(IStorageBackend& storage)
            : storage_(storage)
            , current_term_(0)
        { }

        int init();

        Term getCurrentTerm() const { return current_term_; }

        NodeID getVotedFor() const { return voted_for_; }

        Log& getLog()             { return log_; }
        const Log& getLog() const { return log_; }

        /**
         * Invokes storage IO.
         */
        void setCurrentTerm(Term term);

        /**
         * Invokes storage IO.
         */
        void setVotedFor(NodeID node_id);
    };

    /**
     * This class maintains the cluster state.
     */
    class ClusterManager : private TimerBase
    {
        typedef MethodBinder<DynamicNodeIDAllocationServer*,
                             void (DynamicNodeIDAllocationServer::*)
                                 (const ReceivedDataStructure<protocol::dynamic_node_id::server::Discovery>&)>
            DiscoveryCallback;

        struct Server
        {
            const NodeID node_id;
            Log::Index next_index;
            Log::Index match_index;

            Server()
                : next_index(0)
                , match_index(0)
            { }
        };

        enum { MaxServers = protocol::dynamic_node_id::server::Discovery::FieldTypes::known_nodes::MaxSize };

        const IStorageBackend& storage_;
        const Log& log_;

        Subscriber<protocol::dynamic_node_id::server::Discovery, DiscoveryCallback> discovery_sub_;
        mutable Publisher<protocol::dynamic_node_id::server::Discovery> discovery_pub_;

        Server servers_[MaxServers - 1];   ///< Minus one because the local server is not listed there.

        uint8_t cluster_size_;
        uint8_t num_known_servers_;

        virtual void handleTimerEvent(const TimerEvent& event);

        void handleDiscovery(const ReceivedDataStructure<protocol::dynamic_node_id::server::Discovery>& msg);

        void publishDiscovery() const;

    public:
        enum { ClusterSizeUnknown = 0 };

        /**
         * @param node          Needed to publish and subscribe to Discovery message
         * @param storage       Needed to read the cluster size parameter from the storage
         * @param log           Needed to initialize nextIndex[] values after elections
         */
        ClusterManager(INode& node, const IStorageBackend& storage, const Log& log)
            : storage_(storage)
            , log_(log)
            , discovery_sub_(node)
            , discovery_pub_(node)
            , cluster_size_(0)
            , num_known_servers_(0)
        { }

        /**
         * If cluster_size is set to ClusterSizeUnknown, the class will try to read this parameter from the
         * storage backend using key 'cluster_size'.
         * Returns negative error code.
         */
        int init(uint8_t cluster_size = ClusterSizeUnknown);

        /**
         * An invalid node ID will be returned if there's no such server.
         * The local server is not listed there.
         */
        NodeID getRemoteServerNodeIDAtIndex(uint8_t index) const;

        /**
         * See next_index[] in Raft paper.
         */
        Log::Index getServerNextIndex(NodeID server_node_id) const;
        void incrementServerNextIndexBy(NodeID server_node_id, Log::Index increment);
        void decrementServerNextIndex(NodeID server_node_id);

        /**
         * See match_index[] in Raft paper.
         */
        Log::Index getServerMatchIndex(NodeID server_node_id) const;
        void setServerMatchIndex(NodeID server_node_id, Log::Index match_index);

        /**
         * This method must be called when the current server becomes leader.
         */
        void resetAllServerIndices();

        uint8_t getNumKnownServers() const { return num_known_servers_; }
        uint8_t getConfiguredClusterSize() const { return cluster_size_; }
        uint8_t getQuorumSize() const { return static_cast<uint8_t>(cluster_size_ / 2U + 1U); }
    };

    enum ServerState
    {
        ServerStateFollower,
        ServerStateCandidate,
        ServerStateLeader
    };

    /*
     * Raft-related states
     */
    PersistentState persistent_state_;  ///< Modifications of this state are slow as they involve storage IO.

    Log::Index commit_index_;

    ClusterManager cluster_;

    /*
     * Implementation-specific states
     */
    PendingGetNodeInfoAttemptsMap pending_get_node_info_attempts_;

    MonotonicTime last_activity_timestamp_;
    bool active_mode_;

    ServerState server_state_;

    /*
     * Transport
     */
    Subscriber<protocol::dynamic_node_id::Allocation, AllocationCallback> allocation_sub_;
    Publisher<protocol::dynamic_node_id::Allocation> allocation_pub_;

    Subscriber<protocol::NodeStatus, NodeStatusCallback> node_status_sub_;

    ServiceServer<protocol::dynamic_node_id::server::AppendEntries, AppendEntriesCallback> append_entries_srv_;
    ServiceServer<protocol::dynamic_node_id::server::RequestVote, RequestVoteCallback> request_vote_srv_;
};

}

#endif // UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_SERVER_HPP_INCLUDED
<commit_msg>Raft server: more internals<commit_after>/*
 * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#ifndef UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_SERVER_HPP_INCLUDED
#define UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_SERVER_HPP_INCLUDED

#include <uavcan/build_config.hpp>
#include <uavcan/node/subscriber.hpp>
#include <uavcan/node/publisher.hpp>
#include <uavcan/node/timer.hpp>
#include <uavcan/util/method_binder.hpp>
#include <uavcan/util/map.hpp>
// Types used by the server
#include <uavcan/protocol/dynamic_node_id/server/AppendEntries.hpp>
#include <uavcan/protocol/dynamic_node_id/server/RequestVote.hpp>
#include <uavcan/protocol/dynamic_node_id/server/Entry.hpp>
#include <uavcan/protocol/dynamic_node_id/server/Discovery.hpp>
#include <uavcan/protocol/dynamic_node_id/Allocation.hpp>
#include <uavcan/protocol/GetNodeInfo.hpp>
#include <uavcan/protocol/NodeStatus.hpp>

namespace uavcan
{
/**
 *
 */
class DynamicNodeIDAllocationServer
{
    /*
     * Public type definitions
     */
public:
    /**
     * This interface is used by the server to read and write stable storage.
     * The storage is represented as a key-value container, where keys and values are ASCII strings up to 32
     * characters long, not including the termination byte. Fixed block size allows for absolutely straightforward
     * and efficient implementation of storage backends, e.g. based on text files.
     */
    class IStorageBackend
    {
    public:
        /**
         * Maximum length of keys and values. One pair takes twice as much space.
         */
        enum { MaxStringLength = 32 };

        /**
         * It is guaranteed that the server will never require more than this number of key/value pairs.
         * Total storage space needed is (MaxKeyValuePairs * MaxStringLength * 2), not including storage overhead.
         */
        enum { MaxKeyValuePairs = 400 };

        /**
         * This type is used to exchange data chunks with the backend.
         * It doesn't use any dynamic memory; please refer to the Array<> class for details.
         */
        typedef Array<IntegerSpec<8, SignednessUnsigned, CastModeTruncate>, ArrayModeDynamic, MaxStringLength> String;

        /**
         * Read one value from the storage.
         * If such key does not exist, or if read failed, an empty string will be returned.
         * This method should not block for more than 50 ms.
         */
        virtual String get(const String& key) const = 0;

        /**
         * Create or update value for the given key.
         * This method should not block for more than 50 ms.
         * Failures will be ignored.
         */
        virtual void set(const String& key, const String& value) = 0;

        virtual ~IStorageBackend() { }
    };

private:
    /*
     * Callback type definitions
     */
    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const ReceivedDataStructure<protocol::dynamic_node_id::Allocation>&)>
        AllocationCallback;

    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const ReceivedDataStructure<protocol::NodeStatus>&)> NodeStatusCallback;

    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const protocol::dynamic_node_id::server::AppendEntries::Request&,
                              protocol::dynamic_node_id::server::AppendEntries::Response&)> AppendEntriesCallback;

    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const protocol::dynamic_node_id::server::RequestVote::Request&,
                              protocol::dynamic_node_id::server::RequestVote::Response&)> RequestVoteCallback;

    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const ServiceCallResult<protocol::dynamic_node_id::server::AppendEntries>&)>
        AppendEntriesResponseCallback;

    typedef MethodBinder<DynamicNodeIDAllocationServer*,
                         void (DynamicNodeIDAllocationServer::*)
                             (const ServiceCallResult<protocol::dynamic_node_id::server::RequestVote>&)>
        RequestVoteResponseCallback;

    /*
     * Internal type definitions
     */
    typedef Map<NodeID, uint8_t> PendingGetNodeInfoAttemptsMap;

    typedef StorageType<protocol::dynamic_node_id::server::Entry::FieldTypes::term>::Type Term;

    /**
     * This class extends the storage backend interface with serialization/deserialization functionality.
     */
    class StorageMarshallingDecorator
    {
        IStorageBackend& storage_;

    public:
        StorageMarshallingDecorator(IStorageBackend& storage)
            : storage_(storage)
        {
            // Making sure that there will be no data loss during serialization.
            StaticAssert<(sizeof(Term) <= sizeof(uint32_t))>::check();
        }

        /**
         * Setters do the following:
         *  1. Serialize the value.
         *  2. Update the value on the backend.
         *  3. Read the value back from the backend; return false if read fails.
         *  4. Deserealize the newly read value.
         *  5. Update the argument with deserialized value.
         *  6. Return true.
         * The caller then is supposed to check whether the argument has the desired value.
         */
        bool setAndGetBack(const IStorageBackend::String& key, uint32_t& inout_value);
        bool setAndGetBack(const IStorageBackend::String& key,
                           protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id& inout_value);

        /**
         * Getters simply read and deserialize the value.
         */
        bool get(const IStorageBackend::String& key, uint32_t& out_value) const;
        bool get(const IStorageBackend::String& key,
                 protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id& out_value) const;
    };

    /**
     * Raft log.
     * This class transparently replicates its state to the storage backend, keeping the most recent state in memory.
     * Writes are slow, reads are instantaneous.
     */
    class Log
    {
    public:
        typedef uint8_t Index;

    private:
        enum { Capacity = NodeID::Max + 1 };

        IStorageBackend& storage_;
        protocol::dynamic_node_id::server::Entry entries_[Capacity];
        Index max_index_;             // Index zero always contains an empty entry

    public:
        Log(IStorageBackend& storage)
            : storage_(storage)
            , max_index_(0)
        { }

        /**
         * This method invokes storage IO.
         */
        int init();

        /**
         * This method invokes storage IO.
         */
        void append(const protocol::dynamic_node_id::server::Entry& entry);

        /**
         * This method invokes storage IO.
         */
        void removeEntriesWhereIndexGreaterOrEqual(Index index);

        /**
         * Returns nullptr if there's no such index.
         * This method does not use storage IO.
         */
        const protocol::dynamic_node_id::server::Entry* getEntryAtIndex(Index index) const;

        Index getMaxIndex() const { return max_index_; }

        bool isOtherLogUpToDate(Index other_last_index, Term other_last_term) const;
    };

    /**
     * This class is a convenient container for persistent state variables defined by Raft.
     * Writes are slow, reads are instantaneous.
     */
    class PersistentState
    {
        IStorageBackend& storage_;

        Term current_term_;
        NodeID voted_for_;
        Log log_;

    public:
        PersistentState(IStorageBackend& storage)
            : storage_(storage)
            , current_term_(0)
        { }

        int init();

        Term getCurrentTerm() const { return current_term_; }

        NodeID getVotedFor() const { return voted_for_; }

        Log& getLog()             { return log_; }
        const Log& getLog() const { return log_; }

        /**
         * Invokes storage IO.
         */
        void setCurrentTerm(Term term);

        /**
         * Invokes storage IO.
         */
        void setVotedFor(NodeID node_id);
    };

    /**
     * This class maintains the cluster state.
     */
    class ClusterManager : private TimerBase
    {
        typedef MethodBinder<DynamicNodeIDAllocationServer*,
                             void (DynamicNodeIDAllocationServer::*)
                                 (const ReceivedDataStructure<protocol::dynamic_node_id::server::Discovery>&)>
            DiscoveryCallback;

        struct Server
        {
            const NodeID node_id;
            Log::Index next_index;
            Log::Index match_index;

            Server()
                : next_index(0)
                , match_index(0)
            { }
        };

        enum { MaxServers = protocol::dynamic_node_id::server::Discovery::FieldTypes::known_nodes::MaxSize };

        const IStorageBackend& storage_;
        const Log& log_;

        Subscriber<protocol::dynamic_node_id::server::Discovery, DiscoveryCallback> discovery_sub_;
        mutable Publisher<protocol::dynamic_node_id::server::Discovery> discovery_pub_;

        Server servers_[MaxServers - 1];   ///< Minus one because the local server is not listed there.

        uint8_t cluster_size_;
        uint8_t num_known_servers_;

        virtual void handleTimerEvent(const TimerEvent& event);

        void handleDiscovery(const ReceivedDataStructure<protocol::dynamic_node_id::server::Discovery>& msg);

        void publishDiscovery() const;

    public:
        enum { ClusterSizeUnknown = 0 };

        /**
         * @param node          Needed to publish and subscribe to Discovery message
         * @param storage       Needed to read the cluster size parameter from the storage
         * @param log           Needed to initialize nextIndex[] values after elections
         */
        ClusterManager(INode& node, const IStorageBackend& storage, const Log& log)
            : storage_(storage)
            , log_(log)
            , discovery_sub_(node)
            , discovery_pub_(node)
            , cluster_size_(0)
            , num_known_servers_(0)
        { }

        /**
         * If cluster_size is set to ClusterSizeUnknown, the class will try to read this parameter from the
         * storage backend using key 'cluster_size'.
         * Returns negative error code.
         */
        int init(uint8_t cluster_size = ClusterSizeUnknown);

        /**
         * An invalid node ID will be returned if there's no such server.
         * The local server is not listed there.
         */
        NodeID getRemoteServerNodeIDAtIndex(uint8_t index) const;

        /**
         * See next_index[] in Raft paper.
         */
        Log::Index getServerNextIndex(NodeID server_node_id) const;
        void incrementServerNextIndexBy(NodeID server_node_id, Log::Index increment);
        void decrementServerNextIndex(NodeID server_node_id);

        /**
         * See match_index[] in Raft paper.
         */
        Log::Index getServerMatchIndex(NodeID server_node_id) const;
        void setServerMatchIndex(NodeID server_node_id, Log::Index match_index);

        /**
         * This method must be called when the current server becomes leader.
         */
        void resetAllServerIndices();

        uint8_t getNumKnownServers() const { return num_known_servers_; }
        uint8_t getConfiguredClusterSize() const { return cluster_size_; }
        uint8_t getQuorumSize() const { return static_cast<uint8_t>(cluster_size_ / 2U + 1U); }
    };

    enum ServerState
    {
        ServerStateFollower,
        ServerStateCandidate,
        ServerStateLeader
    };

    /*
     * Raft-related states
     */
    PersistentState persistent_state_;  ///< Modifications of this state are slow as they involve storage IO.

    Log::Index commit_index_;

    ClusterManager cluster_;

    /*
     * Implementation-specific states
     */
    PendingGetNodeInfoAttemptsMap pending_get_node_info_attempts_;

    MonotonicTime last_activity_timestamp_;
    bool active_mode_;

    ServerState server_state_;

    /*
     * Transport
     */
    Subscriber<protocol::dynamic_node_id::Allocation, AllocationCallback> allocation_sub_;
    Publisher<protocol::dynamic_node_id::Allocation> allocation_pub_;

    Subscriber<protocol::NodeStatus, NodeStatusCallback> node_status_sub_;

    ServiceServer<protocol::dynamic_node_id::server::AppendEntries, AppendEntriesCallback> append_entries_srv_;
    ServiceServer<protocol::dynamic_node_id::server::RequestVote, RequestVoteCallback> request_vote_srv_;

    ServiceClient<protocol::dynamic_node_id::server::AppendEntries,
                  AppendEntriesResponseCallback> append_entries_client_;
    ServiceClient<protocol::dynamic_node_id::server::RequestVote,
                  RequestVoteResponseCallback> request_vote_client_;
};

}

#endif // UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_SERVER_HPP_INCLUDED
<|endoftext|>


<commit_before>#include "Atm_led.hpp"

Atm_led& Atm_led::begin(int attached_pin, bool activeLow) {
  static const state_t state_table[] PROGMEM = {
      /*               ON_ENTER    ON_LOOP    ON_EXIT  EVT_ON_TIMER  EVT_OFF_TIMER  EVT_COUNTER  EVT_ON  EVT_OFF  EVT_BLINK  EVT_TOGGLE  EVT_TOGGLE_BLINK ELSE
         */
      /* IDLE      */ ACT_INIT, ATM_SLEEP, -1,        -1,        -1,    -1,   ON, -1,   START, ON,   START, -1,  // LED off
      /* ON        */ ACT_ON,   ATM_SLEEP, -1,        -1,        -1,    -1,   -1, OFF,  START, OFF,  OFF,   -1,  // LED on
      /* START     */ ACT_ON,   -1,        -1,        BLINK_OFF, -1,    DONE, ON, OFF,  START, OFF,  OFF,   -1,  // Start blinking
      /* BLINK_OFF */ ACT_OFF,  -1,        -1,        -1,        START, DONE, ON, IDLE, START, IDLE, IDLE,  -1,
      /* DONE      */ -1,       -1,        ACT_CHAIN, -1,        IDLE,  -1,   ON, IDLE, START, IDLE, IDLE,  -1,    // Wait after last blink
      /* OFF       */ ACT_OFF,  -1,        -1,        -1,        -1,    -1,   -1, -1,   START, IDLE, IDLE,  IDLE,  // All off -> IDLE
  };
  Machine::begin(state_table, ELSE);
  pin = attached_pin;
  _activeLow = activeLow;
  pinMode(pin, OUTPUT);
  digitalWrite(pin, _activeLow ? HIGH : LOW);
  on_timer.set(500);
  off_timer.set(500);
  repeat_count = ATM_COUNTER_OFF;
  counter.set(repeat_count);
  while (state() != 0) cycle();
  return *this;
}

Atm_led& Atm_led::onFinish(Machine& n, uint8_t event /* = EVT_BLINK */) {
  onFinish(n, n, event);
  return *this;
}

Atm_led& Atm_led::onFinish(Machine& n, Machine& p, uint8_t event /* = EVT_BLINK */) {
  machine_next = &n;
  machine_previous = &p;
  machine_event = event;
  flags &= ~ATM_USR_FLAGS;
  flags |= ATM_USR2_FLAG;
  return *this;
}

Atm_led& Atm_led::onFinish(TinyMachine& n, uint8_t event /* = EVT_BLINK */) {
  onFinish(n, n, event);
  return *this;
}

Atm_led& Atm_led::onFinish(TinyMachine& n, TinyMachine& p, uint8_t event /* = EVT_BLINK */) {
  tmachine_next = &n;
  tmachine_previous = &p;
  machine_event = event;
  flags &= ~ATM_USR_FLAGS;
  flags |= ATM_USR4_FLAG;
  return *this;
}

Atm_led& Atm_led::blink(uint32_t duration, uint32_t pause_duration, uint16_t repeat_count /* = ATM_COUNTER_OFF */) {

  blink(duration);  // Time in which led is fully on
  pause(pause_duration);
  repeat(repeat_count);
  return *this;
}

Atm_led& Atm_led::blink(uint32_t duration) {
  on_timer.set(duration);  // Time in which led is fully on
  return *this;
}

Atm_led& Atm_led::pause(uint32_t duration) {
  off_timer.set(duration);  // Time in which led is fully off
  return *this;
}

Atm_led& Atm_led::fade(int fade) { return *this; }  // Dummy for method compatibility with Atm_fade

Atm_led& Atm_led::repeat(int repeat) {
  repeat_count = repeat >= 0 ? repeat : ATM_COUNTER_OFF;
  counter.set(repeat_count);
  return *this;
}

int Atm_led::event(int id) {
  switch (id) {
    case EVT_ON_TIMER:
      return on_timer.expired(this);
    case EVT_OFF_TIMER:
      return off_timer.expired(this);
    case EVT_COUNTER:
      return counter.expired();
  }
  return 0;
}

void Atm_led::chain_next(void) {

  if ((flags & ATM_USR2_FLAG) > 0) {
    machine_next->trigger(machine_event);
  }
  if ((flags & ATM_USR4_FLAG) > 0) {
    tmachine_next->trigger(machine_event);
  }
}

void Atm_led::chain_previous(void) {

  if ((flags & ATM_USR2_FLAG) > 0) {
    machine_previous->trigger(machine_event);
  }
  if ((flags & ATM_USR4_FLAG) > 0) {
    tmachine_previous->trigger(machine_event);
  }
}

void Atm_led::action(int id) {
  switch (id) {
    case ACT_INIT:
      counter.set(repeat_count);
      return;
    case ACT_ON:
      digitalWrite(pin, _activeLow ? LOW : HIGH);
      return;
    case ACT_OFF:
      counter.decrement();
      digitalWrite(pin, _activeLow ? HIGH : LOW);
      return;
    case ACT_CHAIN:
      if ((flags & (ATM_USR2_FLAG | ATM_USR4_FLAG)) > 0) {
        if ((flags & ATM_USR1_FLAG) > 0) {
          chain_previous();
        } else {
          chain_next();
        }
        flags ^= ATM_USR1_FLAG;
      }
      return;
  }
}

Atm_led& Atm_led::trace(Stream& stream) {

  setTrace(&stream, atm_serial_debug::trace,
           "EVT_ON_TIMER\0EVT_OFF_TIMER\0EVT_COUNTER\0EVT_ON\0EVT_OFF\0EVT_BLINK\0EVT_TOGGLE\0EVT_TOGGLE_BLINK\0ELSE\0"
           "IDLE\0ON\0START\0BLINK_OFF\0DONE\0OFF");
  return *this;
}

// TinyMachine version

Att_led& Att_led::begin(int attached_pin, bool activeLow) {
  static const tiny_state_t state_table[] PROGMEM = {
      /*               ON_ENTER    ON_LOOP    ON_EXIT  EVT_ON_TIMER  EVT_OFF_TIMER  EVT_COUNTER  EVT_ON  EVT_OFF  EVT_BLINK  EVT_TOGGLE  EVT_TOGGLE_BLINK ELSE
         */
      /* IDLE      */ ACT_INIT, ATM_SLEEP, -1,        -1,        -1,    -1,   ON, -1,   START, ON,   START, -1,  // LED off
      /* ON        */ ACT_ON,   ATM_SLEEP, -1,        -1,        -1,    -1,   -1, OFF,  START, OFF,  OFF,   -1,  // LED on
      /* START     */ ACT_ON,   -1,        -1,        BLINK_OFF, -1,    DONE, ON, OFF,  START, OFF,  OFF,   -1,  // Start blinking
      /* BLINK_OFF */ ACT_OFF,  -1,        -1,        -1,        START, DONE, ON, IDLE, START, IDLE, IDLE,  -1,
      /* DONE      */ -1,       -1,        ACT_CHAIN, -1,        IDLE,  -1,   ON, IDLE, START, IDLE, IDLE,  -1,    // Wait after last blink
      /* OFF       */ ACT_OFF,  -1,        -1,        -1,        -1,    -1,   -1, -1,   START, IDLE, IDLE,  IDLE,  // All off -> IDLE
  };
  TinyMachine::begin(state_table, ELSE);
  pin = attached_pin;
  _activeLow = activeLow;
  pinMode(pin, OUTPUT);
  digitalWrite(pin, _activeLow ? HIGH : LOW);
  on_timer.set(500);
  off_timer.set(500);
  repeat_count = ATM_COUNTER_OFF;
  counter.set(repeat_count);
  while (state() != 0) cycle();
  return *this;
}

Att_led& Att_led::onFinish(Machine& n, uint8_t event /* = EVT_BLINK */) {
  onFinish(n, n, event);
  return *this;
}

Att_led& Att_led::onFinish(Machine& n, Machine& p, uint8_t event /* = EVT_BLINK */) {
  machine_next = &n;
  machine_previous = &p;
  machine_event = event;
  flags &= ~ATM_USR_FLAGS;
  flags |= ATM_USR2_FLAG;
  return *this;
}

Att_led& Att_led::onFinish(TinyMachine& n, uint8_t event /* = EVT_BLINK */) {
  onFinish(n, n, event);
  return *this;
}

Att_led& Att_led::onFinish(TinyMachine& n, TinyMachine& p, uint8_t event /* = EVT_BLINK */) {
  tmachine_next = &n;
  tmachine_previous = &p;
  machine_event = event;
  flags &= ~ATM_USR_FLAGS;
  flags |= ATM_USR4_FLAG;
  return *this;
}

Att_led& Att_led::blink(uint32_t duration, uint32_t pause_duration, uint16_t repeat_count /* = ATM_COUNTER_OFF */) {

  blink(duration);  // Time in which led is fully on
  pause(pause_duration);
  repeat(repeat_count);
  return *this;
}

Att_led& Att_led::blink(uint32_t duration) {
  on_timer.set(duration);  // Time in which led is fully on
  return *this;
}

Att_led& Att_led::pause(uint32_t duration) {
  off_timer.set(duration);  // Time in which led is fully off
  return *this;
}

Att_led& Att_led::fade(int fade) { return *this; }  // Dummy for method compatibility with Att_fade

Att_led& Att_led::repeat(int repeat) {
  repeat_count = repeat >= 0 ? repeat : ATM_COUNTER_OFF;
  counter.set(repeat_count);
  return *this;
}

void Att_led::chain_next(void) {

  if ((flags & ATM_USR2_FLAG) > 0) {
    machine_next->trigger(machine_event);
  }
  if ((flags & ATM_USR4_FLAG) > 0) {
    tmachine_next->trigger(machine_event);
  }
}

void Att_led::chain_previous(void) {

  if ((flags & ATM_USR2_FLAG) > 0) {
    machine_previous->trigger(machine_event);
  }
  if ((flags & ATM_USR4_FLAG) > 0) {
    tmachine_previous->trigger(machine_event);
  }
}

int Att_led::event(int id) {
  switch (id) {
    case EVT_ON_TIMER:
      return on_timer.expired(this);
    case EVT_OFF_TIMER:
      return off_timer.expired(this);
    case EVT_COUNTER:
      return counter.expired();
  }
  return 0;
}

void Att_led::action(int id) {
  switch (id) {
    case ACT_INIT:
      counter.set(repeat_count);
      return;
    case ACT_ON:
      digitalWrite(pin, _activeLow ? LOW : HIGH);
      return;
    case ACT_OFF:
      counter.decrement();
      digitalWrite(pin, _activeLow ? HIGH : LOW);
      return;
    case ACT_CHAIN:
      if ((flags & (ATM_USR2_FLAG | ATM_USR4_FLAG)) > 0) {
        if ((flags & ATM_USR1_FLAG) > 0) {
          chain_previous();
        } else {
          chain_next();
        }
        flags ^= ATM_USR1_FLAG;
      }
      return;
  }
}
<commit_msg>Reformat Atm_led.cpp<commit_after>#include "Atm_led.hpp"

Atm_led& Atm_led::begin(int attached_pin, bool activeLow) {
  static const state_t state_table[] PROGMEM = {
      /*               ON_ENTER    ON_LOOP    ON_EXIT  EVT_ON_TIMER  EVT_OFF_TIMER  EVT_COUNTER  EVT_ON  EVT_OFF  EVT_BLINK  EVT_TOGGLE  EVT_TOGGLE_BLINK ELSE
         */
      /* IDLE      */ ACT_INIT, ATM_SLEEP, -1,        -1,        -1,    -1,   ON, -1,   START, ON,   START, -1,  // LED off
      /* ON        */ ACT_ON,   ATM_SLEEP, -1,        -1,        -1,    -1,   -1, OFF,  START, OFF,  OFF,   -1,  // LED on
      /* START     */ ACT_ON,   -1,        -1,        BLINK_OFF, -1,    DONE, ON, OFF,  START, OFF,  OFF,   -1,  // Start blinking
      /* BLINK_OFF */ ACT_OFF,  -1,        -1,        -1,        START, DONE, ON, IDLE, START, IDLE, IDLE,  -1,
      /* DONE      */ -1,       -1,        ACT_CHAIN, -1,        IDLE,  -1,   ON, IDLE, START, IDLE, IDLE,  -1,    // Wait after last blink
      /* OFF       */ ACT_OFF,  -1,        -1,        -1,        -1,    -1,   -1, -1,   START, IDLE, IDLE,  IDLE,  // All off -> IDLE
  };
  Machine::begin(state_table, ELSE);
  pin = attached_pin;
  _activeLow = activeLow;
  pinMode(pin, OUTPUT);
  digitalWrite(pin, _activeLow ? HIGH : LOW);
  on_timer.set(500);
  off_timer.set(500);
  repeat_count = ATM_COUNTER_OFF;
  counter.set(repeat_count);
  while (state() != 0) cycle();
  return *this;
}

Atm_led& Atm_led::onFinish(Machine& n, uint8_t event /* = EVT_BLINK */) {
  onFinish(n, n, event);
  return *this;
}

Atm_led& Atm_led::onFinish(Machine& n, Machine& p, uint8_t event /* = EVT_BLINK */) {
  machine_next = &n;
  machine_previous = &p;
  machine_event = event;
  flags &= ~ATM_USR_FLAGS;
  flags |= ATM_USR2_FLAG;
  return *this;
}

Atm_led& Atm_led::onFinish(TinyMachine& n, uint8_t event /* = EVT_BLINK */) {
  onFinish(n, n, event);
  return *this;
}

Atm_led& Atm_led::onFinish(TinyMachine& n, TinyMachine& p, uint8_t event /* = EVT_BLINK */) {
  tmachine_next = &n;
  tmachine_previous = &p;
  machine_event = event;
  flags &= ~ATM_USR_FLAGS;
  flags |= ATM_USR4_FLAG;
  return *this;
}

Atm_led& Atm_led::blink(uint32_t duration, uint32_t pause_duration, uint16_t repeat_count /* = ATM_COUNTER_OFF */) {
  blink(duration);  // Time in which led is fully on
  pause(pause_duration);
  repeat(repeat_count);
  return *this;
}

Atm_led& Atm_led::blink(uint32_t duration) {
  on_timer.set(duration);  // Time in which led is fully on
  return *this;
}

Atm_led& Atm_led::pause(uint32_t duration) {
  off_timer.set(duration);  // Time in which led is fully off
  return *this;
}

Atm_led& Atm_led::fade(int fade) { return *this; }  // Dummy for method compatibility with Atm_fade

Atm_led& Atm_led::repeat(int repeat) {
  repeat_count = repeat >= 0 ? repeat : ATM_COUNTER_OFF;
  counter.set(repeat_count);
  return *this;
}

int Atm_led::event(int id) {
  switch (id) {
    case EVT_ON_TIMER:
      return on_timer.expired(this);
    case EVT_OFF_TIMER:
      return off_timer.expired(this);
    case EVT_COUNTER:
      return counter.expired();
  }
  return 0;
}

void Atm_led::chain_next(void) {
  if ((flags & ATM_USR2_FLAG) > 0) {
    machine_next->trigger(machine_event);
  }
  if ((flags & ATM_USR4_FLAG) > 0) {
    tmachine_next->trigger(machine_event);
  }
}

void Atm_led::chain_previous(void) {
  if ((flags & ATM_USR2_FLAG) > 0) {
    machine_previous->trigger(machine_event);
  }
  if ((flags & ATM_USR4_FLAG) > 0) {
    tmachine_previous->trigger(machine_event);
  }
}

void Atm_led::action(int id) {
  switch (id) {
    case ACT_INIT:
      counter.set(repeat_count);
      return;
    case ACT_ON:
      digitalWrite(pin, _activeLow ? LOW : HIGH);
      return;
    case ACT_OFF:
      counter.decrement();
      digitalWrite(pin, _activeLow ? HIGH : LOW);
      return;
    case ACT_CHAIN:
      if ((flags & (ATM_USR2_FLAG | ATM_USR4_FLAG)) > 0) {
        if ((flags & ATM_USR1_FLAG) > 0) {
          chain_previous();
        } else {
          chain_next();
        }
        flags ^= ATM_USR1_FLAG;
      }
      return;
  }
}

Atm_led& Atm_led::trace(Stream& stream) {
  setTrace(&stream, atm_serial_debug::trace,
           "EVT_ON_TIMER\0EVT_OFF_TIMER\0EVT_COUNTER\0EVT_ON\0EVT_OFF\0EVT_BLINK\0EVT_TOGGLE\0EVT_TOGGLE_BLINK\0ELSE\0"
           "IDLE\0ON\0START\0BLINK_OFF\0DONE\0OFF");
  return *this;
}

// TinyMachine version

Att_led& Att_led::begin(int attached_pin, bool activeLow) {
  static const tiny_state_t state_table[] PROGMEM = {
      /*               ON_ENTER    ON_LOOP    ON_EXIT  EVT_ON_TIMER  EVT_OFF_TIMER  EVT_COUNTER  EVT_ON  EVT_OFF  EVT_BLINK  EVT_TOGGLE  EVT_TOGGLE_BLINK ELSE
         */
      /* IDLE      */ ACT_INIT, ATM_SLEEP, -1,        -1,        -1,    -1,   ON, -1,   START, ON,   START, -1,  // LED off
      /* ON        */ ACT_ON,   ATM_SLEEP, -1,        -1,        -1,    -1,   -1, OFF,  START, OFF,  OFF,   -1,  // LED on
      /* START     */ ACT_ON,   -1,        -1,        BLINK_OFF, -1,    DONE, ON, OFF,  START, OFF,  OFF,   -1,  // Start blinking
      /* BLINK_OFF */ ACT_OFF,  -1,        -1,        -1,        START, DONE, ON, IDLE, START, IDLE, IDLE,  -1,
      /* DONE      */ -1,       -1,        ACT_CHAIN, -1,        IDLE,  -1,   ON, IDLE, START, IDLE, IDLE,  -1,    // Wait after last blink
      /* OFF       */ ACT_OFF,  -1,        -1,        -1,        -1,    -1,   -1, -1,   START, IDLE, IDLE,  IDLE,  // All off -> IDLE
  };
  TinyMachine::begin(state_table, ELSE);
  pin = attached_pin;
  _activeLow = activeLow;
  pinMode(pin, OUTPUT);
  digitalWrite(pin, _activeLow ? HIGH : LOW);
  on_timer.set(500);
  off_timer.set(500);
  repeat_count = ATM_COUNTER_OFF;
  counter.set(repeat_count);
  while (state() != 0) cycle();
  return *this;
}

Att_led& Att_led::onFinish(Machine& n, uint8_t event /* = EVT_BLINK */) {
  onFinish(n, n, event);
  return *this;
}

Att_led& Att_led::onFinish(Machine& n, Machine& p, uint8_t event /* = EVT_BLINK */) {
  machine_next = &n;
  machine_previous = &p;
  machine_event = event;
  flags &= ~ATM_USR_FLAGS;
  flags |= ATM_USR2_FLAG;
  return *this;
}

Att_led& Att_led::onFinish(TinyMachine& n, uint8_t event /* = EVT_BLINK */) {
  onFinish(n, n, event);
  return *this;
}

Att_led& Att_led::onFinish(TinyMachine& n, TinyMachine& p, uint8_t event /* = EVT_BLINK */) {
  tmachine_next = &n;
  tmachine_previous = &p;
  machine_event = event;
  flags &= ~ATM_USR_FLAGS;
  flags |= ATM_USR4_FLAG;
  return *this;
}

Att_led& Att_led::blink(uint32_t duration, uint32_t pause_duration, uint16_t repeat_count /* = ATM_COUNTER_OFF */) {
  blink(duration);  // Time in which led is fully on
  pause(pause_duration);
  repeat(repeat_count);
  return *this;
}

Att_led& Att_led::blink(uint32_t duration) {
  on_timer.set(duration);  // Time in which led is fully on
  return *this;
}

Att_led& Att_led::pause(uint32_t duration) {
  off_timer.set(duration);  // Time in which led is fully off
  return *this;
}

Att_led& Att_led::fade(int fade) { return *this; }  // Dummy for method compatibility with Att_fade

Att_led& Att_led::repeat(int repeat) {
  repeat_count = repeat >= 0 ? repeat : ATM_COUNTER_OFF;
  counter.set(repeat_count);
  return *this;
}

void Att_led::chain_next(void) {
  if ((flags & ATM_USR2_FLAG) > 0) {
    machine_next->trigger(machine_event);
  }
  if ((flags & ATM_USR4_FLAG) > 0) {
    tmachine_next->trigger(machine_event);
  }
}

void Att_led::chain_previous(void) {
  if ((flags & ATM_USR2_FLAG) > 0) {
    machine_previous->trigger(machine_event);
  }
  if ((flags & ATM_USR4_FLAG) > 0) {
    tmachine_previous->trigger(machine_event);
  }
}

int Att_led::event(int id) {
  switch (id) {
    case EVT_ON_TIMER:
      return on_timer.expired(this);
    case EVT_OFF_TIMER:
      return off_timer.expired(this);
    case EVT_COUNTER:
      return counter.expired();
  }
  return 0;
}

void Att_led::action(int id) {
  switch (id) {
    case ACT_INIT:
      counter.set(repeat_count);
      return;
    case ACT_ON:
      digitalWrite(pin, _activeLow ? LOW : HIGH);
      return;
    case ACT_OFF:
      counter.decrement();
      digitalWrite(pin, _activeLow ? HIGH : LOW);
      return;
    case ACT_CHAIN:
      if ((flags & (ATM_USR2_FLAG | ATM_USR4_FLAG)) > 0) {
        if ((flags & ATM_USR1_FLAG) > 0) {
          chain_previous();
        } else {
          chain_next();
        }
        flags ^= ATM_USR1_FLAG;
      }
      return;
  }
}
<|endoftext|>


<commit_before>#include "render/shaderfactory.hpp"

#include <fstream>
#include <sstream>
#include <iostream>
#include <cassert>

void render::ShaderFactory::checkShaderError(GLuint shader) {
	GLint succeeded;

	glGetShaderiv(shader, GL_COMPILE_STATUS, &succeeded);

	if(succeeded == false) {
		GLint maxLength;
		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);

		char infoLog[maxLength];
		glGetShaderInfoLog(shader, maxLength, &maxLength, infoLog);

		//TODO Omzetten naar logging!
		std::cerr << "Shader compile error:" << std::endl << infoLog << std::endl;

		assert(succeeded);
	}
}

const GLuint render::ShaderFactory::getShader(const std::string shaderName, GLenum shaderType) {
	//Check for shader in flyweight pool
	if(shaders.find(shaderName) != shaders.end()) {
		return shaders[shaderName];
	}

	//Shader not in flyweight pool: load and compile shader
	std::ifstream shaderSourceFile(std::string("./shaders/" + shaderName + ".glsl").c_str());

	if(!shaderSourceFile.is_open()) {
		//TODO To logging
		std::cerr << "Could not find shader " << shaderName << std::endl;
		assert(shaderSourceFile.is_open());
	}

	std::stringstream shaderSourceStream;

	while(shaderSourceFile.good()) {
		std::string line;
		std::getline(shaderSourceFile, line);

		shaderSourceStream << line;
	}

	GLuint shader = glCreateShader(shaderType);

	glShaderSource(shader, 1, (const GLchar**) shaderSourceStream.str().c_str(), 0);
	glCompileShader(shader);
	checkShaderError(shader);

	shaders.insert(std::pair<std::string, GLuint>(shaderName, shader));

	return shader;
}
<commit_msg>Derp... Forgot to initialize static member<commit_after>#include "render/shaderfactory.hpp"

#include <fstream>
#include <sstream>
#include <iostream>
#include <cassert>

std::map<const std::string, const GLuint> render::ShaderFactory::shaders;

void render::ShaderFactory::checkShaderError(GLuint shader) {
	GLint succeeded;

	glGetShaderiv(shader, GL_COMPILE_STATUS, &succeeded);

	if(succeeded == false) {
		GLint maxLength;
		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);

		char infoLog[maxLength];
		glGetShaderInfoLog(shader, maxLength, &maxLength, infoLog);

		//TODO Omzetten naar logging!
		std::cerr << "Shader compile error:" << std::endl << infoLog << std::endl;

		assert(succeeded);
	}
}

const GLuint render::ShaderFactory::getShader(const std::string shaderName, GLenum shaderType) {
	//Check for shader in flyweight pool
	if(shaders.find(shaderName) != shaders.end()) {
		return shaders[shaderName];
	}

	//Shader not in flyweight pool: load and compile shader
	std::ifstream shaderSourceFile(std::string("./shaders/" + shaderName + ".glsl").c_str());

	if(!shaderSourceFile.is_open()) {
		//TODO To logging
		std::cerr << "Could not find shader " << shaderName << std::endl;
		assert(shaderSourceFile.is_open());
	}

	std::stringstream shaderSourceStream;

	while(shaderSourceFile.good()) {
		std::string line;
		std::getline(shaderSourceFile, line);

		shaderSourceStream << line;
	}

	GLuint shader = glCreateShader(shaderType);

	glShaderSource(shader, 1, (const GLchar**) shaderSourceStream.str().c_str(), 0);
	glCompileShader(shader);
	checkShaderError(shader);

	shaders.insert(std::pair<std::string, GLuint>(shaderName, shader));

	return shader;
}
<|endoftext|>


<commit_before>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2008, 2009 Ames Laboratory
Iowa State University and The Regents of the University of Michigan All rights
reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

Redistribution and use of HOOMD-blue, in source and binary forms, with or
without modification, are permitted, provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.

* 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.

* Neither the name of the copyright holder nor the names of HOOMD-blue's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR
ANY WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
*/
// $Id$
// $URL$
// Maintainer: joaander

/*! \file ZeroMomentumUpdater.cc
    \brief Defines the ZeroMomentumUpdater class
*/

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

#include <boost/python.hpp>
using namespace boost::python;

#include "ZeroMomentumUpdater.h"

#include <iostream>
#include <math.h>
#include <stdexcept>

using namespace std;

/*! \param sysdef System to zero the momentum of
*/
ZeroMomentumUpdater::ZeroMomentumUpdater(boost::shared_ptr<SystemDefinition> sysdef)
        : Updater(sysdef)
    {
    assert(m_pdata);
    }

/*! Perform the needed calculations to zero the system's momentum
    \param timestep Current time step of the simulation
*/
void ZeroMomentumUpdater::update(unsigned int timestep)
    {
    if (m_prof) m_prof->push("ZeroMomentum");

    // calculate the average momentum
    assert(m_pdata);
    ParticleDataArrays arrays = m_pdata->acquireReadWrite();

    // temp variables for holding the sums
    Scalar sum_px = 0.0;
    Scalar sum_py = 0.0;
    Scalar sum_pz = 0.0;

    for (unsigned int i = 0; i < arrays.nparticles; i++)
        {
        Scalar mass = arrays.mass[i];
        sum_px += mass*arrays.vx[i];
        sum_py += mass*arrays.vy[i];
        sum_pz += mass*arrays.vz[i];
        }

    // calculate the average
    Scalar avg_px = sum_px / Scalar(arrays.nparticles);
    Scalar avg_py = sum_py / Scalar(arrays.nparticles);
    Scalar avg_pz = sum_pz / Scalar(arrays.nparticles);

    // subtract this momentum from every partcile
    for (unsigned int i = 0; i < arrays.nparticles; i++)
        {
        Scalar mass = arrays.mass[i];
        arrays.vx[i] -= avg_px/mass;
        arrays.vy[i] -= avg_py/mass;
        arrays.vz[i] -= avg_pz/mass;
        }

    m_pdata->release();

    if (m_prof) m_prof->pop();
    }

void export_ZeroMomentumUpdater()
    {
    class_<ZeroMomentumUpdater, boost::shared_ptr<ZeroMomentumUpdater>, bases<Updater>, boost::noncopyable>
    ("ZeroMomentumUpdater", init< boost::shared_ptr<SystemDefinition> >())
    ;
    }

#ifdef WIN32
#pragma warning( pop )
#endif

<commit_msg>Fix update.zero_momentum to properly handle rigid bodies. #440<commit_after>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2008, 2009 Ames Laboratory
Iowa State University and The Regents of the University of Michigan All rights
reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

Redistribution and use of HOOMD-blue, in source and binary forms, with or
without modification, are permitted, provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions, and the following disclaimer.

* 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.

* Neither the name of the copyright holder nor the names of HOOMD-blue's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR
ANY WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
*/
// $Id$
// $URL$
// Maintainer: joaander

/*! \file ZeroMomentumUpdater.cc
    \brief Defines the ZeroMomentumUpdater class
*/

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4103 4244 )
#endif

#include <boost/python.hpp>
using namespace boost::python;

#include "ZeroMomentumUpdater.h"

#include <iostream>
#include <math.h>
#include <stdexcept>

using namespace std;

/*! \param sysdef System to zero the momentum of
*/
ZeroMomentumUpdater::ZeroMomentumUpdater(boost::shared_ptr<SystemDefinition> sysdef)
        : Updater(sysdef)
    {
    assert(m_pdata);
    }

/*! Perform the needed calculations to zero the system's momentum
    \param timestep Current time step of the simulation
*/
void ZeroMomentumUpdater::update(unsigned int timestep)
    {
    if (m_prof) m_prof->push("ZeroMomentum");

    // calculate the average momentum
    assert(m_pdata);
    ParticleDataArrays arrays = m_pdata->acquireReadWrite();

    // temp variables for holding the sums
    Scalar sum_px = 0.0;
    Scalar sum_py = 0.0;
    Scalar sum_pz = 0.0;
    unsigned int n = 0;

    // add up the momentum of every free particle
    for (unsigned int i = 0; i < arrays.nparticles; i++)
        {
        if (arrays.body[i] == NO_BODY)
            {
            Scalar mass = arrays.mass[i];
            sum_px += mass*arrays.vx[i];
            sum_py += mass*arrays.vy[i];
            sum_pz += mass*arrays.vz[i];
            n++;
            }
        }

    // add up the linear momentum of all bodies
    boost::shared_ptr<RigidData> rigid_data = m_sysdef->getRigidData();
    unsigned int n_bodies = rigid_data->getNumBodies();
    if (n_bodies > 0)
        {
        ArrayHandle<Scalar4> h_body_vel(rigid_data->getVel(), access_location::host, access_mode::read);
        ArrayHandle<Scalar> h_body_mass(rigid_data->getBodyMass(), access_location::host, access_mode::read);

        for (unsigned int body = 0; body < n_bodies; body++)
            {
            Scalar mass = h_body_mass.data[body];
            Scalar4 vel = h_body_vel.data[body];
            sum_px += mass * vel.x;
            sum_py += mass * vel.y;
            sum_pz += mass * vel.z;
            n++;
            }
        }

    // calculate the average
    Scalar avg_px = sum_px / Scalar(n);
    Scalar avg_py = sum_py / Scalar(n);
    Scalar avg_pz = sum_pz / Scalar(n);

    // subtract this momentum from every free partcile
    for (unsigned int i = 0; i < arrays.nparticles; i++)
        {
        if (arrays.body[i] == NO_BODY)
            {
            Scalar mass = arrays.mass[i];
            arrays.vx[i] -= avg_px/mass;
            arrays.vy[i] -= avg_py/mass;
            arrays.vz[i] -= avg_pz/mass;
            }
        }

    // subtract this momentum from every rigid body
    if (n_bodies > 0)
        {
        ArrayHandle<Scalar4> h_body_vel(rigid_data->getVel(), access_location::host, access_mode::readwrite);
        ArrayHandle<Scalar> h_body_mass(rigid_data->getBodyMass(), access_location::host, access_mode::read);

        for (unsigned int body = 0; body < n_bodies; body++)
            {
            Scalar mass = h_body_mass.data[body];
            h_body_vel.data[body].x -= avg_px/mass;
            h_body_vel.data[body].y -= avg_py/mass;
            h_body_vel.data[body].z -= avg_pz/mass;
            }
        }

    m_pdata->release();

    // update the body particle velocities to reflect the new body velocities
    rigid_data->setRV(false);

    if (m_prof) m_prof->pop();
    }

void export_ZeroMomentumUpdater()
    {
    class_<ZeroMomentumUpdater, boost::shared_ptr<ZeroMomentumUpdater>, bases<Updater>, boost::noncopyable>
    ("ZeroMomentumUpdater", init< boost::shared_ptr<SystemDefinition> >())
    ;
    }

#ifdef WIN32
#pragma warning( pop )
#endif

<|endoftext|>


<commit_before>#ifndef NODES_DEEP_COPY_HPP_
#define NODES_DEEP_COPY_HPP_

// Write a method that takes a pointer to a Node structure as a parameter and
// returns a complete copy of the passed in data structure. The Node data
// structure contains two pointers to other Nodes.

class Node
{
public:
    Node(const Node* first, const Node* second) :
        m_first(first), m_second(second) {}

    ~Node()
    {
        if (nullptr != m_first)
        {
            delete m_first;
        }

        if (nullptr != m_second)
        {
            delete m_second;
        }
    }

    Node* m_first = nullptr;
    Node* m_second = nullptr;
};

Node* DeepCopyOfNode(const Node* const node)
{
    if (nullptr == node)
    {
        return nullptr;
    }

    Node* result = new Node;
    if (nullptr != node->m_first)
    {
        result->m_first = DeepCopyOfNode(node->m_first);
    }

    if (nullptr != node->m_second)
    {
        result->m_second = DeepCopyOfNode(node->m_second);
    }

    return result;
}

#endif /* NODES_DEEP_COPY_HPP_ */
<commit_msg>Minor changes in Nodes Deep Copy<commit_after>#ifndef NODES_DEEP_COPY_HPP_
#define NODES_DEEP_COPY_HPP_

// Write a method that takes a pointer to a Node structure as a parameter and
// returns a complete copy of the passed in data structure. The Node data
// structure contains two pointers to other Nodes.

namespace Algo::DS {

class Node {
public:
    Node(const Node* first, const Node* second) :
        m_first(first), m_second(second) { }

    ~Node() {
        if (nullptr != m_first) {
            delete m_first;
        }

        if (nullptr != m_second) {
            delete m_second;
        }
    }

    Node* m_first = nullptr;
    Node* m_second = nullptr;
};

Node* DeepCopyOfNode(const Node* const node) {
    if (nullptr == node) {
        return nullptr;
    }

    Node* result = new Node;
    if (nullptr != node->m_first) {
        result->m_first = DeepCopyOfNode(node->m_first);
    }

    if (nullptr != node->m_second) {
        result->m_second = DeepCopyOfNode(node->m_second);
    }

    return result;
}

}

#endif /* NODES_DEEP_COPY_HPP_ */
<|endoftext|>


<commit_before>
// CommandBlockEntity.cpp

// Implements the cCommandBlockEntity class representing a single command block in the world

#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules
#include "json/json.h"
#include "CommandBlockEntity.h"
#include "../Entities/Player.h"
#include "../WorldStorage/FastNBT.h"

#include "../CommandOutput.h"
#include "../Root.h"
#include "../Server.h"  // ExecuteConsoleCommand()
#include "../Chunk.h"
#include "../ChatColor.h"

cCommandBlockEntity::cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) :
	super(E_BLOCK_COMMAND_BLOCK, a_X, a_Y, a_Z, a_World),
	m_ShouldExecute(false),
	m_IsPowered(false),
	m_Result(0)
{}

void cCommandBlockEntity::UsedBy(cPlayer * a_Player)
{
	// Nothing to do
	UNUSED(a_Player);
}

void cCommandBlockEntity::SetCommand(const AString & a_Cmd)
{
	m_Command = a_Cmd;

	/*
	Vanilla requires that the server send a Block Entity Update after a command has been set
	Therefore, command blocks don't support on-the-fly (when window is open) updating of a command and therefore...
	...the following code can't be put in UsedBy just before the window opens

	Just documenting my experience in getting this to work :P
	*/
	m_World->BroadcastBlockEntity(GetPosX(), GetPosY(), GetPosZ());
}

void cCommandBlockEntity::SetLastOutput(const AString & a_LastOut)
{
	m_World->BroadcastBlockEntity(GetPosX(), GetPosY(), GetPosZ());
	m_LastOutput = a_LastOut;
}

void cCommandBlockEntity::SetResult(const NIBBLETYPE a_Result)
{
	m_Result = a_Result;
}

const AString & cCommandBlockEntity::GetCommand(void) const
{
	return m_Command;
}

const AString & cCommandBlockEntity::GetLastOutput(void) const
{
	return m_LastOutput;
}

NIBBLETYPE cCommandBlockEntity::GetResult(void) const
{
	return m_Result;
}

void cCommandBlockEntity::Activate(void)
{
	m_ShouldExecute = true;
}

void cCommandBlockEntity::SetRedstonePower(bool a_IsPowered)
{
	if (a_IsPowered && !m_IsPowered)
	{
		Activate();
	}
	m_IsPowered = a_IsPowered;
}

bool cCommandBlockEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
	UNUSED(a_Dt);
	UNUSED(a_Chunk);
	if (!m_ShouldExecute)
	{
		return false;
	}

	m_ShouldExecute = false;
	Execute();
	return true;
}

void cCommandBlockEntity::SendTo(cClientHandle & a_Client)
{
	a_Client.SendUpdateBlockEntity(*this);
}

bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value)
{
	m_PosX = a_Value.get("x", 0).asInt();
	m_PosY = a_Value.get("y", 0).asInt();
	m_PosZ = a_Value.get("z", 0).asInt();

	m_Command    = a_Value.get("Command",     "").asString();
	m_LastOutput = a_Value.get("LastOutput",  "").asString();
	m_Result     = (NIBBLETYPE)a_Value.get("SuccessCount", 0).asInt();

	return true;
}

void cCommandBlockEntity::SaveToJson(Json::Value & a_Value)
{
	a_Value["x"] = m_PosX;
	a_Value["y"] = m_PosY;
	a_Value["z"] = m_PosZ;

	a_Value["Command"]      = m_Command;
	a_Value["LastOutput"]   = m_LastOutput;
	a_Value["SuccessCount"] = m_Result;
}

void cCommandBlockEntity::Execute()
{
	if (m_World != NULL)
	{
		if (!m_World->AreCommandBlocksEnabled())
		{
			return;
		}
	}

	class CommandBlockOutCb :
		public cCommandOutputCallback
	{
		cCommandBlockEntity * m_CmdBlock;

	public:
		CommandBlockOutCb(cCommandBlockEntity * a_CmdBlock) : m_CmdBlock(a_CmdBlock) {}

		virtual void Out(const AString & a_Text)
		{
			// Overwrite field
			m_CmdBlock->SetLastOutput(cClientHandle::FormatChatPrefix(m_CmdBlock->GetWorld()->ShouldUseChatPrefixes(), "SUCCESS", cChatColor::Green, cChatColor::White) + a_Text);
		}
	} CmdBlockOutCb(this);

	// Administrator commands are not executable by command blocks:
	if (
		(m_Command != "stop") &&
		(m_Command != "restart") &&
		(m_Command != "kick") &&
		(m_Command != "ban") &&
		(m_Command != "ipban")
	)
	{
		cServer * Server = cRoot::Get()->GetServer();
		LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str());
		Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb);
	}
	else
	{
		SetLastOutput(cClientHandle::FormatChatPrefix(GetWorld()->ShouldUseChatPrefixes(), "FAILURE", cChatColor::Rose, cChatColor::White) + "Adminstration commands can not be executed");
		LOGD("cCommandBlockEntity: Prevented execution of administration command %s", m_Command.c_str());
	}

	// TODO 2014-01-18 xdot: Update the signal strength.
	m_Result = 0;
}

<commit_msg>Changed null check to assert<commit_after>
// CommandBlockEntity.cpp

// Implements the cCommandBlockEntity class representing a single command block in the world

#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules
#include "json/json.h"
#include "CommandBlockEntity.h"
#include "../Entities/Player.h"
#include "../WorldStorage/FastNBT.h"

#include "../CommandOutput.h"
#include "../Root.h"
#include "../Server.h"  // ExecuteConsoleCommand()
#include "../Chunk.h"
#include "../ChatColor.h"

cCommandBlockEntity::cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World) :
	super(E_BLOCK_COMMAND_BLOCK, a_X, a_Y, a_Z, a_World),
	m_ShouldExecute(false),
	m_IsPowered(false),
	m_Result(0)
{}

void cCommandBlockEntity::UsedBy(cPlayer * a_Player)
{
	// Nothing to do
	UNUSED(a_Player);
}

void cCommandBlockEntity::SetCommand(const AString & a_Cmd)
{
	m_Command = a_Cmd;

	/*
	Vanilla requires that the server send a Block Entity Update after a command has been set
	Therefore, command blocks don't support on-the-fly (when window is open) updating of a command and therefore...
	...the following code can't be put in UsedBy just before the window opens

	Just documenting my experience in getting this to work :P
	*/
	m_World->BroadcastBlockEntity(GetPosX(), GetPosY(), GetPosZ());
}

void cCommandBlockEntity::SetLastOutput(const AString & a_LastOut)
{
	m_World->BroadcastBlockEntity(GetPosX(), GetPosY(), GetPosZ());
	m_LastOutput = a_LastOut;
}

void cCommandBlockEntity::SetResult(const NIBBLETYPE a_Result)
{
	m_Result = a_Result;
}

const AString & cCommandBlockEntity::GetCommand(void) const
{
	return m_Command;
}

const AString & cCommandBlockEntity::GetLastOutput(void) const
{
	return m_LastOutput;
}

NIBBLETYPE cCommandBlockEntity::GetResult(void) const
{
	return m_Result;
}

void cCommandBlockEntity::Activate(void)
{
	m_ShouldExecute = true;
}

void cCommandBlockEntity::SetRedstonePower(bool a_IsPowered)
{
	if (a_IsPowered && !m_IsPowered)
	{
		Activate();
	}
	m_IsPowered = a_IsPowered;
}

bool cCommandBlockEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
	UNUSED(a_Dt);
	UNUSED(a_Chunk);
	if (!m_ShouldExecute)
	{
		return false;
	}

	m_ShouldExecute = false;
	Execute();
	return true;
}

void cCommandBlockEntity::SendTo(cClientHandle & a_Client)
{
	a_Client.SendUpdateBlockEntity(*this);
}

bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value)
{
	m_PosX = a_Value.get("x", 0).asInt();
	m_PosY = a_Value.get("y", 0).asInt();
	m_PosZ = a_Value.get("z", 0).asInt();

	m_Command    = a_Value.get("Command",     "").asString();
	m_LastOutput = a_Value.get("LastOutput",  "").asString();
	m_Result     = (NIBBLETYPE)a_Value.get("SuccessCount", 0).asInt();

	return true;
}

void cCommandBlockEntity::SaveToJson(Json::Value & a_Value)
{
	a_Value["x"] = m_PosX;
	a_Value["y"] = m_PosY;
	a_Value["z"] = m_PosZ;

	a_Value["Command"]      = m_Command;
	a_Value["LastOutput"]   = m_LastOutput;
	a_Value["SuccessCount"] = m_Result;
}

void cCommandBlockEntity::Execute()
{
	ASSERT(m_World != NULL); //Execute should not be called before the command block is attached to a world
	if (!m_World->AreCommandBlocksEnabled())
	{
		return;
	}

	class CommandBlockOutCb :
		public cCommandOutputCallback
	{
		cCommandBlockEntity * m_CmdBlock;

	public:
		CommandBlockOutCb(cCommandBlockEntity * a_CmdBlock) : m_CmdBlock(a_CmdBlock) {}

		virtual void Out(const AString & a_Text)
		{
			// Overwrite field
			m_CmdBlock->SetLastOutput(cClientHandle::FormatChatPrefix(m_CmdBlock->GetWorld()->ShouldUseChatPrefixes(), "SUCCESS", cChatColor::Green, cChatColor::White) + a_Text);
		}
	} CmdBlockOutCb(this);

	// Administrator commands are not executable by command blocks:
	if (
		(m_Command != "stop") &&
		(m_Command != "restart") &&
		(m_Command != "kick") &&
		(m_Command != "ban") &&
		(m_Command != "ipban")
	)
	{
		cServer * Server = cRoot::Get()->GetServer();
		LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str());
		Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb);
	}
	else
	{
		SetLastOutput(cClientHandle::FormatChatPrefix(GetWorld()->ShouldUseChatPrefixes(), "FAILURE", cChatColor::Rose, cChatColor::White) + "Adminstration commands can not be executed");
		LOGD("cCommandBlockEntity: Prevented execution of administration command %s", m_Command.c_str());
	}

	// TODO 2014-01-18 xdot: Update the signal strength.
	m_Result = 0;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <sys/time.h>
#include <stdint.h>

#include "wavelet_tree.h"
#include "memory_usage.h"

using namespace std;

int main(int argc, char** argv)
{

	struct timeval start_time, end_time;
	char rank_or_select, character;
	string filename;
	uint32_t bound;
	long us;
	bool success;

	WaveletTree* wt = NULL;
	uint32_t result = 0;

	if (argc != 5) {
		printf ("Wrong number of parameters: \n./WavletTree filename rank_or_select[R or S] char bound \n");
		return -1;
    }

	filename = argv[1];
	rank_or_select = argv[2][0];
	character = argv[3][0];
	bound = atoi(argv[4]);

	if (rank_or_select == 'R') {
		// Creating wavelet tree
		cout <<"Creating tree: ";
		gettimeofday(&start_time,NULL);
		wt = WaveletTree::CreateTreeFromFASTAFile(filename);
		gettimeofday(&end_time,NULL);

		us = (long)((1000000 * end_time.tv_sec + end_time.tv_usec) -
                       (1000000 * start_time.tv_sec + start_time.tv_usec));
		cout <<us <<"us" <<endl;

		// Rank operation
		cout <<"Rank("<<character <<", " <<bound <<"): ";
		gettimeofday(&start_time,NULL);
		success = wt->Rank(character, bound, result);
		gettimeofday(&end_time,NULL);

		us = (long)((1000000 * end_time.tv_sec + end_time.tv_usec) -
        	(1000000 * start_time.tv_sec + start_time.tv_usec));
		if (success) {
			cout <<result <<" [" <<us <<" us]" <<endl;
		}
		else {
			cout <<"Failed. Wrong index" <<endl;
		}
	}
	else if (rank_or_select == 'S') {
		// Creating wavelet tree
		cout <<"Creating tree: ";
		gettimeofday(&start_time,NULL);
		wt = WaveletTree::CreateTreeFromFASTAFile(filename);
		gettimeofday(&end_time,NULL);

		us = (long)((1000000 * end_time.tv_sec + end_time.tv_usec) -
                       (1000000 * start_time.tv_sec + start_time.tv_usec));
		cout <<us <<"us" <<endl;

		// Rank operation
		cout <<"Select("<<character <<", " <<bound <<"): ";
		gettimeofday(&start_time,NULL);
		success = wt->Select(character, bound, result);
		gettimeofday(&end_time,NULL);

		us = (long)((1000000 * end_time.tv_sec + end_time.tv_usec) -
        	(1000000 * start_time.tv_sec + start_time.tv_usec));

		if (success) {
			cout <<result <<" [" <<us <<" us]" <<endl;
		}
		else {
			cout <<"Failed. Wrong index" <<endl;
		}
	}
	else {
		cout <<"Value of 3rd parameter must be 'R' or 'S'" <<endl;
	}

	cout <<"Memory usage: " <<CalculateMemoryUsage(filename, 3, 1, 131072) <<" B" <<endl;

	delete wt;
	return 0;
}
<commit_msg>Ispravak u main funkciji<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <sys/time.h>
#include <stdint.h>

#include "wavelet_tree.h"
#include "memory_usage.h"

using namespace std;

int main(int argc, char** argv)
{

	struct timeval start_time, end_time;
	char rank_or_select, character;
	string filename;
	uint32_t bound;
	long us;
	bool success;

	WaveletTree* wt = NULL;
	uint32_t result = 0;

	if (argc != 5) {
		cout <<"Wrong number of parameters: \n./WavletTree filename rank_or_select[R or S] char bound \n";
		return -1;
    }

	filename = argv[1];
	rank_or_select = argv[2][0];
	character = argv[3][0];
	bound = atoi(argv[4]);

	if (rank_or_select == 'R') {
		// Creating wavelet tree
		cout <<"Creating tree: ";
		gettimeofday(&start_time,NULL);
		wt = WaveletTree::CreateTreeFromFASTAFile(filename);
		gettimeofday(&end_time,NULL);

		if (wt == NULL) {
			cout <<"FAILED" <<endl;
			cout <<"Could not open file " <<filename <<endl;
			return 1;
		}

		us = (long)((1000000 * end_time.tv_sec + end_time.tv_usec) -
                       (1000000 * start_time.tv_sec + start_time.tv_usec));
		cout <<us <<"us" <<endl;

		// Rank operation
		cout <<"Rank("<<character <<", " <<bound <<"): ";
		gettimeofday(&start_time,NULL);
		success = wt->Rank(character, bound, result);
		gettimeofday(&end_time,NULL);

		us = (long)((1000000 * end_time.tv_sec + end_time.tv_usec) -
        	(1000000 * start_time.tv_sec + start_time.tv_usec));
		if (success) {
			cout <<result <<" [" <<us <<" us]" <<endl;
		}
		else {
			cout <<"Failed. Wrong index" <<endl;
		}
	}
	else if (rank_or_select == 'S') {
		// Creating wavelet tree
		cout <<"Creating tree: ";
		gettimeofday(&start_time,NULL);
		wt = WaveletTree::CreateTreeFromFASTAFile(filename);
		gettimeofday(&end_time,NULL);

		if (wt == NULL) {
			cout <<"FAILED" <<endl;
			cout <<"Could not open file " <<filename <<endl;
			return 1;
		}

		us = (long)((1000000 * end_time.tv_sec + end_time.tv_usec) -
                       (1000000 * start_time.tv_sec + start_time.tv_usec));
		cout <<us <<"us" <<endl;

		// Rank operation
		cout <<"Select("<<character <<", " <<bound <<"): ";
		gettimeofday(&start_time,NULL);
		success = wt->Select(character, bound, result);
		gettimeofday(&end_time,NULL);

		us = (long)((1000000 * end_time.tv_sec + end_time.tv_usec) -
        	(1000000 * start_time.tv_sec + start_time.tv_usec));

		if (success) {
			cout <<result <<" [" <<us <<" us]" <<endl;
		}
		else {
			cout <<"Failed. Wrong index" <<endl;
		}
	}
	else {
		cout <<"Value of 3rd parameter must be 'R' or 'S'" <<endl;
	}

	cout <<"Memory usage: " <<CalculateMemoryUsage(filename, 3, 1, 131072) <<" B" <<endl;

	delete wt;
	return 0;
}
<|endoftext|>