<commit_before>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "kitinformationconfigwidget.h"

#include "devicesupport/devicemanager.h"
#include "devicesupport/devicemanagermodel.h"
#include "devicesupport/idevicefactory.h"
#include "projectexplorerconstants.h"
#include "kit.h"
#include "kitinformation.h"
#include "toolchain.h"
#include "toolchainmanager.h"
#include "environmentwidget.h"

#include <coreplugin/icore.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
#include <utils/fancylineedit.h>
#include <utils/environment.h>
#include <utils/qtcassert.h>
#include <utils/pathchooser.h>

#include <QComboBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QFontMetrics>
#include <QLabel>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QVBoxLayout>

using namespace Core;

namespace ProjectExplorer {
namespace Internal {

// --------------------------------------------------------------------------
// SysRootInformationConfigWidget:
// --------------------------------------------------------------------------

SysRootInformationConfigWidget::SysRootInformationConfigWidget(Kit *k, const KitInformation *ki) :
    KitConfigWidget(k, ki),
    m_ignoreChange(false)
{
    m_chooser = new Utils::PathChooser;
    m_chooser->setExpectedKind(Utils::PathChooser::ExistingDirectory);
    m_chooser->setHistoryCompleter(QLatin1String("PE.SysRoot.History"));
    m_chooser->setFileName(SysRootKitInformation::sysRoot(k));
    connect(m_chooser, SIGNAL(changed(QString)), this, SLOT(pathWasChanged()));
}

SysRootInformationConfigWidget::~SysRootInformationConfigWidget()
{
    delete m_chooser;
}

QString SysRootInformationConfigWidget::displayName() const
{
    return tr("Sysroot:");
}

QString SysRootInformationConfigWidget::toolTip() const
{
    return tr("The root directory of the system image to use.
"
              "Leave empty when building for the desktop.");
}

void SysRootInformationConfigWidget::refresh()
{
    if (!m_ignoreChange)
        m_chooser->setFileName(SysRootKitInformation::sysRoot(m_kit));
}

void SysRootInformationConfigWidget::makeReadOnly()
{
    m_chooser->setReadOnly(true);
}

QWidget *SysRootInformationConfigWidget::mainWidget() const
{
    return m_chooser->lineEdit();
}

QWidget *SysRootInformationConfigWidget::buttonWidget() const
{
    return m_chooser->buttonAtIndex(0);
}

void SysRootInformationConfigWidget::pathWasChanged()
{
    m_ignoreChange = true;
    SysRootKitInformation::setSysRoot(m_kit, m_chooser->fileName());
    m_ignoreChange = false;
}

// --------------------------------------------------------------------------
// ToolChainInformationConfigWidget:
// --------------------------------------------------------------------------

ToolChainInformationConfigWidget::ToolChainInformationConfigWidget(Kit *k, const KitInformation *ki) :
    KitConfigWidget(k, ki),
    m_ignoreChanges(false),
    m_isReadOnly(false)
{
    m_comboBox = new QComboBox;
    m_comboBox->setToolTip(toolTip());

    refresh();
    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentToolChainChanged(int)));

    m_manageButton = new QPushButton(KitConfigWidget::msgManage());
    m_manageButton->setContentsMargins(0, 0, 0, 0);
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageToolChains()));
}

ToolChainInformationConfigWidget::~ToolChainInformationConfigWidget()
{
    delete m_comboBox;
    delete m_manageButton;
}

QString ToolChainInformationConfigWidget::displayName() const
{
    return tr("Compiler:");
}

QString ToolChainInformationConfigWidget::toolTip() const
{
    return tr("The compiler to use for building.
"
              "Make sure the compiler will produce binaries compatible with the target device, "
              "Qt version and other libraries used.");
}

void ToolChainInformationConfigWidget::refresh()
{
    m_ignoreChanges = true;
    m_comboBox->clear();
    foreach (ToolChain *tc, ToolChainManager::toolChains())
        m_comboBox->addItem(tc->displayName(), tc->id());

    if (m_comboBox->count() == 0) {
        m_comboBox->addItem(tr("<No compiler available>"), QString());
        m_comboBox->setEnabled(false);
    } else {
        m_comboBox->setEnabled(m_comboBox->count() > 1 && !m_isReadOnly);
    }

    m_comboBox->setCurrentIndex(indexOf(ToolChainKitInformation::toolChain(m_kit)));
    m_ignoreChanges = false;
}

void ToolChainInformationConfigWidget::makeReadOnly()
{
    m_isReadOnly = true;
    m_comboBox->setEnabled(false);
}

QWidget *ToolChainInformationConfigWidget::mainWidget() const
{
    return m_comboBox;
}

QWidget *ToolChainInformationConfigWidget::buttonWidget() const
{
    return m_manageButton;
}

void ToolChainInformationConfigWidget::manageToolChains()
{
    ICore::showOptionsDialog(Constants::TOOLCHAIN_SETTINGS_PAGE_ID, buttonWidget());
}

void ToolChainInformationConfigWidget::currentToolChainChanged(int idx)
{
    if (m_ignoreChanges)
        return;

    const QString id = m_comboBox->itemData(idx).toString();
    ToolChainKitInformation::setToolChain(m_kit, ToolChainManager::findToolChain(id));
}

int ToolChainInformationConfigWidget::indexOf(const ToolChain *tc)
{
    const QString id = tc ? tc->id() : QString();
    for (int i = 0; i < m_comboBox->count(); ++i) {
        if (id == m_comboBox->itemData(i).toString())
            return i;
    }
    return -1;
}

// --------------------------------------------------------------------------
// DeviceTypeInformationConfigWidget:
// --------------------------------------------------------------------------

DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *workingCopy, const KitInformation *ki) :
    KitConfigWidget(workingCopy, ki), m_comboBox(new QComboBox)
{
    QList<IDeviceFactory *> factories
            = ExtensionSystem::PluginManager::getObjects<IDeviceFactory>();
    foreach (IDeviceFactory *factory, factories) {
        foreach (Id id, factory->availableCreationIds())
            m_comboBox->addItem(factory->displayNameForId(id), id.uniqueIdentifier());
    }

    m_comboBox->setToolTip(toolTip());

    refresh();
    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentTypeChanged(int)));
}

DeviceTypeInformationConfigWidget::~DeviceTypeInformationConfigWidget()
{
    delete m_comboBox;
}

QWidget *DeviceTypeInformationConfigWidget::mainWidget() const
{
    return m_comboBox;
}

QString DeviceTypeInformationConfigWidget::displayName() const
{
    return tr("Device type:");
}

QString DeviceTypeInformationConfigWidget::toolTip() const
{
    return tr("The type of device to run applications on.");
}

void DeviceTypeInformationConfigWidget::refresh()
{
    Id devType = DeviceTypeKitInformation::deviceTypeId(m_kit);
    if (!devType.isValid())
        m_comboBox->setCurrentIndex(-1);
    for (int i = 0; i < m_comboBox->count(); ++i) {
        if (m_comboBox->itemData(i).toInt() == devType.uniqueIdentifier()) {
            m_comboBox->setCurrentIndex(i);
            break;
        }
    }
}

void DeviceTypeInformationConfigWidget::makeReadOnly()
{
    m_comboBox->setEnabled(false);
}

void DeviceTypeInformationConfigWidget::currentTypeChanged(int idx)
{
    Id type = idx < 0 ? Id() : Id::fromUniqueIdentifier(m_comboBox->itemData(idx).toInt());
    DeviceTypeKitInformation::setDeviceTypeId(m_kit, type);
}

// --------------------------------------------------------------------------
// DeviceInformationConfigWidget:
// --------------------------------------------------------------------------

DeviceInformationConfigWidget::DeviceInformationConfigWidget(Kit *workingCopy, const KitInformation *ki) :
    KitConfigWidget(workingCopy, ki),
    m_isReadOnly(false),
    m_ignoreChange(false),
    m_comboBox(new QComboBox),
    m_model(new DeviceManagerModel(DeviceManager::instance()))
{
    m_comboBox->setModel(m_model);

    m_manageButton = new QPushButton(KitConfigWidget::msgManage());

    refresh();
    m_comboBox->setToolTip(toolTip());

    connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToReset()));
    connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentDeviceChanged()));
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageDevices()));
}

DeviceInformationConfigWidget::~DeviceInformationConfigWidget()
{
    delete m_comboBox;
    delete m_model;
    delete m_manageButton;
}

QWidget *DeviceInformationConfigWidget::mainWidget() const
{
    return m_comboBox;
}

QString DeviceInformationConfigWidget::displayName() const
{
    return tr("Device:");
}

QString DeviceInformationConfigWidget::toolTip() const
{
    return tr("The device to run the applications on.");
}

void DeviceInformationConfigWidget::refresh()
{
    m_model->setTypeFilter(DeviceTypeKitInformation::deviceTypeId(m_kit));
    m_comboBox->setCurrentIndex(m_model->indexOf(DeviceKitInformation::device(m_kit)));
}

void DeviceInformationConfigWidget::makeReadOnly()
{
    m_comboBox->setEnabled(false);
}

QWidget *DeviceInformationConfigWidget::buttonWidget() const
{
    return m_manageButton;
}

void DeviceInformationConfigWidget::manageDevices()
{
    ICore::showOptionsDialog(Constants::DEVICE_SETTINGS_PAGE_ID, buttonWidget());
}

void DeviceInformationConfigWidget::modelAboutToReset()
{
    m_selectedId = m_model->deviceId(m_comboBox->currentIndex());
    m_ignoreChange = true;
}

void DeviceInformationConfigWidget::modelReset()
{
    m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
    m_ignoreChange = false;
}

void DeviceInformationConfigWidget::currentDeviceChanged()
{
    if (m_ignoreChange)
        return;
    DeviceKitInformation::setDeviceId(m_kit, m_model->deviceId(m_comboBox->currentIndex()));
}

// --------------------------------------------------------------------
// KitEnvironmentConfigWidget:
// --------------------------------------------------------------------

KitEnvironmentConfigWidget::KitEnvironmentConfigWidget(Kit *workingCopy, const KitInformation *ki) :
    KitConfigWidget(workingCopy, ki),
    m_summaryLabel(new QLabel),
    m_manageButton(new QPushButton),
    m_dialog(0),
    m_editor(0)
{
    refresh();
    m_manageButton->setText(tr("Change..."));
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(editEnvironmentChanges()));
}

QWidget *KitEnvironmentConfigWidget::mainWidget() const
{
    return m_summaryLabel;
}

QString KitEnvironmentConfigWidget::displayName() const
{
    return tr("Environment:");
}

QString KitEnvironmentConfigWidget::toolTip() const
{
    return tr("Additional environment settings when using this kit.");
}

void KitEnvironmentConfigWidget::refresh()
{
    QList<Utils::EnvironmentItem> changes = EnvironmentKitInformation::environmentChanges(m_kit);
    Utils::sort(changes, [](const Utils::EnvironmentItem &lhs, const Utils::EnvironmentItem &rhs)
                         { return QString::localeAwareCompare(lhs.name, rhs.name) < 0; });
    QString shortSummary = Utils::EnvironmentItem::toStringList(changes).join(QLatin1String("; "));
    QFontMetrics fm(m_summaryLabel->font());
    shortSummary = fm.elidedText(shortSummary, Qt::ElideRight, m_summaryLabel->width());
    m_summaryLabel->setText(shortSummary.isEmpty() ? tr("No changes to apply.") : shortSummary);
    if (m_editor)
        m_editor->setPlainText(Utils::EnvironmentItem::toStringList(changes).join(QLatin1Char('\n')));
}

void KitEnvironmentConfigWidget::makeReadOnly()
{
    m_manageButton->setEnabled(false);
    if (m_dialog)
        m_dialog->reject();
}

