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

#ifndef xeumeuleu_locator_hpp
#define xeumeuleu_locator_hpp

#include <xeumeuleu/bridges/xerces/detail/xerces.hpp>
#include <xeumeuleu/bridges/xerces/detail/translate.hpp>
#include <xeumeuleu/bridges/xerces/detail/shared_string.hpp>
#include <sstream>

namespace xml
{
// =============================================================================
/** @class  locator
    @brief  Locator implementation
*/
// Created: MAT 2007-09-20
// =============================================================================
class locator : public XERCES_CPP_NAMESPACE::DOMLocator
{
public:
    //! @name Constructors/Destructor
    //@{
    locator( const shared_string& uri, const XERCES_CPP_NAMESPACE::XMLScanner& scanner )
        : uri_   ( uri )
        , line_  ( scanner.getLocator()->getLineNumber() )
        , column_( scanner.getLocator()->getColumnNumber() )
    {}
    locator( const shared_string& uri )
        : uri_   ( uri )
        , line_  ( 0 )
        , column_( 0 )
    {}
    locator( const locator& rhs )
        : XERCES_CPP_NAMESPACE::DOMLocator()
        , uri_   ( rhs.uri_ )
        , line_  ( rhs.line_ )
        , column_( rhs.column_ )
    {}
    locator( const XERCES_CPP_NAMESPACE::DOMLocator& rhs )
        : uri_   ( translate( rhs.getURI() ) )
        , line_  ( rhs.getLineNumber() )
        , column_( rhs.getColumnNumber() )
    {}
    virtual ~locator()
    {}
    //@}

    //! @name Accessors
    //@{
    virtual XMLFileLoc getLineNumber() const
    {
        return line_;
    }
    virtual XMLFileLoc getColumnNumber() const
    {
        return column_;
    }
#if XERCES_VERSION_MAJOR == 3
    virtual XMLFilePos getByteOffset() const
    {
        return 0;
    }
    virtual XMLFilePos getUtf16Offset() const
    {
        return 0;
    }
    virtual XERCES_CPP_NAMESPACE::DOMNode* getRelatedNode() const
    {
        return 0;
    }
#else
    virtual XMLFilePos getOffset() const
    {
        return -1;
    }
    virtual XERCES_CPP_NAMESPACE::DOMNode* getErrorNode() const
    {
        return 0;
    }
#endif // XERCES_VERSION_MAJOR
    virtual const XMLCh* getURI() const
    {
        return 0;
    }
    //@}

    //! @name Operators
    //@{
    operator std::string() const
    {
        std::stringstream stream;
        stream << " (line " << line_ << ", column " << column_ << ") : ";
        return uri_ + stream.str();
    }
    //@}

    //! @name Modifiers
    //@{
#if XERCES_VERSION_MAJOR < 3
    virtual void setLineNumber( const XMLSSize_t /*line*/ )
    {}
    virtual void setColumnNumber( const XMLSSize_t /*column*/ )
    {}
    virtual void setOffset( const XMLSSize_t /*offset*/ )
    {}
    virtual void setErrorNode( XERCES_CPP_NAMESPACE::DOMNode* const /*node*/ )
    {}
    virtual void setURI( const XMLCh* const /*uri*/ )
    {}
#endif // XERCES_VERSION_MAJOR
    //@}

private:
    //! @name Copy/Assignment
    //@{
    locator& operator=( const locator& ); //!< Assignment operator
    //@}

private:
    //! @name Member data
    //@{
    const shared_string uri_;
    const XMLFileLoc line_, column_;
    //@}
};

}

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

#ifndef xeumeuleu_locator_hpp
#define xeumeuleu_locator_hpp

#include <xeumeuleu/bridges/xerces/detail/xerces.hpp>
#include <xeumeuleu/bridges/xerces/detail/translate.hpp>
#include <xeumeuleu/bridges/xerces/detail/shared_string.hpp>
#include <sstream>

namespace xml
{
// =============================================================================
/** @class  locator
    @brief  Locator implementation
*/
// Created: MAT 2007-09-20
// =============================================================================
class locator
{
public:
    //! @name Constructors/Destructor
    //@{
    locator( const shared_string& uri, const XERCES_CPP_NAMESPACE::XMLScanner& scanner )
        : uri_   ( uri )
        , line_  ( scanner.getLocator()->getLineNumber() )
        , column_( scanner.getLocator()->getColumnNumber() )
    {}
    locator( const shared_string& uri )
        : uri_   ( uri )
        , line_  ( 0 )
        , column_( 0 )
    {}
    locator( const locator& rhs )
        : uri_   ( rhs.uri_ )
        , line_  ( rhs.line_ )
        , column_( rhs.column_ )
    {}
    locator( const XERCES_CPP_NAMESPACE::DOMLocator& rhs )
        : uri_   ( translate( rhs.getURI() ) )
        , line_  ( rhs.getLineNumber() )
        , column_( rhs.getColumnNumber() )
    {}
    //@}

    //! @name Operators
    //@{
    operator std::string() const
    {
        std::stringstream stream;
        stream << " (line " << line_ << ", column " << column_ << ") : ";
        return uri_ + stream.str();
    }
    //@}

private:
    //! @name Copy/Assignment
    //@{
    locator& operator=( const locator& ); //!< Assignment operator
    //@}

private:
    //! @name Member data
    //@{
    const shared_string uri_;
    const XMLFileLoc line_, column_;
    //@}
};

}

#endif // xeumeuleu_locator_hpp
<|endoftext|>


<commit_before>#include "GraphicalUI.hpp"
#include "defines.hpp"
#include "Board.hpp"
#include "Game.hpp"

#include <SFML/Graphics.hpp>
#include <iostream>

ui::GraphicalUI::GraphicalUI()
{
	windowExists = false;

    if (!respawn.loadAndSetTexture("../assets/respawn.png"))
    {
        std::cout << "No se pudo cargar respawn.png!" << std::endl;
    }

    if (!tower.loadAndSetTexture("../assets/tower.png"))
    {
        std::cout << "No se pudo cargar tower.png!" << std::endl;
    }

    if (!attackers.loadAndSetTexture("../assets/attackers.png"))
    {
        std::cout << "No se pudo cargar attackers.png!" << std::endl;
    }

    if (!defenders.loadAndSetTexture("../assets/defenders.png"))
    {
        std::cout << "No se pudo cargar defenders.png!" << std::endl;
    }

    float scaleFactor = 0.5;

    // We multiply by a constant factor to make it a little bit smaller.
    float scaleX = (1 / (respawn.texture.getSize().x / GRID_W)) * scaleFactor;
    float scaleY = (1 / (respawn.texture.getSize().y / GRID_H)) * scaleFactor;

    respawn.sprite.scale(scaleX, scaleY);

    // We center the sprite.
    respawn.sprite.setPosition(
        (GRID_W - respawn.texture.getSize().x * scaleX) * 0.5,
        (GRID_H - respawn.texture.getSize().y * scaleY) * 0.5
        );

    // We multiply by a constant factor to make it a little bit smaller.
    scaleX = (1 / (tower.texture.getSize().x / GRID_W)) * scaleFactor;
    scaleY = (1 / (tower.texture.getSize().y / GRID_H)) * scaleFactor;

    tower.sprite.scale(scaleX, scaleY);

    tower.sprite.setPosition(
        WINDOW_W - (GRID_W + tower.texture.getSize().x * scaleX) * 0.5,
        WINDOW_H - (GRID_H + tower.texture.getSize().y * scaleY) * 0.5
        );

    scaleX = (1 / (attackers.texture.getSize().x / GRID_W)) * scaleFactor;
    scaleY = (1 / (attackers.texture.getSize().y / GRID_H)) * scaleFactor;

    attackers.sprite.scale(scaleX, scaleY);

    scaleX = (1 / (defenders.texture.getSize().x / GRID_W)) * scaleFactor;
    scaleY = (1 / (defenders.texture.getSize().y / GRID_H)) * scaleFactor;

    defenders.sprite.scale(scaleX, scaleY);
}

void ui::GraphicalUI::create(int w, int h, int bpp)
{
	if (!windowExists)
	{
		renderWindow.create(sf::VideoMode(w, h, bpp), "TowDef-AI");
		windowExists = true;
	}
}

void ui::GraphicalUI::drawBoard()
{
    float lineThickness = 1.5;

    sf::RectangleShape lineH(sf::Vector2f(WINDOW_W, lineThickness));
    sf::RectangleShape lineV(sf::Vector2f(lineThickness, WINDOW_H));

    lineH.setFillColor(sf::Color::Black);
    lineV.setFillColor(sf::Color::Black);

    renderWindow.clear(sf::Color(229, 229, 229));

    // The space between each horizontal and vertical line.
    float lineHSpace = WINDOW_H / BOARD_H;
    float lineVSpace = WINDOW_W / BOARD_W;

    for (float i = lineHSpace; i <= WINDOW_H; i += lineHSpace)
    {
        renderWindow.draw(lineH);
        lineH.setPosition(0, i);
    }

    for (float i = lineVSpace; i <= WINDOW_W; i += lineVSpace)
    {
        renderWindow.draw(lineV);
        lineV.setPosition(i, 0);
    }

    lineH.setPosition(0, WINDOW_H - lineThickness);
    renderWindow.draw(lineH);

    lineV.setPosition(WINDOW_W - lineThickness, 0);
    renderWindow.draw(lineV);

    renderWindow.draw(respawn.sprite);
    renderWindow.draw(tower.sprite);
}

void ui::GraphicalUI::show(logic::Game* gameInstance)
{
	if (loopMethod == nullptr)
	{
		std::cout << "ui::show()==> No se establecio ningun metodo a ejecutar." << std::endl;
		return;
	}

	while (renderWindow.isOpen())
    {
        // check all the renderWindow's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (renderWindow.pollEvent(event))
        {
            // "close requested" event: we close the renderWindow
            if (event.type == sf::Event::Closed)
                renderWindow.close();
        }

        // We execute the game loop from the logic part of the game.
        if (!(gameInstance->*loopMethod)())
        {
            renderWindow.close();
        }

        // draw everything here...

        drawBoard();
        drawDefenders(gameInstance);

        // end the current frame
        renderWindow.display();
    }
}

void ui::GraphicalUI::drawDefenders(logic::Game* gameInstance)
{
    sf::Vector2f attScale = attackers.sprite.getScale();

    sf::Vector2f defScale = attackers.sprite.getScale();

    const logic::Board& board = gameInstance->getBoard();

    for (int i = 0; i < BOARD_W; i++)
    {
        for (int j = 0; j < BOARD_H; j++)
        {
            const std::vector<logic::Entity*>* entities = board.getEntitiesAt(i, j);

            if (entities == nullptr) continue;

            if (entities->size() != 0)
            {
                if ((*entities)[0]->getType() == logic::EntityType::ATTACK)
                {
                    attackers.sprite.setPosition(
                        (i * GRID_W) + (GRID_W - attackers.texture.getSize().x * attScale.x) * 0.5,
                        (j * GRID_H) + (GRID_H - attackers.texture.getSize().y * attScale.y) * 0.5
                        );

                    renderWindow.draw(attackers.sprite);
                }
                else if ((*entities)[0]->getType() == logic::EntityType::DEFENSE)
                {
                    defenders.sprite.setPosition(
                        (i * GRID_W) + (GRID_W - defenders.texture.getSize().x * defScale.x) * 0.5,
                        (j * GRID_H) + (GRID_H - defenders.texture.getSize().y * defScale.y) * 0.5
                        );

                    renderWindow.draw(defenders.sprite);
                }
            }
        }
    }
}

void ui::GraphicalUI::drawAttackers(logic::Game *gameInstance)
{

}<commit_msg>Now pressing Q will quit.<commit_after>#include "GraphicalUI.hpp"
#include "defines.hpp"
#include "Board.hpp"
#include "Game.hpp"

#include <SFML/Graphics.hpp>
#include <iostream>

