<commit_before>#include "Engine.h"
#include "Game.h"
#include "ObjectDummy.h"
#include "BodyRigid.h"
#include "BodyDummy.h"
#include "Physics.h"
#include "ShapeCapsule.h"
#include "ActorBase.h"
#include "Visualizer.h"
#include "sys/SysControl.h"

using namespace MathLib;

#ifdef MEMORY_INFO
#define new new(__FILE__, __LINE__)
#endif // MEMORY_INFO

/*
*/
#define ACTOR_BASE_IFPS             (1.0f / 60.0f)
#define ACTOR_BASE_CLAMP            89.9f
#define ACTOR_BASE_COLLISIONS       4

/*
*/
CActorBase::CActorBase()
{
	m_vUp = vec3(0.0f, 0.0f, 1.0f);
	m_pObject = new CObjectDummy();
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(1.0f, 1.0f);

	m_nFlush = 0;
	m_vPosition = Vec3_zero;
	m_vVelocity = Vec3_zero;
	m_fPhiAngle = 0.0f;			//倾斜角		二维平面坐标系中，直线向Y周延伸的方向与X轴正向之间的夹角
	m_fThetaAngle = 0.0f;			//方位角，正北方那条线与当前线条按照顺时针走过的角度

	for (int i = 0; i < NUM_STATES; i++)
	{
		m_pStates[i] = 0;
		m_pTimes[i] = 0.0f;
	}
	m_pDummy->SetEnabled(1);
	m_pObject->SetBody(NULL);
	m_pObject->SetBody(m_pDummy);
	m_pShape->SetBody(NULL);
	m_pShape->SetBody(m_pDummy);

	m_pObject->SetWorldTransform(Get_Body_Transform());
	m_pShape->SetRestitution(0.0f);
	m_pShape->SetCollisionMask(2);

	SetEnabled(1);
	SetViewDirection(vec3(0.0f, 1.0f, 0.0f));
	SetCollision(1);
	SetCollisionRadius(0.3f);
	SetCollisionHeight(1.0f);
	SetFriction(2.0f);
	SetMinVelocity(2.0f);
	SetMaxVelocity(4.0f);
	SetAcceleration(8.0f);
	SetDamping(8.0f);
	SetJumping(1.5f);

	SetGround(0);
	SetCeiling(0);
}

CActorBase::~CActorBase()
{
	m_pDummy->SetObject(NULL);
	delete m_pObject;
	delete m_pDummy;
}

void CActorBase::SetEnabled(int enable)
{
	m_nEnable = enable;
	m_pDummy->SetEnabled(m_nEnable);
}

int CActorBase::IsEnabled() const
{
	return m_nEnable;
}
void CActorBase::Update(float ifps)
{
	if (!m_nEnable)
	{
		return;
	}

	// impulse
	vec3 impulse = vec3_zero;

	// ortho basis
	vec3 tangent, binormal;
	OrthoBasis(m_vUp, tangent, binormal);

	// current basis
	vec3 x = quat(m_vUp, -m_fPhiAngle) * binormal;
	vec3 y = Normalize(Cross(m_vUp, x));
	vec3 z = Normalize(Cross(x, y));

	handle states
		Update_States(1, ifps);

	// old velocity
	float x_velocity = Dot(x, m_vVelocity);
	float y_velocity = Dot(y, m_vVelocity);
	float z_velocity = Dot(z, m_vVelocity);
	// movement
	if (m_pStates[STATE_FORWARD]) impulse += x;
	if (m_pStates[STATE_BACKWARD]) impulse -= x;
	if (m_pStates[STATE_MOVE_LEFT]) impulse += y;
	if (m_pStates[STATE_MOVE_RIGHT]) impulse -= y;
	impulse.normalize();
	//velocity
	if (m_pStates[STATE_RUN])
		impulse *= m_fMaxVelocity;
	else
		impulse *= m_fMinVelocity;
	// jump
	if (m_pStates[STATE_JUMP] == STATE_BEGIN)
	{
		impulse += z * CMathCore::Sqrt(2.0f * 9.8f * m_fJumping) / (m_fAcceleration * ifps);
	}

	// rotate velocity
	if (GetGround())
	{
		m_vVelocity = x * x_velocity + y * y_velocity + z * z_velocity;
	}

	// time
	float time = ifps * g_Engine.pPhysics->GetScale();

	// target velocity
	float target_velocity = Length(vec2(Dot(x, impulse), Dot(y, impulse)));

	// penetration tolerance
	float penetration = g_Engine.pPhysics->GetPenetrationTolerance();
	float penetration_2 = penetration * 2.0f;

	// frozen linear velocity
	float frozen_velocity = g_Engine.pPhysics->GetFrozenLinearVelocity();

	// friction
	float friction = 0.0f;
	if (target_velocity < EPSILON)
	{
		friction = m_fFriction;
	}

	//clear collision flags
	if (GetCollision())
	{
		m_nGround = 0;
		m_nCeiling = 0;
	}
	// movement
	do
	{
		// adaptive time step
		float ifps = Min(time, ACTOR_BASE_IFPS);
		time -= ifps;

		// save old velocity
		float old_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));

		// integrate velocity
		m_vVelocity += impulse * (m_fAcceleration * ifps);
		m_vVelocity += g_Engine.pPhysics->GetGravity() * ifps;

		// damping
		float current_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));
		if (target_velocity < EPSILON || current_velocity > target_velocity)
		{
			m_vVelocity = (x * Dot(x, m_vVelocity) + y * Dot(y, m_vVelocity)) * CMathCore::Exp(-m_fDamping * ifps) + z * Dot(z, m_vVelocity);
		}

		// clamp maximum velocity
		current_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));
		if (current_velocity > old_velocity)
		{
			if (current_velocity > target_velocity)
			{
				m_vVelocity = (x * Dot(x, m_vVelocity) + y * Dot(y, m_vVelocity)) * target_velocity / current_velocity + z * Dot(z, m_vVelocity);
			}
		}

		// frozen velocity
		int is_frozen = 0;
		if (current_velocity < frozen_velocity)
		{
			m_vVelocity = z * Dot(z, m_vVelocity);
			is_frozen = 1;
		}

		// integrate position
		//m_vPosition += Vec3(m_vVelocity * ifps);

		// world collision
		if (GetCollision())
		{
			// get collision
			vec3 tangent, binormal;
			const Vec3 *caps = m_pShape->GetCaps();
			for (int i = 0; i < ACTOR_BASE_COLLISIONS; i++)
			{
				m_pDummy->SetTransform(Get_Body_Transform());
				m_pShape->GetCollision(m_vecContacts, 0.0f);
				if (m_vecContacts.Size() == 0) break;
				float inum_contacts = 1.0f / CMathCore::Itof(m_vecContacts.Size());
				for (int j = 0; j < m_vecContacts.Size(); j++)
				{
					const CShape::Contact &c = m_vecContacts[j];

					vec3 normalCollision = c.normal;

					if (is_frozen && c.depth < penetration_2)
					{
						m_vPosition += Vec3(z * (Max(c.depth - penetration, 0.0f) * inum_contacts * Dot(z, normalCollision)));
					}
					else
					{
						m_vPosition += Vec3(normalCollision * (Max(c.depth - penetration, 0.0f) * inum_contacts));
						is_frozen = 0;
					}
					float normal_velocity = Dot(normalCollision, m_vVelocity);
					if (normal_velocity < 0.0f)
					{
						m_vVelocity -= normalCollision * normal_velocity;
					}
					if (friction > EPSILON)
					{
						OrthoBasis(c.normal, tangent, binormal);
						float tangent_velocity = Dot(tangent, m_vVelocity);
						float binormal_velocity = Dot(binormal, m_vVelocity);
						if (CMathCore::Abs(tangent_velocity) > EPSILON || CMathCore::Abs(binormal_velocity) > EPSILON) {
							float friction_velocity = Clamp(Max(-normal_velocity, 0.0f) * friction * CMathCore::RSqrt(tangent_velocity * tangent_velocity + binormal_velocity * binormal_velocity), -1.0f, 1.0f);
							m_vVelocity -= tangent * tangent_velocity * friction_velocity;
							m_vVelocity -= binormal * binormal_velocity * friction_velocity;
						}
					}
					if (Dot(c.normal, m_vUp) > 0.5f && Dot(vec3(c.point - caps[0]), m_vUp) < 0.0f) m_nGround = 1;
					if (Dot(c.normal, m_vUp) < -0.5f && Dot(vec3(c.point - caps[1]), m_vUp) > 0.0f) m_nCeiling = 1;
				}
			}

			m_vPosition += Vec3(m_vVelocity * ifps);
		}
		while (time > EPSILON);

		// current position
		m_pObject->SetWorldTransform(Get_Body_Transform());
		m_WorldBoundBox.Set(m_BoundBox, Translate(m_vPosition));
		m_WorldBoundSphere.Set(m_BoundSphere, Translate(m_vPosition));
	}
}

/*
*/
void CActorBase::Update_Bounds()
{
	float radius = m_pShape->GetRadius();
	float hheight = m_pShape->GetHHeight();
	m_BoundBox.Set(vec3(-radius, -radius, 0.0f), vec3(radius, radius, (radius + hheight) * 2.0f));
	m_BoundSphere.Set(vec3(0.0f, 0.0f, radius + hheight), radius + hheight);

	m_WorldBoundBox.Set(m_BoundBox, Translate(m_vPosition));
	m_WorldBoundSphere.Set(m_BoundSphere, Translate(m_vPosition));
}

/*
*/
void CActorBase::SetIntersectionMask(int mask)
{
	m_pShape->SetIntersectionMask(mask);
}

int CActorBase::GetIntersectionMask() const
{
	return m_pShape->GetIntersectionMask();
}

/*
*/
void CActorBase::SetCollision(int c)
{
	m_nCollision = c;
}

int CActorBase::GetCollision() const
{
	return m_nCollision;
}
void CActorBase::SetCollisionMask(int mask)
{
	m_pShape->SetCollisionMask(mask);
}

int CActorBase::GetCollisionMask() const
{
	return m_pShape->GetCollisionMask();
}
void CActorBase::SetCollisionRadius(float radius)
{
	if (!Compare(m_pShape->GetRadius(), radius))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (radius - m_pShape->GetRadius()))) * m_pDummy->GetTransform());
		m_pShape->SetRadius(radius);
	}
	Update_Bounds();
}

float CActorBase::GetCollisionRadius() const
{
	return m_pShape->GetRadius();
}

/*
*/
void CActorBase::SetCollisionHeight(float height)
{
	if (!Compare(m_pShape->GetHeight(), height))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (height - m_pShape->GetHeight()) * 0.5f)) * m_pDummy->GetTransform());
		m_pShape->SetHeight(height);
	}
	Update_Bounds();
}
float CActorBase::GetCollisionHeight() const
{
	return m_pShape->GetHeight();
}

void CActorBase::SetMinVelocity(float velocity)
{
	m_fMinVelocity = Max(velocity, 0.0f);
}
float CActorBase::GetMinVelocity() const
{
	return m_fMinVelocity;
}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "Engine.h"
#include "Game.h"
#include "ObjectDummy.h"
#include "BodyRigid.h"
#include "BodyDummy.h"
#include "Physics.h"
#include "ShapeCapsule.h"
#include "ActorBase.h"
#include "Visualizer.h"
#include "sys/SysControl.h"

using namespace MathLib;

#ifdef MEMORY_INFO
#define new new(__FILE__, __LINE__)
#endif // MEMORY_INFO

/*
*/
#define ACTOR_BASE_IFPS             (1.0f / 60.0f)
#define ACTOR_BASE_CLAMP            89.9f
#define ACTOR_BASE_COLLISIONS       4