void KitEnvironmentConfigWidget::editEnvironmentChanges()
{
    if (m_dialog) {
        m_dialog->activateWindow();
        m_dialog->raise();
        return;
    }

    QTC_ASSERT(!m_editor, return);

    m_dialog = new QDialog(m_summaryLabel);
    m_dialog->setWindowTitle(tr("Edit Environment Changes"));
    QVBoxLayout *layout = new QVBoxLayout(m_dialog);
    m_editor = new QPlainTextEdit;
    QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Apply|QDialogButtonBox::Cancel);

    layout->addWidget(m_editor);
    layout->addWidget(buttons);

    connect(buttons, SIGNAL(accepted()), m_dialog, SLOT(accept()));
    connect(buttons, SIGNAL(rejected()), m_dialog, SLOT(reject()));
    connect(m_dialog, SIGNAL(accepted()), this, SLOT(acceptChangesDialog()));
    connect(m_dialog, SIGNAL(rejected()), this, SLOT(closeChangesDialog()));
    connect(buttons->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyChanges()));

    refresh();
    m_dialog->show();
}

void KitEnvironmentConfigWidget::applyChanges()
{
    QTC_ASSERT(m_editor, return);
    auto changes = Utils::EnvironmentItem::fromStringList(m_editor->toPlainText().split(QLatin1Char('\n')));
    EnvironmentKitInformation::setEnvironmentChanges(m_kit, changes);
}

void KitEnvironmentConfigWidget::closeChangesDialog()
{
    m_dialog->deleteLater();
    m_dialog = 0;
    m_editor = 0;
}

void KitEnvironmentConfigWidget::acceptChangesDialog()
{
    applyChanges();
    closeChangesDialog();
}

QWidget *KitEnvironmentConfigWidget::buttonWidget() const
{
    return m_manageButton;
}

} // namespace Internal
} // namespace ProjectExplorer
<commit_msg>Kits: Replace use of Id::fromUniqueId() and Id::toUniqueId()<commit_after>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "kitinformationconfigwidget.h"

#include "devicesupport/devicemanager.h"
#include "devicesupport/devicemanagermodel.h"
#include "devicesupport/idevicefactory.h"
#include "projectexplorerconstants.h"
#include "kit.h"
#include "kitinformation.h"
#include "toolchain.h"
#include "toolchainmanager.h"
#include "environmentwidget.h"

#include <coreplugin/icore.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/algorithm.h>
#include <utils/fancylineedit.h>
#include <utils/environment.h>
#include <utils/qtcassert.h>
#include <utils/pathchooser.h>

#include <QComboBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QFontMetrics>
#include <QLabel>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QVBoxLayout>

using namespace Core;

namespace ProjectExplorer {
namespace Internal {

// --------------------------------------------------------------------------
// SysRootInformationConfigWidget:
// --------------------------------------------------------------------------

SysRootInformationConfigWidget::SysRootInformationConfigWidget(Kit *k, const KitInformation *ki) :
    KitConfigWidget(k, ki),
    m_ignoreChange(false)
{
    m_chooser = new Utils::PathChooser;
    m_chooser->setExpectedKind(Utils::PathChooser::ExistingDirectory);
    m_chooser->setHistoryCompleter(QLatin1String("PE.SysRoot.History"));
    m_chooser->setFileName(SysRootKitInformation::sysRoot(k));
    connect(m_chooser, SIGNAL(changed(QString)), this, SLOT(pathWasChanged()));
}

SysRootInformationConfigWidget::~SysRootInformationConfigWidget()
{
    delete m_chooser;
}

QString SysRootInformationConfigWidget::displayName() const
{
    return tr("Sysroot:");
}

QString SysRootInformationConfigWidget::toolTip() const
{
    return tr("The root directory of the system image to use.
"
              "Leave empty when building for the desktop.");
}

void SysRootInformationConfigWidget::refresh()
{
    if (!m_ignoreChange)
        m_chooser->setFileName(SysRootKitInformation::sysRoot(m_kit));
}

void SysRootInformationConfigWidget::makeReadOnly()
{
    m_chooser->setReadOnly(true);
}

QWidget *SysRootInformationConfigWidget::mainWidget() const
{
    return m_chooser->lineEdit();
}

QWidget *SysRootInformationConfigWidget::buttonWidget() const
{
    return m_chooser->buttonAtIndex(0);
}

void SysRootInformationConfigWidget::pathWasChanged()
{
    m_ignoreChange = true;
    SysRootKitInformation::setSysRoot(m_kit, m_chooser->fileName());
    m_ignoreChange = false;
}

// --------------------------------------------------------------------------
// ToolChainInformationConfigWidget:
// --------------------------------------------------------------------------

ToolChainInformationConfigWidget::ToolChainInformationConfigWidget(Kit *k, const KitInformation *ki) :
    KitConfigWidget(k, ki),
    m_ignoreChanges(false),
    m_isReadOnly(false)
{
    m_comboBox = new QComboBox;
    m_comboBox->setToolTip(toolTip());

    refresh();
    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentToolChainChanged(int)));

    m_manageButton = new QPushButton(KitConfigWidget::msgManage());
    m_manageButton->setContentsMargins(0, 0, 0, 0);
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageToolChains()));
}

ToolChainInformationConfigWidget::~ToolChainInformationConfigWidget()
{
    delete m_comboBox;
    delete m_manageButton;
}

QString ToolChainInformationConfigWidget::displayName() const
{
    return tr("Compiler:");
}

QString ToolChainInformationConfigWidget::toolTip() const
{
    return tr("The compiler to use for building.
"
              "Make sure the compiler will produce binaries compatible with the target device, "
              "Qt version and other libraries used.");
}

void ToolChainInformationConfigWidget::refresh()
{
    m_ignoreChanges = true;
    m_comboBox->clear();
    foreach (ToolChain *tc, ToolChainManager::toolChains())
        m_comboBox->addItem(tc->displayName(), tc->id());

    if (m_comboBox->count() == 0) {
        m_comboBox->addItem(tr("<No compiler available>"), QString());
        m_comboBox->setEnabled(false);
    } else {
        m_comboBox->setEnabled(m_comboBox->count() > 1 && !m_isReadOnly);
    }

    m_comboBox->setCurrentIndex(indexOf(ToolChainKitInformation::toolChain(m_kit)));
    m_ignoreChanges = false;
}

void ToolChainInformationConfigWidget::makeReadOnly()
{
    m_isReadOnly = true;
    m_comboBox->setEnabled(false);
}

QWidget *ToolChainInformationConfigWidget::mainWidget() const
{
    return m_comboBox;
}

QWidget *ToolChainInformationConfigWidget::buttonWidget() const
{
    return m_manageButton;
}

void ToolChainInformationConfigWidget::manageToolChains()
{
    ICore::showOptionsDialog(Constants::TOOLCHAIN_SETTINGS_PAGE_ID, buttonWidget());
}

void ToolChainInformationConfigWidget::currentToolChainChanged(int idx)
{
    if (m_ignoreChanges)
        return;

    const QString id = m_comboBox->itemData(idx).toString();
    ToolChainKitInformation::setToolChain(m_kit, ToolChainManager::findToolChain(id));
}

int ToolChainInformationConfigWidget::indexOf(const ToolChain *tc)
{
    const QString id = tc ? tc->id() : QString();
    for (int i = 0; i < m_comboBox->count(); ++i) {
        if (id == m_comboBox->itemData(i).toString())
            return i;
    }
    return -1;
}

// --------------------------------------------------------------------------
// DeviceTypeInformationConfigWidget:
// --------------------------------------------------------------------------

DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *workingCopy, const KitInformation *ki) :
    KitConfigWidget(workingCopy, ki), m_comboBox(new QComboBox)
{
    QList<IDeviceFactory *> factories
            = ExtensionSystem::PluginManager::getObjects<IDeviceFactory>();
    foreach (IDeviceFactory *factory, factories) {
        foreach (Id id, factory->availableCreationIds())
            m_comboBox->addItem(factory->displayNameForId(id), id.toSetting());
    }

    m_comboBox->setToolTip(toolTip());

    refresh();
    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentTypeChanged(int)));
}

DeviceTypeInformationConfigWidget::~DeviceTypeInformationConfigWidget()
{
    delete m_comboBox;
}

QWidget *DeviceTypeInformationConfigWidget::mainWidget() const
{
    return m_comboBox;
}

QString DeviceTypeInformationConfigWidget::displayName() const
{
    return tr("Device type:");
}

QString DeviceTypeInformationConfigWidget::toolTip() const
{
    return tr("The type of device to run applications on.");
}

void DeviceTypeInformationConfigWidget::refresh()
{
    Id devType = DeviceTypeKitInformation::deviceTypeId(m_kit);
    if (!devType.isValid())
        m_comboBox->setCurrentIndex(-1);
    for (int i = 0; i < m_comboBox->count(); ++i) {
        if (m_comboBox->itemData(i) == devType.toSetting()) {
            m_comboBox->setCurrentIndex(i);
            break;
        }
    }
}

void DeviceTypeInformationConfigWidget::makeReadOnly()
{
    m_comboBox->setEnabled(false);
}

void DeviceTypeInformationConfigWidget::currentTypeChanged(int idx)
{
    Id type = idx < 0 ? Id() : Id::fromSetting(m_comboBox->itemData(idx));
    DeviceTypeKitInformation::setDeviceTypeId(m_kit, type);
}

// --------------------------------------------------------------------------
// DeviceInformationConfigWidget:
// --------------------------------------------------------------------------

DeviceInformationConfigWidget::DeviceInformationConfigWidget(Kit *workingCopy, const KitInformation *ki) :
    KitConfigWidget(workingCopy, ki),
    m_isReadOnly(false),
    m_ignoreChange(false),
    m_comboBox(new QComboBox),
    m_model(new DeviceManagerModel(DeviceManager::instance()))
{
    m_comboBox->setModel(m_model);

    m_manageButton = new QPushButton(KitConfigWidget::msgManage());

    refresh();
    m_comboBox->setToolTip(toolTip());

    connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToReset()));
    connect(m_model, SIGNAL(modelReset()), SLOT(modelReset()));
    connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(currentDeviceChanged()));
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageDevices()));
}

DeviceInformationConfigWidget::~DeviceInformationConfigWidget()
{
    delete m_comboBox;
    delete m_model;
    delete m_manageButton;
}

QWidget *DeviceInformationConfigWidget::mainWidget() const
{
    return m_comboBox;
}

QString DeviceInformationConfigWidget::displayName() const
{
    return tr("Device:");
}

QString DeviceInformationConfigWidget::toolTip() const
{
    return tr("The device to run the applications on.");
}

void DeviceInformationConfigWidget::refresh()
{
    m_model->setTypeFilter(DeviceTypeKitInformation::deviceTypeId(m_kit));
    m_comboBox->setCurrentIndex(m_model->indexOf(DeviceKitInformation::device(m_kit)));
}

void DeviceInformationConfigWidget::makeReadOnly()
{
    m_comboBox->setEnabled(false);
}

QWidget *DeviceInformationConfigWidget::buttonWidget() const
{
    return m_manageButton;
}

void DeviceInformationConfigWidget::manageDevices()
{
    ICore::showOptionsDialog(Constants::DEVICE_SETTINGS_PAGE_ID, buttonWidget());
}

void DeviceInformationConfigWidget::modelAboutToReset()
{
    m_selectedId = m_model->deviceId(m_comboBox->currentIndex());
    m_ignoreChange = true;
}

void DeviceInformationConfigWidget::modelReset()
{
    m_comboBox->setCurrentIndex(m_model->indexForId(m_selectedId));
    m_ignoreChange = false;
}

void DeviceInformationConfigWidget::currentDeviceChanged()
{
    if (m_ignoreChange)
        return;
    DeviceKitInformation::setDeviceId(m_kit, m_model->deviceId(m_comboBox->currentIndex()));
}

// --------------------------------------------------------------------
// KitEnvironmentConfigWidget:
// --------------------------------------------------------------------

KitEnvironmentConfigWidget::KitEnvironmentConfigWidget(Kit *workingCopy, const KitInformation *ki) :
    KitConfigWidget(workingCopy, ki),
    m_summaryLabel(new QLabel),
    m_manageButton(new QPushButton),
    m_dialog(0),
    m_editor(0)
{
    refresh();
    m_manageButton->setText(tr("Change..."));
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(editEnvironmentChanges()));
}