ui::GraphicalUI::GraphicalUI()
{
	windowExists = false;

    if (!respawn.loadAndSetTexture("../assets/respawn.png"))
    {
        std::cout << "No se pudo cargar respawn.png!" << std::endl;
    }

    if (!tower.loadAndSetTexture("../assets/tower.png"))
    {
        std::cout << "No se pudo cargar tower.png!" << std::endl;
    }

    if (!attackers.loadAndSetTexture("../assets/attackers.png"))
    {
        std::cout << "No se pudo cargar attackers.png!" << std::endl;
    }

    if (!defenders.loadAndSetTexture("../assets/defenders.png"))
    {
        std::cout << "No se pudo cargar defenders.png!" << std::endl;
    }

    float scaleFactor = 0.5;

    // We multiply by a constant factor to make it a little bit smaller.
    float scaleX = (1 / (respawn.texture.getSize().x / GRID_W)) * scaleFactor;
    float scaleY = (1 / (respawn.texture.getSize().y / GRID_H)) * scaleFactor;

    respawn.sprite.scale(scaleX, scaleY);

    // We center the sprite.
    respawn.sprite.setPosition(
        (GRID_W - respawn.texture.getSize().x * scaleX) * 0.5,
        (GRID_H - respawn.texture.getSize().y * scaleY) * 0.5
        );

    // We multiply by a constant factor to make it a little bit smaller.
    scaleX = (1 / (tower.texture.getSize().x / GRID_W)) * scaleFactor;
    scaleY = (1 / (tower.texture.getSize().y / GRID_H)) * scaleFactor;

    tower.sprite.scale(scaleX, scaleY);

    tower.sprite.setPosition(
        WINDOW_W - (GRID_W + tower.texture.getSize().x * scaleX) * 0.5,
        WINDOW_H - (GRID_H + tower.texture.getSize().y * scaleY) * 0.5
        );

    scaleX = (1 / (attackers.texture.getSize().x / GRID_W)) * scaleFactor;
    scaleY = (1 / (attackers.texture.getSize().y / GRID_H)) * scaleFactor;

    attackers.sprite.scale(scaleX, scaleY);

    scaleX = (1 / (defenders.texture.getSize().x / GRID_W)) * scaleFactor;
    scaleY = (1 / (defenders.texture.getSize().y / GRID_H)) * scaleFactor;

    defenders.sprite.scale(scaleX, scaleY);
}

void ui::GraphicalUI::create(int w, int h, int bpp)
{
	if (!windowExists)
	{
		renderWindow.create(sf::VideoMode(w, h, bpp), "TowDef-AI");
		windowExists = true;
	}
}

void ui::GraphicalUI::drawBoard()
{
    float lineThickness = 1.5;

    sf::RectangleShape lineH(sf::Vector2f(WINDOW_W, lineThickness));
    sf::RectangleShape lineV(sf::Vector2f(lineThickness, WINDOW_H));

    lineH.setFillColor(sf::Color::Black);
    lineV.setFillColor(sf::Color::Black);

    renderWindow.clear(sf::Color(229, 229, 229));

    // The space between each horizontal and vertical line.
    float lineHSpace = WINDOW_H / BOARD_H;
    float lineVSpace = WINDOW_W / BOARD_W;

    for (float i = lineHSpace; i <= WINDOW_H; i += lineHSpace)
    {
        renderWindow.draw(lineH);
        lineH.setPosition(0, i);
    }

    for (float i = lineVSpace; i <= WINDOW_W; i += lineVSpace)
    {
        renderWindow.draw(lineV);
        lineV.setPosition(i, 0);
    }

    lineH.setPosition(0, WINDOW_H - lineThickness);
    renderWindow.draw(lineH);

    lineV.setPosition(WINDOW_W - lineThickness, 0);
    renderWindow.draw(lineV);

    renderWindow.draw(respawn.sprite);
    renderWindow.draw(tower.sprite);
}

void ui::GraphicalUI::show(logic::Game* gameInstance)
{
	if (loopMethod == nullptr)
	{
		std::cout << "ui::show()==> No se establecio ningun metodo a ejecutar." << std::endl;
		return;
	}

	while (renderWindow.isOpen())
    {
        // check all the renderWindow's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (renderWindow.pollEvent(event))
        {
            // "close requested" event: we close the renderWindow
            if (event.type == sf::Event::Closed)
                renderWindow.close();

            if (event.type == sf::Event::KeyPressed)
            {
                if (event.key.code == sf::Keyboard::Q)
                {
                    renderWindow.close();
                }
            }
        }

        // We execute the game loop from the logic part of the game.
        if (!(gameInstance->*loopMethod)())
        {
            renderWindow.close();
        }

        // draw everything here...

        drawBoard();
        drawDefenders(gameInstance);

        // end the current frame
        renderWindow.display();
    }
}

void ui::GraphicalUI::drawDefenders(logic::Game* gameInstance)
{
    sf::Vector2f attScale = attackers.sprite.getScale();

    sf::Vector2f defScale = attackers.sprite.getScale();

    const logic::Board& board = gameInstance->getBoard();

    for (int i = 0; i < BOARD_W; i++)
    {
        for (int j = 0; j < BOARD_H; j++)
        {
            const std::vector<logic::Entity*>* entities = board.getEntitiesAt(i, j);

            if (entities == nullptr) continue;

            if (entities->size() != 0)
            {
                if ((*entities)[0]->getType() == logic::EntityType::ATTACK)
                {
                    attackers.sprite.setPosition(
                        (i * GRID_W) + (GRID_W - attackers.texture.getSize().x * attScale.x) * 0.5,
                        (j * GRID_H) + (GRID_H - attackers.texture.getSize().y * attScale.y) * 0.5
                        );

                    renderWindow.draw(attackers.sprite);
                }
                else if ((*entities)[0]->getType() == logic::EntityType::DEFENSE)
                {
                    defenders.sprite.setPosition(
                        (i * GRID_W) + (GRID_W - defenders.texture.getSize().x * defScale.x) * 0.5,
                        (j * GRID_H) + (GRID_H - defenders.texture.getSize().y * defScale.y) * 0.5
                        );

                    renderWindow.draw(defenders.sprite);
                }
            }
        }
    }
}

void ui::GraphicalUI::drawAttackers(logic::Game *gameInstance)
{

}<|endoftext|>


<commit_before>#include "StateMachine.h"
#include <algorithm>
#define THREADLESS_STATEMACHINE
bool DriveInstruction::aimTarget(const ObjectPosition &target, Speed &speed, double errorMargin){
	double heading = target.getHeading();
	double distance = target.getDistance();
	if (fabs(heading) > errorMargin){
		speed.rotation = -sign0(heading) * std::min(40.0, std::max(5*log(fabs(heading)), 5.0));
		return false;
	}
	else return fabs(heading) < errorMargin;
}
bool DriveInstruction::catchTarget(const ObjectPosition &target, Speed &speed){
	if (m_pCom->BallInTribbler()) return true;
	double heading = target.getHeading();
	double dist = target.getDistance();
	speed.velocity = 60;
	speed.heading = 0;
	return false;
}

bool DriveInstruction::driveToTarget(const ObjectPosition &target, Speed &speed, double maxDistance){
	double dist = target.getDistance();
	if (dist > maxDistance){
		speed.velocity = std::max(20.0, dist);
		return false;
	}
	else{
		speed.velocity = 20;
		return true;
	}
}

bool DriveInstruction::driveToTargetWithAngle(const ObjectPosition &target, Speed &speed, double maxDistance, double errorMargin){
	double heading = target.getHeading();
	double dist = target.getDistance();
	double velocity = 0;
	double direction = 0;
	double angularSpeed = 0;
	bool onPoint = false;
	if (fabs(heading) > errorMargin){
		if (dist > maxDistance){
			velocity = std::max(30.0, dist); //max speed is limited to 190 in wheelController.cpp
			direction = heading; //drive towards target
			angularSpeed = sign0(heading) * 20; //meanwhile rotate slowly to face the target
		}
		else{ //at location but facing wrong way
			angularSpeed = sign0(heading) * std::max(fabs(heading) * 0.5, 10.0); //rotate
		}
	}
	else{
		if (dist > maxDistance){
			velocity = std::max(30.0, dist);
			direction = heading; //drive towards target
		}
		else onPoint = true;
	}
	speed.velocity = velocity;
	speed.heading = direction;
	speed.rotation = -angularSpeed;
	return onPoint;
}

const BallPosition &DriveInstruction::getClosestBall(bool includeHeading, bool reset){
	return  m_pFieldState->balls.getClosest();
}

StateMachine::StateMachine(ICommunicationModule *pComModule, FieldState *pState,
	const std::map<DriveMode, DriveInstruction*> &driveModes) :driveModes(driveModes), ThreadedClass("Autopilot/StateMachine")
{
	m_pComModule = pComModule;
	m_pFieldState = pState;
	for (auto driveMode : driveModes) driveMode.second->Init(pComModule, pState);
	curDriveMode = this->driveModes.find(DRIVEMODE_IDLE);

}

void StateMachine::setTestMode(DriveMode mode){ testDriveMode = mode; }

void StateMachine::enableTestMode(bool enable)
{
	setTestMode(DRIVEMODE_IDLE);
	testMode = enable;
	if (!testMode) m_pComModule->Drive(0, 0, 0);
}

void StateMachine::StepOnce()
{
#ifdef THREADLESS_STATEMACHINE
	if (!running) return;

	boost::posix_time::ptime time = boost::posix_time::microsec_clock::local_time();
		boost::posix_time::time_duration::tick_type dt = (time - lastStep).total_milliseconds();
		DriveMode newMode = testMode ? curDriveMode->second->step2(double(dt), newMode) : curDriveMode->second->step1(double(dt), newMode);
		auto old = curDriveMode;
		if (testMode){
			if (testDriveMode != DRIVEMODE_IDLE && newMode == DRIVEMODE_IDLE) newMode = testDriveMode;
			else if (newMode != testDriveMode) {
				newMode = DRIVEMODE_IDLE;
				testDriveMode = DRIVEMODE_IDLE;
			}
		}

		if (newMode != curDriveMode->first){
			boost::mutex::scoped_lock lock(mutex);
			std::cout << "state: " << curDriveMode->second->name;

			curDriveMode->second->onExit();
			curDriveMode = driveModes.find(newMode);
			if (curDriveMode == driveModes.end()){
				curDriveMode = driveModes.find(DRIVEMODE_IDLE);
				std::cout << "-> unknown state: " << newMode << std::endl;
			}
			std::cout << " -> " << curDriveMode->second->name << std::endl;

			curDriveMode->second->onEnter1();
		}
#else
#endif
}

void StateMachine::Run()
{
	lastStep = boost::posix_time::microsec_clock::local_time();
	DriveMode newMode = curDriveMode->first;
	curDriveMode->second->onEnter();
	while (!stop_thread) {
#ifdef THREADLESS_STATEMACHINE
		Sleep(100);
		continue;
#else
		// StepOnce is called from FrontCameraVision
		boost::posix_time::ptime time = boost::posix_time::microsec_clock::local_time();
		boost::posix_time::time_duration::tick_type dt = (time - lastStep).total_milliseconds();
		newMode = testMode ? curDriveMode->second->step2(double(dt), newMode) : curDriveMode->second->step1(double(dt), newMode);
		auto old = curDriveMode;
		if (testMode){
			if (testDriveMode != DRIVEMODE_IDLE && newMode == DRIVEMODE_IDLE) newMode = testDriveMode;
			else if (newMode != testDriveMode) {
				//newMode = DRIVEMODE_IDLE;
				//testDriveMode = DRIVEMODE_IDLE;
			}
		}

		if (newMode != curDriveMode->first){
			boost::mutex::scoped_lock lock(mutex);
			std::cout << "state: " << curDriveMode->second->name;

			curDriveMode->second->onExit();
			curDriveMode = driveModes.find(newMode);
			if (curDriveMode == driveModes.end()){
				curDriveMode = driveModes.find(DRIVEMODE_IDLE);
				std::cout << "-> unknown state: " << newMode << std::endl;
			}
			std::cout << " -> " << curDriveMode->second->name << std::endl;

			curDriveMode->second->onEnter1();
			std::this_thread::sleep_for(std::chrono::milliseconds(50)); // this seems to be neccecary
		}
#endif
	}
}

std::string StateMachine::GetDebugInfo(){
	std::ostringstream oss;
	boost::mutex::scoped_lock lock(mutex);
	oss << "[StateMachine] State: " << curDriveMode->second->name;
	return oss.str();
}

StateMachine::~StateMachine()
{
	WaitForStop();
	for (auto &mode : driveModes){ delete mode.second; }
}

