<commit_before>/*/////////////////////////////////////////////////////////////////////////////////
/// An
///    ___   ____ ___ _____ ___  ____
///   / _ \ / ___|_ _|_   _/ _ \|  _ \
///  | | | | |  _ | |  | || | | | |_) |
///  | |_| | |_| || |  | || |_| |  _ <
///   \___/ \____|___| |_| \___/|_| \_\
///                              File
///
/// Copyright (c) 2008-2011 Ismail TARIM <ismail@royalspor.com> and the Ogitor Team
//
/// The MIT License
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////*/
#include "shortcuts.hxx"

#include <QtGui/QAction>
#include <QtGui/QMessageBox>

Shortcuts* Shortcuts::instance = 0;

Shortcuts::Shortcuts()
{

}

Shortcuts* Shortcuts::getInstance()
{
    if (instance == 0)
    {
       QMessageBox msgBox;
       msgBox.setText("Some function wanted the instance of the\nShortcuts class what is nonexistent at the moment.\nThis is probably a bug.");
       msgBox.setWindowTitle("Shortcut instance not found!");
#if OGRE_PLATFORM != OGRE_PLATFORM_LINUX
       msgBox.setIcon(QMessageBox::Icon::Critical);
#endif
       msgBox.exec();
    }

    return instance;
}

void Shortcuts::add(const QString &shortcut, const QString &description, const QString &SPK, const int &keycode)
{
    if (actions.contains(cleanName(SPK)))
        return;

    ShortCut tmpShortCut;
    tmpShortCut.shortcut = shortcut;
    tmpShortCut.description = description;
    tmpShortCut.SPK = SPK;
    tmpShortCut.keycode = keycode;
    actions[cleanName(SPK)] = tmpShortCut;
    QString key = settingsKey(tmpShortCut);
    if (!settings.contains(key))
    {
        settings.setValue(settingsKey(actions[cleanName(SPK)]), shortcut);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_description"), description);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_SPK"), SPK);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_keycode"), keycode);

        settings.setValue(QString("orig_") + settingsKey(actions[cleanName(SPK)]), shortcut);
        settings.setValue(QString("orig_") + settingsKey(actions[cleanName(SPK)] ) + QString("_description"), description);
        settings.setValue(QString("orig_") + settingsKey(actions[cleanName(SPK)] ) + QString("_SPK"), SPK);
        settings.setValue(QString("orig_") + settingsKey(actions[cleanName(SPK)] ) + QString("_keycode"), keycode);
    }
}

QList<ShortCut> Shortcuts::getActions()
{
    return actions.values();
}

QString Shortcuts::settingsKey(ShortCut &shortcut)
{
    return QString("OgitorShortcuts/%1").arg(cleanName(shortcut));
}

QString Shortcuts::settingsKey(const QString &shortcut)
{
    return QString("OgitorShortcuts/%1").arg(cleanName(shortcut));
}

QString Shortcuts::cleanName(const ShortCut &shortcut)
{
    return cleanName(shortcut.SPK);
}

QString Shortcuts::cleanName(const QString &s)
{

    QString h = s;
    return h.remove("&");
}

QString Shortcuts::isReserved(const QString &shortcut, const QString &SPK)
{
    QString isTaken = QString::null;
    if (actions.contains(cleanName(SPK))) {
        QList<ShortCut> alist = actions.values();
        foreach(ShortCut act, alist) {
            if (act.shortcut == shortcut) {
                isTaken = act.shortcut;
                break;
            }
        }
    }
    return isTaken;
}

void Shortcuts::setShortcut(const QString &shortcut, const QString &description, const QString &SPK, const int &keycode)
{
    if (actions.contains(cleanName(SPK)))
    {
        actions[cleanName(SPK)].shortcut = shortcut;
        actions[cleanName(SPK)].description = description;
        actions[cleanName(SPK)].keycode = keycode;
        settings.setValue(settingsKey(actions[cleanName(SPK)]), shortcut);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_description"), description);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_keycode"), keycode);
    }
}

void Shortcuts::clearShortcut(const QString &SPK)
{
    if (actions.contains(cleanName(SPK)))
    {
        QString shortcut = settings.value(QString("orig_") + settingsKey(actions[cleanName(SPK)]), "").toString();
        int keycode = settings.value(QString("orig_") + settingsKey(actions[cleanName(SPK)]) + QString("_keycode"), 0).toInt();
        actions[cleanName(SPK)].shortcut = shortcut;
        actions[cleanName(SPK)].keycode = keycode;
    }
}

void Shortcuts::removeShortcut(const QString &SPK)
{
    settings.remove(settingsKey(actions[cleanName(SPK)]));
}

