<commit_before>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "MarbleWidgetInputHandler.h"

#include <cmath>

#include <QtCore/QDebug>

#include "global.h"
#include "GeoDataPoint.h"
#include "Quaternion.h"
#include "MarbleDirs.h"
#include "MarbleWidget.h"
#include "MarbleMap.h"
#include "MarbleModel.h"
#include "ViewParams.h"

MarbleWidgetInputHandler::MarbleWidgetInputHandler()
    : m_widget( 0 ),
      m_model( 0 )
{
    m_positionSignalConnected = false;
    m_mouseWheelTimer = new QTimer(this);
    connect( m_mouseWheelTimer, SIGNAL( timeout() ),
	     this,              SLOT( restoreViewContext() ) );
}

MarbleWidgetInputHandler::~MarbleWidgetInputHandler()
{
    delete m_mouseWheelTimer;
}

void MarbleWidgetInputHandler::init(MarbleWidget *w)
{
    m_widget = w;
    m_model = w->model();
}

MarbleWidgetDefaultInputHandler::MarbleWidgetDefaultInputHandler()
    : MarbleWidgetInputHandler()
{
    curpmtl.load( MarbleDirs::path("bitmaps/cursor_tl.xpm") );
    curpmtc.load( MarbleDirs::path("bitmaps/cursor_tc.xpm") );
    curpmtr.load( MarbleDirs::path("bitmaps/cursor_tr.xpm") );
    curpmcr.load( MarbleDirs::path("bitmaps/cursor_cr.xpm") );
    curpmcl.load( MarbleDirs::path("bitmaps/cursor_cl.xpm") );
    curpmbl.load( MarbleDirs::path("bitmaps/cursor_bl.xpm") );
    curpmbc.load( MarbleDirs::path("bitmaps/cursor_bc.xpm") );
    curpmbr.load( MarbleDirs::path("bitmaps/cursor_br.xpm") );

    arrowcur [0][0] = QCursor(curpmtl,2,2);
    arrowcur [1][0] = QCursor(curpmtc,10,3);
    arrowcur [2][0] = QCursor(curpmtr,19,2);
    arrowcur [0][1] = QCursor(curpmcl,3,10);
    arrowcur [1][1] = QCursor(Qt::OpenHandCursor);
    arrowcur [2][1] = QCursor(curpmcr,18,10);
    arrowcur [0][2] = QCursor(curpmbl,2,19);
    arrowcur [1][2] = QCursor(curpmbc,11,18);
    arrowcur [2][2] = QCursor(curpmbr,19,19);

    m_leftpressed = false;
    m_midpressed  = false;

    m_dragThreshold = 3;
}

void MarbleWidgetInputHandler::restoreViewContext()
{
    // Needs to stop the timer since it repeats otherwise.
    m_mouseWheelTimer->stop();

    // Redraw the map with the quality set for Marble::Still (if necessary).
    m_widget->setViewContext( Marble::Still );
    if ( m_widget->mapQuality( Marble::Still )
        != m_widget->mapQuality( Marble::Animation ) )
    {
        m_widget->updateChangedMap();
    }
}

bool MarbleWidgetDefaultInputHandler::eventFilter( QObject* o, QEvent* e )
{
    Q_UNUSED( o );

    int polarity = 0;

    if ( m_widget->northPoleY() != 0 )
        polarity = m_widget->northPoleY() / abs(m_widget->northPoleY());

    //	if ( o == marbleWidget ){
    if ( e->type() == QEvent::KeyPress ) {
        QKeyEvent  *k = (QKeyEvent *)e;

        dirx = 0;
        diry = 0;
        switch ( k->key() ) {
        case 0x01000012:
            if ( polarity < 0 )
                dirx = -1;
            else
                dirx = 1;
            break;
        case 0x01000013:
            diry = 1;
            break;
        case 0x01000014:
            if ( polarity < 0 )
                dirx = 1;
            else
                dirx = -1;
            break;
        case 0x01000015:
            diry = -1;
            break;
        case 0x2b:
            m_widget->zoomIn();
            break;
        case 0x2d:
            m_widget->zoomOut();
            break;
        case 0x01000010:
            m_widget->goHome();
            break;
        default:
            break;
        }

        if ( dirx != 0 || diry != 0 ) {
            m_widget->rotateBy( -m_widget->moveStep() * (double)(dirx),
                                -m_widget->moveStep() * (double)(diry) );
        }

        return true;
    }
    else if ( e->type() == QEvent::MouseMove
              || e->type() == QEvent::MouseButtonPress
              || e->type() == QEvent::MouseButtonRelease ) {

        QMouseEvent  *event        = static_cast<QMouseEvent*>(e);
        QRegion       activeRegion = m_widget->activeRegion();

        dirx = 0;
        diry = 0;

        // emit the position string only if the signal got attached
        if ( m_positionSignalConnected ) {
            double  lat;
            double  lon;
            bool    isValid = m_widget->geoCoordinates( event->x(), event->y(),
                                                        lon, lat,
                                                        GeoDataPoint::Radian );

            if ( !isValid ) {
                emit mouseMoveGeoPosition( tr( NOT_AVAILABLE ) );
            }
            else {
                QString position = GeoDataPoint( lon, lat ).toString( GeoDataPoint::DMS );
                emit mouseMoveGeoPosition( position );
            }
        }

        if ( activeRegion.contains( event->pos() ) ) {

            if ( e->type() == QEvent::MouseButtonDblClick) {
                qDebug("check");
            }

            // Regarding mouse button presses:
            if ( e->type() == QEvent::MouseButtonPress
                 && event->button() == Qt::LeftButton ) {

                m_dragtimer.restart();

                m_leftpressed = true;
                m_midpressed  = false;

                // On the single event of a mouse button press these
                // values get stored, to enable us to e.g. calculate the
                // distance of a mouse drag while the mouse button is
                // still down.
                m_leftpressedx = event->x();
                m_leftpressedy = event->y();

                // Calculate translation of center point
                m_leftpresseda =  m_widget->centerLongitude() * DEG2RAD;
                m_leftpressedb =  m_widget->centerLatitude() * DEG2RAD;

                m_widget->setViewContext( Marble::Animation );
            }

            if ( e->type() == QEvent::MouseButtonPress
                 && event->button() == Qt::MidButton) {
                m_midpressed  = true;
                m_leftpressed = false;
                m_midpressedy = event->y();

                m_widget->setViewContext( Marble::Animation );
            }

            if ( e->type() == QEvent::MouseButtonPress
                 && event->button() == Qt::RightButton ) {
                emit rmbRequest( event->x(), event->y() );
            }

            // Regarding mouse button releases:
            if ( e->type() == QEvent::MouseButtonRelease
                 && event->button() == Qt::LeftButton)
            {

                //emit current gps coordinates to be be interpreted
                //as requested
                emit mouseClickScreenPosition( m_leftpressedx, m_leftpressedy );

                // Show menu if mouse cursor position remains unchanged
                // the click takes less than 250 ms
                if ( m_dragtimer.elapsed() <= 250
		     || ( m_leftpressedx == event->x()
			  && m_leftpressedy == event->y() ) ) {
                    emit lmbRequest( m_leftpressedx, m_leftpressedy );
                }

                m_widget->setViewContext( Marble::Still );
                if ( m_widget->mapQuality( Marble::Still )
                    != m_widget->mapQuality( Marble::Animation ) )
                {
                    m_widget->updateChangedMap();
                }

                m_leftpressed = false;
            }

            if ( e->type() == QEvent::MouseButtonRelease
                 && event->button() == Qt::MidButton) {
                m_midpressed = false;

                m_widget->setViewContext( Marble::Still );
                if ( m_widget->mapQuality( Marble::Still )
                    != m_widget->mapQuality( Marble::Animation ) )
                {
                    m_widget->updateChangedMap();
                }
            }

            if ( e->type() == QEvent::MouseButtonRelease
                 && event->button() == Qt::RightButton) {
            }

            // Regarding all kinds of mouse moves:
            if ( m_leftpressed == true ) {
                double  radius = (double)(m_widget->radius());
                int     deltax = event->x() - m_leftpressedx;
                int     deltay = event->y() - m_leftpressedy;

                if ( abs(deltax) <= m_dragThreshold
                     && abs(deltay) <= m_dragThreshold )
                    return true;

                double direction = 1;
                // Choose spin direction by taking into account whether we
                // drag above or below the visible pole.
                if ( m_widget->projection() == Spherical ) {
                    if ( m_widget->northPoleZ() > 0 ) {

                        if ( event->y() < ( - m_widget->northPoleY()
                                        + m_widget->height() / 2 ) )
                            direction = -1;
                    }
                    else {
                        if (event->y() > ( + m_widget->northPoleY()
                                           + m_widget->height() / 2 ) )
                            direction = -1;
                    }
                }
                m_widget->centerOn( RAD2DEG * (double)(m_leftpresseda)
                                    - 90.0 * direction * deltax / radius,
                                    RAD2DEG * (double)(m_leftpressedb)
                                    + 90.0 * deltay / radius );
            }

            if ( m_midpressed == true ) {
                int  eventy = event->y();
                int  dy     = m_midpressedy - eventy;
                m_midpressed = eventy;
                m_widget->zoomViewBy( (int)( 2 * dy / 3 ) );
                m_widget->repaint();
            }
        }
        else {
            m_leftpressed = false;

            dirx = (int)( 3 * event->x() / m_widget->width() ) - 1;

            if ( dirx > 1 )
                dirx = 1;
            if ( dirx < -1 )
                dirx = -1;

            diry = (int)( 3 * event->y() / m_widget->height() ) - 1;
            if ( diry > 1 )
                diry = 1;
            if ( diry < -1 )
                diry = -1;

            //Hack for properly behavior for the arrow
            if( true ) {//m_widget->m_viewParams->m_projection == Equirectangular ) {
                int     radius        = m_widget->radius();

                // Calculate translation of center point
                double centerLat = DEG2RAD * m_widget->centerLatitude();

                int     yCenterOffset = (int)((double)(2 * radius / M_PI) * centerLat);
                int     yTop          =  m_widget->height() / 2 - radius - yCenterOffset;
                int     yBottom       = yTop + 2 * radius;
                yTop = ( yTop > 0 ) ? yTop : 0;
                if ( dirx == 0 && event->y() < yTop)
                    diry=-1;
                if ( dirx == 0 && event->y() > yBottom )
                    diry=1;
            }

            if ( event->button() == Qt::LeftButton
                 && e->type() == QEvent::MouseButtonPress ) {

                if ( polarity < 0 )
                    m_widget->rotateBy( -m_widget->moveStep() * (double)(+dirx),
                                        m_widget->moveStep() * (double)(+diry) );
                else
                    m_widget->rotateBy( -m_widget->moveStep() * (double)(-dirx),
                                        m_widget->moveStep() * (double)(+diry) );
            }
        }

        // Adjusting Cursor shape

        if ( ( m_widget->model()->whichFeatureAt( QPoint( event->x(),
                                                          event->y() ) ) ).size() == 0 )
        {
            if ( m_leftpressed == false )
                arrowcur [1][1] = QCursor(Qt::OpenHandCursor);
            else
                arrowcur [1][1] = QCursor(Qt::ClosedHandCursor);
        }
        else {
            if ( m_leftpressed == false )
                arrowcur [1][1] = QCursor(Qt::PointingHandCursor);
        }

        m_widget->setCursor(arrowcur[dirx+1][diry+1]);

        return true;
    }
    else {
        if ( e->type() == QEvent::Wheel ) {
            // FIXME: disable animation quality after some time
            m_widget->setViewContext( Marble::Animation );

            QWheelEvent  *wheelevt = static_cast<QWheelEvent*>(e);
            m_widget->zoomViewBy( (int)(wheelevt->delta() / 3) );
            m_mouseWheelTimer->start(400);
            return true;
        }
        else
            return false;
    }
}

