<commit_before>/*

Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include <osrm/Coordinate.h>

#include "DouglasPeucker.h"
#include "../DataStructures/SegmentInformation.h"

#include <boost/assert.hpp>

#include <cmath>

#include <limits>

DouglasPeucker::DouglasPeucker()
    : douglas_peucker_thresholds({262144., // z0
                                  131072., // z1
                                  65536.,  // z2
                                  32768.,  // z3
                                  16384.,  // z4
                                  8192.,   // z5
                                  4096.,   // z6
                                  2048.,   // z7
                                  960.,    // z8
                                  480.,    // z9
                                  240.,    // z10
                                  90.,     // z11
                                  50.,     // z12
                                  25.,     // z13
                                  15.,     // z14
                                  5.,      // z15
                                  .65,     // z16
                                  .5,      // z17
                                  .35      // z18
      })
{
}

void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level)
{
    {
        BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level");
        BOOST_ASSERT_MSG(1 < input_geometry.size(), "geometry invalid");
        unsigned left_border = 0;
        unsigned right_border = 1;
        // Sweep over array and identify those ranges that need to be checked
        do
        {
            BOOST_ASSERT_MSG(input_geometry[left_border].necessary,
                             "left border must be necessary");
            BOOST_ASSERT_MSG(input_geometry.back().necessary, "right border must be necessary");

            if (input_geometry[right_border].necessary)
            {
                recursion_stack.emplace(left_border, right_border);
                left_border = right_border;
            }
            ++right_border;
        } while (right_border < input_geometry.size());
    }
    while (!recursion_stack.empty())
    {
        // pop next element
        const GeometryRange pair = recursion_stack.top();
        recursion_stack.pop();
        BOOST_ASSERT_MSG(input_geometry[pair.first].necessary, "left border mus be necessary");
        BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary");
        BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry");
        BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side");
        double max_distance = std::numeric_limits<double>::min();

        unsigned farthest_element_index = pair.second;
        // find index idx of element with max_distance
        for (unsigned i = pair.first + 1; i < pair.second; ++i)
        {
            const double temp_dist = FixedPointCoordinate::ComputePerpendicularDistance(
                input_geometry[i].location,
                input_geometry[pair.first].location,
                input_geometry[pair.second].location);
            const double distance = std::abs(temp_dist);
            if (distance > douglas_peucker_thresholds[zoom_level] && distance > max_distance)
            {
                farthest_element_index = i;
                max_distance = distance;
            }
        }
        if (max_distance > douglas_peucker_thresholds[zoom_level])
        {
            //  mark idx as necessary
            input_geometry[farthest_element_index].necessary = true;
            if (1 < (farthest_element_index - pair.first))
            {
                recursion_stack.emplace(pair.first, farthest_element_index);
            }
            if (1 < (pair.second - farthest_element_index))
            {
                recursion_stack.emplace(farthest_element_index, pair.second);
            }
        }
    }
}
<commit_msg>return gracefully instead of failing of geometry is only a single node<commit_after>/*

Copyright (c) 2013, Project OSRM, Dennis Luxen, others
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.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include <osrm/Coordinate.h>

#include "DouglasPeucker.h"
#include "../DataStructures/SegmentInformation.h"

#include <boost/assert.hpp>

#include <cmath>

#include <limits>

DouglasPeucker::DouglasPeucker()
    : douglas_peucker_thresholds({262144., // z0
                                  131072., // z1
                                  65536.,  // z2
                                  32768.,  // z3
                                  16384.,  // z4
                                  8192.,   // z5
                                  4096.,   // z6
                                  2048.,   // z7
                                  960.,    // z8
                                  480.,    // z9
                                  240.,    // z10
                                  90.,     // z11
                                  50.,     // z12
                                  25.,     // z13
                                  15.,     // z14
                                  5.,      // z15
                                  .65,     // z16
                                  .5,      // z17
                                  .35      // z18
      })
{
}

void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level)
{
    BOOST_ASSERT_MSG(!input_geometry.empty(), "geometry invalid");
    if (input_geometry.size() <= 2)
    {
        return;
    }

    {
        BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level");
        unsigned left_border = 0;
        unsigned right_border = 1;
        // Sweep over array and identify those ranges that need to be checked
        do
        {
            BOOST_ASSERT_MSG(input_geometry[left_border].necessary,
                             "left border must be necessary");
            BOOST_ASSERT_MSG(input_geometry.back().necessary, "right border must be necessary");

            if (input_geometry[right_border].necessary)
            {
                recursion_stack.emplace(left_border, right_border);
                left_border = right_border;
            }
            ++right_border;
        } while (right_border < input_geometry.size());
    }
    while (!recursion_stack.empty())
    {
        // pop next element
        const GeometryRange pair = recursion_stack.top();
        recursion_stack.pop();
        BOOST_ASSERT_MSG(input_geometry[pair.first].necessary, "left border mus be necessary");
        BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary");
        BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry");
        BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side");
        double max_distance = std::numeric_limits<double>::min();

        unsigned farthest_element_index = pair.second;
        // find index idx of element with max_distance
        for (unsigned i = pair.first + 1; i < pair.second; ++i)
        {
            const double temp_dist = FixedPointCoordinate::ComputePerpendicularDistance(
                input_geometry[i].location,
                input_geometry[pair.first].location,
                input_geometry[pair.second].location);
            const double distance = std::abs(temp_dist);
            if (distance > douglas_peucker_thresholds[zoom_level] && distance > max_distance)
            {
                farthest_element_index = i;
                max_distance = distance;
            }
        }
        if (max_distance > douglas_peucker_thresholds[zoom_level])
        {
            //  mark idx as necessary
            input_geometry[farthest_element_index].necessary = true;
            if (1 < (farthest_element_index - pair.first))
            {
                recursion_stack.emplace(pair.first, farthest_element_index);
            }
            if (1 < (pair.second - farthest_element_index))
            {
                recursion_stack.emplace(farthest_element_index, pair.second);
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>TODO-553: spreading start-up further<commit_after><|endoftext|>


<commit_before>#include "../Include/CEntityNode.h"
#include "../Include/CSceneNode.h"
#include "../Include/CMenuNode.h"

#include "cocos2d.h"

using namespace cocos2d;

namespace LM
{

CEntityNode::CEntityNode(EAnchor a_eAnchor, int a_iWidth, int a_iHeight,
						 int a_iXPosition, int a_iYPosition, const std::string& a_sID) :
    m_eAnchor(a_eAnchor),
	m_iXPosition(a_iXPosition),
    m_iYPosition(a_iYPosition),
	m_iWidth(a_iWidth),
	m_iHeight(a_iHeight),
	m_bVisible(true),
	m_bLocked(false),
	m_sID(a_sID),
	m_fEntityStartScale(0),
	m_pCocosEntity(nullptr)
{
}

void CEntityNode::UnInit(bool removeChild)
{
	//m_pCocosEntity->autorelease();
	//m_pCocosEntity->release();
	if (m_pCocosEntity != nullptr) {
		if(removeChild)
			GetParentScene()->removeChild(m_pCocosEntity);

		m_pCocosEntity = nullptr;
		CNode::UnInit();
	}
	else {
		return;
	}
}

void CEntityNode::Revert(bool a_bVisible)
{
	Show(a_bVisible);
	if (m_sID != "")
		CCLOG("reverting : %s", m_sID.c_str());
	m_pCocosEntity->setPosition(m_oEntityStartLocation);
	m_pCocosEntity->setScale(m_fEntityStartScale);
        for (CNode* itNode : m_vChildren)
        {
          CEntityNode* pEntity = dynamic_cast<CEntityNode*>(itNode);
          if (pEntity)
          {
            pEntity->Revert(a_bVisible);
          }
        }
}

cocos2d::Node* CEntityNode::GetCocosEntity()
{
	return m_pCocosEntity;
}

void CEntityNode::AddListener(const std::string& a_rEvent, const CEventCallback& a_rCallback)
{
	std::map<std::string, std::vector<CEventCallback>>::iterator it = m_mListeners.find(a_rEvent);
	if (it != m_mListeners.end())
	{
		it->second.push_back(a_rCallback);
	}
	else
	{
		std::vector<CEventCallback> oCallbacks;
		oCallbacks.push_back(a_rCallback);
		m_mListeners.insert(std::pair<std::string, std::vector<CEventCallback>>(a_rEvent, oCallbacks));
	}
}

void CEntityNode::DisableEvent(const std::string& a_rEvent)
{
	m_oDisabledEvents.insert(a_rEvent);
}

void CEntityNode::EnableEvent(const std::string& a_rEvent)
{
	m_oDisabledEvents.erase(a_rEvent);
}

bool CEntityNode::EventIsDisabled(const std::string& a_rEvent)
{
	return (m_oDisabledEvents.find(a_rEvent) != m_oDisabledEvents.end());
}

bool CEntityNode::IsListeningTo(const std::string& a_rEvent)
{
	if (m_oDisabledEvents.find(a_rEvent) == m_oDisabledEvents.end())
	{
		std::map<std::string, std::vector<CEventCallback>>::iterator it = m_mListeners.find(a_rEvent);
		return (it != m_mListeners.end());
	}
}

void CEntityNode::Dispatch(const std::string& a_rEvent, CEntityNode* a_pSender)
{
	if (m_oDisabledEvents.find(a_rEvent) == m_oDisabledEvents.end())
	{
		std::map<std::string, std::vector<CEventCallback>>::iterator it = m_mListeners.find(a_rEvent);
		if (it != m_mListeners.end())
		{
			for (CEventCallback oCallback : it->second)
			{
				CCLOG("CEntity::Dispatch : Calling callback %s on entity %s", a_rEvent.c_str(), m_sID.c_str());
				oCallback(a_pSender);
			}
		}
	}
}

void CEntityNode::PopulateParent(bool a_bDoScaling)
{

	// Size oVisibleSize = Director::getInstance()->getVisibleSize();
	// Vec2 oOrigin = Director::getInstance()->getVisibleOrigin();
  Size oVisibleSize = GetParentVisibleSize();
  Vec2 oOrigin = GetParentOrigin();

	switch (m_eAnchor)
	{
	case LM::CENTER:
		m_pCocosEntity->setAnchorPoint(Vec2(0.5, 0.5));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width/2, oOrigin.y + oVisibleSize.height/2));
		break;
	case LM::BOTTOM_LEFT:
		m_pCocosEntity->setAnchorPoint(Vec2(0, 0));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x, oOrigin.y));
		break;
	case LM::LEFT:
		m_pCocosEntity->setAnchorPoint(Vec2(0, 0.5));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x, oOrigin.y + oVisibleSize.height / 2));
		break;
	case LM::TOP_LEFT:
		m_pCocosEntity->setAnchorPoint(Vec2(0, 1));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x, oOrigin.y + oVisibleSize.height));
		break;
	case LM::TOP:
		m_pCocosEntity->setAnchorPoint(Vec2(0.5, 1));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width / 2, oOrigin.y + oVisibleSize.height));
		break;
	case LM::TOP_RIGHT:
		m_pCocosEntity->setAnchorPoint(Vec2(1, 1));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width, oOrigin.y + oVisibleSize.height));
		break;
	case LM::RIGHT:
		m_pCocosEntity->setAnchorPoint(Vec2(1, 0.5));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width, oOrigin.y + oVisibleSize.height / 2));
		break;
	case LM::BOTTOM_RIGHT:
		m_pCocosEntity->setAnchorPoint(Vec2(1, 0));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width, oOrigin.y));
		break;
	case LM::BOTTOM:
		m_pCocosEntity->setAnchorPoint(Vec2(0.5, 0));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width / 2, oOrigin.y));
		break;
	case LM::FLOAT:
		m_pCocosEntity->setAnchorPoint(Vec2(0.5, 0.5));
		m_pCocosEntity->setPosition(Vec2(m_iXPosition, m_iYPosition));
		break;
	default:
		break;
	}

	if (a_bDoScaling) {

		float fNewScale;

		if (m_iWidth != 0)
		{
			float fOldWidth = m_pCocosEntity->getBoundingBox().getMaxX() - m_pCocosEntity->getBoundingBox().getMinX();
			float fNewWidth = oVisibleSize.width * ((float)m_iWidth / 100.0f);
			fNewScale = fNewWidth / fOldWidth;
		}
		else
		{
			float fOldHeight = m_pCocosEntity->getBoundingBox().getMaxY() - m_pCocosEntity->getBoundingBox().getMinY();
			float fNewHeight = oVisibleSize.height * ((float)m_iHeight / 100.0f);
			fNewScale = fNewHeight / fOldHeight;
		}

		m_pCocosEntity->setScale(fNewScale);

	}
	cocos2d::Scene* pScene = GetParentScene();
	if (pScene)
	{
		pScene->addChild(m_pCocosEntity, 0);
	}

	m_pCocosEntity->setVisible(m_bVisible);

	m_oEntityStartLocation = m_pCocosEntity->getPosition();
	m_fEntityStartScale = m_pCocosEntity->getScale();

	Dispatch("Init");
}

Scene* CEntityNode::GetParentScene()
{
	CSceneNode* pParentScene = dynamic_cast<CSceneNode*>(m_pParent);
	if (pParentScene)
	{
		return pParentScene->GetScene();
	}
	else
	{
		CEntityNode* pParentNode = dynamic_cast<CEntityNode*>(m_pParent);
		if (pParentNode)
		{
			return pParentNode->GetParentScene();
		}
	}
}

Size CEntityNode::GetParentVisibleSize()
{

  CEntityNode* pParentEntity = dynamic_cast<CEntityNode*>(m_pParent);
  if (pParentEntity)
  {
    return pParentEntity->GetVisibleSize();
  }

  return Director::getInstance()->getVisibleSize();

}

Vec2 CEntityNode::GetParentOrigin()
{
  CEntityNode* pParentEntity = dynamic_cast<CEntityNode*>(m_pParent);
  if (pParentEntity)
  {
    return pParentEntity->GetOrigin();
  }

  return Director::getInstance()->getVisibleOrigin();
}

Size CEntityNode::GetVisibleSize()
{
	//return m_pCocosEntity->getContentSize();
	Rect oBoundingBox = m_pCocosEntity->getBoundingBox();
	return Size(oBoundingBox.getMaxX() - oBoundingBox.getMinX(),
		oBoundingBox.getMaxY() - oBoundingBox.getMinY());
}

Vec2 CEntityNode::GetOrigin()
{
	Rect oBoundingBox = m_pCocosEntity->getBoundingBox();
	return Vec2(oBoundingBox.getMinX(), oBoundingBox.getMinY());
}

void CEntityNode::SetVisible(bool a_bVisible)
{
	m_bVisible = a_bVisible;
}

bool CEntityNode::IsVisible()
{
	return m_bVisible;
}

std::string CEntityNode::GetID()
{
	return m_sID;
}

void CEntityNode::SetID(const std::string& a_rID)
{
	m_sID = a_rID;
}

void CEntityNode::Show(bool a_bVisible)
{
	if (GetID() != "" && a_bVisible)
		CCLOG("Showing entity : %s", GetID().c_str());

	m_bVisible = a_bVisible;
	if (m_pCocosEntity)
	{
		m_pCocosEntity->setVisible(a_bVisible);
		FadeIn();
	}

	for (CNode* itNode : *this)
	{
		CEntityNode* pEntity = dynamic_cast<CEntityNode*>(itNode);
		if (pEntity && (!pEntity->IsListeningTo("Show") || !a_bVisible))
		{
			pEntity->Show(a_bVisible);
		}
	}

}

bool CEntityNode::IsLocked()
{
	return m_bLocked;
}

Vec2 CEntityNode::GetEntityStartLocation()
{
	return m_oEntityStartLocation;
}

float CEntityNode::GetEntityStartScale()
{
	return m_fEntityStartScale;
}

void CEntityNode::Fade()
{
	auto fpReleaseEntity = CallFunc::create([this]() {
		CEntityNode::Release(this);
		this->Revert();
	});

	auto oFadeOut = FadeOut::create(1.0f);
	auto oSequence = Sequence::create(oFadeOut, fpReleaseEntity, nullptr);

	m_pCocosEntity->runAction(oSequence);

	for (CNode* itNode : m_vChildren)
	{
		CEntityNode* pChildEntity = dynamic_cast<CEntityNode*>(itNode);
		if (pChildEntity)
		{
			pChildEntity->Fade();
		}
	}
}

void CEntityNode::FadeIn()
{
	CCLOG("CEntityNode::FadeIn %s", m_sID.c_str());
	auto oFadeIn = FadeIn::create(0.5f);

	m_pCocosEntity->runAction(oFadeIn);

	/*for (CNode* itNode : m_vChildren)
	{
		CEntityNode* pChildEntity = dynamic_cast<CEntityNode*>(itNode);
		if (pChildEntity)
		{
			pChildEntity->FadeIn();
		}
	}*/
}