DriveMode DriveInstruction::prevDriveMode = DRIVEMODE_IDLE;
DriveMode DriveInstruction::ACTIVE_DRIVE_TO_BALL_MODE = DRIVEMODE_IDLE;
cv::Point2d DriveInstruction::lastBallPos = cv::Point2d(0,0);

<commit_msg>newMode init restored in THREADLESS_STATREMACHINE<commit_after>#include "StateMachine.h"
#include <algorithm>
#define THREADLESS_STATEMACHINE
bool DriveInstruction::aimTarget(const ObjectPosition &target, Speed &speed, double errorMargin){
	double heading = target.getHeading();
	double distance = target.getDistance();
	if (fabs(heading) > errorMargin){
		speed.rotation = -sign0(heading) * std::min(40.0, std::max(5*log(fabs(heading)), 5.0));
		return false;
	}
	else return fabs(heading) < errorMargin;
}
bool DriveInstruction::catchTarget(const ObjectPosition &target, Speed &speed){
	if (m_pCom->BallInTribbler()) return true;
	double heading = target.getHeading();
	double dist = target.getDistance();
	speed.velocity = 60;
	speed.heading = 0;
	return false;
}

bool DriveInstruction::driveToTarget(const ObjectPosition &target, Speed &speed, double maxDistance){
	double dist = target.getDistance();
	if (dist > maxDistance){
		speed.velocity = std::max(20.0, dist);
		return false;
	}
	else{
		speed.velocity = 20;
		return true;
	}
}

bool DriveInstruction::driveToTargetWithAngle(const ObjectPosition &target, Speed &speed, double maxDistance, double errorMargin){
	double heading = target.getHeading();
	double dist = target.getDistance();
	double velocity = 0;
	double direction = 0;
	double angularSpeed = 0;
	bool onPoint = false;
	if (fabs(heading) > errorMargin){
		if (dist > maxDistance){
			velocity = std::max(30.0, dist); //max speed is limited to 190 in wheelController.cpp
			direction = heading; //drive towards target
			angularSpeed = sign0(heading) * 20; //meanwhile rotate slowly to face the target
		}
		else{ //at location but facing wrong way
			angularSpeed = sign0(heading) * std::max(fabs(heading) * 0.5, 10.0); //rotate
		}
	}
	else{
		if (dist > maxDistance){
			velocity = std::max(30.0, dist);
			direction = heading; //drive towards target
		}
		else onPoint = true;
	}
	speed.velocity = velocity;
	speed.heading = direction;
	speed.rotation = -angularSpeed;
	return onPoint;
}

const BallPosition &DriveInstruction::getClosestBall(bool includeHeading, bool reset){
	return  m_pFieldState->balls.getClosest();
}

StateMachine::StateMachine(ICommunicationModule *pComModule, FieldState *pState,
	const std::map<DriveMode, DriveInstruction*> &driveModes) :driveModes(driveModes), ThreadedClass("Autopilot/StateMachine")
{
	m_pComModule = pComModule;
	m_pFieldState = pState;
	for (auto driveMode : driveModes) driveMode.second->Init(pComModule, pState);
	curDriveMode = this->driveModes.find(DRIVEMODE_IDLE);

}

void StateMachine::setTestMode(DriveMode mode){ testDriveMode = mode; }

void StateMachine::enableTestMode(bool enable)
{
	setTestMode(DRIVEMODE_IDLE);
	testMode = enable;
	if (!testMode) m_pComModule->Drive(0, 0, 0);
}

void StateMachine::StepOnce()
{
#ifdef THREADLESS_STATEMACHINE

	if (!running) return;
	DriveMode newMode = curDriveMode->first;
	curDriveMode->second->onEnter();

	boost::posix_time::ptime time = boost::posix_time::microsec_clock::local_time();
	boost::posix_time::time_duration::tick_type dt = (time - lastStep).total_milliseconds();
	newMode = testMode ? curDriveMode->second->step2(double(dt), newMode) : curDriveMode->second->step1(double(dt), newMode);
	auto old = curDriveMode;
	if (testMode){
		if (testDriveMode != DRIVEMODE_IDLE && newMode == DRIVEMODE_IDLE) newMode = testDriveMode;
		else if (newMode != testDriveMode) {
			newMode = DRIVEMODE_IDLE;
			testDriveMode = DRIVEMODE_IDLE;
		}
	}

	if (newMode != curDriveMode->first){
		boost::mutex::scoped_lock lock(mutex);
		std::cout << "state: " << curDriveMode->second->name;

		curDriveMode->second->onExit();
		curDriveMode = driveModes.find(newMode);
		if (curDriveMode == driveModes.end()){
			curDriveMode = driveModes.find(DRIVEMODE_IDLE);
			std::cout << "-> unknown state: " << newMode << std::endl;
		}
		std::cout << " -> " << curDriveMode->second->name << std::endl;

		curDriveMode->second->onEnter1();
	}
#else
#endif
}

void StateMachine::Run()
{
	lastStep = boost::posix_time::microsec_clock::local_time();
	DriveMode newMode = curDriveMode->first;
	curDriveMode->second->onEnter();
	while (!stop_thread) {
#ifdef THREADLESS_STATEMACHINE
		Sleep(100);
		continue;
#else
		// StepOnce is called from FrontCameraVision
		boost::posix_time::ptime time = boost::posix_time::microsec_clock::local_time();
		boost::posix_time::time_duration::tick_type dt = (time - lastStep).total_milliseconds();
		newMode = testMode ? curDriveMode->second->step2(double(dt), newMode) : curDriveMode->second->step1(double(dt), newMode);
		auto old = curDriveMode;
		if (testMode){
			if (testDriveMode != DRIVEMODE_IDLE && newMode == DRIVEMODE_IDLE) newMode = testDriveMode;
			else if (newMode != testDriveMode) {
				//newMode = DRIVEMODE_IDLE;
				//testDriveMode = DRIVEMODE_IDLE;
			}
		}

		if (newMode != curDriveMode->first){
			boost::mutex::scoped_lock lock(mutex);
			std::cout << "state: " << curDriveMode->second->name;

			curDriveMode->second->onExit();
			curDriveMode = driveModes.find(newMode);
			if (curDriveMode == driveModes.end()){
				curDriveMode = driveModes.find(DRIVEMODE_IDLE);
				std::cout << "-> unknown state: " << newMode << std::endl;
			}
			std::cout << " -> " << curDriveMode->second->name << std::endl;

			curDriveMode->second->onEnter1();
			std::this_thread::sleep_for(std::chrono::milliseconds(50)); // this seems to be neccecary
		}
#endif
	}
}

std::string StateMachine::GetDebugInfo(){
	std::ostringstream oss;
	boost::mutex::scoped_lock lock(mutex);
	oss << "[StateMachine] State: " << curDriveMode->second->name;
	return oss.str();
}

StateMachine::~StateMachine()
{
	WaitForStop();
	for (auto &mode : driveModes){ delete mode.second; }
}

DriveMode DriveInstruction::prevDriveMode = DRIVEMODE_IDLE;
DriveMode DriveInstruction::ACTIVE_DRIVE_TO_BALL_MODE = DRIVEMODE_IDLE;
cv::Point2d DriveInstruction::lastBallPos = cv::Point2d(0,0);

<|endoftext|>


<commit_before>#include "antsUtilities.h"
#include <algorithm>

#include "itkBSplineScatteredDataPointSetToImageFilter.h"
#include "itkContinuousIndex.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "itkImportImageFilter.h"
#include "itkPointSet.h"
#include "itkTimeProbe.h"
#include "itkVector.h"
#include "itkVectorIndexSelectionCastImageFilter.h"

#include "ReadWriteData.h"

namespace ants
{
template <unsigned int ImageDimension>
int SuperResolution( unsigned int argc, char *argv[] )
{

  typedef float                                   RealType;
  typedef itk::Image<RealType, ImageDimension>    ImageType;

  typedef itk::Vector<RealType, 1>                         ScalarType;
  typedef itk::Image<ScalarType, ImageDimension>           ScalarImageType;
  typedef itk::PointSet<ScalarType, ImageDimension>        PointSetType;
  typedef itk::BSplineScatteredDataPointSetToImageFilter
    <PointSetType, ScalarImageType>                        BSplineFilterType;

  typename ImageType::Pointer domainImage = ITK_NULLPTR;
  ReadImage<ImageType>( domainImage, argv[3] );

  typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New();

  typename PointSetType::Pointer bsplinePoints = PointSetType::New();
  bsplinePoints->Initialize();

  typename BSplineFilterType::WeightsContainerType::Pointer weights =
    BSplineFilterType::WeightsContainerType::New();
  weights->Initialize();

  unsigned int splineOrder = 3;
  typename BSplineFilterType::ArrayType numberOfLevels;
  typename BSplineFilterType::ArrayType ncps;

  std::vector<unsigned int> nlevels = ConvertVector<unsigned int>( std::string( argv[5] ) );
  if ( nlevels.size() == 1 )
    {
    numberOfLevels.Fill( nlevels[0] );
    }
  else if ( nlevels.size() == ImageDimension )
    {
    for ( unsigned int d = 0; d < ImageDimension; d++ )
      {
      numberOfLevels[d] = nlevels[d];
      }
    }
  else
    {
    std::cerr << "Invalid nlevels format." << std::endl;
    return EXIT_FAILURE;
    }

  std::vector<unsigned int> meshSize = ConvertVector<unsigned int>( std::string( argv[4] ) );
  if ( meshSize.size() == 1 )
    {
    ncps.Fill( meshSize[0] + splineOrder );
    }
  else if ( meshSize.size() == ImageDimension )
    {
    for ( unsigned int d = 0; d < ImageDimension; d++ )
      {
      ncps[d] = meshSize[d] + splineOrder;
      }
    }
  else
    {
    std::cerr << "Invalid ncps format." << std::endl;
    return EXIT_FAILURE;
    }

  typename ScalarImageType::DirectionType identity;
  identity.SetIdentity();

  const typename ScalarImageType::RegionType & bufferedRegion = domainImage->GetBufferedRegion();
  const itk::SizeValueType numberOfPixels = bufferedRegion.GetNumberOfPixels();
  const bool filterHandlesMemory = false;

  typedef itk::ImportImageFilter<RealType, ImageDimension> ImporterType;
  typename ImporterType::Pointer importer = ImporterType::New();
  importer->SetImportPointer( domainImage->GetBufferPointer(), numberOfPixels, filterHandlesMemory );
  importer->SetRegion( domainImage->GetBufferedRegion() );
  importer->SetOrigin( domainImage->GetOrigin() );
  importer->SetSpacing( domainImage->GetSpacing() );
  importer->SetDirection( identity );
  importer->Update();

  typename ImageType::IndexType domainBeginIndex = domainImage->GetRequestedRegion().GetIndex();
  typename ImageType::IndexType domainEndIndex;
  for( unsigned int d = 0; d < ImageDimension; d++ )
    {
    domainEndIndex[d] = domainBeginIndex[d] + domainImage->GetRequestedRegion().GetSize()[d] - 1;
    }

  const typename ImporterType::OutputImageType * parametricDomainImage = importer->GetOutput();

  unsigned int N = 0;
  for( unsigned int n = 6; n < argc; n++ )
    {
    typename ImageType::Pointer inputImage = ITK_NULLPTR;
    ReadImage<ImageType>( inputImage, argv[n] );

    itk::ImageRegionConstIteratorWithIndex<ImageType> It( inputImage, inputImage->GetRequestedRegion() );
    for( It.GoToBegin(); !It.IsAtEnd(); ++It )
      {
      typename ImageType::PointType imagePoint;
      inputImage->TransformIndexToPhysicalPoint( It.GetIndex(), imagePoint );

      itk::ContinuousIndex<RealType, ImageDimension> cidx;
      bool isInside = domainImage->TransformPhysicalPointToContinuousIndex( imagePoint, cidx );

      if( isInside )
        {
        for( unsigned int d = 0; d < ImageDimension; d++ )
          {
          if( cidx[d] <= domainBeginIndex[d] || cidx[d] >= domainEndIndex[d] )
            {
            isInside = false;
            break;
            }
          }
        }

      if( !isInside )
        {
        continue;
        }

//       domainImage->SetPixel( index, 1 );

      parametricDomainImage->TransformContinuousIndexToPhysicalPoint( cidx, imagePoint );

      ScalarType scalar;
      scalar[0] = It.Get();

      bsplinePoints->SetPointData( N, scalar );
      bsplinePoints->SetPoint( N, imagePoint );
      weights->InsertElement( N, 1 );

      N++;
      }
    }

  std::cout << bsplinePoints->GetNumberOfPoints() << std::endl;

  itk::TimeProbe timer;
  timer.Start();

  typename ScalarImageType::PointType parametricOrigin = domainImage->GetOrigin();
  for( unsigned int d = 0; d < ImageDimension; d++ )
    {
    parametricOrigin[d] += (
        domainImage->GetSpacing()[d] *
        domainImage->GetLargestPossibleRegion().GetIndex()[d] );
    }

  bspliner->SetOrigin( parametricOrigin );
  bspliner->SetSpacing( domainImage->GetSpacing() );
  bspliner->SetSize( domainImage->GetRequestedRegion().GetSize() );
  bspliner->SetDirection( domainImage->GetDirection() );
  bspliner->SetGenerateOutputImage( true );
  bspliner->SetNumberOfLevels( numberOfLevels );
  bspliner->SetSplineOrder( splineOrder );
  bspliner->SetNumberOfControlPoints( ncps );
  bspliner->SetInput( bsplinePoints );
  bspliner->SetPointWeights( weights );
  bspliner->Update();

  timer.Stop();

  std::cout << "Elapsed Time:  " << timer.GetMean() << std::endl;

  typedef itk::VectorIndexSelectionCastImageFilter<ScalarImageType, ImageType> SelectorType;
  typename SelectorType::Pointer selector = SelectorType::New();
  selector->SetInput( bspliner->GetOutput() );
  selector->SetIndex( 0 );
  selector->Update();

  WriteImage<ImageType>( selector->GetOutput(), argv[2] );

  return EXIT_SUCCESS;
}

// entry point for the library; parameter 'args' is equivalent to 'argv' in (argc,argv) of commandline parameters to
// 'main()'
int SuperResolution( std::vector<std::string> args, std::ostream* /*out_stream = NULL */ )
{
  // put the arguments coming in as 'args' into standard (argc,argv) format;
  // 'args' doesn't have the command name as first, argument, so add it manually;
  // 'args' may have adjacent arguments concatenated into one argument,
  // which the parser should handle
  args.insert( args.begin(), "SuperResolution" );

  int     argc = args.size();
  char* * argv = new char *[args.size() + 1];
  for( unsigned int i = 0; i < args.size(); ++i )
    {
    // allocate space for the string plus a null character
    argv[i] = new char[args[i].length() + 1];
    std::strncpy( argv[i], args[i].c_str(), args[i].length() );
    // place the null character in the end
    argv[i][args[i].length()] = '\0';
    }
  argv[argc] = ITK_NULLPTR;
  // class to automatically cleanup argv upon destruction
  class Cleanup_argv
  {
public:
    Cleanup_argv( char* * argv_, int argc_plus_one_ ) : argv( argv_ ), argc_plus_one( argc_plus_one_ )
    {
    }

    ~Cleanup_argv()
    {
      for( unsigned int i = 0; i < argc_plus_one; ++i )
        {
        delete[] argv[i];
        }
      delete[] argv;
    }

private:
    char* *      argv;
    unsigned int argc_plus_one;
  };
  Cleanup_argv cleanup_argv( argv, argc + 1 );

  // antscout->set_stream( out_stream );

  if ( argc < 7 )
    {
    std::cerr << argv[0] << " imageDimension outputImage domainImage meshSize numberOfLevels inputImage1 ... inputImageN" << std::endl;

    if( argc >= 2 &&
        ( std::string( argv[1] ) == std::string("--help") || std::string( argv[1] ) == std::string("-h") ) )
      {
      return EXIT_SUCCESS;
      }
    return EXIT_FAILURE;
    }

  const int ImageDimension = static_cast<int>( atoi( argv[1] ) );

  switch( ImageDimension )
     {
     case 2:
       return SuperResolution<2>( argc, argv );
       break;
     case 3:
       return SuperResolution<3>( argc, argv );
       break;
     case 4:
       return SuperResolution<4>( argc, argv );
       break;
     default:
        std::cerr << "Unsupported dimension" << std::endl;
        exit( EXIT_FAILURE );
     }
  return EXIT_SUCCESS;
}
} // namespace ants