/*
*/
CActorBase::CActorBase()
{
	m_vUp = vec3(0.0f, 0.0f, 1.0f);
	m_pObject = new CObjectDummy();
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(1.0f, 1.0f);

	m_nFlush = 0;
	m_vPosition = Vec3_zero;
	m_vVelocity = Vec3_zero;
	m_fPhiAngle = 0.0f;			//倾斜角		二维平面坐标系中，直线向Y周延伸的方向与X轴正向之间的夹角
	m_fThetaAngle = 0.0f;			//方位角，正北方那条线与当前线条按照顺时针走过的角度

	for (int i = 0; i < NUM_STATES; i++)
	{
		m_pStates[i] = 0;
		m_pTimes[i] = 0.0f;
	}
	m_pDummy->SetEnabled(1);
	m_pObject->SetBody(NULL);
	m_pObject->SetBody(m_pDummy);
	m_pShape->SetBody(NULL);
	m_pShape->SetBody(m_pDummy);

	m_pObject->SetWorldTransform(Get_Body_Transform());
	m_pShape->SetRestitution(0.0f);
	m_pShape->SetCollisionMask(2);

	SetEnabled(1);
	SetViewDirection(vec3(0.0f, 1.0f, 0.0f));
	SetCollision(1);
	SetCollisionRadius(0.3f);
	SetCollisionHeight(1.0f);
	SetFriction(2.0f);
	SetMinVelocity(2.0f);
	SetMaxVelocity(4.0f);
	SetAcceleration(8.0f);
	SetDamping(8.0f);
	SetJumping(1.5f);

	SetGround(0);
	SetCeiling(0);
}

CActorBase::~CActorBase()
{
	m_pDummy->SetObject(NULL);
	delete m_pObject;
	delete m_pDummy;
}

void CActorBase::SetEnabled(int enable)
{
	m_nEnable = enable;
	m_pDummy->SetEnabled(m_nEnable);
}

int CActorBase::IsEnabled() const
{
	return m_nEnable;
}
void CActorBase::Update(float ifps)
{
	if (!m_nEnable)
	{
		return;
	}

	// impulse
	vec3 impulse = vec3_zero;

	// ortho basis
	vec3 tangent, binormal;
	OrthoBasis(m_vUp, tangent, binormal);

	// current basis
	vec3 x = quat(m_vUp, -m_fPhiAngle) * binormal;
	vec3 y = Normalize(Cross(m_vUp, x));
	vec3 z = Normalize(Cross(x, y));

	handle states
		Update_States(1, ifps);

	// old velocity
	float x_velocity = Dot(x, m_vVelocity);
	float y_velocity = Dot(y, m_vVelocity);
	float z_velocity = Dot(z, m_vVelocity);
	// movement
	if (m_pStates[STATE_FORWARD]) impulse += x;
	if (m_pStates[STATE_BACKWARD]) impulse -= x;
	if (m_pStates[STATE_MOVE_LEFT]) impulse += y;
	if (m_pStates[STATE_MOVE_RIGHT]) impulse -= y;
	impulse.normalize();
	//velocity
	if (m_pStates[STATE_RUN])
		impulse *= m_fMaxVelocity;
	else
		impulse *= m_fMinVelocity;
	// jump
	if (m_pStates[STATE_JUMP] == STATE_BEGIN)
	{
		impulse += z * CMathCore::Sqrt(2.0f * 9.8f * m_fJumping) / (m_fAcceleration * ifps);
	}

	// rotate velocity
	if (GetGround())
	{
		m_vVelocity = x * x_velocity + y * y_velocity + z * z_velocity;
	}

	// time
	float time = ifps * g_Engine.pPhysics->GetScale();

	// target velocity
	float target_velocity = Length(vec2(Dot(x, impulse), Dot(y, impulse)));

	// penetration tolerance
	float penetration = g_Engine.pPhysics->GetPenetrationTolerance();
	float penetration_2 = penetration * 2.0f;

	// frozen linear velocity
	float frozen_velocity = g_Engine.pPhysics->GetFrozenLinearVelocity();

	// friction
	float friction = 0.0f;
	if (target_velocity < EPSILON)
	{
		friction = m_fFriction;
	}

	//clear collision flags
	if (GetCollision())
	{
		m_nGround = 0;
		m_nCeiling = 0;
	}
	// movement
	do
	{
		// adaptive time step
		float ifps = Min(time, ACTOR_BASE_IFPS);
		time -= ifps;

		// save old velocity
		float old_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));

		// integrate velocity
		m_vVelocity += impulse * (m_fAcceleration * ifps);
		m_vVelocity += g_Engine.pPhysics->GetGravity() * ifps;

		// damping
		float current_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));
		if (target_velocity < EPSILON || current_velocity > target_velocity)
		{
			m_vVelocity = (x * Dot(x, m_vVelocity) + y * Dot(y, m_vVelocity)) * CMathCore::Exp(-m_fDamping * ifps) + z * Dot(z, m_vVelocity);
		}

		// clamp maximum velocity
		current_velocity = Length(vec2(Dot(x, m_vVelocity), Dot(y, m_vVelocity)));
		if (current_velocity > old_velocity)
		{
			if (current_velocity > target_velocity)
			{
				m_vVelocity = (x * Dot(x, m_vVelocity) + y * Dot(y, m_vVelocity)) * target_velocity / current_velocity + z * Dot(z, m_vVelocity);
			}
		}

		// frozen velocity
		int is_frozen = 0;
		if (current_velocity < frozen_velocity)
		{
			m_vVelocity = z * Dot(z, m_vVelocity);
			is_frozen = 1;
		}

		// integrate position
		//m_vPosition += Vec3(m_vVelocity * ifps);

		// world collision
		if (GetCollision())
		{
			// get collision
			vec3 tangent, binormal;
			const Vec3 *caps = m_pShape->GetCaps();
			for (int i = 0; i < ACTOR_BASE_COLLISIONS; i++)
			{
				m_pDummy->SetTransform(Get_Body_Transform());
				m_pShape->GetCollision(m_vecContacts, 0.0f);
				if (m_vecContacts.Size() == 0) break;
				float inum_contacts = 1.0f / CMathCore::Itof(m_vecContacts.Size());
				for (int j = 0; j < m_vecContacts.Size(); j++)
				{
					const CShape::Contact &c = m_vecContacts[j];

					vec3 normalCollision = c.normal;

					if (is_frozen && c.depth < penetration_2)
					{
						m_vPosition += Vec3(z * (Max(c.depth - penetration, 0.0f) * inum_contacts * Dot(z, normalCollision)));
					}
					else
					{
						m_vPosition += Vec3(normalCollision * (Max(c.depth - penetration, 0.0f) * inum_contacts));
						is_frozen = 0;
					}
					float normal_velocity = Dot(normalCollision, m_vVelocity);
					if (normal_velocity < 0.0f)
					{
						m_vVelocity -= normalCollision * normal_velocity;
					}
					if (friction > EPSILON)
					{
						OrthoBasis(c.normal, tangent, binormal);
						float tangent_velocity = Dot(tangent, m_vVelocity);
						float binormal_velocity = Dot(binormal, m_vVelocity);
						if (CMathCore::Abs(tangent_velocity) > EPSILON || CMathCore::Abs(binormal_velocity) > EPSILON) {
							float friction_velocity = Clamp(Max(-normal_velocity, 0.0f) * friction * CMathCore::RSqrt(tangent_velocity * tangent_velocity + binormal_velocity * binormal_velocity), -1.0f, 1.0f);
							m_vVelocity -= tangent * tangent_velocity * friction_velocity;
							m_vVelocity -= binormal * binormal_velocity * friction_velocity;
						}
					}
					if (Dot(c.normal, m_vUp) > 0.5f && Dot(vec3(c.point - caps[0]), m_vUp) < 0.0f) m_nGround = 1;
					if (Dot(c.normal, m_vUp) < -0.5f && Dot(vec3(c.point - caps[1]), m_vUp) > 0.0f) m_nCeiling = 1;
				}
			}

			m_vPosition += Vec3(m_vVelocity * ifps);
		}
		while (time > EPSILON);

		// current position
		m_pObject->SetWorldTransform(Get_Body_Transform());
		m_WorldBoundBox.Set(m_BoundBox, Translate(m_vPosition));
		m_WorldBoundSphere.Set(m_BoundSphere, Translate(m_vPosition));
	}
}

/*
*/
void CActorBase::Update_Bounds()
{
	float radius = m_pShape->GetRadius();
	float hheight = m_pShape->GetHHeight();
	m_BoundBox.Set(vec3(-radius, -radius, 0.0f), vec3(radius, radius, (radius + hheight) * 2.0f));
	m_BoundSphere.Set(vec3(0.0f, 0.0f, radius + hheight), radius + hheight);

	m_WorldBoundBox.Set(m_BoundBox, Translate(m_vPosition));
	m_WorldBoundSphere.Set(m_BoundSphere, Translate(m_vPosition));
}

/*
*/
void CActorBase::SetIntersectionMask(int mask)
{
	m_pShape->SetIntersectionMask(mask);
}

int CActorBase::GetIntersectionMask() const
{
	return m_pShape->GetIntersectionMask();
}

/*
*/
void CActorBase::SetCollision(int c)
{
	m_nCollision = c;
}

int CActorBase::GetCollision() const
{
	return m_nCollision;
}
void CActorBase::SetCollisionMask(int mask)
{
	m_pShape->SetCollisionMask(mask);
}

int CActorBase::GetCollisionMask() const
{
	return m_pShape->GetCollisionMask();
}
void CActorBase::SetCollisionRadius(float radius)
{
	if (!Compare(m_pShape->GetRadius(), radius))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (radius - m_pShape->GetRadius()))) * m_pDummy->GetTransform());
		m_pShape->SetRadius(radius);
	}
	Update_Bounds();
}

float CActorBase::GetCollisionRadius() const
{
	return m_pShape->GetRadius();
}

/*
*/
void CActorBase::SetCollisionHeight(float height)
{
	if (!Compare(m_pShape->GetHeight(), height))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (height - m_pShape->GetHeight()) * 0.5f)) * m_pDummy->GetTransform());
		m_pShape->SetHeight(height);
	}
	Update_Bounds();
}
float CActorBase::GetCollisionHeight() const
{
	return m_pShape->GetHeight();
}

void CActorBase::SetMinVelocity(float velocity)
{
	m_fMinVelocity = Max(velocity, 0.0f);
}
float CActorBase::GetMinVelocity() const
{
	return m_fMinVelocity;
}

/*
*/
void CActorBase::SetMaxVelocity(float velocity)
{
	m_fMaxVelocity = Max(velocity, 0.0f);
}<|endoftext|>


<commit_before>/*==========================================================================

  Program:
  Module:    otherTimerLog.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  ==========================================================================*/

// .NAME
// .SECTION Description
// this program tests the TimerLog

#include <stdio.h>
#include "vtkTimerLog.h"
#include "vtkDebugLeaks.h"

void Test(ostream& strm)
{
  // actual test
  float a = 1.0, b = 2.0;
  int i, j;
  strm << "Test vtkTimerLog Start" << endl;
  vtkTimerLog *timer1 = vtkTimerLog::New();

  timer1->SetMaxEntries (5);
  timer1->StartTimer();
  for (j = 0; j < 10; j++)
    {
    timer1->FormatAndMarkEvent("%s%d", "start", j);
    for (i = 0; i < 10000000; i++)
      {
      a *= b;
      }
#ifndef WIN32
    sleep (1);
#else
    Sleep(1000);
#endif
    timer1->FormatAndMarkEvent("%s%d", "end", j);
    }
  timer1->StopTimer();
  strm << "GetElapsedTime: " << timer1->GetElapsedTime() << endl;
  strm << "GetCPUTime: " << timer1->GetCPUTime() << endl;
  timer1->DumpLog( "timing" );
  timer1->ResetLog ();
  unlink("timing");
  timer1->Delete();
  strm << "Test vtkTimerLog End" << endl;
}

int main(int argc, char* argv[])
{
  vtkDebugLeaks::PromptUserOff();

  Test(cout);

  return 0;
}
<commit_msg>ENH: better coverage.<commit_after>/*==========================================================================

  Program:
  Module:    otherTimerLog.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  ==========================================================================*/

// .NAME
// .SECTION Description
// this program tests the TimerLog

#include <stdio.h>
#include "vtkTimerLog.h"
#include "vtkDebugLeaks.h"

