<commit_before>#include "pch.h"
#include "AssemblyUILayer.h"
#include "GameManager.h"
#include "StageManager.h"
#include "DataManager.h"
#include "ResourceManager.h"
#include "InputManager.h"
#include "AssemblyLineLayer.h"
#include "EquipmentStatusLayer.h"
#include "AssemblyDisplayLayer.h"
#include "SkillLineLayer.h"
#include "ButtonLayer.h"
#include "IconLayer.h"

AssemblyUILayer::AssemblyUILayer()
{
	m_viewChangeRect.setRect(1235 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
}

AssemblyUILayer::~AssemblyUILayer()
{
}

bool AssemblyUILayer::init()
{
	if (!cocos2d::Layer::init())
	{
		return false;
	}
	m_IsStarted = false;

	m_AssemblyLineLayer = AssemblyLineLayer::create();
	m_StatusLayer = EquipmentStatusLayer::create();
	m_DisplayLayer = AssemblyDisplayLayer::create();
	m_SkillLineLayer = SkillLineLayer::create();

	m_AssemblyBackground = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_BACKGROUND);
	m_AssemblyFrame = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_FRAME);
	m_ViewChangeArrow = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_ARROW);
	m_EquipmentRect.setRect(140 * RESOLUTION, 40 * RESOLUTION, 390 * RESOLUTION, 580 * RESOLUTION);
	m_SkillRect.setRect(535 * RESOLUTION, 295 * RESOLUTION, 320 * RESOLUTION, 325 * RESOLUTION);

	setUIProperties(m_AssemblyBackground, cocos2d::Point::ZERO, cocos2d::Point::ZERO, RESOLUTION, true, 0);
	setUIProperties(m_AssemblyFrame, cocos2d::Point::ZERO, cocos2d::Point::ZERO, RESOLUTION, true, 0);
	setUIProperties(m_ViewChangeArrow, cocos2d::Point(0.5, 0.5), cocos2d::Point(1055, 360), 1.0f, true, 1);

	m_AssemblyLineLayer->setPosition(cocos2d::Point(0, 0));
	m_StatusLayer->setPosition(cocos2d::Point(545, 0));
	m_DisplayLayer->setPosition(cocos2d::Point(830, 0));
	m_SkillLineLayer->setPosition(cocos2d::Point(1280, 0));

	assemblyLayerButtonInit();

	m_CurrentAssembly = ASSEMBLY_VIEW;
	this->addChild(m_AssemblyBackground);
	m_AssemblyBackground->addChild(m_AssemblyLineLayer);
	m_AssemblyBackground->addChild(m_SkillLineLayer);
	this->addChild(m_AssemblyFrame);
	m_AssemblyFrame->addChild(m_DisplayLayer);
	m_AssemblyFrame->addChild(m_ViewChangeArrow);
	m_AssemblyFrame->addChild(m_StatusLayer);
	return true;
}

