<commit_before>#ifndef BITS_HPP
#define BITS_HPP

#include <cstdint>
#ifdef _MSC_VER
#  include <intrin.h>
#endif

#if defined(__GNUC__)
static int
popcnt(std::uint8_t n)
{
  return __builtin_popcount(n);
}

static int
popcnt(std::uint16_t n)
{
  return __builtin_popcount(n);
}

static int
popcnt(std::uint32_t n)
{
  return __builtin_popcount(n);
}

static int
popcnt(std::uint64_t n)
{
  return __builtin_popcountll(n);
}

#elif defined(_MSC_VER)
static int
popcnt(std::uint8_t n)
{
  return __popcnt16(n);
}

static int
popcnt(std::uint16_t n)
{
  return __popcnt16(n);
}

static int
popcnt(std::uint32_t n)
{
  return __popcnt(n);
}

static int
popcnt(std::uint64_t n)
{
  return __popcnt64(n);
}
#endif  // __GNUC__

// 0x55555555 = 0b01010101010101010101010101010101
// 0x33333333 = 0b00110011001100110011001100110011
// 0x0f0f0f0f = 0b00001111000011110000111100001111
// 0x00ff00ff = 0b00000000111111110000000011111111
// 0x0000ffff = 0b00000000000000001111111111111111

static int
popcnt(std::uint8_t n)
{
  n = (n & 0x55u) + (n >> 1 & 0x55u);
  n = (n & 0x33u) + (n >> 2 & 0x33u);
  return (n & 0x0fu) + (n >> 4 & 0x0fu);
}

static int
popcnt(std::uint16_t n)
{
  n = (n & 0x5555u) + (n >> 1 & 0x5555u);
  n = (n & 0x3333u) + (n >> 2 & 0x3333u);
  n = (n & 0x0f0fu) + (n >> 4 & 0x0f0fu);
  return (n & 0x00ffu) + (n >> 8 & 0x00ffu);
}

static int
popcnt(std::uint32_t n)
{
  n = (n & 0x55555555u) + (n >> 1 & 0x55555555u);
  n = (n & 0x33333333u) + (n >> 2 & 0x33333333u);
  n = (n & 0x0f0f0f0fu) + (n >> 4 & 0x0f0f0f0fu);
  n = (n & 0x00ff00ffu) + (n >> 8 & 0x00ff00ffu);
  return (n & 0x0000ffffu) + (n >> 16 & 0x0000ffffu);
}

static int
popcnt(std::uint64_t n)
{
  n = (n & 0x5555555555555555ull) + (n >> 1 & 0x5555555555555555ull);
  n = (n & 0x3333333333333333ull) + (n >> 2 & 0x3333333333333333ull);
  n = (n & 0x0f0f0f0f0f0f0f0full) + (n >> 4 & 0x0f0f0f0f0f0f0f0full);
  n = (n & 0x00ff00ff00ff00ffull) + (n >> 8 & 0x00ff00ff00ff00ffull);
  n = (n & 0x0000ffff0000ffffull) + (n >> 16 & 0x0000ffff0000ffffull);
  return (n & 0x00000000ffffffffull) + (n >> 32 & 0x00000000ffffffffull);
}

static int
popcnt(std::int8_t n)
{
  return popcnt(static_cast<std::uint8_t>(n));
}

static int
popcnt(std::int16_t n)
{
  return popcnt(static_cast<std::uint16_t>(n));
}

static int
popcnt(std::int32_t n)
{
  return popcnt(static_cast<std::uint32_t>(n));
}

static int
popcnt(std::int64_t n)
{
  return popcnt(static_cast<std::uint64_t>(n));
}

#if defined(__GNUC__)
static int
bsf(std::uint8_t n)
{
  return __builtin_ffs(n) - 1;
}

static int
bsf(std::uint16_t n)
{
  return __builtin_ffs(n) - 1;
}

static int
bsf(std::uint32_t n)
{
  return __builtin_ffs(n) - 1;
}

static int
bsf(std::uint64_t n)
{
  return __builtin_ffsll(n) - 1;
}

#elif defined(_MSC_VER)
static int
bsf(std::uint8_t n)
{
  int index;
  unsigned char isNonZero = _BitScanForward(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static int
bsf(std::uint16_t n)
{
  int index;
  unsigned char isNonZero = _BitScanForward(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static int
bsf(std::uint32_t n)
{
  int index;
  unsigned char isNonZero = _BitScanForward(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static int
bsf(std::uint64_t n)
{
  int index;
  unsigned char isNonZero = _BitScanForward64(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}
#endif  // defined(__GNUC__)

static int
bsf(std::uint8_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n << 1);
    n |= (n << 2);
    n |= (n << 4);
    return popcnt(static_cast<std::uint8_t>(~n));
  }
}

static int
bsf(std::uint16_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n << 1);
    n |= (n << 2);
    n |= (n << 4);
    n |= (n << 8);
    return popcnt(static_cast<std::uint16_t>(~n));
  }
}

static int
bsf(std::uint32_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n << 1);
    n |= (n << 2);
    n |= (n << 4);
    n |= (n << 8);
    n |= (n << 16);
    return popcnt(~n);
  }
}

static int
bsf(std::uint64_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n << 1);
    n |= (n << 2);
    n |= (n << 4);
    n |= (n << 8);
    n |= (n << 16);
    n |= (n << 32);
    return popcnt(~n);
  }
}

static int
bsf(std::int8_t n)
{
  return bsf(static_cast<std::uint8_t>(n));
}

static int
bsf(std::int16_t n)
{
  return bsf(static_cast<std::uint16_t>(n));
}

static int
bsf(std::int32_t n)
{
  return bsf(static_cast<std::uint32_t>(n));
}

static int
bsf(std::int64_t n)
{
  return bsf(static_cast<std::uint64_t>(n));
}

#if defined(__GNUC__)
static int
bsr(std::uint8_t n)
{
  return n == 0 ? -1 : (((__builtin_clz(n) & 0x07u) ^ 0x07u));
}

static int
bsr(std::uint16_t n)
{
  return n == 0 ? -1 : (((__builtin_clz(n) & 0x0fu) ^ 0x0fu));
}

static int
bsr(std::uint32_t n)
{
  return n == 0 ? -1 : (__builtin_clz(n) ^ 0x1fu);
}

static int
bsr(std::uint64_t n)
{
  return n == 0 ? -1 : (__builtin_clzll(n) ^ 0x3fu);
}

