<commit_before>/*
Copyright (c) 2013 Daniele Bartolini, Michele Rossi
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Vector3.h"
#include "LuaStack.h"
#include "LuaEnvironment.h"

namespace crown
{

//-----------------------------------------------------------------------------
CE_EXPORT int vector3(lua_State* L)
{
	LuaStack stack(L);

	float x = stack.get_float(1);
	float y = stack.get_float(2);
	float z = stack.get_float(3);

	stack.push_vector3(Vector3(x, y, z));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_values(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	stack.push_float(a.x);
	stack.push_float(a.y);
	stack.push_float(a.z);

	return 3;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_add(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_vector3(a + b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_subtract(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_vector3(a - b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_multiply(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	float b = stack.get_float(2);

	stack.push_vector3(a * b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_divide(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	float b = stack.get_float(2);

	stack.push_vector3(a / b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_dot(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_float(a.dot(b));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_cross(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_vector3(a.cross(b));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_equals(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_bool(a == b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_lower(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_bool(a < b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_greater(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_bool(a > b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_length(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	stack.push_float(a.length());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_squared_length(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	stack.push_float(a.squared_length());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_set_length(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	float len = stack.get_float(2);

	a.set_length(len);

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_normalize(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	a.normalize();

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_negate(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	a.negate();

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_get_distance_to(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_float(a.get_distance_to(b));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_get_angle_between(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_float(a.get_angle_between(b));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_zero(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	a.zero();

	return 0;
}

//-----------------------------------------------------------------------------
void load_vector3(LuaEnvironment& env)
{
	env.load_module_function("Vector3", "new", 				vector3);
	env.load_module_function("Vector3", "val", 				vector3_values);
	env.load_module_function("Vector3", "add", 				vector3_add);
	env.load_module_function("Vector3", "sub", 				vector3_subtract);
	env.load_module_function("Vector3", "mul", 				vector3_multiply);
	env.load_module_function("Vector3", "div", 				vector3_divide);
	env.load_module_function("Vector3", "dot", 				vector3_dot);
	env.load_module_function("Vector3", "cross", 			vector3_cross);
	env.load_module_function("Vector3", "equals", 			vector3_equals);
	env.load_module_function("Vector3", "lower", 			vector3_lower);
	env.load_module_function("Vector3", "greater", 			vector3_greater);
	env.load_module_function("Vector3", "length", 			vector3_length);
	env.load_module_function("Vector3", "squared_length", 	vector3_squared_length);
	env.load_module_function("Vector3", "set_length", 		vector3_set_length);
	env.load_module_function("Vector3", "normalize", 		vector3_normalize);
	env.load_module_function("Vector3", "negate", 			vector3_negate);
	env.load_module_function("Vector3", "get_distance_to", 	vector3_get_distance_to);
	env.load_module_function("Vector3", "get_angle_between",vector3_get_angle_between);
	env.load_module_function("Vector3", "zero", 			vector3_zero);
}

} // namespace crown<commit_msg>Fix vector3_negate<commit_after>/*
Copyright (c) 2013 Daniele Bartolini, Michele Rossi
Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

#include "Vector3.h"
#include "LuaStack.h"
#include "LuaEnvironment.h"

namespace crown
{

//-----------------------------------------------------------------------------
CE_EXPORT int vector3(lua_State* L)
{
	LuaStack stack(L);

	float x = stack.get_float(1);
	float y = stack.get_float(2);
	float z = stack.get_float(3);

	stack.push_vector3(Vector3(x, y, z));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_values(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	stack.push_float(a.x);
	stack.push_float(a.y);
	stack.push_float(a.z);

	return 3;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_add(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_vector3(a + b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_subtract(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_vector3(a - b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_multiply(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	float b = stack.get_float(2);

	stack.push_vector3(a * b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_divide(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	float b = stack.get_float(2);

	stack.push_vector3(a / b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_dot(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_float(a.dot(b));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_cross(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_vector3(a.cross(b));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_equals(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_bool(a == b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_lower(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_bool(a < b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_greater(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_bool(a > b);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_length(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	stack.push_float(a.length());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_squared_length(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	stack.push_float(a.squared_length());

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_set_length(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	float len = stack.get_float(2);

	a.set_length(len);

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_normalize(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	a.normalize();

	return 0;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_negate(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	stack.push_vector3(-a);

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_get_distance_to(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_float(a.get_distance_to(b));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_get_angle_between(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);
	Vector3& b = stack.get_vector3(2);

	stack.push_float(a.get_angle_between(b));

	return 1;
}

//-----------------------------------------------------------------------------
CE_EXPORT int vector3_zero(lua_State* L)
{
	LuaStack stack(L);

	Vector3& a = stack.get_vector3(1);

	a.zero();

	return 0;
}

//-----------------------------------------------------------------------------
void load_vector3(LuaEnvironment& env)
{
	env.load_module_function("Vector3", "new", 				vector3);
	env.load_module_function("Vector3", "val", 				vector3_values);
	env.load_module_function("Vector3", "add", 				vector3_add);
	env.load_module_function("Vector3", "sub", 				vector3_subtract);
	env.load_module_function("Vector3", "mul", 				vector3_multiply);
	env.load_module_function("Vector3", "div", 				vector3_divide);
	env.load_module_function("Vector3", "dot", 				vector3_dot);
	env.load_module_function("Vector3", "cross", 			vector3_cross);
	env.load_module_function("Vector3", "equals", 			vector3_equals);
	env.load_module_function("Vector3", "lower", 			vector3_lower);
	env.load_module_function("Vector3", "greater", 			vector3_greater);
	env.load_module_function("Vector3", "length", 			vector3_length);
	env.load_module_function("Vector3", "squared_length", 	vector3_squared_length);
	env.load_module_function("Vector3", "set_length", 		vector3_set_length);
	env.load_module_function("Vector3", "normalize", 		vector3_normalize);
	env.load_module_function("Vector3", "negate", 			vector3_negate);
	env.load_module_function("Vector3", "get_distance_to", 	vector3_get_distance_to);
	env.load_module_function("Vector3", "get_angle_between",vector3_get_angle_between);
	env.load_module_function("Vector3", "zero", 			vector3_zero);
}

} // namespace crown<|endoftext|>


<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"

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

using namespace MathLib;

/*
*/
#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();

}<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"

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

using namespace MathLib;

/*
*/
#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);
	}

}<|endoftext|>


<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"

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

using namespace MathLib;

/*
*/
#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);

}<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"

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

using namespace MathLib;

/*
*/
#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);

}<|endoftext|>


<commit_before>//
// DeviceResources.cpp - A wrapper for the Direct3D 11 device and swapchain
//                       (requires DirectX 11.X Xbox One Monolithic Runtime)
//

#include "pch.h"
#include "DeviceResourcesXDK.h"

using namespace DirectX;

using Microsoft::WRL::ComPtr;

// Constructor for DeviceResources.
DX::DeviceResources::DeviceResources(DXGI_FORMAT backBufferFormat, DXGI_FORMAT depthBufferFormat, UINT backBufferCount, bool fastSemantics) :
    m_screenViewport{},
    m_backBufferFormat(backBufferFormat),
    m_depthBufferFormat(depthBufferFormat),
    m_backBufferCount(backBufferCount),
    m_window(nullptr),
    m_d3dFeatureLevel(D3D_FEATURE_LEVEL_11_1),
    m_outputSize{0, 0, 1920, 1080},
    m_fastSemantics(fastSemantics)
{
}

// Configures the Direct3D device, and stores handles to it and the device context.
void DX::DeviceResources::CreateDeviceResources()
{
    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

#ifdef _DEBUG
    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#elif defined(PROFILE)
    creationFlags |= D3D11_CREATE_DEVICE_INSTRUMENTED;
#endif

    if (m_fastSemantics)
    {
        creationFlags |= D3D11_CREATE_DEVICE_IMMEDIATE_CONTEXT_FAST_SEMANTICS;
    }

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
    };

    // Create the Direct3D 11 API device object and a corresponding context.
    ComPtr<ID3D11Device> device;
    ComPtr<ID3D11DeviceContext> context;

    DX::ThrowIfFailed(D3D11CreateDevice(
        nullptr,
        D3D_DRIVER_TYPE_HARDWARE,
        0,
        creationFlags,
        featureLevels,
        _countof(featureLevels),
        D3D11_SDK_VERSION,
        device.GetAddressOf(),      // Returns the Direct3D device created.
        &m_d3dFeatureLevel,         // Returns feature level of device created.
        context.GetAddressOf()      // Returns the device immediate context.
        ));

#ifndef NDEBUG
    ComPtr<ID3D11InfoQueue> d3dInfoQueue;
    if (SUCCEEDED(device.As(&d3dInfoQueue)))
    {
#ifdef _DEBUG
        d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
        d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
#endif
        D3D11_MESSAGE_ID hide[] =
        {
            D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
        };
        D3D11_INFO_QUEUE_FILTER filter = {};
        filter.DenyList.NumIDs = _countof(hide);
        filter.DenyList.pIDList = hide;
        d3dInfoQueue->AddStorageFilterEntries(&filter);
    }
#endif

    DX::ThrowIfFailed(device.As(&m_d3dDevice));
    DX::ThrowIfFailed(context.As(&m_d3dContext));

#if _XDK_VER >= 0x3F5B03F5 /* XDK Edition 170600 */
    {
        D3D11X_GPU_HARDWARE_CONFIGURATION hwConfig = {};
        m_d3dDevice->GetGpuHardwareConfiguration(&hwConfig);
        if (hwConfig.HardwareVersion >= D3D11X_HARDWARE_VERSION_XBOX_ONE_X)
        {
            m_outputSize = { 0, 0, 3840, 2160 };
#ifdef _DEBUG
            OutputDebugStringA("INFO: Swapchain using 4k (3840 x 2160)\n");
#endif
        }
#endif
    }
}

