<commit_before>/// @file   combatHandler.cpp
/// @brief  Contains implementation of combat classes.
/// @author Enrico Fraccaroli
/// @date   May 8 2016
/// @copyright
/// Copyright (c) 2016 Enrico Fraccaroli <enrico.fraccaroli@gmail.com>
/// Permission is hereby granted, free of charge, to any person obtaining a
/// copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:
///     The above copyright notice and this permission notice shall be included
///     in all copies or substantial portions of the Software.
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.

#include "combatHandler.hpp"

#include "utils.hpp"
#include "logger.hpp"
#include "character.hpp"

CombatHandler::CombatHandler(Character * _owner) :
    owner(_owner),
    opponents(),
    predefinedTarget(),
    aimedCharacter()
{
    // Nothing to do.
}

CombatHandler::~CombatHandler()
{
    // Nothing to do.
}

bool CombatHandler::addOpponent(Character * character, unsigned int initAggro)
{
    if (!this->hasOpponent(character))
    {
        if (initAggro == 0)
        {
            initAggro = this->getInitialAggro(character);
        }
        // Add the aggressor.
        opponents.push_back(std::make_shared<Aggression>(character, initAggro));
        // Sort the list.
        this->sortList();
        Logger::log(LogLevel::Debug, "%s engage %s with %s.", owner->getNameCapital(), character->getName(), initAggro);
        return true;
    }
    return false;
}

bool CombatHandler::remOpponent(Character * character)
{
    auto it = std::find_if(opponents.begin(), opponents.end(),
                           [&](std::shared_ptr<Aggression> const & element)
                           {
                               return element->aggressor->name == character->name;
                           });
    if (it != opponents.end())
    {
        Logger::log(LogLevel::Debug, "%s disengages %s", owner->getNameCapital(), character->getName());
        opponents.erase(it, opponents.end());
        return true;
    }
    return false;
}

bool CombatHandler::hasOpponent(Character * character)
{
    return std::find_if(opponents.begin(), opponents.end(),
                        [&](std::shared_ptr<Aggression> const & element)
                        {
                            return element->aggressor->name == character->name;
                        }) != opponents.end();
}

void CombatHandler::setPredefinedTarget(Character * character)
{
    predefinedTarget = character;
}

Character * CombatHandler::getPredefinedTarget()
{
    return predefinedTarget;
}

void CombatHandler::setAimedTarget(Character * character)
{
    aimedCharacter = character;
}

Character * CombatHandler::getAimedTarget()
{
    return aimedCharacter;
}

bool CombatHandler::setAggro(Character * character, unsigned int newAggression)
{
    bool ret = false;
    auto it = std::find_if(opponents.begin(), opponents.end(), [&](std::shared_ptr<Aggression> const & p)
    {
        return p->aggressor->name == character->name;
    });
    if (it != opponents.end())
    {
        // Set the new aggro.
        (*it)->aggression = newAggression;
        // Sort the list.
        this->sortList();
        // Set return value to success.
        ret = true;
    }
    return ret;
}

std::shared_ptr<Aggression> CombatHandler::getTopAggro()
{
    if (opponents.empty())
    {
        return nullptr;
    }
    return *(opponents.begin());
}

bool CombatHandler::moveToTopAggro(Character * character)
{
    // Check if the character is a valid opponent.
    if (!this->hasOpponent(character))
    {
        return false;
    }
    auto topAggressor = this->getTopAggro();
    if (topAggressor == nullptr)
    {
        return false;
    }
    // Check if the character is already the top aggro.
    if (topAggressor->aggressor == character)
    {
        return false;
    }
    // Retrieve the top aggro.
    auto currentAggro = this->getAggro(character);
    auto topAggro = currentAggro;
    for (auto it : opponents)
    {
        if (it->aggression > topAggro)
        {
            topAggro = it->aggression;
        }
    }
    // Just set the aggro of the character enough to be put on the first place.
    this->setAggro(character, topAggro + 1);
    return true;
}

unsigned int CombatHandler::getInitialAggro(Character * character)
{
    if (owner->level > character->level)
    {
        return (owner->level - character->level);
    }
    return (character->level - owner->level);
}

unsigned int CombatHandler::getAggro(Character * character)
{
    for (auto it : opponents)
    {
        if (it->aggressor == character)
        {
            return it->aggression;
        }
    }
    return 0;
}

std::size_t CombatHandler::getSize()
{
    return opponents.size();
}

bool CombatHandler::empty()
{
    return opponents.empty();
}

void CombatHandler::checkList()
{
    auto temporaryList = opponents;
    for (auto it = temporaryList.begin(); it != temporaryList.end(); ++it)
    {
        // Check if the aggressor is null.
        if ((*it)->aggressor == nullptr)
        {
            this->remOpponent((*it)->aggressor);
        }
            // Check if the aggressor is nowhere.
        else if ((*it)->aggressor->room == nullptr)
        {
            this->remOpponent((*it)->aggressor);
        }
    }
}

void CombatHandler::resetList()
{
    auto temporaryList = opponents;
    for (auto it = temporaryList.begin(); it != temporaryList.end(); ++it)
    {
        // Check if the aggressor is null.
        if ((*it)->aggressor == nullptr)
        {
            continue;
        }
        // Remove the owner from its list.
        if (!(*it)->aggressor->combatHandler.remOpponent(owner))
        {
            Logger::log(LogLevel::Error, "Could not remove %s from opponents of %s.",
                        owner->getName(), (*it)->aggressor->getName());
        }
        // Remove from this list the opponent.
        if (!this->remOpponent((*it)->aggressor))
        {
            Logger::log(LogLevel::Error, "Could not remove %s from opponents of %s.",
                        (*it)->aggressor->getName(), owner->getName());
        }
    }
    opponents.clear();
}

CombatHandler::iterator CombatHandler::begin()
{
    return opponents.begin();
}

CombatHandler::iterator CombatHandler::end()
{
    return opponents.end();
}

void CombatHandler::sortList()
{
    std::sort(opponents.begin(), opponents.end(),
              [](std::shared_ptr<Aggression> a, std::shared_ptr<Aggression> b)
              { return a->aggression > b->aggression; });
}

void CombatHandler::printList()
{
    std::cout << "Aggro List:" << std::endl;
    for (auto it : opponents)
    {
        std::cout << "  [" + (*it).aggressor->name + "] " + ToString((*it).aggression) << std::endl;
    }
}
<commit_msg>Correctly remove an opponent from the opponents list of a character<commit_after>/// @file   combatHandler.cpp
/// @brief  Contains implementation of combat classes.
/// @author Enrico Fraccaroli
/// @date   May 8 2016
/// @copyright
/// Copyright (c) 2016 Enrico Fraccaroli <enrico.fraccaroli@gmail.com>
/// Permission is hereby granted, free of charge, to any person obtaining a
/// copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:
///     The above copyright notice and this permission notice shall be included
///     in all copies or substantial portions of the Software.
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.

#include "combatHandler.hpp"

#include "utils.hpp"
#include "logger.hpp"
#include "character.hpp"

CombatHandler::CombatHandler(Character * _owner) :
    owner(_owner),
    opponents(),
    predefinedTarget(),
    aimedCharacter()
{
    // Nothing to do.
}

CombatHandler::~CombatHandler()
{
    // Nothing to do.
}

bool CombatHandler::addOpponent(Character * character, unsigned int initAggro)
{
    if (!this->hasOpponent(character))
    {
        if (initAggro == 0)
        {
            initAggro = this->getInitialAggro(character);
        }
        // Add the aggressor.
        opponents.push_back(std::make_shared<Aggression>(character, initAggro));
        // Sort the list.
        this->sortList();
        Logger::log(LogLevel::Debug, "%s engage %s with %s.", owner->getNameCapital(), character->getName(), initAggro);
        return true;
    }
    return false;
}

bool CombatHandler::remOpponent(Character * character)
{
    for (auto it = opponents.begin(); it != opponents.end(); ++it)
    {
        auto aggression = (*it);
        if (aggression->aggressor->name == character->name)
        {
            // Remove the opponent.
            opponents.erase(it);
            // Check if the opponent is currently the aimed character.
            if (aimedCharacter != nullptr)
            {
                if (aimedCharacter->name == aggression->aggressor->name)
                {
                    aimedCharacter = nullptr;
                }
            }
            // Check if the opponent is currently the predefined target.
            if (predefinedTarget != nullptr)
            {
                if (predefinedTarget->name == aggression->aggressor->name)
                {
                    predefinedTarget = nullptr;
                }
            }
            Logger::log(LogLevel::Debug, "%s disengages %s", owner->getNameCapital(), character->getName());
            return true;
        }
    }
    Logger::log(LogLevel::Debug, "Cannot find %s among the aggressors of %s",
                character->getName(),
                owner->getNameCapital());
    return false;
}

bool CombatHandler::hasOpponent(Character * character)
{
    return std::find_if(opponents.begin(), opponents.end(),
                        [&](std::shared_ptr<Aggression> const & element)
                        {
                            return element->aggressor->name == character->name;
                        }) != opponents.end();
}

void CombatHandler::setPredefinedTarget(Character * character)
{
    predefinedTarget = character;
}

Character * CombatHandler::getPredefinedTarget()
{
    return predefinedTarget;
}

void CombatHandler::setAimedTarget(Character * character)
{
    aimedCharacter = character;
}

Character * CombatHandler::getAimedTarget()
{
    return aimedCharacter;
}

bool CombatHandler::setAggro(Character * character, unsigned int newAggression)
{
    bool ret = false;
    auto it = std::find_if(opponents.begin(), opponents.end(), [&](std::shared_ptr<Aggression> const & p)
    {
        return p->aggressor->name == character->name;
    });
    if (it != opponents.end())
    {
        // Set the new aggro.
        (*it)->aggression = newAggression;
        // Sort the list.
        this->sortList();
        // Set return value to success.
        ret = true;
    }
    return ret;
}

std::shared_ptr<Aggression> CombatHandler::getTopAggro()
{
    if (opponents.empty())
    {
        return nullptr;
    }
    return *(opponents.begin());
}