bool CEntityNode::Lock(CEntityNode* a_pEntity)
{
	if (!a_pEntity->IsLocked())
	{
		a_pEntity->m_bLocked = true;
		for (CNode* itNode : *a_pEntity)
		{
			CEntityNode* pEntity = dynamic_cast<CEntityNode*>(itNode);
			if (pEntity)
			{
				CEntityNode::Lock(pEntity);
			}
		}
		return true;
	}
	return false;
}

void CEntityNode::Release(CEntityNode* a_pEntity)
{
	a_pEntity->m_bLocked = false;
	for (CNode* itNode : *a_pEntity)
	{
		CEntityNode* pEntity = dynamic_cast<CEntityNode*>(itNode);
		if (pEntity)
		{
			CEntityNode::Release(pEntity);
		}
	}
}

} // namespace LM
<commit_msg>[FIX] fixed entities disappearing on transitions<commit_after>#include "../Include/CEntityNode.h"
#include "../Include/CSceneNode.h"
#include "../Include/CMenuNode.h"

#include "cocos2d.h"

using namespace cocos2d;

namespace LM
{

CEntityNode::CEntityNode(EAnchor a_eAnchor, int a_iWidth, int a_iHeight,
						 int a_iXPosition, int a_iYPosition, const std::string& a_sID) :
    m_eAnchor(a_eAnchor),
	m_iXPosition(a_iXPosition),
    m_iYPosition(a_iYPosition),
	m_iWidth(a_iWidth),
	m_iHeight(a_iHeight),
	m_bVisible(true),
	m_bLocked(false),
	m_sID(a_sID),
	m_fEntityStartScale(0),
	m_pCocosEntity(nullptr)
{
}

void CEntityNode::UnInit(bool removeChild)
{
	//m_pCocosEntity->autorelease();
	//m_pCocosEntity->release();
	if (m_pCocosEntity != nullptr) {
		if(removeChild)
			GetParentScene()->removeChild(m_pCocosEntity);

		m_pCocosEntity = nullptr;
		CNode::UnInit(removeChild);
	}
	else {
		return;
	}
}

void CEntityNode::Revert(bool a_bVisible)
{
	Show(a_bVisible);
	if (m_sID != "")
		CCLOG("reverting : %s", m_sID.c_str());
	m_pCocosEntity->setPosition(m_oEntityStartLocation);
	m_pCocosEntity->setScale(m_fEntityStartScale);
        for (CNode* itNode : m_vChildren)
        {
          CEntityNode* pEntity = dynamic_cast<CEntityNode*>(itNode);
          if (pEntity)
          {
            pEntity->Revert(a_bVisible);
          }
        }
}

cocos2d::Node* CEntityNode::GetCocosEntity()
{
	return m_pCocosEntity;
}

void CEntityNode::AddListener(const std::string& a_rEvent, const CEventCallback& a_rCallback)
{
	std::map<std::string, std::vector<CEventCallback>>::iterator it = m_mListeners.find(a_rEvent);
	if (it != m_mListeners.end())
	{
		it->second.push_back(a_rCallback);
	}
	else
	{
		std::vector<CEventCallback> oCallbacks;
		oCallbacks.push_back(a_rCallback);
		m_mListeners.insert(std::pair<std::string, std::vector<CEventCallback>>(a_rEvent, oCallbacks));
	}
}

void CEntityNode::DisableEvent(const std::string& a_rEvent)
{
	m_oDisabledEvents.insert(a_rEvent);
}

void CEntityNode::EnableEvent(const std::string& a_rEvent)
{
	m_oDisabledEvents.erase(a_rEvent);
}

bool CEntityNode::EventIsDisabled(const std::string& a_rEvent)
{
	return (m_oDisabledEvents.find(a_rEvent) != m_oDisabledEvents.end());
}

bool CEntityNode::IsListeningTo(const std::string& a_rEvent)
{
	if (m_oDisabledEvents.find(a_rEvent) == m_oDisabledEvents.end())
	{
		std::map<std::string, std::vector<CEventCallback>>::iterator it = m_mListeners.find(a_rEvent);
		return (it != m_mListeners.end());
	}
}

void CEntityNode::Dispatch(const std::string& a_rEvent, CEntityNode* a_pSender)
{
	if (m_oDisabledEvents.find(a_rEvent) == m_oDisabledEvents.end())
	{
		std::map<std::string, std::vector<CEventCallback>>::iterator it = m_mListeners.find(a_rEvent);
		if (it != m_mListeners.end())
		{
			for (CEventCallback oCallback : it->second)
			{
				CCLOG("CEntity::Dispatch : Calling callback %s on entity %s", a_rEvent.c_str(), m_sID.c_str());
				oCallback(a_pSender);
			}
		}
	}
}

void CEntityNode::PopulateParent(bool a_bDoScaling)
{

	// Size oVisibleSize = Director::getInstance()->getVisibleSize();
	// Vec2 oOrigin = Director::getInstance()->getVisibleOrigin();
  Size oVisibleSize = GetParentVisibleSize();
  Vec2 oOrigin = GetParentOrigin();

	switch (m_eAnchor)
	{
	case LM::CENTER:
		m_pCocosEntity->setAnchorPoint(Vec2(0.5, 0.5));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width/2, oOrigin.y + oVisibleSize.height/2));
		break;
	case LM::BOTTOM_LEFT:
		m_pCocosEntity->setAnchorPoint(Vec2(0, 0));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x, oOrigin.y));
		break;
	case LM::LEFT:
		m_pCocosEntity->setAnchorPoint(Vec2(0, 0.5));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x, oOrigin.y + oVisibleSize.height / 2));
		break;
	case LM::TOP_LEFT:
		m_pCocosEntity->setAnchorPoint(Vec2(0, 1));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x, oOrigin.y + oVisibleSize.height));
		break;
	case LM::TOP:
		m_pCocosEntity->setAnchorPoint(Vec2(0.5, 1));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width / 2, oOrigin.y + oVisibleSize.height));
		break;
	case LM::TOP_RIGHT:
		m_pCocosEntity->setAnchorPoint(Vec2(1, 1));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width, oOrigin.y + oVisibleSize.height));
		break;
	case LM::RIGHT:
		m_pCocosEntity->setAnchorPoint(Vec2(1, 0.5));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width, oOrigin.y + oVisibleSize.height / 2));
		break;
	case LM::BOTTOM_RIGHT:
		m_pCocosEntity->setAnchorPoint(Vec2(1, 0));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width, oOrigin.y));
		break;
	case LM::BOTTOM:
		m_pCocosEntity->setAnchorPoint(Vec2(0.5, 0));
		m_pCocosEntity->setPosition(Vec2(oOrigin.x + oVisibleSize.width / 2, oOrigin.y));
		break;
	case LM::FLOAT:
		m_pCocosEntity->setAnchorPoint(Vec2(0.5, 0.5));
		m_pCocosEntity->setPosition(Vec2(m_iXPosition, m_iYPosition));
		break;
	default:
		break;
	}

	if (a_bDoScaling) {

		float fNewScale;

		if (m_iWidth != 0)
		{
			float fOldWidth = m_pCocosEntity->getBoundingBox().getMaxX() - m_pCocosEntity->getBoundingBox().getMinX();
			float fNewWidth = oVisibleSize.width * ((float)m_iWidth / 100.0f);
			fNewScale = fNewWidth / fOldWidth;
		}
		else
		{
			float fOldHeight = m_pCocosEntity->getBoundingBox().getMaxY() - m_pCocosEntity->getBoundingBox().getMinY();
			float fNewHeight = oVisibleSize.height * ((float)m_iHeight / 100.0f);
			fNewScale = fNewHeight / fOldHeight;
		}

		m_pCocosEntity->setScale(fNewScale);

	}
	cocos2d::Scene* pScene = GetParentScene();
	if (pScene)
	{
		pScene->addChild(m_pCocosEntity, 0);
	}

	m_pCocosEntity->setVisible(m_bVisible);

	m_oEntityStartLocation = m_pCocosEntity->getPosition();
	m_fEntityStartScale = m_pCocosEntity->getScale();

	Dispatch("Init");
}

