<commit_before>#pragma once

#include <sys/sdt.h>

// Systemtap is not available on OS X. The alternative would be dtrace. Actually, systemtap probes are compatible
// with dtrace probes and the other way round. However, Apple's dtrace implementation differs from the original solaris
// implementation. Thus, Apple's dtrace does not understand the USDT probe definition. In order to be able to compile
// the project on Mac we define the probes in this file.

// In order to be compatible with Mac dtrace probes, both provider and probe name have to be uppercase
constexpr bool is_valid_name(const char* name) {
  do {
    if (*name >= 'a' && *name <= 'z') return false;
    if (*name == '-') return false;
  } while (*++name != '\0');
  return true;
}

#if defined(__APPLE__) || defined(__MACOS__)

#include "provider.hpp"

// Construct the probe definition by provider and probe name
#define BUILD_PROBE_NAME(provider, probe, ...)                                                                     \
  static_assert(is_valid_name(#provider) && is_valid_name(#probe), "Provider and probe name must be upper case!"); \
  provider##_##probe(__VA_ARGS__);

#define DTRACE_PROBE(provider, probe) BUILD_PROBE_NAME(provider, probe);
#define DTRACE_PROBE1(provider, probe, param1) BUILD_PROBE_NAME(provider, probe, param1);
#define DTRACE_PROBE2(provider, probe, param1, param2) BUILD_PROBE_NAME(provider, probe, param1, param2);
#define DTRACE_PROBE3(provider, probe, param1, param2, param3) BUILD_PROBE_NAME(provider, probe, param1, param2, param3)
#define DTRACE_PROBE4(provider, probe, param1, param2, param3, param4) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4);
#define DTRACE_PROBE5(provider, probe, param1, param2, param3, param4, param5) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5);
#define DTRACE_PROBE6(provider, probe, param1, param2, param3, param4, param5, param6) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6);
#define DTRACE_PROBE7(provider, probe, param1, param2, param3, param4, param5, param6, param7) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7);
#define DTRACE_PROBE8(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8);
#define DTRACE_PROBE9(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9);
#define DTRACE_PROBE10(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9, \
                       param10)                                                                                \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10);
#define DTRACE_PROBE11(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9,      \
                       param10, param11)                                                                             \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, \
                   param11);
#define DTRACE_PROBE12(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9,      \
                       param10, param11, param12)                                                                    \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, \
                   param11, param12);
#endif
<commit_msg>Disable USDT in TSan builds (#1175)<commit_after>#pragma once

#include <sys/sdt.h>

// Systemtap is not available on OS X. The alternative would be dtrace. Actually, systemtap probes are compatible
// with dtrace probes and the other way round. However, Apple's dtrace implementation differs from the original solaris
// implementation. Thus, Apple's dtrace does not understand the USDT probe definition. In order to be able to compile
// the project on Mac we define the probes in this file.

// In order to be compatible with Mac dtrace probes, both provider and probe name have to be uppercase
constexpr bool is_valid_name(const char* name) {
  do {
    if (*name >= 'a' && *name <= 'z') return false;
    if (*name == '-') return false;
  } while (*++name != '\0');
  return true;
}

#if defined(__APPLE__) || defined(__MACOS__)

#include "provider.hpp"

// Construct the probe definition by provider and probe name. Because TSan has issues and throw false positives, we
// don't use probes in TSan builds
#ifndef __SANITIZE_THREAD__
#define BUILD_PROBE_NAME(provider, probe, ...)                                                                     \
  static_assert(is_valid_name(#provider) && is_valid_name(#probe), "Provider and probe name must be upper case!"); \
  provider##_##probe(__VA_ARGS__);
#else
#define BUILD_PROBE_NAME(provider, probe, ...)
#endif

#define DTRACE_PROBE(provider, probe) BUILD_PROBE_NAME(provider, probe);
#define DTRACE_PROBE1(provider, probe, param1) BUILD_PROBE_NAME(provider, probe, param1);
#define DTRACE_PROBE2(provider, probe, param1, param2) BUILD_PROBE_NAME(provider, probe, param1, param2);
#define DTRACE_PROBE3(provider, probe, param1, param2, param3) BUILD_PROBE_NAME(provider, probe, param1, param2, param3)
#define DTRACE_PROBE4(provider, probe, param1, param2, param3, param4) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4);
#define DTRACE_PROBE5(provider, probe, param1, param2, param3, param4, param5) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5);
#define DTRACE_PROBE6(provider, probe, param1, param2, param3, param4, param5, param6) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6);
#define DTRACE_PROBE7(provider, probe, param1, param2, param3, param4, param5, param6, param7) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7);
#define DTRACE_PROBE8(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8);
#define DTRACE_PROBE9(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9) \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9);
#define DTRACE_PROBE10(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9, \
                       param10)                                                                                \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10);
#define DTRACE_PROBE11(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9,      \
                       param10, param11)                                                                             \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, \
                   param11);
#define DTRACE_PROBE12(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9,      \
                       param10, param11, param12)                                                                    \
  BUILD_PROBE_NAME(provider, probe, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, \
                   param11, param12);
#endif
<|endoftext|>


<commit_before>#include "filelogger.h"
#include <QTime>
#include <storage/storagepaths.h>

LOGGER(FileLogger);

FileLogger::FileLogger()
: dir(StoragePaths().logDirectory())
, out(&outFile)
{
    if (!dir.exists())
    {
        if (!QDir::root().mkpath(dir.absolutePath()))
        {
            LOG_ERROR(QString("Unable to create path %1").arg(dir.absolutePath()));
            return;
        }
        else
        {
            LOG_INFO("Log directory created");
        }
    }

    outFile.setFileName(dir.absoluteFilePath(("glimpse.log")));

    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
    {
        return;
    }
}

FileLogger::~FileLogger()
{
    Logger::removeAppender(this);
    outFile.close();
}

void FileLogger::log(Logger::Level level, const QString &name, const QString &funcName, const QString &message)
{
    Q_UNUSED(name);

    QString levelName;

    switch (level)
    {
    case Logger::Trace:
        levelName = "TRACE";
        break;

    case Logger::Debug:
        levelName = "DEBUG";
        break;

    case Logger::Info:
        levelName = "INFO";
        break;

    case Logger::Warning:
        levelName = "WARNING";
        break;

    case Logger::Error:
        levelName = "ERROR";
        break;
    }

    out << QTime::currentTime().toString() << " " << levelName << " " << funcName << " : " << message << endl;
}
<commit_msg>Added date in filelogger<commit_after>#include "filelogger.h"
#include <QDateTime>
#include <storage/storagepaths.h>

LOGGER(FileLogger);

FileLogger::FileLogger()
: dir(StoragePaths().logDirectory())
, out(&outFile)
{
    if (!dir.exists())
    {
        if (!QDir::root().mkpath(dir.absolutePath()))
        {
            LOG_ERROR(QString("Unable to create path %1").arg(dir.absolutePath()));
            return;
        }
        else
        {
            LOG_INFO("Log directory created");
        }
    }

    outFile.setFileName(dir.absoluteFilePath(("glimpse.log")));

    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
    {
        return;
    }
}

FileLogger::~FileLogger()
{
    Logger::removeAppender(this);
    outFile.close();
}

void FileLogger::log(Logger::Level level, const QString &name, const QString &funcName, const QString &message)
{
    Q_UNUSED(name);

    QString levelName;

    switch (level)
    {
    case Logger::Trace:
        levelName = "TRACE";
        break;

    case Logger::Debug:
        levelName = "DEBUG";
        break;

    case Logger::Info:
        levelName = "INFO";
        break;

    case Logger::Warning:
        levelName = "WARNING";
        break;

    case Logger::Error:
        levelName = "ERROR";
        break;
    }

    out << QDateTime::currentDateTime().toString() << " " << levelName << " " << funcName << " : " << message << endl;
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "fancylineedit.h"

#include <QEvent>
#include <QDebug>
#include <QString>
#include <QPropertyAnimation>
#include <QApplication>
#include <QMenu>
#include <QMouseEvent>
#include <QLabel>
#include <QAbstractButton>
#include <QPainter>
#include <QStyle>
#include <QPaintEvent>

/*!
    \class Utils::FancyLineEdit

    \brief A line edit with an embedded pixmap on one side that is connected to
    a menu.

    Additionally, it can display a grayed hintText (like "Type Here to")
    when not focused and empty. When connecting to the changed signals and
    querying text, one has to be aware that the text is set to that hint
    text if isShowingHintText() returns true (that is, does not contain
    valid user input).
 */

enum { margin = 6 };

#define ICONBUTTON_HEIGHT 18
#define FADE_TIME 160

namespace Utils {

// --------- FancyLineEditPrivate
class FancyLineEditPrivate : public QObject {
public:
    explicit FancyLineEditPrivate(FancyLineEdit *parent);

    virtual bool eventFilter(QObject *obj, QEvent *event);

    FancyLineEdit  *m_lineEdit;
    QPixmap m_pixmap[2];
    QMenu *m_menu[2];
    bool m_menuTabFocusTrigger[2];
    IconButton *m_iconbutton[2];
    bool m_iconEnabled[2];
};

FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
    QObject(parent),
    m_lineEdit(parent)
{
    for (int i = 0; i < 2; ++i) {
        m_menu[i] = 0;
        m_menuTabFocusTrigger[i] = false;
        m_iconbutton[i] = new IconButton(parent);
        m_iconbutton[i]->installEventFilter(this);
        m_iconbutton[i]->hide();
        m_iconbutton[i]->setAutoHide(false);
        m_iconEnabled[i] = false;
    }
}

bool FancyLineEditPrivate::eventFilter(QObject *obj, QEvent *event)
{
    int buttonIndex = -1;
    for (int i = 0; i < 2; ++i) {
        if (obj == m_iconbutton[i]) {
            buttonIndex = i;
            break;
        }
    }
    if (buttonIndex == -1)
        return QObject::eventFilter(obj, event);
    switch (event->type()) {
    case QEvent::FocusIn:
        if (m_menuTabFocusTrigger[buttonIndex] && m_menu[buttonIndex]) {
            m_lineEdit->setFocus();
            m_menu[buttonIndex]->exec(m_iconbutton[buttonIndex]->mapToGlobal(
                    m_iconbutton[buttonIndex]->rect().center()));
            return true;
        }
    default:
        break;
    }
    return QObject::eventFilter(obj, event);
}

// --------- FancyLineEdit
FancyLineEdit::FancyLineEdit(QWidget *parent) :
    QLineEdit(parent),
    d(new FancyLineEditPrivate(this))
{
    ensurePolished();
    updateMargins();

    connect(this, SIGNAL(textChanged(QString)), this, SLOT(checkButtons(QString)));
    connect(d->m_iconbutton[Left], SIGNAL(clicked()), this, SLOT(iconClicked()));
    connect(d->m_iconbutton[Right], SIGNAL(clicked()), this, SLOT(iconClicked()));
}

void FancyLineEdit::checkButtons(const QString &text)
{
    if (m_oldText.isEmpty() || text.isEmpty()) {
        for (int i = 0; i < 2; ++i) {
            if (d->m_iconbutton[i]->hasAutoHide())
                d->m_iconbutton[i]->animateShow(!text.isEmpty());
        }
        m_oldText = text;
    }
}

FancyLineEdit::~FancyLineEdit()
{
}

void FancyLineEdit::setButtonVisible(Side side, bool visible)
{
    d->m_iconbutton[side]->setVisible(visible);
    d->m_iconEnabled[side] = visible;
    updateMargins();
}

bool FancyLineEdit::isButtonVisible(Side side) const
{
    return d->m_iconEnabled[side];
}

void FancyLineEdit::iconClicked()
{
    IconButton *button = qobject_cast<IconButton *>(sender());
    int index = -1;
    for (int i = 0; i < 2; ++i)
        if (d->m_iconbutton[i] == button)
            index = i;
    if (index == -1)
        return;
    if (d->m_menu[index]) {
        d->m_menu[index]->exec(QCursor::pos());
    } else {
        emit buttonClicked((Side)index);
        if (index == Left)
            emit leftButtonClicked();
        else if (index == Right)
            emit rightButtonClicked();
    }
}

void FancyLineEdit::updateMargins()
{
    bool leftToRight = (layoutDirection() == Qt::LeftToRight);
    Side realLeft = (leftToRight ? Left : Right);
    Side realRight = (leftToRight ? Right : Left);

    int leftMargin = d->m_iconbutton[realLeft]->pixmap().width() + 8;
    int rightMargin = d->m_iconbutton[realRight]->pixmap().width() + 8;
    // Note KDE does not reserve space for the highlight color
    if (style()->inherits("OxygenStyle")) {
        leftMargin = qMax(24, leftMargin);
        rightMargin = qMax(24, rightMargin);
    }

    QMargins margins((d->m_iconEnabled[realLeft] ? leftMargin : 0), 0,
                     (d->m_iconEnabled[realRight] ? rightMargin : 0), 0);

    setTextMargins(margins);
}

void FancyLineEdit::updateButtonPositions()
{
    QRect contentRect = rect();
    for (int i = 0; i < 2; ++i) {
        Side iconpos = (Side)i;
        if (layoutDirection() == Qt::RightToLeft)
            iconpos = (iconpos == Left ? Right : Left);

        if (iconpos == FancyLineEdit::Right) {
            const int iconoffset = textMargins().right() + 4;
            d->m_iconbutton[i]->setGeometry(contentRect.adjusted(width() - iconoffset, 0, 0, 0));
        } else {
            const int iconoffset = textMargins().left() + 4;
            d->m_iconbutton[i]->setGeometry(contentRect.adjusted(0, 0, -width() + iconoffset, 0));
        }
    }
}

void FancyLineEdit::resizeEvent(QResizeEvent *)
{
    updateButtonPositions();
}

void FancyLineEdit::setButtonPixmap(Side side, const QPixmap &buttonPixmap)
{
    d->m_iconbutton[side]->setPixmap(buttonPixmap);
    updateMargins();
    updateButtonPositions();
    update();
}

QPixmap FancyLineEdit::buttonPixmap(Side side) const
{
    return d->m_pixmap[side];
}

void FancyLineEdit::setButtonMenu(Side side, QMenu *buttonMenu)
{
     d->m_menu[side] = buttonMenu;
     d->m_iconbutton[side]->setIconOpacity(1.0);
 }

QMenu *FancyLineEdit::buttonMenu(Side side) const
{
    return  d->m_menu[side];
}

bool FancyLineEdit::hasMenuTabFocusTrigger(Side side) const
{
    return d->m_menuTabFocusTrigger[side];
}

void FancyLineEdit::setMenuTabFocusTrigger(Side side, bool v)
{
    if (d->m_menuTabFocusTrigger[side] == v)
        return;

    d->m_menuTabFocusTrigger[side] = v;
    d->m_iconbutton[side]->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus);
}

bool FancyLineEdit::hasAutoHideButton(Side side) const
{
    return d->m_iconbutton[side]->hasAutoHide();
}

void FancyLineEdit::setAutoHideButton(Side side, bool h)
{
    d->m_iconbutton[side]->setAutoHide(h);
    if (h)
        d->m_iconbutton[side]->setIconOpacity(text().isEmpty() ?  0.0 : 1.0);
    else
        d->m_iconbutton[side]->setIconOpacity(1.0);
}

void FancyLineEdit::setButtonToolTip(Side side, const QString &tip)
{
    d->m_iconbutton[side]->setToolTip(tip);
}

void FancyLineEdit::setButtonFocusPolicy(Side side, Qt::FocusPolicy policy)
{
    d->m_iconbutton[side]->setFocusPolicy(policy);
}

// IconButton - helper class to represent a clickable icon

IconButton::IconButton(QWidget *parent)
    : QAbstractButton(parent), m_autoHide(false)
{
    setCursor(Qt::ArrowCursor);
    setFocusPolicy(Qt::NoFocus);
}

void IconButton::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
    pixmapRect.moveCenter(rect().center());

    if (m_autoHide)
        painter.setOpacity(m_iconOpacity);

    painter.drawPixmap(pixmapRect, m_pixmap);
}