bool CombatHandler::moveToTopAggro(Character * character)
{
    // Check if the character is a valid opponent.
    if (!this->hasOpponent(character))
    {
        return false;
    }
    auto topAggressor = this->getTopAggro();
    if (topAggressor == nullptr)
    {
        return false;
    }
    // Check if the character is already the top aggro.
    if (topAggressor->aggressor == character)
    {
        return false;
    }
    // Retrieve the top aggro.
    auto currentAggro = this->getAggro(character);
    auto topAggro = currentAggro;
    for (auto it : opponents)
    {
        if (it->aggression > topAggro)
        {
            topAggro = it->aggression;
        }
    }
    // Just set the aggro of the character enough to be put on the first place.
    this->setAggro(character, topAggro + 1);
    return true;
}

unsigned int CombatHandler::getInitialAggro(Character * character)
{
    if (owner->level > character->level)
    {
        return (owner->level - character->level);
    }
    return (character->level - owner->level);
}

unsigned int CombatHandler::getAggro(Character * character)
{
    for (auto it : opponents)
    {
        if (it->aggressor == character)
        {
            return it->aggression;
        }
    }
    return 0;
}

std::size_t CombatHandler::getSize()
{
    return opponents.size();
}

bool CombatHandler::empty()
{
    return opponents.empty();
}

void CombatHandler::checkList()
{
    auto temporaryList = opponents;
    for (auto it = temporaryList.begin(); it != temporaryList.end(); ++it)
    {
        // Check if the aggressor is null.
        if ((*it)->aggressor == nullptr)
        {
            this->remOpponent((*it)->aggressor);
        }
            // Check if the aggressor is nowhere.
        else if ((*it)->aggressor->room == nullptr)
        {
            this->remOpponent((*it)->aggressor);
        }
    }
}

void CombatHandler::resetList()
{
    for (auto it : opponents)
    {
        if (it->aggressor == nullptr)
        {
            Logger::log(LogLevel::Error, "Found a nullptr aggressor.");
        }
        else
        {
            // Remove the owner from its list.
            if (!it->aggressor->combatHandler.remOpponent(owner))
            {
                Logger::log(LogLevel::Error, "Could not remove %s from opponents of %s.",
                            owner->getName(), it->aggressor->getName());
            }
        }
    }
    opponents.clear();
}

CombatHandler::iterator CombatHandler::begin()
{
    return opponents.begin();
}

CombatHandler::iterator CombatHandler::end()
{
    return opponents.end();
}

void CombatHandler::sortList()
{
    std::sort(opponents.begin(), opponents.end(),
              [](std::shared_ptr<Aggression> a, std::shared_ptr<Aggression> b)
              { return a->aggression > b->aggression; });
}

void CombatHandler::printList()
{
    std::cout << "Aggro List:" << std::endl;
    for (auto it : opponents)
    {
        std::cout << "  [" + (*it).aggressor->name + "] " + ToString((*it).aggression) << std::endl;
    }
}
<|endoftext|>


<commit_before>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <chartsql/qtree/UnionNode.h>

using namespace stx;

namespace csql {

UnionNode::UnionNode(const UnionNode& other) {
  for (const auto& tbl : other.tables_) {
    tables_.emplace_back(tbl->deepCopy());
  }

  for (auto& table : tables_) {
    addChild(&table);
  }
}

UnionNode::UnionNode(
    Vector<RefPtr<QueryTreeNode>> tables) :
    tables_(tables) {
  for (auto& table : tables_) {
    addChild(&table);
  }
}

Vector<RefPtr<QueryTreeNode>> UnionNode::inputTables() const {
  return tables_;
}

RefPtr<QueryTreeNode> UnionNode::deepCopy() const {
  return new UnionNode(*this);
}

} // namespace csql
<commit_msg>UnionNode::toString<commit_after>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <chartsql/qtree/UnionNode.h>

using namespace stx;

namespace csql {

UnionNode::UnionNode(const UnionNode& other) {
  for (const auto& tbl : other.tables_) {
    tables_.emplace_back(tbl->deepCopy());
  }

  for (auto& table : tables_) {
    addChild(&table);
  }
}

UnionNode::UnionNode(
    Vector<RefPtr<QueryTreeNode>> tables) :
    tables_(tables) {
  for (auto& table : tables_) {
    addChild(&table);
  }
}

Vector<RefPtr<QueryTreeNode>> UnionNode::inputTables() const {
  return tables_;
}

RefPtr<QueryTreeNode> UnionNode::deepCopy() const {
  return new UnionNode(*this);
}

String UnionNode::toString() const {
  String str = "(union";

  for (const auto& tbl : tables_) {
    str += " (subexpr " + tbl->toString() + ")";
  }

  str += ")";
  return str;
}

} // namespace csql
<|endoftext|>


<commit_before>#ifndef ITER_IMAP_H_
#define ITER_IMAP_H_

#include "zip.hpp"

#include <utility>
#include <type_traits>

namespace iter {

    namespace detail {

    template <std::size_t Index, typename Functor, typename Tup>
    struct Expander {
        template <typename... Ts>
        static auto call(Functor&& f, Tup&& tup, Ts&&... args)
            -> decltype(Expander<Index-1, Functor, Tup>::call(
                    std::forward<Functor>(f),
                    std::forward<Tup>(tup),
                    std::get<Index-1>(tup),
                    std::forward<Ts>(args)...))
        {
            // recurse
            return Expander<Index-1, Functor, Tup>::call(
                    std::forward<Functor>(f),
                    std::forward<Tup>(tup),
                    std::get<Index-1>(tup), // pull out one element
                    std::forward<Ts>(args)...); // everything already expanded
        }
    };

    template <typename Functor, typename Tup>
    struct Expander<0, Functor, Tup> {
        template <typename... Ts>
        static auto call(Functor&& f, Tup&&, Ts&&... args)
            -> decltype(f(std::forward<Ts>(args)...))
        {
            static_assert(
                std::tuple_size<
                    typename std::remove_reference<Tup>::type>::value
                    == sizeof...(Ts),
                "tuple has not been fully expanded");
            return f(std::forward<Ts>(args)...); // the actual call
        }
    };

    template <typename Functor, typename Tup>
    auto call_with_tuple(Functor&& f, Tup&& tup)
        -> decltype(Expander<std::tuple_size<
                    typename std::remove_reference<Tup>::type>::value,
                    Functor, Tup>::call(
                        std::forward<Functor>(f),
                        std::forward<Tup>(tup)))
    {
        return Expander<std::tuple_size<
            typename std::remove_reference<Tup>::type>::value,
            Functor, Tup>::call(
                std::forward<Functor>(f),
                std::forward<Tup>(tup));
    }

    } // end detail

    //Forward declarations of IMap and imap
    template <typename MapFunc, typename... Containers>
    class IMap;

    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(MapFunc, Containers&&...);

    template <typename MapFunc, typename... Containers>
    class IMap {
        // The imap function is the only thing allowed to create a IMap
        friend IMap imap<MapFunc, Containers...>(MapFunc, Containers&& ...);

        using ZippedType = decltype(zip(std::declval<Containers>()...));
        using ZippedIterType = iterator_type<ZippedType>;
        private:
            MapFunc map_func;
            ZippedType zipped;

            using IMapIterDeref = decltype(detail::call_with_tuple(
                        map_func, *std::begin(zipped)));

            // Value constructor for use only in the imap function
            IMap(MapFunc map_func, Containers&& ... containers) :
                map_func(map_func),
                zipped(zip(std::forward<Containers>(containers)...))
            { }

        public:
            class Iterator
                : public std::iterator<std::input_iterator_tag,
                    typename std::remove_reference<IMapIterDeref>::type >
            {
                private:
                    MapFunc *map_func;
                    ZippedIterType zipiter;

                public:
                    Iterator(MapFunc& map_func, ZippedIterType&& in_zipiter) :
                        map_func(&map_func),
                        zipiter(std::move(in_zipiter))
                    { }

                    IMapIterDeref operator*() {
                        return detail::call_with_tuple(
                                *this->map_func, *(this->zipiter));
                    }

                    Iterator& operator++() {
                        ++this->zipiter;
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->zipiter != other.zipiter;
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }
            };

            Iterator begin() {
                return {this->map_func, this->zipped.begin()};
            }

            Iterator end() {
                return {this->map_func, this->zipped.end()};
            }

    };

    // Helper function to instantiate a IMap
    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(
            MapFunc map_func, Containers&& ... containers) {
        return {map_func, std::forward<Containers>(containers)...};
    }

}

#endif // #ifndef ITER_IMAP_H_
<commit_msg>forwards elements in call_with_tuple<commit_after>#ifndef ITER_IMAP_H_
#define ITER_IMAP_H_

#include "zip.hpp"

#include <utility>
#include <type_traits>
#include <tuple>

namespace iter {

    namespace detail {

    template <std::size_t Index, typename Functor, typename Tup>
    struct Expander {
        template <typename... Ts>
        static auto call(Functor&& f, Tup&& tup, Ts&&... args)
            -> decltype(Expander<Index-1, Functor, Tup>::call(
                    std::forward<Functor>(f),
                    std::forward<Tup>(tup),
                    std::forward<
                        typename std::tuple_element<Index-1,
                            typename std::remove_reference<Tup>::type>::type>(
                        std::get<Index-1>(tup)),
                    std::forward<Ts>(args)...))
        {
            // recurse
            return Expander<Index-1, Functor, Tup>::call(
                    std::forward<Functor>(f),
                    std::forward<Tup>(tup),
                    // pull out one element
                    std::forward<
                        typename std::tuple_element<Index-1,
                            typename std::remove_reference<Tup>::type>::type>(
                        std::get<Index-1>(tup)),
                    std::forward<Ts>(args)...); // everything already expanded
        }
    };

    template <typename Functor, typename Tup>
    struct Expander<0, Functor, Tup> {
        template <typename... Ts>
        static auto call(Functor&& f, Tup&&, Ts&&... args)
            -> decltype(f(std::forward<Ts>(args)...))
        {
            static_assert(
                std::tuple_size<
                    typename std::remove_reference<Tup>::type>::value
                    == sizeof...(Ts),
                "tuple has not been fully expanded");
            return f(std::forward<Ts>(args)...); // the actual call
        }
    };

    template <typename Functor, typename Tup>
    auto call_with_tuple(Functor&& f, Tup&& tup)
        -> decltype(Expander<std::tuple_size<
                    typename std::remove_reference<Tup>::type>::value,
                    Functor, Tup>::call(
                        std::forward<Functor>(f),
                        std::forward<Tup>(tup)))
    {
        return Expander<std::tuple_size<
            typename std::remove_reference<Tup>::type>::value,
            Functor, Tup>::call(
                std::forward<Functor>(f),
                std::forward<Tup>(tup));
    }

    } // end detail

