<commit_before>/*
    Copyright (c) 2011, Alexandre Abadie <Alexandre.Abadie@irisa.fr>
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
        * Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
        * Neither the name of the <organization> nor the
        names of its contributors may be used to endorse or promote products
        derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY Alexandre <email> ''AS IS'' AND ANY
    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL Alexandre <email> BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "medHomepageArea.h"

#include <medHomepageButton.h>
#include <medViewerConfiguration.h>
#include <medViewerConfigurationFactory.h>
#include <medSettingsManager.h>

class medHomepageAreaPrivate
{
public:
    QCheckBox * showOnStartupCheckBox;

    QWidget * navigationWidget;
    QPropertyAnimation * navigationAnimation;

    QWidget * userWidget;
    QPropertyAnimation * userAnimation;

    QWidget * infoWidget;
    QPropertyAnimation * infoAnimation;

    QWidget * aboutWidget;
    QTabWidget * aboutTabWidget;

    QParallelAnimationGroup * animation;
};

medHomepageArea::medHomepageArea ( QWidget * parent ) : QWidget ( parent ), d ( new medHomepageAreaPrivate )
{
    //Setup navigation widget (with buttons for accessing available workspaces)
    d->navigationWidget = new QWidget ( this );
    d->navigationWidget->setMinimumWidth ( 250 );

    //Setup the widget where the medinria general information are displayed
    d->infoWidget = new QWidget ( this );
    d->infoWidget->setMinimumWidth ( 400 );
    d->infoWidget->setMinimumHeight ( 500 );

    //Setup the widget with about, settings and documentation buttons
    d->userWidget = new QWidget ( this );
    d->userWidget->setMinimumWidth ( 250 );
    d->userWidget->setMinimumHeight ( 40 );

    //Setup the about container widget (with a QTabWidget inside)
    d->aboutWidget = new QWidget ( this );
    d->aboutWidget->setMinimumWidth ( 400 );
    d->aboutWidget->setMaximumHeight ( 500 );
    d->aboutWidget->setMinimumHeight ( 500 );
    d->aboutWidget->hide();

    //User widget content with settings, about and help buttons
    QHBoxLayout * userButtonsLayout = new QHBoxLayout;
    medHomepageButton * helpButton = new medHomepageButton ( this );
    helpButton->setText ( "Help" );
    helpButton->setMinimumHeight ( 30 );
    helpButton->setMaximumWidth ( 150 );
    helpButton->setMinimumWidth ( 150 );
    helpButton->setFocusPolicy ( Qt::NoFocus );
    helpButton->setIcon ( QIcon ( ":icons/help.svg" ) );
    helpButton->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon );
    QObject::connect ( helpButton,SIGNAL ( clicked() ),this, SLOT ( onShowHelp() ) );

    medHomepageButton * aboutButton = new medHomepageButton ( this );
    aboutButton->setText ( "About" );
    aboutButton->setMinimumHeight ( 30 );
    aboutButton->setMaximumWidth ( 150 );
    aboutButton->setMinimumWidth ( 150 );
    aboutButton->setFocusPolicy ( Qt::NoFocus );
    aboutButton->setIcon ( QIcon ( ":icons/about.png" ) );
    aboutButton->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon );
    QObject::connect ( aboutButton,SIGNAL ( clicked() ),this, SLOT ( onShowAbout() ) );

    medHomepageButton * settingsButton = new medHomepageButton ( this );
    settingsButton->setText ( "Settings" );
    settingsButton->setMinimumHeight ( 30 );
    settingsButton->setMaximumWidth ( 150 );
    settingsButton->setMinimumWidth ( 150 );
    settingsButton->setFocusPolicy ( Qt::NoFocus );
    settingsButton->setIcon ( QIcon ( ":icons/settings.svg" ) );
    settingsButton->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon );
    QObject::connect ( settingsButton,SIGNAL ( clicked() ),this, SLOT ( onShowSettings() ) );

    userButtonsLayout->insertWidget ( 0, settingsButton );
    userButtonsLayout->insertWidget ( 1, aboutButton );
    userButtonsLayout->insertWidget ( 2, helpButton );

    d->userWidget->setLayout ( userButtonsLayout );

    // Info widget : medinria logo, medinria description, etc. QtWebkit ?
    QVBoxLayout * infoLayout = new QVBoxLayout;
    QLabel * medinriaLabel = new QLabel ( this );
    medinriaLabel->setPixmap ( QPixmap ( ":pixmaps/medinria-logo-homepage.png" ) );
    QLabel * textLabel = new QLabel;

    QTextEdit * textEdit = new QTextEdit;
    textEdit->setHtml ( "medINRIA is a multi-platform medical image processing and visualization software,\
                      and it's free. Through an intuitive user interface, medINRIA offers from standard \
                      to cutting-edge processing functionalities for your medical images such as 2D/3D/4D image visualization, \
                      image registration, or diffusion MR processing and tractography." );
    textEdit->setReadOnly ( true );
    textEdit->setFocusPolicy ( Qt::NoFocus );
    textEdit->setMaximumHeight ( 200 );
    infoLayout->insertWidget ( 0,medinriaLabel );
    infoLayout->insertWidget ( 1, textEdit );
    infoLayout->addStretch();

    d->infoWidget->setLayout ( infoLayout );
    d->infoWidget->setMaximumHeight ( medinriaLabel->height() + textEdit->height() );

    //About widget
    QVBoxLayout * aboutLayout = new QVBoxLayout;
    d->aboutTabWidget = new QTabWidget();

    QLabel * medinriaLabel2 = new QLabel ( this );
    medinriaLabel2->setPixmap ( QPixmap ( ":pixmaps/medinria-logo-homepage.png" ) );

    QTextEdit * aboutTextEdit = new QTextEdit;
    aboutTextEdit->setHtml ( "

\
                              medINRIA is the medical imaging platform developped at INRIA

\
                              INRIA, Copyright 2011

" );
    aboutTextEdit->setFocusPolicy ( Qt::NoFocus );

    QTextBrowser * aboutAuthorTextBrowser = new QTextBrowser;
    aboutAuthorTextBrowser->setSource(QUrl("qrc:authors.html" ));
    aboutAuthorTextBrowser->setFocusPolicy ( Qt::NoFocus );

    QTextEdit * aboutLicenseTextEdit = new QTextEdit;
    QFile license ( ":LICENSE.txt" );
    license.open ( QIODevice::ReadOnly | QIODevice::Text );
    QString licenseContent = license.readAll();
    license.close();
    aboutLicenseTextEdit->setText ( licenseContent );
    aboutLicenseTextEdit->setFocusPolicy ( Qt::NoFocus );

    QHBoxLayout * aboutButtonLayout = new QHBoxLayout;
    QPushButton * hideAboutButton = new QPushButton ( this );
    hideAboutButton->setText ( "Hide" );
    hideAboutButton->setFocusPolicy ( Qt::NoFocus );
    QObject::connect ( hideAboutButton, SIGNAL ( clicked() ), this, SLOT ( onHideAbout() ) );

    aboutButtonLayout->addStretch();
    aboutButtonLayout->addWidget ( hideAboutButton );
    aboutButtonLayout->addStretch();

    d->aboutTabWidget->addTab ( aboutTextEdit, "About" );
    d->aboutTabWidget->addTab ( aboutAuthorTextBrowser, "Authors" );
    d->aboutTabWidget->addTab ( aboutLicenseTextEdit, "License" );

    aboutLayout->addWidget ( medinriaLabel2 );
    aboutLayout->addWidget ( d->aboutTabWidget );
    aboutLayout->addLayout ( aboutButtonLayout );
    aboutLayout->addStretch();
    d->aboutWidget->setLayout ( aboutLayout );

    //Set the position of the widgets
    d->navigationWidget->setProperty ( "pos", QPoint ( 100 ,  this->height() / 4 ) );
    d->userWidget->setProperty ( "pos", QPoint ( this->width() - 350 ,  this->height() - 90 ) );
    d->infoWidget->setProperty ( "pos", QPoint ( this->width() / 2 ,  this->height() / 5 ) );
    d->aboutWidget->setProperty ( "pos", QPoint ( this->width() / 2 ,  this->height() / 5 ) );

    //Setup homepage animations
    d->animation = new QParallelAnimationGroup ( this );
    d->navigationAnimation = new QPropertyAnimation ( d->navigationWidget, "pos" );
    d->navigationAnimation->setDuration ( 750 );
    d->navigationAnimation->setEasingCurve ( QEasingCurve::OutCubic );
    d->navigationAnimation->setStartValue ( QPoint ( - 300,  this->height() / 4 ) );
    d->navigationAnimation->setEndValue ( QPoint ( 100 ,  this->height() / 4 ) );

    d->userAnimation = new QPropertyAnimation ( d->userWidget, "pos" );
    d->userAnimation->setDuration ( 750 );
    d->userAnimation->setEasingCurve ( QEasingCurve::OutCubic );
    d->userAnimation->setStartValue ( QPoint ( this->width() + 250,  this->height() - 90 ) );
    d->userAnimation->setEndValue ( QPoint ( this->width() * 0.8 ,  this->height() - 90 ) );

    d->infoAnimation = new QPropertyAnimation ( d->infoWidget, "pos" );
    d->infoAnimation->setDuration ( 900 );
    d->infoAnimation->setEasingCurve ( QEasingCurve::OutCubic );
    d->infoAnimation->setStartValue ( QPoint ( this->width() + 100 , this->height() / 5 ) );
    d->infoAnimation->setEndValue ( QPoint ( this->width() / 2 ,  this->height() / 5 ) );

    d->animation->addAnimation ( d->navigationAnimation );
    d->animation->addAnimation ( d->userAnimation );
    d->animation->addAnimation ( d->infoAnimation );

    //Setup the startup checkbox
    d->showOnStartupCheckBox = new QCheckBox ( this );
    d->showOnStartupCheckBox->setCheckState(Qt::Checked);
    d->showOnStartupCheckBox->setText ( "Start medINRIA on homepage ?" );
    d->showOnStartupCheckBox->setFocusPolicy ( Qt::NoFocus );
    d->showOnStartupCheckBox->setProperty ( "pos", QPoint ( this->width() - 200 ,  this->height() - 30 ) );
    if ( medSettingsManager::instance()->value ( "startup","default_starting_area" ).toInt() )
        d->showOnStartupCheckBox->setCheckState ( Qt::Unchecked );
    QObject::connect ( d->showOnStartupCheckBox, SIGNAL ( stateChanged ( int ) ), this, SLOT ( onStartWithHomepage ( int ) ) );
}

medHomepageArea::~medHomepageArea()
{
    delete d;

    d = NULL;
}

void medHomepageArea::resizeEvent ( QResizeEvent * event )
{
    //Recompute the widgets position when the window is resized
    d->navigationWidget->setProperty ( "pos", QPoint ( 100 ,  this->height() / 4 ) );
    d->userWidget->setProperty ( "pos", QPoint ( this->width() - 350 ,  this->height() - 90 ) );
    d->infoWidget->setProperty ( "pos", QPoint ( this->width() / 2 ,  this->height() / 5 ) );
    d->aboutWidget->setProperty ( "pos", QPoint ( this->width() / 2 ,  this->height() / 5 ) );
    d->showOnStartupCheckBox->setProperty ( "pos", QPoint ( this->width() - 200 ,  this->height() - 30 ) );

    d->aboutTabWidget->setMaximumHeight ( this->height() / 3 );

    //Update the animations as well
    d->navigationAnimation->setStartValue ( QPoint ( - 300,  this->height() / 4 ) );
    d->navigationAnimation->setEndValue ( QPoint ( 100 ,  this->height() / 4 ) );

    d->userAnimation->setStartValue ( QPoint ( this->width() + 50,  this->height() - 90 ) );
    d->userAnimation->setEndValue ( QPoint ( this->width() - 350 ,  this->height() - 90 ) );

    d->infoAnimation->setStartValue ( QPoint ( this->width() , this->height() / 5 ) );
    d->infoAnimation->setEndValue ( QPoint ( this->width() / 2 ,  this->height() / 5 ) );
}

void medHomepageArea::initPage ( void )
{
    //Initialization of the navigation widget with available workspaces
    QList<QString> configList = medViewerConfigurationFactory::instance()->configurations();
    QVBoxLayout * configurationButtonsLayout = new QVBoxLayout;
    configurationButtonsLayout->setSpacing ( 10 );
    QLabel * configurationLabel = new QLabel ( "Available workspaces" );
    configurationLabel->setTextFormat(Qt::RichText);
    configurationLabel->setAlignment(Qt::AlignHCenter);
    configurationButtonsLayout->addWidget ( configurationLabel );

    medHomepageButton * browserButton = new medHomepageButton ( this );
    browserButton->setToolButtonStyle ( Qt::ToolButtonTextUnderIcon );
    browserButton->setIcon ( QIcon ( ":/icons/folder.png" ) );
    browserButton->setText ( "Browser" );
    browserButton->setMinimumHeight ( 40 );
    browserButton->setMaximumWidth ( 250 );
    browserButton->setMinimumWidth ( 250 );
    browserButton->setFocusPolicy ( Qt::NoFocus );
    configurationButtonsLayout->addWidget ( browserButton );
    QObject::connect ( browserButton, SIGNAL ( clicked() ),this, SLOT ( onShowBrowser() ) );

    for ( int i = 0; i< configList.size(); i++ )
    {
        medHomepageButton * button = new medHomepageButton ( this );
        button->setText ( configList.at ( i ) );
        button->setFocusPolicy ( Qt::NoFocus );
        button->setToolButtonStyle ( Qt::ToolButtonTextUnderIcon );
        button->setMinimumHeight ( 40 );
        button->setMaximumWidth ( 250 );
        button->setMinimumWidth ( 250 );;
        configurationButtonsLayout->addWidget ( button );
        QObject::connect ( button, SIGNAL ( clicked ( QString ) ),this, SLOT ( onShowConfiguration ( QString ) ) );
    }
    configurationButtonsLayout->addStretch();
    d->navigationWidget->setLayout ( configurationButtonsLayout );
    d->navigationWidget->setProperty ( "pos", QPoint ( 100,  100 ) );
    d->navigationWidget->setMinimumHeight ( 55 * ( 1 + configList.size() ) );
}

QParallelAnimationGroup* medHomepageArea::getAnimation ( void )
{
    return d->animation;
}

void medHomepageArea::onShowBrowser ( void )
{
    emit showBrowser();
}

void medHomepageArea::onShowConfiguration ( QString configuration )
{
    emit showViewer();
    emit showConfiguration ( configuration );
}

void medHomepageArea::onShowAbout ( void )
{
    d->infoWidget->hide();
    d->aboutWidget->show();
}

void medHomepageArea::onHideAbout()
{
    d->aboutWidget->hide();
    d->infoWidget->show();
}

void medHomepageArea::onShowHelp ( void )
{
    QMessageBox * msgBox = new QMessageBox ( QApplication::activeWindow() );
    msgBox->setIcon ( QMessageBox::Information );
    msgBox->setText ( "Help ! Help !" );
    msgBox->exec();
    delete msgBox;
}

void medHomepageArea::onShowSettings ( void )
{
    emit showSettings();
}

void medHomepageArea::onStartWithHomepage ( int state )
{
    if ( state == Qt::Checked )
    {
        medSettingsManager::instance()->setValue ( "startup","default_starting_area", 0 );
    }
    else
    {
        medSettingsManager::instance()->setValue ( "startup","default_starting_area", 1 );
    }
}

<commit_msg>Misspelling correction.<commit_after>/*
    Copyright (c) 2011, Alexandre Abadie <Alexandre.Abadie@irisa.fr>
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
        * Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
        * Neither the name of the <organization> nor the
        names of its contributors may be used to endorse or promote products
        derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY Alexandre <email> ''AS IS'' AND ANY
    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL Alexandre <email> BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "medHomepageArea.h"

#include <medHomepageButton.h>
#include <medViewerConfiguration.h>
#include <medViewerConfigurationFactory.h>
#include <medSettingsManager.h>

class medHomepageAreaPrivate
{
public:
    QCheckBox * showOnStartupCheckBox;

    QWidget * navigationWidget;
    QPropertyAnimation * navigationAnimation;

    QWidget * userWidget;
    QPropertyAnimation * userAnimation;

    QWidget * infoWidget;
    QPropertyAnimation * infoAnimation;

    QWidget * aboutWidget;
    QTabWidget * aboutTabWidget;

    QParallelAnimationGroup * animation;
};

medHomepageArea::medHomepageArea ( QWidget * parent ) : QWidget ( parent ), d ( new medHomepageAreaPrivate )
{
    //Setup navigation widget (with buttons for accessing available workspaces)
    d->navigationWidget = new QWidget ( this );
    d->navigationWidget->setMinimumWidth ( 250 );

    //Setup the widget where the medinria general information are displayed
    d->infoWidget = new QWidget ( this );
    d->infoWidget->setMinimumWidth ( 400 );
    d->infoWidget->setMinimumHeight ( 500 );

    //Setup the widget with about, settings and documentation buttons
    d->userWidget = new QWidget ( this );
    d->userWidget->setMinimumWidth ( 250 );
    d->userWidget->setMinimumHeight ( 40 );

    //Setup the about container widget (with a QTabWidget inside)
    d->aboutWidget = new QWidget ( this );
    d->aboutWidget->setMinimumWidth ( 400 );
    d->aboutWidget->setMaximumHeight ( 500 );
    d->aboutWidget->setMinimumHeight ( 500 );
    d->aboutWidget->hide();

    //User widget content with settings, about and help buttons
    QHBoxLayout * userButtonsLayout = new QHBoxLayout;
    medHomepageButton * helpButton = new medHomepageButton ( this );
    helpButton->setText ( "Help" );
    helpButton->setMinimumHeight ( 30 );
    helpButton->setMaximumWidth ( 150 );
    helpButton->setMinimumWidth ( 150 );
    helpButton->setFocusPolicy ( Qt::NoFocus );
    helpButton->setIcon ( QIcon ( ":icons/help.svg" ) );
    helpButton->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon );
    QObject::connect ( helpButton,SIGNAL ( clicked() ),this, SLOT ( onShowHelp() ) );

    medHomepageButton * aboutButton = new medHomepageButton ( this );
    aboutButton->setText ( "About" );
    aboutButton->setMinimumHeight ( 30 );
    aboutButton->setMaximumWidth ( 150 );
    aboutButton->setMinimumWidth ( 150 );
    aboutButton->setFocusPolicy ( Qt::NoFocus );
    aboutButton->setIcon ( QIcon ( ":icons/about.png" ) );
    aboutButton->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon );
    QObject::connect ( aboutButton,SIGNAL ( clicked() ),this, SLOT ( onShowAbout() ) );

    medHomepageButton * settingsButton = new medHomepageButton ( this );
    settingsButton->setText ( "Settings" );
    settingsButton->setMinimumHeight ( 30 );
    settingsButton->setMaximumWidth ( 150 );
    settingsButton->setMinimumWidth ( 150 );
    settingsButton->setFocusPolicy ( Qt::NoFocus );
    settingsButton->setIcon ( QIcon ( ":icons/settings.svg" ) );
    settingsButton->setToolButtonStyle ( Qt::ToolButtonTextBesideIcon );
    QObject::connect ( settingsButton,SIGNAL ( clicked() ),this, SLOT ( onShowSettings() ) );

    userButtonsLayout->insertWidget ( 0, settingsButton );
    userButtonsLayout->insertWidget ( 1, aboutButton );
    userButtonsLayout->insertWidget ( 2, helpButton );

    d->userWidget->setLayout ( userButtonsLayout );

    // Info widget : medinria logo, medinria description, etc. QtWebkit ?
    QVBoxLayout * infoLayout = new QVBoxLayout;
    QLabel * medinriaLabel = new QLabel ( this );
    medinriaLabel->setPixmap ( QPixmap ( ":pixmaps/medinria-logo-homepage.png" ) );
    QLabel * textLabel = new QLabel;

    QTextEdit * textEdit = new QTextEdit;
    textEdit->setHtml ( "medINRIA is a multi-platform medical image processing and visualization software,\
                      and it's free. Through an intuitive user interface, medINRIA offers from standard \
                      to cutting-edge processing functionalities for your medical images such as 2D/3D/4D image visualization, \
                      image registration, or diffusion MR processing and tractography." );
    textEdit->setReadOnly ( true );
    textEdit->setFocusPolicy ( Qt::NoFocus );
    textEdit->setMaximumHeight ( 200 );
    infoLayout->insertWidget ( 0,medinriaLabel );
    infoLayout->insertWidget ( 1, textEdit );
    infoLayout->addStretch();

    d->infoWidget->setLayout ( infoLayout );
    d->infoWidget->setMaximumHeight ( medinriaLabel->height() + textEdit->height() );

    //About widget
    QVBoxLayout * aboutLayout = new QVBoxLayout;
    d->aboutTabWidget = new QTabWidget();

    QLabel * medinriaLabel2 = new QLabel ( this );
    medinriaLabel2->setPixmap ( QPixmap ( ":pixmaps/medinria-logo-homepage.png" ) );

    QTextEdit * aboutTextEdit = new QTextEdit;
    aboutTextEdit->setHtml ( "

\
                              medINRIA is the medical imaging platform developed at INRIA

\
                              INRIA, Copyright 2011

" );
    aboutTextEdit->setFocusPolicy ( Qt::NoFocus );

    QTextBrowser * aboutAuthorTextBrowser = new QTextBrowser;
    aboutAuthorTextBrowser->setSource(QUrl("qrc:authors.html" ));
    aboutAuthorTextBrowser->setFocusPolicy ( Qt::NoFocus );

    QTextEdit * aboutLicenseTextEdit = new QTextEdit;
    QFile license ( ":LICENSE.txt" );
    license.open ( QIODevice::ReadOnly | QIODevice::Text );
    QString licenseContent = license.readAll();
    license.close();
    aboutLicenseTextEdit->setText ( licenseContent );
    aboutLicenseTextEdit->setFocusPolicy ( Qt::NoFocus );

    QHBoxLayout * aboutButtonLayout = new QHBoxLayout;
    QPushButton * hideAboutButton = new QPushButton ( this );
    hideAboutButton->setText ( "Hide" );
    hideAboutButton->setFocusPolicy ( Qt::NoFocus );
    QObject::connect ( hideAboutButton, SIGNAL ( clicked() ), this, SLOT ( onHideAbout() ) );

    aboutButtonLayout->addStretch();
    aboutButtonLayout->addWidget ( hideAboutButton );
    aboutButtonLayout->addStretch();

    d->aboutTabWidget->addTab ( aboutTextEdit, "About" );
    d->aboutTabWidget->addTab ( aboutAuthorTextBrowser, "Authors" );
    d->aboutTabWidget->addTab ( aboutLicenseTextEdit, "License" );

    aboutLayout->addWidget ( medinriaLabel2 );
    aboutLayout->addWidget ( d->aboutTabWidget );
    aboutLayout->addLayout ( aboutButtonLayout );
    aboutLayout->addStretch();
    d->aboutWidget->setLayout ( aboutLayout );

    //Set the position of the widgets
    d->navigationWidget->setProperty ( "pos", QPoint ( 100 ,  this->height() / 4 ) );
    d->userWidget->setProperty ( "pos", QPoint ( this->width() - 350 ,  this->height() - 90 ) );
    d->infoWidget->setProperty ( "pos", QPoint ( this->width() / 2 ,  this->height() / 5 ) );
    d->aboutWidget->setProperty ( "pos", QPoint ( this->width() / 2 ,  this->height() / 5 ) );

    //Setup homepage animations
    d->animation = new QParallelAnimationGroup ( this );
    d->navigationAnimation = new QPropertyAnimation ( d->navigationWidget, "pos" );
    d->navigationAnimation->setDuration ( 750 );
    d->navigationAnimation->setEasingCurve ( QEasingCurve::OutCubic );
    d->navigationAnimation->setStartValue ( QPoint ( - 300,  this->height() / 4 ) );
    d->navigationAnimation->setEndValue ( QPoint ( 100 ,  this->height() / 4 ) );

    d->userAnimation = new QPropertyAnimation ( d->userWidget, "pos" );
    d->userAnimation->setDuration ( 750 );
    d->userAnimation->setEasingCurve ( QEasingCurve::OutCubic );
    d->userAnimation->setStartValue ( QPoint ( this->width() + 250,  this->height() - 90 ) );
    d->userAnimation->setEndValue ( QPoint ( this->width() * 0.8 ,  this->height() - 90 ) );

    d->infoAnimation = new QPropertyAnimation ( d->infoWidget, "pos" );
    d->infoAnimation->setDuration ( 900 );
    d->infoAnimation->setEasingCurve ( QEasingCurve::OutCubic );
    d->infoAnimation->setStartValue ( QPoint ( this->width() + 100 , this->height() / 5 ) );
    d->infoAnimation->setEndValue ( QPoint ( this->width() / 2 ,  this->height() / 5 ) );

    d->animation->addAnimation ( d->navigationAnimation );
    d->animation->addAnimation ( d->userAnimation );
    d->animation->addAnimation ( d->infoAnimation );

    //Setup the startup checkbox
    d->showOnStartupCheckBox = new QCheckBox ( this );
    d->showOnStartupCheckBox->setCheckState(Qt::Checked);
    d->showOnStartupCheckBox->setText ( "Start medINRIA on homepage ?" );
    d->showOnStartupCheckBox->setFocusPolicy ( Qt::NoFocus );
    d->showOnStartupCheckBox->setProperty ( "pos", QPoint ( this->width() - 200 ,  this->height() - 30 ) );
    if ( medSettingsManager::instance()->value ( "startup","default_starting_area" ).toInt() )
        d->showOnStartupCheckBox->setCheckState ( Qt::Unchecked );
    QObject::connect ( d->showOnStartupCheckBox, SIGNAL ( stateChanged ( int ) ), this, SLOT ( onStartWithHomepage ( int ) ) );
}

medHomepageArea::~medHomepageArea()
{
    delete d;

    d = NULL;
}

void medHomepageArea::resizeEvent ( QResizeEvent * event )
{
    //Recompute the widgets position when the window is resized
    d->navigationWidget->setProperty ( "pos", QPoint ( 100 ,  this->height() / 4 ) );
    d->userWidget->setProperty ( "pos", QPoint ( this->width() - 350 ,  this->height() - 90 ) );
    d->infoWidget->setProperty ( "pos", QPoint ( this->width() / 2 ,  this->height() / 5 ) );
    d->aboutWidget->setProperty ( "pos", QPoint ( this->width() / 2 ,  this->height() / 5 ) );
    d->showOnStartupCheckBox->setProperty ( "pos", QPoint ( this->width() - 200 ,  this->height() - 30 ) );

    d->aboutTabWidget->setMaximumHeight ( this->height() / 3 );

    //Update the animations as well
    d->navigationAnimation->setStartValue ( QPoint ( - 300,  this->height() / 4 ) );
    d->navigationAnimation->setEndValue ( QPoint ( 100 ,  this->height() / 4 ) );

    d->userAnimation->setStartValue ( QPoint ( this->width() + 50,  this->height() - 90 ) );
    d->userAnimation->setEndValue ( QPoint ( this->width() - 350 ,  this->height() - 90 ) );

    d->infoAnimation->setStartValue ( QPoint ( this->width() , this->height() / 5 ) );
    d->infoAnimation->setEndValue ( QPoint ( this->width() / 2 ,  this->height() / 5 ) );
}

void medHomepageArea::initPage ( void )
{
    //Initialization of the navigation widget with available workspaces
    QList<QString> configList = medViewerConfigurationFactory::instance()->configurations();
    QVBoxLayout * configurationButtonsLayout = new QVBoxLayout;
    configurationButtonsLayout->setSpacing ( 10 );
    QLabel * configurationLabel = new QLabel ( "Available workspaces" );
    configurationLabel->setTextFormat(Qt::RichText);
    configurationLabel->setAlignment(Qt::AlignHCenter);
    configurationButtonsLayout->addWidget ( configurationLabel );

    medHomepageButton * browserButton = new medHomepageButton ( this );
    browserButton->setToolButtonStyle ( Qt::ToolButtonTextUnderIcon );
    browserButton->setIcon ( QIcon ( ":/icons/folder.png" ) );
    browserButton->setText ( "Browser" );
    browserButton->setMinimumHeight ( 40 );
    browserButton->setMaximumWidth ( 250 );
    browserButton->setMinimumWidth ( 250 );
    browserButton->setFocusPolicy ( Qt::NoFocus );
    configurationButtonsLayout->addWidget ( browserButton );
    QObject::connect ( browserButton, SIGNAL ( clicked() ),this, SLOT ( onShowBrowser() ) );

    for ( int i = 0; i< configList.size(); i++ )
    {
        medHomepageButton * button = new medHomepageButton ( this );
        button->setText ( configList.at ( i ) );
        button->setFocusPolicy ( Qt::NoFocus );
        button->setToolButtonStyle ( Qt::ToolButtonTextUnderIcon );
        button->setMinimumHeight ( 40 );
        button->setMaximumWidth ( 250 );
        button->setMinimumWidth ( 250 );;
        configurationButtonsLayout->addWidget ( button );
        QObject::connect ( button, SIGNAL ( clicked ( QString ) ),this, SLOT ( onShowConfiguration ( QString ) ) );
    }
    configurationButtonsLayout->addStretch();
    d->navigationWidget->setLayout ( configurationButtonsLayout );
    d->navigationWidget->setProperty ( "pos", QPoint ( 100,  100 ) );
    d->navigationWidget->setMinimumHeight ( 55 * ( 1 + configList.size() ) );
}

QParallelAnimationGroup* medHomepageArea::getAnimation ( void )
{
    return d->animation;
}

void medHomepageArea::onShowBrowser ( void )
{
    emit showBrowser();
}

void medHomepageArea::onShowConfiguration ( QString configuration )
{
    emit showViewer();
    emit showConfiguration ( configuration );
}

void medHomepageArea::onShowAbout ( void )
{
    d->infoWidget->hide();
    d->aboutWidget->show();
}

void medHomepageArea::onHideAbout()
{
    d->aboutWidget->hide();
    d->infoWidget->show();
}

void medHomepageArea::onShowHelp ( void )
{
    QMessageBox * msgBox = new QMessageBox ( QApplication::activeWindow() );
    msgBox->setIcon ( QMessageBox::Information );
    msgBox->setText ( "Help ! Help !" );
    msgBox->exec();
    delete msgBox;
}

void medHomepageArea::onShowSettings ( void )
{
    emit showSettings();
}

void medHomepageArea::onStartWithHomepage ( int state )
{
    if ( state == Qt::Checked )
    {
        medSettingsManager::instance()->setValue ( "startup","default_starting_area", 0 );
    }
    else
    {
        medSettingsManager::instance()->setValue ( "startup","default_starting_area", 1 );
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdio.h>

#include "base/stl_util.h"
#include "chrome/browser/chromeos/disks/mock_disk_mount_manager.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"

using ::testing::_;
using ::testing::ReturnRef;
using ::testing::StrEq;

class ExtensionFileBrowserPrivateApiTest : public ExtensionApiTest {
 public:
  ExtensionFileBrowserPrivateApiTest()
      : disk_mount_manager_mock_(NULL),
        test_mount_point_("/tmp") {
    CreateVolumeMap();
  }

  virtual ~ExtensionFileBrowserPrivateApiTest() {
    DCHECK(!disk_mount_manager_mock_);
    STLDeleteValues(&volumes_);
  }

  // ExtensionApiTest override
  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    ExtensionApiTest::SetUpInProcessBrowserTestFixture();

    disk_mount_manager_mock_ = new chromeos::disks::MockDiskMountManager;
    chromeos::disks::DiskMountManager::InitializeForTesting(
        disk_mount_manager_mock_);
    disk_mount_manager_mock_->SetupDefaultReplies();
  }

  // ExtensionApiTest override
  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
    chromeos::disks::DiskMountManager::Shutdown();
    disk_mount_manager_mock_ = NULL;

    ExtensionApiTest::TearDownInProcessBrowserTestFixture();
  }

  void AddTmpMountPoint() {
    fileapi::ExternalFileSystemMountPointProvider* provider =
        browser()->profile()->GetFileSystemContext()->external_provider();
    provider->AddMountPoint(test_mount_point_);
  }

 private:
  void CreateVolumeMap() {
    // These have to be sync'd with values in filebrowser_mount extension.
    volumes_.insert(
        std::pair<std::string, chromeos::disks::DiskMountManager::Disk*>(
            "device_path1",
            new chromeos::disks::DiskMountManager::Disk(
                "device_path1",
                "/media/removable/mount_path1",
                "system_path1",
                "file_path1",
                "device_label1",
                "drive_label1",
                "system_path_prefix1",
                chromeos::DEVICE_TYPE_USB,
                1073741824,
                false,
                false,
                false,
                false,
                false)));
    volumes_.insert(
        std::pair<std::string, chromeos::disks::DiskMountManager::Disk*>(
            "device_path2",
            new chromeos::disks::DiskMountManager::Disk(
                "device_path2",
                "/media/removable/mount_path2",
                "system_path2",
                "file_path2",
                "device_label2",
                "drive_label2",
                "system_path_prefix2",
                chromeos::DEVICE_TYPE_MOBILE,
                47723,
                true,
                true,
                true,
                true,
                false)));
    volumes_.insert(
        std::pair<std::string, chromeos::disks::DiskMountManager::Disk*>(
            "device_path3",
            new chromeos::disks::DiskMountManager::Disk(
                "device_path3",
                "/media/removable/mount_path3",
                "system_path3",
                "file_path3",
                "device_label3",
                "drive_label3",
                "system_path_prefix3",
                chromeos::DEVICE_TYPE_OPTICAL_DISC,
                0,
                true,
                false,
                false,
                true,
                false)));
  }

 protected:
  chromeos::disks::MockDiskMountManager* disk_mount_manager_mock_;
  chromeos::disks::DiskMountManager::DiskMap volumes_;

 private:
  FilePath test_mount_point_;
};

IN_PROC_BROWSER_TEST_F(ExtensionFileBrowserPrivateApiTest, FileBrowserMount) {
  // We will call fileBrowserPrivate.unmountVolume once. To test that method, we
  // check that UnmountPath is really called with the same value.
  AddTmpMountPoint();
  EXPECT_CALL(*disk_mount_manager_mock_, UnmountPath(_))
      .Times(0);
  EXPECT_CALL(*disk_mount_manager_mock_,
              UnmountPath(StrEq("/tmp/test_file.zip"))).Times(1);

  EXPECT_CALL(*disk_mount_manager_mock_, disks())
      .WillRepeatedly(ReturnRef(volumes_));

  ASSERT_TRUE(RunComponentExtensionTest("filebrowser_mount"))  << message_;
}
<commit_msg>Fix flakiness in ExtensionFileBrowserPrivateApiTest.FileBrowserMount<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdio.h>

#include "base/stl_util.h"
#include "chrome/browser/chromeos/disks/mock_disk_mount_manager.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"

using ::testing::_;
using ::testing::ReturnRef;
using ::testing::StrEq;

class ExtensionFileBrowserPrivateApiTest : public ExtensionApiTest {
 public:
  ExtensionFileBrowserPrivateApiTest()
      : disk_mount_manager_mock_(NULL),
        test_mount_point_("/tmp") {
    CreateVolumeMap();
  }

  virtual ~ExtensionFileBrowserPrivateApiTest() {
    DCHECK(!disk_mount_manager_mock_);
    STLDeleteValues(&volumes_);
  }

  // ExtensionApiTest override
  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    ExtensionApiTest::SetUpInProcessBrowserTestFixture();

    disk_mount_manager_mock_ = new chromeos::disks::MockDiskMountManager;
    chromeos::disks::DiskMountManager::InitializeForTesting(
        disk_mount_manager_mock_);
    disk_mount_manager_mock_->SetupDefaultReplies();
  }

  // ExtensionApiTest override
  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
    chromeos::disks::DiskMountManager::Shutdown();
    disk_mount_manager_mock_ = NULL;

    ExtensionApiTest::TearDownInProcessBrowserTestFixture();
  }

  void AddTmpMountPoint() {
    fileapi::ExternalFileSystemMountPointProvider* provider =
        browser()->profile()->GetFileSystemContext()->external_provider();
    provider->AddMountPoint(test_mount_point_);
  }

 private:
  void CreateVolumeMap() {
    // These have to be sync'd with values in filebrowser_mount extension.
    volumes_.insert(
        std::pair<std::string, chromeos::disks::DiskMountManager::Disk*>(
            "device_path1",
            new chromeos::disks::DiskMountManager::Disk(
                "device_path1",
                "/media/removable/mount_path1",
                "system_path1",
                "file_path1",
                "device_label1",
                "drive_label1",
                "system_path_prefix1",
                chromeos::DEVICE_TYPE_USB,
                1073741824,
                false,
                false,
                false,
                false,
                false)));
    volumes_.insert(
        std::pair<std::string, chromeos::disks::DiskMountManager::Disk*>(
            "device_path2",
            new chromeos::disks::DiskMountManager::Disk(
                "device_path2",
                "/media/removable/mount_path2",
                "system_path2",
                "file_path2",
                "device_label2",
                "drive_label2",
                "system_path_prefix2",
                chromeos::DEVICE_TYPE_MOBILE,
                47723,
                true,
                true,
                true,
                true,
                false)));
    volumes_.insert(
        std::pair<std::string, chromeos::disks::DiskMountManager::Disk*>(
            "device_path3",
            new chromeos::disks::DiskMountManager::Disk(
                "device_path3",
                "/media/removable/mount_path3",
                "system_path3",
                "file_path3",
                "device_label3",
                "drive_label3",
                "system_path_prefix3",
                chromeos::DEVICE_TYPE_OPTICAL_DISC,
                0,
                true,
                false,
                false,
                true,
                false)));
  }

 protected:
  chromeos::disks::MockDiskMountManager* disk_mount_manager_mock_;
  chromeos::disks::DiskMountManager::DiskMap volumes_;

 private:
  FilePath test_mount_point_;
};

IN_PROC_BROWSER_TEST_F(ExtensionFileBrowserPrivateApiTest, FileBrowserMount) {
  // We will call fileBrowserPrivate.unmountVolume once. To test that method, we
  // check that UnmountPath is really called with the same value.
  AddTmpMountPoint();
  EXPECT_CALL(*disk_mount_manager_mock_, UnmountPath(_))
      .Times(0);
  EXPECT_CALL(*disk_mount_manager_mock_,
              UnmountPath(StrEq("/tmp/test_file.zip"))).Times(1);

  EXPECT_CALL(*disk_mount_manager_mock_, disks())
      .WillRepeatedly(ReturnRef(volumes_));

  ASSERT_TRUE(RunComponentExtensionTest("filebrowser_mount"))  << message_;

  ui_test_utils::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
  ui_test_utils::RunAllPendingInMessageLoop();
}
<|endoftext|>


<commit_before>#include "binary_tree.h"
#include <stdlib.h>
#include <time.h>

int main() {

	cout << "Let's do some binary tree tests!" << endl;
	srand( time(NULL) ) ;

	int num_keys = 5 ;
	int dummy_key ;
	binary_tree<int> mytree ;
	for(int i=0; i < num_keys; ++i) {
		dummy_key = rand() % 100 + 1 ;
		cout << "setting a leaf to: " << dummy_key << endl;
		mytree.insert(dummy_key) ;
	}

	mytree.printdata() ;
	cout << endl;

}
<commit_msg>Switched binary test file outside of the trees directory.<commit_after><|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2018 Kevin Masson, The appleseedhq Organization
//
// 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.
//

// Interface header.
#include "invalidsamplesaov.h"

// appleseed.renderer headers.
#include "renderer/kernel/rendering/pixelcontext.h"
#include "renderer/kernel/shading/shadingresult.h"
#include "renderer/modeling/aov/aov.h"
#include "renderer/kernel/aov/aovaccumulator.h"
#include "renderer/modeling/frame/frame.h"

// appleseed.foundation headers.
#include "foundation/image/color.h"
#include "foundation/image/image.h"
#include "foundation/utility/api/apistring.h"
#include "foundation/utility/api/specializedapiarrays.h"
#include "foundation/utility/containers/dictionary.h"

// Standard headers.
#include <cstddef>
#include <memory>
#include <string>

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Invalid Samples AOV accumulator.
    //

    const float NoState = 0.0f;
    const float InvalidSample = 1.0f;
    const float ValidSample = 2.0f;

    class InvalidSamplesAOVAccumulator
      : public UnfilteredAOVAccumulator
    {
      public:
        explicit InvalidSamplesAOVAccumulator(Image& image)
          : UnfilteredAOVAccumulator(image)
          , m_invalid_sample_count(0)
        {
        }

       void on_tile_begin(
           const Frame&                frame,
           const size_t                tile_x,
           const size_t                tile_y,
           const size_t                max_spp)
       {
           UnfilteredAOVAccumulator::on_tile_begin(frame, tile_x, tile_y, max_spp);
           m_crop_window = frame.get_crop_window();
       }

        void on_pixel_begin(const Vector2i& pi) override
        {
            m_invalid_sample_count = 0;
        }

        void on_pixel_end(const Vector2i& pi) override
        {
            // Store a hint corresponding to the sample state in the tile.
            // Because of tile margins, pi can lay outside of the crop window.
            if (inside_tile(pi) && m_crop_window.contains(pi))
            {
                const Vector2i pt(pi.x - m_tile_bbox.min.x, pi.y - m_tile_bbox.min.y);

                Color3f color(0.0f);
                color[0] = m_invalid_sample_count > 0 ? InvalidSample : ValidSample;

                m_tile->set_pixel(pt.x, pt.y, color);
            }
        }

        void write(
            const PixelContext&         pixel_context,
            const ShadingPoint&         shading_point,
            const ShadingComponents&    shading_components,
            const AOVComponents&        aov_components,
            ShadingResult&              shading_result) override
        {
            // Detect invalid samples.
            if (inside_tile(pixel_context.get_pixel_coords()))
            {
                if (!shading_result.is_valid())
                    m_invalid_sample_count++;
            }
        }

      private:
        size_t  m_invalid_sample_count;
        AABB2i  m_crop_window;
    };

    //
    // Invalid Samples AOV.
    //

    const char* InvalidSamplesAOVModel = "invalid_samples_aov";

    class InvalidSamplesAOV
      : public UnfilteredAOV
    {
      public:
        explicit InvalidSamplesAOV(const ParamArray& params)
          : UnfilteredAOV("invalid_samples", params)
        {
        }

        void release() override
        {
            delete this;
        }

        const char* get_model() const override
        {
            return InvalidSamplesAOVModel;
        }

        void post_process_image(const Frame& frame) override
        {
            const AABB2u& crop_window = frame.get_crop_window();
            const Image& beauty = frame.image();

            for (size_t y = crop_window.min.y; y <= crop_window.max.y; ++y)
            {
                for (size_t x = crop_window.min.x; x <= crop_window.max.x; ++x)
                {
                    Color3f color;
                    m_image->get_pixel(x, y, color);

                    if (color[0] == NoState)
                    {
                        color = Color3f(0.0f, 1.0f, 1.0f);
                    }
                    else if (color[0] == InvalidSample)
                    {
                        color = Color3f(1.0f, 0.0f, 1.0f);
                    }
                    else if (color[0] == ValidSample)
                    {
                        Color4f beauty_color;
                        beauty.get_pixel(x, y, beauty_color);
                        color.set(0.2f * luminance(beauty_color.rgb())); // 20% of luminance
                    }

                    m_image->set_pixel(x, y, color);
                }
            }
        }

      protected:
        auto_release_ptr<AOVAccumulator> create_accumulator() const override
        {
            return auto_release_ptr<AOVAccumulator>(
                new InvalidSamplesAOVAccumulator(get_image()));
        }
    };
}

//
// InvalidSamplesAOVFactory class implementation.
//

void InvalidSamplesAOVFactory::release()
{
    delete this;
}

const char* InvalidSamplesAOVFactory::get_model() const
{
    return InvalidSamplesAOVModel;
}

Dictionary InvalidSamplesAOVFactory::get_model_metadata() const
{
    return
        Dictionary()
            .insert("name", InvalidSamplesAOVModel)
            .insert("label", "Invalid Samples");
}

DictionaryArray InvalidSamplesAOVFactory::get_input_metadata() const
{
    DictionaryArray metadata;
    return metadata;
}

auto_release_ptr<AOV> InvalidSamplesAOVFactory::create(
    const ParamArray&   params) const
{
    return auto_release_ptr<AOV>(new InvalidSamplesAOV(params));
}

}   // namespace renderer
<commit_msg>Add missing override keyword on a method<commit_after>
//
// This source file is part of appleseed.
// Visit https://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2018 Kevin Masson, The appleseedhq Organization
//
// 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.
//

// Interface header.
#include "invalidsamplesaov.h"

// appleseed.renderer headers.
#include "renderer/kernel/rendering/pixelcontext.h"
#include "renderer/kernel/shading/shadingresult.h"
#include "renderer/modeling/aov/aov.h"
#include "renderer/kernel/aov/aovaccumulator.h"
#include "renderer/modeling/frame/frame.h"

// appleseed.foundation headers.
#include "foundation/image/color.h"
#include "foundation/image/image.h"
#include "foundation/utility/api/apistring.h"
#include "foundation/utility/api/specializedapiarrays.h"
#include "foundation/utility/containers/dictionary.h"

// Standard headers.
#include <cstddef>
#include <memory>
#include <string>

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Invalid Samples AOV accumulator.
    //

    const float NoState = 0.0f;
    const float InvalidSample = 1.0f;
    const float ValidSample = 2.0f;

    class InvalidSamplesAOVAccumulator
      : public UnfilteredAOVAccumulator
    {
      public:
        explicit InvalidSamplesAOVAccumulator(Image& image)
          : UnfilteredAOVAccumulator(image)
          , m_invalid_sample_count(0)
        {
        }

       void on_tile_begin(
           const Frame&                frame,
           const size_t                tile_x,
           const size_t                tile_y,
           const size_t                max_spp) override
       {
           UnfilteredAOVAccumulator::on_tile_begin(frame, tile_x, tile_y, max_spp);
           m_crop_window = frame.get_crop_window();
       }

        void on_pixel_begin(const Vector2i& pi) override
        {
            m_invalid_sample_count = 0;
        }

        void on_pixel_end(const Vector2i& pi) override
        {
            // Store a hint corresponding to the sample state in the tile.
            // Because of tile margins, pi can lay outside of the crop window.
            if (inside_tile(pi) && m_crop_window.contains(pi))
            {
                const Vector2i pt(pi.x - m_tile_bbox.min.x, pi.y - m_tile_bbox.min.y);

                Color3f color(0.0f);
                color[0] = m_invalid_sample_count > 0 ? InvalidSample : ValidSample;

                m_tile->set_pixel(pt.x, pt.y, color);
            }
        }

        void write(
            const PixelContext&         pixel_context,
            const ShadingPoint&         shading_point,
            const ShadingComponents&    shading_components,
            const AOVComponents&        aov_components,
            ShadingResult&              shading_result) override
        {
            // Detect invalid samples.
            if (inside_tile(pixel_context.get_pixel_coords()))
            {
                if (!shading_result.is_valid())
                    m_invalid_sample_count++;
            }
        }

      private:
        size_t  m_invalid_sample_count;
        AABB2i  m_crop_window;
    };

    //
    // Invalid Samples AOV.
    //

    const char* InvalidSamplesAOVModel = "invalid_samples_aov";

    class InvalidSamplesAOV
      : public UnfilteredAOV
    {
      public:
        explicit InvalidSamplesAOV(const ParamArray& params)
          : UnfilteredAOV("invalid_samples", params)
        {
        }

        void release() override
        {
            delete this;
        }

        const char* get_model() const override
        {
            return InvalidSamplesAOVModel;
        }

        void post_process_image(const Frame& frame) override
        {
            const AABB2u& crop_window = frame.get_crop_window();
            const Image& beauty = frame.image();

            for (size_t y = crop_window.min.y; y <= crop_window.max.y; ++y)
            {
                for (size_t x = crop_window.min.x; x <= crop_window.max.x; ++x)
                {
                    Color3f color;
                    m_image->get_pixel(x, y, color);

                    if (color[0] == NoState)
                    {
                        color = Color3f(0.0f, 1.0f, 1.0f);
                    }
                    else if (color[0] == InvalidSample)
                    {
                        color = Color3f(1.0f, 0.0f, 1.0f);
                    }
                    else if (color[0] == ValidSample)
                    {
                        Color4f beauty_color;
                        beauty.get_pixel(x, y, beauty_color);
                        color.set(0.2f * luminance(beauty_color.rgb())); // 20% of luminance
                    }

                    m_image->set_pixel(x, y, color);
                }
            }
        }

      protected:
        auto_release_ptr<AOVAccumulator> create_accumulator() const override
        {
            return auto_release_ptr<AOVAccumulator>(
                new InvalidSamplesAOVAccumulator(get_image()));
        }
    };
}

//
// InvalidSamplesAOVFactory class implementation.
//

void InvalidSamplesAOVFactory::release()
{
    delete this;
}

const char* InvalidSamplesAOVFactory::get_model() const
{
    return InvalidSamplesAOVModel;
}

Dictionary InvalidSamplesAOVFactory::get_model_metadata() const
{
    return
        Dictionary()
            .insert("name", InvalidSamplesAOVModel)
            .insert("label", "Invalid Samples");
}

DictionaryArray InvalidSamplesAOVFactory::get_input_metadata() const
{
    DictionaryArray metadata;
    return metadata;
}

auto_release_ptr<AOV> InvalidSamplesAOVFactory::create(
    const ParamArray&   params) const
{
    return auto_release_ptr<AOV>(new InvalidSamplesAOV(params));
}

}   // namespace renderer
<|endoftext|>


<commit_before>#include <Ogre.h>
#include <utility>
#include "core/engine.h"
#include "core/entity.h"
#include "core/system_loader.h"

#include "ogrerender.h"

using namespace Ogre;

Ygg::OgreRenderSystem::OgreRenderSystem(unsigned long window, SystemLoader *loader)
    :m_parentwindow(window),
      m_loader(loader)
{
}

Ygg::OgreRenderSystem::~OgreRenderSystem()
{
	delete m_root;
}

void Ygg::OgreRenderSystem::Init(Ygg::Engine *engine)
{
	m_root = new Ogre::Root("", "", "");

	// Load required systems
	Ogre::StringVector required_plugins;
	required_plugins.push_back("./RenderSystem_GL");
	required_plugins.push_back("./Plugin_OctreeSceneManager");

	for (auto it = required_plugins.begin(); it != required_plugins.end(); ++it) {
#ifdef _DEBUG
		m_root->loadPlugin(*it + Ogre::String("_d"));
#else
		m_root->loadPlugin(*it);
#endif
	}

	// ToDo, check that plugins were actually loaded

	m_root->setRenderSystem(m_root->getRenderSystemByName("OpenGL Rendering Subsystem"));
	m_root->initialise(false);

	// Setup the window
	Ogre::NameValuePairList params;
	params.insert(std::make_pair("externalWindowHandle", Ogre::StringConverter::toString(m_parentwindow)));

	m_window = m_root->createRenderWindow("Yggdrasil", 800, 600, false, &params);
	m_window->setVisible(true);

	// Setup the scenemanager
	m_scenemgr = m_root->createSceneManager("OctreeSceneManager", "DefaultSceneManager");

	// Setup the camera
	m_camera = m_scenemgr->createCamera("Camera");
	m_camera->setPosition(Ogre::Vector3(10, 10, 10));
	m_camera->lookAt(Ogre::Vector3(0, 0, 0));
	m_camera->setNearClipDistance(5);

	// Setup the viewport
	Ogre::Viewport *vp = m_window->addViewport(m_camera);
	vp->setBackgroundColour(Ogre::ColourValue(0.5f, 1.0f, 0.0f));

	// Match the camera aspect ratio to the viewport
	m_camera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));

	// Create a default material
	Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(
	                                 "DefaultMaterial",
	                                 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	material->getTechnique(0)->getPass(0)->setVertexColourTracking(Ogre::TVC_AMBIENT);
	material->getTechnique(0)->getPass(0)->setDiffuse(Ogre::ColourValue(0.0, 0.2, 1.0, 0.0));

	// Set ambient light
	m_scenemgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

	// Create a light
	Ogre::Light *light = m_scenemgr->createLight("MainLight");
	light->setPosition(20, 80, 50);
}

static void convert_mesh(const std::string& mname, Ygg::Mesh *mdata)
{
	Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual(mname, "General");
	Ogre::SubMesh *submesh = mesh->createSubMesh();

	const size_t nverts = mdata->vertices.size();
	float verts[3 * 2 * nverts];
	const size_t ibufcount = 3 * mdata->indices.size();
	unsigned short faces[ibufcount];

	for (size_t i = 0; i < nverts; ++i) {
		verts[6*i+0] = mdata->vertices[i].x;
		verts[6*i+1] = mdata->vertices[i].y;
		verts[6*i+2] = mdata->vertices[i].z;

		verts[6*i+3] = mdata->normals[i].x;
		verts[6*i+4] = mdata->normals[i].y;
		verts[6*i+5] = mdata->normals[i].z;
	}

	for (size_t i = 0; i < mdata->indices.size(); ++i) {
		faces[i] = mdata->indices[i];
	}

	mesh->sharedVertexData = new Ogre::VertexData();
	mesh->sharedVertexData->vertexCount = nverts;
	mesh->sharedVertexData->vertexStart = 0;

	// Create declaration (memory format) of vertex data
	Ogre::VertexDeclaration *decl = mesh->sharedVertexData->vertexDeclaration;
	size_t offset = 0;

	offset += decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION).getSize();

	offset += decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL).getSize();

	// Allocate vertex buffer
	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
	                                               decl->getVertexSize(0), nverts,
	                                               Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// Upload the vertex data to the GPU
	vbuf->writeData(0, vbuf->getSizeInBytes(), verts, true);

	// Bind the vertex buffer
	Ogre::VertexBufferBinding *binding = mesh->sharedVertexData->vertexBufferBinding;
	binding->setBinding(0, vbuf);

	// Allocate index buffer
	Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
	                                              Ogre::HardwareIndexBuffer::IT_16BIT,
	                                              ibufcount,
	                                              Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// Upload the index data to the GPU
	ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

	// Set parameters of the submesh
	submesh->useSharedVertices = true;
	submesh->indexData->indexBuffer = ibuf;
	submesh->indexData->indexCount = ibufcount;
	submesh->indexData->indexStart = 0;

	// Set bounding information for culling
	// ToDo set better bounds
	mesh->_setBounds(Ogre::AxisAlignedBox(-100, -100, -100, 100, 100, 100));
	mesh->_setBoundingSphereRadius(1000);

	mesh->load();
}

void Ygg::OgreRenderSystem::Convert(Ygg::Engine *engine, std::vector<Entity> *entity_queue)
{
	for (auto it = entity_queue->begin(); it != entity_queue->end(); ++it) {
		Entity *entity = &(*it);

		std::cout << "OGRE: Converting " << entity->name << std::endl;

		// Convert mesh
		MeshComponent *mesh_component = (MeshComponent*)engine->GetComponent(entity, SystemLoader::CID_MESH);
		if (mesh_component != NULL)
		{
			std::cout << "\tFound Mesh" << std::endl;
			convert_mesh(entity->name, &(*m_loader->GetMeshes())[mesh_component->mesh_handles[0]]);
			Ogre::Entity *head = m_scenemgr->createEntity(entity->name, entity->name);
			head->setMaterialName("DefaultMaterial");

			Ogre::SceneNode *headnode = m_scenemgr->getRootSceneNode()->createChildSceneNode();
			headnode->attachObject(head);
			headnode->setPosition(0, 0, 0);
		}
	}
}

void Ygg::OgreRenderSystem::Update(Ygg::Engine *engine, float dt)
{
	m_root->renderOneFrame();
}
<commit_msg>OgreRender: Renaming some variables to be more generic.<commit_after>#include <Ogre.h>
#include <utility>
#include "core/engine.h"
#include "core/entity.h"
#include "core/system_loader.h"

#include "ogrerender.h"

using namespace Ogre;

Ygg::OgreRenderSystem::OgreRenderSystem(unsigned long window, SystemLoader *loader)
    :m_parentwindow(window),
      m_loader(loader)
{
}

Ygg::OgreRenderSystem::~OgreRenderSystem()
{
	delete m_root;
}

void Ygg::OgreRenderSystem::Init(Ygg::Engine *engine)
{
	m_root = new Ogre::Root("", "", "");

	// Load required systems
	Ogre::StringVector required_plugins;
	required_plugins.push_back("./RenderSystem_GL");
	required_plugins.push_back("./Plugin_OctreeSceneManager");

	for (auto it = required_plugins.begin(); it != required_plugins.end(); ++it) {
#ifdef _DEBUG
		m_root->loadPlugin(*it + Ogre::String("_d"));
#else
		m_root->loadPlugin(*it);
#endif
	}

	// ToDo, check that plugins were actually loaded

	m_root->setRenderSystem(m_root->getRenderSystemByName("OpenGL Rendering Subsystem"));
	m_root->initialise(false);

	// Setup the window
	Ogre::NameValuePairList params;
	params.insert(std::make_pair("externalWindowHandle", Ogre::StringConverter::toString(m_parentwindow)));

	m_window = m_root->createRenderWindow("Yggdrasil", 800, 600, false, &params);
	m_window->setVisible(true);

	// Setup the scenemanager
	m_scenemgr = m_root->createSceneManager("OctreeSceneManager", "DefaultSceneManager");

	// Setup the camera
	m_camera = m_scenemgr->createCamera("Camera");
	m_camera->setPosition(Ogre::Vector3(10, 10, 10));
	m_camera->lookAt(Ogre::Vector3(0, 0, 0));
	m_camera->setNearClipDistance(5);

	// Setup the viewport
	Ogre::Viewport *vp = m_window->addViewport(m_camera);
	vp->setBackgroundColour(Ogre::ColourValue(0.5f, 1.0f, 0.0f));

	// Match the camera aspect ratio to the viewport
	m_camera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));

	// Create a default material
	Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(
	                                 "DefaultMaterial",
	                                 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
	material->getTechnique(0)->getPass(0)->setVertexColourTracking(Ogre::TVC_AMBIENT);
	material->getTechnique(0)->getPass(0)->setDiffuse(Ogre::ColourValue(0.0, 0.2, 1.0, 0.0));

	// Set ambient light
	m_scenemgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

	// Create a light
	Ogre::Light *light = m_scenemgr->createLight("MainLight");
	light->setPosition(20, 80, 50);
}

static void convert_mesh(const std::string& mname, Ygg::Mesh *mdata)
{
	Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().createManual(mname, "General");
	Ogre::SubMesh *submesh = mesh->createSubMesh();

	const size_t nverts = mdata->vertices.size();
	float verts[3 * 2 * nverts];
	const size_t ibufcount = 3 * mdata->indices.size();
	unsigned short faces[ibufcount];

	for (size_t i = 0; i < nverts; ++i) {
		verts[6*i+0] = mdata->vertices[i].x;
		verts[6*i+1] = mdata->vertices[i].y;
		verts[6*i+2] = mdata->vertices[i].z;

		verts[6*i+3] = mdata->normals[i].x;
		verts[6*i+4] = mdata->normals[i].y;
		verts[6*i+5] = mdata->normals[i].z;
	}

	for (size_t i = 0; i < mdata->indices.size(); ++i) {
		faces[i] = mdata->indices[i];
	}

	mesh->sharedVertexData = new Ogre::VertexData();
	mesh->sharedVertexData->vertexCount = nverts;
	mesh->sharedVertexData->vertexStart = 0;

	// Create declaration (memory format) of vertex data
	Ogre::VertexDeclaration *decl = mesh->sharedVertexData->vertexDeclaration;
	size_t offset = 0;

	offset += decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION).getSize();

	offset += decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL).getSize();

	// Allocate vertex buffer
	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
	                                               decl->getVertexSize(0), nverts,
	                                               Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// Upload the vertex data to the GPU
	vbuf->writeData(0, vbuf->getSizeInBytes(), verts, true);

	// Bind the vertex buffer
	Ogre::VertexBufferBinding *binding = mesh->sharedVertexData->vertexBufferBinding;
	binding->setBinding(0, vbuf);

	// Allocate index buffer
	Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
	                                              Ogre::HardwareIndexBuffer::IT_16BIT,
	                                              ibufcount,
	                                              Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

	// Upload the index data to the GPU
	ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

	// Set parameters of the submesh
	submesh->useSharedVertices = true;
	submesh->indexData->indexBuffer = ibuf;
	submesh->indexData->indexCount = ibufcount;
	submesh->indexData->indexStart = 0;

	// Set bounding information for culling
	// ToDo set better bounds
	mesh->_setBounds(Ogre::AxisAlignedBox(-100, -100, -100, 100, 100, 100));
	mesh->_setBoundingSphereRadius(1000);

	mesh->load();
}

void Ygg::OgreRenderSystem::Convert(Ygg::Engine *engine, std::vector<Entity> *entity_queue)
{
	for (auto it = entity_queue->begin(); it != entity_queue->end(); ++it) {
		Entity *entity = &(*it);

		std::cout << "OGRE: Converting " << entity->name << std::endl;

		// Convert mesh
		MeshComponent *mesh_component = (MeshComponent*)engine->GetComponent(entity, SystemLoader::CID_MESH);
		if (mesh_component != NULL)
		{
			std::cout << "\tFound Mesh" << std::endl;
			convert_mesh(entity->name, &(*m_loader->GetMeshes())[mesh_component->mesh_handles[0]]);
			Ogre::Entity *ogre_entity = m_scenemgr->createEntity(entity->name, entity->name);
			ogre_entity->setMaterialName("DefaultMaterial");

			Ogre::SceneNode *ogre_node = m_scenemgr->getRootSceneNode()->createChildSceneNode();
			ogre_node->attachObject(ogre_entity);
			ogre_node->setPosition(0, 0, 0);
		}
	}
}

void Ygg::OgreRenderSystem::Update(Ygg::Engine *engine, float dt)
{
	m_root->renderOneFrame();
}
<|endoftext|>


<commit_before>#pragma once
/*
* Covariant Script Runtime Extension
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2017 Michael Lee(李登淳)
* Email: mikecovlee@163.com
* Github: https://github.com/mikecovlee
*/
#include "../cni.hpp"
#include <cstdlib>