QWidget *KitEnvironmentConfigWidget::mainWidget() const
{
    return m_summaryLabel;
}

QString KitEnvironmentConfigWidget::displayName() const
{
    return tr("Environment:");
}

QString KitEnvironmentConfigWidget::toolTip() const
{
    return tr("Additional environment settings when using this kit.");
}

void KitEnvironmentConfigWidget::refresh()
{
    QList<Utils::EnvironmentItem> changes = EnvironmentKitInformation::environmentChanges(m_kit);
    Utils::sort(changes, [](const Utils::EnvironmentItem &lhs, const Utils::EnvironmentItem &rhs)
                         { return QString::localeAwareCompare(lhs.name, rhs.name) < 0; });
    QString shortSummary = Utils::EnvironmentItem::toStringList(changes).join(QLatin1String("; "));
    QFontMetrics fm(m_summaryLabel->font());
    shortSummary = fm.elidedText(shortSummary, Qt::ElideRight, m_summaryLabel->width());
    m_summaryLabel->setText(shortSummary.isEmpty() ? tr("No changes to apply.") : shortSummary);
    if (m_editor)
        m_editor->setPlainText(Utils::EnvironmentItem::toStringList(changes).join(QLatin1Char('\n')));
}

void KitEnvironmentConfigWidget::makeReadOnly()
{
    m_manageButton->setEnabled(false);
    if (m_dialog)
        m_dialog->reject();
}

void KitEnvironmentConfigWidget::editEnvironmentChanges()
{
    if (m_dialog) {
        m_dialog->activateWindow();
        m_dialog->raise();
        return;
    }

    QTC_ASSERT(!m_editor, return);

    m_dialog = new QDialog(m_summaryLabel);
    m_dialog->setWindowTitle(tr("Edit Environment Changes"));
    QVBoxLayout *layout = new QVBoxLayout(m_dialog);
    m_editor = new QPlainTextEdit;
    QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Apply|QDialogButtonBox::Cancel);

    layout->addWidget(m_editor);
    layout->addWidget(buttons);

    connect(buttons, SIGNAL(accepted()), m_dialog, SLOT(accept()));
    connect(buttons, SIGNAL(rejected()), m_dialog, SLOT(reject()));
    connect(m_dialog, SIGNAL(accepted()), this, SLOT(acceptChangesDialog()));
    connect(m_dialog, SIGNAL(rejected()), this, SLOT(closeChangesDialog()));
    connect(buttons->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyChanges()));

    refresh();
    m_dialog->show();
}

void KitEnvironmentConfigWidget::applyChanges()
{
    QTC_ASSERT(m_editor, return);
    auto changes = Utils::EnvironmentItem::fromStringList(m_editor->toPlainText().split(QLatin1Char('\n')));
    EnvironmentKitInformation::setEnvironmentChanges(m_kit, changes);
}

void KitEnvironmentConfigWidget::closeChangesDialog()
{
    m_dialog->deleteLater();
    m_dialog = 0;
    m_editor = 0;
}

void KitEnvironmentConfigWidget::acceptChangesDialog()
{
    applyChanges();
    closeChangesDialog();
}

QWidget *KitEnvironmentConfigWidget::buttonWidget() const
{
    return m_manageButton;
}

} // namespace Internal
} // namespace ProjectExplorer
<|endoftext|>


<commit_before>/**
 @file  unix.c
 @brief ENet Unix system specific functions
*/
#ifndef WIN32

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#define ENET_BUILDING_LIB 1
#include "enet/enet.h"

#ifdef __APPLE__
#undef HAS_POLL
#ifndef HAS_SOCKLEN_T
#define HAS_SOCKLEN_T
#endif
#ifndef HAS_FCNTL
#define HAS_FCNTL
#endif
#endif

#ifdef HAS_FCNTL
#include <fcntl.h>
#endif

#ifdef HAS_POLL
#include <sys/poll.h>
#endif

#if defined(__socklen_t_defined) && !defined(HAS_SOCKLEN_T)
#define HAS_SOCKLEN_T
#endif

#ifndef HAS_SOCKLEN_T
typedef int socklen_t;
#endif

#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif

static enet_uint32 timeBase = 0;

int
enet_initialize (void)
{
    return 0;
}

void
enet_deinitialize (void)
{
}

enet_uint32
enet_time_get (void)
{
    struct timeval timeVal;

    gettimeofday (& timeVal, NULL);

    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
}

void
enet_time_set (enet_uint32 newTimeBase)
{
    struct timeval timeVal;

    gettimeofday (& timeVal, NULL);

    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
}

int
enet_address_set_host (ENetAddress * address, const char * name)
{
    struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYNAME_R
    struct hostent hostData;
    char buffer [2048];
    int errnum;

#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
#endif
#else
    hostEntry = gethostbyname (name);
#endif

    if (hostEntry == NULL ||
        hostEntry -> h_addrtype != AF_INET)
    {
#ifdef HAS_INET_PTON
        if (! inet_pton (AF_INET, name, & address -> host))
#else
        if (! inet_aton (name, (struct in_addr *) & address -> host))
#endif
            return -1;
        return 0;
    }

    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];

    return 0;
}

int
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
{
#ifdef HAS_INET_NTOP
    if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
#else
    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
    if (addr != NULL)
        strncpy (name, addr, nameLength);
    else
#endif
        return -1;
    return 0;
}

int
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
{
    struct in_addr in;
    struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYADDR_R
    struct hostent hostData;
    char buffer [2048];
    int errnum;

    in.s_addr = address -> host;

#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
    hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
#endif
#else
    in.s_addr = address -> host;

    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
#endif

    if (hostEntry == NULL)
      return enet_address_get_host_ip (address, name, nameLength);

    strncpy (name, hostEntry -> h_name, nameLength);

    return 0;
}

int
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
{
    struct sockaddr_in sin;

    memset (& sin, 0, sizeof (struct sockaddr_in));

    sin.sin_family = AF_INET;

    if (address != NULL)
    {
       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
       sin.sin_addr.s_addr = address -> host;
    }
    else
    {
       sin.sin_port = 0;
       sin.sin_addr.s_addr = INADDR_ANY;
    }

    return bind (socket,
                 (struct sockaddr *) & sin,
                 sizeof (struct sockaddr_in));
}

int
enet_socket_listen (ENetSocket socket, int backlog)
{
    return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
}

ENetSocket
enet_socket_create (ENetSocketType type)
{
    ENetSocket sd = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);

    // disable any sig pipe exceptions
    if (sd) {
        int set = 1;
        setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
    }
    return sd;
}

int
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
{
    int result = -1;
    switch (option)
    {
        case ENET_SOCKOPT_NONBLOCK:
#ifdef HAS_FCNTL
            result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
#else
            result = ioctl (socket, FIONBIO, & value);
#endif
            break;

        case ENET_SOCKOPT_BROADCAST:
            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_REUSEADDR:
            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_RCVBUF:
            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_SNDBUF:
            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_RCVTIMEO:
            result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_SNDTIMEO:
            result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
            break;

        default:
            break;
    }
    return result == -1 ? -1 : 0;
}

int
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
    struct sockaddr_in sin;

    memset (& sin, 0, sizeof (struct sockaddr_in));

    sin.sin_family = AF_INET;
    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
    sin.sin_addr.s_addr = address -> host;

    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
}

ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
    int result;
    struct sockaddr_in sin;
    socklen_t sinLength = sizeof (struct sockaddr_in);

    result = accept (socket,
                     address != NULL ? (struct sockaddr *) & sin : NULL,
                     address != NULL ? & sinLength : NULL);

    if (result == -1)
      return ENET_SOCKET_NULL;

    if (address != NULL)
    {
        address -> host = (enet_uint32) sin.sin_addr.s_addr;
        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
    }

    return result;
}

void
enet_socket_destroy (ENetSocket socket)
{
    close (socket);
}

int
enet_socket_send (ENetSocket socket,
                  const ENetAddress * address,
                  const ENetBuffer * buffers,
                  size_t bufferCount)
{
    struct msghdr msgHdr;
    struct sockaddr_in sin;
    int sentLength;

    memset (& msgHdr, 0, sizeof (struct msghdr));

    if (address != NULL)
    {
        memset (& sin, 0, sizeof (struct sockaddr_in));

        sin.sin_family = AF_INET;
        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
        sin.sin_addr.s_addr = address -> host;

        msgHdr.msg_name = & sin;
        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
    }

    msgHdr.msg_iov = (struct iovec *) buffers;
    msgHdr.msg_iovlen = bufferCount;

    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);

    if (sentLength == -1)
    {
       if (errno == EWOULDBLOCK)
         return 0;

       return -1;
    }

    return sentLength;
}

int
enet_socket_receive (ENetSocket socket,
                     ENetAddress * address,
                     ENetBuffer * buffers,
                     size_t bufferCount)
{
    struct msghdr msgHdr;
    struct sockaddr_in sin;
    int recvLength;

    memset (& msgHdr, 0, sizeof (struct msghdr));

    if (address != NULL)
    {
        msgHdr.msg_name = & sin;
        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
    }

    msgHdr.msg_iov = (struct iovec *) buffers;
    msgHdr.msg_iovlen = bufferCount;

    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);

    if (recvLength == -1)
    {
       if (errno == EWOULDBLOCK)
         return 0;

       return -1;
    }

#ifdef HAS_MSGHDR_FLAGS
    if (msgHdr.msg_flags & MSG_TRUNC)
      return -1;
#endif

    if (address != NULL)
    {
        address -> host = (enet_uint32) sin.sin_addr.s_addr;
        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
    }

    return recvLength;
}

int
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
{
    struct timeval timeVal;

    timeVal.tv_sec = timeout / 1000;
    timeVal.tv_usec = (timeout % 1000) * 1000;

    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
}

int
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
{
#ifdef HAS_POLL
    struct pollfd pollSocket;
    int pollCount;

    pollSocket.fd = socket;
    pollSocket.events = 0;

    if (* condition & ENET_SOCKET_WAIT_SEND)
      pollSocket.events |= POLLOUT;

    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
      pollSocket.events |= POLLIN;

    pollCount = poll (& pollSocket, 1, timeout);

    if (pollCount < 0)
      return -1;

    * condition = ENET_SOCKET_WAIT_NONE;

    if (pollCount == 0)
      return 0;

    if (pollSocket.revents & POLLOUT)
      * condition |= ENET_SOCKET_WAIT_SEND;

    if (pollSocket.revents & POLLIN)
      * condition |= ENET_SOCKET_WAIT_RECEIVE;

    return 0;
#else
    fd_set readSet, writeSet;
    struct timeval timeVal;
    int selectCount;

    timeVal.tv_sec = timeout / 1000;
    timeVal.tv_usec = (timeout % 1000) * 1000;

    FD_ZERO (& readSet);
    FD_ZERO (& writeSet);

    if (* condition & ENET_SOCKET_WAIT_SEND)
      FD_SET (socket, & writeSet);

    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
      FD_SET (socket, & readSet);

    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);

    if (selectCount < 0)
      return -1;

    * condition = ENET_SOCKET_WAIT_NONE;

    if (selectCount == 0)
      return 0;

    if (FD_ISSET (socket, & writeSet))
      * condition |= ENET_SOCKET_WAIT_SEND;

    if (FD_ISSET (socket, & readSet))
      * condition |= ENET_SOCKET_WAIT_RECEIVE;

    return 0;
#endif
}

#endif

<commit_msg>fix for platform that don't have SO_NOSIGPIPE<commit_after>/**
 @file  unix.c
 @brief ENet Unix system specific functions
*/
#ifndef WIN32

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>

#define ENET_BUILDING_LIB 1
#include "enet/enet.h"

#ifdef __APPLE__
#undef HAS_POLL
#ifndef HAS_SOCKLEN_T
#define HAS_SOCKLEN_T
#endif
#ifndef HAS_FCNTL
#define HAS_FCNTL
#endif
#endif

#ifdef HAS_FCNTL
#include <fcntl.h>
#endif

#ifdef HAS_POLL
#include <sys/poll.h>
#endif