<commit_msg>BUG:  Didn't get phyiscal domain correct.<commit_after>#include "antsUtilities.h"
#include <algorithm>

#include "itkBSplineScatteredDataPointSetToImageFilter.h"
#include "itkContinuousIndex.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "itkImportImageFilter.h"
#include "itkPointSet.h"
#include "itkTimeProbe.h"
#include "itkVector.h"
#include "itkVectorIndexSelectionCastImageFilter.h"

#include "ReadWriteData.h"

namespace ants
{
template <unsigned int ImageDimension>
int SuperResolution( unsigned int argc, char *argv[] )
{

  typedef float                                   RealType;
  typedef itk::Image<RealType, ImageDimension>    ImageType;

  typedef itk::Vector<RealType, 1>                         ScalarType;
  typedef itk::Image<ScalarType, ImageDimension>           ScalarImageType;
  typedef itk::PointSet<ScalarType, ImageDimension>        PointSetType;
  typedef itk::BSplineScatteredDataPointSetToImageFilter
    <PointSetType, ScalarImageType>                        BSplineFilterType;

  typename ImageType::Pointer domainImage = ITK_NULLPTR;
  ReadImage<ImageType>( domainImage, argv[3] );

  typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New();

  typename PointSetType::Pointer bsplinePoints = PointSetType::New();
  bsplinePoints->Initialize();

  typename BSplineFilterType::WeightsContainerType::Pointer weights =
    BSplineFilterType::WeightsContainerType::New();
  weights->Initialize();

  unsigned int splineOrder = 3;
  typename BSplineFilterType::ArrayType numberOfLevels;
  typename BSplineFilterType::ArrayType ncps;

  std::vector<unsigned int> nlevels = ConvertVector<unsigned int>( std::string( argv[5] ) );
  if ( nlevels.size() == 1 )
    {
    numberOfLevels.Fill( nlevels[0] );
    }
  else if ( nlevels.size() == ImageDimension )
    {
    for ( unsigned int d = 0; d < ImageDimension; d++ )
      {
      numberOfLevels[d] = nlevels[d];
      }
    }
  else
    {
    std::cerr << "Invalid nlevels format." << std::endl;
    return EXIT_FAILURE;
    }

  std::vector<unsigned int> meshSize = ConvertVector<unsigned int>( std::string( argv[4] ) );
  if ( meshSize.size() == 1 )
    {
    ncps.Fill( meshSize[0] + splineOrder );
    }
  else if ( meshSize.size() == ImageDimension )
    {
    for ( unsigned int d = 0; d < ImageDimension; d++ )
      {
      ncps[d] = meshSize[d] + splineOrder;
      }
    }
  else
    {
    std::cerr << "Invalid ncps format." << std::endl;
    return EXIT_FAILURE;
    }

  typename ScalarImageType::DirectionType identity;
  identity.SetIdentity();

  const typename ScalarImageType::RegionType & bufferedRegion = domainImage->GetBufferedRegion();
  const itk::SizeValueType numberOfPixels = bufferedRegion.GetNumberOfPixels();
  const bool filterHandlesMemory = false;

  typedef itk::ImportImageFilter<RealType, ImageDimension> ImporterType;
  typename ImporterType::Pointer importer = ImporterType::New();
  importer->SetImportPointer( domainImage->GetBufferPointer(), numberOfPixels, filterHandlesMemory );
  importer->SetRegion( domainImage->GetBufferedRegion() );
  importer->SetOrigin( domainImage->GetOrigin() );
  importer->SetSpacing( domainImage->GetSpacing() );
  importer->SetDirection( identity );
  importer->Update();

  typename ImageType::IndexType domainBeginIndex = domainImage->GetRequestedRegion().GetIndex();
  typename ImageType::IndexType domainEndIndex;
  for( unsigned int d = 0; d < ImageDimension; d++ )
    {
    domainEndIndex[d] = domainBeginIndex[d] + domainImage->GetRequestedRegion().GetSize()[d] - 1;
    }

  const typename ImporterType::OutputImageType * parametricDomainImage = importer->GetOutput();

  unsigned int N = 0;
  for( unsigned int n = 6; n < argc; n++ )
    {
    typename ImageType::Pointer inputImage = ITK_NULLPTR;
    ReadImage<ImageType>( inputImage, argv[n] );

    itk::ImageRegionConstIteratorWithIndex<ImageType> It( inputImage, inputImage->GetRequestedRegion() );
    for( It.GoToBegin(); !It.IsAtEnd(); ++It )
      {
      typename ImageType::PointType imagePoint;
      inputImage->TransformIndexToPhysicalPoint( It.GetIndex(), imagePoint );

      itk::ContinuousIndex<RealType, ImageDimension> cidx;
      bool isInside = domainImage->TransformPhysicalPointToContinuousIndex( imagePoint, cidx );

      if( isInside )
        {
        for( unsigned int d = 0; d < ImageDimension; d++ )
          {
          if( cidx[d] <= domainBeginIndex[d] || cidx[d] >= domainEndIndex[d] )
            {
            isInside = false;
            break;
            }
          }
        }

      if( !isInside )
        {
        continue;
        }

//       domainImage->SetPixel( index, 1 );

      parametricDomainImage->TransformContinuousIndexToPhysicalPoint( cidx, imagePoint );

      ScalarType scalar;
      scalar[0] = It.Get();

      bsplinePoints->SetPointData( N, scalar );
      bsplinePoints->SetPoint( N, imagePoint );
      weights->InsertElement( N, 1 );

      N++;
      }
    }

  itk::TimeProbe timer;
  timer.Start();

  typename ScalarImageType::PointType parametricOrigin = domainImage->GetOrigin();
  for( unsigned int d = 0; d < ImageDimension; d++ )
    {
    parametricOrigin[d] += (
        domainImage->GetSpacing()[d] *
        domainImage->GetLargestPossibleRegion().GetIndex()[d] );
    }

  bspliner->SetOrigin( parametricOrigin );
  bspliner->SetSpacing( domainImage->GetSpacing() );
  bspliner->SetSize( domainImage->GetRequestedRegion().GetSize() );
  bspliner->SetDirection( domainImage->GetDirection() );
  bspliner->SetGenerateOutputImage( true );
  bspliner->SetNumberOfLevels( numberOfLevels );
  bspliner->SetSplineOrder( splineOrder );
  bspliner->SetNumberOfControlPoints( ncps );
  bspliner->SetInput( bsplinePoints );
  bspliner->SetPointWeights( weights );
  bspliner->Update();

  timer.Stop();

  std::cout << "Elapsed Time:  " << timer.GetMean() << std::endl;

  typedef itk::VectorIndexSelectionCastImageFilter<ScalarImageType, ImageType> SelectorType;
  typename SelectorType::Pointer selector = SelectorType::New();
  selector->SetInput( bspliner->GetOutput() );
  selector->SetIndex( 0 );
  selector->Update();

  WriteImage<ImageType>( selector->GetOutput(), argv[2] );

  return EXIT_SUCCESS;
}

// entry point for the library; parameter 'args' is equivalent to 'argv' in (argc,argv) of commandline parameters to
// 'main()'
int SuperResolution( std::vector<std::string> args, std::ostream* /*out_stream = NULL */ )
{
  // put the arguments coming in as 'args' into standard (argc,argv) format;
  // 'args' doesn't have the command name as first, argument, so add it manually;
  // 'args' may have adjacent arguments concatenated into one argument,
  // which the parser should handle
  args.insert( args.begin(), "SuperResolution" );

  int     argc = args.size();
  char* * argv = new char *[args.size() + 1];
  for( unsigned int i = 0; i < args.size(); ++i )
    {
    // allocate space for the string plus a null character
    argv[i] = new char[args[i].length() + 1];
    std::strncpy( argv[i], args[i].c_str(), args[i].length() );
    // place the null character in the end
    argv[i][args[i].length()] = '\0';
    }
  argv[argc] = ITK_NULLPTR;
  // class to automatically cleanup argv upon destruction
  class Cleanup_argv
  {
public:
    Cleanup_argv( char* * argv_, int argc_plus_one_ ) : argv( argv_ ), argc_plus_one( argc_plus_one_ )
    {
    }

    ~Cleanup_argv()
    {
      for( unsigned int i = 0; i < argc_plus_one; ++i )
        {
        delete[] argv[i];
        }
      delete[] argv;
    }

private:
    char* *      argv;
    unsigned int argc_plus_one;
  };
  Cleanup_argv cleanup_argv( argv, argc + 1 );

  // antscout->set_stream( out_stream );

  if ( argc < 7 )
    {
    std::cerr << argv[0] << " imageDimension outputImage domainImage meshSize numberOfLevels inputImage1 ... inputImageN" << std::endl;

    if( argc >= 2 &&
        ( std::string( argv[1] ) == std::string("--help") || std::string( argv[1] ) == std::string("-h") ) )
      {
      return EXIT_SUCCESS;
      }
    return EXIT_FAILURE;
    }

  const int ImageDimension = static_cast<int>( atoi( argv[1] ) );

  switch( ImageDimension )
     {
     case 2:
       return SuperResolution<2>( argc, argv );
       break;
     case 3:
       return SuperResolution<3>( argc, argv );
       break;
     case 4:
       return SuperResolution<4>( argc, argv );
       break;
     default:
        std::cerr << "Unsupported dimension" << std::endl;
        exit( EXIT_FAILURE );
     }
  return EXIT_SUCCESS;
}
} // namespace ants