Scene* CEntityNode::GetParentScene()
{
	CSceneNode* pParentScene = dynamic_cast<CSceneNode*>(m_pParent);
	if (pParentScene)
	{
		return pParentScene->GetScene();
	}
	else
	{
		CEntityNode* pParentNode = dynamic_cast<CEntityNode*>(m_pParent);
		if (pParentNode)
		{
			return pParentNode->GetParentScene();
		}
	}
}

Size CEntityNode::GetParentVisibleSize()
{

  CEntityNode* pParentEntity = dynamic_cast<CEntityNode*>(m_pParent);
  if (pParentEntity)
  {
    return pParentEntity->GetVisibleSize();
  }

  return Director::getInstance()->getVisibleSize();

}

Vec2 CEntityNode::GetParentOrigin()
{
  CEntityNode* pParentEntity = dynamic_cast<CEntityNode*>(m_pParent);
  if (pParentEntity)
  {
    return pParentEntity->GetOrigin();
  }

  return Director::getInstance()->getVisibleOrigin();
}

Size CEntityNode::GetVisibleSize()
{
	//return m_pCocosEntity->getContentSize();
	Rect oBoundingBox = m_pCocosEntity->getBoundingBox();
	return Size(oBoundingBox.getMaxX() - oBoundingBox.getMinX(),
		oBoundingBox.getMaxY() - oBoundingBox.getMinY());
}

Vec2 CEntityNode::GetOrigin()
{
	Rect oBoundingBox = m_pCocosEntity->getBoundingBox();
	return Vec2(oBoundingBox.getMinX(), oBoundingBox.getMinY());
}

void CEntityNode::SetVisible(bool a_bVisible)
{
	m_bVisible = a_bVisible;
}

bool CEntityNode::IsVisible()
{
	return m_bVisible;
}

std::string CEntityNode::GetID()
{
	return m_sID;
}

void CEntityNode::SetID(const std::string& a_rID)
{
	m_sID = a_rID;
}

void CEntityNode::Show(bool a_bVisible)
{
	if (GetID() != "" && a_bVisible)
		CCLOG("Showing entity : %s", GetID().c_str());

	m_bVisible = a_bVisible;
	if (m_pCocosEntity)
	{
		m_pCocosEntity->setVisible(a_bVisible);
		FadeIn();
	}

	for (CNode* itNode : *this)
	{
		CEntityNode* pEntity = dynamic_cast<CEntityNode*>(itNode);
		if (pEntity && (!pEntity->IsListeningTo("Show") || !a_bVisible))
		{
			pEntity->Show(a_bVisible);
		}
	}

}

bool CEntityNode::IsLocked()
{
	return m_bLocked;
}

Vec2 CEntityNode::GetEntityStartLocation()
{
	return m_oEntityStartLocation;
}

float CEntityNode::GetEntityStartScale()
{
	return m_fEntityStartScale;
}

void CEntityNode::Fade()
{
	auto fpReleaseEntity = CallFunc::create([this]() {
		CEntityNode::Release(this);
		this->Revert();
	});

	auto oFadeOut = FadeOut::create(1.0f);
	auto oSequence = Sequence::create(oFadeOut, fpReleaseEntity, nullptr);

	m_pCocosEntity->runAction(oSequence);

	for (CNode* itNode : m_vChildren)
	{
		CEntityNode* pChildEntity = dynamic_cast<CEntityNode*>(itNode);
		if (pChildEntity)
		{
			pChildEntity->Fade();
		}
	}
}

void CEntityNode::FadeIn()
{
	CCLOG("CEntityNode::FadeIn %s", m_sID.c_str());
	auto oFadeIn = FadeIn::create(0.5f);

	m_pCocosEntity->runAction(oFadeIn);

	/*for (CNode* itNode : m_vChildren)
	{
		CEntityNode* pChildEntity = dynamic_cast<CEntityNode*>(itNode);
		if (pChildEntity)
		{
			pChildEntity->FadeIn();
		}
	}*/
}

bool CEntityNode::Lock(CEntityNode* a_pEntity)
{
	if (!a_pEntity->IsLocked())
	{
		a_pEntity->m_bLocked = true;
		for (CNode* itNode : *a_pEntity)
		{
			CEntityNode* pEntity = dynamic_cast<CEntityNode*>(itNode);
			if (pEntity)
			{
				CEntityNode::Lock(pEntity);
			}
		}
		return true;
	}
	return false;
}

void CEntityNode::Release(CEntityNode* a_pEntity)
{
	a_pEntity->m_bLocked = false;
	for (CNode* itNode : *a_pEntity)
	{
		CEntityNode* pEntity = dynamic_cast<CEntityNode*>(itNode);
		if (pEntity)
		{
			CEntityNode::Release(pEntity);
		}
	}
}

} // namespace LM
<|endoftext|>


<commit_before>#include <vector>
#include <cmath>

#include "../../include/solvers/Solver.h"
#include "../../include/solvers/UCTSolver.h"

namespace mlsolvers
{

mlcore::Action* UCTSolver::pickAction(UCTNode* node, double C)
{
    double best = mdplib::dead_end_cost + 1;
    mlcore::Action* bestAction = nullptr;
    std::vector<mlcore::Action*> unexplored_actions;
                                                                                dprint2("  ==pick action", node);
    auto actions_qvalue_map = action_qvalues_[node];
    int num_actions = actions_qvalue_map.size();
                                                                                dprint2("  num actions", num_actions);
    for (auto action_and_qvalue : actions_qvalue_map) {
        mlcore::Action* a = action_and_qvalue.first;
        if (!problem_->applicable(node->state_, a))
            continue;
        if (counters_node_action_[node][a] == delta_) {  // unexplored action
            unexplored_actions.push_back(a);
            continue;
        }
                                                                                dprint2("    cost for", a);
        if (use_qvalues_for_c_) {
            C = action_and_qvalue.second;
            C /= sqrt(log(num_actions) / (delta_ + 1) + 1);
        }
        double ucb1 = ucb1Cost(node, a, C);
                                                                                dprint2("    ucb1cost =", ucb1);
        if (ucb1 < best) {
            bestAction = a;
            best = ucb1;
        }
    }
    if (unexplored_actions.size() > 0) {
        int idx = rand() % unexplored_actions.size();
                                                                                dprint2("    unexplored", unexplored_actions[idx]);
        return unexplored_actions[idx];
    }
                                                                                dprint2("    best", bestAction);
    return bestAction;
}

double UCTSolver::ucb1Cost(UCTNode* node, mlcore::Action* a, double C)
{
                                                                                dprint4("      counters (node, action) / qvalue =",
                                                                                counters_node_[node],
                                                                                counters_node_action_[node][a],
                                                                                action_qvalues_[node][a]);
    double cost = action_qvalues_[node][a] - C
        * std::sqrt(std::log(counters_node_[node])
                    / counters_node_action_[node][a]);
    return std::min(cost, mdplib::dead_end_cost);
}

mlcore::Action* UCTSolver::solve(mlcore::State* s0)
{
    UCTNode* root = new UCTNode(s0, start_depth_);
    for (int r = 0; r < max_rollouts_; r++) {
        UCTNode* tmp_node = root;
        std::vector<int> cumCost(cutoff_ + 1);
        std::vector<UCTNode*> nodes_in_rollout(cutoff_ + 1);
        std::vector<mlcore::Action*> actions_in_rollout(cutoff_ + 1);
        int maxSteps = 0;
        for (int i = 1; i <= cutoff_; i++) {
            bool first_time_seen = visited_.insert(tmp_node).second;
            if (first_time_seen) {
                counters_node_[tmp_node] = 0;
                                                                                dprint2("count", counters_node_.size());
                for (mlcore::Action* a : problem_->actions()) {
                    if (!problem_->applicable(tmp_node->state_, a))
                        continue;
                    counters_node_action_[tmp_node][a] = delta_;
                    counters_node_[tmp_node] += delta_; // not sure about this
                    action_qvalues_[tmp_node][a] =
                        qvalue(problem_, tmp_node->state_, a);
                }
            }
            if (problem_->goal(tmp_node->state_))
                break;
            maxSteps = i;
            mlcore::Action* a = pickAction(tmp_node, C_);
            mlcore::State* next =
                randomSuccessor(problem_, tmp_node->state_, a);
            cumCost[i] = cumCost[i - 1] + problem_->cost(tmp_node->state_, a);
            nodes_in_rollout[i] = tmp_node;
            actions_in_rollout[i] = a;
            tmp_node = new UCTNode(next, tmp_node->depth_ + 1);
                                                                                dprint2("  ==next", tmp_node);
        }

        for (int i = 1; i <= maxSteps; i++) {
            UCTNode* node = nodes_in_rollout[i];
            mlcore::Action* a = actions_in_rollout[i];
            double newq = counters_node_action_[node][a]
                * action_qvalues_[node][a]
                + cumCost[maxSteps] - cumCost[i - 1];
            newq /= (counters_node_action_[node][a] + 1);
                                                                                dprint3("update-qvalue", node, a);
                                                                                dprint3(counters_node_action_[node][a],
                                                                                newq,
                                                                                cumCost[maxSteps] - cumCost[i - 1]);
            action_qvalues_[node][a] = newq;
            counters_node_[node]++;
            counters_node_action_[node][a]++;
        }
                                                                                dprint1("**************************************");
    }

    if (auto_adjust_depth_) {
        cutoff_++;
        start_depth_++;
    }
    return pickAction(root, 0.0);
}

}