#if defined(__socklen_t_defined) && !defined(HAS_SOCKLEN_T)
#define HAS_SOCKLEN_T
#endif

#ifndef HAS_SOCKLEN_T
typedef int socklen_t;
#endif

#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif

static enet_uint32 timeBase = 0;

int
enet_initialize (void)
{
    return 0;
}

void
enet_deinitialize (void)
{
}

enet_uint32
enet_time_get (void)
{
    struct timeval timeVal;

    gettimeofday (& timeVal, NULL);

    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
}

void
enet_time_set (enet_uint32 newTimeBase)
{
    struct timeval timeVal;

    gettimeofday (& timeVal, NULL);

    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
}

int
enet_address_set_host (ENetAddress * address, const char * name)
{
    struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYNAME_R
    struct hostent hostData;
    char buffer [2048];
    int errnum;

#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
#endif
#else
    hostEntry = gethostbyname (name);
#endif

    if (hostEntry == NULL ||
        hostEntry -> h_addrtype != AF_INET)
    {
#ifdef HAS_INET_PTON
        if (! inet_pton (AF_INET, name, & address -> host))
#else
        if (! inet_aton (name, (struct in_addr *) & address -> host))
#endif
            return -1;
        return 0;
    }

    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];

    return 0;
}

int
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
{
#ifdef HAS_INET_NTOP
    if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
#else
    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
    if (addr != NULL)
        strncpy (name, addr, nameLength);
    else
#endif
        return -1;
    return 0;
}

int
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
{
    struct in_addr in;
    struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYADDR_R
    struct hostent hostData;
    char buffer [2048];
    int errnum;

    in.s_addr = address -> host;

#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
    hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
#endif
#else
    in.s_addr = address -> host;

    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
#endif

    if (hostEntry == NULL)
      return enet_address_get_host_ip (address, name, nameLength);

    strncpy (name, hostEntry -> h_name, nameLength);

    return 0;
}

int
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
{
    struct sockaddr_in sin;

    memset (& sin, 0, sizeof (struct sockaddr_in));

    sin.sin_family = AF_INET;

    if (address != NULL)
    {
       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
       sin.sin_addr.s_addr = address -> host;
    }
    else
    {
       sin.sin_port = 0;
       sin.sin_addr.s_addr = INADDR_ANY;
    }

    return bind (socket,
                 (struct sockaddr *) & sin,
                 sizeof (struct sockaddr_in));
}

int
enet_socket_listen (ENetSocket socket, int backlog)
{
    return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
}

ENetSocket
enet_socket_create (ENetSocketType type)
{
    ENetSocket sd = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);

    // disable any sig pipe exceptions
#ifdef SO_NOSIGPIPE
    if (sd) {
        int set = 1;
        setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
    }
#endif
    return sd;
}

int
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
{
    int result = -1;
    switch (option)
    {
        case ENET_SOCKOPT_NONBLOCK:
#ifdef HAS_FCNTL
            result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
#else
            result = ioctl (socket, FIONBIO, & value);
#endif
            break;

        case ENET_SOCKOPT_BROADCAST:
            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_REUSEADDR:
            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_RCVBUF:
            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_SNDBUF:
            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_RCVTIMEO:
            result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int));
            break;

        case ENET_SOCKOPT_SNDTIMEO:
            result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
            break;

        default:
            break;
    }
    return result == -1 ? -1 : 0;
}

int
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
    struct sockaddr_in sin;

    memset (& sin, 0, sizeof (struct sockaddr_in));

    sin.sin_family = AF_INET;
    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
    sin.sin_addr.s_addr = address -> host;

    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
}

ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
    int result;
    struct sockaddr_in sin;
    socklen_t sinLength = sizeof (struct sockaddr_in);

    result = accept (socket,
                     address != NULL ? (struct sockaddr *) & sin : NULL,
                     address != NULL ? & sinLength : NULL);

    if (result == -1)
      return ENET_SOCKET_NULL;

    if (address != NULL)
    {
        address -> host = (enet_uint32) sin.sin_addr.s_addr;
        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
    }

    return result;
}

void
enet_socket_destroy (ENetSocket socket)
{
    close (socket);
}

int
enet_socket_send (ENetSocket socket,
                  const ENetAddress * address,
                  const ENetBuffer * buffers,
                  size_t bufferCount)
{
    struct msghdr msgHdr;
    struct sockaddr_in sin;
    int sentLength;

    memset (& msgHdr, 0, sizeof (struct msghdr));

    if (address != NULL)
    {
        memset (& sin, 0, sizeof (struct sockaddr_in));

        sin.sin_family = AF_INET;
        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
        sin.sin_addr.s_addr = address -> host;

        msgHdr.msg_name = & sin;
        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
    }

    msgHdr.msg_iov = (struct iovec *) buffers;
    msgHdr.msg_iovlen = bufferCount;

    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);

    if (sentLength == -1)
    {
       if (errno == EWOULDBLOCK)
         return 0;

       return -1;
    }

    return sentLength;
}

int
enet_socket_receive (ENetSocket socket,
                     ENetAddress * address,
                     ENetBuffer * buffers,
                     size_t bufferCount)
{
    struct msghdr msgHdr;
    struct sockaddr_in sin;
    int recvLength;

    memset (& msgHdr, 0, sizeof (struct msghdr));

    if (address != NULL)
    {
        msgHdr.msg_name = & sin;
        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
    }

    msgHdr.msg_iov = (struct iovec *) buffers;
    msgHdr.msg_iovlen = bufferCount;

    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);

    if (recvLength == -1)
    {
       if (errno == EWOULDBLOCK)
         return 0;

       return -1;
    }

#ifdef HAS_MSGHDR_FLAGS
    if (msgHdr.msg_flags & MSG_TRUNC)
      return -1;
#endif

    if (address != NULL)
    {
        address -> host = (enet_uint32) sin.sin_addr.s_addr;
        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
    }

    return recvLength;
}

int
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
{
    struct timeval timeVal;

    timeVal.tv_sec = timeout / 1000;
    timeVal.tv_usec = (timeout % 1000) * 1000;

    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
}

int
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
{
#ifdef HAS_POLL
    struct pollfd pollSocket;
    int pollCount;

    pollSocket.fd = socket;
    pollSocket.events = 0;

    if (* condition & ENET_SOCKET_WAIT_SEND)
      pollSocket.events |= POLLOUT;

    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
      pollSocket.events |= POLLIN;

    pollCount = poll (& pollSocket, 1, timeout);

    if (pollCount < 0)
      return -1;

    * condition = ENET_SOCKET_WAIT_NONE;

    if (pollCount == 0)
      return 0;

    if (pollSocket.revents & POLLOUT)
      * condition |= ENET_SOCKET_WAIT_SEND;

    if (pollSocket.revents & POLLIN)
      * condition |= ENET_SOCKET_WAIT_RECEIVE;

    return 0;
#else
    fd_set readSet, writeSet;
    struct timeval timeVal;
    int selectCount;

    timeVal.tv_sec = timeout / 1000;
    timeVal.tv_usec = (timeout % 1000) * 1000;

    FD_ZERO (& readSet);
    FD_ZERO (& writeSet);

    if (* condition & ENET_SOCKET_WAIT_SEND)
      FD_SET (socket, & writeSet);

    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
      FD_SET (socket, & readSet);

    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);

    if (selectCount < 0)
      return -1;

    * condition = ENET_SOCKET_WAIT_NONE;

    if (selectCount == 0)
      return 0;

    if (FD_ISSET (socket, & writeSet))
      * condition |= ENET_SOCKET_WAIT_SEND;

    if (FD_ISSET (socket, & readSet))
      * condition |= ENET_SOCKET_WAIT_RECEIVE;

    return 0;
#endif
}

#endif

<|endoftext|>


<commit_before>#include <iostream>
#include <GitVersion.h>
#include "emmintrin.h"
#include "include/perf.h"
#include <sys/stat.h>
#include <string>
#include <unistd.h>
#include <utils/BMPImage.h>
#include <encoder/Encoder.h>
#include <decoder/Decoder.h>

using namespace std;

inline bool exists_image(const std::string& name) {
  struct stat buffer;
  return (stat (name.c_str(), &buffer) == 0);
}

#ifdef COUNT_FLOPS
    struct global_op_count __GLOBAL_OP_COUNT;
#endif

#ifdef COUNT_DETAIL_CYCLES
    struct global_function_cycle_count __COUNT_DETAIL_CYCLES;
#endif
void init_counting_flops(){
#ifdef COUNT_FLOPS
    __GLOBAL_OP_COUNT.int_adds=0;
    __GLOBAL_OP_COUNT.int_mults=0;
    __GLOBAL_OP_COUNT.fp_adds=0;
    __GLOBAL_OP_COUNT.fp_mults=0;
#endif
}

void init_counting_cycles(){
#ifdef COUNT_DETAIL_CYCLES
    __COUNT_DETAIL_CYCLES.get_average_pixel_cycles=0;
    __COUNT_DETAIL_CYCLES.get_error_cycles=0;
    __COUNT_DETAIL_CYCLES.get_scale_factor_cycles=0;
    __COUNT_DETAIL_CYCLES.down_sample_cycles=0;
    __COUNT_DETAIL_CYCLES.ifs_transformation_execute_cycles=0;
#endif
}
void print_detailed_cycles(){
#ifdef COUNT_DETAIL_CYCLES
    cout<<"get_average_pixel_cycles: "<<__COUNT_DETAIL_CYCLES.get_average_pixel_cycles<<endl;
    cout<<"get_error_cycles: "<<__COUNT_DETAIL_CYCLES.get_error_cycles<<endl;
    cout<<"get_scale_factor_cycles: "<<__COUNT_DETAIL_CYCLES.get_scale_factor_cycles<<endl;
    cout<<"down_sample_cycles: "<<__COUNT_DETAIL_CYCLES.down_sample_cycles<<endl;
    cout<<"ifs_transformation_execute_cycles: "<<__COUNT_DETAIL_CYCLES.ifs_transformation_execute_cycles<<endl;

#endif
}

void print_op_count(const char* name){
#ifdef COUNT_FLOPS
    cout<<"### Performance count for "<<name<<endl;
    cout<<"int add: "<<__GLOBAL_OP_COUNT.int_adds<<endl;
    cout<<"int mul: "<<__GLOBAL_OP_COUNT.int_mults<<endl;
    cout<<"fp add: "<<__GLOBAL_OP_COUNT.fp_adds<<endl;
    cout<<"fp mul: "<<__GLOBAL_OP_COUNT.fp_mults<<endl;
#endif
}

void print_detail_cycles(const char* name){
#ifdef COUNT_DETAIL_CYCLES

#endif
}

