<commit_before>// Copyright (c) 2012-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "coins.h"

#include "consensus/consensus.h"
#include "memusage.h"
#include "random.h"

#include <assert.h>

bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return uint256(); }
std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
CCoinsViewCursor *CCoinsView::Cursor() const { return nullptr; }

bool CCoinsView::HaveCoin(const COutPoint &outpoint) const
{
    Coin coin;
    return GetCoin(outpoint, coin);
}

CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); }
bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base->HaveCoin(outpoint); }
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }

SaltedOutpointHasher::SaltedOutpointHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}

CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0) {}

size_t CCoinsViewCache::DynamicMemoryUsage() const {
    return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
}

CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const {
    CCoinsMap::iterator it = cacheCoins.find(outpoint);
    if (it != cacheCoins.end())
        return it;
    Coin tmp;
    if (!base->GetCoin(outpoint, tmp))
        return cacheCoins.end();
    CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
    if (ret->second.coin.IsSpent()) {
        // The parent only has an empty entry for this outpoint; we can consider our
        // version as fresh.
        ret->second.flags = CCoinsCacheEntry::FRESH;
    }
    cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
    return ret;
}

bool CCoinsViewCache::GetCoin(const COutPoint &outpoint, Coin &coin) const {
    CCoinsMap::const_iterator it = FetchCoin(outpoint);
    if (it != cacheCoins.end()) {
        coin = it->second.coin;
        return !coin.IsSpent();
    }
    return false;
}

void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possible_overwrite) {
    assert(!coin.IsSpent());
    if (coin.out.scriptPubKey.IsUnspendable()) return;
    CCoinsMap::iterator it;
    bool inserted;
    std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>());
    bool fresh = false;
    if (!inserted) {
        cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
    }
    if (!possible_overwrite) {
        if (!it->second.coin.IsSpent()) {
            throw std::logic_error("Adding new coin that replaces non-pruned entry");
        }
        fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY);
    }
    it->second.coin = std::move(coin);
    it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0);
    cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
}

void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, bool check) {
    bool fCoinbase = tx.IsCoinBase();
    const uint256& txid = tx.GetHash();
    for (size_t i = 0; i < tx.vout.size(); ++i) {
        bool overwrite = check ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase;
        // Always set the possible_overwrite flag to AddCoin for coinbase txn, in order to correctly
        // deal with the pre-BIP30 occurrences of duplicate coinbase transactions.
        cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase), overwrite);
    }
}

bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
    CCoinsMap::iterator it = FetchCoin(outpoint);
    if (it == cacheCoins.end()) return false;
    cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
    if (moveout) {
        *moveout = std::move(it->second.coin);
    }
    if (it->second.flags & CCoinsCacheEntry::FRESH) {
        cacheCoins.erase(it);
    } else {
        it->second.flags |= CCoinsCacheEntry::DIRTY;
        it->second.coin.Clear();
    }
    return true;
}

static const Coin coinEmpty;

const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
    CCoinsMap::const_iterator it = FetchCoin(outpoint);
    if (it == cacheCoins.end()) {
        return coinEmpty;
    } else {
        return it->second.coin;
    }
}

bool CCoinsViewCache::HaveCoin(const COutPoint &outpoint) const {
    CCoinsMap::const_iterator it = FetchCoin(outpoint);
    return (it != cacheCoins.end() && !it->second.coin.IsSpent());
}

bool CCoinsViewCache::HaveCoinInCache(const COutPoint &outpoint) const {
    CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
    return (it != cacheCoins.end() && !it->second.coin.IsSpent());
}

uint256 CCoinsViewCache::GetBestBlock() const {
    if (hashBlock.IsNull())
        hashBlock = base->GetBestBlock();
    return hashBlock;
}

void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
    hashBlock = hashBlockIn;
}

bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
    for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
        if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization).
            CCoinsMap::iterator itUs = cacheCoins.find(it->first);
            if (itUs == cacheCoins.end()) {
                // The parent cache does not have an entry, while the child does
                // We can ignore it if it's both FRESH and pruned in the child
                if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsSpent())) {
                    // Otherwise we will need to create it in the parent
                    // and move the data up and mark it as dirty
                    CCoinsCacheEntry& entry = cacheCoins[it->first];
                    entry.coin = std::move(it->second.coin);
                    cachedCoinsUsage += entry.coin.DynamicMemoryUsage();
                    entry.flags = CCoinsCacheEntry::DIRTY;
                    // We can mark it FRESH in the parent if it was FRESH in the child
                    // Otherwise it might have just been flushed from the parent's cache
                    // and already exist in the grandparent
                    if (it->second.flags & CCoinsCacheEntry::FRESH)
                        entry.flags |= CCoinsCacheEntry::FRESH;
                }
            } else {
                // Assert that the child cache entry was not marked FRESH if the
                // parent cache entry has unspent outputs. If this ever happens,
                // it means the FRESH flag was misapplied and there is a logic
                // error in the calling code.
                if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent())
                    throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");

                // Found the entry in the parent cache
                if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
                    // The grandparent does not have an entry, and the child is
                    // modified and being pruned. This means we can just delete
                    // it from the parent.
                    cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
                    cacheCoins.erase(itUs);
                } else {
                    // A normal modification.
                    cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
                    itUs->second.coin = std::move(it->second.coin);
                    cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
                    itUs->second.flags |= CCoinsCacheEntry::DIRTY;
                    // NOTE: It is possible the child has a FRESH flag here in
                    // the event the entry we found in the parent is pruned. But
                    // we must not copy that FRESH flag to the parent as that
                    // pruned state likely still needs to be communicated to the
                    // grandparent.
                }
            }
        }
        CCoinsMap::iterator itOld = it++;
        mapCoins.erase(itOld);
    }
    hashBlock = hashBlockIn;
    return true;
}

bool CCoinsViewCache::Flush() {
    bool fOk = base->BatchWrite(cacheCoins, hashBlock);
    cacheCoins.clear();
    cachedCoinsUsage = 0;
    return fOk;
}

void CCoinsViewCache::Uncache(const COutPoint& hash)
{
    CCoinsMap::iterator it = cacheCoins.find(hash);
    if (it != cacheCoins.end() && it->second.flags == 0) {
        cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
        cacheCoins.erase(it);
    }
}

unsigned int CCoinsViewCache::GetCacheSize() const {
    return cacheCoins.size();
}

CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const
{
    if (tx.IsCoinBase())
        return 0;

    CAmount nResult = 0;
    for (unsigned int i = 0; i < tx.vin.size(); i++)
        nResult += AccessCoin(tx.vin[i].prevout).out.nValue;

    return nResult;
}

bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
    if (!tx.IsCoinBase()) {
        for (unsigned int i = 0; i < tx.vin.size(); i++) {
            if (!HaveCoin(tx.vin[i].prevout)) {
                return false;
            }
        }
    }
    return true;
}

static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION);
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT;

const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
{
    COutPoint iter(txid, 0);
    while (iter.n < MAX_OUTPUTS_PER_BLOCK) {
        const Coin& alternate = view.AccessCoin(iter);
        if (!alternate.IsSpent()) return alternate;
        ++iter.n;
    }
    return coinEmpty;
}
<commit_msg>Small refactor of CCoinsViewCache::BatchWrite()<commit_after>// Copyright (c) 2012-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "coins.h"

#include "consensus/consensus.h"
#include "memusage.h"
#include "random.h"

#include <assert.h>

bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
uint256 CCoinsView::GetBestBlock() const { return uint256(); }
std::vector<uint256> CCoinsView::GetHeadBlocks() const { return std::vector<uint256>(); }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; }
CCoinsViewCursor *CCoinsView::Cursor() const { return nullptr; }

bool CCoinsView::HaveCoin(const COutPoint &outpoint) const
{
    Coin coin;
    return GetCoin(outpoint, coin);
}

CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { }
bool CCoinsViewBacked::GetCoin(const COutPoint &outpoint, Coin &coin) const { return base->GetCoin(outpoint, coin); }
bool CCoinsViewBacked::HaveCoin(const COutPoint &outpoint) const { return base->HaveCoin(outpoint); }
uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
std::vector<uint256> CCoinsViewBacked::GetHeadBlocks() const { return base->GetHeadBlocks(); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }

SaltedOutpointHasher::SaltedOutpointHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}

CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), cachedCoinsUsage(0) {}

size_t CCoinsViewCache::DynamicMemoryUsage() const {
    return memusage::DynamicUsage(cacheCoins) + cachedCoinsUsage;
}

CCoinsMap::iterator CCoinsViewCache::FetchCoin(const COutPoint &outpoint) const {
    CCoinsMap::iterator it = cacheCoins.find(outpoint);
    if (it != cacheCoins.end())
        return it;
    Coin tmp;
    if (!base->GetCoin(outpoint, tmp))
        return cacheCoins.end();
    CCoinsMap::iterator ret = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::forward_as_tuple(std::move(tmp))).first;
    if (ret->second.coin.IsSpent()) {
        // The parent only has an empty entry for this outpoint; we can consider our
        // version as fresh.
        ret->second.flags = CCoinsCacheEntry::FRESH;
    }
    cachedCoinsUsage += ret->second.coin.DynamicMemoryUsage();
    return ret;
}

bool CCoinsViewCache::GetCoin(const COutPoint &outpoint, Coin &coin) const {
    CCoinsMap::const_iterator it = FetchCoin(outpoint);
    if (it != cacheCoins.end()) {
        coin = it->second.coin;
        return !coin.IsSpent();
    }
    return false;
}

void CCoinsViewCache::AddCoin(const COutPoint &outpoint, Coin&& coin, bool possible_overwrite) {
    assert(!coin.IsSpent());
    if (coin.out.scriptPubKey.IsUnspendable()) return;
    CCoinsMap::iterator it;
    bool inserted;
    std::tie(it, inserted) = cacheCoins.emplace(std::piecewise_construct, std::forward_as_tuple(outpoint), std::tuple<>());
    bool fresh = false;
    if (!inserted) {
        cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
    }
    if (!possible_overwrite) {
        if (!it->second.coin.IsSpent()) {
            throw std::logic_error("Adding new coin that replaces non-pruned entry");
        }
        fresh = !(it->second.flags & CCoinsCacheEntry::DIRTY);
    }
    it->second.coin = std::move(coin);
    it->second.flags |= CCoinsCacheEntry::DIRTY | (fresh ? CCoinsCacheEntry::FRESH : 0);
    cachedCoinsUsage += it->second.coin.DynamicMemoryUsage();
}