void Test(ostream& strm)
{
  // actual test
  float a = 1.0, b = 2.0;
  int i, j;
  strm << "Test vtkTimerLog Start" << endl;
  vtkTimerLog *timer1 = vtkTimerLog::New();

  timer1->SetMaxEntries (3);
  timer1->StartTimer();
  for (j = 0; j < 10; j++)
    {
    timer1->FormatAndMarkEvent("%s%d", "start", j);
    for (i = 0; i < 10000000; i++)
      {
      a *= b;
      }
#ifndef WIN32
    sleep (1);
#else
    Sleep(1000);
#endif
    timer1->FormatAndMarkEvent("%s%d", "end", j);
    }
  timer1->StopTimer();
  strm << *timer1;
  strm << "GetElapsedTime: " << timer1->GetElapsedTime() << endl;
  strm << "GetCPUTime: " << timer1->GetCPUTime() << endl;
  timer1->DumpLog( "timing" );
  timer1->ResetLog ();
  unlink("timing");
  timer1->Delete();
  strm << "Test vtkTimerLog End" << endl;
}

int main(int argc, char* argv[])
{
  vtkDebugLeaks::PromptUserOff();

  Test(cout);

  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Bitsend developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "core.h"
#include "util.h"
#include "main.h"
#include "uint256.h"

std::string COutPoint::ToString() const
{
    return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,64), n);
}

void COutPoint::print() const
{
    LogPrintf("%s\n", ToString());
}

CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, unsigned int nSequenceIn)
{
    prevout = prevoutIn;
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

CTxIn::CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn, unsigned int nSequenceIn)
{
    prevout = COutPoint(hashPrevTx, nOut);
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

std::string CTxIn::ToString() const
{
    std::string str;
    str += "CTxIn(";
    str += prevout.ToString();
    if (prevout.IsNull())
        str += strprintf(", coinbase %s", HexStr(scriptSig));
    else
        str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
    if (nSequence != std::numeric_limits<unsigned int>::max())
        str += strprintf(", nSequence=%u", nSequence);
    str += ")";
    return str;
}

void CTxIn::print() const
{
    LogPrintf("%s\n", ToString());
}

CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
{
    nValue = nValueIn;
    nRounds = -10; // an initial value, should be no way to get this by calculations
    scriptPubKey = scriptPubKeyIn;
}

uint256 CTxOut::GetHash() const
{
    return SerializeHash(*this);
}

std::string CTxOut::ToString() const
{
    return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
}

void CTxOut::print() const
{
    LogPrintf("%s\n", ToString());
}

uint256 CTransaction::GetHash() const
{
    return SerializeHash(*this);
}

bool CTransaction::IsNewerThan(const CTransaction& old) const
{
    if (vin.size() != old.vin.size())
        return false;
    for (unsigned int i = 0; i < vin.size(); i++)
        if (vin[i].prevout != old.vin[i].prevout)
            return false;

    bool fNewer = false;
    unsigned int nLowest = std::numeric_limits<unsigned int>::max();
    for (unsigned int i = 0; i < vin.size(); i++)
    {
        if (vin[i].nSequence != old.vin[i].nSequence)
        {
            if (vin[i].nSequence <= nLowest)
            {
                fNewer = false;
                nLowest = vin[i].nSequence;
            }
            if (old.vin[i].nSequence < nLowest)
            {
                fNewer = true;
                nLowest = old.vin[i].nSequence;
            }
        }
    }
    return fNewer;
}

int64_t CTransaction::GetValueOut() const
{
    int64_t nValueOut = 0;
    BOOST_FOREACH(const CTxOut& txout, vout)
    {
        nValueOut += txout.nValue;
        if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
            throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
    }
    return nValueOut;
}

double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
{
    // In order to avoid disincentivizing cleaning up the UTXO set we don't count
    // the constant overhead for each txin and up to 110 bytes of scriptSig (which
    // is enough to cover a compressed pubkey p2sh redemption) for priority.
    // Providing any more cleanup incentive than making additional inputs free would
    // risk encouraging people to create junk outputs to redeem later.
    if (nTxSize == 0)
        nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
    BOOST_FOREACH(const CTxIn& txin, vin)
    {
        unsigned int offset = 41U + std::min(110U, (unsigned int)txin.scriptSig.size());
        if (nTxSize > offset)
            nTxSize -= offset;
    }
    if (nTxSize == 0) return 0.0;
    return dPriorityInputs / nTxSize;
}

std::string CTransaction::ToString() const
{
    std::string str;
    str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
        GetHash().ToString().substr(0,10),
        nVersion,
        vin.size(),
        vout.size(),
        nLockTime);
    for (unsigned int i = 0; i < vin.size(); i++)
        str += "    " + vin[i].ToString() + "\n";
    for (unsigned int i = 0; i < vout.size(); i++)
        str += "    " + vout[i].ToString() + "\n";
    return str;
}

void CTransaction::print() const
{
    LogPrintf("%s", ToString());
}

// Amount compression:
// * If the amount is 0, output 0
// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10)
//   * call the result n
//   * output 1 + 10*(9*n + d - 1) + e
// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
// (this is decodable, as d is in [1-9] and e is in [0-9])

uint64_t CTxOutCompressor::CompressAmount(uint64_t n)
{
    if (n == 0)
        return 0;
    int e = 0;
    while (((n % 10) == 0) && e < 9) {
        n /= 10;
        e++;
    }
    if (e < 9) {
        int d = (n % 10);
        assert(d >= 1 && d <= 9);
        n /= 10;
        return 1 + (n*9 + d - 1)*10 + e;
    } else {
        return 1 + (n - 1)*10 + 9;
    }
}

uint64_t CTxOutCompressor::DecompressAmount(uint64_t x)
{
    // x = 0  OR  x = 1+10*(9*n + d - 1) + e  OR  x = 1+10*(n - 1) + 9
    if (x == 0)
        return 0;
    x--;
    // x = 10*(9*n + d - 1) + e
    int e = x % 10;
    x /= 10;
    uint64_t n = 0;
    if (e < 9) {
        // x = 9*n + d - 1
        int d = (x % 9) + 1;
        x /= 9;
        // x = n
        n = x*10 + d;
    } else {
        n = x+1;
    }
    while (e) {
        n *= 10;
        e--;
    }
    return n;
}

//BitSend Algoswitch 1
uint256 CBlockHeader::GetHash() const
{

	CChain var1;
	int nHeight= var1.Height();

	if (nHeight <= FORKX17_Main_Net){
	//Debugline BitSendDev
	if(nHeight > 0)	LogPrintf("%d nHeigt We use X11\n", nHeight);
    return HashX11(BEGIN(nVersion), END(nNonce));
	}
    else {
	if(nHeight > 0 )	LogPrintf("%d nHeigt We use X17\n", nHeight);
	   return HashX17(BEGIN(nVersion), END(nNonce));

	}
}
/*
uint256 CBlockHeader::GetHash() const
{
    return HashX11(BEGIN(nVersion), END(nNonce));
}
*/

uint256 CBlock::BuildMerkleTree() const
{
    vMerkleTree.clear();
    BOOST_FOREACH(const CTransaction& tx, vtx)
        vMerkleTree.push_back(tx.GetHash());
    int j = 0;
    for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
    {
        for (int i = 0; i < nSize; i += 2)
        {
            int i2 = std::min(i+1, nSize-1);
            vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
                                       BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
        }
        j += nSize;
    }
    return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
}

std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
{
    if (vMerkleTree.empty())
        BuildMerkleTree();
    std::vector<uint256> vMerkleBranch;
    int j = 0;
    for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
    {
        int i = std::min(nIndex^1, nSize-1);
        vMerkleBranch.push_back(vMerkleTree[j+i]);
        nIndex >>= 1;
        j += nSize;
    }
    return vMerkleBranch;
}

uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
    if (nIndex == -1)
        return 0;
    BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
    {
        if (nIndex & 1)
            hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
        else
            hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
        nIndex >>= 1;
    }
    return hash;
}

void CBlock::print() const
{
	//GetHash2().ToString(),
    LogPrintf("CBlock(hash=disable, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
        nVersion,
        hashPrevBlock.ToString(),
        hashMerkleRoot.ToString(),
        nTime, nBits, nNonce,
        vtx.size());
    for (unsigned int i = 0; i < vtx.size(); i++)
    {
        LogPrintf("  ");
        vtx[i].print();
    }
    LogPrintf("  vMerkleTree: ");
    for (unsigned int i = 0; i < vMerkleTree.size(); i++)
        LogPrintf("%s ", vMerkleTree[i].ToString());
    LogPrintf("\n");
}
<commit_msg>Revert "Commit"<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Bitsend developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "core.h"
#include "util.h"
#include "main.h"
#include "uint256.h"

std::string COutPoint::ToString() const
{
    return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,64), n);
}

void COutPoint::print() const
{
    LogPrintf("%s\n", ToString());
}

CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, unsigned int nSequenceIn)
{
    prevout = prevoutIn;
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

CTxIn::CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn, unsigned int nSequenceIn)
{
    prevout = COutPoint(hashPrevTx, nOut);
    scriptSig = scriptSigIn;
    nSequence = nSequenceIn;
}

std::string CTxIn::ToString() const
{
    std::string str;
    str += "CTxIn(";
    str += prevout.ToString();
    if (prevout.IsNull())
        str += strprintf(", coinbase %s", HexStr(scriptSig));
    else
        str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
    if (nSequence != std::numeric_limits<unsigned int>::max())
        str += strprintf(", nSequence=%u", nSequence);
    str += ")";
    return str;
}

void CTxIn::print() const
{
    LogPrintf("%s\n", ToString());
}

CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn)
{
    nValue = nValueIn;
    nRounds = -10; // an initial value, should be no way to get this by calculations
    scriptPubKey = scriptPubKeyIn;
}

uint256 CTxOut::GetHash() const
{
    return SerializeHash(*this);
}

std::string CTxOut::ToString() const
{
    return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
}

void CTxOut::print() const
{
    LogPrintf("%s\n", ToString());
}

uint256 CTransaction::GetHash() const
{
    return SerializeHash(*this);
}

bool CTransaction::IsNewerThan(const CTransaction& old) const
{
    if (vin.size() != old.vin.size())
        return false;
    for (unsigned int i = 0; i < vin.size(); i++)
        if (vin[i].prevout != old.vin[i].prevout)
            return false;

    bool fNewer = false;
    unsigned int nLowest = std::numeric_limits<unsigned int>::max();
    for (unsigned int i = 0; i < vin.size(); i++)
    {
        if (vin[i].nSequence != old.vin[i].nSequence)
        {
            if (vin[i].nSequence <= nLowest)
            {
                fNewer = false;
                nLowest = vin[i].nSequence;
            }
            if (old.vin[i].nSequence < nLowest)
            {
                fNewer = true;
                nLowest = old.vin[i].nSequence;
            }
        }
    }
    return fNewer;
}

int64_t CTransaction::GetValueOut() const
{
    int64_t nValueOut = 0;
    BOOST_FOREACH(const CTxOut& txout, vout)
    {
        nValueOut += txout.nValue;
        if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
            throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
    }
    return nValueOut;
}

double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const
{
    // In order to avoid disincentivizing cleaning up the UTXO set we don't count
    // the constant overhead for each txin and up to 110 bytes of scriptSig (which
    // is enough to cover a compressed pubkey p2sh redemption) for priority.
    // Providing any more cleanup incentive than making additional inputs free would
    // risk encouraging people to create junk outputs to redeem later.
    if (nTxSize == 0)
        nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);
    BOOST_FOREACH(const CTxIn& txin, vin)
    {
        unsigned int offset = 41U + std::min(110U, (unsigned int)txin.scriptSig.size());
        if (nTxSize > offset)
            nTxSize -= offset;
    }
    if (nTxSize == 0) return 0.0;
    return dPriorityInputs / nTxSize;
}

std::string CTransaction::ToString() const
{
    std::string str;
    str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
        GetHash().ToString().substr(0,10),
        nVersion,
        vin.size(),
        vout.size(),
        nLockTime);
    for (unsigned int i = 0; i < vin.size(); i++)
        str += "    " + vin[i].ToString() + "\n";
    for (unsigned int i = 0; i < vout.size(); i++)
        str += "    " + vout[i].ToString() + "\n";
    return str;
}

void CTransaction::print() const
{
    LogPrintf("%s", ToString());
}

// Amount compression:
// * If the amount is 0, output 0
// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10)
//   * call the result n
//   * output 1 + 10*(9*n + d - 1) + e
// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
// (this is decodable, as d is in [1-9] and e is in [0-9])