<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkEndian.h"
#include "SkFontStream.h"
#include "SkStream.h"

struct SkSFNTHeader {
    uint32_t    fVersion;
    uint16_t    fNumTables;
    uint16_t    fSearchRange;
    uint16_t    fEntrySelector;
    uint16_t    fRangeShift;
};

struct SkTTCFHeader {
    uint32_t    fTag;
    uint32_t    fVersion;
    uint32_t    fNumOffsets;
    uint32_t    fOffset0;   // the first of N (fNumOffsets)
};

union SkSharedTTHeader {
    SkSFNTHeader    fSingle;
    SkTTCFHeader    fCollection;
};

struct SkSFNTDirEntry {
    uint32_t    fTag;
    uint32_t    fChecksum;
    uint32_t    fOffset;
    uint32_t    fLength;
};

static bool read(SkStream* stream, void* buffer, size_t amount) {
    return stream->read(buffer, amount) == amount;
}

static bool skip(SkStream* stream, size_t amount) {
    return stream->skip(amount) == amount;
}

/** Return the number of tables, or if this is a TTC (collection), return the
    number of tables in the first element of the collection. In either case,
    if offsetToDir is not-null, set it to the offset to the beginning of the
    table headers (SkSFNTDirEntry), relative to the start of the stream.

    On an error, return 0 for number of tables, and ignore offsetToDir
 */
static int count_tables(SkStream* stream, int ttcIndex, size_t* offsetToDir) {
    SkASSERT(ttcIndex >= 0);

    SkAutoSMalloc<1024> storage(sizeof(SkSharedTTHeader));
    SkSharedTTHeader* header = (SkSharedTTHeader*)storage.get();

    if (!read(stream, header, sizeof(SkSharedTTHeader))) {
        return 0;
    }

    // by default, SkSFNTHeader is at the start of the stream
    size_t offset = 0;

    // if we're really a collection, the first 4-bytes will be 'ttcf'
    uint32_t tag = SkEndian_SwapBE32(header->fCollection.fTag);
    if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
        unsigned count = SkEndian_SwapBE32(header->fCollection.fNumOffsets);
        if ((unsigned)ttcIndex >= count) {
            return 0;
        }

        if (ttcIndex > 0) { // need to read more of the shared header
            stream->rewind();
            size_t amount = sizeof(SkSharedTTHeader) + ttcIndex * sizeof(uint32_t);
            header = (SkSharedTTHeader*)storage.reset(amount);
            if (!read(stream, header, amount)) {
                return 0;
            }
        }
        // this is the offset to the local SkSFNTHeader
        offset = SkEndian_SwapBE32((&header->fCollection.fOffset0)[ttcIndex]);
        stream->rewind();
        if (!skip(stream, offset)) {
            return 0;
        }
        if (!read(stream, header, sizeof(SkSFNTHeader))) {
            return 0;
        }
    }

    if (offsetToDir) {
        // add the size of the header, so we will point to the DirEntries
        *offsetToDir = offset + sizeof(SkSFNTHeader);
    }
    return SkEndian_SwapBE16(header->fSingle.fNumTables);
}

///////////////////////////////////////////////////////////////////////////////

struct SfntHeader {
    SfntHeader() : fCount(0), fDir(NULL) {}
    ~SfntHeader() { sk_free(fDir); }

    /** If it returns true, then fCount and fDir are properly initialized.
        Note: fDir will point to the raw array of SkSFNTDirEntry values,
        meaning they will still be in the file's native endianness (BE).

        fDir will be automatically freed when this object is destroyed
     */
    bool init(SkStream* stream, int ttcIndex) {
        stream->rewind();

        size_t offsetToDir;
        fCount = count_tables(stream, ttcIndex, &offsetToDir);
        if (0 == fCount) {
            return false;
        }

        stream->rewind();
        if (!skip(stream, offsetToDir)) {
            return false;
        }

        size_t size = fCount * sizeof(SkSFNTDirEntry);
        fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
        return read(stream, fDir, size);
    }

    int             fCount;
    SkSFNTDirEntry* fDir;
};

///////////////////////////////////////////////////////////////////////////////

int SkFontStream::CountTTCEntries(SkStream* stream) {
    stream->rewind();

    SkSharedTTHeader shared;
    if (!read(stream, &shared, sizeof(shared))) {
        return 0;
    }

    // if we're really a collection, the first 4-bytes will be 'ttcf'
    uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
    if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
        return SkEndian_SwapBE32(shared.fCollection.fNumOffsets);
    } else {
        return 1;   // normal 'sfnt' has 1 dir entry
    }
}

int SkFontStream::GetTableTags(SkStream* stream, int ttcIndex,
                               SkFontTableTag tags[]) {
    SfntHeader  header;
    if (!header.init(stream, ttcIndex)) {
        return 0;
    }

    if (tags) {
        for (int i = 0; i < header.fCount; i++) {
            tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
        }
    }
    return header.fCount;
}

size_t SkFontStream::GetTableData(SkStream* stream, int ttcIndex,
                                  SkFontTableTag tag,
                                  size_t offset, size_t length, void* data) {
    SfntHeader  header;
    if (!header.init(stream, ttcIndex)) {
        return 0;
    }

    for (int i = 0; i < header.fCount; i++) {
        if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
            size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
            size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength);
            // now sanity check the caller's offset/length
            if (offset >= realLength) {
                return 0;
            }
            // if the caller is trusting the length from the file, then a
            // hostile file might choose a value which would overflow offset +
            // length.
            if (offset + length < offset) {
                return 0;
            }
            if (length > realLength - offset) {
                length = realLength - offset;
            }
            if (data) {
                // skip the stream to the part of the table we want to copy from
                stream->rewind();
                size_t bytesToSkip = realOffset + offset;
                if (skip(stream, bytesToSkip)) {
                    return 0;
                }
                if (!read(stream, data, length)) {
                    return 0;
                }
            }
            return length;
        }
    }
    return 0;
}
<commit_msg>fix missing ! typo when we switched to skip() helper function. caught by linux unittests.<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkEndian.h"
#include "SkFontStream.h"
#include "SkStream.h"

struct SkSFNTHeader {
    uint32_t    fVersion;
    uint16_t    fNumTables;
    uint16_t    fSearchRange;
    uint16_t    fEntrySelector;
    uint16_t    fRangeShift;
};

struct SkTTCFHeader {
    uint32_t    fTag;
    uint32_t    fVersion;
    uint32_t    fNumOffsets;
    uint32_t    fOffset0;   // the first of N (fNumOffsets)
};

union SkSharedTTHeader {
    SkSFNTHeader    fSingle;
    SkTTCFHeader    fCollection;
};

struct SkSFNTDirEntry {
    uint32_t    fTag;
    uint32_t    fChecksum;
    uint32_t    fOffset;
    uint32_t    fLength;
};

static bool read(SkStream* stream, void* buffer, size_t amount) {
    return stream->read(buffer, amount) == amount;
}

static bool skip(SkStream* stream, size_t amount) {
    return stream->skip(amount) == amount;
}

/** Return the number of tables, or if this is a TTC (collection), return the
    number of tables in the first element of the collection. In either case,
    if offsetToDir is not-null, set it to the offset to the beginning of the
    table headers (SkSFNTDirEntry), relative to the start of the stream.

    On an error, return 0 for number of tables, and ignore offsetToDir
 */
static int count_tables(SkStream* stream, int ttcIndex, size_t* offsetToDir) {
    SkASSERT(ttcIndex >= 0);

    SkAutoSMalloc<1024> storage(sizeof(SkSharedTTHeader));
    SkSharedTTHeader* header = (SkSharedTTHeader*)storage.get();

    if (!read(stream, header, sizeof(SkSharedTTHeader))) {
        return 0;
    }

    // by default, SkSFNTHeader is at the start of the stream
    size_t offset = 0;

    // if we're really a collection, the first 4-bytes will be 'ttcf'
    uint32_t tag = SkEndian_SwapBE32(header->fCollection.fTag);
    if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
        unsigned count = SkEndian_SwapBE32(header->fCollection.fNumOffsets);
        if ((unsigned)ttcIndex >= count) {
            return 0;
        }

        if (ttcIndex > 0) { // need to read more of the shared header
            stream->rewind();
            size_t amount = sizeof(SkSharedTTHeader) + ttcIndex * sizeof(uint32_t);
            header = (SkSharedTTHeader*)storage.reset(amount);
            if (!read(stream, header, amount)) {
                return 0;
            }
        }
        // this is the offset to the local SkSFNTHeader
        offset = SkEndian_SwapBE32((&header->fCollection.fOffset0)[ttcIndex]);
        stream->rewind();
        if (!skip(stream, offset)) {
            return 0;
        }
        if (!read(stream, header, sizeof(SkSFNTHeader))) {
            return 0;
        }
    }

    if (offsetToDir) {
        // add the size of the header, so we will point to the DirEntries
        *offsetToDir = offset + sizeof(SkSFNTHeader);
    }
    return SkEndian_SwapBE16(header->fSingle.fNumTables);
}

///////////////////////////////////////////////////////////////////////////////

struct SfntHeader {
    SfntHeader() : fCount(0), fDir(NULL) {}
    ~SfntHeader() { sk_free(fDir); }

    /** If it returns true, then fCount and fDir are properly initialized.
        Note: fDir will point to the raw array of SkSFNTDirEntry values,
        meaning they will still be in the file's native endianness (BE).

        fDir will be automatically freed when this object is destroyed
     */
    bool init(SkStream* stream, int ttcIndex) {
        stream->rewind();

        size_t offsetToDir;
        fCount = count_tables(stream, ttcIndex, &offsetToDir);
        if (0 == fCount) {
            return false;
        }

        stream->rewind();
        if (!skip(stream, offsetToDir)) {
            return false;
        }

        size_t size = fCount * sizeof(SkSFNTDirEntry);
        fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
        return read(stream, fDir, size);
    }

    int             fCount;
    SkSFNTDirEntry* fDir;
};

///////////////////////////////////////////////////////////////////////////////

int SkFontStream::CountTTCEntries(SkStream* stream) {
    stream->rewind();

    SkSharedTTHeader shared;
    if (!read(stream, &shared, sizeof(shared))) {
        return 0;
    }

    // if we're really a collection, the first 4-bytes will be 'ttcf'
    uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
    if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
        return SkEndian_SwapBE32(shared.fCollection.fNumOffsets);
    } else {
        return 1;   // normal 'sfnt' has 1 dir entry
    }
}

int SkFontStream::GetTableTags(SkStream* stream, int ttcIndex,
                               SkFontTableTag tags[]) {
    SfntHeader  header;
    if (!header.init(stream, ttcIndex)) {
        return 0;
    }

    if (tags) {
        for (int i = 0; i < header.fCount; i++) {
            tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
        }
    }
    return header.fCount;
}

