<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qgeopositioninfosource.h>

#if defined(Q_OS_SYMBIAN)
#   include "qgeopositioninfosource_s60_p.h"
#elif defined(QT_SIMULATOR)
#   include "qgeopositioninfosource_simulator_p.h"
#elif defined(Q_OS_WINCE)
#   include "qgeopositioninfosource_wince_p.h"
#elif defined(Q_WS_MAEMO_6)
#   include "qgeopositioninfosource_maemo_p.h"
#elif defined(Q_WS_MAEMO_5)
#   include "qgeopositioninfosource_maemo5_p.h"
#endif

#if defined (Q_WS_MEEGO)
#include "qgeopositioninfosource_maemo_p.h"
#if defined (GEOCLUE_MASTER_AVAILABLE)
#include "qgeopositioninfosource_geocluemaster_p.h"
#endif
#endif

QTM_BEGIN_NAMESPACE

/*!
    \class QGeoPositionInfoSource
    \brief The QGeoPositionInfoSource class is an abstract base class for the distribution of positional updates.

    \inmodule QtLocation

    \ingroup location

    The static function QGeoPositionInfoSource::createDefaultSource() creates a default
    position source that is appropriate for the platform, if one is available.
    Otherwise, QGeoPositionInfoSource can be subclassed to create an appropriate
    custom source of position data.

    Users of a QGeoPositionInfoSource subclass can request the current position using
    requestUpdate(), or start and stop regular position updates using
    startUpdates() and stopUpdates(). When an update is available,
    positionUpdated() is emitted. The last known position can be accessed with
    lastKnownPosition().

    If regular position updates are required, setUpdateInterval() can be used
    to specify how often these updates should be emitted. If no interval is
    specified, updates are simply provided whenever they are available.
    For example:

    \code
        // Emit updates every 10 seconds if available
        QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(0);
        if (source)
            source->setUpdateInterval(10000);
    \endcode

    To remove an update interval that was previously set, call
    setUpdateInterval() with a value of 0.

    Note that the position source may have a minimum value requirement for
    update intervals, as returned by minimumUpdateInterval().

    \warning On Windows CE it is not possible to detect if a device is GPS enabled.
    The default position source on a Windows CE device without GPS support will never provide any position data.
*/

/*!
    \enum QGeoPositionInfoSource::PositioningMethod
    Defines the types of positioning methods.

    \value SatellitePositioningMethods Satellite-based positioning methods such as GPS.
    \value NonSatellitePositioningMethods Other positioning methods.
    \value AllPositioningMethods A flag that matches all positioning methods.
*/

class QGeoPositionInfoSourcePrivate
{
public:
    int interval;
    QGeoPositionInfoSource::PositioningMethods methods;
};

/*!
    Creates a position source with the specified \a parent.
*/

QGeoPositionInfoSource::QGeoPositionInfoSource(QObject *parent)
        : QObject(parent),
        d(new QGeoPositionInfoSourcePrivate)
{
    d->interval = 0;
    d->methods = 0;
}

/*!
    Destroys the position source.
*/
QGeoPositionInfoSource::~QGeoPositionInfoSource()
{
    delete d;
}

/*!
    \property QGeoPositionInfoSource::updateInterval
    \brief This property holds the requested interval in milliseconds between each update.

    If the update interval is not set (or is set to 0) the
    source will provide updates as often as necessary.

    If the update interval is set, the source will provide updates at an
    interval as close to the requested interval as possible. If the requested
    interval is less than the minimumUpdateInterval(),
    the minimum interval is used instead.

    Changes to the update interval will happen as soon as is practical, however the
    time the change takes may vary between implementations.  Whether or not the elapsed
    time from the previous interval is counted as part of the new interval is also
    implementation dependent.

    The default value for this property is 0.

    Note: Subclass implementations must call the base implementation of
    setUpdateInterval() so that updateInterval() returns the correct value.
*/
void QGeoPositionInfoSource::setUpdateInterval(int msec)
{
    d->interval = msec;
}

int QGeoPositionInfoSource::updateInterval() const
{
    return d->interval;
}

/*!
    Sets the preferred positioning methods for this source to \a methods.

    If \a methods includes a method that is not supported by the source, the
    unsupported method will be ignored.

    If \a methods does not include any methods supported by the source, the
    preferred methods will be set to the set of methods which the source supports.

    \bold {Note:} When reimplementing this method, subclasses must call the
    base method implementation to ensure preferredPositioningMethods() returns the correct value.

    \sa supportedPositioningMethods()
*/
void QGeoPositionInfoSource::setPreferredPositioningMethods(PositioningMethods methods)
{
    d->methods = methods & supportedPositioningMethods();
    if (d->methods == 0) {
        d->methods = supportedPositioningMethods();
    }
}

/*!
    Returns the positioning methods set by setPreferredPositioningMethods().
*/
QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSource::preferredPositioningMethods() const
{
    return d->methods;
}

/*!
    Creates and returns a position source with the given \a parent that
    reads from the system's default sources of location data.

    Returns 0 if the system has no default position source.
*/

QGeoPositionInfoSource *QGeoPositionInfoSource::createDefaultSource(QObject *parent)
{
#if defined(Q_OS_SYMBIAN)
    QGeoPositionInfoSource *ret = NULL;
    TRAPD(error, ret = CQGeoPositionInfoSourceS60::NewL(parent));
    if (error != KErrNone)
        return 0;
    return ret;
#elif defined(QT_SIMULATOR)
    return new QGeoPositionInfoSourceSimulator(parent);
#elif defined(Q_OS_WINCE)
    return new QGeoPositionInfoSourceWinCE(parent);
#elif (defined(Q_WS_MAEMO_6)) || (defined(Q_WS_MAEMO_5))
    QGeoPositionInfoSourceMaemo *source = new QGeoPositionInfoSourceMaemo(parent);

    int status = source->init();
    if (status == -1) {
        delete source;
        return 0;
    }
    return source;
#elif defined(Q_WS_MEEGO)
    // Use Maemo6 backend if its available, otherwise use Geoclue backend
    QSettings settings(QLatin1String("Nokia"), QLatin1String("QtLocationPosAndSat"));
    if (!settings.value("maemo6positioningavailable").isValid()) {
        QGeoPositionInfoSourceMaemo* maemo6Source = new QGeoPositionInfoSourceMaemo(parent);
        int status = maemo6Source->init();
        if (status == -1) {
            delete maemo6Source;
            maemo6Source = 0;
            settings.setValue("maemo6positioningavailable", false);
        } else {
            return maemo6Source;
        }
    }
#ifdef GEOCLUE_MASTER_AVAILABLE
    QGeoPositionInfoSourceGeoclueMaster *geoclueSource = new QGeoPositionInfoSourceGeoclueMaster(parent);
    int status = geoclueSource->init();
    if (status == -1) {
       delete geoclueSource;
       return 0;
    }
    return geoclueSource;
#endif // GEOCLUE_MASTER_AVAILABLE
#else
    qWarning("no default source");
    Q_UNUSED(parent);
    return 0;
#endif
}

/*!
    \fn QGeoPositionInfo QGeoPositionInfoSource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const = 0;

    Returns an update containing the last known position, or a null update
    if none is available.

    If \a fromSatellitePositioningMethodsOnly is true, this returns the last
    known position received from a satellite positioning method; if none
    is available, a null update is returned.
*/

/*!
    \fn virtual PositioningMethods QGeoPositionInfoSource::supportedPositioningMethods() const = 0;

    Returns the positioning methods available to this source.

    \sa setPreferredPositioningMethods()
*/

/*!
    \property QGeoPositionInfoSource::minimumUpdateInterval
    \brief This property holds the minimum time (in milliseconds) required to retrieve a position update.

    This is the minimum value accepted by setUpdateInterval() and
    requestUpdate().
*/

/*!
    \fn virtual void QGeoPositionInfoSource::startUpdates() = 0;

    Starts emitting updates at regular intervals as specified by setUpdateInterval().

    If setUpdateInterval() has not been called, the source will emit updates
    as soon as they become available.

    An updateTimout() signal will be emitted if this QGeoPositionInfoSource subclass determines
    that it will not be able to provide regular updates.  This could happen if a satellite fix is
    lost or if a hardware error is detected.  Position updates will recommence if the data becomes
    available later on.  The updateTimout() signal will not be emitted again until after the
    periodic updates resume.
*/

/*!
    \fn virtual void QGeoPositionInfoSource::stopUpdates() = 0;

    Stops emitting updates at regular intervals.
*/

/*!
    \fn virtual void QGeoPositionInfoSource::requestUpdate(int timeout = 0);

    Attempts to get the current position and emit positionUpdated() with
    this information. If the current position cannot be found within the given \a timeout
    (in milliseconds) or if \a timeout is less than the value returned by
    minimumUpdateInterval(), updateTimeout() is emitted.

    If the timeout is zero, the timeout defaults to a reasonable timeout
    period as appropriate for the source.

    This does nothing if another update request is in progress. However
    it can be called even if startUpdates() has already been called and
    regular updates are in progress.

    If the source uses multiple positioning methods, it tries to gets the
    current position from the most accurate positioning method within the
    given timeout.
*/

/*!
    \fn void QGeoPositionInfoSource::positionUpdated(const QGeoPositionInfo &update);

    If startUpdates() or requestUpdate() is called, this signal is emitted
    when an update becomes available.

    The \a update value holds the value of the new update.
*/

/*!
    \fn void QGeoPositionInfoSource::updateTimeout();

    If requestUpdate() was called, this signal will be emitted if the current position could not
    be retrieved within the specified timeout.

    If startUpdates() has been called, this signal will be emitted if this QGeoPositionInfoSource
    subclass determines that it will not be able to provide further regular updates.  This signal
    will not be emitted again until after the regular updates resume.
*/

#include "moc_qgeopositioninfosource.cpp"

QTM_END_NAMESPACE
<commit_msg>Basic implementation of QGeoPositionInfoSource plugins<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qgeopositioninfosource.h>
#include "qgeopositioninfosourcefactory.h"

#include <QPluginLoader>
#include <QStringList>
#include "qmobilitypluginsearch.h"

#if defined(Q_OS_SYMBIAN)
#   include "qgeopositioninfosource_s60_p.h"
#elif defined(QT_SIMULATOR)
#   include "qgeopositioninfosource_simulator_p.h"
#elif defined(Q_OS_WINCE)
#   include "qgeopositioninfosource_wince_p.h"
#elif defined(Q_WS_MAEMO_6)
#   include "qgeopositioninfosource_maemo_p.h"
#elif defined(Q_WS_MAEMO_5)
#   include "qgeopositioninfosource_maemo5_p.h"
#endif

#if defined (Q_WS_MEEGO)
#include "qgeopositioninfosource_maemo_p.h"
#if defined (GEOCLUE_MASTER_AVAILABLE)
#include "qgeopositioninfosource_geocluemaster_p.h"
#endif
#endif