#elif defined(_MSC_VER)
static int
bsr(std::uint8_t n)
{
  int index;
  unsigned char isNonZero = _BitScanReverse(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static int
bsr(std::uint16_t n)
{
  int index;
  unsigned char isNonZero = _BitScanReverse(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static int
bsr(std::uint32_t n)
{
  int index;
  unsigned char isNonZero = _BitScanReverse(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static int
bsr(std::uint64_t n)
{
  int index;
  unsigned char isNonZero = _BitScanReverse64(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}
#endif  // defined(__GNUC__)

static int
bsr(std::uint8_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    return popcnt(n) - 1;
  }
}

static int
bsr(std::uint16_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    return popcnt(n) - 1;
  }
}

static int
bsr(std::uint32_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    n |= (n >> 16);
    return popcnt(n) - 1;
  }
}

static int
bsr(std::uint64_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    n |= (n >> 16);
    n |= (n >> 32);
    return popcnt(n) - 1;
  }
}

static int
bsr(std::int8_t n)
{
  return bsr(static_cast<std::uint8_t>(n));
}

static int
bsr(std::int16_t n)
{
  return bsr(static_cast<std::uint16_t>(n));
}

static int
bsr(std::int32_t n)
{
  return bsr(static_cast<std::uint32_t>(n));
}

static int
bsr(std::int64_t n)
{
  return bsr(static_cast<std::uint64_t>(n));
}

#endif  // BITS_HPP
<commit_msg>Use SFINAE and std::make_unsigned<commit_after>#ifndef BITS_HPP
#define BITS_HPP

#include <cstdint>
#include <type_traits>
#ifdef _MSC_VER
#  include <intrin.h>
#endif

#if defined(__GNUC__)
static inline int
popcnt(std::uint8_t n)
{
  return __builtin_popcount(n);
}

static inline int
popcnt(std::uint16_t n)
{
  return __builtin_popcount(n);
}

static inline int
popcnt(std::uint32_t n)
{
  return __builtin_popcount(n);
}

static inline int
popcnt(std::uint64_t n)
{
  return __builtin_popcountll(n);
}

#elif defined(_MSC_VER)
static inline int
popcnt(std::uint8_t n)
{
  return __popcnt16(n);
}

static inline int
popcnt(std::uint16_t n)
{
  return __popcnt16(n);
}

static inline int
popcnt(std::uint32_t n)
{
  return __popcnt(n);
}

static inline int
popcnt(std::uint64_t n)
{
  return __popcnt64(n);
}
#else

// 0x55555555 = 0b01010101010101010101010101010101
// 0x33333333 = 0b00110011001100110011001100110011
// 0x0f0f0f0f = 0b00001111000011110000111100001111
// 0x00ff00ff = 0b00000000111111110000000011111111
// 0x0000ffff = 0b00000000000000001111111111111111

static inline int
popcnt(std::uint8_t n)
{
  n = (n & 0x55u) + (n >> 1 & 0x55u);
  n = (n & 0x33u) + (n >> 2 & 0x33u);
  return (n & 0x0fu) + (n >> 4 & 0x0fu);
}

static inline int
popcnt(std::uint16_t n)
{
  n = (n & 0x5555u) + (n >> 1 & 0x5555u);
  n = (n & 0x3333u) + (n >> 2 & 0x3333u);
  n = (n & 0x0f0fu) + (n >> 4 & 0x0f0fu);
  return (n & 0x00ffu) + (n >> 8 & 0x00ffu);
}

static inline int
popcnt(std::uint32_t n)
{
  n = (n & 0x55555555u) + (n >> 1 & 0x55555555u);
  n = (n & 0x33333333u) + (n >> 2 & 0x33333333u);
  n = (n & 0x0f0f0f0fu) + (n >> 4 & 0x0f0f0f0fu);
  n = (n & 0x00ff00ffu) + (n >> 8 & 0x00ff00ffu);
  return (n & 0x0000ffffu) + (n >> 16 & 0x0000ffffu);
}

static inline int
popcnt(std::uint64_t n)
{
  n = (n & 0x5555555555555555ull) + (n >> 1 & 0x5555555555555555ull);
  n = (n & 0x3333333333333333ull) + (n >> 2 & 0x3333333333333333ull);
  n = (n & 0x0f0f0f0f0f0f0f0full) + (n >> 4 & 0x0f0f0f0f0f0f0f0full);
  n = (n & 0x00ff00ff00ff00ffull) + (n >> 8 & 0x00ff00ff00ff00ffull);
  n = (n & 0x0000ffff0000ffffull) + (n >> 16 & 0x0000ffff0000ffffull);
  return (n & 0x00000000ffffffffull) + (n >> 32 & 0x00000000ffffffffull);
}
#endif  // __GNUC__

template<typename T, typename std::enable_if<std::is_signed<T>::value, std::nullptr_t>::type = nullptr>
static inline int
popcnt(T n)
{
  return popcnt(static_cast<typename std::make_unsigned<T>::type>(n));
}

#if defined(__GNUC__)
static inline int
bsf(std::uint8_t n)
{
  return __builtin_ffs(n) - 1;
}

static inline int
bsf(std::uint16_t n)
{
  return __builtin_ffs(n) - 1;
}

static inline int
bsf(std::uint32_t n)
{
  return __builtin_ffs(n) - 1;
}

static inline int
bsf(std::uint64_t n)
{
  return __builtin_ffsll(n) - 1;
}

#elif defined(_MSC_VER)
static inline int
bsf(std::uint8_t n)
{
  int index;
  unsigned char isNonZero = _BitScanForward(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static inline int
bsf(std::uint16_t n)
{
  int index;
  unsigned char isNonZero = _BitScanForward(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static inline int
bsf(std::uint32_t n)
{
  int index;
  unsigned char isNonZero = _BitScanForward(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static inline int
bsf(std::uint64_t n)
{
  int index;
  unsigned char isNonZero = _BitScanForward64(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}
#else

static inline int
bsf(std::uint8_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n << 1);
    n |= (n << 2);
    n |= (n << 4);
    return popcnt(static_cast<std::uint8_t>(~n));
  }
}

static inline int
bsf(std::uint16_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n << 1);
    n |= (n << 2);
    n |= (n << 4);
    n |= (n << 8);
    return popcnt(static_cast<std::uint16_t>(~n));
  }
}

static inline int
bsf(std::uint32_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n << 1);
    n |= (n << 2);
    n |= (n << 4);
    n |= (n << 8);
    n |= (n << 16);
    return popcnt(~n);
  }
}

static inline int
bsf(std::uint64_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n << 1);
    n |= (n << 2);
    n |= (n << 4);
    n |= (n << 8);
    n |= (n << 16);
    n |= (n << 32);
    return popcnt(~n);
  }
}
#endif  // defined(__GNUC__)

template<typename T, typename std::enable_if<std::is_signed<T>::value, std::nullptr_t>::type = nullptr>
static inline int
bfs(T n)
{
  return bfs(static_cast<typename std::make_unsigned<T>::type>(n));
}

#if defined(__GNUC__)
static inline int
bsr(std::uint8_t n)
{
  return n == 0 ? -1 : (((__builtin_clz(n) & 0x07u) ^ 0x07u));
}

static inline int
bsr(std::uint16_t n)
{
  return n == 0 ? -1 : (((__builtin_clz(n) & 0x0fu) ^ 0x0fu));
}

static inline int
bsr(std::uint32_t n)
{
  return n == 0 ? -1 : (__builtin_clz(n) ^ 0x1fu);
}

static inline int
bsr(std::uint64_t n)
{
  return n == 0 ? -1 : (__builtin_clzll(n) ^ 0x3fu);
}

#elif defined(_MSC_VER)
static inline int
bsr(std::uint8_t n)
{
  int index;
  unsigned char isNonZero = _BitScanReverse(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static inline int
bsr(std::uint16_t n)
{
  int index;
  unsigned char isNonZero = _BitScanReverse(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static inline int
bsr(std::uint32_t n)
{
  int index;
  unsigned char isNonZero = _BitScanReverse(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}

static inline int
bsr(std::uint64_t n)
{
  int index;
  unsigned char isNonZero = _BitScanReverse64(reinterpret_cast<unsigned long *>(&index), n);
  return isNonZero ? index : -1;
}
#else

static inline int
bsr(std::uint8_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    return popcnt(n) - 1;
  }
}

static inline int
bsr(std::uint16_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    return popcnt(n) - 1;
  }
}

static inline int
bsr(std::uint32_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    n |= (n >> 16);
    return popcnt(n) - 1;
  }
}

static inline int
bsr(std::uint64_t n)
{
  if (n == 0) {
    return -1;
  } else {
    n |= (n >> 1);
    n |= (n >> 2);
    n |= (n >> 4);
    n |= (n >> 8);
    n |= (n >> 16);
    n |= (n >> 32);
    return popcnt(n) - 1;
  }
}
#endif  // defined(__GNUC__)

template<typename T, typename std::enable_if<std::is_signed<T>::value, std::nullptr_t>::type = nullptr>
static inline int
bsr(T n)
{
  return bsr(static_cast<typename std::make_unsigned<T>::type>(n));
}

#endif  // BITS_HPP
<|endoftext|>


<commit_before>/*****************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2011 Laszlo Papp <djszapi@archlinux.us>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *****************************************************************************/

#include "gamewindowmanager.h"

#include "lib/models/gameviewitem.h"
#include "lib/models/gameitemsmodel.h"
#include "lib/models/commentitemsmodel.h"
#include "lib/authentication.h"

#include <input/inputmanager.h>
#include <engine/scene.h>
#include <graphics/renderwidget.h>

#include <QtDeclarative/QDeclarativeView>
#include <QtDeclarative/QDeclarativeContext>
#include <QtDeclarative>
#include <QtGui/QGraphicsObject>
#include <QtGui/QApplication>
#include <QtGui/QStackedWidget>
#include <QtCore/QTimer>
#include <QtCore/QDebug>

using namespace GluonQMLPlayer;

class GameWindowManager::GameWindowManagerPrivate
{
    public:
        GameWindowManagerPrivate()
            : stackedWidget( new QStackedWidget( 0 ) )
            , gameItemsModel( new GluonPlayer::GameItemsModel() )
            , commentItemsModel( 0 )
            , auth( 0 )
            , declarativeView( new QDeclarativeView(stackedWidget) )
            , renderWidget( new GluonGraphics::RenderWidget(stackedWidget) )
            , ctxt( 0 )
        {
        }

        ~GameWindowManagerPrivate()
        {
            delete stackedWidget;
            delete gameItemsModel;
            delete commentItemsModel;
        }

        QString title;
        QString fileName;

        int msecElapsed;
        int frameCount;

        QStackedWidget *stackedWidget;
        GluonPlayer::GameItemsModel *gameItemsModel;
        GluonPlayer::CommentItemsModel *commentItemsModel;
        GluonPlayer::Authentication* auth;

        QDeclarativeView *declarativeView;
        GluonGraphics::RenderWidget* renderWidget;
        QDeclarativeContext *ctxt;
        QObject* rootObj;
        QObject* login;
};

GameWindowManager::GameWindowManager( const QString& /* filename */ )
    : QObject()
    , d( new GameWindowManagerPrivate )
{
    d->auth = GluonPlayer::Authentication::instance();
    d->renderWidget->initializeGL();

    d->ctxt = d->declarativeView->rootContext();
    d->ctxt->setContextProperty( "authentication", d->auth );
    d->ctxt->setContextProperty( "gameItemsModel", d->gameItemsModel );
    d->ctxt->setContextProperty( "commentItemsModel", d->commentItemsModel );
    d->ctxt->setContextProperty( "gameWindowManager", this );

    // Note QML enum handling is more or less bonkers at the moment
    // It should be removed after the QML enum support is not that flaky
    qmlRegisterUncreatableType<GluonPlayer::GameViewItem>("GluonPlayerGameViewItem", 1, 0, "GameViewItem", QString("Support the Status enumeration"));

    d->declarativeView->setSource( QUrl( "qrc:/main.qml" ) );

    d->rootObj = d->declarativeView->rootObject();
    d->login = d->rootObj->findChild<QObject*>( "login" );
    QObject::connect( d->auth, SIGNAL( initialized() ), d->login, SLOT( providerSet() ) );

    d->stackedWidget->addWidget(d->declarativeView);
    d->stackedWidget->addWidget(d->renderWidget);
    d->stackedWidget->setCurrentIndex(0);
    connect(QApplication::instance(), SIGNAL(lastWindowClosed()), GluonEngine::Game::instance(), SLOT( stopGame()));
}

GameWindowManager::~GameWindowManager ( )
{
    delete d;
}

bool GameWindowManager::isViewportGLWidget( )
{
    return qobject_cast<QGLWidget*>(d->declarativeView);
}

void GameWindowManager::startGame( )
{
    GluonCore::GluonObjectFactory::instance()->loadPlugins();

    m_project = new GluonEngine::GameProject();
    m_project->loadFromFile( m_gameFileName );

    GluonEngine::Game::instance()->setGameProject( m_project );
    GluonEngine::Game::instance()->setCurrentScene( m_project->entryPoint() );

    d->stackedWidget->setCurrentIndex(1);
    d->renderWidget->setFocus();
    GluonEngine::Game::instance()->runGame();
}

void GameWindowManager::pauseGame()
{
    GluonEngine::Game::instance()->setPause( true );
    // stateChanged( "paused" );
}

void GameWindowManager::stopGame()
{
    // d->stackedWidget->setCurrentIndex(0);
    GluonEngine::Game::instance()->stopGame();
}

void GameWindowManager::setProject( int index )
{
    m_gameFileName = d->gameItemsModel->index(index).data(GluonPlayer::GameItemsModel::ProjectFileNameRole).toString();
    openProject();
}

int GameWindowManager::availableGamesCount( ) const
{
    return d->gameItemsModel->rowCount();
}

void GameWindowManager::buildCommentsModel( int index )
{
    QString gameID = d->gameItemsModel->index(index).data(GluonPlayer::GameItemsModel::IDRole).toString();
    if( gameID.isEmpty() )
    {
        return;
    }

    d->commentItemsModel = new GluonPlayer::CommentItemsModel( gameID );
}

void GameWindowManager::setProject( const QModelIndex& index )
{
    m_gameFileName = index.data(GluonPlayer::GameItemsModel::ProjectFileNameRole).toString();
    openProject();
}

void GameWindowManager::openProject()
{
    if( m_gameFileName.isEmpty() )
    {
        return;
    }

    connect( GluonEngine::Game::instance(), SIGNAL( painted( int ) ), d->renderWidget, SLOT( updateGL() ) );
    connect( GluonEngine::Game::instance(), SIGNAL( painted( int ) ), SLOT( countFrames( int ) ) );
    connect( GluonEngine::Game::instance(), SIGNAL( updated( int ) ), SLOT( updateTitle( int ) ) );

    GluonInput::InputManager::instance()->setFilteredObject(d->renderWidget);
    QTimer::singleShot( 1000, this, SLOT( startGame() ) );
}

void GameWindowManager::activated( QModelIndex index )
{
    if( index.isValid() )
    {
    }
}

void GameWindowManager::updateTitle( int msec )
{
    d->msecElapsed += msec;

    static int fps = 0;
    if( d->msecElapsed > 1000 )
    {
        fps = d->frameCount;
        d->frameCount = 0;
        d->msecElapsed = 0;
    }
}

void GameWindowManager::countFrames( int /* time */ )
{
    d->frameCount++;
}

GluonPlayer::GameItemsModel* GameWindowManager::gameItemsModel() const
{
    return d->gameItemsModel;
}

void GameWindowManager::setGameItemsModel(GluonPlayer::GameItemsModel* gameItemsModel)
{
    d->gameItemsModel = gameItemsModel;
}

GluonPlayer::CommentItemsModel* GameWindowManager::commentItemsModel() const
{
    return d->commentItemsModel;
}

void GameWindowManager::setCommentItemsModel(GluonPlayer::CommentItemsModel* commentItemsModel)
{
    d->commentItemsModel = commentItemsModel;
}

void GameWindowManager::show()
{
    d->stackedWidget->show();
}

#include "gamewindowmanager.moc"
<commit_msg>Use setCurrentWidget instead of setCurrentIndex to avoid numbers<commit_after>/*****************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2011 Laszlo Papp <djszapi@archlinux.us>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *****************************************************************************/

#include "gamewindowmanager.h"

#include "lib/models/gameviewitem.h"
#include "lib/models/gameitemsmodel.h"
#include "lib/models/commentitemsmodel.h"
#include "lib/authentication.h"

#include <input/inputmanager.h>
#include <engine/scene.h>
#include <graphics/renderwidget.h>

#include <QtDeclarative/QDeclarativeView>
#include <QtDeclarative/QDeclarativeContext>
#include <QtDeclarative>
#include <QtGui/QGraphicsObject>
#include <QtGui/QApplication>
#include <QtGui/QStackedWidget>
#include <QtCore/QTimer>
#include <QtCore/QDebug>

using namespace GluonQMLPlayer;

class GameWindowManager::GameWindowManagerPrivate
{
    public:
        GameWindowManagerPrivate()
            : stackedWidget( new QStackedWidget( 0 ) )
            , gameItemsModel( new GluonPlayer::GameItemsModel() )
            , commentItemsModel( 0 )
            , auth( 0 )
            , declarativeView( new QDeclarativeView(stackedWidget) )
            , renderWidget( new GluonGraphics::RenderWidget(stackedWidget) )
            , ctxt( 0 )
        {
        }

        ~GameWindowManagerPrivate()
        {
            delete stackedWidget;
            delete gameItemsModel;
            delete commentItemsModel;
        }

        QString title;
        QString fileName;

        int msecElapsed;
        int frameCount;

        QStackedWidget *stackedWidget;
        GluonPlayer::GameItemsModel *gameItemsModel;
        GluonPlayer::CommentItemsModel *commentItemsModel;
        GluonPlayer::Authentication* auth;

        QDeclarativeView *declarativeView;
        GluonGraphics::RenderWidget* renderWidget;
        QDeclarativeContext *ctxt;
        QObject* rootObj;
        QObject* login;
};

GameWindowManager::GameWindowManager( const QString& /* filename */ )
    : QObject()
    , d( new GameWindowManagerPrivate )
{
    d->auth = GluonPlayer::Authentication::instance();
    d->renderWidget->initializeGL();

    d->ctxt = d->declarativeView->rootContext();
    d->ctxt->setContextProperty( "authentication", d->auth );
    d->ctxt->setContextProperty( "gameItemsModel", d->gameItemsModel );
    d->ctxt->setContextProperty( "commentItemsModel", d->commentItemsModel );
    d->ctxt->setContextProperty( "gameWindowManager", this );

    // Note QML enum handling is more or less bonkers at the moment
    // It should be removed after the QML enum support is not that flaky
    qmlRegisterUncreatableType<GluonPlayer::GameViewItem>("GluonPlayerGameViewItem", 1, 0, "GameViewItem", QString("Support the Status enumeration"));

    d->declarativeView->setSource( QUrl( "qrc:/main.qml" ) );

    d->rootObj = d->declarativeView->rootObject();
    d->login = d->rootObj->findChild<QObject*>( "login" );
    QObject::connect( d->auth, SIGNAL( initialized() ), d->login, SLOT( providerSet() ) );

    d->stackedWidget->addWidget(d->declarativeView);
    d->stackedWidget->addWidget(d->renderWidget);
    d->stackedWidget->setCurrentIndex(0);
    connect(QApplication::instance(), SIGNAL(lastWindowClosed()), GluonEngine::Game::instance(), SLOT( stopGame()));
}

GameWindowManager::~GameWindowManager ( )
{
    delete d;
}

bool GameWindowManager::isViewportGLWidget( )
{
    return qobject_cast<QGLWidget*>(d->declarativeView);
}

void GameWindowManager::startGame( )
{
    GluonCore::GluonObjectFactory::instance()->loadPlugins();

    m_project = new GluonEngine::GameProject();
    m_project->loadFromFile( m_gameFileName );

    GluonEngine::Game::instance()->setGameProject( m_project );
    GluonEngine::Game::instance()->setCurrentScene( m_project->entryPoint() );

    d->stackedWidget->setCurrentWidget(d->renderWidget);
    d->renderWidget->setFocus();
    GluonEngine::Game::instance()->runGame();
}

void GameWindowManager::pauseGame()
{
    GluonEngine::Game::instance()->setPause( true );
    // stateChanged( "paused" );
}

void GameWindowManager::stopGame()
{
    GluonEngine::Game::instance()->stopGame();
}

void GameWindowManager::setProject( int index )
{
    m_gameFileName = d->gameItemsModel->index(index).data(GluonPlayer::GameItemsModel::ProjectFileNameRole).toString();
    openProject();
}

int GameWindowManager::availableGamesCount( ) const
{
    return d->gameItemsModel->rowCount();
}

void GameWindowManager::buildCommentsModel( int index )
{
    QString gameID = d->gameItemsModel->index(index).data(GluonPlayer::GameItemsModel::IDRole).toString();
    if( gameID.isEmpty() )
    {
        return;
    }

    d->commentItemsModel = new GluonPlayer::CommentItemsModel( gameID );
}

void GameWindowManager::setProject( const QModelIndex& index )
{
    m_gameFileName = index.data(GluonPlayer::GameItemsModel::ProjectFileNameRole).toString();
    openProject();
}

void GameWindowManager::openProject()
{
    if( m_gameFileName.isEmpty() )
    {
        return;
    }

    connect( GluonEngine::Game::instance(), SIGNAL( painted( int ) ), d->renderWidget, SLOT( updateGL() ) );
    connect( GluonEngine::Game::instance(), SIGNAL( painted( int ) ), SLOT( countFrames( int ) ) );
    connect( GluonEngine::Game::instance(), SIGNAL( updated( int ) ), SLOT( updateTitle( int ) ) );

    GluonInput::InputManager::instance()->setFilteredObject(d->renderWidget);
    QTimer::singleShot( 1000, this, SLOT( startGame() ) );
}

void GameWindowManager::activated( QModelIndex index )
{
    if( index.isValid() )
    {
    }
}

void GameWindowManager::updateTitle( int msec )
{
    d->msecElapsed += msec;

    static int fps = 0;
    if( d->msecElapsed > 1000 )
    {
        fps = d->frameCount;
        d->frameCount = 0;
        d->msecElapsed = 0;
    }
}

void GameWindowManager::countFrames( int /* time */ )
{
    d->frameCount++;
}

GluonPlayer::GameItemsModel* GameWindowManager::gameItemsModel() const
{
    return d->gameItemsModel;
}

void GameWindowManager::setGameItemsModel(GluonPlayer::GameItemsModel* gameItemsModel)
{
    d->gameItemsModel = gameItemsModel;
}

GluonPlayer::CommentItemsModel* GameWindowManager::commentItemsModel() const
{
    return d->commentItemsModel;
}

void GameWindowManager::setCommentItemsModel(GluonPlayer::CommentItemsModel* commentItemsModel)
{
    d->commentItemsModel = commentItemsModel;
}

void GameWindowManager::show()
{
    d->stackedWidget->show();
}

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


<commit_before>#include "base/logging.h"
#include "input/input_state.h"
#include "ui/screen.h"
#include "ui/ui.h"

ScreenManager::ScreenManager() {
	nextScreen_ = 0;
	uiContext_ = 0;
	dialogFinished_ = 0;
}

ScreenManager::~ScreenManager() {
	shutdown();
}

void ScreenManager::switchScreen(Screen *screen) {
	// Note that if a dialog is found, this will be a silent background switch that
	// will only become apparent if the dialog is closed. The previous screen will stick around
	// until that switch.
	// TODO: is this still true?
	if (nextScreen_ != 0) {
		FLOG("WTF? Already had a nextScreen_");
	}
	if (screen == 0) {
		WLOG("Swiching to a zero screen, this can't be good");
	}
	if (stack_.empty() || screen != stack_.back().screen) {
		nextScreen_ = screen;
		nextScreen_->setScreenManager(this);
	}
}

void ScreenManager::update(InputState &input) {
	if (nextScreen_) {
		switchToNext();
	}

	if (stack_.size()) {
		stack_.back().screen->update(input);
	}
}

void ScreenManager::switchToNext() {
	if (!nextScreen_) {
		ELOG("switchToNext: No nextScreen_!");
	}

	Layer temp = {0, 0};
	if (!stack_.empty()) {
		temp = stack_.back();
		stack_.pop_back();
	}
	Layer newLayer = {nextScreen_, 0};
	stack_.push_back(newLayer);
	if (temp.screen) {
		delete temp.screen;
	}
	nextScreen_ = 0;
}

void ScreenManager::touch(const TouchInput &touch) {
	if (!stack_.empty())
		stack_.back().screen->touch(touch);
}

void ScreenManager::key(const KeyInput &key) {
	if (!stack_.empty())
		stack_.back().screen->key(key);
}

void ScreenManager::axis(const AxisInput &axis) {
	if (!stack_.empty())
		stack_.back().screen->axis(axis);
}

void ScreenManager::render() {
	if (!stack_.empty()) {
		switch (stack_.back().flags) {
		case LAYER_SIDEMENU:
		case LAYER_TRANSPARENT:
			if (stack_.size() == 1) {
				ELOG("Can't have sidemenu over nothing");
				break;
			} else {
				auto iter = stack_.end();
				iter--;
				iter--;
				Layer backback = *iter;
				UIDisableBegin();
				// Also shift to the right somehow...
				backback.screen->render();
				UIDisableEnd();
				stack_.back().screen->render();
				break;
			}
		default:
			stack_.back().screen->render();
			break;
		}
	} else {
		ELOG("No current screen!");
	}

	processFinishDialog();
}

void ScreenManager::sendMessage(const char *msg, const char *value) {
	if (!stack_.empty())
		stack_.back().screen->sendMessage(msg, value);
}

void ScreenManager::deviceLost() {
	for (size_t i = 0; i < stack_.size(); i++) {
		stack_[i].screen->deviceLost();
	}
	// Dialogs too? Nah, they should only use the standard UI texture anyway.
	// TODO: Change this when it becomes necessary.
}

Screen *ScreenManager::topScreen() const {
	if (!stack_.empty())
		return stack_.back().screen;
	else
		return 0;
}

void ScreenManager::shutdown() {
	for (auto x = stack_.begin(); x != stack_.end(); x++)
		delete x->screen;
	stack_.clear();
	delete nextScreen_;
	nextScreen_ = 0;
}

void ScreenManager::push(Screen *screen, int layerFlags) {
	if (nextScreen_ && stack_.empty()) {
		// we're during init, this is OK
		switchToNext();
	}
	screen->setScreenManager(this);
	if (screen->isTransparent()) {
		layerFlags |= LAYER_TRANSPARENT;
	}
	Layer layer = {screen, layerFlags};
	stack_.push_back(layer);
}

void ScreenManager::pop() {
	if (stack_.size()) {
		delete stack_.back().screen;
		stack_.pop_back();
	} else {
		ELOG("Can't pop when stack empty");
	}
}

void ScreenManager::RecreateAllViews() {
	for (auto it = stack_.begin(); it != stack_.end(); ++it) {
		it->screen->RecreateViews();
	}
}

void ScreenManager::finishDialog(const Screen *dialog, DialogResult result) {
	if (dialog != stack_.back().screen) {
		ELOG("Wrong dialog being finished!");
		return;
	}
	if (!stack_.size()) {
		ELOG("Must be in a dialog to finishDialog");
		return;
	}
	dialogFinished_ = dialog;
	dialogResult_ = result;
}

void ScreenManager::processFinishDialog() {
	if (dialogFinished_) {
		if (stack_.size()) {
			stack_.pop_back();
		}

		Screen *caller = topScreen();
		if (caller) {
			caller->dialogFinished(dialogFinished_, dialogResult_);
		} else {
			ELOG("ERROR: no top screen when finishing dialog");
		}
		delete dialogFinished_;
		dialogFinished_ = 0;
	}
}
<commit_msg>Don't crash if another dialog is added while finishing.<commit_after>#include "base/logging.h"
#include "input/input_state.h"
#include "ui/screen.h"
#include "ui/ui.h"

ScreenManager::ScreenManager() {
	nextScreen_ = 0;
	uiContext_ = 0;
	dialogFinished_ = 0;
}

ScreenManager::~ScreenManager() {
	shutdown();
}

void ScreenManager::switchScreen(Screen *screen) {
	// Note that if a dialog is found, this will be a silent background switch that
	// will only become apparent if the dialog is closed. The previous screen will stick around
	// until that switch.
	// TODO: is this still true?
	if (nextScreen_ != 0) {
		FLOG("WTF? Already had a nextScreen_");
	}
	if (screen == 0) {
		WLOG("Swiching to a zero screen, this can't be good");
	}
	if (stack_.empty() || screen != stack_.back().screen) {
		nextScreen_ = screen;
		nextScreen_->setScreenManager(this);
	}
}

void ScreenManager::update(InputState &input) {
	if (nextScreen_) {
		switchToNext();
	}

	if (stack_.size()) {
		stack_.back().screen->update(input);
	}
}

void ScreenManager::switchToNext() {
	if (!nextScreen_) {
		ELOG("switchToNext: No nextScreen_!");
	}

	Layer temp = {0, 0};
	if (!stack_.empty()) {
		temp = stack_.back();
		stack_.pop_back();
	}
	Layer newLayer = {nextScreen_, 0};
	stack_.push_back(newLayer);
	if (temp.screen) {
		delete temp.screen;
	}
	nextScreen_ = 0;
}

void ScreenManager::touch(const TouchInput &touch) {
	if (!stack_.empty())
		stack_.back().screen->touch(touch);
}

void ScreenManager::key(const KeyInput &key) {
	if (!stack_.empty())
		stack_.back().screen->key(key);
}

void ScreenManager::axis(const AxisInput &axis) {
	if (!stack_.empty())
		stack_.back().screen->axis(axis);
}

void ScreenManager::render() {
	if (!stack_.empty()) {
		switch (stack_.back().flags) {
		case LAYER_SIDEMENU:
		case LAYER_TRANSPARENT:
			if (stack_.size() == 1) {
				ELOG("Can't have sidemenu over nothing");
				break;
			} else {
				auto iter = stack_.end();
				iter--;
				iter--;
				Layer backback = *iter;
				UIDisableBegin();
				// Also shift to the right somehow...
				backback.screen->render();
				UIDisableEnd();
				stack_.back().screen->render();
				break;
			}
		default:
			stack_.back().screen->render();
			break;
		}
	} else {
		ELOG("No current screen!");
	}

	processFinishDialog();
}

void ScreenManager::sendMessage(const char *msg, const char *value) {
	if (!stack_.empty())
		stack_.back().screen->sendMessage(msg, value);
}

void ScreenManager::deviceLost() {
	for (size_t i = 0; i < stack_.size(); i++) {
		stack_[i].screen->deviceLost();
	}
	// Dialogs too? Nah, they should only use the standard UI texture anyway.
	// TODO: Change this when it becomes necessary.
}

Screen *ScreenManager::topScreen() const {
	if (!stack_.empty())
		return stack_.back().screen;
	else
		return 0;
}

void ScreenManager::shutdown() {
	for (auto x = stack_.begin(); x != stack_.end(); x++)
		delete x->screen;
	stack_.clear();
	delete nextScreen_;
	nextScreen_ = 0;
}

void ScreenManager::push(Screen *screen, int layerFlags) {
	if (nextScreen_ && stack_.empty()) {
		// we're during init, this is OK
		switchToNext();
	}
	screen->setScreenManager(this);
	if (screen->isTransparent()) {
		layerFlags |= LAYER_TRANSPARENT;
	}
	Layer layer = {screen, layerFlags};
	stack_.push_back(layer);
}

void ScreenManager::pop() {
	if (stack_.size()) {
		delete stack_.back().screen;
		stack_.pop_back();
	} else {
		ELOG("Can't pop when stack empty");
	}
}

void ScreenManager::RecreateAllViews() {
	for (auto it = stack_.begin(); it != stack_.end(); ++it) {
		it->screen->RecreateViews();
	}
}

void ScreenManager::finishDialog(const Screen *dialog, DialogResult result) {
	if (stack_.empty()) {
		ELOG("Must be in a dialog to finishDialog");
		return;
	}
	if (dialog != stack_.back().screen) {
		ELOG("Wrong dialog being finished!");
		return;
	}
	dialogFinished_ = dialog;
	dialogResult_ = result;
}

void ScreenManager::processFinishDialog() {
	if (dialogFinished_) {
		// Another dialog may have been pushed before the render, so search for it.
		Screen *caller = 0;
		for (size_t i = 0; i < stack_.size(); ++i) {
			if (stack_[i].screen != dialogFinished_) {
				continue;
			}

			stack_.erase(stack_.begin() + i);
			// The previous screen was the caller (not necessarily the topmost.)
			if (i > 0) {
				caller = stack_[i - 1].screen;
			}
		}

		if (!caller) {
			ELOG("ERROR: no top screen when finishing dialog");
		} else if (caller != topScreen()) {
			// The caller may get confused if we call dialogFinished() now.
			WLOG("Skipping non-top dialog when finishing dialog.");
		} else {
			caller->dialogFinished(dialogFinished_, dialogResult_);
		}
		delete dialogFinished_;
		dialogFinished_ = 0;
	}
}
<|endoftext|>


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

#ifndef _TOOLKIT_HELPER_UNOPROPERTYARRAYHELPER_HXX_
#define _TOOLKIT_HELPER_UNOPROPERTYARRAYHELPER_HXX_

#include <cppuhelper/propshlp.hxx>

#include <tools/table.hxx>

#include <list>

//  ----------------------------------------------------
//  class UnoPropertyArrayHelper
//  ----------------------------------------------------
class UnoPropertyArrayHelper : public ::cppu::IPropertyArrayHelper
{
private:
    Table       maIDs;

protected:
    sal_Bool    ImplHasProperty( sal_uInt16 nPropId ) const;

public:
                UnoPropertyArrayHelper( const ::com::sun::star::uno::Sequence<sal_Int32>& rIDs );
                UnoPropertyArrayHelper( const std::list< sal_uInt16 > &rIDs );

    // ::cppu::IPropertyArrayHelper
    sal_Bool SAL_CALL fillPropertyMembersByHandle( ::rtl::OUString * pPropName, sal_Int16 * pAttributes, sal_Int32 nHandle );
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties();
    ::com::sun::star::beans::Property SAL_CALL getPropertyByName(const ::rtl::OUString& rPropertyName) throw (::com::sun::star::beans::UnknownPropertyException);
    sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& rPropertyName);
    sal_Int32 SAL_CALL getHandleByName( const ::rtl::OUString & rPropertyName );
    sal_Int32 SAL_CALL fillHandles( sal_Int32* pHandles, const ::com::sun::star::uno::Sequence< ::rtl::OUString > & rPropNames );
};

#endif // _TOOLKIT_HELPER_UNOPROPERTYARRAYHELPER_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.4.32); FILE MERGED 2008/03/28 15:40:10 rt 1.4.32.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: unopropertyarrayhelper.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _TOOLKIT_HELPER_UNOPROPERTYARRAYHELPER_HXX_
#define _TOOLKIT_HELPER_UNOPROPERTYARRAYHELPER_HXX_

#include <cppuhelper/propshlp.hxx>

#include <tools/table.hxx>

#include <list>

//  ----------------------------------------------------
//  class UnoPropertyArrayHelper
//  ----------------------------------------------------
class UnoPropertyArrayHelper : public ::cppu::IPropertyArrayHelper
{
private:
    Table       maIDs;

protected:
    sal_Bool    ImplHasProperty( sal_uInt16 nPropId ) const;

public:
                UnoPropertyArrayHelper( const ::com::sun::star::uno::Sequence<sal_Int32>& rIDs );
                UnoPropertyArrayHelper( const std::list< sal_uInt16 > &rIDs );

    // ::cppu::IPropertyArrayHelper
    sal_Bool SAL_CALL fillPropertyMembersByHandle( ::rtl::OUString * pPropName, sal_Int16 * pAttributes, sal_Int32 nHandle );
    ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties();
    ::com::sun::star::beans::Property SAL_CALL getPropertyByName(const ::rtl::OUString& rPropertyName) throw (::com::sun::star::beans::UnknownPropertyException);
    sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& rPropertyName);
    sal_Int32 SAL_CALL getHandleByName( const ::rtl::OUString & rPropertyName );
    sal_Int32 SAL_CALL fillHandles( sal_Int32* pHandles, const ::com::sun::star::uno::Sequence< ::rtl::OUString > & rPropNames );
};

#endif // _TOOLKIT_HELPER_UNOPROPERTYARRAYHELPER_HXX_

<|endoftext|>


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

#include <gtest/gtest.h>
#include "SurgSim/Framework/Timer.h"
//#include "MockObjects.h"  //NOLINT

using SurgSim::Framework::Timer;

TEST(TimerTest, Constructor)
{
	EXPECT_NO_THROW({std::shared_ptr<Timer> timer(new Timer());});

}

TEST(TimerTest, Starting)
{
	std::shared_ptr<Timer> timer(new Timer());
	EXPECT_EQ(timer->getCurrentNumberOfFrames(), 0);
	EXPECT_EQ(timer->getNumberOfClockFails(), 0);
}

TEST(TimerTest, SettingFrames)
{
	std::shared_ptr<Timer> timer(new Timer());
	timer->endFrame();
	EXPECT_EQ(timer->getCurrentNumberOfFrames(), 1);
	EXPECT_EQ(timer->getAverageFrameRate(), timer->getLastFrameRate());
	EXPECT_EQ(timer->getAverageFramePeriod(), timer->getLastFramePeriod());

	timer->start();
	timer->setNumberOfFrames(3);
	for (auto i = 0; i < 5; ++i)
	{
		timer->endFrame();
	}
	EXPECT_EQ(timer->getCurrentNumberOfFrames(), 3);
}

TEST(TimerTest, Comparison)
{
	std::shared_ptr<Timer> timer1(new Timer());
	std::shared_ptr<Timer> timer2(new Timer());

	for (auto i = 0; i < 100; ++i)
	{
		timer2->beginFrame();
		timer2->endFrame();
		timer1->endFrame();
	}
	EXPECT_TRUE(timer1->getAverageFramePeriod() >= timer2->getAverageFramePeriod());
}

<commit_msg>Remove commented-out #include line from TimerTest.cpp<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>
#include "SurgSim/Framework/Timer.h"

using SurgSim::Framework::Timer;

TEST(TimerTest, Constructor)
{
	EXPECT_NO_THROW({std::shared_ptr<Timer> timer(new Timer());});

}

TEST(TimerTest, Starting)
{
	std::shared_ptr<Timer> timer(new Timer());
	EXPECT_EQ(timer->getCurrentNumberOfFrames(), 0);
	EXPECT_EQ(timer->getNumberOfClockFails(), 0);
}

TEST(TimerTest, SettingFrames)
{
	std::shared_ptr<Timer> timer(new Timer());
	timer->endFrame();
	EXPECT_EQ(timer->getCurrentNumberOfFrames(), 1);
	EXPECT_EQ(timer->getAverageFrameRate(), timer->getLastFrameRate());
	EXPECT_EQ(timer->getAverageFramePeriod(), timer->getLastFramePeriod());

	timer->start();
	timer->setNumberOfFrames(3);
	for (auto i = 0; i < 5; ++i)
	{
		timer->endFrame();
	}
	EXPECT_EQ(timer->getCurrentNumberOfFrames(), 3);
}

TEST(TimerTest, Comparison)
{
	std::shared_ptr<Timer> timer1(new Timer());
	std::shared_ptr<Timer> timer2(new Timer());

	for (auto i = 0; i < 100; ++i)
	{
		timer2->beginFrame();
		timer2->endFrame();
		timer1->endFrame();
	}
	EXPECT_TRUE(timer1->getAverageFramePeriod() >= timer2->getAverageFramePeriod());
}

<|endoftext|>


<commit_before>/*
 * A simple pelvis motion control block for use with bipeds. Uses PD control to regulate the pelvis
 * to a fixed height above the feet and drives the yaw to match the average foot yaw.
 *
 */

 #include "controlUtil.h"

struct PelvisMotionControlData {
  RigidBodyManipulator* r;
  double alpha;
  double pelvis_height_previous;
  double nominal_pelvis_height;
  Vector6d Kp;
  Vector6d Kd;

  int pelvis_body_index;
  int rfoot_body_index;
  int lfoot_body_index;
};

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if (nrhs<1) mexErrMsgTxt("usage: ptr = pelvisMotionControlmex(0,robot_obj,alpha,nominal_pelvis_height,Kp,Kd); y=pelvisMotionControlmex(ptr,x)");
  if (nlhs<1) mexErrMsgTxt("take at least one output... please.");

  struct PelvisMotionControlData* pdata;

  if (mxGetScalar(prhs[0])==0) { // then construct the data object and return
    pdata = new struct PelvisMotionControlData;

    // get robot mex model ptr
    if (!mxIsNumeric(prhs[1]) || mxGetNumberOfElements(prhs[1])!=1)
      mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the second argument should be the robot mex ptr");
    memcpy(&(pdata->r),mxGetData(prhs[1]),sizeof(pdata->r));

    if (!mxIsNumeric(prhs[2]) || mxGetNumberOfElements(prhs[2])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the third argument should be alpha");
    memcpy(&(pdata->alpha),mxGetPr(prhs[2]),sizeof(pdata->alpha));

    if (!mxIsNumeric(prhs[3]) || mxGetNumberOfElements(prhs[3])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the fourth argument should be nominal_pelvis_height");
    memcpy(&(pdata->nominal_pelvis_height),mxGetPr(prhs[3]),sizeof(pdata->nominal_pelvis_height));

    if (!mxIsNumeric(prhs[4]) || mxGetM(prhs[4])!=6 || mxGetN(prhs[4])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the fifth argument should be Kp");
    memcpy(&(pdata->Kp),mxGetPr(prhs[4]),sizeof(pdata->Kp));

    if (!mxIsNumeric(prhs[5]) || mxGetM(prhs[5])!=6 || mxGetN(prhs[5])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the sixth argument should be Kd");
    memcpy(&(pdata->Kd),mxGetPr(prhs[5]),sizeof(pdata->Kd));

    mxClassID cid;
    if (sizeof(pdata)==4) cid = mxUINT32_CLASS;
    else if (sizeof(pdata)==8) cid = mxUINT64_CLASS;
    else mexErrMsgIdAndTxt("Drake:pelvisMotionControlmex:PointerSize","Are you on a 32-bit machine or 64-bit machine??");

    pdata->pelvis_height_previous = -1;

    pdata->pelvis_body_index = pdata->r->findLinkInd("pelvis", 0);
    pdata->rfoot_body_index = pdata->r->findLinkInd("r_foot", 0);
    pdata->lfoot_body_index = pdata->r->findLinkInd("l_foot", 0);

    plhs[0] = mxCreateNumericMatrix(1,1,cid,mxREAL);
    memcpy(mxGetData(plhs[0]),&pdata,sizeof(pdata));

    return;
  }

  // first get the ptr back from matlab
  if (!mxIsNumeric(prhs[0]) || mxGetNumberOfElements(prhs[0])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the first argument should be the ptr");
  memcpy(&pdata,mxGetData(prhs[0]),sizeof(pdata));

  int nq = pdata->r->num_dof;

  double *q = mxGetPr(prhs[1]);
  double *qd = &q[nq];
  Map<VectorXd> qdvec(qd,nq);

  pdata->r->doKinematics(q,false,qd);

  // TODO: this must be updated to use quaternions/spatial velocity
  Vector6d pelvis_pose,rfoot_pose,lfoot_pose;
  MatrixXd Jpelvis = MatrixXd::Zero(6,pdata->r->num_dof);
  Vector4d zero = Vector4d::Zero();
  zero(3) = 1.0;
  pdata->r->forwardKin(pdata->pelvis_body_index,zero,1,pelvis_pose);
  pdata->r->forwardJac(pdata->pelvis_body_index,zero,1,Jpelvis);
  pdata->r->forwardKin(pdata->rfoot_body_index,zero,1,rfoot_pose);
  pdata->r->forwardKin(pdata->lfoot_body_index,zero,1,lfoot_pose);

  if (pdata->pelvis_height_previous<0) {
    pdata->pelvis_height_previous = pelvis_pose(2);
  }

  double min_foot_z = std::min(lfoot_pose(2),rfoot_pose(2));
  double mean_foot_yaw = (lfoot_pose(5)+rfoot_pose(5))/2.0;

  double pelvis_height_desired = pdata->alpha*pdata->pelvis_height_previous + (1.0-pdata->alpha)*(min_foot_z + pdata->nominal_pelvis_height);
  pdata->pelvis_height_previous = pelvis_height_desired;

  Vector6d body_des;
  double nan = std::numeric_limits<double>::quiet_NaN();
  body_des << nan,nan,pelvis_height_desired,0,0,mean_foot_yaw;
  Vector6d error;
  error.head<3>()= body_des.head<3>()-pelvis_pose.head<3>();

  Vector3d error_rpy,pose_rpy,des_rpy;
  pose_rpy = pelvis_pose.tail<3>();
  des_rpy = body_des.tail<3>();
  angleDiff(pose_rpy,des_rpy,error_rpy);
  error.tail(3) = error_rpy;

  Vector6d body_vdot = (pdata->Kp.array()*error.array()).matrix() - (pdata->Kd.array()*(Jpelvis*qdvec).array()).matrix();

  plhs[0] = eigenToMatlab(body_vdot);
}<commit_msg>pelvis cpp controller uses angleAverage<commit_after>/*
 * A simple pelvis motion control block for use with bipeds. Uses PD control to regulate the pelvis
 * to a fixed height above the feet and drives the yaw to match the average foot yaw.
 *
 */

 #include "controlUtil.h"

struct PelvisMotionControlData {
  RigidBodyManipulator* r;
  double alpha;
  double pelvis_height_previous;
  double nominal_pelvis_height;
  Vector6d Kp;
  Vector6d Kd;

  int pelvis_body_index;
  int rfoot_body_index;
  int lfoot_body_index;
};

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if (nrhs<1) mexErrMsgTxt("usage: ptr = pelvisMotionControlmex(0,robot_obj,alpha,nominal_pelvis_height,Kp,Kd); y=pelvisMotionControlmex(ptr,x)");
  if (nlhs<1) mexErrMsgTxt("take at least one output... please.");

  struct PelvisMotionControlData* pdata;

  if (mxGetScalar(prhs[0])==0) { // then construct the data object and return
    pdata = new struct PelvisMotionControlData;

    // get robot mex model ptr
    if (!mxIsNumeric(prhs[1]) || mxGetNumberOfElements(prhs[1])!=1)
      mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the second argument should be the robot mex ptr");
    memcpy(&(pdata->r),mxGetData(prhs[1]),sizeof(pdata->r));

    if (!mxIsNumeric(prhs[2]) || mxGetNumberOfElements(prhs[2])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the third argument should be alpha");
    memcpy(&(pdata->alpha),mxGetPr(prhs[2]),sizeof(pdata->alpha));

    if (!mxIsNumeric(prhs[3]) || mxGetNumberOfElements(prhs[3])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the fourth argument should be nominal_pelvis_height");
    memcpy(&(pdata->nominal_pelvis_height),mxGetPr(prhs[3]),sizeof(pdata->nominal_pelvis_height));

    if (!mxIsNumeric(prhs[4]) || mxGetM(prhs[4])!=6 || mxGetN(prhs[4])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the fifth argument should be Kp");
    memcpy(&(pdata->Kp),mxGetPr(prhs[4]),sizeof(pdata->Kp));

    if (!mxIsNumeric(prhs[5]) || mxGetM(prhs[5])!=6 || mxGetN(prhs[5])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the sixth argument should be Kd");
    memcpy(&(pdata->Kd),mxGetPr(prhs[5]),sizeof(pdata->Kd));

    mxClassID cid;
    if (sizeof(pdata)==4) cid = mxUINT32_CLASS;
    else if (sizeof(pdata)==8) cid = mxUINT64_CLASS;
    else mexErrMsgIdAndTxt("Drake:pelvisMotionControlmex:PointerSize","Are you on a 32-bit machine or 64-bit machine??");

    pdata->pelvis_height_previous = -1;

    pdata->pelvis_body_index = pdata->r->findLinkInd("pelvis", 0);
    pdata->rfoot_body_index = pdata->r->findLinkInd("r_foot", 0);
    pdata->lfoot_body_index = pdata->r->findLinkInd("l_foot", 0);

    plhs[0] = mxCreateNumericMatrix(1,1,cid,mxREAL);
    memcpy(mxGetData(plhs[0]),&pdata,sizeof(pdata));

    return;
  }

  // first get the ptr back from matlab
  if (!mxIsNumeric(prhs[0]) || mxGetNumberOfElements(prhs[0])!=1)
    mexErrMsgIdAndTxt("DRC:pelvisMotionControlmex:BadInputs","the first argument should be the ptr");
  memcpy(&pdata,mxGetData(prhs[0]),sizeof(pdata));

  int nq = pdata->r->num_dof;

  double *q = mxGetPr(prhs[1]);
  double *qd = &q[nq];
  Map<VectorXd> qdvec(qd,nq);

  pdata->r->doKinematics(q,false,qd);

  // TODO: this must be updated to use quaternions/spatial velocity
  Vector6d pelvis_pose,rfoot_pose,lfoot_pose;
  MatrixXd Jpelvis = MatrixXd::Zero(6,pdata->r->num_dof);
  Vector4d zero = Vector4d::Zero();
  zero(3) = 1.0;
  pdata->r->forwardKin(pdata->pelvis_body_index,zero,1,pelvis_pose);
  pdata->r->forwardJac(pdata->pelvis_body_index,zero,1,Jpelvis);
  pdata->r->forwardKin(pdata->rfoot_body_index,zero,1,rfoot_pose);
  pdata->r->forwardKin(pdata->lfoot_body_index,zero,1,lfoot_pose);

  if (pdata->pelvis_height_previous<0) {
    pdata->pelvis_height_previous = pelvis_pose(2);
  }

  double min_foot_z = std::min(lfoot_pose(2),rfoot_pose(2));
  double mean_foot_yaw = angleAverage(lfoot_pose(5),rfoot_pose(5));

  double pelvis_height_desired = pdata->alpha*pdata->pelvis_height_previous + (1.0-pdata->alpha)*(min_foot_z + pdata->nominal_pelvis_height);
  pdata->pelvis_height_previous = pelvis_height_desired;

  Vector6d body_des;
  double nan = std::numeric_limits<double>::quiet_NaN();
  body_des << nan,nan,pelvis_height_desired,0,0,mean_foot_yaw;
  Vector6d error;
  error.head<3>()= body_des.head<3>()-pelvis_pose.head<3>();

  Vector3d error_rpy,pose_rpy,des_rpy;
  pose_rpy = pelvis_pose.tail<3>();
  des_rpy = body_des.tail<3>();
  angleDiff(pose_rpy,des_rpy,error_rpy);
  error.tail(3) = error_rpy;

  Vector6d body_vdot = (pdata->Kp.array()*error.array()).matrix() - (pdata->Kd.array()*(Jpelvis*qdvec).array()).matrix();

  plhs[0] = eigenToMatlab(body_vdot);
}<|endoftext|>


<commit_before>#include <plugin.hpp>
#include <output.hpp>
#include <core.hpp>
#include <linux/input.h>
#include <linux/input-event-codes.h>

static bool begins_with(std::string word, std::string prefix)
{
    if (word.length() < prefix.length())
        return false;

    return word.substr(0, prefix.length()) == prefix;
}

/* Initial repeat delay passed */
static int repeat_delay_timeout_handler(void *callback)
{
    (*reinterpret_cast<std::function<void()>*> (callback)) ();
    return 1; // disconnect
};

/* Between each repeat */
static int repeat_once_handler(void *callback)
{
    (*reinterpret_cast<std::function<void()>*> (callback)) ();
    return 1; // continue timer
}

/* Provides a way to bind specific commands to activator bindings.
 *
 * It supports 2 modes:
 *
 * 1. Regular bindings
 * 2. Repeatable bindings - for example, if the user binds a keybinding, then
 * after a specific delay the command begins to be executed repeatedly, until
 * the user released the key. In the config file, repeatable bindings have the
 * prefix repeatable_
 * 3. Always bindings - bindings that can be executed even if a plugin is already
 * active, or if the screen is locked. They have a prefix always_
 * */

class wayfire_command : public wf::plugin_interface_t
{
    std::vector<activator_callback> bindings;

    struct
    {
        uint32_t pressed_button = 0;
        uint32_t pressed_key = 0;
        std::string repeat_command;
    } repeat;

    wl_event_source *repeat_source = NULL, *repeat_delay_source = NULL;

    enum binding_mode {
        BINDING_NORMAL,
        BINDING_REPEAT,
        BINDING_ALWAYS,
    };
    void on_binding(std::string command, binding_mode mode, wf_activator_source source,
        uint32_t value)
    {
        /* We already have a repeatable command, do not accept further bindings */
        if (repeat.pressed_key || repeat.pressed_button)
            return;

        if (!output->activate_plugin(grab_interface, mode == BINDING_ALWAYS))
            return;

        wf::get_core().run(command.c_str());

        /* No repeat necessary in any of those cases */
        if (mode != BINDING_REPEAT || source == ACTIVATOR_SOURCE_GESTURE ||
            value == 0)
        {
            output->deactivate_plugin(grab_interface);
            return;
        }

        /* Grab if grab wasn't active up to now */
        if (!grab_interface->is_grabbed())
            grab_interface->grab();

        repeat.repeat_command = command;
        if (source == ACTIVATOR_SOURCE_KEYBINDING) {
            repeat.pressed_key = value;
        } else {
            repeat.pressed_button = value;
        }

        repeat_delay_source = wl_event_loop_add_timer(wf::get_core().ev_loop,
            repeat_delay_timeout_handler, &on_repeat_delay_timeout);

        wl_event_source_timer_update(repeat_delay_source,
            wf::get_core().config->get_section("input")
                ->get_option("kb_repeat_delay", "400")->as_int());
    }

    std::function<void()> on_repeat_delay_timeout = [=] ()
    {
        repeat_delay_source = NULL;
        repeat_source = wl_event_loop_add_timer(wf::get_core().ev_loop,
            repeat_once_handler, &on_repeat_once);
        on_repeat_once();
    };

    std::function<void()> on_repeat_once = [=] ()
    {
        uint32_t repeat_rate = wf::get_core().config->get_section("input")
            ->get_option("kb_repeat_rate", "40")->as_int();
        if (repeat_rate <= 0 || repeat_rate > 1000)
            return reset_repeat();

        wl_event_source_timer_update(repeat_source, 1000 / repeat_rate);
        wf::get_core().run(repeat.repeat_command.c_str());
    };

    void reset_repeat()
    {
        if (repeat_delay_source)
        {
            wl_event_source_remove(repeat_delay_source);
            repeat_delay_source = NULL;
        }

        if (repeat_source)
        {
            wl_event_source_remove(repeat_source);
            repeat_source = NULL;
        }

        repeat.pressed_key = repeat.pressed_button = 0;

        grab_interface->ungrab();
        output->deactivate_plugin(grab_interface);
    }

    std::function<void(uint32_t, uint32_t)> on_button =
        [=] (uint32_t button, uint32_t state)
    {
        if (button == repeat.pressed_button && state == WLR_BUTTON_RELEASED)
            reset_repeat();
    };

    std::function<void(uint32_t, uint32_t)> on_key =
        [=] (uint32_t key, uint32_t state)
    {
        if (key == repeat.pressed_key && state == WLR_KEY_RELEASED)
            reset_repeat();
    };

    public:

    void setup_bindings_from_config(wayfire_config *config)
    {
        auto section = config->get_section("command");

        std::vector<std::string> command_names;
        const std::string exec_prefix = "command_";
        for (auto command : section->options)
        {
            if (begins_with(command->name, exec_prefix))
            {
                command_names.push_back(
                    command->name.substr(exec_prefix.length()));
            }
        }

        bindings.resize(command_names.size());
        const std::string norepeat = "...norepeat...";
        const std::string noalways = "...noalways...";

        for (size_t i = 0; i < command_names.size(); i++)
        {
            auto command = exec_prefix + command_names[i];
            auto regular_binding_name = "binding_" + command_names[i];
            auto repeat_binding_name = "repeatable_binding_" + command_names[i];
            auto always_binding_name = "always_binding_" + command_names[i];

            auto executable = section->get_option(command, "")->as_string();
            auto repeatable_opt = section->get_option(repeat_binding_name, norepeat);
            auto regular_opt = section->get_option(regular_binding_name, "none");
            auto always_opt = section->get_option(always_binding_name, noalways);

            using namespace std::placeholders;
            if (repeatable_opt->as_string() != norepeat)
            {
                bindings[i] = std::bind(std::mem_fn(&wayfire_command::on_binding),
                    this, executable, BINDING_REPEAT, _1, _2);
                output->add_activator(repeatable_opt, &bindings[i]);
            }
            else if (always_opt->as_string() != noalways)
            {
                bindings[i] = std::bind(std::mem_fn(&wayfire_command::on_binding),
                    this, executable, BINDING_ALWAYS, _1, _2);
                output->add_activator(always_opt, &bindings[i]);
            }
            else
            {
                bindings[i] = std::bind(std::mem_fn(&wayfire_command::on_binding),
                    this, executable, BINDING_NORMAL, _1, _2);
                output->add_activator(regular_opt, &bindings[i]);
            }
        }
    }

    void clear_bindings()
    {
        for (auto& binding : bindings)
            output->rem_binding(&binding);

        bindings.clear();
    }

    wf::signal_callback_t reload_config;

    void init(wayfire_config *config)
    {
        grab_interface->name = "command";
        grab_interface->capabilities = wf::CAPABILITY_GRAB_INPUT;
        grab_interface->callbacks.pointer.button = on_button;
        grab_interface->callbacks.keyboard.key = on_key;
        grab_interface->callbacks.cancel = [=]() {reset_repeat();};

        using namespace std::placeholders;

        setup_bindings_from_config(config);

        reload_config = [=] (wf::signal_data_t*)
        {
            clear_bindings();
            setup_bindings_from_config(wf::get_core().config);
        };

        wf::get_core().connect_signal("reload-config", &reload_config);
    }

    void fini()
    {
        wf::get_core().disconnect_signal("reload-config", &reload_config);
        clear_bindings();
    }
};

DECLARE_WAYFIRE_PLUGIN(wayfire_command);
<commit_msg>command: use raw events instead of grabbing input<commit_after>#include <plugin.hpp>
#include <output.hpp>
#include <core.hpp>
#include <linux/input.h>
#include <linux/input-event-codes.h>
#include <signal-definitions.hpp>

static bool begins_with(std::string word, std::string prefix)
{
    if (word.length() < prefix.length())
        return false;

    return word.substr(0, prefix.length()) == prefix;
}

/* Initial repeat delay passed */
static int repeat_delay_timeout_handler(void *callback)
{
    (*reinterpret_cast<std::function<void()>*> (callback)) ();
    return 1; // disconnect
};

/* Between each repeat */
static int repeat_once_handler(void *callback)
{
    (*reinterpret_cast<std::function<void()>*> (callback)) ();
    return 1; // continue timer
}

/* Provides a way to bind specific commands to activator bindings.
 *
 * It supports 2 modes:
 *
 * 1. Regular bindings
 * 2. Repeatable bindings - for example, if the user binds a keybinding, then
 * after a specific delay the command begins to be executed repeatedly, until
 * the user released the key. In the config file, repeatable bindings have the
 * prefix repeatable_
 * 3. Always bindings - bindings that can be executed even if a plugin is already
 * active, or if the screen is locked. They have a prefix always_
 * */

class wayfire_command : public wf::plugin_interface_t
{
    std::vector<activator_callback> bindings;

    struct
    {
        uint32_t pressed_button = 0;
        uint32_t pressed_key = 0;
        std::string repeat_command;
    } repeat;

    wl_event_source *repeat_source = NULL, *repeat_delay_source = NULL;

    enum binding_mode {
        BINDING_NORMAL,
        BINDING_REPEAT,
        BINDING_ALWAYS,
    };
    void on_binding(std::string command, binding_mode mode, wf_activator_source source,
        uint32_t value)
    {
        /* We already have a repeatable command, do not accept further bindings */
        if (repeat.pressed_key || repeat.pressed_button)
            return;

        if (!output->activate_plugin(grab_interface, mode == BINDING_ALWAYS))
            return;

        wf::get_core().run(command.c_str());

        /* No repeat necessary in any of those cases */
        if (mode != BINDING_REPEAT || source == ACTIVATOR_SOURCE_GESTURE ||
            value == 0)
        {
            output->deactivate_plugin(grab_interface);
            return;
        }

        repeat.repeat_command = command;
        if (source == ACTIVATOR_SOURCE_KEYBINDING) {
            repeat.pressed_key = value;
        } else {
            repeat.pressed_button = value;
        }

        repeat_delay_source = wl_event_loop_add_timer(wf::get_core().ev_loop,
            repeat_delay_timeout_handler, &on_repeat_delay_timeout);

        wl_event_source_timer_update(repeat_delay_source,
            wf::get_core().config->get_section("input")
                ->get_option("kb_repeat_delay", "400")->as_int());

        wf::get_core().connect_signal("pointer_button", &on_button_event);
        wf::get_core().connect_signal("keyboard_key", &on_key_event);
    }

    std::function<void()> on_repeat_delay_timeout = [=] ()
    {
        repeat_delay_source = NULL;
        repeat_source = wl_event_loop_add_timer(wf::get_core().ev_loop,
            repeat_once_handler, &on_repeat_once);
        on_repeat_once();
    };

    std::function<void()> on_repeat_once = [=] ()
    {
        uint32_t repeat_rate = wf::get_core().config->get_section("input")
            ->get_option("kb_repeat_rate", "40")->as_int();
        if (repeat_rate <= 0 || repeat_rate > 1000)
            return reset_repeat();

        wl_event_source_timer_update(repeat_source, 1000 / repeat_rate);
        wf::get_core().run(repeat.repeat_command.c_str());
    };

    void reset_repeat()
    {
        if (repeat_delay_source)
        {
            wl_event_source_remove(repeat_delay_source);
            repeat_delay_source = NULL;
        }

        if (repeat_source)
        {
            wl_event_source_remove(repeat_source);
            repeat_source = NULL;
        }

        repeat.pressed_key = repeat.pressed_button = 0;
        output->deactivate_plugin(grab_interface);

        wf::get_core().disconnect_signal("pointer_button", &on_button_event);
        wf::get_core().disconnect_signal("keyboard_key", &on_key_event);
    }

    wf::signal_callback_t on_button_event = [=] (wf::signal_data_t *data)
    {
        auto ev = static_cast<
            wf::input_event_signal<wlr_event_pointer_button>*>(data);
        if (ev->event->button == repeat.pressed_button &&
            ev->event->state == WLR_BUTTON_RELEASED)
        {
            reset_repeat();
        }
    };

    wf::signal_callback_t on_key_event = [=] (wf::signal_data_t *data)
    {
        auto ev = static_cast<
            wf::input_event_signal<wlr_event_keyboard_key>*>(data);
        if (ev->event->keycode == repeat.pressed_key &&
            ev->event->state == WLR_KEY_RELEASED)
        {
            reset_repeat();
        }
    };

    public:

    void setup_bindings_from_config(wayfire_config *config)
    {
        auto section = config->get_section("command");

        std::vector<std::string> command_names;
        const std::string exec_prefix = "command_";
        for (auto command : section->options)
        {
            if (begins_with(command->name, exec_prefix))
            {
                command_names.push_back(
                    command->name.substr(exec_prefix.length()));
            }
        }

        bindings.resize(command_names.size());
        const std::string norepeat = "...norepeat...";
        const std::string noalways = "...noalways...";

        for (size_t i = 0; i < command_names.size(); i++)
        {
            auto command = exec_prefix + command_names[i];
            auto regular_binding_name = "binding_" + command_names[i];
            auto repeat_binding_name = "repeatable_binding_" + command_names[i];
            auto always_binding_name = "always_binding_" + command_names[i];

            auto executable = section->get_option(command, "")->as_string();
            auto repeatable_opt = section->get_option(repeat_binding_name, norepeat);
            auto regular_opt = section->get_option(regular_binding_name, "none");
            auto always_opt = section->get_option(always_binding_name, noalways);

            using namespace std::placeholders;
            if (repeatable_opt->as_string() != norepeat)
            {
                bindings[i] = std::bind(std::mem_fn(&wayfire_command::on_binding),
                    this, executable, BINDING_REPEAT, _1, _2);
                output->add_activator(repeatable_opt, &bindings[i]);
            }
            else if (always_opt->as_string() != noalways)
            {
                bindings[i] = std::bind(std::mem_fn(&wayfire_command::on_binding),
                    this, executable, BINDING_ALWAYS, _1, _2);
                output->add_activator(always_opt, &bindings[i]);
            }
            else
            {
                bindings[i] = std::bind(std::mem_fn(&wayfire_command::on_binding),
                    this, executable, BINDING_NORMAL, _1, _2);
                output->add_activator(regular_opt, &bindings[i]);
            }
        }
    }

    void clear_bindings()
    {
        for (auto& binding : bindings)
            output->rem_binding(&binding);

        bindings.clear();
    }

    wf::signal_callback_t reload_config;

    void init(wayfire_config *config)
    {
        grab_interface->name = "command";
        grab_interface->capabilities = wf::CAPABILITY_GRAB_INPUT;

        using namespace std::placeholders;

        setup_bindings_from_config(config);

        reload_config = [=] (wf::signal_data_t*)
        {
            clear_bindings();
            setup_bindings_from_config(wf::get_core().config);
        };

        wf::get_core().connect_signal("reload-config", &reload_config);
    }

    void fini()
    {
        wf::get_core().disconnect_signal("reload-config", &reload_config);
        clear_bindings();
    }
};

DECLARE_WAYFIRE_PLUGIN(wayfire_command);
<|endoftext|>


<commit_before>#include <plugin.hpp>
#include <output.hpp>
#include <opengl.hpp>
#include <debug.hpp>
#include <animation.hpp>
#include <render-manager.hpp>

static const char* vertex_shader =
R"(
#version 100

attribute mediump vec2 position;

void main() {

    gl_Position = vec4(position.xy, 0.0, 1.0);
}
)";

static const char* fragment_shader =
R"(
#version 100
precision mediump float;

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_radius;
uniform float u_zoom;
uniform sampler2D u_texture;

const float PI = 3.1415926535;

void main()
{
        float radius = u_radius;

        float zoom = u_zoom;
        float pw = 1.0 / u_resolution.x;
        float ph = 1.0 / u_resolution.y;

        vec4 p0 = vec4(u_mouse.x, u_resolution.y - u_mouse.y, 1.0 / radius, 0.0);
        vec4 p1 = vec4(pw, ph, PI / radius, (zoom - 1.0) * zoom);
        vec4 p2 = vec4(0, 0, -PI / 2.0, 0.0);

        vec4 t0, t1, t2, t3;

        vec3 tc = vec3(1.0, 0.0, 0.0);
        vec2 uv = vec2(gl_FragCoord.x, gl_FragCoord.y);

        t1 = p0.xyww - vec4(uv, 0.0, 0.0);
        t2.x = t2.y = t2.z = t2.w = 1.0 / sqrt(dot(t1.xyz, t1.xyz));
        t0 = t2 - p0;

        t3.x = t3.y = t3.z = t3.w = 1.0 / t2.x;
        t3 = t3 * p1.z + p2.z;
        t3.x = t3.y = t3.z = t3.w = cos(t3.x);

        t3 = t3 * p1.w;

        t1 = t2 * t1;
        t1 = t1 * t3 + vec4(uv, 0.0, 0.0);

        if (t0.z < 0.0) {
                t1.x = uv.x;
                t1.y = uv.y;
        }

        t1 = t1 * p1 + p2;

        tc = texture2D(u_texture, t1.xy).rgb;

        gl_FragColor = vec4(tc, 1.0);
}
)";

class wayfire_fisheye : public wayfire_plugin_t
{

    post_hook_t hook;
    key_callback toggle_cb;
    wf_duration duration;
    float target_zoom;
    bool active, hook_set;
    wf_option radius, zoom;

    GLuint program, posID, mouseID, resID, radiusID, zoomID;

    public:
        void init(wayfire_config *config)
        {
            auto section = config->get_section("fisheye");
            auto toggle_key = section->get_option("toggle", "<super> KEY_F");
            radius = section->get_option("radius", "300");
            zoom = section->get_option("zoom", "7");

            if (!toggle_key->as_key().valid())
                return;

            target_zoom = zoom->as_double();

            hook = [=] (uint32_t fb, uint32_t tex, uint32_t target)
            {
                render(fb, tex, target);
            };

            toggle_cb = [=] (uint32_t key)
            {
                    if (active)
                    {
                        active = false;
                        duration.start(duration.progress(), 0);
                    } else
                    {
                        active = true;
                        duration.start(duration.progress(), target_zoom);

                        if (!hook_set)
                        {
                            hook_set = true;
                            output->render->add_post(&hook);
                        }
                    }
            };

            auto vs = OpenGL::compile_shader(vertex_shader, GL_VERTEX_SHADER);
            auto fs = OpenGL::compile_shader(fragment_shader, GL_FRAGMENT_SHADER);

            program = GL_CALL(glCreateProgram());
            GL_CALL(glAttachShader(program, vs));
            GL_CALL(glAttachShader(program, fs));
            GL_CALL(glLinkProgram(program));

            posID = GL_CALL(glGetAttribLocation(program, "position"));
            mouseID  = GL_CALL(glGetUniformLocation(program, "u_mouse"));
            resID  = GL_CALL(glGetUniformLocation(program, "u_resolution"));
            radiusID  = GL_CALL(glGetUniformLocation(program, "u_radius"));
            zoomID  = GL_CALL(glGetUniformLocation(program, "u_zoom"));

            duration = wf_duration(new_static_option("700"));
            duration.start(0, 0); // so that the first value we get is correct

            output->add_key(toggle_key, &toggle_cb);
        }

        void render(uint32_t fb, uint32_t tex, uint32_t target)
        {
            GetTuple(x, y, output->get_cursor_position());
            GL_CALL(glUseProgram(program));
            GL_CALL(glBindTexture(GL_TEXTURE_2D, tex));
            GL_CALL(glActiveTexture(GL_TEXTURE0));

            static const float vertexData[] = {
                -1.0f, -1.0f,
                 1.0f, -1.0f,
                 1.0f,  1.0f,
                -1.0f,  1.0f
            };

            auto current_zoom = duration.progress();
            target_zoom = zoom->as_double();

            glUniform2f(mouseID, x, y);
            glUniform2f(resID, output->handle->width, output->handle->height);
            glUniform1f(radiusID, radius->as_double());
            glUniform1f(zoomID, current_zoom);

            GL_CALL(glVertexAttribPointer(posID, 2, GL_FLOAT, GL_FALSE, 0, vertexData));
            GL_CALL(glEnableVertexAttribArray(posID));

            GL_CALL(glDisable(GL_BLEND));
            GL_CALL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target));
            GL_CALL(glDrawArrays (GL_TRIANGLE_FAN, 0, 4));
            GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));

            GL_CALL(glDisableVertexAttribArray(posID));
            GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));

            if (active)
            {
                /* Reset animation in case target_zoom
                 * was changed via config */
                duration.start(current_zoom, target_zoom);
            } else if (!duration.running())
            {
                output->render->rem_post(&hook);
                hook_set = false;
            }
        }
};

extern "C"
{
    wayfire_plugin_t *newInstance()
    {
        return new wayfire_fisheye();
    }
}
<commit_msg>fisheye: Add copyright header<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Scott Moreau
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <plugin.hpp>
#include <output.hpp>
#include <opengl.hpp>
#include <debug.hpp>
#include <animation.hpp>
#include <render-manager.hpp>

static const char* vertex_shader =
R"(
#version 100

attribute mediump vec2 position;

void main() {

    gl_Position = vec4(position.xy, 0.0, 1.0);
}
)";

