<commit_before>#include "Parse.hpp"

#include <iostream>
#include <stdexcept>
#include <cctype>

namespace parse
{

namespace tree
{

void Abstraction::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

void Application::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

void Variable::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

} // tree

namespace
{

void skipWhitespace(std::istream& input)
{
    char c = input.peek();

    while (std::isspace(c))
    {
        input.get();
        c = input.peek();
    }
}

std::string parseIdentifier(std::istream& input)
{
    std::string ident;

    skipWhitespace(input);

    while (std::isalnum(input.peek()))
    {
        ident += input.get();
    }

    return ident;
}

std::unique_ptr<tree::Abstraction> parseAbstraction(std::istream& input)
{
    std::unique_ptr<tree::Abstraction> node(new tree::Abstraction);

    if (input.peek() != '^')
    {
        throw std::runtime_error("Parse error");
    }

    input.get();

    std::string argument;

    while ((argument = parseIdentifier(input)).size() > 0)
    {
        node->arguments.push_back(std::move(argument));
    }

    if (node->arguments.size() == 0)
    {
        throw std::runtime_error("Parse error");
    }

    skipWhitespace(input);

    if (input.peek() != '.')
    {
        throw std::runtime_error("Parse error");
    }

    input.get();

    node->body = parseTerm(input);

    return node;
}

} // anonymous

std::unique_ptr<tree::Term> parseTerm(std::istream& input)
{
    std::unique_ptr<tree::Term> node;

    skipWhitespace(input);

    if (input.peek() == '^')
    {
        node = parseAbstraction(input);
    }
    else if (input.peek() == '(')
    {
        node = parseTerm(input);

        skipWhitespace(input);

        if (input.peek() != ')')
        {
            throw std::runtime_error("Parse error");
        }

        input.get();
    }
    else
    {
        std::string name = parseIdentifier(input);

        if (name.size() == 0)
        {
            throw std::runtime_error("Parse error");
        }

        std::unique_ptr<tree::Variable> var(new tree::Variable);
        var->name = std::move(name);

        node = std::move(var);
    }

    skipWhitespace(input);

    if (input.peek() != EOF)
    {
        std::unique_ptr<tree::Term> tempNode = std::move(node);
        std::unique_ptr<tree::Application> appNode = std::unique_ptr<tree::Application>(new tree::Application);
        appNode->terms.push_back(std::move(tempNode));

        do
        {
            appNode->terms.push_back(parseTerm(input));
        } while (input.peek () != EOF);

        node = std::move(appNode);
    }

    return node;
}

} // parse
<commit_msg>Fix associativity of application<commit_after>#include "Parse.hpp"

#include <iostream>
#include <stdexcept>
#include <cctype>

namespace parse
{

namespace tree
{

void Abstraction::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

void Application::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

void Variable::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

} // tree

namespace
{

void skipWhitespace(std::istream& input)
{
    char c = input.peek();

    while (std::isspace(c))
    {
        input.get();
        c = input.peek();
    }
}

std::string parseIdentifier(std::istream& input)
{
    std::string ident;

    skipWhitespace(input);

    while (std::isalnum(input.peek()))
    {
        ident += input.get();
    }

    return ident;
}

std::unique_ptr<tree::Abstraction> parseAbstraction(std::istream& input)
{
    std::unique_ptr<tree::Abstraction> node(new tree::Abstraction);

    if (input.peek() != '^')
    {
        throw std::runtime_error("Parse error");
    }

    input.get();

    std::string argument;

    while ((argument = parseIdentifier(input)).size() > 0)
    {
        node->arguments.push_back(std::move(argument));
    }

    if (node->arguments.size() == 0)
    {
        throw std::runtime_error("Parse error");
    }

    skipWhitespace(input);

    if (input.peek() != '.')
    {
        throw std::runtime_error("Parse error");
    }

    input.get();

    node->body = parseTerm(input);

    return node;
}

std::unique_ptr<tree::Term> parseSubterm(std::istream& input)
{
    std::unique_ptr<tree::Term> node;

    skipWhitespace(input);

    if (input.peek() == '^')
    {
        node = parseAbstraction(input);
    }
    else if (input.peek() == '(')
    {
        input.get();

        node = parseTerm(input);

        skipWhitespace(input);

        if (input.peek() != ')')
        {
            throw std::runtime_error("Parse error");
        }

        input.get();
    }
    else
    {
        std::string name = parseIdentifier(input);

        if (name.size() == 0)
        {
            throw std::runtime_error("Parse error");
        }

        std::unique_ptr<tree::Variable> var(new tree::Variable);
        var->name = std::move(name);

        node = std::move(var);
    }

    return node;
}

} // anonymous

std::unique_ptr<tree::Term> parseTerm(std::istream& input)
{
    std::unique_ptr<tree::Term> node = parseSubterm(input);

    if (input.peek() != EOF)
    {
        std::unique_ptr<tree::Term> tempNode = std::move(node);
        std::unique_ptr<tree::Application> appNode = std::unique_ptr<tree::Application>(new tree::Application);
        appNode->terms.push_back(std::move(tempNode));

        do
        {
            appNode->terms.push_back(parseSubterm(input));
        } while (input.peek () != EOF);

        node = std::move(appNode);
    }

    return node;
}

} // parse
<|endoftext|>


<commit_before>#include "TextDisplayer.h"
#include "ItemCopy.h"
#include "Potential.h"
#include "ClientInfo.h"
#include "RepulsiveCenter.h"
#include "TextDisplayerParameters.h"
#include "PngImage.h"

#include <limits>

namespace map_server
{
	std::mutex TextDisplayer::_mutex;
	std::map<std::string, ClientInfo *> TextDisplayer::_clientMap;

	void TextDisplayer::clearClientMap(void)
	{
		_mutex.lock();

		std::map<std::string, ClientInfo *>::iterator it = _clientMap.begin();
		for (; it != _clientMap.end(); ++it)
		{
			delete (*it).second;
			(*it).second = 0;
		}

		_mutex.unlock();
	}

    TextDisplayer::TextDisplayer(const TextDisplayerParameters *parameters, const std::string& socketId, double width, double height, bool createPotentialImage) :
		_parameters(parameters), _width(width), _height(height), _createPotentialImage(createPotentialImage),
        _maxPotential(new Potential(std::numeric_limits<double>::max(), std::numeric_limits<double>::max())),
        _minPotential(new Potential(-std::numeric_limits<double>::max(), -std::numeric_limits<double>::max())),
		_softThreshold(new Potential(parameters->getSoftThresholdExcludingTerm(), parameters->getSoftThresholdNotExcludingTerm())),
		_hardThreshold(new Potential(parameters->getHardThresholdExcludingTerm(), parameters->getHardThresholdNotExcludingTerm()))
    {
		_mutex.lock();

		std::map<std::string, ClientInfo *>::iterator it = _clientMap.find(socketId);
		if (it == _clientMap.end())
		{
			it = _clientMap.insert(std::pair<std::string, ClientInfo *>(socketId, new ClientInfo())).first;
		}

		_clientInfo = (*it).second;

		_mutex.unlock();
    }

	TextDisplayer::~TextDisplayer()
	{
		int i, n = _itemVector.size();
		for (i = 0; i < n; ++i) delete _itemVector[i];

		delete _maxPotential;
		delete _minPotential;
		delete _softThreshold;
		delete _hardThreshold;
	}

    void TextDisplayer::start(void)
    {
		int visibleTextCount = 0;

		int i, n = _itemVector.size();
		for (i = 0; i < n && visibleTextCount < _parameters->getMaxVisibleTextCount(); ++i)
		{
			ItemCopy *item = _itemVector[i];
			TextInfo *textInfo = 0;
			if (item->getTextInfo1() != 0) textInfo = item->getTextInfo1();
			else if (item->getTextInfo2() != 0) textInfo = item->getTextInfo2();

			if (textInfo != 0)
			{

			}
		}

        if (_createPotentialImage)
        {
            PngImage image1(_width, _height);
            PngImage image2(_width, _height);
            PngImage image3(_width, _height);
            int j;
            for (i = 0; i < _width; ++i)
            {
                for (j = 0; j < _height; ++j)
                {
                    Potential p = getPotential(i, j, 0);

                    double value = 20.0 * p.getExcludingTerm();
                    if (value < 0) value = 0.0;
                    else if (value > 255.0) value = 255.0;
                    image1.setPixel(i, j, value, value, value);

                    value = 20.0 * p.getNotExcludingTerm();
                    if (value < 0) value = 0.0;
                    else if (value > 255.0) value = 255.0;
                    image2.setPixel(i, j, value, value, value);

                    value = 20.0 * p.getExcludingTerm() + 20.0 * p.getNotExcludingTerm();
                    if (value < 0) value = 0.0;
                    else if (value > 255.0) value = 255.0;
                    image3.setPixel(i, j, value, value, value);
                }
            }

            image1.save("potential1.png");
            image2.save("potential2.png");
            image3.save("potential3.png");
        }
    }