<commit_msg>cleaned up the UCT code<commit_after>#include <vector>
#include <cmath>

#include "../../include/solvers/Solver.h"
#include "../../include/solvers/UCTSolver.h"

namespace mlsolvers
{

mlcore::Action* UCTSolver::pickAction(UCTNode* node, double C)
{
    double best = mdplib::dead_end_cost + 1;
    mlcore::Action* bestAction = nullptr;
    std::vector<mlcore::Action*> unexplored_actions;
    auto actions_qvalue_map = action_qvalues_[node];
    int num_actions = actions_qvalue_map.size();
    for (auto action_and_qvalue : actions_qvalue_map) {
        mlcore::Action* a = action_and_qvalue.first;
        if (!problem_->applicable(node->state_, a))
            continue;
        if (counters_node_action_[node][a] == delta_) {  // unexplored action
            unexplored_actions.push_back(a);
            continue;
        }
        if (use_qvalues_for_c_) {
            C = action_and_qvalue.second;
            C /= sqrt(log(num_actions) / (delta_ + 1) + 1);
        }
        double ucb1 = ucb1Cost(node, a, C);
        if (ucb1 < best) {
            bestAction = a;
            best = ucb1;
        }
    }
    if (unexplored_actions.size() > 0) {
        int idx = rand() % unexplored_actions.size();
        return unexplored_actions[idx];
    }
    return bestAction;
}

double UCTSolver::ucb1Cost(UCTNode* node, mlcore::Action* a, double C)
{
    double cost = action_qvalues_[node][a] - C
        * std::sqrt(std::log(counters_node_[node])
                    / counters_node_action_[node][a]);
    return std::min(cost, mdplib::dead_end_cost);
}

mlcore::Action* UCTSolver::solve(mlcore::State* s0)
{
    UCTNode* root = new UCTNode(s0, start_depth_);
    for (int r = 0; r < max_rollouts_; r++) {
        UCTNode* tmp_node = root;
        std::vector<int> cumCost(cutoff_ + 1);
        std::vector<UCTNode*> nodes_in_rollout(cutoff_ + 1);
        std::vector<mlcore::Action*> actions_in_rollout(cutoff_ + 1);
        int maxSteps = 0;
        for (int i = 1; i <= cutoff_; i++) {
            bool first_time_seen = visited_.insert(tmp_node).second;
            if (first_time_seen) {
                counters_node_[tmp_node] = 0;
                for (mlcore::Action* a : problem_->actions()) {
                    if (!problem_->applicable(tmp_node->state_, a))
                        continue;
                    counters_node_action_[tmp_node][a] = delta_;
                    counters_node_[tmp_node] += delta_; // not sure about this
                    action_qvalues_[tmp_node][a] =
                        qvalue(problem_, tmp_node->state_, a);
                }
            }
            if (problem_->goal(tmp_node->state_))
                break;
            maxSteps = i;
            mlcore::Action* a = pickAction(tmp_node, C_);
            mlcore::State* next =
                randomSuccessor(problem_, tmp_node->state_, a);
            cumCost[i] = cumCost[i - 1] + problem_->cost(tmp_node->state_, a);
            nodes_in_rollout[i] = tmp_node;
            actions_in_rollout[i] = a;
            tmp_node = new UCTNode(next, tmp_node->depth_ + 1);
        }

        for (int i = 1; i <= maxSteps; i++) {
            UCTNode* node = nodes_in_rollout[i];
            mlcore::Action* a = actions_in_rollout[i];
            double newq = counters_node_action_[node][a]
                * action_qvalues_[node][a]
                + cumCost[maxSteps] - cumCost[i - 1];
            newq /= (counters_node_action_[node][a] + 1);
            action_qvalues_[node][a] = newq;
            counters_node_[node]++;
            counters_node_action_[node][a]++;
        }
    }

    if (auto_adjust_depth_) {
        cutoff_++;
        start_depth_++;
    }
    return pickAction(root, 0.0);
}

}

<|endoftext|>


<commit_before>#include <vector>
#include <cmath>

#include "../../include/solvers/Solver.h"
#include "../../include/solvers/UCTSolver.h"

namespace mlsolvers
{
    UCTSolver::UCTSolver(mlcore::Problem* problem, double C, int maxRollouts, int cutoff)
    {
        problem_ = problem;
        C_ = C;
        maxRollouts_ = maxRollouts;
        cutoff_ = cutoff;
    }

    mlcore::Action* UCTSolver::pickUCB1Action(mlcore::State* s)
    {
        return pickAction(s, C_);
    }

    mlcore::Action* UCTSolver::pickAction(mlcore::State* s, double C)
    {
        double best = mdplib::dead_end_cost + 1;
        mlcore::Action* bestAction = nullptr;
        for (std::pair<mlcore::Action*,double> entry : qvalues_[s]) {
            mlcore::Action* a = entry.first;
            if (counterSA_[s][a] == 0)
                return a;
            double ucb1 = ucb1Cost(s, a, entry.second);
            if (ucb1 < best) {
                bestAction = a;
                best = ucb1;
            }
        }
        return bestAction;
    }

    double UCTSolver::ucb1Cost(mlcore::State* s, mlcore::Action* a, double C)
    {
        double cost = qvalues_[s][a] - C*std::sqrt(2 * std::log(counterS_[s]) / counterSA_[s][a]);
        if (cost > mdplib::dead_end_cost)
            cost = mdplib::dead_end_cost;
        return cost;
    }

    mlcore::Action* UCTSolver::solve(mlcore::State* s0)
    {
        for (int r = 0; r < maxRollouts_; r++) {
            mlcore::State* tmp = s0;
            std::vector<int> cumCost(cutoff_ + 1);
            std::vector<mlcore::State*> statesRoll(cutoff_ + 1);
            std::vector<mlcore::Action*> actionsRoll(cutoff_ + 1);
            int maxSteps = 0;
            for (int i = 1; i <= cutoff_; i++) {
                if (visited_.insert(tmp).second) {
                    counterS_[tmp] = 0;
                    for (mlcore::Action* a : problem_->actions()) {
                        if (!problem_->applicable(tmp, a))
                            continue;
                        counterSA_[tmp][a] = 0;
                        qvalues_[tmp][a] = qvalue(problem_, tmp, a);
                    }
                }
                maxSteps = i;
                mlcore::Action* a = pickUCB1Action(tmp);
                mlcore::State* next = randomSuccessor(problem_, tmp, a);
                cumCost[i] = cumCost[i - 1] + problem_->cost(tmp, a);
                statesRoll[i] = tmp;
                actionsRoll[i] = a;
                tmp = next;
                if (problem_->goal(tmp))
                    break;
            }

            for (int i = 1; i <= maxSteps; i++) {
                mlcore::State* s = statesRoll[i];
                mlcore::Action* a = actionsRoll[i];
                double newq = counterSA_[s][a]*qvalues_[s][a] + cumCost[maxSteps] - cumCost[i - 1];
                newq /= (counterSA_[s][a] + 1);
                qvalues_[s][a] = newq;
                counterS_[s]++;
                counterSA_[s][a]++;
            }
        }
        return pickAction(s0, 0.0);
    }
}

<commit_msg>minor changes<commit_after>#include <vector>
#include <cmath>

#include "../../include/solvers/Solver.h"
#include "../../include/solvers/UCTSolver.h"

namespace mlsolvers
{

UCTSolver::UCTSolver(
    mlcore::Problem* problem, double C, int maxRollouts, int cutoff)
{
    problem_ = problem;
    C_ = C;
    maxRollouts_ = maxRollouts;
    cutoff_ = cutoff;
}

mlcore::Action* UCTSolver::pickUCB1Action(mlcore::State* s)
{
    return pickAction(s, C_);
}

mlcore::Action* UCTSolver::pickAction(mlcore::State* s, double C)
{
    double best = mdplib::dead_end_cost + 1;
    mlcore::Action* bestAction = nullptr;
    for (std::pair<mlcore::Action*,double> entry : qvalues_[s]) {
        mlcore::Action* a = entry.first;
        if (counterSA_[s][a] == 0)
            return a;
        double ucb1 = ucb1Cost(s, a, entry.second);
        if (ucb1 < best) {
            bestAction = a;
            best = ucb1;
        }
    }
    return bestAction;
}

double UCTSolver::ucb1Cost(mlcore::State* s, mlcore::Action* a, double C)
{
    double cost = qvalues_[s][a] - C *
        std::sqrt(2 * std::log(counterS_[s]) / counterSA_[s][a]);
    if (cost > mdplib::dead_end_cost)
        cost = mdplib::dead_end_cost;
    return cost;
}

mlcore::Action* UCTSolver::solve(mlcore::State* s0)
{
    for (int r = 0; r < maxRollouts_; r++) {
        mlcore::State* tmp = s0;
        std::vector<int> cumCost(cutoff_ + 1);
        std::vector<mlcore::State*> statesRoll(cutoff_ + 1);
        std::vector<mlcore::Action*> actionsRoll(cutoff_ + 1);
        int maxSteps = 0;
        for (int i = 1; i <= cutoff_; i++) {
            if (visited_.insert(tmp).second) {
                counterS_[tmp] = 0;
                for (mlcore::Action* a : problem_->actions()) {
                    if (!problem_->applicable(tmp, a))
                        continue;
                    counterSA_[tmp][a] = 0;
                    qvalues_[tmp][a] = qvalue(problem_, tmp, a);
                }
            }
            maxSteps = i;
            mlcore::Action* a = pickUCB1Action(tmp);
            mlcore::State* next = randomSuccessor(problem_, tmp, a);
            cumCost[i] = cumCost[i - 1] + problem_->cost(tmp, a);
            statesRoll[i] = tmp;
            actionsRoll[i] = a;
            tmp = next;
            if (problem_->goal(tmp))
                break;
        }

        for (int i = 1; i <= maxSteps; i++) {
            mlcore::State* s = statesRoll[i];
            mlcore::Action* a = actionsRoll[i];
            double newq = counterSA_[s][a] * qvalues_[s][a] +
                cumCost[maxSteps] - cumCost[i - 1];
            newq /= (counterSA_[s][a] + 1);
            qvalues_[s][a] = newq;
            counterS_[s]++;
            counterSA_[s][a]++;
        }
    }
    return pickAction(s0, 0.0);
}

}

