<commit_before>#include "digitanksentity.h"

#include <GL/glew.h>

#include <maths.h>
#include <mtrand.h>
#include <geometry.h>

#include <renderer/renderer.h>
#include <renderer/dissolver.h>

#include "digitanksgame.h"
#include "wreckage.h"

REGISTER_ENTITY(CDigitanksEntity);

NETVAR_TABLE_BEGIN(CDigitanksEntity);
NETVAR_TABLE_END();

SAVEDATA_TABLE_BEGIN(CDigitanksEntity);
	SAVEDATA_DEFINE(CSaveData::DATA_COPYVECTOR, CEntityHandle<class CSupplyLine>, m_ahSupplyLinesIntercepted);
SAVEDATA_TABLE_END();

void CDigitanksEntity::Spawn()
{
	BaseClass::Spawn();

	m_bTakeDamage = true;
	m_flTotalHealth = TotalHealth();
	m_flHealth = m_flTotalHealth;

	CalculateVisibility();
}

void CDigitanksEntity::Think()
{
	BaseClass::Think();

	if (!IsAlive() && GameServer()->GetGameTime() > m_flTimeKilled + 1.0f)
	{
		GameServer()->Delete(this);

		if (DigitanksGame()->GetTerrain()->IsPointOverHole(GetOrigin()))
		{
			CWreckage* pWreckage = CreateWreckage();

			if (pWreckage)
				pWreckage->FellIntoHole();
		}
		else if (DigitanksGame()->GetGameType() == GAMETYPE_ARTILLERY)
		{
			switch (RandomInt(0, 8))
			{
			case 0:
			case 6:
			case 7:
			case 8:
			default:
			{
				CreateWreckage();
				break;
			}

			case 1:
			{
				CProjectile* pProjectile = GameServer()->Create<CLargeShell>("CLargeShell");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}

			case 2:
			{
				CProjectile* pProjectile = GameServer()->Create<CAOEShell>("CAOEShell");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}

			case 3:
			{
				CProjectile* pProjectile = GameServer()->Create<CClusterBomb>("CClusterBomb");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}

			case 4:
			{
				CProjectile* pProjectile = GameServer()->Create<CEarthshaker>("CEarthshaker");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}

			case 5:
			{
				CProjectile* pProjectile = GameServer()->Create<CTractorBomb>("CTractorBomb");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}
			}
		}
		else
		{
			// Strategy mode
			CreateWreckage();
		}
	}
}

CWreckage* CDigitanksEntity::CreateWreckage()
{
	// Figure out what to do about structures later.
	if (dynamic_cast<CDigitank*>(this) == NULL)
		return NULL;

	CWreckage* pWreckage = GameServer()->Create<CWreckage>("CWreckage");
	pWreckage->SetOrigin(GetRenderOrigin());
	pWreckage->SetAngles(GetRenderAngles());
	pWreckage->SetModel(GetModel());
	pWreckage->SetGravity(Vector(0, DigitanksGame()->GetGravity(), 0));
	pWreckage->SetOldTeam(GetDigitanksTeam());

	pWreckage->CalculateVisibility();

	CDigitank* pTank = dynamic_cast<CDigitank*>(this);
	if (pTank)
		pWreckage->SetTurretModel(pTank->GetTurretModel());

	bool bColorSwap = GetTeam() && (dynamic_cast<CDigitank*>(this));
	if (bColorSwap)
		pWreckage->SetColorSwap(GetTeam()->GetColor());

	return pWreckage;
}

void CDigitanksEntity::StartTurn()
{
	float flHealth = m_flHealth;
	m_flHealth = Approach(m_flTotalHealth, m_flHealth, HealthRechargeRate());

	if (flHealth - m_flHealth < 0)
		DigitanksGame()->OnTakeDamage(this, NULL, NULL, flHealth - m_flHealth, true, false);

	m_ahSupplyLinesIntercepted.clear();
}

void CDigitanksEntity::EndTurn()
{
	InterceptSupplyLines();
}

void CDigitanksEntity::InterceptSupplyLines()
{
	// Haha... no.
	if (dynamic_cast<CSupplyLine*>(this))
		return;

	if (!GetTeam())
		return;

	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);
		if (!pEntity)
			continue;

		CSupplyLine* pSupplyLine = dynamic_cast<CSupplyLine*>(pEntity);
		if (!pSupplyLine)
			continue;

		if (pSupplyLine->GetTeam() == GetTeam())
			continue;

		if (!pSupplyLine->GetTeam())
			continue;

		if (!pSupplyLine->GetSupplier() || !pSupplyLine->GetEntity())
			continue;

		Vector vecEntity = GetOrigin();
		vecEntity.y = 0;

		Vector vecSupplier = pSupplyLine->GetSupplier()->GetOrigin();
		vecSupplier.y = 0;

		Vector vecUnit = pSupplyLine->GetEntity()->GetOrigin();
		vecUnit.y = 0;

		if (DistanceToLineSegment(vecEntity, vecSupplier, vecUnit) > GetBoundingRadius()+4)
			continue;

		bool bFound = false;
		for (size_t j = 0; j < m_ahSupplyLinesIntercepted.size(); j++)
		{
			if (pSupplyLine == m_ahSupplyLinesIntercepted[j])
			{
				bFound = true;
				break;
			}
		}

		if (!bFound)
		{
			pSupplyLine->Intercept(0.2f);
			m_ahSupplyLinesIntercepted.push_back(pSupplyLine);
		}
	}
}

CDigitanksTeam* CDigitanksEntity::GetDigitanksTeam() const
{
	return static_cast<CDigitanksTeam*>(BaseClass::GetTeam());
}

bool CDigitanksEntity::ShouldRender() const
{
	return GetVisibility(DigitanksGame()->GetCurrentLocalDigitanksTeam()) > 0;
}

void CDigitanksEntity::RenderVisibleArea()
{
	if (VisibleRange() == 0)
		return;

	CRenderingContext c(GameServer()->GetRenderer());
	c.Translate(GetOrigin());
	c.Scale(VisibleRange(), VisibleRange(), VisibleRange());
	c.RenderSphere();
}

float CDigitanksEntity::GetVisibility(CDigitanksTeam* pTeam) const
{
	CDigitanksGame* pGame = DigitanksGame();

	float flConceal = 0.0f;
	if (GetsConcealmentBonus())
	{
		if (pGame->GetTerrain()->GetBit(CTerrain::WorldToArraySpace(m_vecOrigin.Get().x), CTerrain::WorldToArraySpace(m_vecOrigin.Get().z), TB_TREE))
			flConceal = 0.7f;
	}

	float flCloak = GetCloakConcealment();
	if (flCloak > flConceal)
		flConceal = flCloak;

	if (HasLostConcealment())
		flConceal = 0;

	if (!pGame->ShouldRenderFogOfWar())
		return 1 - flConceal;

	if (!pTeam)
		return 0;

	if (pTeam == GetDigitanksTeam())
		return 1 - flConceal/2;

	float flVisibility = pTeam->GetEntityVisibility(GetHandle()) - flConceal;

	if (flVisibility < 0)
		return 0;

	return flVisibility;
}

void CDigitanksEntity::CalculateVisibility()
{
	for (size_t i = 0; i < DigitanksGame()->GetNumTeams(); i++)
		DigitanksGame()->GetDigitanksTeam(i)->CalculateEntityVisibility(this);
}

float CDigitanksEntity::GetVisibility() const
{
	CDigitanksGame* pGame = DigitanksGame();
	if (!pGame)
		return 0;

	return GetVisibility(pGame->GetCurrentLocalDigitanksTeam());
}

float CDigitanksEntity::VisibleRange() const
{
	// Don't use GetOrigin because CDigitank::GetOrigin() can be expensive and we really don't want what it does.
	if (TreesReduceVisibility() && DigitanksGame()->GetTerrain()->IsPointInTrees(m_vecOrigin))
		return BaseVisibleRange()/2;

	return BaseVisibleRange();
}

void CDigitanksEntity::RenderAvailableArea(int iArea)
{
	float flAvailableArea = AvailableArea(iArea);

	if (flAvailableArea == 0)
		return;

	float flScoutScale = 1.0f;

	// Scouts have very tall ones so we can see them underneath on the ground.
	if (GetUnitType() == UNIT_SCOUT)
		flScoutScale = 10;

	if (dynamic_cast<CStructure*>(this) && DigitanksGame()->GetControlMode() == MODE_AIM)
		flScoutScale = 10;

	CRenderingContext c(GameServer()->GetRenderer());
	c.Translate(GetOrigin());
	c.Scale(flAvailableArea, flAvailableArea*flScoutScale, flAvailableArea);
	c.RenderSphere();
}

void CDigitanksEntity::ModifyContext(CRenderingContext* pContext, bool bTransparent)
{
	BaseClass::ModifyContext(pContext, bTransparent);

	CDigitanksTeam* pTeam = DigitanksGame()->GetCurrentTeam();

	float flVisibility = GetVisibility();
	if (flVisibility < 1)
	{
		pContext->SetAlpha(flVisibility);
		pContext->SetBlend(BLEND_ALPHA);
	}
}
<commit_msg>Don't create wreckage on the client.<commit_after>#include "digitanksentity.h"

#include <GL/glew.h>

#include <maths.h>
#include <mtrand.h>
#include <geometry.h>

#include <renderer/renderer.h>
#include <renderer/dissolver.h>

#include "digitanksgame.h"
#include "wreckage.h"

REGISTER_ENTITY(CDigitanksEntity);

NETVAR_TABLE_BEGIN(CDigitanksEntity);
NETVAR_TABLE_END();

SAVEDATA_TABLE_BEGIN(CDigitanksEntity);
	SAVEDATA_DEFINE(CSaveData::DATA_COPYVECTOR, CEntityHandle<class CSupplyLine>, m_ahSupplyLinesIntercepted);
SAVEDATA_TABLE_END();

void CDigitanksEntity::Spawn()
{
	BaseClass::Spawn();

	m_bTakeDamage = true;
	m_flTotalHealth = TotalHealth();
	m_flHealth = m_flTotalHealth;

	CalculateVisibility();
}

void CDigitanksEntity::Think()
{
	BaseClass::Think();

	if (CNetwork::IsHost() && !IsAlive() && GameServer()->GetGameTime() > m_flTimeKilled + 1.0f)
	{
		GameServer()->Delete(this);

		if (DigitanksGame()->GetTerrain()->IsPointOverHole(GetOrigin()))
		{
			CWreckage* pWreckage = CreateWreckage();

			if (pWreckage)
				pWreckage->FellIntoHole();
		}
		else if (DigitanksGame()->GetGameType() == GAMETYPE_ARTILLERY)
		{
			switch (RandomInt(0, 8))
			{
			case 0:
			case 6:
			case 7:
			case 8:
			default:
			{
				CreateWreckage();
				break;
			}

			case 1:
			{
				CProjectile* pProjectile = GameServer()->Create<CLargeShell>("CLargeShell");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}

			case 2:
			{
				CProjectile* pProjectile = GameServer()->Create<CAOEShell>("CAOEShell");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}

			case 3:
			{
				CProjectile* pProjectile = GameServer()->Create<CClusterBomb>("CClusterBomb");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}

			case 4:
			{
				CProjectile* pProjectile = GameServer()->Create<CEarthshaker>("CEarthshaker");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}

			case 5:
			{
				CProjectile* pProjectile = GameServer()->Create<CTractorBomb>("CTractorBomb");
				pProjectile->SetOwner(NULL);
				pProjectile->SetOrigin(GetOrigin());
				pProjectile->Explode();
				break;
			}
			}
		}
		else
		{
			// Strategy mode
			CreateWreckage();
		}
	}
}