#include "MarbleWidgetInputHandler.moc"
<commit_msg>- Qt::- Keycodes<commit_after>//
// This file is part of the Marble Desktop Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>"
// Copyright 2007      Inge Wallin  <ingwa@kde.org>"
//

#include "MarbleWidgetInputHandler.h"

#include <cmath>

#include <QtCore/QDebug>

#include "global.h"
#include "GeoDataPoint.h"
#include "Quaternion.h"
#include "MarbleDirs.h"
#include "MarbleWidget.h"
#include "MarbleMap.h"
#include "MarbleModel.h"
#include "ViewParams.h"

MarbleWidgetInputHandler::MarbleWidgetInputHandler()
    : m_widget( 0 ),
      m_model( 0 )
{
    m_positionSignalConnected = false;
    m_mouseWheelTimer = new QTimer(this);
    connect( m_mouseWheelTimer, SIGNAL( timeout() ),
	     this,              SLOT( restoreViewContext() ) );
}

MarbleWidgetInputHandler::~MarbleWidgetInputHandler()
{
    delete m_mouseWheelTimer;
}

void MarbleWidgetInputHandler::init(MarbleWidget *w)
{
    m_widget = w;
    m_model = w->model();
}

MarbleWidgetDefaultInputHandler::MarbleWidgetDefaultInputHandler()
    : MarbleWidgetInputHandler()
{
    curpmtl.load( MarbleDirs::path("bitmaps/cursor_tl.xpm") );
    curpmtc.load( MarbleDirs::path("bitmaps/cursor_tc.xpm") );
    curpmtr.load( MarbleDirs::path("bitmaps/cursor_tr.xpm") );
    curpmcr.load( MarbleDirs::path("bitmaps/cursor_cr.xpm") );
    curpmcl.load( MarbleDirs::path("bitmaps/cursor_cl.xpm") );
    curpmbl.load( MarbleDirs::path("bitmaps/cursor_bl.xpm") );
    curpmbc.load( MarbleDirs::path("bitmaps/cursor_bc.xpm") );
    curpmbr.load( MarbleDirs::path("bitmaps/cursor_br.xpm") );

    arrowcur [0][0] = QCursor(curpmtl,2,2);
    arrowcur [1][0] = QCursor(curpmtc,10,3);
    arrowcur [2][0] = QCursor(curpmtr,19,2);
    arrowcur [0][1] = QCursor(curpmcl,3,10);
    arrowcur [1][1] = QCursor(Qt::OpenHandCursor);
    arrowcur [2][1] = QCursor(curpmcr,18,10);
    arrowcur [0][2] = QCursor(curpmbl,2,19);
    arrowcur [1][2] = QCursor(curpmbc,11,18);
    arrowcur [2][2] = QCursor(curpmbr,19,19);

    m_leftpressed = false;
    m_midpressed  = false;

    m_dragThreshold = 3;
}

void MarbleWidgetInputHandler::restoreViewContext()
{
    // Needs to stop the timer since it repeats otherwise.
    m_mouseWheelTimer->stop();

    // Redraw the map with the quality set for Marble::Still (if necessary).
    m_widget->setViewContext( Marble::Still );
    if ( m_widget->mapQuality( Marble::Still )
        != m_widget->mapQuality( Marble::Animation ) )
    {
        m_widget->updateChangedMap();
    }
}