int main(int argc, char** argv){
    cout<<"    ______           __        ______                __        __   "<<endl;
    cout<<"   / ____/___ ______/ /_      / ____/________ ______/ /_____ _/ /   "<<endl;
    cout<<"  / /_  / __ `/ ___/ __/_____/ /_  / ___/ __ `/ ___/ __/ __ `/ /    "<<endl;
    cout<<" / __/ / /_/ (__  ) /_/_____/ __/ / /  / /_/ / /__/ /_/ /_/ / /     "<<endl;
    cout<<"/_/    \\__,_/____/\\__/     /_/   /_/   \\__,_/\\___/\\__/\\__,_/_/"<<endl;
    cout<<endl;
    cout<<"Git version: "<<" "<<s_GIT_SHA1_HASH<<" "<<s_GIT_REFSPEC<<endl;
    cout<<"Build type:"<<UTILS_TYPE<<MATCHING_TYPE<<endl;

    // Load some parameters
    bool usage = true;
    int verb;
    u_int32_t threshold = 100;
    string image_path;
    u_int32_t maxphases = 5;
    string outputFile="result.bmp";
    string testFile="log.txt";
    bool decode=true;
    for(int i=1; i<argc && usage; i++) {
        string param(argv[i]);
        if (param == "-v" && i + 1 < argc)
            verb = atoi(argv[i + 1]);
        else if (param == "-t" && i + 1 < argc)
            threshold = atoi(argv[i + 1]);
        else if (param == "-p" && i + 1 < argc)
            maxphases = atoi(argv[i + 1]);
        else if(param=="-o" && i + 1 < argc){
            outputFile=argv[i + 1];
        }
        else if(param=="-f" && i + 1 < argc){
            testFile=argv[i + 1];
        }
        else if(param=="-d" && i+1<argc){
            decode=(string(argv[i+1])==string("1"))?true:false;
        }
        if (param.at(0) == '-') i++;
        else {
            image_path = param;
            usage = false;
        }
    }

    if (argc < 2) {
        std::cout << "Usage: fractal-compression <path-to-image>\n";
        return ERR_NO_IMAGE_PATH;
    }

    if (!exists_image(image_path.c_str())) {
        std::cout << "Provided image does not exist\n";
        return ERR_NO_IMAGE_PATH;
    }

    perf_init();

    BMPImage img(image_path.c_str());
    img.Load();

    // Encoding part
    Encoder enc;
    Transforms transforms;
    ifs_trans_init_transformations(&transforms, img.GetChannels());
    init_counting_flops();
    init_counting_cycles();
    cycles_count_start();

    enc.Encode(img, &transforms, threshold);

    int64_t encodeCycles = cycles_count_stop ();
    print_detailed_cycles();
    print_op_count("encoder");

    printf("Image height: %d, width: %d\n", img.GetHeight(), img.GetWidth());

    // Decoder part
    int64_t decodeCycles=0;
    if(decode){
        BMPImage result(outputFile, img.GetHeight(), img.GetWidth(), transforms.channels);
        Decoder dec;
        init_counting_flops();
        cycles_count_start ();
        dec.Decode(&transforms, result, maxphases);
        decodeCycles = cycles_count_stop ();
        print_op_count("decoder");
        result.Save();
    }

    // Calculate compression ratio
    int64_t transformationsSize=0;
    int64_t transformationNumber=0;
    for(int i=0;i<transforms.channels;++i){
        transformationNumber+=transforms.ch[i].elements;
    }

    transformationsSize=transformationNumber*sizeof(struct ifs_transformation);
    int64_t originalSize=img.getSize();
    double compressionRatio=(double)originalSize/(double)transformationsSize;

    cout<<"#### PERFORMANCE RESULTS #####"<<endl;
    cout<<"Encode cycles: "<<encodeCycles<<endl;
    cout<<"Decode cycles: "<<decodeCycles<<endl;
    cout<<"No. of transformations: "<<transformationNumber<<endl;
    cout<<"Image size: w: "<<img.GetWidth()<<" h: "<<img.GetHeight()<<endl;
    cout<<"Compression ratio: "<<compressionRatio<<endl;

    //Free memory
    ifs_trans_clear_list(&transforms);

    return 0;
}
<commit_msg>Added printf value<commit_after>#include <iostream>
#include <GitVersion.h>
#include "emmintrin.h"
#include "include/perf.h"
#include <sys/stat.h>
#include <string>
#include <unistd.h>
#include <utils/BMPImage.h>
#include <encoder/Encoder.h>
#include <decoder/Decoder.h>

using namespace std;

inline bool exists_image(const std::string& name) {
  struct stat buffer;
  return (stat (name.c_str(), &buffer) == 0);
}

#ifdef COUNT_FLOPS
    struct global_op_count __GLOBAL_OP_COUNT;
#endif

#ifdef COUNT_DETAIL_CYCLES
    struct global_function_cycle_count __COUNT_DETAIL_CYCLES;
#endif
void init_counting_flops(){
#ifdef COUNT_FLOPS
    __GLOBAL_OP_COUNT.int_adds=0;
    __GLOBAL_OP_COUNT.int_mults=0;
    __GLOBAL_OP_COUNT.fp_adds=0;
    __GLOBAL_OP_COUNT.fp_mults=0;
#endif
}

void init_counting_cycles(){
#ifdef COUNT_DETAIL_CYCLES
    __COUNT_DETAIL_CYCLES.get_average_pixel_cycles=0;
    __COUNT_DETAIL_CYCLES.get_error_cycles=0;
    __COUNT_DETAIL_CYCLES.get_scale_factor_cycles=0;
    __COUNT_DETAIL_CYCLES.down_sample_cycles=0;
    __COUNT_DETAIL_CYCLES.ifs_transformation_execute_cycles=0;
#endif
}
void print_detailed_cycles(){
#ifdef COUNT_DETAIL_CYCLES
    cout<<"get_average_pixel_cycles: "<<__COUNT_DETAIL_CYCLES.get_average_pixel_cycles<<endl;
    cout<<"get_error_cycles: "<<__COUNT_DETAIL_CYCLES.get_error_cycles<<endl;
    cout<<"get_scale_factor_cycles: "<<__COUNT_DETAIL_CYCLES.get_scale_factor_cycles<<endl;
    cout<<"down_sample_cycles: "<<__COUNT_DETAIL_CYCLES.down_sample_cycles<<endl;
    cout<<"ifs_transformation_execute_cycles: "<<__COUNT_DETAIL_CYCLES.ifs_transformation_execute_cycles<<endl;

#endif
}

void print_op_count(const char* name){
#ifdef COUNT_FLOPS
    cout<<"### Performance count for "<<name<<endl;
    cout<<"int add: "<<__GLOBAL_OP_COUNT.int_adds<<endl;
    cout<<"int mul: "<<__GLOBAL_OP_COUNT.int_mults<<endl;
    cout<<"fp add: "<<__GLOBAL_OP_COUNT.fp_adds<<endl;
    cout<<"fp mul: "<<__GLOBAL_OP_COUNT.fp_mults<<endl;
#endif
}

void print_detail_cycles(const char* name){
#ifdef COUNT_DETAIL_CYCLES

#endif
}