void IconButton::animateShow(bool visible)
{
    if (visible) {
        QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
        animation->setDuration(FADE_TIME);
        animation->setEndValue(1.0);
        animation->start(QAbstractAnimation::DeleteWhenStopped);
    } else {
        QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
        animation->setDuration(FADE_TIME);
        animation->setEndValue(0.0);
        animation->start(QAbstractAnimation::DeleteWhenStopped);
    }
}

} // namespace Utils
<commit_msg>Cleanup popup menu position.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "fancylineedit.h"

#include <QEvent>
#include <QDebug>
#include <QString>
#include <QPropertyAnimation>
#include <QApplication>
#include <QMenu>
#include <QMouseEvent>
#include <QLabel>
#include <QAbstractButton>
#include <QPainter>
#include <QStyle>
#include <QPaintEvent>
#include <QDesktopWidget>

/*! Opens a menu at the specified widget position.
 * This functions computes the position where to show the menu, and opens it with
 * QMenu::exec().
 * \param menu The menu to open
 * \param widget The widget next to which to open the menu
 */
static void execMenuAtWidget(QMenu *menu, QWidget *widget)
{
    QPoint p;
    QRect screen = qApp->desktop()->availableGeometry(widget);
    QSize sh = menu->sizeHint();
    QRect rect = widget->rect();
    if (widget->isRightToLeft()) {
        if (widget->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height()) {
            p = widget->mapToGlobal(rect.bottomRight());
        } else {
            p = widget->mapToGlobal(rect.topRight() - QPoint(0, sh.height()));
        }
        p.rx() -= sh.width();
    } else {
        if (widget->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height()) {
            p = widget->mapToGlobal(rect.bottomLeft());
        } else {
            p = widget->mapToGlobal(rect.topLeft() - QPoint(0, sh.height()));
        }
    }
    p.rx() = qMax(screen.left(), qMin(p.x(), screen.right() - sh.width()));
    p.ry() += 1;

    menu->exec(p);
}

/*!
    \class Utils::FancyLineEdit

    \brief A line edit with an embedded pixmap on one side that is connected to
    a menu.

    Additionally, it can display a grayed hintText (like "Type Here to")
    when not focused and empty. When connecting to the changed signals and
    querying text, one has to be aware that the text is set to that hint
    text if isShowingHintText() returns true (that is, does not contain
    valid user input).
 */

enum { margin = 6 };

#define ICONBUTTON_HEIGHT 18
#define FADE_TIME 160

namespace Utils {

// --------- FancyLineEditPrivate
class FancyLineEditPrivate : public QObject {
public:
    explicit FancyLineEditPrivate(FancyLineEdit *parent);

    virtual bool eventFilter(QObject *obj, QEvent *event);

    FancyLineEdit  *m_lineEdit;
    QPixmap m_pixmap[2];
    QMenu *m_menu[2];
    bool m_menuTabFocusTrigger[2];
    IconButton *m_iconbutton[2];
    bool m_iconEnabled[2];
};

FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
    QObject(parent),
    m_lineEdit(parent)
{
    for (int i = 0; i < 2; ++i) {
        m_menu[i] = 0;
        m_menuTabFocusTrigger[i] = false;
        m_iconbutton[i] = new IconButton(parent);
        m_iconbutton[i]->installEventFilter(this);
        m_iconbutton[i]->hide();
        m_iconbutton[i]->setAutoHide(false);
        m_iconEnabled[i] = false;
    }
}

bool FancyLineEditPrivate::eventFilter(QObject *obj, QEvent *event)
{
    int buttonIndex = -1;
    for (int i = 0; i < 2; ++i) {
        if (obj == m_iconbutton[i]) {
            buttonIndex = i;
            break;
        }
    }
    if (buttonIndex == -1)
        return QObject::eventFilter(obj, event);
    switch (event->type()) {
    case QEvent::FocusIn:
        if (m_menuTabFocusTrigger[buttonIndex] && m_menu[buttonIndex]) {
            m_lineEdit->setFocus();
            execMenuAtWidget(m_menu[buttonIndex], m_iconbutton[buttonIndex]);
            return true;
        }
    default:
        break;
    }
    return QObject::eventFilter(obj, event);
}

// --------- FancyLineEdit
FancyLineEdit::FancyLineEdit(QWidget *parent) :
    QLineEdit(parent),
    d(new FancyLineEditPrivate(this))
{
    ensurePolished();
    updateMargins();

    connect(this, SIGNAL(textChanged(QString)), this, SLOT(checkButtons(QString)));
    connect(d->m_iconbutton[Left], SIGNAL(clicked()), this, SLOT(iconClicked()));
    connect(d->m_iconbutton[Right], SIGNAL(clicked()), this, SLOT(iconClicked()));
}

void FancyLineEdit::checkButtons(const QString &text)
{
    if (m_oldText.isEmpty() || text.isEmpty()) {
        for (int i = 0; i < 2; ++i) {
            if (d->m_iconbutton[i]->hasAutoHide())
                d->m_iconbutton[i]->animateShow(!text.isEmpty());
        }
        m_oldText = text;
    }
}

FancyLineEdit::~FancyLineEdit()
{
}

void FancyLineEdit::setButtonVisible(Side side, bool visible)
{
    d->m_iconbutton[side]->setVisible(visible);
    d->m_iconEnabled[side] = visible;
    updateMargins();
}

bool FancyLineEdit::isButtonVisible(Side side) const
{
    return d->m_iconEnabled[side];
}

void FancyLineEdit::iconClicked()
{
    IconButton *button = qobject_cast<IconButton *>(sender());
    int index = -1;
    for (int i = 0; i < 2; ++i)
        if (d->m_iconbutton[i] == button)
            index = i;
    if (index == -1)
        return;
    if (d->m_menu[index]) {
        execMenuAtWidget(d->m_menu[index], button);
    } else {
        emit buttonClicked((Side)index);
        if (index == Left)
            emit leftButtonClicked();
        else if (index == Right)
            emit rightButtonClicked();
    }
}

void FancyLineEdit::updateMargins()
{
    bool leftToRight = (layoutDirection() == Qt::LeftToRight);
    Side realLeft = (leftToRight ? Left : Right);
    Side realRight = (leftToRight ? Right : Left);

    int leftMargin = d->m_iconbutton[realLeft]->pixmap().width() + 8;
    int rightMargin = d->m_iconbutton[realRight]->pixmap().width() + 8;
    // Note KDE does not reserve space for the highlight color
    if (style()->inherits("OxygenStyle")) {
        leftMargin = qMax(24, leftMargin);
        rightMargin = qMax(24, rightMargin);
    }

    QMargins margins((d->m_iconEnabled[realLeft] ? leftMargin : 0), 0,
                     (d->m_iconEnabled[realRight] ? rightMargin : 0), 0);

    setTextMargins(margins);
}

void FancyLineEdit::updateButtonPositions()
{
    QRect contentRect = rect();
    for (int i = 0; i < 2; ++i) {
        Side iconpos = (Side)i;
        if (layoutDirection() == Qt::RightToLeft)
            iconpos = (iconpos == Left ? Right : Left);

        if (iconpos == FancyLineEdit::Right) {
            const int iconoffset = textMargins().right() + 4;
            d->m_iconbutton[i]->setGeometry(contentRect.adjusted(width() - iconoffset, 0, 0, 0));
        } else {
            const int iconoffset = textMargins().left() + 4;
            d->m_iconbutton[i]->setGeometry(contentRect.adjusted(0, 0, -width() + iconoffset, 0));
        }
    }
}

void FancyLineEdit::resizeEvent(QResizeEvent *)
{
    updateButtonPositions();
}

void FancyLineEdit::setButtonPixmap(Side side, const QPixmap &buttonPixmap)
{
    d->m_iconbutton[side]->setPixmap(buttonPixmap);
    updateMargins();
    updateButtonPositions();
    update();
}

QPixmap FancyLineEdit::buttonPixmap(Side side) const
{
    return d->m_pixmap[side];
}

void FancyLineEdit::setButtonMenu(Side side, QMenu *buttonMenu)
{
     d->m_menu[side] = buttonMenu;
     d->m_iconbutton[side]->setIconOpacity(1.0);
 }

QMenu *FancyLineEdit::buttonMenu(Side side) const
{
    return  d->m_menu[side];
}

bool FancyLineEdit::hasMenuTabFocusTrigger(Side side) const
{
    return d->m_menuTabFocusTrigger[side];
}

void FancyLineEdit::setMenuTabFocusTrigger(Side side, bool v)
{
    if (d->m_menuTabFocusTrigger[side] == v)
        return;

    d->m_menuTabFocusTrigger[side] = v;
    d->m_iconbutton[side]->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus);
}

