<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "qmljsplugindumper.h"
#include "qmljsmodelmanager.h"

#include <qmljs/qmljsdocument.h>
#include <qmljs/qmljsinterpreter.h>
#include <projectexplorer/filewatcher.h>
#include <projectexplorer/projectexplorer.h>
#include <coreplugin/messagemanager.h>

#include <QtCore/QDir>

using namespace LanguageUtils;
using namespace QmlJS;
using namespace QmlJSTools;
using namespace QmlJSTools::Internal;

PluginDumper::PluginDumper(ModelManager *modelManager)
    : QObject(modelManager)
    , m_modelManager(modelManager)
    , m_pluginWatcher(new ProjectExplorer::FileWatcher(this))
{
    connect(m_pluginWatcher, SIGNAL(fileChanged(QString)), SLOT(pluginChanged(QString)));
}

void PluginDumper::loadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion)
{
    // move to the owning thread
    metaObject()->invokeMethod(this, "onLoadPluginTypes",
                               Q_ARG(QString, libraryPath),
                               Q_ARG(QString, importPath),
                               Q_ARG(QString, importUri),
                               Q_ARG(QString, importVersion));
}

void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion)
{
    const QString canonicalLibraryPath = QDir::cleanPath(libraryPath);
    if (m_runningQmldumps.values().contains(canonicalLibraryPath))
        return;
    const Snapshot snapshot = m_modelManager->snapshot();
    const LibraryInfo libraryInfo = snapshot.libraryInfo(canonicalLibraryPath);
    if (libraryInfo.dumpStatus() != LibraryInfo::DumpNotStartedOrRunning)
        return;

    // avoid inserting the same plugin twice
    int index;
    for (index = 0; index < m_plugins.size(); ++index) {
        if (m_plugins.at(index).qmldirPath == libraryPath)
            break;
    }
    if (index == m_plugins.size())
        m_plugins.append(Plugin());

    Plugin &plugin = m_plugins[index];
    plugin.qmldirPath = canonicalLibraryPath;
    plugin.importPath = importPath;
    plugin.importUri = importUri;
    plugin.importVersion = importVersion;

    // watch plugin libraries
    foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) {
        const QString pluginLibrary = resolvePlugin(canonicalLibraryPath, plugin.path, plugin.name);
        m_pluginWatcher->addFile(pluginLibrary);
        m_libraryToPluginIndex.insert(pluginLibrary, index);
    }

    // watch library xml file
    if (plugin.hasPredumpedQmlTypesFile()) {
        const QString &path = plugin.predumpedQmlTypesFilePath();
        m_pluginWatcher->addFile(path);
        m_libraryToPluginIndex.insert(path, index);
    }

    dump(plugin);
}

void PluginDumper::scheduleCompleteRedump()
{
    metaObject()->invokeMethod(this, "dumpAllPlugins", Qt::QueuedConnection);
}

void PluginDumper::dumpAllPlugins()
{
    foreach (const Plugin &plugin, m_plugins)
        dump(plugin);
}

static QString qmldumpErrorMessage(const QString &libraryPath, const QString &error)
{
    return PluginDumper::tr("Type dump of QML plugin in %1 failed.\nErrors:\n%2\n").
           arg(libraryPath, error);
}

static QString qmldumpFailedMessage(const QString &error)
{
    QString firstLines =
            QStringList(error.split(QLatin1Char('\n')).mid(0, 10)).join(QLatin1String("\n"));
    return PluginDumper::tr("Type dump of C++ plugin failed.\n"
                            "First 10 lines or errors:\n"
                            "\n"
                            "%1"
                            "\n"
                            "Check 'General Messages' output pane for details."
                            ).arg(firstLines);
}

static QList<FakeMetaObject::ConstPtr> parseHelper(const QByteArray &qmlTypeDescriptions, QString *error)
{
    QList<FakeMetaObject::ConstPtr> ret;
    QHash<QString, FakeMetaObject::ConstPtr> newObjects;
    *error = Interpreter::CppQmlTypesLoader::parseQmlTypeDescriptions(qmlTypeDescriptions, &newObjects);

    if (error->isEmpty()) {
        ret = newObjects.values();
    }
    return ret;
}

void PluginDumper::qmlPluginTypeDumpDone(int exitCode)
{
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (!process)
        return;
    process->deleteLater();

    const QString libraryPath = m_runningQmldumps.take(process);
    const Snapshot snapshot = m_modelManager->snapshot();
    LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath);

    if (exitCode != 0) {
        Core::MessageManager *messageManager = Core::MessageManager::instance();
        const QString errorMessages = process->readAllStandardError();
        messageManager->printToOutputPane(qmldumpErrorMessage(libraryPath, errorMessages));
        libraryInfo.setDumpStatus(LibraryInfo::DumpError, qmldumpFailedMessage(errorMessages));
    }

    const QByteArray output = process->readAllStandardOutput();
    QString error;
    QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(output, &error);
    if (exitCode == 0 && !error.isEmpty()) {
        libraryInfo.setDumpStatus(LibraryInfo::DumpError, tr("Type dump of C++ plugin failed. Parse error:\n'%1'").arg(error));
    }

    if (exitCode == 0 && error.isEmpty()) {
        libraryInfo.setMetaObjects(objectsList);
// ### disabled code path for running qmldump to get Qt's builtins
//        if (libraryPath.isEmpty())
//            Interpreter::CppQmlTypesLoader::builtinObjects.append(objectsList);
        libraryInfo.setDumpStatus(LibraryInfo::DumpDone);
    }

    if (!libraryPath.isEmpty())
        m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
}

void PluginDumper::qmlPluginTypeDumpError(QProcess::ProcessError)
{
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (!process)
        return;
    process->deleteLater();

    const QString libraryPath = m_runningQmldumps.take(process);

    Core::MessageManager *messageManager = Core::MessageManager::instance();
    const QString errorMessages = process->readAllStandardError();
    messageManager->printToOutputPane(qmldumpErrorMessage(libraryPath, errorMessages));

    if (!libraryPath.isEmpty()) {
        const Snapshot snapshot = m_modelManager->snapshot();
        LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath);
        libraryInfo.setDumpStatus(LibraryInfo::DumpError, qmldumpFailedMessage(errorMessages));
        m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
    }
}

void PluginDumper::pluginChanged(const QString &pluginLibrary)
{
    const int pluginIndex = m_libraryToPluginIndex.value(pluginLibrary, -1);
    if (pluginIndex == -1)
        return;

    const Plugin &plugin = m_plugins.at(pluginIndex);
    dump(plugin);
}

void PluginDumper::dump(const Plugin &plugin)
{
    if (plugin.hasPredumpedQmlTypesFile()) {
        const Snapshot snapshot = m_modelManager->snapshot();
        LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath);
        if (!libraryInfo.isValid())
            return;

        const QString &path = plugin.predumpedQmlTypesFilePath();
        QFile libraryQmlTypesFile(path);
        if (!libraryQmlTypesFile.open(QFile::ReadOnly | QFile::Text)) {
            libraryInfo.setDumpStatus(LibraryInfo::DumpError,
                                      tr("Could not open file '%1' for reading.").arg(path));
            m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
            return;
        }

        const QByteArray qmlTypeDescriptions = libraryQmlTypesFile.readAll();
        libraryQmlTypesFile.close();

        QString error;
        const QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(qmlTypeDescriptions, &error);

        if (error.isEmpty()) {
            libraryInfo.setMetaObjects(objectsList);
            libraryInfo.setDumpStatus(LibraryInfo::DumpDone);
        } else {
            libraryInfo.setDumpStatus(LibraryInfo::DumpError,
                                      tr("Failed to parse '%1'.\nError: %2").arg(path, error));
        }
        m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
        return;
    }

    ProjectExplorer::Project *activeProject = ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject();
    if (!activeProject)
        return;

    ModelManagerInterface::ProjectInfo info = m_modelManager->projectInfo(activeProject);

    if (info.qmlDumpPath.isEmpty()) {
        const Snapshot snapshot = m_modelManager->snapshot();
        LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath);
        if (!libraryInfo.isValid())
            return;

        libraryInfo.setDumpStatus(LibraryInfo::DumpError,
                                  tr("Could not locate the helper application for dumping type information from C++ plugins.\n"
                                     "Please build the debugging helpers on the Qt version options page."));
        m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
        return;
    }

    QProcess *process = new QProcess(this);
    process->setEnvironment(info.qmlDumpEnvironment.toStringList());
    connect(process, SIGNAL(finished(int)), SLOT(qmlPluginTypeDumpDone(int)));
    connect(process, SIGNAL(error(QProcess::ProcessError)), SLOT(qmlPluginTypeDumpError(QProcess::ProcessError)));
    QStringList args;
    args << QLatin1String("--notrelocatable");
    if (plugin.importUri.isEmpty()) {
        args << QLatin1String("--path");
        args << plugin.importPath;
        if (ComponentVersion(plugin.importVersion).isValid())
            args << plugin.importVersion;
    } else {
        args << plugin.importUri;
        args << plugin.importVersion;
        args << plugin.importPath;
    }
    process->start(info.qmlDumpPath, args);
    m_runningQmldumps.insert(process, plugin.qmldirPath);
}

/*!
  Returns the result of the merge of \a baseName with \a path, \a suffixes, and \a prefix.
  The \a prefix must contain the dot.

  \a qmldirPath is the location of the qmldir file.

  Adapted from QDeclarativeImportDatabase::resolvePlugin.
*/
QString PluginDumper::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
                                    const QString &baseName, const QStringList &suffixes,
                                    const QString &prefix)
{
    QStringList searchPaths;
    searchPaths.append(QLatin1String("."));

    bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath);
    if (!qmldirPluginPathIsRelative)
        searchPaths.prepend(qmldirPluginPath);

    foreach (const QString &pluginPath, searchPaths) {

        QString resolvedPath;

        if (pluginPath == QLatin1String(".")) {
            if (qmldirPluginPathIsRelative)
                resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath);
            else
                resolvedPath = qmldirPath.absolutePath();
        } else {
            resolvedPath = pluginPath;
        }

        QDir dir(resolvedPath);
        foreach (const QString &suffix, suffixes) {
            QString pluginFileName = prefix;

            pluginFileName += baseName;
            pluginFileName += suffix;

            QFileInfo fileInfo(dir, pluginFileName);

            if (fileInfo.exists())
                return fileInfo.absoluteFilePath();
        }
    }

    return QString();
}

/*!
  Returns the result of the merge of \a baseName with \a dir and the platform suffix.

  Adapted from QDeclarativeImportDatabase::resolvePlugin.

  \table
  \header \i Platform \i Valid suffixes
  \row \i Windows     \i \c .dll
  \row \i Unix/Linux  \i \c .so
  \row \i AIX  \i \c .a
  \row \i HP-UX       \i \c .sl, \c .so (HP-UXi)
  \row \i Mac OS X    \i \c .dylib, \c .bundle, \c .so
  \row \i Symbian     \i \c .dll
  \endtable

  Version number on unix are ignored.
*/
QString PluginDumper::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
                                    const QString &baseName)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
                         QStringList()
                         << QLatin1String("d.dll") // try a qmake-style debug build first
                         << QLatin1String(".dll"));
#elif defined(Q_OS_DARWIN)
    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
                         QStringList()
                         << QLatin1String("_debug.dylib") // try a qmake-style debug build first
                         << QLatin1String(".dylib")
                         << QLatin1String(".so")
                         << QLatin1String(".bundle"),
                         QLatin1String("lib"));
#else  // Generic Unix
    QStringList validSuffixList;

#  if defined(Q_OS_HPUX)
/*
    See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF":
    "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit),
    the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix."
 */
    validSuffixList << QLatin1String(".sl");
#   if defined __ia64
    validSuffixList << QLatin1String(".so");
#   endif
#  elif defined(Q_OS_AIX)
    validSuffixList << QLatin1String(".a") << QLatin1String(".so");
#  elif defined(Q_OS_UNIX)
    validSuffixList << QLatin1String(".so");
#  endif

    // Examples of valid library names:
    //  libfoo.so

    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
#endif
}

bool PluginDumper::Plugin::hasPredumpedQmlTypesFile() const
{
    return QFileInfo(predumpedQmlTypesFilePath()).isFile();
}

QString PluginDumper::Plugin::predumpedQmlTypesFilePath() const
{
    return QString("%1%2plugins.qmltypes").arg(qmldirPath, QDir::separator());
}
<commit_msg>QmlJSEditor: Don't warn about failing dumps if dumper is from 2.1<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "qmljsplugindumper.h"
#include "qmljsmodelmanager.h"