    //Forward declarations of IMap and imap
    template <typename MapFunc, typename... Containers>
    class IMap;

    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(MapFunc, Containers&&...);

    template <typename MapFunc, typename... Containers>
    class IMap {
        // The imap function is the only thing allowed to create a IMap
        friend IMap imap<MapFunc, Containers...>(MapFunc, Containers&& ...);

        using ZippedType = decltype(zip(std::declval<Containers>()...));
        using ZippedIterType = iterator_type<ZippedType>;
        private:
            MapFunc map_func;
            ZippedType zipped;

            using IMapIterDeref = decltype(detail::call_with_tuple(
                        map_func, *std::begin(zipped)));

            // Value constructor for use only in the imap function
            IMap(MapFunc map_func, Containers&& ... containers) :
                map_func(map_func),
                zipped(zip(std::forward<Containers>(containers)...))
            { }

        public:
            class Iterator
                : public std::iterator<std::input_iterator_tag,
                    typename std::remove_reference<IMapIterDeref>::type >
            {
                private:
                    MapFunc *map_func;
                    ZippedIterType zipiter;

                public:
                    Iterator(MapFunc& map_func, ZippedIterType&& in_zipiter) :
                        map_func(&map_func),
                        zipiter(std::move(in_zipiter))
                    { }

                    IMapIterDeref operator*() {
                        return detail::call_with_tuple(
                                *this->map_func, *(this->zipiter));
                    }

                    Iterator& operator++() {
                        ++this->zipiter;
                        return *this;
                    }

                    Iterator operator++(int) {
                        auto ret = *this;
                        ++*this;
                        return ret;
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->zipiter != other.zipiter;
                    }

                    bool operator==(const Iterator& other) const {
                        return !(*this != other);
                    }
            };

            Iterator begin() {
                return {this->map_func, this->zipped.begin()};
            }

            Iterator end() {
                return {this->map_func, this->zipped.end()};
            }

    };

    // Helper function to instantiate a IMap
    template <typename MapFunc, typename... Containers>
    IMap<MapFunc, Containers...> imap(
            MapFunc map_func, Containers&& ... containers) {
        return {map_func, std::forward<Containers>(containers)...};
    }

}

#endif // #ifndef ITER_IMAP_H_
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

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 "paddle/operators/math/sequence_padding.h"

namespace paddle {
namespace operators {
namespace math {

template <typename T>
class PaddingLoDTensorFunctor<platform::CPUDeviceContext, T> {
 public:
  void operator()(const platform::CPUDeviceContext& context,
                  const framework::LoDTensor& seq, framework::Tensor& padding,
                  bool norm_by_times) {
    auto lod = seq.lod();
    PADDLE_ENFORCE_GT(lod.size(), 0UL,
                      "The LoD of LoDTensor seq should not be null.");

    const size_t level = 0;
    framework::LoD abs_offset_lod = framework::ToAbsOffset(lod);

    auto seq_dims = seq.dims();
    PADDLE_ENFORCE_EQ(seq_dims[0], abs_offset_lod[level].back(),
                      "The first dimension of LoDTensor seq should be "
                      "equal to the sum of all sequences's length.");

    auto padding_dims = padding.dims();
    PADDLE_ENFORCE_EQ(padding_dims.size(), 3UL,
                      "The input padding should be a 3-D Tensor of shape "
                      "[max_sequence_length, num_sequences, sequence_width].");

    const size_t max_sequence_length = MaximumSequenceLength(lod, level);
    PADDLE_ENFORCE_EQ(padding_dims[0], max_sequence_length,
                      "The first dimension of Tensor padding should be the "
                      "maximum length of all sequences in LoDTensor seq.");

    const size_t num_sequences = abs_offset_lod[level].size() - 1;
    PADDLE_ENFORCE_EQ(padding_dims[1], num_sequences,
                      "The second dimension of Tensor padding should be the "
                      "number of sequences in LoDTensor seq.");

    const size_t sequence_width = seq.numel() / seq_dims[0];
    PADDLE_ENFORCE_EQ(padding_dims[2], sequence_width,
                      "The third dimension of Tensor padding should be the "
                      "width of sequence in LoDTensor seq.");

    const T* seq_data = seq.data<T>();
    T* padding_data = padding.data<T>();
    for (size_t i = 0; i < max_sequence_length; ++i) {
      for (size_t j = 0; j < num_sequences; ++j) {
        size_t start_pos = abs_offset_lod[level][j];
        size_t sequence_length = abs_offset_lod[level][j + 1] - start_pos;
        if (i < sequence_length) {
          // i > 0 => sequence_length > 0
          T scale =
              norm_by_times ? (1.0f / static_cast<T>(sequence_length)) : 1.0f;
          for (size_t k = 0; k < sequence_width; ++k) {
            padding_data[(i * num_sequences + j) * sequence_width + k] =
                seq_data[(start_pos + i) * sequence_width + k] * scale;
          }
        } else {
          memset(padding_data + (i * num_sequences + j) * sequence_width, 0,
                 sequence_width * sizeof(T));
        }
      }
    }
  }
};

template <typename T>
class UnpaddingLoDTensorFunctor<platform::CPUDeviceContext, T> {
 public:
  void operator()(const platform::CPUDeviceContext& context,
                  framework::LoDTensor& seq, const framework::Tensor& padding,
                  bool norm_by_times) {
    auto lod = seq.lod();
    PADDLE_ENFORCE_GT(lod.size(), 0UL,
                      "The LoD of LoDTensor seq should not be null.");

    const size_t level = 0;
    framework::LoD abs_offset_lod = framework::ToAbsOffset(lod);

    auto seq_dims = seq.dims();
    PADDLE_ENFORCE_EQ(seq_dims[0], abs_offset_lod[level].back(),
                      "The first dimension of LoDTensor seq should be "
                      "equal to the sum of all sequences's length.");

    auto padding_dims = padding.dims();
    PADDLE_ENFORCE_EQ(padding_dims.size(), 3UL,
                      "The input padding should be a 3-D Tensor of shape "
                      "[max_sequnece_length, num_sequences, sequence_width].");

    const size_t max_sequence_length = MaximumSequenceLength(lod, level);
    PADDLE_ENFORCE_EQ(padding_dims[0], max_sequence_length,
                      "The first dimension of Tensor padding should be "
                      "the maximum length of all sequences in LoDTensor seq.");

    const size_t num_sequences = abs_offset_lod[level].size() - 1;
    PADDLE_ENFORCE_EQ(padding_dims[1], num_sequences,
                      "The second dimension of Tensor padding should be "
                      "the number of sequences in LoDTensor seq.");

    const size_t sequence_width = seq.numel() / seq_dims[0];
    PADDLE_ENFORCE_EQ(padding_dims[2], sequence_width,
                      "The third dimension of Tensor padding should be the "
                      "width of sequence in LoDTensor seq.");

    const T* padding_data = padding.data<T>();
    T* seq_data = seq.data<T>();
    for (size_t i = 0; i < num_sequences; ++i) {
      size_t start_pos = abs_offset_lod[level][i];
      size_t sequence_length = abs_offset_lod[level][i + 1] - start_pos;
      for (size_t j = 0; j < sequence_length; ++j) {
        // sequence_width > j > 0
        T scale =
            norm_by_times ? (1.0f / static_cast<T>(sequence_length)) : 1.0f;
        for (size_t k = 0; k < sequence_width; ++k) {
          seq_data[(start_pos + j) * sequence_width + k] =
              padding_data[(j * num_sequences + i) * sequence_width + k] *
              scale;
        }
      }
    }
  }
};

template class PaddingLoDTensorFunctor<platform::CPUDeviceContext, float>;
template class UnpaddingLoDTensorFunctor<platform::CPUDeviceContext, float>;

}  // namespace math
}  // namespace operators
}  // namespace paddle
<commit_msg>Fix sequence_padding compile warning<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

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 "paddle/operators/math/sequence_padding.h"