bool MarbleWidgetDefaultInputHandler::eventFilter( QObject* o, QEvent* e )
{
    Q_UNUSED( o );

    int polarity = 0;

    if ( m_widget->northPoleY() != 0 )
        // FIXME: retrieve the polarity from ViewParams instead
        polarity = m_widget->northPoleY() / abs(m_widget->northPoleY());

    //	if ( o == marbleWidget ){
    if ( e->type() == QEvent::KeyPress ) {
        QKeyEvent  *k = (QKeyEvent *)e;

        dirx = 0;
        diry = 0;
        switch ( k->key() ) {
        case Qt::Key_Left:

            // Depending on whether the planet is "upright" or
            // "upside down" we need to choose the direction
            //  of the rotation

            if ( polarity < 0 )
                dirx = -1;
            else
                dirx = 1;
            break;
        case Qt::Key_Up:
            diry = 1;
            break;
        case Qt::Key_Right:

            // Depending on whether the planet is "upright" or
            // "upside down" we need to choose the direction
            //  of the rotation

            if ( polarity < 0 )
                dirx = 1;
            else
                dirx = -1;
            break;
        case Qt::Key_Down:
            diry = -1;
            break;
        case Qt::Key_Plus:
            m_widget->zoomIn();
            break;
        case Qt::Key_Minus:
            m_widget->zoomOut();
            break;
        case Qt::Key_Home:
            m_widget->goHome();
            break;
        default:
            break;
        }

        if ( dirx != 0 || diry != 0 ) {
            m_widget->rotateBy( -m_widget->moveStep() * (double)(dirx),
                                -m_widget->moveStep() * (double)(diry) );
        }

        return true;
    }
    else if ( e->type() == QEvent::MouseMove
              || e->type() == QEvent::MouseButtonPress
              || e->type() == QEvent::MouseButtonRelease ) {

        QMouseEvent  *event        = static_cast<QMouseEvent*>(e);
        QRegion       activeRegion = m_widget->activeRegion();

        dirx = 0;
        diry = 0;

        // emit the position string only if the signal got attached
        if ( m_positionSignalConnected ) {
            double  lat;
            double  lon;
            bool    isValid = m_widget->geoCoordinates( event->x(), event->y(),
                                                        lon, lat,
                                                        GeoDataPoint::Radian );

            if ( !isValid ) {
                emit mouseMoveGeoPosition( tr( NOT_AVAILABLE ) );
            }
            else {
                QString position = GeoDataPoint( lon, lat ).toString( GeoDataPoint::DMS );
                emit mouseMoveGeoPosition( position );
            }
        }

        if ( activeRegion.contains( event->pos() ) ) {

            if ( e->type() == QEvent::MouseButtonDblClick) {
                qDebug("check");
            }

            // Regarding mouse button presses:
            if ( e->type() == QEvent::MouseButtonPress
                 && event->button() == Qt::LeftButton ) {

                m_dragtimer.restart();

                m_leftpressed = true;
                m_midpressed  = false;

                // On the single event of a mouse button press these
                // values get stored, to enable us to e.g. calculate the
                // distance of a mouse drag while the mouse button is
                // still down.
                m_leftpressedx = event->x();
                m_leftpressedy = event->y();

                // Calculate translation of center point
                m_leftpresseda =  m_widget->centerLongitude() * DEG2RAD;
                m_leftpressedb =  m_widget->centerLatitude() * DEG2RAD;

                m_widget->setViewContext( Marble::Animation );
            }

            if ( e->type() == QEvent::MouseButtonPress
                 && event->button() == Qt::MidButton) {
                m_midpressed  = true;
                m_leftpressed = false;
                m_midpressedy = event->y();

                m_widget->setViewContext( Marble::Animation );
            }

            if ( e->type() == QEvent::MouseButtonPress
                 && event->button() == Qt::RightButton ) {
                emit rmbRequest( event->x(), event->y() );
            }

            // Regarding mouse button releases:
            if ( e->type() == QEvent::MouseButtonRelease
                 && event->button() == Qt::LeftButton)
            {

                //emit current gps coordinates to be be interpreted
                //as requested
                emit mouseClickScreenPosition( m_leftpressedx, m_leftpressedy );

                // Show menu if mouse cursor position remains unchanged
                // the click takes less than 250 ms
                if ( m_dragtimer.elapsed() <= 250
		     || ( m_leftpressedx == event->x()
			  && m_leftpressedy == event->y() ) ) {
                    emit lmbRequest( m_leftpressedx, m_leftpressedy );
                }

                m_widget->setViewContext( Marble::Still );
                if ( m_widget->mapQuality( Marble::Still )
                    != m_widget->mapQuality( Marble::Animation ) )
                {
                    m_widget->updateChangedMap();
                }

                m_leftpressed = false;
            }

            if ( e->type() == QEvent::MouseButtonRelease
                 && event->button() == Qt::MidButton) {
                m_midpressed = false;

                m_widget->setViewContext( Marble::Still );
                if ( m_widget->mapQuality( Marble::Still )
                    != m_widget->mapQuality( Marble::Animation ) )
                {
                    m_widget->updateChangedMap();
                }
            }

            if ( e->type() == QEvent::MouseButtonRelease
                 && event->button() == Qt::RightButton) {
            }

            // Regarding all kinds of mouse moves:
            if ( m_leftpressed == true ) {
                double  radius = (double)(m_widget->radius());
                int     deltax = event->x() - m_leftpressedx;
                int     deltay = event->y() - m_leftpressedy;

                if ( abs(deltax) <= m_dragThreshold
                     && abs(deltay) <= m_dragThreshold )
                    return true;

                double direction = 1;
                // Choose spin direction by taking into account whether we
                // drag above or below the visible pole.
                if ( m_widget->projection() == Spherical ) {
                    if ( m_widget->northPoleZ() > 0 ) {

                        if ( event->y() < ( - m_widget->northPoleY()
                                        + m_widget->height() / 2 ) )
                            direction = -1;
                    }
                    else {
                        if (event->y() > ( + m_widget->northPoleY()
                                           + m_widget->height() / 2 ) )
                            direction = -1;
                    }
                }
                m_widget->centerOn( RAD2DEG * (double)(m_leftpresseda)
                                    - 90.0 * direction * deltax / radius,
                                    RAD2DEG * (double)(m_leftpressedb)
                                    + 90.0 * deltay / radius );
            }

            if ( m_midpressed == true ) {
                int  eventy = event->y();
                int  dy     = m_midpressedy - eventy;
                m_midpressed = eventy;
                m_widget->zoomViewBy( (int)( 2 * dy / 3 ) );
                m_widget->repaint();
            }
        }
        else {
            m_leftpressed = false;

            dirx = (int)( 3 * event->x() / m_widget->width() ) - 1;

            if ( dirx > 1 )
                dirx = 1;
            if ( dirx < -1 )
                dirx = -1;

            diry = (int)( 3 * event->y() / m_widget->height() ) - 1;
            if ( diry > 1 )
                diry = 1;
            if ( diry < -1 )
                diry = -1;

            //Hack for properly behavior for the arrow
            if( true ) {//m_widget->m_viewParams->m_projection == Equirectangular ) {
                int     radius        = m_widget->radius();

                // Calculate translation of center point
                double centerLat = DEG2RAD * m_widget->centerLatitude();

                int     yCenterOffset = (int)((double)(2 * radius / M_PI) * centerLat);
                int     yTop          =  m_widget->height() / 2 - radius - yCenterOffset;
                int     yBottom       = yTop + 2 * radius;
                yTop = ( yTop > 0 ) ? yTop : 0;
                if ( dirx == 0 && event->y() < yTop)
                    diry=-1;
                if ( dirx == 0 && event->y() > yBottom )
                    diry=1;
            }

            if ( event->button() == Qt::LeftButton
                 && e->type() == QEvent::MouseButtonPress ) {

                if ( polarity < 0 )
                    m_widget->rotateBy( -m_widget->moveStep() * (double)(+dirx),
                                        m_widget->moveStep() * (double)(+diry) );
                else
                    m_widget->rotateBy( -m_widget->moveStep() * (double)(-dirx),
                                        m_widget->moveStep() * (double)(+diry) );
            }
        }

        // Adjusting Cursor shape

        if ( ( m_widget->model()->whichFeatureAt( QPoint( event->x(),
                                                          event->y() ) ) ).size() == 0 )
        {
            if ( m_leftpressed == false )
                arrowcur [1][1] = QCursor(Qt::OpenHandCursor);
            else
                arrowcur [1][1] = QCursor(Qt::ClosedHandCursor);
        }
        else {
            if ( m_leftpressed == false )
                arrowcur [1][1] = QCursor(Qt::PointingHandCursor);
        }

        m_widget->setCursor(arrowcur[dirx+1][diry+1]);

        return true;
    }
    else {
        if ( e->type() == QEvent::Wheel ) {
            // FIXME: disable animation quality after some time
            m_widget->setViewContext( Marble::Animation );

            QWheelEvent  *wheelevt = static_cast<QWheelEvent*>(e);
            m_widget->zoomViewBy( (int)(wheelevt->delta() / 3) );
            m_mouseWheelTimer->start(400);
            return true;
        }
        else
            return false;
    }
}

#include "MarbleWidgetInputHandler.moc"
<|endoftext|>


<commit_before>/* Copyright (c) 2010-present Advanced Micro Devices, Inc.

 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. */

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3100
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>SWDEV-2 - Change OpenCL version number from  3100 to 3101<commit_after>/* Copyright (c) 2010-present Advanced Micro Devices, Inc.

 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. */

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3101
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>#include "../../common/dep.hpp"
#include <chrono>

using namespace wrd;
using namespace std;

namespace {
    class myNode : public node {
        WRD(CLASS(myNode, node))

    public:
        myNode(int num): number(num) {}

        nbicontainer& subs() override { return nulOf<nbicontainer>(); }
        wbool canRun(const ucontainable& types) const override { return false; }
        str run(const ucontainable& args) override { return str(); }

        int number;
    };

    void benchMarkNMap(int cnt) {
        logger::get().setEnable(false);
        map<std::string, str> vec;

        auto start = chrono::steady_clock::now();
        for(int n=0; n < cnt; n++) {
            vec.insert({"hello", str(new myNode(n))});
        }
        int sz = vec.size();
        auto startDeleting = chrono::steady_clock::now();
        vec.clear();
        auto end = chrono::steady_clock::now();

        auto addingElapsed = startDeleting - start;
        auto removingElapsed = end - startDeleting;
        auto totalElapsed = end - start;

        logger::get().setEnable(true);
        WRD_I("[benchMarkNMap]: map took total %d ms for adding(%dms) & removing(%dms) of %d elems.",
                totalElapsed / chrono::milliseconds(1), addingElapsed / chrono::milliseconds(1),
                removingElapsed / chrono::milliseconds(1), sz);
        logger::get().setEnable(false);

        nmap map1;
        start = chrono::steady_clock::now();
        for(int n=0; n < cnt; n++) {
            map1.add("hello", *(new myNode(n)));
        }
        sz = map1.len();
        startDeleting = chrono::steady_clock::now();
        map1.rel();
        end = chrono::steady_clock::now();

        addingElapsed = startDeleting - start;
        removingElapsed = end - startDeleting;
        totalElapsed = end - start;

        logger::get().setEnable(true);
        WRD_I("[benchMarkNMap]: nmap took total %d ms for adding(%dms) & removing(%dms) of %d elems.",
                totalElapsed / chrono::milliseconds(1), addingElapsed / chrono::milliseconds(1),
                removingElapsed / chrono::milliseconds(1), sz);
    }

    class myMyNode : public myNode {
        WRD(CLASS(myMyNode, myNode))

    public:
        myMyNode(int num): super(num) {}
    };
}

TEST(nmapTest, instantiateTest) {
    nmap map1;
}

TEST(nmapTest, shouldNotCanAddLocalObject) {
    tnmap<std::string, myNode> map1;
    ASSERT_EQ(map1.len(), 0);

    {
        myNode localObj(5);
        ASSERT_TRUE(map1.add("local", localObj));
        ASSERT_FALSE(nul(map1["local"]));
        ASSERT_EQ(map1.len(), 1);
    }

    ASSERT_EQ(map1.len(), 1);
    auto& elem = map1["local"];
    ASSERT_TRUE(nul(elem));
}