    Potential TextDisplayer::getPotential(double x, double y, ItemCopy *selfItem)
    {
        Potential potential;

        const double u0 = _parameters->getEdgeRefPotential();
        const double epsilon = _parameters->getEdgeRangeRatio();
        double a;

        a = x / (epsilon * _width) - 1;
        if (a < 0) potential.addExcludingTerm(u0 * a * a);

        a = y / (epsilon * _height) - 1;
        if (a < 0) potential.addExcludingTerm(u0 * a * a);

        a = (x - _width) / (epsilon * _width) + 1;
        if (a > 0) potential.addExcludingTerm(u0 * a * a);

        a = (y - _height) / (epsilon * _height) + 1;
        if (a > 0) potential.addExcludingTerm(u0 * a * a);

        int i, n = _itemVector.size();
        for (i = 0; i < n; ++i)
        {
            ItemCopy *item = _itemVector[i];
            if (selfItem == 0 || item != selfItem)
            {
                Potential elementaryPotential = std::move(getElementaryPotential(item, x, y));
                potential += elementaryPotential;
                if (_clientInfo->isStopRequested() || !potential.isAcceptable(*_softThreshold)) return std::move(potential);

                // Todo: If a text is displayed for this item, add the potential generated by this text
            }
        }

        return std::move(potential);
    }

    Potential TextDisplayer::getElementaryPotential(ItemCopy *item, double x, double y)
    {
        Potential potential;

        int i, n = item->getRepulsiveCenterVector().size();
        for (i = 0; i < n; ++i)
        {
            const RepulsiveCenter *center = item->getRepulsiveCenterVector()[i];
            double dx = center->getX() - x;
            double dy = center->getY() - y;

            double R1 = center->getV11() * dx + center->getV12() * dy;
            double R2 = center->getV21() * dx + center->getV22() * dy;
            int R = static_cast<int>(R1 * R1 + R2 * R2);
            if (R < _parameters->getPotentialTableSize())
            {
                if (center->getExcluding()) potential.addExcludingTerm(center->getU0() * _parameters->getExcludingPotential(R));
                else potential.addNotExcludingTerm(center->getU0() * _parameters->getNotExcludingPotential(R));

                if (!potential.isAcceptable(*_softThreshold)) break;
            }
        }

        return std::move(potential);
    }
}
<commit_msg>C++ map server: minor change in potential image<commit_after>#include "TextDisplayer.h"
#include "ItemCopy.h"
#include "Potential.h"
#include "ClientInfo.h"
#include "RepulsiveCenter.h"
#include "TextDisplayerParameters.h"
#include "PngImage.h"

#include <limits>

namespace map_server
{
	std::mutex TextDisplayer::_mutex;
	std::map<std::string, ClientInfo *> TextDisplayer::_clientMap;

	void TextDisplayer::clearClientMap(void)
	{
		_mutex.lock();

		std::map<std::string, ClientInfo *>::iterator it = _clientMap.begin();
		for (; it != _clientMap.end(); ++it)
		{
			delete (*it).second;
			(*it).second = 0;
		}

		_mutex.unlock();
	}

    TextDisplayer::TextDisplayer(const TextDisplayerParameters *parameters, const std::string& socketId, double width, double height, bool createPotentialImage) :
		_parameters(parameters), _width(width), _height(height), _createPotentialImage(createPotentialImage),
        _maxPotential(new Potential(std::numeric_limits<double>::max(), std::numeric_limits<double>::max())),
        _minPotential(new Potential(-std::numeric_limits<double>::max(), -std::numeric_limits<double>::max())),
		_softThreshold(new Potential(parameters->getSoftThresholdExcludingTerm(), parameters->getSoftThresholdNotExcludingTerm())),
		_hardThreshold(new Potential(parameters->getHardThresholdExcludingTerm(), parameters->getHardThresholdNotExcludingTerm()))
    {
		_mutex.lock();

		std::map<std::string, ClientInfo *>::iterator it = _clientMap.find(socketId);
		if (it == _clientMap.end())
		{
			it = _clientMap.insert(std::pair<std::string, ClientInfo *>(socketId, new ClientInfo())).first;
		}

		_clientInfo = (*it).second;

		_mutex.unlock();
    }

	TextDisplayer::~TextDisplayer()
	{
		int i, n = _itemVector.size();
		for (i = 0; i < n; ++i) delete _itemVector[i];

		delete _maxPotential;
		delete _minPotential;
		delete _softThreshold;
		delete _hardThreshold;
	}

    void TextDisplayer::start(void)
    {
		int visibleTextCount = 0;

		int i, n = _itemVector.size();
		for (i = 0; i < n && visibleTextCount < _parameters->getMaxVisibleTextCount(); ++i)
		{
			ItemCopy *item = _itemVector[i];
			TextInfo *textInfo = 0;
			if (item->getTextInfo1() != 0) textInfo = item->getTextInfo1();
			else if (item->getTextInfo2() != 0) textInfo = item->getTextInfo2();

			if (textInfo != 0)
			{

			}
		}

        if (_createPotentialImage)
        {
            PngImage image1(_width, _height);
            PngImage image2(_width, _height);
            PngImage image3(_width, _height);
            int j;
            for (i = 0; i < _width; ++i)
            {
                for (j = 0; j < _height; ++j)
                {
                    Potential p = getPotential(i, j, 0);

                    double c = 50.0;

                    double value = c * p.getExcludingTerm();
                    if (value < 0) value = 0.0;
                    else if (value > 255.0) value = 255.0;
                    value = 255.0 - value;
                    image1.setPixel(i, j, value, value, value);

                    value = c * p.getNotExcludingTerm();
                    if (value < 0) value = 0.0;
                    else if (value > 255.0) value = 255.0;
                    value = 255.0 - value;
                    image2.setPixel(i, j, value, value, value);

                    value = c * p.getExcludingTerm() + c * p.getNotExcludingTerm();
                    if (value < 0) value = 0.0;
                    else if (value > 255.0) value = 255.0;
                    value = 255.0 - value;
                    image3.setPixel(i, j, value, value, value);
                }
            }

            image1.save("potential1.png");
            image2.save("potential2.png");
            image3.save("potential3.png");
        }
    }

    Potential TextDisplayer::getPotential(double x, double y, ItemCopy *selfItem)
    {
        Potential potential;

        const double u0 = _parameters->getEdgeRefPotential();
        const double epsilon = _parameters->getEdgeRangeRatio();
        double a;

        a = x / (epsilon * _width) - 1;
        if (a < 0) potential.addExcludingTerm(u0 * a * a);

        a = y / (epsilon * _height) - 1;
        if (a < 0) potential.addExcludingTerm(u0 * a * a);

        a = (x - _width) / (epsilon * _width) + 1;
        if (a > 0) potential.addExcludingTerm(u0 * a * a);

        a = (y - _height) / (epsilon * _height) + 1;
        if (a > 0) potential.addExcludingTerm(u0 * a * a);

        int i, n = _itemVector.size();
        for (i = 0; i < n; ++i)
        {
            ItemCopy *item = _itemVector[i];
            if (selfItem == 0 || item != selfItem)
            {
                Potential elementaryPotential = std::move(getElementaryPotential(item, x, y));
                potential += elementaryPotential;
                if (_clientInfo->isStopRequested() || !potential.isAcceptable(*_softThreshold)) return std::move(potential);

                // Todo: If a text is displayed for this item, add the potential generated by this text
            }
        }

        return std::move(potential);
    }

    Potential TextDisplayer::getElementaryPotential(ItemCopy *item, double x, double y)
    {
        Potential potential;

        int i, n = item->getRepulsiveCenterVector().size();
        for (i = 0; i < n; ++i)
        {
            const RepulsiveCenter *center = item->getRepulsiveCenterVector()[i];
            double dx = center->getX() - x;
            double dy = center->getY() - y;

            double R1 = center->getV11() * dx + center->getV12() * dy;
            double R2 = center->getV21() * dx + center->getV22() * dy;
            int R = static_cast<int>(R1 * R1 + R2 * R2);
            if (R < _parameters->getPotentialTableSize())
            {
                if (center->getExcluding()) potential.addExcludingTerm(center->getU0() * _parameters->getExcludingPotential(R));
                else potential.addNotExcludingTerm(center->getU0() * _parameters->getNotExcludingPotential(R));

                if (!potential.isAcceptable(*_softThreshold)) break;
            }
        }

        return std::move(potential);
    }
}
<|endoftext|>


<commit_before>/**
 * @file hud_fox.cpp
 * @brief Purpose: Contains methods to game class' management.
 *
 * MIT License
 * Copyright (c) 2017 MindScape
 *
 * https://github.com/TecProg2017-2/mindscape/blob/master/LICENSE.md
 */
#include "../include/hud_fox.hpp"

using namespace mindscape;

/**
 * @brief Class Contructor.
 *
 * Sets Hud Fox's firsts informations (attributes' values).
 * (Hud Fox: Fox's health bar).
 *
 * @param name Hud Fox's name(name of the object).
 * @param position Hud Fox's coordinates in the game's map.
 * @param priority Hud Fox's priority in game's execution.
 * @return void.
 */