namespace paddle {
namespace operators {
namespace math {

template <typename T>
class PaddingLoDTensorFunctor<platform::CPUDeviceContext, T> {
 public:
  void operator()(const platform::CPUDeviceContext& context,
                  const framework::LoDTensor& seq, framework::Tensor& padding,
                  bool norm_by_times) {
    auto lod = seq.lod();
    PADDLE_ENFORCE_GT(lod.size(), 0UL,
                      "The LoD of LoDTensor seq should not be null.");

    const size_t level = 0;
    framework::LoD abs_offset_lod = framework::ToAbsOffset(lod);

    auto seq_dims = seq.dims();
    PADDLE_ENFORCE_EQ(seq_dims[0],
                      static_cast<int64_t>(abs_offset_lod[level].back()),
                      "The first dimension of LoDTensor seq should be "
                      "equal to the sum of all sequences's length.");

    auto padding_dims = padding.dims();
    PADDLE_ENFORCE_EQ(padding_dims.size(), 3UL,
                      "The input padding should be a 3-D Tensor of shape "
                      "[max_sequence_length, num_sequences, sequence_width].");

    const int64_t max_sequence_length = MaximumSequenceLength(lod, level);
    PADDLE_ENFORCE_EQ(padding_dims[0], max_sequence_length,
                      "The first dimension of Tensor padding should be the "
                      "maximum length of all sequences in LoDTensor seq.");

    const int64_t num_sequences = abs_offset_lod[level].size() - 1;
    PADDLE_ENFORCE_EQ(padding_dims[1], num_sequences,
                      "The second dimension of Tensor padding should be the "
                      "number of sequences in LoDTensor seq.");

    const int64_t sequence_width = seq.numel() / seq_dims[0];
    PADDLE_ENFORCE_EQ(padding_dims[2], sequence_width,
                      "The third dimension of Tensor padding should be the "
                      "width of sequence in LoDTensor seq.");

    const T* seq_data = seq.data<T>();
    T* padding_data = padding.data<T>();
    for (int64_t i = 0; i < max_sequence_length; ++i) {
      for (int64_t j = 0; j < num_sequences; ++j) {
        int64_t start_pos = abs_offset_lod[level][j];
        int64_t sequence_length = abs_offset_lod[level][j + 1] - start_pos;
        if (i < sequence_length) {
          // i > 0 => sequence_length > 0
          T scale =
              norm_by_times ? (1.0f / static_cast<T>(sequence_length)) : 1.0f;
          for (int64_t k = 0; k < sequence_width; ++k) {
            padding_data[(i * num_sequences + j) * sequence_width + k] =
                seq_data[(start_pos + i) * sequence_width + k] * scale;
          }
        } else {
          memset(padding_data + (i * num_sequences + j) * sequence_width, 0,
                 sequence_width * sizeof(T));
        }
      }
    }
  }
};

template <typename T>
class UnpaddingLoDTensorFunctor<platform::CPUDeviceContext, T> {
 public:
  void operator()(const platform::CPUDeviceContext& context,
                  framework::LoDTensor& seq, const framework::Tensor& padding,
                  bool norm_by_times) {
    auto lod = seq.lod();
    PADDLE_ENFORCE_GT(lod.size(), 0UL,
                      "The LoD of LoDTensor seq should not be null.");

    const size_t level = 0;
    framework::LoD abs_offset_lod = framework::ToAbsOffset(lod);

    auto seq_dims = seq.dims();
    PADDLE_ENFORCE_EQ(seq_dims[0],
                      static_cast<int64_t>(abs_offset_lod[level].back()),
                      "The first dimension of LoDTensor seq should be "
                      "equal to the sum of all sequences's length.");

    auto padding_dims = padding.dims();
    PADDLE_ENFORCE_EQ(padding_dims.size(), 3UL,
                      "The input padding should be a 3-D Tensor of shape "
                      "[max_sequnece_length, num_sequences, sequence_width].");

    const int64_t max_sequence_length = MaximumSequenceLength(lod, level);
    PADDLE_ENFORCE_EQ(padding_dims[0], max_sequence_length,
                      "The first dimension of Tensor padding should be "
                      "the maximum length of all sequences in LoDTensor seq.");

    const int64_t num_sequences = abs_offset_lod[level].size() - 1;
    PADDLE_ENFORCE_EQ(padding_dims[1], num_sequences,
                      "The second dimension of Tensor padding should be "
                      "the number of sequences in LoDTensor seq.");

    const int64_t sequence_width = seq.numel() / seq_dims[0];
    PADDLE_ENFORCE_EQ(padding_dims[2], sequence_width,
                      "The third dimension of Tensor padding should be the "
                      "width of sequence in LoDTensor seq.");

    const T* padding_data = padding.data<T>();
    T* seq_data = seq.data<T>();
    for (int64_t i = 0; i < num_sequences; ++i) {
      int64_t start_pos = abs_offset_lod[level][i];
      int64_t sequence_length = abs_offset_lod[level][i + 1] - start_pos;
      for (int64_t j = 0; j < sequence_length; ++j) {
        // sequence_width > j > 0
        T scale =
            norm_by_times ? (1.0f / static_cast<T>(sequence_length)) : 1.0f;
        for (int64_t k = 0; k < sequence_width; ++k) {
          seq_data[(start_pos + j) * sequence_width + k] =
              padding_data[(j * num_sequences + i) * sequence_width + k] *
              scale;
        }
      }
    }
  }
};

template class PaddingLoDTensorFunctor<platform::CPUDeviceContext, float>;
template class UnpaddingLoDTensorFunctor<platform::CPUDeviceContext, float>;

}  // namespace math
}  // namespace operators
}  // namespace paddle
<|endoftext|>


<commit_before>// Filename: milesAudioSound.cxx
// Created by:  skyler (June 6, 2001)
// Prior system by: cary
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license.  You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////

#include <pandabase.h>
#ifdef HAVE_RAD_MSS //[

#include "milesAudioSound.h"
#include "milesAudioManager.h"

MilesAudioSound::
MilesAudioSound(MilesAudioManager& manager,
    HAUDIO audio, string file_name)
    : _manager(manager), _file_name(file_name),
    _start_time(0), _volume(1.0), _balance(0),
    _loop_count(1),
    _active(true), _paused(false) {
  nassertv(audio);
  nassertv(!file_name.empty());
  audio_debug("MilesAudioSound::MilesAudioSound(manager=0x"<<(void*)&manager
      <<", audio=0x"<<(void*)audio<<", file_name="<<file_name<<")");
  // Make our own copy of the sound header data:
  _audio=AIL_quick_copy(audio);
}

MilesAudioSound::
~MilesAudioSound() {
  audio_debug("MilesAudioSound::~MilesAudioSound() "<<get_name());
  _manager.release_sound(this);
  AIL_quick_unload(_audio);
}

void MilesAudioSound::
play() {
  audio_debug("MilesAudioSound::play() "<<get_name());
  if (_active) {
    // Start playing:
    if (AIL_quick_play(_audio, _loop_count)) {
      audio_debug("  started sound");
    } else {
      audio_debug("  failed to play sound "<<AIL_last_error());
    }
  } else {
    // In case _loop_count gets set to forever (zero):
    audio_debug("  paused");
    _paused=true;
  }
}

void MilesAudioSound::
stop() {
  audio_debug("MilesAudioSound::stop() "<<get_name());
  AIL_quick_halt(_audio);
}

void MilesAudioSound::
set_loop(bool loop) {
  audio_debug("MilesAudioSound::set_loop(loop="<<loop<<") "<<get_name());
  set_loop_count((loop)?0:1);
}

bool MilesAudioSound::
get_loop() const {
  audio_debug("MilesAudioSound::get_loop() returning "<<(_loop_count==0));
  return _loop_count == 0;
}

void MilesAudioSound::
set_loop_count(unsigned long loop_count) {
  audio_debug("MilesAudioSound::set_loop_count(loop_count="<<loop_count<<") "<<get_name());
  if (_loop_count!=loop_count) {
    _loop_count=loop_count;
    if (status()==PLAYING) {
      stop();
      play();
    }
  }
}

unsigned long MilesAudioSound::
get_loop_count() const {
  audio_debug("MilesAudioSound::get_loop_count() returning "<<_loop_count);
  return _loop_count;
}

void MilesAudioSound::set_time(float start_time) {
  audio_debug("MilesAudioSound::set_time(start_time="<<start_time<<") "<<get_name());
  _start_time=start_time;
  S32 milisecond_start_time=S32(1000*_start_time);
  AIL_quick_set_ms_position(_audio, milisecond_start_time);
}

float MilesAudioSound::get_time() const {
  audio_debug("MilesAudioSound::get_time() returning "<<_start_time);
  return _start_time;
}

void MilesAudioSound::set_volume(float volume) {
  audio_debug("MilesAudioSound::set_volume(volume="<<volume<<") "<<get_name());
  // *Set the volume even if our volume is not changing, because the
  // *MilesAudioManager will call set_volume when *its* volume changes.
  // Set the volume:
  _volume=volume;
  // Account for the category of sound:
  volume*=_manager.get_volume();
  // Change to Miles volume, range 0 to 127:
  S32 milesVolume=(S32(127*volume))%128;
  // Account for type:
  S32 audioType=AIL_quick_type(_audio);
  if (audioType==AIL_QUICK_XMIDI_TYPE
      ||
      audioType==AIL_QUICK_DLS_XMIDI_TYPE) {
    // ...it's a midi file.
    AIL_quick_set_volume(_audio, milesVolume, 0); // 0 delay.
    audio_debug("  volume for this midi is now "<<milesVolume);
  } else {
    // ...it's a wav or mp3.
    // Convert balance of -1.0..1.0 to 0..127:
    S32 milesBalance=(S32(63.5*(_balance+1.0)))%128;
    AIL_quick_set_volume(_audio, milesVolume, milesBalance);
    audio_debug("  volume for this wav or mp3 is now "<<milesVolume
        <<", balance="<<milesBalance);
  }
}

float MilesAudioSound::get_volume() const {
  audio_debug("MilesAudioSound::get_volume() returning "<<_volume);
  return _volume;
}

void MilesAudioSound::set_active(bool active) {
  audio_debug("MilesAudioSound::set_active(active="<<active<<") "<<get_name());
  if (_active!=active) {
    _active=active;
    if (_active) {
      // ...activate the sound.
      if (_paused
          &&
          _loop_count==0) {
        // ...this sound was looping when it was paused.
        _paused=false;
        play();
      }
    } else {
      // ...deactivate the sound.
      if (status()==PLAYING) {
        if (_loop_count==0) {
          // ...we're pausing a looping sound.
          _paused=true;
        }
        stop();
      }
    }
  }
}

bool MilesAudioSound::get_active() const {
  audio_debug("MilesAudioSound::get_active() returning "<<_active);
  return _active;
}

void MilesAudioSound::set_balance(float balance_right) {
  audio_debug("MilesAudioSound::set_balance(balance_right="<<balance_right<<") "<<get_name());
  _balance=balance_right;
  // Call set_volume to effect the change:
  set_volume(_volume);
}

float MilesAudioSound::get_balance() const {
  audio_debug("MilesAudioSound::get_balance() returning "<<_balance);
  return _balance;
}

float MilesAudioSound::length() const {
  float length;
  if (AIL_quick_status(_audio)==QSTAT_PLAYING) {
    length=((float)AIL_quick_ms_length(_audio))*0.001;
  } else {
    AIL_quick_play(_audio, 1);
    length=((float)AIL_quick_ms_length(_audio))*0.001;
    AIL_quick_halt(_audio);
  }
  audio_debug("MilesAudioSound::length() returning "<<length);
  return length;
}

const string& MilesAudioSound::get_name() const {
  //audio_debug("MilesAudioSound::get_name() returning "<<_file_name);
  return _file_name;
}

AudioSound::SoundStatus MilesAudioSound::status() const {
  if (!_audio) {
    return AudioSound::BAD;
  }
  switch (AIL_quick_status(_audio)) {
    case QSTAT_LOADED:
    case QSTAT_DONE:
      return AudioSound::READY;
    case QSTAT_PLAYING:
      return AudioSound::PLAYING;
    default:
      return AudioSound::BAD;
  }
}

#endif //]
<commit_msg>Comments and layout<commit_after>// Filename: milesAudioSound.cxx
// Created by:  skyler (June 6, 2001)
// Prior system by: cary
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license.  You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////

#include <pandabase.h>
#ifdef HAVE_RAD_MSS //[