CWreckage* CDigitanksEntity::CreateWreckage()
{
	// Figure out what to do about structures later.
	if (dynamic_cast<CDigitank*>(this) == NULL)
		return NULL;

	CWreckage* pWreckage = GameServer()->Create<CWreckage>("CWreckage");
	pWreckage->SetOrigin(GetRenderOrigin());
	pWreckage->SetAngles(GetRenderAngles());
	pWreckage->SetModel(GetModel());
	pWreckage->SetGravity(Vector(0, DigitanksGame()->GetGravity(), 0));
	pWreckage->SetOldTeam(GetDigitanksTeam());

	pWreckage->CalculateVisibility();

	CDigitank* pTank = dynamic_cast<CDigitank*>(this);
	if (pTank)
		pWreckage->SetTurretModel(pTank->GetTurretModel());

	bool bColorSwap = GetTeam() && (dynamic_cast<CDigitank*>(this));
	if (bColorSwap)
		pWreckage->SetColorSwap(GetTeam()->GetColor());

	return pWreckage;
}

void CDigitanksEntity::StartTurn()
{
	float flHealth = m_flHealth;
	m_flHealth = Approach(m_flTotalHealth, m_flHealth, HealthRechargeRate());

	if (flHealth - m_flHealth < 0)
		DigitanksGame()->OnTakeDamage(this, NULL, NULL, flHealth - m_flHealth, true, false);

	m_ahSupplyLinesIntercepted.clear();
}

void CDigitanksEntity::EndTurn()
{
	InterceptSupplyLines();
}

void CDigitanksEntity::InterceptSupplyLines()
{
	// Haha... no.
	if (dynamic_cast<CSupplyLine*>(this))
		return;

	if (!GetTeam())
		return;

	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);
		if (!pEntity)
			continue;

		CSupplyLine* pSupplyLine = dynamic_cast<CSupplyLine*>(pEntity);
		if (!pSupplyLine)
			continue;

		if (pSupplyLine->GetTeam() == GetTeam())
			continue;

		if (!pSupplyLine->GetTeam())
			continue;

		if (!pSupplyLine->GetSupplier() || !pSupplyLine->GetEntity())
			continue;

		Vector vecEntity = GetOrigin();
		vecEntity.y = 0;

		Vector vecSupplier = pSupplyLine->GetSupplier()->GetOrigin();
		vecSupplier.y = 0;

		Vector vecUnit = pSupplyLine->GetEntity()->GetOrigin();
		vecUnit.y = 0;

		if (DistanceToLineSegment(vecEntity, vecSupplier, vecUnit) > GetBoundingRadius()+4)
			continue;

		bool bFound = false;
		for (size_t j = 0; j < m_ahSupplyLinesIntercepted.size(); j++)
		{
			if (pSupplyLine == m_ahSupplyLinesIntercepted[j])
			{
				bFound = true;
				break;
			}
		}

		if (!bFound)
		{
			pSupplyLine->Intercept(0.2f);
			m_ahSupplyLinesIntercepted.push_back(pSupplyLine);
		}
	}
}

CDigitanksTeam* CDigitanksEntity::GetDigitanksTeam() const
{
	return static_cast<CDigitanksTeam*>(BaseClass::GetTeam());
}

bool CDigitanksEntity::ShouldRender() const
{
	return GetVisibility(DigitanksGame()->GetCurrentLocalDigitanksTeam()) > 0;
}

void CDigitanksEntity::RenderVisibleArea()
{
	if (VisibleRange() == 0)
		return;

	CRenderingContext c(GameServer()->GetRenderer());
	c.Translate(GetOrigin());
	c.Scale(VisibleRange(), VisibleRange(), VisibleRange());
	c.RenderSphere();
}

float CDigitanksEntity::GetVisibility(CDigitanksTeam* pTeam) const
{
	CDigitanksGame* pGame = DigitanksGame();

	CTerrain* pTerrain = pGame->GetTerrain();

	float flConceal = 0.0f;
	if (GetsConcealmentBonus() && pTerrain)
	{
		if (pTerrain->GetBit(CTerrain::WorldToArraySpace(m_vecOrigin.Get().x), CTerrain::WorldToArraySpace(m_vecOrigin.Get().z), TB_TREE))
			flConceal = 0.7f;
	}

	float flCloak = GetCloakConcealment();
	if (flCloak > flConceal)
		flConceal = flCloak;

	if (HasLostConcealment())
		flConceal = 0;

	if (!pGame->ShouldRenderFogOfWar())
		return 1 - flConceal;

	if (!pTeam)
		return 0;

	if (pTeam == GetDigitanksTeam())
		return 1 - flConceal/2;

	float flVisibility = pTeam->GetEntityVisibility(GetHandle()) - flConceal;

	if (flVisibility < 0)
		return 0;

	return flVisibility;
}

void CDigitanksEntity::CalculateVisibility()
{
	for (size_t i = 0; i < DigitanksGame()->GetNumTeams(); i++)
		DigitanksGame()->GetDigitanksTeam(i)->CalculateEntityVisibility(this);
}

float CDigitanksEntity::GetVisibility() const
{
	CDigitanksGame* pGame = DigitanksGame();
	if (!pGame)
		return 0;

	return GetVisibility(pGame->GetCurrentLocalDigitanksTeam());
}

float CDigitanksEntity::VisibleRange() const
{
	// Don't use GetOrigin because CDigitank::GetOrigin() can be expensive and we really don't want what it does.
	if (TreesReduceVisibility() && DigitanksGame()->GetTerrain()->IsPointInTrees(m_vecOrigin))
		return BaseVisibleRange()/2;

	return BaseVisibleRange();
}

void CDigitanksEntity::RenderAvailableArea(int iArea)
{
	float flAvailableArea = AvailableArea(iArea);

	if (flAvailableArea == 0)
		return;

	float flScoutScale = 1.0f;

	// Scouts have very tall ones so we can see them underneath on the ground.
	if (GetUnitType() == UNIT_SCOUT)
		flScoutScale = 10;

	if (dynamic_cast<CStructure*>(this) && DigitanksGame()->GetControlMode() == MODE_AIM)
		flScoutScale = 10;

	CRenderingContext c(GameServer()->GetRenderer());
	c.Translate(GetOrigin());
	c.Scale(flAvailableArea, flAvailableArea*flScoutScale, flAvailableArea);
	c.RenderSphere();
}

void CDigitanksEntity::ModifyContext(CRenderingContext* pContext, bool bTransparent)
{
	BaseClass::ModifyContext(pContext, bTransparent);

	CDigitanksTeam* pTeam = DigitanksGame()->GetCurrentTeam();

	float flVisibility = GetVisibility();
	if (flVisibility < 1)
	{
		pContext->SetAlpha(flVisibility);
		pContext->SetBlend(BLEND_ALPHA);
	}
}
<|endoftext|>


<commit_before>#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include "StateSpace.h"
#include "PriorityQueue.h"
#include "State.h"
#include "encoder.h"
#include "CreateModule.h"

/**
 * @brief Gives a std::string representation of a primitive type
 *
 * @param x Primitive type such as int, double, long
 * @return std::string conversion of param x
 */
template<typename T> std::string to_string(T x) {
	return static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str();
}

//function to calculate a temperature for the select action function as a function of time
double temperature();

//function to select next action
int selectAction(PriorityQueue<int,double>& a_queue);

//function to update a q value
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma);

int main()
{
	// STUFF WE DONT UNDERSTAND, AND DONT NEED TO
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	// Libraries to load
	std::string bodyLibName = "bodyinfo";
	std::string movementLibName = "movementtools";

	// Name of camera module in library
	std::string bodyModuleName = "BodyInfo";
	std::string movementModuleName = "MovementTools";

	// Set broker name, ip and port, finding first available port from 54000
	const std::string brokerName = "MotionTimingBroker";
	int brokerPort = qi::os::findAvailablePort(54000);
	const std::string brokerIp = "0.0.0.0";

	// Default parent port and ip
	int pport = 9559;
	std::string pip = "127.0.0.1";

	// Need this for SOAP serialisation of floats to work
	setlocale(LC_NUMERIC, "C");

	// Create a broker
	boost::shared_ptr<AL::ALBroker> broker;
	try
	{
		broker = AL::ALBroker::createBroker(
				brokerName,
				brokerIp,
				brokerPort,
				pip,
				pport,
				0);
	}
	// Throw error and quit if a broker could not be created
	catch(...)
	{
		std::cerr << "Failed to connect broker to: "
			  << pip
			  << ":"
			  << pport
			  << std::endl;
		AL::ALBrokerManager::getInstance()->killAllBroker();
		AL::ALBrokerManager::kill();

		return 1;
	}

	// Add the broker to NAOqi
	AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
	AL::ALBrokerManager::getInstance()->addBroker(broker);

	CreateModule(movementLibName, movementModuleName, broker, false, true);
	CreateModule(bodyLibName, bodyModuleName, broker, false, true);

	AL::ALProxy bodyInfoProxy(bodyModuleName, pip, pport);
	AL::ALProxy movementToolsProxy(movementModuleName, pip, pport);
	AL::ALMotionProxy motion(pip, pport);
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	//END OF STUFF WE DONT UNDERSTAND, BREATHE NOW

	//learning factor
	const double alpha=0.5;
	//discount factor
	const double gamma=0.5;

	//seed rng
	std::srand(std::time(NULL));

	int action_forwards = FORWARD;
	int action_backwards = BACKWARD;
	int chosen_action = action_forwards;

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<int,double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(action_forwards,0);
	initiator_queue.enqueueWithPriority(action_backwards,0);

	//create encoder
	Encoder encoder;
	encoder.Calibrate();

	//create the state space
	StateSpace space(100,50,initiator_queue);

	//state objects
	State current_state(0,0,FORWARD);
	State old_state(0,0,FORWARD);

	while(true)
	{
		current_state.theta= M_PI * (encoder.GetAngle())/180;
		current_state.theta_dot=(current_state.theta - old_state.theta)/700; //Needs actual time
		current_state.robot_state=static_cast<ROBOT_STATE>(chosen_action);

		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		old_state=current_state;

		chosen_action=selectAction(space[current_state]);

		(chosen_action)?movementToolsProxy.callVoid("swingForwards"):movementToolsProxy.callVoid("swingBackwards");
	}

	return 1;
}

/**
 * @brief Analog to temperature variable in Boltzmann Distribution.
 *
 * @return current system time in milliseconds
 */
double temperature()
{
	return static_cast<double>(std::time(NULL));
}

/**
 * @brief Selects an action to perform based on probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @return integer corresponding to chosen action
 */
int selectAction(const PriorityQueue<int,double>& a_queue)
{
	typedef PriorityQueue<int,double> PQ;
	typedef std::vector< std::pair<int, double> > Vec_Pair;
	typedef std::pair<int, double> Pair;

	double sum= 0;
	size_t i = 0;

	size_t size = a_queue.getSize();
	Vec_Pair action_vec(size);

	//Calculate partition function by iterating over action-values
	for(PQ::const_iterator iter = a_queue.begin(),end=a_queue.end(); iter < end; ++iter)
	{
		sum += std::exp((iter->second)/temperature());
	}
	//Calculate boltzmann factors for action-values
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
	    it->first = a_queue[i].first;
	    it->second = std::exp(a_queue[i].second /temperature()) / sum;
	    ++i;
	}

	//calculate cumulative probability distribution
	for(Vec_Pair::iterator it1 = action_vec.begin()++,it2 = action_vec.begin(),end=action_vec.end(); it1 < end; ++it1,++it2)
	{
	    it1->second += it2->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand())/ RAND_MAX;

	//select action based on probability
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
		//if RN falls within cumulative probability bin return the corresponding action
		if(rand_num < it->second)return it->first;
	}

	return -1; //note that this line should never be reached
}