HudFox::HudFox(
    std::string name,
    std::pair<int, int> position,
    int priority)
    :engine::GameObject(
        name,
        position,
        priority,
        {
            //No engine Keyboard Event needed.
        }
    ) {
        initialize_animations();
        initialize_audio_effects();
};

/**
 * @brief Initiates Hud Fox's music.
 *
 * Sets sound effect of heart.
 * @return void.
 */
void HudFox::initialize_audio_effects() {
    engine::Audio * take_this_hp = new engine::Audio(
        "heart", "../assets/audios/effects_songs/mindscape_heart.wav",
        engine::Audio::CHUNK);

    take_this_hp->set_duration(1);

    add_component(take_this_hp);
}

/**
 * @brief Notifies Hud Fox of Fox's state.
 *
 * Verifies Fox's state and sets stars' animation depending of the quantity of
 *  stars collected.
 *
 * @param game_object Object for observe game's situation,
 * in this case, the Fox.
 * @return void.
 */
void HudFox::notify(engine::Observable* game_object) {
    Fox* fox = dynamic_cast<Fox *>(game_object);

    if(fox) {

        bool give_hp = fox->get_animation_hud_fading();
        int count = fox->get_star_count();
        engine::Animation* actual = get_actual_animation();

        if(actual == animations["three_star_fading"]) {

            if(actual->is_finished) {
                give_hp = false;
                fox->set_star_count(0);
                set_actual_animation(animations["zero_star"]);
            }
        }

        else {

            if(count == 0) {

                if(!(get_actual_animation() == animations["zero_star"])) {
                    set_actual_animation(animations["zero_star"]);
                }
            }

            else if(count == 1) {

                if(!(get_actual_animation() == animations["one_star"])){
                    set_actual_animation(animations["one_star"]);
                }
            }

            else if(count == 2) {

                if(!(get_actual_animation() == animations["two_star"])) {
                    set_actual_animation(animations["two_star"]);
                }
            }

            else if(count == 3 && !give_hp) {

                if(!(get_actual_animation() == animations["three_star"])) {
                    set_actual_animation(animations["three_star"]);
                }
            }

            else if(count == 3 && give_hp) {
                fox->set_animation_hud_fading(false);
                set_actual_animation(animations["three_star_fading"]);
                play_song("heart");
            }
        }
    }
}

/**
 * @brief Initiates Hud Fox's animation.
 *
 * Initiates all Hud Fox's sprites(images).
 *
 * @return void.
 */
void HudFox::initialize_animations() {
    engine::Animation* fox_zero_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_0.png",
        1,1,0.9, "RIGHT"
    );

    engine::Animation* fox_one_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_1.png",
        1,1,0.9, "RIGHT"
    );

    engine::Animation* fox_two_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_2.png",
        1,1,0.9, "RIGHT"
    );

    engine::Animation* fox_three_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_3.png",
        1,1,0.9, "RIGHT"
    );

    engine::Animation* fox_three_star_fading = create_animation(
        "../assets/images/sprites/hud/hud_fox_3_animation.png",
        1,4,1.0, "RIGHT"
    );

    fox_three_star_fading->in_loop = false;

    add_animation("zero_star", fox_zero_star);
    add_animation("one_star", fox_one_star);
    add_animation("two_star", fox_two_star);
    add_animation("three_star", fox_three_star);
    add_animation("three_star_fading", fox_three_star_fading);

    fox_zero_star->activate();
    set_actual_animation(fox_zero_star);
}

/**
 * @brief Creates Hud Fox's animation.
 *
 * Creates all Hud Fox's animation based on Hud Fox's sprites.
 *
 * @param image_path Path of the Hud Fox's sprite.
 * @param sprite_lines Line of the Hud Fox's sprite.
 * @warning Limitations of sprite_lines and sprite_columns are
 * 1 to the quantity of lines/columns in the image.
 * @param sprite_columns Column of the Fox's sprite needed.
 * @param duration Duration of the Hud Fox's image to show up.
 * @param direction Direction of the Hud Fox's image.
 * @return engine::Animation* The animation constructed.
 */
engine::Animation* HudFox::create_animation(
    std::string path,
    int sprite_lines,
    int sprite_columns,
    double duration,
    std::string direction) {

    engine::Game& game = engine::Game::get_instance();
    engine::Animation* animation = new engine::Animation(
        game.get_renderer(),
        path,
        // is_active
        false,
        std::make_pair(0, 0),
        // priority
        1,
        sprite_lines,
        sprite_columns,
        duration,
        // in_loop
        true,
        direction
    );

    animation->set_values(
        std::make_pair(170, 78),
        std::make_pair(170, 78),
        std::make_pair(0, 0)
    );

    return animation;
}
<commit_msg>[INITIALIZATION] Applies initialization in Hud_Fox.cpp variables<commit_after>/**
 * @file hud_fox.cpp
 * @brief Purpose: Contains methods to game class' management.
 *
 * MIT License
 * Copyright (c) 2017 MindScape
 *
 * https://github.com/TecProg2017-2/mindscape/blob/master/LICENSE.md
 */
#include "../include/hud_fox.hpp"

using namespace mindscape;

/**
 * @brief Class Contructor.
 *
 * Sets Hud Fox's firsts informations (attributes' values).
 * (Hud Fox: Fox's health bar).
 *
 * @param name Hud Fox's name(name of the object).
 * @param position Hud Fox's coordinates in the game's map.
 * @param priority Hud Fox's priority in game's execution.
 * @return void.
 */
HudFox::HudFox(
    std::string name,
    std::pair<int, int> position,
    int priority)
    :engine::GameObject(
        name,
        position,
        priority,
        {
            //No engine Keyboard Event needed.
        }
    ) {
        initialize_animations();
        initialize_audio_effects();
};

/**
 * @brief Initiates Hud Fox's sound effect.
 *
 * Sets sound effect of heart.
 * @return void.
 */
void HudFox::initialize_audio_effects() {
    engine::Audio * take_this_hp = nullptr;
    take_this_hp = new engine::Audio(
        "heart", "../assets/audios/effects_songs/mindscape_heart.wav",
        engine::Audio::CHUNK);

    take_this_hp->set_duration(1);

    add_component(take_this_hp);
}

/**
 * @brief Notifies Hud Fox of Fox's state.
 *
 * Verifies Fox's state and sets stars' animation depending of the quantity of
 *  stars collected.
 *
 * @param game_object Object for observe game's situation,
 * in this case, the Fox.
 * @return void.
 */
void HudFox::notify(engine::Observable* game_object) {
    Fox* fox = nullptr;
    fox = dynamic_cast<Fox *>(game_object);

    if(fox) {

        bool give_hp = false;
        give_hp = fox->get_animation_hud_fading();

        engine::Animation* actual = NULL;
        actual = get_actual_animation();

        if(actual == animations["three_star_fading"]) {

            if(actual->is_finished) {
                give_hp = false;
                fox->set_star_count(0);
                set_actual_animation(animations["zero_star"]);
            }
        }

        else {

            int count = 0;
            count = fox->get_star_count();

            if(count == 0) {

                if(!(get_actual_animation() == animations["zero_star"])) {
                    set_actual_animation(animations["zero_star"]);
                }
            }

            else if(count == 1) {

                if(!(get_actual_animation() == animations["one_star"])){
                    set_actual_animation(animations["one_star"]);
                }
            }

            else if(count == 2) {

                if(!(get_actual_animation() == animations["two_star"])) {
                    set_actual_animation(animations["two_star"]);
                }
            }

            else if(count == 3 && !give_hp) {

                if(!(get_actual_animation() == animations["three_star"])) {
                    set_actual_animation(animations["three_star"]);
                }
            }

            else if(count == 3 && give_hp) {
                fox->set_animation_hud_fading(false);
                set_actual_animation(animations["three_star_fading"]);
                play_song("heart");
            }
        }
    }
}

/**
 * @brief Initiates Hud Fox's animation.
 *
 * Initiates all Hud Fox's sprites(images).
 *
 * @return void.
 */
void HudFox::initialize_animations() {

    engine::Animation* fox_zero_star = nullptr;
    fox_zero_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_0.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("zero_star", fox_zero_star);

    engine::Animation* fox_one_star = nullptr;
    fox_one_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_1.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("one_star", fox_one_star);

    engine::Animation* fox_two_star = nullptr;
    fox_two_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_2.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("two_star", fox_two_star);

    engine::Animation* fox_three_star = nullptr;
    fox_three_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_3.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("three_star", fox_three_star);

    engine::Animation* fox_three_star_fading = nullptr;
    fox_three_star_fading = create_animation(
        "../assets/images/sprites/hud/hud_fox_3_animation.png",
        1,4,1.0, "RIGHT"
    );
    fox_three_star_fading->in_loop = false;
    add_animation("three_star_fading", fox_three_star_fading);

    fox_zero_star->activate();
    set_actual_animation(fox_zero_star);
}

/**
 * @brief Creates Hud Fox's animation.
 *
 * Creates all Hud Fox's animation based on Hud Fox's sprites.
 *
 * @param image_path Path of the Hud Fox's sprite.
 * @param sprite_lines Line of the Hud Fox's sprite.
 * @warning Limitations of sprite_lines and sprite_columns are
 * 1 to the quantity of lines/columns in the image.
 * @param sprite_columns Column of the Fox's sprite needed.
 * @param duration Duration of the Hud Fox's image to show up.
 * @param direction Direction of the Hud Fox's image.
 * @return engine::Animation* The animation constructed.
 */