size_t SkFontStream::GetTableData(SkStream* stream, int ttcIndex,
                                  SkFontTableTag tag,
                                  size_t offset, size_t length, void* data) {
    SfntHeader  header;
    if (!header.init(stream, ttcIndex)) {
        return 0;
    }

    for (int i = 0; i < header.fCount; i++) {
        if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
            size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
            size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength);
            // now sanity check the caller's offset/length
            if (offset >= realLength) {
                return 0;
            }
            // if the caller is trusting the length from the file, then a
            // hostile file might choose a value which would overflow offset +
            // length.
            if (offset + length < offset) {
                return 0;
            }
            if (length > realLength - offset) {
                length = realLength - offset;
            }
            if (data) {
                // skip the stream to the part of the table we want to copy from
                stream->rewind();
                size_t bytesToSkip = realOffset + offset;
                if (!skip(stream, bytesToSkip)) {
                    return 0;
                }
                if (!read(stream, data, length)) {
                    return 0;
                }
            }
            return length;
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>
#include <iostream>
#include <memory>
#include <ctime>
#include <math.h>

#include "dynamicmodel.h"
#include "history.h"
#include "modelstate.h"
#include "config.h"
#include "constants.h"
#include "logging.h"
#include "meteo.h"
#include "surfacedensity.h"
#include "metamorphism.h"
#include "compaction.h"
#include "heatsolver.h"
#include "utils.h"

namespace DSM{

DynamicModel::DynamicModel() : _nt(0) { }

void DynamicModel::run(){
   /* MAIN DRIVER ROUTINE
      initializes submodels, runs timeloop and writes output */
   const char * option_name;

   /* read time step */
   option_name = "general:dt";
   _dt = (long) config.getInt(option_name, true, 1, (int)1e9, -1);
   const long dt_per_year = sec_in_year / _dt;
   logger << "INFO: dt_per_year = " << dt_per_year << std::endl;

   /* read stopping criteria */
   option_name = "stopping_criteria:which_stop";
   const int which_stop = config.getInt(option_name, false, 0, 5, 0);
   bool stop_year = false;
   bool stop_dens = false;
   bool stop_depth = false;
   switch (which_stop) {
      case 0   :  stop_year = true; break;
      case 1   :  stop_dens = true; break;
      case 2   :  stop_depth = true; break;
      case 3   :  stop_year = true; stop_dens = true; break;
      case 4   :  stop_year = true; stop_depth = true; break;
      case 5   :  stop_year = true; stop_dens = true; stop_depth = true; break;
      default  :
         logger << "ERROR: unknown value: " << which_stop << " for config option " << option_name << std::endl;
         std::abort();
   }
   int max_years;
   double max_dens, max_depth;
   if (stop_year) {
      option_name = "stopping_criteria:years";
      max_years = config.getInt(option_name, true, 1, (int)1e9, -1);
      logger << "INFO: max_years = " << max_years << std::endl;
   }
   if (stop_dens) {
      option_name = "stopping_criteria:dens";
      max_dens = config.getDouble(option_name, true, 1., 1000., -1.);
      logger << "INFO: max_dens = " << max_dens << std::endl;
   }
   if (stop_depth) {
      option_name = "stopping_criteria:depth";
      max_depth = config.getDouble(option_name, true, 1., 1000., -1.);
      logger << "INFO: max_depth = " << max_depth << std::endl;
   }

   /* setup submodels */
   std::unique_ptr<Meteo> meteo           = instantiate_meteo(*this);
   std::unique_ptr<SurfaceDensity> surf   = instantiate_surfacedensity(*meteo);
   ModelState mstate(*meteo, *surf, *this);
   std::unique_ptr<Metamorphism> mm       = instantiate_metamorphism(mstate, *this);
   std::unique_ptr<Compaction> comp       = instantiate_compaction(mstate, *this);
   std::unique_ptr<HeatSolver> heat       = instantiate_heatsolver(mstate, *this);
   History history(mstate);

   /* print some meteo statistics */
   logger << "INFO: initial surface temperature is: " << meteo->surfaceTemperature() << std::endl;
   logger << "INFO: initial surface wind is: " << meteo->surfaceWind() << std::endl;
   logger << "INFO: initial accumulation rate is: " << meteo->accumulationRate() << std::endl;

   /* start of the main time loop */
   std::clock_t start;
   int kYear = 0;
   while(
         (stop_year ? kYear < max_years : true)
      && (stop_dens ? !mstate.hasReachedDensity(max_dens) : true)
      && (stop_depth ? mstate.totalDepth() < max_depth : true) ){

      start = clock();
      for(int tstep = 0; tstep < dt_per_year; tstep++) {
         runTimeStep(mstate, *mm, *comp, *heat);
         history.update();
      }
      double elapsed = ((double)(clock() - start)) / CLOCKS_PER_SEC;

      logger  << "year=" << kYear
            << ", Tmin=" << mstate.minTemp()
            << ", Tmax=" << mstate.maxTemp()
            << ", rho_max=" << mstate.maxDens()
            << ", sec/year=" << elapsed
            << ", year/hour=" << 3600./elapsed << std::endl;
      kYear++;
   }
   mstate.printSummary();
   mstate.writeModelState();
   history.writeHistory();
}

void DynamicModel::runTimeStep(ModelState& mstate, Metamorphism& mm, Compaction& comp, HeatSolver& heat) {
   accumulate(mstate);
   mm.metamorphism();
   comp.compaction();
   doGridChecks(mstate);
   heat.heatdiffusion();
   _nt++;
}

void DynamicModel::doGridChecks(ModelState& mstate){
   /* PERFORMS A NUMBER OF CHECKS ON THE CONSISTENCY AND EFFICIENCY OF THE GRID */

   /* check minimum thickness, start with second layer (index N-2) */
   Grid& grid = mstate.getGrid();
   int i = grid.size()-2;
   while (i >= 0 ) { // Use while instead of for-loop as size may change during loop
      if (grid[i].dz < dzmin && mstate.gridsize() > 1){
         // Layer is too thin, combine with neighbor
         if (i == 0  || grid[i-1].dz > grid[i+1].dz  ) {
            /* CASE 1: Bottom layer can only be combined with the one above */
            /* CASE 2: Determine smallest neighbour */
            mstate.combineLayers(grid[i+1], grid[i]);
         } else {
            mstate.combineLayers(grid[i-1], grid[i]);
         }
         grid.erase(grid.begin() + i); // NOTE: this is very inefficient
      }
      i--;
   }

   /* check maximum layer thickness */
   Layer& top = grid.back();
   while (grid.back().dz > dzmax ) {
      /* Split in unequal parts 4:1
         all vars are identical except thickness */
      top = grid.back();
      Layer layer = top;
      layer.dz    = top.dz/5.;
      top.dz      = top.dz * 4./5;
      grid.push_back(layer);
   }

   /* remove bottom layers that have attained ice density */
   while(!grid.empty() && grid.front().dens > 900.)
      grid.erase(grid.begin());

   if (grid.empty()) {
      logger << "ERROR: all layers turned to ice and were removed! This probably means that something is wrong with the compaction routine or the accumulation flux" << std::endl;
      std::abort();
   }
}

void DynamicModel::accumulate(ModelState& mstate) {
   const double acc = mstate.getMeteo().accumulationRate();
   if ( doubles_equal(acc, 0.0)) {return;}
   if ( acc < 0.) {
      accumulateNegative(mstate);
   } else {
      accumulatePositive(mstate);
   }
}

void DynamicModel::accumulateNegative(ModelState& mstate) {
   Grid& grid = mstate.getGrid();
   const double evap = std::abs(mstate.getMeteo().accumulationRate() * 1e-3 * _dt);
   while (grid.back().dz * grid.back().dens / rho_w < evap) {
      if (grid.size() < 2) {
         logger << "ERROR: not enough mass present for sublimation / evaporation" << std::endl;
         std::abort();
      }
      logger << "grid size = " << grid.size() << std::endl;
      logger << "DEBUG combining [ " << (grid.end()[-2]).dz * (grid.end()[-2]).dens / rho_w << ", "
             << grid.back().dz * grid.back().dens / rho_w << " ] mm W.E. to meet " << evap << " mm W.E. of subl." << std::endl;
      mstate.combineLayers(grid.end()[-2], grid.back());
      grid.pop_back();
   }
   grid.back().dz -= evap * (rho_w/grid.back().dens);
//   logger << "DEBUG removing " << evap * (rho_w/grid.back().dens) << " m from top layer" << std::endl;
   if (grid.back().dz <= 0.) {
      logger << "ERROR: negative layer thickness after evaporation (programmer error)" << std::endl;
      std::abort();
   }
   return;
}

void DynamicModel::accumulatePositive(ModelState& mstate) {
   Grid& grid = mstate.getGrid();
   const double dens = mstate.getSurf().density();
   const double acc = mstate.getMeteo().accumulationRate() * 1e-3 * _dt; // convert from [mm/s] to [m]
   const double dz = (rho_w/dens) * acc;
   Layer& top = grid.back();

   // grain parameters are mass weighted
   const double U = mstate.getMeteo().surfaceWind();
   const double dfall = std::min(std::max(1.29-0.17*U, 0.20), 1.);
   const double sfall = std::min(std::max(0.08*U + 0.38, 0.5), 0.9);
   const double new_snow = dz*dens;
   const double old_snow = top.dz*top.dz;

#ifdef DEBUG
   const double dold = top.dnd;
   const double sold = top.sph;
#endif

   top.dnd    = (top.dnd*old_snow + dfall*new_snow)/(new_snow+old_snow);
   top.sph    = (top.sph*old_snow + sfall*new_snow)/(new_snow+old_snow);
   top.gs   = (top.gs*old_snow + fs_gs*new_snow)/(new_snow+old_snow);

#ifdef DEBUG
   if (top.dnd > 1. || top.dnd < 0) {
      logger << "DEBUG top.dnd = " << top.dnd << ", U = " << U << std::endl;
      logger << "DEBUG dfall = " << dfall << ", sfall = " << sfall << std::endl;
      logger << "DEBUG dold = " << dold << ", sold = " << sold << std::endl;
      logger << "DEBUG new_snow = " << new_snow << ", old_snow = " << old_snow << std::endl;
      std::abort();
   }
#endif

   top.dens = top.dz/(top.dz+dz)*top.dens + dz/(top.dz+dz)*dens;
   top.dz = top.dz + dz;

}

} // namespace
<commit_msg>not enough mass for evaporation: warning i.s.o error<commit_after>
#include <iostream>
#include <memory>
#include <ctime>
#include <math.h>

#include "dynamicmodel.h"
#include "history.h"
#include "modelstate.h"
#include "config.h"
#include "constants.h"
#include "logging.h"
#include "meteo.h"
#include "surfacedensity.h"
#include "metamorphism.h"
#include "compaction.h"
#include "heatsolver.h"
#include "utils.h"

namespace DSM{

DynamicModel::DynamicModel() : _nt(0) { }

void DynamicModel::run(){
   /* MAIN DRIVER ROUTINE
      initializes submodels, runs timeloop and writes output */
   const char * option_name;

   /* read time step */
   option_name = "general:dt";
   _dt = (long) config.getInt(option_name, true, 1, (int)1e9, -1);
   const long dt_per_year = sec_in_year / _dt;
   logger << "INFO: dt_per_year = " << dt_per_year << std::endl;

   /* read stopping criteria */
   option_name = "stopping_criteria:which_stop";
   const int which_stop = config.getInt(option_name, false, 0, 5, 0);
   bool stop_year = false;
   bool stop_dens = false;
   bool stop_depth = false;
   switch (which_stop) {
      case 0   :  stop_year = true; break;
      case 1   :  stop_dens = true; break;
      case 2   :  stop_depth = true; break;
      case 3   :  stop_year = true; stop_dens = true; break;
      case 4   :  stop_year = true; stop_depth = true; break;
      case 5   :  stop_year = true; stop_dens = true; stop_depth = true; break;
      default  :
         logger << "ERROR: unknown value: " << which_stop << " for config option " << option_name << std::endl;
         std::abort();
   }
   int max_years;
   double max_dens, max_depth;
   if (stop_year) {
      option_name = "stopping_criteria:years";
      max_years = config.getInt(option_name, true, 1, (int)1e9, -1);
      logger << "INFO: max_years = " << max_years << std::endl;
   }
   if (stop_dens) {
      option_name = "stopping_criteria:dens";
      max_dens = config.getDouble(option_name, true, 1., 1000., -1.);
      logger << "INFO: max_dens = " << max_dens << std::endl;
   }
   if (stop_depth) {
      option_name = "stopping_criteria:depth";
      max_depth = config.getDouble(option_name, true, 1., 1000., -1.);
      logger << "INFO: max_depth = " << max_depth << std::endl;
   }

   /* setup submodels */
   std::unique_ptr<Meteo> meteo           = instantiate_meteo(*this);
   std::unique_ptr<SurfaceDensity> surf   = instantiate_surfacedensity(*meteo);
   ModelState mstate(*meteo, *surf, *this);
   std::unique_ptr<Metamorphism> mm       = instantiate_metamorphism(mstate, *this);
   std::unique_ptr<Compaction> comp       = instantiate_compaction(mstate, *this);
   std::unique_ptr<HeatSolver> heat       = instantiate_heatsolver(mstate, *this);
   History history(mstate);

   /* print some meteo statistics */
   logger << "INFO: initial surface temperature is: " << meteo->surfaceTemperature() << std::endl;
   logger << "INFO: initial surface wind is: " << meteo->surfaceWind() << std::endl;
   logger << "INFO: initial accumulation rate is: " << meteo->accumulationRate() << std::endl;

   /* start of the main time loop */
   std::clock_t start;
   int kYear = 0;
   while(
         (stop_year ? kYear < max_years : true)
      && (stop_dens ? !mstate.hasReachedDensity(max_dens) : true)
      && (stop_depth ? mstate.totalDepth() < max_depth : true) ){

      start = clock();
      for(int tstep = 0; tstep < dt_per_year; tstep++) {
         runTimeStep(mstate, *mm, *comp, *heat);
         history.update();
      }
      double elapsed = ((double)(clock() - start)) / CLOCKS_PER_SEC;

      logger  << "year=" << kYear
            << ", Tmin=" << mstate.minTemp()
            << ", Tmax=" << mstate.maxTemp()
            << ", rho_max=" << mstate.maxDens()
            << ", sec/year=" << elapsed
            << ", year/hour=" << 3600./elapsed << std::endl;
      kYear++;
   }
   mstate.printSummary();
   mstate.writeModelState();
   history.writeHistory();
}

void DynamicModel::runTimeStep(ModelState& mstate, Metamorphism& mm, Compaction& comp, HeatSolver& heat) {
   accumulate(mstate);
   mm.metamorphism();
   comp.compaction();
   doGridChecks(mstate);
   heat.heatdiffusion();
   _nt++;
}

void DynamicModel::doGridChecks(ModelState& mstate){
   /* PERFORMS A NUMBER OF CHECKS ON THE CONSISTENCY AND EFFICIENCY OF THE GRID */

   /* check minimum thickness, start with second layer (index N-2) */
   Grid& grid = mstate.getGrid();
   int i = grid.size()-2;
   while (i >= 0 ) { // Use while instead of for-loop as size may change during loop
      if (grid[i].dz < dzmin && mstate.gridsize() > 1){
         // Layer is too thin, combine with neighbor
         if (i == 0  || grid[i-1].dz > grid[i+1].dz  ) {
            /* CASE 1: Bottom layer can only be combined with the one above */
            /* CASE 2: Determine smallest neighbour */
            mstate.combineLayers(grid[i+1], grid[i]);
         } else {
            mstate.combineLayers(grid[i-1], grid[i]);
         }
         grid.erase(grid.begin() + i); // NOTE: this is very inefficient
      }
      i--;
   }

   /* check maximum layer thickness */
   Layer& top = grid.back();
   while (grid.back().dz > dzmax ) {
      /* Split in unequal parts 4:1
         all vars are identical except thickness */
      top = grid.back();
      Layer layer = top;
      layer.dz    = top.dz/5.;
      top.dz      = top.dz * 4./5;
      grid.push_back(layer);
   }

   /* remove bottom layers that have attained ice density */
   while(!grid.empty() && grid.front().dens > 900.)
      grid.erase(grid.begin());

   if (grid.empty()) {
      logger << "ERROR: all layers turned to ice and were removed! This probably means that something is wrong with the compaction routine or the accumulation flux" << std::endl;
      std::abort();
   }
}

void DynamicModel::accumulate(ModelState& mstate) {
   const double acc = mstate.getMeteo().accumulationRate();
   if ( doubles_equal(acc, 0.0)) {return;}
   if ( acc < 0.) {
      accumulateNegative(mstate);
   } else {
      accumulatePositive(mstate);
   }
}

void DynamicModel::accumulateNegative(ModelState& mstate) {
   Grid& grid = mstate.getGrid();
   const double evap = std::abs(mstate.getMeteo().accumulationRate() * 1e-3 * _dt);
   while (grid.back().dz * grid.back().dens / rho_w < evap) {
      if (grid.size() < 2) {
         logger << "WARNING: not enough mass present for sublimation / evaporation" << std::endl;
         return;
      }
      logger << "grid size = " << grid.size() << std::endl;
      logger << "DEBUG combining [ " << (grid.end()[-2]).dz * (grid.end()[-2]).dens / rho_w << ", "
             << grid.back().dz * grid.back().dens / rho_w << " ] mm W.E. to meet " << evap << " mm W.E. of subl." << std::endl;
      mstate.combineLayers(grid.end()[-2], grid.back());
      grid.pop_back();
   }
   grid.back().dz -= evap * (rho_w/grid.back().dens);
//   logger << "DEBUG removing " << evap * (rho_w/grid.back().dens) << " m from top layer" << std::endl;
   if (grid.back().dz <= 0.) {
      logger << "ERROR: negative layer thickness after evaporation (programmer error)" << std::endl;
      std::abort();
   }
   return;
}

void DynamicModel::accumulatePositive(ModelState& mstate) {
   Grid& grid = mstate.getGrid();
   const double dens = mstate.getSurf().density();
   const double acc = mstate.getMeteo().accumulationRate() * 1e-3 * _dt; // convert from [mm/s] to [m]
   const double dz = (rho_w/dens) * acc;
   Layer& top = grid.back();

   // grain parameters are mass weighted
   const double U = mstate.getMeteo().surfaceWind();
   const double dfall = std::min(std::max(1.29-0.17*U, 0.20), 1.);
   const double sfall = std::min(std::max(0.08*U + 0.38, 0.5), 0.9);
   const double new_snow = dz*dens;
   const double old_snow = top.dz*top.dz;

#ifdef DEBUG
   const double dold = top.dnd;
   const double sold = top.sph;
#endif

   top.dnd    = (top.dnd*old_snow + dfall*new_snow)/(new_snow+old_snow);
   top.sph    = (top.sph*old_snow + sfall*new_snow)/(new_snow+old_snow);
   top.gs   = (top.gs*old_snow + fs_gs*new_snow)/(new_snow+old_snow);

#ifdef DEBUG
   if (top.dnd > 1. || top.dnd < 0) {
      logger << "DEBUG top.dnd = " << top.dnd << ", U = " << U << std::endl;
      logger << "DEBUG dfall = " << dfall << ", sfall = " << sfall << std::endl;
      logger << "DEBUG dold = " << dold << ", sold = " << sold << std::endl;
      logger << "DEBUG new_snow = " << new_snow << ", old_snow = " << old_snow << std::endl;
      std::abort();
   }
#endif

   top.dens = top.dz/(top.dz+dz)*top.dens + dz/(top.dz+dz)*dens;
   top.dz = top.dz + dz;

}

} // namespace
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#ifndef __rtkIOFactories_cxx
#define __rtkIOFactories_cxx

// Varian Obi includes
#include "rtkHndImageIOFactory.h"

// Elekta Synergy includes
#include "rtkHisImageIOFactory.h"

// ImagX includes
#include "rtkImagXImageIOFactory.h"

// European Synchrotron Radiation Facility
#include "rtkEdfImageIOFactory.h"

// Xrad small animal scanner
#include "rtkXRadImageIOFactory.h"

namespace rtk
{

void RegisterIOFactories()
{
  rtk::HndImageIOFactory::RegisterOneFactory();
  rtk::HisImageIOFactory::RegisterOneFactory();
  rtk::ImagXImageIOFactory::RegisterOneFactory();
  rtk::EdfImageIOFactory::RegisterOneFactory();
  rtk::XRadImageIOFactory::RegisterOneFactory();
#if ITK_VERSION_MAJOR <= 3
  itk::ImageIOFactory::RegisterBuiltInFactories();
#endif
}

} //namespace rtk

#endif
<commit_msg>Fix missing include<commit_after>/*=========================================================================
 *
 *  Copyright RTK Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#ifndef __rtkIOFactories_cxx
#define __rtkIOFactories_cxx

#include <itkImageIOFactory.h>

// Varian Obi includes
#include "rtkHndImageIOFactory.h"

// Elekta Synergy includes
#include "rtkHisImageIOFactory.h"

// ImagX includes
#include "rtkImagXImageIOFactory.h"

// European Synchrotron Radiation Facility
#include "rtkEdfImageIOFactory.h"

// Xrad small animal scanner
#include "rtkXRadImageIOFactory.h"

namespace rtk
{

void RegisterIOFactories()
{
  rtk::HndImageIOFactory::RegisterOneFactory();
  rtk::HisImageIOFactory::RegisterOneFactory();
  rtk::ImagXImageIOFactory::RegisterOneFactory();
  rtk::EdfImageIOFactory::RegisterOneFactory();
  rtk::XRadImageIOFactory::RegisterOneFactory();
#if ITK_VERSION_MAJOR <= 3
  itk::ImageIOFactory::RegisterBuiltInFactories();
#endif
}

} //namespace rtk

#endif
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "warnings_guard_ne_locks.h"
#include <ne_uri.h>
#include "rtl/ustring.hxx"
#include "osl/time.h"
#include "osl/thread.hxx"
#include "salhelper/thread.hxx"
#include "NeonSession.hxx"
#include "NeonLockStore.hxx"

using namespace webdav_ucp;

namespace webdav_ucp {

class TickerThread : public salhelper::Thread
{
    bool m_bFinish;
    NeonLockStore & m_rLockStore;

public:

    TickerThread( NeonLockStore & rLockStore )
    : Thread( "NeonTickerThread" ), m_bFinish( false ),
      m_rLockStore( rLockStore ) {}

    void finish() { m_bFinish = true; }

private:

    virtual void execute();
};

} // namespace webdav_ucp

void TickerThread::execute()
{
    OSL_TRACE( "TickerThread: start." );

    // we have to go through the loop more often to be able to finish ~quickly
    const int nNth = 25;

    int nCount = nNth;
    while ( !m_bFinish )
    {
        if ( nCount-- <= 0 )
        {
            m_rLockStore.refreshLocks();
            nCount = nNth;
        }

        TimeValue aTV;
        aTV.Seconds = 0;
        aTV.Nanosec = 1000000000 / nNth;
        salhelper::Thread::wait( aTV );
    }

    OSL_TRACE( "TickerThread: stop." );
}

NeonLockStore::NeonLockStore()
    : m_pNeonLockStore( ne_lockstore_create() )
{
    OSL_ENSURE( m_pNeonLockStore, "Unable to create neon lock store!" );
}

NeonLockStore::~NeonLockStore()
{
    stopTicker();

    // release active locks, if any.
    OSL_ENSURE( m_aLockInfoMap.empty(),
                "NeonLockStore::~NeonLockStore - Releasing active locks!" );

    LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
    const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
    while ( it != end )
    {
        NeonLock * pLock = (*it).first;
        (*it).second.xSession->UNLOCK( pLock );

        ne_lockstore_remove( m_pNeonLockStore, pLock );
        ne_lock_destroy( pLock );

        ++it;
    }

    ne_lockstore_destroy( m_pNeonLockStore );
}

void NeonLockStore::startTicker()
{
    osl::MutexGuard aGuard( m_aMutex );

    if ( !m_pTickerThread.is() )
    {
        m_pTickerThread = new TickerThread( *this );
        m_pTickerThread->launch();
    }
}

void NeonLockStore::stopTicker()
{
    osl::MutexGuard aGuard( m_aMutex );

    if ( m_pTickerThread.is() )
    {
        m_pTickerThread->finish();
        m_pTickerThread->join();
        m_pTickerThread.clear();
    }
}

void NeonLockStore::registerSession( HttpSession * pHttpSession )
{
    osl::MutexGuard aGuard( m_aMutex );

    ne_lockstore_register( m_pNeonLockStore, pHttpSession );
}

NeonLock * NeonLockStore::findByUri( OUString const & rUri )
{
    osl::MutexGuard aGuard( m_aMutex );

    ne_uri aUri;
    ne_uri_parse( OUStringToOString(
        rUri, RTL_TEXTENCODING_UTF8 ).getStr(), &aUri );
    return ne_lockstore_findbyuri( m_pNeonLockStore, &aUri );
}

void NeonLockStore::addLock( NeonLock * pLock,
                             rtl::Reference< NeonSession > const & xSession,
                             sal_Int32 nLastChanceToSendRefreshRequest )
{
    osl::MutexGuard aGuard( m_aMutex );

    ne_lockstore_add( m_pNeonLockStore, pLock );
    m_aLockInfoMap[ pLock ]
        = LockInfo( xSession, nLastChanceToSendRefreshRequest );

    startTicker();
}

void NeonLockStore::updateLock( NeonLock * pLock,
                                sal_Int32 nLastChanceToSendRefreshRequest )
{
    osl::MutexGuard aGuard( m_aMutex );

    LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) );
    OSL_ENSURE( it != m_aLockInfoMap.end(),
                "NeonLockStore::updateLock: lock not found!" );

    if ( it != m_aLockInfoMap.end() )
    {
        (*it).second.nLastChanceToSendRefreshRequest
            = nLastChanceToSendRefreshRequest;
    }
}

void NeonLockStore::removeLock( NeonLock * pLock )
{
    osl::MutexGuard aGuard( m_aMutex );

    m_aLockInfoMap.erase( pLock );
    ne_lockstore_remove( m_pNeonLockStore, pLock );

    if ( m_aLockInfoMap.empty() )
        stopTicker();
}

void NeonLockStore::refreshLocks()
{
    osl::MutexGuard aGuard( m_aMutex );

    LockInfoMap::iterator it( m_aLockInfoMap.begin() );
    const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
    while ( it != end )
    {
        LockInfo & rInfo = (*it).second;
        if ( rInfo.nLastChanceToSendRefreshRequest != -1 )
        {
            // 30 seconds or less remaining until lock expires?
            TimeValue t1;
            osl_getSystemTime( &t1 );
            if ( rInfo.nLastChanceToSendRefreshRequest - 30
                     <= sal_Int32( t1.Seconds ) )
            {
                // refresh the lock.
                sal_Int32 nlastChanceToSendRefreshRequest = -1;
                if ( rInfo.xSession->LOCK(
                         (*it).first,
                         /* out param */ nlastChanceToSendRefreshRequest ) )
                {
                    rInfo.nLastChanceToSendRefreshRequest
                        = nlastChanceToSendRefreshRequest;
                }
                else
                {
                    // refresh failed. stop auto-refresh.
                    rInfo.nLastChanceToSendRefreshRequest = -1;
                }
            }
        }
        ++it;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>ucb: NeonLockStore::stopTicker(): avoid deadlock<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "warnings_guard_ne_locks.h"