#include "milesAudioSound.h"
#include "milesAudioManager.h"

MilesAudioSound::
MilesAudioSound(MilesAudioManager& manager,
    HAUDIO audio, string file_name)
    : _manager(manager), _file_name(file_name),
    _start_time(0), _volume(1.0), _balance(0),
    _loop_count(1),
    _active(true), _paused(false) {
  nassertv(audio);
  nassertv(!file_name.empty());
  audio_debug("MilesAudioSound::MilesAudioSound(manager=0x"<<(void*)&manager
      <<", audio=0x"<<(void*)audio<<", file_name="<<file_name<<")");
  // Make our own copy of the sound header data:
  _audio=AIL_quick_copy(audio);
}

MilesAudioSound::
~MilesAudioSound() {
  audio_debug("MilesAudioSound::~MilesAudioSound() "<<get_name());
  _manager.release_sound(this);
  AIL_quick_unload(_audio);
}

void MilesAudioSound::
play() {
  audio_debug("MilesAudioSound::play() "<<get_name());
  if (_active) {
    // Start playing:
    if (AIL_quick_play(_audio, _loop_count)) {
      audio_debug("  started sound");
    } else {
      audio_debug("  failed to play sound "<<AIL_last_error());
    }
  } else {
    // In case _loop_count gets set to forever (zero):
    audio_debug("  paused");
    _paused=true;
  }
}

void MilesAudioSound::
stop() {
  audio_debug("MilesAudioSound::stop() "<<get_name());
  AIL_quick_halt(_audio);
}

void MilesAudioSound::
set_loop(bool loop) {
  audio_debug("MilesAudioSound::set_loop(loop="<<loop<<") "<<get_name());
  set_loop_count((loop)?0:1);
}

bool MilesAudioSound::
get_loop() const {
  audio_debug("MilesAudioSound::get_loop() returning "<<(_loop_count==0));
  return _loop_count == 0;
}

void MilesAudioSound::
set_loop_count(unsigned long loop_count) {
  audio_debug("MilesAudioSound::set_loop_count(loop_count="<<loop_count<<") "<<get_name());
  if (_loop_count!=loop_count) {
    _loop_count=loop_count;
    if (status()==PLAYING) {
      // hack:
      // For now, the loop count is picked up when the sound starts playing.
      // There may be a way to change the loop count of a playing sound, but
      // I'm going to focus on other things.  If you would like to change the
      // need to stop and start the sound, feel free.  Or, maybe I'll spend
      // time on it in the future.  Please set the loop option before starting
      // the sound.
      stop();
      play();
    }
  }
}

unsigned long MilesAudioSound::
get_loop_count() const {
  audio_debug("MilesAudioSound::get_loop_count() returning "<<_loop_count);
  return _loop_count;
}

void MilesAudioSound::
set_time(float start_time) {
  audio_debug("MilesAudioSound::set_time(start_time="<<start_time<<") "<<get_name());
  _start_time=start_time;
  S32 milisecond_start_time=S32(1000*_start_time);
  AIL_quick_set_ms_position(_audio, milisecond_start_time);
}

float MilesAudioSound::
get_time() const {
  audio_debug("MilesAudioSound::get_time() returning "<<_start_time);
  return _start_time;
}

void MilesAudioSound::
set_volume(float volume) {
  audio_debug("MilesAudioSound::set_volume(volume="<<volume<<") "<<get_name());
  // *Set the volume even if our volume is not changing, because the
  // *MilesAudioManager will call set_volume when *its* volume changes.
  // Set the volume:
  _volume=volume;
  // Account for the category of sound:
  volume*=_manager.get_volume();
  // Change to Miles volume, range 0 to 127:
  S32 milesVolume=(S32(127*volume))%128;
  // Account for type:
  S32 audioType=AIL_quick_type(_audio);
  if (audioType==AIL_QUICK_XMIDI_TYPE
      ||
      audioType==AIL_QUICK_DLS_XMIDI_TYPE) {
    // ...it's a midi file.
    AIL_quick_set_volume(_audio, milesVolume, 0); // 0 delay.
    audio_debug("  volume for this midi is now "<<milesVolume);
  } else {
    // ...it's a wav or mp3.
    // Convert balance of -1.0..1.0 to 0..127:
    S32 milesBalance=(S32(63.5*(_balance+1.0)))%128;
    AIL_quick_set_volume(_audio, milesVolume, milesBalance);
    audio_debug("  volume for this wav or mp3 is now "<<milesVolume
        <<", balance="<<milesBalance);
  }
}

float MilesAudioSound::
get_volume() const {
  audio_debug("MilesAudioSound::get_volume() returning "<<_volume);
  return _volume;
}

void MilesAudioSound::
set_active(bool active) {
  audio_debug("MilesAudioSound::set_active(active="<<active<<") "<<get_name());
  if (_active!=active) {
    _active=active;
    if (_active) {
      // ...activate the sound.
      if (_paused
          &&
          _loop_count==0) {
        // ...this sound was looping when it was paused.
        _paused=false;
        play();
      }
    } else {
      // ...deactivate the sound.
      if (status()==PLAYING) {
        if (_loop_count==0) {
          // ...we're pausing a looping sound.
          _paused=true;
        }
        stop();
      }
    }
  }
}

bool MilesAudioSound::
get_active() const {
  audio_debug("MilesAudioSound::get_active() returning "<<_active);
  return _active;
}

void MilesAudioSound::
set_balance(float balance_right) {
  audio_debug("MilesAudioSound::set_balance(balance_right="<<balance_right<<") "<<get_name());
  _balance=balance_right;
  // Call set_volume to effect the change:
  set_volume(_volume);
}

float MilesAudioSound::
get_balance() const {
  audio_debug("MilesAudioSound::get_balance() returning "<<_balance);
  return _balance;
}

float MilesAudioSound::
length() const {
  // hack:
  // For now, the sound needs to be playing, in order to
  // get the right length.  I'm in contact with RAD about the problem.  I've
  // sent them example code.  They've told me they're looking into it.
  // Until then, we'll play the sound to get the length.
  float length;
  if (AIL_quick_status(_audio)==QSTAT_PLAYING) {
    length=((float)AIL_quick_ms_length(_audio))*0.001;
  } else {
    AIL_quick_play(_audio, 1);
    length=((float)AIL_quick_ms_length(_audio))*0.001;
    AIL_quick_halt(_audio);
  }
  audio_debug("MilesAudioSound::length() returning "<<length);
  return length;
}

const string& MilesAudioSound::
get_name() const {
  //audio_debug("MilesAudioSound::get_name() returning "<<_file_name);
  return _file_name;
}

AudioSound::SoundStatus MilesAudioSound::
status() const {
  if (!_audio) {
    return AudioSound::BAD;
  }
  switch (AIL_quick_status(_audio)) {
    case QSTAT_LOADED:
    case QSTAT_DONE:
      return AudioSound::READY;
    case QSTAT_PLAYING:
      return AudioSound::PLAYING;
    default:
      return AudioSound::BAD;
  }
}

#endif //]
<|endoftext|>


<commit_before>#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>

int
main (int argc, char** argv)
{
  // Load input file into a PointCloud<T> with an appropriate type
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  sensor_msgs::PointCloud2 cloud_blob;
  pcl::io::loadPCDFile ("bun0.pcd", cloud_blob);
  pcl::fromROSMsg (cloud_blob, *cloud);
  //* the data should be available in cloud

  // Normal estimation*
  pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
  pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
  pcl::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::KdTreeFLANN<pcl::PointXYZ>);
  tree->setInputCloud (cloud);
  n.setInputCloud (cloud);
  n.setSearchMethod (tree);
  n.setKSearch (20);
  n.compute (*normals);
  //* normals should not contain the point normals + surface curvatures

  // Concatenate the XYZ and normal fields*
  pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>);
  pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
  //* cloud_with_normals = cloud + normals

  // Create search tree*
  pcl::KdTree<pcl::PointNormal>::Ptr tree2 (new pcl::KdTreeFLANN<pcl::PointNormal>);
  tree2->setInputCloud (cloud_with_normals);

  // Initialize objects
  pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
  pcl::PolygonMesh triangles;

  // Set the maximum distance between connected points (maximum edge length)
  gp3.setSearchRadius (0.025);

  // Set typical values for the parameters
  gp3.setMu (2.5);
  gp3.setMaximumNearestNeighbors (100);
  gp3.setMaximumSurfaceAgle(M_PI/4); // 45 degrees
  gp3.setMinimumAngle(M_PI/18); // 10 degrees
  gp3.setMaximumAngle(2*M_PI/3); // 120 degrees
  gp3.setNormalConsistency(false);

  // Get result
  gp3.setInputCloud (cloud_with_normals);
  gp3.setSearchMethod (tree2);
  gp3.reconstruct (triangles);

  // Additional vertex information
  std::vector<int> parts = gp3.getPartIDs();
  std::vector<int> states = gp3.getPointStates();

  // Finish
  return (0);
}
<commit_msg>fix for API change<commit_after>#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>

int
main (int argc, char** argv)
{
  // Load input file into a PointCloud<T> with an appropriate type
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  sensor_msgs::PointCloud2 cloud_blob;
  pcl::io::loadPCDFile ("bun0.pcd", cloud_blob);
  pcl::fromROSMsg (cloud_blob, *cloud);
  //* the data should be available in cloud

  // Normal estimation*
  pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
  pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal>);
  pcl::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::KdTreeFLANN<pcl::PointXYZ>);
  tree->setInputCloud (cloud);
  n.setInputCloud (cloud);
  n.setSearchMethod (tree);
  n.setKSearch (20);
  n.compute (*normals);
  //* normals should not contain the point normals + surface curvatures

  // Concatenate the XYZ and normal fields*
  pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>);
  pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);
  //* cloud_with_normals = cloud + normals

  // Create search tree*
  pcl::KdTree<pcl::PointNormal>::Ptr tree2 (new pcl::KdTreeFLANN<pcl::PointNormal>);
  tree2->setInputCloud (cloud_with_normals);

  // Initialize objects
  pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
  pcl::PolygonMesh triangles;

  // Set the maximum distance between connected points (maximum edge length)
  gp3.setSearchRadius (0.025);

  // Set typical values for the parameters
  gp3.setMu (2.5);
  gp3.setMaximumNearestNeighbors (100);
  gp3.setMaximumSurfaceAngle(M_PI/4); // 45 degrees
  gp3.setMinimumAngle(M_PI/18); // 10 degrees
  gp3.setMaximumAngle(2*M_PI/3); // 120 degrees
  gp3.setNormalConsistency(false);

  // Get result
  gp3.setInputCloud (cloud_with_normals);
  gp3.setSearchMethod (tree2);
  gp3.reconstruct (triangles);

  // Additional vertex information
  std::vector<int> parts = gp3.getPartIDs();
  std::vector<int> states = gp3.getPointStates();

  // Finish
  return (0);
}
<|endoftext|>


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