static cs::extension runtime_ext;
namespace runtime_cs_ext {
	using namespace cs;

	void info()
	{
		std::cout << "Covariant Script Programming Language Interpreter Version " << cs::version << "\n"
		          "Copyright (C) 2017 Michael Lee.All rights reserved.\nThis program comes with ABSOLUTELY NO WARRANTY; for details see <http://www.gnu.org/licenses/>.\n"
		          "This is free software, and you are welcome to redistribute it under certain conditions.\nPlease visit <http://covscript.org/> for more information." << std::endl;
	}

	number time()
	{
		return cov::timer::time(cov::timer::time_unit::milli_sec);
	}

	void delay(number time)
	{
		cov::timer::delay(cov::timer::time_unit::milli_sec, time);
	}

	number rand(number b, number e)
	{
		return cov::rand<number>(b, e);
	}

	number randint(number b, number e)
	{
		return cov::rand<long>(b, e);
	}

	var exception(const string &str)
	{
		return var::make<lang_error>(str);
	}

	extension_t load_extension(const string &path)
	{
		return std::make_shared<extension_holder>(path);
	}

	std::size_t hash(const var &val)
	{
		return val.hash();
	}

	using expression_t=cov::tree<token_base *>;

	var build(const string &expr)
	{
		std::deque<char> buff;
		std::deque<token_base *> tokens;
		expression_t tree;
		for (auto &ch:expr)
			buff.push_back(ch);
		translate_into_tokens(buff, tokens);
		process_brackets(tokens);
		kill_brackets(tokens);
		gen_tree(tree, tokens);
		return var::make<expression_t>(tree);
	}