QTM_BEGIN_NAMESPACE

/*!
    \class QGeoPositionInfoSource
    \brief The QGeoPositionInfoSource class is an abstract base class for the distribution of positional updates.

    \inmodule QtLocation

    \ingroup location

    The static function QGeoPositionInfoSource::createDefaultSource() creates a default
    position source that is appropriate for the platform, if one is available.
    Otherwise, QGeoPositionInfoSource can be subclassed to create an appropriate
    custom source of position data.

    Users of a QGeoPositionInfoSource subclass can request the current position using
    requestUpdate(), or start and stop regular position updates using
    startUpdates() and stopUpdates(). When an update is available,
    positionUpdated() is emitted. The last known position can be accessed with
    lastKnownPosition().

    If regular position updates are required, setUpdateInterval() can be used
    to specify how often these updates should be emitted. If no interval is
    specified, updates are simply provided whenever they are available.
    For example:

    \code
        // Emit updates every 10 seconds if available
        QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(0);
        if (source)
            source->setUpdateInterval(10000);
    \endcode

    To remove an update interval that was previously set, call
    setUpdateInterval() with a value of 0.

    Note that the position source may have a minimum value requirement for
    update intervals, as returned by minimumUpdateInterval().

    \warning On Windows CE it is not possible to detect if a device is GPS enabled.
    The default position source on a Windows CE device without GPS support will never provide any position data.
*/

/*!
    \enum QGeoPositionInfoSource::PositioningMethod
    Defines the types of positioning methods.

    \value SatellitePositioningMethods Satellite-based positioning methods such as GPS.
    \value NonSatellitePositioningMethods Other positioning methods.
    \value AllPositioningMethods A flag that matches all positioning methods.
*/

class QGeoPositionInfoSourcePrivate
{
public:
    int interval;
    QGeoPositionInfoSource::PositioningMethods methods;

    static QList<QGeoPositionInfoSourceFactory*> pluginsSorted();
    static QHash<QString, QGeoPositionInfoSourceFactory*> plugins(bool reload = false);
    static void loadDynamicPlugins(QHash<QString, QGeoPositionInfoSourceFactory*> &plugins);
    static void loadStaticPlugins(QHash<QString, QGeoPositionInfoSourceFactory*> &plugins);
};

QHash<QString, QGeoPositionInfoSourceFactory*> QGeoPositionInfoSourcePrivate::plugins(bool reload)
{
    static QHash<QString, QGeoServiceProviderFactory*> plugins;
    static bool alreadyDiscovered = false;

    if (reload == true)
        alreadyDiscovered = false;

    if (!alreadyDiscovered) {
        loadStaticPlugins(plugins);
        loadDynamicPlugins(plugins);
        alreadyDiscovered = true;
    }
    return plugins;
}

static bool pluginComparator(const QGeoPositionInfoSourceFactory *p1, const QGeoPositionInfoSourceFactory *p2)
{
    return (p1->sourcePriority() > p2->sourcePriority());
}

QList<QGeoPositionInfoSourceFactory*> QGeoPositionInfoSourcePrivate::pluginsSorted()
{
    QList<QGeoPositionInfoSourceFactory*> list = plugins().values();
    qStableSort(list.begin(), list.end(), pluginComparator);
    return list;
}

void QGeoPositionInfoSourcePrivate::loadDynamicPlugins(QHash<QString, QGeoPositionInfoSourceFactory *> &plugins)
{
    QStringList paths;
    paths << mobilityPlugins(QLatin1String("position"));

    QPluginLoader qpl;
    for (int i = 0; i < paths.count(); ++i) {
        qpl.setFileName(paths.at(i));

        QGeoPositionInfoSourceFactory *f =
                qobject_cast<QGeoPositionInfoSourceFactory*>(qpl.instance());
        if (f) {
            QString name = f->providerName();

#if !defined QT_NO_DEBUG
            const bool showDebug = qgetenv("QT_DEBUG_PLUGINS").toInt() > 0;
            if (showDebug)
                qDebug() << "Dynamic: found a service provider plugin with name" << name;
#endif
            plugins->insertMulti(name, f);
        }
    }
}

void QGeoPositionInfoSourcePrivate::loadStaticPlugins(QHash<QString, QGeoPositionInfoSourceFactory *> &plugins)
{
#if !defined QT_NO_DEBUG
    const bool showDebug = qgetenv("QT_DEBUG_PLUGINS").toInt() > 0;
#endif

    QObjectList staticPlugins = QPluginLoader::staticInstances();
    for (int i = 0; i < staticPlugins.count(); ++i) {
        QGeoPositionInfoSourceFactory *f =
                qobject_cast<QGeoPositionInfoSourceFactory*>(staticPlugins.at(i));

        if (f) {
            QString name = f->providerName();

#if !defined QT_NO_DEBUG
            if (showDebug)
                qDebug() << "Static: found a service provider plugin with name" << name;
#endif
            if (!name.isEmpty()) {
                plugins->insertMulti(name, f);
            }
        }

    }
}

/*!
    Creates a position source with the specified \a parent.
*/

QGeoPositionInfoSource::QGeoPositionInfoSource(QObject *parent)
        : QObject(parent),
        d(new QGeoPositionInfoSourcePrivate)
{
    d->interval = 0;
    d->methods = 0;
}

/*!
    Destroys the position source.
*/
QGeoPositionInfoSource::~QGeoPositionInfoSource()
{
    delete d;
}

/*!
    \property QGeoPositionInfoSource::updateInterval
    \brief This property holds the requested interval in milliseconds between each update.

    If the update interval is not set (or is set to 0) the
    source will provide updates as often as necessary.

    If the update interval is set, the source will provide updates at an
    interval as close to the requested interval as possible. If the requested
    interval is less than the minimumUpdateInterval(),
    the minimum interval is used instead.

    Changes to the update interval will happen as soon as is practical, however the
    time the change takes may vary between implementations.  Whether or not the elapsed
    time from the previous interval is counted as part of the new interval is also
    implementation dependent.

    The default value for this property is 0.

    Note: Subclass implementations must call the base implementation of
    setUpdateInterval() so that updateInterval() returns the correct value.
*/
void QGeoPositionInfoSource::setUpdateInterval(int msec)
{
    d->interval = msec;
}

int QGeoPositionInfoSource::updateInterval() const
{
    return d->interval;
}

/*!
    Sets the preferred positioning methods for this source to \a methods.

    If \a methods includes a method that is not supported by the source, the
    unsupported method will be ignored.

    If \a methods does not include any methods supported by the source, the
    preferred methods will be set to the set of methods which the source supports.

    \bold {Note:} When reimplementing this method, subclasses must call the
    base method implementation to ensure preferredPositioningMethods() returns the correct value.

    \sa supportedPositioningMethods()
*/
void QGeoPositionInfoSource::setPreferredPositioningMethods(PositioningMethods methods)
{
    d->methods = methods & supportedPositioningMethods();
    if (d->methods == 0) {
        d->methods = supportedPositioningMethods();
    }
}

/*!
    Returns the positioning methods set by setPreferredPositioningMethods().
*/
QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSource::preferredPositioningMethods() const
{
    return d->methods;
}

/*!
    Creates and returns a position source with the given \a parent that
    reads from the system's default sources of location data.

    Returns 0 if the system has no default position source.
*/

QGeoPositionInfoSource *QGeoPositionInfoSource::createDefaultSource(QObject *parent)
{
#if defined(Q_OS_SYMBIAN)
    QGeoPositionInfoSource *ret = NULL;
    TRAPD(error, ret = CQGeoPositionInfoSourceS60::NewL(parent));
    if (error == KErrNone)
        return ret;
#elif defined(QT_SIMULATOR)
    return new QGeoPositionInfoSourceSimulator(parent);
#elif defined(Q_OS_WINCE)
    return new QGeoPositionInfoSourceWinCE(parent);
#elif (defined(Q_WS_MAEMO_6)) || (defined(Q_WS_MAEMO_5))
    QGeoPositionInfoSourceMaemo *source = new QGeoPositionInfoSourceMaemo(parent);
    int status = source->init();
    if (status != -1)
        return source;
    else
        delete source;
#elif defined(Q_WS_MEEGO)
    // Use Maemo6 backend if its available, otherwise use Geoclue backend
    QSettings settings(QLatin1String("Nokia"), QLatin1String("QtLocationPosAndSat"));
    if (!settings.value("maemo6positioningavailable").isValid()) {
        QGeoPositionInfoSourceMaemo* maemo6Source = new QGeoPositionInfoSourceMaemo(parent);
        int status = maemo6Source->init();
        if (status == -1) {
            delete maemo6Source;
            maemo6Source = 0;
            settings.setValue("maemo6positioningavailable", false);
        } else {
            return maemo6Source;
        }
    }
#ifdef GEOCLUE_MASTER_AVAILABLE
    QGeoPositionInfoSourceGeoclueMaster *geoclueSource = new QGeoPositionInfoSourceGeoclueMaster(parent);
    int status = geoclueSource->init();
    if (status > 0)
       return geoclueSource;
    delete geoclueSource;
#endif // GEOCLUE_MASTER_AVAILABLE
#endif
    // no good platform source, try plugins
    foreach (QGeoPositionInfoSourceFactory *f, d->pluginsSorted()) {
        QGeoPositionInfoSource *src = f->positionInfoSource(parent);
        if (src)
            return src;
    }

    return 0;
}

/*!
    Creates and returns a position source with the given \a parent,
    by loading the plugin named \a sourceName.

    Returns 0 if the plugin cannot be found.
*/
QGeoPositionInfoSource *QGeoPositionInfoSource::createSource(const QString &sourceName, QObject *parent)
{
    QGeoPositionInfoSourceFactory *f = d->plugins().value(sourceName);
    if (f) {
        QGeoPositionInfoSource *src = f->positionInfoSource(parent);
        if (src)
            return src;
    }
    return 0;
}

/*!
    Returns a list of available source plugins.
*/
QStringList QGeoPositionInfoSource::availableSources()
{
    return d->plugins().keys();
}

/*!
    \fn QGeoPositionInfo QGeoPositionInfoSource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const = 0;

    Returns an update containing the last known position, or a null update
    if none is available.

    If \a fromSatellitePositioningMethodsOnly is true, this returns the last
    known position received from a satellite positioning method; if none
    is available, a null update is returned.
*/

/*!
    \fn virtual PositioningMethods QGeoPositionInfoSource::supportedPositioningMethods() const = 0;

    Returns the positioning methods available to this source.

    \sa setPreferredPositioningMethods()
*/

/*!
    \property QGeoPositionInfoSource::minimumUpdateInterval
    \brief This property holds the minimum time (in milliseconds) required to retrieve a position update.

    This is the minimum value accepted by setUpdateInterval() and
    requestUpdate().
*/