TEST(nmapTest, simpleAddDelTest) {
    tnmap<std::string, myNode> map1;
    ASSERT_EQ(map1.len(), 0);

    const int EXPECT_NUMBER = 5;
    map1.add("5", *(new myNode(EXPECT_NUMBER)));
    ASSERT_EQ(map1.len(), 1);

    auto& elem1 = map1["5"];
    ASSERT_FALSE(nul(elem1));
    ASSERT_EQ(elem1.number, EXPECT_NUMBER);
}

TEST(nmapTest, addDel10Elems) {
    tnmap<int, myNode> map1;
    const int cnt = 10;
    for(int n=0; n < cnt; n++) {
        ASSERT_TRUE(map1.add(n, *(new myNode(n))));
    }

    ASSERT_EQ(map1.len(), cnt);
}

TEST(nmapTest, benchMarkNMapTest) {
    benchMarkNMap(100);
    benchMarkNMap(1000);
    benchMarkNMap(10000);
}

TEST(nmapTest, testIter) {
    nmap map1;
    map1.add("0", new myNode(0));
    map1.add("1", new myNode(1));
    map1.add("2", new myNode(2));

    auto e = map1.begin();
    auto head = e++;
    auto index2 = ++e;

    EXPECT_TRUE(map1.begin()+2 == index2);
    EXPECT_TRUE(map1.begin() == head);

    ASSERT_FALSE(e.isEnd());
    ASSERT_EQ(std::to_string(e.getVal<myNode>().number), e.getKey());
    ASSERT_EQ(e.next(1), 0);
}

wbool hasSequentialValueOf(int val, tbicontainable<std::string, myNode>& from) {
    std::vector<int> tray;
    for(auto& elem : from)
        tray.push_back(elem.number);

    for(int n=0; n < val ;n++) {
        wbool found = false;
        for(int n2=0; n < tray.size() ;n2++)
            if(tray[n2] == n) {
                found = true;
                break;
            }
        if(!found)
            return false;
    }
    return true;
}

TEST(nmapTest, testucontainableAPI) {
    //  initial state:
    tnmap<std::string, myNode>* map1 = new tnmap<std::string, myNode>();
    tbicontainable<std::string, myNode>* con = map1;
    ASSERT_EQ(con->len(), 0);

    auto head = con->begin();
    ASSERT_TRUE(head.isEnd());
    auto tail = con->end();
    ASSERT_TRUE(tail.isEnd());

    ASSERT_TRUE(con->add("0", new myNode(0)));
    ASSERT_TRUE(con->add("end", new myMyNode(1)));
    ASSERT_EQ(con->len(), 2);

    // add:
    ASSERT_TRUE(hasSequentialValueOf(1, *con));
    ASSERT_TRUE(hasSequentialValueOf(1, *con));

    {
        tnarr<myNode> tray = map1->getAll<myNode>([](const std::string&, const myNode& elem) {
            return true;
        });
        ASSERT_EQ(tray.len(), 2);

        int cnt = 0;
        tray = map1->getAll<myNode>([&cnt](const std::string&, const myNode& elem) {
            if(cnt++ >= 1) return false;
            return true;
        });
        ASSERT_EQ(tray.len(), 1);
    }

    myMyNode& tray = map1->get<myMyNode>([](const std::string&, const myMyNode& elem) {
        if(elem.number == 1) return true;
        return false;
    });
    ASSERT_FALSE(nul(tray));

    //  del:
    ASSERT_TRUE(con->del("end"));
    ASSERT_EQ(con->len(), 1);
    ASSERT_EQ(map1->get("0").number, 0);

    //  add with element:
    tnmap<std::string, myNode> map2;
    ASSERT_EQ(map2.add(*con), 1);
    ASSERT_TRUE(map2.add("1", new myNode(1)));
    ASSERT_TRUE(map2.add("2", new myMyNode(2)));
    ASSERT_TRUE(map2.add("3", new myNode(3)));
    ASSERT_EQ(map2["2"].number, 2);
    ASSERT_EQ(map2["3"].number, 3);
    ASSERT_EQ(map2.len(), 4);

    auto e = map2.begin();
    e = e + 2;
    ASSERT_EQ(e.getKey(), std::to_string(e.getVal<myNode>().number));
    ASSERT_TRUE(map2.add("5", new myNode(5)));
    ASSERT_TRUE(map2.add("6", new myNode(6)));

    ASSERT_EQ(map2["0"].cast<myNode>().number, 0);
    ASSERT_EQ(map2["1"].cast<myNode>().number, 1);
    ASSERT_EQ(map2["6"].cast<myNode>().number, 6);
    ASSERT_EQ(map2["5"].cast<myNode>().number, 5);
    ASSERT_EQ(map2["2"].cast<myNode>().number, 2);
    ASSERT_EQ(map2["3"].cast<myNode>().number, 3);

    ASSERT_EQ(con->len(), 1);
    ASSERT_EQ(con->add(map2.iterate(1), map2.iterate(3)), 2);
    ASSERT_EQ(con->len(), 3);
    con->rel();
    ASSERT_TRUE(con->len() == 0);

    ASSERT_EQ(con->add(map2.begin() + 2, map2.end()), 4);
    ASSERT_EQ(con->len(), 4);
    ASSERT_EQ(con->del(con->begin() + 1, con->begin() + 3), 2);
    ASSERT_EQ(con->len(), 2);

    delete con;
}

TEST(nmapTest, testRangeBasedForLoop) {

    nmap map1;
    map1.add("3", new myNode(3));
    map1.add("7", new myNode(7));

    int sum = 0;
    for(auto& e : map1) {
        myNode& cast = e.cast<myNode>();
        sum += cast.number;
    }

    int sum2 = 0;
    for(const node& e : map1) {
        const myNode& cast = e.cast<myNode>();
        sum2 += cast.number;
    }
    ASSERT_EQ(sum2, sum);
}
<commit_msg>wrd: test: add TC for multimap<commit_after>#include "../../common/dep.hpp"
#include <chrono>

using namespace wrd;
using namespace std;

namespace {
    class myNode : public node {
        WRD(CLASS(myNode, node))

    public:
        myNode(int num): number(num) {}

        nbicontainer& subs() override { return nulOf<nbicontainer>(); }
        wbool canRun(const ucontainable& types) const override { return false; }
        str run(const ucontainable& args) override { return str(); }

        int number;
    };

    void benchMarkNMap(int cnt) {
        logger::get().setEnable(false);
        map<std::string, str> vec;

        auto start = chrono::steady_clock::now();
        for(int n=0; n < cnt; n++) {
            vec.insert({"hello", str(new myNode(n))});
        }
        int sz = vec.size();
        auto startDeleting = chrono::steady_clock::now();
        vec.clear();
        auto end = chrono::steady_clock::now();

        auto addingElapsed = startDeleting - start;
        auto removingElapsed = end - startDeleting;
        auto totalElapsed = end - start;

        logger::get().setEnable(true);
        WRD_I("[benchMarkNMap]: map took total %d ms for adding(%dms) & removing(%dms) of %d elems.",
                totalElapsed / chrono::milliseconds(1), addingElapsed / chrono::milliseconds(1),
                removingElapsed / chrono::milliseconds(1), sz);
        logger::get().setEnable(false);

        nmap map1;
        start = chrono::steady_clock::now();
        for(int n=0; n < cnt; n++) {
            map1.add("hello", *(new myNode(n)));
        }
        sz = map1.len();
        startDeleting = chrono::steady_clock::now();
        map1.rel();
        end = chrono::steady_clock::now();

        addingElapsed = startDeleting - start;
        removingElapsed = end - startDeleting;
        totalElapsed = end - start;

        logger::get().setEnable(true);
        WRD_I("[benchMarkNMap]: nmap took total %d ms for adding(%dms) & removing(%dms) of %d elems.",
                totalElapsed / chrono::milliseconds(1), addingElapsed / chrono::milliseconds(1),
                removingElapsed / chrono::milliseconds(1), sz);
    }

    class myMyNode : public myNode {
        WRD(CLASS(myMyNode, myNode))

    public:
        myMyNode(int num): super(num) {}
    };
}

TEST(nmapTest, instantiateTest) {
    nmap map1;
}

TEST(nmapTest, shouldNotCanAddLocalObject) {
    tnmap<std::string, myNode> map1;
    ASSERT_EQ(map1.len(), 0);

    {
        myNode localObj(5);
        ASSERT_TRUE(map1.add("local", localObj));
        ASSERT_FALSE(nul(map1["local"]));
        ASSERT_EQ(map1.len(), 1);
    }

    ASSERT_EQ(map1.len(), 1);
    auto& elem = map1["local"];
    ASSERT_TRUE(nul(elem));
}