static const char* fragment_shader =
R"(
#version 100
precision mediump float;

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_radius;
uniform float u_zoom;
uniform sampler2D u_texture;

const float PI = 3.1415926535;

void main()
{
        float radius = u_radius;

        float zoom = u_zoom;
        float pw = 1.0 / u_resolution.x;
        float ph = 1.0 / u_resolution.y;

        vec4 p0 = vec4(u_mouse.x, u_resolution.y - u_mouse.y, 1.0 / radius, 0.0);
        vec4 p1 = vec4(pw, ph, PI / radius, (zoom - 1.0) * zoom);
        vec4 p2 = vec4(0, 0, -PI / 2.0, 0.0);

        vec4 t0, t1, t2, t3;

        vec3 tc = vec3(1.0, 0.0, 0.0);
        vec2 uv = vec2(gl_FragCoord.x, gl_FragCoord.y);

        t1 = p0.xyww - vec4(uv, 0.0, 0.0);
        t2.x = t2.y = t2.z = t2.w = 1.0 / sqrt(dot(t1.xyz, t1.xyz));
        t0 = t2 - p0;

        t3.x = t3.y = t3.z = t3.w = 1.0 / t2.x;
        t3 = t3 * p1.z + p2.z;
        t3.x = t3.y = t3.z = t3.w = cos(t3.x);

        t3 = t3 * p1.w;

        t1 = t2 * t1;
        t1 = t1 * t3 + vec4(uv, 0.0, 0.0);

        if (t0.z < 0.0) {
                t1.x = uv.x;
                t1.y = uv.y;
        }

        t1 = t1 * p1 + p2;

        tc = texture2D(u_texture, t1.xy).rgb;

        gl_FragColor = vec4(tc, 1.0);
}
)";