// These resources need to be recreated every time the window size is changed.
void DX::DeviceResources::CreateWindowSizeDependentResources()
{
    if (!m_window)
    {
        throw std::exception("Call SetWindow with a valid CoreWindow pointer");
    }

    // Clear the previous window size specific context.
    ID3D11RenderTargetView* nullViews[] = {nullptr};
    m_d3dContext->OMSetRenderTargets(_countof(nullViews), nullViews, nullptr);
    m_d3dRenderTargetView.Reset();
    m_d3dDepthStencilView.Reset();
    m_renderTarget.Reset();
    m_depthStencil.Reset();
    m_d3dContext->Flush();

    // Determine the render target size in pixels.
    UINT backBufferWidth = std::max<UINT>(m_outputSize.right - m_outputSize.left, 1);
    UINT backBufferHeight = std::max<UINT>(m_outputSize.bottom - m_outputSize.top, 1);

    if (m_swapChain)
    {
        // If the swap chain already exists, resize it.
        DX::ThrowIfFailed(m_swapChain->ResizeBuffers(
            m_backBufferCount,
            backBufferWidth,
            backBufferHeight,
            m_backBufferFormat,
            0
            ));

        // Xbox One apps do not need to handle DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET.
    }
    else
    {
        // Otherwise, create a new one using the same adapter as the existing Direct3D device.

        // This sequence obtains the DXGI factory that was used to create the Direct3D device above.
        ComPtr<IDXGIDevice1> dxgiDevice;
        DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));

        ComPtr<IDXGIAdapter> dxgiAdapter;
        DX::ThrowIfFailed(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()));

        ComPtr<IDXGIFactory2> dxgiFactory;
        DX::ThrowIfFailed(dxgiAdapter->GetParent(IID_GRAPHICS_PPV_ARGS(dxgiFactory.GetAddressOf())));

        DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
        swapChainDesc.Width = backBufferWidth;
        swapChainDesc.Height = backBufferHeight;
        swapChainDesc.Format = m_backBufferFormat;
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapChainDesc.BufferCount = m_backBufferCount;
        swapChainDesc.SampleDesc.Count = 1;
        swapChainDesc.SampleDesc.Quality = 0;
        swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
        swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
        swapChainDesc.Flags = DXGIX_SWAP_CHAIN_FLAG_QUANTIZATION_RGB_FULL;

        // Create a SwapChain from a CoreWindow.
        DX::ThrowIfFailed(dxgiFactory->CreateSwapChainForCoreWindow(
            m_d3dDevice.Get(),
            m_window,
            &swapChainDesc,
            nullptr,
            m_swapChain.GetAddressOf()
            ));
    }

    // Create a render target view of the swap chain back buffer.
    DX::ThrowIfFailed(m_swapChain->GetBuffer(0, IID_GRAPHICS_PPV_ARGS(m_renderTarget.ReleaseAndGetAddressOf())));

    DX::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(
        m_renderTarget.Get(),
        nullptr,
        m_d3dRenderTargetView.ReleaseAndGetAddressOf()
        ));

    if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN)
    {
        // Create a depth stencil view for use with 3D rendering if needed.
        CD3D11_TEXTURE2D_DESC depthStencilDesc(
            m_depthBufferFormat,
            backBufferWidth,
            backBufferHeight,
            1, // This depth stencil view has only one texture.
            1, // Use a single mipmap level.
            D3D11_BIND_DEPTH_STENCIL
            );

        DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(
            &depthStencilDesc,
            nullptr,
            m_depthStencil.ReleaseAndGetAddressOf()
            ));

        CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
        DX::ThrowIfFailed(m_d3dDevice->CreateDepthStencilView(
            m_depthStencil.Get(),
            &depthStencilViewDesc,
            m_d3dDepthStencilView.ReleaseAndGetAddressOf()
            ));
    }

    // Set the 3D rendering viewport to target the entire window.
    m_screenViewport = CD3D11_VIEWPORT(
        0.0f,
        0.0f,
        static_cast<float>(backBufferWidth),
        static_cast<float>(backBufferHeight)
        );

    m_outputSize.left = m_outputSize.top = 0;
    m_outputSize.right = backBufferWidth;
    m_outputSize.bottom = backBufferHeight;
}

// Prepare the render target for rendering.
void DX::DeviceResources::Prepare()
{
    if (m_fastSemantics)
    {
        DX::ThrowIfFailed(m_swapChain->GetBuffer(0, IID_GRAPHICS_PPV_ARGS(m_renderTarget.ReleaseAndGetAddressOf())));

        m_d3dDevice->PlaceSwapChainView(m_renderTarget.Get(), m_d3dRenderTargetView.Get());

        m_d3dContext->InsertWaitOnPresent(0, m_renderTarget.Get());
    }
}

// Present the contents of the swap chain to the screen.
void DX::DeviceResources::Present(UINT decompressFlags)
{
    if (m_fastSemantics && decompressFlags)
    {
        m_d3dContext->DecompressResource(
            m_renderTarget.Get(), 0, nullptr,
            m_renderTarget.Get(), 0, nullptr,
            m_backBufferFormat, decompressFlags);
    }

    // The first argument instructs DXGI to block until VSync, putting the application
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
    // frames that will never be displayed to the screen.
    DX::ThrowIfFailed(m_swapChain->Present(1, 0));

    // Xbox One apps do not need to handle DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET.
}
<commit_msg>Bad braces<commit_after>//
// DeviceResources.cpp - A wrapper for the Direct3D 11 device and swapchain
//                       (requires DirectX 11.X Xbox One Monolithic Runtime)
//

#include "pch.h"
#include "DeviceResourcesXDK.h"

using namespace DirectX;

using Microsoft::WRL::ComPtr;

// Constructor for DeviceResources.
DX::DeviceResources::DeviceResources(DXGI_FORMAT backBufferFormat, DXGI_FORMAT depthBufferFormat, UINT backBufferCount, bool fastSemantics) :
    m_screenViewport{},
    m_backBufferFormat(backBufferFormat),
    m_depthBufferFormat(depthBufferFormat),
    m_backBufferCount(backBufferCount),
    m_window(nullptr),
    m_d3dFeatureLevel(D3D_FEATURE_LEVEL_11_1),
    m_outputSize{0, 0, 1920, 1080},
    m_fastSemantics(fastSemantics)
{
}

// Configures the Direct3D device, and stores handles to it and the device context.
void DX::DeviceResources::CreateDeviceResources()
{
    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

#ifdef _DEBUG
    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#elif defined(PROFILE)
    creationFlags |= D3D11_CREATE_DEVICE_INSTRUMENTED;
#endif

    if (m_fastSemantics)
    {
        creationFlags |= D3D11_CREATE_DEVICE_IMMEDIATE_CONTEXT_FAST_SEMANTICS;
    }

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
    };

    // Create the Direct3D 11 API device object and a corresponding context.
    ComPtr<ID3D11Device> device;
    ComPtr<ID3D11DeviceContext> context;

    DX::ThrowIfFailed(D3D11CreateDevice(
        nullptr,
        D3D_DRIVER_TYPE_HARDWARE,
        0,
        creationFlags,
        featureLevels,
        _countof(featureLevels),
        D3D11_SDK_VERSION,
        device.GetAddressOf(),      // Returns the Direct3D device created.
        &m_d3dFeatureLevel,         // Returns feature level of device created.
        context.GetAddressOf()      // Returns the device immediate context.
        ));

#ifndef NDEBUG
    ComPtr<ID3D11InfoQueue> d3dInfoQueue;
    if (SUCCEEDED(device.As(&d3dInfoQueue)))
    {
#ifdef _DEBUG
        d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
        d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
#endif
        D3D11_MESSAGE_ID hide[] =
        {
            D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
        };
        D3D11_INFO_QUEUE_FILTER filter = {};
        filter.DenyList.NumIDs = _countof(hide);
        filter.DenyList.pIDList = hide;
        d3dInfoQueue->AddStorageFilterEntries(&filter);
    }
#endif

    DX::ThrowIfFailed(device.As(&m_d3dDevice));
    DX::ThrowIfFailed(context.As(&m_d3dContext));

#if _XDK_VER >= 0x3F5B03F5 /* XDK Edition 170600 */
    {
        D3D11X_GPU_HARDWARE_CONFIGURATION hwConfig = {};
        m_d3dDevice->GetGpuHardwareConfiguration(&hwConfig);
        if (hwConfig.HardwareVersion >= D3D11X_HARDWARE_VERSION_XBOX_ONE_X)
        {
            m_outputSize = { 0, 0, 3840, 2160 };
#ifdef _DEBUG
            OutputDebugStringA("INFO: Swapchain using 4k (3840 x 2160)\n");
#endif
        }
    }
#endif
}