void Shortcuts::load()
{
    QString shortcut = settings.value(settingsKey("SPK_FORWARD"), "W").toString();
    QString description = tr("Move Forwards");
    QString SPK = settings.value(settingsKey("SPK_FORWARD_SPK"), "SPK_FORWARD").toString();
    int keycode = settings.value(settingsKey("SPK_FORWARD_keycode"), Qt::Key_W).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_LEFT"), "A").toString();
    description = tr("Move Left");
    SPK = settings.value(settingsKey("SPK_LEFT_SPK"), "SPK_LEFT").toString();
    keycode = settings.value(settingsKey("SPK_LEFT_keycode"), Qt::Key_A).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_BACKWARD"), "S").toString();
    description = tr("Move Backwards");
    SPK = settings.value(settingsKey("SPK_BACKWARD_SPK"), "SPK_BACKWARD").toString();
    keycode = settings.value(settingsKey("SPK_BACKWARD_keycode"), Qt::Key_S).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_RIGHT"), "D").toString();
    description = tr("Move Right");
    SPK = settings.value(settingsKey("SPK_RIGHT_SPK"), "SPK_RIGHT").toString();
    keycode = settings.value(settingsKey("SPK_RIGHT_keycode"), Qt::Key_D).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_UP"), "E").toString();
    description = tr("Move Up");
    SPK = settings.value(settingsKey("SPK_UP_SPK"), "SPK_UP").toString();
    keycode = settings.value(settingsKey("SPK_UP_keycode"), Qt::Key_E).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_DOWN"), "Q").toString();
    description = tr("Move Down");
    SPK = settings.value(settingsKey("SPK_DOWN_SPK"), "SPK_DOWN").toString();
    keycode = settings.value(settingsKey("SPK_DOWN_keycode"), Qt::Key_Q).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_OBJECT_CENTERED_MOVEMENT"), "Alt").toString();
    description = tr("Object Centered Movement Modifier Key");
    SPK = settings.value(settingsKey("SPK_OBJECT_CENTERED_MOVEMENT_SPK"), "SPK_OBJECT_CENTERED_MOVEMENT").toString();
    keycode = settings.value(settingsKey("SPK_OBJECT_CENTERED_MOVEMENT_keycode"), (Qt::Key_Alt & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_FOCUS_OBJECT"), "F").toString();
    description = tr("Focus Object");
    SPK = settings.value(settingsKey("SPK_FOCUS_OBJECT_SPK"), "SPK_FOCUS_OBJECT").toString();
    keycode = settings.value(settingsKey("SPK_FOCUS_OBJECT_keycode"), Qt::Key_F).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_CLONE"), "Shift").toString();
    description = tr("Clone Modifier");
    SPK = settings.value(settingsKey("SPK_CLONE_SPK"), "SPK_CLONE").toString();
    keycode = settings.value(settingsKey("SPK_CLONE_keycode"), (Qt::Key_Shift & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_DELETE"), "Delete").toString();
    description = tr("Delete Selected");
    SPK = settings.value(settingsKey("SPK_DELETE_SPK"), "SPK_DELETE").toString();
    keycode = settings.value(settingsKey("SPK_DELETE_keycode"), (Qt::Key_Delete & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_REVERSE_UPDATE"), "Shift").toString();
    description = tr("Reverse Update Modifier");
    SPK = settings.value(settingsKey("SPK_REVERSE_UPDATE_SPK"), "SPK_REVERSE_UPDATE").toString();
    keycode = settings.value(settingsKey("SPK_REVERSE_UPDATE_keycode"), (Qt::Key_Shift & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_SWITCH_AXIS"), "End").toString();
    description = tr("Switch Locked Axis");
    SPK = settings.value(settingsKey("SPK_SWITCH_AXIS_SPK"), "SPK_SWITCH_AXIS").toString();
    keycode = settings.value(settingsKey("SPK_SWITCH_AXIS_keycode"), (Qt::Key_End & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_SNAP"), "Ctrl").toString();
    description = tr("Snap to Grid Modifier");
    SPK = settings.value(settingsKey("SPK_SNAP_SPK"), "SPK_SNAP").toString();
    keycode = settings.value(settingsKey("SPK_SNAP_keycode"), (Qt::Key_Control & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_SNAP_GROUND"), "Space").toString();
    description = tr("Snap to Ground Modifier");
    SPK = settings.value(settingsKey("SPK_SNAP_GROUND_SPK"), "SPK_SNAP_GROUND").toString();
    keycode = settings.value(settingsKey("SPK_SNAP_GROUND_keycode"), Qt::Key_Space).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_ADD_TO_SELECTION"), "Shift").toString();
    description = tr("Add to Selection Modifier");
    SPK = settings.value(settingsKey("SPK_ADD_TO_SELECTION_SPK"), "SPK_ADD_TO_SELECTION").toString();
    keycode = settings.value(settingsKey("SPK_ADD_TO_SELECTION_keycode"), (Qt::Key_Shift & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_SUBTRACT_FROM_SELECTION"), "Ctrl").toString();
    description = tr("Subtract from Selection Modifier");
    SPK = settings.value(settingsKey("SPK_SUBTRACT_FROM_SELECTION_SPK"), "SPK_SUBTRACT_FROM_SELECTION").toString();
    keycode = settings.value(settingsKey("SPK_SUBTRACT_FROM_SELECTION_keycode"), (Qt::Key_Control & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_ALWAYS_SELECT"), "Alt").toString();
    description = tr("Always Select Modifier");
    SPK = settings.value(settingsKey("SPK_ALWAYS_SELECT_SPK"), "SPK_ALWAYS_SELECT").toString();
    keycode = settings.value(settingsKey("SPK_ALWAYS_SELECT_keycode"), (Qt::Key_Alt & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);
}

Shortcuts::~Shortcuts()
{
    if (instance != 0)
        delete instance;
}
<commit_msg>- no problem to use it as QMessageBox::Critical in windows, so i changed it to use it instead<commit_after>/*/////////////////////////////////////////////////////////////////////////////////
/// An
///    ___   ____ ___ _____ ___  ____
///   / _ \ / ___|_ _|_   _/ _ \|  _ \
///  | | | | |  _ | |  | || | | | |_) |
///  | |_| | |_| || |  | || |_| |  _ <
///   \___/ \____|___| |_| \___/|_| \_\
///                              File
///
/// Copyright (c) 2008-2011 Ismail TARIM <ismail@royalspor.com> and the Ogitor Team
//
/// The MIT License
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////*/
#include "shortcuts.hxx"

#include <QtGui/QAction>
#include <QtGui/QMessageBox>

Shortcuts* Shortcuts::instance = 0;

Shortcuts::Shortcuts()
{

}

Shortcuts* Shortcuts::getInstance()
{
    if (instance == 0)
    {
       QMessageBox msgBox;
       msgBox.setText("Some function wanted the instance of the\nShortcuts class what is nonexistent at the moment.\nThis is probably a bug.");
       msgBox.setWindowTitle("Shortcut instance not found!");
#if OGRE_PLATFORM != OGRE_PLATFORM_LINUX
       msgBox.setIcon(QMessageBox::Critical);
#endif
       msgBox.exec();
    }

    return instance;
}

void Shortcuts::add(const QString &shortcut, const QString &description, const QString &SPK, const int &keycode)
{
    if (actions.contains(cleanName(SPK)))
        return;

    ShortCut tmpShortCut;
    tmpShortCut.shortcut = shortcut;
    tmpShortCut.description = description;
    tmpShortCut.SPK = SPK;
    tmpShortCut.keycode = keycode;
    actions[cleanName(SPK)] = tmpShortCut;
    QString key = settingsKey(tmpShortCut);
    if (!settings.contains(key))
    {
        settings.setValue(settingsKey(actions[cleanName(SPK)]), shortcut);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_description"), description);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_SPK"), SPK);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_keycode"), keycode);

        settings.setValue(QString("orig_") + settingsKey(actions[cleanName(SPK)]), shortcut);
        settings.setValue(QString("orig_") + settingsKey(actions[cleanName(SPK)] ) + QString("_description"), description);
        settings.setValue(QString("orig_") + settingsKey(actions[cleanName(SPK)] ) + QString("_SPK"), SPK);
        settings.setValue(QString("orig_") + settingsKey(actions[cleanName(SPK)] ) + QString("_keycode"), keycode);
    }
}

QList<ShortCut> Shortcuts::getActions()
{
    return actions.values();
}

QString Shortcuts::settingsKey(ShortCut &shortcut)
{
    return QString("OgitorShortcuts/%1").arg(cleanName(shortcut));
}

QString Shortcuts::settingsKey(const QString &shortcut)
{
    return QString("OgitorShortcuts/%1").arg(cleanName(shortcut));
}

QString Shortcuts::cleanName(const ShortCut &shortcut)
{
    return cleanName(shortcut.SPK);
}

QString Shortcuts::cleanName(const QString &s)
{

    QString h = s;
    return h.remove("&");
}

QString Shortcuts::isReserved(const QString &shortcut, const QString &SPK)
{
    QString isTaken = QString::null;
    if (actions.contains(cleanName(SPK))) {
        QList<ShortCut> alist = actions.values();
        foreach(ShortCut act, alist) {
            if (act.shortcut == shortcut) {
                isTaken = act.shortcut;
                break;
            }
        }
    }
    return isTaken;
}

void Shortcuts::setShortcut(const QString &shortcut, const QString &description, const QString &SPK, const int &keycode)
{
    if (actions.contains(cleanName(SPK)))
    {
        actions[cleanName(SPK)].shortcut = shortcut;
        actions[cleanName(SPK)].description = description;
        actions[cleanName(SPK)].keycode = keycode;
        settings.setValue(settingsKey(actions[cleanName(SPK)]), shortcut);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_description"), description);
        settings.setValue(settingsKey(actions[cleanName(SPK)] ) + QString("_keycode"), keycode);
    }
}

void Shortcuts::clearShortcut(const QString &SPK)
{
    if (actions.contains(cleanName(SPK)))
    {
        QString shortcut = settings.value(QString("orig_") + settingsKey(actions[cleanName(SPK)]), "").toString();
        int keycode = settings.value(QString("orig_") + settingsKey(actions[cleanName(SPK)]) + QString("_keycode"), 0).toInt();
        actions[cleanName(SPK)].shortcut = shortcut;
        actions[cleanName(SPK)].keycode = keycode;
    }
}

void Shortcuts::removeShortcut(const QString &SPK)
{
    settings.remove(settingsKey(actions[cleanName(SPK)]));
}

void Shortcuts::load()
{
    QString shortcut = settings.value(settingsKey("SPK_FORWARD"), "W").toString();
    QString description = tr("Move Forwards");
    QString SPK = settings.value(settingsKey("SPK_FORWARD_SPK"), "SPK_FORWARD").toString();
    int keycode = settings.value(settingsKey("SPK_FORWARD_keycode"), Qt::Key_W).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_LEFT"), "A").toString();
    description = tr("Move Left");
    SPK = settings.value(settingsKey("SPK_LEFT_SPK"), "SPK_LEFT").toString();
    keycode = settings.value(settingsKey("SPK_LEFT_keycode"), Qt::Key_A).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_BACKWARD"), "S").toString();
    description = tr("Move Backwards");
    SPK = settings.value(settingsKey("SPK_BACKWARD_SPK"), "SPK_BACKWARD").toString();
    keycode = settings.value(settingsKey("SPK_BACKWARD_keycode"), Qt::Key_S).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_RIGHT"), "D").toString();
    description = tr("Move Right");
    SPK = settings.value(settingsKey("SPK_RIGHT_SPK"), "SPK_RIGHT").toString();
    keycode = settings.value(settingsKey("SPK_RIGHT_keycode"), Qt::Key_D).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_UP"), "E").toString();
    description = tr("Move Up");
    SPK = settings.value(settingsKey("SPK_UP_SPK"), "SPK_UP").toString();
    keycode = settings.value(settingsKey("SPK_UP_keycode"), Qt::Key_E).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_DOWN"), "Q").toString();
    description = tr("Move Down");
    SPK = settings.value(settingsKey("SPK_DOWN_SPK"), "SPK_DOWN").toString();
    keycode = settings.value(settingsKey("SPK_DOWN_keycode"), Qt::Key_Q).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_OBJECT_CENTERED_MOVEMENT"), "Alt").toString();
    description = tr("Object Centered Movement Modifier Key");
    SPK = settings.value(settingsKey("SPK_OBJECT_CENTERED_MOVEMENT_SPK"), "SPK_OBJECT_CENTERED_MOVEMENT").toString();
    keycode = settings.value(settingsKey("SPK_OBJECT_CENTERED_MOVEMENT_keycode"), (Qt::Key_Alt & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_FOCUS_OBJECT"), "F").toString();
    description = tr("Focus Object");
    SPK = settings.value(settingsKey("SPK_FOCUS_OBJECT_SPK"), "SPK_FOCUS_OBJECT").toString();
    keycode = settings.value(settingsKey("SPK_FOCUS_OBJECT_keycode"), Qt::Key_F).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_CLONE"), "Shift").toString();
    description = tr("Clone Modifier");
    SPK = settings.value(settingsKey("SPK_CLONE_SPK"), "SPK_CLONE").toString();
    keycode = settings.value(settingsKey("SPK_CLONE_keycode"), (Qt::Key_Shift & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_DELETE"), "Delete").toString();
    description = tr("Delete Selected");
    SPK = settings.value(settingsKey("SPK_DELETE_SPK"), "SPK_DELETE").toString();
    keycode = settings.value(settingsKey("SPK_DELETE_keycode"), (Qt::Key_Delete & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_REVERSE_UPDATE"), "Shift").toString();
    description = tr("Reverse Update Modifier");
    SPK = settings.value(settingsKey("SPK_REVERSE_UPDATE_SPK"), "SPK_REVERSE_UPDATE").toString();
    keycode = settings.value(settingsKey("SPK_REVERSE_UPDATE_keycode"), (Qt::Key_Shift & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_SWITCH_AXIS"), "End").toString();
    description = tr("Switch Locked Axis");
    SPK = settings.value(settingsKey("SPK_SWITCH_AXIS_SPK"), "SPK_SWITCH_AXIS").toString();
    keycode = settings.value(settingsKey("SPK_SWITCH_AXIS_keycode"), (Qt::Key_End & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_SNAP"), "Ctrl").toString();
    description = tr("Snap to Grid Modifier");
    SPK = settings.value(settingsKey("SPK_SNAP_SPK"), "SPK_SNAP").toString();
    keycode = settings.value(settingsKey("SPK_SNAP_keycode"), (Qt::Key_Control & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_SNAP_GROUND"), "Space").toString();
    description = tr("Snap to Ground Modifier");
    SPK = settings.value(settingsKey("SPK_SNAP_GROUND_SPK"), "SPK_SNAP_GROUND").toString();
    keycode = settings.value(settingsKey("SPK_SNAP_GROUND_keycode"), Qt::Key_Space).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_ADD_TO_SELECTION"), "Shift").toString();
    description = tr("Add to Selection Modifier");
    SPK = settings.value(settingsKey("SPK_ADD_TO_SELECTION_SPK"), "SPK_ADD_TO_SELECTION").toString();
    keycode = settings.value(settingsKey("SPK_ADD_TO_SELECTION_keycode"), (Qt::Key_Shift & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_SUBTRACT_FROM_SELECTION"), "Ctrl").toString();
    description = tr("Subtract from Selection Modifier");
    SPK = settings.value(settingsKey("SPK_SUBTRACT_FROM_SELECTION_SPK"), "SPK_SUBTRACT_FROM_SELECTION").toString();
    keycode = settings.value(settingsKey("SPK_SUBTRACT_FROM_SELECTION_keycode"), (Qt::Key_Control & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);

    shortcut = settings.value(settingsKey("SPK_ALWAYS_SELECT"), "Alt").toString();
    description = tr("Always Select Modifier");
    SPK = settings.value(settingsKey("SPK_ALWAYS_SELECT_SPK"), "SPK_ALWAYS_SELECT").toString();
    keycode = settings.value(settingsKey("SPK_ALWAYS_SELECT_keycode"), (Qt::Key_Alt & 0xFFF) + 0xFF).toInt();
    add(shortcut, description, SPK, keycode);
}

Shortcuts::~Shortcuts()
{
    if (instance != 0)
        delete instance;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Script Generator project on Qt Labs.
**
** $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 "setupgenerator.h"
#include "shellgenerator.h"
#include "reporthandler.h"
#include "fileout.h"

//#define Q_SCRIPT_LAZY_GENERATOR

void SetupGenerator::addClass(const QString& package, const AbstractMetaClass *cls)
{
  packHash[package].append(cls);
}

void maybeDeclareMetaType(QTextStream &stream, const QString &typeName,
                          QSet<QString> &registeredTypeNames);
bool hasDefaultConstructor(const AbstractMetaClass *meta_class);

void SetupGenerator::generate()
{
  AbstractMetaClassList classes_with_polymorphic_id;
  {
    QHashIterator<QString, QList<const AbstractMetaClass*> > pack(packHash);
    while (pack.hasNext()) {
      pack.next();
      QList<const AbstractMetaClass*> list = pack.value();
      foreach (const AbstractMetaClass *cls, list) {
        if (cls->typeEntry()->isPolymorphicBase()) {
          classes_with_polymorphic_id.append((AbstractMetaClass*)cls);
        }
      }
    }
  }

  QHashIterator<QString, QList<const AbstractMetaClass*> > pack(packHash);
  while (pack.hasNext()) {
    pack.next();
    QList<const AbstractMetaClass*> list = pack.value();
    if (list.isEmpty())
      continue;

    QString packKey = pack.key();
    QString packName = pack.key();
    QStringList components = packName.split("_");
    if ((components.size() > 2) && (components.at(0) == "com")
      && (components.at(1) == "trolltech")) {
        // kill com.trolltech in key
        components.removeAt(0);
        components.removeAt(0);
    }

    QString shortPackName;
    foreach (QString comp, components) {
      comp[0] = comp[0].toUpper();
      shortPackName += comp;
    }
    // add missing camel case (workaround..)
    if (shortPackName == "QtWebkit") {
      shortPackName = "QtWebKit";
    } else if (shortPackName == "QtXmlpatterns") {
      shortPackName = "QtXmlPatterns";
    } else if (shortPackName == "QtOpengl") {
      shortPackName = "QtOpenGL";
    } else if (shortPackName == "QtUitools") {
      shortPackName = "QtUiTools";
    }

    {
      FileOut initFile(m_out_dir + "/generated_cpp/" + packName + "/" + packKey + "_init.cpp");
      QTextStream &s = initFile.stream;

      s << "#include <PythonQt.h>" << endl;

      for (int i=0; i<(list.count()+MAX_CLASSES_PER_FILE-1) / MAX_CLASSES_PER_FILE; i++) {
        s << "#include \"" << packKey << QString::number(i) << ".h\"" << endl;
      }
      s << endl;

      QStringList polymorphicHandlers;
      if (!packName.endsWith("_builtin")) {
        polymorphicHandlers = writePolymorphicHandler(s, list.at(0)->package(), classes_with_polymorphic_id);
        s << endl;
      }

      // declare individual class creation functions
      s << "void PythonQt_init_" << shortPackName << "() {" << endl;

      if (shortPackName.endsWith("Builtin")) {
        shortPackName = shortPackName.mid(shortPackName.length()-strlen("builtin"));
      }

      QStringList cppClassNames;
      foreach (const AbstractMetaClass *cls, list) {

        QString shellCreator;
        if (cls->generateShellClass()) {
          shellCreator = ", PythonQtSetInstanceWrapperOnShell<" + ShellGenerator::shellClassName(cls) + ">";
        }
        if (cls->isQObject()) {
          s << "PythonQt::self()->registerClass(&" << cls->qualifiedCppName() << "::staticMetaObject, \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
        } else {
          QString baseName = cls->baseClass()?cls->baseClass()->qualifiedCppName():"";
          s << "PythonQt::self()->registerCPPClass(\""<< cls->qualifiedCppName() << "\", \"" << baseName << "\", \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
        }
        foreach(AbstractMetaClass* interface, cls->interfaces()) {
          // the interface might be our own class... (e.g. QPaintDevice)
          if (interface->qualifiedCppName() != cls->qualifiedCppName()) {
            s << "PythonQt::self()->addParentClass(\""<< cls->qualifiedCppName() << "\", \"" << interface->qualifiedCppName() << "\",PythonQtUpcastingOffset<" << cls->qualifiedCppName() <<","<<interface->qualifiedCppName()<<">());" << endl;
          }
        }
      }
      s << endl;
      foreach (QString handler, polymorphicHandlers) {
        s << "PythonQt::self()->addPolymorphicHandler(\""<< handler << "\", polymorphichandler_" << handler << ");" << endl;
      }

      s << "}";
      s << endl;
    }
  }
}

QStringList SetupGenerator::writePolymorphicHandler(QTextStream &s, const QString &package,
                                                    const AbstractMetaClassList &classes)
{
  QStringList handlers;
  foreach (AbstractMetaClass *cls, classes) {
    const ComplexTypeEntry *centry = cls->typeEntry();
    if (!centry->isPolymorphicBase())
      continue;
    bool isGraphicsItem = (cls->qualifiedCppName()=="QGraphicsItem");

    AbstractMetaClassList classList = this->classes();
    bool first = true;
    foreach (AbstractMetaClass *clazz, classList) {
      bool inherits = false;
      if (isGraphicsItem) {
        foreach(AbstractMetaClass* interfaze, clazz->interfaces()) {
          if (interfaze->qualifiedCppName()=="QGraphicsItem") {
            inherits = true;
            break;
          }
        }
      } else {
        inherits = clazz->inheritsFrom(cls);
      }
      if (clazz->package() == package && inherits) {
        if (!clazz->typeEntry()->polymorphicIdValue().isEmpty() || isGraphicsItem) {
          // On first find, open the function
          if (first) {
            first = false;

            QString handler = cls->name();
            handlers.append(handler);

            s << "static void* polymorphichandler_" << handler
              << "(const void *ptr, char **class_name)" << endl
              << "{" << endl
              << "    Q_ASSERT(ptr != 0);" << endl
              << "    " << cls->qualifiedCppName() << " *object = ("
              << cls->qualifiedCppName() << " *)ptr;" << endl;
          }

          // For each, add case label
          QString polyId = clazz->typeEntry()->polymorphicIdValue();
          if (isGraphicsItem) {
            polyId = "%1->type() == " + clazz->qualifiedCppName() + "::Type";
          }
          s << "    if ("
            << polyId.replace("%1", "object")
            << ") {" << endl
            << "        *class_name = \"" << clazz->name() << "\";" << endl
            << "        return (" << clazz->qualifiedCppName() << "*)object;" << endl
            << "    }" << endl;
        } else {
          QString warning = QString("class '%1' inherits from polymorphic class '%2', but has no polymorphic id set")
            .arg(clazz->name())
            .arg(cls->name());

          ReportHandler::warning(warning);
        }
      }
    }

    // Close the function if it has been opened
    if (!first) {
      s << "    return NULL;" << endl
        << "}" << endl;
    }
  }

  return handlers;
}
<commit_msg>fixed builtin package name<commit_after>/****************************************************************************
**
** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Script Generator project on Qt Labs.
**
** $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 "setupgenerator.h"
#include "shellgenerator.h"
#include "reporthandler.h"
#include "fileout.h"

//#define Q_SCRIPT_LAZY_GENERATOR

void SetupGenerator::addClass(const QString& package, const AbstractMetaClass *cls)
{
  packHash[package].append(cls);
}

void maybeDeclareMetaType(QTextStream &stream, const QString &typeName,
                          QSet<QString> &registeredTypeNames);
bool hasDefaultConstructor(const AbstractMetaClass *meta_class);

void SetupGenerator::generate()
{
  AbstractMetaClassList classes_with_polymorphic_id;
  {
    QHashIterator<QString, QList<const AbstractMetaClass*> > pack(packHash);
    while (pack.hasNext()) {
      pack.next();
      QList<const AbstractMetaClass*> list = pack.value();
      foreach (const AbstractMetaClass *cls, list) {
        if (cls->typeEntry()->isPolymorphicBase()) {
          classes_with_polymorphic_id.append((AbstractMetaClass*)cls);
        }
      }
    }
  }

  QHashIterator<QString, QList<const AbstractMetaClass*> > pack(packHash);
  while (pack.hasNext()) {
    pack.next();
    QList<const AbstractMetaClass*> list = pack.value();
    if (list.isEmpty())
      continue;

    QString packKey = pack.key();
    QString packName = pack.key();
    QStringList components = packName.split("_");
    if ((components.size() > 2) && (components.at(0) == "com")
      && (components.at(1) == "trolltech")) {
        // kill com.trolltech in key
        components.removeAt(0);
        components.removeAt(0);
    }

    QString shortPackName;
    foreach (QString comp, components) {
      comp[0] = comp[0].toUpper();
      shortPackName += comp;
    }
    // add missing camel case (workaround..)
    if (shortPackName == "QtWebkit") {
      shortPackName = "QtWebKit";
    } else if (shortPackName == "QtXmlpatterns") {
      shortPackName = "QtXmlPatterns";
    } else if (shortPackName == "QtOpengl") {
      shortPackName = "QtOpenGL";
    } else if (shortPackName == "QtUitools") {
      shortPackName = "QtUiTools";
    }

    {
      FileOut initFile(m_out_dir + "/generated_cpp/" + packName + "/" + packKey + "_init.cpp");
      QTextStream &s = initFile.stream;

      s << "#include <PythonQt.h>" << endl;

      for (int i=0; i<(list.count()+MAX_CLASSES_PER_FILE-1) / MAX_CLASSES_PER_FILE; i++) {
        s << "#include \"" << packKey << QString::number(i) << ".h\"" << endl;
      }
      s << endl;

      QStringList polymorphicHandlers;
      if (!packName.endsWith("_builtin")) {
        polymorphicHandlers = writePolymorphicHandler(s, list.at(0)->package(), classes_with_polymorphic_id);
        s << endl;
      }

      // declare individual class creation functions
      s << "void PythonQt_init_" << shortPackName << "() {" << endl;

      if (shortPackName.endsWith("Builtin")) {
        shortPackName = shortPackName.mid(0, shortPackName.length()-strlen("builtin"));
      }

      QStringList cppClassNames;
      foreach (const AbstractMetaClass *cls, list) {

        QString shellCreator;
        if (cls->generateShellClass()) {
          shellCreator = ", PythonQtSetInstanceWrapperOnShell<" + ShellGenerator::shellClassName(cls) + ">";
        }
        if (cls->isQObject()) {
          s << "PythonQt::self()->registerClass(&" << cls->qualifiedCppName() << "::staticMetaObject, \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
        } else {
          QString baseName = cls->baseClass()?cls->baseClass()->qualifiedCppName():"";
          s << "PythonQt::self()->registerCPPClass(\""<< cls->qualifiedCppName() << "\", \"" << baseName << "\", \"" << shortPackName <<"\", PythonQtCreateObject<PythonQtWrapper_" << cls->name() << ">" << shellCreator << ");" << endl;
        }
        foreach(AbstractMetaClass* interface, cls->interfaces()) {
          // the interface might be our own class... (e.g. QPaintDevice)
          if (interface->qualifiedCppName() != cls->qualifiedCppName()) {
            s << "PythonQt::self()->addParentClass(\""<< cls->qualifiedCppName() << "\", \"" << interface->qualifiedCppName() << "\",PythonQtUpcastingOffset<" << cls->qualifiedCppName() <<","<<interface->qualifiedCppName()<<">());" << endl;
          }
        }
      }
      s << endl;
      foreach (QString handler, polymorphicHandlers) {
        s << "PythonQt::self()->addPolymorphicHandler(\""<< handler << "\", polymorphichandler_" << handler << ");" << endl;
      }

      s << "}";
      s << endl;
    }
  }
}

QStringList SetupGenerator::writePolymorphicHandler(QTextStream &s, const QString &package,
                                                    const AbstractMetaClassList &classes)
{
  QStringList handlers;
  foreach (AbstractMetaClass *cls, classes) {
    const ComplexTypeEntry *centry = cls->typeEntry();
    if (!centry->isPolymorphicBase())
      continue;
    bool isGraphicsItem = (cls->qualifiedCppName()=="QGraphicsItem");

    AbstractMetaClassList classList = this->classes();
    bool first = true;
    foreach (AbstractMetaClass *clazz, classList) {
      bool inherits = false;
      if (isGraphicsItem) {
        foreach(AbstractMetaClass* interfaze, clazz->interfaces()) {
          if (interfaze->qualifiedCppName()=="QGraphicsItem") {
            inherits = true;
            break;
          }
        }
      } else {
        inherits = clazz->inheritsFrom(cls);
      }
      if (clazz->package() == package && inherits) {
        if (!clazz->typeEntry()->polymorphicIdValue().isEmpty() || isGraphicsItem) {
          // On first find, open the function
          if (first) {
            first = false;

            QString handler = cls->name();
            handlers.append(handler);

            s << "static void* polymorphichandler_" << handler
              << "(const void *ptr, char **class_name)" << endl
              << "{" << endl
              << "    Q_ASSERT(ptr != 0);" << endl
              << "    " << cls->qualifiedCppName() << " *object = ("
              << cls->qualifiedCppName() << " *)ptr;" << endl;
          }

          // For each, add case label
          QString polyId = clazz->typeEntry()->polymorphicIdValue();
          if (isGraphicsItem) {
            polyId = "%1->type() == " + clazz->qualifiedCppName() + "::Type";
          }
          s << "    if ("
            << polyId.replace("%1", "object")
            << ") {" << endl
            << "        *class_name = \"" << clazz->name() << "\";" << endl
            << "        return (" << clazz->qualifiedCppName() << "*)object;" << endl
            << "    }" << endl;
        } else {
          QString warning = QString("class '%1' inherits from polymorphic class '%2', but has no polymorphic id set")
            .arg(clazz->name())
            .arg(cls->name());

          ReportHandler::warning(warning);
        }
      }
    }

    // Close the function if it has been opened
    if (!first) {
      s << "    return NULL;" << endl
        << "}" << endl;
    }
  }

  return handlers;
}
<|endoftext|>


<commit_before>// @(#)root/geom:$Id$
// Author: Rene Brun   26/12/02

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

////////////////////////////////////////////////////////////////////////////////
// Full description with examples and pictures
//
//
#include "Riostream.h"
#include "TGeoManager.h"
#include "TGeoMedium.h"
#include "TList.h"

ClassImp(TGeoMedium)

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium()
{
// Default constructor
   fId      = 0;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   fMaterial= 0;
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const char *name, Int_t numed, const TGeoMaterial *mat, Double_t *params)
             :TNamed(name,"")
{
// constructor
   fName = fName.Strip();
   fId    = numed;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   fMaterial = (TGeoMaterial*)mat;
   for (Int_t i=0;i<10;i++) {
      if (params) fParams[i] = params[i];
      else        fParams[i] = 0;
   }
   gGeoManager->GetListOfMedia()->Add(this);
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const char *name, Int_t numed, Int_t imat, Int_t isvol, Int_t ifield,
              Double_t fieldm, Double_t tmaxfd, Double_t stemax, Double_t deemax, Double_t epsil, Double_t stmin)
             :TNamed(name,"")
{
// constructor
   fName = fName.Strip();
   fId    = numed;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   TIter next (gGeoManager->GetListOfMaterials());
   TGeoMaterial *mat;
   while ((mat = (TGeoMaterial*)next())) {
      if (mat->GetUniqueID() == (UInt_t)imat) break;
   }
   if (!mat || (mat->GetUniqueID() != (UInt_t)imat)) {
      fMaterial = 0;
      Error("TGeoMedium", "%s, material number %d does not exist",name,imat);
      return;
   }
   fMaterial = (TGeoMaterial*)mat;
   fParams[0] = isvol;
   fParams[1] = ifield;
   fParams[2] = fieldm;
   fParams[3] = tmaxfd;
   fParams[4] = stemax;
   fParams[5] = deemax;
   fParams[6] = epsil;
   fParams[7] = stmin;
   gGeoManager->GetListOfMedia()->Add(this);
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const TGeoMedium& gm) :
  TNamed(gm),
  fId(gm.fId),
  fMaterial(gm.fMaterial)
{
   //copy constructor
   for(Int_t i=0; i<20; i++) fParams[i]=gm.fParams[i];
}

//-----------------------------------------------------------------------------
TGeoMedium& TGeoMedium::operator=(const TGeoMedium& gm)
{
   //assignment operator
   if(this!=&gm) {
      TNamed::operator=(gm);
      fId=gm.fId;
      for(Int_t i=0; i<20; i++) fParams[i]=gm.fParams[i];
      fMaterial=gm.fMaterial;
   }
   return *this;
}

//-----------------------------------------------------------------------------
TGeoMedium::~TGeoMedium()
{
// Destructor
}

//_____________________________________________________________________________
char *TGeoMedium::GetPointerName() const
{
// Provide a pointer name containing uid.
   static TString name;
   name = TString::Format("pMed%d", GetUniqueID());
   return (char*)name.Data();
}

//_____________________________________________________________________________
void TGeoMedium::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
{
// Save a primitive as a C++ statement(s) on output stream "out".
   if (TestBit(TGeoMedium::kMedSavePrimitive)) return;
   fMaterial->SavePrimitive(out,option);
   out << "// Medium: " << GetName() << endl;
   out << "   numed   = " << fId << ";  // medium number" << endl;
   out << "   par[0]  = " << fParams[0] << "; // isvol" << endl;
   out << "   par[1]  = " << fParams[1] << "; // ifield" << endl;
   out << "   par[2]  = " << fParams[2] << "; // fieldm" << endl;
   out << "   par[3]  = " << fParams[3] << "; // tmaxfd" << endl;
   out << "   par[4]  = " << fParams[4] << "; // stemax" << endl;
   out << "   par[5]  = " << fParams[5] << "; // deemax" << endl;
   out << "   par[6]  = " << fParams[6] << "; // epsil" << endl;
   out << "   par[7]  = " << fParams[7] << "; // stmin" << endl;

   out << "   " << GetPointerName() << " = new TGeoMedium(\"" << GetName() << "\", numed," << fMaterial->GetPointerName() << ", par);" << endl;
   SetBit(TGeoMedium::kMedSavePrimitive);
}
<commit_msg>Class documentation added<commit_after>// @(#)root/geom:$Id$
// Author: Rene Brun   26/12/02

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

////////////////////////////////////////////////////////////////////////////////
// Media are used to store properties related to tracking and which are useful
// only when using geometry with a particle transport MC package (via VMC). One
// may define several tracking media for a given material. The media ID are user
// defined values that are not used by the geometry package. In case geometry
// is used via VMC (in GEANT) these numbers are overwritten, so one can only
// rely on these values after gMC->FinishGeometry() is called.
// The media parameters are inspired from GEANT3 and the values defined make sense
// in context of GEANT (3 but also 4) or FLUKA interfaces.
////////////////////////////////////////////////////////////////////////////////

#include "Riostream.h"
#include "TGeoManager.h"
#include "TGeoMedium.h"
#include "TList.h"

ClassImp(TGeoMedium)

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium()
{
// Default constructor
   fId      = 0;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   fMaterial= 0;
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const char *name, Int_t numed, const TGeoMaterial *mat, Double_t *params)
             :TNamed(name,"")
{
// constructor
   fName = fName.Strip();
   fId    = numed;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   fMaterial = (TGeoMaterial*)mat;
   for (Int_t i=0;i<10;i++) {
      if (params) fParams[i] = params[i];
      else        fParams[i] = 0;
   }
   gGeoManager->GetListOfMedia()->Add(this);
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const char *name, Int_t numed, Int_t imat, Int_t isvol, Int_t ifield,
              Double_t fieldm, Double_t tmaxfd, Double_t stemax, Double_t deemax, Double_t epsil, Double_t stmin)
             :TNamed(name,"")
{
// constructor
   fName = fName.Strip();
   fId    = numed;
   for (Int_t i=0; i<20; i++) fParams[i] = 0.;
   TIter next (gGeoManager->GetListOfMaterials());
   TGeoMaterial *mat;
   while ((mat = (TGeoMaterial*)next())) {
      if (mat->GetUniqueID() == (UInt_t)imat) break;
   }
   if (!mat || (mat->GetUniqueID() != (UInt_t)imat)) {
      fMaterial = 0;
      Error("TGeoMedium", "%s, material number %d does not exist",name,imat);
      return;
   }
   fMaterial = (TGeoMaterial*)mat;
   fParams[0] = isvol;
   fParams[1] = ifield;
   fParams[2] = fieldm;
   fParams[3] = tmaxfd;
   fParams[4] = stemax;
   fParams[5] = deemax;
   fParams[6] = epsil;
   fParams[7] = stmin;
   gGeoManager->GetListOfMedia()->Add(this);
}

//-----------------------------------------------------------------------------
TGeoMedium::TGeoMedium(const TGeoMedium& gm) :
  TNamed(gm),
  fId(gm.fId),
  fMaterial(gm.fMaterial)
{
   //copy constructor
   for(Int_t i=0; i<20; i++) fParams[i]=gm.fParams[i];
}

//-----------------------------------------------------------------------------
TGeoMedium& TGeoMedium::operator=(const TGeoMedium& gm)
{
   //assignment operator
   if(this!=&gm) {
      TNamed::operator=(gm);
      fId=gm.fId;
      for(Int_t i=0; i<20; i++) fParams[i]=gm.fParams[i];
      fMaterial=gm.fMaterial;
   }
   return *this;
}

//-----------------------------------------------------------------------------
TGeoMedium::~TGeoMedium()
{
// Destructor
}

//_____________________________________________________________________________
char *TGeoMedium::GetPointerName() const
{
// Provide a pointer name containing uid.
   static TString name;
   name = TString::Format("pMed%d", GetUniqueID());
   return (char*)name.Data();
}

//_____________________________________________________________________________
void TGeoMedium::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
{
// Save a primitive as a C++ statement(s) on output stream "out".
   if (TestBit(TGeoMedium::kMedSavePrimitive)) return;
   fMaterial->SavePrimitive(out,option);
   out << "// Medium: " << GetName() << endl;
   out << "   numed   = " << fId << ";  // medium number" << endl;
   out << "   par[0]  = " << fParams[0] << "; // isvol" << endl;
   out << "   par[1]  = " << fParams[1] << "; // ifield" << endl;
   out << "   par[2]  = " << fParams[2] << "; // fieldm" << endl;
   out << "   par[3]  = " << fParams[3] << "; // tmaxfd" << endl;
   out << "   par[4]  = " << fParams[4] << "; // stemax" << endl;
   out << "   par[5]  = " << fParams[5] << "; // deemax" << endl;
   out << "   par[6]  = " << fParams[6] << "; // epsil" << endl;
   out << "   par[7]  = " << fParams[7] << "; // stmin" << endl;

   out << "   " << GetPointerName() << " = new TGeoMedium(\"" << GetName() << "\", numed," << fMaterial->GetPointerName() << ", par);" << endl;
   SetBit(TGeoMedium::kMedSavePrimitive);
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2022-2022 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Tobias Gödderz
////////////////////////////////////////////////////////////////////////////////

#include "TestHelper.h"

#include "Replication2/ReplicatedLog/LogFollower.h"
#include "Replication2/ReplicatedLog/ReplicatedLog.h"

using namespace arangodb;
using namespace arangodb::replication2;
using namespace arangodb::replication2::replicated_log;
using namespace arangodb::replication2::test;

struct LogFollowerCompactionTest : ReplicatedLogTest {};

TEST_F(LogFollowerCompactionTest, simple_release) {
  using namespace std::string_literals;

  auto leaderLog = makeReplicatedLog(LogId{1});
  auto followerLog = makeReplicatedLog(LogId{1});

  auto follower = followerLog->becomeFollower("follower", LogTerm{1}, "leader");
  auto leader = leaderLog->becomeLeader("leader", LogTerm{1}, {follower}, 2);

  leader->triggerAsyncReplication();
  follower->runAllAsyncAppendEntries();
  ASSERT_TRUE(leader->isLeadershipEstablished());

  auto i = 0;
  // compaction will only run if at least 1000 entries are to be compacted,
  // so let's start with that
  for (; i < 1000; ++i) {
    leader->insert(
        LogPayload::createFromString("log entry #"s + std::to_string(i)));
  }
  // let's add some more
  auto const stopCompactionIdx = leader->insert(
      LogPayload::createFromString("log entry #"s + std::to_string(i++)));
  auto const firstUncompactedIdx = leader->insert(
      LogPayload::createFromString("log entry #"s + std::to_string(i++)));
  leader->insert(
      LogPayload::createFromString("log entry #"s + std::to_string(i++)));
  auto const latestIdx = leader->insert(
      LogPayload::createFromString("log entry #"s + std::to_string(i++)));

  // replicate entries
  follower->runAllAsyncAppendEntries();
  ASSERT_EQ(latestIdx,
            leader->getQuickStatus().getLocalStatistics().value().commitIndex);
  ASSERT_EQ(latestIdx,
            follower->getQuickStatus().getLocalStatistics().value().commitIndex);
  auto const fullLog = follower->copyInMemoryLog();
  ASSERT_EQ(LogIndex{1}, fullLog.getFirstIndex());
  ASSERT_EQ(latestIdx, fullLog.getLastIndex());
  // release some entries
  follower->release(stopCompactionIdx);
  auto const compactedLog = follower->copyInMemoryLog();
  ASSERT_EQ(firstUncompactedIdx, compactedLog.getFirstIndex());
  ASSERT_EQ(latestIdx, compactedLog.getLastIndex());
}
<commit_msg>Added a TODO note<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2022-2022 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Tobias Gödderz
////////////////////////////////////////////////////////////////////////////////

#include "TestHelper.h"

#include "Replication2/ReplicatedLog/LogFollower.h"
#include "Replication2/ReplicatedLog/ReplicatedLog.h"

using namespace arangodb;
using namespace arangodb::replication2;
using namespace arangodb::replication2::replicated_log;
using namespace arangodb::replication2::test;

struct LogFollowerCompactionTest : ReplicatedLogTest {};

TEST_F(LogFollowerCompactionTest, simple_release) {
  using namespace std::string_literals;

  auto leaderLog = makeReplicatedLog(LogId{1});
  auto followerLog = makeReplicatedLog(LogId{1});

  auto follower = followerLog->becomeFollower("follower", LogTerm{1}, "leader");
  auto leader = leaderLog->becomeLeader("leader", LogTerm{1}, {follower}, 2);

  leader->triggerAsyncReplication();
  follower->runAllAsyncAppendEntries();
  ASSERT_TRUE(leader->isLeadershipEstablished());

  auto i = 0;
  // compaction will only run if at least 1000 entries are to be compacted,
  // so let's start with that
  for (; i < 1000; ++i) {
    leader->insert(
        LogPayload::createFromString("log entry #"s + std::to_string(i)));
  }
  // let's add some more
  auto const stopCompactionIdx = leader->insert(
      LogPayload::createFromString("log entry #"s + std::to_string(i++)));
  auto const firstUncompactedIdx = leader->insert(
      LogPayload::createFromString("log entry #"s + std::to_string(i++)));
  leader->insert(
      LogPayload::createFromString("log entry #"s + std::to_string(i++)));
  auto const latestIdx = leader->insert(
      LogPayload::createFromString("log entry #"s + std::to_string(i++)));

  // replicate entries
  follower->runAllAsyncAppendEntries();
  ASSERT_EQ(latestIdx,
            leader->getQuickStatus().getLocalStatistics().value().commitIndex);
  ASSERT_EQ(latestIdx,
            follower->getQuickStatus().getLocalStatistics().value().commitIndex);
  auto const fullLog = follower->copyInMemoryLog();
  ASSERT_EQ(LogIndex{1}, fullLog.getFirstIndex());
  ASSERT_EQ(latestIdx, fullLog.getLastIndex());
  // release some entries
  follower->release(stopCompactionIdx);
  auto const compactedLog = follower->copyInMemoryLog();
  ASSERT_EQ(firstUncompactedIdx, compactedLog.getFirstIndex());
  ASSERT_EQ(latestIdx, compactedLog.getLastIndex());
}

// TODO Add a test that runs a `checkCompaction` during an appendEntries,
//      specifically after core->insertAsync is called (and the new InMemoryLog
//      is created), and before the new InMemoryLog is applied.
//      We probably need another Mock for the PersistedLog, so we can control
//      when the core->insertAsync promise will be resolved.
<|endoftext|>


<commit_before>#include <iostream>
#include <string>

#include "soa.h"

void print_soa_iis(const SoA<int, std::string, int>& soa_iis) {
  for (int i = 0; i < soa_iis.size(); ++i) {
    std::cout << "(" << i << "): " << soa_iis.get<int, 0>(i) << ", "
              << soa_iis.get<std::string, 1>(i) << ", "
              << soa_iis.get<int, 2>(i) << std::endl;
  }
}

int main() {
  SoA<int, std::string, int> soa_iis;
  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;

  soa_iis.push_back(0, "Hi", 2);
  soa_iis.push_back(22, "Kitty", 4);

  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;
  std::cout << std::endl;

  // Iterate the arrays and print out the elements.
  std::cout << "Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // Modify an element
  soa_iis.get<std::string, 1>(0) = "I am changed!";
  std::cout << "Modified the 0th element. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // Erase an element.
  soa_iis.erase(0);
  std::cout << "Erased 0th element. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // Add two new elements...
  soa_iis.push_back(1, "Hi... for now...", 5);
  soa_iis.push_back(80, "I'll survive!'", 20);
  std::cout << "Added 2 new elements. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // And erase the first two.
  soa_iis.erase(0, 2);
  std::cout << "Erased first 2 elements. Arrays now contain:\n";
  print_soa_iis(soa_iis);

  // Kill the arrays via resize.
  soa_iis.resize(0);
  std::cout << "Resized to 0. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;
  std::cout << std::endl;

  // Resize to have some new elements.
  soa_iis.resize(5);
  std::cout << "Resized to 5. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;
  std::cout << std::endl;

  // Modify an element and insert an element.
  soa_iis.get<std::string, 1>(3) = "Oh hai!";
  soa_iis.get<int, 2>(3) = 11;
  soa_iis.get<int, 0>(3) = 22;
  soa_iis.push_back(100, "I'm new!.", 20);
  std::cout
      << "Modified the 4th element and added a new one. Arrays now contain:\n";
      print_soa_iis(soa_iis);
  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;
  std::cout << std::endl;

  // Get arrays and print them.
  std::cout << "Printing arrays individually:\n";
  int* ints0 = soa_iis.array<int, 0>();
  std::string* strings = soa_iis.array<std::string, 1>();
  int* ints1 = soa_iis.array<int, 2>();
  for (int i = 0; i < soa_iis.size(); ++ i) {
    std::cout << "Index: " << i << ": ";
    std::cout << ints0[i] << ", ";
    std::cout << strings[i] << ", ";
    std::cout << ints1[i] << std::endl;
  }
}
<commit_msg>Added swap to the sample.<commit_after>#include <iostream>
#include <string>

#include "soa.h"

void print_soa_iis(const SoA<int, std::string, int> &soa_iis) {
  for (int i = 0; i < soa_iis.size(); ++i) {
    std::cout << "(" << i << "): " << soa_iis.get<int, 0>(i) << ", "
              << soa_iis.get<std::string, 1>(i) << ", "
              << soa_iis.get<int, 2>(i) << std::endl;
  }
}

int main() {
  SoA<int, std::string, int> soa_iis;
  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;

  soa_iis.push_back(22, "Kitty", 4);
  soa_iis.push_back(0, "Hi", 2);

  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;
  std::cout << std::endl;

  // Iterate the arrays and print out the elements.
  std::cout << "Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // Swap the elements.
  soa_iis.swap(0, 1);
  std::cout << "Swapped first two elements. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // Modify an element
  soa_iis.get<std::string, 1>(0) = "I am changed!";
  std::cout << "Modified the 0th element. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // Erase an element.
  soa_iis.erase(0);
  std::cout << "Erased 0th element. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // Add two new elements...
  soa_iis.push_back(1, "Hi... for now...", 5);
  soa_iis.push_back(80, "I'll survive!'", 20);
  std::cout << "Added 2 new elements. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << std::endl;

  // And erase the first two.
  soa_iis.erase(0, 2);
  std::cout << "Erased first 2 elements. Arrays now contain:\n";
  print_soa_iis(soa_iis);

  // Kill the arrays via resize.
  soa_iis.resize(0);
  std::cout << "Resized to 0. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;
  std::cout << std::endl;

  // Resize to have some new elements.
  soa_iis.resize(5);
  std::cout << "Resized to 5. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;
  std::cout << std::endl;

  // Modify an element and insert an element.
  soa_iis.get<std::string, 1>(3) = "Oh hai!";
  soa_iis.get<int, 2>(3) = 11;
  soa_iis.get<int, 0>(3) = 22;
  soa_iis.push_back(100, "I'm new!.", 20);
  std::cout
      << "Modified the 4th element and added a new one. Arrays now contain:\n";
  print_soa_iis(soa_iis);
  std::cout << "size: " << soa_iis.size() << std::endl;
  std::cout << "empty: " << soa_iis.empty() << std::endl;
  std::cout << std::endl;

  // Get arrays and print them.
  std::cout << "Printing arrays individually:\n";
  int *ints0 = soa_iis.array<int, 0>();
  std::string *strings = soa_iis.array<std::string, 1>();
  int *ints1 = soa_iis.array<int, 2>();
  for (int i = 0; i < soa_iis.size(); ++i) {
    std::cout << "Index: " << i << ": ";
    std::cout << ints0[i] << ", ";
    std::cout << strings[i] << ", ";
    std::cout << ints1[i] << std::endl;
  }
}
<|endoftext|>


<commit_before>/* This file is part of Mapnik (c++ mapping toolkit)
 * Copyright (C) 2007 Artem Pavlenko
 *
 * Mapnik is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

//$Id$

#include "styles_model.hpp"

// boost
#include <boost/concept_check.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>
// qt
#include <QList>
#include <QIcon>
#include <QPainter>
#include <QPixmap>

class node : private boost::noncopyable
{
      struct node_base
      {
            virtual QString name() const=0;
            virtual QIcon   icon() const=0;
            virtual ~node_base() {}
      };

      template <typename T>
      struct wrap : public node_base
      {
            wrap(T const& obj)
               : obj_(obj) {}

            ~wrap() {}

            QString name () const
            {
               return obj_.name();
            }

            QIcon icon() const
            {
               return obj_.icon();
            }

            T obj_;
      };

   public:
      template <typename T>
      node ( T const& obj, node * parent=0)
         : impl_(new wrap<T>(obj)),
           parent_(parent)
      {}

      QString name() const
      {
         return impl_->name();
      }

      QIcon icon() const
      {
         return impl_->icon();
      }

      unsigned num_children() const
      {
         return children_.count();
      }

      node * child(unsigned row) const
      {
         return children_.value(row);
      }

      node * parent() const
      {
         return parent_;
      }

      node * add_child(node * child)
      {
         children_.push_back(child);
         return child;
      }
      int row () const
      {
         if (parent_)
            return parent_->children_.indexOf(const_cast<node*>(this));
         else
            return 0;
      }

      ~node()
      {
         qDeleteAll(children_);
      }

   private:
      boost::scoped_ptr<node_base> impl_;
      QList<node*> children_;
      node * parent_;
};

struct symbolizer_info : public boost::static_visitor<QString>
{
      QString operator() (mapnik::point_symbolizer const& sym) const
      {
         boost::ignore_unused_variable_warning(sym);
         return QString("PointSymbolizer");
      }

      QString operator() (mapnik::line_symbolizer const& sym) const
      {
         boost::ignore_unused_variable_warning(sym);
         return QString("LineSymbolizer");
      }

      QString operator() (mapnik::line_pattern_symbolizer const& sym) const
      {
         boost::ignore_unused_variable_warning(sym);
         return QString("LinePatternSymbolizer");
      }

      QString operator() (mapnik::polygon_symbolizer const& sym) const
      {
         boost::ignore_unused_variable_warning(sym);
         return QString("PolygonSymbolizer");
      }

      QString operator() (mapnik::polygon_pattern_symbolizer const& sym) const
      {
         boost::ignore_unused_variable_warning(sym);
         return QString("PolygonSymbolizer");
      }

      QString operator() (mapnik::text_symbolizer const& sym) const
      {
         boost::ignore_unused_variable_warning(sym);
         return QString("TextSymbolizer");
      }

      QString operator() (mapnik::shield_symbolizer const& sym) const
      {
         boost::ignore_unused_variable_warning(sym);
         return QString("ShieldSymbolizer");
      }

      template <typename T>
      QString operator() (T const& ) const
      {
         return QString ("FIXME");
      }
};

struct symbolizer_icon : public boost::static_visitor<QIcon>
{
      QIcon operator() (mapnik::polygon_symbolizer const& sym) const
      {
         QPixmap pix(16,16);
         QPainter painter(&pix);
         mapnik::color const& fill = sym.get_fill();
         QBrush brush(QColor(fill.red(),fill.green(),fill.blue(),fill.alpha()));
         painter.fillRect(0, 0, 16, 16, brush);
         return QIcon(pix);
      }

      QIcon operator() (mapnik::point_symbolizer const& sym) const
      {
	  // FIXME!
	  /*
	    boost::shared_ptr<mapnik::image_data_32> symbol = sym.get_image();
	    if (symbol)
	    {
            QImage image(symbol->getBytes(),
	    symbol->width(),symbol->height(),QImage::Format_ARGB32);
            QPixmap pix = QPixmap::fromImage(image.rgbSwapped());
            return QIcon(pix);
         }
	  */
         return QIcon();
      }
      QIcon operator() (mapnik::line_symbolizer const& sym) const
      {
         QPixmap pix(48,16);
         pix.fill();
         QPainter painter(&pix);
         mapnik::stroke const&  strk = sym.get_stroke();
         mapnik::color const& col = strk.get_color();
         QPen pen(QColor(col.red(),col.green(),col.blue(),col.alpha()));
         pen.setWidth(strk.get_width());
         painter.setPen(pen);
         painter.drawLine(0,7,47,7);
         //painter.drawLine(7,15,12,0);
         //painter.drawLine(12,0,8,15);
         return QIcon(pix);
      }

      template <typename T>
      QIcon operator() (T const& ) const
      {
         return QIcon (":/images/filter.png");
      }
};

class symbolizer_node
{
   public:
      symbolizer_node(mapnik::symbolizer const & sym)
         : sym_(sym) {}
      ~symbolizer_node(){}

      QString name() const
      {
         //return QString("Symbolizer:fixme");
         return boost::apply_visitor(symbolizer_info(),sym_);
      }

      QIcon icon() const
      {
         return boost::apply_visitor(symbolizer_icon(),sym_);//QIcon(":/images/filter.png");
      }
      mapnik::symbolizer const& sym_;
};

class rule_node
{
   public:
      rule_node(QString name,mapnik::rule_type const & r)
         : name_(name),
           rule_(r) {}
      ~rule_node() {}
      QString name() const
      {
         mapnik::expression_ptr filter = rule_.get_filter();

         return QString("TODO!");//filter->to_string().c_str());
      }

      QIcon icon() const
      {
         return QIcon(":/images/filter.png");
      }

   private:
      QString name_;
      mapnik::rule_type const& rule_;
};

class style_node
{
   public:
      style_node(QString name, mapnik::feature_type_style const& style)
         : name_(name),
           style_(style) {}

      ~style_node() {}

      QString name() const
      {
         return name_;
      }

      QIcon icon() const
      {
         return QIcon(":/images/style.png");
      }

   private:
      QString name_;
      mapnik::feature_type_style const& style_;
};

class map_node
{
   public:
      explicit map_node(boost::shared_ptr<mapnik::Map> map)
         : map_(map)  {}
      ~map_node() {}

      QString name() const
      {
         return QString("Map");
      }

      QIcon icon() const
      {
         return QIcon(":/images/map.png");
      }

   private:
      boost::shared_ptr<mapnik::Map> map_;
};

StyleModel::StyleModel(boost::shared_ptr<mapnik::Map> map, QObject * parent)
   : QAbstractItemModel(parent),
     root_(new node(map_node(map)))
{
   typedef std::map<std::string,mapnik::feature_type_style> style_type;
   style_type const & styles = map->styles();
   style_type::const_iterator itr = styles.begin();
   style_type::const_iterator end = styles.end();
   for (; itr != end; ++itr)
   {
      node * style_n = root_->add_child(new node(style_node(QString(itr->first.c_str()),itr->second),root_.get()));
      mapnik::rules const& rules = itr->second.get_rules();
      mapnik::rules::const_iterator itr2 = rules.begin();
      for ( ; itr2 != rules.end();++itr2)
      {
         node* rule_n = style_n->add_child(new node(rule_node(QString("Rule"),*itr2),style_n));
         mapnik::rule_type::symbolizers::const_iterator itr3 = (*itr2).begin();
         for ( ; itr3 !=itr2->end();++itr3)
         {
            rule_n->add_child(new node(symbolizer_node(*itr3),rule_n));
         }
      }
   }
}

StyleModel::~StyleModel() {}

// interface
QModelIndex StyleModel::index (int row, int col, QModelIndex const& parent) const
{
//   qDebug("index() row=%d col=%d parent::internalId() = %lld", row,col,parent.internalId());
   node * parent_node;

   if (!parent.isValid())
      parent_node = root_.get();
   else
      parent_node = static_cast<node*>(parent.internalPointer());

   node * child_node = parent_node->child(row);
   if (child_node)
      return createIndex(row,col,child_node);
   else
      return QModelIndex();
}

QModelIndex StyleModel::parent (QModelIndex const& index) const
{
   node * child_node = static_cast<node*>(index.internalPointer());
   node * parent_node = child_node->parent();
   if (parent_node == root_.get())
      return QModelIndex();

   return createIndex(parent_node->row(),0,parent_node);
}

int StyleModel::rowCount(QModelIndex const& parent) const
{
   //qDebug("rowCount");
   node * parent_node;
   if (parent.column() > 0) return 0;
   if (!parent.isValid())
      parent_node = root_.get();
   else
      parent_node = static_cast<node*>(parent.internalPointer());
   return parent_node->num_children();
}

int StyleModel::columnCount( QModelIndex const&) const
{
   return 1;
}

QVariant StyleModel::data(const QModelIndex & index, int role) const
{
   //qDebug("data index::internalId() = %lld", index.internalId());
   if (!index.isValid())
      return QVariant();
   node * cur_node = static_cast<node*>(index.internalPointer());
   if (cur_node)
   {
      if (role == Qt::DisplayRole)
      {

         return QVariant(cur_node->name());
      }
      else if ( role == Qt::DecorationRole)
      {
         return cur_node->icon();
      }
   }
   return QVariant();
}
<commit_msg>+ show expr string in styles control<commit_after>/* This file is part of Mapnik (c++ mapping toolkit)
 * Copyright (C) 2007 Artem Pavlenko
 *
 * Mapnik is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

//$Id$

#include "styles_model.hpp"
#include <mapnik/expression_string.hpp>
// boost
#include <boost/concept_check.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>
// qt
#include <QList>
#include <QIcon>
#include <QPainter>
#include <QPixmap>

class node : private boost::noncopyable
{
    struct node_base
    {
	virtual QString name() const=0;
	virtual QIcon   icon() const=0;
	virtual ~node_base() {}
    };

    template <typename T>
    struct wrap : public node_base
    {
	wrap(T const& obj)
	    : obj_(obj) {}

	~wrap() {}

	QString name () const
	{
	    return obj_.name();
	}

	QIcon icon() const
	{
	    return obj_.icon();
	}

	T obj_;
    };

public:
    template <typename T>
    node ( T const& obj, node * parent=0)
	: impl_(new wrap<T>(obj)),
	  parent_(parent)
    {}

    QString name() const
    {
	return impl_->name();
    }

    QIcon icon() const
    {
	return impl_->icon();
    }

    unsigned num_children() const
    {
	return children_.count();
    }

    node * child(unsigned row) const
    {
	return children_.value(row);
    }

    node * parent() const
    {
	return parent_;
    }

    node * add_child(node * child)
    {
	children_.push_back(child);
	return child;
    }
    int row () const
    {
	if (parent_)
            return parent_->children_.indexOf(const_cast<node*>(this));
	else
            return 0;
    }

    ~node()
    {
	qDeleteAll(children_);
    }

private:
    boost::scoped_ptr<node_base> impl_;
    QList<node*> children_;
    node * parent_;
};

struct symbolizer_info : public boost::static_visitor<QString>
{
    QString operator() (mapnik::point_symbolizer const& sym) const
    {
	boost::ignore_unused_variable_warning(sym);
	return QString("PointSymbolizer");
    }

    QString operator() (mapnik::line_symbolizer const& sym) const
    {
	boost::ignore_unused_variable_warning(sym);
	return QString("LineSymbolizer");
    }

    QString operator() (mapnik::line_pattern_symbolizer const& sym) const
    {
	boost::ignore_unused_variable_warning(sym);
	return QString("LinePatternSymbolizer");
    }

    QString operator() (mapnik::polygon_symbolizer const& sym) const
    {
	boost::ignore_unused_variable_warning(sym);
	return QString("PolygonSymbolizer");
    }

    QString operator() (mapnik::polygon_pattern_symbolizer const& sym) const
    {
	boost::ignore_unused_variable_warning(sym);
	return QString("PolygonSymbolizer");
    }

    QString operator() (mapnik::text_symbolizer const& sym) const
    {
	boost::ignore_unused_variable_warning(sym);
	return QString("TextSymbolizer");
    }

    QString operator() (mapnik::shield_symbolizer const& sym) const
    {
	boost::ignore_unused_variable_warning(sym);
	return QString("ShieldSymbolizer");
    }

    template <typename T>
    QString operator() (T const& ) const
    {
	return QString ("FIXME");
    }
};

struct symbolizer_icon : public boost::static_visitor<QIcon>
{
    QIcon operator() (mapnik::polygon_symbolizer const& sym) const
    {
	QPixmap pix(16,16);
	QPainter painter(&pix);
	mapnik::color const& fill = sym.get_fill();
	QBrush brush(QColor(fill.red(),fill.green(),fill.blue(),fill.alpha()));
	painter.fillRect(0, 0, 16, 16, brush);
	return QIcon(pix);
    }

    QIcon operator() (mapnik::point_symbolizer const& sym) const
    {
	// FIXME!
	/*
	  boost::shared_ptr<mapnik::image_data_32> symbol = sym.get_image();
	  if (symbol)
	  {
	  QImage image(symbol->getBytes(),
	  symbol->width(),symbol->height(),QImage::Format_ARGB32);
	  QPixmap pix = QPixmap::fromImage(image.rgbSwapped());
	  return QIcon(pix);
	  }
	*/
	return QIcon();
    }
    QIcon operator() (mapnik::line_symbolizer const& sym) const
    {
	QPixmap pix(48,16);
	pix.fill();
	QPainter painter(&pix);
	mapnik::stroke const&  strk = sym.get_stroke();
	mapnik::color const& col = strk.get_color();
	QPen pen(QColor(col.red(),col.green(),col.blue(),col.alpha()));
	pen.setWidth(strk.get_width());
	painter.setPen(pen);
	painter.drawLine(0,7,47,7);
	//painter.drawLine(7,15,12,0);
	//painter.drawLine(12,0,8,15);
	return QIcon(pix);
    }

    template <typename T>
    QIcon operator() (T const& ) const
    {
	return QIcon (":/images/filter.png");
    }
};

class symbolizer_node
{
public:
    symbolizer_node(mapnik::symbolizer const & sym)
	: sym_(sym) {}
    ~symbolizer_node(){}

    QString name() const
    {
	//return QString("Symbolizer:fixme");
	return boost::apply_visitor(symbolizer_info(),sym_);
    }

    QIcon icon() const
    {
	return boost::apply_visitor(symbolizer_icon(),sym_);//QIcon(":/images/filter.png");
    }
    mapnik::symbolizer const& sym_;
};

class rule_node
{
public:
    rule_node(QString name,mapnik::rule_type const & r)
	: name_(name),
	  rule_(r) {}
    ~rule_node() {}
    QString name() const
    {
	mapnik::expression_ptr filter = rule_.get_filter();

	return QString(mapnik::to_expression_string(*filter).c_str());
    }

    QIcon icon() const
    {
	return QIcon(":/images/filter.png");
    }

private:
    QString name_;
    mapnik::rule_type const& rule_;
};

class style_node
{
public:
    style_node(QString name, mapnik::feature_type_style const& style)
	: name_(name),
	  style_(style) {}

    ~style_node() {}

    QString name() const
    {
	return name_;
    }

    QIcon icon() const
    {
	return QIcon(":/images/style.png");
    }

private:
    QString name_;
    mapnik::feature_type_style const& style_;
};

class map_node
{
public:
    explicit map_node(boost::shared_ptr<mapnik::Map> map)
	: map_(map)  {}
    ~map_node() {}

    QString name() const
    {
	return QString("Map");
    }

    QIcon icon() const
    {
	return QIcon(":/images/map.png");
    }

private:
    boost::shared_ptr<mapnik::Map> map_;
};

StyleModel::StyleModel(boost::shared_ptr<mapnik::Map> map, QObject * parent)
    : QAbstractItemModel(parent),
      root_(new node(map_node(map)))
{
    typedef std::map<std::string,mapnik::feature_type_style> style_type;
    style_type const & styles = map->styles();
    style_type::const_iterator itr = styles.begin();
    style_type::const_iterator end = styles.end();
    for (; itr != end; ++itr)
    {
	node * style_n = root_->add_child(new node(style_node(QString(itr->first.c_str()),itr->second),root_.get()));
	mapnik::rules const& rules = itr->second.get_rules();
	mapnik::rules::const_iterator itr2 = rules.begin();
	for ( ; itr2 != rules.end();++itr2)
	{
	    node* rule_n = style_n->add_child(new node(rule_node(QString("Rule"),*itr2),style_n));
	    mapnik::rule_type::symbolizers::const_iterator itr3 = (*itr2).begin();
	    for ( ; itr3 !=itr2->end();++itr3)
	    {
		rule_n->add_child(new node(symbolizer_node(*itr3),rule_n));
	    }
	}
    }
}

StyleModel::~StyleModel() {}

// interface
QModelIndex StyleModel::index (int row, int col, QModelIndex const& parent) const
{
//   qDebug("index() row=%d col=%d parent::internalId() = %lld", row,col,parent.internalId());
    node * parent_node;

    if (!parent.isValid())
	parent_node = root_.get();
    else
	parent_node = static_cast<node*>(parent.internalPointer());

    node * child_node = parent_node->child(row);
    if (child_node)
	return createIndex(row,col,child_node);
    else
	return QModelIndex();
}

QModelIndex StyleModel::parent (QModelIndex const& index) const
{
    node * child_node = static_cast<node*>(index.internalPointer());
    node * parent_node = child_node->parent();
    if (parent_node == root_.get())
	return QModelIndex();

    return createIndex(parent_node->row(),0,parent_node);
}

int StyleModel::rowCount(QModelIndex const& parent) const
{
    //qDebug("rowCount");
    node * parent_node;
    if (parent.column() > 0) return 0;
    if (!parent.isValid())
	parent_node = root_.get();
    else
	parent_node = static_cast<node*>(parent.internalPointer());
    return parent_node->num_children();
}

int StyleModel::columnCount( QModelIndex const&) const
{
    return 1;
}

QVariant StyleModel::data(const QModelIndex & index, int role) const
{
    //qDebug("data index::internalId() = %lld", index.internalId());
    if (!index.isValid())
	return QVariant();
    node * cur_node = static_cast<node*>(index.internalPointer());
    if (cur_node)
    {
	if (role == Qt::DisplayRole)
	{

	    return QVariant(cur_node->name());
	}
	else if ( role == Qt::DecorationRole)
	{
	    return cur_node->icon();
	}
    }
    return QVariant();
}
<|endoftext|>


<commit_before>#include <iostream>
#include "ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
#include "sensor_msgs/NavSatFix.h"
#include "sensor_msgs/Imu.h"
#include "laser_transform_core.h"

using std::string;

int main (int argc, char **argv)
{
  ros::init(argc, argv, "laser_transform");
  ros::NodeHandle n;

  // Declare variables thar can be modified by launch file or command line.
  int rate;
  bool imu_msgs;
  bool gps_msgs;
  string pcl_in_topic;
  string pcl_out_topic;
  string imu_topic;
  string gps_topic;

  // Create a new LaserTransformer object.
  LaserTransform *node_lt = new LaserTransform();

  node_lt->init();

  // while using different parameters.
  ros::NodeHandle private_node_handle_("~");
  private_node_handle_.param("rate", rate, int(10));
  private_node_handle_.param("imu_msgs", imu_msgs, bool(false));
  private_node_handle_.param("gps_msgs", gps_msgs, bool(false));
  private_node_handle_.param("pcl_in_topic", pcl_in_topic, string("/cloud"));
  private_node_handle_.param("pcl_out_topic", pcl_out_topic, string("/cloud_world"));
  private_node_handle_.param("imu_topic", imu_topic, string("/imu/data"));
  private_node_handle_.param("gps_topic", gps_topic, string("/gps/fix"));

  // Create a subscriber
  ros::Subscriber sub_message = n.subscribe(pcl_in_topic.c_str(), 1000, &LaserTransform::messageCallback, node_lt);

  // Create a publisher and name the topic
  ros::Publisher pub_message = n.advertise<sensor_msgs::PointCloud2>(pcl_out_topic.c_str(), 50);

  // Create a publisher for IMU msgs
  ros::Publisher imu_pub = n.advertise<sensor_msgs::Imu>(imu_topic.c_str(), 50);

  // Create a publisher for GPS msgs
  ros::Publisher gps_pub = n.advertise<sensor_msgs::NavSatFix>(gps_topic.c_str(), 50);

  ros::Rate r(rate);

  while (n.ok())
  {
    node_lt->publishMessage(&pub_message);
    if (imu_msgs)
      node_lt->publishImuMessage(&imu_pub);
    if (gps_msgs)
      node_lt->publishNavSatFixMessage(&gps_pub);
    ros::spinOnce();
    r.sleep();
  }

  return 0;
  // end main
}
<commit_msg>add odometry subscriber<commit_after>#include <iostream>
#include "ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
#include "sensor_msgs/NavSatFix.h"
#include "sensor_msgs/Imu.h"
#include "nav_msgs/Odometry.h"
#include "laser_transform_core.h"

using std::string;

int main (int argc, char **argv)
{
  ros::init(argc, argv, "laser_transform");
  ros::NodeHandle n;

  // Declare variables thar can be modified by launch file or command line.
  int rate;
  bool imu_msgs;
  bool gps_msgs;
  string pcl_in_topic;
  string pcl_out_topic;
  string imu_topic;
  string gps_topic;
  //string odo_topic;

  // Create a new LaserTransformer object.
  LaserTransform *node_lt = new LaserTransform();

  node_lt->init();

  // while using different parameters.
  ros::NodeHandle private_node_handle_("~");
  private_node_handle_.param("rate", rate, int(10));
  private_node_handle_.param("imu_msgs", imu_msgs, bool(false));
  private_node_handle_.param("gps_msgs", gps_msgs, bool(false));
  private_node_handle_.param("pcl_in_topic", pcl_in_topic, string("/cloud"));
  private_node_handle_.param("pcl_out_topic", pcl_out_topic, string("/cloud_world"));
  private_node_handle_.param("imu_topic", imu_topic, string("/imu/data"));
  private_node_handle_.param("gps_topic", gps_topic, string("/gps/fix"));

  // Create a subscriber
  ros::Subscriber sub_message = n.subscribe(pcl_in_topic.c_str(), 1000, &LaserTransform::messageCallback, node_lt);

  // Create odometry subscriber
  ros::Subscriber sub_odometry = n.subscribe("/odometry/filtered", 50, &LaserTransform::odometryCallback, node_lt);

  // Create a publisher and name the topic
  ros::Publisher pub_message = n.advertise<sensor_msgs::PointCloud2>(pcl_out_topic.c_str(), 50);

  // Create a publisher for IMU msgs
  ros::Publisher imu_pub = n.advertise<sensor_msgs::Imu>(imu_topic.c_str(), 50);

  // Create a publisher for GPS msgs
  ros::Publisher gps_pub = n.advertise<sensor_msgs::NavSatFix>(gps_topic.c_str(), 50);

  ros::Rate r(rate);

  while (n.ok())
  {
    node_lt->publishMessage(&pub_message);
    if (imu_msgs)
      node_lt->publishImuMessage(&imu_pub);
    if (gps_msgs)
      node_lt->publishNavSatFixMessage(&gps_pub);
    ros::spinOnce();
    r.sleep();
  }

  return 0;
  // end main
}
<|endoftext|>


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

#if !defined (_MSC_VER)
    #include <unistd.h>
#endif // !_MSC_VER

class releaseEvent_thread : public genericThread
{
    public:
        releaseEvent_thread( cl_event *event ) : mEvent( event ) {}

        cl_event * mEvent;

    protected:
        virtual void *    IRun( void )
        {
            usleep( 1000000 );
            log_info( "\tTriggering gate from separate thread...\n" );
            clSetUserEventStatus( *mEvent, CL_COMPLETE );
            return NULL;
        }
};

int test_userevents_multithreaded( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
{
    cl_int error;

    // Set up a user event to act as a gate
    clEventWrapper gateEvent = clCreateUserEvent( context, &error );
    test_error( error, "Unable to create user gate event" );

    // Set up a few actions gated on the user event
    NDRangeKernelAction action1;
    ReadBufferAction action2;
    WriteBufferAction action3;

    clEventWrapper actionEvents[ 3 ];
    Action * actions[] = { &action1, &action2, &action3, NULL };

    for( int i = 0; actions[ i ] != NULL; i++ )
    {
        error = actions[ i ]->Setup( deviceID, context, queue );
        test_error( error, "Unable to set up test action" );

        error = actions[ i ]->Execute( queue, 1, &gateEvent, &actionEvents[ i ] );
        test_error( error, "Unable to execute test action" );
    }

    // Now, instead of releasing the gate, we spawn a separate thread to do so
    releaseEvent_thread thread( &gateEvent );
    log_info( "\tStarting trigger thread...\n" );
    thread.Start();

    log_info( "\tWaiting for actions...\n" );
    error = clWaitForEvents( 3, &actionEvents[ 0 ] );
    test_error( error, "Unable to wait for action events" );

    log_info( "\tActions completed.\n" );

    // If we got here without error, we're good
    return 0;
}

<commit_msg>Use std::thread for userevents_multithreaded test (#824)<commit_after>//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "testBase.h"
#include "action_classes.h"
#include "harness/conversions.h"

#include <thread>

#if !defined (_MSC_VER)
    #include <unistd.h>
#endif // !_MSC_VER

void trigger_user_event(cl_event *event)
{
    usleep(1000000);
    log_info("\tTriggering gate from separate thread...\n");
    clSetUserEventStatus(*event, CL_COMPLETE);
}

int test_userevents_multithreaded( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
{
    cl_int error;

    // Set up a user event to act as a gate
    clEventWrapper gateEvent = clCreateUserEvent( context, &error );
    test_error( error, "Unable to create user gate event" );

    // Set up a few actions gated on the user event
    NDRangeKernelAction action1;
    ReadBufferAction action2;
    WriteBufferAction action3;

    clEventWrapper actionEvents[ 3 ];
    Action * actions[] = { &action1, &action2, &action3, NULL };

    for( int i = 0; actions[ i ] != NULL; i++ )
    {
        error = actions[ i ]->Setup( deviceID, context, queue );
        test_error( error, "Unable to set up test action" );

        error = actions[ i ]->Execute( queue, 1, &gateEvent, &actionEvents[ i ] );
        test_error( error, "Unable to execute test action" );
    }

    // Now, instead of releasing the gate, we spawn a separate thread to do so
    log_info( "\tStarting trigger thread...\n" );
    std::thread thread(trigger_user_event, &gateEvent);

    log_info( "\tWaiting for actions...\n" );
    error = clWaitForEvents( 3, &actionEvents[ 0 ] );
    test_error( error, "Unable to wait for action events" );

    thread.join();
    log_info( "\tActions completed.\n" );

    // If we got here without error, we're good
    return 0;
}

<|endoftext|>