bool FancyLineEdit::hasAutoHideButton(Side side) const
{
    return d->m_iconbutton[side]->hasAutoHide();
}

void FancyLineEdit::setAutoHideButton(Side side, bool h)
{
    d->m_iconbutton[side]->setAutoHide(h);
    if (h)
        d->m_iconbutton[side]->setIconOpacity(text().isEmpty() ?  0.0 : 1.0);
    else
        d->m_iconbutton[side]->setIconOpacity(1.0);
}

void FancyLineEdit::setButtonToolTip(Side side, const QString &tip)
{
    d->m_iconbutton[side]->setToolTip(tip);
}

void FancyLineEdit::setButtonFocusPolicy(Side side, Qt::FocusPolicy policy)
{
    d->m_iconbutton[side]->setFocusPolicy(policy);
}

// IconButton - helper class to represent a clickable icon

IconButton::IconButton(QWidget *parent)
    : QAbstractButton(parent), m_autoHide(false)
{
    setCursor(Qt::ArrowCursor);
    setFocusPolicy(Qt::NoFocus);
}

void IconButton::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
    pixmapRect.moveCenter(rect().center());

    if (m_autoHide)
        painter.setOpacity(m_iconOpacity);

    painter.drawPixmap(pixmapRect, m_pixmap);
}

void IconButton::animateShow(bool visible)
{
    if (visible) {
        QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
        animation->setDuration(FADE_TIME);
        animation->setEndValue(1.0);
        animation->start(QAbstractAnimation::DeleteWhenStopped);
    } else {
        QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
        animation->setDuration(FADE_TIME);
        animation->setEndValue(0.0);
        animation->start(QAbstractAnimation::DeleteWhenStopped);
    }
}

} // namespace Utils
<|endoftext|>


<commit_before>#include "assert.hpp"

#include "TimingTags.hpp"
/*
 * TagType implementation
 */
std::ostream& operator<<(std::ostream& os, const TagType tag_type) {
    if(tag_type == TagType::CLOCK) os << "CLOCK";
    else if (tag_type == TagType::DATA) os << "DATA";
    else if (tag_type == TagType::UNKOWN) os << "UNKOWN";
    else VERIFY(0);
    return os;
}

/*
 * TimingTag implementation
 */
void TimingTag::update_arr(const Time& new_arr_time, const TimingTag& base_tag) {
    //NOTE: leave next alone, since we want to keep the linked list intact
    ASSERT(clock_domain() == base_tag.clock_domain()); //Domain must be the same
    set_arr_time(new_arr_time);
    set_launch_node(base_tag.launch_node());
}

void TimingTag::update_req(const Time& new_req_time, const TimingTag& base_tag) {
    //NOTE: leave next alone, since we want to keep the linked list intact
    //      leave launch_node alone, since it is set by arrival only
    ASSERT(clock_domain() == base_tag.clock_domain()); //Domain must be the same
    set_req_time(new_req_time);
}

/*
 * TimingTags implementation
 */

//Modifiers
void TimingTags::add_tag(MemoryPool& tag_pool, const TimingTag& tag) {
    ASSERT_MSG(tag.next() == nullptr, "Attempted to add new timing tag which is already part of a Linked List");

    //Don't add invalid clock domains
    //Some sources like constant generators may yeild illegal clock domains
    if(tag.clock_domain() == INVALID_CLOCK_DOMAIN) {
        return;
    }

#if NUM_FLAT_TAGS >= 1
    if(num_tags_ < (int) head_tags_.max_size()) {
        //Store it as a head tag
        head_tags_[num_tags_] = tag;
        if(num_tags_ != 0) {
            //Link from previous if it exists
            head_tags_[num_tags_-1].set_next(&head_tags_[num_tags_]);
        }
    } else {
        //Store it in a linked list from head tags

        //Allocate form a central storage pool
        VERIFY(tag_pool.get_requested_size() == sizeof(TimingTag)); //Make sure the pool is the correct size
        TimingTag* new_tag = new(tag_pool.malloc()) TimingTag(tag);

        //Insert one-after the last head in O(1) time
        //Note that we don't maintain the tags in any order since we expect a relatively small number of tags
        //per node
        TimingTag* next_tag = head_tags_[head_tags_.max_size()-1].next(); //Save next link (may be nullptr)
        head_tags_[head_tags_.max_size()-1].set_next(new_tag); //Tag is now in the list
        new_tag->set_next(next_tag); //Attach tail of the list
    }
#else
    //Allocate form a central storage pool
    VERIFY(tag_pool.get_requested_size() == sizeof(TimingTag)); //Make sure the pool is the correct size
    TimingTag* new_tag = new(tag_pool.malloc()) TimingTag(tag);

    if(head_tags_ == nullptr) {
        head_tags_ = new_tag;
    } else {
        //Insert as the head in O(1) time
        //Note that we don't maintain the tags in any order since we expect a relatively small number of tags
        //per node
        TimingTag* next_tag = head_tags_; //Save next link (may be nullptr)
        head_tags_ = new_tag; //Tag is now in the list
        new_tag->set_next(next_tag); //Attach tail of the list
    }
#endif
    //Tag has been added
    num_tags_++;
}

void TimingTags::max_arr(MemoryPool& tag_pool, const Time& new_time, const TimingTag& base_tag) {
    TimingTagIterator iter = find_tag_by_clock_domain(base_tag.clock_domain());
    if(iter == end()) {
        //First time we've seen this domain
        TimingTag tag = TimingTag(new_time, Time(NAN), base_tag);
        add_tag(tag_pool, tag);
    } else {
        TimingTag& matched_tag = *iter;

        //Need to max with existing value
        if(new_time.value() > matched_tag.arr_time().value()) {
            //New value is larger
            //Update max
            matched_tag.update_arr(new_time, base_tag);
        }
    }
}

void TimingTags::min_req(MemoryPool& tag_pool, const Time& new_time, const TimingTag& base_tag) {
    TimingTagIterator iter = find_tag_by_clock_domain(base_tag.clock_domain());
    if(iter == end()) {
        //First time we've seen this domain
        TimingTag tag = TimingTag(Time(NAN), new_time, base_tag);
        add_tag(tag_pool, tag);
    } else {
        TimingTag& matched_tag = *iter;

        //Need to min with existing value
        if(!matched_tag.req_time().valid() || new_time.value() < matched_tag.req_time().value()) {
            //New value is smaller, or no previous valid value existed
            //Update min
            matched_tag.update_req(new_time, base_tag);
        }
    }
}

void TimingTags::clear() {
    //Note that we do not clean up the tag linked list!
    //Since these are allocated in a memory pool they will be freed by
    //the owner of the pool (typically the analyzer that is calling us)
    num_tags_ = 0;

#if NUM_FLAT_TAGS == 0
    //If we are using an un-flattend linked list
    //we must reset the head pointer
    head_tags_ = nullptr;
#endif
}

TimingTagIterator TimingTags::find_tag_by_clock_domain(DomainId domain_id) {
    auto pred = [domain_id](const TimingTag& tag) {
        return tag.clock_domain() == domain_id;
    };
    return std::find_if(begin(), end(), pred);
}

TimingTagConstIterator TimingTags::find_tag_by_clock_domain(DomainId domain_id) const {
    auto pred = [domain_id](const TimingTag& tag) {
        return tag.clock_domain() == domain_id;
    };
    return std::find_if(begin(), end(), pred);
}
<commit_msg>Fix bug in arrival time traversals.<commit_after>#include "assert.hpp"

#include "TimingTags.hpp"
/*
 * TagType implementation
 */
std::ostream& operator<<(std::ostream& os, const TagType tag_type) {
    if(tag_type == TagType::CLOCK) os << "CLOCK";
    else if (tag_type == TagType::DATA) os << "DATA";
    else if (tag_type == TagType::UNKOWN) os << "UNKOWN";
    else VERIFY(0);
    return os;
}

/*
 * TimingTag implementation
 */
void TimingTag::update_arr(const Time& new_arr_time, const TimingTag& base_tag) {
    //NOTE: leave next alone, since we want to keep the linked list intact
    ASSERT(clock_domain() == base_tag.clock_domain()); //Domain must be the same
    set_arr_time(new_arr_time);
    set_launch_node(base_tag.launch_node());
}

void TimingTag::update_req(const Time& new_req_time, const TimingTag& base_tag) {
    //NOTE: leave next alone, since we want to keep the linked list intact
    //      leave launch_node alone, since it is set by arrival only
    ASSERT(clock_domain() == base_tag.clock_domain()); //Domain must be the same
    set_req_time(new_req_time);
}

/*
 * TimingTags implementation
 */

//Modifiers
void TimingTags::add_tag(MemoryPool& tag_pool, const TimingTag& tag) {
    ASSERT_MSG(tag.next() == nullptr, "Attempted to add new timing tag which is already part of a Linked List");

    //Don't add invalid clock domains
    //Some sources like constant generators may yeild illegal clock domains
    if(tag.clock_domain() == INVALID_CLOCK_DOMAIN) {
        return;
    }

#if NUM_FLAT_TAGS >= 1
    if(num_tags_ < (int) head_tags_.max_size()) {
        //Store it as a head tag
        head_tags_[num_tags_] = tag;
        if(num_tags_ != 0) {
            //Link from previous if it exists
            head_tags_[num_tags_-1].set_next(&head_tags_[num_tags_]);
        }
    } else {
        //Store it in a linked list from head tags

        //Allocate form a central storage pool
        VERIFY(tag_pool.get_requested_size() == sizeof(TimingTag)); //Make sure the pool is the correct size
        TimingTag* new_tag = new(tag_pool.malloc()) TimingTag(tag);

        //Insert one-after the last head in O(1) time
        //Note that we don't maintain the tags in any order since we expect a relatively small number of tags
        //per node
        TimingTag* next_tag = head_tags_[head_tags_.max_size()-1].next(); //Save next link (may be nullptr)
        head_tags_[head_tags_.max_size()-1].set_next(new_tag); //Tag is now in the list
        new_tag->set_next(next_tag); //Attach tail of the list
    }
#else
    //Allocate form a central storage pool
    VERIFY(tag_pool.get_requested_size() == sizeof(TimingTag)); //Make sure the pool is the correct size
    TimingTag* new_tag = new(tag_pool.malloc()) TimingTag(tag);

    if(head_tags_ == nullptr) {
        head_tags_ = new_tag;
    } else {
        //Insert as the head in O(1) time
        //Note that we don't maintain the tags in any order since we expect a relatively small number of tags
        //per node
        TimingTag* next_tag = head_tags_; //Save next link (may be nullptr)
        head_tags_ = new_tag; //Tag is now in the list
        new_tag->set_next(next_tag); //Attach tail of the list
    }
#endif
    //Tag has been added
    num_tags_++;
}

