<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_comboBox = new QComboBox;
    m_comboBox->setEnabled(false);
    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());

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

void ToolChainInformationConfigWidget::makeReadOnly()
{
    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));
}

void ToolChainInformationConfigWidget::updateComboBox()
{
    // remove unavailable tool chain:
    int pos = indexOf(0);
    if (pos >= 0)
        m_comboBox->removeItem(pos);

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

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>ProjectExplorer: fix one more capitalization issue<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_comboBox = new QComboBox;
    m_comboBox->setEnabled(false);
    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());

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

void ToolChainInformationConfigWidget::makeReadOnly()
{
    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));
}

void ToolChainInformationConfigWidget::updateComboBox()
{
    // remove unavailable tool chain:
    int pos = indexOf(0);
    if (pos >= 0)
        m_comboBox->removeItem(pos);

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

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
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "GapConductanceConstraint.h"

registerMooseObject("HeatConductionApp", GapConductanceConstraint);

InputParameters
GapConductanceConstraint::validParams()
{
  InputParameters params = ADMortarConstraint::validParams();
  params.addClassDescription(
      "Computes the residual and Jacobian contributions for the 'Lagrange Multiplier' "
      "implementation of the thermal contact problem. For more information, see the "
      "detailed description here: http://tinyurl.com/gmmhbe9");
  params.addRequiredParam<Real>("k", "Gap conductance");
  return params;
}

GapConductanceConstraint::GapConductanceConstraint(const InputParameters & parameters)
  : ADMortarConstraint(parameters), _k(getParam<Real>("k"))
{
}

ADReal
GapConductanceConstraint::computeQpResidual(Moose::MortarType mortar_type)
{
  switch (mortar_type)
  {
    case Moose::MortarType::Primary:
      return _lambda[_qp] * _test_primary[_i][_qp];
    case Moose::MortarType::Secondary:
      return -_lambda[_qp] * _test_secondary[_i][_qp];
    case Moose::MortarType::Lower:
    {
      auto l = (_phys_points_primary[_qp] - _phys_points_secondary[_qp]).norm();
      return (_k * (_u_primary[_qp] - _u_secondary[_qp]) / l - _lambda[_qp]) * _test[_i][_qp];
    }
    default:
      return 0;
  }
}
<commit_msg>Make lm diagonal entry positive instead of negative<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "GapConductanceConstraint.h"

registerMooseObject("HeatConductionApp", GapConductanceConstraint);

InputParameters
GapConductanceConstraint::validParams()
{
  InputParameters params = ADMortarConstraint::validParams();
  params.addClassDescription(
      "Computes the residual and Jacobian contributions for the 'Lagrange Multiplier' "
      "implementation of the thermal contact problem. For more information, see the "
      "detailed description here: http://tinyurl.com/gmmhbe9");
  params.addRequiredParam<Real>("k", "Gap conductance");
  return params;
}

GapConductanceConstraint::GapConductanceConstraint(const InputParameters & parameters)
  : ADMortarConstraint(parameters), _k(getParam<Real>("k"))
{
}

ADReal
GapConductanceConstraint::computeQpResidual(Moose::MortarType mortar_type)
{
  switch (mortar_type)
  {
    case Moose::MortarType::Primary:
      return _lambda[_qp] * _test_primary[_i][_qp];
    case Moose::MortarType::Secondary:
      return -_lambda[_qp] * _test_secondary[_i][_qp];
    case Moose::MortarType::Lower:
    {
      auto l = (_phys_points_primary[_qp] - _phys_points_secondary[_qp]).norm();
      return (_lambda[_qp] - _k * (_u_primary[_qp] - _u_secondary[_qp]) / l) * _test[_i][_qp];
    }
    default:
      return 0;
  }
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/behavior_decider/signal_light_scenario.h"

#include <limits>
#include <string>
#include <vector>

#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/map_util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/proto/planning_internal.pb.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;
using apollo::common::util::WithinBound;
using apollo::perception::TrafficLight;
using apollo::perception::TrafficLightDetection;

void SignalLightScenario::Reset() {}

bool SignalLightScenario::Init() {
  exist_ = true;
  return exist_;
}

int SignalLightScenario::ComputeScenarioDecision(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    PlanningTarget* planning_target) {
  CHECK(frame != nullptr);

  if (!FindValidSignalLight(reference_line_info)) {
    ADEBUG << "No valid signal light along reference line";
    return 0;
  }
  ReadSignals();

  for (const hdmap::PathOverlap* signal_light :
       signal_lights_along_reference_line_) {
    const TrafficLight signal = GetSignal(signal_light->object_id);
    double stop_deceleration =
        GetStopDeceleration(reference_line_info, signal_light);

    if ((signal.color() == TrafficLight::RED &&
         stop_deceleration < FLAGS_max_stop_deceleration) ||
        (signal.color() == TrafficLight::UNKNOWN &&
         stop_deceleration < FLAGS_max_stop_deceleration) ||
        (signal.color() == TrafficLight::YELLOW &&
         stop_deceleration < FLAGS_max_stop_deacceleration_for_yellow_light)) {
      CreateStopObstacle(frame, reference_line_info, signal_light);
    }
  }

  return 0;
}

bool SignalLightScenario::FindValidSignalLight(
    ReferenceLineInfo* const reference_line_info) {
  const std::vector<hdmap::PathOverlap>& signal_lights =
      reference_line_info->reference_line().map_path().signal_overlaps();
  if (signal_lights.size() <= 0) {
    ADEBUG << "No signal lights from reference line.";
    return false;
  } else {
    ADEBUG << "Found signal_lights size=" << signal_lights.size();
  }
  signal_lights_along_reference_line_.clear();
  for (const hdmap::PathOverlap& signal_light : signal_lights) {
    if (signal_light.start_s + FLAGS_max_stop_distance_buffer >
        reference_line_info->AdcSlBoundary().end_s()) {
      signal_lights_along_reference_line_.push_back(&signal_light);
    }
  }
  return signal_lights_along_reference_line_.size() > 0;
}

void SignalLightScenario::ReadSignals() {
  detected_signals_.clear();
  detected_signals_.clear();
  if (AdapterManager::GetTrafficLightDetection()->Empty()) {
    return;
  }
  if (AdapterManager::GetTrafficLightDetection()->GetDelaySec() >
      FLAGS_signal_expire_time_sec) {
    AWARN << "traffic signals msg is expired: "
          << AdapterManager::GetTrafficLightDetection()->GetDelaySec();
    return;
  }
  const TrafficLightDetection& detection =
      AdapterManager::GetTrafficLightDetection()->GetLatestObserved();
  for (int j = 0; j < detection.traffic_light_size(); j++) {
    const TrafficLight& signal = detection.traffic_light(j);
    detected_signals_[signal.id()] = &signal;
  }
}

TrafficLight SignalLightScenario::GetSignal(const std::string& signal_id) {
  const auto* result =
      apollo::common::util::FindPtrOrNull(detected_signals_, signal_id);
  if (result == nullptr) {
    TrafficLight traffic_light;
    traffic_light.set_id(signal_id);
    traffic_light.set_color(TrafficLight::UNKNOWN);
    traffic_light.set_confidence(0.0);
    traffic_light.set_tracking_time(0.0);
    return traffic_light;
  }
  return *result;
}

double SignalLightScenario::GetStopDeceleration(
    ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  double adc_speed =
      common::VehicleStateProvider::instance()->linear_velocity();
  if (adc_speed < FLAGS_max_stop_speed) {
    return 0.0;
  }
  double stop_distance = 0.0;
  double adc_front_s = reference_line_info->AdcSlBoundary().end_s();
  double stop_line_s = signal_light->start_s;

  if (stop_line_s > adc_front_s) {
    stop_distance = stop_line_s - adc_front_s;
  } else {
    stop_distance = stop_line_s + FLAGS_max_stop_distance_buffer - adc_front_s;
  }
  if (stop_distance < 1e-5) {
    // longitudinal_acceleration_lower_bound is a negative value.
    return -FLAGS_longitudinal_acceleration_lower_bound;
  }
  return (adc_speed * adc_speed) / (2 * stop_distance);
}

void SignalLightScenario::CreateStopObstacle(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  // check
  const auto& reference_line = reference_line_info->reference_line();
  const double stop_s =
      signal_light->start_s - FLAGS_traffic_light_stop_distance;
  const double box_center_s =
      signal_light->start_s + FLAGS_virtual_stop_wall_length / 2.0;
  if (!WithinBound(0.0, reference_line.Length(), stop_s) ||
      !WithinBound(0.0, reference_line.Length(), box_center_s)) {
    ADEBUG << "signal " << signal_light->object_id
           << " is not on reference line";
    return;
  }

  // create virtual stop wall
  std::string virtual_obstacle_id =
      FLAGS_signal_light_virtual_obstacle_id_prefix + signal_light->object_id;
  auto* obstacle = frame->CreateVirtualStopObstacle(
      reference_line_info, virtual_obstacle_id, signal_light->start_s);
  if (!obstacle) {
    AERROR << "Failed to create obstacle [" << virtual_obstacle_id << "]";
    return;
  }
  PathObstacle* stop_wall = reference_line_info->AddObstacle(obstacle);
  if (!stop_wall) {
    AERROR << "Failed to create path_obstacle for: " << virtual_obstacle_id;
    return;
  }

  return;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: fixed a bug of colliding with traffic light virtual obstacle<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/behavior_decider/signal_light_scenario.h"

#include <limits>
#include <string>
#include <vector>

#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/map_util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/proto/planning_internal.pb.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;
using apollo::common::util::WithinBound;
using apollo::perception::TrafficLight;
using apollo::perception::TrafficLightDetection;

void SignalLightScenario::Reset() {}

bool SignalLightScenario::Init() {
  exist_ = true;
  return exist_;
}

int SignalLightScenario::ComputeScenarioDecision(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    PlanningTarget* planning_target) {
  CHECK(frame != nullptr);

  if (!FindValidSignalLight(reference_line_info)) {
    ADEBUG << "No valid signal light along reference line";
    return 0;
  }
  ReadSignals();

  for (const hdmap::PathOverlap* signal_light :
       signal_lights_along_reference_line_) {
    const TrafficLight signal = GetSignal(signal_light->object_id);
    double stop_deceleration =
        GetStopDeceleration(reference_line_info, signal_light);

    if ((signal.color() == TrafficLight::RED &&
         stop_deceleration < FLAGS_max_stop_deceleration) ||
        // (signal.color() == TrafficLight::UNKNOWN &&
        //  stop_deceleration < FLAGS_max_stop_deceleration) ||
        (signal.color() == TrafficLight::YELLOW &&
         stop_deceleration < FLAGS_max_stop_deacceleration_for_yellow_light)) {
      CreateStopObstacle(frame, reference_line_info, signal_light);
    }
  }

  return 0;
}

bool SignalLightScenario::FindValidSignalLight(
    ReferenceLineInfo* const reference_line_info) {
  const std::vector<hdmap::PathOverlap>& signal_lights =
      reference_line_info->reference_line().map_path().signal_overlaps();
  if (signal_lights.size() <= 0) {
    ADEBUG << "No signal lights from reference line.";
    return false;
  } else {
    ADEBUG << "Found signal_lights size=" << signal_lights.size();
  }
  signal_lights_along_reference_line_.clear();
  for (const hdmap::PathOverlap& signal_light : signal_lights) {
    if (signal_light.start_s + FLAGS_max_stop_distance_buffer >
        reference_line_info->AdcSlBoundary().end_s()) {
      signal_lights_along_reference_line_.push_back(&signal_light);
    }
  }
  return signal_lights_along_reference_line_.size() > 0;
}

void SignalLightScenario::ReadSignals() {
  detected_signals_.clear();
  detected_signals_.clear();
  if (AdapterManager::GetTrafficLightDetection()->Empty()) {
    return;
  }
  if (AdapterManager::GetTrafficLightDetection()->GetDelaySec() >
      FLAGS_signal_expire_time_sec) {
    AWARN << "traffic signals msg is expired: "
          << AdapterManager::GetTrafficLightDetection()->GetDelaySec();
    return;
  }
  const TrafficLightDetection& detection =
      AdapterManager::GetTrafficLightDetection()->GetLatestObserved();
  for (int j = 0; j < detection.traffic_light_size(); j++) {
    const TrafficLight& signal = detection.traffic_light(j);
    detected_signals_[signal.id()] = &signal;
  }
}

TrafficLight SignalLightScenario::GetSignal(const std::string& signal_id) {
  const auto* result =
      apollo::common::util::FindPtrOrNull(detected_signals_, signal_id);
  if (result == nullptr) {
    TrafficLight traffic_light;
    traffic_light.set_id(signal_id);
    traffic_light.set_color(TrafficLight::UNKNOWN);
    traffic_light.set_confidence(0.0);
    traffic_light.set_tracking_time(0.0);
    return traffic_light;
  }
  return *result;
}

double SignalLightScenario::GetStopDeceleration(
    ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  double adc_speed =
      common::VehicleStateProvider::instance()->linear_velocity();
  if (adc_speed < FLAGS_max_stop_speed) {
    return 0.0;
  }
  double stop_distance = 0.0;
  double adc_front_s = reference_line_info->AdcSlBoundary().end_s();
  double stop_line_s = signal_light->start_s;

  if (stop_line_s > adc_front_s) {
    stop_distance = stop_line_s - adc_front_s;
  } else {
    stop_distance = stop_line_s + FLAGS_max_stop_distance_buffer - adc_front_s;
  }
  if (stop_distance < 1e-5) {
    // longitudinal_acceleration_lower_bound is a negative value.
    return -FLAGS_longitudinal_acceleration_lower_bound;
  }
  return (adc_speed * adc_speed) / (2 * stop_distance);
}

void SignalLightScenario::CreateStopObstacle(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  // check
  const auto& reference_line = reference_line_info->reference_line();
  const double stop_s =
      signal_light->start_s - FLAGS_traffic_light_stop_distance;
  const double box_center_s =
      signal_light->start_s + FLAGS_virtual_stop_wall_length / 2.0;
  if (!WithinBound(0.0, reference_line.Length(), stop_s) ||
      !WithinBound(0.0, reference_line.Length(), box_center_s)) {
    ADEBUG << "signal " << signal_light->object_id
           << " is not on reference line";
    return;
  }

  // create virtual stop wall
  std::string virtual_obstacle_id =
      FLAGS_signal_light_virtual_obstacle_id_prefix + signal_light->object_id;
  auto* obstacle = frame->CreateVirtualStopObstacle(
      reference_line_info, virtual_obstacle_id, signal_light->start_s);
  if (!obstacle) {
    AERROR << "Failed to create obstacle [" << virtual_obstacle_id << "]";
    return;
  }
  PathObstacle* stop_wall = reference_line_info->AddObstacle(obstacle);
  if (!stop_wall) {
    AERROR << "Failed to create path_obstacle for: " << virtual_obstacle_id;
    return;
  }

  return;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file qp_piecewise_st_graph.cc
 **/

#include "modules/planning/tasks/qp_spline_st_speed/qp_piecewise_st_graph.h"

#include <algorithm>
#include <limits>
#include <string>
#include <utility>

#include "modules/common/log.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::VehicleParam;
using apollo::planning_internal::STGraphDebug;

QpPiecewiseStGraph::QpPiecewiseStGraph(
    const QpSplineStSpeedConfig& qp_spline_st_speed_config,
    const VehicleParam& veh_param)
    : qp_spline_st_speed_config_(qp_spline_st_speed_config),
      t_evaluated_resolution_(
          qp_spline_st_speed_config_.total_time() /
          qp_spline_st_speed_config_.number_of_evaluated_graph_t()) {
  Init();
}

void QpPiecewiseStGraph::Init() {
  // init evaluated t positions
  double curr_t = t_evaluated_resolution_;
  for (uint32_t i = 0;
       i < qp_spline_st_speed_config_.number_of_evaluated_graph_t(); ++i) {
    t_evaluated_.push_back(curr_t);
    curr_t += t_evaluated_resolution_;
  }
}

void QpPiecewiseStGraph::SetDebugLogger(
    planning_internal::STGraphDebug* st_graph_debug) {
  if (st_graph_debug) {
    st_graph_debug->Clear();
    st_graph_debug_ = st_graph_debug;
  }
}

Status QpPiecewiseStGraph::Search(
    const StGraphData& st_graph_data, SpeedData* const speed_data,
    const std::pair<double, double>& accel_bound) {
  cruise_.clear();

  // reset piecewise linear generator
  generator_.reset(new PiecewiseLinearGenerator(
      qp_spline_st_speed_config_.number_of_evaluated_graph_t(),
      t_evaluated_resolution_));

  // start to search for best st points
  init_point_ = st_graph_data.init_point();

  // modified total path length
  if (st_graph_data.path_data_length() <
      qp_spline_st_speed_config_.total_path_length()) {
    qp_spline_st_speed_config_.set_total_path_length(
        st_graph_data.path_data_length());
  }

  if (!ApplyConstraint(st_graph_data.init_point(), st_graph_data.speed_limit(),
                       st_graph_data.st_boundaries(), accel_bound)
           .ok()) {
    const std::string msg = "Apply constraint failed!";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }

  if (!ApplyKernel(st_graph_data.st_boundaries(), st_graph_data.speed_limit())
           .ok()) {
    const std::string msg = "Apply kernel failed!";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }

  if (!Solve().ok()) {
    const std::string msg = "Solve qp problem failed!";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }

  // extract output
  speed_data->Clear();
  const auto& res = generator_->params();
  speed_data->AppendSpeedPoint(0.0, 0.0, init_point_.v(), init_point_.a(), 0.0);

  double s = 0.0;
  double v = 0.0;
  double a = 0.0;

  double time = t_evaluated_resolution_;
  double dt = t_evaluated_resolution_;

  for (int i = 0; i < res.rows(); ++i, time += t_evaluated_resolution_) {
    s = res(i, 0);
    if (i == 0) {
      v = s / dt;
      a = (v - init_point_.v()) / dt;
    } else {
      const double curr_v = (s - res(i - 1, 0)) / dt;
      a = (curr_v - v) / dt;
      v = curr_v;
    }
    speed_data->AppendSpeedPoint(s, time, v, a, 0.0);
  }
  return Status::OK();
}

Status QpPiecewiseStGraph::ApplyConstraint(
    const common::TrajectoryPoint& init_point, const SpeedLimit& speed_limit,
    const std::vector<StBoundary>& boundaries,
    const std::pair<double, double>& accel_bound) {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

Status QpPiecewiseStGraph::ApplyKernel(
    const std::vector<StBoundary>& boundaries, const SpeedLimit& speed_limit) {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

Status QpPiecewiseStGraph::AddFollowReferenceLineKernel(
    const std::vector<StBoundary>& boundaries, const double weight) {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

Status QpPiecewiseStGraph::GetSConstraintByTime(
    const std::vector<StBoundary>& boundaries, const double time,
    const double total_path_s, double* const s_upper_bound,
    double* const s_lower_bound) const {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

Status QpPiecewiseStGraph::EstimateSpeedUpperBound(
    const common::TrajectoryPoint& init_point, const SpeedLimit& speed_limit,
    std::vector<double>* speed_upper_bound) const {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: Updated qp_piecewise_st_graph.<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file qp_piecewise_st_graph.cc
 **/

#include "modules/planning/tasks/qp_spline_st_speed/qp_piecewise_st_graph.h"

#include <algorithm>
#include <limits>
#include <string>
#include <utility>

#include "modules/common/log.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::VehicleParam;
using apollo::planning_internal::STGraphDebug;

QpPiecewiseStGraph::QpPiecewiseStGraph(
    const QpSplineStSpeedConfig& qp_spline_st_speed_config,
    const VehicleParam& veh_param)
    : qp_spline_st_speed_config_(qp_spline_st_speed_config),
      t_evaluated_resolution_(
          qp_spline_st_speed_config_.total_time() /
          qp_spline_st_speed_config_.number_of_evaluated_graph_t()) {
  Init();
}

void QpPiecewiseStGraph::Init() {
  // init evaluated t positions
  double curr_t = t_evaluated_resolution_;
  for (uint32_t i = 0;
       i < qp_spline_st_speed_config_.number_of_evaluated_graph_t(); ++i) {
    t_evaluated_.push_back(curr_t);
    curr_t += t_evaluated_resolution_;
  }
}

void QpPiecewiseStGraph::SetDebugLogger(
    planning_internal::STGraphDebug* st_graph_debug) {
  if (st_graph_debug) {
    st_graph_debug->Clear();
    st_graph_debug_ = st_graph_debug;
  }
}

Status QpPiecewiseStGraph::Search(
    const StGraphData& st_graph_data, SpeedData* const speed_data,
    const std::pair<double, double>& accel_bound) {
  cruise_.clear();

  // reset piecewise linear generator
  generator_.reset(new PiecewiseLinearGenerator(
      qp_spline_st_speed_config_.number_of_evaluated_graph_t(),
      t_evaluated_resolution_));

  // start to search for best st points
  init_point_ = st_graph_data.init_point();

  // modified total path length
  if (st_graph_data.path_data_length() <
      qp_spline_st_speed_config_.total_path_length()) {
    qp_spline_st_speed_config_.set_total_path_length(
        st_graph_data.path_data_length());
  }

  if (!ApplyConstraint(st_graph_data.init_point(), st_graph_data.speed_limit(),
                       st_graph_data.st_boundaries(), accel_bound)
           .ok()) {
    const std::string msg = "Apply constraint failed!";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }

  if (!ApplyKernel(st_graph_data.st_boundaries(), st_graph_data.speed_limit())
           .ok()) {
    const std::string msg = "Apply kernel failed!";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }

  if (!Solve().ok()) {
    const std::string msg = "Solve qp problem failed!";
    AERROR << msg;
    return Status(ErrorCode::PLANNING_ERROR, msg);
  }

  // extract output
  speed_data->Clear();
  const auto& res = generator_->params();
  speed_data->AppendSpeedPoint(0.0, 0.0, init_point_.v(), init_point_.a(), 0.0);

  double s = 0.0;
  double v = 0.0;
  double a = 0.0;

  double time = t_evaluated_resolution_;
  double dt = t_evaluated_resolution_;

  for (int i = 0; i < res.rows(); ++i, time += t_evaluated_resolution_) {
    s = res(i, 0);
    if (i == 0) {
      v = s / dt;
      a = (v - init_point_.v()) / dt;
    } else {
      const double curr_v = (s - res(i - 1, 0)) / dt;
      a = (curr_v - v) / dt;
      v = curr_v;
    }
    speed_data->AppendSpeedPoint(s, time, v, a, 0.0);
  }
  return Status::OK();
}

Status QpPiecewiseStGraph::ApplyConstraint(
    const common::TrajectoryPoint& init_point, const SpeedLimit& speed_limit,
    const std::vector<StBoundary>& boundaries,
    const std::pair<double, double>& accel_bound) {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

Status QpPiecewiseStGraph::ApplyKernel(
    const std::vector<StBoundary>& boundaries, const SpeedLimit& speed_limit) {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

Status QpPiecewiseStGraph::AddFollowReferenceLineKernel(
    const std::vector<StBoundary>& boundaries, const double weight) {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

Status QpPiecewiseStGraph::GetSConstraintByTime(
    const std::vector<StBoundary>& boundaries, const double time,
    const double total_path_s, double* const s_upper_bound,
    double* const s_lower_bound) const {
  // TODO(Lianliang): implement this function.
  return Status::OK();
}

Status QpPiecewiseStGraph::EstimateSpeedUpperBound(
    const common::TrajectoryPoint& init_point, const SpeedLimit& speed_limit,
    std::vector<double>* speed_upper_bound) const {
  // TODO(Lianliang): define a QpStGraph class and move this function in it.
  DCHECK_NOTNULL(speed_upper_bound);

  speed_upper_bound->clear();

  // use v to estimate position: not accurate, but feasible in cyclic
  // processing. We can do the following process multiple times and use
  // previous cycle's results for better estimation.
  const double v = init_point.v();

  if (static_cast<double>(t_evaluated_.size() +
                          speed_limit.speed_limit_points().size()) <
      t_evaluated_.size() * std::log(static_cast<double>(
                                speed_limit.speed_limit_points().size()))) {
    uint32_t i = 0;
    uint32_t j = 0;
    const double kDistanceEpsilon = 1e-6;
    while (i < t_evaluated_.size() &&
           j + 1 < speed_limit.speed_limit_points().size()) {
      const double distance = v * t_evaluated_[i];
      if (fabs(distance - speed_limit.speed_limit_points()[j].first) <
          kDistanceEpsilon) {
        speed_upper_bound->push_back(
            speed_limit.speed_limit_points()[j].second);
        ++i;
        ADEBUG << "speed upper bound:" << speed_upper_bound->back();
      } else if (distance < speed_limit.speed_limit_points()[j].first) {
        ++i;
      } else if (distance <= speed_limit.speed_limit_points()[j + 1].first) {
        speed_upper_bound->push_back(speed_limit.GetSpeedLimitByS(distance));
        ADEBUG << "speed upper bound:" << speed_upper_bound->back();
        ++i;
      } else {
        ++j;
      }
    }

    for (uint32_t k = speed_upper_bound->size(); k < t_evaluated_.size(); ++k) {
      speed_upper_bound->push_back(FLAGS_planning_upper_speed_limit);
      ADEBUG << "speed upper bound:" << speed_upper_bound->back();
    }
  } else {
    auto cmp = [](const std::pair<double, double>& p1, const double s) {
      return p1.first < s;
    };

    const auto& speed_limit_points = speed_limit.speed_limit_points();
    for (const double t : t_evaluated_) {
      const double s = v * t;

      // NOTICE: we are using binary search here based on two assumptions:
      // (1) The s in speed_limit_points increase monotonically.
      // (2) The evaluated_t_.size() << number of speed_limit_points.size()
      //
      // If either of the two assumption is failed, a new algorithm must be
      // used
      // to replace the binary search.

      const auto& it = std::lower_bound(speed_limit_points.begin(),
                                        speed_limit_points.end(), s, cmp);
      if (it != speed_limit_points.end()) {
        speed_upper_bound->push_back(it->second);
      } else {
        speed_upper_bound->push_back(speed_limit_points.back().second);
      }
    }
  }

  const double kTimeBuffer = 2.0;
  const double kSpeedBuffer = 0.1;
  for (uint32_t k = 0; k < t_evaluated_.size() && t_evaluated_[k] < kTimeBuffer;
       ++k) {
    speed_upper_bound->at(k) =
        std::fmax(init_point_.v() + kSpeedBuffer, speed_upper_bound->at(k));
  }

  return Status::OK();
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>// (C) 2014 Arek Olek

#pragma once

#include <stack>
#include <vector>

#include <boost/graph/adjacency_list.hpp>

#include "range.hpp"

namespace detail {

  unsigned typedef node;
  std::pair<node, node> typedef edge;

  template <class Graph>
  void visit(Graph& G, Graph& T, node v,
    node& next_rank, std::vector<node>& rank,
    std::vector<node>& deg, std::stack<edge>& edges) {

    rank[v] = next_rank++;

    node w, x, y;
    unsigned min_deg = UINT_MAX;

    for(auto u : range(adjacent_vertices(v, G))) {
      --deg[u];

      if(rank[u] == 0 && deg[u] < min_deg) {
        w = u;
        min_deg = deg[u];
      }
    }

    if(min_deg == UINT_MAX) {
      while(!edges.empty() && rank[edges.top().second] != 0)
        edges.pop();
      if(edges.empty())
        return;
      std::tie(x, y) = edges.top();
    } else std::tie(x, y) = edge(v, w);

    add_edge(x, y, T);

    for(auto u : range(adjacent_vertices(x, G)))
      if(u != y && rank[u] == 0)
        edges.emplace(x, u);

    visit(G, T, y, next_rank, rank, deg, edges);
  }

}

template <class Graph>
Graph rdfs_tree(Graph& G) {
  unsigned n = num_vertices(G);
  Graph T(n);
  unsigned next_rank = 1;
  std::vector<detail::node> rank(n, 0), deg(n);
  std::stack<detail::edge> edges;

  for(auto v : range(vertices(G)))
    deg[v] = degree(v, G);

  detail::visit(G, T, 0, next_rank, rank, deg, edges);

  return T;
}
<commit_msg>fix compile warning<commit_after>// (C) 2014 Arek Olek

#pragma once

#include <stack>
#include <vector>

#include <boost/graph/adjacency_list.hpp>

#include "range.hpp"

namespace detail {

  unsigned typedef node;
  std::pair<node, node> typedef edge;

  template <class Graph>
  void visit(Graph& G, Graph& T, node v,
    node& next_rank, std::vector<node>& rank,
    std::vector<node>& deg, std::stack<edge>& edges) {

    rank[v] = next_rank++;

    node w = -1, x, y;
    unsigned min_deg = UINT_MAX;

    for(auto u : range(adjacent_vertices(v, G))) {
      --deg[u];

      if(rank[u] == 0 && deg[u] < min_deg) {
        w = u;
        min_deg = deg[u];
      }
    }

    if(min_deg == UINT_MAX) {
      while(!edges.empty() && rank[edges.top().second] != 0)
        edges.pop();
      if(edges.empty())
        return;
      std::tie(x, y) = edges.top();
    } else std::tie(x, y) = edge(v, w);

    add_edge(x, y, T);

    for(auto u : range(adjacent_vertices(x, G)))
      if(u != y && rank[u] == 0)
        edges.emplace(x, u);

    visit(G, T, y, next_rank, rank, deg, edges);
  }

}

template <class Graph>
Graph rdfs_tree(Graph& G) {
  unsigned n = num_vertices(G);
  Graph T(n);
  unsigned next_rank = 1;
  std::vector<detail::node> rank(n, 0), deg(n);
  std::stack<detail::edge> edges;

  for(auto v : range(vertices(G)))
    deg[v] = degree(v, G);

  detail::visit(G, T, 0, next_rank, rank, deg, edges);

  return T;
}
<|endoftext|>


<commit_before>#pragma once

#include <bitset>
#include <cstring>
#include <iostream>

namespace bitwise {
	using std::cout;
	using std::ostream;

	template <typename A>
	class binary final {
		template <typename B>
		using conref = const B&;

		constexpr static size_t sz{sizeof(A)};
		constexpr static size_t szB{sz << 3};

		using bitA = std::bitset<szB>;
		using byte = unsigned char;
		using bit = bool;

	public:
		explicit binary(void) = delete;

		explicit binary(conref<A> a) noexcept {
			byte* ptr = new byte[sz];
			memcpy((void *) ptr, (const void* const) &a, sz);

			for (size_t i = 0; i < sz; ++i) {
				static byte ch;
				ch = ptr[i];
				for (size_t j = 0; j < 8; ++j) {
					static bool bitVal;
					bitVal = binary<A>::getBitFromByte(ch, j);
					this->bits[binary<A>::getBitIdx(i, j)] = bitVal;
				}
			}

			delete [] ptr;
		}

		explicit binary(A&& a) noexcept : binary(a) {}

		template <typename... B>
		explicit binary(B... b) = delete;

		inline ~binary(void) noexcept{
			bits.~bitA();
		}

		inline void print(void) const noexcept {
			binary<A>::print(std::cout, *this);
		}

		inline bool getBit(conref<size_t> idx) const noexcept {
			return bits[idx];
		}

		inline bool getBit(conref<byte> byteIdx, conref<byte> bitIdx) const noexcept {
			return binary<A>::getBit(*this, byteIdx, bitIdx);
		}

		template <typename... B>
		inline bool getBit(B... b) const noexcept = delete;

		template <typename B>
		friend inline ostream& operator<<(ostream& os, conref<binary<B>> a) noexcept {
			a.print();

			return os;
		}

		template <typename B>
		friend inline ostream& operator<<(ostream& os, binary<B>&& a) noexcept {
			a.print();

			return os;
		}

	private:
		static inline void print(std::ostream& os, conref<binary<A>> a) noexcept {
			constexpr static size_t szOneLess{sz - 1};

			for (size_t i = 0; i < sz; ++i) {
				for (size_t j = 0; j < 8; ++j) {
					static bit bitIdx;
					bitIdx = (bit) a.bits[getBitIdx(i, j)];
					os << bitIdx;
				}

				if (szOneLess != i) {
					os << ' ';
				}
			}
		}

		static inline bit getBitFromByte(conref<byte> data, conref<byte> bitIdx) noexcept {
			return data & (1 << bitIdx);
		}

		static inline size_t getBitIdx(conref<size_t> byteIdx, conref<size_t> bitIdx) noexcept {
			return (byteIdx << 3) + bitIdx;
		}

		static inline bit getBit(conref<binary<A>> bits, conref<size_t> byteIdx, conref<size_t> bitIdx) noexcept {
			return bits[getBitIdx(byteIdx, bitIdx)];
		}

		bitA bits;
	};
}<commit_msg>added to whole despairagus interproject namespace<commit_after>#pragma once

#include <bitset>
#include <cstring>
#include <iostream>

namespace desparaigus {
	namespace bitwise {
		using std::cout;
		using std::ostream;

		template<typename A>
		class binary final {
			template<typename B>
			using conref = const B &;

			constexpr static size_t sz{sizeof(A)};
			constexpr static size_t szB{sz << 3};

			using bitA = std::bitset<szB>;
			using byte = unsigned char;
			using bit = bool;

		public:
			explicit binary(void) = delete;

			explicit binary(conref<A> a) noexcept {
				byte *ptr = new byte[sz];
				memcpy((void *) ptr, (const void *const) &a, sz);

				for (size_t i = 0; i < sz; ++i) {
					static byte ch;
					ch = ptr[i];
					for (size_t j = 0; j < 8; ++j) {
						static bool bitVal;
						bitVal = binary<A>::getBitFromByte(ch, j);
						this->bits[binary<A>::getBitIdx(i, j)] = bitVal;
					}
				}

				delete[] ptr;
			}

			explicit binary(A &&a) noexcept : binary(a) {
			}

			template<typename... B>
			explicit binary(B... b) = delete;

			inline ~binary(void) noexcept {
				bits.~bitA();
			}

			inline void print(void) const noexcept {
				binary<A>::print(std::cout, *this);
			}

			inline bool getBit(conref<size_t> idx) const noexcept {
				return bits[idx];
			}

			inline bool getBit(conref<byte> byteIdx, conref<byte> bitIdx) const noexcept {
				return binary<A>::getBit(*this, byteIdx, bitIdx);
			}

			template<typename... B>
			inline bool getBit(B... b) const noexcept = delete;

			template<typename B>
			friend inline ostream &operator<<(ostream &os, conref<binary<B>> a) noexcept {
				a.print();

				return os;
			}

			template<typename B>
			friend inline ostream &operator<<(ostream &os, binary<B> &&a) noexcept {
				a.print();

				return os;
			}

		private:
			static inline void print(std::ostream &os, conref<binary<A>> a) noexcept {
				constexpr static size_t szOneLess{sz - 1};

				for (size_t i = 0; i < sz; ++i) {
					for (size_t j = 0; j < 8; ++j) {
						static bit bitIdx;
						bitIdx = (bit) a.bits[getBitIdx(i, j)];
						os << bitIdx;
					}

					if (szOneLess != i) {
						os << ' ';
					}
				}
			}

			static inline bit getBitFromByte(conref<byte> data, conref<byte> bitIdx) noexcept {
				return data & (1 << bitIdx);
			}

			static inline size_t getBitIdx(conref<size_t> byteIdx, conref<size_t> bitIdx) noexcept {
				return (byteIdx << 3) + bitIdx;
			}

			static inline bit getBit(conref<binary<A>> bits, conref<size_t> byteIdx, conref<size_t> bitIdx) noexcept {
				return bits[getBitIdx(byteIdx, bitIdx)];
			}

			bitA bits;
		};
	}
}<|endoftext|>


<commit_before>#include <node.h>
#include <nan.h>
#include <v8.h>
#include "gamepad/Gamepad.h"

using namespace v8;

Nan::Persistent<Object> persistentHandle;
Nan::AsyncResource asyncResource("gamepad");

NAN_METHOD(nGamepad_init) {
  Nan::HandleScope scope;
  Gamepad_init();
  return;
}

NAN_METHOD(nGamepad_shutdown) {
  Nan::HandleScope scope;
  Gamepad_shutdown();
  return;
}

NAN_METHOD(nGamepad_numDevices) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(Nan::New<Number>(Gamepad_numDevices()));
}

Local<Object> nGamepad_toObject(Gamepad_device* device) {
  Local<Object> obj = Nan::New<Object>();
  obj->Set(Nan::New("deviceID").ToLocalChecked(), Nan::New<Number>(device->deviceID));
  obj->Set(Nan::New("description").ToLocalChecked(), Nan::New<String>(device->description).ToLocalChecked());
  obj->Set(Nan::New("vendorID").ToLocalChecked(), Nan::New<Number>(device->vendorID));
  obj->Set(Nan::New("productID").ToLocalChecked(), Nan::New<Number>(device->productID));
  Local<Array> axes = Nan::New<Array>(device->numAxes);
  for (unsigned int i = 0; i < device->numAxes; i++) {
    axes->Set(i, Nan::New<Number>(device->axisStates[i]));
  }
  obj->Set(Nan::New("axisStates").ToLocalChecked(), axes);
  Local<Array> buttons = Nan::New<Array>(device->numButtons);
  for (unsigned int i = 0; i < device->numButtons; i++) {
    buttons->Set(i, Nan::New<Boolean>(device->buttonStates[i]));
  }
  obj->Set(Nan::New("buttonStates").ToLocalChecked(), buttons);
  return obj;
}

NAN_METHOD(nGamepad_deviceAtIndex) {
  Nan::HandleScope scope;
  int deviceIndex = info[0].As<Int32>()->Value();
  struct Gamepad_device* device = Gamepad_deviceAtIndex(deviceIndex);
  if (!device) return;
  info.GetReturnValue().Set(nGamepad_toObject(device));
}

NAN_METHOD(nGamepad_detectDevices) {
  Nan::HandleScope scope;
  Gamepad_detectDevices();
  return;
}

NAN_METHOD(nGamepad_processEvents) {
  Nan::HandleScope scope;
  Gamepad_processEvents();
  return;
}

void nGamepad_deviceAttach_cb(struct Gamepad_device* device, void* context) {
  Local<Value> info[] = {
    Nan::New("attach").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
    nGamepad_toObject(device),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 3, info);
}

void nGamepad_deviceRemove_cb(struct Gamepad_device* device, void* context) {
  Local<Value> info[] = {
    Nan::New("remove").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 2, info);
}

void nGamepad_buttonDown_cb(struct Gamepad_device* device, unsigned int buttonID, double timestamp, void* context) {
  Local<Value> info[] = {
    Nan::New("down").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
    Nan::New<Number>(buttonID),
    Nan::New<Number>(timestamp),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 4, info);
}

void nGamepad_buttonUp_cb(struct Gamepad_device* device, unsigned int buttonID, double timestamp, void* context) {
  Local<Value> info[] = {
    Nan::New("up").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
    Nan::New<Number>(buttonID),
    Nan::New<Number>(timestamp),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 4, info);
}

void nGamepad_axisMove_cb(struct Gamepad_device* device, unsigned int axisID, float value, float lastValue, double timestamp, void * context) {
  Local<Value> info[] = {
    Nan::New("move").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
    Nan::New<Number>(axisID),
    Nan::New<Number>(value),
    Nan::New<Number>(lastValue),
    Nan::New<Number>(timestamp),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 6, info);
}

void init(Local<Object> target) {
  Local<Object> handle = Nan::New<Object>();
  persistentHandle.Reset(handle);

  target->Set(Nan::New<String>("context").ToLocalChecked(), handle);

  Gamepad_deviceAttachFunc(nGamepad_deviceAttach_cb, NULL);
  Gamepad_deviceRemoveFunc(nGamepad_deviceRemove_cb, NULL);
  Gamepad_buttonDownFunc(nGamepad_buttonDown_cb, NULL);
  Gamepad_buttonUpFunc(nGamepad_buttonUp_cb, NULL);
  Gamepad_axisMoveFunc(nGamepad_axisMove_cb, NULL);

  Nan::SetMethod(target, "init", nGamepad_init);
  Nan::SetMethod(target, "shutdown", nGamepad_shutdown);
  Nan::SetMethod(target, "numDevices", nGamepad_numDevices);
  Nan::SetMethod(target, "deviceAtIndex", nGamepad_deviceAtIndex);
  Nan::SetMethod(target, "detectDevices", nGamepad_detectDevices);
  Nan::SetMethod(target, "processEvents", nGamepad_processEvents);
}

NODE_MODULE(gamepad, init)
<commit_msg>Replace deprecated usage of Set with Nan::Set<commit_after>#include <node.h>
#include <nan.h>
#include <v8.h>
#include "gamepad/Gamepad.h"

using namespace v8;

Nan::Persistent<Object> persistentHandle;
Nan::AsyncResource asyncResource("gamepad");

NAN_METHOD(nGamepad_init) {
  Nan::HandleScope scope;
  Gamepad_init();
  return;
}

NAN_METHOD(nGamepad_shutdown) {
  Nan::HandleScope scope;
  Gamepad_shutdown();
  return;
}

NAN_METHOD(nGamepad_numDevices) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(Nan::New<Number>(Gamepad_numDevices()));
}

Local<Object> nGamepad_toObject(Gamepad_device* device) {
  Local<Object> obj = Nan::New<Object>();
  Nan::Set(obj, Nan::New("deviceID").ToLocalChecked(), Nan::New<Number>(device->deviceID));
  Nan::Set(obj, Nan::New("description").ToLocalChecked(), Nan::New<String>(device->description).ToLocalChecked());
  Nan::Set(obj, Nan::New("vendorID").ToLocalChecked(), Nan::New<Number>(device->vendorID));
  Nan::Set(obj, Nan::New("productID").ToLocalChecked(), Nan::New<Number>(device->productID));
  Local<Array> axes = Nan::New<Array>(device->numAxes);
  for (unsigned int i = 0; i < device->numAxes; i++) {
    Nan::Set(axes, i, Nan::New<Number>(device->axisStates[i]));
  }
  Nan::Set(obj, Nan::New("axisStates").ToLocalChecked(), axes);
  Local<Array> buttons = Nan::New<Array>(device->numButtons);
  for (unsigned int i = 0; i < device->numButtons; i++) {
    Nan::Set(buttons, i, Nan::New<Boolean>(device->buttonStates[i]));
  }
  Nan::Set(obj, Nan::New("buttonStates").ToLocalChecked(), buttons);
  return obj;
}

NAN_METHOD(nGamepad_deviceAtIndex) {
  Nan::HandleScope scope;
  int deviceIndex = info[0].As<Int32>()->Value();
  struct Gamepad_device* device = Gamepad_deviceAtIndex(deviceIndex);
  if (!device) return;
  info.GetReturnValue().Set(nGamepad_toObject(device));
}

NAN_METHOD(nGamepad_detectDevices) {
  Nan::HandleScope scope;
  Gamepad_detectDevices();
  return;
}

NAN_METHOD(nGamepad_processEvents) {
  Nan::HandleScope scope;
  Gamepad_processEvents();
  return;
}

void nGamepad_deviceAttach_cb(struct Gamepad_device* device, void* context) {
  Local<Value> info[] = {
    Nan::New("attach").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
    nGamepad_toObject(device),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 3, info);
}

void nGamepad_deviceRemove_cb(struct Gamepad_device* device, void* context) {
  Local<Value> info[] = {
    Nan::New("remove").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 2, info);
}

void nGamepad_buttonDown_cb(struct Gamepad_device* device, unsigned int buttonID, double timestamp, void* context) {
  Local<Value> info[] = {
    Nan::New("down").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
    Nan::New<Number>(buttonID),
    Nan::New<Number>(timestamp),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 4, info);
}

void nGamepad_buttonUp_cb(struct Gamepad_device* device, unsigned int buttonID, double timestamp, void* context) {
  Local<Value> info[] = {
    Nan::New("up").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
    Nan::New<Number>(buttonID),
    Nan::New<Number>(timestamp),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 4, info);
}

void nGamepad_axisMove_cb(struct Gamepad_device* device, unsigned int axisID, float value, float lastValue, double timestamp, void * context) {
  Local<Value> info[] = {
    Nan::New("move").ToLocalChecked(),
    Nan::New<Number>(device->deviceID),
    Nan::New<Number>(axisID),
    Nan::New<Number>(value),
    Nan::New<Number>(lastValue),
    Nan::New<Number>(timestamp),
  };
  asyncResource.runInAsyncScope(Nan::New<Object>(persistentHandle), "on", 6, info);
}

void init(Local<Object> target) {
  Local<Object> handle = Nan::New<Object>();
  persistentHandle.Reset(handle);

  Nan::Set(target, Nan::New<String>("context").ToLocalChecked(), handle);

  Gamepad_deviceAttachFunc(nGamepad_deviceAttach_cb, NULL);
  Gamepad_deviceRemoveFunc(nGamepad_deviceRemove_cb, NULL);
  Gamepad_buttonDownFunc(nGamepad_buttonDown_cb, NULL);
  Gamepad_buttonUpFunc(nGamepad_buttonUp_cb, NULL);
  Gamepad_axisMoveFunc(nGamepad_axisMove_cb, NULL);

  Nan::SetMethod(target, "init", nGamepad_init);
  Nan::SetMethod(target, "shutdown", nGamepad_shutdown);
  Nan::SetMethod(target, "numDevices", nGamepad_numDevices);
  Nan::SetMethod(target, "deviceAtIndex", nGamepad_deviceAtIndex);
  Nan::SetMethod(target, "detectDevices", nGamepad_detectDevices);
  Nan::SetMethod(target, "processEvents", nGamepad_processEvents);
}

NODE_MODULE(gamepad, init)
<|endoftext|>


<commit_before>/*
 * producer.cpp
 *
 *  Created on: Dec 28, 2012
 *      Author: partio
 */

#include "producer.h"

using namespace himan;

producer::producer()
    : itsFmiProducerId(kHPMissingInt)
    , itsProcess(kHPMissingInt)
	, itsCentre(kHPMissingInt)
	, itsTableVersion(kHPMissingInt)
	, itsNeonsName("")
{

}

producer::producer(long theFmiProducerId)
    : itsFmiProducerId(theFmiProducerId)
    , itsProcess(kHPMissingInt)
    , itsCentre(kHPMissingInt)
	, itsTableVersion(kHPMissingInt)
	, itsNeonsName("")
{

}

producer::producer(long theCentre, long theProcess)
    : itsFmiProducerId(kHPMissingInt)
    , itsProcess(theProcess)
    , itsCentre(theCentre)
	, itsTableVersion(kHPMissingInt)
	, itsNeonsName("")
{

}

producer::producer(long theFmiProducerId, long theCentre, long theProcess, const std::string& theNeonsName)
    : itsFmiProducerId(theFmiProducerId)
    , itsProcess(theProcess)
    , itsCentre(theCentre)
	, itsTableVersion(kHPMissingInt)
	, itsNeonsName("")
{

}

void producer::Centre(long theCentre)
{
    itsCentre = theCentre;
}

long producer::Centre() const
{
    return itsCentre;
}

void producer::Process(long theProcess)
{
    itsProcess = theProcess;
}

long producer::Process() const
{
    return itsProcess;
}

void producer::Id(long theId)
{
    itsFmiProducerId = theId;
}

long producer::Id() const
{
    return itsFmiProducerId;
}

void producer::Name(const std::string& theName)
{
    itsNeonsName = theName;
}

std::string producer::Name() const
{
    return itsNeonsName;
}

long producer::TableVersion() const
{
	return itsTableVersion;
}

void producer::TableVersion(long theTableVersion)
{
	itsTableVersion = theTableVersion;
}

std::ostream& producer::Write(std::ostream& file) const
{

    file << "<" << ClassName() << " " << Version() << ">" << std::endl;

    file << "__itsFmiProducerId__ " << itsFmiProducerId << std::endl;
    file << "__itsProcess__ " << itsProcess << std::endl;
    file << "__itsCentre__ " << itsCentre << std::endl;
    file << "__itsNeonsName__ " << itsNeonsName << std::endl;
    file << "__itsTableVersion__ " << itsTableVersion << std::endl;

    return file;

}
<commit_msg>Set default name<commit_after>/*
 * producer.cpp
 *
 *  Created on: Dec 28, 2012
 *      Author: partio
 */

#include "producer.h"

using namespace himan;

producer::producer()
    : itsFmiProducerId(kHPMissingInt)
    , itsProcess(kHPMissingInt)
	, itsCentre(kHPMissingInt)
	, itsTableVersion(kHPMissingInt)
	, itsNeonsName("himanDefaultProducer")
{

}

producer::producer(long theFmiProducerId)
    : itsFmiProducerId(theFmiProducerId)
    , itsProcess(kHPMissingInt)
    , itsCentre(kHPMissingInt)
	, itsTableVersion(kHPMissingInt)
	, itsNeonsName("himanDefaultProducer")
{

}

producer::producer(long theCentre, long theProcess)
    : itsFmiProducerId(kHPMissingInt)
    , itsProcess(theProcess)
    , itsCentre(theCentre)
	, itsTableVersion(kHPMissingInt)
	, itsNeonsName("himanDefaultProducer")
{

}

producer::producer(long theFmiProducerId, long theCentre, long theProcess, const std::string& theNeonsName)
    : itsFmiProducerId(theFmiProducerId)
    , itsProcess(theProcess)
    , itsCentre(theCentre)
	, itsTableVersion(kHPMissingInt)
	, itsNeonsName(theNeonsName)
{

}

void producer::Centre(long theCentre)
{
    itsCentre = theCentre;
}

long producer::Centre() const
{
    return itsCentre;
}

void producer::Process(long theProcess)
{
    itsProcess = theProcess;
}

long producer::Process() const
{
    return itsProcess;
}

void producer::Id(long theId)
{
    itsFmiProducerId = theId;
}

long producer::Id() const
{
    return itsFmiProducerId;
}

void producer::Name(const std::string& theName)
{
    itsNeonsName = theName;
}

std::string producer::Name() const
{
    return itsNeonsName;
}

long producer::TableVersion() const
{
	return itsTableVersion;
}

void producer::TableVersion(long theTableVersion)
{
	itsTableVersion = theTableVersion;
}

std::ostream& producer::Write(std::ostream& file) const
{

    file << "<" << ClassName() << " " << Version() << ">" << std::endl;

    file << "__itsFmiProducerId__ " << itsFmiProducerId << std::endl;
    file << "__itsProcess__ " << itsProcess << std::endl;
    file << "__itsCentre__ " << itsCentre << std::endl;
    file << "__itsNeonsName__ " << itsNeonsName << std::endl;
    file << "__itsTableVersion__ " << itsTableVersion << std::endl;

    return file;

}
<|endoftext|>


<commit_before>#include "SysControl.h"
#include "ControlsApp.h"
#include "ControlsXPad360.h"
#include "Engine.h"
#include "App.h"
#include "Engine.h"
#include "App.h"
#include "Input.h"
#include "ObjectGui.h"
#include "WidgetLabel.h"

//解决跨平台字符集兼容问题
#ifdef _WIN32
#pragma execution_character_set("utf-8")
#endif

using namespace MathLib;

class CSysControlLocal : public CSysControl
{
public:
	CSysControlLocal();
	virtual ~CSysControlLocal();

	virtual void Init();	//角色要初始化，着色器要初始化，
	virtual void Update(float ifps);
	virtual void Shutdown();

	virtual int GetState(int state);		//鼠标状态，键盘状态，人物状态，子弹状态等等。
	virtual int ClearState(int state);

	virtual float GetMouseDX();
	virtual float GetMouseDY();

	virtual void SetMouseGrab(int g);		//设置是否显示鼠标
	virtual int GetMouseGrab();			//获取鼠标状态，是显示呢还是不显示的状态。

	virtual void SetControlMode(ControlMode mode);			//控制模式
	virtual ControlMode GetControlMode() const;				//获取控制模式

private:
	void Update_Mouse(float ifps);
	void Update_Keyboard(float ifps);
	void Update_XPad360(float ifps);

	CControlsApp        *m_pControlsApp;		//控制游戏中移动
	CControlsXPad360    *m_pControlsXPad360;
	ControlMode         m_nControlMode;			//控制模式

	int                 m_nOldMouseX;			//上一个鼠标坐标X
	int                 m_nOldMouseY;			//上一个鼠标坐标Y

	CObjectGui          *m_pTest3DUI;
	CWidgetLabel        *m_pTestMessageLabel;

};

CSysControlLocal::CSysControlLocal()
{

}
CSysControlLocal::~CSysControlLocal()
{

}

void CSysControlLocal::Init()
{
	m_pControlsApp = new CControlsApp;
	m_pControlsXPad360 = new CControlsXPad360(0);

	g_Engine.pApp->SetMouseGrab(0);
	g_Engine.pApp->SetMouseShow(0);

	SetControlMode(CONTROL_KEYBORAD_MOUSE);

	m_pTest3DUI = new CObjectGui(2.0f, 1.0f, "data/core/gui/");
	m_pTest3DUI->SetMouseShow(0);
	m_pTest3DUI->SetBackground(1);
	m_pTest3DUI->SetBackgroundColor(vec4(1.0f, 0.0f, 0.0f, 1.0f));

	m_pTest3DUI->SetScreenSize(800, 400);
	m_pTest3DUI->SetControlDistance(1000.0f);
	m_pTest3DUI->CreateMaterial("gui_base");	 //show in game

	m_pTest3DUI->SetWorldTransform(Translate(0.0f, 0.0f, 2.0f) * MakeRotationFromZY(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f)));

	m_pTestMessageLabel = new CWidgetLabel(m_pTest3DUI->GetGui());	//初始化文字标签
	m_pTest3DUI->GetGui()->AddChild(m_pTestMessageLabel, CGui::ALIGN_CENTER);
	m_pTestMessageLabel->SetFontColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

	m_pTestMessageLabel = new CWidgetLabel(m_pTest3DUI->GetGui());	//初始化文字标签
	m_pTest3DUI->GetGui()->AddChild(m_pTestMessageLabel, CGui::ALIGN_CENTER);
	m_pTestMessageLabel->SetFontColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

	m_pTestMessageLabel->SetFontSize(80);		//设置字体大小
	m_pTestMessageLabel->SetFontOutline(1);		//设置字体轮廓
	m_pTestMessageLabel->SetText("两个黄鹂鸣翠柳\n一行白鹭上青天\n窗含西岭千秋雪\n门泊东吴万里船");

	void CSysControlLocal::Update(float ifps)
	{
		Update_Mouse(ifps);
		Update_Keyboard(ifps);
		Update_XPad360(ifps);
	}

	m_nOldMouseX = 0;
	m_nOldMouseY = 0;
}
void CSysControlLocal::Shutdown()
{
	g_Engine.pApp->SetMouseGrab(0);
	g_Engine.pApp->SetMouseShow(0);
	delete m_pControlsApp;
	m_pControlsApp = NULL;
	delete m_pControlsXPad360;
	m_pControlsXPad360 = NULL;
	delete m_pTestMessageLabel;
	m_pTestMessageLabel = NULL;
	delete m_pTest3DUI;
	m_pTest3DUI = NULL;

}

int CSysControlLocal::GetState(int state)
{

	return m_pControlsApp->GetState(state);
}

int CSysControlLocal::ClearState(int state)
{
	return m_pControlsApp->ClearState(state);
}

float CSysControlLocal::GetMouseDX()
{
	return m_pControlsApp->GetMouseDX();
}

float CSysControlLocal::GetMouseDY()
{
	return m_pControlsApp->GetMouseDY();
}
void CSysControlLocal::SetMouseGrab(int g)
{
	g_Engine.pApp->SetMouseGrab(g);
	g_Engine.pGui->SetMouseShow(!g);
}
int CSysControlLocal::GetMouseGrab()
{
	return g_Engine.pApp->GetMouseGrab();
}

void CSysControlLocal::SetControlMode(ControlMode mode)
{
	m_nControlMode = mode;
}

CSysControl::ControlMode CSysControlLocal::GetControlMode() const
{
	return m_nControlMode;
}

CSysControl::ControlMode CSysControlLocal::GetControlMode() const
{
	return m_nControlMode;
}
void CSysControlLocal::Update_Mouse(float ifps)
{
	float dx = (g_Engine.pApp->GetMouseX() - m_nOldMouseX) * g_Engine.pControls->GetMouseSensitivity() * 0.1f;//0.1f这个数值越大，鼠标移动越快
	float dy = (g_Engine.pApp->GetMouseY() - m_nOldMouseY) * g_Engine.pControls->GetMouseSensitivity() * 0.1f;//0.1这个数值越小，鼠标移动越慢

	m_pControlsApp->SetMouseDX(dx);
	m_pControlsApp->SetMouseDY(dy);

	if (g_Engine.pApp->GetMouseGrab() && g_Engine.pApp->GetActive())
	{
		g_Engine.pApp->SetMouse(g_Engine.pApp->GetWidth() / 2, g_Engine.pApp->GetHeight() / 2);
	}

	m_nOldMouseX = g_Engine.pApp->GetMouseX();
	m_nOldMouseY = g_Engine.pApp->GetMouseY();
}

void CSysControlLocal::Update_Keyboard(float ifps)		//键盘按键响应wsad
{

	if (g_Engine.pInput->IsKeyDown('w'))
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 1);
	if (g_Engine.pInput->IsKeyDown('s'))
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 1);
	if (g_Engine.pInput->IsKeyDown('a'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 1);
	if (g_Engine.pInput->IsKeyDown('d'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 1);

	if (g_Engine.pInput->IsKeyUp('w'))
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 0);
	else if (g_Engine.pInput->IsKeyUp('s'))
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 0);

	if (g_Engine.pInput->IsKeyUp('a'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 0);
	else if (g_Engine.pInput->IsKeyUp('d'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 0);
	if (g_Engine.pInput->IsKeyDown(' '))		//空格跳跃
		m_pControlsApp->SetState(CControls::STATE_JUMP, 1);
	else
		m_pControlsApp->SetState(CControls::STATE_JUMP, 0);
}
void CSysControlLocal::Update_XPad360(float ifps)
{
	m_pControlsXPad360->UpdateEvents();
	CUtilStr strMessage;
	strMessage = CUtilStr("测试3D UI\n"),
	strMessage += CUtilStr(m_pControlsXPad360->GetName()) + "\n";

	strMessage += CUtilStr::Format("\n手柄测试\n");
	strMessage += CUtilStr::Format("LeftX:  %5.2f\n", m_pControlsXPad360->GetLeftX());
	strMessage += CUtilStr::Format("LeftY:  %5.2f\n", m_pControlsXPad360->GetLeftY());
	strMessage += CUtilStr::Format("RightX: %5.2f\n", m_pControlsXPad360->GetRightX());
	strMessage += CUtilStr::Format("RightY: %5.2f\n", m_pControlsXPad360->GetRightY());
	strMessage += "\nTriggers:\n";
	strMessage += CUtilStr::Format("Left:   %5.2f\n", m_pControlsXPad360->GetLeftTrigger());
	strMessage += CUtilStr::Format("Right:  %5.2f\n", m_pControlsXPad360->GetRightTrigger());

	strMessage += CUtilStr::Format("\nButtons:\n");
	for (int i = 0; i < CControlsXPad360::NUM_BUTTONS; ++i)
	{
		strMessage += CUtilStr::Format("%d ", m_pControlsXPad360->GetButton(i));
	}
	m_pTestMessageLabel->SetText(strMessage.Get());

	const float fPadThreshold = 0.5f;
	if (m_pControlsXPad360->GetLeftX() > fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 1);
	else if (m_pControlsXPad360->GetLeftX() < -fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 1);
	else
	{
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 0);
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 0);
	}

}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "SysControl.h"
#include "ControlsApp.h"
#include "ControlsXPad360.h"
#include "Engine.h"
#include "App.h"
#include "Engine.h"
#include "App.h"
#include "Input.h"
#include "ObjectGui.h"
#include "WidgetLabel.h"

//解决跨平台字符集兼容问题
#ifdef _WIN32
#pragma execution_character_set("utf-8")
#endif

using namespace MathLib;

class CSysControlLocal : public CSysControl
{
public:
	CSysControlLocal();
	virtual ~CSysControlLocal();

	virtual void Init();	//角色要初始化，着色器要初始化，
	virtual void Update(float ifps);
	virtual void Shutdown();

	virtual int GetState(int state);		//鼠标状态，键盘状态，人物状态，子弹状态等等。
	virtual int ClearState(int state);

	virtual float GetMouseDX();
	virtual float GetMouseDY();

	virtual void SetMouseGrab(int g);		//设置是否显示鼠标
	virtual int GetMouseGrab();			//获取鼠标状态，是显示呢还是不显示的状态。

	virtual void SetControlMode(ControlMode mode);			//控制模式
	virtual ControlMode GetControlMode() const;				//获取控制模式

private:
	void Update_Mouse(float ifps);
	void Update_Keyboard(float ifps);
	void Update_XPad360(float ifps);

	CControlsApp        *m_pControlsApp;		//控制游戏中移动
	CControlsXPad360    *m_pControlsXPad360;
	ControlMode         m_nControlMode;			//控制模式

	int                 m_nOldMouseX;			//上一个鼠标坐标X
	int                 m_nOldMouseY;			//上一个鼠标坐标Y

	CObjectGui          *m_pTest3DUI;
	CWidgetLabel        *m_pTestMessageLabel;

};

CSysControlLocal::CSysControlLocal()
{

}
CSysControlLocal::~CSysControlLocal()
{

}

void CSysControlLocal::Init()
{
	m_pControlsApp = new CControlsApp;
	m_pControlsXPad360 = new CControlsXPad360(0);

	g_Engine.pApp->SetMouseGrab(0);
	g_Engine.pApp->SetMouseShow(0);

	SetControlMode(CONTROL_KEYBORAD_MOUSE);

	m_pTest3DUI = new CObjectGui(2.0f, 1.0f, "data/core/gui/");
	m_pTest3DUI->SetMouseShow(0);
	m_pTest3DUI->SetBackground(1);
	m_pTest3DUI->SetBackgroundColor(vec4(1.0f, 0.0f, 0.0f, 1.0f));

	m_pTest3DUI->SetScreenSize(800, 400);
	m_pTest3DUI->SetControlDistance(1000.0f);
	m_pTest3DUI->CreateMaterial("gui_base");	 //show in game

	m_pTest3DUI->SetWorldTransform(Translate(0.0f, 0.0f, 2.0f) * MakeRotationFromZY(vec3(0.0f, -1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f)));

	m_pTestMessageLabel = new CWidgetLabel(m_pTest3DUI->GetGui());	//初始化文字标签
	m_pTest3DUI->GetGui()->AddChild(m_pTestMessageLabel, CGui::ALIGN_CENTER);
	m_pTestMessageLabel->SetFontColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

	m_pTestMessageLabel = new CWidgetLabel(m_pTest3DUI->GetGui());	//初始化文字标签
	m_pTest3DUI->GetGui()->AddChild(m_pTestMessageLabel, CGui::ALIGN_CENTER);
	m_pTestMessageLabel->SetFontColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));

	m_pTestMessageLabel->SetFontSize(80);		//设置字体大小
	m_pTestMessageLabel->SetFontOutline(1);		//设置字体轮廓
	m_pTestMessageLabel->SetText("两个黄鹂鸣翠柳\n一行白鹭上青天\n窗含西岭千秋雪\n门泊东吴万里船");

	void CSysControlLocal::Update(float ifps)
	{
		Update_Mouse(ifps);
		Update_Keyboard(ifps);
		Update_XPad360(ifps);
	}

	m_nOldMouseX = 0;
	m_nOldMouseY = 0;
}
void CSysControlLocal::Shutdown()
{
	g_Engine.pApp->SetMouseGrab(0);
	g_Engine.pApp->SetMouseShow(0);
	delete m_pControlsApp;
	m_pControlsApp = NULL;
	delete m_pControlsXPad360;
	m_pControlsXPad360 = NULL;
	delete m_pTestMessageLabel;
	m_pTestMessageLabel = NULL;
	delete m_pTest3DUI;
	m_pTest3DUI = NULL;

}

int CSysControlLocal::GetState(int state)
{

	return m_pControlsApp->GetState(state);
}

int CSysControlLocal::ClearState(int state)
{
	return m_pControlsApp->ClearState(state);
}

float CSysControlLocal::GetMouseDX()
{
	return m_pControlsApp->GetMouseDX();
}

float CSysControlLocal::GetMouseDY()
{
	return m_pControlsApp->GetMouseDY();
}
void CSysControlLocal::SetMouseGrab(int g)
{
	g_Engine.pApp->SetMouseGrab(g);
	g_Engine.pGui->SetMouseShow(!g);
}
int CSysControlLocal::GetMouseGrab()
{
	return g_Engine.pApp->GetMouseGrab();
}

void CSysControlLocal::SetControlMode(ControlMode mode)
{
	m_nControlMode = mode;
}

CSysControl::ControlMode CSysControlLocal::GetControlMode() const
{
	return m_nControlMode;
}

CSysControl::ControlMode CSysControlLocal::GetControlMode() const
{
	return m_nControlMode;
}
void CSysControlLocal::Update_Mouse(float ifps)
{
	float dx = (g_Engine.pApp->GetMouseX() - m_nOldMouseX) * g_Engine.pControls->GetMouseSensitivity() * 0.1f;//0.1f这个数值越大，鼠标移动越快
	float dy = (g_Engine.pApp->GetMouseY() - m_nOldMouseY) * g_Engine.pControls->GetMouseSensitivity() * 0.1f;//0.1这个数值越小，鼠标移动越慢

	m_pControlsApp->SetMouseDX(dx);
	m_pControlsApp->SetMouseDY(dy);

	if (g_Engine.pApp->GetMouseGrab() && g_Engine.pApp->GetActive())
	{
		g_Engine.pApp->SetMouse(g_Engine.pApp->GetWidth() / 2, g_Engine.pApp->GetHeight() / 2);
	}

	m_nOldMouseX = g_Engine.pApp->GetMouseX();
	m_nOldMouseY = g_Engine.pApp->GetMouseY();
}

void CSysControlLocal::Update_Keyboard(float ifps)		//键盘按键响应wsad
{

	if (g_Engine.pInput->IsKeyDown('w'))
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 1);
	if (g_Engine.pInput->IsKeyDown('s'))
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 1);
	if (g_Engine.pInput->IsKeyDown('a'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 1);
	if (g_Engine.pInput->IsKeyDown('d'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 1);

	if (g_Engine.pInput->IsKeyUp('w'))
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 0);
	else if (g_Engine.pInput->IsKeyUp('s'))
		m_pControlsApp->SetState(CControls::STATE_BACKWARD, 0);

	if (g_Engine.pInput->IsKeyUp('a'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 0);
	else if (g_Engine.pInput->IsKeyUp('d'))
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 0);
	if (g_Engine.pInput->IsKeyDown(' '))		//空格跳跃
		m_pControlsApp->SetState(CControls::STATE_JUMP, 1);
	else
		m_pControlsApp->SetState(CControls::STATE_JUMP, 0);
}
void CSysControlLocal::Update_XPad360(float ifps)
{
	m_pControlsXPad360->UpdateEvents();
	CUtilStr strMessage;
	strMessage = CUtilStr("测试3D UI\n"),
	strMessage += CUtilStr(m_pControlsXPad360->GetName()) + "\n";

	strMessage += CUtilStr::Format("\n手柄测试\n");
	strMessage += CUtilStr::Format("LeftX:  %5.2f\n", m_pControlsXPad360->GetLeftX());
	strMessage += CUtilStr::Format("LeftY:  %5.2f\n", m_pControlsXPad360->GetLeftY());
	strMessage += CUtilStr::Format("RightX: %5.2f\n", m_pControlsXPad360->GetRightX());
	strMessage += CUtilStr::Format("RightY: %5.2f\n", m_pControlsXPad360->GetRightY());
	strMessage += "\nTriggers:\n";
	strMessage += CUtilStr::Format("Left:   %5.2f\n", m_pControlsXPad360->GetLeftTrigger());
	strMessage += CUtilStr::Format("Right:  %5.2f\n", m_pControlsXPad360->GetRightTrigger());

	strMessage += CUtilStr::Format("\nButtons:\n");
	for (int i = 0; i < CControlsXPad360::NUM_BUTTONS; ++i)
	{
		strMessage += CUtilStr::Format("%d ", m_pControlsXPad360->GetButton(i));
	}
	m_pTestMessageLabel->SetText(strMessage.Get());

	const float fPadThreshold = 0.5f;
	if (m_pControlsXPad360->GetLeftX() > fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 1);
	else if (m_pControlsXPad360->GetLeftX() < -fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 1);
	else
	{
		m_pControlsApp->SetState(CControls::STATE_MOVE_LEFT, 0);
		m_pControlsApp->SetState(CControls::STATE_MOVE_RIGHT, 0);
	}
	if (m_pControlsXPad360->GetLeftY() > fPadThreshold)
		m_pControlsApp->SetState(CControls::STATE_FORWARD, 1);

}<|endoftext|>