uint64_t CTxOutCompressor::CompressAmount(uint64_t n)
{
    if (n == 0)
        return 0;
    int e = 0;
    while (((n % 10) == 0) && e < 9) {
        n /= 10;
        e++;
    }
    if (e < 9) {
        int d = (n % 10);
        assert(d >= 1 && d <= 9);
        n /= 10;
        return 1 + (n*9 + d - 1)*10 + e;
    } else {
        return 1 + (n - 1)*10 + 9;
    }
}

uint64_t CTxOutCompressor::DecompressAmount(uint64_t x)
{
    // x = 0  OR  x = 1+10*(9*n + d - 1) + e  OR  x = 1+10*(n - 1) + 9
    if (x == 0)
        return 0;
    x--;
    // x = 10*(9*n + d - 1) + e
    int e = x % 10;
    x /= 10;
    uint64_t n = 0;
    if (e < 9) {
        // x = 9*n + d - 1
        int d = (x % 9) + 1;
        x /= 9;
        // x = n
        n = x*10 + d;
    } else {
        n = x+1;
    }
    while (e) {
        n *= 10;
        e--;
    }
    return n;
}

//BitSend Algoswitch 1
uint256 CBlockHeader::GetHash() const
{

	CChain var1;
	int nHeight= var1.Height();

	if (nHeight <= FORKX17_Main_Net){
	//Debugline BitSendDev
	if(nHeight > 0)	LogPrintf("%d nHeigt We use X11\n", nHeight);
    return HashX11(BEGIN(nVersion), END(nNonce));
	}
    else {
	if(nHeight > 0 )	LogPrintf("%d nHeigt We use X17\n", nHeight);
	   return HashX17(BEGIN(nVersion), END(nNonce));

	}
}
uint256 CBlockHeader::GetHash() const
{
    return HashX11(BEGIN(nVersion), END(nNonce));
}
*/

uint256 CBlock::BuildMerkleTree() const
{
    vMerkleTree.clear();
    BOOST_FOREACH(const CTransaction& tx, vtx)
        vMerkleTree.push_back(tx.GetHash());
    int j = 0;
    for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
    {
        for (int i = 0; i < nSize; i += 2)
        {
            int i2 = std::min(i+1, nSize-1);
            vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]),  END(vMerkleTree[j+i]),
                                       BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2])));
        }
        j += nSize;
    }
    return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
}

std::vector<uint256> CBlock::GetMerkleBranch(int nIndex) const
{
    if (vMerkleTree.empty())
        BuildMerkleTree();
    std::vector<uint256> vMerkleBranch;
    int j = 0;
    for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2)
    {
        int i = std::min(nIndex^1, nSize-1);
        vMerkleBranch.push_back(vMerkleTree[j+i]);
        nIndex >>= 1;
        j += nSize;
    }
    return vMerkleBranch;
}

uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
    if (nIndex == -1)
        return 0;
    BOOST_FOREACH(const uint256& otherside, vMerkleBranch)
    {
        if (nIndex & 1)
            hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash));
        else
            hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside));
        nIndex >>= 1;
    }
    return hash;
}

void CBlock::print() const
{
	//GetHash2().ToString(),
    LogPrintf("CBlock(hash=disable, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
        nVersion,
        hashPrevBlock.ToString(),
        hashMerkleRoot.ToString(),
        nTime, nBits, nNonce,
        vtx.size());
    for (unsigned int i = 0; i < vtx.size(); i++)
    {
        LogPrintf("  ");
        vtx[i].print();
    }
    LogPrintf("  vMerkleTree: ");
    for (unsigned int i = 0; i < vMerkleTree.size(); i++)
        LogPrintf("%s ", vMerkleTree[i].ToString());
    LogPrintf("\n");
}
<|endoftext|>


<commit_before>/* BSD 2-Clause License

Copyright (c) 2016, Doi Yusuke
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstring> // for memset
#include <sstream> // for error massage
#include <stdexcept>
#include <unordered_map> // for cashe
#include <fcntl.h> // for open FLAGS
#include <unistd.h> // for tty checks

#include "core.hpp"

template<typename T, typename... Args>
inline std::unique_ptr<T> make_unique(Args&&... args)
{
  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

ics::Core::Core(const std::string& path, speed_t baudrate)
: fd {open(path.c_str(), O_RDWR | O_NOCTTY)},
  oldTio {}
{
  if (fd < 0)
    throw std::runtime_error {"Cannot open deveice"};
  try {
    if (!isatty(fd))
      throw std::invalid_argument {"Not tty device"};
    if (tcgetattr(fd, &oldTio) < 0)
      throw std::runtime_error {"Cannot setup tty"};
    auto newTio = getTermios(); // forward reference
    if (cfsetispeed(&newTio, baudrate) < 0)
      throw std::runtime_error {"Cannot set baudrate"};
    if (cfsetospeed(&newTio, baudrate) < 0)
      throw std::runtime_error {"Cannot set baudrate"};
    if (tcsetattr(fd, TCSANOW, &newTio) < 0)
      throw std::runtime_error {"Cannot setup tty"};
  } catch (...) {
    close(fd);
    throw;
  }
}

ics::Core::~Core() noexcept
{
  if (fd < 0) return;
  closeThis();
}

ics::Core::Core(Core&& rhs) noexcept
: fd {rhs.fd},
  oldTio(rhs.oldTio) // for Ubuntu14.04 compiler
{
  rhs.fd = -1;
}

ics::Core& ics::Core::operator=(Core&& rhs) noexcept
{
  if (fd != rhs.fd) {
    closeThis();
    fd = rhs.fd;
    oldTio = rhs.oldTio;
    rhs.fd = -1;
  }
  return *this;
}

std::unique_ptr<ics::Core> ics::Core::getCore(const std::string& path, speed_t baudrate)
{
  return make_unique<Core>(path, baudrate);
}

void ics::Core::communicate(const Container& tx, Container& rx)
{
  write(fd, tx.data(), tx.size()); // send
  for (auto& receive : rx) read(fd, &receive, 1); // receive
// check section
  auto receive = rx.cbegin();
  for (const auto& send : tx) {
    if (send != *receive) {
      std::stringstream ss;
      ss << "Receive falied(loopback):" << receive - rx.cbegin() << ':' << static_cast<int>(send) << "<->" << static_cast<int>(*receive);
      throw std::runtime_error {ss.str()};
    }
    ++receive;
  }
}

void ics::Core::communicateID(const IDContainerTx& tx, IDContainerRx& rx)
{
  write(fd, tx.data(), tx.size()); // send
  for (auto& receive : rx) read(fd, &receive, 1); // receive
// check section
  auto receive = rx.cbegin();
  for (const auto& send : tx) {
    if (send != *receive) {
      std::stringstream ss;
      ss << "Receive falied(loopback):" << receive - rx.cbegin() << ':' << static_cast<int>(send) << "<->" << static_cast<int>(*receive);
      throw std::runtime_error {ss.str()};
    }
    ++receive;
  }
  if ((tx[0] & 0xE0) != (*receive & 0xE0)) throw std::runtime_error {"Receive failed: invalid target data"};
}

void ics::Core::closeThis() const noexcept
{
  tcsetattr(fd, TCSANOW, &oldTio);
  close(fd);
}

termios ics::Core::getTermios() noexcept
{
  termios newTio;
  std::memset(&newTio, 0, sizeof(newTio));
  newTio.c_iflag = 0;
  newTio.c_oflag = 0;
  newTio.c_cflag = CS8 | CREAD | CLOCAL | PARENB;
  newTio.c_lflag = 0;
  newTio.c_cc[VMIN] = 1;
  newTio.c_cc[VTIME] = 1;
  return newTio;
}
<commit_msg>Remove my make_unique function<commit_after>/* BSD 2-Clause License

Copyright (c) 2016, Doi Yusuke
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cstring> // for memset
#include <sstream> // for error massage
#include <stdexcept>
#include <unordered_map> // for cashe
#include <fcntl.h> // for open FLAGS
#include <unistd.h> // for tty checks

#include "core.hpp"

ics::Core::Core(const std::string& path, speed_t baudrate)
: fd {open(path.c_str(), O_RDWR | O_NOCTTY)},
  oldTio {}
{
  if (fd < 0)
    throw std::runtime_error {"Cannot open deveice"};
  try {
    if (!isatty(fd))
      throw std::invalid_argument {"Not tty device"};
    if (tcgetattr(fd, &oldTio) < 0)
      throw std::runtime_error {"Cannot setup tty"};
    auto newTio = getTermios(); // forward reference
    if (cfsetispeed(&newTio, baudrate) < 0)
      throw std::runtime_error {"Cannot set baudrate"};
    if (cfsetospeed(&newTio, baudrate) < 0)
      throw std::runtime_error {"Cannot set baudrate"};
    if (tcsetattr(fd, TCSANOW, &newTio) < 0)
      throw std::runtime_error {"Cannot setup tty"};
  } catch (...) {
    close(fd);
    throw;
  }
}

ics::Core::~Core() noexcept
{
  if (fd < 0) return;
  closeThis();
}

ics::Core::Core(Core&& rhs) noexcept
: fd {rhs.fd},
  oldTio(rhs.oldTio) // for Ubuntu14.04 compiler
{
  rhs.fd = -1;
}

ics::Core& ics::Core::operator=(Core&& rhs) noexcept
{
  if (fd != rhs.fd) {
    closeThis();
    fd = rhs.fd;
    oldTio = rhs.oldTio;
    rhs.fd = -1;
  }
  return *this;
}

std::unique_ptr<ics::Core> ics::Core::getCore(const std::string& path, speed_t baudrate)
{
  return std::unique_ptr<Core>(path, baudrate);
}

void ics::Core::communicate(const Container& tx, Container& rx)
{
  write(fd, tx.data(), tx.size()); // send
  for (auto& receive : rx) read(fd, &receive, 1); // receive
// check section
  auto receive = rx.cbegin();
  for (const auto& send : tx) {
    if (send != *receive) {
      std::stringstream ss;
      ss << "Receive falied(loopback):" << receive - rx.cbegin() << ':' << static_cast<int>(send) << "<->" << static_cast<int>(*receive);
      throw std::runtime_error {ss.str()};
    }
    ++receive;
  }
}

void ics::Core::communicateID(const IDContainerTx& tx, IDContainerRx& rx)
{
  write(fd, tx.data(), tx.size()); // send
  for (auto& receive : rx) read(fd, &receive, 1); // receive
// check section
  auto receive = rx.cbegin();
  for (const auto& send : tx) {
    if (send != *receive) {
      std::stringstream ss;
      ss << "Receive falied(loopback):" << receive - rx.cbegin() << ':' << static_cast<int>(send) << "<->" << static_cast<int>(*receive);
      throw std::runtime_error {ss.str()};
    }
    ++receive;
  }
  if ((tx[0] & 0xE0) != (*receive & 0xE0)) throw std::runtime_error {"Receive failed: invalid target data"};
}

void ics::Core::closeThis() const noexcept
{
  tcsetattr(fd, TCSANOW, &oldTio);
  close(fd);
}

termios ics::Core::getTermios() noexcept
{
  termios newTio;
  std::memset(&newTio, 0, sizeof(newTio));
  newTio.c_iflag = 0;
  newTio.c_oflag = 0;
  newTio.c_cflag = CS8 | CREAD | CLOCAL | PARENB;
  newTio.c_lflag = 0;
  newTio.c_cc[VMIN] = 1;
  newTio.c_cc[VTIME] = 1;
  return newTio;
}
<|endoftext|>


<commit_before>//
//  Copyright (C) 2015  Clifford Wolf <clifford@clifford.at>
//
//  Permission to use, copy, modify, and/or distribute this software for any
//  purpose with or without fee is hereby granted, provided that the above
//  copyright notice and this permission notice appear in all copies.
//
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
//  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
//  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
//  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
//  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
//  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>

const char *binstr(int v, int n)
{
	static char buffer[16];
	char *p = buffer;

	for (int i = n-1; i >= 0; i--)
		*(p++) = ((v >> i) & 1) ? '1' : '0';
	*(p++) = 0;

	return buffer;
}

void help(const char *cmd)
{
	printf("\n");
	printf("Usage: %s [options]\n", cmd);
	printf("\n");
	printf("    -i <input_freq_mhz>\n");
	printf("        PLL Input Frequency (default: 12 MHz)\n");
	printf("\n");
	printf("    -o <output_freq_mhz>\n");
	printf("        PLL Output Frequency (default: 60 MHz)\n");
	printf("\n");
	printf("    -S\n");
	printf("        Disable SIMPLE feedback path mode\n");
	printf("\n");
	printf("    -f <filename.v>\n");
	printf("        Save PLL configuration as Verilog module\n");
	printf("\n");
	printf("    -q\n");
	printf("        Do not print PLL configuration to stdout\n");
	printf("\n");
	exit(1);
}

int main(int argc, char **argv)
{
	double f_pllin = 12;
	double f_pllout = 60;
	bool simple_feedback = true;
	char* verilog_filename = NULL;
	bool quiet = false;

	int opt;
	while ((opt = getopt(argc, argv, "i:o:S:f:q")) != -1)
	{
		switch (opt)
		{
		case 'i':
			f_pllin = atof(optarg);
			break;
		case 'o':
			f_pllout = atof(optarg);
			break;
		case 'S':
			simple_feedback = false;
			break;
		case 'f':
			verilog_filename = optarg;
			break;
		case 'q':
			quiet = true;
			break;
		default:
			help(argv[0]);
		}
	}

	if (optind != argc)
		help(argv[0]);

	bool found_something = false;
	double best_fout = 0;
	int best_divr = 0;
	int best_divf = 0;
	int best_divq = 0;

	if (f_pllin < 10 || f_pllin > 133) {
		fprintf(stderr, "Error: PLL input frequency %.3f MHz is outside range 10 MHz - 133 MHz!\n", f_pllin);
		exit(1);
	}

	if (f_pllout < 16 || f_pllout > 275) {
		fprintf(stderr, "Error: PLL output frequency %.3f MHz is outside range 16 MHz - 275 MHz!\n", f_pllout);
		exit(1);
	}

	for (int divr = 0; divr <= 15; divr++)
	{
		double f_pfd = f_pllin / (divr + 1);
		if (f_pfd < 10 || f_pfd > 133) continue;

		for (int divf = 0; divf <= 63; divf++)
		{
			if (simple_feedback)
			{
				double f_vco = f_pfd * (divf + 1);
				if (f_vco < 533 || f_vco > 1066) continue;

				for (int divq = 1; divq <= 6; divq++)
				{
					double fout = f_vco * exp2(-divq);

					if (fabs(fout - f_pllout) < fabs(best_fout - f_pllout) || !found_something) {
						best_fout = fout;
						best_divr = divr;
						best_divf = divf;
						best_divq = divq;
						found_something = true;
					}
				}
			}
			else
			{
				for (int divq = 1; divq <= 6; divq++)
				{
					double f_vco = f_pfd * (divf + 1) * exp2(divq);
					if (f_vco < 533 || f_vco > 1066) continue;

					double fout = f_vco * exp2(-divq);

					if (fabs(fout - f_pllout) < fabs(best_fout - f_pllout) || !found_something) {
						best_fout = fout;
						best_divr = divr;
						best_divf = divf;
						best_divq = divq;
						found_something = true;
					}
				}
			}
		}
	}

	double f_pfd = f_pllin / (best_divr + 1);;
	double f_vco = f_pfd * (best_divf + 1);

	int filter_range =
			f_pfd < 17 ? 1 :
			f_pfd < 26 ? 2 :
			f_pfd < 44 ? 3 :
			f_pfd < 66 ? 4 :
			f_pfd < 101 ? 5 : 6;

	if (!simple_feedback)
		f_vco *= exp2(best_divq);

	if (!found_something) {
		fprintf(stderr, "Error: No valid configuration found!\n");
		exit(1);
	}

	if (!quiet)
	{
		printf("\n");

		printf("F_PLLIN:  %8.3f MHz (given)\n", f_pllin);
		printf("F_PLLOUT: %8.3f MHz (requested)\n", f_pllout);
		printf("F_PLLOUT: %8.3f MHz (achieved)\n", best_fout);

		printf("\n");

		printf("FEEDBACK: %s\n", simple_feedback ? "SIMPLE" : "NON_SIMPLE");
		printf("F_PFD: %8.3f MHz\n", f_pfd);
		printf("F_VCO: %8.3f MHz\n", f_vco);

		printf("\n");

		printf("DIVR: %2d (4'b%s)\n", best_divr, binstr(best_divr, 4));
		printf("DIVF: %2d (7'b%s)\n", best_divf, binstr(best_divf, 7));
		printf("DIVQ: %2d (3'b%s)\n", best_divq, binstr(best_divq, 3));

		printf("\n");

		printf("FILTER_RANGE: %d (3'b%s)\n", filter_range, binstr(filter_range, 3));

		printf("\n");
	}

	if (verilog_filename != NULL)
	{
		// open file for writing
		FILE *f;
		f = fopen(verilog_filename, "w");

		// header
		fprintf(f, "/**\n * PLL configuration\n *\n"
					" * This Verilog source file was generated automatically\n"
					" * using the icepll tool from the IceStorm project.\n"
					" * Use at your own risk.\n"
					" *\n"
					" * Given input frequency:      %8.3f MHz\n"
					" * Requested output frequency: %8.3f MHz\n"
					" * Achieved output frequency:  %8.3f MHz\n"
					" */\n\n",
					f_pllin, f_pllout, best_fout);

		// generate Verilog module
		fprintf(f,  "module pll(\n"
					"\tinput  clock_in,\n"
					"\toutput clock_out,\n"
					"\toutput locked\n"
					"\t)\n\n"
				);

		// save iCE40 PLL tile configuration
		fprintf(f, "SB_PLL40_CORE #(\n");
		fprintf(f, "\t\t.FEEDBACK_PATH(\"%s\"),\n", (simple_feedback ? "SIMPLE" : "NON_SIMPLE"));
		fprintf(f, "\t\t.PLLOUT_SELECT(\"GENCLK\"),\n");
		fprintf(f, "\t\t.DIVR(4'b%s),\n", binstr(best_divr, 4));
		fprintf(f, "\t\t.DIVF(7'b%s),\n", binstr(best_divf, 7));
		fprintf(f, "\t\t.DIVQ(3'b%s),\n", binstr(best_divq, 3));
		fprintf(f, "\t\t.FILTER_RANGE(3'b%s),\n", binstr(filter_range, 3));
		fprintf(f, "\t) uut (\n"
					"\t\t.LOCK(locked),\n"
					"\t\t.RESETB(1'b1),\n"
					"\t\t.BYPASS(1'b0),\n"
					"\t\t.REFERENCECLK(clock_in),\n"
					"\t\t.PLLOUTCORE(clock_out),\n"
					"\t\t);\n\n"
				);

		fprintf(f, "endmodule\n");
		fclose(f);

		printf("PLL configuration written to: %s\n", verilog_filename);
	}

	return 0;
}
<commit_msg>icepll: added -m option to choose between saving Verilog header or module<commit_after>//
//  Copyright (C) 2015  Clifford Wolf <clifford@clifford.at>
//
//  Permission to use, copy, modify, and/or distribute this software for any
//  purpose with or without fee is hereby granted, provided that the above
//  copyright notice and this permission notice appear in all copies.
//
//  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
//  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
//  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
//  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
//  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
//  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>