engine::Animation* HudFox::create_animation(
    std::string path,
    int sprite_lines,
    int sprite_columns,
    double duration,
    std::string direction) {

    engine::Game& game = engine::Game::get_instance();

    engine::Animation* animation = nullptr;
    animation = new engine::Animation(
        game.get_renderer(),
        path,
        // is_active
        false,
        std::make_pair(0, 0),
        // priority
        1,
        sprite_lines,
        sprite_columns,
        duration,
        // in_loop
        true,
        direction
    );

    animation->set_values(
        std::make_pair(170, 78),
        std::make_pair(170, 78),
        std::make_pair(0, 0)
    );

    return animation;
}
<|endoftext|>


<commit_before>/**
 * @file hud_fox.cpp
 * @brief Purpose: Contains methods to game class' management.
 *
 * MIT License
 * Copyright (c) 2017 MindScape
 *
 * https://github.com/TecProg2017-2/mindscape/blob/master/LICENSE.md
 */
#include "../include/hud_fox.hpp"

using namespace mindscape;

/**
 * @brief Class Contructor.
 *
 * Sets Hud Fox's firsts informations (attributes' values).
 * (Hud Fox: Fox's health bar).
 *
 * @param name Hud Fox's name(name of the object).
 * @param position Hud Fox's coordinates in the game's map.
 * @param priority Hud Fox's priority in game's execution.
 * @return void.
 */
HudFox::HudFox(
    std::string name,
    std::pair<int, int> position,
    int priority)
    :engine::GameObject(
        name,
        position,
        priority,
        {
            //No engine Keyboard Event needed.
        }
    ) {
        initialize_animations();
        initialize_audio_effects();
};

/**
 * @brief Initiates Hud Fox's sound effect.
 *
 * Sets sound effect of heart.
 * @return void.
 */
void HudFox::initialize_audio_effects() {
    engine::Audio * take_this_hp = nullptr;
    take_this_hp = new engine::Audio(
        "heart", "../assets/audios/effects_songs/mindscape_heart.wav",
        engine::Audio::CHUNK);

    take_this_hp->set_duration(1);

    add_component(take_this_hp);
}

/**
 * @brief Notifies Hud Fox of Fox's state.
 *
 * Verifies Fox's state and sets stars' animation depending of the quantity of
 *  stars collected.
 *
 * @param game_object Object for observe game's situation,
 * in this case, the Fox.
 * @return void.
 */
void HudFox::notify(engine::Observable* game_object) {
    Fox* fox = nullptr;
    fox = dynamic_cast<Fox *>(game_object);

    if(fox) {

        bool give_hp = false;
        give_hp = fox->get_animation_hud_fading();

        engine::Animation* actual = NULL;
        actual = get_actual_animation();

        if(actual == animations["three_star_fading"]) {

            if(actual->is_finished) {
                give_hp = false;
                fox->set_star_count(0);
                set_actual_animation(animations["zero_star"]);
            }
        }

        else {

            int count = 0;
            count = fox->get_star_count();

            if(count == 0) {

                if(!(get_actual_animation() == animations["zero_star"])) {
                    set_actual_animation(animations["zero_star"]);
                }
            }

            else if(count == 1) {

                if(!(get_actual_animation() == animations["one_star"])){
                    set_actual_animation(animations["one_star"]);
                }
            }

            else if(count == 2) {

                if(!(get_actual_animation() == animations["two_star"])) {
                    set_actual_animation(animations["two_star"]);
                }
            }

            else if(count == 3 && !give_hp) {

                if(!(get_actual_animation() == animations["three_star"])) {
                    set_actual_animation(animations["three_star"]);
                }
            }

            else if(count == 3 && give_hp) {
                fox->set_animation_hud_fading(false);
                set_actual_animation(animations["three_star_fading"]);
                play_song("heart");
            }
        }
    }
}

/**
 * @brief Initiates Hud Fox's animation.
 *
 * Initiates all Hud Fox's sprites(images).
 *
 * @return void.
 */
void HudFox::initialize_animations() {

    engine::Animation* fox_zero_star = nullptr;
    fox_zero_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_0.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("zero_star", fox_zero_star);

    engine::Animation* fox_one_star = nullptr;
    fox_one_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_1.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("one_star", fox_one_star);

    engine::Animation* fox_two_star = nullptr;
    fox_two_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_2.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("two_star", fox_two_star);

    engine::Animation* fox_three_star = nullptr;
    fox_three_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_3.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("three_star", fox_three_star);

    engine::Animation* fox_three_star_fading = nullptr;
    fox_three_star_fading = create_animation(
        "../assets/images/sprites/hud/hud_fox_3_animation.png",
        1,4,1.0, "RIGHT"
    );
    fox_three_star_fading->in_loop = false;
    add_animation("three_star_fading", fox_three_star_fading);

    fox_zero_star->activate();
    set_actual_animation(fox_zero_star);
}

/**
 * @brief Creates Hud Fox's animation.
 *
 * Creates all Hud Fox's animation based on Hud Fox's sprites.
 *
 * @param image_path Path of the Hud Fox's sprite.
 * @param sprite_lines Line of the Hud Fox's sprite.
 * @warning Limitations of sprite_lines and sprite_columns are
 * 1 to the quantity of lines/columns in the image.
 * @param sprite_columns Column of the Fox's sprite needed.
 * @param duration Duration of the Hud Fox's image to show up.
 * @param direction Direction of the Hud Fox's image.
 * @return engine::Animation* The animation constructed.
 */
engine::Animation* HudFox::create_animation(
    std::string path,
    int sprite_lines,
    int sprite_columns,
    double duration,
    std::string direction) {

    engine::Game& game = engine::Game::get_instance();

    engine::Animation* animation = nullptr;
    animation = new engine::Animation(
        game.get_renderer(),
        path,
        // is_active
        false,
        std::make_pair(0, 0),
        // priority
        1,
        sprite_lines,
        sprite_columns,
        duration,
        // in_loop
        true,
        direction
    );

    animation->set_values(
        std::make_pair(170, 78),
        std::make_pair(170, 78),
        std::make_pair(0, 0)
    );

    return animation;
}
<commit_msg>[COMMENTS] Apply comment in hud_fox.cpp<commit_after>/**
 * @file hud_fox.cpp
 * @brief Purpose: Contains methods to game class' management.
 *
 * MIT License
 * Copyright (c) 2017 MindScape
 *
 * https://github.com/TecProg2017-2/mindscape/blob/master/LICENSE.md
 */
#include "../include/hud_fox.hpp"

using namespace mindscape;

/**
 * @brief Class Contructor.
 *
 * Sets Hud Fox's firsts informations (attributes' values).
 * (Hud Fox: Fox's health bar).
 *
 * @param name Hud Fox's name(name of the object).
 * @param position Hud Fox's coordinates in the game's map.
 * @param priority Hud Fox's priority in game's execution.
 * @return void.
 */
HudFox::HudFox(
    std::string name,
    std::pair<int, int> position,
    int priority)
    :engine::GameObject(
        name,
        position,
        priority,
        {
            //No engine Keyboard Event needed.
        }
    ) {
        initialize_animations();
        initialize_audio_effects();
};

/**
 * @brief Initiates Hud Fox's sound effect.
 *
 * Sets sound effect of heart.
 * @return void.
 */
void HudFox::initialize_audio_effects() {
    engine::Audio * take_this_hp = nullptr;
    take_this_hp = new engine::Audio(
        "heart", "../assets/audios/effects_songs/mindscape_heart.wav",
        engine::Audio::CHUNK);

    take_this_hp->set_duration(1);

    add_component(take_this_hp);
}

/**
 * @brief Notifies Hud Fox of Fox's state.
 *
 * Verifies Fox's state and sets stars' animation depending of the quantity of
 *  stars collected.
 *
 * @param game_object Object for observe game's situation,
 * in this case, the Fox.
 * @return void.
 */
void HudFox::notify(engine::Observable* game_object) {
    Fox* fox = nullptr;
    fox = dynamic_cast<Fox *>(game_object);

    if(fox) {
    /* If the fox exists */
        bool give_hp = false; /*< Boolean. Boolean that defines if hp is being given or not */
        give_hp = fox->get_animation_hud_fading();

        engine::Animation* actual = NULL;
        actual = get_actual_animation();

        if(actual == animations["three_star_fading"]) {
        /* If stars are fading */
            if(actual->is_finished) {
            /* If stars already faded */
                give_hp = false;
                fox->set_star_count(0);
                set_actual_animation(animations["zero_star"]);
            }
        }

        else {
        /* If the animation is not stars fading */
            int count = 0; /*< Integer. Number of stars */
            count = fox->get_star_count();

            if(count == 0) {
            /* If there are no stars */
                if(!(get_actual_animation() == animations["zero_star"])) {
                    set_actual_animation(animations["zero_star"]);
                }
            }

            else if(count == 1) {
            /* If there is one star */
                if(!(get_actual_animation() == animations["one_star"])){
                    set_actual_animation(animations["one_star"]);
                }
            }

            else if(count == 2) {
            /* If there are two stars */
                if(!(get_actual_animation() == animations["two_star"])) {
                    set_actual_animation(animations["two_star"]);
                }
            }

            else if(count == 3 && !give_hp) {
            /* If there are three stars and is not giving hp */
                if(!(get_actual_animation() == animations["three_star"])) {
                    set_actual_animation(animations["three_star"]);
                }
            }

            else if(count == 3 && give_hp) {
            /* If there are three stars and is giving hp */
                fox->set_animation_hud_fading(false);
                set_actual_animation(animations["three_star_fading"]);
                play_song("heart");
            }
        }
    }
}