void AddCoins(CCoinsViewCache& cache, const CTransaction &tx, int nHeight, bool check) {
    bool fCoinbase = tx.IsCoinBase();
    const uint256& txid = tx.GetHash();
    for (size_t i = 0; i < tx.vout.size(); ++i) {
        bool overwrite = check ? cache.HaveCoin(COutPoint(txid, i)) : fCoinbase;
        // Always set the possible_overwrite flag to AddCoin for coinbase txn, in order to correctly
        // deal with the pre-BIP30 occurrences of duplicate coinbase transactions.
        cache.AddCoin(COutPoint(txid, i), Coin(tx.vout[i], nHeight, fCoinbase), overwrite);
    }
}

bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
    CCoinsMap::iterator it = FetchCoin(outpoint);
    if (it == cacheCoins.end()) return false;
    cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
    if (moveout) {
        *moveout = std::move(it->second.coin);
    }
    if (it->second.flags & CCoinsCacheEntry::FRESH) {
        cacheCoins.erase(it);
    } else {
        it->second.flags |= CCoinsCacheEntry::DIRTY;
        it->second.coin.Clear();
    }
    return true;
}

static const Coin coinEmpty;

const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
    CCoinsMap::const_iterator it = FetchCoin(outpoint);
    if (it == cacheCoins.end()) {
        return coinEmpty;
    } else {
        return it->second.coin;
    }
}

bool CCoinsViewCache::HaveCoin(const COutPoint &outpoint) const {
    CCoinsMap::const_iterator it = FetchCoin(outpoint);
    return (it != cacheCoins.end() && !it->second.coin.IsSpent());
}

bool CCoinsViewCache::HaveCoinInCache(const COutPoint &outpoint) const {
    CCoinsMap::const_iterator it = cacheCoins.find(outpoint);
    return (it != cacheCoins.end() && !it->second.coin.IsSpent());
}

uint256 CCoinsViewCache::GetBestBlock() const {
    if (hashBlock.IsNull())
        hashBlock = base->GetBestBlock();
    return hashBlock;
}

void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) {
    hashBlock = hashBlockIn;
}

bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn) {
    for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end(); it = mapCoins.erase(it)) {
        // Ignore non-dirty entries (optimization).
        if (!(it->second.flags & CCoinsCacheEntry::DIRTY)) {
            continue;
        }
        CCoinsMap::iterator itUs = cacheCoins.find(it->first);
        if (itUs == cacheCoins.end()) {
            // The parent cache does not have an entry, while the child does
            // We can ignore it if it's both FRESH and pruned in the child
            if (!(it->second.flags & CCoinsCacheEntry::FRESH && it->second.coin.IsSpent())) {
                // Otherwise we will need to create it in the parent
                // and move the data up and mark it as dirty
                CCoinsCacheEntry& entry = cacheCoins[it->first];
                entry.coin = std::move(it->second.coin);
                cachedCoinsUsage += entry.coin.DynamicMemoryUsage();
                entry.flags = CCoinsCacheEntry::DIRTY;
                // We can mark it FRESH in the parent if it was FRESH in the child
                // Otherwise it might have just been flushed from the parent's cache
                // and already exist in the grandparent
                if (it->second.flags & CCoinsCacheEntry::FRESH) {
                    entry.flags |= CCoinsCacheEntry::FRESH;
                }
            }
        } else {
            // Assert that the child cache entry was not marked FRESH if the
            // parent cache entry has unspent outputs. If this ever happens,
            // it means the FRESH flag was misapplied and there is a logic
            // error in the calling code.
            if ((it->second.flags & CCoinsCacheEntry::FRESH) && !itUs->second.coin.IsSpent()) {
                throw std::logic_error("FRESH flag misapplied to cache entry for base transaction with spendable outputs");
            }

            // Found the entry in the parent cache
            if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coin.IsSpent()) {
                // The grandparent does not have an entry, and the child is
                // modified and being pruned. This means we can just delete
                // it from the parent.
                cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
                cacheCoins.erase(itUs);
            } else {
                // A normal modification.
                cachedCoinsUsage -= itUs->second.coin.DynamicMemoryUsage();
                itUs->second.coin = std::move(it->second.coin);
                cachedCoinsUsage += itUs->second.coin.DynamicMemoryUsage();
                itUs->second.flags |= CCoinsCacheEntry::DIRTY;
                // NOTE: It is possible the child has a FRESH flag here in
                // the event the entry we found in the parent is pruned. But
                // we must not copy that FRESH flag to the parent as that
                // pruned state likely still needs to be communicated to the
                // grandparent.
            }
        }
    }
    hashBlock = hashBlockIn;
    return true;
}

bool CCoinsViewCache::Flush() {
    bool fOk = base->BatchWrite(cacheCoins, hashBlock);
    cacheCoins.clear();
    cachedCoinsUsage = 0;
    return fOk;
}

void CCoinsViewCache::Uncache(const COutPoint& hash)
{
    CCoinsMap::iterator it = cacheCoins.find(hash);
    if (it != cacheCoins.end() && it->second.flags == 0) {
        cachedCoinsUsage -= it->second.coin.DynamicMemoryUsage();
        cacheCoins.erase(it);
    }
}

unsigned int CCoinsViewCache::GetCacheSize() const {
    return cacheCoins.size();
}

CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const
{
    if (tx.IsCoinBase())
        return 0;

    CAmount nResult = 0;
    for (unsigned int i = 0; i < tx.vin.size(); i++)
        nResult += AccessCoin(tx.vin[i].prevout).out.nValue;

    return nResult;
}

bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
    if (!tx.IsCoinBase()) {
        for (unsigned int i = 0; i < tx.vin.size(); i++) {
            if (!HaveCoin(tx.vin[i].prevout)) {
                return false;
            }
        }
    }
    return true;
}

static const size_t MIN_TRANSACTION_OUTPUT_WEIGHT = WITNESS_SCALE_FACTOR * ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION);
static const size_t MAX_OUTPUTS_PER_BLOCK = MAX_BLOCK_WEIGHT / MIN_TRANSACTION_OUTPUT_WEIGHT;

const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
{
    COutPoint iter(txid, 0);
    while (iter.n < MAX_OUTPUTS_PER_BLOCK) {
        const Coin& alternate = view.AccessCoin(iter);
        if (!alternate.IsSpent()) return alternate;
        ++iter.n;
    }
    return coinEmpty;
}
<|endoftext|>


<commit_before>#include "Button.hpp"
#include <Engine/Util/Input.hpp>

using namespace GUI;

Button::Button(Widget* parent) : Widget(parent) {
    mouseHover = false;
    hasClickedCallback = false;
    size = glm::vec2(64.f, 64.f);
}

Button::~Button() {

}

void Button::Update() {
    double xpos = Input()->CursorX();
    double ypos = Input()->CursorY();

    mouseHover = xpos >= GetPosition().x && xpos < GetPosition().x + size.x && ypos >= GetPosition().y && ypos < GetPosition().y + size.y;

    if (mouseHover && Input()->MousePressed(GLFW_MOUSE_BUTTON_LEFT) && hasClickedCallback) {
        clickedCallback();
    }
}

glm::vec2 Button::GetSize() const {
    return size;
}

void Button::SetSize(const glm::vec2& size) {
    this->size = size;
}

void Button::SetClickedCallback(std::function<void()> callback) {
    clickedCallback = callback;
    hasClickedCallback = true;
}

bool Button::GetMouseHover() const {
    return mouseHover;
}
<commit_msg>Fix forward declaration.<commit_after>#include "Button.hpp"

#include <Engine/Geometry/Rectangle.hpp>
#include <Engine/Util/Input.hpp>

using namespace GUI;

Button::Button(Widget* parent) : Widget(parent) {
    mouseHover = false;
    hasClickedCallback = false;
    size = glm::vec2(64.f, 64.f);
}

Button::~Button() {

}

void Button::Update() {
    double xpos = Input()->CursorX();
    double ypos = Input()->CursorY();

    mouseHover = xpos >= GetPosition().x && xpos < GetPosition().x + size.x && ypos >= GetPosition().y && ypos < GetPosition().y + size.y;

    if (mouseHover && Input()->MousePressed(GLFW_MOUSE_BUTTON_LEFT) && hasClickedCallback) {
        clickedCallback();
    }
}

glm::vec2 Button::GetSize() const {
    return size;
}

void Button::SetSize(const glm::vec2& size) {
    this->size = size;
}

void Button::SetClickedCallback(std::function<void()> callback) {
    clickedCallback = callback;
    hasClickedCallback = true;
}