const char *binstr(int v, int n)
{
	static char buffer[16];
	char *p = buffer;

	for (int i = n-1; i >= 0; i--)
		*(p++) = ((v >> i) & 1) ? '1' : '0';
	*(p++) = 0;

	return buffer;
}

void help(const char *cmd)
{
	printf("\n");
	printf("Usage: %s [options]\n", cmd);
	printf("\n");
	printf("    -i <input_freq_mhz>\n");
	printf("        PLL Input Frequency (default: 12 MHz)\n");
	printf("\n");
	printf("    -o <output_freq_mhz>\n");
	printf("        PLL Output Frequency (default: 60 MHz)\n");
	printf("\n");
	printf("    -S\n");
	printf("        Disable SIMPLE feedback path mode\n");
	printf("\n");
	printf("    -f <filename>\n");
	printf("        Save PLL configuration as Verilog to file\n");
	printf("\n");
	printf("    -m\n");
	printf("        Save PLL configuration as Verilog module (use with -f)\n");
	printf("\n");
	printf("    -q\n");
	printf("        Do not print PLL configuration to stdout\n");
	printf("\n");
	exit(1);
}

int main(int argc, char **argv)
{
	double f_pllin = 12;
	double f_pllout = 60;
	bool simple_feedback = true;
	char* filename = NULL;
	bool save_as_module = false;
	bool quiet = false;

	int opt;
	while ((opt = getopt(argc, argv, "i:o:S:mf:q")) != -1)
	{
		switch (opt)
		{
		case 'i':
			f_pllin = atof(optarg);
			break;
		case 'o':
			f_pllout = atof(optarg);
			break;
		case 'S':
			simple_feedback = false;
			break;
		case 'm':
			save_as_module = true;
			break;
		case 'f':
			filename = optarg;
			break;
		case 'q':
			quiet = true;
			break;
		default:
			help(argv[0]);
		}
	}

	if (optind != argc)
		help(argv[0]);

	// error: shall save as module, but no filename was given
	if (save_as_module && filename == NULL)
		help(argv[0]);

	bool found_something = false;
	double best_fout = 0;
	int best_divr = 0;
	int best_divf = 0;
	int best_divq = 0;

	if (f_pllin < 10 || f_pllin > 133) {
		fprintf(stderr, "Error: PLL input frequency %.3f MHz is outside range 10 MHz - 133 MHz!\n", f_pllin);
		exit(1);
	}

	if (f_pllout < 16 || f_pllout > 275) {
		fprintf(stderr, "Error: PLL output frequency %.3f MHz is outside range 16 MHz - 275 MHz!\n", f_pllout);
		exit(1);
	}

	for (int divr = 0; divr <= 15; divr++)
	{
		double f_pfd = f_pllin / (divr + 1);
		if (f_pfd < 10 || f_pfd > 133) continue;

		for (int divf = 0; divf <= 63; divf++)
		{
			if (simple_feedback)
			{
				double f_vco = f_pfd * (divf + 1);
				if (f_vco < 533 || f_vco > 1066) continue;

				for (int divq = 1; divq <= 6; divq++)
				{
					double fout = f_vco * exp2(-divq);

					if (fabs(fout - f_pllout) < fabs(best_fout - f_pllout) || !found_something) {
						best_fout = fout;
						best_divr = divr;
						best_divf = divf;
						best_divq = divq;
						found_something = true;
					}
				}
			}
			else
			{
				for (int divq = 1; divq <= 6; divq++)
				{
					double f_vco = f_pfd * (divf + 1) * exp2(divq);
					if (f_vco < 533 || f_vco > 1066) continue;

					double fout = f_vco * exp2(-divq);

					if (fabs(fout - f_pllout) < fabs(best_fout - f_pllout) || !found_something) {
						best_fout = fout;
						best_divr = divr;
						best_divf = divf;
						best_divq = divq;
						found_something = true;
					}
				}
			}
		}
	}

	double f_pfd = f_pllin / (best_divr + 1);;
	double f_vco = f_pfd * (best_divf + 1);

	int filter_range =
			f_pfd < 17 ? 1 :
			f_pfd < 26 ? 2 :
			f_pfd < 44 ? 3 :
			f_pfd < 66 ? 4 :
			f_pfd < 101 ? 5 : 6;

	if (!simple_feedback)
		f_vco *= exp2(best_divq);

	if (!found_something) {
		fprintf(stderr, "Error: No valid configuration found!\n");
		exit(1);
	}

	if (!quiet)
	{
		printf("\n");

		printf("F_PLLIN:  %8.3f MHz (given)\n", f_pllin);
		printf("F_PLLOUT: %8.3f MHz (requested)\n", f_pllout);
		printf("F_PLLOUT: %8.3f MHz (achieved)\n", best_fout);

		printf("\n");

		printf("FEEDBACK: %s\n", simple_feedback ? "SIMPLE" : "NON_SIMPLE");
		printf("F_PFD: %8.3f MHz\n", f_pfd);
		printf("F_VCO: %8.3f MHz\n", f_vco);

		printf("\n");

		printf("DIVR: %2d (4'b%s)\n", best_divr, binstr(best_divr, 4));
		printf("DIVF: %2d (7'b%s)\n", best_divf, binstr(best_divf, 7));
		printf("DIVQ: %2d (3'b%s)\n", best_divq, binstr(best_divq, 3));

		printf("\n");

		printf("FILTER_RANGE: %d (3'b%s)\n", filter_range, binstr(filter_range, 3));

		printf("\n");
	}

	// save PLL configuration as file
	if (filename != NULL)
	{
		// open file for writing
		FILE *f;
		f = fopen(filename, "w");

		if (save_as_module)
		{
			// save PLL configuration as Verilog module

			// header
			fprintf(f, "/**\n * PLL configuration\n *\n"
						" * This Verilog module was generated automatically\n"
						" * using the icepll tool from the IceStorm project.\n"
						" * Use at your own risk.\n"
						" *\n"
						" * Given input frequency:      %8.3f MHz\n"
						" * Requested output frequency: %8.3f MHz\n"
						" * Achieved output frequency:  %8.3f MHz\n"
						" */\n\n",
						f_pllin, f_pllout, best_fout);

			// generate Verilog module
			fprintf(f,  "module pll(\n"
						"\tinput  clock_in,\n"
						"\toutput clock_out,\n"
						"\toutput locked\n"
						"\t);\n\n"
					);

			// save iCE40 PLL tile configuration
			fprintf(f, "SB_PLL40_CORE #(\n");
			fprintf(f, "\t\t.FEEDBACK_PATH(\"%s\"),\n", (simple_feedback ? "SIMPLE" : "NON_SIMPLE"));
			fprintf(f, "\t\t.PLLOUT_SELECT(\"GENCLK\"),\n");
			fprintf(f, "\t\t.DIVR(4'b%s),\t\t"      "// DIVR = %2d\n", binstr(best_divr, 4), best_divr);
			fprintf(f, "\t\t.DIVF(7'b%s),\t"        "// DIVF = %2d\n", binstr(best_divf, 7), best_divf);
			fprintf(f, "\t\t.DIVQ(3'b%s),\t\t"      "// DIVQ = %2d\n", binstr(best_divq, 3), best_divq);
			fprintf(f, "\t\t.FILTER_RANGE(3'b%s)\t" "// FILTER_RANGE = %d\n", binstr(filter_range, 3), filter_range);
			fprintf(f, "\t) uut (\n"
						"\t\t.LOCK(locked),\n"
						"\t\t.RESETB(1'b1),\n"
						"\t\t.BYPASS(1'b0),\n"
						"\t\t.REFERENCECLK(clock_in),\n"
						"\t\t.PLLOUTCORE(clock_out),\n"
						"\t\t);\n\n"
					);

			fprintf(f, "endmodule\n");
		}
		else
		{
			// only save PLL configuration values

			// header
			fprintf(f, "/**\n * PLL configuration\n *\n"
						" * This Verilog header file was generated automatically\n"
						" * using the icepll tool from the IceStorm project.\n"
						" * It is intended for use with FPGA primitives SB_PLL40_CORE,\n"
						" * SB_PLL40_PAD, SB_PLL40_2_PAD, SB_PLL40_2F_CORE or SB_PLL40_2F_PAD.\n"
						" * Use at your own risk.\n"
						" *\n"
						" * Given input frequency:      %8.3f MHz\n"
						" * Requested output frequency: %8.3f MHz\n"
						" * Achieved output frequency:  %8.3f MHz\n"
						" */\n\n",
						f_pllin, f_pllout, best_fout);

			// PLL configuration
			fprintf(f, ".FEEDBACK_PATH(\"%s\"),\n", (simple_feedback ? "SIMPLE" : "NON_SIMPLE"));
			fprintf(f, ".PLLOUT_SELECT(\"GENCLK\"),\n");
			fprintf(f, ".DIVR(4'b%s),\t\t"      "// DIVR = %2d\n", binstr(best_divr, 4), best_divr);
			fprintf(f, ".DIVF(7'b%s),\t"        "// DIVF = %2d\n", binstr(best_divf, 7), best_divf);
			fprintf(f, ".DIVQ(3'b%s),\t\t"      "// DIVQ = %2d\n", binstr(best_divq, 3), best_divq);
			fprintf(f, ".FILTER_RANGE(3'b%s)\t" "// FILTER_RANGE = %d\n", binstr(filter_range, 3), filter_range);
		}

		fclose(f);

		printf("PLL configuration written to: %s\n", filename);
	}

	return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <queue>
#include <mutex>
#include <thread>
#include <chrono>
#include <condition_variable>

template <class T> class Channel {
  std::mutex mutex;
  std::queue<T> queue;
  std::condition_variable not_full, not_empty;
  size_t capacity;

public:
  explicit Channel(size_t capacity = 1) : capacity(capacity) {}

  T read() {
    T t;
    std::unique_lock<std::mutex> ul(mutex);
    // lock and wait when empty
    //  wait means release lock and sleep thread
    //  wakeup and re-lock when notified
    not_empty.wait(ul, [this]() { return !queue.empty(); });
    t = queue.front();
    queue.pop();
    ul.unlock();
    not_full.notify_one();
    return t;
  }

  void write(const T &t) {
    std::unique_lock<std::mutex> ul(mutex);
    // wait when full
    not_full.wait(ul, [this]() { return capacity != queue.size(); });
    queue.push(t);
    ul.unlock();
    not_empty.notify_one();
  }
};

class Producer {
  Channel<int> &c;

public:
  explicit Producer(Channel<int> &c) : c(c) {}

  void operator()() {
    for (int i = 0; i < 10; i++) {
      printf("%ld: try to write %d\n", std::this_thread::get_id(), i);
      c.write(i);
      printf("%ld: write %d done\n", std::this_thread::get_id(), i);
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }
  }
};

class Consumer {
  Channel<int> &c;

public:
  explicit Consumer(Channel<int> &c) : c(c) {}

  void operator()() {
    std::this_thread::sleep_for(std::chrono::seconds(5));

    while (true) {
      printf("%ld: try to read\n", std::this_thread::get_id());
      int x = c.read();
      printf("%ld: read %d done\n", std::this_thread::get_id(), x);
    }
  }
};

int main() {
  Channel<int> c(2);
  Producer p(c);
  Consumer s(c);
  std::thread t1(p), t2(s), t3(p), t4(s);
  t1.join();
  t2.join();
  t3.join();
  t4.join();
  return 0;
}
<commit_msg>update<commit_after>#include <iostream>
#include <sstream>
#include <queue>
#include <mutex>
#include <thread>
#include <chrono>
#include <condition_variable>
#include <cstdio>

template <class T> class Channel {
  std::mutex mutex;
  std::queue<T> queue;
  std::condition_variable not_full, not_empty;
  size_t capacity;

public:
  explicit Channel(size_t capacity = 1) : capacity(capacity) {}

  T read() {
    T t;
    {
      std::unique_lock<std::mutex> ul(mutex);
      // lock and wait when empty
      //  wait means release lock and sleep thread
      //  wakeup and re-lock when notified
      not_empty.wait(ul, [this]() { return !queue.empty(); });
      t = queue.front();
      queue.pop();
    }
    // unlock before notify
    not_full.notify_one();
    return t;
  }

  void write(const T &t) {
    {
      std::unique_lock<std::mutex> ul(mutex);
      // wait when full
      not_full.wait(ul, [this]() { return capacity != queue.size(); });
      queue.push(t);
    }
    // unlock before notify
    not_empty.notify_one();
  }
};

class Producer {
  Channel<int> &c;

public:
  explicit Producer(Channel<int> &c) : c(c) {}

  void operator()() {
    for (int i = 0; i < 10; i++) {
      std::stringstream ss;
      ss << std::this_thread::get_id() << ": try to write " << i << "\n";
      fputs(ss.str().c_str(), stderr);

      c.write(i);

      ss.clear();
      ss << std::this_thread::get_id() << ": write " << i << " done\n";
      fputs(ss.str().c_str(), stderr);

      std::this_thread::sleep_for(std::chrono::seconds(1));
    }
  }
};

class Consumer {
  Channel<int> &c;

public:
  explicit Consumer(Channel<int> &c) : c(c) {}

  void operator()() {
    std::this_thread::sleep_for(std::chrono::seconds(5));

    while (true) {
      std::stringstream ss;
      ss << std::this_thread::get_id() << ": try to read\n";
      fputs(ss.str().c_str(), stderr);

      int x = c.read();

      ss.clear();
      ss << std::this_thread::get_id() << ": read " << x << " done\n";
      fputs(ss.str().c_str(), stderr);
    }
  }
};

int main() {
  Channel<int> c(2);
  Producer p(c);
  Consumer s(c);
  std::thread t1(p), t2(s), t3(p), t4(s);
  t1.join();
  t2.join();
  t3.join();
  t4.join();
  return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <queue>
#include <mutex>
#include <thread>
#include <chrono>
#include <condition_variable>

template<class T>
class Channel {
	std::mutex mutex;
	std::queue<T> queue;
	std::condition_variable not_full, not_empty;
	size_t capacity;
public:
	explicit Channel(size_t capacity = 1): capacity(capacity) {}

	T read() {
		T t;
		std::unique_lock<std::mutex> ul(mutex);
		// lock and wait when empty
    //  wait means release lock and sleep thread
    //  wakeup and re-lock when notified
		not_empty.wait(ul, [this](){return !queue.empty();});
		t = queue.front();
		queue.pop();
    ul.unlock();
		not_full.notify_one();
		return t;
	}

	void write(const T& t) {
		std::unique_lock<std::mutex> ul(mutex);
		// wait when full
		not_full.wait(ul, [this](){return capacity != queue.size();});
		queue.push(t);
    ul.unlock();
    not_empty.notify_one();
	}
};

class Producer {
  Channel<int>& c;
public:
  explicit Producer(Channel<int>& c): c(c) {}

  void operator()() {
    for(int i = 0; i < 10; i++) {
      printf("%ld: try to write %d\n", std::this_thread::get_id(), i);
      c.write(i);
      printf("%ld: write %d done\n", std::this_thread::get_id(), i);
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }
  }
};

class Consumer {
  Channel<int>& c;
public:
  explicit Consumer(Channel<int>& c): c(c) {}

  void operator()() {
    std::this_thread::sleep_for(std::chrono::seconds(5));

    while(true) {
      printf("%ld: try to read\n", std::this_thread::get_id());
      int x = c.read();
      printf("%ld: read %d done\n", std::this_thread::get_id(), x);
    }
  }
};

int main() {
  Channel<int> c(2);
  Producer p(c);
  Consumer s(c);
  std::thread t1(p), t2(s), t3(p), t4(s);
  t1.join();
  t2.join();
  return 0;
}
<commit_msg>update<commit_after>#include <stdio.h>
#include <queue>
#include <mutex>
#include <thread>
#include <chrono>
#include <condition_variable>

template <class T> class Channel {
  std::mutex mutex;
  std::queue<T> queue;
  std::condition_variable not_full, not_empty;
  size_t capacity;

public:
  explicit Channel(size_t capacity = 1) : capacity(capacity) {}

  T read() {
    T t;
    std::unique_lock<std::mutex> ul(mutex);
    // lock and wait when empty
    //  wait means release lock and sleep thread
    //  wakeup and re-lock when notified
    not_empty.wait(ul, [this]() { return !queue.empty(); });
    t = queue.front();
    queue.pop();
    ul.unlock();
    not_full.notify_one();
    return t;
  }

  void write(const T &t) {
    std::unique_lock<std::mutex> ul(mutex);
    // wait when full
    not_full.wait(ul, [this]() { return capacity != queue.size(); });
    queue.push(t);
    ul.unlock();
    not_empty.notify_one();
  }
};

class Producer {
  Channel<int> &c;

public:
  explicit Producer(Channel<int> &c) : c(c) {}

  void operator()() {
    for (int i = 0; i < 10; i++) {
      printf("%ld: try to write %d\n", std::this_thread::get_id(), i);
      c.write(i);
      printf("%ld: write %d done\n", std::this_thread::get_id(), i);
      std::this_thread::sleep_for(std::chrono::seconds(1));
    }
  }
};

class Consumer {
  Channel<int> &c;

public:
  explicit Consumer(Channel<int> &c) : c(c) {}

  void operator()() {
    std::this_thread::sleep_for(std::chrono::seconds(5));

    while (true) {
      printf("%ld: try to read\n", std::this_thread::get_id());
      int x = c.read();
      printf("%ld: read %d done\n", std::this_thread::get_id(), x);
    }
  }
};

int main() {
  Channel<int> c(2);
  Producer p(c);
  Consumer s(c);
  std::thread t1(p), t2(s), t3(p), t4(s);
  t1.join();
  t2.join();
  return 0;
}
<|endoftext|>


<commit_before>/*
 * cube.cpp
 *
 *  Created on: Nov 25, 2013
 *      Author: leo
 */

#include "cube.h"
#include <iostream>
using namespace std;

GLfloat cube::side_vertices[] = {
				// front base cube
				-0.5, -0.5,  0.5,
				 0.5, -0.5,  0.5,
				 0.5,  0.5,  0.5,
				-0.5,  0.5,  0.5,
				// back base cube
				-0.5, -0.5, -0.5,
				 0.5, -0.5, -0.5,
				 0.5,  0.5, -0.5,
				-0.5,  0.5, -0.5,
};

GLfloat cube::side_colors[] = {
				// front base cube
				1.0, 1.0, 1.0, 0.0,
				1.0, 1.0, 1.0, 0.0,
				1.0, 1.0, 1.0, 0.0,
				1.0, 1.0, 1.0, 0.0,
				// back base cube
				1.0, 1.0, 1.0, 0.0,
				1.0, 1.0, 1.0, 0.0,
				1.0, 1.0, 1.0, 0.0,
				1.0, 1.0, 1.0, 0.0,

//				// any mixture for debugging
//				// front base cube
//				0.0, 1.0, 0.0,  //green
//				1.0, 1.0, 0.0,  //yellow
//				1.0, 0.5, 0.0, //orange
//				1.0, 0.0, 0.0,  //red
//				// back base cube
//				0.0, 1.0, 0.0,  //green
//				0.0, 0.0, 1.0,  //blue
//				1.0, 0.5, 0.0, //orange
//				0.0, 0.0, 0.0, //black

};

GLfloat cube::tex_coords[] ={
				// front base cube
				1.0, 1.0,
				1.0, 0.0,
				0.0, 0.0,
				0.0, 1.0,
				// back base cube
				1.0, 1.0,
				1.0, 0.0,
				0.0, 0.0,
				0.0, 1.0,
};

GLushort cube::base_elements[] = {
		// front
		0, 1, 2, 2, 3, 0,
		// top
		3, 2, 6, 6, 7, 3,
		// back
		7, 6, 5, 5, 4, 7,
		// bottom
		4, 5, 1, 1, 0, 4,
		// left
		4, 0, 3, 3, 7, 4,
		// right
		1, 5, 6, 6, 2, 1, };

cube::cube(GLuint program, int offset_index) {
	translation = mat4(1.0);
	rotation = mat4(1.0);

	// base cube elements
	glGenBuffers(1, &base_elements_ibo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, base_elements_ibo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(base_elements), base_elements, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	// side vertices
	glGenBuffers(1, &pos_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, pos_vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(side_vertices), side_vertices, GL_STATIC_DRAW);

	// based on the shader variable name
	GLint pos_attrib = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(pos_attrib);
	glVertexAttribPointer(pos_attrib, 3, GL_FLOAT, GL_FALSE, 0,  0);

	// side colors
	glGenBuffers(1, &col_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, col_vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(side_colors), side_colors, GL_STATIC_DRAW);

	// based on the shader variable name
	GLint col_attrib = glGetAttribLocation(program, "in_Color");
	glEnableVertexAttribArray(col_attrib);
	glVertexAttribPointer(col_attrib, 4, GL_FLOAT, GL_FALSE, 0, 0);

	// textures
	glGenBuffers(1, &tex_coord);
	glBindBuffer(GL_ARRAY_BUFFER, tex_coord);
	glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_STATIC_DRAW);

	GLint tex_attrib = glGetAttribLocation(program, "in_texcoord");
	glEnableVertexAttribArray(tex_attrib);
	glVertexAttribPointer(tex_attrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

	glGenTextures(1, &texture_id);
	glBindTexture(GL_TEXTURE_2D, texture_id);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, wood_image.width, wood_image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, wood_image.pixel_data);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

cube::cube() {
	col_vbo = pos_vbo = base_elements_ibo = texture_id = tex_coord = -1;
}

cube::~cube() {
	glDeleteBuffers(1, &pos_vbo);
	glDeleteBuffers(1, &col_vbo);
	glDeleteBuffers(1, &base_elements_ibo);
	glDeleteTextures(1, &texture_id);
}

void cube::draw(){
	//	 draw base using buffer element
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, base_elements_ibo);
	GLint size;  glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, texture_id);
		glDrawElements(GL_TRIANGLES, size/sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
//	glDrawArrays(GL_TRIANGLES, 0,36);

}
<commit_msg>fixing textures<commit_after>/*
 * cube.cpp
 *
 *  Created on: Nov 25, 2013
 *      Author: leo
 */

#include "cube.h"
#include <iostream>
using namespace std;

GLfloat cube::side_vertices[] = {
//				// front base cube
//				-0.5, -0.5,  0.5,
//				 0.5, -0.5,  0.5,
//				 0.5,  0.5,  0.5,
//				-0.5,  0.5,  0.5,
//				// back base cube
//				-0.5, -0.5, -0.5,
//				 0.5, -0.5, -0.5,
//				 0.5,  0.5, -0.5,
//				-0.5,  0.5, -0.5,
		// starting the side vertices
				-0.5, -0.5, -0.5,
				 0.5, -0.5, -0.5,
				 0.5,  0.5, -0.5,
				 0.5,  0.5, -0.5,
				-0.5,  0.5, -0.5,
				-0.5, -0.5, -0.5,

				-0.5, -0.5,  0.5,
				 0.5, -0.5,  0.5,
				 0.5,  0.5,  0.5,
				 0.5,  0.5,  0.5,
				-0.5,  0.5,  0.5,
				-0.5, -0.5,  0.5,

				-0.5,  0.5,  0.5,
				-0.5,  0.5, -0.5,
				-0.5, -0.5, -0.5,
				-0.5, -0.5, -0.5,
				-0.5, -0.5,  0.5,
				-0.5,  0.5,  0.5,

			 	 0.5,  0.5,  0.5,
				 0.5,  0.5, -0.5,
				 0.5, -0.5, -0.5,
				 0.5, -0.5, -0.5,
				 0.5, -0.5,  0.5,
				 0.5,  0.5,  0.5,

				-0.5, -0.5, -0.5,
				 0.5, -0.5, -0.5,
				 0.5, -0.5,  0.5,
				 0.5, -0.5,  0.5,
				-0.5, -0.5,  0.5,
				-0.5, -0.5, -0.5,

				-0.5,  0.5, -0.5,
				 0.5,  0.5, -0.5,
				 0.5,  0.5,  0.5,
				 0.5,  0.5,  0.5,
				-0.5,  0.5,  0.5,
				-0.5,  0.5, -0.5,

};

GLfloat cube::side_colors[] = {
//				// front base cube
//				1.0, 1.0, 1.0, 0.0,
//				1.0, 1.0, 1.0, 0.0,
//				1.0, 1.0, 1.0, 0.0,
//				1.0, 1.0, 1.0, 0.0,
//				// back base cube
//				1.0, 1.0, 1.0, 0.0,
//				1.0, 1.0, 1.0, 0.0,
//				1.0, 1.0, 1.0, 0.0,
//				1.0, 1.0, 1.0, 0.0,

//				// any mixture for debugging
//				// front base cube
//				0.0, 1.0, 0.0,  //green
//				1.0, 1.0, 0.0,  //yellow
//				1.0, 0.5, 0.0, //orange
//				1.0, 0.0, 0.0,  //red
//				// back base cube
//				0.0, 1.0, 0.0,  //green
//				0.0, 0.0, 1.0,  //blue
//				1.0, 0.5, 0.0, //orange
//				0.0, 0.0, 0.0, //black

		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,

		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,

		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,

		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,

		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,

		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,
		1.0, 1.0, 1.0, 0.0,

};

GLfloat cube::tex_coords[] ={
				// front base cube
				1.0, 1.0,
				1.0, 0.0,
				0.0, 0.0,
				0.0, 0.0,
				0.0, 1.0,
				1.0, 1.0,

				1.0, 1.0,
				1.0, 0.0,
				0.0, 0.0,
				0.0, 0.0,
				0.0, 1.0,
				1.0, 1.0,

				1.0, 1.0,
				1.0, 0.0,
				0.0, 0.0,
				0.0, 0.0,
				0.0, 1.0,
				1.0, 1.0,

				// back base cube
				1.0, 1.0,
				1.0, 0.0,
				0.0, 0.0,
				0.0, 0.0,
				0.0, 1.0,
				1.0, 1.0,

				1.0, 1.0,
				1.0, 0.0,
				0.0, 0.0,
				0.0, 0.0,
				0.0, 1.0,
				1.0, 1.0,

				1.0, 1.0,
				1.0, 0.0,
				0.0, 0.0,
				0.0, 0.0,
				0.0, 1.0,
				1.0, 1.0,

};

GLushort cube::base_elements[] = {
		// front
		0, 1, 2, 2, 3, 0,
		// top
		3, 2, 6, 6, 7, 3,
		// back
		7, 6, 5, 5, 4, 7,
		// bottom
		4, 5, 1, 1, 0, 4,
		// left
		4, 0, 3, 3, 7, 4,
		// right
		1, 5, 6, 6, 2, 1, };

cube::cube(GLuint program, int offset_index) {
	translation = mat4(1.0);
	rotation = mat4(1.0);

	// base cube elements
	glGenBuffers(1, &base_elements_ibo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, base_elements_ibo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(base_elements), base_elements, GL_STATIC_DRAW);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	// side vertices
	glGenBuffers(1, &pos_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, pos_vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(side_vertices), side_vertices, GL_STATIC_DRAW);

	// based on the shader variable name
	GLint pos_attrib = glGetAttribLocation(program, "vPosition");
	glEnableVertexAttribArray(pos_attrib);
	glVertexAttribPointer(pos_attrib, 3, GL_FLOAT, GL_FALSE, 0,  0);

	// side colors
	glGenBuffers(1, &col_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, col_vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(side_colors), side_colors, GL_STATIC_DRAW);

	// based on the shader variable name
	GLint col_attrib = glGetAttribLocation(program, "in_Color");
	glEnableVertexAttribArray(col_attrib);
	glVertexAttribPointer(col_attrib, 4, GL_FLOAT, GL_FALSE, 0, 0);

	// textures
	glGenBuffers(1, &tex_coord);
	glBindBuffer(GL_ARRAY_BUFFER, tex_coord);
	glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_STATIC_DRAW);

	GLint tex_attrib = glGetAttribLocation(program, "in_texcoord");
	glEnableVertexAttribArray(tex_attrib);
	glVertexAttribPointer(tex_attrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

	glGenTextures(1, &texture_id);
	glBindTexture(GL_TEXTURE_2D, texture_id);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, wood_image.width, wood_image.height, 0, GL_RGB, GL_UNSIGNED_BYTE, wood_image.pixel_data);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

cube::cube() {
	col_vbo = pos_vbo = base_elements_ibo = texture_id = tex_coord = -1;
}

cube::~cube() {
	glDeleteBuffers(1, &pos_vbo);
	glDeleteBuffers(1, &col_vbo);
	glDeleteBuffers(1, &base_elements_ibo);
	glDeleteTextures(1, &texture_id);
}

void cube::draw(){
	//	 draw base using buffer element
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, base_elements_ibo);
	GLint size;  glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, texture_id);
//		glDrawElements(GL_TRIANGLES, size/sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
	glDrawArrays(GL_TRIANGLES, 0,36);

}
<|endoftext|>


