<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/

#include "maemotoolchain.h"

#include "maemoglobal.h"
#include "maemomanager.h"
#include "maemoqtversion.h"
#include "qt4projectmanagerconstants.h"
#include "qtversionmanager.h"

#include <projectexplorer/gccparser.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/toolchainmanager.h>
#include <utils/environment.h>

#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>

namespace Qt4ProjectManager {
namespace Internal {

static const char *const MAEMO_QT_VERSION_KEY = "Qt4ProjectManager.Maemo.QtVersion";

// --------------------------------------------------------------------------
// MaemoToolChain
// --------------------------------------------------------------------------

MaemoToolChain::MaemoToolChain(bool autodetected) :
    ProjectExplorer::GccToolChain(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID), autodetected),
    m_qtVersionId(-1)
{
    updateId();
}

MaemoToolChain::MaemoToolChain(const MaemoToolChain &tc) :
    ProjectExplorer::GccToolChain(tc),
    m_qtVersionId(tc.m_qtVersionId)
{ }

MaemoToolChain::~MaemoToolChain()
{ }

QString MaemoToolChain::typeName() const
{
    return MaemoToolChainFactory::tr("Maemo GCC");
}

ProjectExplorer::Abi MaemoToolChain::targetAbi() const
{
    return m_targetAbi;
}

QString MaemoToolChain::mkspec() const
{
    return QString(); // always use default
}

bool MaemoToolChain::isValid() const
{
    return GccToolChain::isValid() && m_qtVersionId >= 0 && m_targetAbi.isValid();
}

bool MaemoToolChain::canClone() const
{
    return false;
}

void MaemoToolChain::addToEnvironment(Utils::Environment &env) const
{
    BaseQtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
    if (!v)
        return;
    const QString maddeRoot = MaemoGlobal::maddeRoot(v->qmakeCommand());

    // put this into environment to make pkg-config stuff work
    env.prependOrSet(QLatin1String("SYSROOT_DIR"), QDir::toNativeSeparators(sysroot()));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madbin")
        .arg(maddeRoot)));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madlib")
        .arg(maddeRoot)));
    env.prependOrSet(QLatin1String("PERL5LIB"),
        QDir::toNativeSeparators(QString("%1/madlib/perl5").arg(maddeRoot)));

    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin").arg(maddeRoot)));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
                                                  .arg(MaemoGlobal::targetRoot(v->qmakeCommand()))));

    const QString manglePathsKey = QLatin1String("GCCWRAPPER_PATHMANGLE");
    if (!env.hasKey(manglePathsKey)) {
        const QStringList pathsToMangle = QStringList() << QLatin1String("/lib")
            << QLatin1String("/opt") << QLatin1String("/usr");
        env.set(manglePathsKey, QString());
        foreach (const QString &path, pathsToMangle)
            env.appendOrSet(manglePathsKey, path, QLatin1String(":"));
    }
}

QString MaemoToolChain::sysroot() const
{
    BaseQtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
    if (!v)
        return QString();

    if (m_sysroot.isEmpty()) {
        QFile file(QDir::cleanPath(MaemoGlobal::targetRoot(v->qmakeCommand())) + QLatin1String("/information"));
        if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream stream(&file);
            while (!stream.atEnd()) {
                const QString &line = stream.readLine().trimmed();
                const QStringList &list = line.split(QLatin1Char(' '));
                if (list.count() > 1 && list.at(0) == QLatin1String("sysroot"))
                    m_sysroot = MaemoGlobal::maddeRoot(v->qmakeCommand()) + QLatin1String("/sysroots/") + list.at(1);
            }
        }
    }
    return m_sysroot;
}

bool MaemoToolChain::operator ==(const ProjectExplorer::ToolChain &tc) const
{
    if (!ToolChain::operator ==(tc))
        return false;

    const MaemoToolChain *tcPtr = static_cast<const MaemoToolChain *>(&tc);
    return m_qtVersionId == tcPtr->m_qtVersionId;
}

ProjectExplorer::ToolChainConfigWidget *MaemoToolChain::configurationWidget()
{
    return new MaemoToolChainConfigWidget(this);
}

QVariantMap MaemoToolChain::toMap() const
{
    QVariantMap result = GccToolChain::toMap();
    result.insert(QLatin1String(MAEMO_QT_VERSION_KEY), m_qtVersionId);
    return result;
}

bool MaemoToolChain::fromMap(const QVariantMap &data)
{
    if (!GccToolChain::fromMap(data))
        return false;

    m_qtVersionId = data.value(QLatin1String(MAEMO_QT_VERSION_KEY), -1).toInt();

    return isValid();
}

void MaemoToolChain::setQtVersionId(int id)
{
    if (id < 0) {
        m_targetAbi = ProjectExplorer::Abi();
        m_qtVersionId = -1;
        updateId(); // Will trigger toolChainUpdated()!
        return;
    }

    MaemoQtVersion *version = dynamic_cast<MaemoQtVersion *>(QtVersionManager::instance()->version(id));
    Q_ASSERT(version);
    ProjectExplorer::Abi::OSFlavor flavour = ProjectExplorer::Abi::HarmattanLinuxFlavor;
    if (version->osVersion() == MaemoDeviceConfig::Maemo5)
        flavour = ProjectExplorer::Abi::MaemoLinuxFlavor;
    else if (version->osVersion() == MaemoDeviceConfig::Maemo6)
        flavour = ProjectExplorer::Abi::HarmattanLinuxFlavor;
    else if (version->osVersion() == MaemoDeviceConfig::Meego)
        flavour = ProjectExplorer::Abi::MeegoLinuxFlavor;
    else
        return;

    m_qtVersionId = id;

    Q_ASSERT(version->qtAbis().count() == 1);
    m_targetAbi = version->qtAbis().at(0);

    updateId(); // Will trigger toolChainUpdated()!
    setDisplayName(MaemoToolChainFactory::tr("Maemo GCC for %1").arg(version->displayName()));
}

int MaemoToolChain::qtVersionId() const
{
    return m_qtVersionId;
}

void MaemoToolChain::updateId()
{
    setId(QString::fromLatin1("%1:%2.%3").arg(Constants::MAEMO_TOOLCHAIN_ID)
          .arg(m_qtVersionId).arg(debuggerCommand()));
}

// --------------------------------------------------------------------------
// MaemoToolChainConfigWidget
// --------------------------------------------------------------------------

MaemoToolChainConfigWidget::MaemoToolChainConfigWidget(MaemoToolChain *tc) :
    ProjectExplorer::ToolChainConfigWidget(tc)
{
    QVBoxLayout *layout = new QVBoxLayout(this);
    QLabel *label = new QLabel;
    BaseQtVersion *v = QtVersionManager::instance()->version(tc->qtVersionId());
    Q_ASSERT(v);
    label->setText(tr("
"
                      "
Path to MADDE:	%1
"
                      "
Path to MADDE target:	%2
"
                      "
Debugger:%3
")
                   .arg(QDir::toNativeSeparators(MaemoGlobal::maddeRoot(v->qmakeCommand())),
                        QDir::toNativeSeparators(MaemoGlobal::targetRoot(v->qmakeCommand())),
                        QDir::toNativeSeparators(tc->debuggerCommand())));
    layout->addWidget(label);
}

void MaemoToolChainConfigWidget::apply()
{
    // nothing to do!
}

void MaemoToolChainConfigWidget::discard()
{
    // nothing to do!
}

bool MaemoToolChainConfigWidget::isDirty() const
{
    return false;
}

// --------------------------------------------------------------------------
// MaemoToolChainFactory
// --------------------------------------------------------------------------

MaemoToolChainFactory::MaemoToolChainFactory() :
    ProjectExplorer::ToolChainFactory()
{ }

QString MaemoToolChainFactory::displayName() const
{
    return tr("Maemo GCC");
}

QString MaemoToolChainFactory::id() const
{
    return QLatin1String(Constants::MAEMO_TOOLCHAIN_ID);
}

QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::autoDetect()
{
    QtVersionManager *vm = QtVersionManager::instance();
    connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
            this, SLOT(handleQtVersionChanges(QList<int>)));

    QList<int> versionList;
    foreach (BaseQtVersion *v, vm->versions())
        versionList.append(v->uniqueId());

    return createToolChainList(versionList);
}

void MaemoToolChainFactory::handleQtVersionChanges(const QList<int> &changes)
{
    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
    QList<ProjectExplorer::ToolChain *> tcList = createToolChainList(changes);
    foreach (ProjectExplorer::ToolChain *tc, tcList)
        tcm->registerToolChain(tc);
}

QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::createToolChainList(const QList<int> &changes)
{
    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
    QtVersionManager *vm = QtVersionManager::instance();
    QList<ProjectExplorer::ToolChain *> result;

    foreach (int i, changes) {
        BaseQtVersion *v = vm->version(i);
        if (!v) {
            // remove tool chain:
            QList<ProjectExplorer::ToolChain *> toRemove;
            foreach (ProjectExplorer::ToolChain *tc, tcm->toolChains()) {
                if (!tc->id().startsWith(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID)))
                    continue;
                MaemoToolChain *mTc = static_cast<MaemoToolChain *>(tc);
                if (mTc->qtVersionId() == i)
                    toRemove.append(mTc);
            }
            foreach (ProjectExplorer::ToolChain *tc, toRemove)
                tcm->deregisterToolChain(tc);
        } else if (MaemoQtVersion *mqv = dynamic_cast<MaemoQtVersion *>(v)) {
            // add tool chain:
            MaemoToolChain *mTc = new MaemoToolChain(true);
            mTc->setQtVersionId(i);
            QString target = "Maemo 5";
            if (v->supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID))
                target = "Maemo 6";
            else if (v->supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID))
                target = "Meego";
            mTc->setDisplayName(tr("%1 GCC (%2)").arg(target).arg(MaemoGlobal::maddeRoot(mqv->qmakeCommand())));
            mTc->setCompilerPath(MaemoGlobal::targetRoot(mqv->qmakeCommand()) + QLatin1String("/bin/gcc"));
            mTc->setDebuggerCommand(ProjectExplorer::ToolChainManager::instance()->defaultDebugger(mqv->qtAbis().at(0)));
            if (mTc->debuggerCommand().isEmpty())
                mTc->setDebuggerCommand(MaemoGlobal::targetRoot(mqv->qmakeCommand()) + QLatin1String("/bin/gdb"));
            result.append(mTc);
        }
    }
    return result;
}

} // namespace Internal
} // namespace Qt4ProjectManager
<commit_msg>Maemo: Fix possible assert<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/

#include "maemotoolchain.h"

#include "maemoglobal.h"
#include "maemomanager.h"
#include "maemoqtversion.h"
#include "qt4projectmanagerconstants.h"
#include "qtversionmanager.h"

#include <projectexplorer/gccparser.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/toolchainmanager.h>
#include <utils/environment.h>