#include <qmljs/qmljsdocument.h>
#include <qmljs/qmljsinterpreter.h>
#include <projectexplorer/filewatcher.h>
#include <projectexplorer/projectexplorer.h>
#include <coreplugin/messagemanager.h>

#include <QtCore/QDir>

using namespace LanguageUtils;
using namespace QmlJS;
using namespace QmlJSTools;
using namespace QmlJSTools::Internal;

PluginDumper::PluginDumper(ModelManager *modelManager)
    : QObject(modelManager)
    , m_modelManager(modelManager)
    , m_pluginWatcher(new ProjectExplorer::FileWatcher(this))
{
    connect(m_pluginWatcher, SIGNAL(fileChanged(QString)), SLOT(pluginChanged(QString)));
}

void PluginDumper::loadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion)
{
    // move to the owning thread
    metaObject()->invokeMethod(this, "onLoadPluginTypes",
                               Q_ARG(QString, libraryPath),
                               Q_ARG(QString, importPath),
                               Q_ARG(QString, importUri),
                               Q_ARG(QString, importVersion));
}

void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion)
{
    const QString canonicalLibraryPath = QDir::cleanPath(libraryPath);
    if (m_runningQmldumps.values().contains(canonicalLibraryPath))
        return;
    const Snapshot snapshot = m_modelManager->snapshot();
    const LibraryInfo libraryInfo = snapshot.libraryInfo(canonicalLibraryPath);
    if (libraryInfo.dumpStatus() != LibraryInfo::DumpNotStartedOrRunning)
        return;

    // avoid inserting the same plugin twice
    int index;
    for (index = 0; index < m_plugins.size(); ++index) {
        if (m_plugins.at(index).qmldirPath == libraryPath)
            break;
    }
    if (index == m_plugins.size())
        m_plugins.append(Plugin());

    Plugin &plugin = m_plugins[index];
    plugin.qmldirPath = canonicalLibraryPath;
    plugin.importPath = importPath;
    plugin.importUri = importUri;
    plugin.importVersion = importVersion;

    // watch plugin libraries
    foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) {
        const QString pluginLibrary = resolvePlugin(canonicalLibraryPath, plugin.path, plugin.name);
        m_pluginWatcher->addFile(pluginLibrary);
        m_libraryToPluginIndex.insert(pluginLibrary, index);
    }

    // watch library xml file
    if (plugin.hasPredumpedQmlTypesFile()) {
        const QString &path = plugin.predumpedQmlTypesFilePath();
        m_pluginWatcher->addFile(path);
        m_libraryToPluginIndex.insert(path, index);
    }

    dump(plugin);
}

void PluginDumper::scheduleCompleteRedump()
{
    metaObject()->invokeMethod(this, "dumpAllPlugins", Qt::QueuedConnection);
}

void PluginDumper::dumpAllPlugins()
{
    foreach (const Plugin &plugin, m_plugins)
        dump(plugin);
}

static QString qmldumpErrorMessage(const QString &libraryPath, const QString &error)
{
    return PluginDumper::tr("Type dump of QML plugin in %1 failed.\nErrors:\n%2\n").
           arg(libraryPath, error);
}

static QString qmldumpFailedMessage(const QString &error)
{
    QString firstLines =
            QStringList(error.split(QLatin1Char('\n')).mid(0, 10)).join(QLatin1String("\n"));
    return PluginDumper::tr("Type dump of C++ plugin failed.\n"
                            "First 10 lines or errors:\n"
                            "\n"
                            "%1"
                            "\n"
                            "Check 'General Messages' output pane for details."
                            ).arg(firstLines);
}

static QList<FakeMetaObject::ConstPtr> parseHelper(const QByteArray &qmlTypeDescriptions, QString *error)
{
    QList<FakeMetaObject::ConstPtr> ret;
    QHash<QString, FakeMetaObject::ConstPtr> newObjects;
    *error = Interpreter::CppQmlTypesLoader::parseQmlTypeDescriptions(qmlTypeDescriptions, &newObjects);

    if (error->isEmpty()) {
        ret = newObjects.values();
    }
    return ret;
}

void PluginDumper::qmlPluginTypeDumpDone(int exitCode)
{
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (!process)
        return;
    process->deleteLater();

    const QString libraryPath = m_runningQmldumps.take(process);
    const Snapshot snapshot = m_modelManager->snapshot();
    LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath);

    if (exitCode != 0) {
        Core::MessageManager *messageManager = Core::MessageManager::instance();
        const QString errorMessages = process->readAllStandardError();
        messageManager->printToOutputPane(qmldumpErrorMessage(libraryPath, errorMessages));

        if (errorMessages.contains(QLatin1String("Usage: qmldump [plugin/import/path plugin.uri]"))) {
            // outdated qmldump from 2.1.
            // TODO: Show a warning that qmldump should be recompiled.
            libraryInfo.setDumpStatus(LibraryInfo::DumpDone);
            if (!libraryPath.isEmpty())
                m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
            return;
        } else {
            libraryInfo.setDumpStatus(LibraryInfo::DumpError, qmldumpFailedMessage(errorMessages));
        }
    }

    const QByteArray output = process->readAllStandardOutput();
    QString error;
    QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(output, &error);
    if (exitCode == 0 && !error.isEmpty()) {
        libraryInfo.setDumpStatus(LibraryInfo::DumpError, tr("Type dump of C++ plugin failed. Parse error:\n'%1'").arg(error));
    }

    if (exitCode == 0 && error.isEmpty()) {
        libraryInfo.setMetaObjects(objectsList);
// ### disabled code path for running qmldump to get Qt's builtins
//        if (libraryPath.isEmpty())
//            Interpreter::CppQmlTypesLoader::builtinObjects.append(objectsList);
        libraryInfo.setDumpStatus(LibraryInfo::DumpDone);
    }

    if (!libraryPath.isEmpty())
        m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
}

void PluginDumper::qmlPluginTypeDumpError(QProcess::ProcessError)
{
    QProcess *process = qobject_cast<QProcess *>(sender());
    if (!process)
        return;
    process->deleteLater();

    const QString libraryPath = m_runningQmldumps.take(process);

    Core::MessageManager *messageManager = Core::MessageManager::instance();
    const QString errorMessages = process->readAllStandardError();
    messageManager->printToOutputPane(qmldumpErrorMessage(libraryPath, errorMessages));

    if (!libraryPath.isEmpty()) {
        const Snapshot snapshot = m_modelManager->snapshot();
        LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath);
        libraryInfo.setDumpStatus(LibraryInfo::DumpError, qmldumpFailedMessage(errorMessages));
        m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
    }
}

void PluginDumper::pluginChanged(const QString &pluginLibrary)
{
    const int pluginIndex = m_libraryToPluginIndex.value(pluginLibrary, -1);
    if (pluginIndex == -1)
        return;

    const Plugin &plugin = m_plugins.at(pluginIndex);
    dump(plugin);
}

void PluginDumper::dump(const Plugin &plugin)
{
    if (plugin.hasPredumpedQmlTypesFile()) {
        const Snapshot snapshot = m_modelManager->snapshot();
        LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath);
        if (!libraryInfo.isValid())
            return;

        const QString &path = plugin.predumpedQmlTypesFilePath();
        QFile libraryQmlTypesFile(path);
        if (!libraryQmlTypesFile.open(QFile::ReadOnly | QFile::Text)) {
            libraryInfo.setDumpStatus(LibraryInfo::DumpError,
                                      tr("Could not open file '%1' for reading.").arg(path));
            m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
            return;
        }

        const QByteArray qmlTypeDescriptions = libraryQmlTypesFile.readAll();
        libraryQmlTypesFile.close();

        QString error;
        const QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(qmlTypeDescriptions, &error);

        if (error.isEmpty()) {
            libraryInfo.setMetaObjects(objectsList);
            libraryInfo.setDumpStatus(LibraryInfo::DumpDone);
        } else {
            libraryInfo.setDumpStatus(LibraryInfo::DumpError,
                                      tr("Failed to parse '%1'.\nError: %2").arg(path, error));
        }
        m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
        return;
    }

    ProjectExplorer::Project *activeProject = ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject();
    if (!activeProject)
        return;

    ModelManagerInterface::ProjectInfo info = m_modelManager->projectInfo(activeProject);

    if (info.qmlDumpPath.isEmpty()) {
        const Snapshot snapshot = m_modelManager->snapshot();
        LibraryInfo libraryInfo = snapshot.libraryInfo(plugin.qmldirPath);
        if (!libraryInfo.isValid())
            return;

        libraryInfo.setDumpStatus(LibraryInfo::DumpError,
                                  tr("Could not locate the helper application for dumping type information from C++ plugins.\n"
                                     "Please build the debugging helpers on the Qt version options page."));
        m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
        return;
    }

    QProcess *process = new QProcess(this);
    process->setEnvironment(info.qmlDumpEnvironment.toStringList());
    connect(process, SIGNAL(finished(int)), SLOT(qmlPluginTypeDumpDone(int)));
    connect(process, SIGNAL(error(QProcess::ProcessError)), SLOT(qmlPluginTypeDumpError(QProcess::ProcessError)));
    QStringList args;
    args << QLatin1String("--notrelocatable");
    if (plugin.importUri.isEmpty()) {
        args << QLatin1String("--path");
        args << plugin.importPath;
        if (ComponentVersion(plugin.importVersion).isValid())
            args << plugin.importVersion;
    } else {
        args << plugin.importUri;
        args << plugin.importVersion;
        args << plugin.importPath;
    }
    process->start(info.qmlDumpPath, args);
    m_runningQmldumps.insert(process, plugin.qmldirPath);
}

/*!
  Returns the result of the merge of \a baseName with \a path, \a suffixes, and \a prefix.
  The \a prefix must contain the dot.

  \a qmldirPath is the location of the qmldir file.

  Adapted from QDeclarativeImportDatabase::resolvePlugin.
*/
QString PluginDumper::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
                                    const QString &baseName, const QStringList &suffixes,
                                    const QString &prefix)
{
    QStringList searchPaths;
    searchPaths.append(QLatin1String("."));

    bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath);
    if (!qmldirPluginPathIsRelative)
        searchPaths.prepend(qmldirPluginPath);

    foreach (const QString &pluginPath, searchPaths) {

        QString resolvedPath;

        if (pluginPath == QLatin1String(".")) {
            if (qmldirPluginPathIsRelative)
                resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath);
            else
                resolvedPath = qmldirPath.absolutePath();
        } else {
            resolvedPath = pluginPath;
        }

        QDir dir(resolvedPath);
        foreach (const QString &suffix, suffixes) {
            QString pluginFileName = prefix;

            pluginFileName += baseName;
            pluginFileName += suffix;

            QFileInfo fileInfo(dir, pluginFileName);

            if (fileInfo.exists())
                return fileInfo.absoluteFilePath();
        }
    }

    return QString();
}

/*!
  Returns the result of the merge of \a baseName with \a dir and the platform suffix.

  Adapted from QDeclarativeImportDatabase::resolvePlugin.

  \table
  \header \i Platform \i Valid suffixes
  \row \i Windows     \i \c .dll
  \row \i Unix/Linux  \i \c .so
  \row \i AIX  \i \c .a
  \row \i HP-UX       \i \c .sl, \c .so (HP-UXi)
  \row \i Mac OS X    \i \c .dylib, \c .bundle, \c .so
  \row \i Symbian     \i \c .dll
  \endtable

  Version number on unix are ignored.
*/
QString PluginDumper::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
                                    const QString &baseName)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
                         QStringList()
                         << QLatin1String("d.dll") // try a qmake-style debug build first
                         << QLatin1String(".dll"));
#elif defined(Q_OS_DARWIN)
    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
                         QStringList()
                         << QLatin1String("_debug.dylib") // try a qmake-style debug build first
                         << QLatin1String(".dylib")
                         << QLatin1String(".so")
                         << QLatin1String(".bundle"),
                         QLatin1String("lib"));
#else  // Generic Unix
    QStringList validSuffixList;

#  if defined(Q_OS_HPUX)
/*
    See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF":
    "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit),
    the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix."
 */
    validSuffixList << QLatin1String(".sl");
#   if defined __ia64
    validSuffixList << QLatin1String(".so");
#   endif
#  elif defined(Q_OS_AIX)
    validSuffixList << QLatin1String(".a") << QLatin1String(".so");
#  elif defined(Q_OS_UNIX)
    validSuffixList << QLatin1String(".so");
#  endif

    // Examples of valid library names:
    //  libfoo.so

    return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
#endif
}

bool PluginDumper::Plugin::hasPredumpedQmlTypesFile() const
{
    return QFileInfo(predumpedQmlTypesFilePath()).isFile();
}