/*!
    \fn virtual void QGeoPositionInfoSource::startUpdates() = 0;

    Starts emitting updates at regular intervals as specified by setUpdateInterval().

    If setUpdateInterval() has not been called, the source will emit updates
    as soon as they become available.

    An updateTimout() signal will be emitted if this QGeoPositionInfoSource subclass determines
    that it will not be able to provide regular updates.  This could happen if a satellite fix is
    lost or if a hardware error is detected.  Position updates will recommence if the data becomes
    available later on.  The updateTimout() signal will not be emitted again until after the
    periodic updates resume.
*/

/*!
    \fn virtual void QGeoPositionInfoSource::stopUpdates() = 0;

    Stops emitting updates at regular intervals.
*/

/*!
    \fn virtual void QGeoPositionInfoSource::requestUpdate(int timeout = 0);

    Attempts to get the current position and emit positionUpdated() with
    this information. If the current position cannot be found within the given \a timeout
    (in milliseconds) or if \a timeout is less than the value returned by
    minimumUpdateInterval(), updateTimeout() is emitted.

    If the timeout is zero, the timeout defaults to a reasonable timeout
    period as appropriate for the source.

    This does nothing if another update request is in progress. However
    it can be called even if startUpdates() has already been called and
    regular updates are in progress.

    If the source uses multiple positioning methods, it tries to gets the
    current position from the most accurate positioning method within the
    given timeout.
*/

/*!
    \fn void QGeoPositionInfoSource::positionUpdated(const QGeoPositionInfo &update);

    If startUpdates() or requestUpdate() is called, this signal is emitted
    when an update becomes available.

    The \a update value holds the value of the new update.
*/

/*!
    \fn void QGeoPositionInfoSource::updateTimeout();

    If requestUpdate() was called, this signal will be emitted if the current position could not
    be retrieved within the specified timeout.

    If startUpdates() has been called, this signal will be emitted if this QGeoPositionInfoSource
    subclass determines that it will not be able to provide further regular updates.  This signal
    will not be emitted again until after the regular updates resume.
*/

#include "moc_qgeopositioninfosource.cpp"

QTM_END_NAMESPACE
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2015, Nagoya University
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither the name of Autoware nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <ros/ros.h>
#include <ros/console.h>
#include <visualization_msgs/MarkerArray.h>

#include <iostream>
#include <vector>
#include <string>

#include "waypoint_follower/lane.h"
#include "waypoint_follower/libwaypoint_follower.h"
#include "runtime_manager/traffic_light.h"

static ros::Publisher _lane_mark_pub;

static constexpr int32_t TRAFFIC_LIGHT_RED     = 0;
static constexpr int32_t TRAFFIC_LIGHT_GREEN   = 1;
static constexpr int32_t TRAFFIC_LIGHT_UNKNOWN = 2;

static std_msgs::ColorRGBA _initial_color;
static std_msgs::ColorRGBA _color;

void createWaypointVelocityMarker(waypoint_follower::lane lane_waypoint, visualization_msgs::MarkerArray *marker_array)
{

  // display by markers the velocity of each waypoint.
  visualization_msgs::Marker velocity;
  velocity.header.frame_id = "map";
  velocity.header.stamp = ros::Time();
  velocity.ns = "waypoint_velocity";
  velocity.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
  velocity.action = visualization_msgs::Marker::ADD;
  velocity.scale.z = 0.4;
  velocity.color.a = 1.0;
  velocity.color.r = 1;
  velocity.color.g = 1;
  velocity.color.b = 1;
  velocity.frame_locked = true;

  for (unsigned int i = 0; i < lane_waypoint.waypoints.size(); i++)
  {

    //std::cout << _waypoints[i].GetX() << " " << _waypoints[i].GetY() << " " << _waypoints[i].GetZ() << " " << _waypoints[i].GetVelocity_kmh() << std::endl;
    velocity.id = i;
    velocity.pose.position = lane_waypoint.waypoints[i].pose.pose.position;
    velocity.pose.position.z += 0.2;
    velocity.pose.orientation.w = 1.0;

    // double to string
    std::ostringstream oss;
    oss << std::fixed << std::setprecision(2) << mps2kmph(lane_waypoint.waypoints[i].twist.twist.linear.x) << " km/h";
    velocity.text = oss.str();

    //C++11 version
    //std::string velocity = std::to_string(test_pose.velocity_kmh);
    //velocity.erase(velocity.find_first_of(".") + 3);
    //std::string kmh = " km/h";
    //std::string text = velocity + kmh;
    //marker.text = text;

    marker_array->markers.push_back(velocity);
  }
}

void createWaypointMarker(waypoint_follower::lane lane_waypoint,visualization_msgs::MarkerArray *marker_array)
{
  visualization_msgs::Marker waypoint_mark;
  waypoint_mark.header.frame_id =  "map";
  waypoint_mark.header.stamp = ros::Time();
  waypoint_mark.ns = "waypoint_marker";
  waypoint_mark.id = 0;
  waypoint_mark.type = visualization_msgs::Marker::POINTS;
  waypoint_mark.action = visualization_msgs::Marker::ADD;
  waypoint_mark.scale.x = 0.1;
  waypoint_mark.scale.y = 0.1;
  waypoint_mark.color.r = 1.0;
  waypoint_mark.color.g = 1.0;
  waypoint_mark.color.b = 1.0;
  waypoint_mark.color.a = 1.0;
  waypoint_mark.frame_locked = true;

  for (unsigned int i = 0; i < lane_waypoint.waypoints.size(); i++)
  {
    geometry_msgs::Point point;
    point = lane_waypoint.waypoints[i].pose.pose.position;
    waypoint_mark.points.push_back(point);

  }
  marker_array->markers.push_back(waypoint_mark);
}

void createPathMarker(std_msgs::ColorRGBA color , waypoint_follower::lane lane_waypoint,visualization_msgs::MarkerArray *marker_array)
{
  visualization_msgs::Marker lane_waypoint_marker;
  lane_waypoint_marker.header.frame_id = "map";
  lane_waypoint_marker.header.stamp = ros::Time();
  lane_waypoint_marker.ns = "path_marker";
  lane_waypoint_marker.id = 0;
  lane_waypoint_marker.type = visualization_msgs::Marker::LINE_STRIP;
  lane_waypoint_marker.action = visualization_msgs::Marker::ADD;
  lane_waypoint_marker.scale.x = 0.2;
  lane_waypoint_marker.color = color;
  lane_waypoint_marker.frame_locked = true;

  for (unsigned int i = 0; i < lane_waypoint.waypoints.size(); i++)
    {
      geometry_msgs::Point point;
      point = lane_waypoint.waypoints[i].pose.pose.position;
      lane_waypoint_marker.points.push_back(point);

    }
  marker_array->markers.push_back(lane_waypoint_marker);
}

static void laneCallback(const waypoint_follower::laneConstPtr &msg)
{
  visualization_msgs::MarkerArray marker_array;
  createWaypointVelocityMarker(*msg, &marker_array);
  createWaypointMarker(*msg, &marker_array);
  createPathMarker(_color, *msg, &marker_array);

  _lane_mark_pub.publish(marker_array);
}

static void lightCallback(const runtime_manager::traffic_lightConstPtr& msg)
{
  std_msgs::ColorRGBA color;
  color.a = 1.0;

  switch (msg->traffic_light)
  {
  case TRAFFIC_LIGHT_RED:
    color.r = 1.0;
    _color = color;
    break;
  case TRAFFIC_LIGHT_GREEN:
    color.g = 1.0;
    _color = color;
    break;
  case TRAFFIC_LIGHT_UNKNOWN:
    _color = _initial_color;
    break;
  default:
    ROS_ERROR("unknown traffic_light");
    return;
  }
}

static void trafficCallback(const waypoint_follower::laneConstPtr &msg)
{
  visualization_msgs::MarkerArray marker_array;
  createWaypointVelocityMarker(*msg, &marker_array);
  createWaypointMarker(*msg, &marker_array);
  createPathMarker(_color, *msg, &marker_array);

  _lane_mark_pub.publish(marker_array);

}