class wayfire_fisheye : public wayfire_plugin_t
{

    post_hook_t hook;
    key_callback toggle_cb;
    wf_duration duration;
    float target_zoom;
    bool active, hook_set;
    wf_option radius, zoom;

    GLuint program, posID, mouseID, resID, radiusID, zoomID;

    public:
        void init(wayfire_config *config)
        {
            auto section = config->get_section("fisheye");
            auto toggle_key = section->get_option("toggle", "<super> KEY_F");
            radius = section->get_option("radius", "300");
            zoom = section->get_option("zoom", "7");

            if (!toggle_key->as_key().valid())
                return;

            target_zoom = zoom->as_double();

            hook = [=] (uint32_t fb, uint32_t tex, uint32_t target)
            {
                render(fb, tex, target);
            };

            toggle_cb = [=] (uint32_t key)
            {
                    if (active)
                    {
                        active = false;
                        duration.start(duration.progress(), 0);
                    } else
                    {
                        active = true;
                        duration.start(duration.progress(), target_zoom);

                        if (!hook_set)
                        {
                            hook_set = true;
                            output->render->add_post(&hook);
                        }
                    }
            };

            auto vs = OpenGL::compile_shader(vertex_shader, GL_VERTEX_SHADER);
            auto fs = OpenGL::compile_shader(fragment_shader, GL_FRAGMENT_SHADER);

            program = GL_CALL(glCreateProgram());
            GL_CALL(glAttachShader(program, vs));
            GL_CALL(glAttachShader(program, fs));
            GL_CALL(glLinkProgram(program));

            posID = GL_CALL(glGetAttribLocation(program, "position"));
            mouseID  = GL_CALL(glGetUniformLocation(program, "u_mouse"));
            resID  = GL_CALL(glGetUniformLocation(program, "u_resolution"));
            radiusID  = GL_CALL(glGetUniformLocation(program, "u_radius"));
            zoomID  = GL_CALL(glGetUniformLocation(program, "u_zoom"));

            duration = wf_duration(new_static_option("700"));
            duration.start(0, 0); // so that the first value we get is correct

            output->add_key(toggle_key, &toggle_cb);
        }