<commit_before>// Copyright (c) 2018 The COLX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "curl.h"
#include "util.h"
#include "clientversion.h"

#include <stdlib.h>
#include <curl/curl.h>

using namespace std;

//
// private section
//

static void CurlGlobalInit()
{
    static bool initialized = false;
    if (!initialized) {
        curl_global_init(CURL_GLOBAL_DEFAULT);
        initialized = true;
    }
}

struct CurlScopeInit
{
    CurlScopeInit() {
        CurlGlobalInit();
        curl_ = curl_easy_init();
    }

    ~CurlScopeInit() {
        if (curl_) curl_easy_cleanup(curl_);
    }

    inline CURL* instance() { return curl_; }

    inline operator CURL*() { return curl_; }

private:
    CurlScopeInit(const CurlScopeInit&);
    CurlScopeInit& operator=(const CurlScopeInit&);

private:
    CURL *curl_;
};

struct MemoryBuffer
{
  char* memory;
  size_t size;
};

static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
    size_t realsize = size * nmemb;
    struct MemoryBuffer *mem = (struct MemoryBuffer*)userp;

    mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
    if (mem->memory == NULL) {
        /* out of memory! */
        error("%s: not enough memory (realloc returned NULL)\n", __func__);
        return 0;
    } else {
        memcpy(&(mem->memory[mem->size]), contents, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0;
        return realsize;
    }
}