#include "condition.h"

#if defined(__WIN32__) && !defined(PTHREADS_WIN32)

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

namespace embree
{
  struct ConditionImplementation
  {
    __forceinline ConditionImplementation ()
      : count(0)
    {
      //mutex = CreateMutex(NULL,FALSE,NULL);
      event = CreateEvent(NULL,TRUE,FALSE,NULL);
    }

    __forceinline ~ConditionImplementation ()
    {
      //CloseHandle(mutex);
      CloseHandle(event);
    }

    __forceinline void wait(MutexSys& mutex_in)
    {
      /* atomically increment thread count */
      //WaitForSingleObject(mutex,INFINITE);
	    //mutex.lock();
      ssize_t cnt0 = atomic_add(&count,+1);
	    //mutex.unlock();
      //ReleaseMutex(mutex);
      mutex_in.unlock();

      /* all threads except the last one are wait in the barrier */
      if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0)
        throw std::runtime_error("WaitForSingleObject failed");

      /* atomically decrement thread count */
      mutex_in.lock();
  	  //WaitForSingleObject(mutex,INFINITE);
	    mutex.lock();
      ssize_t cnt1 = atomic_add(&count,-1);
	    mutex.unlock();
      //ReleaseMutex(mutex);

      /* the last thread that left the barrier resets the event again */
      if (cnt1 == 1) {
        if (ResetEvent(event) == 0)
          throw std::runtime_error("ResetEvent failed");
      }
    }

    __forceinline void broadcast()
    {
      /* we support only one broadcast at a given time */
      //WaitForSingleObject(mutex,INFINITE);
	    //mutex.lock();
	    bool hasWaiters = count > 0;
	    //mutex.unlock();
	    //ReleaseMutex(mutex);

      /* if threads are waiting, let them continue */
      if (hasWaiters)
      {
        if (SetEvent(event) == 0)
          throw std::runtime_error("SetEvent failed");
      }
    }

  public:
    //HANDLE mutex;
    AtomicMutex mutex;
    HANDLE event;
    volatile atomic_t count;
  };
}
#endif

#if defined(__UNIX__) || defined(PTHREADS_WIN32)
#include <pthread.h>
namespace embree
{
  struct ConditionImplementation
  {
    __forceinline ConditionImplementation () {
      pthread_cond_init(&cond,NULL);
    }

    __forceinline ~ConditionImplementation() {
      pthread_cond_destroy(&cond);
    }

    __forceinline void wait(MutexSys& mutex) {
      pthread_cond_wait(&cond, (pthread_mutex_t*)mutex.mutex);
    }

    __forceinline void broadcast() {
      pthread_cond_broadcast(&cond);
    }

  public:
    pthread_cond_t cond;
  };
}
#endif

namespace embree
{
  ConditionSys::ConditionSys () {
    cond = new ConditionImplementation;
  }

  ConditionSys::~ConditionSys() {
    delete (ConditionImplementation*) cond;
  }

  void ConditionSys::wait(MutexSys& mutex) {
    ((ConditionImplementation*) cond)->wait(mutex);
  }

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

#include "condition.h"

#if defined(__WIN32__) && !defined(PTHREADS_WIN32)

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

namespace embree
{
#if 1
  struct ConditionImplementation
  {
    __forceinline ConditionImplementation ()
    {
      InitializeConditionVariable(&cond);
    }

    __forceinline ~ConditionImplementation ()
    {

    }

    __forceinline void wait(MutexSys& mutex_in)
    {
      SleepConditionVariableCS(&cond, (LPCRITICAL_SECTION)mutex_in.mutex, INFINITE);
    }

    __forceinline void broadcast()
    {
      WakeAllConditionVariable(&cond);
    }

  public:
    CONDITION_VARIABLE cond;
  };
#else
  struct ConditionImplementation
  {
    __forceinline ConditionImplementation ()
      : count(0)
    {
      //mutex = CreateMutex(NULL,FALSE,NULL);
      event = CreateEvent(NULL,TRUE,FALSE,NULL);
    }

    __forceinline ~ConditionImplementation ()
    {
      //CloseHandle(mutex);
      CloseHandle(event);
    }

    __forceinline void wait(MutexSys& mutex_in)
    {
      /* atomically increment thread count */
      //WaitForSingleObject(mutex,INFINITE);
      //mutex.lock();
      ssize_t cnt0 = atomic_add(&count,+1);
      //mutex.unlock();
      //ReleaseMutex(mutex);
      mutex_in.unlock();

      /* all threads except the last one are wait in the barrier */
      if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0)
        throw std::runtime_error("WaitForSingleObject failed");

      /* atomically decrement thread count */
      mutex_in.lock();
      //WaitForSingleObject(mutex,INFINITE);
      //mutex.lock();
      ssize_t cnt1 = atomic_add(&count,-1);
      //mutex.unlock();
      //ReleaseMutex(mutex);

      /* the last thread that left the barrier resets the event again */
      if (cnt1 == 1) {
        if (ResetEvent(event) == 0)
          throw std::runtime_error("ResetEvent failed");
      }
    }

    __forceinline void broadcast()
    {
      /* we support only one broadcast at a given time */
      //WaitForSingleObject(mutex,INFINITE);
      //mutex.lock();
      bool hasWaiters = count > 0;
      //mutex.unlock();
      //ReleaseMutex(mutex);

      /* if threads are waiting, let them continue */
      if (hasWaiters)
	{
	  if (SetEvent(event) == 0)
	    throw std::runtime_error("SetEvent failed");
	}
    }

  public:
    //HANDLE mutex;
    AtomicMutex mutex;
    HANDLE event;
    volatile atomic_t count;
  };
#endif
}
#endif

#if defined(__UNIX__) || defined(PTHREADS_WIN32)
#include <pthread.h>
namespace embree
{
  struct ConditionImplementation
  {
    __forceinline ConditionImplementation () {
      pthread_cond_init(&cond,NULL);
    }

    __forceinline ~ConditionImplementation() {
      pthread_cond_destroy(&cond);
    }

    __forceinline void wait(MutexSys& mutex) {
      pthread_cond_wait(&cond, (pthread_mutex_t*)mutex.mutex);
    }

    __forceinline void broadcast() {
      pthread_cond_broadcast(&cond);
    }

  public:
    pthread_cond_t cond;
  };
}
#endif

namespace embree
{
  ConditionSys::ConditionSys () {
    cond = new ConditionImplementation;
  }

  ConditionSys::~ConditionSys() {
    delete (ConditionImplementation*) cond;
  }

  void ConditionSys::wait(MutexSys& mutex) {
    ((ConditionImplementation*) cond)->wait(mutex);
  }

  void ConditionSys::broadcast() {
    ((ConditionImplementation*) cond)->broadcast();
  }
}
<|endoftext|>


<commit_before>/***************************************************************************
 *  stream/test_push_sort.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2004 Roman Dementiev <dementiev@mpi-sb.mpg.de>
 *
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or copy at
 *  http://www.boost.org/LICENSE_1_0.txt)
 **************************************************************************/

//! \example stream/test_push_sort.cpp
//! This is an example of how to use some basic algorithms from
//! stream package. This example shows how to create
//! \c sorted_runs data structure
//! using \c stream::use_push specialization of \c stream::runs_creator class

#include <limits>
#include <stxxl/stream>

const unsigned long long megabyte = 1024 * 1024;
const unsigned int block_size = 1 * megabyte;

typedef unsigned value_type;

struct Cmp : public std::binary_function<value_type, value_type, bool>
{
    typedef unsigned value_type;
    bool operator () (const value_type & a, const value_type & b) const
    {
        return a < b;
    }
    value_type min_value()
    {
        return (std::numeric_limits<value_type>::min)();
    }
    value_type max_value()
    {
        return (std::numeric_limits<value_type>::max)();
    }
};

int main()
{
#if STXXL_PARALLEL_MULTIWAY_MERGE
    STXXL_MSG("STXXL_PARALLEL_MULTIWAY_MERGE");
#endif
    // special parameter type
    typedef stxxl::stream::use_push<value_type> InputType;
    typedef stxxl::stream::runs_creator<InputType, Cmp, 4096, stxxl::RC> CreateRunsAlg;
    typedef CreateRunsAlg::sorted_runs_type SortedRunsType;

    unsigned size = (30 * 1024 * 128 / (sizeof(value_type) * 2));

    unsigned i = 0;

    Cmp c;
    CreateRunsAlg SortedRuns(c, 1024 * 128);
    value_type oldcrc(0);

    stxxl::random_number32 rnd;
    //stxxl::random_number<> rnd_max;
    unsigned cnt = size;
    while (cnt > 0)
    {
        const value_type tmp = rnd();
        oldcrc += tmp;
        SortedRuns.push(tmp);                   // push into the sorter
        --cnt;
    }

    SortedRunsType Runs = SortedRuns.result();  // get sorted_runs data structure
    assert(stxxl::stream::check_sorted_runs(Runs, Cmp()));

    // merge the runs
    stxxl::stream::runs_merger<SortedRunsType, Cmp> merger(Runs, Cmp(), 1024 * 512 / 10 + 12 * 4096);
    stxxl::vector<value_type, 4, stxxl::lru_pager<8>, block_size, STXXL_DEFAULT_ALLOC_STRATEGY> array;
    STXXL_MSG(size << " " << Runs.elements);
    STXXL_MSG("CRC: " << oldcrc);
    value_type crc(0);
    for (i = 0; i < size; ++i)
    {
        crc += *merger;
        array.push_back(*merger);
        ++merger;
    }
    STXXL_MSG("CRC: " << crc);
    assert(stxxl::is_sorted(array.begin(), array.end(), Cmp()));
    assert(merger.empty());

    return 0;
}
<commit_msg>Make test_push_sort work; refactor.<commit_after>/***************************************************************************
 *  stream/test_push_sort.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2004 Roman Dementiev <dementiev@mpi-sb.mpg.de>
 *  Copyright (C) 2010 Johannes Singler <singler@ira.uka.de>
 *
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or copy at
 *  http://www.boost.org/LICENSE_1_0.txt)
 **************************************************************************/