static void temporalCallback(const waypoint_follower::laneConstPtr &msg)
{
  visualization_msgs::MarkerArray marker_array;
  createWaypointVelocityMarker(*msg, &marker_array);
  createWaypointMarker(*msg, &marker_array);
  createPathMarker(_color, *msg, &marker_array);

  _lane_mark_pub.publish(marker_array);

}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "marker_publisher");
  ros::NodeHandle nh;
  ros::NodeHandle private_nh("~");

  ros::Subscriber lane_sub = nh.subscribe("lane_waypoints",10,laneCallback);
  ros::Subscriber traffic_sub = nh.subscribe("traffic_waypoints",10,trafficCallback);
  ros::Subscriber light_sub = nh.subscribe("traffic_light",10,lightCallback);
  ros::Subscriber temporal_sub = nh.subscribe("temporal_waypoints",10,temporalCallback);

  _lane_mark_pub = nh.advertise<visualization_msgs::MarkerArray>("lane_waypoint_mark", 10, true);

  //initialize path color
  _initial_color.b = 1.0;
  _initial_color.g = 0.7;
  _initial_color.a = 1.0;
  _color = _initial_color;

  ros::spin();

}
<commit_msg>published local path marker ,and some fix in order to be easy to see<commit_after>/*
 *  Copyright (c) 2015, Nagoya University
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither the name of Autoware nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <ros/ros.h>
#include <ros/console.h>
#include <visualization_msgs/MarkerArray.h>
#include <std_msgs/Int32.h>

#include <iostream>
#include <vector>
#include <string>

#include "waypoint_follower/lane.h"
#include "waypoint_follower/libwaypoint_follower.h"
#include "runtime_manager/traffic_light.h"

static ros::Publisher _lane_mark_pub;

static constexpr int32_t TRAFFIC_LIGHT_RED     = 0;
static constexpr int32_t TRAFFIC_LIGHT_GREEN   = 1;
static constexpr int32_t TRAFFIC_LIGHT_UNKNOWN = 2;

static std_msgs::ColorRGBA _initial_color;
static std_msgs::ColorRGBA _global_color;
static std_msgs::ColorRGBA g_local_color;
static const double g_global_alpha = 0.2;
static const double g_local_alpha = 1.0;
static int _closest_waypoint = -1;

void createGlobalWaypointVelocityMarker(const waypoint_follower::lane &lane_waypoint, visualization_msgs::MarkerArray *marker_array)
{

  // display by markers the velocity of each waypoint.
  visualization_msgs::Marker velocity;
  velocity.header.frame_id = "map";
  velocity.header.stamp = ros::Time();
  velocity.ns = "waypoint_velocity";
  velocity.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
  velocity.action = visualization_msgs::Marker::ADD;
  velocity.scale.z = 0.4;
  velocity.color.a = 1.0;
  velocity.color.r = 1;
  velocity.color.g = 1;
  velocity.color.b = 1;
  velocity.frame_locked = true;

  for (unsigned int i = 0; i < lane_waypoint.waypoints.size(); i++)
  {

    //std::cout << _waypoints[i].GetX() << " " << _waypoints[i].GetY() << " " << _waypoints[i].GetZ() << " " << _waypoints[i].GetVelocity_kmh() << std::endl;
    velocity.id = i;
    velocity.pose.position = lane_waypoint.waypoints[i].pose.pose.position;
    velocity.pose.position.z += 0.2;
    velocity.pose.orientation.w = 1.0;

    // double to string
    std::ostringstream oss;
    oss << std::fixed << std::setprecision(2) << mps2kmph(lane_waypoint.waypoints[i].twist.twist.linear.x) << " km/h";
    velocity.text = oss.str();

    //C++11 version
    //std::string velocity = std::to_string(test_pose.velocity_kmh);
    //velocity.erase(velocity.find_first_of(".") + 3);
    //std::string kmh = " km/h";
    //std::string text = velocity + kmh;
    //marker.text = text;

    marker_array->markers.push_back(velocity);
  }
}

void createLocalWaypointVelocityMarker(int closest_waypoint,const waypoint_follower::lane &lane_waypoint, visualization_msgs::MarkerArray *marker_array)
{

  // display by markers the velocity of each waypoint.
  visualization_msgs::Marker velocity;
  velocity.header.frame_id = "map";
  velocity.header.stamp = ros::Time();
  velocity.ns = "waypoint_velocity";
  velocity.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
  velocity.action = visualization_msgs::Marker::ADD;
  velocity.scale.z = 0.4;
  velocity.color.a = 1.0;
  velocity.color.r = 1;
  velocity.color.g = 1;
  velocity.color.b = 1;
  velocity.frame_locked = true;

  for (unsigned int i = 0; i < lane_waypoint.waypoints.size(); i++)
  {
    velocity.id = closest_waypoint+i;
    velocity.pose.position = lane_waypoint.waypoints[i].pose.pose.position;
    velocity.pose.position.z += 0.2;
    velocity.pose.orientation.w = 1.0;

    // double to string
    std::ostringstream oss;
    oss << std::fixed << std::setprecision(2) << mps2kmph(lane_waypoint.waypoints[i].twist.twist.linear.x) << " km/h";
    velocity.text = oss.str();

    //C++11 version
    //std::string velocity = std::to_string(test_pose.velocity_kmh);
    //velocity.erase(velocity.find_first_of(".") + 3);
    //std::string kmh = " km/h";
    //std::string text = velocity + kmh;
    //marker.text = text;

    marker_array->markers.push_back(velocity);
  }

  for (int i = closest_waypoint -1 ; i > -1 ; i--)
    {
      velocity.id = i;
      velocity.action = visualization_msgs::Marker::DELETE;
      marker_array->markers.push_back(velocity);
    }

}

void createGlobalWaypointMarker(waypoint_follower::lane lane_waypoint,visualization_msgs::MarkerArray *marker_array)
{
  visualization_msgs::Marker waypoint_mark;
  waypoint_mark.header.frame_id =  "map";
  waypoint_mark.header.stamp = ros::Time();
  waypoint_mark.ns = "waypoint_marker";
  waypoint_mark.id = 0;
  waypoint_mark.type = visualization_msgs::Marker::POINTS;
  waypoint_mark.action = visualization_msgs::Marker::ADD;
  waypoint_mark.scale.x = 0.1;
  waypoint_mark.scale.y = 0.1;
  waypoint_mark.color.r = 1.0;
  waypoint_mark.color.g = 1.0;
  waypoint_mark.color.b = 1.0;
  waypoint_mark.color.a = 1.0;
  waypoint_mark.frame_locked = true;

  for (unsigned int i = 0; i < lane_waypoint.waypoints.size(); i++)
  {
    geometry_msgs::Point point;
    point = lane_waypoint.waypoints[i].pose.pose.position;
    waypoint_mark.points.push_back(point);

  }
  marker_array->markers.push_back(waypoint_mark);
}

void createGlobalPathMarker(std_msgs::ColorRGBA color , const waypoint_follower::lane &lane_waypoint,visualization_msgs::MarkerArray *marker_array)
{
  visualization_msgs::Marker lane_waypoint_marker;
  lane_waypoint_marker.header.frame_id = "map";
  lane_waypoint_marker.header.stamp = ros::Time();
  lane_waypoint_marker.ns = "global_path_marker";
  lane_waypoint_marker.id = 0;
  lane_waypoint_marker.type = visualization_msgs::Marker::LINE_STRIP;
  lane_waypoint_marker.action = visualization_msgs::Marker::ADD;
  lane_waypoint_marker.scale.x = 2.0;
  lane_waypoint_marker.color = color;
  lane_waypoint_marker.frame_locked = true;

  for (unsigned int i = 0; i < lane_waypoint.waypoints.size(); i++)
    {
      geometry_msgs::Point point;
      point = lane_waypoint.waypoints[i].pose.pose.position;
      lane_waypoint_marker.points.push_back(point);

    }
  marker_array->markers.push_back(lane_waypoint_marker);
}

void createLocalPathMarker(std_msgs::ColorRGBA color , const waypoint_follower::lane &lane_waypoint,visualization_msgs::MarkerArray *marker_array)
{
  visualization_msgs::Marker lane_waypoint_marker;
  lane_waypoint_marker.header.frame_id = "map";
  lane_waypoint_marker.header.stamp = ros::Time();
  lane_waypoint_marker.ns = "local_path_marker";
  lane_waypoint_marker.id = 0;
  lane_waypoint_marker.type = visualization_msgs::Marker::LINE_STRIP;
  lane_waypoint_marker.action = visualization_msgs::Marker::ADD;
  lane_waypoint_marker.scale.x = 0.2;
  lane_waypoint_marker.color = color;
  lane_waypoint_marker.frame_locked = true;

  for (unsigned int i = 0; i < lane_waypoint.waypoints.size(); i++)
    {
      geometry_msgs::Point point;
      point = lane_waypoint.waypoints[i].pose.pose.position;
      lane_waypoint_marker.points.push_back(point);

    }
  marker_array->markers.push_back(lane_waypoint_marker);
}

static void laneCallback(const waypoint_follower::laneConstPtr &msg)
{
  visualization_msgs::MarkerArray marker_array;
  createGlobalWaypointVelocityMarker(*msg, &marker_array);
  //createGlobalWaypointMarker(*msg, &marker_array);
  createGlobalPathMarker(_global_color, *msg, &marker_array);

  _lane_mark_pub.publish(marker_array);
}

static void lightCallback(const runtime_manager::traffic_lightConstPtr& msg)
{
  std_msgs::ColorRGBA global_color;
  global_color.a = g_global_alpha;

  std_msgs::ColorRGBA local_color;
  local_color.a = g_local_alpha;

  switch (msg->traffic_light)
  {
  case TRAFFIC_LIGHT_RED:
    global_color.r = 1.0;
    _global_color = global_color;
    local_color.r = 1.0;
    g_local_color = local_color;
    break;
  case TRAFFIC_LIGHT_GREEN:
    global_color.g = 1.0;
    _global_color = global_color;
    local_color.g = 1.0;
    g_local_color = local_color;
    break;
  case TRAFFIC_LIGHT_UNKNOWN:
    _global_color = _initial_color;
    g_local_color = _initial_color;
    break;
  default:
    ROS_ERROR("unknown traffic_light");
    return;
  }
}

static void trafficCallback(const waypoint_follower::laneConstPtr &msg)
{
  visualization_msgs::MarkerArray marker_array;
  createGlobalWaypointVelocityMarker(*msg, &marker_array);
  //createGlobalWaypointMarker(*msg, &marker_array);
  createGlobalPathMarker(_global_color, *msg, &marker_array);

  _lane_mark_pub.publish(marker_array);

}

static void temporalCallback(const waypoint_follower::laneConstPtr &msg)
{
  visualization_msgs::MarkerArray marker_array;
  if(_closest_waypoint != -1)
    createLocalWaypointVelocityMarker(_closest_waypoint,*msg, &marker_array);
  //createLocalWaypointMarker(*msg, &marker_array);
  createLocalPathMarker(g_local_color, *msg, &marker_array);

  _lane_mark_pub.publish(marker_array);

}

static void closestCallback(const std_msgs::Int32ConstPtr &msg)
{
  _closest_waypoint = msg->data;
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "waypoints_marker_publisher");
  ros::NodeHandle nh;
  ros::NodeHandle private_nh("~");

  //subscribe traffic light
  ros::Subscriber light_sub = nh.subscribe("traffic_light",10,lightCallback);

  //subscribe global waypoints
  ros::Subscriber lane_sub = nh.subscribe("lane_waypoints",10,laneCallback);
  ros::Subscriber traffic_sub = nh.subscribe("traffic_waypoints",10,trafficCallback);

  //subscribe local waypoints
  ros::Subscriber temporal_sub = nh.subscribe("temporal_waypoints",10,temporalCallback);
  ros::Subscriber closest_sub = nh.subscribe("closest_waypoint",10,closestCallback);

  _lane_mark_pub = nh.advertise<visualization_msgs::MarkerArray>("lane_waypoint_mark", 10, true);

  //initialize path color
  _initial_color.b = 1.0;
  _initial_color.g = 0.7;
  _global_color = _initial_color;
  _global_color.a = g_global_alpha;
  g_local_color = _initial_color;
  g_local_color.a = g_local_alpha;

  ros::spin();

}
<|endoftext|>


<commit_before>#include <FAST/Data/SpatialDataObject.hpp>
#include <fstream>
#include "Renderer.hpp"
#include "Window.hpp"

namespace fast {

Renderer::Renderer() {
}

uint Renderer::addInputData(DataObject::pointer data) {
    uint nr = getNrOfInputConnections();
    if(nr > 0)
        createInputPort<DataObject>(nr);
    setInputData(nr, data);
    return nr;
}

uint Renderer::addInputConnection(DataPort::pointer port) {
    uint nr = getNrOfInputConnections();
    if(nr > 0)
        createInputPort<DataObject>(nr);
    setInputConnection(nr, port);
    return nr;
}

void Renderer::lock() {
    mMutex.lock();
}

void Renderer::unlock() {
    mMutex.unlock();
}

void Renderer::stopPipeline() {
    mStop = true;
    mHasRendered = true;
    mRenderedCV.notify_one();
    ProcessObject::stopPipeline();
}

void Renderer::postDraw() {
    mHasRendered = true;
    mRenderedCV.notify_one();
}

void Renderer::execute() {
    std::unique_lock<std::mutex> lock(mMutex);
    if(mStop) {
        return;
    }

    // Check if current images has not been rendered, if not wait
    while(!mHasRendered) {
        mRenderedCV.wait(lock);
    }
    // This simply gets the input data for each connection and puts it into a data structure
    for(uint inputNr = 0; inputNr < getNrOfInputConnections(); inputNr++) {
        if(hasNewInputData(inputNr)) {
            SpatialDataObject::pointer input = getInputData<SpatialDataObject>(inputNr);

            mHasRendered = false;
            mDataToRender[inputNr] = input;
        }
    }
}

BoundingBox Renderer::getBoundingBox(bool transform) {
    std::vector<Vector3f> coordinates;

    if(mDataToRender.size() == 0)
        throw Exception("Renderer has no input data. Unable to create bounding box and thereby initialize GL scene.");

    for(auto it : mDataToRender) {
        BoundingBox transformedBoundingBox;
        if(transform) {
            transformedBoundingBox = it.second->getTransformedBoundingBox();
        } else {
            transformedBoundingBox = it.second->getBoundingBox();
        }

        MatrixXf corners = transformedBoundingBox.getCorners();
        for(uint j = 0; j < 8; j++) {
            coordinates.push_back((Vector3f)corners.row(j));
        }
    }

    if(coordinates.size() == 0)
        throw Exception("Renderer did not get any data. Unable to create bounding box and thereby initialize GL scene.");

    return BoundingBox(coordinates);
}

void Renderer::createShaderProgram(std::vector<std::string> shaderFilenames, std::string programName) {
    // We need an active GL context to do this, and we also need to initialize the OpenGLFunctions
    Window::getMainGLContext()->makeCurrent();
    initializeOpenGLFunctions();

    uint programID = glCreateProgram();
    mShaderProgramIDs[programName] = programID;

    for(std::string filename : shaderFilenames) {
        attachShader(filename, programName);
    }
}

void Renderer::attachShader(std::string filename, std::string programName) {
    // Make sure shader is created
    if(mShaderProgramIDs.count(programName) == 0)
        createShaderProgram({}, programName);

    // Load GLSL Shader from source file
    std::ifstream fd(filename.c_str());
    if(fd.fail()) {
        throw Exception("Unable to read shader program " + filename);
    }
    auto src = std::string(std::istreambuf_iterator<char>(fd),
                           (std::istreambuf_iterator<char>()));

    // Create shader object
    const char * source = src.c_str();
    uint shaderID;
    // Extract file extension and create the correct shader type
    auto idx = filename.rfind(".");
    auto ext = filename.substr(idx + 1);
    /*if(ext == "comp") { // symbol not present on mac
        shaderID = glCreateShader(GL_COMPUTE_SHADER);
    } else*/
    if(ext == "frag") {
        shaderID = glCreateShader(GL_FRAGMENT_SHADER);
    } else if(ext == "geom") {
      shaderID = glCreateShader(GL_GEOMETRY_SHADER);
    } else if(ext == "tcs") {
       shaderID =  glCreateShader(GL_TESS_CONTROL_SHADER);
    } else if(ext == "tes") {
       shaderID =  glCreateShader(GL_TESS_EVALUATION_SHADER);
    } else if(ext == "vert") {
        shaderID =  glCreateShader(GL_VERTEX_SHADER);
    } else {
        throw Exception("Unknown shader extension. Extension should indicate shader type (.vert, .frag, .geom, .tes, .comp)");
    }
    glShaderSource(shaderID, 1, &source, nullptr);
    glCompileShader(shaderID);

    // Display errors
    int status;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status);
    if(!status) {
        int length;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &length);
        std::unique_ptr<char[]> buffer(new char[length]);
        glGetShaderInfoLog(shaderID, length, nullptr, buffer.get());
        throw Exception("Unable to compile shader " + filename + ": " + buffer.get());
    }

    // Attach shader and free allocated memory
    glAttachShader(getShaderProgram(programName), shaderID);
    glDeleteShader(shaderID);
}