QString PluginDumper::Plugin::predumpedQmlTypesFilePath() const
{
    return QString("%1%2plugins.qmltypes").arg(qmldirPath, QDir::separator());
}
<|endoftext|>


<commit_before>// -*- mode:c++; indent-tabs-mode:nil; -*-

/*
  Copyright (c) 2014, 2015, Anders Ronnbrant, anders.ronnbrant@gmail.com

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*/

#include "RecorderSink.h"
#include "RecorderBase.h"

#include "zmqutils.h"

#include <zmq.hpp>

#include <chrono>
#include <map>

typedef std::chrono::milliseconds msec;
typedef std::chrono::microseconds usec;

RecorderSink::RecorderSink()
    : RecorderBase("Backend") {
}

RecorderSink::~RecorderSink() {
  if (poller_running_.load()) {
    stop();
  }
}

void
RecorderSink::start(bool verbose) {
  verbose_mode_.store(verbose);
  poller_running_.store(true);
  poller_thread_ = std::thread(&RecorderSink::run, this);
}

void
RecorderSink::stop() {
  poller_running_.store(false);
  if (poller_thread_.joinable()) {
    poller_thread_.join();
  }
}

void
RecorderSink::run() {
  zmq::socket_t sock(*RecorderBase::socket_context, ZMQ_PULL);
  int constexpr recvhvm = 16000;
  sock.setsockopt(ZMQ_RCVHWM, &recvhvm, sizeof(recvhvm));
  zmqutils::bind(&sock, RecorderBase::socket_address.c_str());

  zmq::message_t zmsg;
  bool messages_to_process = true;
  std::array<int32_t, 4096> counter;
  counter.fill(0);
  int64_t count = 0;
  zmq_pollitem_t pollitems[] = { { sock, 0, ZMQ_POLLIN, 0 } };

  auto t1 = std::chrono::high_resolution_clock::now();

  while (poller_running_.load() || messages_to_process) {
    if (!zmqutils::poll(pollitems)) {
      messages_to_process = false;
      continue;
    }

    auto type = zmqutils::pop<PayloadType>(&sock, &zmsg);

    switch (type) {
      case PayloadType::DATA: {
        auto rcid = zmqutils::pop<int16_t>(&sock, &zmsg);
        sock.recv(&zmsg);
        auto const num_params = zmsg.size() / sizeof(Item);
        count += num_params;
        counter[rcid] += num_params;
        //for (size_t i = 0; i < num_params; ++i) {
        //  auto* item = static_cast<Item*>(zmsg.data()) + i;
        //  int32_t length = item->length;
        //}
      } break;;
      case PayloadType::INIT_ITEM: {
        auto init = zmqutils::pop<InitItem>(&sock, &zmsg);
        if (verbose_mode_.load()) {
          printf("(ITEM): %4d-%d '%s' '%s'\n",
                 init.recorder_id,
                 init.key,
                 init.name,
                 init.desc);
        }
      } break;;
      case PayloadType::INIT_RECORDER: {
        auto const pkg = zmqutils::pop<InitRecorder>(&sock, &zmsg);
        if (verbose_mode_.load()) {
          printf("(REC):  %4d(%ld) L%d '%s'\n",
                 pkg.recorder_id,
                 pkg.external_id,
                 pkg.recorder_num_items,
                 pkg.recorder_name);
        }
      } break;;
      default:
        break;;
    }

    size_t idx = 0;
    while (idx < (zmsg.size()/sizeof(Item))) {
      ++idx;
    }
  }
  sock.close();

  auto const mib = 1<<20;

  auto t2 = std::chrono::high_resolution_clock::now();
  auto duration = std::chrono::duration_cast<usec>(t2 - t1);
  double duration_msec = duration.count()/1000.0;
  printf("Messages:     %ld (%.3fms)\n", count, duration_msec);
  printf("Messages/sec: %.1f (%.1fMiB/sec)\n",
         count * 1000 / duration_msec,
         sizeof(Item) * count * 1000 / (mib * duration_msec));

  for (size_t i = 0; i < counter.max_size(); ++i) {
    if (counter[i] == 0) {
      continue;
    }
    printf("(RECV): %2lu:%d\n", i, counter[i]);
  }
}
<commit_msg>Count total number of messages received<commit_after>// -*- mode:c++; indent-tabs-mode:nil; -*-

/*
  Copyright (c) 2014, 2015, Anders Ronnbrant, anders.ronnbrant@gmail.com

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*/

#include "RecorderSink.h"
#include "RecorderBase.h"

#include "zmqutils.h"

#include <zmq.hpp>

#include <chrono>
#include <map>

typedef std::chrono::milliseconds msec;
typedef std::chrono::microseconds usec;

RecorderSink::RecorderSink()
    : RecorderBase("Backend") {
}

RecorderSink::~RecorderSink() {
  if (poller_running_.load()) {
    stop();
  }
}

void
RecorderSink::start(bool verbose) {
  verbose_mode_.store(verbose);
  poller_running_.store(true);
  poller_thread_ = std::thread(&RecorderSink::run, this);
}

void
RecorderSink::stop() {
  poller_running_.store(false);
  if (poller_thread_.joinable()) {
    poller_thread_.join();
  }
}

void
RecorderSink::run() {
  zmq::socket_t sock(*RecorderBase::socket_context, ZMQ_PULL);
  int constexpr recvhvm = 16000;
  sock.setsockopt(ZMQ_RCVHWM, &recvhvm, sizeof(recvhvm));
  zmqutils::bind(&sock, RecorderBase::socket_address.c_str());

  zmq::message_t zmsg;
  bool messages_to_process = true;
  std::array<int32_t, 4096> counter;
  counter.fill(0);
  int64_t count = 0;
  zmq_pollitem_t pollitems[] = { { sock, 0, ZMQ_POLLIN, 0 } };

  auto t1 = std::chrono::high_resolution_clock::now();

  while (poller_running_.load() || messages_to_process) {
    if (!zmqutils::poll(pollitems)) {
      messages_to_process = false;
      continue;
    }

    auto type = zmqutils::pop<PayloadType>(&sock, &zmsg);

    switch (type) {
      case PayloadType::DATA: {
        auto rcid = zmqutils::pop<int16_t>(&sock, &zmsg);
        sock.recv(&zmsg);
        auto const num_params = zmsg.size() / sizeof(Item);
        count += num_params;
        counter[rcid] += num_params;
        //for (size_t i = 0; i < num_params; ++i) {
        //  auto* item = static_cast<Item*>(zmsg.data()) + i;
        //  int32_t length = item->length;
        //}
      } break;;
      case PayloadType::INIT_ITEM: {
        auto init = zmqutils::pop<InitItem>(&sock, &zmsg);
        if (verbose_mode_.load()) {
          printf("(ITEM): %4d-%d '%s' '%s'\n",
                 init.recorder_id,
                 init.key,
                 init.name,
                 init.desc);
        }
      } break;;
      case PayloadType::INIT_RECORDER: {
        auto const pkg = zmqutils::pop<InitRecorder>(&sock, &zmsg);
        if (verbose_mode_.load()) {
          printf("(REC):  %4d(%ld) L%d '%s'\n",
                 pkg.recorder_id,
                 pkg.external_id,
                 pkg.recorder_num_items,
                 pkg.recorder_name);
        }
      } break;;
      default:
        break;;
    }

    size_t idx = 0;
    while (idx < (zmsg.size()/sizeof(Item))) {
      ++idx;
    }
  }
  sock.close();

  auto const mib = 1<<20;

  auto t2 = std::chrono::high_resolution_clock::now();
  auto duration = std::chrono::duration_cast<usec>(t2 - t1);
  double duration_msec = duration.count()/1000.0;
  printf("Messages:     %ld (%.3fms)\n", count, duration_msec);
  printf("Messages/sec: %.1f (%.1fMiB/sec)\n",
         count * 1000 / duration_msec,
         sizeof(Item) * count * 1000 / (mib * duration_msec));

  int total = 0;
  for (size_t i = 0; i < counter.max_size(); ++i) {
    if (counter[i] == 0) {
      continue;
    }
    printf("(RECV): %2lu:%d\n", i, counter[i]);
    total += counter[i];
  }
  printf("(RECV): %d\n", total);
}
<|endoftext|>


<commit_before>/************************************************************************************\
This source file is part of the Awesome Portable Rendering Interface Library         *
For latest info, see http://libapril.sourceforge.net/                                *
**************************************************************************************
Copyright (c) 2010 Kresimir Spes (kreso@cateia.com),                                 *
                     Ivan Vucica (ivan@vucica.net)                                   *
*                                                                                *
* This program is free software; you can redistribute it and/or modify it under      *
* the terms of the BSD license: http://www.opensource.org/licenses/bsd-license.php   *
\************************************************************************************/
#include <stdio.h>
#include <algorithm>

#ifdef USE_IL
#include <IL/il.h>
#endif

#include "RenderSystem.h"
#ifdef _OPENGL
#include "RenderSystem_GL.h"
#else
#include "RenderSystem_DirectX9.h"
#endif
#include "ImageSource.h"

April::RenderSystem* rendersys;

namespace April
{
	void april_writelog(chstr message)
	{
		printf("%s\n",message.c_str());
	}

	void (*g_logFunction)(chstr)=april_writelog;

	int hexstr_to_int(chstr s)
	{
		int i;
		sscanf(s.c_str(),"%x",&i);
		return i;
	}

	void hexstr_to_argb(chstr hex,unsigned char* a,unsigned char* r,unsigned char* g,unsigned char* b)
	{
		hstr value = hex;
		if (value(0,2) != "0x") value="0x"+value;
		if (value.size() == 8)
		{
			*r=hexstr_to_int(value(2,2));
			*g=hexstr_to_int(value(4,2));
			*b=hexstr_to_int(value(6,2));
			*a=255;
		}
		else if (value.size() == 10)
		{
			*a=hexstr_to_int(value(2,2));
			*r=hexstr_to_int(value(4,2));
			*g=hexstr_to_int(value(6,2));
			*b=hexstr_to_int(value(8,2));
		}
		else throw "Color format must be either 0xAARRGGBB or 0xRRGGBB";
	}
/*****************************************************************************************/
	void PlainVertex::operator=(const gtypes::Vector3& v)
	{
		this->x=v.x;
		this->y=v.y;
		this->z=v.z;
	}
/*****************************************************************************************/
	Color::Color(float a,float r,float g,float b)
	{
		setColor(a,r,g,b);
	}

	Color::Color(unsigned int color)
	{
		setColor(color);
	}

	Color::Color(chstr hex)
	{
		setColor(hex);
	}

	Color::Color()
	{
		a=r=g=b=255;
	}

	void Color::setColor(float a,float r,float g,float b)
	{
		this->a=(unsigned char)(a*255); this->r=(unsigned char)(r*255);
		this->g=(unsigned char)(g*255); this->b=(unsigned char)(b*255);
	}

	void Color::setColor(unsigned int color)
	{
		this->a=color/256/256/256; this->r=color/256/256%256; this->g=color/256%256; this->b=color%256;
	}

	void Color::setColor(chstr hex)
	{
		// this is going to bite me in the arse on a little endian system...
		hexstr_to_argb(hex,&a,&r,&g,&b);
	}
/*****************************************************************************************/
	Texture::Texture()
	{
		mFilename="";
		mUnusedTimer=0;
	}

	Texture::~Texture()
	{
		for (Texture** it=mDynamicLinks.iter();it;it=mDynamicLinks.next())
			(*it)->removeDynamicLink(this);
	}

	Color Texture::getPixel(int x,int y)
	{
		return Color(0,0,0,0);
	}

	Color Texture::getInterpolatedPixel(float x,float y)
	{
		return Color(0,0,0,0);
	}

	void Texture::update(float time_increase)
	{
		if (mDynamic && isLoaded())
		{
			float max_time=rendersys->getIdleTextureUnloadTime();
			if (max_time > 0)
			{
				if (mUnusedTimer > max_time) unload();
				mUnusedTimer+=time_increase;
			}
		}
	}

	void Texture::addDynamicLink(Texture* lnk)
	{
		if (mDynamicLinks.contains(lnk)) return;
		mDynamicLinks+=lnk;
		lnk->addDynamicLink(this);
	}

	void Texture::removeDynamicLink(Texture* lnk)
	{
		if (mDynamicLinks.contains(lnk))
			mDynamicLinks-=lnk;
	}

	void  Texture::_resetUnusedTimer(bool recursive)
	{
		mUnusedTimer=0;
		if (recursive)
		{
			for (Texture** it=mDynamicLinks.iter();it;it=mDynamicLinks.next())
				(*it)->_resetUnusedTimer(0);
		}
	}
/*****************************************************************************************/
	RAMTexture::RAMTexture(chstr filename,bool dynamic)
	{
		mFilename=filename;
		mBuffer=0;
		if (!dynamic) load();
	}

