<commit_before>//==============================================================================
// CellML annotation view CellML element details widget
//==============================================================================

#include "cellmlannotationviewcellmlelementdetailswidget.h"
#include "cellmlannotationviewcellmlelementitem.h"
#include "cellmlannotationviewcellmllistwidget.h"
#include "cellmlannotationviewlistswidget.h"
#include "cellmlannotationviewmetadatalistwidget.h"
#include "cellmlannotationviewwidget.h"
#include "treeview.h"

//==============================================================================

#include "ui_cellmlannotationviewcellmlelementdetailswidget.h"

//==============================================================================

#include <QComboBox>
#include <QFormLayout>
#include <QLabel>
#include <QPushButton>
#include <QScrollBar>

//==============================================================================

namespace OpenCOR {
namespace CellMLAnnotationView {

//==============================================================================

bool CellmlAnnotationViewCellmlElementDetailsWidget::Item::operator==(const Item &pItem) const
{
    // Return whether the given item is equal to the current one

    return    (type == pItem.type)
           && (element == pItem.element)
           && (number == pItem.number);
}

//==============================================================================

CellmlAnnotationViewCellmlElementDetailsWidget::CellmlAnnotationViewCellmlElementDetailsWidget(CellmlAnnotationViewWidget *pParent) :
    QScrollArea(pParent),
    CommonWidget(pParent),
    mParent(pParent),
    mGui(new Ui::CellmlAnnotationViewCellmlElementDetailsWidget),
    mItems(Items()),
    mCmetaIdValue(0)
{
    // Set up the GUI

    mGui->setupUi(this);

    // Create the widget (and its layout) which will contain our GUI

    mWidget = new QWidget(this);
    mLayout = new QFormLayout(mWidget);

    mWidget->setLayout(mLayout);

    // Add our widget to our scroll area

    setWidget(mWidget);
}

//==============================================================================

CellmlAnnotationViewCellmlElementDetailsWidget::~CellmlAnnotationViewCellmlElementDetailsWidget()
{
    // Delete the GUI

    delete mGui;
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::retranslateUi()
{
    // Retranslate our GUI

    mGui->retranslateUi(this);

    // For the rest of our GUI, it's easier to just update it, so...

    updateGui();
}

//==============================================================================

CellmlAnnotationViewCellmlElementDetailsWidget::Item CellmlAnnotationViewCellmlElementDetailsWidget::item(const Type &pType,
                                                                                CellMLSupport::CellmlFileElement *pElement,
                                                                                const int &pNumber)
{
    // Return a formatted Item 'object'

    Item res;

    res.type    = pType;
    res.element = pElement;
    res.number  = pNumber;

    return res;
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::updateGui(const Items &pItems)
{
    // Prevent ourselves from being updated (to avoid any flickering)

    setUpdatesEnabled(false);

    // Keep track of the items

    mItems = pItems;

    // Reset our cmeta:id widget

    if (mCmetaIdValue) {
        disconnect(mCmetaIdValue, SIGNAL(editTextChanged(const QString &)),
                   this, SLOT(newCmetaId(const QString &)));

        mCmetaIdValue = 0;
    }

    // Remove everything from our form layout

    for (int i = 0, iMax = mLayout->count(); i < iMax; ++i) {
        QLayoutItem *item = mLayout->takeAt(0);

        delete item->widget();
        delete item;
    }

    // Go through the different items which properties we want to add to the GUI

    for (int i = 0, iLast = pItems.count()-1; i <= iLast; ++i) {
        Item item = pItems[i];

        // Determine which widget should be shown/hidden

        bool showName = false;
        bool showXlinkHref = false;
        bool showUnitReference = false;
        bool showComponentReference = false;
        bool showUnit = false;
        bool showInitialValue = false;
        bool showPublicInterface = false;
        bool showPrivateInterface = false;
        bool showRelationship = false;
        bool showRelationshipNamespace = false;
        bool showComponent = false;
        bool showFirstComponent = false;
        bool showSecondComponent = false;
        bool showFirstVariable = false;
        bool showSecondVariable = false;

        switch (item.type) {
        case Model:
        case Unit:
        case UnitElement:
        case Component:
        case Group:
        case Connection:
            showName = true;

            break;
        case Import:
            showXlinkHref = true;

            break;
        case ImportUnit:
            showName = true;
            showUnitReference = true;

            break;
        case ImportComponent:
            showName = true;
            showComponentReference = true;

            break;
        case Variable:
            showName = true;
            showUnit = true;
            showInitialValue = true;
            showPublicInterface = true;
            showPrivateInterface = true;

            break;
        case RelationshipReference:
            showRelationship = true;
            showRelationshipNamespace = true;

            break;
        case ComponentReference:
            showComponent = true;

            break;
        case ComponentMapping:
            showFirstComponent = true;
            showSecondComponent = true;

            break;
        case VariableMapping:
            showFirstVariable = true;
            showSecondVariable = true;

            break;
        };

        // Add whatever we need
        // Note: as long as all of the widgets' parent is our widget, then they
        //       will get automatically deleted, so no need to delete them in
        //       ~CellmlAnnotationViewCellmlElementDetailsWidget()...

        // Add a bold centered label as a header to let the user know what type
        // of item we are talking about

        mLayout->addRow(mParent->newLabel(mWidget, typeAsString(item.type),
                                          true, 1.25, Qt::AlignCenter));

        // Show the item's cmeta:id, keeping in mind that we only want to allow
        // the editing of the cmeta:id of the very first item

        QString cmetaId = item.element->cmetaId();

        if (i == iLast) {
            // This is our 'main' item, so we want to allow the user to edit its
            // cmeta:id. For this, we use a QComboBox, but we also want to have
            // a QPushButton to allow the user to switch to the editing mode of
            // the metadata associated with the cmeta:id, so we create a meta
            // widget which contains both a QComboBox and a QPushButton

            QWidget *cmetaIdWidget = new QWidget(mWidget);

            QHBoxLayout *cmetaIdWidgetLayout = new QHBoxLayout(cmetaIdWidget);

            cmetaIdWidgetLayout->setMargin(0);

            cmetaIdWidget->setLayout(cmetaIdWidgetLayout);

            // Create our QComboBox widget

            mCmetaIdValue = new QComboBox(mWidget);

            mCmetaIdValue->addItems(mParent->listsWidget()->metadataList()->ids());

            mCmetaIdValue->setEditable(true);

            bool cmetaIdFound = false;

            for (int i = 0, iMax = mCmetaIdValue->count(); i < iMax; ++i)
                if (!cmetaId.compare(mCmetaIdValue->itemText(i))) {
                    // The cmeta:id could be found in our list of metadata ids,
                    // so set our cmeta:id index to it

                    mCmetaIdValue->setCurrentIndex(i);

                    cmetaIdFound = true;

                    break;
                }

            if (!cmetaIdFound)
                // The cmeta:id couldn't be found in our list of metadata ids,
                // so 'manually' set it

                mCmetaIdValue->setEditText(cmetaId);

            // Create our QPushButton

            QPushButton *editButton = new QPushButton(mWidget);
            // Note #1: ideally, we could assign a QAction to our QPushButton,
            //          but this cannot be done, so... we assign a few
            //          properties by hand...
            // Note #2: to use a QToolButton would allow us to assign a QAction
            //          to it, but a QToolButton doesn't look quite the same as
            //          a QPushButton on some platforms, so...

            editButton->setIcon(QIcon(":/oxygen/actions/format-list-unordered.png"));
            editButton->setStatusTip(tr("Edit the metadata"));
            editButton->setToolTip(tr("Edit"));
            editButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

            connect(editButton, SIGNAL(clicked()),
                    this, SLOT(editMetadata()));

            // Add our QComboBox and QPushButton to our cmeta:id widget

            cmetaIdWidgetLayout->addWidget(mCmetaIdValue);
            cmetaIdWidgetLayout->addWidget(editButton);

            // Add our cmeta:id widget to our main layout

            mLayout->addRow(mParent->newLabel(mWidget, tr("cmeta:id:"), true),
                            cmetaIdWidget);

            // Make our cmeta:id value the widget to tab to after our CellML
            // tree view

            setTabOrder(qobject_cast<QWidget *>(mParent->listsWidget()->cellmlList()->treeView()),
                        mCmetaIdValue);
            setTabOrder(mCmetaIdValue, editButton);
            setTabOrder(editButton,
                        qobject_cast<QWidget *>(mParent->listsWidget()->metadataList()->treeView()));

            // Create a connection to keep track of changes to our cmeta:id
            // value

            connect(mCmetaIdValue, SIGNAL(editTextChanged(const QString &)),
                    this, SLOT(newCmetaId(const QString &)));
        } else {
            // Not our 'main' item, so just display its cmeta:id

            addRow(tr("cmeta:id:"), cmetaId.isEmpty()?"/":cmetaId);
        }

        // Show the item's remaining properties

        if (showName) {
            // Retrieve the name of the CellML element
            // Note: in the case of a group or a connection, there won't be a
            //       name, so we use the item's name, hoping one was provided...

            QString name = ((item.type == Group) || (item.type == Connection))?
                               (item.number == -1)?
                                   "/":
                                   (item.type == Group)?
                                       tr("Group #%1").arg(item.number):
                                       tr("Connection #%1").arg(item.number):
                               static_cast<CellMLSupport::CellmlFileNamedElement *>(item.element)->name();

            addRow(tr("Name:"), name);
        }

        if (showXlinkHref)
            addRow(tr("xlink:href:"),
                   static_cast<CellMLSupport::CellmlFileImport *>(item.element)->xlinkHref());

        if (showUnitReference)
            addRow(tr("Unit reference:"),
                   static_cast<CellMLSupport::CellmlFileImportUnit *>(item.element)->unitReference());

        if (showComponentReference)
            addRow(tr("Component reference:"),
                   static_cast<CellMLSupport::CellmlFileImportComponent *>(item.element)->componentReference());

        if (showUnit)
            addRow(tr("Unit:"),
                   static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->unit());

        if (showInitialValue) {
            QString initialValue = static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->initialValue();

            addRow(tr("Initial value:"),
                   initialValue.isEmpty()?"/":initialValue);
        }

        if (showPublicInterface)
            addRow(tr("Public interface:"),
                   static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->publicInterfaceAsString());

        if (showPrivateInterface)
            addRow(tr("Private interface:"),
                   static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->privateInterfaceAsString());

        if (showRelationship)
            addRow(tr("Relationship:"),
                   static_cast<CellMLSupport::CellmlFileRelationshipReference *>(item.element)->relationship());

        if (showRelationshipNamespace) {
            QString relationshipNamespace = static_cast<CellMLSupport::CellmlFileRelationshipReference *>(item.element)->relationshipNamespace();

            addRow(tr("Relationship namespace:"),
                   relationshipNamespace.isEmpty()?"/":relationshipNamespace);
        }

        if (showComponent)
            addRow(tr("Component:"),
                   static_cast<CellMLSupport::CellmlFileComponentReference *>(item.element)->component());

        if (showFirstComponent)
            addRow(tr("First component:"),
                   static_cast<CellMLSupport::CellmlFileMapComponents *>(item.element)->firstComponent());

        if (showSecondComponent)
            addRow(tr("Second component:"),
                   static_cast<CellMLSupport::CellmlFileMapComponents *>(item.element)->secondComponent());

        if (showFirstVariable)
            addRow(tr("First variable:"),
                   static_cast<CellMLSupport::CellmlFileMapVariablesItem *>(item.element)->firstVariable());

        if (showSecondVariable)
            addRow(tr("Second variable:"),
                   static_cast<CellMLSupport::CellmlFileMapVariablesItem *>(item.element)->secondVariable());
    }

    // Allow ourselves to be updated again

    setUpdatesEnabled(true);

    // Scroll down to the bottom of ourselves, just in case things don't fit
    // within the viewport
    // Note: for this, we need to be up-to-date, hence we make a call to
    //       qApp->processEvents() and this can only be done when we are once
    //       again visible...

    qApp->processEvents();

    verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::updateGui()
{
    // Update the GUI using our existing items
    // Note: this can be as a result of, for example, a need to retranslate the
    //       GUI or a change in the metadata...

    updateGui(mItems);
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::addRow(const QString &pLabel,
                                                            const QString &pValue)
{
    // Add a row to our form layout

    mLayout->addRow(mParent->newLabel(mWidget, pLabel, true),
                    mParent->newLabel(mWidget, pValue));
}

//==============================================================================

QString CellmlAnnotationViewCellmlElementDetailsWidget::typeAsString(const Type &pType) const
{
    switch (pType) {
    case Import:
        return tr("Import");
    case ImportUnit:
        return tr("Imported unit");
    case ImportComponent:
        return tr("Imported component");
    case Unit:
        return tr("Unit");
    case UnitElement:
        return tr("Unit element");
    case Component:
        return tr("Component");
    case Variable:
        return tr("Variable");
    case Group:
        return tr("Group");
    case RelationshipReference:
        return tr("Relationshop reference");
    case ComponentReference:
        return tr("Component reference");
    case Connection:
        return tr("Connection");
    case ComponentMapping:
        return tr("Component mapping");
    case VariableMapping:
        return tr("Variable mapping");
    default:
        // Model

        return tr("Model");
    }
}

//==============================================================================

QComboBox * CellmlAnnotationViewCellmlElementDetailsWidget::cmetaIdValue() const
{
    // Return our cmeta:id value widget

    return mCmetaIdValue;
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::newCmetaId(const QString &pCmetaId)
{
    // Keep track of the new cmeta:id value

    mParent->listsWidget()->cellmlList()->currentCellmlElementItem()->element()->setCmetaId(pCmetaId);
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::editMetadata() const
{
    // Switch to the editing side of the metadata

    mParent->listsWidget()->metadataList()->setCurrentId(mCmetaIdValue->currentText());
}

//==============================================================================

}   // namespace CellMLAnnotationView
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Fixed a flickering issue on Mac OS X.<commit_after>//==============================================================================
// CellML annotation view CellML element details widget
//==============================================================================

#include "cellmlannotationviewcellmlelementdetailswidget.h"
#include "cellmlannotationviewcellmlelementitem.h"
#include "cellmlannotationviewcellmllistwidget.h"
#include "cellmlannotationviewlistswidget.h"
#include "cellmlannotationviewmetadatalistwidget.h"
#include "cellmlannotationviewwidget.h"
#include "treeview.h"

//==============================================================================

#include "ui_cellmlannotationviewcellmlelementdetailswidget.h"

//==============================================================================

#include <QComboBox>
#include <QFormLayout>
#include <QLabel>
#include <QPushButton>
#include <QScrollBar>

//==============================================================================

namespace OpenCOR {
namespace CellMLAnnotationView {

//==============================================================================

bool CellmlAnnotationViewCellmlElementDetailsWidget::Item::operator==(const Item &pItem) const
{
    // Return whether the given item is equal to the current one

    return    (type == pItem.type)
           && (element == pItem.element)
           && (number == pItem.number);
}

//==============================================================================

CellmlAnnotationViewCellmlElementDetailsWidget::CellmlAnnotationViewCellmlElementDetailsWidget(CellmlAnnotationViewWidget *pParent) :
    QScrollArea(pParent),
    CommonWidget(pParent),
    mParent(pParent),
    mGui(new Ui::CellmlAnnotationViewCellmlElementDetailsWidget),
    mItems(Items()),
    mCmetaIdValue(0)
{
    // Set up the GUI

    mGui->setupUi(this);

    // Create the widget (and its layout) which will contain our GUI

    mWidget = new QWidget(this);
    mLayout = new QFormLayout(mWidget);

    mWidget->setLayout(mLayout);

    // Add our widget to our scroll area

    setWidget(mWidget);
}

//==============================================================================

CellmlAnnotationViewCellmlElementDetailsWidget::~CellmlAnnotationViewCellmlElementDetailsWidget()
{
    // Delete the GUI

    delete mGui;
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::retranslateUi()
{
    // Retranslate our GUI

    mGui->retranslateUi(this);

    // For the rest of our GUI, it's easier to just update it, so...

    updateGui();
}

//==============================================================================

CellmlAnnotationViewCellmlElementDetailsWidget::Item CellmlAnnotationViewCellmlElementDetailsWidget::item(const Type &pType,
                                                                                CellMLSupport::CellmlFileElement *pElement,
                                                                                const int &pNumber)
{
    // Return a formatted Item 'object'

    Item res;

    res.type    = pType;
    res.element = pElement;
    res.number  = pNumber;

    return res;
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::updateGui(const Items &pItems)
{
    // Prevent ourselves from being updated (to avoid any flickering)

    setUpdatesEnabled(false);

    // Keep track of the items

    mItems = pItems;

    // Reset our cmeta:id widget

    if (mCmetaIdValue) {
        disconnect(mCmetaIdValue, SIGNAL(editTextChanged(const QString &)),
                   this, SLOT(newCmetaId(const QString &)));

        mCmetaIdValue = 0;
    }

    // Remove everything from our form layout

    for (int i = 0, iMax = mLayout->count(); i < iMax; ++i) {
        QLayoutItem *item = mLayout->takeAt(0);

        delete item->widget();
        delete item;
    }

    // Go through the different items which properties we want to add to the GUI

    for (int i = 0, iLast = pItems.count()-1; i <= iLast; ++i) {
        Item item = pItems[i];

        // Determine which widget should be shown/hidden

        bool showName = false;
        bool showXlinkHref = false;
        bool showUnitReference = false;
        bool showComponentReference = false;
        bool showUnit = false;
        bool showInitialValue = false;
        bool showPublicInterface = false;
        bool showPrivateInterface = false;
        bool showRelationship = false;
        bool showRelationshipNamespace = false;
        bool showComponent = false;
        bool showFirstComponent = false;
        bool showSecondComponent = false;
        bool showFirstVariable = false;
        bool showSecondVariable = false;

        switch (item.type) {
        case Model:
        case Unit:
        case UnitElement:
        case Component:
        case Group:
        case Connection:
            showName = true;

            break;
        case Import:
            showXlinkHref = true;

            break;
        case ImportUnit:
            showName = true;
            showUnitReference = true;

            break;
        case ImportComponent:
            showName = true;
            showComponentReference = true;

            break;
        case Variable:
            showName = true;
            showUnit = true;
            showInitialValue = true;
            showPublicInterface = true;
            showPrivateInterface = true;

            break;
        case RelationshipReference:
            showRelationship = true;
            showRelationshipNamespace = true;

            break;
        case ComponentReference:
            showComponent = true;

            break;
        case ComponentMapping:
            showFirstComponent = true;
            showSecondComponent = true;

            break;
        case VariableMapping:
            showFirstVariable = true;
            showSecondVariable = true;

            break;
        };

        // Add whatever we need
        // Note: as long as all of the widgets' parent is our widget, then they
        //       will get automatically deleted, so no need to delete them in
        //       ~CellmlAnnotationViewCellmlElementDetailsWidget()...

        // Add a bold centered label as a header to let the user know what type
        // of item we are talking about

        mLayout->addRow(mParent->newLabel(mWidget, typeAsString(item.type),
                                          true, 1.25, Qt::AlignCenter));

        // Show the item's cmeta:id, keeping in mind that we only want to allow
        // the editing of the cmeta:id of the very first item

        QString cmetaId = item.element->cmetaId();

        if (i == iLast) {
            // This is our 'main' item, so we want to allow the user to edit its
            // cmeta:id. For this, we use a QComboBox, but we also want to have
            // a QPushButton to allow the user to switch to the editing mode of
            // the metadata associated with the cmeta:id, so we create a meta
            // widget which contains both a QComboBox and a QPushButton

            QWidget *cmetaIdWidget = new QWidget(mWidget);

            QHBoxLayout *cmetaIdWidgetLayout = new QHBoxLayout(cmetaIdWidget);

            cmetaIdWidgetLayout->setMargin(0);

            cmetaIdWidget->setLayout(cmetaIdWidgetLayout);

            // Create our QComboBox widget

            mCmetaIdValue = new QComboBox(mWidget);

            mCmetaIdValue->addItems(mParent->listsWidget()->metadataList()->ids());

            mCmetaIdValue->setEditable(true);

            bool cmetaIdFound = false;

            for (int i = 0, iMax = mCmetaIdValue->count(); i < iMax; ++i)
                if (!cmetaId.compare(mCmetaIdValue->itemText(i))) {
                    // The cmeta:id could be found in our list of metadata ids,
                    // so set our cmeta:id index to it

                    mCmetaIdValue->setCurrentIndex(i);

                    cmetaIdFound = true;

                    break;
                }

            if (!cmetaIdFound)
                // The cmeta:id couldn't be found in our list of metadata ids,
                // so 'manually' set it

                mCmetaIdValue->setEditText(cmetaId);

            // Create our QPushButton

            QPushButton *editButton = new QPushButton(mWidget);
            // Note #1: ideally, we could assign a QAction to our QPushButton,
            //          but this cannot be done, so... we assign a few
            //          properties by hand...
            // Note #2: to use a QToolButton would allow us to assign a QAction
            //          to it, but a QToolButton doesn't look quite the same as
            //          a QPushButton on some platforms, so...

            editButton->setIcon(QIcon(":/oxygen/actions/format-list-unordered.png"));
            editButton->setStatusTip(tr("Edit the metadata"));
            editButton->setToolTip(tr("Edit"));
            editButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

            connect(editButton, SIGNAL(clicked()),
                    this, SLOT(editMetadata()));

            // Add our QComboBox and QPushButton to our cmeta:id widget

            cmetaIdWidgetLayout->addWidget(mCmetaIdValue);
            cmetaIdWidgetLayout->addWidget(editButton);

            // Add our cmeta:id widget to our main layout

            mLayout->addRow(mParent->newLabel(mWidget, tr("cmeta:id:"), true),
                            cmetaIdWidget);

            // Make our cmeta:id value the widget to tab to after our CellML
            // tree view

            setTabOrder(qobject_cast<QWidget *>(mParent->listsWidget()->cellmlList()->treeView()),
                        mCmetaIdValue);
            setTabOrder(mCmetaIdValue, editButton);
            setTabOrder(editButton,
                        qobject_cast<QWidget *>(mParent->listsWidget()->metadataList()->treeView()));

            // Create a connection to keep track of changes to our cmeta:id
            // value

            connect(mCmetaIdValue, SIGNAL(editTextChanged(const QString &)),
                    this, SLOT(newCmetaId(const QString &)));
        } else {
            // Not our 'main' item, so just display its cmeta:id

            addRow(tr("cmeta:id:"), cmetaId.isEmpty()?"/":cmetaId);
        }

        // Show the item's remaining properties

        if (showName) {
            // Retrieve the name of the CellML element
            // Note: in the case of a group or a connection, there won't be a
            //       name, so we use the item's name, hoping one was provided...

            QString name = ((item.type == Group) || (item.type == Connection))?
                               (item.number == -1)?
                                   "/":
                                   (item.type == Group)?
                                       tr("Group #%1").arg(item.number):
                                       tr("Connection #%1").arg(item.number):
                               static_cast<CellMLSupport::CellmlFileNamedElement *>(item.element)->name();

            addRow(tr("Name:"), name);
        }

        if (showXlinkHref)
            addRow(tr("xlink:href:"),
                   static_cast<CellMLSupport::CellmlFileImport *>(item.element)->xlinkHref());

        if (showUnitReference)
            addRow(tr("Unit reference:"),
                   static_cast<CellMLSupport::CellmlFileImportUnit *>(item.element)->unitReference());

        if (showComponentReference)
            addRow(tr("Component reference:"),
                   static_cast<CellMLSupport::CellmlFileImportComponent *>(item.element)->componentReference());

        if (showUnit)
            addRow(tr("Unit:"),
                   static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->unit());

        if (showInitialValue) {
            QString initialValue = static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->initialValue();

            addRow(tr("Initial value:"),
                   initialValue.isEmpty()?"/":initialValue);
        }

        if (showPublicInterface)
            addRow(tr("Public interface:"),
                   static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->publicInterfaceAsString());

        if (showPrivateInterface)
            addRow(tr("Private interface:"),
                   static_cast<CellMLSupport::CellmlFileVariable *>(item.element)->privateInterfaceAsString());

        if (showRelationship)
            addRow(tr("Relationship:"),
                   static_cast<CellMLSupport::CellmlFileRelationshipReference *>(item.element)->relationship());

        if (showRelationshipNamespace) {
            QString relationshipNamespace = static_cast<CellMLSupport::CellmlFileRelationshipReference *>(item.element)->relationshipNamespace();

            addRow(tr("Relationship namespace:"),
                   relationshipNamespace.isEmpty()?"/":relationshipNamespace);
        }

        if (showComponent)
            addRow(tr("Component:"),
                   static_cast<CellMLSupport::CellmlFileComponentReference *>(item.element)->component());

        if (showFirstComponent)
            addRow(tr("First component:"),
                   static_cast<CellMLSupport::CellmlFileMapComponents *>(item.element)->firstComponent());

        if (showSecondComponent)
            addRow(tr("Second component:"),
                   static_cast<CellMLSupport::CellmlFileMapComponents *>(item.element)->secondComponent());

        if (showFirstVariable)
            addRow(tr("First variable:"),
                   static_cast<CellMLSupport::CellmlFileMapVariablesItem *>(item.element)->firstVariable());

        if (showSecondVariable)
            addRow(tr("Second variable:"),
                   static_cast<CellMLSupport::CellmlFileMapVariablesItem *>(item.element)->secondVariable());
    }

    // Scroll down to the bottom of ourselves, just in case things don't fit
    // within the viewport

    qApp->processEvents();

    verticalScrollBar()->setValue(verticalScrollBar()->maximum());

    // Allow ourselves to be updated again

    setUpdatesEnabled(true);
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::updateGui()
{
    // Update the GUI using our existing items
    // Note: this can be as a result of, for example, a need to retranslate the
    //       GUI or a change in the metadata...

    updateGui(mItems);
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::addRow(const QString &pLabel,
                                                            const QString &pValue)
{
    // Add a row to our form layout

    mLayout->addRow(mParent->newLabel(mWidget, pLabel, true),
                    mParent->newLabel(mWidget, pValue));
}

//==============================================================================

QString CellmlAnnotationViewCellmlElementDetailsWidget::typeAsString(const Type &pType) const
{
    switch (pType) {
    case Import:
        return tr("Import");
    case ImportUnit:
        return tr("Imported unit");
    case ImportComponent:
        return tr("Imported component");
    case Unit:
        return tr("Unit");
    case UnitElement:
        return tr("Unit element");
    case Component:
        return tr("Component");
    case Variable:
        return tr("Variable");
    case Group:
        return tr("Group");
    case RelationshipReference:
        return tr("Relationshop reference");
    case ComponentReference:
        return tr("Component reference");
    case Connection:
        return tr("Connection");
    case ComponentMapping:
        return tr("Component mapping");
    case VariableMapping:
        return tr("Variable mapping");
    default:
        // Model

        return tr("Model");
    }
}

//==============================================================================

QComboBox * CellmlAnnotationViewCellmlElementDetailsWidget::cmetaIdValue() const
{
    // Return our cmeta:id value widget

    return mCmetaIdValue;
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::newCmetaId(const QString &pCmetaId)
{
    // Keep track of the new cmeta:id value

    mParent->listsWidget()->cellmlList()->currentCellmlElementItem()->element()->setCmetaId(pCmetaId);
}

//==============================================================================

void CellmlAnnotationViewCellmlElementDetailsWidget::editMetadata() const
{
    // Switch to the editing side of the metadata

    mParent->listsWidget()->metadataList()->setCurrentId(mCmetaIdValue->currentText());
}

//==============================================================================

}   // namespace CellMLAnnotationView
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


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

#include <string>

#include "gtest/gtest.h"

#include "modules/common/configs/config_gflags.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/integration_tests/planning_test_base.h"
#include "modules/planning/planning.h"

namespace apollo {
namespace planning {

using common::adapter::AdapterManager;

DECLARE_string(test_routing_response_file);
DECLARE_string(test_localization_file);
DECLARE_string(test_chassis_file);

/**
 * @class GarageTest
 * @brief This is an integration test that uses the garage map.
 */

class GarageTest : public PlanningTestBase {
 public:
  virtual void SetUp() {
    FLAGS_map_dir = "modules/planning/testdata/garage_map";
    FLAGS_base_map_filename = "base_map.txt";
    FLAGS_test_data_dir = "modules/planning/testdata/garage_test";
    FLAGS_planning_upper_speed_limit = 12.5;
    FLAGS_enable_lag_prediction = false;
  }
};

/*
 * test stop for not-nudgable obstacle
 */
TEST_F(GarageTest, stop_obstacle) {
  FLAGS_test_prediction_file = "stop_obstacle_prediction.pb.txt";
  FLAGS_test_localization_file = "stop_obstacle_localization.pb.txt";
  FLAGS_test_chassis_file = "stop_obstacle_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * test follow head_vehicle
 */
TEST_F(GarageTest, follow) {
  FLAGS_test_prediction_file = "follow_prediction.pb.txt";
  FLAGS_test_localization_file = "follow_localization.pb.txt";
  FLAGS_test_chassis_file = "follow_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * test stop for destination
 */
TEST_F(GarageTest, stop_dest) {
  FLAGS_test_prediction_file = "stop_dest_prediction.pb.txt";
  FLAGS_test_localization_file = "stop_dest_localization.pb.txt";
  FLAGS_test_chassis_file = "stop_dest_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * test stop for out of map
 * planning should fail in this case, but the module should not core.
 */
TEST_F(GarageTest, out_of_map) {
  FLAGS_test_prediction_file = "out_of_map_prediction.pb.txt";
  FLAGS_test_localization_file = "out_of_map_localization.pb.txt";
  FLAGS_test_chassis_file = "out_of_map_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * test stop passed stop line
 */
TEST_F(GarageTest, stop_over_line) {
  FLAGS_enable_stop_sign = false;

  std::string seq_num = "1";
  FLAGS_test_prediction_file = seq_num + "_prediction.pb.txt";
  FLAGS_test_localization_file = seq_num + "_localization.pb.txt";
  FLAGS_test_chassis_file = seq_num + "_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

}  // namespace planning
}  // namespace apollo

TMAIN;
<commit_msg>planning: enable stop sign<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include <string>

#include "gtest/gtest.h"

#include "modules/common/configs/config_gflags.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/integration_tests/planning_test_base.h"
#include "modules/planning/planning.h"

namespace apollo {
namespace planning {

using common::adapter::AdapterManager;

DECLARE_string(test_routing_response_file);
DECLARE_string(test_localization_file);
DECLARE_string(test_chassis_file);

/**
 * @class GarageTest
 * @brief This is an integration test that uses the garage map.
 */

class GarageTest : public PlanningTestBase {
 public:
  virtual void SetUp() {
    FLAGS_map_dir = "modules/planning/testdata/garage_map";
    FLAGS_base_map_filename = "base_map.txt";
    FLAGS_test_data_dir = "modules/planning/testdata/garage_test";
    FLAGS_planning_upper_speed_limit = 12.5;
    FLAGS_enable_lag_prediction = false;
    FLAGS_enable_stop_sign = false;
  }
};

/*
 * test stop for not-nudgable obstacle
 */
TEST_F(GarageTest, stop_obstacle) {
  FLAGS_test_prediction_file = "stop_obstacle_prediction.pb.txt";
  FLAGS_test_localization_file = "stop_obstacle_localization.pb.txt";
  FLAGS_test_chassis_file = "stop_obstacle_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * test follow head_vehicle
 */
TEST_F(GarageTest, follow) {
  FLAGS_test_prediction_file = "follow_prediction.pb.txt";
  FLAGS_test_localization_file = "follow_localization.pb.txt";
  FLAGS_test_chassis_file = "follow_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * test stop for destination
 */
TEST_F(GarageTest, stop_dest) {
  FLAGS_test_prediction_file = "stop_dest_prediction.pb.txt";
  FLAGS_test_localization_file = "stop_dest_localization.pb.txt";
  FLAGS_test_chassis_file = "stop_dest_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * test stop for out of map
 * planning should fail in this case, but the module should not core.
 */
TEST_F(GarageTest, out_of_map) {
  FLAGS_test_prediction_file = "out_of_map_prediction.pb.txt";
  FLAGS_test_localization_file = "out_of_map_localization.pb.txt";
  FLAGS_test_chassis_file = "out_of_map_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

/*
 * test stop passed stop line
 */
TEST_F(GarageTest, stop_over_line) {
  FLAGS_enable_stop_sign = false;

  std::string seq_num = "1";
  FLAGS_test_prediction_file = seq_num + "_prediction.pb.txt";
  FLAGS_test_localization_file = seq_num + "_localization.pb.txt";
  FLAGS_test_chassis_file = seq_num + "_chassis.pb.txt";
  PlanningTestBase::SetUp();
  RUN_GOLDEN_TEST;
}

}  // namespace planning
}  // namespace apollo

TMAIN;
<|endoftext|>


<commit_before>#include "stm32f4xx.h"

// All of these belong to port D.
const uint16_t orangeLedPin = 13;
const uint16_t greenLedPin = 12;
const uint16_t redLedPin = 14;
const uint16_t blueLedPin = 15;

void enableGPIOD();
void enableOutputPin(GPIO_TypeDef* gpio, uint16_t pin);
void setPin(GPIO_TypeDef* gpio, uint16_t pin, bool value);
void enableTIM2();
void enableTimerUpdateInterrupt(TIM_TypeDef* tim);
void setPrescaler(TIM_TypeDef* tim, uint16_t prescaler);
uint32_t millisecondsToMicroseconds(uint32_t ms);
void setPeriod(TIM_TypeDef* tim, uint32_t value);
void enableAutoReload(TIM_TypeDef* tim);
void enableCounter(TIM_TypeDef* tim);
void resetTimer(TIM_TypeDef* tim);
void enableIRQ(IRQn_Type irq);
void resetTimerInterrupt(TIM_TypeDef* tim);

void main() {
	enableGPIOD();

	enableOutputPin(GPIOD, orangeLedPin);
	enableOutputPin(GPIOD, greenLedPin);
	enableOutputPin(GPIOD, redLedPin);
	enableOutputPin(GPIOD, blueLedPin);
	setPin(GPIOD, blueLedPin, true);

	enableTIM2();
	enableIRQ(TIM2_IRQn);
	enableTimerUpdateInterrupt(TIM2);
	setPrescaler(TIM2, 16 - 1); // Set scale to microseconds, based on a 16 MHz clock
	setPeriod(TIM2, millisecondsToMicroseconds(1000) - 1);
	enableAutoReload(TIM2);
	enableCounter(TIM2);
	resetTimer(TIM2);
}

void enableGPIOD() {
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
}

void enableOutputPin(GPIO_TypeDef* gpio, uint16_t pin) {
	gpio->MODER |= 0b01 << (pin * 2);
}

void setPin(GPIO_TypeDef* gpio, uint16_t pin, bool value) {
	if (value) {
		gpio->BSRRL = 1 << pin;
	} else {
		gpio->BSRRH = 1 << pin;
	}
}

void enableTIM2() {
	RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
}

void enableTimerUpdateInterrupt(TIM_TypeDef* tim) {
	tim->DIER |= TIM_DIER_UIE;
}

// Note: according to section 18.4.11 of the reference manual, there's a +1 on the value in the prescaler.
// So, for example, setting the prescaler to 10 has the effect of dividing the clock by 11.
void setPrescaler(TIM_TypeDef* tim, uint16_t prescaler) {
	tim->PSC = prescaler;
}

uint32_t millisecondsToMicroseconds(uint32_t ms) {
	return ms * 1000;
}

void setPeriod(TIM_TypeDef* tim, uint32_t value) {
	tim->ARR = value;
}

void enableAutoReload(TIM_TypeDef* tim) {
	tim->CR1 |= TIM_CR1_ARPE;
}

void enableCounter(TIM_TypeDef* tim) {
	tim->CR1 |= TIM_CR1_CEN;
}

void resetTimer(TIM_TypeDef* tim) {
	tim->EGR |= TIM_EGR_UG;
}

void enableIRQ(IRQn_Type irq) {
	NVIC_EnableIRQ(irq);
}

void resetTimerInterrupt(TIM_TypeDef* tim) {
	tim->SR = 0;
}

extern "C" {
	void TIM2_IRQHandler() {
		if (TIM2->SR & TIM_SR_UIF) {
			GPIOD->ODR ^= 1 << orangeLedPin;
		}

		resetTimerInterrupt(TIM2);
	}
}<commit_msg>Cycle through LEDs.<commit_after>#include "stm32f4xx.h"

void enableGPIOD();
void enableOutputPin(GPIO_TypeDef* gpio, uint16_t pin);
void setPin(GPIO_TypeDef* gpio, uint16_t pin, bool value);
void enableTIM2();
void enableTimerUpdateInterrupt(TIM_TypeDef* tim);
void setPrescaler(TIM_TypeDef* tim, uint16_t prescaler);
uint32_t millisecondsToMicroseconds(uint32_t ms);
void setPeriod(TIM_TypeDef* tim, uint32_t value);
void enableAutoReload(TIM_TypeDef* tim);
void enableCounter(TIM_TypeDef* tim);
void resetTimer(TIM_TypeDef* tim);
void enableIRQ(IRQn_Type irq);
void resetTimerInterrupt(TIM_TypeDef* tim);
void onTIM2Tick();

// All of these belong to port D.
const uint16_t greenLedPin = 12;
const uint16_t orangeLedPin = 13;
const uint16_t redLedPin = 14;
const uint16_t blueLedPin = 15;
const uint16_t pinCount = 4;
const uint16_t pins[pinCount] = {greenLedPin, orangeLedPin, redLedPin, blueLedPin};

uint16_t lastPinOn = 0;

void main() {
	enableGPIOD();

	for (auto i = 0; i < pinCount; i++) {
		enableOutputPin(GPIOD, pins[i]);
	}

	enableTIM2();
	enableIRQ(TIM2_IRQn);
	enableTimerUpdateInterrupt(TIM2);
	setPrescaler(TIM2, 16 - 1); // Set scale to microseconds, based on a 16 MHz clock
	setPeriod(TIM2, millisecondsToMicroseconds(300) - 1);
	enableAutoReload(TIM2);
	enableCounter(TIM2);
	resetTimer(TIM2);
}

void enableGPIOD() {
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
}

void enableOutputPin(GPIO_TypeDef* gpio, uint16_t pin) {
	gpio->MODER |= 0b01 << (pin * 2);
}

void setPin(GPIO_TypeDef* gpio, uint16_t pin, bool value) {
	if (value) {
		gpio->BSRRL = 1 << pin;
	} else {
		gpio->BSRRH = 1 << pin;
	}
}

void enableTIM2() {
	RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
}

void enableTimerUpdateInterrupt(TIM_TypeDef* tim) {
	tim->DIER |= TIM_DIER_UIE;
}

// Note: according to section 18.4.11 of the reference manual, there's a +1 on the value in the prescaler.
// So, for example, setting the prescaler to 10 has the effect of dividing the clock by 11.
void setPrescaler(TIM_TypeDef* tim, uint16_t prescaler) {
	tim->PSC = prescaler;
}

uint32_t millisecondsToMicroseconds(uint32_t ms) {
	return ms * 1000;
}

void setPeriod(TIM_TypeDef* tim, uint32_t value) {
	tim->ARR = value;
}

void enableAutoReload(TIM_TypeDef* tim) {
	tim->CR1 |= TIM_CR1_ARPE;
}

void enableCounter(TIM_TypeDef* tim) {
	tim->CR1 |= TIM_CR1_CEN;
}

void resetTimer(TIM_TypeDef* tim) {
	tim->EGR |= TIM_EGR_UG;
}

void enableIRQ(IRQn_Type irq) {
	NVIC_EnableIRQ(irq);
}

void resetTimerInterrupt(TIM_TypeDef* tim) {
	tim->SR = 0;
}

void onTIM2Tick() {
	lastPinOn = (lastPinOn + 1) % pinCount;

	for (auto i = 0; i < pinCount; i++) {
		setPin(GPIOD, pins[i], i == lastPinOn);
	}
}

extern "C" {
	void TIM2_IRQHandler() {
		if (TIM2->SR & TIM_SR_UIF) {
			onTIM2Tick();
		}

		resetTimerInterrupt(TIM2);
	}
}<|endoftext|>


<commit_before>/****************** <VPR heading BEGIN do not edit this line> *****************
 *
 * VR Juggler Portable Runtime
 *
 * Original Authors:
 *   Allen Bierbaum, Patrick Hartling, Kevin Meinert, Carolina Cruz-Neira
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ****************** <VPR heading END do not edit this line> ******************/

/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vpr/vprConfig.h>

#include <stdlib.h>
#include <sstream>

#include <vpr/IO/IOException.h>
#include <vpr/Util/Assert.h>
#include <vpr/Util/Debug.h>
#include <vpr/md/NSPR/NSPRHelpers.h>
#include <vpr/md/NSPR/DynLoad/LibraryNSPR.h>

namespace vpr
{

LibraryNSPR::~LibraryNSPR() throw ()
{
   if ( NULL != mLibrary )
   {
      try
      {
         unload();
      }
      catch (vpr::IOException& ex)
      {
         vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
            << clrOutBOLD(clrYELLOW, "WARNING")
            << ": Failed to unload library during destruction" << std::endl
            << ex.what() << std::endl << vprDEBUG_FLUSH;
      }
   }
}
void LibraryNSPR::load()
{
   // Make sure a library object has not already been loaded.
   if ( NULL != mLibrary )
   {
      try
      {
         unload();
      }
      catch (vpr::IOException& ex)
      {
         std::ostringstream msg_stream;
         msg_stream << "Library unload failed during loading:\n"
                    << ex.getExtendedDescription();
         throw vpr::IOException(msg_stream.str(), VPR_LOCATION);
      }
   }

   mLibrary = PR_LoadLibrary(mName.c_str());

   if ( NULL == mLibrary )
   {
      std::ostringstream msg_stream;
      vpr::NSPR_PrintError("Failed to load library -- ", msg_stream);
      throw vpr::IOException(msg_stream.str(), VPR_LOCATION);
   }
}

void LibraryNSPR::unload()
{
   if ( NULL == mLibrary )
   {
      throw vpr::IOException("No library to unload", VPR_LOCATION);
   }

   if ( PR_UnloadLibrary(mLibrary) == PR_FAILURE )
   {
      std::ostringstream msg_stream;
      vpr::NSPR_PrintError("Failed to unload library -- ", msg_stream);
      throw vpr::IOException(msg_stream.str(), VPR_LOCATION);
   }
   else
   {
      mLibrary = NULL;
   }
}

} // End of vpr namespace
<commit_msg>Minor formatting nit.<commit_after>/****************** <VPR heading BEGIN do not edit this line> *****************
 *
 * VR Juggler Portable Runtime
 *
 * Original Authors:
 *   Allen Bierbaum, Patrick Hartling, Kevin Meinert, Carolina Cruz-Neira
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ****************** <VPR heading END do not edit this line> ******************/

/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vpr/vprConfig.h>

#include <stdlib.h>
#include <sstream>

#include <vpr/IO/IOException.h>
#include <vpr/Util/Assert.h>
#include <vpr/Util/Debug.h>
#include <vpr/md/NSPR/NSPRHelpers.h>
#include <vpr/md/NSPR/DynLoad/LibraryNSPR.h>

namespace vpr
{

LibraryNSPR::~LibraryNSPR() throw ()
{
   if ( NULL != mLibrary )
   {
      try
      {
         unload();
      }
      catch (vpr::IOException& ex)
      {
         vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
            << clrOutBOLD(clrYELLOW, "WARNING")
            << ": Failed to unload library during destruction" << std::endl
            << ex.what() << std::endl << vprDEBUG_FLUSH;
      }
   }
}

void LibraryNSPR::load()
{
   // Make sure a library object has not already been loaded.
   if ( NULL != mLibrary )
   {
      try
      {
         unload();
      }
      catch (vpr::IOException& ex)
      {
         std::ostringstream msg_stream;
         msg_stream << "Library unload failed during loading:\n"
                    << ex.getExtendedDescription();
         throw vpr::IOException(msg_stream.str(), VPR_LOCATION);
      }
   }

   mLibrary = PR_LoadLibrary(mName.c_str());

   if ( NULL == mLibrary )
   {
      std::ostringstream msg_stream;
      vpr::NSPR_PrintError("Failed to load library -- ", msg_stream);
      throw vpr::IOException(msg_stream.str(), VPR_LOCATION);
   }
}

void LibraryNSPR::unload()
{
   if ( NULL == mLibrary )
   {
      throw vpr::IOException("No library to unload", VPR_LOCATION);
   }

   if ( PR_UnloadLibrary(mLibrary) == PR_FAILURE )
   {
      std::ostringstream msg_stream;
      vpr::NSPR_PrintError("Failed to unload library -- ", msg_stream);
      throw vpr::IOException(msg_stream.str(), VPR_LOCATION);
   }
   else
   {
      mLibrary = NULL;
   }
}

} // End of vpr namespace
<|endoftext|>


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

/*!
* \file format_compressed.hpp
* \brief %FormatCompressed abstract class header file
*/

#ifndef VMF_FORMAT_COMPRESSED_H
#define VMF_FORMAT_COMPRESSED_H

#include "vmf/format.hpp"

namespace vmf
{
/*!
* class FormatCompressed
* \brief FormatCompressed abstract class is a %Format interface extension for %Compressor use
*/
class VMF_EXPORT FormatCompressed : public Format
{
public:
    /*!
    * \brief Default class constructor
    */
    FormatCompressed(std::shared_ptr<Format> format,
                     const std::string& compressorId,
                     bool _ignoreUnknownCompressor = false);

    /*!
    * \brief Class destructor
    */
    virtual ~FormatCompressed();

    /*!
    * \brief Sserialize input metadata and related stuff to XML string.
    */
    virtual std::string store(
        const MetadataSet& set,
        const std::vector<std::shared_ptr<MetadataSchema>>& schemas = {},
        const std::vector<std::shared_ptr<MetadataStream::VideoSegment>>& segments = {},
        //const std::vector<Stat>& stats = {},
		const AttribMap& attribs = AttribMap() // nextId, checksum, etc
        );

    /*!
    * \brief Deserialize input XML string to metadata and related stuff.
    */
    virtual ParseCounters parse(
        const std::string& text,
        std::vector<std::shared_ptr<MetadataInternal>>& metadata,
        std::vector<std::shared_ptr<MetadataSchema>>& schemas,
        std::vector<std::shared_ptr<MetadataStream::VideoSegment>>& segments,
        //std::vector<Stat>& stats,
        AttribMap& attribs // nextId, checksum, etc
        );

protected:
    /*!
    * \brief Performs compression of text data
    * \param input Input string
    * \return Compressed string
    */
    virtual std::string compress(const std::string& input);

    /*!
    * \brief Performs decompression of previously compressed data
    * \param input Input string
    * \return Decompressed string
    */
    virtual std::string decompress(const std::string& input);

    std::shared_ptr<Format> format;
    std::shared_ptr<vmf::MetadataSchema> cSchema;
    std::string compressorId;
    bool ignoreUnknownCompressor;
};

}//vmf

#endif //VMF_FORMAT_COMPRESSED_H
<commit_msg>FormatCompressed: doxy comments<commit_after>/*
* Copyright 2016 Intel(r) Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http ://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

/*!
* \file format_compressed.hpp
* \brief Serialization and deserialization based on instances of Compressor and Format classes
*/

#ifndef VMF_FORMAT_COMPRESSED_H
#define VMF_FORMAT_COMPRESSED_H

#include "vmf/format.hpp"

namespace vmf
{
/*!
* \class FormatCompressed
* \brief FormatCompressed class is a %Format interface extension for %Compressor use
*/
class VMF_EXPORT FormatCompressed : public Format
{
public:
    /*!
     * \brief Constructor taking compressor ID and format to be used at data reading/writing
     * \note This class can be used for reading w/o specifying the compressor ID
     * \note To use both compression and encryption
     * pass this class to FormatEncrypted constructor as the format argument
     * \param format Shared pointer to instance of Format class
     * \param compressorId ID of compression algorithm
     * \param _ignoreUnknownCompressor Flag specifying what to do with unknown compressor:
     * throw an exception (false) or pass compressed data as VMF metadata
     */
    FormatCompressed(std::shared_ptr<Format> format,
                     const std::string& compressorId,
                     bool _ignoreUnknownCompressor = false);

    /*!
    * \brief Class destructor
    */
    virtual ~FormatCompressed();

    /*!
     * \brief Serialize input metadata and related stuff to string
     */
    virtual std::string store(
        const MetadataSet& set,
        const std::vector<std::shared_ptr<MetadataSchema>>& schemas = {},
        const std::vector<std::shared_ptr<MetadataStream::VideoSegment>>& segments = {},
        //const std::vector<Stat>& stats = {},
		const AttribMap& attribs = AttribMap() // nextId, checksum, etc
        );

    /*!
     * \brief Deserialize input string to metadata and related stuff
     * \param text input string
     * \param metadata Metadata records
     * \param schemas Schemas of the metadata
     * \param segments Video segments
     * \param attribs Attributes like nextId, checksum, etc.
     * \return Numbers of items read by categories
     */
    virtual ParseCounters parse(
        const std::string& text,
        std::vector<std::shared_ptr<MetadataInternal>>& metadata,
        std::vector<std::shared_ptr<MetadataSchema>>& schemas,
        std::vector<std::shared_ptr<MetadataStream::VideoSegment>>& segments,
        //std::vector<Stat>& stats,
        AttribMap& attribs // nextId, checksum, etc
        );

protected:
    /*!
    * \brief Performs compression of text data
    * \param input Input string
    * \return Compressed string
    */
    virtual std::string compress(const std::string& input);

    /*!
    * \brief Performs decompression of previously compressed data
    * \param input Input string
    * \return Decompressed string
    */
    virtual std::string decompress(const std::string& input);

    std::shared_ptr<Format> format;
    std::shared_ptr<vmf::MetadataSchema> cSchema;
    std::string compressorId;
    bool ignoreUnknownCompressor;
};

}//vmf

#endif //VMF_FORMAT_COMPRESSED_H
<|endoftext|>


<commit_before>#include "GPU.H"

#include "CAMERA.H"
#include "LOAD_LEV.H"
#include "PROFILE.H"

#include <assert.h>
#include <LIBGPU.H>

unsigned long GnFrameCounter = 19;
unsigned long GnLastFrameCount = 19;
struct PSXTEXTSTRUCT* psxtextinfo;
struct PSXSPRITESTRUCT* psxspriteinfo;
int rgbscaleme = 256;
int gfx_debugging_mode;
struct DB_STRUCT db;
struct MMTEXTURE* RoomTextInfo;
unsigned long GadwOrderingTables_V2[512];
static int LnFlipFrame;
unsigned long GadwOrderingTables[5128];
unsigned long GadwPolygonBuffers[52260];

void GPU_UseOrderingTables(unsigned long* pBuffers, int nOTSize)//5DF68(<), 5F1C8(<)
{
	db.order_table[0] = &pBuffers[0];
	db.order_table[1] = &pBuffers[nOTSize];
	db.nOTSize = nOTSize;
	db.pickup_order_table[0] = (unsigned long*)&db.disp[1];
	db.pickup_order_table[1] = &GadwOrderingTables_V2[256];
#if 0
	//Should be safe to use 32-bit ptrs tho
	db.order_table[0] = (unsigned long*)((unsigned long) pBuffers & 0xFFFFFF);
	db.order_table[1] = (unsigned long*)((unsigned long) &pBuffers[nOTSize] & 0xFFFFFF);
	db.nOTSize = nOTSize;
	db.pickup_order_table[0] = (unsigned long*)((unsigned long)&db.disp[1] & 0xFFFFFF);
	db.pickup_order_table[1] = (unsigned long*)((unsigned long)&GadwOrderingTables_V2[256] & 0xFFFFFF);
#endif
	return;
}

void GPU_UsePolygonBuffers(unsigned long* pBuffers, int nPBSize)//5DFB0(<),
{
#if 1
	db.nPBSize = nPBSize;
	db.poly_buffer[0] = &pBuffers[0];
	db.poly_buffer[1] = &pBuffers[nPBSize];
#else
	db.nPBSize = nPBSize;
	db.poly_buffer[0] = (unsigned long*)((unsigned long)pBuffers & 0xFFFFFF);
	db.poly_buffer[1] = (unsigned long*)((unsigned long)&pBuffers[nPBSize] & 0xFFFFFF);
#endif
	return;
}

void GPU_SyncBothScreens()//5F374(<), 60054(<)
{
	DrawSync(0);

	db.current_buffer ^= 1;
	if (db.current_buffer != 0)
	{
		MoveImage(&db.disp[1].disp, db.disp[0].disp.x, db.disp[0].disp.y);
		//TODO: Verify ra += 0x10;! prolly else skip loc_5F3A8 (implemented but should be checked).
	}
	else
	{
		//loc_5F3A8
		MoveImage(&db.disp[0].disp, db.disp[1].disp.x, db.disp[1].disp.y);
	}

	DrawSync(0);

	return;
}

void GPU_BeginScene()//5F0F0(<), 5FDD0(<)
{
	db.ot = db.order_table[db.current_buffer];
	db.polyptr = (char*)db.poly_buffer[db.current_buffer];
	db.curpolybuf = (char*)db.poly_buffer[db.current_buffer];
	db.polybuf_limit = (char*)(db.poly_buffer[db.current_buffer]) + 26000;
	db.pickup_ot = db.pickup_order_table[db.current_buffer];
	ClearOTagR(db.order_table[db.current_buffer], db.nOTSize);

	return;
}

int GPU_FlipNoIdle()//5E078(<), 5F264(<)
{
#if DEBUG_VERSION
	if (ProfileDraw)
	{
		ProfileRGB(255, 255, 255);
		ProfileAddOT(&db.ot[0]);
	}//loc_5E0B0
#endif

	DrawSync(0);//TODO confirm retail is sub_6B144 draw sync

#if DEBUG_VERSION
	if (ProfileDraw)
	{
		ProfileAddDrawOT(&db.ot[0]);
	}//loc_5E0D8
#endif

	LnFlipFrame = GnLastFrameCount;

	if (GnLastFrameCount < 2)
	{
		//loc_5E0F4
		do
		{
			VSync(0);
			LnFlipFrame++;
		} while (LnFlipFrame < 2);
	}
	else
	{
		//loc_5E120
		VSync(0);
		LnFlipFrame++;
	}

	//loc_5E138
	//v0 = db.current_buffer;
	GnLastFrameCount = 0;
	PutDispEnv(&db.disp[db.current_buffer]);
	DrawOTagEnv(&db.ot[db.nOTSize - 1], &db.draw[db.current_buffer]);

#if DEBUG_VERSION
	ProfileStartCount();
#endif

	db.current_buffer ^= 1;

	return LnFlipFrame;
}

void GPU_FlipStory(unsigned long* gfx)//5E448(<), * (F)
{
	RECT r;
	RECT* fuckmyanalpassage;

	DrawSync(0);
	VSync(0);

	PutDispEnv(&db.disp[db.current_buffer]);
	fuckmyanalpassage = (RECT*)&db.disp[db.current_buffer ^ 1].disp;
	r.x = fuckmyanalpassage->x;
	r.y = fuckmyanalpassage->y;
	r.w = fuckmyanalpassage->w;
	r.h = fuckmyanalpassage->h;
	LoadImage(&r, gfx);

	DrawOTagEnv(&db.ot[db.nOTSize - 1], &db.draw[db.current_buffer]);
	db.current_buffer ^= 1;
}

void GPU_GetScreenPosition(short* x, short* y)//5F34C, ?
{
	*x = db.disp[0].screen.x;
	*y = db.disp[0].screen.y;
	return;
}

/*   PSX VRAM   (H)
 *  ----------- 1024px
 *  | TL | TR |  |
 *  -----------  v
 *  | BL | BR |
 *  -----------
 *(W)1024px-->
 *
 */
void GPU_ClearVRAM()//5F2D0(<), 5FFB0(<) (F)
{
	RECT r;

	DrawSync(0);
	VSync(0);

	//Clear TL
	r.x = 0;
	r.y = 0;
	r.w = 512;
	r.h = 256;
	clear_a_rect(&r);

	//Clear BL
	r.y = 256;
	clear_a_rect(&r);

	//Clear BR
	r.x = 512;
	clear_a_rect(&r);

	//Clear TR
	r.y = 0;
	clear_a_rect(&r);

	DrawSync(0);
	VSync(0);

	return;
}

void clear_a_rect(RECT* r)//5F334(<), 60014(<) (F)
{
	ClearImage(r, 0, 48, 0);

	return;
}

//@Gh0stblade - Not sure why this is so unoptimal, we can basically &disp[db.current_buffer]... double check code.
void GPU_FlipToBuffer(int buffer_index)//5F3C8(<), 600A8(<) (F)
{
	DrawSync(0);
	VSync(0);

	buffer_index &= 1;

	if (buffer_index)
	{
		PutDispEnv(&db.disp[1]);
		db.current_buffer = buffer_index ^ 1;
		PutDrawEnv(&db.draw[1]);
	}
	else
	{
		PutDispEnv(&db.disp[0]);
		db.current_buffer = buffer_index ^ 1;
		PutDrawEnv(&db.draw[0]);
	}

	return;
}

void GPU_EndScene()//5DFDC(<), 5F23C(!)
{
#if 0
	//int nPolys;
	//static int nWorstPolys;

	lui	$v0, 0x4EC4
	int a0 = &db.polyptr[0];
	int v1 = &db.curpolybuf[0];
	int v0 = 0x4EC4EC4F;
	a0 -= v1;
	v0 = a0 * v0;
	a0 >>= 31;
	v1 = psxtextinfo->u2v2pad;
	v0 >>= 4;
	v0 -= a0;

	if (v1 < v0)
	{
		u2v2pad = v0;
	}//loc_5E020

	//loc_5E020
#endif

	OptimiseOTagR(&db.ot[0], db.nOTSize);

#if 0
	nop

	ProfileRGB(255, 255, 255);

	a0 = db.nOTSize;
	do_gfx_debug_mode(&db.ot[db.nOTSize - 1]);

	ProfileRGB(0, 255, 255);
#endif
	return;
}

long OptimiseOTagR(unsigned long* ot, int nOTSize)//86CC4(<), 88D08(<)
{
	unsigned long* a1;
	unsigned long* a3;
	unsigned long v0;
	unsigned long* v1;
	long at = 0;

	if (nOTSize < 8)
	{
		return 0;
	}

	a1 = &ot[nOTSize - 1];
	v1 = &ot[1];
	v0 = a1[0];

	//loc_86CE4
	do
	{
		a1--;

		if ((unsigned long*)v0 == a1)
		{
			a3 = a1 - 1;
			if (a1 == ot)
			{
				return at;
			}

			//loc_86CF4
			do
			{
				v0 = a1[0];
				a1--;
				if (a1 == v1)
				{
					break;
				}

				at++;
			} while ((unsigned long*) v0 == a1);

			//loc_86D08
			a3[0] = v0;
		}
		v0 = a1[0];
	} while (a1 != ot);

	//loc_86D0C
	return at;
}

void draw_rotate_sprite(long a0, long a1, long a2)//5F134, 5FE14 (F)
{
	long t0;
	short* r_cossinptr;
	long t6;
	long t5;
	long t1;
	long t4;

	DelRotAng = (DelRotAng - 52) & 0xFFF;
	r_cossinptr = &rcossin_tbl[DelRotAng * 2];

	t6 = ((-a2 / 2) * r_cossinptr[0]) / 4096;
	t5 = ((-a2 / 2) * r_cossinptr[1]) / 4096;

	*(long*) &db.polyptr[4] = 0x2C808080;
	*(long*) &db.polyptr[12] = 0;
	*(long*) &db.polyptr[20] = 0x1303F00;

	t0 = t6 - t5;
	a2 = -t6;
	t4 = a2 - t5;
	a2 += t5;
	t1 = t6 + t5;

	*(short*) &db.polyptr[8] = t0 + (t0 / 2) + a0;
	*(short*) &db.polyptr[10] = t5 + t6 + a1;

	*(short*) &db.polyptr[16] = t4 + (t4 / 2) + a0;
	*(short*) &db.polyptr[18] = -t5 + t6 + a1;

	*(short*) &db.polyptr[24] = t1 + (t1 / 2) + a0;
	*(short*) &db.polyptr[26] = (t5 - t6) + a1;

	*(short*) &db.polyptr[28] = 0x3F;//width/height of loading cd?
	*(short*) &db.polyptr[36] = 0x3F3F;

	*(short*) &db.polyptr[32] = a2 + (a2 / 2) + a0;
	*(short*) &db.polyptr[34] = a1 + (-t5 - t6);

	*(long*) &db.polyptr[0] = db.ot[0] | 0x09000000;
	db.ot[0] = (unsigned long)&db.polyptr[0];

	db.polyptr += 0x28;//sizeof(POLY_F3); * 2?

	*(long*) &db.polyptr[4] = 0x2C808080;
	*(long*) &db.polyptr[8] = 0x780100;
	*(long*) &db.polyptr[12] = 0x6800;
	*(long*) &db.polyptr[16] = 0x7801FF;

	*(long*) &db.polyptr[20] = 0x13468FF;
	*(long*) &db.polyptr[24] = 0xEF0100;
	*(short*) &db.polyptr[28] = 0xDF00;
	*(long*) &db.polyptr[32] = 0xEF01FF;

	*(short*) &db.polyptr[36] = 0xDFFF;

	*(long*) &db.polyptr[0] = db.ot[0] | 0x9000000;
	db.ot[0] = (unsigned long)db.polyptr;

	sizeof(POLY_G3);
	db.polyptr += 0x28;
	return;
}

void GPU_SetScreenPosition(short x, short y)//5F360(<), 60040(<)
{
	db.disp[0].screen.x = x;
	db.disp[0].screen.y = y;
	db.disp[1].screen.x = x;
	db.disp[1].screen.y = y;

	return;
}<commit_msg>Revert.<commit_after>#include "GPU.H"

#include "CAMERA.H"
#include "LOAD_LEV.H"
#include "PROFILE.H"

#include <assert.h>
#include <LIBGPU.H>

unsigned long GnFrameCounter = 19;
unsigned long GnLastFrameCount = 19;
struct PSXTEXTSTRUCT* psxtextinfo;
struct PSXSPRITESTRUCT* psxspriteinfo;
int rgbscaleme = 256;
int gfx_debugging_mode;
struct DB_STRUCT db;
struct MMTEXTURE* RoomTextInfo;
unsigned long GadwOrderingTables_V2[512];
static int LnFlipFrame;
unsigned long GadwOrderingTables[5128];
unsigned long GadwPolygonBuffers[52260];

void GPU_UseOrderingTables(unsigned long* pBuffers, int nOTSize)//5DF68(<), 5F1C8(<)
{
	db.order_table[0] = &pBuffers[0];
	db.order_table[1] = &pBuffers[nOTSize];
	db.nOTSize = nOTSize;
	db.pickup_order_table[0] = (unsigned long*)&db.disp[1];
	db.pickup_order_table[1] = &GadwOrderingTables_V2[256];
#if 0
	//Should be safe to use 32-bit ptrs tho
	db.order_table[0] = (unsigned long*)((unsigned long) pBuffers & 0xFFFFFF);
	db.order_table[1] = (unsigned long*)((unsigned long) &pBuffers[nOTSize] & 0xFFFFFF);
	db.nOTSize = nOTSize;
	db.pickup_order_table[0] = (unsigned long*)((unsigned long)&db.disp[1] & 0xFFFFFF);
	db.pickup_order_table[1] = (unsigned long*)((unsigned long)&GadwOrderingTables_V2[256] & 0xFFFFFF);
#endif
	return;
}

void GPU_UsePolygonBuffers(unsigned long* pBuffers, int nPBSize)//5DFB0(<),
{
#if 1
	db.nPBSize = nPBSize;
	db.poly_buffer[0] = &pBuffers[0];
	db.poly_buffer[1] = &pBuffers[nPBSize];
#else
	db.nPBSize = nPBSize;
	db.poly_buffer[0] = (unsigned long*)((unsigned long)pBuffers & 0xFFFFFF);
	db.poly_buffer[1] = (unsigned long*)((unsigned long)&pBuffers[nPBSize] & 0xFFFFFF);
#endif
	return;
}

void GPU_SyncBothScreens()//5F374(<), 60054(<)
{
	DrawSync(0);

	db.current_buffer ^= 1;
	if (db.current_buffer != 0)
	{
		MoveImage(&db.disp[1].disp, db.disp[0].disp.x, db.disp[0].disp.y);
		//TODO: Verify ra += 0x10;! prolly else skip loc_5F3A8 (implemented but should be checked).
	}
	else
	{
		//loc_5F3A8
		MoveImage(&db.disp[0].disp, db.disp[1].disp.x, db.disp[1].disp.y);
	}

	DrawSync(0);

	return;
}

void GPU_BeginScene()//5F0F0(<), 5FDD0(<)
{
	db.ot = db.order_table[db.current_buffer];
	db.polyptr = (char*)db.poly_buffer[db.current_buffer];
	db.curpolybuf = (char*)db.poly_buffer[db.current_buffer];
	db.polybuf_limit = (char*)(db.poly_buffer[db.current_buffer]) + 26000;
	db.pickup_ot = db.pickup_order_table[db.current_buffer];
	ClearOTagR(db.order_table[db.current_buffer], db.nOTSize);

	return;
}

int GPU_FlipNoIdle()//5E078(<), 5F264(<)
{
#if DEBUG_VERSION
	if (ProfileDraw)
	{
		ProfileRGB(255, 255, 255);
		ProfileAddOT(&db.ot[0]);
	}//loc_5E0B0
#endif

	DrawSync(0);//TODO confirm retail is sub_6B144 draw sync

#if DEBUG_VERSION
	if (ProfileDraw)
	{
		ProfileAddDrawOT(&db.ot[0]);
	}//loc_5E0D8
#endif

	LnFlipFrame = GnLastFrameCount;

	if (GnLastFrameCount < 2)
	{
		//loc_5E0F4
		do
		{
			VSync(0);
			LnFlipFrame++;
		} while (LnFlipFrame < 2);
	}
	else
	{
		//loc_5E120
		VSync(0);
		LnFlipFrame++;
	}

	//loc_5E138
	//v0 = db.current_buffer;
	GnLastFrameCount = 0;
	PutDispEnv(&db.disp[db.current_buffer]);
	DrawOTagEnv(&db.ot[db.nOTSize - 1], &db.draw[db.current_buffer]);

#if DEBUG_VERSION
	ProfileStartCount();
#endif

	db.current_buffer ^= 1;

	return LnFlipFrame;
}

void GPU_FlipStory(unsigned long* gfx)//5E448(<), * (F)
{
	RECT r;
	RECT* fuckmyanalpassage;

	DrawSync(0);
	VSync(0);

	PutDispEnv(&db.disp[db.current_buffer]);
	fuckmyanalpassage = (RECT*)&db.disp[db.current_buffer ^ 1].disp;
	r.x = fuckmyanalpassage->x;
	r.y = fuckmyanalpassage->y;
	r.w = fuckmyanalpassage->w;
	r.h = fuckmyanalpassage->h;
	LoadImage(&r, gfx);

	DrawOTagEnv(&db.ot[db.nOTSize - 1], &db.draw[db.current_buffer]);
	db.current_buffer ^= 1;
}

void GPU_GetScreenPosition(short* x, short* y)//5F34C, ?
{
	*x = db.disp[0].screen.x;
	*y = db.disp[0].screen.y;
	return;
}

/*   PSX VRAM   (H)
 *  ----------- 1024px
 *  | TL | TR |  |
 *  -----------  v
 *  | BL | BR |
 *  -----------
 *(W)1024px-->
 *
 */
void GPU_ClearVRAM()//5F2D0(<), 5FFB0(<) (F)
{
	RECT r;

	DrawSync(0);
	VSync(0);

	//Clear TL
	r.x = 0;
	r.y = 0;
	r.w = 512;
	r.h = 256;
	clear_a_rect(&r);

	//Clear BL
	r.y = 256;
	clear_a_rect(&r);

	//Clear BR
	r.x = 512;
	clear_a_rect(&r);

	//Clear TR
	r.y = 0;
	clear_a_rect(&r);

	DrawSync(0);
	VSync(0);

	return;
}

void clear_a_rect(RECT* r)//5F334(<), 60014(<) (F)
{
	ClearImage(r, 0, 48, 0);

	return;
}

//@Gh0stblade - Not sure why this is so unoptimal, we can basically &disp[db.current_buffer]... double check code.
void GPU_FlipToBuffer(int buffer_index)//5F3C8(<), 600A8(<) (F)
{
	DrawSync(0);
	VSync(0);

	buffer_index &= 1;

	if (buffer_index)
	{
		PutDispEnv(&db.disp[1]);
		db.current_buffer = buffer_index ^ 1;
		PutDrawEnv(&db.draw[1]);
	}
	else
	{
		PutDispEnv(&db.disp[0]);
		db.current_buffer = buffer_index ^ 1;
		PutDrawEnv(&db.draw[0]);
	}

	return;
}

void GPU_EndScene()//5DFDC(<), 5F23C(<) (F)
{
#if DEBUG_VERSION
	int nPolys;
	static int nWorstPolys;

	nPolys = ((int) &db.polyptr[0] - (int) &db.curpolybuf[0]) * 0x4EC4EC4F / 16 - (((long) &db.polyptr[0] - (long) &db.curpolybuf[0]) >> 31);

	if (psxtextinfo->u2v2pad < nPolys)
	{
		psxtextinfo->u2v2pad = nPolys;
	}

	//loc_5E020
#endif

	OptimiseOTagR(&db.ot[0], db.nOTSize);

#if DEBUG_VERSION
	ProfileRGB(255, 255, 255);
	do_gfx_debug_mode(&db.ot[db.nOTSize - 1]);
	ProfileRGB(0, 255, 255);
#endif

	return;
}

long OptimiseOTagR(unsigned long* ot, int nOTSize)//86CC4(<), 88D08(<)
{
	unsigned long* a1;
	unsigned long* a3;
	unsigned long v0;
	unsigned long* v1;
	long at = 0;

	if (nOTSize < 8)
	{
		return 0;
	}

	a1 = &ot[nOTSize - 1];
	v1 = &ot[1];
	v0 = a1[0];

	//loc_86CE4
	do
	{
		a1--;

		if ((unsigned long*)v0 == a1)
		{
			a3 = a1 - 1;
			if (a1 == ot)
			{
				return at;
			}

			//loc_86CF4
			do
			{
				v0 = a1[0];
				a1--;
				if (a1 == v1)
				{
					break;
				}

				at++;
			} while ((unsigned long*) v0 == a1);

			//loc_86D08
			a3[0] = v0;
		}
		v0 = a1[0];
	} while (a1 != ot);

	//loc_86D0C
	return at;
}

void draw_rotate_sprite(long a0, long a1, long a2)//5F134, 5FE14 (F)
{
	long t0;
	short* r_cossinptr;
	long t6;
	long t5;
	long t1;
	long t4;

	DelRotAng = (DelRotAng - 52) & 0xFFF;
	r_cossinptr = &rcossin_tbl[DelRotAng * 2];

	t6 = ((-a2 / 2) * r_cossinptr[0]) / 4096;
	t5 = ((-a2 / 2) * r_cossinptr[1]) / 4096;

	*(long*) &db.polyptr[4] = 0x2C808080;
	*(long*) &db.polyptr[12] = 0;
	*(long*) &db.polyptr[20] = 0x1303F00;

	t0 = t6 - t5;
	a2 = -t6;
	t4 = a2 - t5;
	a2 += t5;
	t1 = t6 + t5;

	*(short*) &db.polyptr[8] = t0 + (t0 / 2) + a0;
	*(short*) &db.polyptr[10] = t5 + t6 + a1;

	*(short*) &db.polyptr[16] = t4 + (t4 / 2) + a0;
	*(short*) &db.polyptr[18] = -t5 + t6 + a1;

	*(short*) &db.polyptr[24] = t1 + (t1 / 2) + a0;
	*(short*) &db.polyptr[26] = (t5 - t6) + a1;

	*(short*) &db.polyptr[28] = 0x3F;//width/height of loading cd?
	*(short*) &db.polyptr[36] = 0x3F3F;

	*(short*) &db.polyptr[32] = a2 + (a2 / 2) + a0;
	*(short*) &db.polyptr[34] = a1 + (-t5 - t6);

	*(long*) &db.polyptr[0] = db.ot[0] | 0x09000000;
	db.ot[0] = (unsigned long)&db.polyptr[0];

	db.polyptr += 0x28;//sizeof(POLY_F3); * 2?

	*(long*) &db.polyptr[4] = 0x2C808080;
	*(long*) &db.polyptr[8] = 0x780100;
	*(long*) &db.polyptr[12] = 0x6800;
	*(long*) &db.polyptr[16] = 0x7801FF;

	*(long*) &db.polyptr[20] = 0x13468FF;
	*(long*) &db.polyptr[24] = 0xEF0100;
	*(short*) &db.polyptr[28] = 0xDF00;
	*(long*) &db.polyptr[32] = 0xEF01FF;

	*(short*) &db.polyptr[36] = 0xDFFF;

	*(long*) &db.polyptr[0] = db.ot[0] | 0x9000000;
	db.ot[0] = (unsigned long)db.polyptr;

	sizeof(POLY_G3);
	db.polyptr += 0x28;
	return;
}

void GPU_SetScreenPosition(short x, short y)//5F360(<), 60040(<)
{
	db.disp[0].screen.x = x;
	db.disp[0].screen.y = y;
	db.disp[1].screen.x = x;
	db.disp[1].screen.y = y;

	return;
}

<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
The MIT License

Copyright (c) 2008, 2009 Aristid Breitkreuz, Ash Berlin, Ruediger Sonderfeld

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 FLUSSPFERD_CONTEXT_HPP
#define FLUSSPFERD_CONTEXT_HPP

#include "object.hpp"
#include <boost/shared_ptr.hpp>
#include <string>

namespace flusspferd {

class value;
class object;
class native_object_base;

/**
 * Javascript %context.
 *
 * @ingroup contexts
 */
class context {
  class impl;
  boost::shared_ptr<impl> p;

  struct context_private;

public:
  /// Constructor for an empty, invalid context.
  context();

  /// Destructor.
  ~context();

#ifndef IN_DOXYGEN
  struct detail;
  friend struct detail;

  context(detail const&);
#endif

  /// Check if the context is valid.
  bool is_valid() const;

  /// Compare to another context for equality.
  bool operator==(context const &o) const {
    return p == o.p;
  }

  /// Create a new valid context.
  static context create();

  /// Get the global Javascript object of the context.
  object global();

  /// Get the Javascript scope chain object.
  object scope_chain();

  /**
   * Run the garbage collector.
   *
   * @see flusspferd::gc
   */
  void gc();

  /**
   * Tie the context to the current thread. Must be called
   * before the context is used in a thread.
   * Newly created contexts are tied to the creating thread.
   * User set_clear() before tieing the context to a new thread.
   */
  void set_thread();

  /**
   * Untie the context from the current thread. Must be called
   * before tieing the context to another thread with set_thread().
   */
  void clear_thread();

  /**
   * Add a prototype to the context's prototype registry.
   *
   * @param name The name and ID of the prototype.
   * @param proto The prototype.
   */
  void add_prototype(std::string const &name, object const &proto);

  /**
   * Get a prototype from the context's prototype registry.
   *
   * @param name The name and ID of the prototype.
   * @return The prototype.
   */
  object prototype(std::string const &name) const;

  /**
   * Add a prototype to the context's prototype registry.
   *
   * @param T     The class whose name (T::class_info::full_name())
   *              is to be used.
   * @param proto The prototype.
   */
  template<typename T>
  void add_prototype(object const &proto) {
    add_prototype(T::class_info::full_name(), proto);
  }

  /**
   * Get a prototype from the context's prototype registry.
   *
   * @param T     The class whose name (T::class_info::full_name())
   *              is to be used.
   * @return      The prototype.
   */
  template<typename T>
  object prototype() const {
    return prototype(T::class_info::full_name());
  }

  /**
   * Add a constructor to the context's constructor registry.
   *
   * @param name The name and ID of the constructor.
   * @param ctor The constructor.
   */
  void add_constructor(std::string const &name, object const &ctor);

  /**
   * Get a constructor to the context's constructor registry.
   *
   * @param name The name and ID of the constructor.
   * @return     The constructor.
   */
  object constructor(std::string const &name) const;

  /**
   * Add a constructor to the context's constructor registry.
   *
   * @param T     The class whose name (T::class_info::full_name())
   *              is to be used.
   * @param ctor  The constructor.
   */
  template<typename T>
  void add_constructor(object const &ctor) {
    add_constructor(T::class_info::full_name(), ctor);
  }

  /**
   * Get a constructor from the context's constructor registry.
   *
   * @param T     The class whose name (T::class_info::full_name())
   *              is to be used.
   * @return      The constructor.
   */
  template<typename T>
  object constructor() const {
    return constructor(T::class_info::full_name());
  }
};

template<>
inline object context::prototype<native_object_base>() const {
  return object();
}

/**
 * Compare two context%s for inequality.
 *
 * @relates context
 */
inline bool operator!=(context const &a, context const &b) {
  return !(a == b);
}

}

#endif /* FLUSSPFERD_CONTEXT_HPP */
<commit_msg>fixed error in documentation<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
The MIT License

Copyright (c) 2008, 2009 Aristid Breitkreuz, Ash Berlin, Ruediger Sonderfeld

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 FLUSSPFERD_CONTEXT_HPP
#define FLUSSPFERD_CONTEXT_HPP

#include "object.hpp"
#include <boost/shared_ptr.hpp>
#include <string>

namespace flusspferd {

class value;
class object;
class native_object_base;

/**
 * Javascript %context.
 *
 * @ingroup contexts
 */
class context {
  class impl;
  boost::shared_ptr<impl> p;

  struct context_private;

public:
  /// Constructor for an empty, invalid context.
  context();

  /// Destructor.
  ~context();

#ifndef IN_DOXYGEN
  struct detail;
  friend struct detail;

  context(detail const&);
#endif

  /// Check if the context is valid.
  bool is_valid() const;

  /// Compare to another context for equality.
  bool operator==(context const &o) const {
    return p == o.p;
  }

  /// Create a new valid context.
  static context create();

  /// Get the global Javascript object of the context.
  object global();

  /// Get the Javascript scope chain object.
  object scope_chain();

  /**
   * Run the garbage collector.
   *
   * @see flusspferd::gc
   */
  void gc();

  /**
   * Tie the context to the current thread. Must be called
   * before the context is used in a thread.
   * Newly created contexts are tied to the creating thread.
   * Use clear_thread() before tieing the context to a new thread.
   */
  void set_thread();

  /**
   * Untie the context from the current thread. Must be called
   * before tieing the context to another thread with set_thread().
   */
  void clear_thread();

  /**
   * Add a prototype to the context's prototype registry.
   *
   * @param name The name and ID of the prototype.
   * @param proto The prototype.
   */
  void add_prototype(std::string const &name, object const &proto);

  /**
   * Get a prototype from the context's prototype registry.
   *
   * @param name The name and ID of the prototype.
   * @return The prototype.
   */
  object prototype(std::string const &name) const;

  /**
   * Add a prototype to the context's prototype registry.
   *
   * @param T     The class whose name (T::class_info::full_name())
   *              is to be used.
   * @param proto The prototype.
   */
  template<typename T>
  void add_prototype(object const &proto) {
    add_prototype(T::class_info::full_name(), proto);
  }

  /**
   * Get a prototype from the context's prototype registry.
   *
   * @param T     The class whose name (T::class_info::full_name())
   *              is to be used.
   * @return      The prototype.
   */
  template<typename T>
  object prototype() const {
    return prototype(T::class_info::full_name());
  }

  /**
   * Add a constructor to the context's constructor registry.
   *
   * @param name The name and ID of the constructor.
   * @param ctor The constructor.
   */
  void add_constructor(std::string const &name, object const &ctor);

  /**
   * Get a constructor to the context's constructor registry.
   *
   * @param name The name and ID of the constructor.
   * @return     The constructor.
   */
  object constructor(std::string const &name) const;

  /**
   * Add a constructor to the context's constructor registry.
   *
   * @param T     The class whose name (T::class_info::full_name())
   *              is to be used.
   * @param ctor  The constructor.
   */
  template<typename T>
  void add_constructor(object const &ctor) {
    add_constructor(T::class_info::full_name(), ctor);
  }

  /**
   * Get a constructor from the context's constructor registry.
   *
   * @param T     The class whose name (T::class_info::full_name())
   *              is to be used.
   * @return      The constructor.
   */
  template<typename T>
  object constructor() const {
    return constructor(T::class_info::full_name());
  }
};

template<>
inline object context::prototype<native_object_base>() const {
  return object();
}

/**
 * Compare two context%s for inequality.
 *
 * @relates context
 */
inline bool operator!=(context const &a, context const &b) {
  return !(a == b);
}

}

#endif /* FLUSSPFERD_CONTEXT_HPP */
<|endoftext|>