<|endoftext|>


<commit_before>
#include <iostream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>

#include <boost/algorithm/string.hpp>

#include <llvm/Support/raw_os_ostream.h>

#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>
#include <libevmjit/Compiler.h>
#include <libevmjit/ExecutionEngine.h>

void show_usage()
{
    // FIXME: Use arg[0] as program name?
    std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
}

int main(int argc, char** argv)
{

    std::string input_file;
    bool opt_dissassemble = false;
    bool opt_show_bytes = false;
	bool opt_compile = false;
	bool opt_interpret = false;
	bool opt_dump_graph = false;
	bool opt_unknown = false;

    for (int i = 1; i < argc; i++)
    {
        std::string option = argv[i];
        if (option == "-b")
            opt_show_bytes = true;
        else if (option == "-c")
            opt_compile = true;
        else if (option == "-d")
			opt_dissassemble = true;
		else if (option == "-i")
			opt_interpret = true;
		else if (option == "-g")
			opt_dump_graph = true;
		else if (option[0] != '-' && input_file.empty())
			input_file = option;
        else
        {
            opt_unknown = true;
            break;
        }
    }

    if (opt_unknown ||
        input_file.empty() ||
        (!opt_show_bytes && !opt_compile && !opt_dissassemble && !opt_interpret))
    {
        show_usage();
        exit(1);
    }

    std::ifstream ifs(input_file);
    if (!ifs.is_open())
    {
        std::cerr << "cannot open file " << input_file << std::endl;
        exit(1);
    }

    std::string src((std::istreambuf_iterator<char>(ifs)),
		    (std::istreambuf_iterator<char>()));

    boost::algorithm::trim(src);

	using namespace dev;

    bytes bytecode = fromHex(src);

    if (opt_show_bytes)
    {
        std::cout << memDump(bytecode) << std::endl;
    }

    if (opt_dissassemble)
    {
        std::string assembly = eth::disassemble(bytecode);
        std::cout << assembly << std::endl;
    }

    if (opt_compile)
    {
    	auto compiler = eth::jit::Compiler();
		auto module = compiler.compile({bytecode.data(), bytecode.size()});
		llvm::raw_os_ostream out(std::cout);
		module->print(out, nullptr);

		if (opt_dump_graph)
		{
			std::ofstream ofs("blocks.dot");
			compiler.dumpBasicBlockGraph(ofs);
			ofs.close();
			std::cout << "Basic blocks graph written to block.dot\n";
		}
    }

	if (opt_interpret)
	{
		auto engine = eth::jit::ExecutionEngine();
		auto module = eth::jit::Compiler().compile({bytecode.data(), bytecode.size()});
		module->dump();
		u256 gas = 10000;
		auto result = engine.run(std::move(module), gas);
		return result;
	}

    return 0;
}
<commit_msg>minor changes in the compiler driver<commit_after>
#include <iostream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>

#include <boost/algorithm/string.hpp>

#include <llvm/Support/raw_os_ostream.h>

#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>
#include <libevmjit/Compiler.h>
#include <libevmjit/ExecutionEngine.h>

void show_usage()
{
    // FIXME: Use arg[0] as program name?
    std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
}

int main(int argc, char** argv)
{

    std::string input_file;
    bool opt_dissassemble = false;
    bool opt_show_bytes = false;
	bool opt_compile = false;
	bool opt_interpret = false;
	bool opt_dump_graph = false;
	bool opt_unknown = false;

    for (int i = 1; i < argc; i++)
    {
        std::string option = argv[i];
        if (option == "-b")
            opt_show_bytes = true;
        else if (option == "-c")
            opt_compile = true;
        else if (option == "-d")
			opt_dissassemble = true;
		else if (option == "-i")
			opt_interpret = true;
		else if (option == "-g")
			opt_dump_graph = true;
		else if (option[0] != '-' && input_file.empty())
			input_file = option;
        else
        {
            opt_unknown = true;
            break;
        }
    }

    if (opt_unknown ||
        input_file.empty() ||
        (!opt_show_bytes && !opt_compile && !opt_dissassemble && !opt_interpret))
    {
        show_usage();
        exit(1);
    }

    std::ifstream ifs(input_file);
    if (!ifs.is_open())
    {
        std::cerr << "cannot open file " << input_file << std::endl;
        exit(1);
    }

    std::string src((std::istreambuf_iterator<char>(ifs)),
		    (std::istreambuf_iterator<char>()));

    boost::algorithm::trim(src);

	using namespace dev;

    bytes bytecode = fromHex(src);

    if (opt_show_bytes)
    {
        std::cout << memDump(bytecode) << std::endl;
    }

    if (opt_dissassemble)
    {
        std::string assembly = eth::disassemble(bytecode);
        std::cout << assembly << std::endl;
    }

    if (opt_compile || opt_interpret)
    {
    	auto compiler = eth::jit::Compiler();
		auto module = compiler.compile({bytecode.data(), bytecode.size()});

		module->dump();

		if (opt_dump_graph)
		{
			std::ofstream ofs("blocks.dot");
			compiler.dumpBasicBlockGraph(ofs);
			ofs.close();
			std::cout << "Basic blocks graph written to block.dot\n";
		}

		if (opt_interpret)
		{
			auto engine = eth::jit::ExecutionEngine();
			u256 gas = 10000;
			auto result = engine.run(std::move(module), gas);
			return result;
		}
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2008 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ManagerFile>

#include <QtCore/QDir>
#include <QtCore/QHash>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtDBus/QDBusVariant>

#include <TelepathyQt4/KeyFile>
#include <TelepathyQt4/Constants>

#include "TelepathyQt4/debug-internal.h"

namespace Tp
{

struct ManagerFile::Private
{
    QString cmName;
    KeyFile keyFile;
    QHash<QString, ParamSpecList> protocolParams;

    Private(const QString &cnName);

    void init();
    bool parse(const QString &fileName);
    bool isValid() const;

    bool hasParameter(const QString &protocol, const QString &paramName) const;
    ParamSpec *getParameter(const QString &protocol, const QString &paramName);
    QStringList protocols() const;
    ParamSpecList parameters(const QString &protocol) const;

    QVariant valueForKey(const QString &param, const QString &signature);
};

ManagerFile::Private::Private(const QString &cmName)
    : cmName(cmName)
{
    init();
}

void ManagerFile::Private::init()
{
    // TODO: should we cache the configDirs anywhere?
    QStringList configDirs;

    QString xdgDataHome = QString::fromLocal8Bit(qgetenv("XDG_DATA_HOME"));
    if (xdgDataHome.isEmpty()) {
        configDirs << QDir::homePath() + "/.local/share/data/telepathy/managers/";
    }
    else {
        configDirs << xdgDataHome + QLatin1String("/telepathy/managers/");
    }

    QString xdgDataDirsEnv = QString::fromLocal8Bit(qgetenv("XDG_DATA_DIRS"));
    if (xdgDataDirsEnv.isEmpty()) {
        configDirs << "/usr/local/share/telepathy/managers/";
        configDirs << "/usr/share/telepathy/managers/";
    }
    else {
        QStringList xdgDataDirs = xdgDataDirsEnv.split(QLatin1Char(':'));
        Q_FOREACH (const QString xdgDataDir, xdgDataDirs) {
            configDirs << xdgDataDir + QLatin1String("/telepathy/managers/");
        }
    }

    Q_FOREACH (const QString configDir, configDirs) {
        QString fileName = configDir + cmName + QLatin1String(".manager");
        if (QFile::exists(fileName)) {
            debug() << "parsing manager file" << fileName;
            if (!parse(fileName)) {
                warning() << "error parsing manager file" << fileName;
                continue;
            }
            return;
        }
    }
}

bool ManagerFile::Private::parse(const QString &fileName)
{
    keyFile.setFileName(fileName);
    if (keyFile.status() != KeyFile::NoError) {
        return false;
    }

    /* read supported protocols and parameters */
    QString protocol;
    QStringList groups = keyFile.allGroups();
    Q_FOREACH (const QString group, groups) {
        if (group.startsWith("Protocol ")) {
            protocol = group.right(group.length() - 9);
            keyFile.setGroup(group);

            ParamSpecList paramSpecList;
            QString param;
            QStringList params = keyFile.keys();
            Q_FOREACH (param, params) {
                ParamSpec spec;
                spec.flags = 0;
                if (param.startsWith("param-")) {
                    spec.name = param.right(param.length() - 6);

                    if (spec.name.endsWith("password")) {
                        spec.flags |= ConnMgrParamFlagSecret;
                    }

                    QStringList values = keyFile.value(param).split(QChar(' '));

                    spec.signature = values[0];
                    if (values.contains("secret")) {
                        spec.flags |= ConnMgrParamFlagSecret;
                    }
                    if (values.contains("dbus-property")) {
                        spec.flags |= ConnMgrParamFlagDBusProperty;
                    }
                    if (values.contains("required")) {
                        spec.flags |= ConnMgrParamFlagRequired;
                    }
                    if (values.contains("register")) {
                        spec.flags |= ConnMgrParamFlagRegister;
                    }

                    paramSpecList.append(spec);
                }
            }

            protocolParams[protocol] = paramSpecList;

            /* now that we have all param-* created, let's find their default values */
            Q_FOREACH (param, params) {
                if (param.startsWith("default-")) {
                    QString paramName = param.right(param.length() - 8);

                    if (!hasParameter(protocol, paramName)) {
                        warning() << "param" << paramName
                                  << "has default value set, but not a definition";
                        continue;
                    }

                    ParamSpec *spec = getParameter(protocol, paramName);

                    spec->flags |= ConnMgrParamFlagHasDefault;

                    /* map based on the param dbus signature, otherwise use
                     * QString */
                    QVariant value = valueForKey(param, spec->signature);
                    spec->defaultValue = QDBusVariant(value);
                }
            }
        }
    }

    return true;
}

bool ManagerFile::Private::isValid() const
{
    return (keyFile.status() == KeyFile::NoError);
}

bool ManagerFile::Private::hasParameter(const QString &protocol,
                                        const QString &paramName) const
{
    ParamSpecList paramSpecList = protocolParams[protocol];
    Q_FOREACH (ParamSpec paramSpec, paramSpecList) {
        if (paramSpec.name == paramName) {
            return true;
        }
    }
    return false;
}

ParamSpec *ManagerFile::Private::getParameter(const QString &protocol,
                                              const QString &paramName)
{
    ParamSpecList &paramSpecList = protocolParams[protocol];
    for (int i = 0; i < paramSpecList.size(); ++i) {
        ParamSpec &paramSpec = paramSpecList[i];
        if (paramSpec.name == paramName) {
            return &paramSpec;
        }
    }
    return NULL;
}

QStringList ManagerFile::Private::protocols() const
{
    return protocolParams.keys();
}

ParamSpecList ManagerFile::Private::parameters(const QString &protocol) const
{
    return protocolParams.value(protocol);
}

QVariant ManagerFile::Private::valueForKey(const QString &param,
                                           const QString &signature)
{
    QVariant::Type type = ManagerFile::variantTypeFromDBusSignature(signature);

    if (type == QVariant::Invalid) {
        return QVariant(type);
    }

    switch (type) {
        case QVariant::Bool:
            {
                QString value = keyFile.value(param);
                if (value.toLower() == "true" || value == "1") {
                    return QVariant(true);
                }
                else {
                    return QVariant(false);
                }
                break;
            }
        case QVariant::Int:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toInt());
            }
        case QVariant::UInt:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toUInt());
            }
        case QVariant::LongLong:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toLongLong());
            }
        case QVariant::ULongLong:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toULongLong());
            }
        case QVariant::Double:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toDouble());
            }
        case QVariant::StringList:
            {
                QStringList value = keyFile.valueAsStringList(param);
                return QVariant(value);
            }
        default:
            {
                QString value = keyFile.value(param);
                return QVariant(value);
            }
    }
}