#include <ne_uri.h>
#include "rtl/ustring.hxx"
#include "osl/time.h"
#include "osl/thread.hxx"
#include "salhelper/thread.hxx"
#include "NeonSession.hxx"
#include "NeonLockStore.hxx"

using namespace webdav_ucp;

namespace webdav_ucp {

class TickerThread : public salhelper::Thread
{
    bool m_bFinish;
    NeonLockStore & m_rLockStore;

public:

    TickerThread( NeonLockStore & rLockStore )
    : Thread( "NeonTickerThread" ), m_bFinish( false ),
      m_rLockStore( rLockStore ) {}

    void finish() { m_bFinish = true; }

private:

    virtual void execute();
};

} // namespace webdav_ucp

void TickerThread::execute()
{
    OSL_TRACE( "TickerThread: start." );

    // we have to go through the loop more often to be able to finish ~quickly
    const int nNth = 25;

    int nCount = nNth;
    while ( !m_bFinish )
    {
        if ( nCount-- <= 0 )
        {
            m_rLockStore.refreshLocks();
            nCount = nNth;
        }

        TimeValue aTV;
        aTV.Seconds = 0;
        aTV.Nanosec = 1000000000 / nNth;
        salhelper::Thread::wait( aTV );
    }

    OSL_TRACE( "TickerThread: stop." );
}