	RAMTexture::~RAMTexture()
	{
		unload();
	}

	void RAMTexture::load()
	{
		if (!mBuffer)
		{
			rendersys->logMessage("loading RAM texture '"+mFilename+"'");
			mBuffer=loadImage(mFilename);
			mWidth=mBuffer->w;
			mHeight=mBuffer->h;
		}
	}

	void RAMTexture::unload()
	{
		if (mBuffer)
		{
			rendersys->logMessage("unloading RAM texture '"+mFilename+"'");
			delete mBuffer;
			mBuffer=0;
		}
	}

	bool RAMTexture::isLoaded()
	{
		return mBuffer != 0;
	}

	Color RAMTexture::getPixel(int x,int y)
	{
		if (!mBuffer) load();
		mUnusedTimer=0;
		return mBuffer->getPixel(x,y);
	}

	Color RAMTexture::getInterpolatedPixel(float x,float y)
	{
		if (!mBuffer) load();
		mUnusedTimer=0;
		return mBuffer->getInterpolatedPixel(x,y);
	}

	int RAMTexture::getSizeInBytes()
	{
		return 0;
	}
/*****************************************************************************************/
	RenderSystem::RenderSystem()
	{
		mAlphaMultiplier=1.0f;
		mUpdateCallback=0;
		mMouseDownCallback=0;
		mMouseUpCallback=0;
		mMouseMoveCallback=0;
		mKeyDownCallback=0;
		mKeyUpCallback=0;
		mCharCallback=0;
		mQuitCallback=0;
		mDynamicLoading=0;
		mIdleUnloadTime=0;
	}

	RenderSystem::~RenderSystem()
	{

	}

	void RenderSystem::drawColoredQuad(float x,float y,float w,float h,float r,float g,float b,float a)
	{
		PlainVertex v[4];
		v[0].x=x;   v[0].y=y;   v[0].z=0;
		v[1].x=x+w; v[1].y=y;   v[1].z=0;
		v[2].x=x;   v[2].y=y+h; v[2].z=0;
		v[3].x=x+w; v[3].y=y+h; v[3].z=0;

		render(TriangleStrip,v,4,r,g,b,a);
	}

	void RenderSystem::drawTexturedQuad(float x,float y,float w,float h,float sx,float sy,float sw,float sh)
	{
		TexturedVertex v[4];
		v[0].x=x;   v[0].y=y;   v[0].z=0; v[0].u=sx;    v[0].v=sy;
		v[1].x=x+w; v[1].y=y;   v[1].z=0; v[1].u=sx+sw; v[1].v=sy;
		v[2].x=x;   v[2].y=y+h; v[2].z=0; v[2].u=sx;    v[2].v=sy+sh;
		v[3].x=x+w; v[3].y=y+h; v[3].z=0; v[3].u=sx+sw; v[3].v=sy+sh;

		render(TriangleStrip,v,4);
	}

	void RenderSystem::drawTexturedQuad(float x,float y,float w,float h,float sx,float sy,float sw,float sh,float r,float g,float b,float a)
	{
		TexturedVertex v[4];
		v[0].x=x;   v[0].y=y;   v[0].z=0; v[0].u=sx;    v[0].v=sy;
		v[1].x=x+w; v[1].y=y;   v[1].z=0; v[1].u=sx+sw; v[1].v=sy;
		v[2].x=x;   v[2].y=y+h; v[2].z=0; v[2].u=sx;    v[2].v=sy+sh;
		v[3].x=x+w; v[3].y=y+h; v[3].z=0; v[3].u=sx+sw; v[3].v=sy+sh;

		render(TriangleStrip,v,4,r,g,b,a);
	}

	void RenderSystem::logMessage(chstr message,chstr prefix)
	{
		g_logFunction(prefix+message);
	}

	void RenderSystem::registerUpdateCallback(bool (*callback)(float))
	{
		mUpdateCallback=callback;
	}

	void RenderSystem::registerMouseCallbacks(void (*mouse_dn)(float,float,int),
								              void (*mouse_up)(float,float,int),
								              void (*mouse_move)(float,float))
	{
			mMouseDownCallback=mouse_dn;
			mMouseUpCallback=mouse_up;
			mMouseMoveCallback=mouse_move;

	}
	void RenderSystem::registerKeyboardCallbacks(void (*key_dn)(unsigned int),
								                 void (*key_up)(unsigned int),
												 void (*char_callback)(unsigned int))
	{
		mKeyDownCallback=key_dn;
		mKeyUpCallback=key_up;
		mCharCallback=char_callback;
	}

	Texture* RenderSystem::loadRAMTexture(chstr filename,bool dynamic)
	{
		return new RAMTexture(filename,dynamic);
	}