// These resources need to be recreated every time the window size is changed.
void DX::DeviceResources::CreateWindowSizeDependentResources()
{
    if (!m_window)
    {
        throw std::exception("Call SetWindow with a valid CoreWindow pointer");
    }

    // Clear the previous window size specific context.
    ID3D11RenderTargetView* nullViews[] = {nullptr};
    m_d3dContext->OMSetRenderTargets(_countof(nullViews), nullViews, nullptr);
    m_d3dRenderTargetView.Reset();
    m_d3dDepthStencilView.Reset();
    m_renderTarget.Reset();
    m_depthStencil.Reset();
    m_d3dContext->Flush();

    // Determine the render target size in pixels.
    UINT backBufferWidth = std::max<UINT>(m_outputSize.right - m_outputSize.left, 1);
    UINT backBufferHeight = std::max<UINT>(m_outputSize.bottom - m_outputSize.top, 1);

    if (m_swapChain)
    {
        // If the swap chain already exists, resize it.
        DX::ThrowIfFailed(m_swapChain->ResizeBuffers(
            m_backBufferCount,
            backBufferWidth,
            backBufferHeight,
            m_backBufferFormat,
            0
            ));

        // Xbox One apps do not need to handle DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET.
    }
    else
    {
        // Otherwise, create a new one using the same adapter as the existing Direct3D device.

        // This sequence obtains the DXGI factory that was used to create the Direct3D device above.
        ComPtr<IDXGIDevice1> dxgiDevice;
        DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));

        ComPtr<IDXGIAdapter> dxgiAdapter;
        DX::ThrowIfFailed(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()));

        ComPtr<IDXGIFactory2> dxgiFactory;
        DX::ThrowIfFailed(dxgiAdapter->GetParent(IID_GRAPHICS_PPV_ARGS(dxgiFactory.GetAddressOf())));

        DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
        swapChainDesc.Width = backBufferWidth;
        swapChainDesc.Height = backBufferHeight;
        swapChainDesc.Format = m_backBufferFormat;
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapChainDesc.BufferCount = m_backBufferCount;
        swapChainDesc.SampleDesc.Count = 1;
        swapChainDesc.SampleDesc.Quality = 0;
        swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
        swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
        swapChainDesc.Flags = DXGIX_SWAP_CHAIN_FLAG_QUANTIZATION_RGB_FULL;

        // Create a SwapChain from a CoreWindow.
        DX::ThrowIfFailed(dxgiFactory->CreateSwapChainForCoreWindow(
            m_d3dDevice.Get(),
            m_window,
            &swapChainDesc,
            nullptr,
            m_swapChain.GetAddressOf()
            ));
    }

    // Create a render target view of the swap chain back buffer.
    DX::ThrowIfFailed(m_swapChain->GetBuffer(0, IID_GRAPHICS_PPV_ARGS(m_renderTarget.ReleaseAndGetAddressOf())));

    DX::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(
        m_renderTarget.Get(),
        nullptr,
        m_d3dRenderTargetView.ReleaseAndGetAddressOf()
        ));

    if (m_depthBufferFormat != DXGI_FORMAT_UNKNOWN)
    {
        // Create a depth stencil view for use with 3D rendering if needed.
        CD3D11_TEXTURE2D_DESC depthStencilDesc(
            m_depthBufferFormat,
            backBufferWidth,
            backBufferHeight,
            1, // This depth stencil view has only one texture.
            1, // Use a single mipmap level.
            D3D11_BIND_DEPTH_STENCIL
            );

        DX::ThrowIfFailed(m_d3dDevice->CreateTexture2D(
            &depthStencilDesc,
            nullptr,
            m_depthStencil.ReleaseAndGetAddressOf()
            ));

        CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
        DX::ThrowIfFailed(m_d3dDevice->CreateDepthStencilView(
            m_depthStencil.Get(),
            &depthStencilViewDesc,
            m_d3dDepthStencilView.ReleaseAndGetAddressOf()
            ));
    }

    // Set the 3D rendering viewport to target the entire window.
    m_screenViewport = CD3D11_VIEWPORT(
        0.0f,
        0.0f,
        static_cast<float>(backBufferWidth),
        static_cast<float>(backBufferHeight)
        );

    m_outputSize.left = m_outputSize.top = 0;
    m_outputSize.right = backBufferWidth;
    m_outputSize.bottom = backBufferHeight;
}

// Prepare the render target for rendering.
void DX::DeviceResources::Prepare()
{
    if (m_fastSemantics)
    {
        DX::ThrowIfFailed(m_swapChain->GetBuffer(0, IID_GRAPHICS_PPV_ARGS(m_renderTarget.ReleaseAndGetAddressOf())));

        m_d3dDevice->PlaceSwapChainView(m_renderTarget.Get(), m_d3dRenderTargetView.Get());

        m_d3dContext->InsertWaitOnPresent(0, m_renderTarget.Get());
    }
}

// Present the contents of the swap chain to the screen.
void DX::DeviceResources::Present(UINT decompressFlags)
{
    if (m_fastSemantics && decompressFlags)
    {
        m_d3dContext->DecompressResource(
            m_renderTarget.Get(), 0, nullptr,
            m_renderTarget.Get(), 0, nullptr,
            m_backBufferFormat, decompressFlags);
    }

    // The first argument instructs DXGI to block until VSync, putting the application
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
    // frames that will never be displayed to the screen.
    DX::ThrowIfFailed(m_swapChain->Present(1, 0));

    // Xbox One apps do not need to handle DXGI_ERROR_DEVICE_REMOVED or DXGI_ERROR_DEVICE_RESET.
}
<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011-2014 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "local_storage.hpp"
#include <cmath>
#include <map>
#include <string>
#include <vector>
#include <glog/logging.h>
#include "jubatus/util/data/intern.h"

using std::string;
using std::vector;

namespace jubatus {
namespace core {
namespace storage {

local_storage::local_storage() {
}

local_storage::~local_storage() {
}

void local_storage::get(const string& feature, feature_val1_t& ret) const {
  ret.clear();
  id_features3_t::const_iterator cit = tbl_.find(feature);
  if (cit == tbl_.end()) {
    return;
  }
  const id_feature_val3_t& m = cit->second;
  for (id_feature_val3_t::const_iterator it = m.begin(); it != m.end(); ++it) {
    ret.push_back(make_pair(class2id_.get_key(it->first), it->second.v1));
  }
}

void local_storage::get2(const string& feature, feature_val2_t& ret) const {
  ret.clear();
  id_features3_t::const_iterator cit = tbl_.find(feature);
  if (cit == tbl_.end()) {
    return;
  }
  const id_feature_val3_t& m = cit->second;
  for (id_feature_val3_t::const_iterator it = m.begin(); it != m.end(); ++it) {
    ret.push_back(make_pair(class2id_.get_key(it->first),
                            val2_t(it->second.v1, it->second.v2)));
  }
}

void local_storage::get3(const string& feature, feature_val3_t& ret) const {
  ret.clear();
  id_features3_t::const_iterator cit = tbl_.find(feature);
  if (cit == tbl_.end()) {
    return;
  }
  const id_feature_val3_t& m = cit->second;
  for (id_feature_val3_t::const_iterator it = m.begin(); it != m.end(); ++it) {
    ret.push_back(make_pair(class2id_.get_key(it->first), it->second));
  }
}

void local_storage::inp(const common::sfv_t& sfv, map_feature_val1_t& ret)
    const {
  ret.clear();

  vector<float> ret_id(class2id_.size());
  for (common::sfv_t::const_iterator it = sfv.begin(); it != sfv.end(); ++it) {
    const string& feature = it->first;
    const float val = it->second;
    id_features3_t::const_iterator it2 = tbl_.find(feature);
    if (it2 == tbl_.end()) {
      continue;
    }
    const id_feature_val3_t& m = it2->second;
    for (id_feature_val3_t::const_iterator it3 = m.begin(); it3 != m.end();
        ++it3) {
      ret_id[it3->first] += it3->second.v1 * val;
    }
  }

  for (size_t i = 0; i < ret_id.size(); ++i) {
    ret[class2id_.get_key(i)] = ret_id[i];
  }
}

void local_storage::set(
    const string& feature,
    const string& klass,
    const val1_t& w) {
  tbl_[feature][class2id_.get_id(klass)].v1 = w;
}

void local_storage::set2(
    const string& feature,
    const string& klass,
    const val2_t& w) {
  val3_t& val3 = tbl_[feature][class2id_.get_id(klass)];
  val3.v1 = w.v1;
  val3.v2 = w.v2;
}

void local_storage::set3(
    const string& feature,
    const string& klass,
    const val3_t& w) {
  tbl_[feature][class2id_.get_id(klass)] = w;
}

void local_storage::get_status(std::map<string, std::string>& status) const {
  status["num_features"] =
    jubatus::util::lang::lexical_cast<std::string>(tbl_.size());
  status["num_classes"] =
    jubatus::util::lang::lexical_cast<std::string>(class2id_.size());
}

float feature_fabssum(const id_feature_val3_t& f) {
  float sum = 0.f;
  for (id_feature_val3_t::const_iterator it = f.begin(); it != f.end(); ++it) {
    sum += std::fabs(it->second.v1);
  }
  return sum;
}

void local_storage::bulk_update(
    const common::sfv_t& sfv,
    float step_width,
    const string& inc_class,
    const string& dec_class) {
  uint64_t inc_id = class2id_.get_id(inc_class);
  typedef common::sfv_t::const_iterator iter_t;
  if (dec_class != "") {
    uint64_t dec_id = class2id_.get_id(dec_class);
    for (iter_t it = sfv.begin(); it != sfv.end(); ++it) {
      float val = it->second * step_width;
      id_feature_val3_t& feature_row = tbl_[it->first];
      feature_row[inc_id].v1 += val;
      feature_row[dec_id].v1 -= val;
    }
  } else {
    for (iter_t it = sfv.begin(); it != sfv.end(); ++it) {
      float val = it->second * step_width;
      id_feature_val3_t& feature_row = tbl_[it->first];
      feature_row[inc_id].v1 += val;
    }
  }
}

void local_storage::update(
    const string& feature,
    const string& inc_class,
    const string& dec_class,
    const val1_t& v) {
  id_feature_val3_t& feature_row = tbl_[feature];
  feature_row[class2id_.get_id(inc_class)].v1 += v;
  feature_row[class2id_.get_id(dec_class)].v1 -= v;
}

void local_storage::register_label(const std::string& label) {
  // get_id method creates an entry when the label doesn't exist
  class2id_.get_id(label);
}

vector<string> local_storage::get_labels() const {
  return class2id_.get_all_id2key();
}

bool local_storage::set_label(const std::string& label) {
  return class2id_.set_key(label);
}

void local_storage::delete_class(const std::string& name) {
  uint64_t delete_id = class2id_.get_id_const(name);
  if (delete_id == common::key_manager::NOTFOUND)
    return;
  for (id_features3_t::iterator it = tbl_.begin();
       it != tbl_.end();
       ++it) {
    it->second.erase(delete_id);
    if (it->second.empty()) {
      tbl_.erase(it);
    }
  }
  class2id_.delete_key(name);
}

void local_storage::clear() {
  // Clear and minimize
  id_features3_t().swap(tbl_);
  common::key_manager().swap(class2id_);
}

void local_storage::pack(msgpack::packer<msgpack::sbuffer>& packer) const {
  packer.pack(*this);
}

void local_storage::unpack(msgpack::object o) {
  o.convert(this);
}

std::string local_storage::type() const {
  return "local_storage";
}

}  // namespace storage
}  // namespace core
}  // namespace jubatus
<commit_msg>Use unordered_map in inp function of local_storage instead of vector<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011-2014 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License version 2.1 as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "local_storage.hpp"
#include <cmath>
#include <map>
#include <string>
#include <vector>
#include <glog/logging.h>
#include "jubatus/util/data/intern.h"