void AssemblyUILayer::update(float dTime)
{
	MouseInfo mouseInput = GET_INPUT_MANAGER()->getMouseInfo();
	if (m_CurrentAssembly == ASSEMBLY_VIEW)
	{
		m_StatusLayer->update(dTime);
		m_DisplayLayer->update(dTime);

		if (m_EquipmentRect.containsPoint(mouseInput.m_MouseMove))
		{
			m_AssemblyLineLayer->updateEquipments(dTime);
			m_AssemblyLineLayer->containerScroll(mouseInput.m_ScollValue, mouseInput.m_MouseMove);
			GET_INPUT_MANAGER()->resetMouseWheel();

			if (mouseInput.m_DoubleClick == false && mouseInput.m_MouseState == MS_LEFT_UP)
			{
				m_AssemblyLineLayer->updateClickItem(mouseInput.m_MouseMove);
				m_AssemblyLineLayer->setClickedItem(mouseInput.m_MouseMove);
				m_StatusLayer->setCurClickedItem(m_AssemblyLineLayer->getClickedItem());
				GET_INPUT_MANAGER()->resetMouseState();
			}
			if (mouseInput.m_DoubleClick)
			{
				m_AssemblyLineLayer->updateDoubleClickItem(mouseInput.m_MouseMove);
				m_AssemblyLineLayer->setConfirmSet(mouseInput.m_MouseMove);
				m_StatusLayer->setConfirmSet(m_AssemblyLineLayer->getConfirmSet());
				m_DisplayLayer->setConfirmSet(m_AssemblyLineLayer->getConfirmSet());
				m_DisplayLayer->assembleRobot();
				m_DisplayLayer->moveScanBar();
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}
		else
		{
			m_AssemblyLineLayer->hideLabelLayer();
			if (mouseInput.m_ScollValue < 0)
			{
				viewChange(SKILL_VIEW);
			}
			else if (mouseInput.m_ScollValue > 0)
			{
				GET_INPUT_MANAGER()->resetMouseWheel();
			}

			//meaningless double click error exception
			if (mouseInput.m_DoubleClick)
			{
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}

		//view change arrow
		if (m_viewChangeRect.containsPoint(mouseInput.m_MouseEnd[LEFT_CLICK_POINT]))
		{
			viewChange(SKILL_VIEW);
		}
	}
	else if (m_CurrentAssembly == SKILL_VIEW)
	{
		m_DisplayLayer->update(dTime);
		if (m_SkillRect.containsPoint(mouseInput.m_MouseMove))
		{
			m_SkillLineLayer->updateSkills(dTime);
			m_SkillLineLayer->containerScroll(mouseInput.m_ScollValue, mouseInput.m_MouseMove);
			GET_INPUT_MANAGER()->resetMouseWheel();
			if (mouseInput.m_DoubleClick)
			{
				m_SkillLineLayer->updateDoubleClickSkill(mouseInput.m_MouseMove);
				m_SkillLineLayer->setSkillSet(mouseInput.m_MouseMove);
				m_DisplayLayer->moveScanBar();
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}
		else
		{
			m_SkillLineLayer->hideLabelLayer();
			if (mouseInput.m_ScollValue > 0)
			{
				viewChange(ASSEMBLY_VIEW);
			}
			else if (mouseInput.m_ScollValue < 0)
			{
				GET_INPUT_MANAGER()->resetMouseWheel();
			}
			//meaningless double click error exception
			if (mouseInput.m_DoubleClick)
			{
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}

		//view change arrow
		if (m_viewChangeRect.containsPoint(mouseInput.m_MouseEnd[LEFT_CLICK_POINT]))
		{
			viewChange(ASSEMBLY_VIEW);
		}
		m_ButtonConfirm->update(dTime);
		m_ButtonCancel->update(dTime);
	}
}

void AssemblyUILayer::viewChange(AssemblyLayerType moveViewTo)
{
	if (m_AssemblyBackground->getNumberOfRunningActions() == 0)
	{
		cocos2d::ActionInterval* moveAction0;
		cocos2d::ActionInterval* moveAction1;
		if (moveViewTo == SKILL_VIEW)
		{
			moveAction0 = cocos2d::MoveTo::create(1.0f, cocos2d::Point(-830 * RESOLUTION, 0));
			moveAction1 = cocos2d::MoveTo::create(1.2f, cocos2d::Point(-830 * RESOLUTION, 0));
			m_viewChangeRect.setRect(20 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
			m_ViewChangeArrow->setRotation(180);
			m_ButtonConfirm->setButtonRect(cocos2d::Point(-830 * RESOLUTION, 0));
			m_ButtonCancel->setButtonRect(cocos2d::Point(-830 * RESOLUTION, 0));
			m_AssemblyLineLayer->setVisible(false);
			m_StatusLayer->setVisible(false);
			m_SkillLineLayer->setVisible(true);
			m_EquipmentRect.setRect(0, 0, 0, 0);
			m_SkillRect.setRect(535 * RESOLUTION, 295 * RESOLUTION, 320 * RESOLUTION, 325 * RESOLUTION);
			m_CurrentAssembly = SKILL_VIEW;
		}
		else
		{
			moveAction0 = cocos2d::MoveTo::create(1.0f, cocos2d::Point(0, 0));
			moveAction1 = cocos2d::MoveTo::create(1.2f, cocos2d::Point(0, 0));
			m_viewChangeRect.setRect(1235 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
			m_ViewChangeArrow->setRotation(0);
			m_ButtonConfirm->setButtonRect(cocos2d::Point(0 * RESOLUTION, 0));
			m_ButtonCancel->setButtonRect(cocos2d::Point(0 * RESOLUTION, 0));
			m_AssemblyLineLayer->setVisible(true);
			m_StatusLayer->setVisible(true);
			m_SkillLineLayer->setVisible(false);
			m_EquipmentRect.setRect(140 * RESOLUTION, 40 * RESOLUTION, 390 * RESOLUTION, 580 * RESOLUTION);
			m_SkillRect.setRect(0, 0, 0, 0);
			m_CurrentAssembly = ASSEMBLY_VIEW;
		}
		cocos2d::Action* action0 = cocos2d::EaseExponentialOut::create(moveAction0);
		cocos2d::Action* action1 = cocos2d::EaseExponentialOut::create(moveAction1);
		m_AssemblyFrame->runAction(action0);
		m_AssemblyBackground->runAction(action1);
	}
	GET_INPUT_MANAGER()->resetMousePoints();
	GET_INPUT_MANAGER()->resetMouseWheel();
}

void AssemblyUILayer::assemblyLayerButtonInit()
{
	m_ButtonConfirm = ButtonLayer::create();
	m_ButtonCancel = ButtonLayer::create();

	m_ButtonConfirm->setButtonProperties(BUTTON_ASSEMBLY_CONFIRM, cocos2d::Point(0 * RESOLUTION, 0), cocos2d::Point(1670, 90), "Confirm", 35);
	m_ButtonCancel->setButtonProperties(BUTTON_ASSEMBLY_CONFIRM, cocos2d::Point(0 * RESOLUTION, 0), cocos2d::Point(1900, 90), "Cancel", 35);

	m_ButtonConfirm->setButtonFunc(std::bind(&AssemblyUILayer::confirmAssembly, this));
	m_ButtonCancel->setButtonFunc(std::bind(&AssemblyUILayer::toTitleScene, this));

	m_AssemblyFrame->addChild(m_ButtonConfirm);
	m_AssemblyFrame->addChild(m_ButtonCancel);
}

void AssemblyUILayer::moveContainer(bool moveLeft, cocos2d::Node* container, cocos2d::Rect containerRect)
{
	if (moveLeft)
	{
		if (container->getBoundingBox().getMaxX() - 140 > containerRect.getMaxX())
		{
			container->setPosition(cocos2d::Point(container->getPosition().x - 15, container->getPosition().y));
		}
		GET_INPUT_MANAGER()->resetMouseWheel();
	}
	else
	{
		if (container->getBoundingBox().getMinX() * RESOLUTION < containerRect.getMinX())
		{
			container->setPosition(cocos2d::Point(container->getPosition().x + 15, container->getPosition().y));
		}
		GET_INPUT_MANAGER()->resetMouseWheel();
	}
}

void AssemblyUILayer::confirmAssembly()
{
	if (checkAssemblyComplete(m_AssemblyLineLayer->getConfirmSet()))
	{
		if (!m_IsStarted)
		{
			m_IsStarted = true;
			GET_DATA_MANAGER()->setEquipmentItem(m_AssemblyLineLayer->getConfirmSet());
			GET_DATA_MANAGER()->initWorldData();
			GET_INPUT_MANAGER()->resetMouseInfo();
			GET_GAME_MANAGER()->changeScene(GET_STAGE_MANAGER()->getGameScene(), GAME_SCENE);
			GET_STAGE_MANAGER()->start();
		}
	}
	else
	{
		//̿ϼ ޽ !
	}
}

void AssemblyUILayer::toTitleScene()
{
	//߿ Լ ٲٱ
	exit(0);
}

bool AssemblyUILayer::checkAssemblyComplete(ConfirmSet confirmSet)
{
	bool okToStart = false;
	if (confirmSet.m_Head == HL_START || confirmSet.m_Engine == EL_START ||
		confirmSet.m_Armor == AL_START || confirmSet.m_Melee == ML_START ||
		confirmSet.m_Range == RL_START || confirmSet.m_Steam == SCL_START || confirmSet.m_Leg == LL_START)
	{
		okToStart = false;
	}
// 	if (m_DisplayLayer->getPowerOver())
// 	{
//		okToStart = false;
// 	}

	return okToStart;
}

void AssemblyUILayer::onExit()
{
	m_IsStarted = false;
}

<commit_msg>일단 작동되게 만듬<commit_after>#include "pch.h"
#include "AssemblyUILayer.h"
#include "GameManager.h"
#include "StageManager.h"
#include "DataManager.h"
#include "ResourceManager.h"
#include "InputManager.h"
#include "AssemblyLineLayer.h"
#include "EquipmentStatusLayer.h"
#include "AssemblyDisplayLayer.h"
#include "SkillLineLayer.h"
#include "ButtonLayer.h"
#include "IconLayer.h"

AssemblyUILayer::AssemblyUILayer()
{
	m_viewChangeRect.setRect(1235 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
}

AssemblyUILayer::~AssemblyUILayer()
{
}

bool AssemblyUILayer::init()
{
	if (!cocos2d::Layer::init())
	{
		return false;
	}
	m_IsStarted = false;

	m_AssemblyLineLayer = AssemblyLineLayer::create();
	m_StatusLayer = EquipmentStatusLayer::create();
	m_DisplayLayer = AssemblyDisplayLayer::create();
	m_SkillLineLayer = SkillLineLayer::create();

	m_AssemblyBackground = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_BACKGROUND);
	m_AssemblyFrame = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_FRAME);
	m_ViewChangeArrow = GET_RESOURCE_MANAGER()->createSprite(ST_ASSEMBLY_ARROW);
	m_EquipmentRect.setRect(140 * RESOLUTION, 40 * RESOLUTION, 390 * RESOLUTION, 580 * RESOLUTION);
	m_SkillRect.setRect(535 * RESOLUTION, 295 * RESOLUTION, 320 * RESOLUTION, 325 * RESOLUTION);

	setUIProperties(m_AssemblyBackground, cocos2d::Point::ZERO, cocos2d::Point::ZERO, RESOLUTION, true, 0);
	setUIProperties(m_AssemblyFrame, cocos2d::Point::ZERO, cocos2d::Point::ZERO, RESOLUTION, true, 0);
	setUIProperties(m_ViewChangeArrow, cocos2d::Point(0.5, 0.5), cocos2d::Point(1055, 360), 1.0f, true, 1);

	m_AssemblyLineLayer->setPosition(cocos2d::Point(0, 0));
	m_StatusLayer->setPosition(cocos2d::Point(545, 0));
	m_DisplayLayer->setPosition(cocos2d::Point(830, 0));
	m_SkillLineLayer->setPosition(cocos2d::Point(1280, 0));

	assemblyLayerButtonInit();

	m_CurrentAssembly = ASSEMBLY_VIEW;
	this->addChild(m_AssemblyBackground);
	m_AssemblyBackground->addChild(m_AssemblyLineLayer);
	m_AssemblyBackground->addChild(m_SkillLineLayer);
	this->addChild(m_AssemblyFrame);
	m_AssemblyFrame->addChild(m_DisplayLayer);
	m_AssemblyFrame->addChild(m_ViewChangeArrow);
	m_AssemblyFrame->addChild(m_StatusLayer);
	return true;
}

void AssemblyUILayer::update(float dTime)
{
	MouseInfo mouseInput = GET_INPUT_MANAGER()->getMouseInfo();
	if (m_CurrentAssembly == ASSEMBLY_VIEW)
	{
		m_StatusLayer->update(dTime);
		m_DisplayLayer->update(dTime);

		if (m_EquipmentRect.containsPoint(mouseInput.m_MouseMove))
		{
			m_AssemblyLineLayer->updateEquipments(dTime);
			m_AssemblyLineLayer->containerScroll(mouseInput.m_ScollValue, mouseInput.m_MouseMove);
			GET_INPUT_MANAGER()->resetMouseWheel();

			if (mouseInput.m_DoubleClick == false && mouseInput.m_MouseState == MS_LEFT_UP)
			{
				m_AssemblyLineLayer->updateClickItem(mouseInput.m_MouseMove);
				m_AssemblyLineLayer->setClickedItem(mouseInput.m_MouseMove);
				m_StatusLayer->setCurClickedItem(m_AssemblyLineLayer->getClickedItem());
				GET_INPUT_MANAGER()->resetMouseState();
			}
			if (mouseInput.m_DoubleClick)
			{
				m_AssemblyLineLayer->updateDoubleClickItem(mouseInput.m_MouseMove);
				m_AssemblyLineLayer->setConfirmSet(mouseInput.m_MouseMove);
				m_StatusLayer->setConfirmSet(m_AssemblyLineLayer->getConfirmSet());
				m_DisplayLayer->setConfirmSet(m_AssemblyLineLayer->getConfirmSet());
				m_DisplayLayer->assembleRobot();
				m_DisplayLayer->moveScanBar();
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}
		else
		{
			m_AssemblyLineLayer->hideLabelLayer();
			if (mouseInput.m_ScollValue < 0)
			{
				viewChange(SKILL_VIEW);
			}
			else if (mouseInput.m_ScollValue > 0)
			{
				GET_INPUT_MANAGER()->resetMouseWheel();
			}

			//meaningless double click error exception
			if (mouseInput.m_DoubleClick)
			{
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}

		//view change arrow
		if (m_viewChangeRect.containsPoint(mouseInput.m_MouseEnd[LEFT_CLICK_POINT]))
		{
			viewChange(SKILL_VIEW);
		}
	}
	else if (m_CurrentAssembly == SKILL_VIEW)
	{
		m_DisplayLayer->update(dTime);
		if (m_SkillRect.containsPoint(mouseInput.m_MouseMove))
		{
			m_SkillLineLayer->updateSkills(dTime);
			m_SkillLineLayer->containerScroll(mouseInput.m_ScollValue, mouseInput.m_MouseMove);
			GET_INPUT_MANAGER()->resetMouseWheel();
			if (mouseInput.m_DoubleClick)
			{
				m_SkillLineLayer->updateDoubleClickSkill(mouseInput.m_MouseMove);
				m_SkillLineLayer->setSkillSet(mouseInput.m_MouseMove);
				m_DisplayLayer->moveScanBar();
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}
		else
		{
			m_SkillLineLayer->hideLabelLayer();
			if (mouseInput.m_ScollValue > 0)
			{
				viewChange(ASSEMBLY_VIEW);
			}
			else if (mouseInput.m_ScollValue < 0)
			{
				GET_INPUT_MANAGER()->resetMouseWheel();
			}
			//meaningless double click error exception
			if (mouseInput.m_DoubleClick)
			{
				GET_INPUT_MANAGER()->resetMouseDoubleClick();
			}
		}

		//view change arrow
		if (m_viewChangeRect.containsPoint(mouseInput.m_MouseEnd[LEFT_CLICK_POINT]))
		{
			viewChange(ASSEMBLY_VIEW);
		}
		m_ButtonConfirm->update(dTime);
		m_ButtonCancel->update(dTime);
	}
}

void AssemblyUILayer::viewChange(AssemblyLayerType moveViewTo)
{
	if (m_AssemblyBackground->getNumberOfRunningActions() == 0)
	{
		cocos2d::ActionInterval* moveAction0;
		cocos2d::ActionInterval* moveAction1;
		if (moveViewTo == SKILL_VIEW)
		{
			moveAction0 = cocos2d::MoveTo::create(1.0f, cocos2d::Point(-830 * RESOLUTION, 0));
			moveAction1 = cocos2d::MoveTo::create(1.2f, cocos2d::Point(-830 * RESOLUTION, 0));
			m_viewChangeRect.setRect(20 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
			m_ViewChangeArrow->setRotation(180);
			m_ButtonConfirm->setButtonRect(cocos2d::Point(-830 * RESOLUTION, 0));
			m_ButtonCancel->setButtonRect(cocos2d::Point(-830 * RESOLUTION, 0));
			m_AssemblyLineLayer->setVisible(false);
			m_StatusLayer->setVisible(false);
			m_SkillLineLayer->setVisible(true);
			m_EquipmentRect.setRect(0, 0, 0, 0);
			m_SkillRect.setRect(535 * RESOLUTION, 295 * RESOLUTION, 320 * RESOLUTION, 325 * RESOLUTION);
			m_CurrentAssembly = SKILL_VIEW;
		}
		else
		{
			moveAction0 = cocos2d::MoveTo::create(1.0f, cocos2d::Point(0, 0));
			moveAction1 = cocos2d::MoveTo::create(1.2f, cocos2d::Point(0, 0));
			m_viewChangeRect.setRect(1235 * RESOLUTION, 310 * RESOLUTION, 25 * RESOLUTION, 100 * RESOLUTION);
			m_ViewChangeArrow->setRotation(0);
			m_ButtonConfirm->setButtonRect(cocos2d::Point(0 * RESOLUTION, 0));
			m_ButtonCancel->setButtonRect(cocos2d::Point(0 * RESOLUTION, 0));
			m_AssemblyLineLayer->setVisible(true);
			m_StatusLayer->setVisible(true);
			m_SkillLineLayer->setVisible(false);
			m_EquipmentRect.setRect(140 * RESOLUTION, 40 * RESOLUTION, 390 * RESOLUTION, 580 * RESOLUTION);
			m_SkillRect.setRect(0, 0, 0, 0);
			m_CurrentAssembly = ASSEMBLY_VIEW;
		}
		cocos2d::Action* action0 = cocos2d::EaseExponentialOut::create(moveAction0);
		cocos2d::Action* action1 = cocos2d::EaseExponentialOut::create(moveAction1);
		m_AssemblyFrame->runAction(action0);
		m_AssemblyBackground->runAction(action1);
	}
	GET_INPUT_MANAGER()->resetMousePoints();
	GET_INPUT_MANAGER()->resetMouseWheel();
}

void AssemblyUILayer::assemblyLayerButtonInit()
{
	m_ButtonConfirm = ButtonLayer::create();
	m_ButtonCancel = ButtonLayer::create();

	m_ButtonConfirm->setButtonProperties(BUTTON_ASSEMBLY_CONFIRM, cocos2d::Point(0 * RESOLUTION, 0), cocos2d::Point(1670, 90), "Confirm", 35);
	m_ButtonCancel->setButtonProperties(BUTTON_ASSEMBLY_CONFIRM, cocos2d::Point(0 * RESOLUTION, 0), cocos2d::Point(1900, 90), "Cancel", 35);

	m_ButtonConfirm->setButtonFunc(std::bind(&AssemblyUILayer::confirmAssembly, this));
	m_ButtonCancel->setButtonFunc(std::bind(&AssemblyUILayer::toTitleScene, this));

	m_AssemblyFrame->addChild(m_ButtonConfirm);
	m_AssemblyFrame->addChild(m_ButtonCancel);
}

void AssemblyUILayer::moveContainer(bool moveLeft, cocos2d::Node* container, cocos2d::Rect containerRect)
{
	if (moveLeft)
	{
		if (container->getBoundingBox().getMaxX() - 140 > containerRect.getMaxX())
		{
			container->setPosition(cocos2d::Point(container->getPosition().x - 15, container->getPosition().y));
		}
		GET_INPUT_MANAGER()->resetMouseWheel();
	}
	else
	{
		if (container->getBoundingBox().getMinX() * RESOLUTION < containerRect.getMinX())
		{
			container->setPosition(cocos2d::Point(container->getPosition().x + 15, container->getPosition().y));
		}
		GET_INPUT_MANAGER()->resetMouseWheel();
	}
}

void AssemblyUILayer::confirmAssembly()
{
	if (checkAssemblyComplete(m_AssemblyLineLayer->getConfirmSet()))
	{
		if (!m_IsStarted)
		{
			m_IsStarted = true;
			GET_DATA_MANAGER()->setEquipmentItem(m_AssemblyLineLayer->getConfirmSet());
			GET_DATA_MANAGER()->initWorldData();
			GET_INPUT_MANAGER()->resetMouseInfo();
			GET_GAME_MANAGER()->changeScene(GET_STAGE_MANAGER()->getGameScene(), GAME_SCENE);
			GET_STAGE_MANAGER()->start();
		}
	}
	else
	{
		//̿ϼ ޽ !
	}
}

void AssemblyUILayer::toTitleScene()
{
	//߿ Լ ٲٱ
	exit(0);
}

bool AssemblyUILayer::checkAssemblyComplete(ConfirmSet confirmSet)
{
	bool okToStart = false;
	if (confirmSet.m_Head == HL_START || confirmSet.m_Engine == EL_START ||
		confirmSet.m_Armor == AL_START || confirmSet.m_Melee == ML_START ||
		confirmSet.m_Range == RL_START || confirmSet.m_Steam == SCL_START || confirmSet.m_Leg == LL_START)
	{
		okToStart = false;
	}
// 	if (m_DisplayLayer->getPowerOver())
// 	{
//		okToStart = false;
// 	}

	return true;
}

void AssemblyUILayer::onExit()
{
	m_IsStarted = false;
}

<|endoftext|>


<commit_before>#pragma once

#include <array>
#include <vector>

#include "Runtime/RetroTypes.hpp"

#include <zeus/CColor.hpp>
#include <zeus/CMatrix4f.hpp>
#include <zeus/CVector3f.hpp>
#include <zeus/CVector4f.hpp>

namespace urde {
class CElementGen;
class CParticleGlobals {
  CParticleGlobals() = default;
  static std::unique_ptr<CParticleGlobals> g_ParticleGlobals;

public:
  int m_EmitterTime = 0;
  float m_EmitterTimeReal = 0.f;
  void SetEmitterTime(int frame) {
    m_EmitterTime = frame;
    m_EmitterTimeReal = frame;
  }

  int m_ParticleLifetime = 0;
  float m_ParticleLifetimeReal = 0.f;
  void SetParticleLifetime(int frame) {
    m_ParticleLifetime = frame;
    m_ParticleLifetimeReal = frame;
  }

   int m_ParticleLifetimePercentage = 0;
   float m_ParticleLifetimePercentageReal = 0.f;
   float m_ParticleLifetimePercentageRemainder = 0.f;
   void UpdateParticleLifetimeTweenValues(int frame) {
    float lt = m_ParticleLifetime != 0.0f ? m_ParticleLifetime : 1.0f;
    m_ParticleLifetimePercentageReal = 100.0f * frame / lt;
    m_ParticleLifetimePercentage = int(m_ParticleLifetimePercentageReal);
    m_ParticleLifetimePercentageRemainder = m_ParticleLifetimePercentageReal - m_ParticleLifetimePercentage;
    m_ParticleLifetimePercentage = zeus::clamp(0, m_ParticleLifetimePercentage, 100);
  }

  const std::array<float, 8>* m_particleAccessParameters = nullptr;

  struct SParticleSystem {
    FourCC x0_type;
    CElementGen* x4_system;
  };

  SParticleSystem* m_currentParticleSystem = nullptr;

  static CParticleGlobals* instance() {
    if (!g_ParticleGlobals)
      g_ParticleGlobals.reset(new CParticleGlobals());

    return g_ParticleGlobals.get();
  }
};

struct SParticleInstanceTex {
  zeus::CVector4f pos[4];
  zeus::CColor color;
  zeus::CVector2f uvs[4];
};
extern std::vector<SParticleInstanceTex> g_instTexData;

struct SParticleInstanceIndTex {
  zeus::CVector4f pos[4];
  zeus::CColor color;
  zeus::CVector4f texrTindUVs[4];
  zeus::CVector4f sceneUVs;
};
extern std::vector<SParticleInstanceIndTex> g_instIndTexData;

struct SParticleInstanceNoTex {
  zeus::CVector4f pos[4];
  zeus::CColor color;
};
extern std::vector<SParticleInstanceNoTex> g_instNoTexData;

struct SParticleUniforms {
  zeus::CMatrix4f mvp;
  zeus::CColor moduColor;
};

} // namespace urde
<commit_msg>CParticleGlobals: Make use of std::array where applicable<commit_after>#pragma once

#include <array>
#include <vector>

#include "Runtime/RetroTypes.hpp"

#include <zeus/CColor.hpp>
#include <zeus/CMatrix4f.hpp>
#include <zeus/CVector3f.hpp>
#include <zeus/CVector4f.hpp>

namespace urde {
class CElementGen;
class CParticleGlobals {
  CParticleGlobals() = default;
  static std::unique_ptr<CParticleGlobals> g_ParticleGlobals;

public:
  int m_EmitterTime = 0;
  float m_EmitterTimeReal = 0.f;
  void SetEmitterTime(int frame) {
    m_EmitterTime = frame;
    m_EmitterTimeReal = frame;
  }

  int m_ParticleLifetime = 0;
  float m_ParticleLifetimeReal = 0.f;
  void SetParticleLifetime(int frame) {
    m_ParticleLifetime = frame;
    m_ParticleLifetimeReal = frame;
  }

   int m_ParticleLifetimePercentage = 0;
   float m_ParticleLifetimePercentageReal = 0.f;
   float m_ParticleLifetimePercentageRemainder = 0.f;
   void UpdateParticleLifetimeTweenValues(int frame) {
    float lt = m_ParticleLifetime != 0.0f ? m_ParticleLifetime : 1.0f;
    m_ParticleLifetimePercentageReal = 100.0f * frame / lt;
    m_ParticleLifetimePercentage = int(m_ParticleLifetimePercentageReal);
    m_ParticleLifetimePercentageRemainder = m_ParticleLifetimePercentageReal - m_ParticleLifetimePercentage;
    m_ParticleLifetimePercentage = zeus::clamp(0, m_ParticleLifetimePercentage, 100);
  }

  const std::array<float, 8>* m_particleAccessParameters = nullptr;

  struct SParticleSystem {
    FourCC x0_type;
    CElementGen* x4_system;
  };

  SParticleSystem* m_currentParticleSystem = nullptr;

  static CParticleGlobals* instance() {
    if (!g_ParticleGlobals)
      g_ParticleGlobals.reset(new CParticleGlobals());

    return g_ParticleGlobals.get();
  }
};

struct SParticleInstanceTex {
  std::array<zeus::CVector4f, 4> pos;
  zeus::CColor color;
  std::array<zeus::CVector2f, 4> uvs;
};
extern std::vector<SParticleInstanceTex> g_instTexData;

struct SParticleInstanceIndTex {
  std::array<zeus::CVector4f, 4> pos;
  zeus::CColor color;
  std::array<zeus::CVector4f, 4> texrTindUVs;
  zeus::CVector4f sceneUVs;
};
extern std::vector<SParticleInstanceIndTex> g_instIndTexData;

struct SParticleInstanceNoTex {
  std::array<zeus::CVector4f, 4> pos;
  zeus::CColor color;
};
extern std::vector<SParticleInstanceNoTex> g_instNoTexData;

struct SParticleUniforms {
  zeus::CMatrix4f mvp;
  zeus::CColor moduColor;
};

} // namespace urde
<|endoftext|>


<commit_before>#include "UIHandler.h"

UIHandler::UIHandler()
{
}

UIHandler::~UIHandler()
{
}

void UIHandler::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext)
{
	this->m_maxUIComponents = 10;
	this->m_nrOfUIComponents = 0;
	for (int i = 0; i < this->m_maxUIComponents; i++)
	{
		UIComponent* newUIComp = new UIComponent;
		this->m_UIComponents.push_back(newUIComp);
	}

	this->m_maxTextComponents = 10;
	this->m_nrOfTextComponents = 0;
	for (int i = 0; i < this->m_maxTextComponents; i++)
	{
		TextComponent* newTextComp = new TextComponent;
		this->m_textComponents.push_back(newTextComp);
	}

	this->m_spriteBatch = new DirectX::SpriteBatch(deviceContext);
	this->m_spriteFont = new DirectX::SpriteFont(device, L"consolas.spritefont");
	DirectX::CreateWICTextureFromFile(device, L"cat.png", nullptr, &this->m_texture);

	this->m_UIComponents.at(0)->position = DirectX::XMFLOAT2(10.f, 10.f);
	this->m_UIComponents.at(0)->layerDepth = 1.f;
	this->m_UIComponents.at(0)->active = true;
	this->m_nrOfUIComponents++;

	this->m_UIComponents.at(1)->position = DirectX::XMFLOAT2(200.f, 100.f);
	this->m_UIComponents.at(1)->scale = 0.5f;
	this->m_UIComponents.at(1)->rotation = 2.0f;
	this->m_UIComponents.at(1)->layerDepth = 0.f;
	this->m_UIComponents.at(1)->active = true;
	this->m_nrOfUIComponents++;

	this->m_textComponents.at(0)->active = true;
	this->m_textComponents.at(0)->text = L"Hello";
	this->m_textComponents.at(0)->layerDepth = 0.5f;
	this->m_nrOfTextComponents++;

	this->m_textComponents.at(1)->active = true;
	this->m_textComponents.at(1)->text = L"Darkness my old friend";
	this->m_textComponents.at(1)->position = DirectX::XMFLOAT2(50.f, 85.f);
	this->m_textComponents.at(1)->scale = DirectX::XMFLOAT2(0.5f, 0.5f);
	this->m_textComponents.at(1)->layerDepth = 0.5f;
	this->m_nrOfTextComponents++;
}

void UIHandler::DrawUI()
{
	UIComponent* tempUIComp = nullptr;
	TextComponent* tempTextComp = nullptr;
	this->m_spriteBatch->Begin(DirectX::SpriteSortMode::SpriteSortMode_BackToFront);
	for (int i = 0; i < this->m_nrOfUIComponents; i++)
	{
		tempUIComp = this->m_UIComponents.at(i);
		this->m_spriteBatch->Draw(this->m_texture, tempUIComp->position, nullptr, DirectX::Colors::White, tempUIComp->rotation, DirectX::XMFLOAT2(0.f, 0.f), tempUIComp->scale, DirectX::SpriteEffects::SpriteEffects_None, tempUIComp->layerDepth);
	}
	for (int i = 0; i < this->m_nrOfTextComponents; i++)
	{
		tempTextComp = this->m_textComponents.at(i);
		this->m_spriteFont->DrawString(this->m_spriteBatch, tempTextComp->text.c_str(), tempTextComp->position, DirectX::Colors::White, tempTextComp->rotation, DirectX::XMFLOAT2(0.f, 0.f), tempTextComp->scale, DirectX::SpriteEffects::SpriteEffects_None, tempTextComp->layerDepth);
	}
	this->m_spriteBatch->End();
}

void UIHandler::Shutdown()
{
	for (int i = 0; i < this->m_maxUIComponents; i++)
	{
		delete this->m_UIComponents.at(i);
	}
	for (int i = 0; i < this->m_maxTextComponents; i++)
	{
		delete this->m_textComponents.at(i);
	}
	//this->m_spriteBatch.release();
	if (this->m_spriteBatch)
	{
		delete this->m_spriteBatch;
		this->m_spriteBatch = nullptr;
	}
	if (this->m_spriteFont)
	{
		delete this->m_spriteFont;
		this->m_spriteFont = nullptr;
	}
	if (this->m_texture)
	{
		this->m_texture->Release();
		this->m_texture = nullptr;
	}
}

UIComponent* UIHandler::GetNextUIComponent()
{
	if (this->m_nrOfUIComponents < this->m_maxUIComponents)
	{
		return this->m_UIComponents.at(this->m_nrOfUIComponents++);
	}
	return nullptr;
}

TextComponent* UIHandler::GetNextTextComponent()
{
	if (this->m_nrOfTextComponents < this->m_maxTextComponents)
	{
		return this->m_textComponents.at(this->m_nrOfTextComponents++);
	}
	return nullptr;
}

void UIHandler::UpdateUIComponentsclicked(DirectX::XMFLOAT2 mousePos)
{
	std::vector<UIComponent*>::iterator uiCompIter;
	for (uiCompIter = this->m_UIComponents.begin(); uiCompIter != this->m_UIComponents.end(); uiCompIter++)
	{
		(*uiCompIter)->UpdateClicked(mousePos);
	}
}

void UIHandler::UpdateUIComponentsclicked(DirectX::XMFLOAT2 mousePos, DirectX::XMFLOAT2 windowSize)
{
	std::vector<UIComponent*>::iterator uiCompIter;
	for (uiCompIter = this->m_UIComponents.begin(); uiCompIter != this->m_UIComponents.end(); uiCompIter++)
	{
		(*uiCompIter)->UpdateClicked(mousePos, windowSize);
	}
}
<commit_msg>UPDATE only draw ui and text components if active<commit_after>#include "UIHandler.h"

UIHandler::UIHandler()
{
}

UIHandler::~UIHandler()
{
}

void UIHandler::Initialize(ID3D11Device* device, ID3D11DeviceContext* deviceContext)
{
	this->m_maxUIComponents = 10;
	this->m_nrOfUIComponents = 0;
	for (int i = 0; i < this->m_maxUIComponents; i++)
	{
		UIComponent* newUIComp = new UIComponent;
		this->m_UIComponents.push_back(newUIComp);
	}

	this->m_maxTextComponents = 10;
	this->m_nrOfTextComponents = 0;
	for (int i = 0; i < this->m_maxTextComponents; i++)
	{
		TextComponent* newTextComp = new TextComponent;
		this->m_textComponents.push_back(newTextComp);
	}

	this->m_spriteBatch = new DirectX::SpriteBatch(deviceContext);
	this->m_spriteFont = new DirectX::SpriteFont(device, L"consolas.spritefont");
	DirectX::CreateWICTextureFromFile(device, L"cat.png", nullptr, &this->m_texture);

	this->m_UIComponents.at(0)->position = DirectX::XMFLOAT2(10.f, 10.f);
	this->m_UIComponents.at(0)->layerDepth = 1.f;
	this->m_UIComponents.at(0)->active = true;
	this->m_nrOfUIComponents++;

	this->m_UIComponents.at(1)->position = DirectX::XMFLOAT2(200.f, 100.f);
	this->m_UIComponents.at(1)->scale = 0.5f;
	this->m_UIComponents.at(1)->rotation = 2.0f;
	this->m_UIComponents.at(1)->layerDepth = 0.f;
	this->m_UIComponents.at(1)->active = true;
	this->m_nrOfUIComponents++;

	this->m_textComponents.at(0)->active = true;
	this->m_textComponents.at(0)->text = L"Hello";
	this->m_textComponents.at(0)->layerDepth = 0.5f;
	this->m_nrOfTextComponents++;

	this->m_textComponents.at(1)->active = true;
	this->m_textComponents.at(1)->text = L"Darkness my old friend";
	this->m_textComponents.at(1)->position = DirectX::XMFLOAT2(50.f, 85.f);
	this->m_textComponents.at(1)->scale = DirectX::XMFLOAT2(0.5f, 0.5f);
	this->m_textComponents.at(1)->layerDepth = 0.5f;
	this->m_nrOfTextComponents++;
}

void UIHandler::DrawUI()
{
	UIComponent* tempUIComp = nullptr;
	TextComponent* tempTextComp = nullptr;
	this->m_spriteBatch->Begin(DirectX::SpriteSortMode::SpriteSortMode_BackToFront);
	for (int i = 0; i < this->m_nrOfUIComponents; i++)
	{
		tempUIComp = this->m_UIComponents.at(i);
		if (tempUIComp->active)
		{
			this->m_spriteBatch->Draw(this->m_texture, tempUIComp->position, nullptr, DirectX::Colors::White, tempUIComp->rotation, DirectX::XMFLOAT2(0.f, 0.f), tempUIComp->scale, DirectX::SpriteEffects::SpriteEffects_None, tempUIComp->layerDepth);
		}
	}
	for (int i = 0; i < this->m_nrOfTextComponents; i++)
	{
		tempTextComp = this->m_textComponents.at(i);
		if (tempTextComp->active)
		{
			this->m_spriteFont->DrawString(this->m_spriteBatch, tempTextComp->text.c_str(), tempTextComp->position, DirectX::Colors::White, tempTextComp->rotation, DirectX::XMFLOAT2(0.f, 0.f), tempTextComp->scale, DirectX::SpriteEffects::SpriteEffects_None, tempTextComp->layerDepth);
		}
	}
	this->m_spriteBatch->End();
}

void UIHandler::Shutdown()
{
	for (int i = 0; i < this->m_maxUIComponents; i++)
	{
		delete this->m_UIComponents.at(i);
	}
	for (int i = 0; i < this->m_maxTextComponents; i++)
	{
		delete this->m_textComponents.at(i);
	}
	//this->m_spriteBatch.release();
	if (this->m_spriteBatch)
	{
		delete this->m_spriteBatch;
		this->m_spriteBatch = nullptr;
	}
	if (this->m_spriteFont)
	{
		delete this->m_spriteFont;
		this->m_spriteFont = nullptr;
	}
	if (this->m_texture)
	{
		this->m_texture->Release();
		this->m_texture = nullptr;
	}
}

UIComponent* UIHandler::GetNextUIComponent()
{
	if (this->m_nrOfUIComponents < this->m_maxUIComponents)
	{
		return this->m_UIComponents.at(this->m_nrOfUIComponents++);
	}
	return nullptr;
}

TextComponent* UIHandler::GetNextTextComponent()
{
	if (this->m_nrOfTextComponents < this->m_maxTextComponents)
	{
		return this->m_textComponents.at(this->m_nrOfTextComponents++);
	}
	return nullptr;
}

void UIHandler::UpdateUIComponentsclicked(DirectX::XMFLOAT2 mousePos)
{
	std::vector<UIComponent*>::iterator uiCompIter;
	for (uiCompIter = this->m_UIComponents.begin(); uiCompIter != this->m_UIComponents.end(); uiCompIter++)
	{
		(*uiCompIter)->UpdateClicked(mousePos);
	}
}

void UIHandler::UpdateUIComponentsclicked(DirectX::XMFLOAT2 mousePos, DirectX::XMFLOAT2 windowSize)
{
	std::vector<UIComponent*>::iterator uiCompIter;
	for (uiCompIter = this->m_UIComponents.begin(); uiCompIter != this->m_UIComponents.end(); uiCompIter++)
	{
		(*uiCompIter)->UpdateClicked(mousePos, windowSize);
	}
}
<|endoftext|>


<commit_before>#include "Scheduler.h"
//#include "Assert.h"

//TODO: Split to files. One file - one class.

namespace MT
{
	static const size_t TASK_BUFFER_CAPACITY = 4096;

	ThreadContext::ThreadContext()
		: taskScheduler(nullptr)
		, hasNewTasksEvent(EventReset::AUTOMATIC, true)
		, state(ThreadState::ALIVE)
		, descBuffer(TASK_BUFFER_CAPACITY)
	{
	}

	ThreadContext::~ThreadContext()
	{
	}

	FiberContext::FiberContext()
		: currentTask(nullptr)
		, threadContext(nullptr)
		, taskStatus(FiberTaskStatus::UNKNOWN)
		, subtaskFibersCount(0)
	{
	}

	void FiberContext::WaitGroupAndYield(TaskGroup::Type group)
	{
		VERIFY(group != currentGroup, "Can't wait the same group. Deadlock detected!", return);
		VERIFY(group < TaskGroup::COUNT, "Invalid group!", return);
		ASSERT(threadContext->taskScheduler->IsWorkerThread(), "Can't use WaitGroup outside Task. Use TaskScheduler.WaitGroup() instead.");

		ConcurrentQueueLIFO<TaskDesc> & groupQueue = threadContext->taskScheduler->waitTaskQueues[group];

		//change status
		taskStatus = FiberTaskStatus::AWAITING;

		// copy current task to awaiting queue
		groupQueue.Push(*currentTask);

		//
		ASSERT(threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

		//switch to scheduler
		Fiber::SwitchTo(fiber, threadContext->schedulerFiber);
	}

	void FiberContext::RunSubtasksAndYield(TaskGroup::Type taskGroup, fixed_array<TaskBucket>& buckets)
	{
		ASSERT(threadContext, "Sanity check failed!");

		ASSERT(currentTask, "Sanity check failed!");
		ASSERT(taskGroup < TaskGroup::COUNT, "Sanity check failed!");

		// ATTENTION !
		// copy current task description to stack.
		//  pointer to parentTask alive until all child task finished
		TaskDesc parentTask = *currentTask;

		ASSERT(threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

		for (size_t bucketIndex = 0; bucketIndex < buckets.size(); ++bucketIndex)
		{
			TaskBucket& bucket = buckets[bucketIndex];
			for (size_t i = 0; i < bucket.count; ++i)
				bucket.tasks[i].desc.parentTask = &parentTask;
		}

		//add subtask to scheduler
		threadContext->taskScheduler->RunTasksImpl(taskGroup, buckets, &parentTask);

		//
		ASSERT(threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

		//switch to scheduler
		Fiber::SwitchTo(fiber, threadContext->schedulerFiber);
	}

	TaskScheduler::GroupStats::GroupStats()
	{
		inProgressTaskCount.Set(0);
		allDoneEvent.Create( EventReset::MANUAL, true );
	}

	TaskScheduler::TaskScheduler()
		: roundRobinThreadIndex(0)
	{

		//query number of processor
		threadsCount = Max(Thread::GetNumberOfHardwareThreads() - 2, 1);

		if (threadsCount > MT_MAX_THREAD_COUNT)
		{
			threadsCount = MT_MAX_THREAD_COUNT;
		}

		// create fiber pool
		for (uint32 i = 0; i < MT_MAX_FIBERS_COUNT; i++)
		{
			FiberContext& context = fiberContext[i];
			context.fiber.Create(MT_FIBER_STACK_SIZE, FiberMain, &context);
			availableFibers.Push( &context );
		}

		// create worker thread pool
		for (uint32 i = 0; i < threadsCount; i++)
		{
			threadContext[i].taskScheduler = this;
			threadContext[i].thread.Start( MT_SCHEDULER_STACK_SIZE, ThreadMain, &threadContext[i] );
		}

	}

	TaskScheduler::~TaskScheduler()
	{
		for (uint32 i = 0; i < threadsCount; i++)
		{
			threadContext[i].state.Set(ThreadState::EXIT);
			threadContext[i].hasNewTasksEvent.Signal();
		}

		for (uint32 i = 0; i < threadsCount; i++)
		{
			threadContext[i].thread.Stop();
		}
	}

	FiberContext* TaskScheduler::RequestFiberContext()
	{
		FiberContext *fiber = nullptr;
		if (!availableFibers.TryPop(fiber))
		{
			ASSERT(false, "Fibers pool is empty");
		}
		return fiber;
	}

	void TaskScheduler::ReleaseFiberContext(FiberContext* fiberContext)
	{
		ASSERT(fiberContext != nullptr, "Can't release nullptr Fiber");

		fiberContext->currentGroup = TaskGroup::GROUP_UNDEFINED;
		fiberContext->currentTask = nullptr;

		availableFibers.Push(fiberContext);
	}

	void TaskScheduler::RestoreAwaitingTasks(TaskGroup::Type taskGroup)
	{
		ConcurrentQueueLIFO<TaskDesc> & groupQueue = waitTaskQueues[taskGroup];
		//TODO: move awaiting tasks into execution thread queues
	}

	bool TaskScheduler::ExecuteTask (ThreadContext& context, const TaskDesc & taskDesc)
	{
		bool canDropExecutionContext = false;

		TaskDesc taskInProgress = taskDesc;
		for(int iteration = 0;;iteration++)
		{
			ASSERT(taskInProgress.taskFunc != nullptr, "Invalid task function pointer");
			ASSERT(taskInProgress.fiberContext, "Invalid execution context.");

			taskInProgress.fiberContext->threadContext = &context;

			// update task status
			taskInProgress.fiberContext->taskStatus = FiberTaskStatus::RUNNED;

			ASSERT(context.thread.IsCurrentThread(), "Thread context sanity check failed");
			ASSERT(taskInProgress.fiberContext->threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

			// run current task code
			Fiber::SwitchTo(context.schedulerFiber, taskInProgress.fiberContext->fiber);

			// if task was done
			if (taskInProgress.fiberContext->taskStatus == FiberTaskStatus::FINISHED)
			{
				TaskGroup::Type taskGroup = taskInProgress.fiberContext->currentGroup;

				ASSERT(taskGroup < TaskGroup::COUNT, "Invalid group.");

				//update group status
				int groupTaskCount = context.taskScheduler->groupStats[taskGroup].inProgressTaskCount.Dec();
				ASSERT(groupTaskCount >= 0, "Sanity check failed!");
				if (groupTaskCount == 0)
				{
					//restore awaiting tasks
					context.taskScheduler->RestoreAwaitingTasks(taskGroup);

					context.taskScheduler->groupStats[taskGroup].allDoneEvent.Signal();
				}

				groupTaskCount = context.taskScheduler->allGroupStats.inProgressTaskCount.Dec();
				ASSERT(groupTaskCount >= 0, "Sanity check failed!");
				if (groupTaskCount == 0)
				{
					//notify all tasks in all group finished
					context.taskScheduler->allGroupStats.allDoneEvent.Signal();
				}

				//raise up releasing task fiber flag
				canDropExecutionContext = true;

				//
				if (iteration > 0)
				{
					context.taskScheduler->ReleaseTaskDescription(taskInProgress);
				}

				//
				if (taskInProgress.parentTask != nullptr)
				{
					int subTasksCount = taskInProgress.parentTask->fiberContext->subtaskFibersCount.Dec();
					ASSERT(subTasksCount >= 0, "Sanity check failed!");

					if (subTasksCount == 0)
					{
						// this is a last subtask. restore parent task

						TaskDesc * parent = taskInProgress.parentTask;

						ASSERT(context.thread.IsCurrentThread(), "Thread context sanity check failed");

						// WARNING!! Thread context can changed here! Set actual current thread context.
						parent->fiberContext->threadContext = &context;

						ASSERT(parent->fiberContext->threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

						// copy parent to current task.
						// can't just use pointer, because parent pointer is pointer on fiber stack
						taskInProgress = *parent;

						taskInProgress.fiberContext->currentTask = &taskInProgress;
					} else
					{
						// subtask still not finished
						// exiting
						break;
					}
				} else
				{
					// no parent task
					// exiting
					break;
				}
			} else
			{
				if (taskInProgress.fiberContext->taskStatus == FiberTaskStatus::AWAITING)
				{
					// current task was yielded, due to awaiting another task group
					// exiting
					break;
				} else
				{
					// current task was yielded, due to subtask spawn
					// exiting
					break;
				}

			}

		} // loop

		return canDropExecutionContext;
	}

	void TaskScheduler::FiberMain(void* userData)
	{
		FiberContext& context = *(FiberContext*)(userData);

		for(;;)
		{
			ASSERT(context.currentTask, "Invalid task in fiber context");
			ASSERT(context.currentTask->taskFunc, "Invalid task function");
			ASSERT(context.currentGroup < TaskGroup::COUNT, "Invalid task group");
			ASSERT(context.threadContext, "Invalid thread context");
			ASSERT(context.threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

			context.currentTask->taskFunc( context, context.currentTask->userData );

			context.taskStatus = FiberTaskStatus::FINISHED;

			Fiber::SwitchTo(context.fiber, context.threadContext->schedulerFiber);
		}

	}

	void TaskScheduler::ThreadMain( void* userData )
	{
		ThreadContext& context = *(ThreadContext*)(userData);
		ASSERT(context.taskScheduler, "Task scheduler must be not null!");
		context.schedulerFiber.CreateFromThread(context.thread);

		while(context.state.Get() != ThreadState::EXIT)
		{
			GroupedTask task;
			if (context.queue.TryPop(task))
			{
				//there is a new task

				context.taskScheduler->PrepareTaskDescription(task);
				ASSERT(task.desc.fiberContext, "Can't get execution context from pool");
				ASSERT(task.desc.fiberContext->currentTask->taskFunc, "Sanity check failed");

				for(;;)
				{
					// prevent invalid fiber resume from child tasks, before ExecuteTask is done
					task.desc.fiberContext->subtaskFibersCount.Inc();
					bool canDropContext = ExecuteTask(context, task.desc);
					int subtaskCount = task.desc.fiberContext->subtaskFibersCount.Dec();
					ASSERT(subtaskCount >= 0, "Sanity check failed");

					bool taskIsFinished = (task.desc.fiberContext->taskStatus == FiberTaskStatus::FINISHED);
					bool taskIsAwait = (task.desc.fiberContext->taskStatus == FiberTaskStatus::AWAITING);

					if (canDropContext)
					{
						context.taskScheduler->ReleaseTaskDescription(task.desc);
						ASSERT(task.desc.fiberContext == nullptr, "Sanity check failed");
					}

					// if subtasks still exist, drop current task execution. current task will be resumed when last subtask finished
					if (subtaskCount > 0)
					{
						break;
					}

					//if task is finished or task is in await state drop execution
					if (taskIsFinished || taskIsAwait)
					{
						break;
					}

					// no subtasks and status is not finished, this mean all subtasks already finished before parent return from ExecuteTask
					// continue task execution
				}

				if (task.desc.fiberContext)
					task.desc.fiberContext->currentTask = nullptr;

			}
			else
			{
				//TODO: can try to steal tasks from other threads
				context.hasNewTasksEvent.Wait(2000);
			}
		}
	}

	void TaskScheduler::RunTasksImpl(TaskGroup::Type taskGroup, fixed_array<TaskBucket>& buckets, TaskDesc * parentTask)
	{
		ASSERT(taskGroup < TaskGroup::COUNT, "Invalid group.");

		size_t count = 0;

		for (size_t i = 0; i < buckets.size(); ++i)
			count += buckets[i].count;

		if (parentTask)
		{
			parentTask->fiberContext->subtaskFibersCount.Add((uint32)count);
		}

		for (size_t i = 0; i < buckets.size(); ++i)
		{
			int bucketIndex = roundRobinThreadIndex.Inc() % threadsCount;
			ThreadContext & context = threadContext[bucketIndex];

			TaskBucket& bucket = buckets[i];

			allGroupStats.allDoneEvent.Reset();
			allGroupStats.inProgressTaskCount.Add((uint32)bucket.count);

			groupStats[taskGroup].allDoneEvent.Reset();
			groupStats[taskGroup].inProgressTaskCount.Add((uint32)bucket.count);

			context.queue.PushRange(bucket.tasks, bucket.count);

			context.hasNewTasksEvent.Signal();

		}
	}

	bool TaskScheduler::WaitGroup(TaskGroup::Type group, uint32 milliseconds)
	{
		VERIFY(IsWorkerThread() == false, "Can't use WaitGroup inside Task. Use FiberContext.WaitGroupAndYield() instead.", return false);

		return groupStats[group].allDoneEvent.Wait(milliseconds);
	}

	bool TaskScheduler::WaitAll(uint32 milliseconds)
	{
		VERIFY(IsWorkerThread() == false, "Can't use WaitAll inside Task.", return false);

		return allGroupStats.allDoneEvent.Wait(milliseconds);
	}

	bool TaskScheduler::IsEmpty()
	{
		for (uint32 i = 0; i < MT_MAX_THREAD_COUNT; i++)
		{
			if (!threadContext[i].queue.IsEmpty())
			{
				return false;
			}
		}
		return true;
	}

	uint32 TaskScheduler::GetWorkerCount() const
	{
		return threadsCount;
	}

	bool TaskScheduler::IsWorkerThread() const
	{
		for (uint32 i = 0; i < MT_MAX_THREAD_COUNT; i++)
		{
			if (threadContext[i].thread.IsCurrentThread())
			{
				return true;
			}
		}
		return false;
	}

	void TaskScheduler::ReleaseTaskDescription(TaskDesc& description)
	{
		ReleaseFiberContext(description.fiberContext);
		description.fiberContext = nullptr;
	}

	bool TaskScheduler::PrepareTaskDescription(GroupedTask& task)
	{
		task.desc.fiberContext = RequestFiberContext();
		task.desc.fiberContext->currentTask = &task.desc;
		task.desc.fiberContext->currentGroup = task.group;
		return task.desc.fiberContext != nullptr;
	}

}
<commit_msg>Small improvement in diagnostic<commit_after>#include "Scheduler.h"
//#include "Assert.h"

//TODO: Split to files. One file - one class.

namespace MT
{
	static const size_t TASK_BUFFER_CAPACITY = 4096;

	ThreadContext::ThreadContext()
		: taskScheduler(nullptr)
		, hasNewTasksEvent(EventReset::AUTOMATIC, true)
		, state(ThreadState::ALIVE)
		, descBuffer(TASK_BUFFER_CAPACITY)
	{
	}

	ThreadContext::~ThreadContext()
	{
	}

	FiberContext::FiberContext()
		: currentTask(nullptr)
		, currentGroup(TaskGroup::GROUP_UNDEFINED)
		, threadContext(nullptr)
		, taskStatus(FiberTaskStatus::UNKNOWN)
		, subtaskFibersCount(0)
	{
	}

	void FiberContext::WaitGroupAndYield(TaskGroup::Type group)
	{
		VERIFY(group != currentGroup, "Can't wait the same group. Deadlock detected!", return);
		VERIFY(group < TaskGroup::COUNT, "Invalid group!", return);
		ASSERT(threadContext->taskScheduler->IsWorkerThread(), "Can't use WaitGroup outside Task. Use TaskScheduler.WaitGroup() instead.");

		ConcurrentQueueLIFO<TaskDesc> & groupQueue = threadContext->taskScheduler->waitTaskQueues[group];

		//change status
		taskStatus = FiberTaskStatus::AWAITING;

		// copy current task to awaiting queue
		groupQueue.Push(*currentTask);

		//
		ASSERT(threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

		//switch to scheduler
		Fiber::SwitchTo(fiber, threadContext->schedulerFiber);
	}

	void FiberContext::RunSubtasksAndYield(TaskGroup::Type taskGroup, fixed_array<TaskBucket>& buckets)
	{
		ASSERT(threadContext, "Sanity check failed!");

		ASSERT(currentTask, "Sanity check failed!");
		ASSERT(taskGroup < TaskGroup::COUNT, "Sanity check failed!");

		// ATTENTION !
		// copy current task description to stack.
		//  pointer to parentTask alive until all child task finished
		TaskDesc parentTask = *currentTask;

		ASSERT(threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

		for (size_t bucketIndex = 0; bucketIndex < buckets.size(); ++bucketIndex)
		{
			TaskBucket& bucket = buckets[bucketIndex];
			for (size_t i = 0; i < bucket.count; ++i)
				bucket.tasks[i].desc.parentTask = &parentTask;
		}

		//add subtask to scheduler
		threadContext->taskScheduler->RunTasksImpl(taskGroup, buckets, &parentTask);

		//
		ASSERT(threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

		//switch to scheduler
		Fiber::SwitchTo(fiber, threadContext->schedulerFiber);
	}

	TaskScheduler::GroupStats::GroupStats()
	{
		inProgressTaskCount.Set(0);
		allDoneEvent.Create( EventReset::MANUAL, true );
	}

	TaskScheduler::TaskScheduler()
		: roundRobinThreadIndex(0)
	{

		//query number of processor
		threadsCount = Max(Thread::GetNumberOfHardwareThreads() - 2, 1);

		if (threadsCount > MT_MAX_THREAD_COUNT)
		{
			threadsCount = MT_MAX_THREAD_COUNT;
		}

		// create fiber pool
		for (uint32 i = 0; i < MT_MAX_FIBERS_COUNT; i++)
		{
			FiberContext& context = fiberContext[i];
			context.fiber.Create(MT_FIBER_STACK_SIZE, FiberMain, &context);
			availableFibers.Push( &context );
		}

		// create worker thread pool
		for (uint32 i = 0; i < threadsCount; i++)
		{
			threadContext[i].taskScheduler = this;
			threadContext[i].thread.Start( MT_SCHEDULER_STACK_SIZE, ThreadMain, &threadContext[i] );
		}

	}

	TaskScheduler::~TaskScheduler()
	{
		for (uint32 i = 0; i < threadsCount; i++)
		{
			threadContext[i].state.Set(ThreadState::EXIT);
			threadContext[i].hasNewTasksEvent.Signal();
		}

		for (uint32 i = 0; i < threadsCount; i++)
		{
			threadContext[i].thread.Stop();
		}
	}

	FiberContext* TaskScheduler::RequestFiberContext()
	{
		FiberContext *fiber = nullptr;
		if (!availableFibers.TryPop(fiber))
		{
			ASSERT(false, "Fibers pool is empty");
		}
		return fiber;
	}

	void TaskScheduler::ReleaseFiberContext(FiberContext* fiberContext)
	{
		ASSERT(fiberContext != nullptr, "Can't release nullptr Fiber");

		fiberContext->currentGroup = TaskGroup::GROUP_UNDEFINED;
		fiberContext->currentTask = nullptr;

		availableFibers.Push(fiberContext);
	}

	void TaskScheduler::RestoreAwaitingTasks(TaskGroup::Type taskGroup)
	{
		ConcurrentQueueLIFO<TaskDesc> & groupQueue = waitTaskQueues[taskGroup];
		//TODO: move awaiting tasks into execution thread queues
	}

	bool TaskScheduler::ExecuteTask (ThreadContext& context, const TaskDesc & taskDesc)
	{
		bool canDropExecutionContext = false;

		TaskDesc taskInProgress = taskDesc;
		for(int iteration = 0;;iteration++)
		{
			ASSERT(taskInProgress.taskFunc != nullptr, "Invalid task function pointer");
			ASSERT(taskInProgress.fiberContext, "Invalid execution context.");

			taskInProgress.fiberContext->threadContext = &context;

			// update task status
			taskInProgress.fiberContext->taskStatus = FiberTaskStatus::RUNNED;

			ASSERT(context.thread.IsCurrentThread(), "Thread context sanity check failed");
			ASSERT(taskInProgress.fiberContext->threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

			// run current task code
			Fiber::SwitchTo(context.schedulerFiber, taskInProgress.fiberContext->fiber);

			// if task was done
			if (taskInProgress.fiberContext->taskStatus == FiberTaskStatus::FINISHED)
			{
				TaskGroup::Type taskGroup = taskInProgress.fiberContext->currentGroup;

				ASSERT(taskGroup < TaskGroup::COUNT, "Invalid group.");

				//update group status
				int groupTaskCount = context.taskScheduler->groupStats[taskGroup].inProgressTaskCount.Dec();
				ASSERT(groupTaskCount >= 0, "Sanity check failed!");
				if (groupTaskCount == 0)
				{
					//restore awaiting tasks
					context.taskScheduler->RestoreAwaitingTasks(taskGroup);

					context.taskScheduler->groupStats[taskGroup].allDoneEvent.Signal();
				}

				groupTaskCount = context.taskScheduler->allGroupStats.inProgressTaskCount.Dec();
				ASSERT(groupTaskCount >= 0, "Sanity check failed!");
				if (groupTaskCount == 0)
				{
					//notify all tasks in all group finished
					context.taskScheduler->allGroupStats.allDoneEvent.Signal();
				}

				//raise up releasing task fiber flag
				canDropExecutionContext = true;

				//
				if (iteration > 0)
				{
					context.taskScheduler->ReleaseTaskDescription(taskInProgress);
				}

				//
				if (taskInProgress.parentTask != nullptr)
				{
					int subTasksCount = taskInProgress.parentTask->fiberContext->subtaskFibersCount.Dec();
					ASSERT(subTasksCount >= 0, "Sanity check failed!");

					if (subTasksCount == 0)
					{
						// this is a last subtask. restore parent task

						TaskDesc * parent = taskInProgress.parentTask;

						ASSERT(context.thread.IsCurrentThread(), "Thread context sanity check failed");

						// WARNING!! Thread context can changed here! Set actual current thread context.
						parent->fiberContext->threadContext = &context;

						ASSERT(parent->fiberContext->threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

						// copy parent to current task.
						// can't just use pointer, because parent pointer is pointer on fiber stack
						taskInProgress = *parent;

						taskInProgress.fiberContext->currentTask = &taskInProgress;
					} else
					{
						// subtask still not finished
						// exiting
						break;
					}
				} else
				{
					// no parent task
					// exiting
					break;
				}
			}
			else if (taskInProgress.fiberContext->taskStatus == FiberTaskStatus::AWAITING)
			{
				// current task was yielded, due to awaiting another task group
				// exiting
				break;
			}
			else if (taskInProgress.fiberContext->taskStatus == FiberTaskStatus::RUNNED)
			{
				// current task was yielded, due to subtask spawn
				// exiting
				break;
			}
			else
			{
				ASSERT(false, "State is not supperted. Undefined behaviour!")
			}
		} // loop

		return canDropExecutionContext;
	}

	void TaskScheduler::FiberMain(void* userData)
	{
		FiberContext& context = *(FiberContext*)(userData);

		for(;;)
		{
			ASSERT(context.currentTask, "Invalid task in fiber context");
			ASSERT(context.currentTask->taskFunc, "Invalid task function");
			ASSERT(context.currentGroup < TaskGroup::COUNT, "Invalid task group");
			ASSERT(context.threadContext, "Invalid thread context");
			ASSERT(context.threadContext->thread.IsCurrentThread(), "Thread context sanity check failed");

			context.currentTask->taskFunc( context, context.currentTask->userData );

			context.taskStatus = FiberTaskStatus::FINISHED;

			Fiber::SwitchTo(context.fiber, context.threadContext->schedulerFiber);
		}

	}

	void TaskScheduler::ThreadMain( void* userData )
	{
		ThreadContext& context = *(ThreadContext*)(userData);
		ASSERT(context.taskScheduler, "Task scheduler must be not null!");
		context.schedulerFiber.CreateFromThread(context.thread);

		while(context.state.Get() != ThreadState::EXIT)
		{
			GroupedTask task;
			if (context.queue.TryPop(task))
			{
				//there is a new task

				context.taskScheduler->PrepareTaskDescription(task);
				ASSERT(task.desc.fiberContext, "Can't get execution context from pool");
				ASSERT(task.desc.fiberContext->currentTask->taskFunc, "Sanity check failed");

				for(;;)
				{
					// prevent invalid fiber resume from child tasks, before ExecuteTask is done
					task.desc.fiberContext->subtaskFibersCount.Inc();
					bool canDropContext = ExecuteTask(context, task.desc);
					int subtaskCount = task.desc.fiberContext->subtaskFibersCount.Dec();
					ASSERT(subtaskCount >= 0, "Sanity check failed");

					bool taskIsFinished = (task.desc.fiberContext->taskStatus == FiberTaskStatus::FINISHED);
					bool taskIsAwait = (task.desc.fiberContext->taskStatus == FiberTaskStatus::AWAITING);

					if (canDropContext)
					{
						context.taskScheduler->ReleaseTaskDescription(task.desc);
						ASSERT(task.desc.fiberContext == nullptr, "Sanity check failed");
					}

					// if subtasks still exist, drop current task execution. current task will be resumed when last subtask finished
					if (subtaskCount > 0)
					{
						break;
					}

					//if task is finished or task is in await state drop execution
					if (taskIsFinished || taskIsAwait)
					{
						break;
					}

					// no subtasks and status is not finished, this mean all subtasks already finished before parent return from ExecuteTask
					// continue task execution
				}

				if (task.desc.fiberContext)
					task.desc.fiberContext->currentTask = nullptr;

			}
			else
			{
				//TODO: can try to steal tasks from other threads
				context.hasNewTasksEvent.Wait(2000);
			}
		}
	}

	void TaskScheduler::RunTasksImpl(TaskGroup::Type taskGroup, fixed_array<TaskBucket>& buckets, TaskDesc * parentTask)
	{
		ASSERT(taskGroup < TaskGroup::COUNT, "Invalid group.");

		size_t count = 0;

		for (size_t i = 0; i < buckets.size(); ++i)
			count += buckets[i].count;

		if (parentTask)
		{
			parentTask->fiberContext->subtaskFibersCount.Add((uint32)count);
		}

		for (size_t i = 0; i < buckets.size(); ++i)
		{
			int bucketIndex = roundRobinThreadIndex.Inc() % threadsCount;
			ThreadContext & context = threadContext[bucketIndex];

			TaskBucket& bucket = buckets[i];

			allGroupStats.allDoneEvent.Reset();
			allGroupStats.inProgressTaskCount.Add((uint32)bucket.count);

			groupStats[taskGroup].allDoneEvent.Reset();
			groupStats[taskGroup].inProgressTaskCount.Add((uint32)bucket.count);

			context.queue.PushRange(bucket.tasks, bucket.count);

			context.hasNewTasksEvent.Signal();

		}
	}

	bool TaskScheduler::WaitGroup(TaskGroup::Type group, uint32 milliseconds)
	{
		VERIFY(IsWorkerThread() == false, "Can't use WaitGroup inside Task. Use FiberContext.WaitGroupAndYield() instead.", return false);

		return groupStats[group].allDoneEvent.Wait(milliseconds);
	}

	bool TaskScheduler::WaitAll(uint32 milliseconds)
	{
		VERIFY(IsWorkerThread() == false, "Can't use WaitAll inside Task.", return false);

		return allGroupStats.allDoneEvent.Wait(milliseconds);
	}

	bool TaskScheduler::IsEmpty()
	{
		for (uint32 i = 0; i < MT_MAX_THREAD_COUNT; i++)
		{
			if (!threadContext[i].queue.IsEmpty())
			{
				return false;
			}
		}
		return true;
	}

	uint32 TaskScheduler::GetWorkerCount() const
	{
		return threadsCount;
	}

	bool TaskScheduler::IsWorkerThread() const
	{
		for (uint32 i = 0; i < MT_MAX_THREAD_COUNT; i++)
		{
			if (threadContext[i].thread.IsCurrentThread())
			{
				return true;
			}
		}
		return false;
	}

	void TaskScheduler::ReleaseTaskDescription(TaskDesc& description)
	{
		ReleaseFiberContext(description.fiberContext);
		description.fiberContext = nullptr;
	}

	bool TaskScheduler::PrepareTaskDescription(GroupedTask& task)
	{
		task.desc.fiberContext = RequestFiberContext();
		task.desc.fiberContext->currentTask = &task.desc;
		task.desc.fiberContext->currentGroup = task.group;
		return task.desc.fiberContext != nullptr;
	}

}
<|endoftext|>


<commit_before>#include "cinder/app/AppNative.h"
#include "cinder/gl/gl.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class RetinaSampleApp : public AppNative {
  public:
	void prepareSettings( Settings *settings ) override;
	void setup();
	void mouseDrag( MouseEvent event );
	void mouseDown( MouseEvent event );
	void keyDown( KeyEvent event );
	void displayChange();
	void draw();

	// This will maintain a list of points which we will draw line segments between
	list<Vec2f>		mPoints;
};

void RetinaSampleApp::prepareSettings( Settings *settings )
{
	settings->setWindowSize( 800, 600 );
	settings->enableHighDensityDisplay();
	console() << "settings->getHighDensityDisplayEnabled()= " << settings->isHighDensityDisplayEnabled() << endl;

}

void RetinaSampleApp::setup()
{
	getWindow()->getSignalDisplayChange().connect( std::bind( &RetinaSampleApp::displayChange, this ) );
}

void RetinaSampleApp::mouseDrag( MouseEvent event )
{
	console() << event.getPos()	<< endl;
	mPoints.push_back( event.getPos() );
}

void RetinaSampleApp::mouseDown( MouseEvent event )
{
	console() << "getWindowContentScale = " << getWindowContentScale() << endl;
	console() << event.getPos()	<< endl;
}

void RetinaSampleApp::keyDown( KeyEvent event )
{
	if( event.getChar() == 'f' )
		setFullScreen( ! isFullScreen() );
}

void RetinaSampleApp::displayChange()
{
	console() << "Window display changed: " << getWindow()->getDisplay()->getBounds() << std::endl;
	console() << "ContentScale = " << getWindowContentScale() << endl;
	console() << "getWindowCenter() = " << getWindowCenter() << endl;
	console() << "getWindow()->toPixels( 1.0f ) = " << toPixels( 1.0f ) << endl;

}

void RetinaSampleApp::draw()
{

	// float c = getWindowContentScale();

	gl::clear( Color( 0.1f, 0.1f, 0.15f ) );
	gl::color( 1.0f, 0.5f, 0.25f );

	gl::pushMatrices();
		gl::begin( GL_LINE_STRIP );
		glLineWidth( getWindow()->toPixels( 1.0f ) );
		for( auto pointIter = mPoints.begin(); pointIter != mPoints.end(); ++pointIter ) {
			gl::vertex( *pointIter );
		}
		gl::end();
	gl::popMatrices();

	gl::pushMatrices();
		glColor3f( 1.0f, 0.2f, 0.15f );
		gl::translate( getWindowCenter() );
		gl::rotate( getElapsedSeconds() * 5 );
		gl::drawSolidRect( Rectf( toPixels( Area( -100, -100, 100, 100 ) ) ) );
	gl::popMatrices();

}

CINDER_APP_NATIVE( RetinaSampleApp, RendererGl )
<commit_msg>samples/RetinaSample to reflect more common use case<commit_after>#include "cinder/app/AppNative.h"
#include "cinder/gl/gl.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class RetinaSampleApp : public AppNative {
  public:
	void prepareSettings( Settings *settings ) override;
	void setup();
	void mouseDrag( MouseEvent event );
	void keyDown( KeyEvent event );
	void displayChange();
	void draw();

	// This will maintain a list of points which we will draw line segments between
	list<Vec2f>		mPoints;
};

void RetinaSampleApp::prepareSettings( Settings *settings )
{
	settings->enableHighDensityDisplay();
	console() << "settings->getHighDensityDisplayEnabled()= " << settings->isHighDensityDisplayEnabled() << endl;
}

void RetinaSampleApp::setup()
{
	getWindow()->getSignalDisplayChange().connect( std::bind( &RetinaSampleApp::displayChange, this ) );
}

void RetinaSampleApp::mouseDrag( MouseEvent event )
{
	mPoints.push_back( event.getPos() );
}

void RetinaSampleApp::keyDown( KeyEvent event )
{
	if( event.getChar() == 'f' )
		setFullScreen( ! isFullScreen() );
}

void RetinaSampleApp::displayChange()
{
	console() << "Window display changed: " << getWindow()->getDisplay()->getBounds() << std::endl;
	console() << "ContentScale = " << getWindowContentScale() << endl;
	console() << "getWindowCenter() = " << getWindowCenter() << endl;
	console() << "getWindow()->toPixels( 1.0f ) = " << toPixels( 1.0f ) << endl;
}

void RetinaSampleApp::draw()
{
	gl::clear( Color( 0.1f, 0.1f, 0.15f ) );
	gl::color( 1.0f, 0.5f, 0.25f );

	gl::pushMatrices();
		glLineWidth( getWindow()->toPixels( 1.0f ) );
		gl::begin( GL_LINE_STRIP );
		for( auto pointIter = mPoints.begin(); pointIter != mPoints.end(); ++pointIter ) {
			gl::vertex( *pointIter );
		}
		gl::end();
	gl::popMatrices();

	gl::pushMatrices();
		glColor3f( 1.0f, 0.2f, 0.15f );
		gl::translate( getWindowCenter() );
		gl::rotate( getElapsedSeconds() * 5 );
		gl::drawSolidRect( Rectf( Area( -100, -100, 100, 100 ) ) );
	gl::popMatrices();
}

CINDER_APP_NATIVE( RetinaSampleApp, RendererGl )<|endoftext|>


<commit_before>/*
  ---------------------------------------------------------------------------------
  FIXME: Consider avoiding using STL in this instrumentation. Which
  might improve performance

  FIXME: Try to avoid current requirement of
  -finstrument-functions-exclude-file-list=/usr/
  -finstrument-functions-exclude-function-list=static_initialization_and_destruction
  ---------------------------------------------------------------------------------
*/

#include "libunwind_wtf.h"

#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <thread>

#define UNW_LOCAL_ONLY
#include <libunwind.h>

#define WTF_ENABLE 1
#include <wtf/macros.h>

// not needed for profiling to function. Just for main().
#include <chrono>

using namespace std;
namespace
{
using Event    = ::wtf::ScopedEventIf<kWtfEnabledForNamespace>;
using Scope    = ::wtf::AutoScopeIf<kWtfEnabledForNamespace>;
using EventPtr = shared_ptr<Event>;
using ScopePtr = unique_ptr<Scope>;

inline unordered_map<string, queue<ScopePtr>>& gMap() __attribute__((no_instrument_function));
inline unordered_map<string, queue<ScopePtr>>& gMap()
{
    // TODO: measure timings with rwlock and compare
    thread_local unordered_map<string, queue<ScopePtr>> tlMap {};
    return tlMap;
};

inline map<void*, string>& gFuncNamesMap() __attribute__((no_instrument_function));
inline map<void*, string>& gFuncNamesMap()
{
    // TODO: measure timings with rwlock and compare
    thread_local map<void*, string> tlFuncNamesMap {};
    return tlFuncNamesMap;
};

inline void ensureFunctionName(void* caller) __attribute__((no_instrument_function));
inline void ensureFunctionName(void* caller)
{
    if (gFuncNamesMap().find(caller) != gFuncNamesMap().end())
        return;

    // FIXME: handle errors appropriately
    unw_context_t ctx;
    unw_cursor_t c;
    unw_getcontext(&ctx);
    unw_init_local(&c, &ctx);
    unw_step(&c);
    unw_step(&c);

    thread_local char name[200];
    unw_word_t offset;
    unw_get_proc_name(&c, name, 200, &offset);

    gFuncNamesMap()[caller] = name;
}
}

extern "C"
{
void __cyg_profile_func_enter (void *func,  void *caller)
{
    WTF_AUTO_THREAD_ENABLE();

    ensureFunctionName(caller);

    ::wtf::ScopedEventIf<kWtfEnabledForNamespace> __wtf_scope_event0_35{gFuncNamesMap()[caller].c_str()};
    ScopePtr s(new Scope(__wtf_scope_event0_35));
    s->Enter();

    gMap()[gFuncNamesMap()[caller]].emplace(std::move(s));
}

void __cyg_profile_func_exit (void *func, void *caller)
{
    gMap()[gFuncNamesMap()[caller]].pop();
}
} //extern C

void saveProfiling(const char* filename)
{
    ::wtf::Runtime::GetInstance()->SaveToFile(filename);
}
<commit_msg>Few small changes: removed include, added a fixme<commit_after>/*
  ---------------------------------------------------------------------------------
  FIXME: Consider avoiding using STL in this instrumentation. Which
  might improve performance

  FIXME: Try to avoid current requirement of
  -finstrument-functions-exclude-file-list=/usr/
  -finstrument-functions-exclude-function-list=static_initialization_and_destruction

  FIXME: symbol visibility

  ---------------------------------------------------------------------------------
*/

#include "libunwind_wtf.h"

#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <thread>

#define UNW_LOCAL_ONLY
#include <libunwind.h>

#define WTF_ENABLE 1
#include <wtf/macros.h>

using namespace std;
namespace
{
using Event    = ::wtf::ScopedEventIf<kWtfEnabledForNamespace>;
using Scope    = ::wtf::AutoScopeIf<kWtfEnabledForNamespace>;
using EventPtr = shared_ptr<Event>;
using ScopePtr = unique_ptr<Scope>;

inline unordered_map<string, queue<ScopePtr>>& gMap() __attribute__((no_instrument_function));
inline unordered_map<string, queue<ScopePtr>>& gMap()
{
    // TODO: measure timings with rwlock and compare
    thread_local unordered_map<string, queue<ScopePtr>> tlMap {};
    return tlMap;
};

inline map<void*, string>& gFuncNamesMap() __attribute__((no_instrument_function));
inline map<void*, string>& gFuncNamesMap()
{
    // TODO: measure timings with rwlock and compare
    thread_local map<void*, string> tlFuncNamesMap {};
    return tlFuncNamesMap;
};

inline void ensureFunctionName(void* caller) __attribute__((no_instrument_function));
inline void ensureFunctionName(void* caller)
{
    if (gFuncNamesMap().find(caller) != gFuncNamesMap().end())
        return;

    // FIXME: handle errors appropriately
    unw_context_t ctx;
    unw_cursor_t c;
    unw_getcontext(&ctx);
    unw_init_local(&c, &ctx);
    unw_step(&c);
    unw_step(&c);

    thread_local char name[200];
    unw_word_t offset;
    unw_get_proc_name(&c, name, 200, &offset);

    gFuncNamesMap()[caller] = name;
}
}

extern "C"
{
void __cyg_profile_func_enter (void *func,  void *caller)
{
    WTF_AUTO_THREAD_ENABLE();

    ensureFunctionName(caller);

    ::wtf::ScopedEventIf<kWtfEnabledForNamespace> __wtf_scope_event0_35{gFuncNamesMap()[caller].c_str()};
    ScopePtr s(new Scope(__wtf_scope_event0_35));
    s->Enter();

    gMap()[gFuncNamesMap()[caller]].emplace(std::move(s));
}

void __cyg_profile_func_exit (void *func, void *caller)
{
    gMap()[gFuncNamesMap()[caller]].pop();
}
} //extern C

void saveProfiling(const char* filename)
{
    ::wtf::Runtime::GetInstance()->SaveToFile(filename);
}
<|endoftext|>


<commit_before>//
// Allocate objects smaller than a page.
//

#include "types.h"
#include "mmu.h"
#include "kernel.hh"
#include "spinlock.h"
#include "kalloc.hh"
#include "mtrace.h"
#include "cpu.hh"

// allocate in power-of-two sizes up to 2^KMMAX
// must be < 12
#define KMMAX 11

struct header {
  struct header *next;
};

struct freelist {
  struct header *buckets[KMMAX+1];
  char name[MAXNAME];
  struct spinlock lock;
};

struct freelist freelists[NCPU];

void
kminit(void)
{
  for (int c = 0; c < NCPU; c++) {
    freelists[c].name[0] = (char) c + '0';
    safestrcpy(freelists[c].name+1, "freelist", MAXNAME-1);
    initlock(&freelists[c].lock, freelists[c].name, LOCKSTAT_KMALLOC);
  }
}

// get more space for freelists[c].buckets[b]
void
morecore(int c, int b)
{
  char *p = kalloc();
  if(p == 0)
    return;

  int sz = 1 << b;
  for(char *q = p;
      q + sz + sizeof(struct header) <= p + PGSIZE;
      q += sz + sizeof(struct header)){
    struct header *h = (struct header *) q;
    h->next = freelists[c].buckets[b];
    freelists[c].buckets[b] = h;
  }
}

void *
kmalloc(u64 nbytes)
{
  int nn = 1, b = 0;
  void *r = 0;
  struct header *h;
  int c = mycpu()->id;

  while(nn < nbytes && b <= KMMAX){
    nn *= 2;
    b++;
  }
  if(nn != (1 << b))
    panic("kmalloc oops");
  if(b > KMMAX)
    panic("kmalloc too big");

  acquire(&freelists[c].lock);
  if(freelists[c].buckets[b] == 0)
    morecore(c, b);
  h = freelists[c].buckets[b];
  if(h){
    freelists[c].buckets[b] = h->next;
    r = h + 1;
    h->next = (header*) (long) b;
  }
  release(&freelists[c].lock);

  if (r)
    mtlabel(mtrace_label_heap, r, nbytes, "kmalloc'ed", sizeof("kmalloc'ed"));
  if(r == 0)
    cprintf("kmalloc(%d) failed\n", (int) nbytes);
  return r;
}

void
kmfree(void *ap)
{
  int c = mycpu()->id;
  struct header *h;
  int b;

  acquire(&freelists[c].lock);

  h = (struct header *) ((char *)ap - sizeof(struct header));
  b = (long) h->next;
  if(b < 0 || b > KMMAX)
    panic("kmfree bad bucket");

  verifyfree((char*) ap, (1<<b) - sizeof(struct header));
  if (ALLOC_MEMSET)
    memset(ap, 3, (1<<b) - sizeof(struct header));

  h->next = freelists[c].buckets[b];
  freelists[c].buckets[b] = h;
  mtunlabel(mtrace_label_heap, ap);
  release(&freelists[c].lock);
}

int
kmalign(void **p, int align, u64 size)
{
  void *mem = kmalloc(size + (align-1) + sizeof(void*));
  char *amem = ((char*)mem) + sizeof(void*);
  amem += align - ((uptr)amem & (align - 1));
  ((void**)amem)[-1] = mem;
  *p = amem;
  return 0;
}

void kmalignfree(void *mem)
{
  kmfree(((void**)mem)[-1]);
}
<commit_msg>atomic (lockless) kmalloc<commit_after>//
// Allocate objects smaller than a page.
//

#include "types.h"
#include "mmu.h"
#include "kernel.hh"
#include "spinlock.h"
#include "kalloc.hh"
#include "mtrace.h"
#include "cpu.hh"

// allocate in power-of-two sizes up to 2^KMMAX
// must be < 12
#define KMMAX 11

struct header {
  struct header *next;
};

struct freelist {
  std::atomic<header*> buckets[KMMAX+1];
  char name[MAXNAME];
};

struct freelist freelists[NCPU];

void
kminit(void)
{
  for (int c = 0; c < NCPU; c++) {
    freelists[c].name[0] = (char) c + '0';
    safestrcpy(freelists[c].name+1, "freelist", MAXNAME-1);
  }
}

// get more space for freelists[c].buckets[b]
int
morecore(int c, int b)
{
  char *p = kalloc();
  if(p == 0)
    return -1;

  int sz = 1 << b;
  for(char *q = p;
      q + sz + sizeof(struct header) <= p + PGSIZE;
      q += sz + sizeof(struct header)){
    struct header *h = (struct header *) q;
    h->next = freelists[c].buckets[b];
    freelists[c].buckets[b] = h;
  }

  return 0;
}

void *
kmalloc(u64 nbytes)
{
  int nn = 1, b = 0;

  while(nn < nbytes && b <= KMMAX){
    nn *= 2;
    b++;
  }
  if(nn != (1 << b))
    panic("kmalloc oops");
  if(b > KMMAX)
    panic("kmalloc too big");

  scoped_gc_epoch gc;
  struct header *h;
  int c = mycpu()->id;

  for (;;) {
    h = freelists[c].buckets[b];
    if (!h) {
      if (morecore(c, b) < 0) {
        cprintf("kmalloc(%d) failed\n", (int) nbytes);
        return 0;
      }
    } else {
      if (cmpxch(&freelists[c].buckets[b], h, h->next))
        break;
    }
  }

  void *r = h + 1;
  h->next = (header*) (long) b;

  mtlabel(mtrace_label_heap, r, nbytes, "kmalloc'ed", sizeof("kmalloc'ed"));
  return r;
}

void
kmfree(void *ap)
{
  int c = mycpu()->id;
  struct header *h;
  int b;

  h = (struct header *) ((char *)ap - sizeof(struct header));
  b = (long) h->next;
  if(b < 0 || b > KMMAX)
    panic("kmfree bad bucket");

  verifyfree((char*) ap, (1<<b) - sizeof(struct header));
  if (ALLOC_MEMSET)
    memset(ap, 3, (1<<b) - sizeof(struct header));

  h->next = freelists[c].buckets[b];
  while (!cmpxch_update(&freelists[c].buckets[b], &h->next, h))
    ; /* spin */

  mtunlabel(mtrace_label_heap, ap);
}

int
kmalign(void **p, int align, u64 size)
{
  void *mem = kmalloc(size + (align-1) + sizeof(void*));
  char *amem = ((char*)mem) + sizeof(void*);
  amem += align - ((uptr)amem & (align - 1));
  ((void**)amem)[-1] = mem;
  *p = amem;
  return 0;
}

void kmalignfree(void *mem)
{
  kmfree(((void**)mem)[-1]);
}
<|endoftext|>


<commit_before>#include "module_scanningsonar.h"
#include <QtCore>
#include <stdio.h>
#include "scanningsonar_form.h"
#include "sonarreturndata.h"
#include "sonardatasourceserial.h"
#include "sonardatasourcefile.h"
#include "sonardatacsvrecorder.h"
#include "sonardata852recorder.h"
#include <Module_ThrusterControlLoop/module_thrustercontrolloop.h>
#include <Module_Simulation/module_simulation.h>
Module_ScanningSonar::Module_ScanningSonar(QString id, Module_Simulation *sim)
    : RobotModule(id)
{
    this->sim = sim;
    setDefaultValue("serialPort", "COM1");

    setDefaultValue("range", 50);
    setDefaultValue("gain", 20);
    setDefaultValue("trainAngle", 70);
    setDefaultValue("sectorWidth", 120);
    setDefaultValue("stepSize", 1);
    setDefaultValue("pulseLength", 127);
    setDefaultValue("dataPoints", 25);
    setDefaultValue("switchDelay", 0);
    setDefaultValue("frequency", 0);
    setDefaultValue("readFromFile", false);
    setDefaultValue("recorderFilename", "output.txt");
    setDefaultValue("fileReaderDelay", 100);

    qRegisterMetaType<SonarReturnData>("SonarReturnData");
    recorder = NULL;
    source = NULL;
    timer.moveToThread(this);
}

Module_ScanningSonar::~Module_ScanningSonar()
{
}

void Module_ScanningSonar::init()
{
    connect(&timer,SIGNAL(timeout()), this, SLOT(doNextScan()));
    connect(this, SIGNAL(enabled(bool)), this, SLOT(gotEnabledChanged(bool)));

    /* connect simulation */
    connect(sim,SIGNAL(newSonarData(SonarReturnData)), this, SLOT(refreshSimData(SonarReturnData)));
    connect(this,SIGNAL(requestSonarSignal()),sim,SLOT(requestSonarSlot()));
    reset();

}

void Module_ScanningSonar::terminate()
{
    QTimer::singleShot(0,&timer,SLOT(stop()));
    logger->debug("Destroying sonar data source and recorder.");
    if (this->source != NULL) {
        delete this->source;
        source = NULL;
    }

    if (recorder != NULL) {
        recorder->stop();
        delete recorder;
        recorder = NULL;
    }
    RobotModule::terminate();
}

void Module_ScanningSonar::refreshSimData(SonarReturnData data)
{
    addData("currentHeading",data.getHeadPosition());
    addData("range",data.getRange());
    emit newSonarData(data);
    emit dataChanged(this);
}

bool Module_ScanningSonar::doNextScan()
{

    if(sim->isEnabled())
    {
        emit requestSonarSignal();
        return true;
    }
    else
    {

        if (!source || !source->isOpen())
            return false;

        const SonarReturnData d = source->getNextPacket();

        if (d.isPacketValid()) {
            setHealthToOk();
            addData("currentHeading", d.getHeadPosition());
            addData("range", d.getRange());
            emit newSonarData(d);
            emit dataChanged(this);
            return true;
        } else {
            setHealthToSick("Received bullshit. Dropping packet.");
            return false;
        }
    }
}

void Module_ScanningSonar::reset()
{
    RobotModule::reset();

    logger->debug("Destroying and sonar data source.");
    if (this->source != NULL) {
        this->source->stop();
        delete this->source;
        source = NULL;
    }

    if (recorder != NULL) {
        recorder->stop();
        delete recorder;
        recorder = NULL;
    }

    if (!isEnabled())
        return;

    if (getSettingsValue("enableRecording").toBool()) {
        if (getSettingsValue("formatCSV").toBool())
            recorder = new SonarDataCSVRecorder(*this);
        else
            recorder = new SonarData852Recorder(*this);

        recorder->start();
    }

    if (sim->isEnabled())
    {
        // XXX: this is inadequate for small sonar ranges
        timer.setInterval(100);
        timer.start();

    } else {

        if (getSettingsValue("readFromFile").toBool())
        {
            source = new SonarDataSourceFile(*this, getSettingsValue("filename").toString());
            if(!source->isOpen())
            {
                logger->error("source not opened");
                source = NULL;
            }
        }
        else {
            source = new SonarDataSourceSerial(*this);
        }

        logger->debug("Restarting reader.");
        if(source != NULL)
        {
           timer.setInterval(0); // timerSlot will block
           timer.start();
           setHealthToOk();
       }
        else
        {
            setHealthToSick("source is null");
        }
    }

}

QList<RobotModule*> Module_ScanningSonar::getDependencies()
{
    QList<RobotModule*> ret;
    ret.append(sim);
    return ret;
}

QWidget* Module_ScanningSonar::createView(QWidget* parent)
{
    return new ScanningSonarForm(this, parent);
}

void Module_ScanningSonar::gotEnabledChanged(bool state)
{
    if (!state)
        reset();
}
<commit_msg>ScanningSonar: Sleep if sonar is not working<commit_after>#include "module_scanningsonar.h"
#include <QtCore>
#include <stdio.h>
#include "scanningsonar_form.h"
#include "sonarreturndata.h"
#include "sonardatasourceserial.h"
#include "sonardatasourcefile.h"
#include "sonardatacsvrecorder.h"
#include "sonardata852recorder.h"
#include <Module_ThrusterControlLoop/module_thrustercontrolloop.h>
#include <Module_Simulation/module_simulation.h>
Module_ScanningSonar::Module_ScanningSonar(QString id, Module_Simulation *sim)
    : RobotModule(id)
{
    this->sim = sim;
    setDefaultValue("serialPort", "COM1");

    setDefaultValue("range", 50);
    setDefaultValue("gain", 20);
    setDefaultValue("trainAngle", 70);
    setDefaultValue("sectorWidth", 120);
    setDefaultValue("stepSize", 1);
    setDefaultValue("pulseLength", 127);
    setDefaultValue("dataPoints", 25);
    setDefaultValue("switchDelay", 0);
    setDefaultValue("frequency", 0);
    setDefaultValue("readFromFile", false);
    setDefaultValue("recorderFilename", "output.txt");
    setDefaultValue("fileReaderDelay", 100);

    qRegisterMetaType<SonarReturnData>("SonarReturnData");
    recorder = NULL;
    source = NULL;
    timer.moveToThread(this);
}

Module_ScanningSonar::~Module_ScanningSonar()
{
}

void Module_ScanningSonar::init()
{
    connect(&timer,SIGNAL(timeout()), this, SLOT(doNextScan()));
    connect(this, SIGNAL(enabled(bool)), this, SLOT(gotEnabledChanged(bool)));

    /* connect simulation */
    connect(sim,SIGNAL(newSonarData(SonarReturnData)), this, SLOT(refreshSimData(SonarReturnData)));
    connect(this,SIGNAL(requestSonarSignal()),sim,SLOT(requestSonarSlot()));
    reset();

}

void Module_ScanningSonar::terminate()
{
    QTimer::singleShot(0,&timer,SLOT(stop()));
    logger->debug("Destroying sonar data source and recorder.");
    if (this->source != NULL) {
        delete this->source;
        source = NULL;
    }

    if (recorder != NULL) {
        recorder->stop();
        delete recorder;
        recorder = NULL;
    }
    RobotModule::terminate();
}

void Module_ScanningSonar::refreshSimData(SonarReturnData data)
{
    addData("currentHeading",data.getHeadPosition());
    addData("range",data.getRange());
    emit newSonarData(data);
    emit dataChanged(this);
}

bool Module_ScanningSonar::doNextScan()
{

    if(sim->isEnabled())
    {
        emit requestSonarSignal();
        return true;
    }
    else
    {

        if (!source || !source->isOpen()) {
            msleep(100);
            return false;
        }

        const SonarReturnData d = source->getNextPacket();

        if (d.isPacketValid()) {
            setHealthToOk();
            addData("currentHeading", d.getHeadPosition());
            addData("range", d.getRange());
            emit newSonarData(d);
            emit dataChanged(this);
            return true;
        } else {
            setHealthToSick("Received bullshit. Dropping packet.");
            return false;
        }
    }
}

void Module_ScanningSonar::reset()
{
    RobotModule::reset();

    logger->debug("Destroying and sonar data source.");
    if (this->source != NULL) {
        this->source->stop();
        delete this->source;
        source = NULL;
    }

    if (recorder != NULL) {
        recorder->stop();
        delete recorder;
        recorder = NULL;
    }

    if (!isEnabled())
        return;

    if (getSettingsValue("enableRecording").toBool()) {
        if (getSettingsValue("formatCSV").toBool())
            recorder = new SonarDataCSVRecorder(*this);
        else
            recorder = new SonarData852Recorder(*this);

        recorder->start();
    }

    if (sim->isEnabled())
    {
        // XXX: this is inadequate for small sonar ranges
        timer.setInterval(100);
        timer.start();

    } else {

        if (getSettingsValue("readFromFile").toBool())
        {
            source = new SonarDataSourceFile(*this, getSettingsValue("filename").toString());
            if(!source->isOpen())
            {
                logger->error("source not opened");
                source = NULL;
            }
        }
        else {
            source = new SonarDataSourceSerial(*this);
        }

        logger->debug("Restarting reader.");
        if(source != NULL)
        {
           timer.setInterval(0); // timerSlot will block
           timer.start();
           setHealthToOk();
       }
        else
        {
            setHealthToSick("source is null");
        }
    }

}

QList<RobotModule*> Module_ScanningSonar::getDependencies()
{
    QList<RobotModule*> ret;
    ret.append(sim);
    return ret;
}

QWidget* Module_ScanningSonar::createView(QWidget* parent)
{
    return new ScanningSonarForm(this, parent);
}

void Module_ScanningSonar::gotEnabledChanged(bool state)
{
    if (!state)
        reset();
}
<|endoftext|>


<commit_before>#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>

#include <pcl/compression/octree_pointcloud_compression.h>

#include <stdio.h>
#include <sstream>
#include <stdlib.h>

using namespace std;
using namespace pcl;
using namespace pcl::octree;

#ifdef WIN32
# define sleep(x) Sleep((x)*1000)
#endif

class SimpleOpenNIViewer
{
public:
  SimpleOpenNIViewer () :
    viewer (" Point Cloud Compression Example")
  {
  }

  void
  cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud)
  {
    if (!viewer.wasStopped ())
    {
      // stringstream to store compressed point cloud
      std::stringstream compressedData;
      // output pointcloud
      PointCloud<PointXYZRGB>::Ptr cloudOut (new PointCloud<PointXYZRGB> ());

      // compress point cloud
      PointCloudEncoder->encodePointCloud (cloud, compressedData);

      // decompress point cloud
      PointCloudDecoder->decodePointCloud (compressedData, cloudOut);

      // show decompressed point cloud
      viewer.showCloud (cloudOut);
    }
  }

  void
  run ()
  {

    bool showStatistics = true;

    // for a full list of profiles see: /io/include/pcl/compression/compression_profiles.h
    compression_Profiles_e compressionProfile = pcl::octree::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;

    // instantiate point cloud compression for encoding and decoding
    PointCloudEncoder = new PointCloudCompression<PointXYZRGB> (compressionProfile, showStatistics);
    PointCloudDecoder = new PointCloudCompression<PointXYZRGB> ();

    // create a new grabber for OpenNI devices
    pcl::Grabber* interface = new pcl::OpenNIGrabber ();

    // make callback function from member function
    boost::function<void
    (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&)> f = boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);

    // connect callback function for desired signal. In this case its a point cloud with color values
    boost::signals2::connection c = interface->registerCallback (f);

    // start receiving point clouds
    interface->start ();

    while (!viewer.wasStopped ())
    {
      sleep (1);
    }

    interface->stop ();

    // delete point cloud compression instances
    delete (PointCloudEncoder);
    delete (PointCloudDecoder);

  }

  pcl::visualization::CloudViewer viewer;

  PointCloudCompression<PointXYZRGB>* PointCloudEncoder;
  PointCloudCompression<PointXYZRGB>* PointCloudDecoder;

};

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

  SimpleOpenNIViewer v;
  v.run ();

  return 0;
}
<commit_msg>fxining octree_pointcloud_compression.h include in tutorial<commit_after>#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>

#include <pcl/io/octree_pointcloud_compression.h>

#include <stdio.h>
#include <sstream>
#include <stdlib.h>

using namespace std;
using namespace pcl;
using namespace pcl::octree;

#ifdef WIN32
# define sleep(x) Sleep((x)*1000)
#endif

class SimpleOpenNIViewer
{
public:
  SimpleOpenNIViewer () :
    viewer (" Point Cloud Compression Example")
  {
  }

  void
  cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud)
  {
    if (!viewer.wasStopped ())
    {
      // stringstream to store compressed point cloud
      std::stringstream compressedData;
      // output pointcloud
      PointCloud<PointXYZRGB>::Ptr cloudOut (new PointCloud<PointXYZRGB> ());

      // compress point cloud
      PointCloudEncoder->encodePointCloud (cloud, compressedData);

      // decompress point cloud
      PointCloudDecoder->decodePointCloud (compressedData, cloudOut);

      // show decompressed point cloud
      viewer.showCloud (cloudOut);
    }
  }

  void
  run ()
  {

    bool showStatistics = true;

    // for a full list of profiles see: /io/include/pcl/compression/compression_profiles.h
    compression_Profiles_e compressionProfile = pcl::octree::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;

    // instantiate point cloud compression for encoding and decoding
    PointCloudEncoder = new PointCloudCompression<PointXYZRGB> (compressionProfile, showStatistics);
    PointCloudDecoder = new PointCloudCompression<PointXYZRGB> ();

    // create a new grabber for OpenNI devices
    pcl::Grabber* interface = new pcl::OpenNIGrabber ();

    // make callback function from member function
    boost::function<void
    (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&)> f = boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);

    // connect callback function for desired signal. In this case its a point cloud with color values
    boost::signals2::connection c = interface->registerCallback (f);

    // start receiving point clouds
    interface->start ();

    while (!viewer.wasStopped ())
    {
      sleep (1);
    }

    interface->stop ();

    // delete point cloud compression instances
    delete (PointCloudEncoder);
    delete (PointCloudDecoder);

  }

  pcl::visualization::CloudViewer viewer;

  PointCloudCompression<PointXYZRGB>* PointCloudEncoder;
  PointCloudCompression<PointXYZRGB>* PointCloudDecoder;

};

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

  SimpleOpenNIViewer v;
  v.run ();

  return 0;
}
<|endoftext|>


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

#include "clotho/data_spaces/analysis/allele_frequency/frequency_evaluator_def.hpp"
#include "clotho/data_spaces/association_matrix/column_aligned_association_matrix.hpp"
#include <boost/dynamic_bitset.hpp>
#include "clotho/utility/debruijn_bit_walker.hpp"

namespace clotho {
namespace genetics {

template < class BlockType >
struct frequency_evaluator< association_matrix< BlockType, column_aligned > > {
    typedef association_matrix< BlockType, column_aligned > space_type;
    typedef typename space_type::block_type                 block_type;

    typedef typename space_type::bit_helper_type                        bit_helper_type;
    typedef typename clotho::utility::debruijn_bit_walker< block_type > bit_walker_type;

    typedef size_t *                                        result_type;

    void operator()( space_type & ss, boost::dynamic_bitset<> & indices, result_type * res ) {
        size_t M = ss.column_count();
        size_t N = ss.block_column_count();

        size_t buffer[ bit_helper_type::BITS_PER_BLOCK ];
        memset( buffer, 0, bit_helper_type::BITS_PER_BLOCK * sizeof( size_t ) );

        typedef typename space_type::raw_block_pointer iterator;

        size_t i = 0, j = M;
        while( j ) {
            iterator first = ss.begin_block_row( i );
            iterator last = ss.end_block_row( i );

            size_t k = 0;
            while( first != last ) {
                block_type b = *first++;
                if( indices.test(k++) ) {
                    while( b ) {
                        unsigned int b_idx = bit_walker_type::unset_next_index( b );
                        buffer[ b_idx ] += 1;
                    }
                }
            }

            size_t l = (( j < bit_helper_type::BITS_PER_BLOCK) ? j : bit_helper_type::BITS_PER_BLOCK);

            memcpy( res + i * bit_helper_type::BITS_PER_BLOCK, buffer, sizeof( size_t ) * l );
            memset( buffer, 0, bit_helper_type::BITS_PER_BLOCK * sizeof( size_t ) );

            j -= l;
            ++i;
        }
    }
};

}   // namespace genetics
}   // namespace clotho

#endif  // CLOTHO_COLUMN_ALIGNED_FREQUENCY_EVALUATOR_HPP_
<commit_msg>Cleaned up compiler warning<commit_after>//   Copyright 2015 Patrick Putnam
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
#ifndef CLOTHO_COLUMN_ALIGNED_FREQUENCY_EVALUATOR_HPP_
#define CLOTHO_COLUMN_ALIGNED_FREQUENCY_EVALUATOR_HPP_

#include "clotho/data_spaces/analysis/allele_frequency/frequency_evaluator_def.hpp"
#include "clotho/data_spaces/association_matrix/column_aligned_association_matrix.hpp"
#include <boost/dynamic_bitset.hpp>
#include "clotho/utility/debruijn_bit_walker.hpp"

namespace clotho {
namespace genetics {

template < class BlockType >
struct frequency_evaluator< association_matrix< BlockType, column_aligned > > {
    typedef association_matrix< BlockType, column_aligned > space_type;
    typedef typename space_type::block_type                 block_type;

    typedef typename space_type::bit_helper_type                        bit_helper_type;
    typedef typename clotho::utility::debruijn_bit_walker< block_type > bit_walker_type;

    typedef size_t *                                        result_type;

    void operator()( space_type & ss, boost::dynamic_bitset<> & indices, result_type res ) {
        size_t M = ss.column_count();
//        size_t N = ss.block_column_count();

        size_t buffer[ bit_helper_type::BITS_PER_BLOCK ];
        memset( buffer, 0, bit_helper_type::BITS_PER_BLOCK * sizeof( size_t ) );

        typedef typename space_type::raw_block_pointer iterator;

        size_t i = 0, j = M;
        while( j ) {
            iterator first = ss.begin_block_row( i );
            iterator last = ss.end_block_row( i );

            size_t k = 0;
            while( first != last ) {
                block_type b = *first++;
                if( indices.test(k++) ) {
                    while( b ) {
                        unsigned int b_idx = bit_walker_type::unset_next_index( b );
                        buffer[ b_idx ] += 1;
                    }
                }
            }

            size_t l = (( j < bit_helper_type::BITS_PER_BLOCK) ? j : bit_helper_type::BITS_PER_BLOCK);

            memcpy( res + i * bit_helper_type::BITS_PER_BLOCK, buffer, sizeof( size_t ) * l );
            memset( buffer, 0, bit_helper_type::BITS_PER_BLOCK * sizeof( size_t ) );

            j -= l;
            ++i;
        }
    }
};

}   // namespace genetics
}   // namespace clotho

#endif  // CLOTHO_COLUMN_ALIGNED_FREQUENCY_EVALUATOR_HPP_
<|endoftext|>


<commit_before>#ifndef CPP_REF_HPP
#define CPP_REF_HPP

#include <stdexcept>
#include <utility>
#include <cassert>

struct ref_counted {
  virtual ~ref_counted() { }
  std::size_t rc = 0;

  friend void incref(ref_counted* self) { self->rc++; }
  friend void decref(ref_counted* self) { if(--self->rc == 0) delete self; }
};

template<class T> class ref;

class ref_any {
  using ptr_type = ref_counted*;
  ptr_type ptr;
public:
  ref_any() : ptr(nullptr) { }

  ref_any(ptr_type ptr) : ptr(ptr) {
    if(ptr) incref(ptr);
  }

  ptr_type get() const { return ptr; }

  ~ref_any() { if(ptr) decref(ptr); }

  ref_any(const ref_any& other) noexcept : ptr(other.ptr) {
    if(ptr) incref(ptr);
  }

  ref_any(ref_any&& other) noexcept : ptr(std::move(other.ptr)) {
    other.ptr = nullptr;
  }

  ref_any& operator=(const ref_any& other) noexcept {
    if(this == &other) return *this;

    if(ptr) decref(ptr);
    ptr = other.ptr;
    if(ptr) incref(ptr);

    return *this;
  }

  ref_any& operator=(ref_any&& other) noexcept{
    if(this == &other) return *this;

    if(ptr) decref(ptr);
    ptr = std::move(other.ptr);
    other.ptr = nullptr;

    return *this;
  }

  explicit operator bool() const { return ptr; }
  bool operator==(const ref_any& other) const { return ptr == other.ptr; }
  bool operator!=(const ref_any& other) const { return ptr != other.ptr; }
  bool operator<(const ref_any& other) const { return ptr < other.ptr; }

  std::size_t rc() const {
    if(ptr) return ptr->rc;
    throw std::invalid_argument("null pointer");
  }

  // type recovery
  template<class T> ref<T> cast() const;
};

template<class T>
struct control_block : ref_counted, T {
  template<class ... Args>
  control_block(Args&& ... args) : T(std::forward<Args>(args)...) { }
};

template<class T>
class ref {
  ref_any impl;
protected:
  ref(control_block<T>* block) : impl(block) { }
  friend ref ref_any::cast<T>() const;
public:

  template<class ... Args>
  static ref make(Args&& ... args) {
    return new control_block<T>(std::forward<Args>(args)...);
  }

  T* get() const {
    if(impl) return static_cast< control_block<T>* >(impl.get());
    return nullptr;
  }

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

  ref() = default;
  ref(const ref& ) = default;
  ref(ref&& ) = default;

  ref& operator=(const ref& ) = default;
  ref& operator=(ref&& ) = default;

  // type erasure
  ref_any any() const { return impl; }

  explicit operator bool() const { return bool(impl); }
  bool operator==(const ref& other) const { return impl == other.impl; }
  bool operator!=(const ref& other) const { return impl != other.impl; }
  bool operator<(const ref& other) const { return impl < other.impl; }

};

template<class T>
ref<T> ref_any::cast() const {
  return static_cast<control_block<T>*>(ptr);
}

template<class T, class ... Args>
static ref<T> make_ref(Args&& ... args) { return ref<T>::make(std::forward<Args>(args)...); }

#endif
<commit_msg>friend class lol<commit_after>#ifndef CPP_REF_HPP
#define CPP_REF_HPP

#include <stdexcept>
#include <utility>
#include <cassert>

struct ref_counted {
  virtual ~ref_counted() { }
  std::size_t rc = 0;

  friend void incref(ref_counted* self) { self->rc++; }
  friend void decref(ref_counted* self) { if(--self->rc == 0) delete self; }
};

template<class T> class ref;

class ref_any {
  using ptr_type = ref_counted*;
  ptr_type ptr;
public:
  ref_any() : ptr(nullptr) { }

  ref_any(ptr_type ptr) : ptr(ptr) {
    if(ptr) incref(ptr);
  }

  ptr_type get() const { return ptr; }

  ~ref_any() { if(ptr) decref(ptr); }

  ref_any(const ref_any& other) noexcept : ptr(other.ptr) {
    if(ptr) incref(ptr);
  }

  ref_any(ref_any&& other) noexcept : ptr(std::move(other.ptr)) {
    other.ptr = nullptr;
  }

  ref_any& operator=(const ref_any& other) noexcept {
    if(this == &other) return *this;

    if(ptr) decref(ptr);
    ptr = other.ptr;
    if(ptr) incref(ptr);

    return *this;
  }

  ref_any& operator=(ref_any&& other) noexcept{
    if(this == &other) return *this;

    if(ptr) decref(ptr);
    ptr = std::move(other.ptr);
    other.ptr = nullptr;

    return *this;
  }

  explicit operator bool() const { return ptr; }
  bool operator==(const ref_any& other) const { return ptr == other.ptr; }
  bool operator!=(const ref_any& other) const { return ptr != other.ptr; }
  bool operator<(const ref_any& other) const { return ptr < other.ptr; }

  std::size_t rc() const {
    if(ptr) return ptr->rc;
    throw std::invalid_argument("null pointer");
  }

  // type recovery
  template<class T> ref<T> cast() const;
};

template<class T>
struct control_block : ref_counted, T {
  template<class ... Args>
  control_block(Args&& ... args) : T(std::forward<Args>(args)...) { }
};

template<class T>
class ref {
  ref_any impl;
protected:
  ref(control_block<T>* block) : impl(block) { }
  friend class ref_any;
public:

  template<class ... Args>
  static ref make(Args&& ... args) {
    return new control_block<T>(std::forward<Args>(args)...);
  }

  T* get() const {
    if(impl) return static_cast< control_block<T>* >(impl.get());
    return nullptr;
  }

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

  ref() = default;
  ref(const ref& ) = default;
  ref(ref&& ) = default;

  ref& operator=(const ref& ) = default;
  ref& operator=(ref&& ) = default;

  // type erasure
  ref_any any() const { return impl; }

  explicit operator bool() const { return bool(impl); }
  bool operator==(const ref& other) const { return impl == other.impl; }
  bool operator!=(const ref& other) const { return impl != other.impl; }
  bool operator<(const ref& other) const { return impl < other.impl; }

};

template<class T>
ref<T> ref_any::cast() const {
  return static_cast<control_block<T>*>(ptr);
}

template<class T, class ... Args>
static ref<T> make_ref(Args&& ... args) { return ref<T>::make(std::forward<Args>(args)...); }

#endif
<|endoftext|>