//
// public API
//

bool CURLGetRedirect(const CUrl& url, CUrl& redirect, string& error)
{
    CurlScopeInit curl;
    CURLcode res;
    char *location;
    long response_code;

    redirect.clear();
    error.clear();

    if (url.empty()) {
        error = "url is empty";
        return false;
    }

    if (!curl.instance()) {
        error = "curl init failed";
        return false;
    }

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        error = strprintf("curl_easy_perform failed: %s", curl_easy_strerror(res));
        return false;
    }

    res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
    if ((res == CURLE_OK) && ((response_code / 100) != 3)) {
        /* a redirect implies a 3xx response code */
        error = "Not a redirect";
        return false;
    }
    else {
        res = curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &location);
        if ((res == CURLE_OK) && location) {
            /* This is the new absolute URL that you could redirect to, even if
             * the Location: response header may have been a relative URL. */
            redirect = location;
            return true;
        }
        else {
            error = strprintf("curl_easy_getinfo failed: %s", curl_easy_strerror(res));
            return false;
        }
    }
}

bool CURLDownloadToMem(const CUrl& url, string& buff, string& error)
{
    CurlScopeInit curl;
    CURLcode res;
    struct MemoryBuffer chunk;

    buff.clear();
    error.clear();

    if (url.empty()) {
        error = "url is empty";
        return false;
    }

    if (!curl.instance()) {
        error = "curl init failed";
        return false;
    }

    chunk.memory = (char*)malloc(1);  /* will be grown as needed by the realloc above */
    chunk.size = 0;    /* no data at this point */

    /* specify URL to get */
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

    /* send all data to this function  */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);

    /* we pass our 'chunk' struct to the callback function */
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    /* some servers don't like requests that are made without a user-agent */
    const string agent = FormatFullVersion();
    curl_easy_setopt(curl, CURLOPT_USERAGENT, agent.c_str());

    /* get it! */
    res = curl_easy_perform(curl);

    /* check for errors */
    if (res != CURLE_OK) {
        error = strprintf("curl_easy_perform failed: %s", curl_easy_strerror(res));
    } else {
        long response_code = 0;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        if (response_code / 100 != 2) {
            error = strprintf("response code is not OK: %d", response_code);
            DebugPrintf("%s: response code=%d, response content=%s", __func__, response_code, string(chunk.memory, chunk.size));
        } else {
            /*
            * Now, our chunk.memory points to a memory block that is chunk.size
            * bytes big and contains the remote file.
            */
            DebugPrintf("%s: %lu bytes retrieved\n", __func__, (long)chunk.size);
            buff.assign(chunk.memory, chunk.size);
        }
    }

    free(chunk.memory);
    return !buff.empty();
}