	var solve(expression_t &tree)
	{
		return parse_expr(tree.root());
	}

	void init()
	{
		runtime_ext.add_var("std_version", var::make_constant<number>(std_version));
		runtime_ext.add_var("info", var::make_protect<callable>(cni(info)));
		runtime_ext.add_var("time", var::make_protect<callable>(cni(time)));
		runtime_ext.add_var("delay", var::make_protect<callable>(cni(delay)));
		runtime_ext.add_var("rand", var::make_protect<callable>(cni(rand)));
		runtime_ext.add_var("randint", var::make_protect<callable>(cni(randint)));
		runtime_ext.add_var("exception", var::make_protect<callable>(cni(exception)));
		runtime_ext.add_var("load_extension", var::make_protect<callable>(cni(load_extension), true));
		runtime_ext.add_var("hash", var::make_protect<callable>(cni(hash), true));
		runtime_ext.add_var("build", var::make_protect<callable>(cni(build)));
		runtime_ext.add_var("solve", var::make_protect<callable>(cni(solve)));
	}
}
<commit_msg>更换开源协议<commit_after>#pragma once
/*
* Covariant Script Runtime Extension
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2017 Michael Lee(李登淳)
* Email: mikecovlee@163.com
* Github: https://github.com/mikecovlee
*/
#include "../cni.hpp"
#include <cstdlib>