/**
 * @brief Updates the utility (Q-value) of the system
 *
 * @param space Reference to StateSpace object
 * @param new_state Reference to State instance giving the new system state
 * @param old_state Reference to State instance giving the old system state
 * @param alpha Learning rate of temporal difference learning algorithm
 * @param gamma Discount factor applied to q-learning equation
 */
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma)
{
    //oldQ value reference
    double oldQ = space[old_state].search(action).second;

    //reward given to current state
    double R = new_state.getReward();

    //optimal Q value for new state i.e. first element
    double maxQ = space[new_state].peekFront().second;

    //new Q value determined by Q learning algorithm
    double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

    // change priority of action to new Q value
    space[old_state].changePriority(action, newQ);
}

/**
 * @brief Selects an action to perform based on probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @return integer corresponding to chosen action
 */
int selectActionAlt(const PriorityQueue<int, double>& a_queue) {

	// queue to store action values
	PriorityQueue<int, double> actionQueue(MAX);

	double sum = 0.0;

	// calculate partition function by iterating over action-values
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(), end = a_queue.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature());
	}

	// compute Boltzmann factors for action-values and enqueue to actionQueue
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(); iter < a_queue.end(); ++iter) {
		double priority = std::exp(iter.operator*().second / temperature()) / sum;
		actionQueue.enqueueWithPriority(iter.operator*().first, priority);
	}

	// calculate cumulative probability distribution
	for (PriorityQueue<int, double>::const_iterator it1 = actionQueue.begin()++, it2 = actionQueue.begin(), end = actionQueue.end(); it1 < end; ++it1, ++it2) {
		// change priority of it1->first data item in actionQueue to
		// sum of priorities of it1 and it2 items
		actionQueue.changePriority(it1->first, it1->second + it2->second);
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	// choose action based on random number relation to priorities within action queue
	for (PriorityQueue<int, double>::const_iterator iter = actionQueue.begin(), end = actionQueue.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached
}
<commit_msg>comments and casting<commit_after>#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include "StateSpace.h"
#include "PriorityQueue.h"
#include "State.h"
#include "encoder.h"
#include "CreateModule.h"

/**
 * @brief Gives a std::string representation of a primitive type
 *
 * @param x Primitive type such as int, double, long
 * @return std::string conversion of param x
 */
template<typename T> std::string to_string(T x) {
	return static_cast<std::ostringstream&>((std::ostringstream() << std::dec << x)).str();
}

//function to calculate a temperature for the select action function as a function of time
double temperature();

//function to select next action
int selectAction(PriorityQueue<int,double>& a_queue);

//function to update a q value
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma);

int main()
{
	// STUFF WE DONT UNDERSTAND, AND DONT NEED TO
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	// Libraries to load
	std::string bodyLibName = "bodyinfo";
	std::string movementLibName = "movementtools";

	// Name of camera module in library
	std::string bodyModuleName = "BodyInfo";
	std::string movementModuleName = "MovementTools";

	// Set broker name, ip and port, finding first available port from 54000
	const std::string brokerName = "MotionTimingBroker";
	int brokerPort = qi::os::findAvailablePort(54000);
	const std::string brokerIp = "0.0.0.0";

	// Default parent port and ip
	int pport = 9559;
	std::string pip = "127.0.0.1";

	// Need this for SOAP serialisation of floats to work
	setlocale(LC_NUMERIC, "C");

	// Create a broker
	boost::shared_ptr<AL::ALBroker> broker;
	try
	{
		broker = AL::ALBroker::createBroker(
				brokerName,
				brokerIp,
				brokerPort,
				pip,
				pport,
				0);
	}
	// Throw error and quit if a broker could not be created
	catch(...)
	{
		std::cerr << "Failed to connect broker to: "
			  << pip
			  << ":"
			  << pport
			  << std::endl;
		AL::ALBrokerManager::getInstance()->killAllBroker();
		AL::ALBrokerManager::kill();

		return 1;
	}

	// Add the broker to NAOqi
	AL::ALBrokerManager::setInstance(broker->fBrokerManager.lock());
	AL::ALBrokerManager::getInstance()->addBroker(broker);

	CreateModule(movementLibName, movementModuleName, broker, false, true);
	CreateModule(bodyLibName, bodyModuleName, broker, false, true);

	AL::ALProxy bodyInfoProxy(bodyModuleName, pip, pport);
	AL::ALProxy movementToolsProxy(movementModuleName, pip, pport);
	AL::ALMotionProxy motion(pip, pport);
	//__________________________________________________________________________________________
	//__________________________________________________________________________________________
	//END OF STUFF WE DONT UNDERSTAND, BREATHE NOW

	//learning factor
	const double alpha=0.5;
	//discount factor
	const double gamma=0.5;

	//seed rng
	std::srand(static_cast<unsigned int>(std::time(NULL)));

	int action_forwards = FORWARD;
	int action_backwards = BACKWARD;
	int chosen_action = action_forwards;

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<int,double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(action_forwards,0);
	initiator_queue.enqueueWithPriority(action_backwards,0);

	//create encoder
	Encoder encoder;
	encoder.Calibrate();

	//create the state space
	StateSpace space(100,50,initiator_queue);

	//state objects
	State current_state(0,0,FORWARD);
	State old_state(0,0,FORWARD);

	while(true)
	{
		// set current state angle to angle received from encoder
		// and set current state velocity to difference in new and
		// old state angles over some time difference
		current_state.theta= M_PI * (encoder.GetAngle())/180;
		current_state.theta_dot=(current_state.theta - old_state.theta)/700; //Needs actual time
		current_state.robot_state=static_cast<ROBOT_STATE>(chosen_action);

		// call updateQ function with state space, old and current states
		// and learning rate, discount factor
		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		// set old_state to current_state
		old_state=current_state;

		// determine chosen_action for current state
		chosen_action=selectAction(space[current_state]);

		// depending upon chosen action, call robot movement tools proxy with either
		// swingForwards or swingBackwards commands.
		(chosen_action)?movementToolsProxy.callVoid("swingForwards"):movementToolsProxy.callVoid("swingBackwards");
	}

	return 1;
}

/**
 * @brief Analog to temperature variable in Boltzmann Distribution.
 *
 * @return current system time in milliseconds
 */
double temperature()
{
	return static_cast<double>(std::time(NULL));
}

/**
 * @brief Selects an action to perform based on probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @return integer corresponding to chosen action
 */
int selectAction(const PriorityQueue<int,double>& a_queue)
{
	typedef PriorityQueue<int,double> PQ;
	typedef std::vector< std::pair<int, double> > Vec_Pair;
	typedef std::pair<int, double> Pair;

	double sum= 0;
	size_t i = 0;

	size_t size = a_queue.getSize();
	Vec_Pair action_vec(size);

	//Calculate partition function by iterating over action-values
	for(PQ::const_iterator iter = a_queue.begin(),end=a_queue.end(); iter < end; ++iter)
	{
		sum += std::exp((iter->second)/temperature());
	}
	//Calculate boltzmann factors for action-values
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
	    it->first = a_queue[i].first;
	    it->second = std::exp(a_queue[i].second /temperature()) / sum;
	    ++i;
	}

	//calculate cumulative probability distribution
	for(Vec_Pair::iterator it1 = action_vec.begin()++,it2 = action_vec.begin(),end=action_vec.end(); it1 < end; ++it1,++it2)
	{
	    it1->second += it2->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand())/ RAND_MAX;

	//select action based on probability
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
		//if RN falls within cumulative probability bin return the corresponding action
		if(rand_num < it->second)return it->first;
	}

	return -1; //note that this line should never be reached
}

/**
 * @brief Updates the utility (Q-value) of the system
 *
 * @param space Reference to StateSpace object
 * @param new_state Reference to State instance giving the new system state
 * @param old_state Reference to State instance giving the old system state
 * @param alpha Learning rate of temporal difference learning algorithm
 * @param gamma Discount factor applied to q-learning equation
 */
void updateQ(StateSpace & space, int action, State & new_state, State & old_state, double alpha, double gamma)
{
    //oldQ value reference
    double oldQ = space[old_state].search(action).second;

    //reward given to current state
    double R = new_state.getReward();

    //optimal Q value for new state i.e. first element
    double maxQ = space[new_state].peekFront().second;

    //new Q value determined by Q learning algorithm
    double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

    // change priority of action to new Q value
    space[old_state].changePriority(action, newQ);
}

/**
 * @brief Selects an action to perform based on probabilities.
 *
 * @param a_queue A priority queue instance storing integral types with double type priorities,
 *		  represents the queue of possible actions with pre-initialised priority levels.
 * @return integer corresponding to chosen action
 */
int selectActionAlt(const PriorityQueue<int, double>& a_queue) {

	// queue to store action values
	PriorityQueue<int, double> actionQueue(MAX);

	double sum = 0.0;

	// calculate partition function by iterating over action-values
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(), end = a_queue.end(); iter < end; ++iter) {
		sum += std::exp((iter->second) / temperature());
	}

	// compute Boltzmann factors for action-values and enqueue to actionQueue
	for (PriorityQueue<int, double>::const_iterator iter = a_queue.begin(); iter < a_queue.end(); ++iter) {
		double priority = std::exp(iter.operator*().second / temperature()) / sum;
		actionQueue.enqueueWithPriority(iter.operator*().first, priority);
	}

	// calculate cumulative probability distribution
	for (PriorityQueue<int, double>::const_iterator it1 = actionQueue.begin()++, it2 = actionQueue.begin(), end = actionQueue.end(); it1 < end; ++it1, ++it2) {
		// change priority of it1->first data item in actionQueue to
		// sum of priorities of it1 and it2 items
		actionQueue.changePriority(it1->first, it1->second + it2->second);
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()) / RAND_MAX;

	// choose action based on random number relation to priorities within action queue
	for (PriorityQueue<int, double>::const_iterator iter = actionQueue.begin(), end = actionQueue.end(); iter < end; ++iter) {
		if (rand_num < iter->second)
			return iter->first;
	}

	return -1; //note that this line should never be reached
}
<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __INSTRUCTIONSCHEDULER_HPP
#define __INSTRUCTIONSCHEDULER_HPP

#include <map>
#include <set>
#include <deque>
#include <mutex>
#include <bh.h>
#include "ResourceManager.hpp"
#include "SourceKernelCall.hpp"

class InstructionScheduler
{
private:
    typedef std::map<bh_base*, BaseArray*> ArrayMap;
    typedef std::map<bh_opcode, bh_extmethod_impl> FunctionMap;

    typedef std::map<KernelID, Kernel> KernelMap;
    typedef std::pair<KernelID, SourceKernelCall> KernelCall;
    typedef std::deque<KernelCall> CallQueue;
    typedef std::map<size_t, BaseArray*> ViewList;

    std::mutex kernelMutex;
    std::map<size_t,size_t> knownKernelID;
    KernelMap kernelMap;
    CallQueue callQueue;