using std::string;
using std::vector;

namespace jubatus {
namespace core {
namespace storage {

local_storage::local_storage() {
}

local_storage::~local_storage() {
}

void local_storage::get(const string& feature, feature_val1_t& ret) const {
  ret.clear();
  id_features3_t::const_iterator cit = tbl_.find(feature);
  if (cit == tbl_.end()) {
    return;
  }
  const id_feature_val3_t& m = cit->second;
  for (id_feature_val3_t::const_iterator it = m.begin(); it != m.end(); ++it) {
    ret.push_back(make_pair(class2id_.get_key(it->first), it->second.v1));
  }
}

void local_storage::get2(const string& feature, feature_val2_t& ret) const {
  ret.clear();
  id_features3_t::const_iterator cit = tbl_.find(feature);
  if (cit == tbl_.end()) {
    return;
  }
  const id_feature_val3_t& m = cit->second;
  for (id_feature_val3_t::const_iterator it = m.begin(); it != m.end(); ++it) {
    ret.push_back(make_pair(class2id_.get_key(it->first),
                            val2_t(it->second.v1, it->second.v2)));
  }
}

void local_storage::get3(const string& feature, feature_val3_t& ret) const {
  ret.clear();
  id_features3_t::const_iterator cit = tbl_.find(feature);
  if (cit == tbl_.end()) {
    return;
  }
  const id_feature_val3_t& m = cit->second;
  for (id_feature_val3_t::const_iterator it = m.begin(); it != m.end(); ++it) {
    ret.push_back(make_pair(class2id_.get_key(it->first), it->second));
  }
}

void local_storage::inp(const common::sfv_t& sfv, map_feature_val1_t& ret)
    const {
  ret.clear();

  // Use uin64_t map instead of string map as hash function for string is slow
  jubatus::util::data::unordered_map<uint64_t, float> ret_id;
  for (common::sfv_t::const_iterator it = sfv.begin(); it != sfv.end(); ++it) {
    const string& feature = it->first;
    const float val = it->second;
    id_features3_t::const_iterator it2 = tbl_.find(feature);
    if (it2 == tbl_.end()) {
      continue;
    }
    const id_feature_val3_t& m = it2->second;
    for (id_feature_val3_t::const_iterator it3 = m.begin(); it3 != m.end();
        ++it3) {
      ret_id[it3->first] += it3->second.v1 * val;
    }
  }

  std::vector<std::string> labels = class2id_.get_all_id2key();
  for (size_t i = 0; i < labels.size(); ++i) {
    const std::string& label = labels[i];
    uint64_t id = class2id_.get_id_const(label);
    if (id == common::key_manager::NOTFOUND || ret_id.count(id) == 0) {
      ret[label] = 0.0;
    } else {
      ret[label] = ret_id[id];
    }
  }
}

void local_storage::set(
    const string& feature,
    const string& klass,
    const val1_t& w) {
  tbl_[feature][class2id_.get_id(klass)].v1 = w;
}

void local_storage::set2(
    const string& feature,
    const string& klass,
    const val2_t& w) {
  val3_t& val3 = tbl_[feature][class2id_.get_id(klass)];
  val3.v1 = w.v1;
  val3.v2 = w.v2;
}

void local_storage::set3(
    const string& feature,
    const string& klass,
    const val3_t& w) {
  tbl_[feature][class2id_.get_id(klass)] = w;
}

void local_storage::get_status(std::map<string, std::string>& status) const {
  status["num_features"] =
    jubatus::util::lang::lexical_cast<std::string>(tbl_.size());
  status["num_classes"] =
    jubatus::util::lang::lexical_cast<std::string>(class2id_.size());
}

float feature_fabssum(const id_feature_val3_t& f) {
  float sum = 0.f;
  for (id_feature_val3_t::const_iterator it = f.begin(); it != f.end(); ++it) {
    sum += std::fabs(it->second.v1);
  }
  return sum;
}

void local_storage::bulk_update(
    const common::sfv_t& sfv,
    float step_width,
    const string& inc_class,
    const string& dec_class) {
  uint64_t inc_id = class2id_.get_id(inc_class);
  typedef common::sfv_t::const_iterator iter_t;
  if (dec_class != "") {
    uint64_t dec_id = class2id_.get_id(dec_class);
    for (iter_t it = sfv.begin(); it != sfv.end(); ++it) {
      float val = it->second * step_width;
      id_feature_val3_t& feature_row = tbl_[it->first];
      feature_row[inc_id].v1 += val;
      feature_row[dec_id].v1 -= val;
    }
  } else {
    for (iter_t it = sfv.begin(); it != sfv.end(); ++it) {
      float val = it->second * step_width;
      id_feature_val3_t& feature_row = tbl_[it->first];
      feature_row[inc_id].v1 += val;
    }
  }
}

void local_storage::update(
    const string& feature,
    const string& inc_class,
    const string& dec_class,
    const val1_t& v) {
  id_feature_val3_t& feature_row = tbl_[feature];
  feature_row[class2id_.get_id(inc_class)].v1 += v;
  feature_row[class2id_.get_id(dec_class)].v1 -= v;
}

void local_storage::register_label(const std::string& label) {
  // get_id method creates an entry when the label doesn't exist
  class2id_.get_id(label);
}

vector<string> local_storage::get_labels() const {
  return class2id_.get_all_id2key();
}

bool local_storage::set_label(const std::string& label) {
  return class2id_.set_key(label);
}

void local_storage::delete_class(const std::string& name) {
  uint64_t delete_id = class2id_.get_id_const(name);
  if (delete_id == common::key_manager::NOTFOUND)
    return;
  for (id_features3_t::iterator it = tbl_.begin();
       it != tbl_.end();
       ++it) {
    it->second.erase(delete_id);
    if (it->second.empty()) {
      tbl_.erase(it);
    }
  }
  class2id_.delete_key(name);
}

void local_storage::clear() {
  // Clear and minimize
  id_features3_t().swap(tbl_);
  common::key_manager().swap(class2id_);
}

void local_storage::pack(msgpack::packer<msgpack::sbuffer>& packer) const {
  packer.pack(*this);
}

void local_storage::unpack(msgpack::object o) {
  o.convert(this);
}

std::string local_storage::type() const {
  return "local_storage";
}

}  // namespace storage
}  // namespace core
}  // namespace jubatus
<|endoftext|>


<commit_before>/* sample_plugin.cc

   Jeremy Barnes, 11 September 2015
   Mich, 2016-12-14
   Copyright (c) 2015 Datacratic Inc.  All rights reserved.
 */

#include "mldb/types/value_description.h"
#include "mldb/core/function.h"
#include "mldb/core/plugin.h"
#include "mldb/rest/poly_entity.h"

using namespace MLDB;
using namespace std;

/// We are defining a new Function here, so we need to derive from
/// Datacratic::MLDB::Function and implement that interface.
struct HelloWorldFunction: public MLDB::Function {

    /// Our constructor knows about the MLDB server we're integrated
    /// into, its configuration and includes a progress object that
    /// we can optionally use to give feedback into initialization
    /// progress (we don't use it, as initialization is intstantaneous).
    HelloWorldFunction(MLDB::MldbServer * server,
                       PolyConfig config,
                       std::function<bool (Json::Value)> onProgress)
        : MLDB::Function(server)
    {
    }

    /// Return the status of the plugin.  We return a simple constant
    /// string.  This is what will be returned from the
    /// GET /v1/functions/.../status API route.
    virtual Any getStatus() const
    {
        return std::string("A-OK");
    }

    /// Return the function information.  This tells MLDB about what the
    /// types of the input and output are, in order to allow for the
    /// function to be compiled as part of an SQL expression.  We
    /// return a single pin called "hello" with a string value, so that's
    /// what we return.
    virtual FunctionInfo getFunctionInfo() const
    {
        vector<KnownColumn> cols;
        cols.emplace_back(PathElement("world"),
                          make_shared<Utf8StringValueInfo>(),
                          COLUMN_IS_DENSE);

        FunctionInfo result;
        result.output = std::make_shared<RowValueInfo>(cols, SCHEMA_CLOSED);
        cols.clear();
        result.input.emplace_back(new RowValueInfo(cols, SCHEMA_CLOSED));
        return result;
    }

    /// Apply the function.  The applier contains information about the
    /// function itself, and the context gives us the input arguments.
    /// Since we don't do anything complicated or read the input, neither
    /// argument is used.
    virtual ExpressionValue apply(const FunctionApplier & applier,
                                  const ExpressionValue & context) const
    {
        // Create the string "world" as of the current timestamp.  In MLDB,
        // every data point has an associated timestamp at which it's known.
        ExpressionValue world("world", Date::now());

        return world;
    }
};

/// Create the plugin itself.  In our case, we only want the plugin as a
/// way to load up the HelloWorld function, so we don't add any
/// functionality over the base class.

struct SamplePlugin: public MLDB::Plugin {

    SamplePlugin(MldbServer * server)
        : MLDB::Plugin(server)
    {
    }

    /// Override the getStatus method to return a custom method
    Any getStatus() const
    {
        return std::string("SamplePlugin is loaded");
    }
};

extern "C" {

/// This is the function that MLDB will call to initialize the plugin.
/// It needs to return a newly created plugin.
MLDB::Plugin * mldbPluginEnter(MldbServer * server)
{
    return new SamplePlugin(server);
}

} // extern C