int main(int argc, char** argv){
    cout<<"    ______           __        ______                __        __   "<<endl;
    cout<<"   / ____/___ ______/ /_      / ____/________ ______/ /_____ _/ /   "<<endl;
    cout<<"  / /_  / __ `/ ___/ __/_____/ /_  / ___/ __ `/ ___/ __/ __ `/ /    "<<endl;
    cout<<" / __/ / /_/ (__  ) /_/_____/ __/ / /  / /_/ / /__/ /_/ /_/ / /     "<<endl;
    cout<<"/_/    \\__,_/____/\\__/     /_/   /_/   \\__,_/\\___/\\__/\\__,_/_/"<<endl;
    cout<<endl;
    cout<<"Git version: "<<" "<<s_GIT_SHA1_HASH<<" "<<s_GIT_REFSPEC<<endl;
    cout<<"Build type:"<<UTILS_TYPE<<MATCHING_TYPE<<endl;

    // Load some parameters
    bool usage = true;
    int verb;
    u_int32_t threshold = 100;
    string image_path;
    u_int32_t maxphases = 5;
    string outputFile="result.bmp";
    string testFile="log.txt";
    bool decode=true;
    for(int i=1; i<argc && usage; i++) {
        string param(argv[i]);
        if (param == "-v" && i + 1 < argc)
            verb = atoi(argv[i + 1]);
        else if (param == "-t" && i + 1 < argc)
            threshold = atoi(argv[i + 1]);
        else if (param == "-p" && i + 1 < argc)
            maxphases = atoi(argv[i + 1]);
        else if(param=="-o" && i + 1 < argc){
            outputFile=argv[i + 1];
        }
        else if(param=="-f" && i + 1 < argc){
            testFile=argv[i + 1];
        }
        else if(param=="-d" && i+1<argc){
            decode=(string(argv[i+1])==string("1"))?true:false;
        }
        if (param.at(0) == '-') i++;
        else {
            image_path = param;
            usage = false;
        }
    }

    if (argc < 2) {
        std::cout << "Usage: fractal-compression <path-to-image>\n";
        return ERR_NO_IMAGE_PATH;
    }

    if (!exists_image(image_path.c_str())) {
        std::cout << "Provided image does not exist\n";
        return ERR_NO_IMAGE_PATH;
    }

    perf_init();

    BMPImage img(image_path.c_str());
    img.Load();

    // Encoding part
    Encoder enc;
    Transforms transforms;
    ifs_trans_init_transformations(&transforms, img.GetChannels());
    init_counting_flops();
    init_counting_cycles();
    cycles_count_start();

    enc.Encode(img, &transforms, threshold);

    int64_t encodeCycles = cycles_count_stop ();
    print_detailed_cycles();
    print_op_count("encoder");

    printf("Image height: %d, width: %d\n", img.GetHeight(), img.GetWidth());

    // Decoder part
    int64_t decodeCycles=0;
    if(decode){
        BMPImage result(outputFile, img.GetHeight(), img.GetWidth(), transforms.channels);
        Decoder dec;
        init_counting_flops();
        cycles_count_start ();
        dec.Decode(&transforms, result, maxphases);
        decodeCycles = cycles_count_stop ();
        print_op_count("decoder");
        result.Save();
    }else{
        cout<<"Not running decoding"<<endl;
    }

    // Calculate compression ratio
    int64_t transformationsSize=0;
    int64_t transformationNumber=0;
    for(int i=0;i<transforms.channels;++i){
        transformationNumber+=transforms.ch[i].elements;
    }

    transformationsSize=transformationNumber*sizeof(struct ifs_transformation);
    int64_t originalSize=img.getSize();
    double compressionRatio=(double)originalSize/(double)transformationsSize;

    cout<<"#### PERFORMANCE RESULTS #####"<<endl;
    cout<<"Encode cycles: "<<encodeCycles<<endl;
    cout<<"Decode cycles: "<<decodeCycles<<endl;
    cout<<"No. of transformations: "<<transformationNumber<<endl;
    cout<<"Image size: w: "<<img.GetWidth()<<" h: "<<img.GetHeight()<<endl;
    cout<<"Compression ratio: "<<compressionRatio<<endl;

    //Free memory
    ifs_trans_clear_list(&transforms);

    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <boost/asio.hpp>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/service.h>

#include "vtrc-common/vtrc-thread-pool.h"
#include "vtrc-client-base/vtrc-client.h"
#include "protocol/vtrc-rpc-lowlevel.pb.h"

#include <boost/random.hpp>
#include <boost/random/random_device.hpp>

void on_connect( const boost::system::error_code &err )
{
    std::cout << "connected "
              << err.value( ) << " "
              << err.message( ) << "\n";
}

using namespace vtrc;

int main( )
{

    common::thread_pool tp(4);
    client::vtrc_client cl( tp.get_io_service( ) );

    cl.connect( "127.0.0.1", "44667" );
    ///cl.async_connect( "127.0.0.1", "44667", on_connect );

    sleep( 2 );

    vtrc_rpc_lowlevel::test_rpc::Stub s( cl.get_channel( ).get( ) );

    vtrc_rpc_lowlevel::message_info mi;

    for( int i=0; i<10000000; ++i ) {
        s.test( NULL, &mi, &mi, NULL );
        std::cout << "response: " << mi.message_type( ) << "\n";
    }

    tp.join_all( );

    return 0;

}
<commit_msg>protocol<commit_after>#include <iostream>
#include <boost/asio.hpp>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/service.h>

#include "vtrc-common/vtrc-thread-pool.h"
#include "vtrc-client-base/vtrc-client.h"
#include "protocol/vtrc-rpc-lowlevel.pb.h"

#include <boost/random.hpp>
#include <boost/random/random_device.hpp>

void on_connect( const boost::system::error_code &err )
{
    std::cout << "connected "
              << err.value( ) << " "
              << err.message( ) << "\n";
}

using namespace vtrc;

int main( )
{

    common::thread_pool tp(4);
    client::vtrc_client cl( tp.get_io_service( ) );

    cl.connect( "127.0.0.1", "44667" );
    ///cl.async_connect( "127.0.0.1", "44667", on_connect );

    sleep( 2 );

    vtrc_rpc_lowlevel::test_rpc::Stub s( cl.get_channel( ).get( ) );

    vtrc_rpc_lowlevel::message_info mi;

    for( int i=0; i<10000000; ++i ) {
        s.test( NULL, &mi, &mi, NULL );
        std::cout << "response: " << mi.message_type( ) << "\n";
    }

    tp.join_all( );

    return 0;

}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Mirants Lu. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "voyager/core/timerlist.h"
#include "voyager/util/logging.h"
#include "voyager/util/timeops.h"

namespace voyager {

class Timer {
 private:
  friend class TimerList;

  Timer(uint64_t value, uint64_t interval, const TimerProcCallback& cb)
      : micros_value(value),
        micros_interval(interval),
        timerproc_cb(cb),
        repeat(false) {
    if (micros_interval > 0) {
      repeat = true;
    }
  }

  Timer(uint64_t value, uint64_t interval, TimerProcCallback&& cb)
      : micros_value(value),
        micros_interval(interval),
        timerproc_cb(std::move(cb)),
        repeat(false) {
    if (micros_interval > 0) {
      repeat = true;
    }
  }

  ~Timer() {
  }

  uint64_t micros_value;
  uint64_t micros_interval;
  TimerProcCallback timerproc_cb;
  bool repeat;
};

TimerList::TimerList(EventLoop* ev)
    : eventloop_(CHECK_NOTNULL(ev)) {
}

TimerList::~TimerList() {
  for (auto& t : timer_ptrs_) {
    delete t;
  }
}

TimerId TimerList::Insert(uint64_t micros_value,
                          uint64_t micros_interval,
                          const TimerProcCallback& cb) {
  TimerId timer(micros_value, new Timer(micros_value, micros_interval, cb));
  eventloop_->RunInLoop([this, timer]() {
    InsertInLoop(timer);
  });
  return timer;
}

TimerId TimerList::Insert(uint64_t micros_value,
                          uint64_t micros_interval,
                          TimerProcCallback&& cb) {
  TimerId timer(micros_value,
                new Timer(micros_value, micros_interval, std::move(cb)));
  eventloop_->RunInLoop([this, timer]() {
    InsertInLoop(timer);
  });
  return timer;
}

void TimerList::Erase(TimerId timer) {
  eventloop_->RunInLoop([this, timer]() {
    EraseInLoop(timer);
  });
}

void TimerList::InsertInLoop(TimerId timer) {
  eventloop_->AssertInMyLoop();
  timers_.insert(timer);
  timer_ptrs_.insert(timer.second);
}

void TimerList::EraseInLoop(TimerId timer) {
  eventloop_->AssertInMyLoop();
  std::set<Timer*>::iterator it = timer_ptrs_.find(timer.second);
  if (it != timer_ptrs_.end()) {
    timer.first = timer.second->micros_value;
    timers_.erase(timer);
    delete *it;
    timer_ptrs_.erase(it);
  }
}

uint64_t TimerList::TimeoutMicros() const {
  eventloop_->AssertInMyLoop();
  if (timers_.empty()) {
    return -1;
  }
  std::set<TimerId>::iterator it = timers_.begin();
  if (it->first < timeops::NowMicros()) {
    return 0;
  } else {
    return (it->first - timeops::NowMicros());
  }
}

void TimerList::RunTimerProcs() {
  eventloop_->AssertInMyLoop();
  if (timers_.empty()) {
    return;
  }

  uint64_t micros_now = timeops::NowMicros();
  std::set<TimerId>::iterator it;
  while (true) {
    it = timers_.begin();
    if (it != timers_.end() && it->first <= micros_now) {
      Timer* t = it->second;
      timers_.erase(it);
      t->timerproc_cb();
      if (t->repeat) {
        t->micros_value += t->micros_interval;
        TimerId timer(t->micros_value, t);
        timers_.insert(timer);
      } else {
        delete t;
        timer_ptrs_.erase(t);
      }
    } else {
      break;
    }
  }
}

}  // namespace voyager
<commit_msg>fix timer<commit_after>// Copyright (c) 2016 Mirants Lu. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "voyager/core/timerlist.h"
#include "voyager/util/logging.h"
#include "voyager/util/timeops.h"

namespace voyager {

class Timer {
 private:
  friend class TimerList;

  Timer(uint64_t value, uint64_t interval, const TimerProcCallback& cb)
      : micros_value(value),
        micros_interval(interval),
        timerproc_cb(cb),
        repeat(false) {
    if (micros_interval > 0) {
      repeat = true;
    }
  }

  Timer(uint64_t value, uint64_t interval, TimerProcCallback&& cb)
      : micros_value(value),
        micros_interval(interval),
        timerproc_cb(std::move(cb)),
        repeat(false) {
    if (micros_interval > 0) {
      repeat = true;
    }
  }

  ~Timer() {
  }

  uint64_t micros_value;
  uint64_t micros_interval;
  TimerProcCallback timerproc_cb;
  bool repeat;
};

TimerList::TimerList(EventLoop* ev)
    : eventloop_(CHECK_NOTNULL(ev)) {
}

TimerList::~TimerList() {
  for (auto& t : timer_ptrs_) {
    delete t;
  }
}

TimerId TimerList::Insert(uint64_t micros_value,
                          uint64_t micros_interval,
                          const TimerProcCallback& cb) {
  TimerId timer(micros_value, new Timer(micros_value, micros_interval, cb));
  eventloop_->RunInLoop([this, timer]() {
    InsertInLoop(timer);
  });
  return timer;
}

TimerId TimerList::Insert(uint64_t micros_value,
                          uint64_t micros_interval,
                          TimerProcCallback&& cb) {
  TimerId timer(micros_value,
                new Timer(micros_value, micros_interval, std::move(cb)));
  eventloop_->RunInLoop([this, timer]() {
    InsertInLoop(timer);
  });
  return timer;
}

void TimerList::Erase(TimerId timer) {
  eventloop_->RunInLoop([this, timer]() {
    EraseInLoop(timer);
  });
}

void TimerList::InsertInLoop(TimerId timer) {
  eventloop_->AssertInMyLoop();
  timers_.insert(timer);
  timer_ptrs_.insert(timer.second);
}

void TimerList::EraseInLoop(TimerId timer) {
  eventloop_->AssertInMyLoop();
  std::set<Timer*>::iterator it = timer_ptrs_.find(timer.second);
  if (it != timer_ptrs_.end()) {
    timer.first = timer.second->micros_value;
    timers_.erase(timer);
    delete *it;
    timer_ptrs_.erase(it);
  }
}

uint64_t TimerList::TimeoutMicros() const {
  eventloop_->AssertInMyLoop();
  if (timers_.empty()) {
    return -1;
  }
  std::set<TimerId>::iterator it = timers_.begin();
  uint64_t now = timeops::NowMicros();
  if (it->first <= now) {
    return 0;
  } else {
    return (it->first - now);
  }
}

void TimerList::RunTimerProcs() {
  eventloop_->AssertInMyLoop();
  if (timers_.empty()) {
    return;
  }

  uint64_t micros_now = timeops::NowMicros();
  std::set<TimerId>::iterator it;
  while (true) {
    it = timers_.begin();
    if (it != timers_.end() && it->first <= micros_now) {
      Timer* t = it->second;
      timers_.erase(it);
      TimerProcCallback cb = t->timerproc_cb;
      if (t->repeat) {
        t->micros_value += t->micros_interval;
        TimerId timer(t->micros_value, t);
        timers_.insert(timer);
      } else {
        delete t;
        timer_ptrs_.erase(t);
      }
      // 为了避免周期定时无法移除定时器的问题。
      cb();
    } else {
      break;
    }
  }
}

}  // namespace voyager
<|endoftext|>


<commit_before>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <time.h>

#include "dwr.h"
#include "widgets.h"

CheckBox::CheckBox(const char flag, const QString &text, QWidget *parent) :
        QCheckBox(text, parent)
{
    this->flag = flag;
}

char CheckBox::getFlag()
{
    if (this->isChecked()) {
        return this->flag;
    }
    return NO_FLAG;
}

void CheckBox::stateChanged(int state)
{
    super::stateChanged(state);
}

bool CheckBox::updateState(QString flags)
{
    bool checked = flags.indexOf(QChar(this->flag)) >= 0;
    this->setChecked(checked);
    return checked;
}

LevelComboBox::LevelComboBox(QWidget *parent) : QComboBox(parent)
{
    this->addItem("Normal");
    this->addItem("Fast");
    this->addItem("Very Fast");
}

char LevelComboBox::getFlag()
{
    switch(this->currentIndex()) {
        case 1:
           return 'f';
        case 2:
            return 'F';
        default:
            return NO_FLAG;
    }
}

bool LevelComboBox::updateState(QString flags)
{
    if (flags.indexOf(QChar('f')) >= 0) {
        this->setCurrentIndex(1);
        return true;
    } else {
        if (flags.indexOf(QChar('F')) >= 0) {
            this->setCurrentIndex(2);
            return true;
        }
    }
    this->setCurrentIndex(0);
    return false;
}

ButtonEntry::ButtonEntry(QWidget *parent) :
        QWidget(parent)
{
    QVBoxLayout *vbox = new QVBoxLayout();
    QHBoxLayout *hbox = new QHBoxLayout();
    this->textBox = new QLineEdit(this);
    this->button = new QPushButton("Click", this);
    this->label = new QLabel("", this);
    vbox->addWidget(this->label);
    hbox->addWidget(this->textBox);
    hbox->addWidget(this->button);
    vbox->addLayout(hbox);
    this->setLayout(vbox);
    connect(this->button, SIGNAL(clicked()), this, SLOT(handleButton()));
    connect(this->textBox, SIGNAL(textEdited(QString)), this, SLOT(handleEdit(QString)));
}

QString ButtonEntry::text()
{
    return this->textBox->text();
}

void ButtonEntry::setText(QString text)
{
    this->textBox->setText(text);
}

FileEntry::FileEntry(QWidget *parent) : ButtonEntry(parent)
{
    this->button->setText("Browse...");
    this->label->setText("ROM File");
}

void FileEntry::handleButton()
{
    QString filename = QFileDialog::getOpenFileName(
           this, "Choose the ROM file", "./", "NES ROM Files (*.nes)");
    this->textBox->setText(filename);
}

DirEntry::DirEntry(QWidget *parent) : ButtonEntry(parent)
{
    this->button->setText("Browse...");
#ifdef _WIN32
    this->label->setText("Output Folder");
#else
    this->label->setText("Output Directory");
#endif
}

void DirEntry::handleButton()
{
    QString dirName = QFileDialog::getExistingDirectory(this,
#ifdef _WIN32
            "Choose the output folder",
#else
            "Choose the output directory",
#endif
            "./");
    this->textBox->setText(dirName);
}

SeedEntry::SeedEntry(QWidget *parent) : ButtonEntry(parent)
{
    this->button->setText("Random");
    this->label->setText("Seed");
    this->handleButton();
}

void SeedEntry::handleButton()
{
    uint64_t seed;
    char seedString[21];
    srand(time(NULL));
    seed = ((uint64_t)rand() << 32) | ((uint64_t)rand() & 0xffffffffL);
    snprintf(seedString, 21, "%" PRIu64, seed);
    this->textBox->setText(QString(seedString));
}

uint64_t SeedEntry::getSeed()
{
    uint64_t seed;
    sscanf(this->textBox->text().toLatin1().constData(), "%"PRIu64, &seed);
    return seed;
}

FlagEntry::FlagEntry(QWidget *parent) : ButtonEntry(parent)
{
    this->button->setText("Defaults");
    this->label->setText("Flags");
}

void FlagEntry::handleButton()
{
    this->setText(DEFAULT_FLAGS);
    this->textBox->textEdited(this->text());
}

void FlagEntry::handleEdit(QString text)
{
    this->textEdited(text);
}

<commit_msg>Fixed a compile error on OSX<commit_after>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <time.h>

#include "dwr.h"
#include "widgets.h"

CheckBox::CheckBox(const char flag, const QString &text, QWidget *parent) :
        QCheckBox(text, parent)
{
    this->flag = flag;
}

char CheckBox::getFlag()
{
    if (this->isChecked()) {
        return this->flag;
    }
    return NO_FLAG;
}

void CheckBox::stateChanged(int state)
{
    super::stateChanged(state);
}

bool CheckBox::updateState(QString flags)
{
    bool checked = flags.indexOf(QChar(this->flag)) >= 0;
    this->setChecked(checked);
    return checked;
}

LevelComboBox::LevelComboBox(QWidget *parent) : QComboBox(parent)
{
    this->addItem("Normal");
    this->addItem("Fast");
    this->addItem("Very Fast");
}

char LevelComboBox::getFlag()
{
    switch(this->currentIndex()) {
        case 1:
           return 'f';
        case 2:
            return 'F';
        default:
            return NO_FLAG;
    }
}

bool LevelComboBox::updateState(QString flags)
{
    if (flags.indexOf(QChar('f')) >= 0) {
        this->setCurrentIndex(1);
        return true;
    } else {
        if (flags.indexOf(QChar('F')) >= 0) {
            this->setCurrentIndex(2);
            return true;
        }
    }
    this->setCurrentIndex(0);
    return false;
}

ButtonEntry::ButtonEntry(QWidget *parent) :
        QWidget(parent)
{
    QVBoxLayout *vbox = new QVBoxLayout();
    QHBoxLayout *hbox = new QHBoxLayout();
    this->textBox = new QLineEdit(this);
    this->button = new QPushButton("Click", this);
    this->label = new QLabel("", this);
    vbox->addWidget(this->label);
    hbox->addWidget(this->textBox);
    hbox->addWidget(this->button);
    vbox->addLayout(hbox);
    this->setLayout(vbox);
    connect(this->button, SIGNAL(clicked()), this, SLOT(handleButton()));
    connect(this->textBox, SIGNAL(textEdited(QString)), this, SLOT(handleEdit(QString)));
}

QString ButtonEntry::text()
{
    return this->textBox->text();
}

void ButtonEntry::setText(QString text)
{
    this->textBox->setText(text);
}

FileEntry::FileEntry(QWidget *parent) : ButtonEntry(parent)
{
    this->button->setText("Browse...");
    this->label->setText("ROM File");
}

void FileEntry::handleButton()
{
    QString filename = QFileDialog::getOpenFileName(
           this, "Choose the ROM file", "./", "NES ROM Files (*.nes)");
    this->textBox->setText(filename);
}

DirEntry::DirEntry(QWidget *parent) : ButtonEntry(parent)
{
    this->button->setText("Browse...");
#ifdef _WIN32
    this->label->setText("Output Folder");
#else
    this->label->setText("Output Directory");
#endif
}

void DirEntry::handleButton()
{
    QString dirName = QFileDialog::getExistingDirectory(this,
#ifdef _WIN32
            "Choose the output folder",
#else
            "Choose the output directory",
#endif
            "./");
    this->textBox->setText(dirName);
}

SeedEntry::SeedEntry(QWidget *parent) : ButtonEntry(parent)
{
    this->button->setText("Random");
    this->label->setText("Seed");
    this->handleButton();
}

void SeedEntry::handleButton()
{
    uint64_t seed;
    char seedString[21];
    srand(time(NULL));
    seed = ((uint64_t)rand() << 32) | ((uint64_t)rand() & 0xffffffffL);
    snprintf(seedString, 21, "%" PRIu64, seed);
    this->textBox->setText(QString(seedString));
}

uint64_t SeedEntry::getSeed()
{
    uint64_t seed;
    sscanf(this->textBox->text().toLatin1().constData(), "%" PRIu64, &seed);
    return seed;
}

FlagEntry::FlagEntry(QWidget *parent) : ButtonEntry(parent)
{
    this->button->setText("Defaults");
    this->label->setText("Flags");
}

void FlagEntry::handleButton()
{
    this->setText(DEFAULT_FLAGS);
    this->textBox->textEdited(this->text());
}

void FlagEntry::handleEdit(QString text)
{
    this->textEdited(text);
}

<|endoftext|>


<commit_before>#include <Eigen/Core>
#include <cmath>
#include <iostream>
#include "drake/core/Gradient.h"
#include "drake/util/drakeGeometryUtil.h"
#include "drake/util/eigen_matrix_compare.h"
#include "drake/util/testUtil.h"
#include "gtest/gtest.h"

using Eigen::Isometry3d;
using Eigen::Vector3d;
using Eigen::Vector4d;
using Eigen::Matrix;
using Eigen::Matrix3d;
using Eigen::MatrixXd;
using Eigen::Dynamic;
using Eigen::Quaterniond;
using Eigen::Translation3d;
using std::default_random_engine;
using drake::util::MatrixCompareType;
using Drake::initializeAutoDiff;

namespace drake {
namespace util {
namespace {

void testExpmap2quat(const Vector4d &quat);

void testRotationConversionFunctions() {
  int ntests = 100;
  default_random_engine generator;
  // quat2axis, axis2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    auto a = quat2axis(q);
    auto q_back = axis2quat(a);
    valuecheck(acos(std::abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // quat2rotmat, rotmat2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    Matrix3d R = quat2rotmat(q);
    Vector4d q_back = rotmat2quat(R);
    valuecheck(acos(std::abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // quat2rpy, rpy2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    Vector3d rpy = quat2rpy(q);
    Vector4d q_back = rpy2quat(rpy);
    valuecheck(acos(std::abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // rotmat2axis, axis2rotmat
  for (int i = 0; i < ntests; i++) {
    Matrix3d R = uniformlyRandomRotmat(generator);
    Vector4d a = rotmat2axis(R);
    Matrix3d R_back = axis2rotmat(a);
    EXPECT_TRUE(CompareMatrices(R, R_back, 1e-6, MatrixCompareType::absolute));
  }
  // rotmat2rpy, rpy2rotmat
  for (int i = 0; i < ntests; i++) {
    Matrix3d R = uniformlyRandomRotmat(generator);
    Vector3d rpy = rotmat2rpy(R);
    Matrix3d R_back = rpy2rotmat(rpy);
    EXPECT_TRUE(CompareMatrices(R, R_back, 1e-6, MatrixCompareType::absolute));
  }
  // rpy2axis, axis2rpy
  for (int i = 0; i < ntests; i++) {
    Vector3d rpy = uniformlyRandomRPY(generator);
    Vector4d axis = rpy2axis(rpy);
    Vector3d rpy_back = axis2rpy(axis);
    EXPECT_TRUE(
        CompareMatrices(rpy, rpy_back, 1e-6, MatrixCompareType::absolute));
  }
  // expmap2quat, quat2expmap
  Vector4d quat_degenerate = Vector4d::Zero();
  quat_degenerate(0) = 1.0;
  testExpmap2quat(quat_degenerate);
  quat_degenerate(0) = -1.0;
  testExpmap2quat(quat_degenerate);
  for (int i = 0; i < ntests; i++) {
    Vector4d quat = uniformlyRandomQuat(generator);
    testExpmap2quat(quat);
  }
  // quat2eigenQuaternion
  Vector4d quat = uniformlyRandomQuat(generator);
  Quaterniond eigenQuat = quat2eigenQuaternion(quat);
  Matrix3d R_expected = quat2rotmat(quat);
  Matrix3d R_eigen = eigenQuat.matrix();
  EXPECT_TRUE(
      CompareMatrices(R_expected, R_eigen, 1e-6, MatrixCompareType::absolute));
}

void testDHomogTrans(int ntests) {
  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3));
    //  T.setIdentity();
    //  T = AngleAxisd(M_PI_2, Vector3d(1.0, 0.0, 0.0));

    const int nv = 6;
    const int nq = 7;

    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    //    setLinearIndices(S);
    //    S.setIdentity();
    //    std::cout << S << "\n\n";

    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    //    setLinearIndices(qdot_to_v);
    //    std::cout << qdot_to_v << "\n\n";

    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    volatile auto vol = dT;
    //  std::cout << dT << std::endl << std::endl;
  }
}

void testDHomogTransInv(int ntests, bool check) {
  Isometry3d T;
  std::default_random_engine generator;
  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    //    T = Quaterniond(q(0), q(1), q(2), q(3)) *
    //    Translation3d(Vector3d::Random());
    T = Quaterniond(q(0), q(1), q(2), q(3));

    const int nv = 6;
    const int nq = 7;

    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();

    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto dTInv = dHomogTransInv(T, dT);
    volatile auto vol = dTInv;

    if (check) {
      auto dTInvInv = dHomogTransInv(T.inverse(), dTInv);

      if (!dT.matrix().isApprox(dTInvInv.matrix(), 1e-10)) {
        std::cout << "dTInv:\n" << dTInv << "\n\n";
        std::cout << "dT:\n" << dT << "\n\n";
        std::cout << "dTInvInv:\n" << dTInvInv << "\n\n";
        std::cout << "dTInvInv - dT:\n" << dTInvInv - dT << "\n\n";

        throw std::runtime_error("wrong");
      }
    }
  }
}

void testDTransformAdjoint(int ntests) {
  const int nv = 6;
  const int nq = 34;
  const int cols_X = 3;

  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto X = Matrix<double, 6, Dynamic>::Random(6, cols_X).eval();
    auto dX = MatrixXd::Random(X.size(), nq).eval();
    //    auto dX = Matrix<double, X.SizeAtCompileTime, nq>::Random().eval();
    auto dAdT_times_X = dTransformSpatialMotion(T, X, dT, dX).eval();
    volatile auto vol = dAdT_times_X;
  }
}

void testDTransformAdjointTranspose(int ntests) {
  const int nv = 6;
  const int nq = 34;
  const int cols_X = 3;

  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto X = Matrix<double, 6, Dynamic>::Random(6, cols_X).eval();
    auto dX = MatrixXd::Random(X.size(), nq).eval();
    //    auto dX = Matrix<double, X.SizeAtCompileTime, nq>::Random().eval();
    auto dAdTtranspose_times_X = dTransformSpatialForce(T, X, dT, dX).eval();
    volatile auto vol = dAdTtranspose_times_X;
  }
}

void testNormalizeVec(int ntests) {
  const int x_rows = 4;

  for (int testnr = 0; testnr < ntests; testnr++) {
    auto x = Matrix<double, x_rows, 1>::Random().eval();
    Matrix<double, x_rows, 1> x_norm;
    Matrix<double, x_rows, x_rows> dx_norm;
    Matrix<double, x_rows * x_rows, x_rows> ddx_norm;
    normalizeVec(x, x_norm, &dx_norm, &ddx_norm);
    //    std::cout << "gradientNumRows: " << gradientNumRows(x_rows, x_rows, 1)
    //    << std::endl;

    volatile auto volx_norm = x_norm;
    volatile auto voldx_norm = dx_norm;
    volatile auto volddx_norm = ddx_norm;

    //    std::cout << "x_norm:\n" << x_norm << std::endl << std::endl;
    //    std::cout << "dx_norm:\n" << dx_norm << std::endl << std::endl;
    //    std::cout << "ddx_norm:\n" << ddx_norm << std::endl << std::endl;
  }
}

void testSpatialCrossProduct() {
  auto a = (Matrix<double, TWIST_SIZE, 1>::Random()).eval();
  auto b = (Matrix<double, TWIST_SIZE, TWIST_SIZE>::Identity()).eval();
  auto a_crm_b = crossSpatialMotion(a, b);
  auto a_crf_b = crossSpatialForce(a, b);
  EXPECT_TRUE(CompareMatrices(a_crf_b, -a_crm_b.transpose(), 1e-8,
                              MatrixCompareType::absolute));
}

void testdrpy2rotmat() {
  default_random_engine generator;
  Vector3d rpy = uniformlyRandomRPY(generator);
  Matrix3d R = rpy2rotmat(rpy);
  Matrix<double, 9, 3> dR = drpy2rotmat(rpy);
  Matrix<double, 9, 3> dR_num = Matrix<double, 9, 3>::Zero();
  for (int i = 0; i < 3; i++) {
    Vector3d err = Vector3d::Zero();
    err(i) = 1e-7;
    Vector3d rpyi = rpy + err;
    Matrix3d Ri = rpy2rotmat(rpyi);
    Matrix3d Ri_err = (Ri - R) / err(i);
    for (int j = 0; j < 9; j++) {
      dR_num(j, i) = Ri_err(j);
      valuecheck(dR(j, i), dR_num(j, i), 1e-3);
    }
  }
}

void testExpmap2quat(const Vector4d &quat) {
  auto quat_autodiff = initializeAutoDiff(quat);
  auto expmap_autodiff = quat2expmap(quat_autodiff);
  auto expmap = autoDiffToValueMatrix(expmap_autodiff);
  auto expmap_grad = autoDiffToGradientMatrix(expmap_autodiff);
  auto quat_back_autodiff = expmap2quat(initializeAutoDiff(expmap));
  auto quat_back = autoDiffToValueMatrix(quat_back_autodiff);
  auto quat_back_grad = autoDiffToGradientMatrix(quat_back_autodiff);
  valuecheck(std::abs((quat.transpose() * quat_back).value()), 1.0, 1e-8);
  Matrix3d identity = Matrix3d::Identity();
  EXPECT_TRUE(CompareMatrices((expmap_grad * quat_back_grad).eval(), identity,
                              1e-10, MatrixCompareType::absolute));
}

TEST(drakeGeometryUtilTest, AllTests) {
  testRotationConversionFunctions();

  int ntests = 100000;
  std::cout << "testDHomogTrans elapsed time: "
            << measure<>::execution(testDHomogTrans, ntests) << std::endl;
  std::cout << "testDHomogTransInv elapsed time: "
            << measure<>::execution(testDHomogTransInv, ntests, false)
            << std::endl;
  std::cout << "testDTransformAdjoint elapsed time: "
            << measure<>::execution(testDTransformAdjoint, ntests) << std::endl;
  std::cout << "testDTransformAdjointTranspose elapsed time: "
            << measure<>::execution(testDTransformAdjointTranspose, ntests)
            << std::endl;
  std::cout << "testNormalizeVec elapsed time: "
            << measure<>::execution(testNormalizeVec, ntests) << std::endl;

  testDHomogTransInv(1000, true);
  testSpatialCrossProduct();
  testdrpy2rotmat();
}

}  // namespace
}  // namespace util
}  // namespace drake
<commit_msg>Per Issue #2055:  * set 'ntests = 1' everywhere -- forget doing any kind of benchmarking here,    and just run every test loop for one iteration;  * turn calls to individual test functions into actual gtest test functions,    instead of glomming them all into a single "AllTests" gtest function.<commit_after>#include <Eigen/Core>
#include <cmath>
#include <iostream>
#include "drake/core/Gradient.h"
#include "drake/util/drakeGeometryUtil.h"
#include "drake/util/eigen_matrix_compare.h"
#include "drake/util/testUtil.h"
#include "gtest/gtest.h"

using Eigen::Isometry3d;
using Eigen::Vector3d;
using Eigen::Vector4d;
using Eigen::Matrix;
using Eigen::Matrix3d;
using Eigen::MatrixXd;
using Eigen::Dynamic;
using Eigen::Quaterniond;
using Eigen::Translation3d;
using std::default_random_engine;
using drake::util::MatrixCompareType;
using Drake::initializeAutoDiff;

namespace drake {
namespace util {
namespace {

void testExpmap2quat(const Vector4d &quat);

TEST(DrakeGeometryUtilTest, RotationConversionFunctions) {
  int ntests = 1;
  default_random_engine generator;
  // quat2axis, axis2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    auto a = quat2axis(q);
    auto q_back = axis2quat(a);
    valuecheck(acos(std::abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // quat2rotmat, rotmat2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    Matrix3d R = quat2rotmat(q);
    Vector4d q_back = rotmat2quat(R);
    valuecheck(acos(std::abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // quat2rpy, rpy2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    Vector3d rpy = quat2rpy(q);
    Vector4d q_back = rpy2quat(rpy);
    valuecheck(acos(std::abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // rotmat2axis, axis2rotmat
  for (int i = 0; i < ntests; i++) {
    Matrix3d R = uniformlyRandomRotmat(generator);
    Vector4d a = rotmat2axis(R);
    Matrix3d R_back = axis2rotmat(a);
    EXPECT_TRUE(CompareMatrices(R, R_back, 1e-6, MatrixCompareType::absolute));
  }
  // rotmat2rpy, rpy2rotmat
  for (int i = 0; i < ntests; i++) {
    Matrix3d R = uniformlyRandomRotmat(generator);
    Vector3d rpy = rotmat2rpy(R);
    Matrix3d R_back = rpy2rotmat(rpy);
    EXPECT_TRUE(CompareMatrices(R, R_back, 1e-6, MatrixCompareType::absolute));
  }
  // rpy2axis, axis2rpy
  for (int i = 0; i < ntests; i++) {
    Vector3d rpy = uniformlyRandomRPY(generator);
    Vector4d axis = rpy2axis(rpy);
    Vector3d rpy_back = axis2rpy(axis);
    EXPECT_TRUE(
        CompareMatrices(rpy, rpy_back, 1e-6, MatrixCompareType::absolute));
  }
  // expmap2quat, quat2expmap
  Vector4d quat_degenerate = Vector4d::Zero();
  quat_degenerate(0) = 1.0;
  testExpmap2quat(quat_degenerate);
  quat_degenerate(0) = -1.0;
  testExpmap2quat(quat_degenerate);
  for (int i = 0; i < ntests; i++) {
    Vector4d quat = uniformlyRandomQuat(generator);
    testExpmap2quat(quat);
  }
  // quat2eigenQuaternion
  Vector4d quat = uniformlyRandomQuat(generator);
  Quaterniond eigenQuat = quat2eigenQuaternion(quat);
  Matrix3d R_expected = quat2rotmat(quat);
  Matrix3d R_eigen = eigenQuat.matrix();
  EXPECT_TRUE(
      CompareMatrices(R_expected, R_eigen, 1e-6, MatrixCompareType::absolute));
}

TEST(DrakeGeometryUtilTest, DHomogTrans) {
  const int ntests = 1;
  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3));
    //  T.setIdentity();
    //  T = AngleAxisd(M_PI_2, Vector3d(1.0, 0.0, 0.0));

    const int nv = 6;
    const int nq = 7;

    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    //    setLinearIndices(S);
    //    S.setIdentity();
    //    std::cout << S << "\n\n";

    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    //    setLinearIndices(qdot_to_v);
    //    std::cout << qdot_to_v << "\n\n";

    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    volatile auto vol = dT;
    //  std::cout << dT << std::endl << std::endl;
  }
}

TEST(DrakeGeometryUtilTest, DHomogTransInv) {
  const int ntests = 1;
  const bool check = true;
  Isometry3d T;
  std::default_random_engine generator;
  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    //    T = Quaterniond(q(0), q(1), q(2), q(3)) *
    //    Translation3d(Vector3d::Random());
    T = Quaterniond(q(0), q(1), q(2), q(3));

    const int nv = 6;
    const int nq = 7;

    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();

    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto dTInv = dHomogTransInv(T, dT);
    volatile auto vol = dTInv;

    if (check) {
      auto dTInvInv = dHomogTransInv(T.inverse(), dTInv);

      if (!dT.matrix().isApprox(dTInvInv.matrix(), 1e-10)) {
        std::cout << "dTInv:\n" << dTInv << "\n\n";
        std::cout << "dT:\n" << dT << "\n\n";
        std::cout << "dTInvInv:\n" << dTInvInv << "\n\n";
        std::cout << "dTInvInv - dT:\n" << dTInvInv - dT << "\n\n";

        throw std::runtime_error("wrong");
      }
    }
  }
}

TEST(DrakeGeometryUtilTest, DTransformAdjoint) {
  const int ntests = 1;
  const int nv = 6;
  const int nq = 34;
  const int cols_X = 3;

  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto X = Matrix<double, 6, Dynamic>::Random(6, cols_X).eval();
    auto dX = MatrixXd::Random(X.size(), nq).eval();
    //    auto dX = Matrix<double, X.SizeAtCompileTime, nq>::Random().eval();
    auto dAdT_times_X = dTransformSpatialMotion(T, X, dT, dX).eval();
    volatile auto vol = dAdT_times_X;
  }
}

TEST(DrakeGeometryUtilTest, DTransformAdjointTranspose) {
  const int ntests = 1;
  const int nv = 6;
  const int nq = 34;
  const int cols_X = 3;

  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto X = Matrix<double, 6, Dynamic>::Random(6, cols_X).eval();
    auto dX = MatrixXd::Random(X.size(), nq).eval();
    //    auto dX = Matrix<double, X.SizeAtCompileTime, nq>::Random().eval();
    auto dAdTtranspose_times_X = dTransformSpatialForce(T, X, dT, dX).eval();
    volatile auto vol = dAdTtranspose_times_X;
  }
}

TEST(DrakeGeometryUtilTest, NormalizeVec) {
  const int ntests = 1;
  const int x_rows = 4;

  for (int testnr = 0; testnr < ntests; testnr++) {
    auto x = Matrix<double, x_rows, 1>::Random().eval();
    Matrix<double, x_rows, 1> x_norm;
    Matrix<double, x_rows, x_rows> dx_norm;
    Matrix<double, x_rows * x_rows, x_rows> ddx_norm;
    normalizeVec(x, x_norm, &dx_norm, &ddx_norm);
    //    std::cout << "gradientNumRows: " << gradientNumRows(x_rows, x_rows, 1)
    //    << std::endl;

    volatile auto volx_norm = x_norm;
    volatile auto voldx_norm = dx_norm;
    volatile auto volddx_norm = ddx_norm;

    //    std::cout << "x_norm:\n" << x_norm << std::endl << std::endl;
    //    std::cout << "dx_norm:\n" << dx_norm << std::endl << std::endl;
    //    std::cout << "ddx_norm:\n" << ddx_norm << std::endl << std::endl;
  }
}

TEST(DrakeGeometryUtilTest, SpatialCrossProduct) {
  auto a = (Matrix<double, TWIST_SIZE, 1>::Random()).eval();
  auto b = (Matrix<double, TWIST_SIZE, TWIST_SIZE>::Identity()).eval();
  auto a_crm_b = crossSpatialMotion(a, b);
  auto a_crf_b = crossSpatialForce(a, b);
  EXPECT_TRUE(CompareMatrices(a_crf_b, -a_crm_b.transpose(), 1e-8,
                              MatrixCompareType::absolute));
}

TEST(DrakeGeometryUtilTest, drpy2rotmat) {
  default_random_engine generator;
  Vector3d rpy = uniformlyRandomRPY(generator);
  Matrix3d R = rpy2rotmat(rpy);
  Matrix<double, 9, 3> dR = drpy2rotmat(rpy);
  Matrix<double, 9, 3> dR_num = Matrix<double, 9, 3>::Zero();
  for (int i = 0; i < 3; i++) {
    Vector3d err = Vector3d::Zero();
    err(i) = 1e-7;
    Vector3d rpyi = rpy + err;
    Matrix3d Ri = rpy2rotmat(rpyi);
    Matrix3d Ri_err = (Ri - R) / err(i);
    for (int j = 0; j < 9; j++) {
      dR_num(j, i) = Ri_err(j);
      valuecheck(dR(j, i), dR_num(j, i), 1e-3);
    }
  }
}

void testExpmap2quat(const Vector4d &quat) {
  auto quat_autodiff = initializeAutoDiff(quat);
  auto expmap_autodiff = quat2expmap(quat_autodiff);
  auto expmap = autoDiffToValueMatrix(expmap_autodiff);
  auto expmap_grad = autoDiffToGradientMatrix(expmap_autodiff);
  auto quat_back_autodiff = expmap2quat(initializeAutoDiff(expmap));
  auto quat_back = autoDiffToValueMatrix(quat_back_autodiff);
  auto quat_back_grad = autoDiffToGradientMatrix(quat_back_autodiff);
  valuecheck(std::abs((quat.transpose() * quat_back).value()), 1.0, 1e-8);
  Matrix3d identity = Matrix3d::Identity();
  EXPECT_TRUE(CompareMatrices((expmap_grad * quat_back_grad).eval(), identity,
                              1e-10, MatrixCompareType::absolute));
}

}  // namespace
}  // namespace util
}  // namespace drake
<|endoftext|>