/**
 * @brief Initiates Hud Fox's animation.
 *
 * Initiates all Hud Fox's sprites(images).
 *
 * @return void.
 */
void HudFox::initialize_animations() {

    engine::Animation* fox_zero_star = nullptr;
    fox_zero_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_0.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("zero_star", fox_zero_star);

    engine::Animation* fox_one_star = nullptr;
    fox_one_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_1.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("one_star", fox_one_star);

    engine::Animation* fox_two_star = nullptr;
    fox_two_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_2.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("two_star", fox_two_star);

    engine::Animation* fox_three_star = nullptr;
    fox_three_star = create_animation(
        "../assets/images/sprites/hud/hud_fox_3.png",
        1,1,0.9, "RIGHT"
    );
    add_animation("three_star", fox_three_star);

    engine::Animation* fox_three_star_fading = nullptr;
    fox_three_star_fading = create_animation(
        "../assets/images/sprites/hud/hud_fox_3_animation.png",
        1,4,1.0, "RIGHT"
    );
    fox_three_star_fading->in_loop = false;
    add_animation("three_star_fading", fox_three_star_fading);

    fox_zero_star->activate();
    set_actual_animation(fox_zero_star);
}

/**
 * @brief Creates Hud Fox's animation.
 *
 * Creates all Hud Fox's animation based on Hud Fox's sprites.
 *
 * @param image_path Path of the Hud Fox's sprite.
 * @param sprite_lines Line of the Hud Fox's sprite.
 * @warning Limitations of sprite_lines and sprite_columns are
 * 1 to the quantity of lines/columns in the image.
 * @param sprite_columns Column of the Fox's sprite needed.
 * @param duration Duration of the Hud Fox's image to show up.
 * @param direction Direction of the Hud Fox's image.
 * @return engine::Animation* The animation constructed.
 */
engine::Animation* HudFox::create_animation(
    std::string path,
    int sprite_lines,
    int sprite_columns,
    double duration,
    std::string direction) {

    engine::Game& game = engine::Game::get_instance();

    engine::Animation* animation = nullptr;
    animation = new engine::Animation(
        game.get_renderer(),
        path,
        // is_active
        false,
        std::make_pair(0, 0),
        // priority
        1,
        sprite_lines,
        sprite_columns,
        duration,
        // in_loop
        true,
        direction
    );

    animation->set_values(
        std::make_pair(170, 78),
        std::make_pair(170, 78),
        std::make_pair(0, 0)
    );

    return animation;
}
<|endoftext|>


<commit_before>/* dlvhex -- Answer-Set Programming with external interfaces.
 * Copyright (C) 2005, 2006, 2007 Roman Schindlauer
 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner
 * Copyright (C) 2009, 2010 Peter Schüller
 *
 * This file is part of dlvhex.
 *
 * dlvhex is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * dlvhex 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 dlvhex; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */

/**
 * @file   RuleTable.hpp
 * @author Peter Schueller <ps@kr.tuwien.ac.at>
 *
 * @brief  Table for storing Rules
 */

#ifndef RULETABLE_HPP_INCLUDED__12102010
#define RULETABLE_HPP_INCLUDED__12102010

#include "dlvhex/PlatformDefinitions.h"
#include "dlvhex/Rule.hpp"
#include "dlvhex/Table.hpp"

#include <boost/multi_index/member.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/ordered_index.hpp>

DLVHEX_NAMESPACE_BEGIN

class RuleTable:
	public Table<
		// value type is symbol struct
		Rule,
		// index is
		boost::multi_index::indexed_by<
			// address = running ID for constant access
			boost::multi_index::random_access<
				boost::multi_index::tag<impl::AddressTag>
			>,
			// kind
			boost::multi_index::ordered_non_unique<
				boost::multi_index::tag<impl::KindTag>,
				BOOST_MULTI_INDEX_MEMBER(Rule,IDKind,kind)
			>
      // TODO more indices required?
		>
	>
{
	// types
public:
  typedef Container::index<impl::AddressTag>::type AddressIndex;
  typedef Container::index<impl::KindTag>::type KindIndex;

	// methods
public:
  // retrieve by ID
  // assert that id.kind is correct for Rule
  // assert that ID exists in table
	inline const Rule& getByID(ID id) const throw ();

	// store rule (no duplicate check is done/required)
	inline ID storeAndGetID(const Rule& rule) throw();
	inline void clear();
};

// retrieve by ID
// assert that id.kind is correct for Rule
// assert that ID exists
const Rule&
RuleTable::getByID(
  ID id) const throw ()
{
	assert(id.isRule());
	assert(id.isRegularRule() || id.isConstraint() || id.isWeakConstraint());
  const AddressIndex& idx = container.get<impl::AddressTag>();
  // the following check only works for random access indices, but here it is ok
  assert( id.address < idx.size() );
  return idx.at(id.address);
}

// store rule (no duplicate check is done/required)
ID RuleTable::storeAndGetID(
		const Rule& rule) throw()
{
	assert(ID(rule.kind,0).isRule());
	assert(ID(rule.kind,0).isRegularRule() ||
    ID(rule.kind,0).isConstraint() ||
    ID(rule.kind,0).isWeakConstraint());
	assert(!(rule.head.empty() && rule.body.empty()));
	assert(!(rule.head.empty() && ID(rule.kind,0).isRegularRule()));
	assert(!(rule.head.size() > 1 && !ID(rule.kind,0).isRuleDisjunctive()));

	AddressIndex& idx = container.get<impl::AddressTag>();

	AddressIndex::const_iterator it;
	bool success;
	boost::tie(it, success) = idx.push_back(rule);
	(void)success;
	assert(success);

	return ID(
			rule.kind, // kind
			container.project<impl::AddressTag>(it) - idx.begin() // address
			);
}

void RuleTable::clear(){
  container.clear();
}

DLVHEX_NAMESPACE_END

#endif // RULETABLE_HPP_INCLUDED__12102010
<commit_msg>Adding hashed index to the RuleTable.<commit_after>/* dlvhex -- Answer-Set Programming with external interfaces.
 * Copyright (C) 2005, 2006, 2007 Roman Schindlauer
 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner
 * Copyright (C) 2009, 2010 Peter Schüller
 *
 * This file is part of dlvhex.
 *
 * dlvhex is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * dlvhex 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 dlvhex; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */

/**
 * @file   RuleTable.hpp
 * @author Peter Schueller <ps@kr.tuwien.ac.at>
 *
 * @brief  Table for storing Rules
 */

#ifndef RULETABLE_HPP_INCLUDED__12102010
#define RULETABLE_HPP_INCLUDED__12102010

#include "dlvhex/PlatformDefinitions.h"
#include "dlvhex/Rule.hpp"
#include "dlvhex/Table.hpp"

#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/composite_key.hpp>

DLVHEX_NAMESPACE_BEGIN

class RuleTable:
	public Table<
		// value type is symbol struct
		Rule,
		// index is
		boost::multi_index::indexed_by<
			// address = running ID for constant access
			boost::multi_index::random_access<
				boost::multi_index::tag<impl::AddressTag>
			>,
			// kind
			boost::multi_index::ordered_non_unique<
				boost::multi_index::tag<impl::KindTag>,
				BOOST_MULTI_INDEX_MEMBER(Rule,IDKind,kind)
			>,
			// element
			boost::multi_index::hashed_unique<
				boost::multi_index::tag<impl::ElementTag>,
				boost::multi_index::composite_key<
				  Rule,
				  BOOST_MULTI_INDEX_MEMBER(Rule,IDKind,kind),
				  BOOST_MULTI_INDEX_MEMBER(Rule,Tuple,head),
				  BOOST_MULTI_INDEX_MEMBER(Rule,Tuple,body),
				  BOOST_MULTI_INDEX_MEMBER(Rule,ID,weight),
				  BOOST_MULTI_INDEX_MEMBER(Rule,ID,level)
				>
			>
      // TODO more indices required?
		>
	>
{
	// types
public:
  typedef Container::index<impl::AddressTag>::type AddressIndex;
  typedef Container::index<impl::KindTag>::type KindIndex;
  typedef Container::index<impl::ElementTag>::type ElementIndex;
  typedef ElementIndex::iterator ElementIterator;
	// methods
public:
	inline int getSize();
  // retrieve by ID
  // assert that id.kind is correct for Rule
  // assert that ID exists in table
	inline const Rule& getByID(ID id) const throw ();

        // get the ID of the rule
	inline ID getIDByElement(const Rule& rule) const throw();

	// store rule (no duplicate check is done/required)
	inline ID storeAndGetID(const Rule& rule) throw();
	inline void clear();
};