/// Put this declaration in "file scope" so it doesn't clash with other
/// plugin initializations.
namespace {

/// Register our function with MLDB.  We say here that our function
/// helloWorld takes an integer for configuration (which is ignored),
/// has the given description and has no documentation available.

Package package("mldb_sample_plugin");

static RegisterFunctionType<HelloWorldFunction, int>
regHelloWorldFunction(package,
                      "helloWorld",
                      "Sample function that always returns hello = \"world\"",
                      "No documentation available");
} // file scope
<commit_msg>Fix plugin.cc<commit_after>/* sample_plugin.cc

   Jeremy Barnes, 11 September 2015
   Mich, 2016-12-14
   Copyright (c) 2015 Datacratic Inc.  All rights reserved.
 */

#include "mldb/types/value_description.h"
#include "mldb/core/function.h"
#include "mldb/core/plugin.h"
#include "mldb/rest/poly_entity.h"

using namespace MLDB;
using namespace std;

/// We are defining a new Function here, so we need to derive from
/// Datacratic::MLDB::Function and implement that interface.
struct HelloWorldFunction: public MLDB::Function {

    /// Our constructor knows about the MLDB server we're integrated
    /// into, its configuration and includes a progress object that
    /// we can optionally use to give feedback into initialization
    /// progress (we don't use it, as initialization is intstantaneous).
    HelloWorldFunction(MLDB::MldbServer * server,
                       PolyConfig config,
                       std::function<bool (Json::Value)> onProgress)
        : MLDB::Function(server, config)
    {
    }

    /// Return the status of the plugin.  We return a simple constant
    /// string.  This is what will be returned from the
    /// GET /v1/functions/.../status API route.
    virtual Any getStatus() const
    {
        return std::string("A-OK");
    }

    /// Return the function information.  This tells MLDB about what the
    /// types of the input and output are, in order to allow for the
    /// function to be compiled as part of an SQL expression.  We
    /// return a single pin called "hello" with a string value, so that's
    /// what we return.
    virtual FunctionInfo getFunctionInfo() const
    {
        vector<KnownColumn> cols;
        cols.emplace_back(PathElement("world"),
                          make_shared<Utf8StringValueInfo>(),
                          COLUMN_IS_DENSE);

        FunctionInfo result;
        result.output = std::make_shared<RowValueInfo>(cols, SCHEMA_CLOSED);
        cols.clear();
        result.input.emplace_back(new RowValueInfo(cols, SCHEMA_CLOSED));
        return result;
    }

    /// Apply the function.  The applier contains information about the
    /// function itself, and the context gives us the input arguments.
    /// Since we don't do anything complicated or read the input, neither
    /// argument is used.
    virtual ExpressionValue apply(const FunctionApplier & applier,
                                  const ExpressionValue & context) const
    {
        // Create the string "world" as of the current timestamp.  In MLDB,
        // every data point has an associated timestamp at which it's known.
        ExpressionValue world("world", Date::now());

        return world;
    }
};

/// Create the plugin itself.  In our case, we only want the plugin as a
/// way to load up the HelloWorld function, so we don't add any
/// functionality over the base class.

struct SamplePlugin: public MLDB::Plugin {

    SamplePlugin(MldbServer * server)
        : MLDB::Plugin(server)
    {
    }

    /// Override the getStatus method to return a custom method
    Any getStatus() const
    {
        return std::string("SamplePlugin is loaded");
    }
};

extern "C" {

/// This is the function that MLDB will call to initialize the plugin.
/// It needs to return a newly created plugin.
MLDB::Plugin * mldbPluginEnter(MldbServer * server)
{
    return new SamplePlugin(server);
}

} // extern C

/// Put this declaration in "file scope" so it doesn't clash with other
/// plugin initializations.
namespace {

/// Register our function with MLDB.  We say here that our function
/// helloWorld takes an integer for configuration (which is ignored),
/// has the given description and has no documentation available.

Package package("mldb_sample_plugin");

static RegisterFunctionType<HelloWorldFunction, int>
regHelloWorldFunction(package,
                      "helloWorld",
                      "Sample function that always returns hello = \"world\"",
                      "No documentation available");
} // file scope
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include "AlloShared/StatsUtils.hpp"
#include <boost/bind.hpp>
#include <boost/algorithm/string/join.hpp>

#include "AlloReceiver/Stats.hpp"

static Stats stats;

class receiver
{
public:
	receiver(boost::asio::io_service& io_service,
		const boost::asio::ip::address& listen_address,
		const boost::asio::ip::address& multicast_address,
		short multicast_port,
		int face)
		: socket_(io_service), face(face)
	{
		// Create the socket so that multiple may be bound to the same address.
		boost::asio::ip::udp::endpoint listen_endpoint(
			listen_address, multicast_port);
		socket_.open(listen_endpoint.protocol());
		socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
		socket_.bind(listen_endpoint);

		// Join the multicast group.
		socket_.set_option(
			boost::asio::ip::multicast::join_group(multicast_address));

		socket_.async_receive_from(
			boost::asio::buffer(data_, max_length), sender_endpoint_,
			boost::bind(&receiver::handle_receive_from, this,
			boost::asio::placeholders::error,
			boost::asio::placeholders::bytes_transferred));
	}

	void handle_receive_from(const boost::system::error_code& error,
		size_t bytes_recvd)
	{
		if (!error)
		{
			stats.store(StatsUtils::NALU(face, bytes_recvd, face, StatsUtils::NALU::SENT));

			socket_.async_receive_from(
				boost::asio::buffer(data_, max_length), sender_endpoint_,
				boost::bind(&receiver::handle_receive_from, this,
				boost::asio::placeholders::error,
				boost::asio::placeholders::bytes_transferred));
		}
	}

private:
	boost::asio::ip::udp::socket socket_;
	boost::asio::ip::udp::endpoint sender_endpoint_;
	enum { max_length = 65536 };
	char data_[max_length];
	int face;
};

int main(int argc, char* argv[])
{
	try
	{
		if (argc < 5)
		{
			std::cerr << "Usage: receiver <listen_address> <multicast_address> <stats interval> <port>+" << std::endl;
			return 1;
		}

		std::vector<short> ports;
		for (int i = 4; i < argc; i++)
		{
			ports.push_back(atoi(argv[i]));
		}

		boost::asio::ip::address listen_address    = boost::asio::ip::address::from_string(argv[1]);
		boost::asio::ip::address multicast_address = boost::asio::ip::address::from_string(argv[2]);
		size_t statsInterval = atoi(argv[3]);

		std::stringstream ss;
		std::copy(ports.begin(), ports.end(), std::ostream_iterator<short>(ss, ", "));

		std::cout << "Monitoring packets from " << multicast_address.to_string() <<
			" with port(s) " << ss.str().substr(0, ss.str().length() - 2) <<
			" on interface address " << listen_address.to_string() << std::endl;

		std::vector<receiver*> receivers;
		std::vector<boost::asio::io_service*> io_services;

		for (int i = 0; i < ports.size(); i++)
		{
			io_services.push_back(new boost::asio::io_service());
			receivers.push_back(new receiver(*io_services[i],
				                         boost::asio::ip::address::from_string(argv[1]),
				                         boost::asio::ip::address::from_string(argv[2]),
				                         ports[i],
				                         i));
		}

		stats.autoSummary(boost::chrono::seconds(statsInterval),
			              AlloReceiver::statValsMaker,
						  AlloReceiver::postProcessorMaker,
						  AlloReceiver::formatStringMaker);

		std::vector<boost::thread> io_threads;

		for (boost::asio::io_service* io_service : io_services)
		{
			io_threads.push_back(boost::thread(boost::bind(&boost::asio::io_service::run, io_service)));
		}

		for (boost::thread& io_thread : io_threads)
		{
			io_thread.join();
		}
	}
	catch (std::exception& e)
	{
		std::cerr << "Exception: " << e.what() << "\n";
	}

	return 0;
}<commit_msg>Compiles on Linux.<commit_after>#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include "AlloShared/StatsUtils.hpp"
#include <boost/bind.hpp>
#include <boost/algorithm/string/join.hpp>

#include "AlloReceiver/Stats.hpp"

static Stats stats;

class receiver
{
public:
	receiver(boost::asio::io_service& io_service,
		const boost::asio::ip::address& listen_address,
		const boost::asio::ip::address& multicast_address,
		short multicast_port,
		int face)
		: socket_(io_service), face(face)
	{
		// Create the socket so that multiple may be bound to the same address.
		boost::asio::ip::udp::endpoint listen_endpoint(
			listen_address, multicast_port);
		socket_.open(listen_endpoint.protocol());
		socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
		socket_.bind(listen_endpoint);

		// Join the multicast group.
		socket_.set_option(
			boost::asio::ip::multicast::join_group(multicast_address));

		socket_.async_receive_from(
			boost::asio::buffer(data_, max_length), sender_endpoint_,
			boost::bind(&receiver::handle_receive_from, this,
			boost::asio::placeholders::error,
			boost::asio::placeholders::bytes_transferred));
	}

	void handle_receive_from(const boost::system::error_code& error,
		size_t bytes_recvd)
	{
		if (!error)
		{
			stats.store(StatsUtils::NALU(face, bytes_recvd, face, StatsUtils::NALU::SENT));

			socket_.async_receive_from(
				boost::asio::buffer(data_, max_length), sender_endpoint_,
				boost::bind(&receiver::handle_receive_from, this,
				boost::asio::placeholders::error,
				boost::asio::placeholders::bytes_transferred));
		}
	}

private:
	boost::asio::ip::udp::socket socket_;
	boost::asio::ip::udp::endpoint sender_endpoint_;
	enum { max_length = 65536 };
	char data_[max_length];
	int face;
};