static cs::extension runtime_ext;
namespace runtime_cs_ext {
	using namespace cs;

	void info()
	{
		std::cout << "Covariant Script Programming Language Interpreter\nVersion: " << cs::version << "\n"
		          "Copyright (C) 2017 Michael Lee.All rights reserved.\n"
		          "This program is free software: you can redistribute it and/or modify"
		          "it under the terms of the GNU Affero General Public License as published"
		          "by the Free Software Foundation, either version 3 of the License, or"
		          "(at your option) any later version.\n"
		          "\n"
		          "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 Affero General Public License for more details.\n"
		          "\n"
		          "You should have received a copy of the GNU Affero General Public License"
		          "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n"
		          "Please visit <http://covscript.org/> for more information." << std::endl;
	}

	number time()
	{
		return cov::timer::time(cov::timer::time_unit::milli_sec);
	}

	void delay(number time)
	{
		cov::timer::delay(cov::timer::time_unit::milli_sec, time);
	}

	number rand(number b, number e)
	{
		return cov::rand<number>(b, e);
	}

	number randint(number b, number e)
	{
		return cov::rand<long>(b, e);
	}

	var exception(const string &str)
	{
		return var::make<lang_error>(str);
	}

	extension_t load_extension(const string &path)
	{
		return std::make_shared<extension_holder>(path);
	}