	void RenderSystem::setIdentityTransform()
	{
		mModelviewMatrix.setIdentity();
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::translate(float x,float y,float z)
	{
		mModelviewMatrix.translate(x,y,z);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::rotate(float angle,float ax,float ay,float az)
	{
		mModelviewMatrix.rotate(ax,ay,az,angle);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::scale(float s)
	{
		mModelviewMatrix.scale(s);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::scale(float sx,float sy,float sz)
	{
		mModelviewMatrix.scale(sx,sy,sz);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::lookAt(const gtypes::Vector3 &eye, const gtypes::Vector3 &direction, const gtypes::Vector3 &up)
	{
		mModelviewMatrix.lookAt(eye,direction,up);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::setOrthoProjection(float w,float h,float x_offset,float y_offset)
	{
		float t=getPixelOffset(),wnd_w=getWindowWidth(),wnd_h=getWindowHeight();
		mProjectionMatrix.ortho(w,h,x_offset+t*w/wnd_w,y_offset+t*t/wnd_h);
		_setProjectionMatrix(mProjectionMatrix);
	}

    void RenderSystem::setPerspective(float fov, float aspect, float nearClip, float farClip)
	{
		mProjectionMatrix.perspective(fov,aspect,nearClip,farClip);
		_setProjectionMatrix(mProjectionMatrix);
	}

	void RenderSystem::setModelviewMatrix(const gtypes::Matrix4& matrix)
	{
		mModelviewMatrix=matrix;
		_setModelviewMatrix(matrix);
	}
	void RenderSystem::setProjectionMatrix(const gtypes::Matrix4& matrix)
	{
		mProjectionMatrix=matrix;
		_setProjectionMatrix(matrix);
	}

	const gtypes::Matrix4& RenderSystem::getModelviewMatrix()
	{
		return mModelviewMatrix;
	}

	const gtypes::Matrix4& RenderSystem::getProjectionMatrix()
	{
		return mProjectionMatrix;
	}
/*********************************************************************************/
	void init(chstr rendersystem_name,int w,int h,bool fullscreen,chstr title)
	{
		#ifdef USE_IL
			ilInit();
		#endif

		#ifdef _OPENGL
			createGLRenderSystem(w,h,fullscreen,title);
		#else
			createDX9RenderSystem(w,h,fullscreen,title);
		#endif
	}

	void setLogFunction(void (*fnptr)(chstr))
	{
		g_logFunction=fnptr;
	}

	void destroy()
	{
		delete rendersys;
	}

}
<commit_msg>- fixed glitch with setOrthoProjection<commit_after>/************************************************************************************\
This source file is part of the Awesome Portable Rendering Interface Library         *
For latest info, see http://libapril.sourceforge.net/                                *
**************************************************************************************
Copyright (c) 2010 Kresimir Spes (kreso@cateia.com),                                 *
                     Ivan Vucica (ivan@vucica.net)                                   *
*                                                                                *
* This program is free software; you can redistribute it and/or modify it under      *
* the terms of the BSD license: http://www.opensource.org/licenses/bsd-license.php   *
\************************************************************************************/
#include <stdio.h>
#include <algorithm>

#ifdef USE_IL
#include <IL/il.h>
#endif

#include "RenderSystem.h"
#ifdef _OPENGL
#include "RenderSystem_GL.h"
#else
#include "RenderSystem_DirectX9.h"
#endif
#include "ImageSource.h"

April::RenderSystem* rendersys;

namespace April
{
	void april_writelog(chstr message)
	{
		printf("%s\n",message.c_str());
	}

	void (*g_logFunction)(chstr)=april_writelog;

	int hexstr_to_int(chstr s)
	{
		int i;
		sscanf(s.c_str(),"%x",&i);
		return i;
	}

	void hexstr_to_argb(chstr hex,unsigned char* a,unsigned char* r,unsigned char* g,unsigned char* b)
	{
		hstr value = hex;
		if (value(0,2) != "0x") value="0x"+value;
		if (value.size() == 8)
		{
			*r=hexstr_to_int(value(2,2));
			*g=hexstr_to_int(value(4,2));
			*b=hexstr_to_int(value(6,2));
			*a=255;
		}
		else if (value.size() == 10)
		{
			*a=hexstr_to_int(value(2,2));
			*r=hexstr_to_int(value(4,2));
			*g=hexstr_to_int(value(6,2));
			*b=hexstr_to_int(value(8,2));
		}
		else throw "Color format must be either 0xAARRGGBB or 0xRRGGBB";
	}
/*****************************************************************************************/
	void PlainVertex::operator=(const gtypes::Vector3& v)
	{
		this->x=v.x;
		this->y=v.y;
		this->z=v.z;
	}
/*****************************************************************************************/
	Color::Color(float a,float r,float g,float b)
	{
		setColor(a,r,g,b);
	}

	Color::Color(unsigned int color)
	{
		setColor(color);
	}

	Color::Color(chstr hex)
	{
		setColor(hex);
	}

	Color::Color()
	{
		a=r=g=b=255;
	}

	void Color::setColor(float a,float r,float g,float b)
	{
		this->a=(unsigned char)(a*255); this->r=(unsigned char)(r*255);
		this->g=(unsigned char)(g*255); this->b=(unsigned char)(b*255);
	}

	void Color::setColor(unsigned int color)
	{
		this->a=color/256/256/256; this->r=color/256/256%256; this->g=color/256%256; this->b=color%256;
	}

	void Color::setColor(chstr hex)
	{
		// this is going to bite me in the arse on a little endian system...
		hexstr_to_argb(hex,&a,&r,&g,&b);
	}
/*****************************************************************************************/
	Texture::Texture()
	{
		mFilename="";
		mUnusedTimer=0;
	}

	Texture::~Texture()
	{
		for (Texture** it=mDynamicLinks.iter();it;it=mDynamicLinks.next())
			(*it)->removeDynamicLink(this);
	}

	Color Texture::getPixel(int x,int y)
	{
		return Color(0,0,0,0);
	}

	Color Texture::getInterpolatedPixel(float x,float y)
	{
		return Color(0,0,0,0);
	}

	void Texture::update(float time_increase)
	{
		if (mDynamic && isLoaded())
		{
			float max_time=rendersys->getIdleTextureUnloadTime();
			if (max_time > 0)
			{
				if (mUnusedTimer > max_time) unload();
				mUnusedTimer+=time_increase;
			}
		}
	}

	void Texture::addDynamicLink(Texture* lnk)
	{
		if (mDynamicLinks.contains(lnk)) return;
		mDynamicLinks+=lnk;
		lnk->addDynamicLink(this);
	}

	void Texture::removeDynamicLink(Texture* lnk)
	{
		if (mDynamicLinks.contains(lnk))
			mDynamicLinks-=lnk;
	}

	void  Texture::_resetUnusedTimer(bool recursive)
	{
		mUnusedTimer=0;
		if (recursive)
		{
			for (Texture** it=mDynamicLinks.iter();it;it=mDynamicLinks.next())
				(*it)->_resetUnusedTimer(0);
		}
	}
/*****************************************************************************************/
	RAMTexture::RAMTexture(chstr filename,bool dynamic)
	{
		mFilename=filename;
		mBuffer=0;
		if (!dynamic) load();
	}

	RAMTexture::~RAMTexture()
	{
		unload();
	}

	void RAMTexture::load()
	{
		if (!mBuffer)
		{
			rendersys->logMessage("loading RAM texture '"+mFilename+"'");
			mBuffer=loadImage(mFilename);
			mWidth=mBuffer->w;
			mHeight=mBuffer->h;
		}
	}

	void RAMTexture::unload()
	{
		if (mBuffer)
		{
			rendersys->logMessage("unloading RAM texture '"+mFilename+"'");
			delete mBuffer;
			mBuffer=0;
		}
	}

	bool RAMTexture::isLoaded()
	{
		return mBuffer != 0;
	}

	Color RAMTexture::getPixel(int x,int y)
	{
		if (!mBuffer) load();
		mUnusedTimer=0;
		return mBuffer->getPixel(x,y);
	}

	Color RAMTexture::getInterpolatedPixel(float x,float y)
	{
		if (!mBuffer) load();
		mUnusedTimer=0;
		return mBuffer->getInterpolatedPixel(x,y);
	}

	int RAMTexture::getSizeInBytes()
	{
		return 0;
	}
/*****************************************************************************************/
	RenderSystem::RenderSystem()
	{
		mAlphaMultiplier=1.0f;
		mUpdateCallback=0;
		mMouseDownCallback=0;
		mMouseUpCallback=0;
		mMouseMoveCallback=0;
		mKeyDownCallback=0;
		mKeyUpCallback=0;
		mCharCallback=0;
		mQuitCallback=0;
		mDynamicLoading=0;
		mIdleUnloadTime=0;
	}

	RenderSystem::~RenderSystem()
	{

	}

	void RenderSystem::drawColoredQuad(float x,float y,float w,float h,float r,float g,float b,float a)
	{
		PlainVertex v[4];
		v[0].x=x;   v[0].y=y;   v[0].z=0;
		v[1].x=x+w; v[1].y=y;   v[1].z=0;
		v[2].x=x;   v[2].y=y+h; v[2].z=0;
		v[3].x=x+w; v[3].y=y+h; v[3].z=0;

		render(TriangleStrip,v,4,r,g,b,a);
	}

	void RenderSystem::drawTexturedQuad(float x,float y,float w,float h,float sx,float sy,float sw,float sh)
	{
		TexturedVertex v[4];
		v[0].x=x;   v[0].y=y;   v[0].z=0; v[0].u=sx;    v[0].v=sy;
		v[1].x=x+w; v[1].y=y;   v[1].z=0; v[1].u=sx+sw; v[1].v=sy;
		v[2].x=x;   v[2].y=y+h; v[2].z=0; v[2].u=sx;    v[2].v=sy+sh;
		v[3].x=x+w; v[3].y=y+h; v[3].z=0; v[3].u=sx+sw; v[3].v=sy+sh;

		render(TriangleStrip,v,4);
	}

	void RenderSystem::drawTexturedQuad(float x,float y,float w,float h,float sx,float sy,float sw,float sh,float r,float g,float b,float a)
	{
		TexturedVertex v[4];
		v[0].x=x;   v[0].y=y;   v[0].z=0; v[0].u=sx;    v[0].v=sy;
		v[1].x=x+w; v[1].y=y;   v[1].z=0; v[1].u=sx+sw; v[1].v=sy;
		v[2].x=x;   v[2].y=y+h; v[2].z=0; v[2].u=sx;    v[2].v=sy+sh;
		v[3].x=x+w; v[3].y=y+h; v[3].z=0; v[3].u=sx+sw; v[3].v=sy+sh;

		render(TriangleStrip,v,4,r,g,b,a);
	}

	void RenderSystem::logMessage(chstr message,chstr prefix)
	{
		g_logFunction(prefix+message);
	}

	void RenderSystem::registerUpdateCallback(bool (*callback)(float))
	{
		mUpdateCallback=callback;
	}

	void RenderSystem::registerMouseCallbacks(void (*mouse_dn)(float,float,int),
								              void (*mouse_up)(float,float,int),
								              void (*mouse_move)(float,float))
	{
			mMouseDownCallback=mouse_dn;
			mMouseUpCallback=mouse_up;
			mMouseMoveCallback=mouse_move;

	}
	void RenderSystem::registerKeyboardCallbacks(void (*key_dn)(unsigned int),
								                 void (*key_up)(unsigned int),
												 void (*char_callback)(unsigned int))
	{
		mKeyDownCallback=key_dn;
		mKeyUpCallback=key_up;
		mCharCallback=char_callback;
	}

	Texture* RenderSystem::loadRAMTexture(chstr filename,bool dynamic)
	{
		return new RAMTexture(filename,dynamic);
	}

	void RenderSystem::setIdentityTransform()
	{
		mModelviewMatrix.setIdentity();
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::translate(float x,float y,float z)
	{
		mModelviewMatrix.translate(x,y,z);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::rotate(float angle,float ax,float ay,float az)
	{
		mModelviewMatrix.rotate(ax,ay,az,angle);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::scale(float s)
	{
		mModelviewMatrix.scale(s);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::scale(float sx,float sy,float sz)
	{
		mModelviewMatrix.scale(sx,sy,sz);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::lookAt(const gtypes::Vector3 &eye, const gtypes::Vector3 &direction, const gtypes::Vector3 &up)
	{
		mModelviewMatrix.lookAt(eye,direction,up);
		_setModelviewMatrix(mModelviewMatrix);
	}

	void RenderSystem::setOrthoProjection(float w,float h,float x_offset,float y_offset)
	{
		float t=getPixelOffset(),wnd_w=getWindowWidth(),wnd_h=getWindowHeight();
		mProjectionMatrix.ortho(w,h,x_offset+t*w/wnd_w,y_offset+t*h/wnd_h);
		_setProjectionMatrix(mProjectionMatrix);
	}

    void RenderSystem::setPerspective(float fov, float aspect, float nearClip, float farClip)
	{
		mProjectionMatrix.perspective(fov,aspect,nearClip,farClip);
		_setProjectionMatrix(mProjectionMatrix);
	}

	void RenderSystem::setModelviewMatrix(const gtypes::Matrix4& matrix)
	{
		mModelviewMatrix=matrix;
		_setModelviewMatrix(matrix);
	}
	void RenderSystem::setProjectionMatrix(const gtypes::Matrix4& matrix)
	{
		mProjectionMatrix=matrix;
		_setProjectionMatrix(matrix);
	}

	const gtypes::Matrix4& RenderSystem::getModelviewMatrix()
	{
		return mModelviewMatrix;
	}

	const gtypes::Matrix4& RenderSystem::getProjectionMatrix()
	{
		return mProjectionMatrix;
	}
/*********************************************************************************/
	void init(chstr rendersystem_name,int w,int h,bool fullscreen,chstr title)
	{
		#ifdef USE_IL
			ilInit();
		#endif

		#ifdef _OPENGL
			createGLRenderSystem(w,h,fullscreen,title);
		#else
			createDX9RenderSystem(w,h,fullscreen,title);
		#endif
	}

	void setLogFunction(void (*fnptr)(chstr))
	{
		g_logFunction=fnptr;
	}

	void destroy()
	{
		delete rendersys;
	}

}
<|endoftext|>


<commit_before>/*
 * SmoothFilter.cpp
 *
 *  Created on: Feb 21, 2013
 *      Author: link
 */

#include "SmoothFilter.hpp"
#include <cmath>
#include <algorithm>

#include<iostream>
using namespace std;

SmoothFilter::SmoothFilter(const double& maxDeviation,
        const double& deviantThreshold, const double &minLength,
        const double &maxLength) :
        _maxDeviation(maxDeviation), _deviantThreshold(
                deviantThreshold), _minLength(minLength), _maxLength(
                maxLength) {

}

SmoothFilter::SmoothFilter(const SmoothFilter &toCopy) :
        _maxDeviation(toCopy._maxDeviation), _deviantThreshold(
                toCopy._deviantThreshold), _minLength(
                toCopy._minLength), _maxLength(toCopy._maxLength) {

}

SmoothFilter::~SmoothFilter() {
    // TODO Auto-generated destructor stub
}

std::vector<std::list<cv::Point2f> > SmoothFilter::filterFeatures(
        const std::vector<std::list<cv::Point2f> >& features) {

    std::vector<bool> toKill(features.size());
    std::vector<std::list<cv::Point2f> > result(features);
    int counter = 0;
    for (int i = 0; i < toKill.size(); ++i) {
        if (3 > features[i].size()) {
            toKill[i] = false;
        } else {
            std::list<cv::Point2f>::const_iterator it = features[i].begin();
//			cerr<<"pre"<<endl;
            cv::Point2f first = *it;
            cv::Point2f second = *(++it);
            cv::Point2f third = *(++it);
//			cv::Vec2f v1 = third - second;
//			cv::Vec2f v2 = second - first;
//			cerr<<"in "<<acos(
//                    (v1[0] * v2[0] + v1[1] * v2[1])
//                            / (cv::norm(v1) + cv::norm(v2)))/CV_PI<<endl;

            double a = cv::norm(second - third);
            double b = cv::norm(first - second);
            double c = cv::norm(third - first);

//			cerr<<"in "<<acos((b*b+c*c-a*a)/(2*b*c))/CV_PI;

            if (a > _minLength && b > _minLength
                    && (_maxDeviation
                            < acos(
                                    (b * b + c * c - a * a)
                                            / (2 * b * c))
                            || _maxLength < a + b)) {
                toKill[i] = true;
                ++counter;
//				std::cerr<<"to kill "<<counter<<" "<<i<<std::endl;
            } else {
                toKill[i] = false;
            }
//			cerr<<"post"<<endl;
        }
    }

    if (_deviantThreshold >= counter/(double)features.size()) {
        for (unsigned int j = 0; j < toKill.size(); ++j) {
            if (toKill[j]) {
                // cerr << "bug in " << j << endl;
                result.erase(result.begin() + j);
                toKill.erase(toKill.begin() + j);
                --j;
                //  cerr << "bug out" << endl;
            }
        }
    }
    return result;
}

FeatureFilter *SmoothFilter::constructCopy() const {
    SmoothFilter *copy = new SmoothFilter(*this);
    return copy;
}

<commit_msg>Fixed stop conditions in SmoothFilter<commit_after>/*
 * SmoothFilter.cpp
 *
 *  Created on: Feb 21, 2013
 *      Author: link
 */

#include "SmoothFilter.hpp"
#include <cmath>
#include <algorithm>

#include<iostream>
using namespace std;

SmoothFilter::SmoothFilter(const double& maxDeviation,
        const double& deviantThreshold, const double &minLength,
        const double &maxLength) :
        _maxDeviation(maxDeviation), _deviantThreshold(
                deviantThreshold), _minLength(minLength), _maxLength(
                maxLength) {

}

SmoothFilter::SmoothFilter(const SmoothFilter &toCopy) :
        _maxDeviation(toCopy._maxDeviation), _deviantThreshold(
                toCopy._deviantThreshold), _minLength(
                toCopy._minLength), _maxLength(toCopy._maxLength) {

}

SmoothFilter::~SmoothFilter() {
    // TODO Auto-generated destructor stub
}

std::vector<std::list<cv::Point2f> > SmoothFilter::filterFeatures(
        const std::vector<std::list<cv::Point2f> >& features) {

    std::vector<bool> toKill(features.size());
    std::vector<std::list<cv::Point2f> > result(features);
    int counter = 0;
    for (unsigned int i = 0; i < toKill.size(); ++i) {
        if (3 > features[i].size()) {
            toKill[i] = false;
        } else {
            std::list<cv::Point2f>::const_iterator it =
                    features[i].begin();
//			cerr<<"pre"<<endl;
            cv::Point2f first = *it;
            cv::Point2f second = *(++it);
            cv::Point2f third = *(++it);
//			cv::Vec2f v1 = third - second;
//			cv::Vec2f v2 = second - first;
//			cerr<<"in "<<acos(
//                    (v1[0] * v2[0] + v1[1] * v2[1])
//                            / (cv::norm(v1) + cv::norm(v2)))/CV_PI<<endl;

            double a = cv::norm(second - third);
            double b = cv::norm(first - second);
            double c = cv::norm(third - first);

//			cerr<<"in "<<acos((b*b+c*c-a*a)/(2*b*c))/CV_PI;

            if (a > _minLength && b > _minLength
                    && (_maxDeviation
                            < acos(
                                    (b * b + c * c - a * a)
                                            / (2 * b * c))
                            || _maxLength < a + b)) {
                toKill[i] = true;
                ++counter;
//				std::cerr<<"to kill "<<counter<<" "<<i<<std::endl;
            } else {
                toKill[i] = false;
            }
//			cerr<<"post"<<endl;
        }
    }

    if (_deviantThreshold >= counter/(double)features.size()) {
        for (unsigned int j = 0; j < toKill.size(); ++j) {
            if (toKill[j]) {
                // cerr << "bug in " << j << endl;
                result.erase(result.begin() + j);
                toKill.erase(toKill.begin() + j);
                --j;
                //  cerr << "bug out" << endl;
            }
        }
    }
    return result;
}

FeatureFilter *SmoothFilter::constructCopy() const {
    SmoothFilter *copy = new SmoothFilter(*this);
    return copy;
}

<|endoftext|>


<commit_before>// $Id: NumericalSAS_test.C,v 1.4 2000/06/06 13:19:04 oliver Exp $
#include <BALL/CONCEPT/classTest.h>

///////////////////////////
#include <BALL/STRUCTURE/numericalSAS.h>
#include <BALL/KERNEL/fragment.h>
#include <BALL/MATHS/surface.h>
#include <BALL/DATATYPE/hashMap.h>
///////////////////////////

START_TEST(NumericalSAS, "$Id: NumericalSAS_test.C,v 1.4 2000/06/06 13:19:04 oliver Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;

CHECK(calculateSASArea(const	Composite&, float, int))
	Fragment	f;
	Atom a1, a2;
	a1.setRadius(1.0);
	a2.setRadius(1.0);
	a2.setPosition(Vector3(10.0, 0.0, 0.0));

	f.insert(a1);
	f.insert(a2);

	float area = calculateSASArea(f, 1.5, 624);

	PRECISION(0.001)
	TEST_REAL_EQUAL(area, 157.07963)
RESULT

CHECK(calculateSASAtomAreas())
	Fragment	f;
	Atom a1, a2;
	a1.setRadius(1.0);
	a2.setRadius(1.0);
	a2.setPosition(Vector3(10.0, 0.0, 0.0));

	f.insert(a1);
	f.insert(a2);

	HashMap<Atom*, float>	atom_map;

	float area = calculateSASAtomAreas(f, atom_map, 1.5, 624);

	PRECISION(0.001)
	TEST_REAL_EQUAL(area, 157.07963)
	TEST_REAL_EQUAL(atom_map[&a1], area / 2.0)
	TEST_REAL_EQUAL(atom_map[&a2], area / 2.0)
RESULT

CHECK(calculateSASPoints())
	Fragment	f;
	Atom a1, a2;
	a1.setRadius(1.0);
	a2.setRadius(1.0);
	a2.setPosition(Vector3(10.0, 0.0, 0.0));

	f.insert(a1);
	f.insert(a2);

	Surface surface;
	float area = calculateSASPoints(f, surface, 1.5, 624);

	PRECISION(0.001)
	TEST_REAL_EQUAL(area, 157.07963)
	TEST_EQUAL(surface.vertex.size(), 1284)
	TEST_EQUAL(surface.normal.size(), 1284)

	// sum up all normals to check for integrality of the
	// surface elements
	float surface_elements = 0;
	for (Position i = 0; i < surface.normal.size(); i++)
	{
		surface_elements += surface.normal[i].getLength();
	}
	TEST_REAL_EQUAL(surface_elements, area)
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<commit_msg>added: test for calculateSASVolume<commit_after>// $Id: NumericalSAS_test.C,v 1.5 2000/06/15 17:24:22 oliver Exp $
#include <BALL/CONCEPT/classTest.h>

///////////////////////////
#include <BALL/STRUCTURE/numericalSAS.h>
#include <BALL/KERNEL/fragment.h>
#include <BALL/MATHS/surface.h>
#include <BALL/DATATYPE/hashMap.h>
///////////////////////////

START_TEST(NumericalSAS, "$Id: NumericalSAS_test.C,v 1.5 2000/06/15 17:24:22 oliver Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;

CHECK(calculateSASArea(const BaseFragment&, float probe_radius, Size number_of_points))
	Fragment	f;
	Atom a1, a2;
	a1.setRadius(1.0);
	a2.setRadius(1.0);
	a2.setPosition(Vector3(10.0, 0.0, 0.0));

	f.insert(a1);
	f.insert(a2);

	float area = calculateSASArea(f, 1.5, 624);

	PRECISION(0.001)
	TEST_REAL_EQUAL(area, 157.07963)
RESULT

CHECK(calculateSASVolume(const BaseFragment&, float probe_radius, Size number_of_points))
	Fragment	f;
	Atom a1, a2;
	a1.setRadius(1.0);
	a2.setRadius(1.0);
	a2.setPosition(Vector3(10.0, 0.0, 0.0));

	f.insert(a1);
	f.insert(a2);

	float volume = calculateSASVolume(f, 1.5, 624);

	PRECISION(0.001)
	TEST_REAL_EQUAL(volume, 130.899)
RESULT

CHECK(calculateSASAtomAreas())
	Fragment	f;
	Atom a1, a2;
	a1.setRadius(1.0);
	a2.setRadius(1.0);
	a2.setPosition(Vector3(10.0, 0.0, 0.0));

	f.insert(a1);
	f.insert(a2);

	HashMap<Atom*, float>	atom_map;

	float area = calculateSASAtomAreas(f, atom_map, 1.5, 624);

	PRECISION(0.001)
	TEST_REAL_EQUAL(area, 157.07963)
	TEST_REAL_EQUAL(atom_map[&a1], area / 2.0)
	TEST_REAL_EQUAL(atom_map[&a2], area / 2.0)
RESULT

CHECK(calculateSASPoints())
	Fragment	f;
	Atom a1, a2;
	a1.setRadius(1.0);
	a2.setRadius(1.0);
	a2.setPosition(Vector3(10.0, 0.0, 0.0));

	f.insert(a1);
	f.insert(a2);

	Surface surface;
	float area = calculateSASPoints(f, surface, 1.5, 624);

	PRECISION(0.001)
	TEST_REAL_EQUAL(area, 157.07963)
	TEST_EQUAL(surface.vertex.size(), 1284)
	TEST_EQUAL(surface.normal.size(), 1284)

	// sum up all normals to check for integrality of the
	// surface elements
	float surface_elements = 0;
	for (Position i = 0; i < surface.normal.size(); i++)
	{
		surface_elements += surface.normal[i].getLength();
	}
	TEST_REAL_EQUAL(surface_elements, area)
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST
<|endoftext|>


<commit_before>#include "main.hpp"

#include "WebcamImageTransform.hpp"

void WebcamImageTransform::create(const graphics::ScreenRectBuffer *rectangle,
      uint32_t input_width, uint32_t input_height,
      uint32_t output_width, uint32_t output_height) {
  this->rectangle = rectangle;
  this->input_width = input_width;
  this->input_height = input_height;
  this->output_width = output_width;
  this->output_height = output_height;

  const auto overscan = ((float)input_width / input_height) / ((float)output_width / output_height);

  // column-major!!!
  transform = glm::mat3(-.95f, 0.f, 0.f,
                        0.f, -.95f * overscan, 0.f,
                        1.f, 1.f, 1.f);
  inverseTransform = glm::inverse(transform);

  static const char *vertexShaderSource = R"glsl(
    #version 330 core
    layout(location=0) in vec2 position;

    uniform mat3 transform;

    out vec2 texcoord;

    void main() {
      vec2 pixelTexcoord = position * .5 + .5;
      texcoord = vec2(transform * vec3(pixelTexcoord, 1.));
      gl_Position = vec4(position, 0., 1.);
    }
  )glsl";

  static const char *fragmentShaderSource = R"glsl(
    #version 330 core
    uniform sampler2D source;

    uniform vec3 imageParameters;

    in vec2 texcoord;

    out vec4 frag_color;

    const float PI = 3.14159265;

    vec3 rgb2hsv(vec3 rgb) {
      float cmin = min(rgb.r, min(rgb.g, rgb.b));
      float cmax = max(rgb.r, max(rgb.g, rgb.b));
      float d = cmax - cmin;
      float eps = 0.00001;
      if (d < eps || cmax < eps) {
        return vec3(0, 0, cmax);
      }

      float _h;
      if (cmax == rgb.r) {
        _h = (rgb.g - rgb.b) / d;
        if (_h < 0.) {
          _h += 6.;
        }
      } else if (cmax == rgb.g) {
        _h = ((rgb.b - rgb.r) / d) + 2.;
      } else {
        _h = ((rgb.r - rgb.g) / d) + 4.;
      }

      return vec3(_h * 60. * (PI / 180.), d / cmax, cmax);
    }

    vec3 hsv2rgb(vec3 hsv) {
      // rapidtables.com/convert/color/hsv-to-rgb.htm
      float _h = hsv.x * 180. / PI;
      float _c = hsv.y * hsv.z;
      float _x = _c * (1. - abs(mod(_h / 60., 2.) - 1.));
      float _m = hsv.z - _c;
      vec3 _r;
      if (/* 0. <= _h && */ _h < 60.) {
        _r.r = _c;
        _r.g = _x;
        _r.b = 0.;
      } else if (_h < 120.) {
        _r.r = _x;
        _r.g = _c;
        _r.b = 0.;
      } else if (_h < 180.) {
        _r.r = 0.;
        _r.g = _c;
        _r.b = _x;
      } else if (_h < 240.) {
        _r.r = 0.;
        _r.g = _x;
        _r.b = _c;
      } else if (_h < 300.) {
        _r.r = _x;
        _r.g = 0.;
        _r.b = _c;
      } else /* if (_h < 360.) */ {
        _r.r = _c;
        _r.g = 0.;
        _r.b = _x;
      }
      return _r + vec3(_m);
    }

    void main() {
      vec3 rgb = texture(source, texcoord).bgr;
      rgb = imageParameters[0] * rgb + imageParameters[1]; // increase overall brightness
      vec3 hsv = rgb2hsv(rgb);
      hsv.y = hsv.y * imageParameters[2]; // increase saturation
      rgb = clamp(hsv2rgb(hsv), 0., 1.);
      frag_color = vec4(rgb, 0.);
    }
  )glsl";

  pipeline.create(vertexShaderSource, fragmentShaderSource, graphics::Pipeline::BlendMode::None);

  pipeline_transform_location = pipeline.getUniformLocation("transform");
  pipeline_source_location = pipeline.getUniformLocation("source");
  pipeline_imageParameters_location = pipeline.getUniformLocation("imageParameters");
}

void WebcamImageTransform::destroy() {
  pipeline.destroy();
}

void WebcamImageTransform::draw(graphics::Texture &input, graphics::Framebuffer &output) {
  assert(input.getWidth() == input_width);
  assert(input.getHeight() == input_height);
  assert(output.getWidth() == output_width);
  assert(output.getHeight() == output_height);

  output.bind();
  glViewport(0, 0, output.getWidth(), output.getHeight());
  pipeline.bind();
  glUniformMatrix3fv(pipeline_transform_location, 1, GL_FALSE, &transform[0][0]);
  input.bind(0u);
  glUniform1i(pipeline_source_location, 0u);
  glUniform3f(pipeline_imageParameters_location, brightnessMul, brightnessAdd, saturation);
  rectangle->draw();
}
<commit_msg>Change visible webcam image area<commit_after>#include "main.hpp"

#include "WebcamImageTransform.hpp"

void WebcamImageTransform::create(const graphics::ScreenRectBuffer *rectangle,
      uint32_t input_width, uint32_t input_height,
      uint32_t output_width, uint32_t output_height) {
  this->rectangle = rectangle;
  this->input_width = input_width;
  this->input_height = input_height;
  this->output_width = output_width;
  this->output_height = output_height;

  const auto overscan = ((float)input_width / input_height) / ((float)output_width / output_height);

  // column-major!!!
  transform = glm::mat3(-.7f, 0.f, 0.f,
                        0.f, -.7f * overscan, 0.f,
                        1.f, .8f, 1.f);
  inverseTransform = glm::inverse(transform);

  static const char *vertexShaderSource = R"glsl(
    #version 330 core
    layout(location=0) in vec2 position;

    uniform mat3 transform;

    out vec2 texcoord;

    void main() {
      vec2 pixelTexcoord = position * .5 + .5;
      texcoord = vec2(transform * vec3(pixelTexcoord, 1.));
      gl_Position = vec4(position, 0., 1.);
    }
  )glsl";

  static const char *fragmentShaderSource = R"glsl(
    #version 330 core
    uniform sampler2D source;

    uniform vec3 imageParameters;

    in vec2 texcoord;

    out vec4 frag_color;

    const float PI = 3.14159265;

    vec3 rgb2hsv(vec3 rgb) {
      float cmin = min(rgb.r, min(rgb.g, rgb.b));
      float cmax = max(rgb.r, max(rgb.g, rgb.b));
      float d = cmax - cmin;
      float eps = 0.00001;
      if (d < eps || cmax < eps) {
        return vec3(0, 0, cmax);
      }

      float _h;
      if (cmax == rgb.r) {
        _h = (rgb.g - rgb.b) / d;
        if (_h < 0.) {
          _h += 6.;
        }
      } else if (cmax == rgb.g) {
        _h = ((rgb.b - rgb.r) / d) + 2.;
      } else {
        _h = ((rgb.r - rgb.g) / d) + 4.;
      }

      return vec3(_h * 60. * (PI / 180.), d / cmax, cmax);
    }

    vec3 hsv2rgb(vec3 hsv) {
      // rapidtables.com/convert/color/hsv-to-rgb.htm
      float _h = hsv.x * 180. / PI;
      float _c = hsv.y * hsv.z;
      float _x = _c * (1. - abs(mod(_h / 60., 2.) - 1.));
      float _m = hsv.z - _c;
      vec3 _r;
      if (/* 0. <= _h && */ _h < 60.) {
        _r.r = _c;
        _r.g = _x;
        _r.b = 0.;
      } else if (_h < 120.) {
        _r.r = _x;
        _r.g = _c;
        _r.b = 0.;
      } else if (_h < 180.) {
        _r.r = 0.;
        _r.g = _c;
        _r.b = _x;
      } else if (_h < 240.) {
        _r.r = 0.;
        _r.g = _x;
        _r.b = _c;
      } else if (_h < 300.) {
        _r.r = _x;
        _r.g = 0.;
        _r.b = _c;
      } else /* if (_h < 360.) */ {
        _r.r = _c;
        _r.g = 0.;
        _r.b = _x;
      }
      return _r + vec3(_m);
    }

    void main() {
      vec3 rgb = texture(source, texcoord).bgr;
      rgb = imageParameters[0] * rgb + imageParameters[1]; // increase overall brightness
      vec3 hsv = rgb2hsv(rgb);
      hsv.y = hsv.y * imageParameters[2]; // increase saturation
      rgb = clamp(hsv2rgb(hsv), 0., 1.);
      frag_color = vec4(rgb, 0.);
    }
  )glsl";

  pipeline.create(vertexShaderSource, fragmentShaderSource, graphics::Pipeline::BlendMode::None);

  pipeline_transform_location = pipeline.getUniformLocation("transform");
  pipeline_source_location = pipeline.getUniformLocation("source");
  pipeline_imageParameters_location = pipeline.getUniformLocation("imageParameters");
}

void WebcamImageTransform::destroy() {
  pipeline.destroy();
}

void WebcamImageTransform::draw(graphics::Texture &input, graphics::Framebuffer &output) {
  assert(input.getWidth() == input_width);
  assert(input.getHeight() == input_height);
  assert(output.getWidth() == output_width);
  assert(output.getHeight() == output_height);

  output.bind();
  glViewport(0, 0, output.getWidth(), output.getHeight());
  pipeline.bind();
  glUniformMatrix3fv(pipeline_transform_location, 1, GL_FALSE, &transform[0][0]);
  input.bind(0u);
  glUniform1i(pipeline_source_location, 0u);
  glUniform3f(pipeline_imageParameters_location, brightnessMul, brightnessAdd, saturation);
  rectangle->draw();
}
<|endoftext|>


<commit_before><commit_msg>macro for debugging code<commit_after><|endoftext|>


<commit_before><commit_msg>client: move all mds selection code into choose_target_mds<commit_after><|endoftext|>


<commit_before><commit_msg>uclient: set NAME_MAX = PAGE_SIZE<commit_after><|endoftext|>


<commit_before>#include "Header.h"
#include "Parameters.h"
#include <shlobj.h>
#include "FileCode.h"

bool OleReady;

void ShellInit()
{
	HRESULT hres = OleInitialize(NULL);
	OleReady = ((hres == S_FALSE) || (hres == S_OK));
}

void ShellDest()
{
	if (OleReady)
		OleUninitialize();
}

bool CreateShortcut(char* Destination, char* Target, char* StartIn, char* Parameters, char* Desc)
{
	if (!OleReady)
		return false;

    HRESULT hres;
    IShellLink* psl;

    // Get a pointer to the IShellLink interface.
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                            IID_IShellLink, (LPVOID*)&psl);
    if (SUCCEEDED(hres))
    {
        IPersistFile* ppf;

        // Set the path to the shortcut target and add the description.
        psl->SetPath(Target);
		if (Parameters != NULL) psl->SetArguments(Parameters);
        if (Desc != NULL) psl->SetDescription(Desc);
		if (StartIn != NULL) psl->SetWorkingDirectory(StartIn);

        // Query IShellLink for the IPersistFile interface for saving the
        // shortcut in persistent storage.
        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

        if (SUCCEEDED(hres))
        {
            WCHAR wsz[MAX_PATH];

            // Ensure that the string is Unicode.
            MultiByteToWideChar(CP_ACP, 0, Destination, -1, wsz, MAX_PATH);

            // Save the link by calling IPersistFile::Save.
            hres = ppf->Save(wsz, TRUE);
            ppf->Release();
        }
        psl->Release();
    }
    return (SUCCEEDED(hres) ? true : false);
}

bool GetFolder(HWND hDlg, int nFolder, char* Buffer)
{
	LPITEMIDLIST idl;
	SHGetSpecialFolderLocation(hDlg, nFolder, &idl);
	if (idl == 0) return false;

	BOOL res = SHGetPathFromIDList(idl, Buffer);
	CoTaskMemFree(idl);
	return (res != FALSE);
}

bool CreateDesktopShortcut(HWND hDlg, char* Folder)
{
	char Destination[MyMaxPath];
	if (!GetFolder(hDlg, CSIDL_DESKTOP, Destination))
		return false;

	strcat(Destination, "\\" ProgramName ".lnk");

	char Target[MyMaxPath];
	strcpy(Target, Folder);
	strcat(Target, "\\" PrimaryFile);

	return CreateShortcut(Destination, Target, Folder, NULL, ProgramName " - " Description);
}

bool CreateStartMenuShortcut(HWND hDlg, char* Folder)
{
	char Destination[MyMaxPath];
	if (!GetFolder(hDlg, CSIDL_PROGRAMS, Destination))
		return false;

	strcat(Destination, "\\" ProgramName);
	if (!EnsureFolder(Destination))
		return false;

	strcat(Destination, "\\");
	char* i = &Destination[strlen(Destination)];

	char Target[MyMaxPath];
	strcpy(Target, Folder);
	strcat(Target, "\\" PrimaryFile);

	strcpy(i, ProgramName ".lnk");
	bool res = CreateShortcut(Destination, Target, Folder, NULL, ProgramName " - " Description);

	strcpy(i, "Readme.lnk");
	strcpy(&Target[strlen(Folder)+1], "readme.htm");
	res &= CreateShortcut(Destination, Target, NULL, NULL, ProgramName " - Read Me");

	return res;
}

void WriteRegistry(char* Path, char* Local, char* Value)
{
	HKEY hKey;
	RegCreateKey(HKEY_CLASSES_ROOT, Path, &hKey);
	if (hKey != NULL)
	{
		RegSetValueEx(hKey, Local, 0, REG_SZ, (BYTE*) Value, strlen(Value)+1);
		RegCloseKey(hKey);
	}
}

bool RegisterFiletypes(HWND hDlg, char* Folder)
{
#define HASKELL_HANDLER "hugs_haskell"

	char Buffer[MyMaxPath];
	Buffer[0] = '\"';
	strcpy(&Buffer[1], Folder);
	char* FileName = &Buffer[strlen(Folder)+1];
	FileName[0] = '\\';
	FileName++;

	//Register the two extensions
	WriteRegistry(".hs" , "", HASKELL_HANDLER);
	WriteRegistry(".lhs", "", HASKELL_HANDLER);

	//Allow the user to create a template
	WriteRegistry(".hs\\ShellNew", "FileName", "");

	WriteRegistry(HASKELL_HANDLER,                 "", "Haskell Script");
	strcpy(FileName, PrimaryFile "\",1");
	WriteRegistry(HASKELL_HANDLER "\\DefaultIcon", "", Buffer);
	WriteRegistry(HASKELL_HANDLER "\\shell",       "", "");

	strcpy(FileName, PrimaryFile "\" \"%1\"");
	WriteRegistry(HASKELL_HANDLER "\\shell\\Open",          "", "");
	WriteRegistry(HASKELL_HANDLER "\\shell\\Open\\command", "", Buffer);

	strcpy(FileName, PrimaryFile "\" /edit \"%1\"");
	WriteRegistry(HASKELL_HANDLER "\\shell\\Edit",          "", "");
	WriteRegistry(HASKELL_HANDLER "\\shell\\Edit\\command", "", Buffer);

	return true;
}

void GetProgramFiles(HWND hDlg, char* Buffer)
{
	char* s = getenv("PROGRAMFILES");
	strcpy(Buffer, (s != NULL ? s : "C:\\Program Files"));
}

int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
	switch(uMsg)
	{
	case BFFM_INITIALIZED:
		char Buffer[MyMaxPath];
		GetWindowText((HWND) lpData, Buffer, MyMaxPath);
		SendMessage(hWnd, BFFM_SETSELECTION, TRUE, (LPARAM) Buffer);
		break;
	}

	return 0;
}

void Browse(HWND hDlg, HWND hText)
{
	const int bif_NEWDIALOGSTYLE = 0x40;

	BROWSEINFO bi;
	bi.hwndOwner = hDlg;
	bi.pidlRoot = NULL;
	bi.pszDisplayName = NULL;
	bi.lpszTitle = "Select the installation folder for " ProgramName;
	bi.ulFlags = BIF_RETURNONLYFSDIRS | bif_NEWDIALOGSTYLE;
	bi.lpfn = &BrowseCallbackProc;
	bi.lParam = (LPARAM) hText;
	bi.iImage = 0;

	LPITEMIDLIST idl = SHBrowseForFolder(&bi);

	if (idl != NULL)
	{
		char Buffer[MyMaxPath];
		SHGetPathFromIDList(idl, Buffer);
		SetWindowText(hText, Buffer);
		CoTaskMemFree(idl);
	}
}
<commit_msg>from Neil Mitchell: adds logging for actions created using the shell, namely shortcuts and registry keys.<commit_after>#include "Header.h"
#include "Parameters.h"
#include <shlobj.h>
#include "FileCode.h"
#include "InstallLog.h"

bool OleReady;

void ShellInit()
{
	HRESULT hres = OleInitialize(NULL);
	OleReady = ((hres == S_FALSE) || (hres == S_OK));
}

void ShellDest()
{
	if (OleReady)
		OleUninitialize();
}

bool CreateShortcut(char* Destination, char* Target, char* StartIn, char* Parameters, char* Desc)
{
	if (!OleReady)
		return false;

    HRESULT hres;
    IShellLink* psl;

    // Get a pointer to the IShellLink interface.
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                            IID_IShellLink, (LPVOID*)&psl);
    if (SUCCEEDED(hres))
    {
        IPersistFile* ppf;

        // Set the path to the shortcut target and add the description.
        psl->SetPath(Target);
		if (Parameters != NULL) psl->SetArguments(Parameters);
        if (Desc != NULL) psl->SetDescription(Desc);
		if (StartIn != NULL) psl->SetWorkingDirectory(StartIn);

        // Query IShellLink for the IPersistFile interface for saving the
        // shortcut in persistent storage.
        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

        if (SUCCEEDED(hres))
        {
            WCHAR wsz[MAX_PATH];

            // Ensure that the string is Unicode.
            MultiByteToWideChar(CP_ACP, 0, Destination, -1, wsz, MAX_PATH);

            // Save the link by calling IPersistFile::Save.
            hres = ppf->Save(wsz, TRUE);
            ppf->Release();
        }
        psl->Release();
    }
    bool Res = (SUCCEEDED(hres) ? true : false);
	if (Res)
		WriteInstallLog("FILE %s", Destination);
	return Res;
}

bool GetFolder(HWND hDlg, int nFolder, char* Buffer)
{
	LPITEMIDLIST idl;
	SHGetSpecialFolderLocation(hDlg, nFolder, &idl);
	if (idl == 0) return false;

	BOOL res = SHGetPathFromIDList(idl, Buffer);
	CoTaskMemFree(idl);
	return (res != FALSE);
}

bool CreateDesktopShortcut(HWND hDlg, char* Folder)
{
	char Destination[MyMaxPath];
	if (!GetFolder(hDlg, CSIDL_DESKTOP, Destination))
		return false;

	strcat(Destination, "\\" ProgramName ".lnk");

	char Target[MyMaxPath];
	strcpy(Target, Folder);
	strcat(Target, "\\" PrimaryFile);

	return CreateShortcut(Destination, Target, Folder, NULL, ProgramName " - " Description);
}

bool CreateStartMenuShortcut(HWND hDlg, char* Folder)
{
	char Destination[MyMaxPath];
	if (!GetFolder(hDlg, CSIDL_PROGRAMS, Destination))
		return false;

	strcat(Destination, "\\" ProgramName);
	if (!EnsureFolder(Destination))
		return false;

	strcat(Destination, "\\");
	char* i = &Destination[strlen(Destination)];

	char Target[MyMaxPath];
	strcpy(Target, Folder);
	strcat(Target, "\\" PrimaryFile);

	strcpy(i, ProgramName ".lnk");
	bool res = CreateShortcut(Destination, Target, Folder, NULL, ProgramName " - " Description);

	strcpy(i, "Readme.lnk");
	strcpy(&Target[strlen(Folder)+1], "readme.htm");
	res &= CreateShortcut(Destination, Target, NULL, NULL, ProgramName " - Read Me");

	return res;
}

void WriteRegistry(char* Path, char* Local, char* Value)
{
	HKEY hKey;
	RegCreateKey(HKEY_CLASSES_ROOT, Path, &hKey);
	if (hKey != NULL)
	{
		RegSetValueEx(hKey, Local, 0, REG_SZ, (BYTE*) Value, strlen(Value)+1);
		RegCloseKey(hKey);

		WriteInstallLog("REG\tHKEY_CLASSES_ROOT\t%s", Path);
	}
}

bool RegisterFiletypes(HWND hDlg, char* Folder)
{
#define HASKELL_HANDLER "hugs_haskell"

	char Buffer[MyMaxPath];
	Buffer[0] = '\"';
	strcpy(&Buffer[1], Folder);
	char* FileName = &Buffer[strlen(Folder)+1];
	FileName[0] = '\\';
	FileName++;

	//Register the two extensions
	WriteRegistry(".hs" , "", HASKELL_HANDLER);
	WriteRegistry(".lhs", "", HASKELL_HANDLER);

	//Allow the user to create a template
	WriteRegistry(".hs\\ShellNew", "FileName", "");

	WriteRegistry(HASKELL_HANDLER,                 "", "Haskell Script");
	strcpy(FileName, PrimaryFile "\",1");
	WriteRegistry(HASKELL_HANDLER "\\DefaultIcon", "", Buffer);
	WriteRegistry(HASKELL_HANDLER "\\shell",       "", "");

	strcpy(FileName, PrimaryFile "\" \"%1\"");
	WriteRegistry(HASKELL_HANDLER "\\shell\\Open",          "", "");
	WriteRegistry(HASKELL_HANDLER "\\shell\\Open\\command", "", Buffer);

	strcpy(FileName, PrimaryFile "\" /edit \"%1\"");
	WriteRegistry(HASKELL_HANDLER "\\shell\\Edit",          "", "");
	WriteRegistry(HASKELL_HANDLER "\\shell\\Edit\\command", "", Buffer);

	return true;
}

void GetProgramFiles(HWND hDlg, char* Buffer)
{
	char* s = getenv("PROGRAMFILES");
	strcpy(Buffer, (s != NULL ? s : "C:\\Program Files"));
}

int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
	switch(uMsg)
	{
	case BFFM_INITIALIZED:
		char Buffer[MyMaxPath];
		GetWindowText((HWND) lpData, Buffer, MyMaxPath);
		SendMessage(hWnd, BFFM_SETSELECTION, TRUE, (LPARAM) Buffer);
		break;
	}

	return 0;
}

void Browse(HWND hDlg, HWND hText)
{
	const int bif_NEWDIALOGSTYLE = 0x40;

	BROWSEINFO bi;
	bi.hwndOwner = hDlg;
	bi.pidlRoot = NULL;
	bi.pszDisplayName = NULL;
	bi.lpszTitle = "Select the installation folder for " ProgramName;
	bi.ulFlags = BIF_RETURNONLYFSDIRS | bif_NEWDIALOGSTYLE;
	bi.lpfn = &BrowseCallbackProc;
	bi.lParam = (LPARAM) hText;
	bi.iImage = 0;

	LPITEMIDLIST idl = SHBrowseForFolder(&bi);

	if (idl != NULL)
	{
		char Buffer[MyMaxPath];
		SHGetPathFromIDList(idl, Buffer);
		SetWindowText(hText, Buffer);
		CoTaskMemFree(idl);
	}
}
<|endoftext|>


<commit_before>#include "genomeScanFastaFiles.h"
#include "ErrorWarning.h"

uint genomeScanFastaFiles (Parameters *P, char* G, bool flagRun) {//scans fasta files. flagRun=false: check and find full size, flaRun=true: collect all the data

    uint N=0;//total number of bases in the genome, including chr "spacers"
    if (!flagRun && P->chrLength.size()>0)
    {//previous chr records exist
       P->chrStart.pop_back();//remove last record, it will be recorded again
       N =  P->chrStart.back()+P->chrLength.back();
       P->chrLength.pop_back();//remove last record, it will be recorded again
    };

    ifstream fileIn;
    for (uint ii=0;ii<P->genomeFastaFiles.size();ii++) {//all the input files
        fileIn.open(P->genomeFastaFiles.at(ii).c_str());
        if ( !fileIn.good() )
        {//
            ostringstream errOut;
            errOut << "EXITING because of INPUT ERROR: could not open genomeFastaFile: " <<P->genomeFastaFiles.at(ii) <<"\n";
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_INPUT_FILES, *P);
        };
        char cc=fileIn.peek();
        if ( !fileIn.good() )
        {//
            ostringstream errOut;
            errOut << "EXITING because of INPUT ERROR: could not read from genomeFastaFile: " <<P->genomeFastaFiles.at(ii) <<"\n";
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_INPUT_FILES, *P);
        };
        if (cc!='>')
        {
            ostringstream errOut;
            errOut << "EXITING because of INPUT ERROR: the file format of the genomeFastaFile: " <<P->genomeFastaFiles.at(ii) << "is not fasta:";
            errOut << " the first character is " <<cc<<" , not > .\n";
            errOut << " Solution: check formatting of the fasta file. Make sure the file is uncompressed (unzipped).\n";
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_INPUT_FILES, *P);
        };         while(!fileIn.eof()) {//read each file until eof
            string lineIn (4096,'.');
            getline(fileIn,lineIn);
            if (lineIn[0]=='>') {//new chromosome
                if (!flagRun) {
                    istringstream lineInStream (lineIn);
                    lineInStream.ignore(1,' ');
                    string chrName1;
                    lineInStream >> chrName1;
                    P->chrName.push_back(chrName1);
                };

                if (!flagRun && P->chrStart.size()>0) P->chrLength.push_back(N-P->chrStart.at(P->chrStart.size()-1)); //true length of the chr

                if (N>0) {//pad the chromosomes to bins boudnaries
                    N = ( (N+1)/P->genomeChrBinNbases+1 )*P->genomeChrBinNbases;
                };

                if (!flagRun) {
                    P->chrStart.push_back(N);
                    P->inOut->logMain << P->genomeFastaFiles.at(ii)<<" : chr # " << P->chrStart.size()-1 << "  \""<<P->chrName.at(P->chrStart.size()-1)<<"\" chrStart: "<<N<<"\n"<<flush;
                };
            } else {//char lines
                if (flagRun) lineIn.copy(G+N,lineIn.size(),0);
                N += lineIn.size();
            };
        };
        fileIn.close();
    };

    if (!flagRun) P->chrLength.push_back(N-P->chrStart.at(P->chrStart.size()-1)); //true length of the last chr

    N = ( (N+1)/P->genomeChrBinNbases+1)*P->genomeChrBinNbases;

    if (!flagRun)
    {
        P->nChrReal=P->chrStart.size();
        P->chrStart.push_back(N); //last chromosome end+1
        for (uint ii=0;ii<P->nChrReal;ii++) {
            P->chrNameIndex[P->chrName[ii]]=ii;
        };
    } else
    {//convert the genome to 0,1,2,3,4
        for (uint jj=0;jj<N;jj++) {
            switch (int(G[jj])){
                case(65): case(97):  G[jj]=char(0);break;//A
                case(67): case(99):  G[jj]=char(1);break;//C
                case(71): case(103): G[jj]=char(2);break;//G
                case(84): case(116): G[jj]=char(3);break;//T
                case(78): case(110): G[jj]=char(4);break;//N
                case(48):            G[jj]=GENOME_spacingChar;break;//chromosomal breaks within the sequences
                default:              //anything else
                    if (G[jj]!=GENOME_spacingChar) {
                         //P->inOut->logMain << "Unexpected character: char="<< G[jj] << "   int="<<int(G[jj])<<"   at " << jj << " , replacing with N\n";
                         G[jj]=char(4);
                    };
            };
        };
    };

    return N;
};

<commit_msg>improved optics and clarity of error message<commit_after>#include "genomeScanFastaFiles.h"
#include "ErrorWarning.h"

uint genomeScanFastaFiles (Parameters *P, char* G, bool flagRun) {//scans fasta files. flagRun=false: check and find full size, flaRun=true: collect all the data

    uint N=0;//total number of bases in the genome, including chr "spacers"
    if (!flagRun && P->chrLength.size()>0)
    {//previous chr records exist
       P->chrStart.pop_back();//remove last record, it will be recorded again
       N =  P->chrStart.back()+P->chrLength.back();
       P->chrLength.pop_back();//remove last record, it will be recorded again
    };

    ifstream fileIn;
    for (uint ii=0;ii<P->genomeFastaFiles.size();ii++) {//all the input files
        fileIn.open(P->genomeFastaFiles.at(ii).c_str());
        if ( !fileIn.good() )
        {//
            ostringstream errOut;
            errOut << "EXITING because of INPUT ERROR: could not open genomeFastaFile: " <<P->genomeFastaFiles.at(ii) <<"\n";
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_INPUT_FILES, *P);
        };
        char cc=fileIn.peek();
        if ( !fileIn.good() )
        {//
            ostringstream errOut;
            errOut << "EXITING because of INPUT ERROR: could not read from genomeFastaFile: " <<P->genomeFastaFiles.at(ii) <<"\n";
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_INPUT_FILES, *P);
        };
        if (cc!='>')
        {
            ostringstream errOut;
            errOut << "EXITING because of INPUT ERROR: the file format of the genomeFastaFile: " <<P->genomeFastaFiles.at(ii) << " is not fasta:";
            errOut << " the first character is '" <<cc<<"' ("<< (cc+0) << "), not '>'.\n";
            errOut << " Solution: check formatting of the fasta file. Make sure the file is uncompressed (unzipped).\n";
            exitWithError(errOut.str(),std::cerr, P->inOut->logMain, EXIT_CODE_INPUT_FILES, *P);
        };         while(!fileIn.eof()) {//read each file until eof
            string lineIn (4096,'.');
            getline(fileIn,lineIn);
            if (lineIn[0]=='>') {//new chromosome
                if (!flagRun) {
                    istringstream lineInStream (lineIn);
                    lineInStream.ignore(1,' ');
                    string chrName1;
                    lineInStream >> chrName1;
                    P->chrName.push_back(chrName1);
                };

                if (!flagRun && P->chrStart.size()>0) P->chrLength.push_back(N-P->chrStart.at(P->chrStart.size()-1)); //true length of the chr

                if (N>0) {//pad the chromosomes to bins boudnaries
                    N = ( (N+1)/P->genomeChrBinNbases+1 )*P->genomeChrBinNbases;
                };

                if (!flagRun) {
                    P->chrStart.push_back(N);
                    P->inOut->logMain << P->genomeFastaFiles.at(ii)<<" : chr # " << P->chrStart.size()-1 << "  \""<<P->chrName.at(P->chrStart.size()-1)<<"\" chrStart: "<<N<<"\n"<<flush;
                };
            } else {//char lines
                if (flagRun) lineIn.copy(G+N,lineIn.size(),0);
                N += lineIn.size();
            };
        };
        fileIn.close();
    };