        void render(uint32_t fb, uint32_t tex, uint32_t target)
        {
            GetTuple(x, y, output->get_cursor_position());
            GL_CALL(glUseProgram(program));
            GL_CALL(glBindTexture(GL_TEXTURE_2D, tex));
            GL_CALL(glActiveTexture(GL_TEXTURE0));

            static const float vertexData[] = {
                -1.0f, -1.0f,
                 1.0f, -1.0f,
                 1.0f,  1.0f,
                -1.0f,  1.0f
            };

            auto current_zoom = duration.progress();
            target_zoom = zoom->as_double();

            glUniform2f(mouseID, x, y);
            glUniform2f(resID, output->handle->width, output->handle->height);
            glUniform1f(radiusID, radius->as_double());
            glUniform1f(zoomID, current_zoom);

            GL_CALL(glVertexAttribPointer(posID, 2, GL_FLOAT, GL_FALSE, 0, vertexData));
            GL_CALL(glEnableVertexAttribArray(posID));

            GL_CALL(glDisable(GL_BLEND));
            GL_CALL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target));
            GL_CALL(glDrawArrays (GL_TRIANGLE_FAN, 0, 4));
            GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));

            GL_CALL(glDisableVertexAttribArray(posID));
            GL_CALL(glBindTexture(GL_TEXTURE_2D, 0));

            if (active)
            {
                /* Reset animation in case target_zoom
                 * was changed via config */
                duration.start(current_zoom, target_zoom);
            } else if (!duration.running())
            {
                output->render->rem_post(&hook);
                hook_set = false;
            }
        }
};