void Renderer::activateShader(std::string programName) {
    // Check if linked
    int status;
    uint programID = getShaderProgram(programName) ;
    glGetProgramiv(programID, GL_LINK_STATUS, &status);
    if(!status) {
        // Shader is not linked, link it
        glLinkProgram(programID);
        glGetProgramiv(programID, GL_LINK_STATUS, &status);
        if(!status) {
            // Link failed, throw exception
            int length;
            glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &length);
            std::unique_ptr<char[]> buffer(new char[length]);
            glGetProgramInfoLog(programID, length, nullptr, buffer.get());
            throw Exception("Unable to link shader program: " + std::string(buffer.get()));
        }
    }
    glUseProgram(getShaderProgram(programName));
}

void Renderer::deactivateShader() {
    glUseProgram(0);
}

uint Renderer::getShaderProgram(std::string programName) {
    try {
        return mShaderProgramIDs.at(programName);
    } catch(...) {
        throw Exception("Shader program with name " + programName + " not found");
    }
}

void Renderer::setShaderUniform(std::string name, Matrix4f matrix, std::string shaderProgram) {
    glUniformMatrix4fv(getShaderUniformLocation(name, shaderProgram), 1, GL_FALSE, matrix.data());
}

void Renderer::setShaderUniform(std::string name, Affine3f matrix, std::string shaderProgram) {
    setShaderUniform(name, matrix.matrix(), shaderProgram);
}

void Renderer::setShaderUniform(std::string name, Vector3f vector, std::string shaderProgram) {
    glUniform3f(getShaderUniformLocation(name, shaderProgram), vector.x(), vector.y(), vector.z());
}

void Renderer::setShaderUniform(std::string name, float value, std::string shaderProgram) {
    glUniform1f(getShaderUniformLocation(name, shaderProgram), value);
}

void Renderer::setShaderUniform(std::string name, bool value, std::string shaderProgram) {
    glUniform1i(getShaderUniformLocation(name, shaderProgram), value);
}

void Renderer::setShaderUniform(std::string name, int value, std::string shaderProgram) {
    glUniform1i(getShaderUniformLocation(name, shaderProgram), value);
}

int Renderer::getShaderUniformLocation(std::string name, std::string shaderProgram) {
    int location = glGetUniformLocation(getShaderProgram(shaderProgram), name.c_str());
    if(location == -1)
        throw Exception("Unable to find location of matrix4f uniform " + name + " in shader program " + shaderProgram);
    return location;
}

void Renderer::reset() {
    mStop = false;
    mHasRendered = false;
}

}
<commit_msg>Lock renderer mutex on getBoundingBox<commit_after>#include <FAST/Data/SpatialDataObject.hpp>
#include <fstream>
#include "Renderer.hpp"
#include "Window.hpp"

namespace fast {

Renderer::Renderer() {
}

uint Renderer::addInputData(DataObject::pointer data) {
    uint nr = getNrOfInputConnections();
    if(nr > 0)
        createInputPort<DataObject>(nr);
    setInputData(nr, data);
    return nr;
}

uint Renderer::addInputConnection(DataPort::pointer port) {
    uint nr = getNrOfInputConnections();
    if(nr > 0)
        createInputPort<DataObject>(nr);
    setInputConnection(nr, port);
    return nr;
}

void Renderer::lock() {
    mMutex.lock();
}

void Renderer::unlock() {
    mMutex.unlock();
}

void Renderer::stopPipeline() {
    mStop = true;
    mHasRendered = true;
    mRenderedCV.notify_one();
    ProcessObject::stopPipeline();
}

void Renderer::postDraw() {
    mHasRendered = true;
    mRenderedCV.notify_one();
}

void Renderer::execute() {
    std::unique_lock<std::mutex> lock(mMutex);
    if(mStop) {
        return;
    }

    // Check if current images has not been rendered, if not wait
    while(!mHasRendered) {
        mRenderedCV.wait(lock);
    }
    // This simply gets the input data for each connection and puts it into a data structure
    for(uint inputNr = 0; inputNr < getNrOfInputConnections(); inputNr++) {
        if(hasNewInputData(inputNr)) {
            SpatialDataObject::pointer input = getInputData<SpatialDataObject>(inputNr);

            mHasRendered = false;
            mDataToRender[inputNr] = input;
        }
    }
}

BoundingBox Renderer::getBoundingBox(bool transform) {
    std::unique_lock<std::mutex> lock(mMutex);
    std::vector<Vector3f> coordinates;

    if(mDataToRender.size() == 0)
        throw Exception("Renderer has no input data. Unable to create bounding box and thereby initialize GL scene.");

    for(auto it : mDataToRender) {
        BoundingBox transformedBoundingBox;
        if(transform) {
            transformedBoundingBox = it.second->getTransformedBoundingBox();
        } else {
            transformedBoundingBox = it.second->getBoundingBox();
        }

        MatrixXf corners = transformedBoundingBox.getCorners();
        for(uint j = 0; j < 8; j++) {
            coordinates.push_back((Vector3f)corners.row(j));
        }
    }

    if(coordinates.size() == 0)
        throw Exception("Renderer did not get any data. Unable to create bounding box and thereby initialize GL scene.");

    return BoundingBox(coordinates);
}

void Renderer::createShaderProgram(std::vector<std::string> shaderFilenames, std::string programName) {
    // We need an active GL context to do this, and we also need to initialize the OpenGLFunctions
    Window::getMainGLContext()->makeCurrent();
    initializeOpenGLFunctions();

    uint programID = glCreateProgram();
    mShaderProgramIDs[programName] = programID;

    for(std::string filename : shaderFilenames) {
        attachShader(filename, programName);
    }
}

void Renderer::attachShader(std::string filename, std::string programName) {
    // Make sure shader is created
    if(mShaderProgramIDs.count(programName) == 0)
        createShaderProgram({}, programName);

    // Load GLSL Shader from source file
    std::ifstream fd(filename.c_str());
    if(fd.fail()) {
        throw Exception("Unable to read shader program " + filename);
    }
    auto src = std::string(std::istreambuf_iterator<char>(fd),
                           (std::istreambuf_iterator<char>()));

    // Create shader object
    const char * source = src.c_str();
    uint shaderID;
    // Extract file extension and create the correct shader type
    auto idx = filename.rfind(".");
    auto ext = filename.substr(idx + 1);
    /*if(ext == "comp") { // symbol not present on mac
        shaderID = glCreateShader(GL_COMPUTE_SHADER);
    } else*/
    if(ext == "frag") {
        shaderID = glCreateShader(GL_FRAGMENT_SHADER);
    } else if(ext == "geom") {
      shaderID = glCreateShader(GL_GEOMETRY_SHADER);
    } else if(ext == "tcs") {
       shaderID =  glCreateShader(GL_TESS_CONTROL_SHADER);
    } else if(ext == "tes") {
       shaderID =  glCreateShader(GL_TESS_EVALUATION_SHADER);
    } else if(ext == "vert") {
        shaderID =  glCreateShader(GL_VERTEX_SHADER);
    } else {
        throw Exception("Unknown shader extension. Extension should indicate shader type (.vert, .frag, .geom, .tes, .comp)");
    }
    glShaderSource(shaderID, 1, &source, nullptr);
    glCompileShader(shaderID);

    // Display errors
    int status;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status);
    if(!status) {
        int length;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &length);
        std::unique_ptr<char[]> buffer(new char[length]);
        glGetShaderInfoLog(shaderID, length, nullptr, buffer.get());
        throw Exception("Unable to compile shader " + filename + ": " + buffer.get());
    }

    // Attach shader and free allocated memory
    glAttachShader(getShaderProgram(programName), shaderID);
    glDeleteShader(shaderID);
}