    if (!flagRun) P->chrLength.push_back(N-P->chrStart.at(P->chrStart.size()-1)); //true length of the last chr

    N = ( (N+1)/P->genomeChrBinNbases+1)*P->genomeChrBinNbases;

    if (!flagRun)
    {
        P->nChrReal=P->chrStart.size();
        P->chrStart.push_back(N); //last chromosome end+1
        for (uint ii=0;ii<P->nChrReal;ii++) {
            P->chrNameIndex[P->chrName[ii]]=ii;
        };
    } else
    {//convert the genome to 0,1,2,3,4
        for (uint jj=0;jj<N;jj++) {
            switch (int(G[jj])){
                case(65): case(97):  G[jj]=char(0);break;//A
                case(67): case(99):  G[jj]=char(1);break;//C
                case(71): case(103): G[jj]=char(2);break;//G
                case(84): case(116): G[jj]=char(3);break;//T
                case(78): case(110): G[jj]=char(4);break;//N
                case(48):            G[jj]=GENOME_spacingChar;break;//chromosomal breaks within the sequences
                default:              //anything else
                    if (G[jj]!=GENOME_spacingChar) {
                         //P->inOut->logMain << "Unexpected character: char="<< G[jj] << "   int="<<int(G[jj])<<"   at " << jj << " , replacing with N\n";
                         G[jj]=char(4);
                    };
            };
        };
    };

    return N;
};

<|endoftext|>