extern "C"
{
    wayfire_plugin_t *newInstance()
    {
        return new wayfire_fisheye();
    }
}
<|endoftext|>


<commit_before>/*******************************************************************************/
/* Bela Csound Rendering functions                                             */
/*                                                                             */
/*******************************************************************************/

#include <Bela.h>
#include <Midi.h>
#include <csound/csound.hpp>
#include <vector>
#include <sstream>

#define ANCHNS 8

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);

struct CsChan {
  std::vector<MYFLT> data;
  std::stringstream name;
};

struct CsData {
  Csound *csound;
  int blocksize;
  int res;
  int count;
  CsChan channel[ANCHNS];
};

CsData gCsData;

bool setup(BelaContext *context, void *Data)
{
  Csound *csound;
  const char *csdfile = "my.csd"; /* CSD name */
  const char *midiDev = "-Mhw:1,0,0"; /* MIDI device */
  const char *args[] = { "csound", csdfile, "-iadc", "-odac", "-+rtaudio=null",
			 "--realtime", "--daemon", midiDev };
  int numArgs = (int) (sizeof(args)/sizeof(char *));

  if(context->audioInChannels != context->audioOutChannels) {
    printf("Number of audio inputs != number of audio outputs.\n");
    return false;
  }

  /* setup Csound */
  csound = new Csound();
  csound->SetHostImplementedAudioIO(1,0);
  csound->SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  gCsData.csound = csound;
  gCsData.res = csound->Compile(numArgs, args);
  gCsData.blocksize = csound->GetKsmps()*csound->GetNchnls();
  gCsData.count = 0;

  /* set up the channels */
  for(int i; i < ANCHNS; i++) {
    gCsData.channel[i].data.resize(csound->GetKsmps());
    gCsData.channel[i].name << "analogue" << i+1;
  }

  if(gCsData.res != 0) return false;
  else return true;
}