	std::size_t hash(const var &val)
	{
		return val.hash();
	}

	using expression_t=cov::tree<token_base *>;

	var build(const string &expr)
	{
		std::deque<char> buff;
		std::deque<token_base *> tokens;
		expression_t tree;
		for (auto &ch:expr)
			buff.push_back(ch);
		translate_into_tokens(buff, tokens);
		process_brackets(tokens);
		kill_brackets(tokens);
		gen_tree(tree, tokens);
		return var::make<expression_t>(tree);
	}

	var solve(expression_t &tree)
	{
		return parse_expr(tree.root());
	}

	void init()
	{
		runtime_ext.add_var("std_version", var::make_constant<number>(std_version));
		runtime_ext.add_var("info", var::make_protect<callable>(cni(info)));
		runtime_ext.add_var("time", var::make_protect<callable>(cni(time)));
		runtime_ext.add_var("delay", var::make_protect<callable>(cni(delay)));
		runtime_ext.add_var("rand", var::make_protect<callable>(cni(rand)));
		runtime_ext.add_var("randint", var::make_protect<callable>(cni(randint)));
		runtime_ext.add_var("exception", var::make_protect<callable>(cni(exception)));
		runtime_ext.add_var("load_extension", var::make_protect<callable>(cni(load_extension), true));
		runtime_ext.add_var("hash", var::make_protect<callable>(cni(hash), true));
		runtime_ext.add_var("build", var::make_protect<callable>(cni(build)));
		runtime_ext.add_var("solve", var::make_protect<callable>(cni(solve)));
	}
}
<|endoftext|>