int RuleTable::getSize()
{
  return container.size();
}

// retrieve by ID
// assert that id.kind is correct for Rule
// assert that ID exists
const Rule&
RuleTable::getByID(
  ID id) const throw ()
{
	assert(id.isRule());
	assert(id.isRegularRule() || id.isConstraint() || id.isWeakConstraint());
  const AddressIndex& idx = container.get<impl::AddressTag>();
  // the following check only works for random access indices, but here it is ok
  assert( id.address < idx.size() );
  return idx.at(id.address);
}

// getID by rule
ID RuleTable::getIDByElement(const Rule& rule) const throw()
{
  const ElementIndex& sidx = container.get<impl::ElementTag>();
  ElementIndex::const_iterator it = sidx.find( boost::make_tuple(rule.kind, rule.head, rule.body, rule.weight, rule.level) );
  if( it == sidx.end() )
    return ID_FAIL;
  else
    {
      const AddressIndex& aidx = container.get<impl::AddressTag>();
      return ID(
		it->kind, // kind
		container.project<impl::AddressTag>(it) - aidx.begin() // address
		);
    }
}

// store rule (no duplicate check is done/required)
ID RuleTable::storeAndGetID(
		const Rule& rule) throw()
{
	assert(ID(rule.kind,0).isRule());
	assert(ID(rule.kind,0).isRegularRule() ||
    ID(rule.kind,0).isConstraint() ||
    ID(rule.kind,0).isWeakConstraint());
	assert(!(rule.head.empty() && rule.body.empty()));
	assert(!(rule.head.empty() && ID(rule.kind,0).isRegularRule()));
	assert(!(rule.head.size() > 1 && !ID(rule.kind,0).isRuleDisjunctive()));

	AddressIndex& idx = container.get<impl::AddressTag>();

	AddressIndex::const_iterator it;
	bool success;
	boost::tie(it, success) = idx.push_back(rule);
	(void)success;
	assert(success);

	return ID(
			rule.kind, // kind
			container.project<impl::AddressTag>(it) - idx.begin() // address
			);
}

void RuleTable::clear(){
  container.clear();
}

DLVHEX_NAMESPACE_END

#endif // RULETABLE_HPP_INCLUDED__12102010
<|endoftext|>


<commit_before>#include <node.h>
#include <v8.h>
#include <sys/mount.h>
#include <fstream>

#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>

using namespace v8;
using namespace node;

static Handle<Value> _set_ipv4_address ( const Arguments* args ){
	HandleScope scope;

	v8::String::Utf8Value device( args[0]->ToString( ) );
	v8::String::Utf8Value address( args[1]->ToString( ) );
	v8::String::Utf8Value mask( args[2]->ToString( ) );

	int t_socket;
	struct ifreq ifr, if_netmask;
	struct sockaddr_in sin, netmask_sin;

	t_socket	= socket( AF_INET, SOCK_DGRAM, 0 );
	if( t_socket < 0 ){
		return False( );
	}

	strncpy( ifr.ifr_name, *device_name, sizeof( ifr.ifr_name ) );
	sin.sin_family	= AF_INET;

	inet_aton( *new_address, &sin.sin_addr );
	inet_aton( *net_mask, &netmask_sin.sin_addr );

	memcpy( &ifr.ifr_addr, &sin, sizeof( struct socketaddr ) );

	int t_result;
	t_result	= ioctl( t_socket, SIOCSIFADDR, &ifr );
	if( t_result < 0 ){
		return False( );
	}

	strncpy( if_netmask.ifr_name, *device_name, sizeof( if_netmask.ifr_name ) );
	memcpy( &if_netmask.ifr_netmask, &netmask_sin, sizeof( struct sockaddr ) );

	int t_netmask_result;
	t_netmask_result = ioctl( t_socket, SIOCSIFNETMASK, &if_netmask );
	if( t_netmask_result < 0 ){
		return False( );
	}else{
		return True( );
	}
}

extern "C" void init (Handle<Object> target){
	HandleScope scope;

	target->Set( String::New( "set_ipv4_address" ), FunctionTemplate::New( _set_ipv4_address )->GetFunction( ) );
}
<commit_msg>Typo's.<commit_after>#include <node.h>
#include <v8.h>
#include <sys/mount.h>
#include <fstream>

#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>

using namespace v8;
using namespace node;

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

	v8::String::Utf8Value device( args[0]->ToString( ) );
	v8::String::Utf8Value address( args[1]->ToString( ) );
	v8::String::Utf8Value mask( args[2]->ToString( ) );

	int t_socket;
	struct ifreq ifr, if_netmask;
	struct sockaddr_in sin, netmask_sin;

	t_socket	= socket( AF_INET, SOCK_DGRAM, 0 );
	if( t_socket < 0 ){
		return False( );
	}

	strncpy( ifr.ifr_name, *device, sizeof( ifr.ifr_name ) );
	sin.sin_family	= AF_INET;

	inet_aton( *address, &sin.sin_addr );
	inet_aton( *mask, &netmask_sin.sin_addr );

	memcpy( &ifr.ifr_addr, &sin, sizeof( struct sockaddr ) );

	int t_result;
	t_result	= ioctl( t_socket, SIOCSIFADDR, &ifr );
	if( t_result < 0 ){
		return False( );
	}

	strncpy( if_netmask.ifr_name, *device, sizeof( if_netmask.ifr_name ) );
	memcpy( &if_netmask.ifr_netmask, &netmask_sin, sizeof( struct sockaddr ) );

	int t_netmask_result;
	t_netmask_result = ioctl( t_socket, SIOCSIFNETMASK, &if_netmask );
	if( t_netmask_result < 0 ){
		return False( );
	}else{
		return True( );
	}
}

extern "C" void init (Handle<Object> target){
	HandleScope scope;

	target->Set( String::New( "set_ipv4_address" ), FunctionTemplate::New( _set_ipv4_address )->GetFunction( ) );
}
<|endoftext|>


<commit_before>/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/

// Google Test Library
#include <gtest/gtest.h>

// Module
#include "../ports.h"

namespace ports {
    namespace testing {

        static const uint64 PORT_LATENCY = 1;
        static const uint32 PORT_FANOUT = 1;
        static const uint32 PORT_BANDWIDTH = 1;

        static const int DATA_LIMIT = 5;
        static const uint64 CLOCK_LIMIT = 10;

        class A
        {
            public:
                A();
                void clock( uint64 cycle);

            private:
                std::unique_ptr<WritePort<int>> to_B;
                std::unique_ptr<ReadPort<int>> from_B;

                std::unique_ptr<ReadPort<int>> init;
                std::unique_ptr<WritePort<bool>> stop;

                void process_data( int data, uint64 cycle);
        };

        class B
        {
            public:
                B();
                void clock( uint64 cycle);

            private:
                std::unique_ptr<WritePort<int>> to_A;
                std::unique_ptr<ReadPort<int>> from_A;

                void process_data ( int data, uint64 cycle);
        };

    } // namespace testing
} // namespace ports

#define GTEST_ASSERT_NO_DEATH( statement)                        \
    ASSERT_EXIT( { statement}::exit(EXIT_SUCCESS),               \
                 ::testing::ExitedWithCode(EXIT_SUCCESS), "");   \
    statement

TEST( test_ports, Test_Ports_A_B)
{
    GTEST_ASSERT_NO_DEATH( ports::testing::A a;);
    GTEST_ASSERT_NO_DEATH( ports::testing::B b;);

    GTEST_ASSERT_NO_DEATH( WritePort<int> init( "init_A", ports::testing::PORT_BANDWIDTH,
                                                ports::testing::PORT_FANOUT););
    GTEST_ASSERT_NO_DEATH( ReadPort<bool> stop( "stop", ports::testing::PORT_LATENCY););

    // connect all the ports
    GTEST_ASSERT_NO_DEATH( init_ports(););

    // init object A by value 0
    GTEST_ASSERT_NO_DEATH( init.write( 0, 0););

    for ( uint64 cycle = 0; cycle < ports::testing::CLOCK_LIMIT; cycle++)
    {
        //check the stop port from object A
        bool is_ready;
        GTEST_ASSERT_NO_DEATH( is_ready = stop.is_ready( cycle););
        if ( is_ready)
        {
            GTEST_ASSERT_NO_DEATH( stop.read( cycle););
            break;
        }

        a.clock( cycle);
        b.clock( cycle);

        GTEST_ASSERT_NO_DEATH( check_ports( cycle););
    }

    GTEST_ASSERT_NO_DEATH( destroy_ports(););

    std::cout << "------------\n"
              << "CLOCK_LIMIT (" << ports::testing::CLOCK_LIMIT
              << ")  has been reached\n\n";
}

int main( int argc, char** argv)
{
    ::testing::InitGoogleTest( &argc, argv);
    ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    return RUN_ALL_TESTS();
}