void TimingTags::max_arr(MemoryPool& tag_pool, const Time& new_time, const TimingTag& base_tag) {
    TimingTagIterator iter = find_tag_by_clock_domain(base_tag.clock_domain());
    if(iter == end()) {
        //First time we've seen this domain
        TimingTag tag = TimingTag(new_time, Time(NAN), base_tag);
        add_tag(tag_pool, tag);
    } else {
        TimingTag& matched_tag = *iter;

        //Need to max with existing value
        if(!matched_tag.arr_time().valid() || new_time.value() > matched_tag.arr_time().value()) {
            //New value is larger, or no previous valid value existed
            //Update max
            matched_tag.update_arr(new_time, base_tag);
        }
    }
}

void TimingTags::min_req(MemoryPool& tag_pool, const Time& new_time, const TimingTag& base_tag) {
    TimingTagIterator iter = find_tag_by_clock_domain(base_tag.clock_domain());
    if(iter == end()) {
        //First time we've seen this domain
        TimingTag tag = TimingTag(Time(NAN), new_time, base_tag);
        add_tag(tag_pool, tag);
    } else {
        TimingTag& matched_tag = *iter;

        //Need to min with existing value
        if(!matched_tag.req_time().valid() || new_time.value() < matched_tag.req_time().value()) {
            //New value is smaller, or no previous valid value existed
            //Update min
            matched_tag.update_req(new_time, base_tag);
        }
    }
}

void TimingTags::clear() {
    //Note that we do not clean up the tag linked list!
    //Since these are allocated in a memory pool they will be freed by
    //the owner of the pool (typically the analyzer that is calling us)
    num_tags_ = 0;

#if NUM_FLAT_TAGS == 0
    //If we are using an un-flattend linked list
    //we must reset the head pointer
    head_tags_ = nullptr;
#endif
}

TimingTagIterator TimingTags::find_tag_by_clock_domain(DomainId domain_id) {
    auto pred = [domain_id](const TimingTag& tag) {
        return tag.clock_domain() == domain_id;
    };
    return std::find_if(begin(), end(), pred);
}