void Renderer::activateShader(std::string programName) {
    // Check if linked
    int status;
    uint programID = getShaderProgram(programName) ;
    glGetProgramiv(programID, GL_LINK_STATUS, &status);
    if(!status) {
        // Shader is not linked, link it
        glLinkProgram(programID);
        glGetProgramiv(programID, GL_LINK_STATUS, &status);
        if(!status) {
            // Link failed, throw exception
            int length;
            glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &length);
            std::unique_ptr<char[]> buffer(new char[length]);
            glGetProgramInfoLog(programID, length, nullptr, buffer.get());
            throw Exception("Unable to link shader program: " + std::string(buffer.get()));
        }
    }
    glUseProgram(getShaderProgram(programName));
}

void Renderer::deactivateShader() {
    glUseProgram(0);
}

uint Renderer::getShaderProgram(std::string programName) {
    try {
        return mShaderProgramIDs.at(programName);
    } catch(...) {
        throw Exception("Shader program with name " + programName + " not found");
    }
}

void Renderer::setShaderUniform(std::string name, Matrix4f matrix, std::string shaderProgram) {
    glUniformMatrix4fv(getShaderUniformLocation(name, shaderProgram), 1, GL_FALSE, matrix.data());
}

void Renderer::setShaderUniform(std::string name, Affine3f matrix, std::string shaderProgram) {
    setShaderUniform(name, matrix.matrix(), shaderProgram);
}

void Renderer::setShaderUniform(std::string name, Vector3f vector, std::string shaderProgram) {
    glUniform3f(getShaderUniformLocation(name, shaderProgram), vector.x(), vector.y(), vector.z());
}

void Renderer::setShaderUniform(std::string name, float value, std::string shaderProgram) {
    glUniform1f(getShaderUniformLocation(name, shaderProgram), value);
}

void Renderer::setShaderUniform(std::string name, bool value, std::string shaderProgram) {
    glUniform1i(getShaderUniformLocation(name, shaderProgram), value);
}

void Renderer::setShaderUniform(std::string name, int value, std::string shaderProgram) {
    glUniform1i(getShaderUniformLocation(name, shaderProgram), value);
}

int Renderer::getShaderUniformLocation(std::string name, std::string shaderProgram) {
    int location = glGetUniformLocation(getShaderProgram(shaderProgram), name.c_str());
    if(location == -1)
        throw Exception("Unable to find location of matrix4f uniform " + name + " in shader program " + shaderProgram);
    return location;
}

void Renderer::reset() {
    mStop = false;
    mHasRendered = false;
}

}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_FEATURE_HPP
#define MAPNIK_FEATURE_HPP

// mapnik
#include <mapnik/value.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/raster.hpp>

// boost
#include <boost/version.hpp>
#if BOOST_VERSION >= 104000
#include <boost/property_map/property_map.hpp>
#else
#include <boost/property_map.hpp>
#endif
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>

// stl
#include <map>

namespace mapnik {

typedef boost::shared_ptr<raster> raster_ptr;
typedef std::map<std::string,int> map_type;
typedef boost::associative_property_map<map_type> base_type;

class feature_impl;

class context : private boost::noncopyable,
                public base_type

{
    friend class feature_impl;
public:

    context()
        : base_type(mapping_) {}

    void push(std::string const& name)
    {
        mapping_.insert(std::make_pair(name,mapping_.size()));
    }

private:
    map_type mapping_;
};

typedef boost::shared_ptr<context> context_ptr;

class feature_impl : private boost::noncopyable
{
public:
    typedef mapnik::value value_type;
    typedef std::vector<value_type> cont_type;

    feature_impl(context_ptr const& ctx, int id)
        : id_(id),
          ctx_(ctx),
          data_(ctx_->mapping_.size())
    {}

    inline int id() const { return id_;}

    inline void set_id(int id) { id_ = id;}

    template <typename T>
    void put(std::string const& key, T const& val)
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            data_[itr->second] = value(val);
        }
    }

    void put(std::string const& key, value const& val)
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            data_[itr->second] = val;
        }
    }

    value_type const& get(std::string const& key) const
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            return data_[itr->second];
        }
        static const value_type default_value;
        return default_value;
    }

    boost::ptr_vector<geometry_type> & paths()
    {
        return geom_cont_;
    }

    void add_geometry(geometry_type * geom)
    {
        geom_cont_.push_back(geom);
    }

    unsigned num_geometries() const
    {
        return geom_cont_.size();
    }

    geometry_type const& get_geometry(unsigned index) const
    {
        return geom_cont_[index];
    }

    geometry_type& get_geometry(unsigned index)
    {
        return geom_cont_[index];
    }

    box2d<double> envelope() const
    {
        box2d<double> result;
        for (unsigned i=0;i<num_geometries();++i)
        {
            geometry_type const& geom = get_geometry(i);
            if (i==0)
            {
                box2d<double> box = geom.envelope();
                result.init(box.minx(),box.miny(),box.maxx(),box.maxy());
            }
            else
            {
                result.expand_to_include(geom.envelope());
            }
        }
        return result;
    }

    const raster_ptr& get_raster() const
    {
        return raster_;
    }

    void set_raster(raster_ptr const& raster)
    {
        raster_ = raster;
    }

    std::string to_string() const
    {
        std::stringstream ss;
        ss << "Feature (" << std::endl;
        map_type::const_iterator itr = ctx_->mapping_.begin();
        map_type::const_iterator end = ctx_->mapping_.end();
        for ( ;itr!=end; ++itr)
        {
            ss << "  " << itr->first  << ":" <<  data_[itr->second] << std::endl;
        }
        ss << ")" << std::endl;
        return ss.str();
    }

private:
    int id_;
    context_ptr ctx_;
    boost::ptr_vector<geometry_type> geom_cont_;
    raster_ptr raster_;
    cont_type data_;
};

inline std::ostream& operator<< (std::ostream & out,feature_impl const& f)
{
    out << f.to_string();
    return out;
}

typedef feature_impl Feature;

}

#endif // MAPNIK_FEATURE_HPP
<commit_msg>+ add typedefs<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_FEATURE_HPP
#define MAPNIK_FEATURE_HPP

// mapnik
#include <mapnik/value.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/raster.hpp>

// boost
#include <boost/version.hpp>
#if BOOST_VERSION >= 104000
#include <boost/property_map/property_map.hpp>
#else
#include <boost/property_map.hpp>
#endif
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>

// stl
#include <map>

namespace mapnik {

typedef boost::shared_ptr<raster> raster_ptr;
typedef std::map<std::string,int> map_type;
typedef boost::associative_property_map<map_type> base_type;

class feature_impl;

class context : private boost::noncopyable,
                public base_type

{
    friend class feature_impl;
public:
    typedef map_type::value_type value_type;
    typedef map_type::key_type key_type;
    typedef map_type::size_type size_type;
    typedef map_type::difference_type difference_type;
    typedef map_type::iterator iterator;

    context()
        : base_type(mapping_) {}

    void push(std::string const& name)
    {
        mapping_.insert(std::make_pair(name,mapping_.size()));
    }

private:
    map_type mapping_;
};

typedef boost::shared_ptr<context> context_ptr;

class feature_impl : private boost::noncopyable
{
public:
    typedef mapnik::value value_type;
    typedef std::vector<value_type> cont_type;

    feature_impl(context_ptr const& ctx, int id)
        : id_(id),
          ctx_(ctx),
          data_(ctx_->mapping_.size())
    {}

    inline int id() const { return id_;}

    inline void set_id(int id) { id_ = id;}

    template <typename T>
    void put(std::string const& key, T const& val)
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            data_[itr->second] = value(val);
        }
    }

    void put(std::string const& key, value const& val)
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            data_[itr->second] = val;
        }
    }

    value_type const& get(std::string const& key) const
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            return data_[itr->second];
        }
        static const value_type default_value;
        return default_value;
    }

    boost::ptr_vector<geometry_type> & paths()
    {
        return geom_cont_;
    }

    void add_geometry(geometry_type * geom)
    {
        geom_cont_.push_back(geom);
    }

    unsigned num_geometries() const
    {
        return geom_cont_.size();
    }

    geometry_type const& get_geometry(unsigned index) const
    {
        return geom_cont_[index];
    }

    geometry_type& get_geometry(unsigned index)
    {
        return geom_cont_[index];
    }

    box2d<double> envelope() const
    {
        box2d<double> result;
        for (unsigned i=0;i<num_geometries();++i)
        {
            geometry_type const& geom = get_geometry(i);
            if (i==0)
            {
                box2d<double> box = geom.envelope();
                result.init(box.minx(),box.miny(),box.maxx(),box.maxy());
            }
            else
            {
                result.expand_to_include(geom.envelope());
            }
        }
        return result;
    }

    const raster_ptr& get_raster() const
    {
        return raster_;
    }

    void set_raster(raster_ptr const& raster)
    {
        raster_ = raster;
    }

    std::string to_string() const
    {
        std::stringstream ss;
        ss << "Feature (" << std::endl;
        map_type::const_iterator itr = ctx_->mapping_.begin();
        map_type::const_iterator end = ctx_->mapping_.end();
        for ( ;itr!=end; ++itr)
        {
            ss << "  " << itr->first  << ":" <<  data_[itr->second] << std::endl;
        }
        ss << ")" << std::endl;
        return ss.str();
    }

private:
    int id_;
    context_ptr ctx_;
    boost::ptr_vector<geometry_type> geom_cont_;
    raster_ptr raster_;
    cont_type data_;
};

inline std::ostream& operator<< (std::ostream & out,feature_impl const& f)
{
    out << f.to_string();
    return out;
}

typedef feature_impl Feature;

}

#endif // MAPNIK_FEATURE_HPP
<|endoftext|>


<commit_before>// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TEveGeoNodeEditor.h"
#include "TEveGValuators.h"

#include "TEveGeoNode.h"
#include "TGeoNode.h"

#include "TVirtualPad.h"
#include "TColor.h"

#include "TGLabel.h"
#include "TGButton.h"
#include "TGNumberEntry.h"
#include "TGColorSelect.h"
#include "TGDoubleSlider.h"