TEST(nmapTest, simpleAddDelTest) {
    tnmap<std::string, myNode> map1;
    ASSERT_EQ(map1.len(), 0);

    const int EXPECT_NUMBER = 5;
    map1.add("5", *(new myNode(EXPECT_NUMBER)));
    ASSERT_EQ(map1.len(), 1);

    auto& elem1 = map1["5"];
    ASSERT_FALSE(nul(elem1));
    ASSERT_EQ(elem1.number, EXPECT_NUMBER);
}

TEST(nmapTest, addDel10Elems) {
    tnmap<int, myNode> map1;
    const int cnt = 10;
    for(int n=0; n < cnt; n++) {
        ASSERT_TRUE(map1.add(n, *(new myNode(n))));
    }

    ASSERT_EQ(map1.len(), cnt);
}

TEST(nmapTest, benchMarkNMapTest) {
    benchMarkNMap(100);
    benchMarkNMap(1000);
    benchMarkNMap(10000);
}

TEST(nmapTest, testIter) {
    nmap map1;
    map1.add("0", new myNode(0));
    map1.add("1", new myNode(1));
    map1.add("2", new myNode(2));

    auto e = map1.begin();
    auto head = e++;
    auto index2 = ++e;

    EXPECT_TRUE(map1.begin()+2 == index2);
    EXPECT_TRUE(map1.begin() == head);

    ASSERT_FALSE(e.isEnd());
    ASSERT_EQ(std::to_string(e.getVal<myNode>().number), e.getKey());
    ASSERT_EQ(e.next(1), 0);
}

wbool hasSequentialValueOf(int val, tbicontainable<std::string, myNode>& from) {
    std::vector<int> tray;
    for(auto& elem : from)
        tray.push_back(elem.number);

    for(int n=0; n < val ;n++) {
        wbool found = false;
        for(int n2=0; n < tray.size() ;n2++)
            if(tray[n2] == n) {
                found = true;
                break;
            }
        if(!found)
            return false;
    }
    return true;
}

TEST(nmapTest, testucontainableAPI) {
    //  initial state:
    tnmap<std::string, myNode>* map1 = new tnmap<std::string, myNode>();
    tbicontainable<std::string, myNode>* con = map1;
    ASSERT_EQ(con->len(), 0);

    auto head = con->begin();
    ASSERT_TRUE(head.isEnd());
    auto tail = con->end();
    ASSERT_TRUE(tail.isEnd());

    ASSERT_TRUE(con->add("0", new myNode(0)));
    ASSERT_TRUE(con->add("end", new myMyNode(1)));
    ASSERT_EQ(con->len(), 2);

    // add:
    ASSERT_TRUE(hasSequentialValueOf(1, *con));
    ASSERT_TRUE(hasSequentialValueOf(1, *con));

    {
        tnarr<myNode> tray = map1->getAll<myNode>([](const std::string&, const myNode& elem) {
            return true;
        });
        ASSERT_EQ(tray.len(), 2);

        int cnt = 0;
        tray = map1->getAll<myNode>([&cnt](const std::string&, const myNode& elem) {
            if(cnt++ >= 1) return false;
            return true;
        });
        ASSERT_EQ(tray.len(), 1);
    }

    myMyNode& tray = map1->get<myMyNode>([](const std::string&, const myMyNode& elem) {
        if(elem.number == 1) return true;
        return false;
    });
    ASSERT_FALSE(nul(tray));

    //  del:
    ASSERT_TRUE(con->del("end"));
    ASSERT_EQ(con->len(), 1);
    ASSERT_EQ(map1->get("0").number, 0);

    //  add with element:
    tnmap<std::string, myNode> map2;
    ASSERT_EQ(map2.add(*con), 1);
    ASSERT_TRUE(map2.add("1", new myNode(1)));
    ASSERT_TRUE(map2.add("2", new myMyNode(2)));
    ASSERT_TRUE(map2.add("3", new myNode(3)));
    ASSERT_EQ(map2["2"].number, 2);
    ASSERT_EQ(map2["3"].number, 3);
    ASSERT_EQ(map2.len(), 4);

    auto e = map2.begin();
    e = e + 2;
    ASSERT_EQ(e.getKey(), std::to_string(e.getVal<myNode>().number));
    ASSERT_TRUE(map2.add("5", new myNode(5)));
    ASSERT_TRUE(map2.add("6", new myNode(6)));

    ASSERT_EQ(map2["0"].cast<myNode>().number, 0);
    ASSERT_EQ(map2["1"].cast<myNode>().number, 1);
    ASSERT_EQ(map2["6"].cast<myNode>().number, 6);
    ASSERT_EQ(map2["5"].cast<myNode>().number, 5);
    ASSERT_EQ(map2["2"].cast<myNode>().number, 2);
    ASSERT_EQ(map2["3"].cast<myNode>().number, 3);

    ASSERT_EQ(con->len(), 1);
    ASSERT_EQ(con->add(map2.iterate(1), map2.iterate(3)), 2);
    ASSERT_EQ(con->len(), 3);
    con->rel();
    ASSERT_TRUE(con->len() == 0);

    ASSERT_EQ(con->add(map2.begin() + 2, map2.end()), 4);
    ASSERT_EQ(con->len(), 4);
    ASSERT_EQ(con->del(con->begin() + 1, con->begin() + 3), 2);
    ASSERT_EQ(con->len(), 2);

    delete con;
}

TEST(nmapTest, testRangeBasedForLoop) {

    nmap map1;
    map1.add("3", new myNode(3));
    map1.add("7", new myNode(7));

    int sum = 0;
    for(auto& e : map1) {
        myNode& cast = e.cast<myNode>();
        sum += cast.number;
    }

    int sum2 = 0;
    for(const node& e : map1) {
        const myNode& cast = e.cast<myNode>();
        sum2 += cast.number;
    }
    ASSERT_EQ(sum2, sum);
}

TEST(nmapTest, addMultipleKey) {
    nmap m;
    m.add("1", new myNode(1));
    m.add("2", new myNode(2));
    m.add("1", new myNode(3));
    m.add("3", new myNode(4));

    wcnt key1found = 0;
    for(auto e=m.begin(); e ;++e)
        if(e.getKey() == "1")
            key1found++;
    ASSERT_EQ(key1found, 2);
}

TEST(nmapTest, searchMultipleKey) {
    nmap m;
    m.add("1", new myNode(1));
    m.add("2", new myNode(2));
    m.add("1", new myNode(3));
    m.add("3", new myNode(4));

    wint val = m.get("1").cast<myNode>().number;
    ASSERT_TRUE(val == 1 || val == 3);

    auto founds = m.getAll("1");
    ASSERT_EQ(founds.len(), 2);
    auto e = founds.begin();
    wint val1 = e++.get<myNode>().number,
         val2 = e.get<myNode>().number;
    ASSERT_TRUE(val1 == 1 || val1 == 3);
    ASSERT_TRUE(val2 == 1 || val2 == 3);
    ASSERT_NE(val1, val2);
}

TEST(nmapTest, testDeletionByKey) {
    nmap m;
    m.add("1", new myNode(1));
    m.add("2", new myNode(2));
    m.add("1", new myNode(3));

    ASSERT_EQ(m.del("1"), 2);
    ASSERT_EQ(m.len(), 1);

    auto e = m.begin();
    ASSERT_EQ(e.getKey(), std::string("2"));
    ASSERT_EQ(e.getVal<myNode>().number, 2);
}

TEST(nmapTest, testDeletionByIter) {
    nmap m;
    m.add("1", new myNode(1));
    m.add("2", new myNode(2));
    m.add("1", new myNode(3));

    auto e = m.begin();
    while(e.getKey() == "1")
        ++e;
    ASSERT_TRUE(m.del(e));
    ASSERT_EQ(m.len(), 2);

    e = m.begin();
    ASSERT_EQ(e.getKey(), "1");
    wint val1 = e++.getVal<myNode>().number,
         val2 = e.getVal<myNode>().number;
    ASSERT_EQ(e.getKey(), "1");

    ASSERT_TRUE(val1 == 1 || val1 == 3);
    ASSERT_TRUE(val2 == 1 || val2 == 3);
    ASSERT_NE(val1, val2);
}
<|endoftext|>


<commit_before>/* Copyright (c) 2010-present Advanced Micro Devices, Inc.

 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. */

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3144
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>SWDEV-2 - Change OpenCL version number from  3144 to 3145<commit_after>/* Copyright (c) 2010-present Advanced Micro Devices, Inc.

 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. */

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3145
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: grdocsh.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: rt $ $Date: 2008-03-12 11:38:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#ifndef _SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#ifndef _SFXAPP_HXX
#include <sfx2/app.hxx>
#endif
#ifndef _SFX_SRCHITEM_HXX
#include <sfx2/srchitem.hxx>
#endif

#ifndef _GLOBNAME_HXX //autogen
#include <tools/globname.hxx>
#endif

#ifndef _SO_CLSIDS_HXX //autogen
#include <sot/clsids.hxx>
#endif

#include <sfx2/objface.hxx>

#include "app.hrc"
#include "strings.hrc"
#include "glob.hrc"

#ifndef SD_GRAPHIC_DOC_SHELL_HXX
#include "GraphicDocShell.hxx"
#endif
#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif
#include "drawdoc.hxx"
#include "sdresid.hxx"

using namespace sd;
#define GraphicDocShell
#include "sdgslots.hxx"