int main(int argc, char* argv[])
{
	try
	{
		if (argc < 5)
		{
			std::cerr << "Usage: receiver <listen_address> <multicast_address> <stats interval> <port>+" << std::endl;
			return 1;
		}

		std::vector<short> ports;
		for (int i = 4; i < argc; i++)
		{
			ports.push_back(atoi(argv[i]));
		}

		boost::asio::ip::address listen_address    = boost::asio::ip::address::from_string(argv[1]);
		boost::asio::ip::address multicast_address = boost::asio::ip::address::from_string(argv[2]);
		size_t statsInterval = atoi(argv[3]);

		std::stringstream ss;
		std::copy(ports.begin(), ports.end(), std::ostream_iterator<short>(ss, ", "));

		std::cout << "Monitoring packets from " << multicast_address.to_string() <<
			" with port(s) " << ss.str().substr(0, ss.str().length() - 2) <<
			" on interface address " << listen_address.to_string() << std::endl;

		std::vector<receiver*> receivers;
		std::vector<boost::asio::io_service*> io_services;

		for (int i = 0; i < ports.size(); i++)
		{
			io_services.push_back(new boost::asio::io_service());
			receivers.push_back(new receiver(*io_services[i],
				                         boost::asio::ip::address::from_string(argv[1]),
				                         boost::asio::ip::address::from_string(argv[2]),
				                         ports[i],
				                         i));
		}

		stats.autoSummary(boost::chrono::seconds(statsInterval),
			              AlloReceiver::statValsMaker,
						  AlloReceiver::postProcessorMaker,
						  AlloReceiver::formatStringMaker());

		std::vector<boost::thread> io_threads;

		for (boost::asio::io_service* io_service : io_services)
		{
			io_threads.push_back(boost::thread(boost::bind(&boost::asio::io_service::run, io_service)));
		}

		for (boost::thread& io_thread : io_threads)
		{
			io_thread.join();
		}
	}
	catch (std::exception& e)
	{
		std::cerr << "Exception: " << e.what() << "\n";
	}

	return 0;
}
<|endoftext|>


<commit_before>#include "blackhole/formatter/json.hpp"

#include <array>

#include <boost/variant/apply_visitor.hpp>

#ifndef RAPIDJSON_HAS_STDSTRING
#define RAPIDJSON_HAS_STDSTRING 1
#endif
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <rapidjson/pointer.h>

#include "blackhole/record.hpp"
#include "blackhole/extensions/writer.hpp"

#include "blackhole/detail/attribute.hpp"
#include "blackhole/detail/unimplemented.hpp"

namespace blackhole {
namespace formatter {

namespace {

struct visitor_t {
    typedef void result_type;

    rapidjson::Value& node;
    rapidjson::MemoryPoolAllocator<>& allocator;

    const string_view& name;

    auto operator()(std::nullptr_t) -> void {
        node.AddMember(rapidjson::StringRef(name.data(), name.size()), rapidjson::kNullType, allocator);
    }

    // For `bool`, `std::int64_t`, `std::uint64_t` and `double` types.
    template<typename T>
    auto operator()(T value) -> void {
        static_assert(
            std::is_same<T, bool>::value ||
            std::is_same<T, std::int64_t>::value ||
            std::is_same<T, std::uint64_t>::value ||
            std::is_same<T, double>::value, "type mismatch");
        node.AddMember(rapidjson::StringRef(name.data(), name.size()), value, allocator);
    }

    auto operator()(const string_view& value) -> void {
        node.AddMember(rapidjson::StringRef(name.data(), name.size()),
            rapidjson::StringRef(value.data(), value.size()), allocator);
    }
};

template<typename Map, typename F>
inline auto find(const Map& map, const typename Map::key_type& key, const F& fn) ->
    typename Map::mapped_type
{
    const auto it = map.find(key);
    if (it == map.end()) {
        return fn();
    } else {
        return it->second;
    }
}

/// A RapidJSON Stream concept implementation required to avoid intermediate buffer allocation.
struct stream_t {
    typedef char Ch;

    writer_t& wr;

    /// Writes a character directly into the underlying buffer.
    auto Put(Ch c) -> void {
        wr.inner << c;
    }

    /// Does nothing, because there is no intermediate buffer.
    auto Flush() -> void {}
};

template<typename> class builder;

}  // namespace

class json_t::factory_t {
public:
    // A JSON routing pointer for attributes that weren't mentioned in `routing` map.
    rapidjson::Pointer rest;
    // Routing map from attribute name to its JSON pointer.
    std::unordered_map<std::string, rapidjson::Pointer> routing;

    factory_t() :
        rest("")
    {}

    factory_t(routing_t routing) :
        rest(routing.unspecified)
    {
        for (const auto& route : routing.specified) {
            for (const auto& name : route.second) {
                this->routing.insert({name, rapidjson::Pointer(route.first)});
            }
        }
    }

    template<typename Document>
    auto get(const string_view& name, Document& root) -> rapidjson::Value& {
        const auto& route = find(routing, name.to_string(), [&]() -> const rapidjson::Pointer& {
            return rest;
        });

        return route.GetWithDefault(root, rapidjson::kObjectType);
    }

    template<typename Document>
    auto create(Document& root, const record_t& record) -> builder<Document>;
};

template<typename Document>
class json_t::builder {
    Document& root;
    const record_t& record;
    factory_t& factory;

public:
    builder(Document& root, const record_t& record, factory_t& factory) :
        root(root),
        record(record),
        factory(factory)
    {}

    auto message() -> void {
        apply("message", record.message());
    }

    auto severity() -> void {
        apply("severity", static_cast<std::int64_t>(record.severity()));
    }

    auto timestamp() -> void {
        apply("timestamp", std::chrono::duration_cast<
            std::chrono::microseconds
        >(record.timestamp().time_since_epoch()).count());
    }

    auto build(writer_t& writer) -> void {
        stream_t stream{writer};
        rapidjson::Writer<stream_t> wr(stream);
        root.Accept(wr);
    }

    auto attributes() -> void {
        // TODO: Make flattened range
        // TODO: Make uniqued range.
        for (const auto& attributes : record.attributes()) {
            for (const auto& attribute : attributes.get()) {
                apply(attribute.first, attribute.second);
            }
        }
    }

private:
    template<typename T>
    auto apply(const string_view& name, const T& value) -> void {
        visitor_t visitor{factory.get(name, root), root.GetAllocator(), name};
        visitor(value);
    }

    auto apply(const string_view& name, const attribute::view_t& value) -> void {
        visitor_t visitor{factory.get(name, root), root.GetAllocator(), name};
        boost::apply_visitor(visitor, value.inner().value);
    }
};

template<typename Document>
auto json_t::factory_t::create(Document& root, const record_t& record) ->
    builder<Document>
{
    return builder<Document>{root, record, *this};
}

json_t::json_t() :
    factory(new factory_t)
{}

json_t::json_t(routing_t routing) :
    factory(new factory_t(std::move(routing)))
{}

json_t::~json_t() {}

auto json_t::format(const record_t& record, writer_t& writer) -> void {
    typedef rapidjson::GenericDocument<
        rapidjson::UTF8<>,
        rapidjson::MemoryPoolAllocator<>,
        rapidjson::MemoryPoolAllocator<>
    > document_type;

    std::array<char, 4096> value_buffer;
    std::array<char, 1024> parse_buffer;
    rapidjson::MemoryPoolAllocator<> value_allocator(value_buffer.data(), value_buffer.size());
    rapidjson::MemoryPoolAllocator<> parse_allocator(parse_buffer.data(), parse_buffer.size());

    document_type root(&value_allocator, parse_buffer.size(), &parse_allocator);
    root.SetObject();

    // TODO: Try to use `AutoUTF<>` or `AutoUTFOutputStream` for UTF-8 validation.

    auto builder = factory->create(root, record);
    builder.message();
    builder.severity();
    builder.timestamp();
    builder.attributes();

    builder.build(writer);

    // TODO: Add newline if required. Obtained through config.
    // if (config.newline) {
    //     writer << '\n';
    // }
}

}  // namespace formatter
}  // namespace blackhole
<commit_msg>chore(): clean up<commit_after>#include "blackhole/formatter/json.hpp"

#include <array>

#include <boost/variant/apply_visitor.hpp>

#ifndef RAPIDJSON_HAS_STDSTRING
#define RAPIDJSON_HAS_STDSTRING 1
#endif
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <rapidjson/pointer.h>

#include "blackhole/record.hpp"
#include "blackhole/extensions/writer.hpp"

#include "blackhole/detail/attribute.hpp"
#include "blackhole/detail/unimplemented.hpp"

namespace blackhole {
namespace formatter {

namespace {

struct visitor_t {
    typedef void result_type;

    rapidjson::Value& node;
    rapidjson::MemoryPoolAllocator<>& allocator;

    const string_view& name;

    auto operator()(std::nullptr_t) -> void {
        node.AddMember(rapidjson::StringRef(name.data(), name.size()), rapidjson::kNullType, allocator);
    }

    // For `bool`, `std::int64_t`, `std::uint64_t` and `double` types.
    template<typename T>
    auto operator()(T value) -> void {
        static_assert(
            std::is_same<T, bool>::value ||
            std::is_same<T, std::int64_t>::value ||
            std::is_same<T, std::uint64_t>::value ||
            std::is_same<T, double>::value, "type mismatch");
        node.AddMember(rapidjson::StringRef(name.data(), name.size()), value, allocator);
    }

    auto operator()(const string_view& value) -> void {
        node.AddMember(rapidjson::StringRef(name.data(), name.size()),
            rapidjson::StringRef(value.data(), value.size()), allocator);
    }
};

template<typename Map, typename F>
inline auto find(const Map& map, const typename Map::key_type& key, const F& fn) ->
    typename Map::mapped_type
{
    const auto it = map.find(key);
    if (it == map.end()) {
        return fn();
    } else {
        return it->second;
    }
}

/// A RapidJSON Stream concept implementation required to avoid intermediate buffer allocation.
struct stream_t {
    typedef char Ch;

    writer_t& wr;

    /// Writes a character directly into the underlying buffer.
    auto Put(Ch c) -> void {
        wr.inner << c;
    }