    ArrayMap arrayMap;
    FunctionMap functionMap;
    void compileAndRun(SourceKernelCall sourceKernel);
    void build(KernelID id, const std::string source);
    bh_error extmethod(bh_instruction* inst);
    bh_error call_child(const bh_ir_kernel& kernel);
    SourceKernelCall generateKernel(const bh_ir_kernel& kernel);
    std::string generateFunctionBody(const bh_ir_kernel& kernel, const size_t kdims,
                                     const std::vector<bh_index>& shape,
                                     const std::vector<std::vector<size_t> >& dimOrders,
                                     bool& float64, bool& complex, bool& integer, bool& random);
    void sync(const std::set<bh_base*>& arrays);
    void discard(const std::set<bh_base*>& arrays);
    void beginDim(std::stringstream& source,
                  std::stringstream& indentss,
                  std::vector<std::string>& beforesource,
                  const size_t dims);
    void endDim(std::stringstream& source,
                std::stringstream& indentss,
                std::vector<std::string>& beforesource,
                std::set<bh_view>& save,
                std::map<size_t,size_t>& incr_idx,
                const std::vector<bh_index>& shape,
                const size_t dims,
                const size_t kdims,
                const bh_index elements,
                const bh_ir_kernel& kernel);
    std::vector<std::vector<size_t> > genDimOrders(const std::map<bh_intp, bh_int64>& sweeps, const size_t ndim);
public:
    InstructionScheduler() {}
    void registerFunction(bh_opcode opcode, bh_extmethod_impl extmothod);
    bh_error schedule(const bh_ir* bhir);
};

#endif
<commit_msg>cleanup<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __INSTRUCTIONSCHEDULER_HPP
#define __INSTRUCTIONSCHEDULER_HPP

#include <map>
#include <set>
#include <deque>
#include <mutex>
#include <bh.h>
#include "ResourceManager.hpp"
#include "SourceKernelCall.hpp"

class InstructionScheduler
{
private:
    typedef std::map<bh_base*, BaseArray*> ArrayMap;
    typedef std::map<bh_opcode, bh_extmethod_impl> FunctionMap;

    typedef std::map<KernelID, Kernel> KernelMap;
    typedef std::pair<KernelID, SourceKernelCall> KernelCall;
    typedef std::deque<KernelCall> CallQueue;

    std::mutex kernelMutex;
    std::map<size_t,size_t> knownKernelID;
    KernelMap kernelMap;
    CallQueue callQueue;

    ArrayMap arrayMap;
    FunctionMap functionMap;
    void compileAndRun(SourceKernelCall sourceKernel);
    void build(KernelID id, const std::string source);
    bh_error extmethod(bh_instruction* inst);
    bh_error call_child(const bh_ir_kernel& kernel);
    SourceKernelCall generateKernel(const bh_ir_kernel& kernel);
    std::string generateFunctionBody(const bh_ir_kernel& kernel, const size_t kdims,
                                     const std::vector<bh_index>& shape,
                                     const std::vector<std::vector<size_t> >& dimOrders,
                                     bool& float64, bool& complex, bool& integer, bool& random);
    void sync(const std::set<bh_base*>& arrays);
    void discard(const std::set<bh_base*>& arrays);
    void beginDim(std::stringstream& source,
                  std::stringstream& indentss,
                  std::vector<std::string>& beforesource,
                  const size_t dims);
    void endDim(std::stringstream& source,
                std::stringstream& indentss,
                std::vector<std::string>& beforesource,
                std::set<bh_view>& save,
                std::map<size_t,size_t>& incr_idx,
                const std::vector<bh_index>& shape,
                const size_t dims,
                const size_t kdims,
                const bh_index elements,
                const bh_ir_kernel& kernel);
    std::vector<std::vector<size_t> > genDimOrders(const std::map<bh_intp, bh_int64>& sweeps, const size_t ndim);
public:
    InstructionScheduler() {}
    void registerFunction(bh_opcode opcode, bh_extmethod_impl extmothod);
    bh_error schedule(const bh_ir* bhir);
};

#endif
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#ifndef _Stroika_Foundation_IO_Network_InternetAddress_inl_
#define _Stroika_Foundation_IO_Network_InternetAddress_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include "../../Configuration/Endian.h"
#include "../../Memory/Bits.h"

namespace Stroika::Foundation::IO::Network {

    /*
     ********************************************************************************
     *********************** IO::Network::InternetAddress ***************************
     ********************************************************************************
     */
    constexpr InternetAddress::InternetAddress ()
        : fAddressFamily_{AddressFamily::UNKNOWN}
        , fV4_{}
    {
    }
    constexpr InternetAddress::InternetAddress (const in_addr_t& i)
        : fAddressFamily_ (AddressFamily::V4)
#if qPlatform_POSIX
        , fV4_
    {
        i
    }
#elif qPlatform_Windows
        , fV4_
    {
        in_addr
        {
            {
                static_cast<uint8_t> (Memory::BitSubstring (i, 0, 8)),
                    static_cast<uint8_t> (Memory::BitSubstring (i, 8, 16)),
                    static_cast<uint8_t> (Memory::BitSubstring (i, 16, 24)),
                    static_cast<uint8_t> (Memory::BitSubstring (i, 24, 32))
            }
        }
    }
#endif
    {
#if qPlatform_Windows
        Assert (fV4_.s_addr == i);
#endif
    }
    inline InternetAddress::InternetAddress (const in_addr_t& i, ByteOrder byteOrder)
        : fAddressFamily_ (AddressFamily::V4)
#if qPlatform_POSIX
        , fV4_
    {
        i
    }
#endif
    {
#if qPlatform_Windows
        fV4_.s_addr = i;
#endif
        if (byteOrder == ByteOrder::Host) {
            fV4_.s_addr = htonl (fV4_.s_addr); //NB no ':' cuz some systems use macro
        }
    }
    inline constexpr InternetAddress::InternetAddress (const in_addr& i)
        : fAddressFamily_{AddressFamily::V4}
        , fV4_{i}
    {
    }
    inline InternetAddress::InternetAddress (const in_addr& i, ByteOrder byteOrder)
        : fAddressFamily_{AddressFamily::V4}
        , fV4_{i}
    {
        if (byteOrder == ByteOrder::Host) {
            fV4_.s_addr = htonl (fV4_.s_addr); //NB no ':' cuz some systems use macro
        }
    }
    constexpr InternetAddress::InternetAddress (byte octet1, byte octet2, byte octet3, byte octet4)
        : InternetAddress (array<byte, 4>{octet1, octet2, octet3, octet4})
    {
    }
    constexpr InternetAddress::InternetAddress (uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4)
        : InternetAddress (array<uint8_t, 4>{octet1, octet2, octet3, octet4})
    {
    }
    constexpr InternetAddress::InternetAddress (tuple<uint8_t, uint8_t, uint8_t, uint8_t> octets)
        : InternetAddress (array<uint8_t, 4>{get<0> (octets), get<1> (octets), get<2> (octets), get<3> (octets)})
    {
    }
    constexpr InternetAddress::InternetAddress (array<uint8_t, 4> octets, AddressFamily af)
        : fAddressFamily_{af}
        , fArray_4_uint_{octets}
    {
    }
    constexpr InternetAddress::InternetAddress (array<byte, 4> octets, AddressFamily af)
        : fAddressFamily_{af}
        , fArray_4_byte_{octets}
    {
    }
    constexpr InternetAddress::InternetAddress (const in6_addr& i)
        : fAddressFamily_ (AddressFamily::V6)
        , fV6_{i}
    {
    }
    constexpr InternetAddress::InternetAddress (array<uint8_t, 16> octets, AddressFamily af)
        : fAddressFamily_{af}
        , fArray_16_uint_{octets}
    {
    }
    constexpr InternetAddress::InternetAddress (array<byte, 16> octets, AddressFamily af)
        : fAddressFamily_{af}
        , fArray_16_byte_{octets}
    {
    }
    template <typename ITERABLE_OF_UINT8OrByte, enable_if_t<Configuration::IsIterableOfT_v<ITERABLE_OF_UINT8OrByte, byte> or Configuration::IsIterableOfT_v<ITERABLE_OF_UINT8OrByte, uint8_t>>*>
    inline InternetAddress::InternetAddress (ITERABLE_OF_UINT8OrByte octets, AddressFamily af)
        : fAddressFamily_{af}
    {
        Require (af != AddressFamily::V4 or octets.size () == 4);
        Require (af != AddressFamily::V6 or octets.size () == 16);
        size_t i = 0;
        for (auto b : octets) {
            fArray_16_uint_[i++] = static_cast<uint8_t> (b);
        }
    }
    constexpr bool InternetAddress::empty () const
    {
        return fAddressFamily_ == AddressFamily::UNKNOWN;
    }
    inline void InternetAddress::clear ()
    {
        fAddressFamily_ = AddressFamily::UNKNOWN;
    }
    constexpr InternetAddress::AddressFamily InternetAddress::GetAddressFamily () const
    {
        return fAddressFamily_;
    }
    constexpr optional<size_t> InternetAddress::GetAddressSize () const
    {
        switch (GetAddressFamily ()) {
            case AddressFamily::V4:
                return 4;
            case AddressFamily::V6:
                return 16;
            default:
                return nullopt;
        }
    }
    template <>
    String InternetAddress::As<String> () const;
#if qPlatform_POSIX
    template <>
    inline in_addr_t InternetAddress::As<in_addr_t> () const
    {
        Require (fAddressFamily_ == AddressFamily::V4);
        return fV4_.s_addr;
    }
#endif
    template <>
    constexpr in_addr InternetAddress::As<in_addr> () const
    {
        Require (fAddressFamily_ == AddressFamily::V4);
        return fV4_;
    }
    template <>
    constexpr array<uint8_t, 4> InternetAddress::As<array<uint8_t, 4>> () const
    {
        Require (GetAddressSize () == 4u);
        return fArray_4_uint_;
    }
    template <>
    constexpr array<byte, 4> InternetAddress::As<array<byte, 4>> () const
    {
        Require (GetAddressSize () == 4u);
        return fArray_4_byte_;
    }
    template <>
    constexpr array<uint8_t, 16> InternetAddress::As<array<uint8_t, 16>> () const
    {
        Require (GetAddressSize () == 16u);
        return fArray_16_uint_;
    }
    template <>
    constexpr array<byte, 16> InternetAddress::As<array<byte, 16>> () const
    {
        Require (GetAddressSize () == 16u);
        return fArray_16_byte_;
    }
    template <>
    inline vector<byte> InternetAddress::As<vector<byte>> () const
    {
        Require (GetAddressSize ().has_value ());
        Assert (*GetAddressSize () <= 16);
        return vector<byte>{fArray_16_byte_.begin (), fArray_16_byte_.begin () + *GetAddressSize ()};
    }
    template <>
    inline vector<uint8_t> InternetAddress::As<vector<uint8_t>> () const
    {
        Require (GetAddressSize ().has_value ());
        Assert (*GetAddressSize () <= 16);
        return vector<uint8_t>{fArray_16_uint_.begin (), fArray_16_uint_.begin () + *GetAddressSize ()};
    }
    template <>
    [[deprecated ("array<byte,4> works better so this is deprecated since Stroika v2.1d13")]] inline tuple<uint8_t, uint8_t, uint8_t, uint8_t> InternetAddress::As<tuple<uint8_t, uint8_t, uint8_t, uint8_t>> () const
    {
        Require (fAddressFamily_ == AddressFamily::V4);
        switch (Configuration::GetEndianness ()) {
            case Configuration::Endian::eLittleByte:
                return make_tuple<uint8_t, uint8_t, uint8_t, uint8_t> (
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 0, 8)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 8, 16)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 16, 24)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 24, 32)));
            case Configuration::Endian::eBigByte:
                return make_tuple<uint8_t, uint8_t, uint8_t, uint8_t> (
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 24, 32)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 16, 24)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 8, 16)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 0, 8)));
            default:
                AssertNotImplemented ();
                return tuple<uint8_t, uint8_t, uint8_t, uint8_t>{};
        }
    }
    template <>
    constexpr in6_addr InternetAddress::As<in6_addr> () const
    {
        Require (fAddressFamily_ == AddressFamily::V6);
        return fV6_;
    }
    template <>
    inline in_addr InternetAddress::As<in_addr> (ByteOrder byteOrder) const
    {
        Require (fAddressFamily_ == AddressFamily::V4);
        if (byteOrder == ByteOrder::Network) {
            return fV4_;
        }
        else {
            in_addr tmp = fV4_;
            tmp.s_addr  = ntohl (tmp.s_addr);
            return tmp;
        }
    }

    /*
     ********************************************************************************
     ********************** InternetAddress::ThreeWayComparer ***********************
     ********************************************************************************
     */
    constexpr int InternetAddress::ThreeWayComparer::operator() (const InternetAddress& lhs, const InternetAddress& rhs) const
    {
        if (int cmp = Common::ThreeWayCompare (lhs.fAddressFamily_, rhs.fAddressFamily_)) {
            return cmp;
        }
        switch (lhs.fAddressFamily_) {
            case AddressFamily::UNKNOWN: {
                return 0;
            } break;
            case AddressFamily::V4: {
                return Common::COMPARE_EQUAL (lhs.fArray_4_uint_.begin (), lhs.fArray_4_uint_.end (), rhs.fArray_4_uint_.begin ());
            } break;
            case AddressFamily::V6: {
                return Common::COMPARE_EQUAL (lhs.fArray_16_uint_.begin (), lhs.fArray_16_uint_.end (), rhs.fArray_16_uint_.begin ());
            } break;
        }
        AssertNotReached ();
        return 0;
    }

    /*
     ********************************************************************************
     ************************* InternetAddress operators ****************************
     ********************************************************************************
     */
    inline bool operator< (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) < 0;
    }
    inline bool operator<= (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) <= 0;
    }
    inline bool operator== (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) == 0;
    }
    inline bool operator!= (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) != 0;
    }
    inline bool operator>= (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) >= 0;
    }
    inline bool operator> (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) > 0;
    }

    namespace V4 {
        constexpr InternetAddress kAddrAny{in_addr{}};
    }
    namespace V6 {
        constexpr InternetAddress kAddrAny{in6_addr{}};
    }
    namespace V4 {
        constexpr InternetAddress kLocalhost{0x7f, 0x0, 0x0, 0x1};
    }
    namespace V6 {
        constexpr InternetAddress kLocalhost{in6_addr{{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}}};
    }
    namespace V6 {
        constexpr InternetAddress kV4MappedLocalhost{in6_addr{{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1}}}};
    }

}