//! \example stream/test_push_sort.cpp
//! This is an example of how to use some basic algorithms from
//! stream package. This example shows how to create
//! \c sorted_runs data structure
//! using \c stream::use_push specialization of \c stream::runs_creator class

#include <limits>
#include <stxxl/stream>

const unsigned long long megabyte = 1024 * 1024;
const unsigned int block_size = 1 * megabyte;

typedef unsigned value_type;

struct Cmp : public std::binary_function<value_type, value_type, bool>
{
    typedef unsigned value_type;
    bool operator () (const value_type & a, const value_type & b) const
    {
        return a < b;
    }
    value_type min_value()
    {
        return (std::numeric_limits<value_type>::min)();
    }
    value_type max_value()
    {
        return (std::numeric_limits<value_type>::max)();
    }
};

int main()
{
#if STXXL_PARALLEL_MULTIWAY_MERGE
    STXXL_MSG("STXXL_PARALLEL_MULTIWAY_MERGE");
#endif
    // special parameter type
    typedef stxxl::stream::use_push<value_type> InputType;
    typedef stxxl::stream::runs_creator<InputType, Cmp, 4096, stxxl::RC> CreateRunsAlg;
    typedef CreateRunsAlg::sorted_runs_type SortedRunsType;

    unsigned input_size = (50 * megabyte / sizeof(value_type));

    Cmp c;
    CreateRunsAlg SortedRuns(c, 10 * megabyte);
    value_type checksum_before(0);

    stxxl::random_number32 rnd;

    for (unsigned cnt = input_size; cnt > 0; --cnt)
    {
        const value_type element = rnd();
        checksum_before += element;
        SortedRuns.push(element);                   // push into the sorter
    }

    SortedRunsType Runs = SortedRuns.result();  // get sorted_runs data structure
    assert(stxxl::stream::check_sorted_runs(Runs, Cmp()));

    // merge the runs
    stxxl::stream::runs_merger<SortedRunsType, Cmp> merger(Runs, Cmp(), 10 * megabyte);
    stxxl::vector<value_type, 4, stxxl::lru_pager<8>, block_size, STXXL_DEFAULT_ALLOC_STRATEGY> array;
    STXXL_MSG(input_size << " " << Runs.elements);
    STXXL_MSG("checksum before: " << checksum_before);
    value_type checksum_after(0);
    for (unsigned i = 0; i < input_size; ++i)
    {
        checksum_after += *merger;
        array.push_back(*merger);
        ++merger;
    }
    STXXL_MSG("checksum after:  " << checksum_after);
    assert(stxxl::is_sorted(array.begin(), array.end(), Cmp()));
    assert(checksum_before == checksum_after);
    assert(merger.empty());

    return 0;
}
<|endoftext|>


<commit_before>#include <node.h>
#include <v8.h>
#include <vector>
#include "mouse.h"
#include "deadbeef_rand.h"
#include "screen.h"
#include "screengrab.h"
#include "keypress.h"

using namespace v8;

/*
 __  __
|  \/  | ___  _   _ ___  ___
| |\/| |/ _ \| | | / __|/ _ \
| |  | | (_) | |_| \__ \  __/
|_|  |_|\___/ \__,_|___/\___|

 */

Handle<Value> moveMouse(const Arguments& args)
{
  HandleScope scope;
  if (args.Length() < 2)
  {
    ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
    return scope.Close(Undefined());
  }
  size_t x = args[0]->Int32Value();
  size_t y = args[1]->Int32Value();

  MMPoint point;
  point = MMPointMake(x, y);
  moveMouse(point);
  return scope.Close(String::New("1"));
}

Handle<Value> getMousePos(const Arguments& args)
{
  HandleScope scope;

  MMPoint pos = getMousePos();

  //Return object with .x and .y.
  Local<Object> obj = Object::New();
  obj->Set(String::NewSymbol("x"), Number::New(pos.x));
  obj->Set(String::NewSymbol("y"), Number::New(pos.y));
  return scope.Close(obj);
}

Handle<Value> mouseClick(const Arguments& args)
{
  HandleScope scope;

  MMMouseButton button = LEFT_BUTTON;

  clickMouse(button);
  return scope.Close(String::New("1"));
}

/*
 _  __          _                         _
| |/ /___ _   _| |__   ___   __ _ _ __ __| |
| ' // _ \ | | | '_ \ / _ \ / _` | '__/ _` |
| . \  __/ |_| | |_) | (_) | (_| | | | (_| |
|_|\_\___|\__, |_.__/ \___/ \__,_|_|  \__,_|
          |___/
 */

char *get(v8::Local<v8::Value> value, const char *fallback = "")
{
    if (value->IsString())
    {
        v8::String::AsciiValue string(value);
        char *str = (char *) malloc(string.length() + 1);
        strcpy(str, *string);
        return str;
    }
    char *str = (char *) malloc(strlen(fallback) + 1);
    strcpy(str, fallback);
    return str;
}

Handle<Value> keyTap(const Arguments& args)
{
  HandleScope scope;

  MMKeyFlags flags = MOD_NONE;

  char c = get(args[0])[0];

  if (strlen(&c)==1)
  {
    tapKey(c, flags);
  }

  return scope.Close(String::New("1"));
}

Handle<Value> typeString(const Arguments& args)
{
  HandleScope scope;

  char *str = get(args[0]);

  typeString(str);

  return scope.Close(String::New("1"));
}

/*
  _____
 / ____|
| (___   ___ _ __ ___  ___ _ __
 \___ \ / __| '__/ _ \/ _ \ '_ \
 ____) | (__| | |  __/  __/ | | |
|_____/ \___|_|  \___|\___|_| |_|

 */

Handle<Value> captureScreen(const Arguments& args)
{
  HandleScope scope;

  MMRect rect;
  MMBitmapRef bitmap = NULL;
  MMSize displaySize = getMainDisplaySize();

  rect = MMRectMake(0, 0, displaySize.width, displaySize.height);

  bitmap = copyMMBitmapFromDisplayInRect(rect);

  return scope.Close(External::Wrap(bitmap));

  //return scope.Close(String::New("1"));
}

void init(Handle<Object> target)
{
  target->Set(String::NewSymbol("moveMouse"),
      FunctionTemplate::New(moveMouse)->GetFunction());

  target->Set(String::NewSymbol("getMousePos"),
      FunctionTemplate::New(getMousePos)->GetFunction());

  target->Set(String::NewSymbol("mouseClick"),
      FunctionTemplate::New(mouseClick)->GetFunction());

  target->Set(String::NewSymbol("keyTap"),
      FunctionTemplate::New(keyTap)->GetFunction());

  target->Set(String::NewSymbol("typeString"),
      FunctionTemplate::New(typeString)->GetFunction());

  target->Set(String::NewSymbol("captureScreen"),
      FunctionTemplate::New(captureScreen)->GetFunction());
}

NODE_MODULE(robotjs, init)
<commit_msg>Moved screen related functions to it's own branch.<commit_after>#include <node.h>
#include <v8.h>
#include <vector>
#include "mouse.h"
#include "deadbeef_rand.h"
#include "keypress.h"

using namespace v8;

/*
 __  __
|  \/  | ___  _   _ ___  ___
| |\/| |/ _ \| | | / __|/ _ \
| |  | | (_) | |_| \__ \  __/
|_|  |_|\___/ \__,_|___/\___|

 */

Handle<Value> moveMouse(const Arguments& args)
{
  HandleScope scope;
  if (args.Length() < 2)
  {
    ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
    return scope.Close(Undefined());
  }
  size_t x = args[0]->Int32Value();
  size_t y = args[1]->Int32Value();

  MMPoint point;
  point = MMPointMake(x, y);
  moveMouse(point);
  return scope.Close(String::New("1"));
}

Handle<Value> getMousePos(const Arguments& args)
{
  HandleScope scope;

  MMPoint pos = getMousePos();

  //Return object with .x and .y.
  Local<Object> obj = Object::New();
  obj->Set(String::NewSymbol("x"), Number::New(pos.x));
  obj->Set(String::NewSymbol("y"), Number::New(pos.y));
  return scope.Close(obj);
}

Handle<Value> mouseClick(const Arguments& args)
{
  HandleScope scope;

  MMMouseButton button = LEFT_BUTTON;

  clickMouse(button);
  return scope.Close(String::New("1"));
}

/*
 _  __          _                         _
| |/ /___ _   _| |__   ___   __ _ _ __ __| |
| ' // _ \ | | | '_ \ / _ \ / _` | '__/ _` |
| . \  __/ |_| | |_) | (_) | (_| | | | (_| |
|_|\_\___|\__, |_.__/ \___/ \__,_|_|  \__,_|
          |___/
 */

char *get(v8::Local<v8::Value> value, const char *fallback = "")
{
    if (value->IsString())
    {
        v8::String::AsciiValue string(value);
        char *str = (char *) malloc(string.length() + 1);
        strcpy(str, *string);
        return str;
    }
    char *str = (char *) malloc(strlen(fallback) + 1);
    strcpy(str, fallback);
    return str;
}

Handle<Value> keyTap(const Arguments& args)
{
  HandleScope scope;

  MMKeyFlags flags = MOD_NONE;

  char c = get(args[0])[0];

  if (strlen(&c)==1)
  {
    tapKey(c, flags);
  }

  return scope.Close(String::New("1"));
}

Handle<Value> typeString(const Arguments& args)
{
  HandleScope scope;

  char *str = get(args[0]);

  typeString(str);

  return scope.Close(String::New("1"));
}

void init(Handle<Object> target)
{
  target->Set(String::NewSymbol("moveMouse"),
      FunctionTemplate::New(moveMouse)->GetFunction());

  target->Set(String::NewSymbol("getMousePos"),
      FunctionTemplate::New(getMousePos)->GetFunction());

  target->Set(String::NewSymbol("mouseClick"),
      FunctionTemplate::New(mouseClick)->GetFunction());

  target->Set(String::NewSymbol("keyTap"),
      FunctionTemplate::New(keyTap)->GetFunction());

  target->Set(String::NewSymbol("typeString"),
      FunctionTemplate::New(typeString)->GetFunction());
}