NeonLockStore::NeonLockStore()
    : m_pNeonLockStore( ne_lockstore_create() )
{
    OSL_ENSURE( m_pNeonLockStore, "Unable to create neon lock store!" );
}

NeonLockStore::~NeonLockStore()
{
    stopTicker();

    // release active locks, if any.
    OSL_ENSURE( m_aLockInfoMap.empty(),
                "NeonLockStore::~NeonLockStore - Releasing active locks!" );

    LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
    const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
    while ( it != end )
    {
        NeonLock * pLock = (*it).first;
        (*it).second.xSession->UNLOCK( pLock );

        ne_lockstore_remove( m_pNeonLockStore, pLock );
        ne_lock_destroy( pLock );

        ++it;
    }

    ne_lockstore_destroy( m_pNeonLockStore );
}

void NeonLockStore::startTicker()
{
    osl::MutexGuard aGuard( m_aMutex );

    if ( !m_pTickerThread.is() )
    {
        m_pTickerThread = new TickerThread( *this );
        m_pTickerThread->launch();
    }
}

void NeonLockStore::stopTicker()
{
    rtl::Reference<TickerThread> pTickerThread;
    {
        osl::MutexGuard aGuard( m_aMutex );

        if (!m_pTickerThread.is())
        {
            return; // nothing to do
        }
        m_pTickerThread->finish(); // needs mutex
        // the TickerThread may run refreshLocks() at most once after this
        pTickerThread = m_pTickerThread;
        m_pTickerThread.clear();
    }

    pTickerThread->join(); // without m_aMutex locked (to prevent deadlock)
}

void NeonLockStore::registerSession( HttpSession * pHttpSession )
{
    osl::MutexGuard aGuard( m_aMutex );

    ne_lockstore_register( m_pNeonLockStore, pHttpSession );
}

NeonLock * NeonLockStore::findByUri( OUString const & rUri )
{
    osl::MutexGuard aGuard( m_aMutex );

    ne_uri aUri;
    ne_uri_parse( OUStringToOString(
        rUri, RTL_TEXTENCODING_UTF8 ).getStr(), &aUri );
    return ne_lockstore_findbyuri( m_pNeonLockStore, &aUri );
}

void NeonLockStore::addLock( NeonLock * pLock,
                             rtl::Reference< NeonSession > const & xSession,
                             sal_Int32 nLastChanceToSendRefreshRequest )
{
    osl::MutexGuard aGuard( m_aMutex );

    ne_lockstore_add( m_pNeonLockStore, pLock );
    m_aLockInfoMap[ pLock ]
        = LockInfo( xSession, nLastChanceToSendRefreshRequest );

    startTicker();
}

void NeonLockStore::updateLock( NeonLock * pLock,
                                sal_Int32 nLastChanceToSendRefreshRequest )
{
    osl::MutexGuard aGuard( m_aMutex );

    LockInfoMap::iterator it( m_aLockInfoMap.find( pLock ) );
    OSL_ENSURE( it != m_aLockInfoMap.end(),
                "NeonLockStore::updateLock: lock not found!" );

    if ( it != m_aLockInfoMap.end() )
    {
        (*it).second.nLastChanceToSendRefreshRequest
            = nLastChanceToSendRefreshRequest;
    }
}

void NeonLockStore::removeLock( NeonLock * pLock )
{
    osl::MutexGuard aGuard( m_aMutex );

    m_aLockInfoMap.erase( pLock );
    ne_lockstore_remove( m_pNeonLockStore, pLock );

    if ( m_aLockInfoMap.empty() )
        stopTicker();
}

void NeonLockStore::refreshLocks()
{
    osl::MutexGuard aGuard( m_aMutex );

    LockInfoMap::iterator it( m_aLockInfoMap.begin() );
    const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
    while ( it != end )
    {
        LockInfo & rInfo = (*it).second;
        if ( rInfo.nLastChanceToSendRefreshRequest != -1 )
        {
            // 30 seconds or less remaining until lock expires?
            TimeValue t1;
            osl_getSystemTime( &t1 );
            if ( rInfo.nLastChanceToSendRefreshRequest - 30
                     <= sal_Int32( t1.Seconds ) )
            {
                // refresh the lock.
                sal_Int32 nlastChanceToSendRefreshRequest = -1;
                if ( rInfo.xSession->LOCK(
                         (*it).first,
                         /* out param */ nlastChanceToSendRefreshRequest ) )
                {
                    rInfo.nLastChanceToSendRefreshRequest
                        = nlastChanceToSendRefreshRequest;
                }
                else
                {
                    // refresh failed. stop auto-refresh.
                    rInfo.nLastChanceToSendRefreshRequest = -1;
                }
            }
        }
        ++it;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// ref http://www.cnblogs.com/easonliu/p/4563780.html
class Solution {
private:
    bool isOK(char op1, char op2) {
        if (op1 == '*' || op1 == '/' || op2 == ')') return true;
        else return op2 == '+' || op2 == '-';
    }
    int calc(int a, int b, char op) {
        if (op == '+') return a + b;
        else if (op == '-') return a - b;
        else if (op == '*') return a * b;
        else return a / b;
    }
public:
    int calculate(string s) {
        stack<int> stk_val;
        stack<char> stk_op;
        int res = 0, tmp;
        for (int i = 0; i <= s.length(); ++i) {
            //操作数
            if (i < s.length() && isdigit(s[i])) {
                res = 0;
                while (i < s.length() && isdigit(s[i])) {
                    res *= 10;
                    res += s[i++] - '0';
                }
                stk_val.push(res);
            }
            //运算符
            if (i == s.length() || s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || s[i] == ')') {
                while (!stk_op.empty() && stk_op.top() != '(' && (i == s.length() || isOK(stk_op.top(), s[i]))) {
                    tmp = stk_val.top();
                    stk_val.pop();
                    stk_val.top() = calc(stk_val.top(), tmp, stk_op.top());
                    stk_op.pop();
                }
                if (i == s.length()) break;
                else if (s[i] == ')') stk_op.pop();
                else stk_op.push(s[i]);
            } else if (s[i] == '(') {
                stk_op.push(s[i]);
            }
        }
        return stk_val.top();
    }
};<commit_msg>add more<commit_after>// ref http://www.cnblogs.com/easonliu/p/4563780.html
class Solution {
private:
    bool isOK(char op1, char op2) {
        if (op1 == '*' || op1 == '/' || op2 == ')') return true;
        else return op2 == '+' || op2 == '-';
    }
    int calc(int a, int b, char op) {
        if (op == '+') return a + b;
        else if (op == '-') return a - b;
        else if (op == '*') return a * b;
        else return a / b;
    }
public:
    int calculate(string s) {
        stack<int> stk_val;
        stack<char> stk_op;

        int res = 0, tmp;
        for (int i = 0; i <= s.length(); ++i) {
            //操作数
            if (i < s.length() && isdigit(s[i])) {
                res = 0;
                while (i < s.length() && isdigit(s[i])) {
                    res *= 10;
                    res += s[i++] - '0';
                }
                stk_val.push(res);
            }
            //运算符
            if (i == s.length() || s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || s[i] == ')') {
                while (!stk_op.empty() && stk_op.top() != '(' && (i == s.length() || isOK(stk_op.top(), s[i]))) {
                    tmp = stk_val.top();
                    stk_val.pop();
                    stk_val.top() = calc(stk_val.top(), tmp, stk_op.top());
                    stk_op.pop();
                }
                if (i == s.length()) {
                    break;
                } else if (s[i] == ')') {
                    stk_op.pop();
                }else{
                    stk_op.push(s[i]);
                }
            } else if (s[i] == '(') {
                stk_op.push(s[i]);
            }
        }
        return stk_val.top();
    }
};<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char const *argv[]) {

	return 0;
}
<commit_msg>adding graph.gonna start<commit_after>//http://codeforces.com/problemset/problem/115/A
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char const *argv[]) {

	return 0;
}
<|endoftext|>