#endif /*_Stroika_Foundation_IO_Network_InternetAddress_inl_*/
<commit_msg>disale AssertNotReached () in constexpr function and comment @todo to fix<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#ifndef _Stroika_Foundation_IO_Network_InternetAddress_inl_
#define _Stroika_Foundation_IO_Network_InternetAddress_inl_ 1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include "../../Configuration/Endian.h"
#include "../../Memory/Bits.h"

namespace Stroika::Foundation::IO::Network {

    /*
     ********************************************************************************
     *********************** IO::Network::InternetAddress ***************************
     ********************************************************************************
     */
    constexpr InternetAddress::InternetAddress ()
        : fAddressFamily_{AddressFamily::UNKNOWN}
        , fV4_{}
    {
    }
    constexpr InternetAddress::InternetAddress (const in_addr_t& i)
        : fAddressFamily_ (AddressFamily::V4)
#if qPlatform_POSIX
        , fV4_
    {
        i
    }
#elif qPlatform_Windows
        , fV4_
    {
        in_addr
        {
            {
                static_cast<uint8_t> (Memory::BitSubstring (i, 0, 8)),
                    static_cast<uint8_t> (Memory::BitSubstring (i, 8, 16)),
                    static_cast<uint8_t> (Memory::BitSubstring (i, 16, 24)),
                    static_cast<uint8_t> (Memory::BitSubstring (i, 24, 32))
            }
        }
    }
#endif
    {
#if qPlatform_Windows
        Assert (fV4_.s_addr == i);
#endif
    }
    inline InternetAddress::InternetAddress (const in_addr_t& i, ByteOrder byteOrder)
        : fAddressFamily_ (AddressFamily::V4)
#if qPlatform_POSIX
        , fV4_
    {
        i
    }
#endif
    {
#if qPlatform_Windows
        fV4_.s_addr = i;
#endif
        if (byteOrder == ByteOrder::Host) {
            fV4_.s_addr = htonl (fV4_.s_addr); //NB no ':' cuz some systems use macro
        }
    }
    inline constexpr InternetAddress::InternetAddress (const in_addr& i)
        : fAddressFamily_{AddressFamily::V4}
        , fV4_{i}
    {
    }
    inline InternetAddress::InternetAddress (const in_addr& i, ByteOrder byteOrder)
        : fAddressFamily_{AddressFamily::V4}
        , fV4_{i}
    {
        if (byteOrder == ByteOrder::Host) {
            fV4_.s_addr = htonl (fV4_.s_addr); //NB no ':' cuz some systems use macro
        }
    }
    constexpr InternetAddress::InternetAddress (byte octet1, byte octet2, byte octet3, byte octet4)
        : InternetAddress (array<byte, 4>{octet1, octet2, octet3, octet4})
    {
    }
    constexpr InternetAddress::InternetAddress (uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4)
        : InternetAddress (array<uint8_t, 4>{octet1, octet2, octet3, octet4})
    {
    }
    constexpr InternetAddress::InternetAddress (tuple<uint8_t, uint8_t, uint8_t, uint8_t> octets)
        : InternetAddress (array<uint8_t, 4>{get<0> (octets), get<1> (octets), get<2> (octets), get<3> (octets)})
    {
    }
    constexpr InternetAddress::InternetAddress (array<uint8_t, 4> octets, AddressFamily af)
        : fAddressFamily_{af}
        , fArray_4_uint_{octets}
    {
    }
    constexpr InternetAddress::InternetAddress (array<byte, 4> octets, AddressFamily af)
        : fAddressFamily_{af}
        , fArray_4_byte_{octets}
    {
    }
    constexpr InternetAddress::InternetAddress (const in6_addr& i)
        : fAddressFamily_ (AddressFamily::V6)
        , fV6_{i}
    {
    }
    constexpr InternetAddress::InternetAddress (array<uint8_t, 16> octets, AddressFamily af)
        : fAddressFamily_{af}
        , fArray_16_uint_{octets}
    {
    }
    constexpr InternetAddress::InternetAddress (array<byte, 16> octets, AddressFamily af)
        : fAddressFamily_{af}
        , fArray_16_byte_{octets}
    {
    }
    template <typename ITERABLE_OF_UINT8OrByte, enable_if_t<Configuration::IsIterableOfT_v<ITERABLE_OF_UINT8OrByte, byte> or Configuration::IsIterableOfT_v<ITERABLE_OF_UINT8OrByte, uint8_t>>*>
    inline InternetAddress::InternetAddress (ITERABLE_OF_UINT8OrByte octets, AddressFamily af)
        : fAddressFamily_{af}
    {
        Require (af != AddressFamily::V4 or octets.size () == 4);
        Require (af != AddressFamily::V6 or octets.size () == 16);
        size_t i = 0;
        for (auto b : octets) {
            fArray_16_uint_[i++] = static_cast<uint8_t> (b);
        }
    }
    constexpr bool InternetAddress::empty () const
    {
        return fAddressFamily_ == AddressFamily::UNKNOWN;
    }
    inline void InternetAddress::clear ()
    {
        fAddressFamily_ = AddressFamily::UNKNOWN;
    }
    constexpr InternetAddress::AddressFamily InternetAddress::GetAddressFamily () const
    {
        return fAddressFamily_;
    }
    constexpr optional<size_t> InternetAddress::GetAddressSize () const
    {
        switch (GetAddressFamily ()) {
            case AddressFamily::V4:
                return 4;
            case AddressFamily::V6:
                return 16;
            default:
                return nullopt;
        }
    }
    template <>
    String InternetAddress::As<String> () const;
#if qPlatform_POSIX
    template <>
    inline in_addr_t InternetAddress::As<in_addr_t> () const
    {
        Require (fAddressFamily_ == AddressFamily::V4);
        return fV4_.s_addr;
    }
#endif
    template <>
    constexpr in_addr InternetAddress::As<in_addr> () const
    {
        Require (fAddressFamily_ == AddressFamily::V4);
        return fV4_;
    }
    template <>
    constexpr array<uint8_t, 4> InternetAddress::As<array<uint8_t, 4>> () const
    {
        Require (GetAddressSize () == 4u);
        return fArray_4_uint_;
    }
    template <>
    constexpr array<byte, 4> InternetAddress::As<array<byte, 4>> () const
    {
        Require (GetAddressSize () == 4u);
        return fArray_4_byte_;
    }
    template <>
    constexpr array<uint8_t, 16> InternetAddress::As<array<uint8_t, 16>> () const
    {
        Require (GetAddressSize () == 16u);
        return fArray_16_uint_;
    }
    template <>
    constexpr array<byte, 16> InternetAddress::As<array<byte, 16>> () const
    {
        Require (GetAddressSize () == 16u);
        return fArray_16_byte_;
    }
    template <>
    inline vector<byte> InternetAddress::As<vector<byte>> () const
    {
        Require (GetAddressSize ().has_value ());
        Assert (*GetAddressSize () <= 16);
        return vector<byte>{fArray_16_byte_.begin (), fArray_16_byte_.begin () + *GetAddressSize ()};
    }
    template <>
    inline vector<uint8_t> InternetAddress::As<vector<uint8_t>> () const
    {
        Require (GetAddressSize ().has_value ());
        Assert (*GetAddressSize () <= 16);
        return vector<uint8_t>{fArray_16_uint_.begin (), fArray_16_uint_.begin () + *GetAddressSize ()};
    }
    template <>
    [[deprecated ("array<byte,4> works better so this is deprecated since Stroika v2.1d13")]] inline tuple<uint8_t, uint8_t, uint8_t, uint8_t> InternetAddress::As<tuple<uint8_t, uint8_t, uint8_t, uint8_t>> () const
    {
        Require (fAddressFamily_ == AddressFamily::V4);
        switch (Configuration::GetEndianness ()) {
            case Configuration::Endian::eLittleByte:
                return make_tuple<uint8_t, uint8_t, uint8_t, uint8_t> (
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 0, 8)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 8, 16)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 16, 24)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 24, 32)));
            case Configuration::Endian::eBigByte:
                return make_tuple<uint8_t, uint8_t, uint8_t, uint8_t> (
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 24, 32)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 16, 24)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 8, 16)),
                    static_cast<uint8_t> (Memory::BitSubstring (fV4_.s_addr, 0, 8)));
            default:
                AssertNotImplemented ();
                return tuple<uint8_t, uint8_t, uint8_t, uint8_t>{};
        }
    }
    template <>
    constexpr in6_addr InternetAddress::As<in6_addr> () const
    {
        Require (fAddressFamily_ == AddressFamily::V6);
        return fV6_;
    }
    template <>
    inline in_addr InternetAddress::As<in_addr> (ByteOrder byteOrder) const
    {
        Require (fAddressFamily_ == AddressFamily::V4);
        if (byteOrder == ByteOrder::Network) {
            return fV4_;
        }
        else {
            in_addr tmp = fV4_;
            tmp.s_addr  = ntohl (tmp.s_addr);
            return tmp;
        }
    }

    /*
     ********************************************************************************
     ********************** InternetAddress::ThreeWayComparer ***********************
     ********************************************************************************
     */
    constexpr int InternetAddress::ThreeWayComparer::operator() (const InternetAddress& lhs, const InternetAddress& rhs) const
    {
        if (int cmp = Common::ThreeWayCompare (lhs.fAddressFamily_, rhs.fAddressFamily_)) {
            return cmp;
        }
        switch (lhs.fAddressFamily_) {
            case AddressFamily::UNKNOWN: {
                return 0;
            } break;
            case AddressFamily::V4: {
                return Common::COMPARE_EQUAL (lhs.fArray_4_uint_.begin (), lhs.fArray_4_uint_.end (), rhs.fArray_4_uint_.begin ());
            } break;
            case AddressFamily::V6: {
                return Common::COMPARE_EQUAL (lhs.fArray_16_uint_.begin (), lhs.fArray_16_uint_.end (), rhs.fArray_16_uint_.begin ());
            } break;
        }
        //AssertNotReached ();	@todo - this really should be an assertion failure, but tricky cuz constexpr function could fix with template)
        return 0;
    }

    /*
     ********************************************************************************
     ************************* InternetAddress operators ****************************
     ********************************************************************************
     */
    inline bool operator< (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) < 0;
    }
    inline bool operator<= (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) <= 0;
    }
    inline bool operator== (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) == 0;
    }
    inline bool operator!= (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) != 0;
    }
    inline bool operator>= (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) >= 0;
    }
    inline bool operator> (const InternetAddress& lhs, const InternetAddress& rhs)
    {
        return Common::ThreeWayCompare (lhs, rhs) > 0;
    }

    namespace V4 {
        constexpr InternetAddress kAddrAny{in_addr{}};
    }
    namespace V6 {
        constexpr InternetAddress kAddrAny{in6_addr{}};
    }
    namespace V4 {
        constexpr InternetAddress kLocalhost{0x7f, 0x0, 0x0, 0x1};
    }
    namespace V6 {
        constexpr InternetAddress kLocalhost{in6_addr{{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}}};
    }
    namespace V6 {
        constexpr InternetAddress kV4MappedLocalhost{in6_addr{{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1}}}};
    }

}