bool Button::GetMouseHover() const {
    return mouseHover;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "ServiceDispatcher.h"

//--- standard modules used ----------------------------------------------------
#include "Registry.h"
#include "Timers.h"
#include "ServiceHandler.h"
#include "Renderer.h"
#include "Dbg.h"

//---- ServiceDispatchersModule -----------------------------------------------------------
RegisterModule(ServiceDispatchersModule);

ServiceDispatchersModule::ServiceDispatchersModule(const char *name) : WDModule(name)
{
}

ServiceDispatchersModule::~ServiceDispatchersModule()
{
}

bool ServiceDispatchersModule::Init(const Anything &config)
{
	if (config.IsDefined("ServiceDispatchers")) {
		HierarchyInstaller ai("ServiceDispatcher");
		return RegisterableObject::Install(config["ServiceDispatchers"], "ServiceDispatcher", &ai);
	}
	return false;
}

bool ServiceDispatchersModule::ResetFinis(const Anything &config)
{
	AliasTerminator at("ServiceDispatcher");
	return RegisterableObject::ResetTerminate("ServiceDispatcher", &at);
}

bool ServiceDispatchersModule::Finis()
{
	return StdFinis("ServiceDispatcher", "ServiceDispatchers");
}

//---- ServiceDispatcher -----------------------------------------------------------
RegisterServiceDispatcher(ServiceDispatcher);

ServiceDispatcher::ServiceDispatcher(const char *ServiceDispatcherName)
	: HierarchConfNamed(ServiceDispatcherName)
{
	StartTrace(ServiceDispatcher.Ctor);
}

ServiceDispatcher::~ServiceDispatcher()
{
	StartTrace(ServiceDispatcher.Dtor);

}

void ServiceDispatcher::Dispatch2Service(ostream &reply, Context &ctx)
{
	StartTrace(ServiceDispatcher.Dispatch2Service);
	ctx.Push("ServiceDispatcher", this);
	ServiceHandler *sh = FindServiceHandler(ctx);

	// if no service handler is found DefaultHandler is used
	if (!sh) {
		String def = ctx.Lookup("DefaultHandler", "WebAppService");
		Trace("not found, looking for DefaultHandler:" << def);
		sh = ServiceHandler::FindServiceHandler(def);
	}
	sh->HandleService(reply, ctx);
}

ServiceHandler *ServiceDispatcher::FindServiceHandler(Context &ctx)
{
	StartTrace(ServiceDispatcher.FindServiceHandler);
	String name = FindServiceName(ctx);
	Trace("Service:" << name);
	return ServiceHandler::FindServiceHandler(name);
}

String ServiceDispatcher::FindServiceName(Context &ctx)
{
	StartTrace(ServiceDispatcher.FindServiceName);

	return ctx.Lookup("DefaultService", "WebAppService");
}

RegisterServiceDispatcher(RendererDispatcher);
//--- RendererDispatcher ---------------------------------------------------
RendererDispatcher::RendererDispatcher(const char *rendererDispatcherName)
	: ServiceDispatcher(rendererDispatcherName)
{

}

RendererDispatcher::~RendererDispatcher()
{

}

long RendererDispatcher::FindURIPrefixInList(const String &requestURI, const ROAnything &uriPrefixList)
{
	StartTrace(RendererDispatcher.FindURIPrefixInList);

	long apSz = uriPrefixList.GetSize();
	for (long i = 0; i < apSz; i++) {
		const char *uriPrefix = uriPrefixList.SlotName(i);
		if ( uriPrefix && requestURI.StartsWith(uriPrefix) ) {
			return i;
		}
	}
	return -1;
}

String RendererDispatcher::FindServiceName(Context &ctx)
{
	StartTrace(RendererDispatcher.FindServiceName);

	ROAnything uriPrefixList(ctx.Lookup("URIPrefix2ServiceMap"));
	String requestURI(ctx.Lookup("REQUEST_URI", ""));
	Anything query(ctx.GetQuery());
	SubTraceAny(uriPrefixList, uriPrefixList, "Service Prefixes: ");

	long matchedPrefix = FindURIPrefixInList(requestURI, uriPrefixList);
	if (matchedPrefix >= 0) {
		String service;
		Renderer::RenderOnString(service, ctx, uriPrefixList[matchedPrefix]);
		query["Service"] = service;
		query["URIPrefix"] = uriPrefixList.SlotName(matchedPrefix);

		SubTraceAny(query, query, "Query: ");
		Trace("Service:<" << service << ">");
		return service;
	} else if (uriPrefixList.GetSize() > 0) {
		query["Error"] = "ServiceNotFound";
	}

	String defaultHandler(ServiceDispatcher::FindServiceName(ctx));
	Trace("Service:<" << defaultHandler << ">");
	return defaultHandler;
}

//---- registry interface
RegCacheImpl(ServiceDispatcher);	// FindServiceDispatcher()
<commit_msg>tracing request URI<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "ServiceDispatcher.h"

//--- standard modules used ----------------------------------------------------
#include "Registry.h"
#include "Timers.h"
#include "ServiceHandler.h"
#include "Renderer.h"
#include "Dbg.h"

//---- ServiceDispatchersModule -----------------------------------------------------------
RegisterModule(ServiceDispatchersModule);

ServiceDispatchersModule::ServiceDispatchersModule(const char *name) : WDModule(name)
{
}

ServiceDispatchersModule::~ServiceDispatchersModule()
{
}

bool ServiceDispatchersModule::Init(const Anything &config)
{
	if (config.IsDefined("ServiceDispatchers")) {
		HierarchyInstaller ai("ServiceDispatcher");
		return RegisterableObject::Install(config["ServiceDispatchers"], "ServiceDispatcher", &ai);
	}
	return false;
}

bool ServiceDispatchersModule::ResetFinis(const Anything &config)
{
	AliasTerminator at("ServiceDispatcher");
	return RegisterableObject::ResetTerminate("ServiceDispatcher", &at);
}

bool ServiceDispatchersModule::Finis()
{
	return StdFinis("ServiceDispatcher", "ServiceDispatchers");
}

//---- ServiceDispatcher -----------------------------------------------------------
RegisterServiceDispatcher(ServiceDispatcher);

ServiceDispatcher::ServiceDispatcher(const char *ServiceDispatcherName)
	: HierarchConfNamed(ServiceDispatcherName)
{
	StartTrace(ServiceDispatcher.Ctor);
}

ServiceDispatcher::~ServiceDispatcher()
{
	StartTrace(ServiceDispatcher.Dtor);

}

void ServiceDispatcher::Dispatch2Service(ostream &reply, Context &ctx)
{
	StartTrace(ServiceDispatcher.Dispatch2Service);
	ctx.Push("ServiceDispatcher", this);
	ServiceHandler *sh = FindServiceHandler(ctx);

	// if no service handler is found DefaultHandler is used
	if (!sh) {
		String def = ctx.Lookup("DefaultHandler", "WebAppService");
		Trace("not found, looking for DefaultHandler:" << def);
		sh = ServiceHandler::FindServiceHandler(def);
	}
	sh->HandleService(reply, ctx);
}

ServiceHandler *ServiceDispatcher::FindServiceHandler(Context &ctx)
{
	StartTrace(ServiceDispatcher.FindServiceHandler);
	String name = FindServiceName(ctx);
	Trace("Service:" << name);
	return ServiceHandler::FindServiceHandler(name);
}

String ServiceDispatcher::FindServiceName(Context &ctx)
{
	StartTrace(ServiceDispatcher.FindServiceName);

	return ctx.Lookup("DefaultService", "WebAppService");
}

RegisterServiceDispatcher(RendererDispatcher);
//--- RendererDispatcher ---------------------------------------------------
RendererDispatcher::RendererDispatcher(const char *rendererDispatcherName)
	: ServiceDispatcher(rendererDispatcherName)
{

}

RendererDispatcher::~RendererDispatcher()
{

}

long RendererDispatcher::FindURIPrefixInList(const String &requestURI, const ROAnything &uriPrefixList)
{
	StartTrace(RendererDispatcher.FindURIPrefixInList);

	long apSz = uriPrefixList.GetSize();
	for (long i = 0; i < apSz; i++) {
		const char *uriPrefix = uriPrefixList.SlotName(i);
		if ( uriPrefix && requestURI.StartsWith(uriPrefix) ) {
			return i;
		}
	}
	return -1;
}

String RendererDispatcher::FindServiceName(Context &ctx)
{
	StartTrace(RendererDispatcher.FindServiceName);

	ROAnything uriPrefixList(ctx.Lookup("URIPrefix2ServiceMap"));
	String requestURI(ctx.Lookup("REQUEST_URI", ""));
	Trace("request URI [" << requestURI << "]");
	Anything query(ctx.GetQuery());
	SubTraceAny(uriPrefixList, uriPrefixList, "Service Prefixes: ");

	long matchedPrefix = FindURIPrefixInList(requestURI, uriPrefixList);
	if (matchedPrefix >= 0) {
		String service;
		Renderer::RenderOnString(service, ctx, uriPrefixList[matchedPrefix]);
		query["Service"] = service;
		query["URIPrefix"] = uriPrefixList.SlotName(matchedPrefix);

		SubTraceAny(query, query, "Query: ");
		Trace("Service:<" << service << ">");
		return service;
	} else if (uriPrefixList.GetSize() > 0) {
		query["Error"] = "ServiceNotFound";
	}

	String defaultHandler(ServiceDispatcher::FindServiceName(ctx));
	Trace("Service:<" << defaultHandler << ">");
	return defaultHandler;
}

//---- registry interface
RegCacheImpl(ServiceDispatcher);	// FindServiceDispatcher()
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI Widget Text クラス（ヘッダー）
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "widgets/widget_director.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	GUI widget_text クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct widget_text : public widget {

		typedef widget_text value_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_text パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {
			text_param	text_param_;
			param(const std::string& text = "") : text_param_(text,
				img::rgba8(255, 255), img::rgba8(0, 255),
				vtx::placement(vtx::placement::holizontal::LEFT,
					vtx::placement::vertical::TOP))
			{ }
		};

	private:
		widget_director&	wd_;

		param				param_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_text(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		virtual ~widget_text() { }

		//-----------------------------------------------------------------//
		/*!
			@brief	型を取得
		*/
		//-----------------------------------------------------------------//
		type_id type() const { return get_type_id<value_type>(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	widget 型の基本名称を取得
			@return widget 型の基本名称
		*/
		//-----------------------------------------------------------------//
		const char* type_name() const { return "text"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ハイブリッド・ウィジェットのサイン
			@return ハイブリッド・ウィジェットの場合「true」を返す。
		*/
		//-----------------------------------------------------------------//
		bool hybrid() const { return false; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得(ro)
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		const param& get_local_param() const { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		param& at_local_param() { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize();

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update();

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render();

		//-----------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-----------------------------------------------------------------//
		void service() { }

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のセーブ
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool save(sys::preference& pre);

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre);
	};

}
<commit_msg>update into header<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI Widget Text クラス @n
			Copyright 2017 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "core/glcore.hpp"
#include "widgets/widget_director.hpp"
#include "widgets/widget_frame.hpp"
#include "widgets/widget_utils.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	GUI widget_text クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct widget_text : public widget {

		typedef widget_text value_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_text パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {
			text_param	text_param_;
			param(const std::string& text = "") : text_param_(text,
				img::rgba8(255, 255), img::rgba8(0, 255),
				vtx::placement(vtx::placement::holizontal::LEFT,
					vtx::placement::vertical::TOP))
			{ }
		};

	private:
		widget_director&	wd_;

		param				param_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_text(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		virtual ~widget_text() { }

		//-----------------------------------------------------------------//
		/*!
			@brief	型を取得
		*/
		//-----------------------------------------------------------------//
		type_id type() const override { return get_type_id<value_type>(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	widget 型の基本名称を取得
			@return widget 型の基本名称
		*/
		//-----------------------------------------------------------------//
		const char* type_name() const override { return "text"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ハイブリッド・ウィジェットのサイン
			@return ハイブリッド・ウィジェットの場合「true」を返す。
		*/
		//-----------------------------------------------------------------//
		bool hybrid() const override { return false; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得(ro)
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		const param& get_local_param() const { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		param& at_local_param() { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override {
			// 標準的に固定
			at_param().state_.set(widget::state::POSITION_LOCK);
			at_param().state_.set(widget::state::SIZE_LOCK);
			at_param().state_.set(widget::state::MOVE_ROOT);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-----------------------------------------------------------------//
		void service() override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override {
			using namespace gl;
			core& core = core::get_instance();

			const vtx::spos& vsz = core.get_size();
			const widget::param& wp = get_param();

			if(wp.clip_.size.x > 0 && wp.clip_.size.y > 0) {

				auto clip = wp.clip_;
				glPushMatrix();

				vtx::irect rect;
				if(wp.state_[widget::state::CLIP_PARENTS]) {
					vtx::ipos o(0);
					vtx::ipos w(0);
					widget_frame* par = static_cast<widget_frame*>(wp.parents_);
					if(par != nullptr && par->type() == get_type_id<widget_frame>()) {
						const auto& plate = par->get_local_param().plate_param_;
						o.x = plate.frame_width_;
						o.y = plate.frame_width_ + plate.caption_width_;
						w.x = plate.frame_width_ * 2;
						w.y = o.y + plate.frame_width_ + 4;
						clip.size.y -= plate.frame_width_;
					}
					rect.org  = wp.rpos_ + o;
					rect.size = wp.rect_.size - w;
				} else {
					rect.org.set(0);
					rect.size = wp.rect_.size;
				}

				widget::text_param tpr = param_.text_param_;
				const img::rgbaf& cf = wd_.get_color();
				tpr.fore_color_ *= cf.r;
				tpr.fore_color_.alpha_scale(cf.a);
				tpr.shadow_color_ *= cf.r;
				tpr.shadow_color_.alpha_scale(cf.a);
				draw_text(tpr, rect, clip);

				core.at_fonts().restore_matrix();

				glPopMatrix();
				glViewport(0, 0, vsz.x, vsz.y);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のセーブ
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool save(sys::preference& pre) override {
			std::string path;
			path += '/';
			path += wd_.create_widget_name(this);
			int err = 0;
			if(!pre.put_text(path + "/text", param_.text_param_.get_text())) ++err;
			return err == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override {
			std::string path;
			path += '/';
			path += wd_.create_widget_name(this);

			int err = 0;
			std::string s;
			if(!pre.get_text(path + "/text", s)) {
				++err;
			} else {
				param_.text_param_.set_text(s);
			}
			return err == 0;
		}
	};

}
<|endoftext|>


<commit_before>// RUN: %clangxx_hwasan %s
#include <stddef.h>
#include <new>

char *__dummy;

void *operator new(size_t size) { return __dummy; }
void *operator new[](size_t size) { return __dummy; }
void *operator new(size_t size, std::nothrow_t const&) noexcept {
  return __dummy;
}
void *operator new[](size_t size, std::nothrow_t const&) noexcept {
  return __dummy;
}

void operator delete(void *ptr) noexcept {}
void operator delete[](void *ptr) noexcept {}
void operator delete(void *ptr, std::nothrow_t const&) noexcept {}
void operator delete[](void *ptr, std::nothrow_t const&) noexcept {}

int main() {
  return 0;
}
<commit_msg>Set an output file name for the override-new-delete.cpp test.<commit_after>// RUN: %clangxx_hwasan %s -o %t
#include <stddef.h>
#include <new>

char *__dummy;

void *operator new(size_t size) { return __dummy; }
void *operator new[](size_t size) { return __dummy; }
void *operator new(size_t size, std::nothrow_t const&) noexcept {
  return __dummy;
}
void *operator new[](size_t size, std::nothrow_t const&) noexcept {
  return __dummy;
}

void operator delete(void *ptr) noexcept {}
void operator delete[](void *ptr) noexcept {}
void operator delete(void *ptr, std::nothrow_t const&) noexcept {}
void operator delete[](void *ptr, std::nothrow_t const&) noexcept {}

int main() {
  return 0;
}
<|endoftext|>


<commit_before>#ifndef CHARTS_CONFIG_HH
#define CHARTS_CONFIG_HH 1

#include <memory>
#include <utility>
#include <vector>

#include "catalogue.hh"
#include "projection.hh"
#include "track.hh"

class Config;

template <typename T>
class ConfigIterator
{
    ConfigIterator(const Config * config, std::size_t index)
        : config_(config), index_(index)
    {
    }

    friend class Config;

public:
    ConfigIterator(const ConfigIterator & rhs) = default;
    ConfigIterator & operator=(const ConfigIterator & rhs) = default;

    ConfigIterator & operator++()
    {
        ++index_;
        return *this;
    }

    const std::shared_ptr<T> operator->() const;

    T & operator*() const
    {
        return *(*this).operator->();
    }

    bool operator==(const ConfigIterator & rhs) const
    {
        if (config_ != rhs.config_)
            return false;

        if (index_ != rhs.index_)
            return false;

        return true;
    }

    bool operator!=(const ConfigIterator & rhs) const
    {
        return !(*this == rhs);
    }

private:
    const Config * config_;
    std::size_t index_;
};

class Config
{
    struct Implementation;
    std::unique_ptr<Implementation> imp_;

    template <typename T>
    friend class ConfigIterator;

    template <typename T>
    const std::shared_ptr<T> get_collection_item(std::size_t i) const;

public:
    Config(int arc, char * arv[]);
    ~Config();

    const ln_lnlat_posn location() const;
    const CanvasPoint canvas_dimensions() const;
    double canvas_margin() const;
    const std::string projection_type() const;
    const ln_equ_posn projection_centre() const;
    const ln_equ_posn projection_dimensions() const;
    const std::string projection_level() const;
    double t() const;
    const std::string stylesheet() const;
    const std::string output() const;

    template <typename T>
    struct View
    {
        explicit View(const Config * config)
            : config_(config)
        {
        }

        const ConfigIterator<T> begin() const
        {
            return ConfigIterator<T>(config_, 0);
        }
        const ConfigIterator<T> end() const;
        const Config * config_;
    };

    template <typename T>
    const View<T> view() const
    {
        return View<T>(this);
    }

    const std::vector<std::string> planets() const;
    bool planets_labels() const;

    bool moon() const;
    bool sun() const;

private:
    timestamp sanitize_timestamp(const timestamp & ts) const;
    void update_timestamps();
};

#endif
<commit_msg>move template implementations out of class<commit_after>#ifndef CHARTS_CONFIG_HH
#define CHARTS_CONFIG_HH 1

#include <memory>
#include <utility>
#include <vector>

#include "catalogue.hh"
#include "projection.hh"
#include "track.hh"

class Config;

template <typename T>
class ConfigIterator
{
    ConfigIterator(const Config * config, std::size_t index)
        : config_(config), index_(index)
    {
    }

    friend class Config;

public:
    ConfigIterator(const ConfigIterator & rhs) = default;
    ConfigIterator & operator=(const ConfigIterator & rhs) = default;

    ConfigIterator & operator++()
    {
        ++index_;
        return *this;
    }

    const std::shared_ptr<T> operator->() const;

    T & operator*() const
    {
        return *(*this).operator->();
    }

    bool operator==(const ConfigIterator & rhs) const
    {
        if (config_ != rhs.config_)
            return false;

        if (index_ != rhs.index_)
            return false;

        return true;
    }

    bool operator!=(const ConfigIterator & rhs) const
    {
        return !(*this == rhs);
    }

private:
    const Config * config_;
    std::size_t index_;
};

class Config
{
    struct Implementation;
    std::unique_ptr<Implementation> imp_;

    template <typename T>
    friend class ConfigIterator;

    template <typename T>
    const std::shared_ptr<T> get_collection_item(std::size_t i) const;

public:
    Config(int arc, char * arv[]);
    ~Config();

    const ln_lnlat_posn location() const;
    const CanvasPoint canvas_dimensions() const;
    double canvas_margin() const;
    const std::string projection_type() const;
    const ln_equ_posn projection_centre() const;
    const ln_equ_posn projection_dimensions() const;
    const std::string projection_level() const;
    double t() const;
    const std::string stylesheet() const;
    const std::string output() const;

    template <typename T>
    struct View;

    template <typename T>
    const View<T> view() const;

    const std::vector<std::string> planets() const;
    bool planets_labels() const;

    bool moon() const;
    bool sun() const;

private:
    timestamp sanitize_timestamp(const timestamp & ts) const;
    void update_timestamps();
};

template <typename T>
struct Config::View
{
    explicit View(const Config * config)
        : config_(config)
    {
    }

    const ConfigIterator<T> begin() const
    {
        return ConfigIterator<T>(config_, 0);
    }
    const ConfigIterator<T> end() const;
    const Config * config_;
};

template <typename T>
const Config::View<T> Config::view() const
{
    return View<T>(this);
}

#endif
<|endoftext|>


<commit_before>#include "Debug.h"

#include <sstream>
#include <string>

void CDebug::Init(void)
{
  v8::HandleScope scope;

  v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
  m_global_context = v8::Context::New(NULL, global_template);
  m_global_context->SetSecurityToken(v8::Undefined());
}

void CDebug::SetEnable(bool enable)
{
  if (m_enabled == enable) return;

  v8::HandleScope scope;
  v8::Context::Scope context_scope(m_global_context);

  if (enable)
  {
    v8::Handle<v8::External> data = v8::External::New(this);

    v8::Debug::SetDebugEventListener(OnDebugEvent, data);
    v8::Debug::SetMessageHandler(OnDebugMessage, this);
  }
  else
  {
    v8::Debug::SetDebugEventListener(NULL);
    v8::Debug::SetMessageHandler(NULL);
  }

  m_enabled = enable;
}

void CDebug::OnDebugEvent(v8::DebugEvent event, v8::Handle<v8::Object> exec_state,
  v8::Handle<v8::Object> event_data, v8::Handle<v8::Value> data)
{
  v8::HandleScope scope;

  CDebug *pThis = static_cast<CDebug *>(v8::Handle<v8::External>::Cast(data)->Value());

  if (pThis->m_onDebugEvent.ptr() == Py_None) return;

  v8::Context::Scope context_scope(pThis->m_global_context);

  CJavascriptObjectPtr event_obj(new CJavascriptObject(pThis->m_global_context, event_data));

  py::call<void>(pThis->m_onDebugEvent.ptr(), event, event_obj);
}

void CDebug::OnDebugMessage(const uint16_t* message, int length, void* data)
{
  CDebug *pThis = static_cast<CDebug *>(data);

  if (pThis->m_onDebugMessage.ptr() == Py_None) return;

  std::wstring msg(reinterpret_cast<std::wstring::const_pointer>(message), length);

  py::call<void>(pThis->m_onDebugMessage.ptr(), msg);
}

void CDebug::Expose(void)
{
  py::class_<CDebug, boost::noncopyable>("JSDebug", py::no_init)
    .add_property("enabled", &CDebug::IsEnabled, &CDebug::SetEnable)

    .def_readwrite("onDebugEvent", &CDebug::m_onDebugEvent)
    .def_readwrite("onDebugMessage", &CDebug::m_onDebugMessage)
    ;

  py::enum_<v8::DebugEvent>("JSDebugEvent")
    .value("Break", v8::Break)
    .value("Exception", v8::Exception)
    .value("NewFunction", v8::NewFunction)
    .value("BeforeCompile", v8::BeforeCompile)
    .value("AfterCompile", v8::AfterCompile)
    ;

  def("debug", &CDebug::GetInstance,
    py::return_value_policy<py::reference_existing_object>());
}
<commit_msg>use a flag to disable debug events for python callback functions<commit_after>#include "Debug.h"

#include <sstream>
#include <string>

void CDebug::Init(void)
{
  v8::HandleScope scope;

  v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
  m_global_context = v8::Context::New(NULL, global_template);
  m_global_context->SetSecurityToken(v8::Undefined());

  v8::Handle<v8::External> data = v8::External::New(this);

  v8::Debug::SetDebugEventListener(OnDebugEvent, data);
  v8::Debug::SetMessageHandler(OnDebugMessage, this);
}

void CDebug::SetEnable(bool enable)
{
  if (m_enabled == enable) return;

  m_enabled = enable;
}

void CDebug::OnDebugEvent(v8::DebugEvent event, v8::Handle<v8::Object> exec_state,
  v8::Handle<v8::Object> event_data, v8::Handle<v8::Value> data)
{
  v8::HandleScope scope;

  CDebug *pThis = static_cast<CDebug *>(v8::Handle<v8::External>::Cast(data)->Value());

  if (!pThis->m_enabled) return;

  if (pThis->m_onDebugEvent.ptr() == Py_None) return;

  v8::Context::Scope context_scope(pThis->m_global_context);

  CJavascriptObjectPtr event_obj(new CJavascriptObject(pThis->m_global_context, event_data));

  py::call<void>(pThis->m_onDebugEvent.ptr(), event, event_obj);
}

void CDebug::OnDebugMessage(const uint16_t* message, int length, void* data)
{
  CDebug *pThis = static_cast<CDebug *>(data);

  if (!pThis->m_enabled) return;

  if (pThis->m_onDebugMessage.ptr() == Py_None) return;

  std::wstring msg(reinterpret_cast<std::wstring::const_pointer>(message), length);

  py::call<void>(pThis->m_onDebugMessage.ptr(), msg);
}

void CDebug::Expose(void)
{
  py::class_<CDebug, boost::noncopyable>("JSDebug", py::no_init)
    .add_property("enabled", &CDebug::IsEnabled, &CDebug::SetEnable)

    .def_readwrite("onDebugEvent", &CDebug::m_onDebugEvent)
    .def_readwrite("onDebugMessage", &CDebug::m_onDebugMessage)
    ;

  py::enum_<v8::DebugEvent>("JSDebugEvent")
    .value("Break", v8::Break)
    .value("Exception", v8::Exception)
    .value("NewFunction", v8::NewFunction)
    .value("BeforeCompile", v8::BeforeCompile)
    .value("AfterCompile", v8::AfterCompile)
    ;

  def("debug", &CDebug::GetInstance,
    py::return_value_policy<py::reference_existing_object>());
}
<|endoftext|>


<commit_before>#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#include <cppuhelper/factory.hxx>
#include <uno/mapping.hxx>
#include "provider.hxx"
#include "renderer.hxx"

#include <com/sun/star/registry/XRegistryKey.hpp>

using namespace com::sun::star;

namespace unographic {

// --------------------
// - *_createInstance -
// --------------------

static uno::Reference< uno::XInterface > SAL_CALL GraphicProvider_createInstance( const uno::Reference< lang::XMultiServiceFactory >& rxManager)
{
    return SAL_STATIC_CAST( ::cppu::OWeakObject*, new GraphicProvider );
}

// -----------------------------------------------------------------------------

static uno::Reference< uno::XInterface > SAL_CALL GraphicRendererVCL_createInstance( const uno::Reference< lang::XMultiServiceFactory >& rxManager)
{
    return SAL_STATIC_CAST( ::cppu::OWeakObject*, new GraphicRendererVCL );
}

// ------------------------------------------
// - component_getImplementationEnvironment -
// ------------------------------------------

extern "C" void SAL_CALL component_getImplementationEnvironment( const sal_Char** ppEnvTypeName, uno_Environment** ppEnv )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

// -----------------------
// - component_writeInfo -
// -----------------------

extern "C" sal_Bool SAL_CALL component_writeInfo( void* pServiceManager, void* pRegistryKey )
{
    sal_Bool bRet = sal_False;

    if( pRegistryKey )
    {
        try
        {
            uno::Reference< registry::XRegistryKey >    xNewKey;
            uno::Sequence< ::rtl::OUString >            aServices;

            // GraphicProvider
            xNewKey = reinterpret_cast< registry::XRegistryKey * >( pRegistryKey )->createKey(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
                        GraphicProvider::getImplementationName_Static() +
                        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );

            aServices = GraphicProvider::getSupportedServiceNames_Static();

            for( int i = 0; i < aServices.getLength(); i++ )
                xNewKey->createKey( aServices.getConstArray()[ i ] );

            // GraphicRendererVCL
            xNewKey = reinterpret_cast< registry::XRegistryKey * >( pRegistryKey )->createKey(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
                        GraphicRendererVCL::getImplementationName_Static() +
                        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );

            aServices = ( GraphicRendererVCL::getSupportedServiceNames_Static() );

            for( int i = 0; i < aServices.getLength(); i++ )
                xNewKey->createKey( aServices.getConstArray()[ i ] );

            bRet = true;
        }
        catch (registry::InvalidRegistryException &)
        {
            OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
        }
    }

    return bRet;
}

// ------------------------
// - component_getFactory -
// ------------------------

extern "C" void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* pRegistryKey )
{
    void * pRet = 0;

    if( pServiceManager && ( 0 == GraphicProvider::getImplementationName_Static().compareToAscii( pImplName ) ) )
    {
        uno::Reference< lang::XSingleServiceFactory > xFactory( ::cppu::createOneInstanceFactory(
            reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ),
            GraphicProvider::getImplementationName_Static(),
            GraphicProvider_createInstance,
            GraphicProvider::getSupportedServiceNames_Static() ) );

        if( xFactory.is())
        {
            xFactory->acquire();
            pRet = xFactory.get();
        }
    }
    else if( pServiceManager && ( 0 == GraphicRendererVCL::getImplementationName_Static().compareToAscii( pImplName ) ) )
    {
        uno::Reference< lang::XSingleServiceFactory > xFactory( ::cppu::createOneInstanceFactory(
            reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ),
            GraphicRendererVCL::getImplementationName_Static(),
            GraphicRendererVCL_createInstance,
            GraphicRendererVCL::getSupportedServiceNames_Static() ) );

        if( xFactory.is())
        {
            xFactory->acquire();
            pRet = xFactory.get();
        }
    }

    return pRet;
}

}
<commit_msg>#i10000# for scope<commit_after>#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#include <cppuhelper/factory.hxx>
#include <uno/mapping.hxx>
#include "provider.hxx"
#include "renderer.hxx"

#include <com/sun/star/registry/XRegistryKey.hpp>

using namespace com::sun::star;

namespace unographic {

// --------------------
// - *_createInstance -
// --------------------

static uno::Reference< uno::XInterface > SAL_CALL GraphicProvider_createInstance( const uno::Reference< lang::XMultiServiceFactory >& rxManager)
{
    return SAL_STATIC_CAST( ::cppu::OWeakObject*, new GraphicProvider );
}

// -----------------------------------------------------------------------------

static uno::Reference< uno::XInterface > SAL_CALL GraphicRendererVCL_createInstance( const uno::Reference< lang::XMultiServiceFactory >& rxManager)
{
    return SAL_STATIC_CAST( ::cppu::OWeakObject*, new GraphicRendererVCL );
}

// ------------------------------------------
// - component_getImplementationEnvironment -
// ------------------------------------------

extern "C" void SAL_CALL component_getImplementationEnvironment( const sal_Char** ppEnvTypeName, uno_Environment** ppEnv )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

// -----------------------
// - component_writeInfo -
// -----------------------

extern "C" sal_Bool SAL_CALL component_writeInfo( void* pServiceManager, void* pRegistryKey )
{
    sal_Bool bRet = sal_False;

    if( pRegistryKey )
    {
        try
        {
            uno::Reference< registry::XRegistryKey >    xNewKey;
            uno::Sequence< ::rtl::OUString >            aServices;

            // GraphicProvider
            xNewKey = reinterpret_cast< registry::XRegistryKey * >( pRegistryKey )->createKey(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
                        GraphicProvider::getImplementationName_Static() +
                        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );

            aServices = GraphicProvider::getSupportedServiceNames_Static();

            int i;
            for( i = 0; i < aServices.getLength(); i++ )
                xNewKey->createKey( aServices.getConstArray()[ i ] );

            // GraphicRendererVCL
            xNewKey = reinterpret_cast< registry::XRegistryKey * >( pRegistryKey )->createKey(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) +
                        GraphicRendererVCL::getImplementationName_Static() +
                        ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) );

            aServices = ( GraphicRendererVCL::getSupportedServiceNames_Static() );

            for( i = 0; i < aServices.getLength(); i++ )
                xNewKey->createKey( aServices.getConstArray()[ i ] );

            bRet = true;
        }
        catch (registry::InvalidRegistryException &)
        {
            OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
        }
    }

    return bRet;
}

// ------------------------
// - component_getFactory -
// ------------------------

extern "C" void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* pRegistryKey )
{
    void * pRet = 0;

    if( pServiceManager && ( 0 == GraphicProvider::getImplementationName_Static().compareToAscii( pImplName ) ) )
    {
        uno::Reference< lang::XSingleServiceFactory > xFactory( ::cppu::createOneInstanceFactory(
            reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ),
            GraphicProvider::getImplementationName_Static(),
            GraphicProvider_createInstance,
            GraphicProvider::getSupportedServiceNames_Static() ) );

        if( xFactory.is())
        {
            xFactory->acquire();
            pRet = xFactory.get();
        }
    }
    else if( pServiceManager && ( 0 == GraphicRendererVCL::getImplementationName_Static().compareToAscii( pImplName ) ) )
    {
        uno::Reference< lang::XSingleServiceFactory > xFactory( ::cppu::createOneInstanceFactory(
            reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ),
            GraphicRendererVCL::getImplementationName_Static(),
            GraphicRendererVCL_createInstance,
            GraphicRendererVCL::getSupportedServiceNames_Static() ) );

        if( xFactory.is())
        {
            xFactory->acquire();
            pRet = xFactory.get();
        }
    }

    return pRet;
}

}
<|endoftext|>


<commit_before>// Copyright 2012-2013 Samplecount S.L.
//
// 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 "Methcla/Audio/IO/OpenSLESDriver.hpp"
#include "Methcla/Memory.hpp"
#include "opensl_io.h"

#include <android/log.h>
#include <cassert>
#include <stdexcept>

#define LOGI(...) \
  __android_log_print(ANDROID_LOG_INFO, "OpenSLESDriver", __VA_ARGS__)
#define LOGW(...) \
  __android_log_print(ANDROID_LOG_WARN, "OpenSLESDriver", __VA_ARGS__)

using namespace Methcla::Audio::IO;

OpenSLESDriver::OpenSLESDriver()
    : m_stream(nullptr)
    , m_sampleRate(44100)
    , m_numInputs(0)
    , m_numOutputs(2)
    , m_bufferSize(512)
    , m_inputBuffers(nullptr)
    , m_outputBuffers(nullptr)
{
    m_stream = opensl_open(
        (int)m_sampleRate,
        (int)m_numInputs,
        (int)m_numOutputs,
        (int)m_bufferSize,
        processCallback,
        this
    );
    if (m_stream == nullptr) {
        throw std::runtime_error("OpenSLESDriver: Couldn't open audio stream");
    }

    m_inputBuffers = makeBuffers(m_numInputs, m_bufferSize);
    m_outputBuffers = makeBuffers(m_numOutputs, m_bufferSize);
}

OpenSLESDriver::~OpenSLESDriver()
{
    if (m_stream != nullptr)
        opensl_close(m_stream);
}

void OpenSLESDriver::start()
{
    if (m_stream != nullptr)
        opensl_start(m_stream);
}

void OpenSLESDriver::stop()
{
    if (m_stream != nullptr)
        opensl_pause(m_stream);
}

void OpenSLESDriver::processCallback(
    void* context, int sample_rate, int buffer_frames,
    int input_channels, const short* input_buffer,
    int output_channels, short* output_buffer)
{
    OpenSLESDriver* self = static_cast<OpenSLESDriver*>(context);

    const size_t numInputs = self->m_numInputs;
    const size_t numOutputs = self->m_numOutputs;
    const size_t bufferSize = self->m_bufferSize;
    const size_t numFrames = (size_t)buffer_frames;

    assert( self->m_sampleRate == (double)sample_rate );
    assert( numInputs == (size_t)input_channels );
    assert( numOutputs == (size_t)output_channels );
    assert( buffer_frames >= 0 && bufferSize <= (size_t)buffer_frames );

    sample_t** inputBuffers = self->m_inputBuffers;
    sample_t** outputBuffers = self->m_outputBuffers;

    // Deinterleave and convert input
    for (size_t curChan = 0; curChan < numInputs; curChan++) {
        for (size_t curFrame = 0; curFrame < numFrames; curFrame++) {
            inputBuffers[curChan][curFrame] = input_buffer[curFrame * numInputs + curChan] / 32768.f;
        }
    }

    // Run DSP graph
    try {
        self->process(numFrames, inputBuffers, outputBuffers);
    } catch (std::exception& e) {
        LOGW(e.what());
    }
#ifndef NDEBUG
    catch (...) {
        LOGW("Unknown exception caught");
    }
#endif

    // Convert and interleave output
    for (size_t curChan = 0; curChan < numOutputs; curChan++) {
        for (size_t curFrame = 0; curFrame < numFrames; curFrame++) {
            output_buffer[curFrame * numOutputs + curChan] = outputBuffers[curChan][curFrame] * 32767.f;
        }
    }
}

Driver* Methcla::Audio::IO::defaultPlatformDriver()
{
    return new OpenSLESDriver();
}
<commit_msg>Fix compiler warning in release mode<commit_after>// Copyright 2012-2013 Samplecount S.L.
//
// 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 "Methcla/Audio/IO/OpenSLESDriver.hpp"
#include "Methcla/Memory.hpp"
#include "opensl_io.h"

#include <android/log.h>
#include <cassert>
#include <stdexcept>

#define LOGI(...) \
  __android_log_print(ANDROID_LOG_INFO, "OpenSLESDriver", __VA_ARGS__)
#define LOGW(...) \
  __android_log_print(ANDROID_LOG_WARN, "OpenSLESDriver", __VA_ARGS__)

using namespace Methcla::Audio::IO;

OpenSLESDriver::OpenSLESDriver()
    : m_stream(nullptr)
    , m_sampleRate(44100)
    , m_numInputs(0)
    , m_numOutputs(2)
    , m_bufferSize(512)
    , m_inputBuffers(nullptr)
    , m_outputBuffers(nullptr)
{
    m_stream = opensl_open(
        (int)m_sampleRate,
        (int)m_numInputs,
        (int)m_numOutputs,
        (int)m_bufferSize,
        processCallback,
        this
    );
    if (m_stream == nullptr) {
        throw std::runtime_error("OpenSLESDriver: Couldn't open audio stream");
    }

    m_inputBuffers = makeBuffers(m_numInputs, m_bufferSize);
    m_outputBuffers = makeBuffers(m_numOutputs, m_bufferSize);
}

OpenSLESDriver::~OpenSLESDriver()
{
    if (m_stream != nullptr)
        opensl_close(m_stream);
}

void OpenSLESDriver::start()
{
    if (m_stream != nullptr)
        opensl_start(m_stream);
}

void OpenSLESDriver::stop()
{
    if (m_stream != nullptr)
        opensl_pause(m_stream);
}

void OpenSLESDriver::processCallback(
    void* context, int sample_rate, int buffer_frames,
    int input_channels, const short* input_buffer,
    int output_channels, short* output_buffer)
{
    OpenSLESDriver* self = static_cast<OpenSLESDriver*>(context);

    const size_t numInputs = self->m_numInputs;
    const size_t numOutputs = self->m_numOutputs;
    const size_t numFrames = (size_t)buffer_frames;

    assert( self->m_sampleRate == (double)sample_rate );
    assert( numInputs == (size_t)input_channels );
    assert( numOutputs == (size_t)output_channels );
    assert( buffer_frames >= 0 && self->m_bufferSize <= (size_t)buffer_frames );

    sample_t** inputBuffers = self->m_inputBuffers;
    sample_t** outputBuffers = self->m_outputBuffers;

    // Deinterleave and convert input
    for (size_t curChan = 0; curChan < numInputs; curChan++) {
        for (size_t curFrame = 0; curFrame < numFrames; curFrame++) {
            inputBuffers[curChan][curFrame] = input_buffer[curFrame * numInputs + curChan] / 32768.f;
        }
    }

    // Run DSP graph
    try {
        self->process(numFrames, inputBuffers, outputBuffers);
    } catch (std::exception& e) {
        LOGW(e.what());
    }
#ifndef NDEBUG
    catch (...) {
        LOGW("Unknown exception caught");
    }
#endif

    // Convert and interleave output
    for (size_t curChan = 0; curChan < numOutputs; curChan++) {
        for (size_t curFrame = 0; curFrame < numFrames; curFrame++) {
            output_buffer[curFrame * numOutputs + curChan] = outputBuffers[curChan][curFrame] * 32767.f;
        }
    }
}

Driver* Methcla::Audio::IO::defaultPlatformDriver()
{
    return new OpenSLESDriver();
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015-2017, Robotics and Biology Lab, TU Berlin
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "hybrid_automaton/ForceTorqueSensor.h"

namespace ha
{
	HA_SENSOR_REGISTER("ForceTorqueSensor", ForceTorqueSensor);

        ForceTorqueSensor::ForceTorqueSensor() : _port(DEFAULT_FT_PORT)
	{
	}

	ForceTorqueSensor::~ForceTorqueSensor()
	{
	}

	ForceTorqueSensor::ForceTorqueSensor(const ForceTorqueSensor& ss)
		:Sensor(ss)
	{
		_port = ss._port;
	}
	::Eigen::MatrixXd ForceTorqueSensor::transformWrench(const ::Eigen::MatrixXd& wrench, const ::Eigen::MatrixXd& transform) const
	{
		::Eigen::Matrix3d frameRot = transform.block(0,0,3,3);
		::Eigen::Vector3d frameTrans(transform(0,3), transform(1,3), transform(2,3));
		::Eigen::Vector3d forcePart(wrench(0,0), wrench(1,0),wrench(2,0));
		::Eigen::Vector3d momentPart(wrench(3,0), wrench(4,0),wrench(5,0));

		forcePart = frameRot*forcePart;
		momentPart = frameRot*(momentPart - frameTrans.cross(forcePart));

		Eigen::MatrixXd wrenchOut(6,1);
		wrenchOut(0) = forcePart(0); wrenchOut(1) = forcePart(1); wrenchOut(2) = forcePart(2);
		wrenchOut(3) = momentPart(0); wrenchOut(4) = momentPart(1); wrenchOut(5) = momentPart(2);
		return wrenchOut;
	}

	int k;
	::Eigen::MatrixXd ForceTorqueSensor::getCurrentValue() const
	{
		//This is the F/T wrench from the hardware - It must be in EE frame
		::Eigen::MatrixXd forceTorque = _system->getForceTorqueMeasurement(_port);
		::Eigen::MatrixXd eeFrame = _system->getFramePose("EE");

		//Transform FT wrench to world frame
		Eigen::MatrixXd ftOut = transformWrench(forceTorque, eeFrame.inverse());

		//Transform FT wrench to given frame
		ftOut = transformWrench(ftOut, _frame);

		if((k++)%2000 == 0)
			HA_INFO("ForceTorqueSensor.getCurrentValue","ftout: "<<ftOut.transpose());
		return ftOut;
	}

	DescriptionTreeNode::Ptr ForceTorqueSensor::serialize(const DescriptionTree::ConstPtr& factory) const
	{
		DescriptionTreeNode::Ptr tree = factory->createNode("Sensor");
		tree->setAttribute<std::string>(std::string("type"), this->getType());
		tree->setAttribute<int>(std::string("port"), _port);
        return tree;
	}

	void ForceTorqueSensor::deserialize(const DescriptionTreeNode::ConstPtr& tree, const System::ConstPtr& system, const HybridAutomaton* ha)
	{
		if (tree->getType() != "Sensor") {
			HA_THROW_ERROR("ForceTorqueSensor.deserialize", "DescriptionTreeNode must have type 'Sensor', not '" << tree->getType() << "'!");
		}
		tree->getAttribute<std::string>("type", _type, "");
		tree->getAttribute<int>("port", _port, DEFAULT_FT_PORT);

		if(_port > 2 || _port <0)
		{
			HA_THROW_ERROR("ForceTorqueSensor.deserialize", "Port number " << _port << " "
				<< "invalid - it must be between 0 and 2!");
		}

		if (_type == "" || !HybridAutomaton::isSensorRegistered(_type)) {
			HA_THROW_ERROR("ForceTorqueSensor.deserialize", "SensorType type '" << _type << "' "
				<< "invalid - empty or not registered with HybridAutomaton!");
		}

    _frame.resize(4,4);
    _frame.setIdentity();
    if(tree->getAttribute< Eigen::MatrixXd>("frame", _frame))
		{
      HA_INFO("ForceTorqueSensor.deserialize", "Using external frame to express F/T value in");
      if(_frame.cols()!=4 || _frame.rows()!=4)
      {
        HA_THROW_ERROR("ForceTorqueSensor.deserialize", "frame parameter must be 4x4 homogeneous transform!");
      }
		}

		_system = system;
	}
}
<commit_msg>fix transform<commit_after>/*
 * Copyright 2015-2017, Robotics and Biology Lab, TU Berlin
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "hybrid_automaton/ForceTorqueSensor.h"

namespace ha
{
	HA_SENSOR_REGISTER("ForceTorqueSensor", ForceTorqueSensor);

        ForceTorqueSensor::ForceTorqueSensor() : _port(DEFAULT_FT_PORT)
	{
	}

	ForceTorqueSensor::~ForceTorqueSensor()
	{
	}

	ForceTorqueSensor::ForceTorqueSensor(const ForceTorqueSensor& ss)
		:Sensor(ss)
	{
		_port = ss._port;
	}
	::Eigen::MatrixXd ForceTorqueSensor::transformWrench(const ::Eigen::MatrixXd& wrench, const ::Eigen::MatrixXd& transform) const
	{
		::Eigen::Matrix3d frameRot = transform.block(0,0,3,3);
		::Eigen::Vector3d frameTrans(transform(0,3), transform(1,3), transform(2,3));
		::Eigen::Vector3d forcePart(wrench(0,0), wrench(1,0),wrench(2,0));
		::Eigen::Vector3d momentPart(wrench(3,0), wrench(4,0),wrench(5,0));

		forcePart = frameRot.transpose()*forcePart;
		momentPart = frameRot.transpose()*(momentPart - frameTrans.cross(forcePart));

		Eigen::MatrixXd wrenchOut(6,1);
		wrenchOut(0) = forcePart(0); wrenchOut(1) = forcePart(1); wrenchOut(2) = forcePart(2);
		wrenchOut(3) = momentPart(0); wrenchOut(4) = momentPart(1); wrenchOut(5) = momentPart(2);
		return wrenchOut;
	}

	int k;
	::Eigen::MatrixXd ForceTorqueSensor::getCurrentValue() const
	{
		//This is the F/T wrench from the hardware - It must be in EE frame
		::Eigen::MatrixXd forceTorque = _system->getForceTorqueMeasurement(_port);
		::Eigen::MatrixXd eeFrame = _system->getFramePose("EE");

		//Transform FT wrench to world frame
		Eigen::MatrixXd ftOut = transformWrench(forceTorque, eeFrame.inverse());

		//Transform FT wrench to given frame
		ftOut = transformWrench(ftOut, _frame);

		if((k++)%2000 == 0)
			HA_INFO("ForceTorqueSensor.getCurrentValue","ftout: "<<ftOut.transpose());
		return ftOut;
	}

	DescriptionTreeNode::Ptr ForceTorqueSensor::serialize(const DescriptionTree::ConstPtr& factory) const
	{
		DescriptionTreeNode::Ptr tree = factory->createNode("Sensor");
		tree->setAttribute<std::string>(std::string("type"), this->getType());
		tree->setAttribute<int>(std::string("port"), _port);
        return tree;
	}

	void ForceTorqueSensor::deserialize(const DescriptionTreeNode::ConstPtr& tree, const System::ConstPtr& system, const HybridAutomaton* ha)
	{
		if (tree->getType() != "Sensor") {
			HA_THROW_ERROR("ForceTorqueSensor.deserialize", "DescriptionTreeNode must have type 'Sensor', not '" << tree->getType() << "'!");
		}
		tree->getAttribute<std::string>("type", _type, "");
		tree->getAttribute<int>("port", _port, DEFAULT_FT_PORT);

		if(_port > 2 || _port <0)
		{
			HA_THROW_ERROR("ForceTorqueSensor.deserialize", "Port number " << _port << " "
				<< "invalid - it must be between 0 and 2!");
		}

		if (_type == "" || !HybridAutomaton::isSensorRegistered(_type)) {
			HA_THROW_ERROR("ForceTorqueSensor.deserialize", "SensorType type '" << _type << "' "
				<< "invalid - empty or not registered with HybridAutomaton!");
		}

    _frame.resize(4,4);
    _frame.setIdentity();
    if(tree->getAttribute< Eigen::MatrixXd>("frame", _frame))
		{
      HA_INFO("ForceTorqueSensor.deserialize", "Using external frame to express F/T value in");
      if(_frame.cols()!=4 || _frame.rows()!=4)
      {
        HA_THROW_ERROR("ForceTorqueSensor.deserialize", "frame parameter must be 4x4 homogeneous transform!");
      }
		}

		_system = system;
	}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unchss.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 04:26:10 $
 *
 *  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
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _SFXITEMSET_HXX //autogen
#include <svtools/itemset.hxx>
#endif
#ifndef _SFXSTYLE_HXX //autogen
#include <svtools/style.hxx>
#endif
#ifndef _SFXSMPLHINT_HXX //autogen
#include <svtools/smplhint.hxx>
#endif
#ifndef _SVDOBJ_HXX
#include <svx/svdobj.hxx>
#endif

#include "unchss.hxx"

#include "strings.hrc"
#include "glob.hxx"
#include "sdresid.hxx"
#include "drawdoc.hxx"
#include "stlsheet.hxx"

TYPEINIT1(StyleSheetUndoAction, SdUndoAction);

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

StyleSheetUndoAction::StyleSheetUndoAction(SdDrawDocument* pTheDoc,
                                           SfxStyleSheet* pTheStyleSheet,
                                           const SfxItemSet* pTheNewItemSet) :
                      SdUndoAction(pTheDoc)
{
    DBG_ASSERT(pTheStyleSheet, "Undo ohne StyleSheet ???");
    pStyleSheet = pTheStyleSheet;

    // ItemSets anlegen; Vorsicht, das neue koennte aus einem anderen Pool
    // stammen, also mitsamt seinen Items clonen
    pNewSet = new SfxItemSet((SfxItemPool&)SdrObject::GetGlobalDrawObjectItemPool(), pTheNewItemSet->GetRanges());
    pTheDoc->MigrateItemSet( pTheNewItemSet, pNewSet, pTheDoc );

    pOldSet = new SfxItemSet((SfxItemPool&)SdrObject::GetGlobalDrawObjectItemPool(),pStyleSheet->GetItemSet().GetRanges());
    pTheDoc->MigrateItemSet( &pStyleSheet->GetItemSet(), pOldSet, pTheDoc );

    aComment = String(SdResId(STR_UNDO_CHANGE_PRES_OBJECT));
    String aName(pStyleSheet->GetName());

    // Layoutnamen und Separator loeschen
    String aSep( RTL_CONSTASCII_USTRINGPARAM( SD_LT_SEPARATOR ) );
    USHORT nPos = aName.Search(aSep);
    if( nPos != STRING_NOTFOUND )
        aName.Erase(0, nPos + aSep.Len());

    // Platzhalter durch Vorlagennamen ersetzen
    nPos = aComment.Search(sal_Unicode('$'));
    aComment.Erase(nPos, 1);
    aComment.Insert(aName, nPos);
}

/*************************************************************************
|*
|* Undo()
|*
\************************************************************************/

void StyleSheetUndoAction::Undo()
{
    SfxItemSet aNewSet( pDoc->GetItemPool(), pOldSet->GetRanges() );
    pDoc->MigrateItemSet( pOldSet, &aNewSet, pDoc );

    pStyleSheet->GetItemSet().Set(aNewSet);
    if( pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PSEUDO )
        ( (SdStyleSheet*)pStyleSheet )->GetRealStyleSheet()->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
    else
        pStyleSheet->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
}

/*************************************************************************
|*
|* Redo()
|*
\************************************************************************/

void StyleSheetUndoAction::Redo()
{
    SfxItemSet aNewSet( pDoc->GetItemPool(), pOldSet->GetRanges() );
    pDoc->MigrateItemSet( pNewSet, &aNewSet, pDoc );

    pStyleSheet->GetItemSet().Set(aNewSet);
    if( pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PSEUDO )
        ( (SdStyleSheet*)pStyleSheet )->GetRealStyleSheet()->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
    else
        pStyleSheet->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
}

/*************************************************************************
|*
|* Repeat()
|*
\************************************************************************/

void StyleSheetUndoAction::Repeat()
{
    DBG_ASSERT(FALSE, "StyleSheetUndoAction::Repeat: nicht implementiert");
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

StyleSheetUndoAction::~StyleSheetUndoAction()
{
    delete pNewSet;
    delete pOldSet;
}

/*************************************************************************
|*
|* Kommentar liefern
|*
\************************************************************************/

String StyleSheetUndoAction::GetComment() const
{
    return aComment;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.5.280); FILE MERGED 2006/09/01 17:37:02 kaib 1.5.280.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: unchss.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 18:44:14 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _SFXITEMSET_HXX //autogen
#include <svtools/itemset.hxx>
#endif
#ifndef _SFXSTYLE_HXX //autogen
#include <svtools/style.hxx>
#endif
#ifndef _SFXSMPLHINT_HXX //autogen
#include <svtools/smplhint.hxx>
#endif
#ifndef _SVDOBJ_HXX
#include <svx/svdobj.hxx>
#endif

#include "unchss.hxx"

#include "strings.hrc"
#include "glob.hxx"
#include "sdresid.hxx"
#include "drawdoc.hxx"
#include "stlsheet.hxx"

TYPEINIT1(StyleSheetUndoAction, SdUndoAction);

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

StyleSheetUndoAction::StyleSheetUndoAction(SdDrawDocument* pTheDoc,
                                           SfxStyleSheet* pTheStyleSheet,
                                           const SfxItemSet* pTheNewItemSet) :
                      SdUndoAction(pTheDoc)
{
    DBG_ASSERT(pTheStyleSheet, "Undo ohne StyleSheet ???");
    pStyleSheet = pTheStyleSheet;

    // ItemSets anlegen; Vorsicht, das neue koennte aus einem anderen Pool
    // stammen, also mitsamt seinen Items clonen
    pNewSet = new SfxItemSet((SfxItemPool&)SdrObject::GetGlobalDrawObjectItemPool(), pTheNewItemSet->GetRanges());
    pTheDoc->MigrateItemSet( pTheNewItemSet, pNewSet, pTheDoc );

    pOldSet = new SfxItemSet((SfxItemPool&)SdrObject::GetGlobalDrawObjectItemPool(),pStyleSheet->GetItemSet().GetRanges());
    pTheDoc->MigrateItemSet( &pStyleSheet->GetItemSet(), pOldSet, pTheDoc );

    aComment = String(SdResId(STR_UNDO_CHANGE_PRES_OBJECT));
    String aName(pStyleSheet->GetName());

    // Layoutnamen und Separator loeschen
    String aSep( RTL_CONSTASCII_USTRINGPARAM( SD_LT_SEPARATOR ) );
    USHORT nPos = aName.Search(aSep);
    if( nPos != STRING_NOTFOUND )
        aName.Erase(0, nPos + aSep.Len());

    // Platzhalter durch Vorlagennamen ersetzen
    nPos = aComment.Search(sal_Unicode('$'));
    aComment.Erase(nPos, 1);
    aComment.Insert(aName, nPos);
}

/*************************************************************************
|*
|* Undo()
|*
\************************************************************************/

void StyleSheetUndoAction::Undo()
{
    SfxItemSet aNewSet( pDoc->GetItemPool(), pOldSet->GetRanges() );
    pDoc->MigrateItemSet( pOldSet, &aNewSet, pDoc );

    pStyleSheet->GetItemSet().Set(aNewSet);
    if( pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PSEUDO )
        ( (SdStyleSheet*)pStyleSheet )->GetRealStyleSheet()->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
    else
        pStyleSheet->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
}

/*************************************************************************
|*
|* Redo()
|*
\************************************************************************/

void StyleSheetUndoAction::Redo()
{
    SfxItemSet aNewSet( pDoc->GetItemPool(), pOldSet->GetRanges() );
    pDoc->MigrateItemSet( pNewSet, &aNewSet, pDoc );

    pStyleSheet->GetItemSet().Set(aNewSet);
    if( pStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PSEUDO )
        ( (SdStyleSheet*)pStyleSheet )->GetRealStyleSheet()->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
    else
        pStyleSheet->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED));
}

/*************************************************************************
|*
|* Repeat()
|*
\************************************************************************/

void StyleSheetUndoAction::Repeat()
{
    DBG_ASSERT(FALSE, "StyleSheetUndoAction::Repeat: nicht implementiert");
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

StyleSheetUndoAction::~StyleSheetUndoAction()
{
    delete pNewSet;
    delete pOldSet;
}

/*************************************************************************
|*
|* Kommentar liefern
|*
\************************************************************************/

String StyleSheetUndoAction::GetComment() const
{
    return aComment;
}

<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2012, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Consulting LLC nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/GlobalEnvironment.hpp>
#include <pdal/plang/PythonEnvironment.hpp>

namespace pdal
{

//
// static functions
//

static GlobalEnvironment* t = 0;
static boost::once_flag flag = BOOST_ONCE_INIT;

GlobalEnvironment& GlobalEnvironment::get()
{
    boost::call_once(init, flag);
    return *t;
}

void GlobalEnvironment::startup()
{
    get();
}

void GlobalEnvironment::shutdown()
{
    // Shutdown could be called multiple times?
    if (t != 0)
    {
        delete t;
        t = 0;
    }

}

void GlobalEnvironment::init()
{
    t = new GlobalEnvironment();
}

//
// regular member functions
//

GlobalEnvironment::GlobalEnvironment()
{
    // this should be the not-a-thread thread environment
    (void) createThreadEnvironment(boost::thread::id());

#ifdef PDAL_HAVE_PYTHON
    m_pythonEnvironment = new pdal::plang::PythonEnvironment();
#endif

    return;
}

GlobalEnvironment::~GlobalEnvironment()
{
    while (m_threadMap.size())
    {
        thread_map::iterator iter = m_threadMap.begin();
        ThreadEnvironment* env = iter->second;
        delete env;
        m_threadMap.erase(iter);
    }

#ifdef PDAL_HAVE_PYTHON
    delete m_pythonEnvironment;
    m_pythonEnvironment = 0;
#endif

    return;
}

void GlobalEnvironment::createThreadEnvironment(boost::thread::id id)
{
    ThreadEnvironment* threadEnv = new ThreadEnvironment(id);

    // FIXME: What happens if the id is already in the map?
    m_threadMap.insert( std::make_pair(id, threadEnv ) );
}

ThreadEnvironment& GlobalEnvironment::getThreadEnvironment(boost::thread::id id)
{
    thread_map::iterator iter =  m_threadMap.find(id);
    if (iter == m_threadMap.end())
        throw pdal_error("bad thread id!");

    ThreadEnvironment* threadEnv = iter->second;

    return *threadEnv;
}

#ifdef PDAL_HAVE_PYTHON
plang::PythonEnvironment& GlobalEnvironment::getPythonEnvironment()
{
    return *m_pythonEnvironment;
}
#endif

boost::random::mt19937* GlobalEnvironment::getRNG()
{
    return getThreadEnvironment().getRNG();
}

} //namespaces
<commit_msg>minor error checks<commit_after>/******************************************************************************
* Copyright (c) 2012, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Consulting LLC nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/GlobalEnvironment.hpp>
#include <pdal/plang/PythonEnvironment.hpp>

namespace pdal
{

//
// static functions
//

static GlobalEnvironment* t = 0;
static boost::once_flag flag = BOOST_ONCE_INIT;

GlobalEnvironment& GlobalEnvironment::get()
{
    boost::call_once(init, flag);
    return *t;
}

void GlobalEnvironment::startup()
{
    if (t != 0) // sanity check
    {
        throw pdal_error("attempt to reinitialize global environment");
    }

    get();
}

void GlobalEnvironment::shutdown()
{
    if (t == 0) // sanity check
    {
        throw pdal_error("bad global shutdown call -- was called more than once or was called without corresponding startup");
    }

    delete t;
    t = 0;

    return;
}

void GlobalEnvironment::init()
{
    t = new GlobalEnvironment();
}

//
// regular member functions
//

GlobalEnvironment::GlobalEnvironment()
{
    // this should be the not-a-thread thread environment
    (void) createThreadEnvironment(boost::thread::id());

#ifdef PDAL_HAVE_PYTHON
    m_pythonEnvironment = new pdal::plang::PythonEnvironment();
#endif

    return;
}

GlobalEnvironment::~GlobalEnvironment()
{
    while (m_threadMap.size())
    {
        thread_map::iterator iter = m_threadMap.begin();
        ThreadEnvironment* env = iter->second;
        delete env;
        m_threadMap.erase(iter);
    }

#ifdef PDAL_HAVE_PYTHON
    delete m_pythonEnvironment;
    m_pythonEnvironment = 0;
#endif

    return;
}

void GlobalEnvironment::createThreadEnvironment(boost::thread::id id)
{
    ThreadEnvironment* threadEnv = new ThreadEnvironment(id);

    if (m_threadMap.find(id) != m_threadMap.end())
    {
        throw pdal_error("thread already registered");
    }

    m_threadMap.insert( std::make_pair(id, threadEnv ) );
}

ThreadEnvironment& GlobalEnvironment::getThreadEnvironment(boost::thread::id id)
{
    thread_map::iterator iter =  m_threadMap.find(id);
    if (iter == m_threadMap.end())
        throw pdal_error("bad thread id!");

    ThreadEnvironment* threadEnv = iter->second;

    return *threadEnv;
}

#ifdef PDAL_HAVE_PYTHON
plang::PythonEnvironment& GlobalEnvironment::getPythonEnvironment()
{
    return *m_pythonEnvironment;
}
#endif

boost::random::mt19937* GlobalEnvironment::getRNG()
{
    return getThreadEnvironment().getRNG();
}

} //namespaces
<|endoftext|>