void render(BelaContext *context, void *Data)
{
  if(gCsData.res == 0) {
    int n,i,k,count, frmcount,blocksize,res;
    Csound *csound = gCsData.csound;
    MYFLT scal = csound->Get0dBFS();
    MYFLT* audioIn = csound->GetSpin();
    MYFLT* audioOut = csound->GetSpout();
    int nchnls = csound->GetNchnls();
    int chns = nchnls < context->audioOutChannels ?
      nchnls : context->audioOutChannels;
    int an_chns = context->analogInChannels > ANCHNS ?
      ANCHNS : context->analogInChannels;
    CsChan *channel = &(gCsData.channel[0]);
    float frm = 0, incr = ((float) context->analogFrames)/context->audioFrames;
    int an_chans = context->analogInChannels;
    count = gCsData.count;
    blocksize = gCsData.blocksize;

    /* this is called when Csound is not running */
    if(count < 0) {
      for(n = 0; n < context->audioFrames; n++){
	for(i = 0; i < context->audioOutChannels; i++){
	  audioWrite(context,n,i,0);
	}
      }
      return;
    }

    /* this is where Csound is called */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {
	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     &(channel[i].data[0]));
	}
	/* run csound */
	if((res = csound->PerformKsmps()) == 0) count = 0;
	else {
	  count = -1;
	  break;
	}
      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }

      /* read analogue data
         analogue frame pos gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].data[frmcount] = analogRead(context,k,i);
      }
    }
    gCsData.res = res;
    gCsData.count = count;
  }
}

void cleanup(BelaContext *context, void *Data)
{
  delete gCsData.csound;
}

/** MIDI Input functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  Midi *midi = new Midi;
  midi->readFrom(dev);
  midi->enableParser(false);
  *userData = (void *) midi;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  delete (Midi *) userData;
}

int ReadMidiData(CSOUND *csound, void *userData,
		 unsigned char *mbuf, int nbytes) {
  int n = 0;
  Midi midi = (Midi *) userData;

  while((byte = midi->getInput()) >= 0) {
    *mbuf++ = (unsigned char) byte;
    if(++n == nbytes) break;
  }

  return n;
}
<commit_msg>marking as static<commit_after>/*******************************************************************************/
/* Bela Csound Rendering functions                                             */
/*                                                                             */
/*******************************************************************************/