#endif /*_Stroika_Foundation_IO_Network_InternetAddress_inl_*/
<|endoftext|>


<commit_before>
// Qt includes
#include <QApplication>
#include <QDebug>
#include <QList>
#include <QTimer>

// CTKVTK includes
#include "ctkVTKConnection.h"

// STD includes
#include <cstdlib>
#include <iostream>

// VTK includes
#include <vtkCallbackCommand.h>
#include <vtkCommand.h>
#include <vtkObject.h>
#include <vtkSmartPointer.h>
#include <vtkTimerLog.h>

void doit(vtkObject* vtkNotUsed(obj), unsigned long vtkNotUsed(event),
          void* client_data, void* vtkNotUsed(param))
{
  QTimer* t = reinterpret_cast<QTimer*>(client_data);
  t->stop();
}

int ctkVTKConnectionTest1( int argc, char * argv [] )
{
  QApplication app(argc, argv);

  int objects = 1000;
  int events = 100;

  vtkObject* obj = vtkObject::New();
  vtkObject* obj2 = vtkObject::New();
  vtkObject* obj3 = vtkObject::New();
  vtkObject* obj4 = vtkObject::New();
  vtkObject* obj5 = vtkObject::New();

  QObject*   topObject = new QObject(0);
  // It could be here any kind of Qt object, QTimer has a no op slot so use it
  QTimer*    slotObject = new QTimer(topObject);

  for (int i = 0; i < objects; ++i)
    {
    ctkVTKConnection* connection = new ctkVTKConnection(topObject);
    connection->observeDeletion(false);
    connection->setup(obj, vtkCommand::ModifiedEvent,
                      slotObject, SLOT(stop()));

    vtkCallbackCommand* callback = vtkCallbackCommand::New();
    callback->SetClientData(slotObject);
    callback->SetCallback(doit);

    obj2->AddObserver(vtkCommand::ModifiedEvent, callback);
    callback->Delete();

    ctkVTKConnection* connection2 = new ctkVTKConnection(topObject);
    connection2->observeDeletion(true);
    connection2->setup(obj3, vtkCommand::ModifiedEvent,
                      slotObject, SLOT(stop()));

    ctkVTKConnection* connection3 = new ctkVTKConnection(topObject);
    connection3->observeDeletion(false);
    connection3->setup(obj4, vtkCommand::ModifiedEvent,
                      new QTimer(topObject), SLOT(stop()));

    ctkVTKConnection* connection4 = new ctkVTKConnection(topObject);
    connection4->observeDeletion(true);
    connection4->setup(obj5, vtkCommand::ModifiedEvent,
                      slotObject, SLOT(stop()));
    }

  vtkSmartPointer<vtkTimerLog> timerLog =
    vtkSmartPointer<vtkTimerLog>::New();

  timerLog->StartTimer();
  for (int i = 0; i < events; ++i)
    {
    obj->Modified();
    }
  timerLog->StopTimer();

  double t1 = timerLog->GetElapsedTime();
  qDebug() << events << "events listened by" << objects << "objects (ctkVTKConnection): " << t1 << "seconds";

  // Callback only

  vtkSmartPointer<vtkTimerLog> timerLog2 =
    vtkSmartPointer<vtkTimerLog>::New();
  timerLog2->StartTimer();
  for (int i = 0; i < events; ++i)
    {
    obj2->Modified();
    }
  timerLog2->StopTimer();

  double t2 = timerLog2->GetElapsedTime();
  qDebug() << events << "events listened by" << objects <<"objects (vtkCallbacks): " << t2 << "seconds";
  double ratio = t1 / t2;
  qDebug() << "ctkVTKConnection / vtkCallbacks: " << ratio;

  vtkSmartPointer<vtkTimerLog> timerLog3 =
    vtkSmartPointer<vtkTimerLog>::New();

  timerLog3->StartTimer();
  for (int i = 0; i < events; ++i)
    {
    obj3->Modified();
    }
  timerLog3->StopTimer();

  double t3 = timerLog3->GetElapsedTime();
  qDebug() << events << "events listened by" << objects << "objects (observed ctkVTKConnection): " << t3 << "seconds";

  vtkSmartPointer<vtkTimerLog> timerLog4 =
    vtkSmartPointer<vtkTimerLog>::New();

  timerLog4->StartTimer();
  for (int i = 0; i < events; ++i)
    {
    obj4->Modified();
    }
  timerLog4->StopTimer();

  double t4 = timerLog4->GetElapsedTime();
  qDebug() << events << "events listened by" << objects << "objects (ctkVTKConnection, 1-1): " << t4 << "seconds";

  obj->Delete();
  obj2->Delete();
  obj3->Delete();

  delete topObject;

  obj4->Delete();
  obj5->Delete();

  // Ideally a ratio ~= 1. but the ratio can be more in Debug mode... up to 2.
  if (ratio > 2.)
    {
    return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}
<commit_msg>BUG: Fix ctkVTKConnectionTest1 - Do not check for "ratio" if build in Debug<commit_after>
// Qt includes
#include <QApplication>
#include <QDebug>
#include <QList>
#include <QTimer>

// CTKVTK includes
#include "ctkVTKConnection.h"

// VTK includes
#include <vtkCallbackCommand.h>
#include <vtkCommand.h>
#include <vtkObject.h>
#include <vtkSmartPointer.h>
#include <vtkTimerLog.h>

// STD includes
#include <cstdlib>
#include <iostream>

//-----------------------------------------------------------------------------
void doit(vtkObject* vtkNotUsed(obj), unsigned long vtkNotUsed(event),
          void* client_data, void* vtkNotUsed(param))
{
  QTimer* t = reinterpret_cast<QTimer*>(client_data);
  t->stop();
}

//-----------------------------------------------------------------------------
int ctkVTKConnectionTest1( int argc, char * argv [] )
{
  QApplication app(argc, argv);

  int objects = 1000;
  int events = 100;

  vtkObject* obj = vtkObject::New();
  vtkObject* obj2 = vtkObject::New();
  vtkObject* obj3 = vtkObject::New();
  vtkObject* obj4 = vtkObject::New();
  vtkObject* obj5 = vtkObject::New();

  QObject*   topObject = new QObject(0);
  // It could be here any kind of Qt object, QTimer has a no op slot so use it
  QTimer*    slotObject = new QTimer(topObject);

  for (int i = 0; i < objects; ++i)
    {
    ctkVTKConnection* connection = new ctkVTKConnection(topObject);
    connection->observeDeletion(false);
    connection->setup(obj, vtkCommand::ModifiedEvent,
                      slotObject, SLOT(stop()));

    vtkCallbackCommand* callback = vtkCallbackCommand::New();
    callback->SetClientData(slotObject);
    callback->SetCallback(doit);

    obj2->AddObserver(vtkCommand::ModifiedEvent, callback);
    callback->Delete();

    ctkVTKConnection* connection2 = new ctkVTKConnection(topObject);
    connection2->observeDeletion(true);
    connection2->setup(obj3, vtkCommand::ModifiedEvent,
                      slotObject, SLOT(stop()));

    ctkVTKConnection* connection3 = new ctkVTKConnection(topObject);
    connection3->observeDeletion(false);
    connection3->setup(obj4, vtkCommand::ModifiedEvent,
                      new QTimer(topObject), SLOT(stop()));

    ctkVTKConnection* connection4 = new ctkVTKConnection(topObject);
    connection4->observeDeletion(true);
    connection4->setup(obj5, vtkCommand::ModifiedEvent,
                      slotObject, SLOT(stop()));
    }

  vtkSmartPointer<vtkTimerLog> timerLog =
    vtkSmartPointer<vtkTimerLog>::New();

  timerLog->StartTimer();
  for (int i = 0; i < events; ++i)
    {
    obj->Modified();
    }
  timerLog->StopTimer();

  double t1 = timerLog->GetElapsedTime();
  qDebug() << events << "events listened by" << objects << "objects (ctkVTKConnection): " << t1 << "seconds";

  // Callback only

  vtkSmartPointer<vtkTimerLog> timerLog2 =
    vtkSmartPointer<vtkTimerLog>::New();
  timerLog2->StartTimer();
  for (int i = 0; i < events; ++i)
    {
    obj2->Modified();
    }
  timerLog2->StopTimer();

  double t2 = timerLog2->GetElapsedTime();
  qDebug() << events << "events listened by" << objects <<"objects (vtkCallbacks): " << t2 << "seconds";
  double ratio = t1 / t2;
  qDebug() << "ctkVTKConnection / vtkCallbacks: " << ratio;

  vtkSmartPointer<vtkTimerLog> timerLog3 =
    vtkSmartPointer<vtkTimerLog>::New();

  timerLog3->StartTimer();
  for (int i = 0; i < events; ++i)
    {
    obj3->Modified();
    }
  timerLog3->StopTimer();

  double t3 = timerLog3->GetElapsedTime();
  qDebug() << events << "events listened by" << objects << "objects (observed ctkVTKConnection): " << t3 << "seconds";

  vtkSmartPointer<vtkTimerLog> timerLog4 =
    vtkSmartPointer<vtkTimerLog>::New();

  timerLog4->StartTimer();
  for (int i = 0; i < events; ++i)
    {
    obj4->Modified();
    }
  timerLog4->StopTimer();

  double t4 = timerLog4->GetElapsedTime();
  qDebug() << events << "events listened by" << objects << "objects (ctkVTKConnection, 1-1): " << t4 << "seconds";

  obj->Delete();
  obj2->Delete();
  obj3->Delete();

  delete topObject;

  obj4->Delete();
  obj5->Delete();

#ifdef QT_NO_DEBUG // In Debug mode, the ratio can be over 2 !
  // Ideally a ratio ~= 1.
  if (ratio > 1.2)
    {
    return EXIT_FAILURE;
    }
#endif
  return EXIT_SUCCESS;
}
<|endoftext|>


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

#include "pch.h"

#include <core/sdk/IPlugin.h>
#include <core/sdk/IPlaybackRemote.h>

musik::core::sdk::IPlaybackService* playback;

static HHOOK hook = NULL;

LRESULT CALLBACK ShellProc(int code, WPARAM wParam, LPARAM lParam) {
    if (code == HC_ACTION && playback) {
        if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
            PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
            switch (p->vkCode) {
                case VK_MEDIA_NEXT_TRACK:
                    playback->Next();
                    return 0;
                case VK_MEDIA_PLAY_PAUSE:
                    playback->PauseOrResume();
                    return 0;
                case VK_MEDIA_PREV_TRACK:
                    playback->Previous();
                    return 0;
                case VK_MEDIA_STOP:
                    playback->Stop();
                    return 0;
            }

            bool ctrl = GetAsyncKeyState(VK_RCONTROL) & 0x8000;
            bool alt = GetAsyncKeyState(VK_RMENU) & 0x8000;
            //bool win = GetAsyncKeyState(VK_LWIN) & 0x8000;

            if (ctrl && alt) {
                switch (p->vkCode) {
                    case 'I':
                    case 'i':
                        playback->SetVolume(playback->GetVolume() + 0.05);
                        return 1;

                    case 'K':
                    case 'k':
                        playback->SetVolume(playback->GetVolume() - 0.05);
                        return 1;

                    case 'L':
                    case 'l':
                        playback->Next();
                        return 1;

                    case 'J':
                    case 'j':
                        playback->Previous();
                        return 1;

                    case 'M':
                    case 'm':
                        playback->Previous();
                        return 1;
                }
            }
        }
    }

    return CallNextHookEx(nullptr, code, wParam, lParam);
}

BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
    switch (reason) {
        case DLL_PROCESS_ATTACH:
            hook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC) ShellProc, module, 0L);
            break;

        case DLL_PROCESS_DETACH:
            UnhookWindowsHookEx(hook);
            hook = nullptr;
            break;
    }

    return TRUE;
}

class MMShellHook:
    public musik::core::sdk::IPlugin,
    public musik::core::sdk::IPlaybackRemote {
        public:
            void Destroy() {
            }

            const char* Name() {
                return "win32globalhotkeys";
            }

            const char* Version() {
                return "0.1";
            }

            const char* Author() {
                return "clangen";
            }

            virtual void SetPlaybackService(musik::core::sdk::IPlaybackService* playback) {
                ::playback = playback;
            }

            virtual void OnTrackChanged(musik::core::sdk::ITrack* track) {
            }
};

static MMShellHook plugin;

extern "C" __declspec(dllexport) musik::core::sdk::IPlugin* GetPlugin() {
    return &plugin;
}

extern "C" __declspec(dllexport) musik::core::sdk::IPlaybackRemote* GetPlaybackRemote() {
    return &plugin;
}<commit_msg>Fixed a small error in the win32 global hotkeys implementation... mute was not properly wired up.<commit_after>//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2016 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include "pch.h"

#include <core/sdk/IPlugin.h>
#include <core/sdk/IPlaybackRemote.h>

musik::core::sdk::IPlaybackService* playback;

static HHOOK hook = NULL;

LRESULT CALLBACK ShellProc(int code, WPARAM wParam, LPARAM lParam) {
    if (code == HC_ACTION && playback) {
        if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
            PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
            switch (p->vkCode) {
                case VK_MEDIA_NEXT_TRACK:
                    playback->Next();
                    return 0;
                case VK_MEDIA_PLAY_PAUSE:
                    playback->PauseOrResume();
                    return 0;
                case VK_MEDIA_PREV_TRACK:
                    playback->Previous();
                    return 0;
                case VK_MEDIA_STOP:
                    playback->Stop();
                    return 0;
            }

            bool ctrl = GetAsyncKeyState(VK_RCONTROL) & 0x8000;
            bool alt = GetAsyncKeyState(VK_RMENU) & 0x8000;
            //bool win = GetAsyncKeyState(VK_LWIN) & 0x8000;

            if (ctrl && alt) {
                switch (p->vkCode) {
                    case 'I':
                    case 'i':
                        playback->SetVolume(playback->GetVolume() + 0.05);
                        return 1;

                    case 'K':
                    case 'k':
                        playback->SetVolume(playback->GetVolume() - 0.05);
                        return 1;

                    case 'L':
                    case 'l':
                        playback->Next();
                        return 1;

                    case 'J':
                    case 'j':
                        playback->Previous();
                        return 1;

                    case 'M':
                    case 'm':
                        playback->ToggleMute();
                        return 1;
                }
            }
        }
    }

    return CallNextHookEx(nullptr, code, wParam, lParam);
}

BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
    switch (reason) {
        case DLL_PROCESS_ATTACH:
            hook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC) ShellProc, module, 0L);
            break;

        case DLL_PROCESS_DETACH:
            UnhookWindowsHookEx(hook);
            hook = nullptr;
            break;
    }

    return TRUE;
}

class MMShellHook:
    public musik::core::sdk::IPlugin,
    public musik::core::sdk::IPlaybackRemote {
        public:
            void Destroy() {
            }

            const char* Name() {
                return "win32globalhotkeys";
            }

            const char* Version() {
                return "0.1";
            }

            const char* Author() {
                return "clangen";
            }

            virtual void SetPlaybackService(musik::core::sdk::IPlaybackService* playback) {
                ::playback = playback;
            }

            virtual void OnTrackChanged(musik::core::sdk::ITrack* track) {
            }
};

static MMShellHook plugin;

extern "C" __declspec(dllexport) musik::core::sdk::IPlugin* GetPlugin() {
    return &plugin;
}

extern "C" __declspec(dllexport) musik::core::sdk::IPlaybackRemote* GetPlaybackRemote() {
    return &plugin;
}<|endoftext|>


<commit_before>
#include "PhysicalOperators.h"

namespace srch2 {
namespace instantsearch {

////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// Union lists sorted by ID /////////////////////////////////////

UnionSortedByIDOperator::UnionSortedByIDOperator() {
	//TODO
}
UnionSortedByIDOperator::~UnionSortedByIDOperator(){
	//TODO
}
bool UnionSortedByIDOperator::open(QueryEvaluatorInternal * queryEvaluator, PhysicalPlanExecutionParameters & params){
	this->queryEvaluator = queryEvaluator;
	/*
	 * 1. open all children (no parameters known to pass as of now)
	 * 2. initialize nextRecordItems vector.
	 */
	for(unsigned childOffset = 0 ; childOffset != this->getPhysicalPlanOptimizationNode()->getChildrenCount() ; ++childOffset){
		this->getPhysicalPlanOptimizationNode()->getChildAt(childOffset)->getExecutableNode()->open(queryEvaluator , params);
	}

	unsigned numberOfChildren = this->getPhysicalPlanOptimizationNode()->getChildrenCount();
	for(unsigned childOffset = 0; childOffset < numberOfChildren; ++childOffset){
		PhysicalPlanRecordItem * recordItem =
				this->getPhysicalPlanOptimizationNode()->getChildAt(childOffset)->getExecutableNode()->getNext(params);
		this->nextItemsFromChildren.push_back(recordItem);
	}

	listsHaveMoreRecordsInThem = true;
	return true;

}
PhysicalPlanRecordItem * UnionSortedByIDOperator::getNext(const PhysicalPlanExecutionParameters & params) {

	if(listsHaveMoreRecordsInThem == false){
		return NULL;
	}

	/*
	 * 1. iterate on nextItemsFromChildren
	 * 2. find the min ID on top,
	 * 3. remove all top records that have the same ID as min ID
	 * 4. return the min ID (which has the most Score in ties)
	 */
	// find the min ID
	unsigned numberOfChildren = this->getPhysicalPlanOptimizationNode()->getChildrenCount();
	PhysicalPlanRecordItem * minIDRecord = NULL;
	for(unsigned childOffset = 0; childOffset < numberOfChildren; ++childOffset){
		PhysicalPlanRecordItem * recordItem = this->nextItemsFromChildren.at(childOffset);
		if(recordItem == NULL){
			continue;
		}
		if(minIDRecord == NULL){
			minIDRecord = recordItem;
		}else if((minIDRecord->getRecordId() > recordItem->getRecordId()) // find the 1. min ID and 2. max score
				|| (minIDRecord->getRecordId() == recordItem->getRecordId() &&
						minIDRecord->getRecordRuntimeScore() < recordItem->getRecordRuntimeScore())){
			minIDRecord = recordItem;
		}

	}
	if(minIDRecord == NULL){
		return NULL;
	}
	// now remove all minID records from all lists
	for(unsigned childOffset = 0; childOffset < numberOfChildren; ++childOffset){
		if(this->nextItemsFromChildren.at(childOffset)->getRecordId() == minIDRecord->getRecordId()){
			this->nextItemsFromChildren.at(childOffset) =
					this->getPhysicalPlanOptimizationNode()->getChildAt(childOffset)->getExecutableNode()->getNext(params);
		}
	}
	// and now return the minId record
	return minIDRecord;
}
bool UnionSortedByIDOperator::close(PhysicalPlanExecutionParameters & params){
	this->queryEvaluator = NULL;
	this->listsHaveMoreRecordsInThem = true;
	return true;
}
bool UnionSortedByIDOperator::verifyByRandomAccess(PhysicalPlanRandomAccessVerificationParameters & parameters) {
	//TODO
}

// The cost of open of a child is considered only once in the cost computation
// of parent open function.
unsigned UnionSortedByIDOptimizationOperator::getCostOfOpen(const PhysicalPlanExecutionParameters & params){
	//TODO
}
// The cost of getNext of a child is multiplied by the estimated number of calls to this function
// when the cost of parent is being calculated.
unsigned UnionSortedByIDOptimizationOperator::getCostOfGetNext(const PhysicalPlanExecutionParameters & params) {
	//TODO
}
// the cost of close of a child is only considered once since each node's close function is only called once.
unsigned UnionSortedByIDOptimizationOperator::getCostOfClose(const PhysicalPlanExecutionParameters & params) {
	//TODO
}
void UnionSortedByIDOptimizationOperator::getOutputProperties(IteratorProperties & prop){
	prop.addProperty(PhysicalPlanIteratorProperty_SortById);
}
void UnionSortedByIDOptimizationOperator::getRequiredInputProperties(IteratorProperties & prop){
	// the only requirement for input is to be sorted by ID
	prop.addProperty(PhysicalPlanIteratorProperty_SortById);
}
PhysicalPlanNodeType UnionSortedByIDOptimizationOperator::getType() {
	return PhysicalPlanNode_UnionSortedById;
}
bool UnionSortedByIDOptimizationOperator::validateChildren(){
	for(unsigned i = 0 ; i < getChildrenCount() ; i++){
		PhysicalPlanOptimizationNode * child = getChildAt(i);
		PhysicalPlanNodeType childType = child->getType();
		switch (childType) {
			case PhysicalPlanNode_RandomAccessTerm:
			case PhysicalPlanNode_RandomAccessAnd:
			case PhysicalPlanNode_RandomAccessOr:
			case PhysicalPlanNode_RandomAccessNot:
			case PhysicalPlanNode_UnionLowestLevelTermVirtualList:
				// this operator cannot have TVL as a child, TVL overhead is not needed for this operator
				return false;
			default:{
				continue;
			}
		}
	}
	return true;
}

}
}
<commit_msg>A missed part in UnionSortedByIdOperator is added.<commit_after>
#include "PhysicalOperators.h"