namespace sd
{
TYPEINIT1(GraphicDocShell, DrawDocShell);

SFX_IMPL_INTERFACE(GraphicDocShell, SfxObjectShell, SdResId(0))
{
    SFX_CHILDWINDOW_REGISTRATION(SID_SEARCH_DLG);
    SFX_CHILDWINDOW_REGISTRATION( SID_HYPERLINK_INSERT );
}

SFX_IMPL_OBJECTFACTORY( GraphicDocShell, SvGlobalName(SO3_SDRAW_CLASSID_60), SFXOBJECTSHELL_STD_NORMAL, "sdraw" )

GraphicDocShell::GraphicDocShell(SfxObjectCreateMode eMode,
                                     BOOL bDataObject,
                                     DocumentType eDocType,BOOL bScriptSupport) :
    DrawDocShell(eMode, bDataObject, eDocType, bScriptSupport)
{
    SetStyleFamily( SD_STYLE_FAMILY_GRAPHICS );
}

GraphicDocShell::~GraphicDocShell()
{
}

} // end of namespace sd
<commit_msg>INTEGRATION: CWS changefileheader (1.14.16); FILE MERGED 2008/04/01 15:34:25 thb 1.14.16.3: #i85898# Stripping all external header guards 2008/04/01 12:38:44 thb 1.14.16.2: #i85898# Stripping all external header guards 2008/03/31 13:57:59 rt 1.14.16.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: grdocsh.cxx,v $
 * $Revision: 1.15 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#ifndef _SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#include <sfx2/app.hxx>
#include <sfx2/srchitem.hxx>
#include <tools/globname.hxx>

#ifndef _SO_CLSIDS_HXX //autogen
#include <sot/clsids.hxx>
#endif

#include <sfx2/objface.hxx>

#include "app.hrc"
#include "strings.hrc"
#include "glob.hrc"
#include "GraphicDocShell.hxx"
#include "DrawDocShell.hxx"
#include "drawdoc.hxx"
#include "sdresid.hxx"

using namespace sd;
#define GraphicDocShell
#include "sdgslots.hxx"

namespace sd
{
TYPEINIT1(GraphicDocShell, DrawDocShell);

SFX_IMPL_INTERFACE(GraphicDocShell, SfxObjectShell, SdResId(0))
{
    SFX_CHILDWINDOW_REGISTRATION(SID_SEARCH_DLG);
    SFX_CHILDWINDOW_REGISTRATION( SID_HYPERLINK_INSERT );
}

SFX_IMPL_OBJECTFACTORY( GraphicDocShell, SvGlobalName(SO3_SDRAW_CLASSID_60), SFXOBJECTSHELL_STD_NORMAL, "sdraw" )

GraphicDocShell::GraphicDocShell(SfxObjectCreateMode eMode,
                                     BOOL bDataObject,
                                     DocumentType eDocType,BOOL bScriptSupport) :
    DrawDocShell(eMode, bDataObject, eDocType, bScriptSupport)
{
    SetStyleFamily( SD_STYLE_FAMILY_GRAPHICS );
}

GraphicDocShell::~GraphicDocShell()
{
}

} // end of namespace sd
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include <sys/stat.h>
#include <iostream>
#include <string>
using namespace std;

#include "config.h"

#include "client/SyntheticClient.h"
#include "client/Client.h"

#include "msg/SimpleMessenger.h"

#include "mon/MonClient.h"

#include "common/Timer.h"
#include "common/common_init.h"

#ifndef DARWIN
#include <envz.h>
#endif // DARWIN

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, const char **argv, char *envp[])
{
  //cerr << "csyn starting" << std::endl;
  vector<const char*> args;
  argv_to_vec(argc, argv, args);
  common_init(args, "csyn", false, true);
  parse_syn_options(args);   // for SyntheticClient

  vec_to_argv(args, argc, argv);

  if (g_conf.clock_tare) g_clock.tare();

  // get monmap
  MonClient mc;
  if (mc.build_initial_monmap() < 0)
    return -1;

  // start up network
  SimpleMessenger *messenger = new SimpleMessenger();
  cout << "starting csyn" << std::endl;

  list<Client*> clients;
  list<SyntheticClient*> synclients;

  cout << "mounting and starting " << g_conf.num_client << " syn client(s)" << std::endl;
  for (int i=0; i<g_conf.num_client; i++) {
    messenger->register_entity(entity_name_t(entity_name_t::TYPE_CLIENT,-1));
    Client *client = new Client(messenger, &mc);
    SyntheticClient *syn = new SyntheticClient(client);
    clients.push_back(client);
    synclients.push_back(syn);
  }

  messenger->start();

  for (list<SyntheticClient*>::iterator p = synclients.begin();
       p != synclients.end();
       p++)
    (*p)->start_thread();

  cout << "waiting for client(s) to finish" << std::endl;
  while (!clients.empty()) {
    Client *client = clients.front();
    SyntheticClient *syn = synclients.front();
    clients.pop_front();
    synclients.pop_front();
    syn->join_thread();
    delete syn;
    delete client;
  }

  // wait for messenger to finish
  messenger->wait();

  return 0;
}

<commit_msg>csyn: properly use multiple clients<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include <sys/stat.h>
#include <iostream>
#include <string>
using namespace std;

#include "config.h"

#include "client/SyntheticClient.h"
#include "client/Client.h"

#include "msg/SimpleMessenger.h"

#include "mon/MonClient.h"

#include "common/Timer.h"
#include "common/common_init.h"

#ifndef DARWIN
#include <envz.h>
#endif // DARWIN

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, const char **argv, char *envp[])
{
  //cerr << "csyn starting" << std::endl;
  vector<const char*> args;
  argv_to_vec(argc, argv, args);
  common_init(args, "csyn", false, true);
  parse_syn_options(args);   // for SyntheticClient

  vec_to_argv(args, argc, argv);

  if (g_conf.clock_tare) g_clock.tare();

  // get monmap
  MonClient mc;
  if (mc.build_initial_monmap() < 0)
    return -1;

  cout << "starting csyn" << std::endl;

  list<Client*> clients;
  list<SyntheticClient*> synclients;
  SimpleMessenger* messengers[g_conf.num_client];
  MonClient* mclients[g_conf.num_client];

  cout << "mounting and starting " << g_conf.num_client << " syn client(s)" << std::endl;
  for (int i=0; i<g_conf.num_client; i++) {
    messengers[i] = new SimpleMessenger();
    messengers[i]->register_entity(entity_name_t(entity_name_t::TYPE_CLIENT,-1));
    messengers[i]->bind();
    mclients[i] = new MonClient();
    mclients[i]->build_initial_monmap();
    Client *client = new Client(messengers[i], mclients[i]);
    SyntheticClient *syn = new SyntheticClient(client);
    clients.push_back(client);
    synclients.push_back(syn);
    messengers[i]->start();
  }

  for (list<SyntheticClient*>::iterator p = synclients.begin();
       p != synclients.end();
       p++)
    (*p)->start_thread();

  cout << "waiting for client(s) to finish" << std::endl;
  while (!clients.empty()) {
    Client *client = clients.front();
    SyntheticClient *syn = synclients.front();
    clients.pop_front();
    synclients.pop_front();
    syn->join_thread();
    delete syn;
    delete client;
  }

  for (int i = 0; i < g_conf.num_client; ++i) {
    // wait for messenger to finish
    delete mclients[i];
    messengers[i]->wait();
    messengers[i]->destroy();
  }
  return 0;
}

<|endoftext|>


<commit_before>
// This file is part of node-lmdb, the Node.js binding for lmdb
// Copyright (c) 2013 Timur Kristóf
// Licensed to you under the terms of 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 "node-lmdb.h"

using namespace v8;
using namespace node;

Nan::Persistent<Function> EnvWrap::txnCtor;

Nan::Persistent<Function> EnvWrap::dbiCtor;

typedef struct EnvSyncData {
    uv_work_t request;
    Nan::Callback *callback;
    EnvWrap *ew;
    MDB_env *env;
    int rc;
} EnvSyncData;

EnvWrap::EnvWrap() {
    this->env = nullptr;
}

EnvWrap::~EnvWrap() {
    // Close if not closed already
    if (this->env) {
        mdb_env_close(env);
    }
}

NAN_METHOD(EnvWrap::ctor) {
    Nan::HandleScope scope;

    int rc;

    EnvWrap* ew = new EnvWrap();
    rc = mdb_env_create(&(ew->env));

    if (rc != 0) {
        mdb_env_close(ew->env);
        return Nan::ThrowError(mdb_strerror(rc));
    }

    ew->Wrap(info.This());
    ew->Ref();

    NanReturnThis();
}

template<class T>
int applyUint32Setting(int (*f)(MDB_env *, T), MDB_env* e, Local<Object> options, T dflt, const char* keyName) {
    int rc;
    const Local<Value> value = options->Get(Nan::New<String>(keyName).ToLocalChecked());
    if (value->IsUint32()) {
        rc = f(e, value->Uint32Value());
    }
    else {
        rc = f(e, dflt);
    }

    return rc;

}