bool CURLDownloadToFile(const CUrl& url, const string& path, ProgressReport callback, string& error)
{
    error = "not implemented";
    return false;
}
<commit_msg>autoupdate: peer and host verification disabled due to issues on Mac and Win<commit_after>// Copyright (c) 2018 The COLX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "curl.h"
#include "util.h"
#include "clientversion.h"

#include <stdlib.h>
#include <curl/curl.h>

using namespace std;

//
// private section
//

static void CurlGlobalInit()
{
    static bool initialized = false;
    if (!initialized) {
        curl_global_init(CURL_GLOBAL_DEFAULT);
        initialized = true;
    }
}

struct CurlScopeInit
{
    CurlScopeInit() {
        CurlGlobalInit();
        curl_ = curl_easy_init();
    }

    ~CurlScopeInit() {
        if (curl_) curl_easy_cleanup(curl_);
    }

    inline CURL* instance() { return curl_; }

    inline operator CURL*() { return curl_; }

private:
    CurlScopeInit(const CurlScopeInit&);
    CurlScopeInit& operator=(const CurlScopeInit&);

private:
    CURL *curl_;
};

struct MemoryBuffer
{
  char* memory;
  size_t size;
};

static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
    size_t realsize = size * nmemb;
    struct MemoryBuffer *mem = (struct MemoryBuffer*)userp;

    mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
    if (mem->memory == NULL) {
        /* out of memory! */
        error("%s: not enough memory (realloc returned NULL)\n", __func__);
        return 0;
    } else {
        memcpy(&(mem->memory[mem->size]), contents, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0;
        return realsize;
    }
}

//
// public API
//

bool CURLGetRedirect(const CUrl& url, CUrl& redirect, string& error)
{
    CurlScopeInit curl;
    CURLcode res;
    char *location;
    long response_code;

    redirect.clear();
    error.clear();

    if (url.empty()) {
        error = "url is empty";
        return false;
    }

    if (!curl.instance()) {
        error = "curl init failed";
        return false;
    }

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

    /* disable peer and host verification because of issues on Mac and Win */
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

    res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        error = strprintf("curl_easy_perform failed: %s", curl_easy_strerror(res));
        return false;
    }

    res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
    if ((res == CURLE_OK) && ((response_code / 100) != 3)) {
        /* a redirect implies a 3xx response code */
        error = "Not a redirect";
        return false;
    }
    else {
        res = curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &location);
        if ((res == CURLE_OK) && location) {
            /* This is the new absolute URL that you could redirect to, even if
             * the Location: response header may have been a relative URL. */
            redirect = location;
            return true;
        }
        else {
            error = strprintf("curl_easy_getinfo failed: %s", curl_easy_strerror(res));
            return false;
        }
    }
}

bool CURLDownloadToMem(const CUrl& url, string& buff, string& error)
{
    CurlScopeInit curl;
    CURLcode res;
    struct MemoryBuffer chunk;

    buff.clear();
    error.clear();

    if (url.empty()) {
        error = "url is empty";
        return false;
    }

    if (!curl.instance()) {
        error = "curl init failed";
        return false;
    }

    chunk.memory = (char*)malloc(1);  /* will be grown as needed by the realloc above */
    chunk.size = 0;    /* no data at this point */

    /* specify URL to get */
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

    /* send all data to this function  */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);

    /* we pass our 'chunk' struct to the callback function */
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    /* some servers don't like requests that are made without a user-agent */
    const string agent = FormatFullVersion();
    curl_easy_setopt(curl, CURLOPT_USERAGENT, agent.c_str());

    /* disable peer and host verification because of issues on Mac and Win */
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

    /* get it! */
    res = curl_easy_perform(curl);

    /* check for errors */
    if (res != CURLE_OK) {
        error = strprintf("curl_easy_perform failed: %s", curl_easy_strerror(res));
    } else {
        long response_code = 0;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
        if (response_code / 100 != 2) {
            error = strprintf("response code is not OK: %d", response_code);
            DebugPrintf("%s: response code=%d, response content=%s", __func__, response_code, string(chunk.memory, chunk.size));
        } else {
            /*
            * Now, our chunk.memory points to a memory block that is chunk.size
            * bytes big and contains the remote file.
            */
            DebugPrintf("%s: %lu bytes retrieved\n", __func__, (long)chunk.size);
            buff.assign(chunk.memory, chunk.size);
        }
    }

    free(chunk.memory);
    return !buff.empty();
}

bool CURLDownloadToFile(const CUrl& url, const string& path, ProgressReport callback, string& error)
{
    error = "not implemented";
    return false;
}
<|endoftext|>


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

#include <botan/pipe.h>
#include <botan/hex.h>
using namespace Botan;

#include "common.h"

void strip_comments(std::string& line)
   {
   if(line.find('#') != std::string::npos)
      line = line.erase(line.find('#'), std::string::npos);
   }

void strip_newlines(std::string& line)
   {
   while(line.find('\n') != std::string::npos)
      line = line.erase(line.find('\n'), 1);
   }

/* Strip comments, whitespace, etc */
void strip(std::string& line)
   {
   strip_comments(line);

#if 0
   while(line.find(' ') != std::string::npos)
      line = line.erase(line.find(' '), 1);
#endif

   while(line.find('\t') != std::string::npos)
      line = line.erase(line.find('\t'), 1);
   }

SecureVector<byte> decode_hex(const std::string& in)
   {
   SecureVector<byte> result;

   try {
      Botan::Pipe pipe(new Botan::Hex_Decoder);
      pipe.process_msg(in);
      result = pipe.read_all();
   }
   catch(std::exception& e)
      {
      result.destroy();
      }
   return result;
   }

std::string hex_encode(const byte in[], u32bit len)
   {
   Botan::Pipe pipe(new Botan::Hex_Encoder);
   pipe.process_msg(in, len);
   return pipe.read_all_as_string();
   }

std::vector<std::string> parse(const std::string& line)
   {
   const char DELIMITER = ':';
   std::vector<std::string> substr;
   std::string::size_type start = 0, end = line.find(DELIMITER);
   while(end != std::string::npos)
      {
      substr.push_back(line.substr(start, end-start));
      start = end+1;
      end = line.find(DELIMITER, start);
      }
   if(line.size() > start)
      substr.push_back(line.substr(start));
   while(substr.size() <= 4) // at least 5 substr, some possibly empty
      substr.push_back("");
   return substr;
   }

<commit_msg>Avoid VC++ warning<commit_after>#include <iostream>
#include <vector>
#include <string>

#include <botan/pipe.h>
#include <botan/hex.h>
using namespace Botan;

#include "common.h"

void strip_comments(std::string& line)
   {
   if(line.find('#') != std::string::npos)
      line = line.erase(line.find('#'), std::string::npos);
   }

void strip_newlines(std::string& line)
   {
   while(line.find('\n') != std::string::npos)
      line = line.erase(line.find('\n'), 1);
   }

/* Strip comments, whitespace, etc */
void strip(std::string& line)
   {
   strip_comments(line);

#if 0
   while(line.find(' ') != std::string::npos)
      line = line.erase(line.find(' '), 1);
#endif

   while(line.find('\t') != std::string::npos)
      line = line.erase(line.find('\t'), 1);
   }

SecureVector<byte> decode_hex(const std::string& in)
   {
   SecureVector<byte> result;

   try {
      Botan::Pipe pipe(new Botan::Hex_Decoder);
      pipe.process_msg(in);
      result = pipe.read_all();
   }
   catch(std::exception)
      {
      result.destroy();
      }
   return result;
   }

std::string hex_encode(const byte in[], u32bit len)
   {
   Botan::Pipe pipe(new Botan::Hex_Encoder);
   pipe.process_msg(in, len);
   return pipe.read_all_as_string();
   }

std::vector<std::string> parse(const std::string& line)
   {
   const char DELIMITER = ':';
   std::vector<std::string> substr;
   std::string::size_type start = 0, end = line.find(DELIMITER);
   while(end != std::string::npos)
      {
      substr.push_back(line.substr(start, end-start));
      start = end+1;
      end = line.find(DELIMITER, start);
      }
   if(line.size() > start)
      substr.push_back(line.substr(start));
   while(substr.size() <= 4) // at least 5 substr, some possibly empty
      substr.push_back("");
   return substr;
   }

<|endoftext|>