//______________________________________________________________________________
// TEveGeoNodeEditor
//
// Editor for TEveGeoNode class.

ClassImp(TEveGeoNodeEditor)

//______________________________________________________________________________
TEveGeoNodeEditor::TEveGeoNodeEditor(const TGWindow *p,
                                     Int_t width, Int_t height,
                                     UInt_t options, Pixel_t back) :
   TGedFrame(p,width, height, options | kVerticalFrame, back),

   fNodeRE (0),

   fVizNode(0),
   fVizNodeDaughters(0),
   fVizVolume(0),
   fVizVolumeDaughters(0)
{
   // Constructor.

   MakeTitle("GeoNode");

   // --- Visibility control

   fVizNode = new TGCheckButton(this, "VizNode");
   AddFrame(fVizNode, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
   fVizNode->Connect
      ("Toggled(Bool_t)",
       "TEveGeoNodeEditor", this, "DoVizNode()");

   fVizNodeDaughters = new TGCheckButton(this, "VizNodeDaughters");
   AddFrame(fVizNodeDaughters, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
   fVizNodeDaughters->Connect
      ("Toggled(Bool_t)",
       "TEveGeoNodeEditor", this, "DoVizNodeDaughters()");

   fVizVolume = new TGCheckButton(this, "VizVolume");
   AddFrame(fVizVolume, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
   fVizVolume->Connect
      ("Toggled(Bool_t)",
       "TEveGeoNodeEditor", this, "DoVizVolume()");

   fVizVolumeDaughters = new TGCheckButton(this, "VizVolumeDaughters");
   AddFrame(fVizVolumeDaughters, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
   fVizVolumeDaughters->Connect
      ("Toggled(Bool_t)",
       "TEveGeoNodeEditor", this, "DoVizVolumeDaughters()");
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoNodeEditor::SetModel(TObject* obj)
{
   // Set model object.

   fNodeRE = dynamic_cast<TEveGeoNode*>(obj);
   TGeoNode*  node = fNodeRE->fNode;
   TGeoVolume* vol = node->GetVolume();

   fVizNode->SetState(node->TGeoAtt::IsVisible() ? kButtonDown : kButtonUp);
   fVizNodeDaughters->SetState(node->TGeoAtt::IsVisDaughters() ? kButtonDown : kButtonUp);
   fVizVolume->SetState(vol->IsVisible() ? kButtonDown : kButtonUp);
   fVizVolumeDaughters->SetState(vol->IsVisDaughters() ? kButtonDown : kButtonUp);
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoNodeEditor::DoVizNode()
{
   // Slot for VizNode.

   fNodeRE->SetRnrSelf(fVizNode->IsOn());
   Update();
}

//______________________________________________________________________________
void TEveGeoNodeEditor::DoVizNodeDaughters()
{
   // Slot for VizNodeDaughters.

   fNodeRE->SetRnrChildren(fVizNodeDaughters->IsOn());
   Update();
}

//______________________________________________________________________________
void TEveGeoNodeEditor::DoVizVolume()
{
   // Slot for VizVolume.

   fNodeRE->fNode->GetVolume()->SetVisibility(fVizVolume->IsOn());
   Update();
}

//______________________________________________________________________________
void TEveGeoNodeEditor::DoVizVolumeDaughters()
{
   // Slot for VizVolumeDaughters.

   fNodeRE->fNode->GetVolume()->VisibleDaughters(fVizVolumeDaughters->IsOn());
   Update();
}

//______________________________________________________________________________
// TEveGeoTopNodeEditor
//
// Editor for TEveGeoTopNode class.

ClassImp(TEveGeoTopNodeEditor)

//______________________________________________________________________________
TEveGeoTopNodeEditor::TEveGeoTopNodeEditor(const TGWindow *p,
                                           Int_t width, Int_t height,
                                           UInt_t options, Pixel_t back) :
   TGedFrame(p, width, height, options | kVerticalFrame, back),

   fTopNodeRE   (0),
   fVisOption   (0),
   fVisLevel    (0),
   fMaxVisNodes (0)
{
   // Constructor.

   MakeTitle("GeoTopNode");

   Int_t labelW = 64;

   fVisOption = new TEveGValuator(this, "VisOption:", 90, 0);
   fVisOption->SetLabelWidth(labelW);
   fVisOption->SetShowSlider(kFALSE);
   fVisOption->SetNELength(4);
   fVisOption->Build();
   fVisOption->SetLimits(0, 2, 10, TGNumberFormat::kNESInteger);
   fVisOption->SetToolTip("Visualization option passed to TGeoPainter.");
   fVisOption->Connect("ValueSet(Double_t)", "TEveGeoTopNodeEditor", this, "DoVisOption()");
   AddFrame(fVisOption, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));

   fVisLevel = new TEveGValuator(this, "VisLevel:", 90, 0);
   fVisLevel->SetLabelWidth(labelW);
   fVisLevel->SetShowSlider(kFALSE);
   fVisLevel->SetNELength(4);
   fVisLevel->Build();
   fVisLevel->SetLimits(0, 10, 10, TGNumberFormat::kNESInteger);
   fVisLevel->SetToolTip("Level (depth) to which the geometry is traversed.\nWhen zero, maximum number of nodes to draw can be specified.");
   fVisLevel->Connect("ValueSet(Double_t)", "TEveGeoTopNodeEditor", this, "DoVisLevel()");
   AddFrame(fVisLevel, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));

   fMaxVisNodes = new TEveGValuator(this, "MaxNodes:", 90, 0);
   fMaxVisNodes->SetLabelWidth(labelW);
   fMaxVisNodes->SetShowSlider(kFALSE);
   fMaxVisNodes->SetNELength(6);
   fMaxVisNodes->Build();
   fMaxVisNodes->SetLimits(100, 999999, 0, TGNumberFormat::kNESInteger);
   fMaxVisNodes->SetToolTip("Maximum number of nodes to draw.");
   fMaxVisNodes->Connect("ValueSet(Double_t)", "TEveGeoTopNodeEditor", this, "DoMaxVisNodes()");
   AddFrame(fMaxVisNodes, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoTopNodeEditor::SetModel(TObject* obj)
{
   // Set model object.

   fTopNodeRE = dynamic_cast<TEveGeoTopNode*>(obj);

   fVisOption  ->SetValue(fTopNodeRE->GetVisOption());
   fVisLevel   ->SetValue(fTopNodeRE->GetVisLevel());
   fMaxVisNodes->SetValue(fTopNodeRE->GetMaxVisNodes());
   if (fTopNodeRE->GetVisLevel() > 0)
      fMaxVisNodes->UnmapWindow();
   else
      fMaxVisNodes->MapWindow();
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoTopNodeEditor::DoVisOption()
{
   // Slot for VisOption.

   fTopNodeRE->SetVisOption(Int_t(fVisOption->GetValue()));
   Update();
}

//______________________________________________________________________________
void TEveGeoTopNodeEditor::DoVisLevel()
{
   // Slot for VisLevel.

   fTopNodeRE->SetVisLevel(Int_t(fVisLevel->GetValue()));
   Update();
}

//______________________________________________________________________________
void TEveGeoTopNodeEditor::DoMaxVisNodes()
{
   // Slot for MaxVisNodes.

   fTopNodeRE->SetMaxVisNodes(Int_t(fMaxVisNodes->GetValue()));
   Update();
}
<commit_msg>Increase GUI maximum for visibility level of TEveGeoNode to 30. Requested by PANDA@FAIR.<commit_after>// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TEveGeoNodeEditor.h"
#include "TEveGValuators.h"

#include "TEveGeoNode.h"
#include "TGeoNode.h"

#include "TVirtualPad.h"
#include "TColor.h"

#include "TGLabel.h"
#include "TGButton.h"
#include "TGNumberEntry.h"
#include "TGColorSelect.h"
#include "TGDoubleSlider.h"

//______________________________________________________________________________
// TEveGeoNodeEditor
//
// Editor for TEveGeoNode class.

ClassImp(TEveGeoNodeEditor)

//______________________________________________________________________________
TEveGeoNodeEditor::TEveGeoNodeEditor(const TGWindow *p,
                                     Int_t width, Int_t height,
                                     UInt_t options, Pixel_t back) :
   TGedFrame(p,width, height, options | kVerticalFrame, back),

   fNodeRE (0),

   fVizNode(0),
   fVizNodeDaughters(0),
   fVizVolume(0),
   fVizVolumeDaughters(0)
{
   // Constructor.

   MakeTitle("GeoNode");

   // --- Visibility control

   fVizNode = new TGCheckButton(this, "VizNode");
   AddFrame(fVizNode, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
   fVizNode->Connect
      ("Toggled(Bool_t)",
       "TEveGeoNodeEditor", this, "DoVizNode()");

   fVizNodeDaughters = new TGCheckButton(this, "VizNodeDaughters");
   AddFrame(fVizNodeDaughters, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
   fVizNodeDaughters->Connect
      ("Toggled(Bool_t)",
       "TEveGeoNodeEditor", this, "DoVizNodeDaughters()");

   fVizVolume = new TGCheckButton(this, "VizVolume");
   AddFrame(fVizVolume, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
   fVizVolume->Connect
      ("Toggled(Bool_t)",
       "TEveGeoNodeEditor", this, "DoVizVolume()");

   fVizVolumeDaughters = new TGCheckButton(this, "VizVolumeDaughters");
   AddFrame(fVizVolumeDaughters, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
   fVizVolumeDaughters->Connect
      ("Toggled(Bool_t)",
       "TEveGeoNodeEditor", this, "DoVizVolumeDaughters()");
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoNodeEditor::SetModel(TObject* obj)
{
   // Set model object.

   fNodeRE = dynamic_cast<TEveGeoNode*>(obj);
   TGeoNode*  node = fNodeRE->fNode;
   TGeoVolume* vol = node->GetVolume();

   fVizNode->SetState(node->TGeoAtt::IsVisible() ? kButtonDown : kButtonUp);
   fVizNodeDaughters->SetState(node->TGeoAtt::IsVisDaughters() ? kButtonDown : kButtonUp);
   fVizVolume->SetState(vol->IsVisible() ? kButtonDown : kButtonUp);
   fVizVolumeDaughters->SetState(vol->IsVisDaughters() ? kButtonDown : kButtonUp);
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoNodeEditor::DoVizNode()
{
   // Slot for VizNode.

   fNodeRE->SetRnrSelf(fVizNode->IsOn());
   Update();
}

//______________________________________________________________________________
void TEveGeoNodeEditor::DoVizNodeDaughters()
{
   // Slot for VizNodeDaughters.

   fNodeRE->SetRnrChildren(fVizNodeDaughters->IsOn());
   Update();
}

//______________________________________________________________________________
void TEveGeoNodeEditor::DoVizVolume()
{
   // Slot for VizVolume.

   fNodeRE->fNode->GetVolume()->SetVisibility(fVizVolume->IsOn());
   Update();
}

//______________________________________________________________________________
void TEveGeoNodeEditor::DoVizVolumeDaughters()
{
   // Slot for VizVolumeDaughters.

   fNodeRE->fNode->GetVolume()->VisibleDaughters(fVizVolumeDaughters->IsOn());
   Update();
}

//______________________________________________________________________________
// TEveGeoTopNodeEditor
//
// Editor for TEveGeoTopNode class.

ClassImp(TEveGeoTopNodeEditor)

//______________________________________________________________________________
TEveGeoTopNodeEditor::TEveGeoTopNodeEditor(const TGWindow *p,
                                           Int_t width, Int_t height,
                                           UInt_t options, Pixel_t back) :
   TGedFrame(p, width, height, options | kVerticalFrame, back),

   fTopNodeRE   (0),
   fVisOption   (0),
   fVisLevel    (0),
   fMaxVisNodes (0)
{
   // Constructor.

   MakeTitle("GeoTopNode");

   Int_t labelW = 64;

   fVisOption = new TEveGValuator(this, "VisOption:", 90, 0);
   fVisOption->SetLabelWidth(labelW);
   fVisOption->SetShowSlider(kFALSE);
   fVisOption->SetNELength(4);
   fVisOption->Build();
   fVisOption->SetLimits(0, 2, 10, TGNumberFormat::kNESInteger);
   fVisOption->SetToolTip("Visualization option passed to TGeoPainter.");
   fVisOption->Connect("ValueSet(Double_t)", "TEveGeoTopNodeEditor", this, "DoVisOption()");
   AddFrame(fVisOption, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));

   fVisLevel = new TEveGValuator(this, "VisLevel:", 90, 0);
   fVisLevel->SetLabelWidth(labelW);
   fVisLevel->SetShowSlider(kFALSE);
   fVisLevel->SetNELength(4);
   fVisLevel->Build();
   fVisLevel->SetLimits(0, 30, 31, TGNumberFormat::kNESInteger);
   fVisLevel->SetToolTip("Level (depth) to which the geometry is traversed.\nWhen zero, maximum number of nodes to draw can be specified.");
   fVisLevel->Connect("ValueSet(Double_t)", "TEveGeoTopNodeEditor", this, "DoVisLevel()");
   AddFrame(fVisLevel, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));

   fMaxVisNodes = new TEveGValuator(this, "MaxNodes:", 90, 0);
   fMaxVisNodes->SetLabelWidth(labelW);
   fMaxVisNodes->SetShowSlider(kFALSE);
   fMaxVisNodes->SetNELength(6);
   fMaxVisNodes->Build();
   fMaxVisNodes->SetLimits(100, 999999, 0, TGNumberFormat::kNESInteger);
   fMaxVisNodes->SetToolTip("Maximum number of nodes to draw.");
   fMaxVisNodes->Connect("ValueSet(Double_t)", "TEveGeoTopNodeEditor", this, "DoMaxVisNodes()");
   AddFrame(fMaxVisNodes, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoTopNodeEditor::SetModel(TObject* obj)
{
   // Set model object.

   fTopNodeRE = dynamic_cast<TEveGeoTopNode*>(obj);

   fVisOption  ->SetValue(fTopNodeRE->GetVisOption());
   fVisLevel   ->SetValue(fTopNodeRE->GetVisLevel());
   fMaxVisNodes->SetValue(fTopNodeRE->GetMaxVisNodes());
   if (fTopNodeRE->GetVisLevel() > 0)
      fMaxVisNodes->UnmapWindow();
   else
      fMaxVisNodes->MapWindow();
}

/******************************************************************************/

//______________________________________________________________________________
void TEveGeoTopNodeEditor::DoVisOption()
{
   // Slot for VisOption.

   fTopNodeRE->SetVisOption(Int_t(fVisOption->GetValue()));
   Update();
}

//______________________________________________________________________________
void TEveGeoTopNodeEditor::DoVisLevel()
{
   // Slot for VisLevel.

   fTopNodeRE->SetVisLevel(Int_t(fVisLevel->GetValue()));
   Update();
}

//______________________________________________________________________________
void TEveGeoTopNodeEditor::DoMaxVisNodes()
{
   // Slot for MaxVisNodes.

   fTopNodeRE->SetMaxVisNodes(Int_t(fMaxVisNodes->GetValue()));
   Update();
}
<|endoftext|>


<commit_before>/*
 * This file is part of the Yildiz-Engine project, licenced under the MIT License  (MIT)
 *
 * Copyright (c) 2019 Grégory Van den Borre
 *
 * More infos available: https://engine.yildiz-games.be
 *
 * 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.
 */

/**
*@author Grégory Van den Borre
*/

#include "../includes/Root.hpp"
#include "../includes/EnumConversion.h"
#include "../includes/JniRoot.h"

JNIEXPORT void JNICALL Java_jni_JniRoot_constructor(
    JNIEnv *env,
    jobject) {
    LOG_FUNCTION
    try {
        yz::Root::create();
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_initPhysFS(
    JNIEnv *env,
    jobject,
    POINTER vfsPointer) {
    LOG_FUNCTION
    yz::ogre::vfs::registerPhysFSToOgre(reinterpret_cast<yz::physfs::Wrapper*>(vfsPointer));
}

JNIEXPORT void JNICALL Java_jni_JniRoot_loadPlugin(
    JNIEnv* env,
    jobject,
    jstring jplugin) {
    LOG_FUNCTION
    JniStringWrapper plugin = JniStringWrapper(env, jplugin);
    try {
        yz::Root::get()->loadPlugin(plugin.getValue());
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_loadRenderer(
    JNIEnv *env,
    jobject,
    jstring jrenderer) {
    LOG_FUNCTION
    JniStringWrapper renderer = JniStringWrapper(env, jrenderer);
    try {
        yz::Root::get()->initialise(renderer.getValue());
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT POINTER JNICALL Java_jni_JniRoot_createSceneManager(
    JNIEnv* env,
    jobject,
    jstring jname) {
    LOG_FUNCTION
    JniStringWrapper name = JniStringWrapper(env, jname);
    try {
        return reinterpret_cast<POINTER>(yz::Root::get()->createSceneManager(name.getValue()));
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
    return INVALID_POINTER;
}

JNIEXPORT void JNICALL Java_jni_JniRoot_createRenderWindow(
    JNIEnv* env,
    jobject,
    jint width,
    jint height,
    jlong handle) {
    LOG_FUNCTION
    try {
        yz::Root::get()->createRenderWindow(width, height, handle);
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_createRenderWindowGlContext(
    JNIEnv* env,
    jobject,
    jint width,
    jint height) {
    LOG_FUNCTION
    try {
        yz::Root::get()->createRenderWindow(width, height);
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_addResourcePath(
    JNIEnv* env,
    jobject,
    jstring jname,
    jstring jpath,
    jint type) {
    LOG_FUNCTION
    JniStringWrapper name = JniStringWrapper(env, jname);
    JniStringWrapper path = JniStringWrapper(env, jpath);
    try {
        yz::Root::get()->addResourcePath(name.getValue(), path.getValue(), type);
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_renderOneFrame(
    JNIEnv* env,
    jobject) {
    LOG_FUNCTION
    try {
        yz::Root::get()->renderOneFrame();
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_close(
    JNIEnv* env,
    jobject) {
    LOG_FUNCTION
    try {
        yz::Root::get()->close();
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}
<commit_msg>Update JniRoot.cpp<commit_after>/*
 * This file is part of the Yildiz-Engine project, licenced under the MIT License  (MIT)
 *
 * Copyright (c) 2019 Grégory Van den Borre
 *
 * More infos available: https://engine.yildiz-games.be
 *
 * 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.
 */

/**
*@author Grégory Van den Borre
*/

#include <OgreArchiveManager.h>
#include "../includes/Root.hpp"
#include "../includes/EnumConversion.h"
#include "../includes/JniRoot.h"

JNIEXPORT void JNICALL Java_jni_JniRoot_constructor(
    JNIEnv *env,
    jobject) {
    LOG_FUNCTION
    try {
        yz::Root::create();
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_initPhysFS(
    JNIEnv *env,
    jobject,
    POINTER vfsPointer) {
    LOG_FUNCTION
    Ogre::ArchiveManager::getSingleton().addArchiveFactory(new ArchiveFactory(reinterpret_cast<yz::physfs::Wrapper*>(vfsPointer)));
}

JNIEXPORT void JNICALL Java_jni_JniRoot_loadPlugin(
    JNIEnv* env,
    jobject,
    jstring jplugin) {
    LOG_FUNCTION
    JniStringWrapper plugin = JniStringWrapper(env, jplugin);
    try {
        yz::Root::get()->loadPlugin(plugin.getValue());
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_loadRenderer(
    JNIEnv *env,
    jobject,
    jstring jrenderer) {
    LOG_FUNCTION
    JniStringWrapper renderer = JniStringWrapper(env, jrenderer);
    try {
        yz::Root::get()->initialise(renderer.getValue());
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT POINTER JNICALL Java_jni_JniRoot_createSceneManager(
    JNIEnv* env,
    jobject,
    jstring jname) {
    LOG_FUNCTION
    JniStringWrapper name = JniStringWrapper(env, jname);
    try {
        return reinterpret_cast<POINTER>(yz::Root::get()->createSceneManager(name.getValue()));
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
    return INVALID_POINTER;
}

JNIEXPORT void JNICALL Java_jni_JniRoot_createRenderWindow(
    JNIEnv* env,
    jobject,
    jint width,
    jint height,
    jlong handle) {
    LOG_FUNCTION
    try {
        yz::Root::get()->createRenderWindow(width, height, handle);
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_createRenderWindowGlContext(
    JNIEnv* env,
    jobject,
    jint width,
    jint height) {
    LOG_FUNCTION
    try {
        yz::Root::get()->createRenderWindow(width, height);
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_addResourcePath(
    JNIEnv* env,
    jobject,
    jstring jname,
    jstring jpath,
    jint type) {
    LOG_FUNCTION
    JniStringWrapper name = JniStringWrapper(env, jname);
    JniStringWrapper path = JniStringWrapper(env, jpath);
    try {
        yz::Root::get()->addResourcePath(name.getValue(), path.getValue(), type);
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_renderOneFrame(
    JNIEnv* env,
    jobject) {
    LOG_FUNCTION
    try {
        yz::Root::get()->renderOneFrame();
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}

JNIEXPORT void JNICALL Java_jni_JniRoot_close(
    JNIEnv* env,
    jobject) {
    LOG_FUNCTION
    try {
        yz::Root::get()->close();
    } catch (std::exception& e) {
        throwException(env, e.what());
    }
}
<|endoftext|>


<commit_before><commit_msg>fixed multithreading bug<commit_after><|endoftext|>