NAN_METHOD(EnvWrap::open) {
    Nan::HandleScope scope;

    int rc;
    int flags = 0;

    // Get the wrapper
    EnvWrap *ew = Nan::ObjectWrap::Unwrap<EnvWrap>(info.This());

    if (!ew->env) {
        return Nan::ThrowError("The environment is already closed.");
    }

    Local<Object> options = info[0]->ToObject();
    Local<String> path = options->Get(Nan::New<String>("path").ToLocalChecked())->ToString();

    // Parse the maxDbs option
    rc = applyUint32Setting<unsigned>(&mdb_env_set_maxdbs, ew->env, options, 1, "maxDbs");
    if (rc != 0) {
        return Nan::ThrowError(mdb_strerror(rc));
    }

    // Parse the mapSize option
    Local<Value> mapSizeOption = options->Get(Nan::New<String>("mapSize").ToLocalChecked());
    if (mapSizeOption->IsNumber()) {
        double mapSizeDouble = mapSizeOption->NumberValue();
        size_t mapSizeSizeT = (size_t) mapSizeDouble;
        rc = mdb_env_set_mapsize(ew->env, mapSizeSizeT);
        if (rc != 0) {
            return Nan::ThrowError(mdb_strerror(rc));
        }
    }

    // Parse the maxDbs option
    // NOTE: mdb.c defines DEFAULT_READERS as 126
    rc = applyUint32Setting<unsigned>(&mdb_env_set_maxreaders, ew->env, options, 126, "maxReaders");
    if (rc != 0) {
        return Nan::ThrowError(mdb_strerror(rc));
    }

    // NOTE: MDB_FIXEDMAP is not exposed here since it is "highly experimental" + it is irrelevant for this use case
    // NOTE: MDB_NOTLS is not exposed here because it is irrelevant for this use case, as node will run all this on a single thread anyway
    setFlagFromValue(&flags, MDB_NOSUBDIR, "noSubdir", false, options);
    setFlagFromValue(&flags, MDB_RDONLY, "readOnly", false, options);
    setFlagFromValue(&flags, MDB_WRITEMAP, "useWritemap", false, options);
    setFlagFromValue(&flags, MDB_NOMETASYNC, "noMetaSync", false, options);
    setFlagFromValue(&flags, MDB_NOSYNC, "noSync", false, options);
    setFlagFromValue(&flags, MDB_MAPASYNC, "mapAsync", false, options);

    // Set MDB_NOTLS to enable multiple read-only transactions on the same thread (in this case, the nodejs main thread)
    flags |= MDB_NOTLS;

    // TODO: make file attributes configurable
    rc = mdb_env_open(ew->env, *String::Utf8Value(path), flags, 0664);

    if (rc != 0) {
        mdb_env_close(ew->env);
        ew->env = nullptr;
        return Nan::ThrowError(mdb_strerror(rc));
    }

    return;
}

NAN_METHOD(EnvWrap::close) {
    EnvWrap *ew = Nan::ObjectWrap::Unwrap<EnvWrap>(info.This());
    ew->Unref();

    if (!ew->env) {
        return Nan::ThrowError("The environment is already closed.");
    }

    mdb_env_close(ew->env);
    ew->env = nullptr;

    return;
}

NAN_METHOD(EnvWrap::beginTxn) {
    Nan::HandleScope scope;

    const int argc = 2;

    Local<Value> argv[argc] = { info.This(), info[0] };
    Local<Object> instance = Nan::NewInstance(Nan::New(txnCtor), argc, argv).ToLocalChecked();

    info.GetReturnValue().Set(instance);
}

NAN_METHOD(EnvWrap::openDbi) {
    Nan::HandleScope scope;

    const unsigned argc = 2;
    Local<Value> argv[argc] = { info.This(), info[0] };
    Local<Object> instance = Nan::NewInstance(Nan::New(dbiCtor), argc, argv).ToLocalChecked();

    info.GetReturnValue().Set(instance);
}

NAN_METHOD(EnvWrap::sync) {
    Nan::HandleScope scope;

    EnvWrap *ew = Nan::ObjectWrap::Unwrap<EnvWrap>(info.This());

    if (!ew->env) {
        return Nan::ThrowError("The environment is already closed.");
    }

    Local<Function> callback = info[0].As<Function>();

    EnvSyncData *d = new EnvSyncData;
    d->request.data = d;
    d->ew = ew;
    d->env = ew->env;
    d->callback = new Nan::Callback(callback);

    uv_queue_work(uv_default_loop(), &(d->request), [](uv_work_t *request) -> void {
        // Performing the sync (this will be called on a separate thread)
        EnvSyncData *d = static_cast<EnvSyncData*>(request->data);
        d->rc = mdb_env_sync(d->env, 1);
    }, [](uv_work_t *request, int) -> void {
        Nan::HandleScope scope;

        // Executed after the sync is finished
        EnvSyncData *d = static_cast<EnvSyncData*>(request->data);
        const unsigned argc = 1;
        Local<Value> argv[argc];

        if (d->rc == 0) {
            argv[0] = Nan::Null();
        }
        else {
            argv[0] = Nan::Error(mdb_strerror(d->rc));
        }

        d->callback->Call(argc, argv);
        delete d->callback;
        delete d;
    });

    return;
}

void EnvWrap::setupExports(Handle<Object> exports) {
    // EnvWrap: Prepare constructor template
    Local<FunctionTemplate> envTpl = Nan::New<FunctionTemplate>(EnvWrap::ctor);
    envTpl->SetClassName(Nan::New<String>("Env").ToLocalChecked());
    envTpl->InstanceTemplate()->SetInternalFieldCount(1);
    // EnvWrap: Add functions to the prototype
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("open").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::open));
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("close").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::close));
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("beginTxn").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::beginTxn));
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("openDbi").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::openDbi));
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("sync").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::sync));
    // TODO: wrap mdb_env_copy too
    // TODO: wrap mdb_env_stat too
    // TODO: wrap mdb_env_info too

    // TxnWrap: Prepare constructor template
    Local<FunctionTemplate> txnTpl = Nan::New<FunctionTemplate>(TxnWrap::ctor);
    txnTpl->SetClassName(Nan::New<String>("Txn").ToLocalChecked());
    txnTpl->InstanceTemplate()->SetInternalFieldCount(1);
    // TxnWrap: Add functions to the prototype
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("commit").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::commit));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("abort").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::abort));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getString").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getString));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getStringUnsafe").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getStringUnsafe));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getBinary").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getBinary));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getBinaryUnsafe").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getBinaryUnsafe));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getNumber").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getNumber));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getBoolean").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getBoolean));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("putString").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::putString));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("putBinary").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::putBinary));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("putNumber").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::putNumber));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("putBoolean").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::putBoolean));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("del").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::del));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("reset").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::reset));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("renew").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::renew));
    // TODO: wrap mdb_cmp too
    // TODO: wrap mdb_dcmp too
    // TxnWrap: Get constructor
    EnvWrap::txnCtor.Reset( txnTpl->GetFunction());

    // DbiWrap: Prepare constructor template
    Local<FunctionTemplate> dbiTpl = Nan::New<FunctionTemplate>(DbiWrap::ctor);
    dbiTpl->SetClassName(Nan::New<String>("Dbi").ToLocalChecked());
    dbiTpl->InstanceTemplate()->SetInternalFieldCount(1);
    // DbiWrap: Add functions to the prototype
    dbiTpl->PrototypeTemplate()->Set(Nan::New<String>("close").ToLocalChecked(), Nan::New<FunctionTemplate>(DbiWrap::close));
    dbiTpl->PrototypeTemplate()->Set(Nan::New<String>("drop").ToLocalChecked(), Nan::New<FunctionTemplate>(DbiWrap::drop));
    dbiTpl->PrototypeTemplate()->Set(Nan::New<String>("stat").ToLocalChecked(), Nan::New<FunctionTemplate>(DbiWrap::stat));
    // TODO: wrap mdb_stat too
    // DbiWrap: Get constructor
    EnvWrap::dbiCtor.Reset( dbiTpl->GetFunction());

    // Set exports
    exports->Set(Nan::New<String>("Env").ToLocalChecked(), envTpl->GetFunction());
}
<commit_msg>default maxdb = 10<commit_after>
// This file is part of node-lmdb, the Node.js binding for lmdb
// Copyright (c) 2013 Timur Kristóf
// Licensed to you under the terms of 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 "node-lmdb.h"

using namespace v8;
using namespace node;

Nan::Persistent<Function> EnvWrap::txnCtor;

Nan::Persistent<Function> EnvWrap::dbiCtor;

typedef struct EnvSyncData {
    uv_work_t request;
    Nan::Callback *callback;
    EnvWrap *ew;
    MDB_env *env;
    int rc;
} EnvSyncData;

EnvWrap::EnvWrap() {
    this->env = nullptr;
}

EnvWrap::~EnvWrap() {
    // Close if not closed already
    if (this->env) {
        mdb_env_close(env);
    }
}