#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>

namespace Qt4ProjectManager {
namespace Internal {

static const char *const MAEMO_QT_VERSION_KEY = "Qt4ProjectManager.Maemo.QtVersion";

// --------------------------------------------------------------------------
// MaemoToolChain
// --------------------------------------------------------------------------

MaemoToolChain::MaemoToolChain(bool autodetected) :
    ProjectExplorer::GccToolChain(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID), autodetected),
    m_qtVersionId(-1)
{
    updateId();
}

MaemoToolChain::MaemoToolChain(const MaemoToolChain &tc) :
    ProjectExplorer::GccToolChain(tc),
    m_qtVersionId(tc.m_qtVersionId)
{ }

MaemoToolChain::~MaemoToolChain()
{ }

QString MaemoToolChain::typeName() const
{
    return MaemoToolChainFactory::tr("Maemo GCC");
}

ProjectExplorer::Abi MaemoToolChain::targetAbi() const
{
    return m_targetAbi;
}

QString MaemoToolChain::mkspec() const
{
    return QString(); // always use default
}

bool MaemoToolChain::isValid() const
{
    return GccToolChain::isValid() && m_qtVersionId >= 0 && m_targetAbi.isValid();
}

bool MaemoToolChain::canClone() const
{
    return false;
}

void MaemoToolChain::addToEnvironment(Utils::Environment &env) const
{
    BaseQtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
    if (!v)
        return;
    const QString maddeRoot = MaemoGlobal::maddeRoot(v->qmakeCommand());

    // put this into environment to make pkg-config stuff work
    env.prependOrSet(QLatin1String("SYSROOT_DIR"), QDir::toNativeSeparators(sysroot()));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madbin")
        .arg(maddeRoot)));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madlib")
        .arg(maddeRoot)));
    env.prependOrSet(QLatin1String("PERL5LIB"),
        QDir::toNativeSeparators(QString("%1/madlib/perl5").arg(maddeRoot)));

    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin").arg(maddeRoot)));
    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
                                                  .arg(MaemoGlobal::targetRoot(v->qmakeCommand()))));

    const QString manglePathsKey = QLatin1String("GCCWRAPPER_PATHMANGLE");
    if (!env.hasKey(manglePathsKey)) {
        const QStringList pathsToMangle = QStringList() << QLatin1String("/lib")
            << QLatin1String("/opt") << QLatin1String("/usr");
        env.set(manglePathsKey, QString());
        foreach (const QString &path, pathsToMangle)
            env.appendOrSet(manglePathsKey, path, QLatin1String(":"));
    }
}

QString MaemoToolChain::sysroot() const
{
    BaseQtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
    if (!v)
        return QString();

    if (m_sysroot.isEmpty()) {
        QFile file(QDir::cleanPath(MaemoGlobal::targetRoot(v->qmakeCommand())) + QLatin1String("/information"));
        if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream stream(&file);
            while (!stream.atEnd()) {
                const QString &line = stream.readLine().trimmed();
                const QStringList &list = line.split(QLatin1Char(' '));
                if (list.count() > 1 && list.at(0) == QLatin1String("sysroot"))
                    m_sysroot = MaemoGlobal::maddeRoot(v->qmakeCommand()) + QLatin1String("/sysroots/") + list.at(1);
            }
        }
    }
    return m_sysroot;
}

bool MaemoToolChain::operator ==(const ProjectExplorer::ToolChain &tc) const
{
    if (!ToolChain::operator ==(tc))
        return false;

    const MaemoToolChain *tcPtr = static_cast<const MaemoToolChain *>(&tc);
    return m_qtVersionId == tcPtr->m_qtVersionId;
}

ProjectExplorer::ToolChainConfigWidget *MaemoToolChain::configurationWidget()
{
    return new MaemoToolChainConfigWidget(this);
}

QVariantMap MaemoToolChain::toMap() const
{
    QVariantMap result = GccToolChain::toMap();
    result.insert(QLatin1String(MAEMO_QT_VERSION_KEY), m_qtVersionId);
    return result;
}

bool MaemoToolChain::fromMap(const QVariantMap &data)
{
    if (!GccToolChain::fromMap(data))
        return false;

    m_qtVersionId = data.value(QLatin1String(MAEMO_QT_VERSION_KEY), -1).toInt();

    return isValid();
}

void MaemoToolChain::setQtVersionId(int id)
{
    if (id < 0) {
        m_targetAbi = ProjectExplorer::Abi();
        m_qtVersionId = -1;
        updateId(); // Will trigger toolChainUpdated()!
        return;
    }

    MaemoQtVersion *version = dynamic_cast<MaemoQtVersion *>(QtVersionManager::instance()->version(id));
    Q_ASSERT(version);
    ProjectExplorer::Abi::OSFlavor flavour = ProjectExplorer::Abi::HarmattanLinuxFlavor;
    if (version->osVersion() == MaemoDeviceConfig::Maemo5)
        flavour = ProjectExplorer::Abi::MaemoLinuxFlavor;
    else if (version->osVersion() == MaemoDeviceConfig::Maemo6)
        flavour = ProjectExplorer::Abi::HarmattanLinuxFlavor;
    else if (version->osVersion() == MaemoDeviceConfig::Meego)
        flavour = ProjectExplorer::Abi::MeegoLinuxFlavor;
    else
        return;

    m_qtVersionId = id;

    Q_ASSERT(version->qtAbis().count() == 1);
    m_targetAbi = version->qtAbis().at(0);

    updateId(); // Will trigger toolChainUpdated()!
    setDisplayName(MaemoToolChainFactory::tr("Maemo GCC for %1").arg(version->displayName()));
}

int MaemoToolChain::qtVersionId() const
{
    return m_qtVersionId;
}

void MaemoToolChain::updateId()
{
    setId(QString::fromLatin1("%1:%2.%3").arg(Constants::MAEMO_TOOLCHAIN_ID)
          .arg(m_qtVersionId).arg(debuggerCommand()));
}

// --------------------------------------------------------------------------
// MaemoToolChainConfigWidget
// --------------------------------------------------------------------------

MaemoToolChainConfigWidget::MaemoToolChainConfigWidget(MaemoToolChain *tc) :
    ProjectExplorer::ToolChainConfigWidget(tc)
{
    QVBoxLayout *layout = new QVBoxLayout(this);
    QLabel *label = new QLabel;
    BaseQtVersion *v = QtVersionManager::instance()->version(tc->qtVersionId());
    Q_ASSERT(v);
    label->setText(tr("
"
                      "
Path to MADDE:	%1
"
                      "
Path to MADDE target:	%2
"
                      "
Debugger:%3
")
                   .arg(QDir::toNativeSeparators(MaemoGlobal::maddeRoot(v->qmakeCommand())),
                        QDir::toNativeSeparators(MaemoGlobal::targetRoot(v->qmakeCommand())),
                        QDir::toNativeSeparators(tc->debuggerCommand())));
    layout->addWidget(label);
}

void MaemoToolChainConfigWidget::apply()
{
    // nothing to do!
}

void MaemoToolChainConfigWidget::discard()
{
    // nothing to do!
}

bool MaemoToolChainConfigWidget::isDirty() const
{
    return false;
}

// --------------------------------------------------------------------------
// MaemoToolChainFactory
// --------------------------------------------------------------------------

MaemoToolChainFactory::MaemoToolChainFactory() :
    ProjectExplorer::ToolChainFactory()
{ }

QString MaemoToolChainFactory::displayName() const
{
    return tr("Maemo GCC");
}

QString MaemoToolChainFactory::id() const
{
    return QLatin1String(Constants::MAEMO_TOOLCHAIN_ID);
}

QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::autoDetect()
{
    QtVersionManager *vm = QtVersionManager::instance();
    connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
            this, SLOT(handleQtVersionChanges(QList<int>)));

    QList<int> versionList;
    foreach (BaseQtVersion *v, vm->versions())
        versionList.append(v->uniqueId());

    return createToolChainList(versionList);
}

void MaemoToolChainFactory::handleQtVersionChanges(const QList<int> &changes)
{
    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
    QList<ProjectExplorer::ToolChain *> tcList = createToolChainList(changes);
    foreach (ProjectExplorer::ToolChain *tc, tcList)
        tcm->registerToolChain(tc);
}

QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::createToolChainList(const QList<int> &changes)
{
    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
    QtVersionManager *vm = QtVersionManager::instance();
    QList<ProjectExplorer::ToolChain *> result;

    foreach (int i, changes) {
        BaseQtVersion *v = vm->version(i);
        if (!v || !v->isValid()) {
            // remove tool chain:
            QList<ProjectExplorer::ToolChain *> toRemove;
            foreach (ProjectExplorer::ToolChain *tc, tcm->toolChains()) {
                if (!tc->id().startsWith(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID)))
                    continue;
                MaemoToolChain *mTc = static_cast<MaemoToolChain *>(tc);
                if (mTc->qtVersionId() == i)
                    toRemove.append(mTc);
            }
            foreach (ProjectExplorer::ToolChain *tc, toRemove)
                tcm->deregisterToolChain(tc);
        } else if (MaemoQtVersion *mqv = dynamic_cast<MaemoQtVersion *>(v)) {
            // add tool chain:
            MaemoToolChain *mTc = new MaemoToolChain(true);
            mTc->setQtVersionId(i);
            QString target = "Maemo 5";
            if (v->supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID))
                target = "Maemo 6";
            else if (v->supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID))
                target = "Meego";
            mTc->setDisplayName(tr("%1 GCC (%2)").arg(target).arg(MaemoGlobal::maddeRoot(mqv->qmakeCommand())));
            mTc->setCompilerPath(MaemoGlobal::targetRoot(mqv->qmakeCommand()) + QLatin1String("/bin/gcc"));
            mTc->setDebuggerCommand(ProjectExplorer::ToolChainManager::instance()->defaultDebugger(mqv->qtAbis().at(0)));
            if (mTc->debuggerCommand().isEmpty())
                mTc->setDebuggerCommand(MaemoGlobal::targetRoot(mqv->qmakeCommand()) + QLatin1String("/bin/gdb"));
            result.append(mTc);
        }
    }
    return result;
}

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


<commit_before>/*
 * display_visibility_manager.cpp
 *
 *  Created on: Aug 27, 2012
 *      Author: gossow
 */

#include "display_group_visibility_property.h"

#include "rviz/properties/bool_property.h"
#include "rviz/display_context.h"
#include "rviz/bit_allocator.h"
#include "rviz/display.h"
#include "rviz/display_group.h"