/**
 * \class ManagerFile
 * \headerfile <TelepathyQt4/manager-file.h> <TelepathyQt4/ManagerFile>
 *
 * The ManagerFile class provides an easy way to read telepathy manager files
 * according to http://telepathy.freedesktop.org/spec.html.
 */

/**
 * Create a ManagerFile object used to read .manager compliant files.
 *
 * \param cmName Name of the connection manager to read the file for.
 */
ManagerFile::ManagerFile(const QString &cmName)
    : mPriv(new Private(cmName))
{
}

/**
 * Class destructor.
 */
ManagerFile::~ManagerFile()
{
    delete mPriv;
}

/**
 * Check whether or not a ManagerFile object is valid. If the file for the
 * specified connection manager cannot be found it will be considered invalid.
 *
 * \return true if valid, false otherwise.
 */
bool ManagerFile::isValid() const
{
    return mPriv->isValid();
}

/**
 * Return a list of all protocols defined in the manager file.
 *
 * \return List of all protocols defined in the file.
 */
QStringList ManagerFile::protocols() const
{
    return mPriv->protocols();
}

/**
 * Return a list of all protocols defined in the manager file.
 *
 * \param protocol Name of the protocol to look for.
 * \return List of ParamSpec of a specific protocol defined in the file, or an
 *         empty list if the protocol is not defined.
 */
ParamSpecList ManagerFile::parameters(const QString &protocol) const
{
    return mPriv->parameters(protocol);
}

QVariant::Type ManagerFile::variantTypeFromDBusSignature(const QString &signature)
{
    QVariant::Type type;
    if (signature == "b")
        type = QVariant::Bool;
    else if (signature == "n" || signature == "i")
        type = QVariant::Int;
    else if (signature == "q" || signature == "u")
        type = QVariant::UInt;
    else if (signature == "x")
        type = QVariant::LongLong;
    else if (signature == "t")
        type = QVariant::ULongLong;
    else if (signature == "d")
        type = QVariant::Double;
    else if (signature == "as")
        type = QVariant::StringList;
    else if (signature == "s" || signature == "o")
        type = QVariant::String;
    else
        type = QVariant::Invalid;

    return type;
}

} // Tp
<commit_msg>manager-file: Fixed build with some gcc versions.<commit_after>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2008 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ManagerFile>

#include <QtCore/QDir>
#include <QtCore/QHash>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtDBus/QDBusVariant>

#include <TelepathyQt4/KeyFile>
#include <TelepathyQt4/Constants>

#include "TelepathyQt4/debug-internal.h"

namespace Tp
{

struct ManagerFile::Private
{
    QString cmName;
    KeyFile keyFile;
    QHash<QString, ParamSpecList> protocolParams;

    Private(const QString &cnName);

    void init();
    bool parse(const QString &fileName);
    bool isValid() const;

    bool hasParameter(const QString &protocol, const QString &paramName) const;
    ParamSpec *getParameter(const QString &protocol, const QString &paramName);
    QStringList protocols() const;
    ParamSpecList parameters(const QString &protocol) const;

    QVariant valueForKey(const QString &param, const QString &signature);
};

ManagerFile::Private::Private(const QString &cmName)
    : cmName(cmName)
{
    init();
}

void ManagerFile::Private::init()
{
    // TODO: should we cache the configDirs anywhere?
    QStringList configDirs;

    QString xdgDataHome = QString::fromLocal8Bit(qgetenv("XDG_DATA_HOME"));
    if (xdgDataHome.isEmpty()) {
        configDirs << QDir::homePath() + "/.local/share/data/telepathy/managers/";
    }
    else {
        configDirs << xdgDataHome + QLatin1String("/telepathy/managers/");
    }

    QString xdgDataDirsEnv = QString::fromLocal8Bit(qgetenv("XDG_DATA_DIRS"));
    if (xdgDataDirsEnv.isEmpty()) {
        configDirs << "/usr/local/share/telepathy/managers/";
        configDirs << "/usr/share/telepathy/managers/";
    }
    else {
        QStringList xdgDataDirs = xdgDataDirsEnv.split(QLatin1Char(':'));
        Q_FOREACH (const QString xdgDataDir, xdgDataDirs) {
            configDirs << xdgDataDir + QLatin1String("/telepathy/managers/");
        }
    }

    Q_FOREACH (const QString configDir, configDirs) {
        QString fileName = configDir + cmName + QLatin1String(".manager");
        if (QFile::exists(fileName)) {
            debug() << "parsing manager file" << fileName;
            if (!parse(fileName)) {
                warning() << "error parsing manager file" << fileName;
                continue;
            }
            return;
        }
    }
}

bool ManagerFile::Private::parse(const QString &fileName)
{
    keyFile.setFileName(fileName);
    if (keyFile.status() != KeyFile::NoError) {
        return false;
    }

    /* read supported protocols and parameters */
    QString protocol;
    QStringList groups = keyFile.allGroups();
    Q_FOREACH (const QString group, groups) {
        if (group.startsWith("Protocol ")) {
            protocol = group.right(group.length() - 9);
            keyFile.setGroup(group);

            ParamSpecList paramSpecList;
            QString param;
            QStringList params = keyFile.keys();
            Q_FOREACH (param, params) {
                ParamSpec spec;
                spec.flags = 0;
                if (param.startsWith("param-")) {
                    spec.name = param.right(param.length() - 6);

                    if (spec.name.endsWith("password")) {
                        spec.flags |= ConnMgrParamFlagSecret;
                    }

                    QStringList values = keyFile.value(param).split(QChar(' '));

                    spec.signature = values[0];
                    if (values.contains("secret")) {
                        spec.flags |= ConnMgrParamFlagSecret;
                    }
                    if (values.contains("dbus-property")) {
                        spec.flags |= ConnMgrParamFlagDBusProperty;
                    }
                    if (values.contains("required")) {
                        spec.flags |= ConnMgrParamFlagRequired;
                    }
                    if (values.contains("register")) {
                        spec.flags |= ConnMgrParamFlagRegister;
                    }

                    paramSpecList.append(spec);
                }
            }

            protocolParams[protocol] = paramSpecList;

            /* now that we have all param-* created, let's find their default values */
            Q_FOREACH (param, params) {
                if (param.startsWith("default-")) {
                    QString paramName = param.right(param.length() - 8);

                    if (!hasParameter(protocol, paramName)) {
                        warning() << "param" << paramName
                                  << "has default value set, but not a definition";
                        continue;
                    }

                    ParamSpec *spec = getParameter(protocol, paramName);

                    spec->flags |= ConnMgrParamFlagHasDefault;

                    /* map based on the param dbus signature, otherwise use
                     * QString */
                    QVariant value = valueForKey(param, spec->signature);
                    spec->defaultValue = QDBusVariant(value);
                }
            }
        }
    }

    return true;
}

bool ManagerFile::Private::isValid() const
{
    return (keyFile.status() == KeyFile::NoError);
}

bool ManagerFile::Private::hasParameter(const QString &protocol,
                                        const QString &paramName) const
{
    ParamSpecList paramSpecList = protocolParams[protocol];
    Q_FOREACH (ParamSpec paramSpec, paramSpecList) {
        if (paramSpec.name == paramName) {
            return true;
        }
    }
    return false;
}

ParamSpec *ManagerFile::Private::getParameter(const QString &protocol,
                                              const QString &paramName)
{
    ParamSpecList &paramSpecList = protocolParams[protocol];
    for (int i = 0; i < paramSpecList.size(); ++i) {
        ParamSpec &paramSpec = paramSpecList[i];
        if (paramSpec.name == paramName) {
            return &paramSpec;
        }
    }
    return NULL;
}

QStringList ManagerFile::Private::protocols() const
{
    return protocolParams.keys();
}

ParamSpecList ManagerFile::Private::parameters(const QString &protocol) const
{
    return protocolParams.value(protocol);
}

QVariant ManagerFile::Private::valueForKey(const QString &param,
                                           const QString &signature)
{
    QVariant::Type type = ManagerFile::variantTypeFromDBusSignature(signature);

    if (type == QVariant::Invalid) {
        return QVariant(type);
    }

    switch (type) {
        case QVariant::Bool:
            {
                QString value = keyFile.value(param);
                if (value.toLower() == "true" || value == "1") {
                    return QVariant(true);
                }
                else {
                    return QVariant(false);
                }
                break;
            }
        case QVariant::Int:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toInt());
            }
        case QVariant::UInt:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toUInt());
            }
        case QVariant::LongLong:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toLongLong());
            }
        case QVariant::ULongLong:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toULongLong());
            }
        case QVariant::Double:
            {
                QString value = keyFile.value(param);
                return QVariant(value.toDouble());
            }
        case QVariant::StringList:
            {
                QStringList value = keyFile.valueAsStringList(param);
                return QVariant(value);
            }
        default:
            break;
    }
    QString value = keyFile.value(param);
    return QVariant(value);
}

/**
 * \class ManagerFile
 * \headerfile <TelepathyQt4/manager-file.h> <TelepathyQt4/ManagerFile>
 *
 * The ManagerFile class provides an easy way to read telepathy manager files
 * according to http://telepathy.freedesktop.org/spec.html.
 */