NAN_METHOD(EnvWrap::ctor) {
    Nan::HandleScope scope;

    int rc;

    EnvWrap* ew = new EnvWrap();
    rc = mdb_env_create(&(ew->env));

    if (rc != 0) {
        mdb_env_close(ew->env);
        return Nan::ThrowError(mdb_strerror(rc));
    }

    ew->Wrap(info.This());
    ew->Ref();

    NanReturnThis();
}

template<class T>
int applyUint32Setting(int (*f)(MDB_env *, T), MDB_env* e, Local<Object> options, T dflt, const char* keyName) {
    int rc;
    const Local<Value> value = options->Get(Nan::New<String>(keyName).ToLocalChecked());
    if (value->IsUint32()) {
        rc = f(e, value->Uint32Value());
    }
    else {
        rc = f(e, dflt);
    }

    return rc;

}

NAN_METHOD(EnvWrap::open) {
    Nan::HandleScope scope;

    int rc;
    int flags = 0;

    // Get the wrapper
    EnvWrap *ew = Nan::ObjectWrap::Unwrap<EnvWrap>(info.This());

    if (!ew->env) {
        return Nan::ThrowError("The environment is already closed.");
    }

    Local<Object> options = info[0]->ToObject();
    Local<String> path = options->Get(Nan::New<String>("path").ToLocalChecked())->ToString();

    // Parse the maxDbs option
    rc = applyUint32Setting<unsigned>(&mdb_env_set_maxdbs, ew->env, options, 10, "maxDbs");
    if (rc != 0) {
        return Nan::ThrowError(mdb_strerror(rc));
    }

    // Parse the mapSize option
    Local<Value> mapSizeOption = options->Get(Nan::New<String>("mapSize").ToLocalChecked());
    if (mapSizeOption->IsNumber()) {
        double mapSizeDouble = mapSizeOption->NumberValue();
        size_t mapSizeSizeT = (size_t) mapSizeDouble;
        rc = mdb_env_set_mapsize(ew->env, mapSizeSizeT);
        if (rc != 0) {
            return Nan::ThrowError(mdb_strerror(rc));
        }
    }

    // Parse the maxDbs option
    // NOTE: mdb.c defines DEFAULT_READERS as 126
    rc = applyUint32Setting<unsigned>(&mdb_env_set_maxreaders, ew->env, options, 126, "maxReaders");
    if (rc != 0) {
        return Nan::ThrowError(mdb_strerror(rc));
    }

    // NOTE: MDB_FIXEDMAP is not exposed here since it is "highly experimental" + it is irrelevant for this use case
    // NOTE: MDB_NOTLS is not exposed here because it is irrelevant for this use case, as node will run all this on a single thread anyway
    setFlagFromValue(&flags, MDB_NOSUBDIR, "noSubdir", false, options);
    setFlagFromValue(&flags, MDB_RDONLY, "readOnly", false, options);
    setFlagFromValue(&flags, MDB_WRITEMAP, "useWritemap", false, options);
    setFlagFromValue(&flags, MDB_NOMETASYNC, "noMetaSync", false, options);
    setFlagFromValue(&flags, MDB_NOSYNC, "noSync", false, options);
    setFlagFromValue(&flags, MDB_MAPASYNC, "mapAsync", false, options);

    // Set MDB_NOTLS to enable multiple read-only transactions on the same thread (in this case, the nodejs main thread)
    flags |= MDB_NOTLS;

    // TODO: make file attributes configurable
    rc = mdb_env_open(ew->env, *String::Utf8Value(path), flags, 0664);

    if (rc != 0) {
        mdb_env_close(ew->env);
        ew->env = nullptr;
        return Nan::ThrowError(mdb_strerror(rc));
    }

    return;
}

NAN_METHOD(EnvWrap::close) {
    EnvWrap *ew = Nan::ObjectWrap::Unwrap<EnvWrap>(info.This());
    ew->Unref();

    if (!ew->env) {
        return Nan::ThrowError("The environment is already closed.");
    }

    mdb_env_close(ew->env);
    ew->env = nullptr;

    return;
}

NAN_METHOD(EnvWrap::beginTxn) {
    Nan::HandleScope scope;

    const int argc = 2;

    Local<Value> argv[argc] = { info.This(), info[0] };
    Local<Object> instance = Nan::NewInstance(Nan::New(txnCtor), argc, argv).ToLocalChecked();

    info.GetReturnValue().Set(instance);
}

NAN_METHOD(EnvWrap::openDbi) {
    Nan::HandleScope scope;

    const unsigned argc = 2;
    Local<Value> argv[argc] = { info.This(), info[0] };
    Local<Object> instance = Nan::NewInstance(Nan::New(dbiCtor), argc, argv).ToLocalChecked();

    info.GetReturnValue().Set(instance);
}

NAN_METHOD(EnvWrap::sync) {
    Nan::HandleScope scope;

    EnvWrap *ew = Nan::ObjectWrap::Unwrap<EnvWrap>(info.This());

    if (!ew->env) {
        return Nan::ThrowError("The environment is already closed.");
    }

    Local<Function> callback = info[0].As<Function>();

    EnvSyncData *d = new EnvSyncData;
    d->request.data = d;
    d->ew = ew;
    d->env = ew->env;
    d->callback = new Nan::Callback(callback);

    uv_queue_work(uv_default_loop(), &(d->request), [](uv_work_t *request) -> void {
        // Performing the sync (this will be called on a separate thread)
        EnvSyncData *d = static_cast<EnvSyncData*>(request->data);
        d->rc = mdb_env_sync(d->env, 1);
    }, [](uv_work_t *request, int) -> void {
        Nan::HandleScope scope;

        // Executed after the sync is finished
        EnvSyncData *d = static_cast<EnvSyncData*>(request->data);
        const unsigned argc = 1;
        Local<Value> argv[argc];

        if (d->rc == 0) {
            argv[0] = Nan::Null();
        }
        else {
            argv[0] = Nan::Error(mdb_strerror(d->rc));
        }

        d->callback->Call(argc, argv);
        delete d->callback;
        delete d;
    });

    return;
}

void EnvWrap::setupExports(Handle<Object> exports) {
    // EnvWrap: Prepare constructor template
    Local<FunctionTemplate> envTpl = Nan::New<FunctionTemplate>(EnvWrap::ctor);
    envTpl->SetClassName(Nan::New<String>("Env").ToLocalChecked());
    envTpl->InstanceTemplate()->SetInternalFieldCount(1);
    // EnvWrap: Add functions to the prototype
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("open").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::open));
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("close").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::close));
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("beginTxn").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::beginTxn));
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("openDbi").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::openDbi));
    envTpl->PrototypeTemplate()->Set(Nan::New<String>("sync").ToLocalChecked(), Nan::New<FunctionTemplate>(EnvWrap::sync));
    // TODO: wrap mdb_env_copy too
    // TODO: wrap mdb_env_stat too
    // TODO: wrap mdb_env_info too

    // TxnWrap: Prepare constructor template
    Local<FunctionTemplate> txnTpl = Nan::New<FunctionTemplate>(TxnWrap::ctor);
    txnTpl->SetClassName(Nan::New<String>("Txn").ToLocalChecked());
    txnTpl->InstanceTemplate()->SetInternalFieldCount(1);
    // TxnWrap: Add functions to the prototype
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("commit").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::commit));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("abort").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::abort));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getString").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getString));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getStringUnsafe").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getStringUnsafe));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getBinary").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getBinary));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getBinaryUnsafe").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getBinaryUnsafe));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getNumber").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getNumber));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("getBoolean").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::getBoolean));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("putString").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::putString));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("putBinary").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::putBinary));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("putNumber").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::putNumber));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("putBoolean").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::putBoolean));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("del").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::del));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("reset").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::reset));
    txnTpl->PrototypeTemplate()->Set(Nan::New<String>("renew").ToLocalChecked(), Nan::New<FunctionTemplate>(TxnWrap::renew));
    // TODO: wrap mdb_cmp too
    // TODO: wrap mdb_dcmp too
    // TxnWrap: Get constructor
    EnvWrap::txnCtor.Reset( txnTpl->GetFunction());

    // DbiWrap: Prepare constructor template
    Local<FunctionTemplate> dbiTpl = Nan::New<FunctionTemplate>(DbiWrap::ctor);
    dbiTpl->SetClassName(Nan::New<String>("Dbi").ToLocalChecked());
    dbiTpl->InstanceTemplate()->SetInternalFieldCount(1);
    // DbiWrap: Add functions to the prototype
    dbiTpl->PrototypeTemplate()->Set(Nan::New<String>("close").ToLocalChecked(), Nan::New<FunctionTemplate>(DbiWrap::close));
    dbiTpl->PrototypeTemplate()->Set(Nan::New<String>("drop").ToLocalChecked(), Nan::New<FunctionTemplate>(DbiWrap::drop));
    dbiTpl->PrototypeTemplate()->Set(Nan::New<String>("stat").ToLocalChecked(), Nan::New<FunctionTemplate>(DbiWrap::stat));
    // TODO: wrap mdb_stat too
    // DbiWrap: Get constructor
    EnvWrap::dbiCtor.Reset( dbiTpl->GetFunction());

    // Set exports
    exports->Set(Nan::New<String>("Env").ToLocalChecked(), envTpl->GetFunction());
}
<|endoftext|>