namespace rviz
{

DisplayGroupVisibilityProperty::DisplayGroupVisibilityProperty(
    uint32_t vis_bit,
    DisplayGroup* display_group,
    Display* parent_display,
    const QString& name,
    bool default_value,
    const QString& description,
    Property* parent,
    const char *changed_slot,
    QObject* receiver )
: DisplayVisibilityProperty( vis_bit, display_group, name, default_value, description, parent, changed_slot, receiver )
, display_group_(display_group)
, parent_display_(parent_display)
{
  connect( display_group, SIGNAL( displayAdded( rviz::Display* ) ), this, SLOT( onDisplayAdded( rviz::Display* ) ));
  connect( display_group, SIGNAL( displayRemoved( rviz::Display* ) ), this, SLOT( onDisplayRemoved( rviz::Display* ) ));

  for( int i = 0; i < display_group->numDisplays(); i++ )
  {
    rviz::Display* display = display_group->getDisplayAt( i );
    if ( display != parent )
    {
      onDisplayAdded( display );
    }
  }
}

void DisplayGroupVisibilityProperty::update()
{
  DisplayVisibilityProperty::update();
  std::map<rviz::Display*, DisplayVisibilityProperty*>::iterator it = disp_vis_props_.begin();
  for( ; it != disp_vis_props_.end(); it++ )
  {
    it->second->update();
  }
}

void DisplayGroupVisibilityProperty::sortDisplayList()
{
  // remove and re-add everything in our property list
  // in the same order as it appears in the display group
  for( int i = 0; i < display_group_->numDisplays(); i++ )
  {
    rviz::Display* display = display_group_->getDisplayAt( i );
    std::map<rviz::Display*, DisplayVisibilityProperty*>::iterator it = disp_vis_props_.find( display );
    if ( it != disp_vis_props_.end() )
    {
      takeChild( it->second );
      addChild( it->second );
    }
  }
}

void DisplayGroupVisibilityProperty::onDisplayAdded( Display* display )
{
  DisplayGroup* display_group = qobject_cast<DisplayGroup*>( display );
  DisplayVisibilityProperty* vis_prop;
  if( display_group )
  {
    vis_prop = new DisplayGroupVisibilityProperty( vis_bit_, display_group, parent_display_, "", true, "Uncheck to hide everything in this Display Group", this );
  }
  else
  {
    vis_prop = new DisplayVisibilityProperty( vis_bit_, display, "", true, "Show or hide this Display", this );
  }
  disp_vis_props_[ display ] = vis_prop;
  sortDisplayList();
}

void DisplayGroupVisibilityProperty::onDisplayRemoved( Display* display )
{
  std::map<rviz::Display*, DisplayVisibilityProperty*>::iterator it = disp_vis_props_.find( display );
  if ( it != disp_vis_props_.end() )
  {
    Property* child = takeChild( it->second );
    child->setParent( NULL );
    delete child;
    disp_vis_props_.erase( display );
  }
}

DisplayGroupVisibilityProperty::~DisplayGroupVisibilityProperty()
{
}

}
<commit_msg>bugfix in visibility property: don't show parent display in list<commit_after>/*
 * display_visibility_manager.cpp
 *
 *  Created on: Aug 27, 2012
 *      Author: gossow
 */

#include "display_group_visibility_property.h"

#include "rviz/properties/bool_property.h"
#include "rviz/display_context.h"
#include "rviz/bit_allocator.h"
#include "rviz/display.h"
#include "rviz/display_group.h"

namespace rviz
{

DisplayGroupVisibilityProperty::DisplayGroupVisibilityProperty(
    uint32_t vis_bit,
    DisplayGroup* display_group,
    Display* parent_display,
    const QString& name,
    bool default_value,
    const QString& description,
    Property* parent,
    const char *changed_slot,
    QObject* receiver )
: DisplayVisibilityProperty( vis_bit, display_group, name, default_value, description, parent, changed_slot, receiver )
, display_group_(display_group)
, parent_display_(parent_display)
{
  connect( display_group, SIGNAL( displayAdded( rviz::Display* ) ), this, SLOT( onDisplayAdded( rviz::Display* ) ));
  connect( display_group, SIGNAL( displayRemoved( rviz::Display* ) ), this, SLOT( onDisplayRemoved( rviz::Display* ) ));

  for( int i = 0; i < display_group->numDisplays(); i++ )
  {
    rviz::Display* display = display_group->getDisplayAt( i );
    if ( display != parent_display )
    {
      onDisplayAdded( display );
    }
  }
}

void DisplayGroupVisibilityProperty::update()
{
  DisplayVisibilityProperty::update();
  std::map<rviz::Display*, DisplayVisibilityProperty*>::iterator it = disp_vis_props_.begin();
  for( ; it != disp_vis_props_.end(); it++ )
  {
    it->second->update();
  }
}

void DisplayGroupVisibilityProperty::sortDisplayList()
{
  // remove and re-add everything in our property list
  // in the same order as it appears in the display group
  for( int i = 0; i < display_group_->numDisplays(); i++ )
  {
    rviz::Display* display = display_group_->getDisplayAt( i );
    std::map<rviz::Display*, DisplayVisibilityProperty*>::iterator it = disp_vis_props_.find( display );
    if ( it != disp_vis_props_.end() )
    {
      takeChild( it->second );
      addChild( it->second );
    }
  }
}

void DisplayGroupVisibilityProperty::onDisplayAdded( Display* display )
{
  DisplayGroup* display_group = qobject_cast<DisplayGroup*>( display );
  DisplayVisibilityProperty* vis_prop;
  if( display_group )
  {
    vis_prop = new DisplayGroupVisibilityProperty( vis_bit_, display_group, parent_display_, "", true, "Uncheck to hide everything in this Display Group", this );
  }
  else
  {
    vis_prop = new DisplayVisibilityProperty( vis_bit_, display, "", true, "Show or hide this Display", this );
  }
  disp_vis_props_[ display ] = vis_prop;
  sortDisplayList();
}

void DisplayGroupVisibilityProperty::onDisplayRemoved( Display* display )
{
  std::map<rviz::Display*, DisplayVisibilityProperty*>::iterator it = disp_vis_props_.find( display );
  if ( it != disp_vis_props_.end() )
  {
    Property* child = takeChild( it->second );
    child->setParent( NULL );
    delete child;
    disp_vis_props_.erase( display );
  }
}

DisplayGroupVisibilityProperty::~DisplayGroupVisibilityProperty()
{
}

}
<|endoftext|>


<commit_before>/**
 *  @file Reactor.cpp
 *
 *  A zero-dimensional reactor
 */

// Copyright 2001  California Institute of Technology

#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif

#include "Reactor.h"
#include "../CVode.h"
#include "FlowDevice.h"
#include "Wall.h"

namespace Cantera {

    doublereal quadInterp(doublereal x0, doublereal* x, doublereal* y);

    Reactor::Reactor() : ReactorBase(),
                         FuncEval(),
                         m_kin(0),
                         m_integ(0),
                         m_temp_atol(1.e-11),
                         m_maxstep(0.0),
                         m_vdot(0.0),
                         m_Q(0.0),
                         m_emis(0.0),
                         m_h(0.0),
                         m_area(1.0),
                         m_ext_temp(0.0),
                         m_ext_temp4(0.0),
                         m_kv(0.0),
                         m_p0(OneAtm),
                         m_rtol(1.e-9),
                         m_trad_set(false),
                         m_chem(true),
                         m_energy(true)
    {
        m_integ = new CVodeInt;

        // use backward differencing, with a full Jacobian computed
        // numerically, and use a Newton linear iterator
        m_integ->setMethod(BDF_Method);
        m_integ->setProblemType(DENSE + NOJAC);
        m_integ->setIterator(Newton_Iter);
    }

    // overloaded method of FuncEval. Called by the integrator to
    // get the initial conditions.
    void Reactor::getInitialConditions(double t0, size_t leny, double* y)
    {
        m_init = true;
        if (m_mix == 0) {
            cout << "Error: reactor is empty." << endl;
            return;
        }
        m_time = t0;

        // total mass
        doublereal mass = m_mix->density() * m_vol;

        // set components y + 2 ... y + K + 1 to the
        // mass M_k of each species
        m_mix->getMassFractions(leny-2, y+2);
        scale(y + 2, y + m_nsp + 2, y + 2, mass);

        // set the first component to the total internal
        // energy
        y[0] = m_thermo->intEnergy_mass() * mass;

        // set the second component to the total volume
        y[1] = m_vol;
    }

    /**
     *  Must be called before calling method 'advance'
     */
    void Reactor::initialize(doublereal t0) {
        m_mix->restoreState(m_state);
        m_sdot.resize(m_nsp, 0.0);
        m_atol.resize(m_nsp + 2);
        fill(m_atol.begin(), m_atol.end(), 1.e-15);
        m_integ->setTolerances(m_rtol, neq(), m_atol.begin());
        m_integ->setMaxStep(m_maxstep);
        m_integ->initialize(t0, *this);

        m_enthalpy = m_thermo->enthalpy_mass();
        m_pressure = m_thermo->pressure();
        m_intEnergy = m_thermo->intEnergy_mass();

        m_init = true;
    }

    void Reactor::updateState(doublereal* y) {

        phase_t& mix = *m_mix;  // define for readability

        // The components of y are the total internal energy,
        // the total volume, and the mass of each species.
        // Set the mass fractions and  density of the mixture.

        doublereal u   = y[0];
        m_vol          = y[1];
        doublereal* mss = y + 2;
        doublereal mass = accumulate(y+2, y+2+m_nsp, 0.0);
        m_mix->setMassFractions(mss);
        m_mix->setDensity(mass/m_vol);

        doublereal temp = temperature();
        mix.setTemperature(temp);

        if (m_energy) {
            doublereal u_mass = u/mass;       // specific int. energy
            doublereal delta;

            do {
                delta = -(m_thermo->intEnergy_mass()
                    - u_mass)/m_thermo->cv_mass();
                temp += delta;
                mix.setTemperature(temp);
            }
            while (fabs(delta) > m_temp_atol);
        }
        mix.setTemperature(temp);
        m_state[0] = temp;

        // save parameters needed by other connected reactors
        m_enthalpy = m_thermo->enthalpy_mass();
        m_pressure = m_thermo->pressure();
        m_intEnergy = m_thermo->intEnergy_mass();
    }