/**
 * Create a ManagerFile object used to read .manager compliant files.
 *
 * \param cmName Name of the connection manager to read the file for.
 */
ManagerFile::ManagerFile(const QString &cmName)
    : mPriv(new Private(cmName))
{
}

/**
 * Class destructor.
 */
ManagerFile::~ManagerFile()
{
    delete mPriv;
}

/**
 * Check whether or not a ManagerFile object is valid. If the file for the
 * specified connection manager cannot be found it will be considered invalid.
 *
 * \return true if valid, false otherwise.
 */
bool ManagerFile::isValid() const
{
    return mPriv->isValid();
}

/**
 * Return a list of all protocols defined in the manager file.
 *
 * \return List of all protocols defined in the file.
 */
QStringList ManagerFile::protocols() const
{
    return mPriv->protocols();
}

/**
 * Return a list of all protocols defined in the manager file.
 *
 * \param protocol Name of the protocol to look for.
 * \return List of ParamSpec of a specific protocol defined in the file, or an
 *         empty list if the protocol is not defined.
 */
ParamSpecList ManagerFile::parameters(const QString &protocol) const
{
    return mPriv->parameters(protocol);
}

QVariant::Type ManagerFile::variantTypeFromDBusSignature(const QString &signature)
{
    QVariant::Type type;
    if (signature == "b")
        type = QVariant::Bool;
    else if (signature == "n" || signature == "i")
        type = QVariant::Int;
    else if (signature == "q" || signature == "u")
        type = QVariant::UInt;
    else if (signature == "x")
        type = QVariant::LongLong;
    else if (signature == "t")
        type = QVariant::ULongLong;
    else if (signature == "d")
        type = QVariant::Double;
    else if (signature == "as")
        type = QVariant::StringList;
    else if (signature == "s" || signature == "o")
        type = QVariant::String;
    else
        type = QVariant::Invalid;

    return type;
}

} // Tp
<|endoftext|>


<commit_before>// Copyright © 2016 by Donald King <chronos@chronos-tachyon.net>
// Available under the MIT License. See LICENSE for details.

#include "event/poller.h"

#include <sys/epoll.h>
#include <unistd.h>

#include "base/logging.h"
#include "base/util.h"

static uint32_t epoll_mask(event::Set set) noexcept {
  uint32_t result = EPOLLET;
  if (set.readable()) result |= EPOLLIN | EPOLLRDHUP;
  if (set.writable()) result |= EPOLLOUT;
  if (set.priority()) result |= EPOLLPRI;
  return result;
}

static event::Set epoll_unmask(uint32_t bits) noexcept {
  event::Set set;
  set.set_readable(bits & (EPOLLIN | EPOLLRDHUP));
  set.set_writable(bits & EPOLLOUT);
  set.set_priority(bits & EPOLLPRI);
  set.set_hangup(bits & EPOLLHUP);
  set.set_error(bits & EPOLLERR);
  return set;
}

namespace event {

namespace {

class EPollPoller : public Poller {
 public:
  explicit EPollPoller(int epoll_fd) noexcept : epoll_fd_(epoll_fd) {}
  ~EPollPoller() noexcept override { ::close(epoll_fd_); }

  PollerType type() const noexcept override { return PollerType::epoll_poller; }

  base::Result add(base::FD fd, base::token_t t, Set set) override {
    epoll_event ev;
    ::bzero(&ev, sizeof(ev));
    ev.events = epoll_mask(set);
    ev.data.u64 = uint64_t(t);
    auto pair = DCHECK_NOTNULL(fd)->acquire_fd();
    int rc = ::epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, pair.first, &ev);
    if (rc != 0) {
      int err_no = errno;
      return base::Result::from_errno(err_no, "epoll_ctl(2)");
    }
    return base::Result();
  }

  base::Result modify(base::FD fd, base::token_t t, Set set) override {
    epoll_event ev;
    ::bzero(&ev, sizeof(ev));
    ev.events = epoll_mask(set);
    ev.data.u64 = uint64_t(t);
    auto pair = DCHECK_NOTNULL(fd)->acquire_fd();
    int rc = ::epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, pair.first, &ev);
    if (rc != 0) {
      int err_no = errno;
      return base::Result::from_errno(err_no, "epoll_ctl(2)");
    }
    return base::Result();
  }

  base::Result remove(base::FD fd) override {
    epoll_event dummy;
    auto pair = DCHECK_NOTNULL(fd)->acquire_fd();
    int rc = ::epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, pair.first, &dummy);
    if (rc != 0) {
      int err_no = errno;
      return base::Result::from_errno(err_no, "epoll_ctl(2)");
    }
    return base::Result();
  }

  base::Result wait(EventVec* out, int timeout_ms) const override {
    base::Result result;
    std::array<epoll_event, 8> ev = {};
    std::size_t num = ev.size();
    while (num >= ev.size()) {
      ev.fill(epoll_event());
      int n = ::epoll_wait(epoll_fd_, ev.data(), ev.size(), timeout_ms);
      if (n < 0) {
        int err_no = errno;
        if (err_no == EINTR) break;
        result = base::Result::from_errno(err_no, "epoll_wait(2)");
        break;
      }
      num = n;
      if (num > ev.size()) n = ev.size();
      for (std::size_t i = 0; i < num; ++i) {
        Set set = epoll_unmask(ev[i].events);
        auto t = base::token_t(ev[i].data.u64);
        out->emplace_back(t, set);
      }
      timeout_ms = 0;
    }
    return result;
  }

 private:
  const int epoll_fd_;
};

base::Result new_epoll_poller(PollerPtr* out, const PollerOptions& opts) {
  int fd = ::epoll_create1(EPOLL_CLOEXEC);
  if (fd == -1) {
    int err_no = errno;
    return base::Result::from_errno(err_no, "epoll_create1(2)");
  }
  *out = std::make_shared<EPollPoller>(fd);
  return base::Result();
}

}  // anonymous namespace

base::Result new_poller(PollerPtr* out, const PollerOptions& opts) {
  DCHECK_NOTNULL(out)->reset();
  auto type = opts.type();
  switch (type) {
    case PollerType::unspecified:
    case PollerType::epoll_poller:
      return new_epoll_poller(out, opts);

    default:
      return base::Result::not_implemented();
  }
}

}  // namespace event
<commit_msg>Implement poll(2) polling.<commit_after>// Copyright © 2016 by Donald King <chronos@chronos-tachyon.net>
// Available under the MIT License. See LICENSE for details.

#include "event/poller.h"

#include <poll.h>
#include <sys/epoll.h>
#include <unistd.h>

#include "base/logging.h"
#include "base/util.h"

static short poll_mask(event::Set set) noexcept {
  short result = 0;
  if (set.readable()) result |= POLLIN | POLLRDHUP;
  if (set.writable()) result |= POLLOUT;
  if (set.priority()) result |= POLLPRI;
  return result;
}

static event::Set poll_unmask(short bits) noexcept {
  event::Set set;
  set.set_readable(bits & (POLLIN | POLLRDHUP));
  set.set_writable(bits & POLLOUT);
  set.set_priority(bits & POLLPRI);
  set.set_hangup(bits & POLLHUP);
  set.set_error(bits & POLLERR);
  return set;
}

static uint32_t epoll_mask(event::Set set) noexcept {
  uint32_t result = EPOLLET;
  if (set.readable()) result |= EPOLLIN | EPOLLRDHUP;
  if (set.writable()) result |= EPOLLOUT;
  if (set.priority()) result |= EPOLLPRI;
  return result;
}

static event::Set epoll_unmask(uint32_t bits) noexcept {
  event::Set set;
  set.set_readable(bits & (EPOLLIN | EPOLLRDHUP));
  set.set_writable(bits & EPOLLOUT);
  set.set_priority(bits & EPOLLPRI);
  set.set_hangup(bits & EPOLLHUP);
  set.set_error(bits & EPOLLERR);
  return set;
}

namespace event {

namespace {

class PollPoller : public Poller {
 public:
  PollPoller() = default;

  PollerType type() const noexcept override { return PollerType::poll_poller; }

  base::Result add(base::FD fd, base::token_t t, Set set) override {
    auto lock = base::acquire_lock(mu_);
    auto fdpair = fd->acquire_fd();
    map_[fdpair.first] = Item(std::move(fd), t, set);
    return base::Result();
  }

  base::Result modify(base::FD fd, base::token_t t, Set set) override {
    auto lock = base::acquire_lock(mu_);
    auto fdpair = fd->acquire_fd();
    map_[fdpair.first] = Item(std::move(fd), t, set);
    return base::Result();
  }

  base::Result remove(base::FD fd) override {
    auto lock = base::acquire_lock(mu_);
    auto fdpair = fd->acquire_fd();
    map_.erase(fdpair.first);
    return base::Result();
  }

  base::Result wait(EventVec* out, int timeout_ms) const override {
    auto lock = base::acquire_lock(mu_);
    const std::size_t n = map_.size();

    std::vector<Activation> acts;
    acts.reserve(n);
    for (const auto& pair : map_) {
      const auto& item = pair.second;
      int fdnum;
      base::RLock rlock;
      std::tie(fdnum, rlock) = item.filedesc->acquire_fd();
      acts.emplace_back(std::move(rlock), fdnum, item.token, item.set);
    }

    std::vector<struct pollfd> pfds;
    pfds.resize(n);
    for (std::size_t i = 0; i < n; ++i) {
      auto& act = acts[i];
      auto& pfd = pfds[i];
      ::bzero(&pfd, sizeof(pfd));
      pfd.fd = act.fdnum;
      pfd.events = poll_mask(act.set);
      pfd.revents = 0;
    }

    int rc = ::poll(pfds.data(), pfds.size(), timeout_ms);
    if (rc < 0) {
      int err_no = errno;
      if (err_no == EINTR) return base::Result();
      return base::Result::from_errno(err_no, "poll(2)");
    }
    if (rc > 0) {
      for (std::size_t i = 0; i < n; ++i) {
        auto& act = acts[i];
        auto& pfd = pfds[i];
        if (pfd.revents != 0) {
          Set set = poll_unmask(pfd.revents);
          out->emplace_back(act.token, set);
        }
      }
    }
    return base::Result();
  }

 private:
  struct Item {
    base::FD filedesc;
    base::token_t token;
    Set set;

    Item() noexcept = default;
    Item(base::FD fd, base::token_t t, Set s) noexcept
        : filedesc(std::move(fd)),
          token(t),
          set(s) {}
  };

  struct Activation {
    base::RLock lock;
    int fdnum;
    base::token_t token;
    Set set;

    Activation(base::RLock lk, int n, base::token_t t, Set s) noexcept
        : lock(std::move(lk)),
          fdnum(n),
          token(t),
          set(s) {}
  };

  mutable std::mutex mu_;
  std::map<int, Item> map_;
};

class EPollPoller : public Poller {
 public:
  explicit EPollPoller(int epoll_fd) noexcept : epoll_fd_(epoll_fd) {}
  ~EPollPoller() noexcept override { ::close(epoll_fd_); }