    /// Does nothing, because there is no intermediate buffer.
    auto Flush() -> void {}
};

}  // namespace

class json_t::factory_t {
public:
    // A JSON routing pointer for attributes that weren't mentioned in `routing` map.
    rapidjson::Pointer rest;
    // Routing map from attribute name to its JSON pointer.
    std::unordered_map<std::string, rapidjson::Pointer> routing;

    factory_t() :
        rest("")
    {}

    factory_t(routing_t routing) :
        rest(routing.unspecified)
    {
        for (const auto& route : routing.specified) {
            for (const auto& name : route.second) {
                this->routing.insert({name, rapidjson::Pointer(route.first)});
            }
        }
    }

    template<typename Document>
    auto get(const string_view& name, Document& root) -> rapidjson::Value& {
        const auto& route = find(routing, name.to_string(), [&]() -> const rapidjson::Pointer& {
            return rest;
        });

        return route.GetWithDefault(root, rapidjson::kObjectType);
    }

    template<typename Document>
    auto create(Document& root, const record_t& record) -> builder<Document>;
};

template<typename Document>
class json_t::builder {
    Document& root;
    const record_t& record;
    factory_t& factory;

public:
    builder(Document& root, const record_t& record, factory_t& factory) :
        root(root),
        record(record),
        factory(factory)
    {}

    auto message() -> void {
        apply("message", record.message());
    }

    auto severity() -> void {
        apply("severity", static_cast<std::int64_t>(record.severity()));
    }

    auto timestamp() -> void {
        apply("timestamp", std::chrono::duration_cast<
            std::chrono::microseconds
        >(record.timestamp().time_since_epoch()).count());
    }

    auto build(writer_t& writer) -> void {
        stream_t stream{writer};
        rapidjson::Writer<stream_t> wr(stream);
        root.Accept(wr);
    }

    auto attributes() -> void {
        // TODO: Make flattened range
        // TODO: Make uniqued range.
        for (const auto& attributes : record.attributes()) {
            for (const auto& attribute : attributes.get()) {
                apply(attribute.first, attribute.second);
            }
        }
    }

private:
    template<typename T>
    auto apply(const string_view& name, const T& value) -> void {
        visitor_t visitor{factory.get(name, root), root.GetAllocator(), name};
        visitor(value);
    }

    auto apply(const string_view& name, const attribute::view_t& value) -> void {
        visitor_t visitor{factory.get(name, root), root.GetAllocator(), name};
        boost::apply_visitor(visitor, value.inner().value);
    }
};

template<typename Document>
auto json_t::factory_t::create(Document& root, const record_t& record) ->
    builder<Document>
{
    return builder<Document>{root, record, *this};
}

json_t::json_t() :
    factory(new factory_t)
{}

json_t::json_t(routing_t routing) :
    factory(new factory_t(std::move(routing)))
{}

json_t::~json_t() {}

auto json_t::format(const record_t& record, writer_t& writer) -> void {
    typedef rapidjson::GenericDocument<
        rapidjson::UTF8<>,
        rapidjson::MemoryPoolAllocator<>,
        rapidjson::MemoryPoolAllocator<>
    > document_type;

    std::array<char, 4096> value_buffer;
    std::array<char, 1024> parse_buffer;
    rapidjson::MemoryPoolAllocator<> value_allocator(value_buffer.data(), value_buffer.size());
    rapidjson::MemoryPoolAllocator<> parse_allocator(parse_buffer.data(), parse_buffer.size());

    document_type root(&value_allocator, parse_buffer.size(), &parse_allocator);
    root.SetObject();

    // TODO: Try to use `AutoUTF<>` or `AutoUTFOutputStream` for UTF-8 validation.

    auto builder = factory->create(root, record);
    builder.message();
    builder.severity();
    builder.timestamp();
    builder.attributes();

    builder.build(writer);

    // TODO: Add newline if required. Obtained through config.
    // if (config.newline) {
    //     writer << '\n';
    // }
}

}  // namespace formatter
}  // namespace blackhole
<|endoftext|>


<commit_before>// Fill out your copyright notice in the Description page of Project Settings.

#include "coopgame.h"
#include "NativeCoopPlayerController.h"
#include "CoopPlayerCameraManager.h"
#include "online/CoopGamePlayerState.h"
#include "OnlineSubsystem.h"
#include "Online.h"
#include "Runtime/UMG/Public/UMG.h"
#include "ui/hud/NativeInGameMenuWidget.h"
#include "ui/hud/NativeInstructionsWidget.h"
#include "ui/hud/NativeCharacterSelectWidget.h"