    /**
     * Called by the integrator to evaluate ydot given y at time 'time'.
     */
    void Reactor::eval(doublereal time, doublereal* y, doublereal* ydot)
    {
        int i;
        m_time = time;
        updateState(y);          // synchronize the reactor state with y

        m_vdot = 0.0;
        m_Q    = 0.0;

        // compute wall terms
        doublereal vdot;
        for (i = 0; i < m_nwalls; i++) {
            vdot = m_lr[i]*m_wall[i]->vdot(time);
            m_vdot += vdot;
            m_Q += m_lr[i]*m_wall[i]->Q(time);
        }

        // volume equation
        ydot[1] = m_vdot;

        /* species equations
         *  Equation is:
         *  \dot M_k = \hat W_k \dot\omega_k + \dot m_{in} Y_{k,in}
         *             - \dot m_{out} Y_{k} + A \dot s_k.
         */
        const doublereal* mw = m_mix->molecularWeights().begin();

        int n;

        m_kin->getNetProductionRates(ydot+2);   // "omega dot"
        for (n = 0; n < m_nsp; n++) {
            ydot[n+2] *= m_vol;     //           moles/s/m^3 -> moles/s
            //            ydot[n+2] += m_sdot[n];
            ydot[n+2] *= mw[n];
        }

        /**
         *  Energy equation.
         * \dot U = -P\dot V + A \dot q + \dot m_{in} h_{in}
         * - \dot m_{out} h.
         */
        if (m_energy) {
            ydot[0] = - m_thermo->pressure() * m_vdot - m_Q;
        }
        else {
            ydot[0] = 0.0;
        }

        // add terms for open system
        if (m_open) {

            const doublereal* mf = m_mix->massFractions();
            doublereal enthalpy = m_thermo->enthalpy_mass();

            // outlets

            int n;
            doublereal mdot_out;
            for (i = 0; i < m_nOutlets; i++) {
                mdot_out = m_outlet[i]->massFlowRate();
                for (n = 0; n < m_nsp; n++) {
                    ydot[2+n] -= mdot_out * mf[n];
                }
                ydot[0] -= mdot_out * enthalpy;
            }

            // inlets

            doublereal mdot_in;
            for (i = 0; i < m_nInlets; i++) {
                mdot_in = m_inlet[i]->massFlowRate();
                for (n = 0; n < m_nsp; n++) {
                    ydot[2+n] += m_inlet[i]->massFlowRate(n);
                }
                ydot[0] += mdot_in * m_inlet[i]->enthalpy_mass();
            }
        }
    }
}
<commit_msg>added support for surface chemistry.<commit_after>/**
 *  @file Reactor.cpp
 *
 *  A zero-dimensional reactor
 */

// Copyright 2001  California Institute of Technology

#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif

#include "Reactor.h"
#include "../CVode.h"
#include "FlowDevice.h"
#include "Wall.h"
#include "../InterfaceKinetics.h"
#include "../SurfPhase.h"

namespace Cantera {

    doublereal quadInterp(doublereal x0, doublereal* x, doublereal* y);

    Reactor::Reactor() : ReactorBase(),
                         FuncEval(),
                         m_kin(0),
                         m_integ(0),
                         m_temp_atol(1.e-11),
                         m_maxstep(0.0),
                         m_vdot(0.0),
                         m_Q(0.0),
                         m_emis(0.0),
                         m_h(0.0),
                         m_area(1.0),
                         m_ext_temp(0.0),
                         m_ext_temp4(0.0),
                         m_kv(0.0),
                         m_p0(OneAtm),
                         m_rtol(1.e-9),
                         m_trad_set(false),
                         m_chem(true),
                         m_energy(true)
    {
        m_integ = new CVodeInt;
        // use backward differencing, with a full Jacobian computed
        // numerically, and use a Newton linear iterator
        m_integ->setMethod(BDF_Method);
        m_integ->setProblemType(DENSE + NOJAC);
        m_integ->setIterator(Newton_Iter);
    }

    // overloaded method of FuncEval. Called by the integrator to
    // get the initial conditions.
    void Reactor::getInitialConditions(double t0, size_t leny, double* y)
    {
        m_init = true;
        if (m_mix == 0) {
            cout << "Error: reactor is empty." << endl;
            return;
        }
        m_time = t0;

        // total mass
        doublereal mass = m_mix->density() * m_vol;

        // set components y + 2 ... y + K + 1 to the
        // mass M_k of each species
        m_mix->getMassFractions(leny-2, y+2);
        scale(y + 2, y + m_nsp + 2, y + 2, mass);

        // set the first component to the total internal
        // energy
        y[0] = m_thermo->intEnergy_mass() * mass;

        // set the second component to the total volume
        y[1] = m_vol;

        // set the remaining components to the surface species
        // coverages on the walls
        int loc = m_nsp + 2;
        SurfPhase* surf;
        for (int m = 0; m < m_nwalls; m++) {
            surf = m_wall[m]->surface(m_lr[m]);
            if (surf) {
                surf->getCoverages(y+loc);
                loc += surf->nSpecies();
            }
        }
    }

    /**
     *  Must be called before calling method 'advance'
     */
    void Reactor::initialize(doublereal t0) {
        m_mix->restoreState(m_state);
        m_sdot.resize(m_nsp, 0.0);
        m_nv = m_nsp + 2;
        for (int w = 0; w < m_nwalls; w++)
            if (m_wall[w]->surface(m_lr[w]))
                m_nv += m_wall[w]->surface(m_lr[w])->nSpecies();
        m_atol.resize(neq());
        fill(m_atol.begin(), m_atol.end(), 1.e-15);
        m_integ->setTolerances(m_rtol, neq(), m_atol.begin());
        m_integ->setMaxStep(m_maxstep);
        m_integ->initialize(t0, *this);

        m_enthalpy = m_thermo->enthalpy_mass();
        m_pressure = m_thermo->pressure();
        m_intEnergy = m_thermo->intEnergy_mass();

        int nt, maxnt;
        for (int m = 0; m < m_nwalls; m++) {
            if (m_wall[m]->kinetics(m_lr[m])) {
                nt = m_wall[m]->kinetics(m_lr[m])->nTotalSpecies();
                if (nt > maxnt) maxnt = nt;
                if (m_wall[m]->kinetics(m_lr[m])) {
                    if (&m_kin->thermo(0) !=
                        &m_wall[m]->kinetics(m_lr[m])->thermo(0)) {
                        throw CanteraError("Reactor::initialize",
                            "First phase of all kinetics managers must be"
                            " the gas.");
                    }
                }
            }
        }
        m_work.resize(maxnt);

        m_init = true;
    }

    void Reactor::updateState(doublereal* y) {

        phase_t& mix = *m_mix;  // define for readability

        // The components of y are the total internal energy,
        // the total volume, and the mass of each species.
        // Set the mass fractions and  density of the mixture.

        doublereal u   = y[0];
        m_vol          = y[1];
        doublereal* mss = y + 2;
        doublereal mass = accumulate(y+2, y+2+m_nsp, 0.0);
        m_mix->setMassFractions(mss);
        m_mix->setDensity(mass/m_vol);

        doublereal temp = temperature();
        mix.setTemperature(temp);

        if (m_energy) {
            doublereal u_mass = u/mass;       // specific int. energy
            doublereal delta;

            do {
                delta = -(m_thermo->intEnergy_mass()
                    - u_mass)/m_thermo->cv_mass();
                temp += delta;
                mix.setTemperature(temp);
            }
            while (fabs(delta) > m_temp_atol);
        }
        mix.setTemperature(temp);
        m_state[0] = temp;

        int loc = m_nsp + 2;
        SurfPhase* surf;
        for (int m = 0; m < m_nwalls; m++) {
            surf = m_wall[m]->surface(m_lr[m]);
            if (surf) {
                surf->setTemperature(temp);
                surf->setCoverages(y+loc);
                loc += surf->nSpecies();
            }
        }

        // save parameters needed by other connected reactors
        m_enthalpy = m_thermo->enthalpy_mass();
        m_pressure = m_thermo->pressure();
        m_intEnergy = m_thermo->intEnergy_mass();
    }

    /**
     * Called by the integrator to evaluate ydot given y at time 'time'.
     */
    void Reactor::eval(doublereal time, doublereal* y, doublereal* ydot)
    {
        int i, k, nk;
        m_time = time;
        updateState(y);          // synchronize the reactor state with y

        m_vdot = 0.0;
        m_Q    = 0.0;

        // compute wall terms
        doublereal vdot, rs0, sum, wallarea;
        Kinetics* kin;
        SurfPhase* surf;
        int lr, ns, loc = m_nsp+2, surfloc;
        fill(m_sdot.begin(), m_sdot.end(), 0.0);
        for (i = 0; i < m_nwalls; i++) {
            lr = 1 - 2*m_lr[i];
            vdot = lr*m_wall[i]->vdot(time);
            m_vdot += vdot;
            m_Q += lr*m_wall[i]->Q(time);
            kin = m_wall[i]->kinetics(m_lr[i]);
            surf = m_wall[i]->surface(m_lr[i]);
            if (surf && kin) {
                rs0 = 1.0/surf->siteDensity();
                nk = surf->nSpecies();
                sum = 0.0;
                kin->getNetProductionRates(m_work.begin());
                ns = kin->surfacePhaseIndex();
                surfloc = kin->kineticsSpeciesIndex(0,ns);
                for (k = 1; k < nk; k++) {
                    ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k);
                    sum -= ydot[loc + k];
                }
                ydot[loc] = sum;
                loc += nk;

                wallarea = m_wall[i]->area();
                for (k = 0; k < m_nsp; k++) {
                    m_sdot[k] += m_work[k]*wallarea;
                }
            }
        }

        // volume equation
        ydot[1] = m_vdot;

        /* species equations
         *  Equation is:
         *  \dot M_k = \hat W_k \dot\omega_k + \dot m_{in} Y_{k,in}
         *             - \dot m_{out} Y_{k} + A \dot s_k.
         */
        const doublereal* mw = m_mix->molecularWeights().begin();

        int n;

        m_kin->getNetProductionRates(ydot+2);   // "omega dot"
        for (n = 0; n < m_nsp; n++) {
            ydot[n+2] *= m_vol;     //           moles/s/m^3 -> moles/s
            ydot[n+2] += m_sdot[n];
            ydot[n+2] *= mw[n];
        }

        /**
         *  Energy equation.
         * \dot U = -P\dot V + A \dot q + \dot m_{in} h_{in}
         * - \dot m_{out} h.
         */
        if (m_energy) {
            ydot[0] = - m_thermo->pressure() * m_vdot - m_Q;
        }
        else {
            ydot[0] = 0.0;
        }