namespace ports {
    namespace testing {
        A::A()
            : to_B{ make_write_port<int>( "A_to_B", PORT_BANDWIDTH, PORT_FANOUT)}
            , from_B{ make_read_port<int>( "B_to_A", PORT_LATENCY)}

            , init{ make_read_port<int> ( "init_A", PORT_LATENCY)}
            , stop{ make_write_port<bool> ( "stop", PORT_BANDWIDTH, PORT_FANOUT)}
        { }

        void A::process_data( int data, uint64 cycle)
        {
            ++data;

            // If data limit is exceeded
            // then send a stop signal
            if ( data > DATA_LIMIT)
            {
                GTEST_ASSERT_NO_DEATH( stop->write( true, cycle););
                return;
            }

            GTEST_ASSERT_NO_DEATH( to_B->write( data, cycle););
        }

        void A::clock( uint64 cycle)
        {
            int data;

            bool is_init_ready;
            bool is_from_B_ready;
            while( true)
            {
                GTEST_ASSERT_NO_DEATH( is_init_ready = init->is_ready( cycle););
                GTEST_ASSERT_NO_DEATH( is_from_B_ready = from_B->is_ready( cycle););
                if( is_init_ready)
                    { GTEST_ASSERT_NO_DEATH( data = init->read( cycle););}
                else if ( is_from_B_ready)
                    { GTEST_ASSERT_NO_DEATH( data = from_B->read( cycle););}
                else
                    break;

                process_data( data, cycle);
            }
        }

        B::B()
            : to_A{ make_write_port<int>( "B_to_A", PORT_BANDWIDTH, PORT_FANOUT)}
            , from_A{ make_read_port<int>( "A_to_B", PORT_LATENCY)}
        { }

        void B::process_data( int data, uint64 cycle)
        {
            ++data;

            GTEST_ASSERT_NO_DEATH( to_A->write( data, cycle););
        }

        void B::clock( uint64 cycle)
        {
            bool is_from_A_ready;
            GTEST_ASSERT_NO_DEATH( is_from_A_ready = from_A->is_ready( cycle););
            if ( is_from_A_ready)
            {
                int data;
                GTEST_ASSERT_NO_DEATH( data = from_A->read( cycle););
                GTEST_ASSERT_NO_DEATH( process_data( data, cycle););
            }
        }

    } // namespace testing
} // namespace ports