TimingTagConstIterator TimingTags::find_tag_by_clock_domain(DomainId domain_id) const {
    auto pred = [domain_id](const TimingTag& tag) {
        return tag.clock_domain() == domain_id;
    };
    return std::find_if(begin(), end(), pred);
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2014 Micah C Chambers (micahc.vt@gmail.com)
 *
 * 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 opt.cpp Contains implementation for base optimizer
 *
 *****************************************************************************/

#include "opt.h"

#include <iostream>
#include <iomanip>

namespace npl {

/**
 * @brief Constructor for optimizer function.
 *
 * @param dim       Dimensionality of state vector
 * @param valfunc   Function which computes the energy of the underlying
 *                  mathematical function
 * @param gradfunc  Function which computes the gradient of energy in the
 *                  underlying mathematical function
 * @param valgradfunc
 *                  Function which computes the both the energy and
 *                  gradient in the underlying mathematical function
 * @param callback  Function which should be called at the end of each
 *                  iteration (for instance, to debug)
 */
Optimizer::Optimizer(size_t dim, const ValFunc& valfunc, const GradFunc& gradfunc,
        const ValGradFunc& valgradfunc, const CallBackFunc& callback)
        : state_x(dim)
{
    stop_G = 0.00001;
    stop_X = 0;
    stop_F = 0;
    stop_Its = -1;

    m_compF = valfunc;
    m_compG = gradfunc;
    m_compFG = valgradfunc;

    m_callback = callback;
};

/**
 * @brief Constructor for optimizer function.
 *
 * @param dim       Dimensionality of state vector
 * @param valfunc   Function which computes the energy of the underlying
 *                  mathematical function
 * @param gradfunc  Function which computes the gradient of energy in the
 *                  underlying mathematical function
 * @param callback  Function which should be called at the end of each
 *                  iteration (for instance, to debug)
 */
Optimizer::Optimizer(size_t dim, const ValFunc& valfunc, const GradFunc&
            gradfunc, const CallBackFunc& callback)
            : state_x(dim)
{
    stop_G = 0.00001;
    stop_X = 0;
    stop_F = 0;
    stop_Its = -1;

    m_compF = valfunc;
    m_compG = gradfunc;
    m_compFG = [&](const VectorXd& x, double& value, VectorXd& grad) -> int
    {
        return !(valfunc(x, value)==0 && gradfunc(x, grad)==0);
    };

    m_callback = callback;
};

std::string Optimizer::explainStop(StopReason r)
{
    switch(r) {
        case ENDGRAD:
            return "Optimizer stopped due to gradient below threshold.";
        case ENDSTEP:
            return "Optimizer stopped due to step size below threshold.";
        case ENDVALUE:
            return "Optimizer stopped due to change in value below threshold.";
        case ENDITERS:
            return "Optimizer stopped due to number iterations.";
        case ENDFAIL:
            return "Optimizer due to failure of callback functions.";
    }
    return "Unknown stop condition!";
}

/**
 * @brief Tests a gradient function using the value function.
 *
 * @param error     Error between analytical and numeric gradient
 * @param x         Position to test
 * @param stepsize  Step to take when testing gradient (will be taken in each
 *                  dimension successively)
 * @param tol       Tolerance, error below the tolerance will cause the
 *                  function to return 0, higher error will cause the function to return -1
 * @param valfunc   Function values compute
 * @param gradfunc  Function gradient compute
 *
 * @return
 */
int testgrad(double& error, const VectorXd& x, double stepsize, double tol,
        const ValFunc& valfunc, const GradFunc& gradfunc)
{
//#ifndef NDEBUG
    size_t wid = 18;
    std::cerr << "Testing Gradient" << std::endl;
    std::cerr << std::setw(wid) << "Dim" << std::setw(wid) << "Analytic" <<
        std::setw(wid) << "Numeric" << std::endl;
//#endif //NDEBUG
    VectorXd g(x.rows());
    if(gradfunc(x, g) != 0)
        return -1;

    double v = 0;
    double center = 0;
    if(valfunc(x, center) != 0)
        return -1;

    VectorXd step = VectorXd::Zero(x.rows());
    VectorXd gbrute(x.rows());
    for(size_t dd=0; dd<x.rows(); dd++) {
        step[dd] = stepsize;
        if(valfunc(x+step, v) != 0)
            return -1;
        step[dd] = 0;

        gbrute[dd] = (v-center)/stepsize;

//#ifndef NDEBUG
    std::cerr << std::setw(wid) << dd << std::setw(wid) << g[dd] <<
        std::setw(wid) << gbrute[dd] << std::endl;
//#endif //NDEBUG
    }

    error = (gbrute - g).norm();
    if(error > tol)
        return -2;

    return 0;
}

/**
 * @brief The number of calls to the Generalized Rosenbrock Gradient Function.
 * This is only for benchmarking purposes, and is not thread safe.
 */
static size_t gRosenbrock_G_calls = 0;

/**
 * @brief The number of calls to the Generalized Rosenbrock Value Function.
 * This is only for benchmarking purposes, and is not thread safe.
 */
static size_t gRosenbrock_V_calls = 0;

/**
 * @brief Returns the number of times the Value and Gradient functions for the
 * Generalized Rosenbrock Function were called.
 *
 * @param vcalls Value calls
 * @param gcalls Gradient calls
 */
void gRosenbrock_callCounts(size_t& vcalls, size_t& gcalls)
{
    gcalls = gRosenbrock_G_calls;
    vcalls = gRosenbrock_V_calls;
}

/**
 * @brief Implements generized rosenbrock value
 *
 * @param x Position vector
 * @param v values
 *
 * @return
 */
int gRosenbrock_V(const VectorXd& x, double& v)
{
    gRosenbrock_V_calls++;;
    v = 0;
    for(size_t ii=0; ii<x.rows()-1; ii++)
        v += pow(x[ii]-1,2)+100*pow(x[ii+1]-x[ii]*x[ii], 2);

    // i=N-1
    size_t ii=x.rows()-1;
    v += pow(x[ii]-1,2)+100*pow(-x[ii]*x[ii], 2);
    return 0;
}

/**
 * @brief Implements generized rosenbrock gradient
 *
 * @param x Position vector
 * @param gradient Gradient at the position
 *
 * @return
 */
int gRosenbrock_G(const VectorXd& x, VectorXd& gradient)
{
    gRosenbrock_G_calls++;;
//    gradient.resize(x.rows());

    for(size_t ii=1; ii<x.rows()-1; ii++)
        gradient[ii] = 2*(x[ii]-1)-400*(x[ii+1]-x[ii]*x[ii])*x[ii]+
                    200*(x[ii]-x[ii-1]*x[ii-1]);

    // boundaries
    size_t ii=0;
    gradient[ii] = 2*(x[ii]-1)-400*(x[ii+1]-x[ii]*x[ii])*x[ii];

    ii=x.rows()-1;
    gradient[ii] = 2*(x[ii]-1)-400*(-x[ii]*x[ii])*x[ii]+
                200*(x[ii]-x[ii-1]*x[ii-1]);

    return 0;
}

}
<commit_msg>Gradient test always prints now<commit_after>/******************************************************************************
 * Copyright 2014 Micah C Chambers (micahc.vt@gmail.com)
 *
 * 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 opt.cpp Contains implementation for base optimizer
 *
 *****************************************************************************/

#include "opt.h"

#include <iostream>
#include <iomanip>

namespace npl {

/**
 * @brief Constructor for optimizer function.
 *
 * @param dim       Dimensionality of state vector
 * @param valfunc   Function which computes the energy of the underlying
 *                  mathematical function
 * @param gradfunc  Function which computes the gradient of energy in the
 *                  underlying mathematical function
 * @param valgradfunc
 *                  Function which computes the both the energy and
 *                  gradient in the underlying mathematical function
 * @param callback  Function which should be called at the end of each
 *                  iteration (for instance, to debug)
 */
Optimizer::Optimizer(size_t dim, const ValFunc& valfunc, const GradFunc& gradfunc,
        const ValGradFunc& valgradfunc, const CallBackFunc& callback)
        : state_x(dim)
{
    stop_G = 0.00001;
    stop_X = 0;
    stop_F = 0;
    stop_Its = -1;

    m_compF = valfunc;
    m_compG = gradfunc;
    m_compFG = valgradfunc;

    m_callback = callback;
};

/**
 * @brief Constructor for optimizer function.
 *
 * @param dim       Dimensionality of state vector
 * @param valfunc   Function which computes the energy of the underlying
 *                  mathematical function
 * @param gradfunc  Function which computes the gradient of energy in the
 *                  underlying mathematical function
 * @param callback  Function which should be called at the end of each
 *                  iteration (for instance, to debug)
 */
Optimizer::Optimizer(size_t dim, const ValFunc& valfunc, const GradFunc&
            gradfunc, const CallBackFunc& callback)
            : state_x(dim)
{
    stop_G = 0.00001;
    stop_X = 0;
    stop_F = 0;
    stop_Its = -1;

    m_compF = valfunc;
    m_compG = gradfunc;
    m_compFG = [&](const VectorXd& x, double& value, VectorXd& grad) -> int
    {
        return !(valfunc(x, value)==0 && gradfunc(x, grad)==0);
    };

    m_callback = callback;
};

std::string Optimizer::explainStop(StopReason r)
{
    switch(r) {
        case ENDGRAD:
            return "Optimizer stopped due to gradient below threshold.";
        case ENDSTEP:
            return "Optimizer stopped due to step size below threshold.";
        case ENDVALUE:
            return "Optimizer stopped due to change in value below threshold.";
        case ENDITERS:
            return "Optimizer stopped due to number iterations.";
        case ENDFAIL:
            return "Optimizer due to failure of callback functions.";
    }
    return "Unknown stop condition!";
}

/**
 * @brief Tests a gradient function using the value function.
 *
 * @param error     Error between analytical and numeric gradient
 * @param x         Position to test
 * @param stepsize  Step to take when testing gradient (will be taken in each
 *                  dimension successively)
 * @param tol       Tolerance, error below the tolerance will cause the
 *                  function to return 0, higher error will cause the function to return -1
 * @param valfunc   Function values compute
 * @param gradfunc  Function gradient compute
 *
 * @return
 */
int testgrad(double& error, const VectorXd& x, double stepsize, double tol,
        const ValFunc& valfunc, const GradFunc& gradfunc)
{
    size_t wid = 18;
    std::cerr << "Testing Gradient" << std::endl;
    std::cerr << std::setw(wid) << "Dim" << std::setw(wid) << "Analytic" <<
        std::setw(wid) << "Numeric" << std::endl;
    VectorXd g(x.rows());
    if(gradfunc(x, g) != 0)
        return -1;

    double v = 0;
    double center = 0;
    if(valfunc(x, center) != 0)
        return -1;

    VectorXd step = VectorXd::Zero(x.rows());
    VectorXd gbrute(x.rows());
    for(size_t dd=0; dd<x.rows(); dd++) {
        step[dd] = stepsize;
        if(valfunc(x+step, v) != 0)
            return -1;
        step[dd] = 0;

        gbrute[dd] = (v-center)/stepsize;

        std::cerr << std::setw(wid) << dd << std::setw(wid) << g[dd] <<
            std::setw(wid) << gbrute[dd] << std::endl;
    }

    error = (gbrute - g).norm();
    std::cerr << "SumSqr Error: " << error << std::endl;
    if(error > tol)
        return -2;

    return 0;
}

/**
 * @brief The number of calls to the Generalized Rosenbrock Gradient Function.
 * This is only for benchmarking purposes, and is not thread safe.
 */
static size_t gRosenbrock_G_calls = 0;

/**
 * @brief The number of calls to the Generalized Rosenbrock Value Function.
 * This is only for benchmarking purposes, and is not thread safe.
 */
static size_t gRosenbrock_V_calls = 0;

/**
 * @brief Returns the number of times the Value and Gradient functions for the
 * Generalized Rosenbrock Function were called.
 *
 * @param vcalls Value calls
 * @param gcalls Gradient calls
 */
void gRosenbrock_callCounts(size_t& vcalls, size_t& gcalls)
{
    gcalls = gRosenbrock_G_calls;
    vcalls = gRosenbrock_V_calls;
}

/**
 * @brief Implements generized rosenbrock value
 *
 * @param x Position vector
 * @param v values
 *
 * @return
 */
int gRosenbrock_V(const VectorXd& x, double& v)
{
    gRosenbrock_V_calls++;;
    v = 0;
    for(size_t ii=0; ii<x.rows()-1; ii++)
        v += pow(x[ii]-1,2)+100*pow(x[ii+1]-x[ii]*x[ii], 2);

    // i=N-1
    size_t ii=x.rows()-1;
    v += pow(x[ii]-1,2)+100*pow(-x[ii]*x[ii], 2);
    return 0;
}

/**
 * @brief Implements generized rosenbrock gradient
 *
 * @param x Position vector
 * @param gradient Gradient at the position
 *
 * @return
 */
int gRosenbrock_G(const VectorXd& x, VectorXd& gradient)
{
    gRosenbrock_G_calls++;;
//    gradient.resize(x.rows());

    for(size_t ii=1; ii<x.rows()-1; ii++)
        gradient[ii] = 2*(x[ii]-1)-400*(x[ii+1]-x[ii]*x[ii])*x[ii]+
                    200*(x[ii]-x[ii-1]*x[ii-1]);

    // boundaries
    size_t ii=0;
    gradient[ii] = 2*(x[ii]-1)-400*(x[ii+1]-x[ii]*x[ii])*x[ii];

    ii=x.rows()-1;
    gradient[ii] = 2*(x[ii]-1)-400*(-x[ii]*x[ii])*x[ii]+
                200*(x[ii]-x[ii-1]*x[ii-1]);

    return 0;
}

}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	Fixed FIFO (first in first out) テンプレート
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2020 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace utils {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  固定サイズ FIFO クラス
		@param[in]	UNIT	基本形
		@param[in]	SIZE	バッファサイズ（最低２）
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class UNIT, uint32_t SIZE>
	class fixed_fifo {

		volatile uint32_t	get_;
		volatile uint32_t	put_;

		UNIT	buff_[SIZE];

	public:
        //-----------------------------------------------------------------//
        /*!
            @brief  コンストラクター
        */
        //-----------------------------------------------------------------//
		fixed_fifo() noexcept : get_(0), put_(0) { }

        //-----------------------------------------------------------------//
        /*!
            @brief  バッファのサイズを返す
			@return	バッファのサイズ
        */
        //-----------------------------------------------------------------//
		inline uint32_t size() const noexcept { return SIZE; }

        //-----------------------------------------------------------------//
        /*!
            @brief  長さを返す
			@return	長さ
        */
        //-----------------------------------------------------------------//
		uint32_t length() const noexcept {
			if(put_ >= get_) return (put_ - get_);
			else return (SIZE + put_ - get_);
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  クリア
        */
        //-----------------------------------------------------------------//
		inline void clear() noexcept { get_ = put_ = 0; }

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納参照を得る
			@param[in]	ofs	オフセット（格納領域を超えたオフセットは未定義）
			@return 値の格納参照
        */
        //-----------------------------------------------------------------//
		inline UNIT& put_at(uint32_t ofs = 0) noexcept {
			return buff_[(put_ + ofs) % SIZE];
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納ポイントの移動
        */
        //-----------------------------------------------------------------//
		inline void put_go() noexcept {
			volatile auto put = put_;
			++put;
			if(put >= SIZE) {
				put = 0;
			}
			put_ = put;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納
			@param[in]	v	値
        */
        //-----------------------------------------------------------------//
		void put(const UNIT& v) noexcept {
			buff_[put_] = v;
			put_go();
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得参照を得る
			@param[in]	ofs	オフセット（格納領域を超えたオフセットは未定義）
			@return	値の取得参照
        */
        //-----------------------------------------------------------------//
		inline const UNIT& get_at(uint32_t ofs = 0) const noexcept {
			return buff_[(get_ + ofs) % SIZE];
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
        */
        //-----------------------------------------------------------------//
		inline void get_go() noexcept {
			volatile auto get = get_;
			++get;
			if(get >= SIZE) {
				get = 0;
			}
			get_ = get;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
			@return	値
        */
        //-----------------------------------------------------------------//
		UNIT get() noexcept {
			UNIT v = buff_[get_];
			get_go();
			return v;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  get 位置を返す
			@return	位置
        */
        //-----------------------------------------------------------------//
		inline uint16_t pos_get() const noexcept { return get_; }

        //-----------------------------------------------------------------//
        /*!
            @brief  put 位置を返す
			@return	位置
        */
        //-----------------------------------------------------------------//
		inline uint16_t pos_put() const noexcept { return put_; }
	};
}
<commit_msg>Update: turn constexpr at size() API<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	Fixed FIFO (first in first out) テンプレート
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2020 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace utils {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  固定サイズ FIFO クラス
		@param[in]	UNIT	基本形
		@param[in]	SIZE	バッファサイズ（最低２）
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class UNIT, uint32_t SIZE>
	class fixed_fifo {

		volatile uint32_t	get_;
		volatile uint32_t	put_;

		UNIT	buff_[SIZE];

	public:
        //-----------------------------------------------------------------//
        /*!
            @brief  コンストラクター
        */
        //-----------------------------------------------------------------//
		fixed_fifo() noexcept : get_(0), put_(0) { }

        //-----------------------------------------------------------------//
        /*!
            @brief  バッファのサイズを返す
			@return	バッファのサイズ
        */
        //-----------------------------------------------------------------//
		constexpr uint32_t size() const noexcept { return SIZE; }

        //-----------------------------------------------------------------//
        /*!
            @brief  長さを返す
			@return	長さ
        */
        //-----------------------------------------------------------------//
		uint32_t length() const noexcept {
			if(put_ >= get_) return (put_ - get_);
			else return (SIZE + put_ - get_);
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  クリア
        */
        //-----------------------------------------------------------------//
		inline void clear() noexcept { get_ = put_ = 0; }

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納参照を得る
			@param[in]	ofs	オフセット（格納領域を超えたオフセットは未定義）
			@return 値の格納参照
        */
        //-----------------------------------------------------------------//
		inline UNIT& put_at(uint32_t ofs = 0) noexcept {
			return buff_[(put_ + ofs) % SIZE];
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納ポイントの移動
        */
        //-----------------------------------------------------------------//
		inline void put_go() noexcept {
			volatile auto put = put_;
			++put;
			if(put >= SIZE) {
				put = 0;
			}
			put_ = put;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納
			@param[in]	v	値
        */
        //-----------------------------------------------------------------//
		void put(const UNIT& v) noexcept {
			buff_[put_] = v;
			put_go();
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得参照を得る
			@param[in]	ofs	オフセット（格納領域を超えたオフセットは未定義）
			@return	値の取得参照
        */
        //-----------------------------------------------------------------//
		inline const UNIT& get_at(uint32_t ofs = 0) const noexcept {
			return buff_[(get_ + ofs) % SIZE];
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
        */
        //-----------------------------------------------------------------//
		inline void get_go() noexcept {
			volatile auto get = get_;
			++get;
			if(get >= SIZE) {
				get = 0;
			}
			get_ = get;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
			@return	値
        */
        //-----------------------------------------------------------------//
		UNIT get() noexcept {
			UNIT v = buff_[get_];
			get_go();
			return v;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  get 位置を返す
			@return	位置
        */
        //-----------------------------------------------------------------//
		inline uint16_t pos_get() const noexcept { return get_; }

        //-----------------------------------------------------------------//
        /*!
            @brief  put 位置を返す
			@return	位置
        */
        //-----------------------------------------------------------------//
		inline uint16_t pos_put() const noexcept { return put_; }
	};
}
<|endoftext|>


<commit_before>#include <vsqx.h>
using namespace std;

#define CHECK_ROOT_ELEMENT	0
#define CHECK_BEFORE_LOAD	0

VsqxDoc::VsqxDoc()
{
	init();
}

VsqxDoc::VsqxDoc(string filePath)
{
	init();
	setPath(filePath);
}

VsqxDoc::~VsqxDoc()
{
	delete path;
}

void VsqxDoc::init()
{
	path = new string;
	path->clear();

	info = new VsqxInfo;
}

void VsqxDoc::setPath(std::string filePath)
{
	path->append(filePath.c_str());
}

bool VsqxDoc::isVsqx()
{
	XMLDocument doc;
	doc.LoadFile(path->c_str());
	if(doc.Error() == true)//Have Error
		return false;
#if CHECK_ROOT_ELEMENT == 1
	if(strcmp(doc.RootElement()->Name(),"vsq3") != 0)//Vocaloid 3 root element name
		return false;
#endif
	return true;
}

int VsqxDoc::load()
{
#if CHECK_BEFORE_LOAD == 1
	if(isVsqx() == false)
	{
		setError("%s: Faild to load %s.\n",__func__,path->c_str());
		return 0;
	}
#endif
	XMLDocument doc;
	doc.LoadFile(path->c_str());
	XMLElement *rootElement = doc.RootElement();

	XMLElement *venderElement = rootElement->FirstChildElement("vender");
	if(venderElement == NULL)//vender not Found
		info->setVender("Unknown");
	else
		info->setVender(venderElement->GetText());

	XMLElement *versionElement = rootElement->FirstChildElement("version");
	if(versionElement == NULL)//vender not Found
		info->setVersion("0.0.0");//Unknown
	else
		info->setVersion(versionElement->GetText());

	XMLElement *voiceTableElement = rootElement->FirstChildElement("vVoiceTable");
	if(voiceElement != NULL)//voice data found
	{
		XMLElement element = voiceTableElement->FirstChildElement("vVoice");//just so we won't loadup something weird
	}
	return 1;
}

VsqxInfo* VsqxDoc::getInfo()
{
	return info;
}

int VsqxDoc::getError(char* buffer,int bufSize, bool keepMessage)
{
	int length = errorString.length();
	if(length != 0)//have error
	{
		//bigger than -1, a valed buffer size
		if(bufSize >= 0)
		{
			int copyLength = bufSize-1 > length ? length : bufSize-1;
			memcpy(buffer,errorString.c_str(),length);
			buffer[copyLength] = 0;
		}
		else//else, just copy
			strcpy(buffer,errorString.c_str());

		if(keepMessage == false)
			errorString.clear();

		return 1;
	}
	if(bufSize > 0)
		buffer[0] = 0;
	return 0;
}

void VsqxDoc::setError(const char* format,...)
{
	if(errorString.length() != 0)
		errorString.clear();

	char* str = new char[2000];
	va_list arglist;
	va_start(arglist,format);
	vsprintf(str,format,arglist);
	va_end(arglist);

	errorString.append(str);

	delete [] str;
}

////////////////////////////////////////////////
//VsqxInfo
////////////////////////////////////////////////
VsqxInfo::VsqxInfo()
{
	vender = new string("");
	version = new string("");
}

VsqxInfo::~VsqxInfo()
{
	delete vender;
	delete version;
}

void VsqxInfo::setVender(string str)
{
	*vender = str;
}

void VsqxInfo::setVersion(string str)
{
	*version = str;
}

const char* VsqxInfo::getVender()
{
	return vender->c_str();
}
const char* VsqxInfo::getVersion()
{
	return version->c_str();
}

<commit_msg>develop oops fix commit<commit_after>#include <vsqx.h>
using namespace std;

#define CHECK_ROOT_ELEMENT	0
#define CHECK_BEFORE_LOAD	0

VsqxDoc::VsqxDoc()
{
	init();
}

VsqxDoc::VsqxDoc(string filePath)
{
	init();
	setPath(filePath);
}

VsqxDoc::~VsqxDoc()
{
	delete path;
}

void VsqxDoc::init()
{
	path = new string;
	path->clear();

	info = new VsqxInfo;
}

void VsqxDoc::setPath(std::string filePath)
{
	path->append(filePath.c_str());
}

bool VsqxDoc::isVsqx()
{
	XMLDocument doc;
	doc.LoadFile(path->c_str());
	if(doc.Error() == true)//Have Error
		return false;
#if CHECK_ROOT_ELEMENT == 1
	if(strcmp(doc.RootElement()->Name(),"vsq3") != 0)//Vocaloid 3 root element name
		return false;
#endif
	return true;
}

int VsqxDoc::load()
{
#if CHECK_BEFORE_LOAD == 1
	if(isVsqx() == false)
	{
		setError("%s: Faild to load %s.\n",__func__,path->c_str());
		return 0;
	}
#endif
	XMLDocument doc;
	doc.LoadFile(path->c_str());
	XMLElement *rootElement = doc.RootElement();

	XMLElement *venderElement = rootElement->FirstChildElement("vender");
	if(venderElement == NULL)//vender not Found
		info->setVender("Unknown");
	else
		info->setVender(venderElement->GetText());

	XMLElement *versionElement = rootElement->FirstChildElement("version");
	if(versionElement == NULL)//vender not Found
		info->setVersion("0.0.0");//Unknown
	else
		info->setVersion(versionElement->GetText());

	XMLElement *voiceTableElement = rootElement->FirstChildElement("vVoiceTable");
	if(voiceTableElement != NULL)//voice data found
	{
		XMLElement *element = voiceTableElement->FirstChildElement("vVoiceTable");//just so we won't loadup something weird
	}
	return 1;
}

VsqxInfo* VsqxDoc::getInfo()
{
	return info;
}

int VsqxDoc::getError(char* buffer,int bufSize, bool keepMessage)
{
	int length = errorString.length();
	if(length != 0)//have error
	{
		//bigger than -1, a valed buffer size
		if(bufSize >= 0)
		{
			int copyLength = bufSize-1 > length ? length : bufSize-1;
			memcpy(buffer,errorString.c_str(),length);
			buffer[copyLength] = 0;
		}
		else//else, just copy
			strcpy(buffer,errorString.c_str());

		if(keepMessage == false)
			errorString.clear();

		return 1;
	}
	if(bufSize > 0)
		buffer[0] = 0;
	return 0;
}

void VsqxDoc::setError(const char* format,...)
{
	if(errorString.length() != 0)
		errorString.clear();

	char* str = new char[2000];
	va_list arglist;
	va_start(arglist,format);
	vsprintf(str,format,arglist);
	va_end(arglist);

	errorString.append(str);

	delete [] str;
}

////////////////////////////////////////////////
//VsqxInfo
////////////////////////////////////////////////
VsqxInfo::VsqxInfo()
{
	vender = new string("");
	version = new string("");
}

VsqxInfo::~VsqxInfo()
{
	delete vender;
	delete version;
}

void VsqxInfo::setVender(string str)
{
	*vender = str;
}

void VsqxInfo::setVersion(string str)
{
	*version = str;
}

const char* VsqxInfo::getVender()
{
	return vender->c_str();
}
const char* VsqxInfo::getVersion()
{
	return version->c_str();
}

<|endoftext|>


<commit_before>#ifndef DECAM__HH
#define DECAM__HH

#include <string>
#include <vector>

namespace DECam
{

    /// @class Traits
    /// @brief Type information for the Dark Energy Camera.

    struct Traits
    {

        static const std::vector< std::string > frames;

        static bool frame_exists( const std::string& frame );

    };

}

const std::vector< std::string > DECam::Traits::frames( { "S1", "S2", "S3", "N1", "N2", "N3", "S8", "S9", "S14", "S15", "S20", "S25", "N8", "N9", "N14", "N15",
        "N20", "N25", "S10", "S11", "S12", "S13", "S18", "S19", "S16", "S17", "S21", "S22", "S23", "S24", "S26", "S27", "S28", "S29", "S30", "S31", "N4", "N5",
        "N6", "N7", "S4", "S5", "S6", "S7", "N10", "N11", "N12", "N13", "N18", "N19", "N16", "N17", "N21", "N22", "N23", "N24", "N26", "N27", "N28", "N29",
        "N30", "N31", "FS1", "FS2", "FS3", "FS4", "FN1", "FN2", "FN3", "FN4" } );

inline bool DECam::Traits::frame_exists( const std::string& frame )
{
    return std::find( frames.begin(), frames.end(), frame ) != frames.end();
}

#endif

// HDU  usually
//      chip
//  2   S1
//  3   S2
//  4   S3
//  5   N1
//  6   N2
//  7   N3
//  8   S8
//  9   S9
// 10   S14
// 11   S15
// 12   S20
// 13   S25
// 14   N8
// 15   N9
// 16   N14
// 17   N15
// 18   N20
// 19   N25
// 20   S10
// 21   S11
// 22   S12
// 23   S13
// 24   S18
// 25   S19
// 26   S16
// 27   S17
// 28   S21
// 29   S22
// 30   S23
// 31   S24
// 32   S26
// 33   S27
// 34   S28
// 35   S29
// 36   S30
// 37   S31
// 38   N4
// 39   N5
// 40   N6
// 41   N7
// 42   S4
// 43   S5
// 44   S6
// 45   S7
// 46   N10
// 47   N11
// 48   N12
// 49   N13
// 50   N18
// 51   N19
// 52   N16
// 53   N17
// 54   N21
// 55   N22
// 56   N23
// 57   N24
// 58   N26
// 59   N27
// 60   N28
// 61   N29
// 62   N30
// 63   N31
// 64   FS1
// 65   FS2
// 66   FS3
// 67   FS4
// 68   FN1
// 69   FN2
// 70   FN3
// 71   FN4
<commit_msg>Commented out non science chips.<commit_after>#ifndef DECAM__HH
#define DECAM__HH

#include <string>
#include <vector>

namespace DECam
{

    /// @class Traits
    /// @brief Type information for the Dark Energy Camera.

    struct Traits
    {

        static const std::vector< std::string > frames;

        static bool frame_exists( const std::string& frame );

    };

}

const std::vector< std::string > DECam::Traits::frames( { "S1", "S2", "S3", "N1", "N2", "N3", "S8", "S9", "S14", "S15", "S20", "S25", "N8", "N9", "N14", "N15",
        "N20", "N25", "S10", "S11", "S12", "S13", "S18", "S19", "S16", "S17", "S21", "S22", "S23", "S24", "S26", "S27", "S28", "S29", "S30", "S31", "N4", "N5",
        "N6", "N7", "S4", "S5", "S6", "S7", "N10", "N11", "N12", "N13", "N18", "N19", "N16", "N17", "N21", "N22", "N23", "N24", "N26", "N27", "N28", "N29",
        "N30", "N31" } ); // , "FS1", "FS2", "FS3", "FS4", "FN1", "FN2", "FN3", "FN4" } );

inline bool DECam::Traits::frame_exists( const std::string& frame )
{
    return std::find( frames.begin(), frames.end(), frame ) != frames.end();
}

#endif

// HDU  usually
//      chip
//  2   S1
//  3   S2
//  4   S3
//  5   N1
//  6   N2
//  7   N3
//  8   S8
//  9   S9
// 10   S14
// 11   S15
// 12   S20
// 13   S25
// 14   N8
// 15   N9
// 16   N14
// 17   N15
// 18   N20
// 19   N25
// 20   S10
// 21   S11
// 22   S12
// 23   S13
// 24   S18
// 25   S19
// 26   S16
// 27   S17
// 28   S21
// 29   S22
// 30   S23
// 31   S24
// 32   S26
// 33   S27
// 34   S28
// 35   S29
// 36   S30
// 37   S31
// 38   N4
// 39   N5
// 40   N6
// 41   N7
// 42   S4
// 43   S5
// 44   S6
// 45   S7
// 46   N10
// 47   N11
// 48   N12
// 49   N13
// 50   N18
// 51   N19
// 52   N16
// 53   N17
// 54   N21
// 55   N22
// 56   N23
// 57   N24
// 58   N26
// 59   N27
// 60   N28
// 61   N29
// 62   N30
// 63   N31
// 64   FS1
// 65   FS2
// 66   FS3
// 67   FS4
// 68   FN1
// 69   FN2
// 70   FN3
// 71   FN4
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 <math.h>
#include <stdio.h>  // FIXME(brettw) erase me.
#ifndef _WIN32
#include <sys/time.h>
#endif
#include <time.h>

#include <algorithm>

#include "ppapi/c/dev/ppp_printing_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_input_event.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
#include "ppapi/cpp/graphics_2d.h"
#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/cpp/url_loader.h"
#include "ppapi/cpp/url_request_info.h"
#include "ppapi/cpp/var.h"

static const int kStepsPerCircle = 800;

void FlushCallback(void* data, int32_t result);

void FillRect(pp::ImageData* image, int left, int top, int width, int height,
              uint32_t color) {
  for (int y = std::max(0, top);
       y < std::min(image->size().height() - 1, top + height);
       y++) {
    for (int x = std::max(0, left);
         x < std::min(image->size().width() - 1, left + width);
         x++)
      *image->GetAddr32(pp::Point(x, y)) = color;
  }
}

class MyScriptableObject : public pp::deprecated::ScriptableObject {
 public:
  explicit MyScriptableObject(pp::Instance* instance) : instance_(instance) {}

  virtual bool HasMethod(const pp::Var& method, pp::Var* exception) {
    return method.AsString() == "toString";
  }

  virtual bool HasProperty(const pp::Var& name, pp::Var* exception) {
    if (name.is_string() && name.AsString() == "blah")
      return true;
    return false;
  }

  virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception) {
    if (name.is_string() && name.AsString() == "blah")
      return pp::Var(instance_, new MyScriptableObject(instance_));
    return pp::Var();
  }

  virtual void GetAllPropertyNames(std::vector<pp::Var>* names,
                                   pp::Var* exception) {
    names->push_back("blah");
  }

  virtual pp::Var Call(const pp::Var& method,
                       const std::vector<pp::Var>& args,
                       pp::Var* exception) {
    if (method.AsString() == "toString")
      return pp::Var("hello world");
    return pp::Var();
  }

 private:
  pp::Instance* instance_;
};

class MyFetcherClient {
 public:
  virtual void DidFetch(bool success, const std::string& data) = 0;
};

class MyFetcher {
 public:
  MyFetcher() : client_(NULL) {
    callback_factory_.Initialize(this);
  }

  void Start(const pp::Instance& instance,
             const pp::Var& url,
             MyFetcherClient* client) {
    pp::URLRequestInfo request;
    request.SetURL(url);
    request.SetMethod("GET");

    loader_ = pp::URLLoader(instance);
    client_ = client;

    pp::CompletionCallback callback =
        callback_factory_.NewCallback(&MyFetcher::DidOpen);
    int rv = loader_.Open(request, callback);
    if (rv != PP_ERROR_WOULDBLOCK)
      callback.Run(rv);
  }

  void StartWithOpenedLoader(const pp::URLLoader& loader,
                             MyFetcherClient* client) {
    loader_ = loader;
    client_ = client;

    ReadMore();
  }

 private:
  void ReadMore() {
    pp::CompletionCallback callback =
        callback_factory_.NewCallback(&MyFetcher::DidRead);
    int rv = loader_.ReadResponseBody(buf_, sizeof(buf_), callback);
    if (rv != PP_ERROR_WOULDBLOCK)
      callback.Run(rv);
  }

  void DidOpen(int32_t result) {
    if (result == PP_OK) {
      ReadMore();
    } else {
      DidFinish(result);
    }
  }

  void DidRead(int32_t result) {
    if (result > 0) {
      data_.append(buf_, result);
      ReadMore();
    } else {
      DidFinish(result);
    }
  }

  void DidFinish(int32_t result) {
    if (client_)
      client_->DidFetch(result == PP_OK, data_);
  }

  pp::CompletionCallbackFactory<MyFetcher> callback_factory_;
  pp::URLLoader loader_;
  MyFetcherClient* client_;
  char buf_[4096];
  std::string data_;
};

class MyInstance : public pp::Instance, public MyFetcherClient {
 public:
  MyInstance(PP_Instance instance)
      : pp::Instance(instance),
        time_at_last_check_(0.0),
        fetcher_(NULL),
        width_(0),
        height_(0),
        animation_counter_(0),
        print_settings_valid_(false) {}

  virtual ~MyInstance() {
    if (fetcher_) {
      delete fetcher_;
      fetcher_ = NULL;
    }
  }

  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
    return true;
  }

  virtual bool HandleDocumentLoad(const pp::URLLoader& loader) {
    fetcher_ = new MyFetcher();
    fetcher_->StartWithOpenedLoader(loader, this);
    return true;
  }

  virtual bool HandleInputEvent(const PP_InputEvent& event) {
    switch (event.type) {
      case PP_INPUTEVENT_TYPE_MOUSEDOWN:
        //SayHello();
        return true;
      case PP_INPUTEVENT_TYPE_MOUSEMOVE:
        return true;
      case PP_INPUTEVENT_TYPE_KEYDOWN:
        return true;
      default:
        return false;
    }
  }

  virtual pp::Var GetInstanceObject() {
    return pp::Var(this, new MyScriptableObject(this));
  }

  pp::ImageData PaintImage(int width, int height) {
    pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
                        pp::Size(width, height), false);
    if (image.is_null()) {
      printf("Couldn't allocate the image data\n");
      return image;
    }

    // Fill with semitransparent gradient.
    for (int y = 0; y < image.size().height(); y++) {
      char* row = &static_cast<char*>(image.data())[y * image.stride()];
      for (int x = 0; x < image.size().width(); x++) {
        row[x * 4 + 0] = y;
        row[x * 4 + 1] = y;
        row[x * 4 + 2] = 0;
        row[x * 4 + 3] = y;
      }
    }

    float radians = static_cast<float>(animation_counter_) / kStepsPerCircle *
        2 * 3.14159265358979F;

    float radius = static_cast<float>(std::min(width, height)) / 2.0f - 3.0f;
    int x = static_cast<int>(cos(radians) * radius + radius + 2);
    int y = static_cast<int>(sin(radians) * radius + radius + 2);

    FillRect(&image, x - 3, y - 3, 7, 7, 0x80000000);
    return image;
  }

  void Paint() {
    pp::ImageData image = PaintImage(width_, height_);
    if (!image.is_null()) {
      device_context_.ReplaceContents(&image);
      device_context_.Flush(pp::CompletionCallback(&FlushCallback, this));
    }
  }

  virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
    if (position.size().width() == width_ &&
        position.size().height() == height_)
      return;  // We don't care about the position, only the size.

    width_ = position.size().width();
    height_ = position.size().height();

    device_context_ = pp::Graphics2D(this, pp::Size(width_, height_), false);
    if (!BindGraphics(device_context_)) {
      printf("Couldn't bind the device context\n");
      return;
    }

    Paint();
  }

  void UpdateFps() {
// Time code doesn't currently compile on Windows, just skip FPS for now.
#ifndef _WIN32
    pp::Var window = GetWindowObject();
    pp::Var doc = window.GetProperty("document");
    pp::Var fps = doc.Call("getElementById", "fps");

    struct timeval tv;
    struct timezone tz = {0, 0};
    gettimeofday(&tv, &tz);

    double time_now = tv.tv_sec + tv.tv_usec / 1000000.0;

    if (animation_counter_ > 0) {
      char fps_text[64];
      sprintf(fps_text, "%g fps",
              kStepsPerCircle / (time_now - time_at_last_check_));
      fps.SetProperty("innerHTML", fps_text);
    }

    time_at_last_check_ = time_now;
#endif
  }

  // Print interfaces.
  virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats(
      uint32_t* format_count) {
    PP_PrintOutputFormat_Dev* format =
        reinterpret_cast<PP_PrintOutputFormat_Dev*>(
            pp::Module::Get()->core()->MemAlloc(
                sizeof(PP_PrintOutputFormat_Dev)));
    *format = PP_PRINTOUTPUTFORMAT_RASTER;
    *format_count = 1;
    return format;
  }

  virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) {
    if (print_settings_.format != PP_PRINTOUTPUTFORMAT_RASTER)
      return 0;

    print_settings_ = print_settings;
    print_settings_valid_ = true;
    return 1;
  }

  virtual pp::Resource PrintPages(
      const PP_PrintPageNumberRange_Dev* page_ranges,
      uint32_t page_range_count) {
    if (!print_settings_valid_)
      return pp::Resource();

    if (page_range_count != 1)
      return pp::Resource();

    // Check if the page numbers are valid. We returned 1 in PrintBegin so we
    // only have 1 page to print.
    if (page_ranges[0].first_page_number || page_ranges[0].last_page_number) {
      return pp::Resource();
    }

    int width = static_cast<int>(
        (print_settings_.printable_area.size.width / 72.0) *
         print_settings_.dpi);
    int height = static_cast<int>(
        (print_settings_.printable_area.size.height / 72.0) *
         print_settings_.dpi);

    return PaintImage(width, height);
  }

  virtual void PrintEnd() {
    print_settings_valid_ = false;
  }

  void OnFlush() {
    if (animation_counter_ % kStepsPerCircle == 0)
      UpdateFps();
    animation_counter_++;
    Paint();
  }

 private:
  void Log(const pp::Var& var) {
    pp::Var doc = GetWindowObject().GetProperty("document");
    if (console_.is_undefined()) {
      pp::Var body = doc.GetProperty("body");
      console_ = doc.Call("createElement", "pre");
      console_.GetProperty("style").SetProperty("backgroundColor", "lightgray");
      body.Call("appendChild", console_);
    }
    console_.Call("appendChild", doc.Call("createTextNode", var));
    console_.Call("appendChild", doc.Call("createTextNode", "\n"));
  }

  void SayHello() {
    pp::Var window = GetWindowObject();
    pp::Var doc = window.GetProperty("document");
    pp::Var body = doc.GetProperty("body");

    pp::Var obj(this, new MyScriptableObject(this));

    // Our object should have its toString method called.
    Log("Testing MyScriptableObject::toString():");
    Log(obj);

    // body.appendChild(body) should throw an exception
    Log("\nCalling body.appendChild(body):");
    pp::Var exception;
    body.Call("appendChild", body, &exception);
    Log(exception);

    Log("\nEnumeration of window properties:");
    std::vector<pp::Var> props;
    window.GetAllPropertyNames(&props);
    for (size_t i = 0; i < props.size(); ++i)
      Log(props[i]);

    pp::Var location = window.GetProperty("location");
    pp::Var href = location.GetProperty("href");

    if (!fetcher_) {
      fetcher_ = new MyFetcher();
      fetcher_->Start(*this, href, this);
    }
  }

  void DidFetch(bool success, const std::string& data) {
    Log("\nDownloaded location.href:");
    if (success) {
      Log(data);
    } else {
      Log("Failed to download.");
    }
    delete fetcher_;
    fetcher_ = NULL;
  }

  pp::Var console_;
  pp::Graphics2D device_context_;

  double time_at_last_check_;

  MyFetcher* fetcher_;

  int width_;
  int height_;

  // Incremented for each flush we get.
  int animation_counter_;
  bool print_settings_valid_;
  PP_PrintSettings_Dev print_settings_;
};

void FlushCallback(void* data, int32_t result) {
  static_cast<MyInstance*>(data)->OnFlush();
}

class MyModule : public pp::Module {
 public:
  MyModule() : pp::Module() {}
  virtual ~MyModule() {}

  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new MyInstance(instance);
  }
};

namespace pp {

// Factory function for your specialization of the Module object.
Module* CreateModule() {
  return new MyModule();
}

}  // namespace pp
<commit_msg>Added plugin size to error logging and a logging statement when the plugin size changes. I found these changes useful while debugging issues when modifying the plugin.<commit_after>// Copyright (c) 2010 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 <math.h>
#include <stdio.h>  // FIXME(brettw) erase me.
#ifndef _WIN32
#include <sys/time.h>
#endif
#include <time.h>

#include <algorithm>

#include "ppapi/c/dev/ppp_printing_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_input_event.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
#include "ppapi/cpp/graphics_2d.h"
#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/cpp/url_loader.h"
#include "ppapi/cpp/url_request_info.h"
#include "ppapi/cpp/var.h"

static const int kStepsPerCircle = 800;

void FlushCallback(void* data, int32_t result);

void FillRect(pp::ImageData* image, int left, int top, int width, int height,
              uint32_t color) {
  for (int y = std::max(0, top);
       y < std::min(image->size().height() - 1, top + height);
       y++) {
    for (int x = std::max(0, left);
         x < std::min(image->size().width() - 1, left + width);
         x++)
      *image->GetAddr32(pp::Point(x, y)) = color;
  }
}

class MyScriptableObject : public pp::deprecated::ScriptableObject {
 public:
  explicit MyScriptableObject(pp::Instance* instance) : instance_(instance) {}

  virtual bool HasMethod(const pp::Var& method, pp::Var* exception) {
    return method.AsString() == "toString";
  }

  virtual bool HasProperty(const pp::Var& name, pp::Var* exception) {
    if (name.is_string() && name.AsString() == "blah")
      return true;
    return false;
  }

  virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception) {
    if (name.is_string() && name.AsString() == "blah")
      return pp::Var(instance_, new MyScriptableObject(instance_));
    return pp::Var();
  }

  virtual void GetAllPropertyNames(std::vector<pp::Var>* names,
                                   pp::Var* exception) {
    names->push_back("blah");
  }

  virtual pp::Var Call(const pp::Var& method,
                       const std::vector<pp::Var>& args,
                       pp::Var* exception) {
    if (method.AsString() == "toString")
      return pp::Var("hello world");
    return pp::Var();
  }

 private:
  pp::Instance* instance_;
};

class MyFetcherClient {
 public:
  virtual void DidFetch(bool success, const std::string& data) = 0;
};

class MyFetcher {
 public:
  MyFetcher() : client_(NULL) {
    callback_factory_.Initialize(this);
  }

  void Start(const pp::Instance& instance,
             const pp::Var& url,
             MyFetcherClient* client) {
    pp::URLRequestInfo request;
    request.SetURL(url);
    request.SetMethod("GET");

    loader_ = pp::URLLoader(instance);
    client_ = client;

    pp::CompletionCallback callback =
        callback_factory_.NewCallback(&MyFetcher::DidOpen);
    int rv = loader_.Open(request, callback);
    if (rv != PP_ERROR_WOULDBLOCK)
      callback.Run(rv);
  }

  void StartWithOpenedLoader(const pp::URLLoader& loader,
                             MyFetcherClient* client) {
    loader_ = loader;
    client_ = client;

    ReadMore();
  }

 private:
  void ReadMore() {
    pp::CompletionCallback callback =
        callback_factory_.NewCallback(&MyFetcher::DidRead);
    int rv = loader_.ReadResponseBody(buf_, sizeof(buf_), callback);
    if (rv != PP_ERROR_WOULDBLOCK)
      callback.Run(rv);
  }

  void DidOpen(int32_t result) {
    if (result == PP_OK) {
      ReadMore();
    } else {
      DidFinish(result);
    }
  }

  void DidRead(int32_t result) {
    if (result > 0) {
      data_.append(buf_, result);
      ReadMore();
    } else {
      DidFinish(result);
    }
  }

  void DidFinish(int32_t result) {
    if (client_)
      client_->DidFetch(result == PP_OK, data_);
  }

  pp::CompletionCallbackFactory<MyFetcher> callback_factory_;
  pp::URLLoader loader_;
  MyFetcherClient* client_;
  char buf_[4096];
  std::string data_;
};

class MyInstance : public pp::Instance, public MyFetcherClient {
 public:
  MyInstance(PP_Instance instance)
      : pp::Instance(instance),
        time_at_last_check_(0.0),
        fetcher_(NULL),
        width_(0),
        height_(0),
        animation_counter_(0),
        print_settings_valid_(false) {}

  virtual ~MyInstance() {
    if (fetcher_) {
      delete fetcher_;
      fetcher_ = NULL;
    }
  }

  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
    return true;
  }

  virtual bool HandleDocumentLoad(const pp::URLLoader& loader) {
    fetcher_ = new MyFetcher();
    fetcher_->StartWithOpenedLoader(loader, this);
    return true;
  }

  virtual bool HandleInputEvent(const PP_InputEvent& event) {
    switch (event.type) {
      case PP_INPUTEVENT_TYPE_MOUSEDOWN:
        //SayHello();
        return true;
      case PP_INPUTEVENT_TYPE_MOUSEMOVE:
        return true;
      case PP_INPUTEVENT_TYPE_KEYDOWN:
        return true;
      default:
        return false;
    }
  }

  virtual pp::Var GetInstanceObject() {
    return pp::Var(this, new MyScriptableObject(this));
  }

  pp::ImageData PaintImage(int width, int height) {
    pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
                        pp::Size(width, height), false);
    if (image.is_null()) {
      printf("Couldn't allocate the image data: %d, %d\n", width, height);
      return image;
    }

    // Fill with semitransparent gradient.
    for (int y = 0; y < image.size().height(); y++) {
      char* row = &static_cast<char*>(image.data())[y * image.stride()];
      for (int x = 0; x < image.size().width(); x++) {
        row[x * 4 + 0] = y;
        row[x * 4 + 1] = y;
        row[x * 4 + 2] = 0;
        row[x * 4 + 3] = y;
      }
    }

    // Draw the orbiting box.
    float radians = static_cast<float>(animation_counter_) / kStepsPerCircle *
        2 * 3.14159265358979F;

    float radius = static_cast<float>(std::min(width, height)) / 2.0f - 3.0f;
    int x = static_cast<int>(cos(radians) * radius + radius + 2);
    int y = static_cast<int>(sin(radians) * radius + radius + 2);

    const uint32_t box_bgra = 0x80000000;  // Alpha 50%.
    FillRect(&image, x - 3, y - 3, 7, 7, box_bgra);
    return image;
  }

  void Paint() {
    pp::ImageData image = PaintImage(width_, height_);
    if (!image.is_null()) {
      device_context_.ReplaceContents(&image);
      device_context_.Flush(pp::CompletionCallback(&FlushCallback, this));
    } else {
      printf("NullImage: %d, %d\n", width_, height_);
    }
  }

  virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
    if (position.size().width() == width_ &&
        position.size().height() == height_)
      return;  // We don't care about the position, only the size.

    width_ = position.size().width();
    height_ = position.size().height();
    printf("DidChangeView relevant change: width=%d height:%d\n",
           width_, height_);

    device_context_ = pp::Graphics2D(this, pp::Size(width_, height_), false);
    if (!BindGraphics(device_context_)) {
      printf("Couldn't bind the device context\n");
      return;
    }

    Paint();
  }

  void UpdateFps() {
// Time code doesn't currently compile on Windows, just skip FPS for now.
#ifndef _WIN32
    pp::Var window = GetWindowObject();
    pp::Var doc = window.GetProperty("document");
    pp::Var fps = doc.Call("getElementById", "fps");

    struct timeval tv;
    struct timezone tz = {0, 0};
    gettimeofday(&tv, &tz);

    double time_now = tv.tv_sec + tv.tv_usec / 1000000.0;

    if (animation_counter_ > 0) {
      char fps_text[64];
      sprintf(fps_text, "%g fps",
              kStepsPerCircle / (time_now - time_at_last_check_));
      fps.SetProperty("innerHTML", fps_text);
    }

    time_at_last_check_ = time_now;
#endif
  }

  // Print interfaces.
  virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats(
      uint32_t* format_count) {
    PP_PrintOutputFormat_Dev* format =
        reinterpret_cast<PP_PrintOutputFormat_Dev*>(
            pp::Module::Get()->core()->MemAlloc(
                sizeof(PP_PrintOutputFormat_Dev)));
    *format = PP_PRINTOUTPUTFORMAT_RASTER;
    *format_count = 1;
    return format;
  }

  virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) {
    if (print_settings_.format != PP_PRINTOUTPUTFORMAT_RASTER)
      return 0;

    print_settings_ = print_settings;
    print_settings_valid_ = true;
    return 1;
  }

  virtual pp::Resource PrintPages(
      const PP_PrintPageNumberRange_Dev* page_ranges,
      uint32_t page_range_count) {
    if (!print_settings_valid_)
      return pp::Resource();

    if (page_range_count != 1)
      return pp::Resource();

    // Check if the page numbers are valid. We returned 1 in PrintBegin so we
    // only have 1 page to print.
    if (page_ranges[0].first_page_number || page_ranges[0].last_page_number) {
      return pp::Resource();
    }

    int width = static_cast<int>(
        (print_settings_.printable_area.size.width / 72.0) *
         print_settings_.dpi);
    int height = static_cast<int>(
        (print_settings_.printable_area.size.height / 72.0) *
         print_settings_.dpi);

    return PaintImage(width, height);
  }

  virtual void PrintEnd() {
    print_settings_valid_ = false;
  }

  void OnFlush() {
    if (animation_counter_ % kStepsPerCircle == 0)
      UpdateFps();
    animation_counter_++;
    Paint();
  }

 private:
  void Log(const pp::Var& var) {
    pp::Var doc = GetWindowObject().GetProperty("document");
    if (console_.is_undefined()) {
      pp::Var body = doc.GetProperty("body");
      console_ = doc.Call("createElement", "pre");
      console_.GetProperty("style").SetProperty("backgroundColor", "lightgray");
      body.Call("appendChild", console_);
    }
    console_.Call("appendChild", doc.Call("createTextNode", var));
    console_.Call("appendChild", doc.Call("createTextNode", "\n"));
  }

  void SayHello() {
    pp::Var window = GetWindowObject();
    pp::Var doc = window.GetProperty("document");
    pp::Var body = doc.GetProperty("body");

    pp::Var obj(this, new MyScriptableObject(this));

    // Our object should have its toString method called.
    Log("Testing MyScriptableObject::toString():");
    Log(obj);

    // body.appendChild(body) should throw an exception
    Log("\nCalling body.appendChild(body):");
    pp::Var exception;
    body.Call("appendChild", body, &exception);
    Log(exception);

    Log("\nEnumeration of window properties:");
    std::vector<pp::Var> props;
    window.GetAllPropertyNames(&props);
    for (size_t i = 0; i < props.size(); ++i)
      Log(props[i]);

    pp::Var location = window.GetProperty("location");
    pp::Var href = location.GetProperty("href");

    if (!fetcher_) {
      fetcher_ = new MyFetcher();
      fetcher_->Start(*this, href, this);
    }
  }

  void DidFetch(bool success, const std::string& data) {
    Log("\nDownloaded location.href:");
    if (success) {
      Log(data);
    } else {
      Log("Failed to download.");
    }
    delete fetcher_;
    fetcher_ = NULL;
  }

  pp::Var console_;
  pp::Graphics2D device_context_;

  double time_at_last_check_;

  MyFetcher* fetcher_;

  int width_;
  int height_;

  // Incremented for each flush we get.
  int animation_counter_;
  bool print_settings_valid_;
  PP_PrintSettings_Dev print_settings_;
};

void FlushCallback(void* data, int32_t result) {
  static_cast<MyInstance*>(data)->OnFlush();
}

class MyModule : public pp::Module {
 public:
  MyModule() : pp::Module() {}
  virtual ~MyModule() {}

  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new MyInstance(instance);
  }
};

namespace pp {

// Factory function for your specialization of the Module object.
Module* CreateModule() {
  return new MyModule();
}

}  // namespace pp
<|endoftext|>