ANativeCoopPlayerController::ANativeCoopPlayerController(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
	, m_instructionsWidget(nullptr)
	, m_inGameMenuWidget(nullptr)
{
	// assign the class types we wish to use
	PlayerCameraManagerClass = ACoopPlayerCameraManager::StaticClass();
}

// -----------------------------------------
// AActor
// -----------------------------------------
void ANativeCoopPlayerController::BeginPlay()
{
	if (IsLocalPlayerController())
	{
		if (InstructionsWidget)
		{
			m_instructionsWidget = CreateWidget<UNativeInstructionsWidget>(this, InstructionsWidget);
			if (m_instructionsWidget)
			{
				m_instructionsWidget->AddToViewport();
				m_instructionsWidget->SetVisibility(ESlateVisibility::Hidden);
			}
		}

		if (InGameMenuWidget)
		{
			m_inGameMenuWidget = CreateWidget<UNativeInGameMenuWidget>(this, InGameMenuWidget);
			if (m_inGameMenuWidget)
			{
				m_inGameMenuWidget->AddToViewport();
				m_inGameMenuWidget->SetVisibility(ESlateVisibility::Hidden);
				m_inGameMenuWidget->OnHideMenuRequested.AddDynamic(this, &self_t::HideInGameMenu);
			}
		}

		if (CharacterSelectWidget)
		{
			m_characterSelectWidget = CreateWidget<UNativeCharacterSelectWidget>(this, CharacterSelectWidget);
			if (m_characterSelectWidget)
			{
				m_characterSelectWidget->AddToViewport();
				m_characterSelectWidget->SetVisibility(ESlateVisibility::Hidden);
			}
		}
	}

	Super::BeginPlay();
}

// -----------------------------------------
// APlayerController
// -----------------------------------------
void ANativeCoopPlayerController::SetupInputComponent()
{
	// let the base class do it's thing
	Super::SetupInputComponent();

	// bind our ui commands
	InputComponent->BindAction("Instructions", IE_Pressed, this, &self_t::OnShowInstructionsPressed);
	InputComponent->BindAction("Instructions", IE_Released, this, &self_t::OnShowInstructionsReleased);
	InputComponent->BindAction("ToggleMenu", IE_Pressed, this, &self_t::ShowInGameMenu);
}

// -----------------------------------------
// User Interface
// -----------------------------------------
void ANativeCoopPlayerController::OnShowInstructionsPressed()
{
	if (m_instructionsWidget)
	{
		m_instructionsWidget->SetVisibility(ESlateVisibility::Visible);
	}
}

void ANativeCoopPlayerController::OnShowInstructionsReleased()
{
	if (m_instructionsWidget)
	{
		m_instructionsWidget->SetVisibility(ESlateVisibility::Hidden);
	}
}

bool ANativeCoopPlayerController::IsGameMenuVisible() const
{
	UE_LOG(LogCoopGameNotImplemented, Error, TEXT("ANativeCoopPlayerController::IsGameMenuVisible()"));
	return false;
}

void ANativeCoopPlayerController::ShowInGameMenu()
{
	if (m_inGameMenuWidget)
	{
		m_inGameMenuWidget->SetVisibility(ESlateVisibility::Visible);

		FInputModeUIOnly inputModeUIOnly;
		SetInputMode(inputModeUIOnly);

		bShowMouseCursor = true;
		bEnableClickEvents = true;
		bEnableMouseOverEvents = true;
	}
}

void ANativeCoopPlayerController::HideInGameMenu()
{
	if (m_inGameMenuWidget)
	{
		m_inGameMenuWidget->SetVisibility(ESlateVisibility::Hidden);

		FInputModeGameOnly inputModeGameOnly;
		SetInputMode(inputModeGameOnly);

		bShowMouseCursor = false;
		bEnableClickEvents = false;
		bEnableMouseOverEvents = false;
	}
}

void ANativeCoopPlayerController::ShowCharacterSelect()
{
	if (m_characterSelectWidget)
	{
		m_characterSelectWidget->SetVisibility(ESlateVisibility::Visible);

		FInputModeUIOnly inputModeUIOnly;
		SetInputMode(inputModeUIOnly);

		bShowMouseCursor = true;
		bEnableClickEvents = true;
		bEnableMouseOverEvents = true;
	}
}

void ANativeCoopPlayerController::HideCharacterSelect()
{
	if (m_characterSelectWidget)
	{
		m_characterSelectWidget->SetVisibility(ESlateVisibility::Hidden);

		FInputModeGameOnly inputModeGameOnly;
		SetInputMode(inputModeGameOnly);

		bShowMouseCursor = false;
		bEnableClickEvents = false;
		bEnableMouseOverEvents = false;
	}
}

// -----------------------------------------
// Online
// -----------------------------------------
void ANativeCoopPlayerController::ClientStartOnlineGame_Implementation()
{
	if (!IsPrimaryPlayer())
		return;

	auto playerState = Cast<ACoopGamePlayerState>(PlayerState);
	if (playerState)
	{
		auto onlineSubsystem = IOnlineSubsystem::Get();
		if (onlineSubsystem)
		{
			auto sessions = onlineSubsystem->GetSessionInterface();
			if (sessions.IsValid())
			{
				UE_LOG(LogCoopGameOnline, Log, TEXT("Starting sesion %s on client"), *playerState->SessionName.ToString());
				sessions->StartSession(playerState->SessionName);
			}
		}
	}
	else
	{
		// player state hasn't been replicated yet, retry
		GetWorld()->GetTimerManager().SetTimer(m_timerHandleWaitingForPlayerState, this, &self_t::ClientStartOnlineGame_Implementation, 0.1f, false);
	}
}

void ANativeCoopPlayerController::ClientEndOnlineGame_Implementation()
{
	if (!IsPrimaryPlayer())
		return;

	auto playerState = Cast<ACoopGamePlayerState>(PlayerState);
	if (playerState)
	{
		auto onlineSubsystem = IOnlineSubsystem::Get();
		if (onlineSubsystem)
		{
			auto sessions = onlineSubsystem->GetSessionInterface();
			if (sessions.IsValid())
			{
				UE_LOG(LogCoopGameOnline, Log, TEXT("Ending session %s on client"), *playerState->SessionName.ToString());
				sessions->EndSession(playerState->SessionName);
			}
		}
	}
}

void ANativeCoopPlayerController::SetPlayerCharacter(TSubclassOf<ANativeCoopCharacter> characterToUse)
{
	UE_LOG(LogCoopGameWeapon, Verbose, TEXT("ANativeCoopPlayerController::SetPlayerCharacter()"));
	if (Role < ROLE_Authority)
	{
		ServerSetPlayerCharacter(characterToUse);
		return;
	}

	if (PlayerState && Cast<ACoopGamePlayerState>(PlayerState))
	{
		auto playerState = Cast<ACoopGamePlayerState>(PlayerState);
		playerState->SelectedCharacter = characterToUse;
	}
}

void ANativeCoopPlayerController::ServerSetPlayerCharacter_Implementation(TSubclassOf<ANativeCoopCharacter> characterToUse)
{
	SetPlayerCharacter(characterToUse);
}

bool ANativeCoopPlayerController::ServerSetPlayerCharacter_Validate(TSubclassOf<ANativeCoopCharacter> characterToUse)
{
	return true;
}
<commit_msg>allow player to change character even after the game has started<commit_after>// Fill out your copyright notice in the Description page of Project Settings.

#include "coopgame.h"
#include "NativeCoopPlayerController.h"
#include "CoopPlayerCameraManager.h"
#include "online/CoopGamePlayerState.h"
#include "OnlineSubsystem.h"
#include "Online.h"
#include "Runtime/UMG/Public/UMG.h"
#include "ui/hud/NativeInGameMenuWidget.h"
#include "ui/hud/NativeInstructionsWidget.h"
#include "ui/hud/NativeCharacterSelectWidget.h"
#include "GameFramework/GameMode.h"

ANativeCoopPlayerController::ANativeCoopPlayerController(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
	, m_instructionsWidget(nullptr)
	, m_inGameMenuWidget(nullptr)
{
	// assign the class types we wish to use
	PlayerCameraManagerClass = ACoopPlayerCameraManager::StaticClass();
}

// -----------------------------------------
// AActor
// -----------------------------------------
void ANativeCoopPlayerController::BeginPlay()
{
	if (IsLocalPlayerController())
	{
		if (InstructionsWidget)
		{
			m_instructionsWidget = CreateWidget<UNativeInstructionsWidget>(this, InstructionsWidget);
			if (m_instructionsWidget)
			{
				m_instructionsWidget->AddToViewport();
				m_instructionsWidget->SetVisibility(ESlateVisibility::Hidden);
			}
		}

		if (InGameMenuWidget)
		{
			m_inGameMenuWidget = CreateWidget<UNativeInGameMenuWidget>(this, InGameMenuWidget);
			if (m_inGameMenuWidget)
			{
				m_inGameMenuWidget->AddToViewport();
				m_inGameMenuWidget->SetVisibility(ESlateVisibility::Hidden);
				m_inGameMenuWidget->OnHideMenuRequested.AddDynamic(this, &self_t::HideInGameMenu);
			}
		}

		if (CharacterSelectWidget)
		{
			m_characterSelectWidget = CreateWidget<UNativeCharacterSelectWidget>(this, CharacterSelectWidget);
			if (m_characterSelectWidget)
			{
				m_characterSelectWidget->AddToViewport();
				m_characterSelectWidget->SetVisibility(ESlateVisibility::Hidden);
			}
		}
	}

	Super::BeginPlay();
}

// -----------------------------------------
// APlayerController
// -----------------------------------------
void ANativeCoopPlayerController::SetupInputComponent()
{
	// let the base class do it's thing
	Super::SetupInputComponent();

	// bind our ui commands
	InputComponent->BindAction("Instructions", IE_Pressed, this, &self_t::OnShowInstructionsPressed);
	InputComponent->BindAction("Instructions", IE_Released, this, &self_t::OnShowInstructionsReleased);
	InputComponent->BindAction("ToggleMenu", IE_Pressed, this, &self_t::ShowInGameMenu);
}

// -----------------------------------------
// User Interface
// -----------------------------------------
void ANativeCoopPlayerController::OnShowInstructionsPressed()
{
	if (m_instructionsWidget)
	{
		m_instructionsWidget->SetVisibility(ESlateVisibility::Visible);
	}
}

void ANativeCoopPlayerController::OnShowInstructionsReleased()
{
	if (m_instructionsWidget)
	{
		m_instructionsWidget->SetVisibility(ESlateVisibility::Hidden);
	}
}

bool ANativeCoopPlayerController::IsGameMenuVisible() const
{
	UE_LOG(LogCoopGameNotImplemented, Error, TEXT("ANativeCoopPlayerController::IsGameMenuVisible()"));
	return false;
}

void ANativeCoopPlayerController::ShowInGameMenu()
{
	if (m_inGameMenuWidget)
	{
		m_inGameMenuWidget->SetVisibility(ESlateVisibility::Visible);

		FInputModeUIOnly inputModeUIOnly;
		SetInputMode(inputModeUIOnly);

		bShowMouseCursor = true;
		bEnableClickEvents = true;
		bEnableMouseOverEvents = true;
	}
}

void ANativeCoopPlayerController::HideInGameMenu()
{
	if (m_inGameMenuWidget)
	{
		m_inGameMenuWidget->SetVisibility(ESlateVisibility::Hidden);

		FInputModeGameOnly inputModeGameOnly;
		SetInputMode(inputModeGameOnly);

		bShowMouseCursor = false;
		bEnableClickEvents = false;
		bEnableMouseOverEvents = false;
	}
}

void ANativeCoopPlayerController::ShowCharacterSelect()
{
	if (m_characterSelectWidget)
	{
		m_characterSelectWidget->SetVisibility(ESlateVisibility::Visible);

		FInputModeUIOnly inputModeUIOnly;
		SetInputMode(inputModeUIOnly);

		bShowMouseCursor = true;
		bEnableClickEvents = true;
		bEnableMouseOverEvents = true;
	}
}

void ANativeCoopPlayerController::HideCharacterSelect()
{
	if (m_characterSelectWidget)
	{
		m_characterSelectWidget->SetVisibility(ESlateVisibility::Hidden);

		FInputModeGameOnly inputModeGameOnly;
		SetInputMode(inputModeGameOnly);

		bShowMouseCursor = false;
		bEnableClickEvents = false;
		bEnableMouseOverEvents = false;
	}
}

// -----------------------------------------
// Online
// -----------------------------------------
void ANativeCoopPlayerController::ClientStartOnlineGame_Implementation()
{
	if (!IsPrimaryPlayer())
		return;

	auto playerState = Cast<ACoopGamePlayerState>(PlayerState);
	if (playerState)
	{
		auto onlineSubsystem = IOnlineSubsystem::Get();
		if (onlineSubsystem)
		{
			auto sessions = onlineSubsystem->GetSessionInterface();
			if (sessions.IsValid())
			{
				UE_LOG(LogCoopGameOnline, Log, TEXT("Starting sesion %s on client"), *playerState->SessionName.ToString());
				sessions->StartSession(playerState->SessionName);
			}
		}
	}
	else
	{
		// player state hasn't been replicated yet, retry
		GetWorld()->GetTimerManager().SetTimer(m_timerHandleWaitingForPlayerState, this, &self_t::ClientStartOnlineGame_Implementation, 0.1f, false);
	}
}

void ANativeCoopPlayerController::ClientEndOnlineGame_Implementation()
{
	if (!IsPrimaryPlayer())
		return;

	auto playerState = Cast<ACoopGamePlayerState>(PlayerState);
	if (playerState)
	{
		auto onlineSubsystem = IOnlineSubsystem::Get();
		if (onlineSubsystem)
		{
			auto sessions = onlineSubsystem->GetSessionInterface();
			if (sessions.IsValid())
			{
				UE_LOG(LogCoopGameOnline, Log, TEXT("Ending session %s on client"), *playerState->SessionName.ToString());
				sessions->EndSession(playerState->SessionName);
			}
		}
	}
}

void ANativeCoopPlayerController::SetPlayerCharacter(TSubclassOf<ANativeCoopCharacter> characterToUse)
{
	UE_LOG(LogCoopGameWeapon, Verbose, TEXT("ANativeCoopPlayerController::SetPlayerCharacter()"));
	if (Role < ROLE_Authority)
	{
		ServerSetPlayerCharacter(characterToUse);
		return;
	}

	if (PlayerState && Cast<ACoopGamePlayerState>(PlayerState))
	{
		auto playerState = Cast<ACoopGamePlayerState>(PlayerState);
		playerState->SelectedCharacter = characterToUse;

		// if the match is already in progress, let's restart the player so that he ends up with the selected character
		AGameMode* gameMode = Cast<AGameMode>(GetWorld()->GetAuthGameMode());
		if (gameMode && gameMode->GetMatchState() == MatchState::InProgress)
		{
			auto existingPawn = GetPawn();
			UnPossess();
			existingPawn->Destroy();
			gameMode->RestartPlayer(this);
		}
	}
}

void ANativeCoopPlayerController::ServerSetPlayerCharacter_Implementation(TSubclassOf<ANativeCoopCharacter> characterToUse)
{
	SetPlayerCharacter(characterToUse);
}

bool ANativeCoopPlayerController::ServerSetPlayerCharacter_Validate(TSubclassOf<ANativeCoopCharacter> characterToUse)
{
	return true;
}
<|endoftext|>