<commit_msg>Add semantic tests to ports test (#229)<commit_after>/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/

// Google Test Library
#include <gtest/gtest.h>

// Module
#include "../ports.h"

#include <cassert>

namespace ports {
    namespace testing {

        static const uint64 PORT_LATENCY = 1;
        static const uint32 PORT_FANOUT = 1;
        static const uint32 PORT_BANDWIDTH = 1;

        static const int DATA_LIMIT = 5;
        static const uint64 CLOCK_LIMIT = 10;

        class Logic
        {
            public:
                enum class CheckCode
                {
                    DATA_FROM_A,
                    DATA_FROM_B,
                    DATA_INIT,
                    IS_FROM_A_READY,
                    IS_FROM_B_READY,
                    IS_INIT_READY,
                    IS_STOP_READY
                };

                bool check_readiness( uint64 cycle, CheckCode code, bool is_ready);
                bool check_data( uint64 cycle, CheckCode code, int data) const;

            private:
                static const int NONE = -1;
                static const uint64 EXPECTED_MAX_CYCLE = 8;

                struct State
                {
                    bool is_from_A_ready;
                    bool is_from_B_ready;
                    bool is_init_ready;
                    int data_from_A;
                    int data_from_B;
                };

                State blogic[EXPECTED_MAX_CYCLE + 1] =
                //  |IS_FROM_A_READY|IS_FROM_B_READY|IS_INIT_READY|DATA_FROM_A|DATA_FROM_B|
                {
                   { false,          false,          false,        NONE,       NONE        },
                   { false,          false,          true,         NONE,       NONE        },
                   { true,           false,          false,        1,          NONE        },
                   { false,          true,           false,        NONE,       2           },
                   { true,           false,          false,        3,          NONE        },
                   { false,          true,           false,        NONE,       4           },
                   { true,           false,          false,        5,          NONE        },
                   { false,          true,           false,        NONE,       6           },
                   { false,          false,          false,        NONE,       NONE        }
                };
        };

        class A
        {
            public:
                A();
                void clock( uint64 cycle);

            private:
                std::unique_ptr<WritePort<int>> to_B;
                std::unique_ptr<ReadPort<int>> from_B;

                std::unique_ptr<ReadPort<int>> init;
                std::unique_ptr<WritePort<bool>> stop;

                void process_data( int data, uint64 cycle);
        };

        class B
        {
            public:
                B();
                void clock( uint64 cycle);

            private:
                std::unique_ptr<WritePort<int>> to_A;
                std::unique_ptr<ReadPort<int>> from_A;

                void process_data ( int data, uint64 cycle);
        };

        static Logic logic{};
    } // namespace testing
} // namespace ports

#define GTEST_ASSERT_NO_DEATH( statement)                        \
    ASSERT_EXIT( { statement}::exit(EXIT_SUCCESS),               \
                 ::testing::ExitedWithCode(EXIT_SUCCESS), "");   \
    statement

using ports::testing::Logic;

TEST( test_ports, Test_Ports_A_B)
{
    GTEST_ASSERT_NO_DEATH( ports::testing::A a;);
    GTEST_ASSERT_NO_DEATH( ports::testing::B b;);

    GTEST_ASSERT_NO_DEATH( WritePort<int> init( "init_A", ports::testing::PORT_BANDWIDTH,
                                                ports::testing::PORT_FANOUT););
    GTEST_ASSERT_NO_DEATH( ReadPort<bool> stop( "stop", ports::testing::PORT_LATENCY););

    // connect all the ports
    GTEST_ASSERT_NO_DEATH( init_ports(););

    // init object A by value 0
    GTEST_ASSERT_NO_DEATH( init.write( 0, 0););

    for ( uint64 cycle = 0; cycle < ports::testing::CLOCK_LIMIT; cycle++)
    {
        //check the stop port from object A
        bool is_ready;
        GTEST_ASSERT_NO_DEATH( is_ready = stop.is_ready( cycle););
        ASSERT_TRUE( ports::testing::logic.check_readiness( cycle,
                                                            Logic::CheckCode::IS_STOP_READY,
                                                            is_ready));
        if ( is_ready)
        {
            GTEST_ASSERT_NO_DEATH( stop.read( cycle););
            break;
        }

        a.clock( cycle);
        b.clock( cycle);

        GTEST_ASSERT_NO_DEATH( check_ports( cycle););
    }

    GTEST_ASSERT_NO_DEATH( destroy_ports(););
}

int main( int argc, char** argv)
{
    ::testing::InitGoogleTest( &argc, argv);
    ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    return RUN_ALL_TESTS();
}

namespace ports {
    namespace testing {

        bool Logic::check_readiness( uint64 cycle, CheckCode code, bool is_ready)
        {
            if ( cycle > EXPECTED_MAX_CYCLE)
                return false;

            bool is_ok = false;
            switch ( code)
            {
                case CheckCode::IS_STOP_READY:
                    // STOP port should be ready only in the expected max cycle
                    return (cycle == EXPECTED_MAX_CYCLE) == is_ready;

                case CheckCode::IS_INIT_READY:
                    is_ok = blogic[cycle].is_init_ready == is_ready;

                    // If it is ready it will be read in the current cycle
                    // so blogic should be updated to not interfere with
                    // subsequent checks in the same cycle
                    if ( is_ok && is_ready)
                        blogic[cycle].is_init_ready = false;

                    break;

                case CheckCode::IS_FROM_A_READY:
                    is_ok = blogic[cycle].is_from_A_ready == is_ready;

                    // If it is ready it will be read in the current cycle
                    // so blogic should be updated to not interfere with
                    // subsequent checks in the same cycle
                    if ( is_ok && is_ready)
                        blogic[cycle].is_from_A_ready = false;

                    break;

                case CheckCode::IS_FROM_B_READY:
                    is_ok = blogic[cycle].is_from_B_ready == is_ready;

                    // If it is ready it will be read in the current cycle
                    // so blogic should be updated to not interfere with
                    // subsequent checks in the same cycle
                    if ( is_ok && is_ready)
                        blogic[cycle].is_from_B_ready = false;

                    break;

                default:
                    break;
            }

            return is_ok;
        }

        bool Logic::check_data( uint64 cycle, CheckCode code, int data) const
        {
            if ( cycle > EXPECTED_MAX_CYCLE || data < 0)
                return false;

            switch ( code)
            {
                case CheckCode::DATA_INIT:
                    // data from init port should be equal to 0
                    // merely in cycle 1
                    return cycle == 1 && data == 0;

                case CheckCode::DATA_FROM_A:
                    return blogic[cycle].data_from_A == data;

                case CheckCode::DATA_FROM_B:
                    return blogic[cycle].data_from_B == data;

                default:
                    return false;
            };
        }

        A::A()
            : to_B{ make_write_port<int>( "A_to_B", PORT_BANDWIDTH, PORT_FANOUT)}
            , from_B{ make_read_port<int>( "B_to_A", PORT_LATENCY)}

            , init{ make_read_port<int> ( "init_A", PORT_LATENCY)}
            , stop{ make_write_port<bool> ( "stop", PORT_BANDWIDTH, PORT_FANOUT)}
        { }

        void A::process_data( int data, uint64 cycle)
        {
            ++data;

            // If data limit is exceeded
            // stop signal will be sent
            if ( data > DATA_LIMIT)
            {
                GTEST_ASSERT_NO_DEATH( stop->write( true, cycle););
                return;
            }

            GTEST_ASSERT_NO_DEATH( to_B->write( data, cycle););
        }

        void A::clock( uint64 cycle)
        {
            int data;

            bool is_init_ready;
            bool is_from_B_ready;
            while( true)
            {
                GTEST_ASSERT_NO_DEATH( is_init_ready = init->is_ready( cycle););
                ASSERT_TRUE( ports::testing::logic.check_readiness( cycle,
                                                                    Logic::CheckCode::IS_INIT_READY,
                                                                    is_init_ready));

                GTEST_ASSERT_NO_DEATH( is_from_B_ready = from_B->is_ready( cycle););
                ASSERT_TRUE( ports::testing::logic.check_readiness( cycle,
                                                                    Logic::CheckCode::IS_FROM_B_READY,
                                                                    is_from_B_ready));

                if( is_init_ready)
                {
                    GTEST_ASSERT_NO_DEATH( data = init->read( cycle););
                    ASSERT_TRUE( ports::testing::logic.check_data( cycle,
                                                                   Logic::CheckCode::DATA_INIT,
                                                                   data));
                }
                else if ( is_from_B_ready)
                {
                    GTEST_ASSERT_NO_DEATH( data = from_B->read( cycle););
                    ASSERT_TRUE( ports::testing::logic.check_data( cycle,
                                                                   Logic::CheckCode::DATA_FROM_B,
                                                                   data));
                }
                else
                    break;

                process_data( data, cycle);
            }
        }

        B::B()
            : to_A{ make_write_port<int>( "B_to_A", PORT_BANDWIDTH, PORT_FANOUT)}
            , from_A{ make_read_port<int>( "A_to_B", PORT_LATENCY)}
        { }

        void B::process_data( int data, uint64 cycle)
        {
            ++data;

            GTEST_ASSERT_NO_DEATH( to_A->write( data, cycle););
        }

        void B::clock( uint64 cycle)
        {
            bool is_from_A_ready;
            GTEST_ASSERT_NO_DEATH( is_from_A_ready = from_A->is_ready( cycle););
            ASSERT_TRUE( ports::testing::logic.check_readiness( cycle,
                                                                Logic::CheckCode::IS_FROM_A_READY,
                                                                is_from_A_ready));
            if ( is_from_A_ready)
            {
                int data;
                GTEST_ASSERT_NO_DEATH( data = from_A->read( cycle););
                ASSERT_TRUE( ports::testing::logic.check_data( cycle,
                                                               Logic::CheckCode::DATA_FROM_A,
                                                               data));

                GTEST_ASSERT_NO_DEATH( process_data( data, cycle););
            }
        }

    } // namespace testing
} // namespace ports

<|endoftext|>


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

Copyright (c) 2008, 2009 Aristid Breitkreuz, Ash Berlin, Rüdiger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef FLUSSPFERD_ARRAY_HPP
#define FLUSSPFERD_ARRAY_HPP

#include "object.hpp"
#include <boost/utility/in_place_factory.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <cassert>

namespace flusspferd {

/**
 * A class for holding a Javascript Array.
 *
 * @see flusspferd::create_array()
 *
 * @ingroup value_types
 * @ingroup property_types
 */
class array : public object {
public:
  /// Construct an #array from a Javascript Array object.
  array(object const &o);

  /// Assign a Javascript Array object to an #array object.
  array &operator=(object const &o);

public:
  /// Get the length of the Array.
  std::size_t length() const;

  /// Set the length of the array, resizing it in the process.
  void set_length(std::size_t);

  /// Get the length of the Array.
  std::size_t size() const { return length(); }

  /// Get an array element.
  value get_element(std::size_t n) const;

  /// Set an array element.
  void set_element(std::size_t n, value const &x);

  /// Const Array Iterator
  class iterator
    : public boost::iterator_facade<
    iterator, value, boost::random_access_traversal_tag, value
    >
  {
    typedef boost::iterator_facade<
      iterator, value, boost::random_access_traversal_tag, value
      > parent_t;

    array const *a;
    std::size_t pos;
  public:
#ifndef IN_DOXYGEN
    explicit
    iterator(array const &a, std::size_t pos = 0) : a(&a),   pos(pos)  { }
#endif
    iterator(iterator const &i)                   : a(i.a), pos(i.pos) { }

    iterator &operator=(iterator const &o) {
      a = o.a;
      pos = o.pos;
      return *this;
    }

  private:
    friend class boost::iterator_core_access;

    void increment() {
      assert(a);
      ++pos;
      assert(pos <= a->size());
    }
    void decrement() {
      assert(a && pos > 0);
      --pos;
    }
    void advance(std::size_t n) {
      assert(a);
      pos += n;
      assert(pos <= a->size());
    }
    bool equal(iterator const &i) const {
      assert(a && i.a);
      return a == i.a && pos == i.pos;
    }
    parent_t::reference dereference() const {
      assert(a && pos < a->size());
      return a->get_element(pos);
    }
    parent_t::difference_type distance_to(iterator const &i) const {
      assert(a && a == i.a);
      typedef parent_t::difference_type diff_t;
      return static_cast<diff_t>(pos) - static_cast<diff_t>(i.pos);
    }
  };

  iterator begin() const { return iterator(*this); }
  iterator end()   const { return iterator(*this, length()); }
private:
  void check();
};

template<>
struct detail::convert<array> {
  typedef to_value_helper<array> to_value;

  struct from_value {
    boost::optional<root_array> root;

    array perform(value const &v) {
      root = boost::in_place(array(v.to_object()));
      return root.get();
    }
  };
};

}

#endif
<commit_msg>fixed bug in array::iterator::distance_to<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:enc=utf-8:
/*
The MIT License

Copyright (c) 2008, 2009 Aristid Breitkreuz, Ash Berlin, Rüdiger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef FLUSSPFERD_ARRAY_HPP
#define FLUSSPFERD_ARRAY_HPP

#include "object.hpp"
#include <boost/utility/in_place_factory.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <cassert>

namespace flusspferd {

/**
 * A class for holding a Javascript Array.
 *
 * @see flusspferd::create_array()
 *
 * @ingroup value_types
 * @ingroup property_types
 */
class array : public object {
public:
  /// Construct an #array from a Javascript Array object.
  array(object const &o);

  /// Assign a Javascript Array object to an #array object.
  array &operator=(object const &o);

public:
  /// Get the length of the Array.
  std::size_t length() const;

  /// Set the length of the array, resizing it in the process.
  void set_length(std::size_t);

  /// Get the length of the Array.
  std::size_t size() const { return length(); }

  /// Get an array element.
  value get_element(std::size_t n) const;

  /// Set an array element.
  void set_element(std::size_t n, value const &x);

  /// Const Array Iterator
  class iterator
    : public boost::iterator_facade<
    iterator, value, boost::random_access_traversal_tag, value
    >
  {
    typedef boost::iterator_facade<
      iterator, value, boost::random_access_traversal_tag, value
      > parent_t;

    array const *a;
    std::size_t pos;
  public:
#ifndef IN_DOXYGEN
    explicit
    iterator(array const &a, std::size_t pos = 0) : a(&a),   pos(pos)  { }
#endif
    iterator(iterator const &i)                   : a(i.a), pos(i.pos) { }

    iterator &operator=(iterator const &o) {
      a = o.a;
      pos = o.pos;
      return *this;
    }

  private:
    friend class boost::iterator_core_access;

    void increment() {
      assert(a);
      ++pos;
      assert(pos <= a->size());
    }
    void decrement() {
      assert(a && pos > 0);
      --pos;
    }
    void advance(std::size_t n) {
      assert(a);
      pos += n;
      assert(pos <= a->size());
    }
    bool equal(iterator const &i) const {
      assert(a && i.a);
      return a == i.a && pos == i.pos;
    }
    parent_t::reference dereference() const {
      assert(a && pos < a->size());
      return a->get_element(pos);
    }
    parent_t::difference_type distance_to(iterator const &i) const {
      assert(a && a == i.a);
      typedef parent_t::difference_type diff_t;
      return static_cast<diff_t>(i.pos) - static_cast<diff_t>(pos);
    }
  };

  iterator begin() const { return iterator(*this); }
  iterator end()   const { return iterator(*this, length()); }
private:
  void check();
};

template<>
struct detail::convert<array> {
  typedef to_value_helper<array> to_value;

  struct from_value {
    boost::optional<root_array> root;

    array perform(value const &v) {
      root = boost::in_place(array(v.to_object()));
      return root.get();
    }
  };
};

}

#endif
<|endoftext|>