        // add terms for open system
        if (m_open) {

            const doublereal* mf = m_mix->massFractions();
            doublereal enthalpy = m_thermo->enthalpy_mass();

            // outlets

            int n;
            doublereal mdot_out;
            for (i = 0; i < m_nOutlets; i++) {
                mdot_out = m_outlet[i]->massFlowRate();
                for (n = 0; n < m_nsp; n++) {
                    ydot[2+n] -= mdot_out * mf[n];
                }
                ydot[0] -= mdot_out * enthalpy;
            }

            // inlets

            doublereal mdot_in;
            for (i = 0; i < m_nInlets; i++) {
                mdot_in = m_inlet[i]->massFlowRate();
                for (n = 0; n < m_nsp; n++) {
                    ydot[2+n] += m_inlet[i]->massFlowRate(n);
                }
                ydot[0] += mdot_in * m_inlet[i]->enthalpy_mass();
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>runtime/profiling: more fixes for threading<commit_after><|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkDataObject.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkDataObject.h"
#include "itkProcessObject.h"
#include "itkObjectFactory.h"
#include "itkSmartPointerForwardReference.txx"

// Manual instantiation is necessary to prevent link errors
template class itk::SmartPointerForwardReference<itk::ProcessObject>;

namespace itk
{

// after use by filter
bool DataObject::m_GlobalReleaseDataFlag = false;

DataObjectError
::DataObjectError()
  : ExceptionObject(), m_DataObject(0)
{
}

DataObjectError
::DataObjectError(const char *file, unsigned int lineNumber)
  : ExceptionObject(file, lineNumber), m_DataObject(0)
{
}

DataObjectError
::DataObjectError(const std::string& file, unsigned int lineNumber)
  : ExceptionObject(file, lineNumber), m_DataObject(0)
{
}

DataObjectError
::DataObjectError(const DataObjectError &orig)
  : ExceptionObject( orig )
{
  m_DataObject = orig.m_DataObject;
}

DataObjectError&
DataObjectError
::operator=( const DataObjectError& orig)
{
  ExceptionObject::operator= (orig);
  m_DataObject = orig.m_DataObject;
  return *this;
}

void
DataObjectError
::SetDataObject(DataObject *dobj)
{
  m_DataObject = dobj;
}

DataObject*
DataObjectError
::GetDataObject()
{
  return m_DataObject;
}

void
DataObjectError
::PrintSelf(std::ostream& os, Indent indent) const
{
  ExceptionObject::Print( os);

  os << indent << "Data object: ";
  if (m_DataObject)
    {
    os << std::endl;
    m_DataObject->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(None)" << std::endl;
    }
}

InvalidRequestedRegionError
::InvalidRequestedRegionError()
  : DataObjectError()
{
}

InvalidRequestedRegionError
::InvalidRequestedRegionError(const char *file, unsigned int lineNumber)
  : DataObjectError(file, lineNumber)
{
}

InvalidRequestedRegionError
::InvalidRequestedRegionError(const std::string& file, unsigned int lineNumber)
  : DataObjectError(file, lineNumber)
{
}

InvalidRequestedRegionError
::InvalidRequestedRegionError(const InvalidRequestedRegionError &orig)
  : DataObjectError( orig )
{
}

InvalidRequestedRegionError&
InvalidRequestedRegionError
::operator=( const InvalidRequestedRegionError& orig)
{
  DataObjectError::operator= (orig);
  return *this;
}

void
InvalidRequestedRegionError
::PrintSelf(std::ostream& os, Indent indent) const
{
  DataObjectError::PrintSelf( os, indent );
}

//----------------------------------------------------------------------------
DataObject::
DataObject() : m_UpdateMTime()
{
  m_Source = 0;
  m_SourceOutputIndex = 0;
  m_ReleaseDataFlag = false;

  // We have to assume that if a user is creating the data on their own,
  // then they will fill it with valid data.
  m_DataReleased = false;

  m_PipelineMTime = 0;
}

//----------------------------------------------------------------------------
DataObject
::~DataObject()
{
}

//----------------------------------------------------------------------------
void
DataObject
::Initialize()
{
// We don't modify ourselves because the "ReleaseData" methods depend upon
// no modification when initialized.
//
}

//----------------------------------------------------------------------------
void
DataObject
::SetGlobalReleaseDataFlag(bool val)
{
  if (val == m_GlobalReleaseDataFlag)
    {
    return;
    }
  m_GlobalReleaseDataFlag = val;
}

//----------------------------------------------------------------------------
bool
DataObject
::GetGlobalReleaseDataFlag()
{
  return m_GlobalReleaseDataFlag;
}

//----------------------------------------------------------------------------
void
DataObject
::ReleaseData()
{
  this->Initialize();
  m_DataReleased = true;
}

//----------------------------------------------------------------------------
bool
DataObject
::ShouldIReleaseData() const
{
  return ( m_GlobalReleaseDataFlag || m_ReleaseDataFlag );
}

//----------------------------------------------------------------------------
// Set the process object that generates this data object.
//
void
DataObject
::DisconnectPipeline()
{
  itkDebugMacro( "disconnecting from the pipeline." );

  // disconnect ourselves from the current process object
  if (m_Source)
    {
    m_Source->SetNthOutput(m_SourceOutputIndex, 0);
    }

  // set our release data flag to off by default (purposely done after
  // we have disconnected from the pipeline so the new output of the
  // source can copy our original ReleaseDataFlag)
  this->ReleaseDataFlagOff();

  // reset our PipelineMTime (there is now nothing upstream from us)
  m_PipelineMTime = 0;

  this->Modified();
}

bool
DataObject
::DisconnectSource(ProcessObject *arg, unsigned int idx) const
{
  if ( m_Source == arg && m_SourceOutputIndex == idx)
    {
    itkDebugMacro( "disconnecting source  " << arg
                   << ", source output index " << idx);

    m_Source = 0;
    m_SourceOutputIndex = 0;
    this->Modified();
    return true;
    }
  else
    {
    itkDebugMacro( "could not disconnect source  " << arg
                   << ", source output index " << idx);
    return false;
    }
}

bool
DataObject
::ConnectSource(ProcessObject *arg, unsigned int idx) const
{
  if ( m_Source != arg || m_SourceOutputIndex != idx)
    {
    itkDebugMacro( "connecting source  " << arg
                   << ", source output index " << idx);

    m_Source = arg;
    m_SourceOutputIndex = idx;
    this->Modified();
    return true;
    }
  else
    {
    itkDebugMacro( "could not connect source  " << arg
                   << ", source output index " << idx);

    return false;
    }
}

//----------------------------------------------------------------------------

SmartPointerForwardReference<ProcessObject>
DataObject
::GetSource() const
{
  itkDebugMacro("returning Source address " << m_Source.GetPointer() );
  return m_Source.GetPointer();
}

unsigned int
DataObject
::GetSourceOutputIndex() const
{
  itkDebugMacro("returning Source index " << m_SourceOutputIndex );
  return m_SourceOutputIndex;
}

//----------------------------------------------------------------------------
void
DataObject
::PrintSelf(std::ostream& os, Indent indent) const
{
  Object::PrintSelf(os,indent);

  if ( m_Source )
    {
    os << indent << "Source: (" << m_Source.GetPointer() << ") \n";
    os << indent << "Source output index: " << m_SourceOutputIndex << "\n";
    }
  else
    {
    os << indent << "Source: (none)\n";
    os << indent << "Source output index:  0\n";
    }

  os << indent << "Release Data: "
     << (m_ReleaseDataFlag ? "On\n" : "Off\n");

  os << indent << "Data Released: "
     << (m_DataReleased ? "True\n" : "False\n");

  os << indent << "Global Release Data: "
     << (m_GlobalReleaseDataFlag ? "On\n" : "Off\n");

  os << indent << "PipelineMTime: " << m_PipelineMTime << std::endl;
  os << indent << "UpdateMTime: " << m_UpdateMTime << std::endl;
}

// The following methods are used for updating the data processing pipeline.
//

//----------------------------------------------------------------------------
void
DataObject
::Update()
{
  this->UpdateOutputInformation();
  this->PropagateRequestedRegion();
  this->UpdateOutputData();
}

void
DataObject
::UpdateOutputInformation()
{
  if (this->GetSource())
    {
    this->GetSource()->UpdateOutputInformation();
    }
}

void
DataObject
::ResetPipeline()
{
  this->PropagateResetPipeline();
}

void
DataObject
::PropagateResetPipeline()
{
  if (m_Source)
    {
    m_Source->PropagateResetPipeline();
    }
}

//----------------------------------------------------------------------------
void
DataObject
::PropagateRequestedRegion() throw (InvalidRequestedRegionError)
{
  // If we need to update due to PipelineMTime, or the fact that our
  // data was released, then propagate the update region to the source
  // if there is one.
  if ( m_UpdateMTime < m_PipelineMTime || m_DataReleased ||
       this->RequestedRegionIsOutsideOfTheBufferedRegion() )
    {
    if ( m_Source )
      {
      m_Source->PropagateRequestedRegion(this);
      }
    }

  // Check that the requested region lies within the largest possible region
  if ( ! this->VerifyRequestedRegion() )
    {
    // invalid requested region, throw an exception
    InvalidRequestedRegionError e(__FILE__, __LINE__);
    e.SetLocation(ITK_LOCATION);
    e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
    e.SetDataObject(this);

    throw e;
    // return;
    }
}

//----------------------------------------------------------------------------
void
DataObject
::UpdateOutputData()
{
  // If we need to update due to PipelineMTime, or the fact that our
  // data was released, then propagate the UpdateOutputData to the source
  // if there is one.
  if ( m_UpdateMTime < m_PipelineMTime || m_DataReleased ||
       this->RequestedRegionIsOutsideOfTheBufferedRegion() )
    {
    if ( m_Source )
      {
      m_Source->UpdateOutputData(this);
      }
    }
}

//----------------------------------------------------------------------------
void
DataObject
::DataHasBeenGenerated()
{
  m_DataReleased = 0;
  this->Modified();
  m_UpdateMTime.Modified();
}

//----------------------------------------------------------------------------
unsigned long
DataObject
::GetUpdateMTime() const
{
  return m_UpdateMTime.GetMTime();
}

} // end namespace itk
<commit_msg>BUG: 5647. Attempting to solve link issue in MinGW when using Shared libraries.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkDataObject.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

  Portions of this code are covered under the VTK copyright.
  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkDataObject.h"
#include "itkProcessObject.h"
#include "itkObjectFactory.h"
#include "itkSmartPointerForwardReference.txx"

// Manual instantiation is necessary to prevent link errors
ITKCommon_EXPORT template class itk::SmartPointerForwardReference<itk::ProcessObject>;

namespace itk
{

// after use by filter
bool DataObject::m_GlobalReleaseDataFlag = false;

DataObjectError
::DataObjectError()
  : ExceptionObject(), m_DataObject(0)
{
}

DataObjectError
::DataObjectError(const char *file, unsigned int lineNumber)
  : ExceptionObject(file, lineNumber), m_DataObject(0)
{
}

DataObjectError
::DataObjectError(const std::string& file, unsigned int lineNumber)
  : ExceptionObject(file, lineNumber), m_DataObject(0)
{
}

DataObjectError
::DataObjectError(const DataObjectError &orig)
  : ExceptionObject( orig )
{
  m_DataObject = orig.m_DataObject;
}

DataObjectError&
DataObjectError
::operator=( const DataObjectError& orig)
{
  ExceptionObject::operator= (orig);
  m_DataObject = orig.m_DataObject;
  return *this;
}

void
DataObjectError
::SetDataObject(DataObject *dobj)
{
  m_DataObject = dobj;
}

DataObject*
DataObjectError
::GetDataObject()
{
  return m_DataObject;
}

void
DataObjectError
::PrintSelf(std::ostream& os, Indent indent) const
{
  ExceptionObject::Print( os);

  os << indent << "Data object: ";
  if (m_DataObject)
    {
    os << std::endl;
    m_DataObject->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(None)" << std::endl;
    }
}

InvalidRequestedRegionError
::InvalidRequestedRegionError()
  : DataObjectError()
{
}

InvalidRequestedRegionError
::InvalidRequestedRegionError(const char *file, unsigned int lineNumber)
  : DataObjectError(file, lineNumber)
{
}

InvalidRequestedRegionError
::InvalidRequestedRegionError(const std::string& file, unsigned int lineNumber)
  : DataObjectError(file, lineNumber)
{
}

InvalidRequestedRegionError
::InvalidRequestedRegionError(const InvalidRequestedRegionError &orig)
  : DataObjectError( orig )
{
}

InvalidRequestedRegionError&
InvalidRequestedRegionError
::operator=( const InvalidRequestedRegionError& orig)
{
  DataObjectError::operator= (orig);
  return *this;
}

void
InvalidRequestedRegionError
::PrintSelf(std::ostream& os, Indent indent) const
{
  DataObjectError::PrintSelf( os, indent );
}

//----------------------------------------------------------------------------
DataObject::
DataObject() : m_UpdateMTime()
{
  m_Source = 0;
  m_SourceOutputIndex = 0;
  m_ReleaseDataFlag = false;

  // We have to assume that if a user is creating the data on their own,
  // then they will fill it with valid data.
  m_DataReleased = false;

  m_PipelineMTime = 0;
}

//----------------------------------------------------------------------------
DataObject
::~DataObject()
{
}

//----------------------------------------------------------------------------
void
DataObject
::Initialize()
{
// We don't modify ourselves because the "ReleaseData" methods depend upon
// no modification when initialized.
//
}

//----------------------------------------------------------------------------
void
DataObject
::SetGlobalReleaseDataFlag(bool val)
{
  if (val == m_GlobalReleaseDataFlag)
    {
    return;
    }
  m_GlobalReleaseDataFlag = val;
}

//----------------------------------------------------------------------------
bool
DataObject
::GetGlobalReleaseDataFlag()
{
  return m_GlobalReleaseDataFlag;
}

//----------------------------------------------------------------------------
void
DataObject
::ReleaseData()
{
  this->Initialize();
  m_DataReleased = true;
}

//----------------------------------------------------------------------------
bool
DataObject
::ShouldIReleaseData() const
{
  return ( m_GlobalReleaseDataFlag || m_ReleaseDataFlag );
}

//----------------------------------------------------------------------------
// Set the process object that generates this data object.
//
void
DataObject
::DisconnectPipeline()
{
  itkDebugMacro( "disconnecting from the pipeline." );

  // disconnect ourselves from the current process object
  if (m_Source)
    {
    m_Source->SetNthOutput(m_SourceOutputIndex, 0);
    }

  // set our release data flag to off by default (purposely done after
  // we have disconnected from the pipeline so the new output of the
  // source can copy our original ReleaseDataFlag)
  this->ReleaseDataFlagOff();

  // reset our PipelineMTime (there is now nothing upstream from us)
  m_PipelineMTime = 0;

  this->Modified();
}

bool
DataObject
::DisconnectSource(ProcessObject *arg, unsigned int idx) const
{
  if ( m_Source == arg && m_SourceOutputIndex == idx)
    {
    itkDebugMacro( "disconnecting source  " << arg
                   << ", source output index " << idx);

    m_Source = 0;
    m_SourceOutputIndex = 0;
    this->Modified();
    return true;
    }
  else
    {
    itkDebugMacro( "could not disconnect source  " << arg
                   << ", source output index " << idx);
    return false;
    }
}

bool
DataObject
::ConnectSource(ProcessObject *arg, unsigned int idx) const
{
  if ( m_Source != arg || m_SourceOutputIndex != idx)
    {
    itkDebugMacro( "connecting source  " << arg
                   << ", source output index " << idx);

    m_Source = arg;
    m_SourceOutputIndex = idx;
    this->Modified();
    return true;
    }
  else
    {
    itkDebugMacro( "could not connect source  " << arg
                   << ", source output index " << idx);

    return false;
    }
}

//----------------------------------------------------------------------------

SmartPointerForwardReference<ProcessObject>
DataObject
::GetSource() const
{
  itkDebugMacro("returning Source address " << m_Source.GetPointer() );
  return m_Source.GetPointer();
}

unsigned int
DataObject
::GetSourceOutputIndex() const
{
  itkDebugMacro("returning Source index " << m_SourceOutputIndex );
  return m_SourceOutputIndex;
}

//----------------------------------------------------------------------------
void
DataObject
::PrintSelf(std::ostream& os, Indent indent) const
{
  Object::PrintSelf(os,indent);

  if ( m_Source )
    {
    os << indent << "Source: (" << m_Source.GetPointer() << ") \n";
    os << indent << "Source output index: " << m_SourceOutputIndex << "\n";
    }
  else
    {
    os << indent << "Source: (none)\n";
    os << indent << "Source output index:  0\n";
    }

  os << indent << "Release Data: "
     << (m_ReleaseDataFlag ? "On\n" : "Off\n");

  os << indent << "Data Released: "
     << (m_DataReleased ? "True\n" : "False\n");

  os << indent << "Global Release Data: "
     << (m_GlobalReleaseDataFlag ? "On\n" : "Off\n");

  os << indent << "PipelineMTime: " << m_PipelineMTime << std::endl;
  os << indent << "UpdateMTime: " << m_UpdateMTime << std::endl;
}

// The following methods are used for updating the data processing pipeline.
//

//----------------------------------------------------------------------------
void
DataObject
::Update()
{
  this->UpdateOutputInformation();
  this->PropagateRequestedRegion();
  this->UpdateOutputData();
}

void
DataObject
::UpdateOutputInformation()
{
  if (this->GetSource())
    {
    this->GetSource()->UpdateOutputInformation();
    }
}

void
DataObject
::ResetPipeline()
{
  this->PropagateResetPipeline();
}

void
DataObject
::PropagateResetPipeline()
{
  if (m_Source)
    {
    m_Source->PropagateResetPipeline();
    }
}

//----------------------------------------------------------------------------
void
DataObject
::PropagateRequestedRegion() throw (InvalidRequestedRegionError)
{
  // If we need to update due to PipelineMTime, or the fact that our
  // data was released, then propagate the update region to the source
  // if there is one.
  if ( m_UpdateMTime < m_PipelineMTime || m_DataReleased ||
       this->RequestedRegionIsOutsideOfTheBufferedRegion() )
    {
    if ( m_Source )
      {
      m_Source->PropagateRequestedRegion(this);
      }
    }

  // Check that the requested region lies within the largest possible region
  if ( ! this->VerifyRequestedRegion() )
    {
    // invalid requested region, throw an exception
    InvalidRequestedRegionError e(__FILE__, __LINE__);
    e.SetLocation(ITK_LOCATION);
    e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
    e.SetDataObject(this);

    throw e;
    // return;
    }
}

//----------------------------------------------------------------------------
void
DataObject
::UpdateOutputData()
{
  // If we need to update due to PipelineMTime, or the fact that our
  // data was released, then propagate the UpdateOutputData to the source
  // if there is one.
  if ( m_UpdateMTime < m_PipelineMTime || m_DataReleased ||
       this->RequestedRegionIsOutsideOfTheBufferedRegion() )
    {
    if ( m_Source )
      {
      m_Source->UpdateOutputData(this);
      }
    }
}

//----------------------------------------------------------------------------
void
DataObject
::DataHasBeenGenerated()
{
  m_DataReleased = 0;
  this->Modified();
  m_UpdateMTime.Modified();
}

//----------------------------------------------------------------------------
unsigned long
DataObject
::GetUpdateMTime() const
{
  return m_UpdateMTime.GetMTime();
}

} // end namespace itk
<|endoftext|>


<commit_before>#include <handy/handy.h>

using namespace std;
using namespace handy;

struct Report {
    long connected;
    long retry;
    long sended;
    long recved;
    Report() { memset(this, 0, sizeof(*this)); }
};

int main(int argc, const char* argv[]) {
    if (argc < 9) {
        printf("usage %s <host> <begin port> <end port> <conn count> <create seconds> <subprocesses> <hearbeat interval> <send size> <management port>\n", argv[0]);
        return 1;
    }
    int c = 1;
    string host = argv[c++];
    int begin_port = atoi(argv[c++]);
    int end_port = atoi(argv[c++]);
    int conn_count = atoi(argv[c++]);
    int create_seconds = atoi(argv[c++]);
    int processes = atoi(argv[c++]);
    conn_count = conn_count / processes;
    int heartbeat_interval = atoi(argv[c++]);
    int bsz = atoi(argv[c++]);
    int man_port = atoi(argv[c++]);

    int pid = 1;
    for (int i = 0; i < processes; i ++) {
        pid = fork();
        if (pid == 0) { // a child process, break
            sleep(1);
            break;
        }
    }

    EventBase base;
    if (pid == 0) { //child process
        char *buf = new char[bsz];
        ExitCaller ec1([=] {delete[] buf; });
        Slice msg(buf, bsz);
        char heartbeat[] = "heartbeat";
        int send = 0;
        int connected = 0;
        int retry = 0;
        int recved = 0;

        vector<TcpConnPtr> allConns;
        info("creating %d connections", conn_count);
        for (int k = 0; k < create_seconds; k ++) {
            base.runAfter(1000*k, [&]{
                int c = conn_count / create_seconds;
                for (int i = 0; i < c; i++) {
                    short port = begin_port + (i % (end_port - begin_port));
                    auto con = TcpConn::createConnection(&base, host, port, 20*1000);
                    allConns.push_back(con);
                    con->setReconnectInterval(20*1000);
                    con->onMsg(new LengthCodec, [&](const TcpConnPtr& con, const Slice& msg) {
                        if (heartbeat_interval == 0) { // echo the msg if no interval
                            con->sendMsg(msg);
                            send++;
                        }
                        recved ++;
                    });
                    con->onState([&, i](const TcpConnPtr &con) {
                        TcpConn::State st = con->getState();
                        if (st == TcpConn::Connected) {
                            connected++;
//                            send ++;
//                            con->sendMsg(msg);
                        } else if (st == TcpConn::Failed || st == TcpConn::Closed) { //连接出错
                            if (st == TcpConn::Closed) { connected--; }
                            retry++;
                        }
                    });
                }

            });
        }
        if (heartbeat_interval) {
            base.runAfter(heartbeat_interval * 1000, [&] {
                for (int i = 0; i < heartbeat_interval; i ++) {
                    base.runAfter(i*1000, [&,i]{
                        size_t block = allConns.size() / heartbeat_interval;
                        for (size_t j=i*block; j<(i+1)*block && j<allConns.size(); j++) {
                            if (allConns[i]->getState() == TcpConn::Connected) {
                                allConns[i]->sendMsg(msg);
                                send++;
                            }
                        }
                    });
                }
            }, heartbeat_interval * 1000);
        }
        TcpConnPtr report = TcpConn::createConnection(&base, "127.0.0.1", man_port, 3000);
        report->onMsg(new LineCodec, [&](const TcpConnPtr& con, Slice msg) {
            if (msg == "exit") {
                info("recv exit msg from master, so exit");
                base.exit();
            }
        });
        report->onState([&](const TcpConnPtr& con) {
            if (con->getState() == TcpConn::Closed) {
                base.exit();
            }
        });
        base.runAfter(2000, [&]() {
            report->sendMsg(util::format("%d connected: %ld retry: %ld send: %ld recved: %ld",
                                         getpid(), connected, retry, send, recved));
        }, 100);
        base.loop();
    } else { // master process
        map<int, Report> subs;
        TcpServerPtr master = TcpServer::startServer(&base, "127.0.0.1", man_port);
        master->onConnMsg(new LineCodec, [&](const TcpConnPtr& con, Slice msg) {
            auto fs = msg.split(' ');
            if (fs.size() != 9) {
                error("number of fields is %lu expected 7", fs.size());
                return;
            }
            Report& c = subs[atoi(fs[0].data())];
            c.connected = atoi(fs[2].data());
            c.retry= atoi(fs[4].data());
            c.sended = atoi(fs[6].data());
            c.recved = atoi(fs[8].data());
        });
        base.runAfter(3000, [&](){
            for(auto& s: subs) {
                Report& r = s.second;
                printf("pid: %6ld connected %6ld retry %6ld sended %6ld recved %6ld\n", (long)s.first, r.connected, r.retry, r.sended, r.recved);
            }
            printf("\n");
        }, 3000);
        base.loop();
    }
    info("program exited");
}
<commit_msg>add signal handling<commit_after>#include <handy/handy.h>

using namespace std;
using namespace handy;

struct Report {
    long connected;
    long retry;
    long sended;
    long recved;
    Report() { memset(this, 0, sizeof(*this)); }
};

int main(int argc, const char* argv[]) {
    if (argc < 9) {
        printf("usage %s <host> <begin port> <end port> <conn count> <create seconds> <subprocesses> <hearbeat interval> <send size> <management port>\n", argv[0]);
        return 1;
    }
    int c = 1;
    string host = argv[c++];
    int begin_port = atoi(argv[c++]);
    int end_port = atoi(argv[c++]);
    int conn_count = atoi(argv[c++]);
    int create_seconds = atoi(argv[c++]);
    int processes = atoi(argv[c++]);
    conn_count = conn_count / processes;
    int heartbeat_interval = atoi(argv[c++]);
    int bsz = atoi(argv[c++]);
    int man_port = atoi(argv[c++]);

    int pid = 1;
    for (int i = 0; i < processes; i ++) {
        pid = fork();
        if (pid == 0) { // a child process, break
            sleep(1);
            break;
        }
    }

    EventBase base;
    if (pid == 0) { //child process
        char *buf = new char[bsz];
        ExitCaller ec1([=] {delete[] buf; });
        Slice msg(buf, bsz);
        char heartbeat[] = "heartbeat";
        int send = 0;
        int connected = 0;
        int retry = 0;
        int recved = 0;

        vector<TcpConnPtr> allConns;
        info("creating %d connections", conn_count);
        for (int k = 0; k < create_seconds; k ++) {
            base.runAfter(1000*k, [&]{
                int c = conn_count / create_seconds;
                for (int i = 0; i < c; i++) {
                    short port = begin_port + (i % (end_port - begin_port));
                    auto con = TcpConn::createConnection(&base, host, port, 20*1000);
                    allConns.push_back(con);
                    con->setReconnectInterval(20*1000);
                    con->onMsg(new LengthCodec, [&](const TcpConnPtr& con, const Slice& msg) {
                        if (heartbeat_interval == 0) { // echo the msg if no interval
                            con->sendMsg(msg);
                            send++;
                        }
                        recved ++;
                    });
                    con->onState([&, i](const TcpConnPtr &con) {
                        TcpConn::State st = con->getState();
                        if (st == TcpConn::Connected) {
                            connected++;
//                            send ++;
//                            con->sendMsg(msg);
                        } else if (st == TcpConn::Failed || st == TcpConn::Closed) { //连接出错
                            if (st == TcpConn::Closed) { connected--; }
                            retry++;
                        }
                    });
                }

            });
        }
        if (heartbeat_interval) {
            base.runAfter(heartbeat_interval * 1000, [&] {
                for (int i = 0; i < heartbeat_interval; i ++) {
                    base.runAfter(i*1000, [&,i]{
                        size_t block = allConns.size() / heartbeat_interval;
                        for (size_t j=i*block; j<(i+1)*block && j<allConns.size(); j++) {
                            if (allConns[i]->getState() == TcpConn::Connected) {
                                allConns[i]->sendMsg(msg);
                                send++;
                            }
                        }
                    });
                }
            }, heartbeat_interval * 1000);
        }
        TcpConnPtr report = TcpConn::createConnection(&base, "127.0.0.1", man_port, 3000);
        report->onMsg(new LineCodec, [&](const TcpConnPtr& con, Slice msg) {
            if (msg == "exit") {
                info("recv exit msg from master, so exit");
                base.exit();
            }
        });
        report->onState([&](const TcpConnPtr& con) {
            if (con->getState() == TcpConn::Closed) {
                base.exit();
            }
        });
        base.runAfter(2000, [&]() {
            report->sendMsg(util::format("%d connected: %ld retry: %ld send: %ld recved: %ld",
                                         getpid(), connected, retry, send, recved));
        }, 100);
        base.loop();
    } else { // master process
        map<int, Report> subs;
        TcpServerPtr master = TcpServer::startServer(&base, "127.0.0.1", man_port);
        master->onConnMsg(new LineCodec, [&](const TcpConnPtr& con, Slice msg) {
            auto fs = msg.split(' ');
            if (fs.size() != 9) {
                error("number of fields is %lu expected 7", fs.size());
                return;
            }
            Report& c = subs[atoi(fs[0].data())];
            c.connected = atoi(fs[2].data());
            c.retry= atoi(fs[4].data());
            c.sended = atoi(fs[6].data());
            c.recved = atoi(fs[8].data());
        });
        base.runAfter(3000, [&](){
            for(auto& s: subs) {
                Report& r = s.second;
                printf("pid: %6ld connected %6ld retry %6ld sended %6ld recved %6ld\n", (long)s.first, r.connected, r.retry, r.sended, r.recved);
            }
            printf("\n");
        }, 3000);
        Signal::signal(SIGCHLD, []{
            int status = 0;
            wait(&status);
            error("wait result: status: %d is signaled: %d signal: %d", status,  WIFSIGNALED(status), WTERMSIG(status));
        });
        base.loop();
    }
    info("program exited");
}
<|endoftext|>


<commit_before>#include "routing/index_graph_starter.hpp"

#include "geometry/distance.hpp"

namespace
{
using namespace routing;

m2::PointD CalcProjectionToSegment(Segment const & segment, m2::PointD const & point,
                                   WorldGraph & graph)
{
  m2::ProjectionToSection<m2::PointD> projection;
  projection.SetBounds(graph.GetPoint(segment, false), graph.GetPoint(segment, true));
  return projection(point);
}
}

namespace routing
{
// static
Segment constexpr IndexGraphStarter::kStartFakeSegment;
Segment constexpr IndexGraphStarter::kFinishFakeSegment;

IndexGraphStarter::IndexGraphStarter(FakeVertex const & start, FakeVertex const & finish,
                                     WorldGraph & graph)
  : m_graph(graph)
  , m_start(start.GetSegment(),
            CalcProjectionToSegment(start.GetSegment(), start.GetPoint(), graph))
  , m_finish(finish.GetSegment(),
             CalcProjectionToSegment(finish.GetSegment(), finish.GetPoint(), graph))
{
}

m2::PointD const & IndexGraphStarter::GetPoint(Segment const & segment, bool front)
{
  if (segment == kStartFakeSegment || (!front && m_start.Fits(segment)))
    return m_start.GetPoint();

  if (segment == kFinishFakeSegment || (front && m_finish.Fits(segment)))
    return m_finish.GetPoint();

  return m_graph.GetPoint(segment, front);
}

// static
size_t IndexGraphStarter::GetRouteNumPoints(vector<Segment> const & segments)
{
  // Valid route contains at least 3 segments:
  // start fake, finish fake and at least one normal nearest segment.
  CHECK_GREATER_OR_EQUAL(segments.size(), 3, ());

  // -2 for fake start and finish.
  // +1 for front point of first segment.
  return segments.size() - 1;
}

m2::PointD const & IndexGraphStarter::GetRoutePoint(vector<Segment> const & segments,
                                                    size_t pointIndex)
{
  if (pointIndex == 0)
    return m_start.GetPoint();

  CHECK_LESS(pointIndex, segments.size(), ());
  return GetPoint(segments[pointIndex], true /* front */);
}

void IndexGraphStarter::GetEdgesList(Segment const & segment, bool isOutgoing,
                                     vector<SegmentEdge> & edges)
{
  edges.clear();

  if (segment == kStartFakeSegment)
  {
    GetFakeToNormalEdges(m_start, isOutgoing, edges);
    return;
  }

  if (segment == kFinishFakeSegment)
  {
    GetFakeToNormalEdges(m_finish, isOutgoing, edges);
    return;
  }

  m_graph.GetEdgeList(segment, isOutgoing, IsLeap(segment.GetMwmId()), edges);
  GetNormalToFakeEdge(segment, m_start, kStartFakeSegment, isOutgoing, edges);
  GetNormalToFakeEdge(segment, m_finish, kFinishFakeSegment, isOutgoing, edges);
}

void IndexGraphStarter::GetFakeToNormalEdges(FakeVertex const & fakeVertex, bool isOutgoing,
                                             vector<SegmentEdge> & edges)
{
  if (m_graph.GetMode() == WorldGraph::Mode::LeapsOnly)
  {
    ConnectLeapToTransitions(fakeVertex, isOutgoing, edges);
    return;
  }

  GetFakeToNormalEdge(fakeVertex, true /* forward */, edges);

  if (!m_graph.GetRoadGeometry(fakeVertex.GetMwmId(), fakeVertex.GetFeatureId()).IsOneWay())
    GetFakeToNormalEdge(fakeVertex, false /* forward */, edges);
}

void IndexGraphStarter::GetFakeToNormalEdge(FakeVertex const & fakeVertex, bool forward,
                                            vector<SegmentEdge> & edges)
{
  auto const segment = fakeVertex.GetSegmentWithDirection(forward);
  m2::PointD const & pointTo = GetPoint(segment, true /* front */);
  double const weight = m_graph.GetEstimator().CalcLeapWeight(fakeVertex.GetPoint(), pointTo);
  edges.emplace_back(segment, weight);
}

void IndexGraphStarter::GetNormalToFakeEdge(Segment const & segment, FakeVertex const & fakeVertex,
                                            Segment const & fakeSegment, bool isOutgoing,
                                            vector<SegmentEdge> & edges)
{
  m2::PointD const & pointFrom = GetPoint(segment, isOutgoing);
  if (segment.GetMwmId() == fakeVertex.GetMwmId() &&
      m_graph.GetMode() == WorldGraph::Mode::LeapsOnly)
  {
    if (m_graph.IsTransition(segment, isOutgoing))
    {
      edges.emplace_back(fakeSegment,
                         m_graph.GetEstimator().CalcLeapWeight(pointFrom, fakeVertex.GetPoint()));
    }
    return;
  }

  if (!fakeVertex.Fits(segment))
    return;

  edges.emplace_back(fakeSegment,
                     m_graph.GetEstimator().CalcLeapWeight(pointFrom, fakeVertex.GetPoint()));
}

void IndexGraphStarter::ConnectLeapToTransitions(FakeVertex const & fakeVertex, bool isOutgoing,
                                                 vector<SegmentEdge> & edges)
{
  edges.clear();
  m2::PointD const & segmentPoint = fakeVertex.GetPoint();

  // Note. If |isOutgoing| == true it's necessary to add edges which connect the start with all
  // exits of its mwm. So |isEnter| below should be set to false.
  // If |isOutgoing| == false all enters of the finish mwm should be connected with the finish point.
  // So |isEnter| below should be set to true.
  m_graph.ForEachTransition(
      fakeVertex.GetMwmId(), !isOutgoing /* isEnter */, [&](Segment const & transition) {
        edges.emplace_back(transition, m_graph.GetEstimator().CalcLeapWeight(
          segmentPoint, GetPoint(transition, isOutgoing)));
      });
}
}  // namespace routing
<commit_msg>[routing] Pull request #6054 review fixes<commit_after>#include "routing/index_graph_starter.hpp"

#include "geometry/distance.hpp"

namespace
{
using namespace routing;

m2::PointD CalcProjectionToSegment(Segment const & segment, m2::PointD const & point,
                                   WorldGraph & graph)
{
  m2::ProjectionToSection<m2::PointD> projection;
  projection.SetBounds(graph.GetPoint(segment, false /* front */),
                       graph.GetPoint(segment, true /* front */));
  return projection(point);
}
}  // namespace

namespace routing
{
// static
Segment constexpr IndexGraphStarter::kStartFakeSegment;
Segment constexpr IndexGraphStarter::kFinishFakeSegment;

IndexGraphStarter::IndexGraphStarter(FakeVertex const & start, FakeVertex const & finish,
                                     WorldGraph & graph)
  : m_graph(graph)
  , m_start(start.GetSegment(),
            CalcProjectionToSegment(start.GetSegment(), start.GetPoint(), graph))
  , m_finish(finish.GetSegment(),
             CalcProjectionToSegment(finish.GetSegment(), finish.GetPoint(), graph))
{
}

m2::PointD const & IndexGraphStarter::GetPoint(Segment const & segment, bool front)
{
  if (segment == kStartFakeSegment || (!front && m_start.Fits(segment)))
    return m_start.GetPoint();

  if (segment == kFinishFakeSegment || (front && m_finish.Fits(segment)))
    return m_finish.GetPoint();

  return m_graph.GetPoint(segment, front);
}

// static
size_t IndexGraphStarter::GetRouteNumPoints(vector<Segment> const & segments)
{
  // Valid route contains at least 3 segments:
  // start fake, finish fake and at least one normal nearest segment.
  CHECK_GREATER_OR_EQUAL(segments.size(), 3, ());

  // -2 for fake start and finish.
  // +1 for front point of first segment.
  return segments.size() - 1;
}

m2::PointD const & IndexGraphStarter::GetRoutePoint(vector<Segment> const & segments,
                                                    size_t pointIndex)
{
  if (pointIndex == 0)
    return m_start.GetPoint();

  CHECK_LESS(pointIndex, segments.size(), ());
  return GetPoint(segments[pointIndex], true /* front */);
}

void IndexGraphStarter::GetEdgesList(Segment const & segment, bool isOutgoing,
                                     vector<SegmentEdge> & edges)
{
  edges.clear();

  if (segment == kStartFakeSegment)
  {
    GetFakeToNormalEdges(m_start, isOutgoing, edges);
    return;
  }

  if (segment == kFinishFakeSegment)
  {
    GetFakeToNormalEdges(m_finish, isOutgoing, edges);
    return;
  }

  m_graph.GetEdgeList(segment, isOutgoing, IsLeap(segment.GetMwmId()), edges);
  GetNormalToFakeEdge(segment, m_start, kStartFakeSegment, isOutgoing, edges);
  GetNormalToFakeEdge(segment, m_finish, kFinishFakeSegment, isOutgoing, edges);
}

void IndexGraphStarter::GetFakeToNormalEdges(FakeVertex const & fakeVertex, bool isOutgoing,
                                             vector<SegmentEdge> & edges)
{
  if (m_graph.GetMode() == WorldGraph::Mode::LeapsOnly)
  {
    ConnectLeapToTransitions(fakeVertex, isOutgoing, edges);
    return;
  }

  GetFakeToNormalEdge(fakeVertex, true /* forward */, edges);

  if (!m_graph.GetRoadGeometry(fakeVertex.GetMwmId(), fakeVertex.GetFeatureId()).IsOneWay())
    GetFakeToNormalEdge(fakeVertex, false /* forward */, edges);
}

void IndexGraphStarter::GetFakeToNormalEdge(FakeVertex const & fakeVertex, bool forward,
                                            vector<SegmentEdge> & edges)
{
  auto const segment = fakeVertex.GetSegmentWithDirection(forward);
  m2::PointD const & pointTo = GetPoint(segment, true /* front */);
  double const weight = m_graph.GetEstimator().CalcLeapWeight(fakeVertex.GetPoint(), pointTo);
  edges.emplace_back(segment, weight);
}

void IndexGraphStarter::GetNormalToFakeEdge(Segment const & segment, FakeVertex const & fakeVertex,
                                            Segment const & fakeSegment, bool isOutgoing,
                                            vector<SegmentEdge> & edges)
{
  m2::PointD const & pointFrom = GetPoint(segment, isOutgoing);
  if (segment.GetMwmId() == fakeVertex.GetMwmId() &&
      m_graph.GetMode() == WorldGraph::Mode::LeapsOnly)
  {
    if (m_graph.IsTransition(segment, isOutgoing))
    {
      edges.emplace_back(fakeSegment,
                         m_graph.GetEstimator().CalcLeapWeight(pointFrom, fakeVertex.GetPoint()));
    }
    return;
  }

  if (!fakeVertex.Fits(segment))
    return;

  edges.emplace_back(fakeSegment,
                     m_graph.GetEstimator().CalcLeapWeight(pointFrom, fakeVertex.GetPoint()));
}

void IndexGraphStarter::ConnectLeapToTransitions(FakeVertex const & fakeVertex, bool isOutgoing,
                                                 vector<SegmentEdge> & edges)
{
  edges.clear();
  m2::PointD const & segmentPoint = fakeVertex.GetPoint();

  // Note. If |isOutgoing| == true it's necessary to add edges which connect the start with all
  // exits of its mwm. So |isEnter| below should be set to false.
  // If |isOutgoing| == false all enters of the finish mwm should be connected with the finish point.
  // So |isEnter| below should be set to true.
  m_graph.ForEachTransition(
      fakeVertex.GetMwmId(), !isOutgoing /* isEnter */, [&](Segment const & transition) {
        edges.emplace_back(transition, m_graph.GetEstimator().CalcLeapWeight(
          segmentPoint, GetPoint(transition, isOutgoing)));
      });
}
}  // namespace routing
<|endoftext|>


<commit_before>#include "Terrain.hpp"

namespace Chimera {

Terrain::Terrain() { SetDefaults(); }

Terrain::~Terrain() {}

void Terrain::SetDefaults() {
    terrain.setDefaults();
    VertexBufferObject = 0;
    IndexBufferObject = 0;
}

bool Terrain::LoadTexture2D(char* FileName, float Scale, float Offset) {
    return terrain.loadTexture2D(FileName, Scale, Offset);
}

bool Terrain::LoadBinary(char* FileName) {

    bool okLoad = terrain.loadBinary(FileName);

    unsigned int sizeBufferVertex = terrain.vertices.size() * sizeof(VertexData);
    unsigned int sizeBufferIndex = terrain.indices.size() * sizeof(unsigned int);

    glGenBuffers(1, &VertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, VertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, sizeBufferVertex, &terrain.vertices[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glGenBuffers(1, &IndexBufferObject);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferObject);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeBufferIndex, &terrain.indices[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    // TODO: TESTAR SE VALORES PASSAM!!!!!
    bspTree.Init(&terrain.vertices[0], &terrain.indices[0], terrain.indices.size(), terrain.getMin(), terrain.getMax());

    return true;
}

int Terrain::CheckVisibility(Frustum& _frustum, bool SortVisibleGeometryNodes) {
    return bspTree.CheckVisibility(_frustum, SortVisibleGeometryNodes);
}

void Terrain::Render(bool VisualizeRenderingOrder) {
    glBindBuffer(GL_ARRAY_BUFFER, VertexBufferObject);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(VertexData), (void*)(sizeof(glm::vec3) * 0));

    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, sizeof(VertexData), (void*)(sizeof(glm::vec3) * 1));

    bspTree.Render(VisualizeRenderingOrder);

    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void Terrain::RenderSlow() {
    glBindBuffer(GL_ARRAY_BUFFER, VertexBufferObject);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(VertexData), (void*)(sizeof(glm::vec3) * 0));

    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, sizeof(VertexData), (void*)(sizeof(glm::vec3) * 1));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferObject);

    glDrawElements(GL_TRIANGLES, terrain.indices.size(), GL_UNSIGNED_INT, NULL);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void Terrain::RenderSlowToShadowMap() {
    glBindBuffer(GL_ARRAY_BUFFER, VertexBufferObject);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(VertexData), (void*)(sizeof(glm::vec3) * 0));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferObject);

    glDrawElements(GL_TRIANGLES, terrain.indices.size(), GL_UNSIGNED_INT, NULL);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glDisableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void Terrain::RenderAABB(int Depth) { bspTree.RenderAABB(Depth); }

void Terrain::Destroy() {
    terrain.destroy();

    if (VertexBufferObject != 0) {
        glDeleteBuffers(1, &VertexBufferObject);
    }

    if (IndexBufferObject != 0) {
        glDeleteBuffers(1, &IndexBufferObject);
    }

    bspTree.Destroy();
}
} // namespace Chimera<commit_msg>removido antigo terrain<commit_after><|endoftext|>