  PollerType type() const noexcept override { return PollerType::epoll_poller; }

  base::Result add(base::FD fd, base::token_t t, Set set) override {
    epoll_event ev;
    ::bzero(&ev, sizeof(ev));
    ev.events = epoll_mask(set);
    ev.data.u64 = uint64_t(t);
    auto pair = DCHECK_NOTNULL(fd)->acquire_fd();
    int rc = ::epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, pair.first, &ev);
    if (rc != 0) {
      int err_no = errno;
      return base::Result::from_errno(err_no, "epoll_ctl(2)");
    }
    return base::Result();
  }

  base::Result modify(base::FD fd, base::token_t t, Set set) override {
    epoll_event ev;
    ::bzero(&ev, sizeof(ev));
    ev.events = epoll_mask(set);
    ev.data.u64 = uint64_t(t);
    auto pair = DCHECK_NOTNULL(fd)->acquire_fd();
    int rc = ::epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, pair.first, &ev);
    if (rc != 0) {
      int err_no = errno;
      return base::Result::from_errno(err_no, "epoll_ctl(2)");
    }
    return base::Result();
  }

  base::Result remove(base::FD fd) override {
    epoll_event dummy;
    auto pair = DCHECK_NOTNULL(fd)->acquire_fd();
    int rc = ::epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, pair.first, &dummy);
    if (rc != 0) {
      int err_no = errno;
      return base::Result::from_errno(err_no, "epoll_ctl(2)");
    }
    return base::Result();
  }

  base::Result wait(EventVec* out, int timeout_ms) const override {
    base::Result result;
    std::array<epoll_event, 8> ev = {};
    std::size_t num = ev.size();
    while (num >= ev.size()) {
      ev.fill(epoll_event());
      int n = ::epoll_wait(epoll_fd_, ev.data(), ev.size(), timeout_ms);
      if (n < 0) {
        int err_no = errno;
        if (err_no == EINTR) break;
        result = base::Result::from_errno(err_no, "epoll_wait(2)");
        break;
      }
      num = n;
      if (num > ev.size()) n = ev.size();
      for (std::size_t i = 0; i < num; ++i) {
        Set set = epoll_unmask(ev[i].events);
        auto t = base::token_t(ev[i].data.u64);
        out->emplace_back(t, set);
      }
      timeout_ms = 0;
    }
    return result;
  }

 private:
  const int epoll_fd_;
};

base::Result new_poll_poller(PollerPtr* out, const PollerOptions& opts) {
  *out = std::make_shared<PollPoller>();
  return base::Result();
}

base::Result new_epoll_poller(PollerPtr* out, const PollerOptions& opts) {
  int fd = ::epoll_create1(EPOLL_CLOEXEC);
  if (fd == -1) {
    int err_no = errno;
    return base::Result::from_errno(err_no, "epoll_create1(2)");
  }
  *out = std::make_shared<EPollPoller>(fd);
  return base::Result();
}

}  // anonymous namespace

base::Result new_poller(PollerPtr* out, const PollerOptions& opts) {
  DCHECK_NOTNULL(out)->reset();
  auto type = opts.type();
  switch (type) {
    case PollerType::poll_poller:
      return new_poll_poller(out, opts);

    case PollerType::unspecified:
    case PollerType::epoll_poller:
      return new_epoll_poller(out, opts);

    default:
      return base::Result::not_implemented();
  }
}

}  // namespace event
<|endoftext|>


<commit_before>/*
    Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>

    This file is part of Magnum.

    Magnum 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.

    Magnum 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.
*/

#include "CubeMapExample.h"

#include <PluginManager/PluginManager.h>
#include <Math/Constants.h>
#include <AbstractShaderProgram.h>
#include <DefaultFramebuffer.h>
#include <IndexedMesh.h>
#include <Renderer.h>
#include <Texture.h>
#include <SceneGraph/Camera3D.h>
#include <Trade/AbstractImporter.h>

#include "CubeMap.h"
#include "Reflector.h"
#include "configure.h"

using namespace Corrade::PluginManager;

namespace Magnum { namespace Examples {

CubeMapExample::CubeMapExample(int& argc, char** argv): GlutApplication(argc, argv, "Cube map example") {
    Renderer::setFeature(Renderer::Feature::DepthTest, true);
    Renderer::setFeature(Renderer::Feature::FaceCulling, true);

    /* Set up perspective camera */
    (cameraObject = new Object3D(&scene))
        ->translate(Vector3::zAxis(3.0f));
    (camera = new SceneGraph::Camera3D<>(cameraObject))
        ->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend)
        ->setPerspective(deg(55.0f), 0.001f, 100.0f);

    /* Load TGA importer plugin */
    PluginManager<Trade::AbstractImporter> manager(MAGNUM_PLUGINS_IMPORTER_DIR);
    Trade::AbstractImporter* importer;
    if(manager.load("TgaImporter") != AbstractPluginManager::LoadOk || !(importer = manager.instance("TgaImporter"))) {
        Error() << "Cannot load TGAImporter plugin from" << manager.pluginDirectory();
        std::exit(1);
    }
    resourceManager.set<Trade::AbstractImporter>("tga-importer", importer, ResourceDataState::Final, ResourcePolicy::Manual);

    /* Add objects to scene */
    (new CubeMap(argc == 2 ? argv[1] : "", &scene, &drawables))
        ->scale(Vector3(20.0f));

    (new Reflector(&scene, &drawables))
        ->scale(Vector3(0.5f))
        ->translate(Vector3::xAxis(-0.5f));

    (new Reflector(&scene, &drawables))
        ->scale(Vector3(0.3f))
        ->rotate(deg(37.0f), Vector3::xAxis())
        ->translate(Vector3::xAxis(0.3f));

    /* We don't need the importer anymore */
    resourceManager.free<Trade::AbstractImporter>();
}

void CubeMapExample::viewportEvent(const Vector2i& size) {
    defaultFramebuffer.setViewport({{}, size});
    camera->setViewport(size);
}

void CubeMapExample::drawEvent() {
    defaultFramebuffer.clear(DefaultFramebuffer::Clear::Depth);
    defaultFramebuffer.invalidate({DefaultFramebuffer::InvalidationAttachment::Color});

    camera->draw(drawables);
    swapBuffers();
}

void CubeMapExample::keyPressEvent(KeyEvent& event) {
    if(event.key() == KeyEvent::Key::Up)
        cameraObject->rotate(deg(-10.0f), cameraObject->transformation().right().normalized());

    else if(event.key() == KeyEvent::Key::Down)
        cameraObject->rotate(deg(10.0f), cameraObject->transformation().right().normalized());

    else if(event.key() == KeyEvent::Key::Left || event.key() == KeyEvent::Key::Right) {
        GLfloat translationY = cameraObject->transformation().translation().y();
        cameraObject->translate(Vector3::yAxis(-translationY))
            ->rotateY(event.key() == KeyEvent::Key::Left ? deg(10.0f) : deg(-10.0f))
            ->translate(Vector3::yAxis(translationY));

    } else return;

    redraw();
}

}}

MAGNUM_APPLICATION_MAIN(Magnum::Examples::CubeMapExample)
<commit_msg>cubemap: assert that ARB_invalidate_subdata is supported.<commit_after>/*
    Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>

    This file is part of Magnum.

    Magnum 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.

    Magnum 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.
*/

#include "CubeMapExample.h"

#include <PluginManager/PluginManager.h>
#include <Math/Constants.h>
#include <AbstractShaderProgram.h>
#include <DefaultFramebuffer.h>
#include <Extensions.h>
#include <IndexedMesh.h>
#include <Renderer.h>
#include <Texture.h>
#include <SceneGraph/Camera3D.h>
#include <Trade/AbstractImporter.h>

#include "CubeMap.h"
#include "Reflector.h"
#include "configure.h"

using namespace Corrade::PluginManager;

namespace Magnum { namespace Examples {

CubeMapExample::CubeMapExample(int& argc, char** argv): GlutApplication(argc, argv, "Cube map example") {
    MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::invalidate_subdata);

    Renderer::setFeature(Renderer::Feature::DepthTest, true);
    Renderer::setFeature(Renderer::Feature::FaceCulling, true);

    /* Set up perspective camera */
    (cameraObject = new Object3D(&scene))
        ->translate(Vector3::zAxis(3.0f));
    (camera = new SceneGraph::Camera3D<>(cameraObject))
        ->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend)
        ->setPerspective(deg(55.0f), 0.001f, 100.0f);

    /* Load TGA importer plugin */
    PluginManager<Trade::AbstractImporter> manager(MAGNUM_PLUGINS_IMPORTER_DIR);
    Trade::AbstractImporter* importer;
    if(manager.load("TgaImporter") != AbstractPluginManager::LoadOk || !(importer = manager.instance("TgaImporter"))) {
        Error() << "Cannot load TGAImporter plugin from" << manager.pluginDirectory();
        std::exit(1);
    }
    resourceManager.set<Trade::AbstractImporter>("tga-importer", importer, ResourceDataState::Final, ResourcePolicy::Manual);

    /* Add objects to scene */
    (new CubeMap(argc == 2 ? argv[1] : "", &scene, &drawables))
        ->scale(Vector3(20.0f));

    (new Reflector(&scene, &drawables))
        ->scale(Vector3(0.5f))
        ->translate(Vector3::xAxis(-0.5f));

    (new Reflector(&scene, &drawables))
        ->scale(Vector3(0.3f))
        ->rotate(deg(37.0f), Vector3::xAxis())
        ->translate(Vector3::xAxis(0.3f));

    /* We don't need the importer anymore */
    resourceManager.free<Trade::AbstractImporter>();
}

void CubeMapExample::viewportEvent(const Vector2i& size) {
    defaultFramebuffer.setViewport({{}, size});
    camera->setViewport(size);
}

void CubeMapExample::drawEvent() {
    defaultFramebuffer.clear(DefaultFramebuffer::Clear::Depth);
    defaultFramebuffer.invalidate({DefaultFramebuffer::InvalidationAttachment::Color});

    camera->draw(drawables);
    swapBuffers();
}

void CubeMapExample::keyPressEvent(KeyEvent& event) {
    if(event.key() == KeyEvent::Key::Up)
        cameraObject->rotate(deg(-10.0f), cameraObject->transformation().right().normalized());

    else if(event.key() == KeyEvent::Key::Down)
        cameraObject->rotate(deg(10.0f), cameraObject->transformation().right().normalized());

    else if(event.key() == KeyEvent::Key::Left || event.key() == KeyEvent::Key::Right) {
        GLfloat translationY = cameraObject->transformation().translation().y();
        cameraObject->translate(Vector3::yAxis(-translationY))
            ->rotateY(event.key() == KeyEvent::Key::Left ? deg(10.0f) : deg(-10.0f))
            ->translate(Vector3::yAxis(translationY));

    } else return;

    redraw();
}

}}

MAGNUM_APPLICATION_MAIN(Magnum::Examples::CubeMapExample)
<|endoftext|>