#include <Bela.h>
#include <Midi.h>
#include <csound/csound.hpp>
#include <vector>
#include <sstream>

#define ANCHNS 8

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);

struct CsChan {
  std::vector<MYFLT> data;
  std::stringstream name;
};

struct CsData {
  Csound *csound;
  int blocksize;
  int res;
  int count;
  CsChan channel[ANCHNS];
};

static CsData gCsData;

bool setup(BelaContext *context, void *Data)
{
  Csound *csound;
  const char *csdfile = "my.csd"; /* CSD name */
  const char *midiDev = "-Mhw:1,0,0"; /* MIDI device */
  const char *args[] = { "csound", csdfile, "-iadc", "-odac", "-+rtaudio=null",
			 "--realtime", "--daemon", midiDev };
  int numArgs = (int) (sizeof(args)/sizeof(char *));

  if(context->audioInChannels != context->audioOutChannels) {
    printf("Number of audio inputs != number of audio outputs.\n");
    return false;
  }

  /* setup Csound */
  csound = new Csound();
  csound->SetHostImplementedAudioIO(1,0);
  csound->SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  gCsData.csound = csound;
  gCsData.res = csound->Compile(numArgs, args);
  gCsData.blocksize = csound->GetKsmps()*csound->GetNchnls();
  gCsData.count = 0;

  /* set up the channels */
  for(int i; i < ANCHNS; i++) {
    gCsData.channel[i].data.resize(csound->GetKsmps());
    gCsData.channel[i].name << "analogue" << i+1;
  }

  if(gCsData.res != 0) return false;
  else return true;
}

void render(BelaContext *context, void *Data)
{
  if(gCsData.res == 0) {
    int n,i,k,count, frmcount,blocksize,res;
    Csound *csound = gCsData.csound;
    MYFLT scal = csound->Get0dBFS();
    MYFLT* audioIn = csound->GetSpin();
    MYFLT* audioOut = csound->GetSpout();
    int nchnls = csound->GetNchnls();
    int chns = nchnls < context->audioOutChannels ?
      nchnls : context->audioOutChannels;
    int an_chns = context->analogInChannels > ANCHNS ?
      ANCHNS : context->analogInChannels;
    CsChan *channel = &(gCsData.channel[0]);
    float frm = 0, incr = ((float) context->analogFrames)/context->audioFrames;
    int an_chans = context->analogInChannels;
    count = gCsData.count;
    blocksize = gCsData.blocksize;

    /* this is called when Csound is not running */
    if(count < 0) {
      for(n = 0; n < context->audioFrames; n++){
	for(i = 0; i < context->audioOutChannels; i++){
	  audioWrite(context,n,i,0);
	}
      }
      return;
    }

    /* this is where Csound is called */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {
	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     &(channel[i].data[0]));
	}
	/* run csound */
	if((res = csound->PerformKsmps()) == 0) count = 0;
	else {
	  count = -1;
	  break;
	}
      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }

      /* read analogue data
         analogue frame pos gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].data[frmcount] = analogRead(context,k,i);
      }
    }
    gCsData.res = res;
    gCsData.count = count;
  }
}

void cleanup(BelaContext *context, void *Data)
{
  delete gCsData.csound;
}

/** MIDI Input functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  Midi *midi = new Midi;
  midi->readFrom(dev);
  midi->enableParser(false);
  *userData = (void *) midi;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  delete (Midi *) userData;
}

int ReadMidiData(CSOUND *csound, void *userData,
		 unsigned char *mbuf, int nbytes) {
  int n = 0;
  Midi midi = (Midi *) userData;

  while((byte = midi->getInput()) >= 0) {
    *mbuf++ = (unsigned char) byte;
    if(++n == nbytes) break;
  }

  return n;
}
<|endoftext|>