NODE_MODULE(robotjs, init)
<|endoftext|>


<commit_before>#include <memory>
#include "../externals/json/json.h"
#include "math.h"
#include "window.h"
#include "gameobject.h"
#include "camera.h"

#include "debugger.h"

Camera::Camera() : mActivePan(-1), mScene("def"){
	mBox.Set(0, 0, Window::Box().W(), Window::Box().H());
	mSceneBox.Set(0, 0, 0, 0);
}
Camera::~Camera(){
	mFocus.reset();
}
void Camera::SetFocus(std::shared_ptr<GameObject> obj){
	mFocus = obj;
}
void Camera::Update(){
	//TODO: Update camera offsets to apply window centering on resize? The centering offset doesn't
	//seem to work. I tried also applying it to the camera but that didn't seem to help.. Hmm

	//If a pan is set, do that instead of following focus
	if (mActivePan != -1)
		return;

	//Try to lock the focus weak pointer, ie. check to see if
	//the camera should be following something
	auto s = mFocus.lock();
	//If there's no focus don't have the camera try to follow one
	if (!s){
		return;
	}

	Rectf focBox = s->Box();
	//Adjust camera position
	float x, y;
	x = (focBox.X() + focBox.w / 2) - mBox.w / 2;
	y = (focBox.Y() + focBox.h / 2) - mBox.h / 2;

	//Clamp the camera values to keep them in range
	mBox.Set(Math::Clamp(x, 0, mSceneBox.w - mBox.w),
		Math::Clamp(y, 0, mSceneBox.h - mBox.h));
}
bool Camera::InCamera(Rectf box) const{
	return Math::CheckCollision(mBox, box);
}
void Camera::Move(Vector2f v){
	mBox += v;
}
void Camera::Move(float deltaT){
	if (mActivePan != -1){
		//If the distance between the camera and destination is less than the distance moved in a frame,
		//set the camera to the destination
		if (Math::Distance(mBox.pos, mPans.at(mActivePan).destination) <= mPans.at(mActivePan).speed * deltaT){
			mBox.Set(mPans.at(mActivePan).destination);
			mScene = mPans.at(mActivePan).name;
			mActivePan = -1;
			return;
		}
		//If we haven't arrived, continue moving
		mBox.pos += Math::Normalize(mPans.at(mActivePan).destination - mBox.pos) * mPans.at(mActivePan).speed * deltaT;
	}
}
void Camera::Pan(std::string name){
	//Try to find the animation with the name
	for (int i = 0; i < mPans.size(); ++i){
		if (mPans.at(i).name == name){
			mActivePan = i;
			mScene = "busy";
			return;
		}
	}
	//If lookup failed set active to -1, ie none
	mActivePan = -1;
	mScene = "";
}
std::string Camera::Scene(){
	return mScene;
}

void Camera::SetBox(Rectf box){
	//The camera box can't be bigger than the scene box
	if (mSceneBox.w != 0 && mSceneBox.h != 0){
		mBox.Set(mBox.X(), mBox.Y(),
			Math::Clamp(box.w, 0, mSceneBox.w),
			Math::Clamp(box.h, 0, mSceneBox.h));
	}
	//If no scene box is set yet, just allow the change, as we check again
	//when setting a scene box
	else
		mBox = box;
}
void Camera::SetSceneBox(Rectf box){
	mSceneBox = box;
	//Make sure the camera is smaller than the scene box
	mBox.Set(mBox.X(), mBox.Y(),
		Math::Clamp(mBox.w, 0, mSceneBox.w),
		Math::Clamp(mBox.h, 0, mSceneBox.h));
}
Rectf Camera::SceneBox(){
	return mSceneBox;
}
Rectf Camera::Box() const{
	return mBox;
}
Vector2f Camera::Offset() const{
	return Vector2f(mBox.X() - Centering().x, mBox.Y() - Centering().y);
}
Vector2f Camera::Centering() const{
	Recti winBox = Window::Box();
	return Vector2f((winBox.w / 2 - mSceneBox.w / 2),
		(winBox.h / 2 - mSceneBox.h / 2));
}
Json::Value Camera::Save(){
	Json::Value val;
	val["mBox"]		= mBox.Save();
	val["sceneBox"] = mSceneBox.Save();
	//save the pan instructions
	for (int i = 0; i < mPans.size(); ++i){
		val["pans"][i]["name"]  = mPans.at(i).name;
		val["pans"][i]["speed"] = mPans.at(i).speed;
		val["pans"][i]["dest"]  = mPans.at(i).destination.Save();
	}

	return val;
}
void Camera::Load(Json::Value val){
	mSceneBox.Load(val["sceneBox"]);
	//We need to make sure the camera box is a valid size
	Rectf box;
	box.Load(val["mBox"]);
	SetBox(box);

	//Load pan instructions
	for (int i = 0; i < val["pans"].size(); ++i){
		CameraPan pan;
		pan.name = val["pans"][i]["name"].asString();
		pan.speed = val["pans"][i]["speed"].asInt();
		pan.destination.Load(val["pans"][i]["dest"]);

		mPans.push_back(pan);
	}

}<commit_msg>If cam pan lookup failed it shouldn't set name to ""<commit_after>#include <memory>
#include "../externals/json/json.h"
#include "math.h"
#include "window.h"
#include "gameobject.h"
#include "camera.h"

#include "debugger.h"

Camera::Camera() : mActivePan(-1), mScene("def"){
	mBox.Set(0, 0, Window::Box().W(), Window::Box().H());
	mSceneBox.Set(0, 0, 0, 0);
}
Camera::~Camera(){
	mFocus.reset();
}
void Camera::SetFocus(std::shared_ptr<GameObject> obj){
	mFocus = obj;
}
void Camera::Update(){
	//TODO: Update camera offsets to apply window centering on resize? The centering offset doesn't
	//seem to work. I tried also applying it to the camera but that didn't seem to help.. Hmm

	//If a pan is set, do that instead of following focus
	if (mActivePan != -1)
		return;

	//Try to lock the focus weak pointer, ie. check to see if
	//the camera should be following something
	auto s = mFocus.lock();
	//If there's no focus don't have the camera try to follow one
	if (!s){
		return;
	}

	Rectf focBox = s->Box();
	//Adjust camera position
	float x, y;
	x = (focBox.X() + focBox.w / 2) - mBox.w / 2;
	y = (focBox.Y() + focBox.h / 2) - mBox.h / 2;

	//Clamp the camera values to keep them in range
	mBox.Set(Math::Clamp(x, 0, mSceneBox.w - mBox.w),
		Math::Clamp(y, 0, mSceneBox.h - mBox.h));
}
bool Camera::InCamera(Rectf box) const{
	return Math::CheckCollision(mBox, box);
}
void Camera::Move(Vector2f v){
	mBox += v;
}
void Camera::Move(float deltaT){
	if (mActivePan != -1){
		//If the distance between the camera and destination is less than the distance moved in a frame,
		//set the camera to the destination
		if (Math::Distance(mBox.pos, mPans.at(mActivePan).destination) <= mPans.at(mActivePan).speed * deltaT){
			mBox.Set(mPans.at(mActivePan).destination);
			mScene = mPans.at(mActivePan).name;
			mActivePan = -1;
			return;
		}
		//If we haven't arrived, continue moving
		mBox.pos += Math::Normalize(mPans.at(mActivePan).destination - mBox.pos) * mPans.at(mActivePan).speed * deltaT;
	}
}
void Camera::Pan(std::string name){
	//Try to find the animation with the name
	for (int i = 0; i < mPans.size(); ++i){
		if (mPans.at(i).name == name){
			mActivePan = i;
			mScene = "busy";
			return;
		}
	}
	//If lookup failed set active to -1, ie none
	mActivePan = -1;
}
std::string Camera::Scene(){
	return mScene;
}

void Camera::SetBox(Rectf box){
	//The camera box can't be bigger than the scene box
	if (mSceneBox.w != 0 && mSceneBox.h != 0){
		mBox.Set(mBox.X(), mBox.Y(),
			Math::Clamp(box.w, 0, mSceneBox.w),
			Math::Clamp(box.h, 0, mSceneBox.h));
	}
	//If no scene box is set yet, just allow the change, as we check again
	//when setting a scene box
	else
		mBox = box;
}
void Camera::SetSceneBox(Rectf box){
	mSceneBox = box;
	//Make sure the camera is smaller than the scene box
	mBox.Set(mBox.X(), mBox.Y(),
		Math::Clamp(mBox.w, 0, mSceneBox.w),
		Math::Clamp(mBox.h, 0, mSceneBox.h));
}
Rectf Camera::SceneBox(){
	return mSceneBox;
}
Rectf Camera::Box() const{
	return mBox;
}
Vector2f Camera::Offset() const{
	return Vector2f(mBox.X() - Centering().x, mBox.Y() - Centering().y);
}
Vector2f Camera::Centering() const{
	Recti winBox = Window::Box();
	return Vector2f((winBox.w / 2 - mSceneBox.w / 2),
		(winBox.h / 2 - mSceneBox.h / 2));
}
Json::Value Camera::Save(){
	Json::Value val;
	val["mBox"]		= mBox.Save();
	val["sceneBox"] = mSceneBox.Save();
	//save the pan instructions
	for (int i = 0; i < mPans.size(); ++i){
		val["pans"][i]["name"]  = mPans.at(i).name;
		val["pans"][i]["speed"] = mPans.at(i).speed;
		val["pans"][i]["dest"]  = mPans.at(i).destination.Save();
	}

	return val;
}
void Camera::Load(Json::Value val){
	mSceneBox.Load(val["sceneBox"]);
	//We need to make sure the camera box is a valid size
	Rectf box;
	box.Load(val["mBox"]);
	SetBox(box);

	//Load pan instructions
	for (int i = 0; i < val["pans"].size(); ++i){
		CameraPan pan;
		pan.name = val["pans"][i]["name"].asString();
		pan.speed = val["pans"][i]["speed"].asInt();
		pan.destination.Load(val["pans"][i]["dest"]);

		mPans.push_back(pan);
	}

}<|endoftext|>