namespace srch2 {
namespace instantsearch {

////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// Union lists sorted by ID /////////////////////////////////////

UnionSortedByIDOperator::UnionSortedByIDOperator() {
	//TODO
}
UnionSortedByIDOperator::~UnionSortedByIDOperator(){
	//TODO
}
bool UnionSortedByIDOperator::open(QueryEvaluatorInternal * queryEvaluator, PhysicalPlanExecutionParameters & params){
	this->queryEvaluator = queryEvaluator;
	/*
	 * 1. open all children (no parameters known to pass as of now)
	 * 2. initialize nextRecordItems vector.
	 */
	for(unsigned childOffset = 0 ; childOffset != this->getPhysicalPlanOptimizationNode()->getChildrenCount() ; ++childOffset){
		this->getPhysicalPlanOptimizationNode()->getChildAt(childOffset)->getExecutableNode()->open(queryEvaluator , params);
	}

	unsigned numberOfChildren = this->getPhysicalPlanOptimizationNode()->getChildrenCount();
	for(unsigned childOffset = 0; childOffset < numberOfChildren; ++childOffset){
		PhysicalPlanRecordItem * recordItem =
				this->getPhysicalPlanOptimizationNode()->getChildAt(childOffset)->getExecutableNode()->getNext(params);
		this->nextItemsFromChildren.push_back(recordItem);
	}

	listsHaveMoreRecordsInThem = true;
	return true;

}
PhysicalPlanRecordItem * UnionSortedByIDOperator::getNext(const PhysicalPlanExecutionParameters & params) {

	if(listsHaveMoreRecordsInThem == false){
		return NULL;
	}

	/*
	 * 1. iterate on nextItemsFromChildren
	 * 2. find the min ID on top,
	 * 3. remove all top records that have the same ID as min ID
	 * 4. return the min ID (which has the most Score in ties)
	 */
	// find the min ID
	unsigned numberOfChildren = this->getPhysicalPlanOptimizationNode()->getChildrenCount();
	PhysicalPlanRecordItem * minIDRecord = NULL;
	for(unsigned childOffset = 0; childOffset < numberOfChildren; ++childOffset){
		PhysicalPlanRecordItem * recordItem = this->nextItemsFromChildren.at(childOffset);
		if(recordItem == NULL){
			continue;
		}
		if(minIDRecord == NULL){
			minIDRecord = recordItem;
		}else if((minIDRecord->getRecordId() > recordItem->getRecordId()) // find the 1. min ID and 2. max score
				|| (minIDRecord->getRecordId() == recordItem->getRecordId() &&
						minIDRecord->getRecordRuntimeScore() < recordItem->getRecordRuntimeScore())){
			minIDRecord = recordItem;
		}

	}
	if(minIDRecord == NULL){
		return NULL;
	}
	// now remove all minID records from all lists
	vector<float> runtimeScores;
	vector<TrieNodePointer> recordKeywordMatchPrefixes;
	vector<unsigned> recordKeywordMatchEditDistances;
	vector<unsigned> recordKeywordMatchBitmaps;
	vector<unsigned> positionIndexOffsets;
	for(unsigned childOffset = 0; childOffset < numberOfChildren; ++childOffset){
		if(this->nextItemsFromChildren.at(childOffset)->getRecordId() == minIDRecord->getRecordId()){
			this->nextItemsFromChildren.at(childOffset)->getRecordMatchingPrefixes(recordKeywordMatchPrefixes);
			this->nextItemsFromChildren.at(childOffset)->getRecordMatchEditDistances(recordKeywordMatchEditDistances);
			this->nextItemsFromChildren.at(childOffset)->getRecordMatchAttributeBitmaps(recordKeywordMatchBitmaps);
			this->nextItemsFromChildren.at(childOffset)->getPositionIndexOffsets(positionIndexOffsets);
			// static score, not for now
			// and remove it from this list by substituting it by the next one
			this->nextItemsFromChildren.at(childOffset) =
					this->getPhysicalPlanOptimizationNode()->getChildAt(childOffset)->getExecutableNode()->getNext(params);
		}
	}
	// prepare the record and return it
	minIDRecord->setRecordMatchingPrefixes(recordKeywordMatchPrefixes);
	minIDRecord->setRecordMatchEditDistances(recordKeywordMatchEditDistances);
	minIDRecord->setRecordMatchAttributeBitmaps(recordKeywordMatchBitmaps);
	minIDRecord->setPositionIndexOffsets(positionIndexOffsets);

	return minIDRecord;
}
bool UnionSortedByIDOperator::close(PhysicalPlanExecutionParameters & params){
	this->queryEvaluator = NULL;
	this->listsHaveMoreRecordsInThem = true;
	return true;
}
bool UnionSortedByIDOperator::verifyByRandomAccess(PhysicalPlanRandomAccessVerificationParameters & parameters) {
	//TODO
}

// The cost of open of a child is considered only once in the cost computation
// of parent open function.
unsigned UnionSortedByIDOptimizationOperator::getCostOfOpen(const PhysicalPlanExecutionParameters & params){
	//TODO
}
// The cost of getNext of a child is multiplied by the estimated number of calls to this function
// when the cost of parent is being calculated.
unsigned UnionSortedByIDOptimizationOperator::getCostOfGetNext(const PhysicalPlanExecutionParameters & params) {
	//TODO
}
// the cost of close of a child is only considered once since each node's close function is only called once.
unsigned UnionSortedByIDOptimizationOperator::getCostOfClose(const PhysicalPlanExecutionParameters & params) {
	//TODO
}
void UnionSortedByIDOptimizationOperator::getOutputProperties(IteratorProperties & prop){
	prop.addProperty(PhysicalPlanIteratorProperty_SortById);
}
void UnionSortedByIDOptimizationOperator::getRequiredInputProperties(IteratorProperties & prop){
	// the only requirement for input is to be sorted by ID
	prop.addProperty(PhysicalPlanIteratorProperty_SortById);
}
PhysicalPlanNodeType UnionSortedByIDOptimizationOperator::getType() {
	return PhysicalPlanNode_UnionSortedById;
}
bool UnionSortedByIDOptimizationOperator::validateChildren(){
	for(unsigned i = 0 ; i < getChildrenCount() ; i++){
		PhysicalPlanOptimizationNode * child = getChildAt(i);
		PhysicalPlanNodeType childType = child->getType();
		switch (childType) {
			case PhysicalPlanNode_RandomAccessTerm:
			case PhysicalPlanNode_RandomAccessAnd:
			case PhysicalPlanNode_RandomAccessOr:
			case PhysicalPlanNode_RandomAccessNot:
			case PhysicalPlanNode_UnionLowestLevelTermVirtualList:
				// this operator cannot have TVL as a child, TVL overhead is not needed for this operator
				return false;
			default:{
				continue;
			}
		}
	}
	return true;
}

}
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////
//                                                                  //
//  AddMyTaskCorPIDTOFQA                                            //
//  Author: Brennan Schaefer, Oak Ridge National Laboratory, 2016   //
//                                                                  //
//////////////////////////////////////////////////////////////////////

class AliAnalysisDataContainer;

AliAnalysisTaskCorPIDTOFQA* AddMyTaskCorPIDTOFQA(TString name = "name")
{
    // get the manager via the static access member. since it's static, you don't need
    // an instance of the class to call the function
    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr) {
        return 0x0;
    }
    // get the input event handler, again via a static method.
    // this handler is part of the managing system and feeds events
    // to your task
    if (!mgr->GetInputEventHandler()) {
        return 0x0;
    }
    // by default, a file is open for writing. here, we get the filename
    TString fileName = AliAnalysisManager::GetCommonFileName();
    fileName += ":MyTask";      // create a subfolder in the file
    // now we create an instance of your task
    AliAnalysisTaskCorPIDTOFQA* task = new AliAnalysisTaskCorPIDTOFQA(name.Data());
    if(!task) return 0x0;
    // add your task to the manager
    mgr->AddTask(task);
    // your task needs input: here we connect the manager to your task
    mgr->ConnectInput(task,0,mgr->GetCommonInputContainer());
    // same for the output
    mgr->ConnectOutput(task,1,mgr->CreateContainer("MyOutputContainer", TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));
    // in the end, this macro returns a pointer to your task. this will be convenient later on
    // when you will run your analysis in an analysis train on grid
    return task;
}
<commit_msg>adding multiple subwagons for systematic studies<commit_after>//////////////////////////////////////////////////////////////////////
//                                                                  //
//  AddMyTaskCorPIDTOFQA                                            //
//  Author: Brennan Schaefer, Oak Ridge National Laboratory, 2016   //
//                                                                  //
//////////////////////////////////////////////////////////////////////
#include <stdlib.h>

class AliAnalysisDataContainer;

AliAnalysisTaskCorPIDTOFQA* AddMyTaskCorPIDTOFQA(TString name = "name")
{
    // get the manager via the static access member. since it's static, you don't need
    // an instance of the class to call the function
    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr) {
        return 0x0;
    }
    // get the input event handler, again via a static method.
    // this handler is part of the managing system and feeds events
    // to your task
    if (!mgr->GetInputEventHandler()) {
        return 0x0;
    }
    // by default, a file is open for writing. here, we get the filename
    TString fileName = AliAnalysisManager::GetCommonFileName();
    // fileName += ":MyTask";      // create a subfolder in the file
    // now we create an instance of your task
    // AliAnalysisTaskCorPIDTOFQA* task = new BSchaefer_devel::AliAnalysisTaskCorPIDTOFQA(name.Data());
    AliAnalysisTaskCorPIDTOFQA* task = new AliAnalysisTaskCorPIDTOFQA(name.Data());
    if(!task) return 0x0;
    // add your task to the manager
    mgr->AddTask(task);
    // your task needs input: here we connect the manager to your task
    // if(run_mode == 0)    mgr->ConnectInput(task    ,0,mgr->GetCommonInputContainer());
    // if(run_mode == 1)    mgr->ConnectInput(task_PID,0,mgr->GetCommonInputContainer());
    mgr->ConnectInput(task,0,mgr->GetCommonInputContainer());
    // same for the output

    int run_mode = 0;
    run_mode = atoi(name);
    // cout<<endl<<endl<<endl<<run_mode<<endl<<endl<<endl;

    if(run_mode == 0){   mgr->ConnectOutput(task,1,mgr->CreateContainer("cOutput",     TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));    }
    if(run_mode == 1){   mgr->ConnectOutput(task,1,mgr->CreateContainer("cOutput_PID", TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));    }
    if(run_mode == 2){   mgr->ConnectOutput(task,1,mgr->CreateContainer("cOutput_TPC", TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));    }
    if(run_mode == 3){   mgr->ConnectOutput(task,1,mgr->CreateContainer("cOutput_nCl", TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));    }
    if(run_mode == 4){   mgr->ConnectOutput(task,1,mgr->CreateContainer("cOutput_DCA", TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));    }
    if(run_mode == 5){   mgr->ConnectOutput(task,1,mgr->CreateContainer("cOutput_sid", TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));    }
    if(run_mode == 6){   mgr->ConnectOutput(task,1,mgr->CreateContainer("cOutput_glo", TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));    }
    // mgr->ConnectOutput(task,1,mgr->CreateContainer("cOutput",     TList::Class(), AliAnalysisManager::kOutputContainer, fileName.Data()));
    // in the end, this macro returns a pointer to your task. this will be convenient later on
    // when you will run your analysis in an analysis train on grid
    return task;
}
<|endoftext|>