<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2013 Torus Knot Software Ltd

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 "OgreStableHeaders.h"
#include "OgrePrefabFactory.h"
#include "OgreHardwareBufferManager.h"
#include "OgreMesh.h"
#include "OgreSubMesh.h"

namespace Ogre {
	//---------------------------------------------------------------------
	bool PrefabFactory::createPrefab(Mesh* mesh)
	{
		const String& resourceName = mesh->getName();

		if(resourceName == "Prefab_Plane")
		{
			createPlane(mesh);
			return true;
		}
		else if(resourceName == "Prefab_Cube")
		{
			createCube(mesh);
			return true;
		}
		else if(resourceName == "Prefab_Sphere")
		{
			createSphere(mesh);
			return true;
		}

		return false;
	}
	//---------------------------------------------------------------------
	void PrefabFactory::createPlane(Mesh* mesh)
	{
		SubMesh* sub = mesh->createSubMesh();
		float vertices[32] = {
			-100, -100, 0,	// pos
			0,0,1,			// normal
			0,1,			// texcoord
			100, -100, 0,
			0,0,1,
			1,1,
			100,  100, 0,
			0,0,1,
			1,0,
			-100,  100, 0 ,
			0,0,1,
			0,0
		};
		mesh->sharedVertexData = OGRE_NEW VertexData();
		mesh->sharedVertexData->vertexCount = 4;
		VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
		VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;

		size_t offset = 0;
		decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
		offset += VertexElement::getTypeSize(VET_FLOAT2);

		HardwareVertexBufferSharedPtr vbuf =
			HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		bind->setBinding(0, vbuf);

		vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

		sub->useSharedVertices = true;
		HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
			createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,
			6,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

		unsigned short faces[6] = {0,1,2,
			0,2,3 };
		sub->indexData->indexBuffer = ibuf;
		sub->indexData->indexCount = 6;
		sub->indexData->indexStart =0;
		ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

		mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true);
		mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100));
	}
	//---------------------------------------------------------------------
	void PrefabFactory::createCube(Mesh* mesh)
	{
		SubMesh* sub = mesh->createSubMesh();

		const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides
		const int NUM_ENTRIES_PER_VERTEX = 8;
		const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX;
		const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides

		const Real CUBE_SIZE = 100.0f;
		const Real CUBE_HALF_SIZE = CUBE_SIZE / 2.0f;

		// Create 4 vertices per side instead of 6 that are shared for the whole cube.
		// The reason for this is with only 6 vertices the normals will look bad
		// since each vertex can "point" in a different direction depending on the face it is included in.
		float vertices[NUM_VERTEX_ENTRIES] = {
			// front side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,	// pos
			0,0,1,	// normal
			0,1,	// texcoord
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,0,1,
			1,1,
			CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,0,1,
			1,0,
			-CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE ,
			0,0,1,
			0,0,

			// back side
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			0,1,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			1,1,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			1,0,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			0,0,

			// left side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			-1,0,0,
			0,1,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			-1,0,0,
			1,1,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			-1,0,0,
			1,0,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			-1,0,0,
			0,0,

			// right side
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			1,0,0,
			0,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			1,0,0,
			1,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			1,0,0,
			1,0,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			1,0,0,
			0,0,

			// up side
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,1,0,
			0,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,1,0,
			1,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,1,0,
			1,0,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,1,0,
			0,0,

			// down side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,-1,0,
			0,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,-1,0,
			1,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,-1,0,
			1,0,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,-1,0,
			0,0
		};

		mesh->sharedVertexData = OGRE_NEW VertexData();
		mesh->sharedVertexData->vertexCount = NUM_VERTICES;
		VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
		VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;

		size_t offset = 0;
		decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
		offset += VertexElement::getTypeSize(VET_FLOAT2);

		HardwareVertexBufferSharedPtr vbuf =
			HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		bind->setBinding(0, vbuf);

		vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

		sub->useSharedVertices = true;
		HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
			createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,
			NUM_INDICES,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

		unsigned short faces[NUM_INDICES] = {
			// front
			0,1,2,
			0,2,3,

			// back
			4,5,6,
			4,6,7,

			// left
			8,9,10,
			8,10,11,

			// right
			12,13,14,
			12,14,15,

			// up
			16,17,18,
			16,18,19,

			// down
			20,21,22,
			20,22,23
		};

		sub->indexData->indexBuffer = ibuf;
		sub->indexData->indexCount = NUM_INDICES;
		sub->indexData->indexStart = 0;
		ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

		mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true);

		mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE);
	}
	//---------------------------------------------------------------------
	void PrefabFactory::createSphere(Mesh* mesh)
	{
		// sphere creation code taken from the DeferredShading sample, originally from the wiki
		SubMesh *pSphereVertex = mesh->createSubMesh();

		const int NUM_SEGMENTS = 16;
		const int NUM_RINGS = 16;
		const Real SPHERE_RADIUS = 50.0;

		mesh->sharedVertexData = OGRE_NEW VertexData();
		VertexData* vertexData = mesh->sharedVertexData;

		// define the vertex format
		VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
		size_t currOffset = 0;
		// positions
		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
		currOffset += VertexElement::getTypeSize(VET_FLOAT3);
		// normals
		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
		currOffset += VertexElement::getTypeSize(VET_FLOAT3);
		// two dimensional texture coordinates
		vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

		// allocate the vertex buffer
		vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1);
		HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
		VertexBufferBinding* binding = vertexData->vertexBufferBinding;
		binding->setBinding(0, vBuf);
		float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

		// allocate index buffer
		pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1);
		pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
		HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
		unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));

		float fDeltaRingAngle = (Math::PI / NUM_RINGS);
		float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS);
		unsigned short wVerticeIndex = 0 ;

		// Generate the group of rings for the sphere
		for( int ring = 0; ring <= NUM_RINGS; ring++ ) {
			float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle);
			float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle);

			// Generate the group of segments for the current ring
			for(int seg = 0; seg <= NUM_SEGMENTS; seg++) {
				float x0 = r0 * sinf(seg * fDeltaSegAngle);
				float z0 = r0 * cosf(seg * fDeltaSegAngle);

				// Add one vertex to the strip which makes up the sphere
				*pVertex++ = x0;
				*pVertex++ = y0;
				*pVertex++ = z0;

				Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
				*pVertex++ = vNormal.x;
				*pVertex++ = vNormal.y;
				*pVertex++ = vNormal.z;

				*pVertex++ = (float) seg / (float) NUM_SEGMENTS;
				*pVertex++ = (float) ring / (float) NUM_RINGS;

				if (ring != NUM_RINGS) {
					// each vertex (except the last) has six indicies pointing to it
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
					*pIndices++ = wVerticeIndex;
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS;
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
					*pIndices++ = wVerticeIndex + 1;
					*pIndices++ = wVerticeIndex;
					wVerticeIndex ++;
				}
			}; // end for seg
		} // end for ring

		// Unlock
		vBuf->unlock();
		iBuf->unlock();
		// Generate face list
		pSphereVertex->useSharedVertices = true;

		// the original code was missing this line:
		mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS),
			Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false );

		mesh->_setBoundingSphereRadius(SPHERE_RADIUS);
	}
	//---------------------------------------------------------------------
}
<commit_msg>Fix double precision builds when using c++11<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2013 Torus Knot Software Ltd

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 "OgreStableHeaders.h"
#include "OgrePrefabFactory.h"
#include "OgreHardwareBufferManager.h"
#include "OgreMesh.h"
#include "OgreSubMesh.h"

namespace Ogre {
	//---------------------------------------------------------------------
	bool PrefabFactory::createPrefab(Mesh* mesh)
	{
		const String& resourceName = mesh->getName();

		if(resourceName == "Prefab_Plane")
		{
			createPlane(mesh);
			return true;
		}
		else if(resourceName == "Prefab_Cube")
		{
			createCube(mesh);
			return true;
		}
		else if(resourceName == "Prefab_Sphere")
		{
			createSphere(mesh);
			return true;
		}

		return false;
	}
	//---------------------------------------------------------------------
	void PrefabFactory::createPlane(Mesh* mesh)
	{
		SubMesh* sub = mesh->createSubMesh();
		float vertices[32] = {
			-100, -100, 0,	// pos
			0,0,1,			// normal
			0,1,			// texcoord
			100, -100, 0,
			0,0,1,
			1,1,
			100,  100, 0,
			0,0,1,
			1,0,
			-100,  100, 0 ,
			0,0,1,
			0,0
		};
		mesh->sharedVertexData = OGRE_NEW VertexData();
		mesh->sharedVertexData->vertexCount = 4;
		VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
		VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;

		size_t offset = 0;
		decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
		offset += VertexElement::getTypeSize(VET_FLOAT2);

		HardwareVertexBufferSharedPtr vbuf =
			HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		bind->setBinding(0, vbuf);

		vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

		sub->useSharedVertices = true;
		HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
			createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,
			6,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

		unsigned short faces[6] = {0,1,2,
			0,2,3 };
		sub->indexData->indexBuffer = ibuf;
		sub->indexData->indexCount = 6;
		sub->indexData->indexStart =0;
		ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

		mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true);
		mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100));
	}
	//---------------------------------------------------------------------
	void PrefabFactory::createCube(Mesh* mesh)
	{
		SubMesh* sub = mesh->createSubMesh();

		const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides
		const int NUM_ENTRIES_PER_VERTEX = 8;
		const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX;
		const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides

		const float CUBE_SIZE = 100.0f;
		const float CUBE_HALF_SIZE = CUBE_SIZE / 2.0f;

		// Create 4 vertices per side instead of 6 that are shared for the whole cube.
		// The reason for this is with only 6 vertices the normals will look bad
		// since each vertex can "point" in a different direction depending on the face it is included in.
		float vertices[NUM_VERTEX_ENTRIES] = {
			// front side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,	// pos
			0,0,1,	// normal
			0,1,	// texcoord
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,0,1,
			1,1,
			CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,0,1,
			1,0,
			-CUBE_HALF_SIZE,  CUBE_HALF_SIZE, CUBE_HALF_SIZE ,
			0,0,1,
			0,0,

			// back side
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			0,1,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			1,1,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			1,0,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,0,-1,
			0,0,

			// left side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			-1,0,0,
			0,1,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			-1,0,0,
			1,1,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			-1,0,0,
			1,0,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			-1,0,0,
			0,0,

			// right side
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			1,0,0,
			0,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			1,0,0,
			1,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			1,0,0,
			1,0,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			1,0,0,
			0,0,

			// up side
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,1,0,
			0,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,1,0,
			1,1,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,1,0,
			1,0,
			-CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,1,0,
			0,0,

			// down side
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,-1,0,
			0,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			0,-1,0,
			1,1,
			CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,-1,0,
			1,0,
			-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE,
			0,-1,0,
			0,0
		};

		mesh->sharedVertexData = OGRE_NEW VertexData();
		mesh->sharedVertexData->vertexCount = NUM_VERTICES;
		VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration;
		VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding;

		size_t offset = 0;
		decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
		offset += VertexElement::getTypeSize(VET_FLOAT3);
		decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
		offset += VertexElement::getTypeSize(VET_FLOAT2);

		HardwareVertexBufferSharedPtr vbuf =
			HardwareBufferManager::getSingleton().createVertexBuffer(
			offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
		bind->setBinding(0, vbuf);

		vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);

		sub->useSharedVertices = true;
		HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
			createIndexBuffer(
			HardwareIndexBuffer::IT_16BIT,
			NUM_INDICES,
			HardwareBuffer::HBU_STATIC_WRITE_ONLY);

		unsigned short faces[NUM_INDICES] = {
			// front
			0,1,2,
			0,2,3,

			// back
			4,5,6,
			4,6,7,

			// left
			8,9,10,
			8,10,11,

			// right
			12,13,14,
			12,14,15,

			// up
			16,17,18,
			16,18,19,

			// down
			20,21,22,
			20,22,23
		};

		sub->indexData->indexBuffer = ibuf;
		sub->indexData->indexCount = NUM_INDICES;
		sub->indexData->indexStart = 0;
		ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);

		mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE,
			CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true);

		mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE);
	}
	//---------------------------------------------------------------------
	void PrefabFactory::createSphere(Mesh* mesh)
	{
		// sphere creation code taken from the DeferredShading sample, originally from the wiki
		SubMesh *pSphereVertex = mesh->createSubMesh();

		const int NUM_SEGMENTS = 16;
		const int NUM_RINGS = 16;
		const Real SPHERE_RADIUS = 50.0;

		mesh->sharedVertexData = OGRE_NEW VertexData();
		VertexData* vertexData = mesh->sharedVertexData;

		// define the vertex format
		VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
		size_t currOffset = 0;
		// positions
		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION);
		currOffset += VertexElement::getTypeSize(VET_FLOAT3);
		// normals
		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL);
		currOffset += VertexElement::getTypeSize(VET_FLOAT3);
		// two dimensional texture coordinates
		vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

		// allocate the vertex buffer
		vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1);
		HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
		VertexBufferBinding* binding = vertexData->vertexBufferBinding;
		binding->setBinding(0, vBuf);
		float* pVertex = static_cast<float*>(vBuf->lock(HardwareBuffer::HBL_DISCARD));

		// allocate index buffer
		pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1);
		pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
		HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer;
		unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(HardwareBuffer::HBL_DISCARD));

		float fDeltaRingAngle = (Math::PI / NUM_RINGS);
		float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS);
		unsigned short wVerticeIndex = 0 ;

		// Generate the group of rings for the sphere
		for( int ring = 0; ring <= NUM_RINGS; ring++ ) {
			float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle);
			float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle);

			// Generate the group of segments for the current ring
			for(int seg = 0; seg <= NUM_SEGMENTS; seg++) {
				float x0 = r0 * sinf(seg * fDeltaSegAngle);
				float z0 = r0 * cosf(seg * fDeltaSegAngle);

				// Add one vertex to the strip which makes up the sphere
				*pVertex++ = x0;
				*pVertex++ = y0;
				*pVertex++ = z0;

				Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy();
				*pVertex++ = vNormal.x;
				*pVertex++ = vNormal.y;
				*pVertex++ = vNormal.z;

				*pVertex++ = (float) seg / (float) NUM_SEGMENTS;
				*pVertex++ = (float) ring / (float) NUM_RINGS;

				if (ring != NUM_RINGS) {
					// each vertex (except the last) has six indicies pointing to it
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
					*pIndices++ = wVerticeIndex;
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS;
					*pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1;
					*pIndices++ = wVerticeIndex + 1;
					*pIndices++ = wVerticeIndex;
					wVerticeIndex ++;
				}
			}; // end for seg
		} // end for ring

		// Unlock
		vBuf->unlock();
		iBuf->unlock();
		// Generate face list
		pSphereVertex->useSharedVertices = true;

		// the original code was missing this line:
		mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS),
			Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false );

		mesh->_setBoundingSphereRadius(SPHERE_RADIUS);
	}
	//---------------------------------------------------------------------
}
<|endoftext|>


<commit_before>/**************************************************************************
 * The MIT License                                                        *
 * Copyright (c) 2013 Antony Arciuolo.                                    *
 * arciuolo@gmail.com                                                     *
 *                                                                        *
 * 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 <oGUI/oGUIMenu.h>
#include <oBase/assert.h>
#include <oCore/windows/win_error.h>
#include <oBasis/oError.h> // @tony fixme

using namespace ouro;

#if 0
// not in use (yet?)
static int oGUIMenuFindPosition(ouro::menu_handle _hParentMenu, int _ItemID)
{
	const int n = oGUIMenuGetNumItems(_hParentMenu);
	for (int i = 0; i < n; i++)
	{
		int ID = GetMenuItemID(_hParentMenu, i);
		if (ID == _ItemID)
			return i;
	}
	return oInvalid;
}
#endif

static int oGUIMenuFindPosition(ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu)
{
	const int n = GetMenuItemCount((HMENU)_hParentMenu);
	for (int i = 0; i < n; i++)
	{
		ouro::menu_handle hSubmenu = (ouro::menu_handle)GetSubMenu((HMENU)_hParentMenu, i);
		if (hSubmenu == _hSubmenu)
			return i;
	}
	return oInvalid;
}

#ifdef oENABLE_ASSERTS
// Returns true if the specified menu contains all IDs [first,last]
static bool oGUIMenuContainsRange(ouro::menu_handle _hMenu, int _ItemIDRangeFirst, int _ItemIDRangeLast)
{
	MENUITEMINFO mii;
	mii.cbSize = sizeof(MENUITEMINFO);
	mii.fMask = MIIM_ID;

	int nFound = 0;
	const int n = oGUIMenuGetNumItems(_hMenu);
	for (int i = 0; i < n; i++)
	{
		UINT uID = GetMenuItemID((HMENU)_hMenu, i);
		if (uID == oInvalid)
			return false;
		int ID = oInt(uID);
		if (ID >= _ItemIDRangeFirst && ID <= _ItemIDRangeLast)
			nFound++;
	}

	return nFound == (_ItemIDRangeLast - _ItemIDRangeFirst + 1);
}
#endif

char* oGUIMenuGetTextByPosition(char* _StrDestination, size_t _SizeofStrDestination, ouro::menu_handle _hMenu, int _MenuItemPosition)
{
	if (!GetMenuStringA((HMENU)_hMenu, _MenuItemPosition, _StrDestination, oInt(_SizeofStrDestination), MF_BYPOSITION))
		return nullptr;
	return _StrDestination;
}

ouro::menu_handle oGUIMenuCreate(bool _IsTopLevelMenu)
{
	return (ouro::menu_handle)(_IsTopLevelMenu ? CreateMenu() : CreatePopupMenu());
}

void oGUIMenuDestroy(ouro::menu_handle _hMenu)
{
	if (IsMenu((HMENU)_hMenu))
		oVB(DestroyMenu((HMENU)_hMenu));
}

void oGUIMenuAttach(ouro::window_handle _hWindow, ouro::menu_handle _hMenu)
{
	oVB(SetMenu((HWND)_hWindow, (HMENU)_hMenu));
}

int oGUIMenuGetNumItems(ouro::menu_handle _hMenu)
{
	return oInt(GetMenuItemCount((HMENU)_hMenu));
}

void oGUIMenuAppendSubmenu(ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu, const char* _Text)
{
	oVB(AppendMenu((HMENU)_hParentMenu, MF_STRING|MF_POPUP, (UINT_PTR)_hSubmenu, _Text));
}

void oGUIMenuRemoveSubmenu(ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu)
{
	int p = oGUIMenuFindPosition(_hParentMenu, _hSubmenu);
	if (p != oInvalid && !RemoveMenu((HMENU)_hParentMenu, p, MF_BYPOSITION))
	{
		DWORD hr = GetLastError();
		if (GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND)
			oV(hr);
	}
}

void oGUIMenuAppendItem(ouro::menu_handle _hParentMenu, int _ItemID, const char* _Text)
{
	oVB(AppendMenu((HMENU)_hParentMenu, MF_STRING, (UINT_PTR)_ItemID, _Text));
}

void oGUIMenuRemoveItem(ouro::menu_handle _hParentMenu, int _ItemID)
{
	if (!RemoveMenu((HMENU)_hParentMenu, _ItemID, MF_BYCOMMAND))
	{
		DWORD hr = GetLastError();
		if (GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND)
			oV(hr);
	}
}

void oGUIMenuRemoveAllItems(ouro::menu_handle _hMenu)
{
	int n = GetMenuItemCount((HMENU)_hMenu);
	while (n)
	{
		DeleteMenu((HMENU)_hMenu, n-1, MF_BYPOSITION);
		n = GetMenuItemCount((HMENU)_hMenu);
	}
}

void oGUIMenuItemToSubmenu(ouro::menu_handle _hParentMenu, int _ItemID, ouro::menu_handle _hSubmenu)
{
	mstring text;
	oVERIFY(oGUIMenuGetText(text, _hParentMenu, _ItemID));
	oVB(RemoveMenu((HMENU)_hParentMenu, _ItemID, MF_BYCOMMAND));
	oVB(InsertMenu((HMENU)_hParentMenu, _ItemID, MF_STRING|MF_POPUP, (UINT_PTR)_hSubmenu, text));
}

void oGUIMenuSubmenuToItem(ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu, int _ItemID, bool _Enabled)
{
	int p = oGUIMenuFindPosition(_hParentMenu, _hSubmenu);
	oASSERT(p != oInvalid, "the specified submenu is not under the specified parent menu");

	mstring text;
	oVERIFY(oGUIMenuGetTextByPosition(text, text.capacity(), _hParentMenu, p));
	oVB(DeleteMenu((HMENU)_hParentMenu, p, MF_BYPOSITION));

	UINT uFlags = MF_BYPOSITION|MF_STRING;
	if (!_Enabled)
		uFlags |= MF_GRAYED;

	oVB(InsertMenu((HMENU)_hParentMenu, p, uFlags, (UINT_PTR)_ItemID, text.c_str()));
}

void oGUIMenuAppendSeparator(ouro::menu_handle _hParentMenu)
{
	oVB(AppendMenu((HMENU)_hParentMenu, MF_SEPARATOR, 0, nullptr));
}

void oGUIMenuCheck(ouro::menu_handle _hMenu, int _ItemID, bool _Checked)
{
	if (-1 == CheckMenuItem((HMENU)_hMenu, oUInt(_ItemID), MF_BYCOMMAND | (_Checked ? MF_CHECKED : MF_UNCHECKED)))
		oASSERT(false, "MenuItemID not found in the specified menu");
}

bool oGUIMenuIsChecked(ouro::menu_handle _hMenu, int _ItemID)
{
	MENUITEMINFO mii;
	ZeroMemory(&mii, sizeof(mii));
	mii.cbSize = sizeof(mii);
	mii.fMask = MIIM_STATE;
	if (!GetMenuItemInfo((HMENU)_hMenu, oUInt(_ItemID), FALSE, &mii))
		return false;

	if (mii.fState & MFS_CHECKED)
		return true;

	oErrorSetLast(0);
	return false;
}

void oGUIMenuCheckRadio(ouro::menu_handle _hMenu, int _ItemIDRadioRangeFirst, int _ItemIDRadioRangeLast, int _ItemIDToCheck)
{
	// CheckMenuRadioItem returns false if the menu is wrong, but doesn't set a
	// useful last error (S_OK is returned when I ran into this) so add our own
	// check here.
	oASSERT(oGUIMenuGetNumItems(_hMenu) >= (_ItemIDRadioRangeLast-_ItemIDRadioRangeFirst+1), "A radio range was specified that is larger than the number of elements in the list (menu count=%d, range implies %d items)", oGUIMenuGetNumItems(_hMenu), (_ItemIDRadioRangeLast-_ItemIDRadioRangeFirst+1));
	oASSERT(oGUIMenuContainsRange(_hMenu, _ItemIDRadioRangeFirst, _ItemIDRadioRangeLast), "The specified menu 0x%p does not include the specified range [%d,%d] with selected %d. Most API works with an ancestor menu but this requires the immediate parent, so if the ranges look correct check the specified _hMenu.", _hMenu, _ItemIDRadioRangeFirst, _ItemIDRadioRangeLast, _ItemIDToCheck);
	oVB(CheckMenuRadioItem((HMENU)_hMenu, _ItemIDRadioRangeFirst, _ItemIDRadioRangeLast, _ItemIDToCheck, MF_BYCOMMAND));
}

int oGUIMenuGetCheckedRadio(ouro::menu_handle _hMenu, int _ItemIDRadioRangeFirst, int _ItemIDRadioRangeLast)
{
	for (int i = _ItemIDRadioRangeFirst; i <= _ItemIDRadioRangeLast; i++)
		if (oGUIMenuIsChecked(_hMenu, i))
			return i;
	return oInvalid;
}

void oGUIMenuEnable(ouro::menu_handle _hMenu, int _ItemID, bool _Enabled)
{
	if (-1 == EnableMenuItem((HMENU)_hMenu, oUInt(_ItemID), MF_BYCOMMAND | (_Enabled ? MF_ENABLED : MF_GRAYED)))
		oASSERT(false, "MenuItemID not found in the specified menu");
}

bool oGUIMenuIsEnabled(ouro::menu_handle _hMenu, int _ItemID)
{
	MENUITEMINFO mii;
	ZeroMemory(&mii, sizeof(mii));
	mii.cbSize = sizeof(mii);
	mii.fMask = MIIM_STATE;
	oVB(GetMenuItemInfo((HMENU)_hMenu, oUInt(_ItemID), FALSE, &mii));
	if (mii.fState & (MF_GRAYED|MF_DISABLED))
		return false;
	return true;
}

char* oGUIMenuGetText(char* _StrDestination, size_t _SizeofStrDestination, ouro::menu_handle _hMenu, int _ItemID)
{
	if (!GetMenuStringA((HMENU)_hMenu, _ItemID, _StrDestination, oInt(_SizeofStrDestination), MF_BYCOMMAND))
		return nullptr;
	return _StrDestination;
}

char* oGUIMenuGetText(char* _StrDestination, size_t _SizeofStrDestination, ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu)
{
	int pos = oGUIMenuFindPosition(_hParentMenu, _hSubmenu);
	if (pos == oInvalid)
		return nullptr;
	return oGUIMenuGetTextByPosition(_StrDestination, _SizeofStrDestination, _hParentMenu, pos);
}
<commit_msg>Forgot this file.. Prep for VS2012 upgrade: better std::error_category compat, don't use SafeInt3 - favor a simpler assert in the few places it matters. Thus also get rid of oInt and reduce the usage of oInvalid.<commit_after>/**************************************************************************
 * The MIT License                                                        *
 * Copyright (c) 2013 Antony Arciuolo.                                    *
 * arciuolo@gmail.com                                                     *
 *                                                                        *
 * 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 <oGUI/oGUIMenu.h>
#include <oBase/assert.h>
#include <oCore/windows/win_error.h>
#include <oBasis/oError.h> // @tony fixme

using namespace ouro;

#if 0
// not in use (yet?)
static int oGUIMenuFindPosition(ouro::menu_handle _hParentMenu, int _ItemID)
{
	const int n = oGUIMenuGetNumItems(_hParentMenu);
	for (int i = 0; i < n; i++)
	{
		int ID = GetMenuItemID(_hParentMenu, i);
		if (ID == _ItemID)
			return i;
	}
	return oInvalid;
}
#endif

static int oGUIMenuFindPosition(ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu)
{
	const int n = GetMenuItemCount((HMENU)_hParentMenu);
	for (int i = 0; i < n; i++)
	{
		ouro::menu_handle hSubmenu = (ouro::menu_handle)GetSubMenu((HMENU)_hParentMenu, i);
		if (hSubmenu == _hSubmenu)
			return i;
	}
	return -1;
}

#ifdef oENABLE_ASSERTS
// Returns true if the specified menu contains all IDs [first,last]
static bool oGUIMenuContainsRange(ouro::menu_handle _hMenu, int _ItemIDRangeFirst, int _ItemIDRangeLast)
{
	MENUITEMINFO mii;
	mii.cbSize = sizeof(MENUITEMINFO);
	mii.fMask = MIIM_ID;

	int nFound = 0;
	const int n = oGUIMenuGetNumItems(_hMenu);
	for (int i = 0; i < n; i++)
	{
		UINT uID = GetMenuItemID((HMENU)_hMenu, i);
		oCHECK_SIZE(int, uID);
		if (uID == ~0u)
			return false;
		int ID = static_cast<int>(uID);
		if (ID >= _ItemIDRangeFirst && ID <= _ItemIDRangeLast)
			nFound++;
	}

	return nFound == (_ItemIDRangeLast - _ItemIDRangeFirst + 1);
}
#endif

char* oGUIMenuGetTextByPosition(char* _StrDestination, size_t _SizeofStrDestination, ouro::menu_handle _hMenu, int _MenuItemPosition)
{
	oCHECK_SIZE(int, _SizeofStrDestination);
	if (!GetMenuStringA((HMENU)_hMenu, _MenuItemPosition, _StrDestination, static_cast<int>(_SizeofStrDestination), MF_BYPOSITION))
		return nullptr;
	return _StrDestination;
}

ouro::menu_handle oGUIMenuCreate(bool _IsTopLevelMenu)
{
	return (ouro::menu_handle)(_IsTopLevelMenu ? CreateMenu() : CreatePopupMenu());
}

void oGUIMenuDestroy(ouro::menu_handle _hMenu)
{
	if (IsMenu((HMENU)_hMenu))
		oVB(DestroyMenu((HMENU)_hMenu));
}

void oGUIMenuAttach(ouro::window_handle _hWindow, ouro::menu_handle _hMenu)
{
	oVB(SetMenu((HWND)_hWindow, (HMENU)_hMenu));
}

int oGUIMenuGetNumItems(ouro::menu_handle _hMenu)
{

	return GetMenuItemCount((HMENU)_hMenu);
}

void oGUIMenuAppendSubmenu(ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu, const char* _Text)
{
	oVB(AppendMenu((HMENU)_hParentMenu, MF_STRING|MF_POPUP, (UINT_PTR)_hSubmenu, _Text));
}

void oGUIMenuRemoveSubmenu(ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu)
{
	int p = oGUIMenuFindPosition(_hParentMenu, _hSubmenu);
	if (p != -1 && !RemoveMenu((HMENU)_hParentMenu, p, MF_BYPOSITION))
	{
		DWORD hr = GetLastError();
		if (GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND)
			oV(hr);
	}
}

void oGUIMenuAppendItem(ouro::menu_handle _hParentMenu, int _ItemID, const char* _Text)
{
	oVB(AppendMenu((HMENU)_hParentMenu, MF_STRING, (UINT_PTR)_ItemID, _Text));
}

void oGUIMenuRemoveItem(ouro::menu_handle _hParentMenu, int _ItemID)
{
	if (!RemoveMenu((HMENU)_hParentMenu, _ItemID, MF_BYCOMMAND))
	{
		DWORD hr = GetLastError();
		if (GetLastError() != ERROR_RESOURCE_TYPE_NOT_FOUND)
			oV(hr);
	}
}

void oGUIMenuRemoveAllItems(ouro::menu_handle _hMenu)
{
	int n = GetMenuItemCount((HMENU)_hMenu);
	while (n)
	{
		DeleteMenu((HMENU)_hMenu, n-1, MF_BYPOSITION);
		n = GetMenuItemCount((HMENU)_hMenu);
	}
}

void oGUIMenuItemToSubmenu(ouro::menu_handle _hParentMenu, int _ItemID, ouro::menu_handle _hSubmenu)
{
	mstring text;
	oVERIFY(oGUIMenuGetText(text, _hParentMenu, _ItemID));
	oVB(RemoveMenu((HMENU)_hParentMenu, _ItemID, MF_BYCOMMAND));
	oVB(InsertMenu((HMENU)_hParentMenu, _ItemID, MF_STRING|MF_POPUP, (UINT_PTR)_hSubmenu, text));
}

void oGUIMenuSubmenuToItem(ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu, int _ItemID, bool _Enabled)
{
	int p = oGUIMenuFindPosition(_hParentMenu, _hSubmenu);
	oASSERT(p != -1, "the specified submenu is not under the specified parent menu");

	mstring text;
	oVERIFY(oGUIMenuGetTextByPosition(text, text.capacity(), _hParentMenu, p));
	oVB(DeleteMenu((HMENU)_hParentMenu, p, MF_BYPOSITION));

	UINT uFlags = MF_BYPOSITION|MF_STRING;
	if (!_Enabled)
		uFlags |= MF_GRAYED;

	oVB(InsertMenu((HMENU)_hParentMenu, p, uFlags, (UINT_PTR)_ItemID, text.c_str()));
}

void oGUIMenuAppendSeparator(ouro::menu_handle _hParentMenu)
{
	oVB(AppendMenu((HMENU)_hParentMenu, MF_SEPARATOR, 0, nullptr));
}

void oGUIMenuCheck(ouro::menu_handle _hMenu, int _ItemID, bool _Checked)
{
	oASSERT(_ItemID >= 0, "");
	if (-1 == CheckMenuItem((HMENU)_hMenu, static_cast<unsigned int>(_ItemID), MF_BYCOMMAND | (_Checked ? MF_CHECKED : MF_UNCHECKED)))
		oASSERT(false, "MenuItemID not found in the specified menu");
}

bool oGUIMenuIsChecked(ouro::menu_handle _hMenu, int _ItemID)
{
	MENUITEMINFO mii;
	ZeroMemory(&mii, sizeof(mii));
	mii.cbSize = sizeof(mii);
	mii.fMask = MIIM_STATE;
	oASSERT(_ItemID >= 0, "");
	if (!GetMenuItemInfo((HMENU)_hMenu, static_cast<unsigned int>(_ItemID), FALSE, &mii))
		return false;

	if (mii.fState & MFS_CHECKED)
		return true;

	oErrorSetLast(0);
	return false;
}

void oGUIMenuCheckRadio(ouro::menu_handle _hMenu, int _ItemIDRadioRangeFirst, int _ItemIDRadioRangeLast, int _ItemIDToCheck)
{
	// CheckMenuRadioItem returns false if the menu is wrong, but doesn't set a
	// useful last error (S_OK is returned when I ran into this) so add our own
	// check here.
	oASSERT(oGUIMenuGetNumItems(_hMenu) >= (_ItemIDRadioRangeLast-_ItemIDRadioRangeFirst+1), "A radio range was specified that is larger than the number of elements in the list (menu count=%d, range implies %d items)", oGUIMenuGetNumItems(_hMenu), (_ItemIDRadioRangeLast-_ItemIDRadioRangeFirst+1));
	oASSERT(oGUIMenuContainsRange(_hMenu, _ItemIDRadioRangeFirst, _ItemIDRadioRangeLast), "The specified menu 0x%p does not include the specified range [%d,%d] with selected %d. Most API works with an ancestor menu but this requires the immediate parent, so if the ranges look correct check the specified _hMenu.", _hMenu, _ItemIDRadioRangeFirst, _ItemIDRadioRangeLast, _ItemIDToCheck);
	oVB(CheckMenuRadioItem((HMENU)_hMenu, _ItemIDRadioRangeFirst, _ItemIDRadioRangeLast, _ItemIDToCheck, MF_BYCOMMAND));
}

int oGUIMenuGetCheckedRadio(ouro::menu_handle _hMenu, int _ItemIDRadioRangeFirst, int _ItemIDRadioRangeLast)
{
	for (int i = _ItemIDRadioRangeFirst; i <= _ItemIDRadioRangeLast; i++)
		if (oGUIMenuIsChecked(_hMenu, i))
			return i;
	return -1;
}

void oGUIMenuEnable(ouro::menu_handle _hMenu, int _ItemID, bool _Enabled)
{
	oASSERT(_ItemID >= 0, "");
	if (-1 == EnableMenuItem((HMENU)_hMenu, static_cast<unsigned int>(_ItemID), MF_BYCOMMAND | (_Enabled ? MF_ENABLED : MF_GRAYED)))
		oASSERT(false, "MenuItemID not found in the specified menu");
}

bool oGUIMenuIsEnabled(ouro::menu_handle _hMenu, int _ItemID)
{
	MENUITEMINFO mii;
	ZeroMemory(&mii, sizeof(mii));
	mii.cbSize = sizeof(mii);
	mii.fMask = MIIM_STATE;
	oASSERT(_ItemID >= 0, "");
	oVB(GetMenuItemInfo((HMENU)_hMenu, static_cast<unsigned int>(_ItemID), FALSE, &mii));
	if (mii.fState & (MF_GRAYED|MF_DISABLED))
		return false;
	return true;
}

char* oGUIMenuGetText(char* _StrDestination, size_t _SizeofStrDestination, ouro::menu_handle _hMenu, int _ItemID)
{
	oCHECK_SIZE(int, _SizeofStrDestination);
	if (!GetMenuStringA((HMENU)_hMenu, _ItemID, _StrDestination, static_cast<int>(_SizeofStrDestination), MF_BYCOMMAND))
		return nullptr;
	return _StrDestination;
}

char* oGUIMenuGetText(char* _StrDestination, size_t _SizeofStrDestination, ouro::menu_handle _hParentMenu, ouro::menu_handle _hSubmenu)
{
	int pos = oGUIMenuFindPosition(_hParentMenu, _hSubmenu);
	if (pos == -1)
		return nullptr;
	return oGUIMenuGetTextByPosition(_StrDestination, _SizeofStrDestination, _hParentMenu, pos);
}
<|endoftext|>


<commit_before>// Trie.cpp

#include "Trie.h"
#include "Node.h"
#include "Util.h"

Trie::Trie() {
  root = new Node( char(0), false );
}

Trie::~Trie() {
  delete root;
}

// add details
void Trie::addWord( std::string s ) {
  Node* current = root;

  if( s.length() == 0 ) {
    current->setCompleteWord();
    return;
  }

  // loop through each character and build a Trie
  for( int i = 0; i < s.length(); ++i ) {
    Node* nextNode = current->findChild( s[i] );
    if( !nextNode ) {
      Node* temp = new Node( s[i], false ) ;
      current->appendChild( temp );
      current = temp;
    } else {
      current = nextNode;
    }

    if( i == s.length() - 1 ) {
      current->setCompleteWord();
    }
  }
}

bool Trie::removeWord( std::string s ) {
  bool bRet = false;
  // effectively we are reseting the marker bit
  // we could potentially get rid of un wanted characters but I would leave up for optimization
  //TODO: optimize to remove un-necessary children
  Node* current = root;

  if( s.length() == 0 ) {
    current->setCompleteWord( false );
  }

  // loop through each character and build a Trie
  for( int i = 0; i < s.length(); ++i ) {
    Node* nextNode = current->findChild( s[i] );
    if( !nextNode ) {
    // if we dont find the child, the word is not in TRIE
    // bail out here
    bRet = true; // just for the hack of doing it
    break;
  } else {
    current = nextNode;
  }

  if( i == s.length() - 1 ) {
    bRet = true;
    current->setCompleteWord( false );
    break;
  }
}

return bRet;
}

void Trie::generatePrefixes(Node *node, string currentWord){

  std::vector<Node*> children = node->getChildren();

  bool validWord  = false;
  char c = node->getData();
  string newWord = currentWord.append(1, c);

  if( node->isCompleteWord() ) {
    validWord = true;

  // since we have a valid word, we should put in our queue
  // here we are also interested in prefixes
  // so we shall check if we have something on stack
    if( mLCWStack.size() > 0 ){
      std::list<std::string>::iterator itr = mLCWStack.begin();
      while( itr != mLCWStack.end() ){
        stringpair* sp = new stringpair(newWord, *itr);
        m_prefixQueue.push( sp );
        itr++;
      }
    }

    mLCWStack.push_back( newWord );
  }

  // recurse with next child
  for( int i = 0; i < children.size(); ++i) {
    Node* nextNode = children [ i ];
    generatePrefixes( nextNode, newWord );
  }

  // pop back the inserted word
  if( validWord ){
    mLCWStack.pop_front();
  }
}

void Trie::validateMatchForPrefix(const std::string targetString, const std::string prefix) {
  // since we have prefix, lets get the remaining part (?? can we call postfix)
  std::string secondPart = targetString.substr( prefix.length() );
  // for first char, check if there is path from root,
  // if it has, try following it.
  // if it matches all the way, we have got a composite word
  Node* curr = root;
  string compositeWord = prefix;

  for( int i = 0; i < secondPart.length(); i++ ) {
    Node* nextNode = curr->findChild( secondPart[ i ] );
    if( !nextNode ){
      return;
    }

  // we will always keep composite word upto date
  // if we find a complete word, we will just use composite
    compositeWord.append(1, secondPart[i]);

    if( nextNode->isCompleteWord() ){
      stringpair *sp = new stringpair( targetString, compositeWord );
    //TODO: validate sp here
      m_prefixQueue.push( sp );
    }

    curr = nextNode;
  }
}

string Trie::findLongestComposite(){
  mLCWStack.clear();

  // find all prefix matches
  generatePrefixes( root, "" );

  // LCW stack is now free to use
  mLCWStack.clear();

  // this shall give a queue full of string pairs
  // lets process each individually
  while( !m_prefixQueue.empty() ) {
  // get next pair
    stringpair *sp = m_prefixQueue.front();
    m_prefixQueue.pop();

  // if we already have a match, push it to stack
    if( sp->isMatch() ){
      mLCWStack.push_back( sp->compositeString );
    } else if( sp->compositeString.length() > sp->prefix.length() ){
      validateMatchForPrefix( sp->compositeString, sp->prefix );
    }
  }

  mLCWStack.sort();
  mLCWStack.unique();
  mLCWStack.sort( sortDescending );

  return "";
}

void Trie::printFirstN(const int n){
  // std::cout << std::endl <<"Printing Top : " << n  << " elements " << std::endl;

  if( n < mLCWStack.size() ) {
    std::list<std::string>::iterator itr = mLCWStack.begin();
    int i = 0;
    for( ; itr != mLCWStack.end() && i < n ; ++itr, ++i) {
      std::cout << std::string(*itr) << std::endl;
    }
  }else {
    for_each(mLCWStack.begin(), mLCWStack.end(), printString);
  }
}
<commit_msg> Updated to print total count<commit_after>// Trie.cpp

#include "Trie.h"
#include "Node.h"
#include "Util.h"

Trie::Trie() {
  root = new Node( char(0), false );
}

Trie::~Trie() {
  delete root;
}

// add details
void Trie::addWord( std::string s ) {
  Node* current = root;

  if( s.length() == 0 ) {
    current->setCompleteWord();
    return;
  }

  // loop through each character and build a Trie
  for( int i = 0; i < s.length(); ++i ) {
    Node* nextNode = current->findChild( s[i] );
    if( !nextNode ) {
      Node* temp = new Node( s[i], false ) ;
      current->appendChild( temp );
      current = temp;
    } else {
      current = nextNode;
    }

    if( i == s.length() - 1 ) {
      current->setCompleteWord();
    }
  }
}

bool Trie::removeWord( std::string s ) {
  bool bRet = false;
  // effectively we are reseting the marker bit
  // we could potentially get rid of un wanted characters but I would leave up for optimization
  //TODO: optimize to remove un-necessary children
  Node* current = root;

  if( s.length() == 0 ) {
    current->setCompleteWord( false );
  }

  // loop through each character and build a Trie
  for( int i = 0; i < s.length(); ++i ) {
    Node* nextNode = current->findChild( s[i] );
    if( !nextNode ) {
    // if we dont find the child, the word is not in TRIE
    // bail out here
    bRet = true; // just for the hack of doing it
    break;
  } else {
    current = nextNode;
  }

  if( i == s.length() - 1 ) {
    bRet = true;
    current->setCompleteWord( false );
    break;
  }
}

return bRet;
}

void Trie::generatePrefixes(Node *node, string currentWord){

  std::vector<Node*> children = node->getChildren();

  bool validWord  = false;
  char c = node->getData();
  string newWord = currentWord.append(1, c);

  if( node->isCompleteWord() ) {
    validWord = true;

  // since we have a valid word, we should put in our queue
  // here we are also interested in prefixes
  // so we shall check if we have something on stack
    if( mLCWStack.size() > 0 ){
      std::list<std::string>::iterator itr = mLCWStack.begin();
      while( itr != mLCWStack.end() ){
        stringpair* sp = new stringpair(newWord, *itr);
        m_prefixQueue.push( sp );
        itr++;
      }
    }

    mLCWStack.push_back( newWord );
  }

  // recurse with next child
  for( int i = 0; i < children.size(); ++i) {
    Node* nextNode = children [ i ];
    generatePrefixes( nextNode, newWord );
  }

  // pop back the inserted word
  if( validWord ){
    mLCWStack.pop_front();
  }
}

void Trie::validateMatchForPrefix(const std::string targetString, const std::string prefix) {
  // since we have prefix, lets get the remaining part (?? can we call postfix)
  std::string secondPart = targetString.substr( prefix.length() );
  // for first char, check if there is path from root,
  // if it has, try following it.
  // if it matches all the way, we have got a composite word
  Node* curr = root;
  string compositeWord = prefix;

  for( int i = 0; i < secondPart.length(); i++ ) {
    Node* nextNode = curr->findChild( secondPart[ i ] );
    if( !nextNode ){
      return;
    }

  // we will always keep composite word upto date
  // if we find a complete word, we will just use composite
    compositeWord.append(1, secondPart[i]);

    if( nextNode->isCompleteWord() ){
      stringpair *sp = new stringpair( targetString, compositeWord );
    //TODO: validate sp here
      m_prefixQueue.push( sp );
    }

    curr = nextNode;
  }
}

string Trie::findLongestComposite(){
  mLCWStack.clear();

  // find all prefix matches
  generatePrefixes( root, "" );

  // LCW stack is now free to use
  mLCWStack.clear();

  // this shall give a queue full of string pairs
  // lets process each individually
  while( !m_prefixQueue.empty() ) {
  // get next pair
    stringpair *sp = m_prefixQueue.front();
    m_prefixQueue.pop();

  // if we already have a match, push it to stack
    if( sp->isMatch() ){
      mLCWStack.push_back( sp->compositeString );
    } else if( sp->compositeString.length() > sp->prefix.length() ){
      validateMatchForPrefix( sp->compositeString, sp->prefix );
    }
  }

  mLCWStack.sort();
  mLCWStack.unique();
  mLCWStack.sort( sortDescending );

  return "";
}

void Trie::printFirstN(const int n){
  // std::cout << std::endl <<"Printing Top : " << n  << " elements " << std::endl;
  //
  std::cout << " Number of composite words " << mLCWStack.size() << std::endl;

  if( n < mLCWStack.size() ) {
    std::list<std::string>::iterator itr = mLCWStack.begin();
    int i = 0;
    for( ; itr != mLCWStack.end() && i < n ; ++itr, ++i) {
      std::cout << std::string(*itr) << std::endl;
    }
  }else {
    for_each(mLCWStack.begin(), mLCWStack.end(), printString);
  }
}
<|endoftext|>


<commit_before>/*
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <gtest/gtest.h>
#include <qi/application.hpp>
#include <qi/log.hpp>
#include <qi/session.hpp>

TEST(ServiceDirectory, DoubleListen)
{
  qi::Session sd;

  try {
    sd.listenStandalone("tcp://127.0.0.1:0");
    sd.listen("tcp://127.0.0.1:0");
  }
  catch(std::runtime_error& e)
  {
    qiLogError("test_sd") << e.what();
    ASSERT_TRUE(false);
  }
}

struct Serv
{
  static int response = 4242;
  int f()
  {
    return response;
  }
};
QI_REGISTER_OBJECT(Serv, f);

TEST(ServiceDirectory, MultiRegister)
{
  qi::Session sd1;
  qi::Session sd2;

  sd1.listenStandalone("tcp://127.0.0.1:0");
  sd2.listenStandalone("tcp://127.0.0.1:0");

  sd1.registerService("Serv", boost::make_shared<Serv>());
  sd2.registerService("Serv", boost::make_shared<Serv>());

  {
    qi::Session client;
    client.connect(sd1.url());
    ASSERT_EQ(Serv::response, client.service("Serv").value().call<int>("f"));
  }
  {
    qi::Session client;
    client.connect(sd2.url());
    ASSERT_EQ(Serv::response, client.service("Serv").value().call<int>("f"));
  }
}

TEST(ServiceDirectory, Republish)
{
  qi::Session sd1;
  qi::Session sd2;

  sd1.listenStandalone("tcp://127.0.0.1:0");
  sd2.listenStandalone("tcp://127.0.0.1:0");

  sd1.registerService("Serv", boost::make_shared<Serv>());

  sd2.registerService("Serv", sd1.service("Serv"));

  ASSERT_EQ(Serv::response, sd1.service("Serv").value().call<int>("f"));
  ASSERT_EQ(Serv::response, sd2.service("Serv").value().call<int>("f"));
  {
    qi::Session client;
    client.connect(sd1.url());
    ASSERT_EQ(Serv::response, client.service("Serv").value().call<int>("f"));
  }
  {
    qi::Session client;
    client.connect(sd2.url());
    ASSERT_EQ(Serv::response, client.service("Serv").value().call<int>("f"));
  }
}

TEST(ServiceDirectory, ServiceEndpointMatchesServiceDirectorys)
{
  auto session = qi::makeSession();
  session->listenStandalone("tcp://127.0.0.1:0");
  session->registerService("Service", boost::make_shared<Serv>());
  auto serviceInfo = session->services().value().back();
  ASSERT_EQ(session->endpoints(), serviceInfo.endpoints());
}

TEST(ServiceDirectory, ReRegisterRemoteServiceRenewEndpoints)
{
  auto session1 = qi::makeSession();
  auto session2 = qi::makeSession();
  session1->listenStandalone("tcp://127.0.0.1:0");
  session2->listenStandalone("tcp://127.0.0.1:0");
  session1->registerService("Service", boost::make_shared<Serv>());
  auto serviceInfo1 = session1->services().value().back();
  auto remoteService = session1->service("Service").value();
  session2->registerService("Service", remoteService);
  auto serviceInfo2 = session2->services().value().back();
  ASSERT_NE(serviceInfo1.endpoints(), serviceInfo2.endpoints());
  ASSERT_NE(session1->endpoints(), serviceInfo2.endpoints());
  ASSERT_EQ(session2->endpoints(), serviceInfo2.endpoints());
}

TEST(ServiceDirectory, CallMessagesAreProperlyDispatched)
{
  auto session1 = qi::makeSession();
  auto session2 = qi::makeSession();
  session1->listenStandalone("tcp://127.0.0.1:0");
  session2->listenStandalone("tcp://127.0.0.1:0");

  // Dummy services are registered to offset the indexes, so that they
  // cannot match by chance between the two service directories
  auto originalService = boost::make_shared<Serv>();
  session2->registerService("A", boost::make_shared<Serv>());
  session2->registerService("B", boost::make_shared<Serv>());
  session2->registerService("C", boost::make_shared<Serv>());
  session1->registerService("Service", originalService);

  auto remoteService = session1->service("Service").value();
  session2->registerService("Service", remoteService);

  auto remoteRemoteService = session2->service("Service").value();
  ASSERT_EQ(Serv::response, remoteRemoteService.call<int>("f"));
}

TEST(ServiceDirectory, RegisterServiceFromNonListeningSessionAndCallThroughAnIntermediate)
{
  auto sessionMainServer = qi::makeSession();
  auto sessionMainClient = qi::makeSession();
  auto sessionSecondaryFromMain = qi::makeSession();
  auto sessionSecondaryServer = qi::makeSession();
  auto sessionSecondaryClient = qi::makeSession();

  sessionMainServer->listenStandalone("tcp://127.0.0.1:0");
  sessionSecondaryServer->listenStandalone("tcp://127.0.0.1:0");
  sessionMainClient->connect(sessionMainServer->endpoints()[0]);
  sessionSecondaryFromMain->connect(sessionMainServer->endpoints()[0]);
  sessionSecondaryClient->connect(sessionSecondaryServer->endpoints()[0]);

  // Dummy services are registered to offset the indexes, so that they
  // cannot match by chance between the two service directories
  sessionMainServer->registerService("A", boost::make_shared<Serv>());
  sessionMainServer->registerService("B", boost::make_shared<Serv>());
  sessionMainServer->registerService("C", boost::make_shared<Serv>());

  auto originalService = boost::make_shared<Serv>();
  sessionMainClient->registerService("Service", originalService);

  auto remoteService = sessionSecondaryFromMain->service("Service").value();
  sessionSecondaryServer->registerService("Service", remoteService);

  auto remoteRemoteService = sessionSecondaryClient->service("Service").value();
  ASSERT_EQ(Serv::response, remoteRemoteService.call<int>("f"));
}

int main(int argc, char **argv) {
  qi::Application app(argc, argv);
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

<commit_msg>Service Directory: fix compilation after test change<commit_after>/*
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <gtest/gtest.h>
#include <qi/application.hpp>
#include <qi/log.hpp>
#include <qi/session.hpp>

TEST(ServiceDirectory, DoubleListen)
{
  qi::Session sd;

  try {
    sd.listenStandalone("tcp://127.0.0.1:0");
    sd.listen("tcp://127.0.0.1:0");
  }
  catch(std::runtime_error& e)
  {
    qiLogError("test_sd") << e.what();
    ASSERT_TRUE(false);
  }
}

struct Serv
{
  static const int response;
  int f()
  {
    return response;
  }
};
const int Serv::response = 4242;

QI_REGISTER_OBJECT(Serv, f);

TEST(ServiceDirectory, MultiRegister)
{
  qi::Session sd1;
  qi::Session sd2;

  sd1.listenStandalone("tcp://127.0.0.1:0");
  sd2.listenStandalone("tcp://127.0.0.1:0");

  sd1.registerService("Serv", boost::make_shared<Serv>());
  sd2.registerService("Serv", boost::make_shared<Serv>());

  {
    qi::Session client;
    client.connect(sd1.url());
    ASSERT_EQ(Serv::response, client.service("Serv").value().call<int>("f"));
  }
  {
    qi::Session client;
    client.connect(sd2.url());
    ASSERT_EQ(Serv::response, client.service("Serv").value().call<int>("f"));
  }
}

TEST(ServiceDirectory, Republish)
{
  qi::Session sd1;
  qi::Session sd2;

  sd1.listenStandalone("tcp://127.0.0.1:0");
  sd2.listenStandalone("tcp://127.0.0.1:0");

  sd1.registerService("Serv", boost::make_shared<Serv>());

  sd2.registerService("Serv", sd1.service("Serv"));

  ASSERT_EQ(Serv::response, sd1.service("Serv").value().call<int>("f"));
  ASSERT_EQ(Serv::response, sd2.service("Serv").value().call<int>("f"));
  {
    qi::Session client;
    client.connect(sd1.url());
    ASSERT_EQ(Serv::response, client.service("Serv").value().call<int>("f"));
  }
  {
    qi::Session client;
    client.connect(sd2.url());
    ASSERT_EQ(Serv::response, client.service("Serv").value().call<int>("f"));
  }
}

TEST(ServiceDirectory, ServiceEndpointMatchesServiceDirectorys)
{
  auto session = qi::makeSession();
  session->listenStandalone("tcp://127.0.0.1:0");
  session->registerService("Service", boost::make_shared<Serv>());
  auto serviceInfo = session->services().value().back();
  ASSERT_EQ(session->endpoints(), serviceInfo.endpoints());
}

TEST(ServiceDirectory, ReRegisterRemoteServiceRenewEndpoints)
{
  auto session1 = qi::makeSession();
  auto session2 = qi::makeSession();
  session1->listenStandalone("tcp://127.0.0.1:0");
  session2->listenStandalone("tcp://127.0.0.1:0");
  session1->registerService("Service", boost::make_shared<Serv>());
  auto serviceInfo1 = session1->services().value().back();
  auto remoteService = session1->service("Service").value();
  session2->registerService("Service", remoteService);
  auto serviceInfo2 = session2->services().value().back();
  ASSERT_NE(serviceInfo1.endpoints(), serviceInfo2.endpoints());
  ASSERT_NE(session1->endpoints(), serviceInfo2.endpoints());
  ASSERT_EQ(session2->endpoints(), serviceInfo2.endpoints());
}

TEST(ServiceDirectory, CallMessagesAreProperlyDispatched)
{
  auto session1 = qi::makeSession();
  auto session2 = qi::makeSession();
  session1->listenStandalone("tcp://127.0.0.1:0");
  session2->listenStandalone("tcp://127.0.0.1:0");

  // Dummy services are registered to offset the indexes, so that they
  // cannot match by chance between the two service directories
  auto originalService = boost::make_shared<Serv>();
  session2->registerService("A", boost::make_shared<Serv>());
  session2->registerService("B", boost::make_shared<Serv>());
  session2->registerService("C", boost::make_shared<Serv>());
  session1->registerService("Service", originalService);

  auto remoteService = session1->service("Service").value();
  session2->registerService("Service", remoteService);

  auto remoteRemoteService = session2->service("Service").value();
  ASSERT_EQ(Serv::response, remoteRemoteService.call<int>("f"));
}

TEST(ServiceDirectory, RegisterServiceFromNonListeningSessionAndCallThroughAnIntermediate)
{
  auto sessionMainServer = qi::makeSession();
  auto sessionMainClient = qi::makeSession();
  auto sessionSecondaryFromMain = qi::makeSession();
  auto sessionSecondaryServer = qi::makeSession();
  auto sessionSecondaryClient = qi::makeSession();

  sessionMainServer->listenStandalone("tcp://127.0.0.1:0");
  sessionSecondaryServer->listenStandalone("tcp://127.0.0.1:0");
  sessionMainClient->connect(sessionMainServer->endpoints()[0]);
  sessionSecondaryFromMain->connect(sessionMainServer->endpoints()[0]);
  sessionSecondaryClient->connect(sessionSecondaryServer->endpoints()[0]);

  // Dummy services are registered to offset the indexes, so that they
  // cannot match by chance between the two service directories
  sessionMainServer->registerService("A", boost::make_shared<Serv>());
  sessionMainServer->registerService("B", boost::make_shared<Serv>());
  sessionMainServer->registerService("C", boost::make_shared<Serv>());

  auto originalService = boost::make_shared<Serv>();
  sessionMainClient->registerService("Service", originalService);

  auto remoteService = sessionSecondaryFromMain->service("Service").value();
  sessionSecondaryServer->registerService("Service", remoteService);

  auto remoteRemoteService = sessionSecondaryClient->service("Service").value();
  ASSERT_EQ(Serv::response, remoteRemoteService.call<int>("f"));
}

int main(int argc, char **argv) {
  qi::Application app(argc, argv);
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

<|endoftext|>


<commit_before>#include <smartref/smartref.h>
<commit_msg>Added some extra tests for DegelateType.<commit_after>#include <smartref/smartref.h>
#include <reflection/reflect.h>
#include <utils/utils.h>

using namespace std;
using namespace smartref;
using namespace reflection;

template<typename T>
struct RefVirtual : using_<T> {};

template<typename T>
struct RefCRTP : using_<T, RefCRTP<T>> {};

static_assert(reflect<DelegateType<decltype(declval<RefVirtual<int> &>())>> == reflect<int>);
static_assert(reflect<DelegateType<decltype(declval<RefCRTP<int> &>())>> == reflect<int>);
<|endoftext|>


<commit_before>#include "System.h"
System::System()
{
	this->m_inputHandler = NULL;
	this->m_window = NULL;
}

System::~System()
{
}

int System::Shutdown()
{
	int result = 0;
	//Destroy the display window
	SDL_DestroyWindow(m_window);
	//Quit SDL subsystems
	SDL_Quit();
	this->m_gsh.ShutDown();
	this->m_graphicsHandler->Shutdown();
	delete this->m_graphicsHandler;
	this->m_graphicsHandler = nullptr;
	delete this->m_camera;
	this->m_camera = nullptr;
	this->m_inputHandler->Shutdown();
	delete this->m_inputHandler;
	this->m_inputHandler = nullptr;
	this->m_physicsHandler.ShutDown();
	DebugHandler::instance().Shutdown();

	/*Delete animation class ptr here.*/
	delete this->m_Anim;

	return result;

}

int System::Initialize()
{
	int result = 1;
	this->m_fullscreen = false;
	this->m_running = true;
	this->m_window = NULL;
	//Get the instance if this application
	this->m_hinstance = GetModuleHandle(NULL);

	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		printf("SDL failed in initializing the window! SDL_Error: %hS\n", SDL_GetError());
	}
	else
	{
		printf("SDL succeeded in initializing the window!\n");
	}

	m_window = SDL_CreateWindow("SSD Application", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
	if (m_window == NULL)
	{
		printf("Window creation failed! SDL_ERROR: %hS\n", SDL_GetError());
	}
	else
	{
		printf("Window creation succeeded!\n");

		SDL_SysWMinfo wmInfo;
		SDL_VERSION(&wmInfo.version);
		SDL_GetWindowWMInfo(m_window, &wmInfo);
		m_hwnd = wmInfo.info.win.window;
	}

	this->m_graphicsHandler = new GraphicsHandler();
	if (this->m_graphicsHandler->Initialize(&this->m_hwnd, DirectX::XMINT2(SCREEN_WIDTH, SCREEN_HEIGHT)))
	{
		printf("GraphicsHandler did not work. RIP!\n");
	}
	this->m_camera = new Camera();
	this->m_camera->Initialize();
	//this->m_camera->SetRotationAroundPosOffset(0.0f, 1.0f, 1.0f);
	Camera* oldCam = this->m_graphicsHandler->SetCamera(this->m_camera);
	delete oldCam;
	oldCam = nullptr;
	//Initialize the PhysicsHandler
	this->m_physicsHandler.Initialize();

	DirectX::XMFLOAT3 temp = DirectX::XMFLOAT3(0, 0, 0);
	DirectX::XMVECTOR test = DirectX::XMLoadFloat3(&temp);

	DirectX::XMFLOAT3 temp2 = DirectX::XMFLOAT3(0, 0, 2.1);
	DirectX::XMVECTOR test2 = DirectX::XMLoadFloat3(&temp2);

	this->m_physicsHandler.CreatePhysicsComponent(test);
	this->m_physicsHandler.RotateBB_X(this->m_physicsHandler.getDynamicComponents(0));
	this->m_physicsHandler.CreatePhysicsComponent(test2);

	//Initialize the InputHandler
	this->m_inputHandler = new InputHandler();
	this->m_inputHandler->Initialize(SCREEN_WIDTH, SCREEN_HEIGHT);
	//Initialize the ComponentHandler. This must happen before the initialization of the gamestatehandler
	this->m_componentHandler.Initialize(this->m_graphicsHandler, &this->m_physicsHandler);
	//Initialize the GameStateHandler
	this->m_gsh.Initialize(&this->m_componentHandler);
	//Initialize the network module
	this->m_networkModule.Initialize();

	this->m_Anim = new Animation();

	DebugHandler::instance().CreateCustomLabel("Frame counter", 0);

	return result;
}

//Do not place things here without talking to the system designers. Place any update method in the System::Update(float dt) method
int System::Run()
{
	int result = 0;
	LARGE_INTEGER frequency, currTime, prevTime, elapsedTime;
	QueryPerformanceFrequency(&frequency);
	//QueryPerformanceCounter(&prevTime);
	QueryPerformanceCounter(&currTime);
	while (this->m_running)
	{
		DebugHandler::instance().StartProgram();
		prevTime = currTime;
		QueryPerformanceCounter(&currTime);
		elapsedTime.QuadPart = currTime.QuadPart - prevTime.QuadPart;
		elapsedTime.QuadPart *= 1000000;
		elapsedTime.QuadPart /= frequency.QuadPart;

		//Prepare the InputHandler
		this->m_inputHandler->Update();
		//Handle events and update inputhandler through said events
		result = this->HandleEvents();
		SDL_PumpEvents();
		//Update game
		if (this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_ESCAPE))
		{
			this->m_running = false;
		}
		if (!this->Update((float)elapsedTime.QuadPart))
		{
			this->m_running = false;
		}
		if (this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_F))
		{
			this->FullscreenToggle();
		}
		if (this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_C))
		{
			DebugHandler::instance().ResetMinMax();
			printf("Reseted min max on timers\n");
		}

		DebugHandler::instance().EndProgram();
		DebugHandler::instance().Display((float)elapsedTime.QuadPart);
	}
	if (this->m_fullscreen)
		this->FullscreenToggle();

	return result;
}

//Place all the update functions within the System::Update(float deltaTime) function.
int System::Update(float deltaTime)
{
	DebugHandler::instance().StartTimer("Update");
	int result = 1;

	//Update the network module
	this->m_networkModule.Update();

	int translateCameraX = 0, translateCameraY = 0, translateCameraZ = 0;
	int rotateCameraY = 0;
	std::list<CameraPacket> cList;

	//Check for camera updates from the network
	cList = this->m_networkModule.PacketBuffer_GetCameraPackets();
	OBB* tempHold = nullptr;
	this->m_physicsHandler.GetPhysicsComponentOBB(tempHold, 0);

	this->m_graphicsHandler->RenderBoundingVolume(*tempHold);
	if (!cList.empty())
	{
		std::list<CameraPacket>::iterator iter;

		for (iter = cList.begin(); iter != cList.end();)
		{
			this->m_camera->SetCameraPos((iter)->pos);
			this->m_camera->Update();
			iter++;
		}

		cList.empty();	//When we have read all the packets, empty the list

	}

	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_W))
	{
		translateCameraZ++;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_S))
	{
		translateCameraZ--;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_SPACE))
	{
		translateCameraY++;
		if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_LSHIFT))
		{
			translateCameraY *= -1;
		}
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_D))
	{
		translateCameraX++;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_A))
	{
		translateCameraX--;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_E))
	{
		rotateCameraY++;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_Q))
	{
		rotateCameraY--;
	}
	if (translateCameraY || translateCameraX || translateCameraZ || rotateCameraY)
	{
		DirectX::XMFLOAT3 posTranslation = DirectX::XMFLOAT3(float(translateCameraX) * (deltaTime / 1000000.0f), float(translateCameraY) * (deltaTime / 1000000.0f), float(translateCameraZ) * (deltaTime / 1000000.0f));
		this->m_camera->ApplyLocalTranslation(posTranslation);
		//this->m_camera->AddToLookAt(posTranslation);
		float rotationAmount = DirectX::XM_PI / 6;
		rotationAmount *= deltaTime / 1000000.0f;
		DirectX::XMFLOAT4 newRotation = DirectX::XMFLOAT4(0.0f, rotateCameraY * DirectX::XMScalarSin(rotationAmount / 2.0f), 0.0f, DirectX::XMScalarCos(rotationAmount / 2.0f));
		this->m_camera->SetRotation(newRotation);
		this->m_camera->Update();

		//Send updates over the network
		if (this->m_networkModule.GetNrOfConnectedClients() != 0)
		{
			DirectX::XMFLOAT4 updatePos;
			this->m_camera->GetCameraPos(updatePos);
			this->m_networkModule.SendCameraPacket(updatePos);
		}

	}
	//Network
	if(this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_J))
	{
		if (this->m_networkModule.GetNrOfConnectedClients() <= 0)	//If the network module is NOT connected to other clients
		{
			if (this->m_networkModule.Join(this->m_ip))				//If we succsefully connected
			{
				printf("Joined client with the ip %s\n", this->m_ip);
			}
			else
			{
				printf("Failed to connect to the client\n", this->m_ip);
			}

		}
		else
		{
			printf("Join failed since this module is already connected to other clients\n");
		}
	}
	if (this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_K))
	{
		this->m_networkModule.SendFlagPacket(DISCONNECT_REQUEST);
	}
	//Update the logic first followed by the physics followed by the animations and lastly the graphics
	this->m_gsh.Update(deltaTime, this->m_inputHandler);
	//Update animations here. Temp place right now.
	m_Anim->Update(deltaTime);
	m_graphicsHandler->SetTempAnimComponent((void*)m_Anim->GetAnimationComponentTEMP());

	this->m_physicsHandler.Update();

	DebugHandler::instance().UpdateCustomLabelIncrease(0, 1.0f);
	DebugHandler::instance().EndTimer();
	//Render
	DebugHandler::instance().StartTimer("Render");
	this->m_graphicsHandler->Render();
	DebugHandler::instance().EndTimer();
	return result;
}

int System::HandleEvents()
{
	SDL_Event m_event;
	while (SDL_PollEvent(&m_event))
	{
		switch (m_event.type)
		{
#pragma region
		case SDL_WINDOWEVENT:
		{
			switch (m_event.window.event)
			{
			case SDL_WINDOWEVENT_ENTER:
			{
				//OnMouseFocus();
				break;
			}
			case SDL_WINDOWEVENT_LEAVE:
			{
				//OnMouseBlur();
				break;
			}
			case SDL_WINDOWEVENT_FOCUS_GAINED:
			{
				//OnInputFocus();
				break;
			}
			case SDL_WINDOWEVENT_FOCUS_LOST:
			{
				//OnInputBlur();
				break;
			}
			case SDL_WINDOWEVENT_SHOWN:
			{
				break;
			}
			case SDL_WINDOWEVENT_HIDDEN:
			{
				break;
			}
			case SDL_WINDOWEVENT_EXPOSED:
			{
				break;
			}
			case SDL_WINDOWEVENT_MOVED:
			{
				break;
			}
			case SDL_WINDOWEVENT_RESIZED:
			{
				break;
			}
			case SDL_WINDOWEVENT_SIZE_CHANGED:
			{
				break;
			}
			case SDL_WINDOWEVENT_MINIMIZED:
			{
				break;
			}
			case SDL_WINDOWEVENT_MAXIMIZED:
			{
				break;
			}
			case SDL_WINDOWEVENT_RESTORED:
			{
				break;
			}
			case SDL_WINDOWEVENT_CLOSE:
			{
				break;
			}
			}
			break;
		}
#pragma endregion window events
		case SDL_MOUSEMOTION:
		{
			break;
		}
		case SDL_QUIT:
		{
			//The big X in the corner
			this->m_running = false;
			break;
		}
#pragma region
		case SDL_KEYDOWN:
		{
			//OnKeyDown(Event->key.keysym.sym, Event->key.keysym.mod, Event->key.keysym.scancode);

			this->m_inputHandler->SetKeyState(m_event.key.keysym.scancode, true);
			break;
		}
		case SDL_KEYUP:
		{
			//OnKeyUp(Event->key.keysym.sym, Event->key.keysym.mod, Event->key.keysym.scancode);
			this->m_inputHandler->SetKeyState(m_event.key.keysym.scancode, false);
			break;
		}
		case SDL_MOUSEBUTTONDOWN:
		{
			this->m_inputHandler->SetMouseState(m_event.button.button, true);
			break;
		}
		case SDL_MOUSEBUTTONUP:
		{
			this->m_inputHandler->SetMouseState(m_event.button.button, false);
			break;
		}
#pragma endregion Key / Button events
		case SDL_MOUSEWHEEL:
		{
			this->m_inputHandler->ApplyMouseWheel(m_event.wheel.x, m_event.wheel.y);
			break;
		}
		}
	}
	return 1;
}

int System::FullscreenToggle()
{
	int result = 0;
	this->m_fullscreen = SDL_GetWindowFlags(this->m_window) & SDL_WINDOW_FULLSCREEN;
	SDL_SetWindowFullscreen(this->m_window, this->m_fullscreen ? 0 : SDL_WINDOW_FULLSCREEN);
	this->m_fullscreen = SDL_GetWindowFlags(this->m_window) & SDL_WINDOW_FULLSCREEN;
	return result;
}
<commit_msg>UPDATE Moved logic to after physics<commit_after>#include "System.h"
System::System()
{
	this->m_inputHandler = NULL;
	this->m_window = NULL;
}

System::~System()
{
}

int System::Shutdown()
{
	int result = 0;
	//Destroy the display window
	SDL_DestroyWindow(m_window);
	//Quit SDL subsystems
	SDL_Quit();
	this->m_gsh.ShutDown();
	this->m_graphicsHandler->Shutdown();
	delete this->m_graphicsHandler;
	this->m_graphicsHandler = nullptr;
	delete this->m_camera;
	this->m_camera = nullptr;
	this->m_inputHandler->Shutdown();
	delete this->m_inputHandler;
	this->m_inputHandler = nullptr;
	this->m_physicsHandler.ShutDown();
	DebugHandler::instance().Shutdown();

	/*Delete animation class ptr here.*/
	delete this->m_Anim;

	return result;

}

int System::Initialize()
{
	int result = 1;
	this->m_fullscreen = false;
	this->m_running = true;
	this->m_window = NULL;
	//Get the instance if this application
	this->m_hinstance = GetModuleHandle(NULL);

	if (SDL_Init(SDL_INIT_VIDEO) < 0)
	{
		printf("SDL failed in initializing the window! SDL_Error: %hS\n", SDL_GetError());
	}
	else
	{
		printf("SDL succeeded in initializing the window!\n");
	}

	m_window = SDL_CreateWindow("SSD Application", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
	if (m_window == NULL)
	{
		printf("Window creation failed! SDL_ERROR: %hS\n", SDL_GetError());
	}
	else
	{
		printf("Window creation succeeded!\n");

		SDL_SysWMinfo wmInfo;
		SDL_VERSION(&wmInfo.version);
		SDL_GetWindowWMInfo(m_window, &wmInfo);
		m_hwnd = wmInfo.info.win.window;
	}

	this->m_graphicsHandler = new GraphicsHandler();
	if (this->m_graphicsHandler->Initialize(&this->m_hwnd, DirectX::XMINT2(SCREEN_WIDTH, SCREEN_HEIGHT)))
	{
		printf("GraphicsHandler did not work. RIP!\n");
	}
	this->m_camera = new Camera();
	this->m_camera->Initialize();
	//this->m_camera->SetRotationAroundPosOffset(0.0f, 1.0f, 1.0f);
	Camera* oldCam = this->m_graphicsHandler->SetCamera(this->m_camera);
	delete oldCam;
	oldCam = nullptr;
	//Initialize the PhysicsHandler
	this->m_physicsHandler.Initialize();

	DirectX::XMFLOAT3 temp = DirectX::XMFLOAT3(0, 0, 0);
	DirectX::XMVECTOR test = DirectX::XMLoadFloat3(&temp);

	DirectX::XMFLOAT3 temp2 = DirectX::XMFLOAT3(0, 0, 2.1);
	DirectX::XMVECTOR test2 = DirectX::XMLoadFloat3(&temp2);

	this->m_physicsHandler.CreatePhysicsComponent(test);
	this->m_physicsHandler.RotateBB_X(this->m_physicsHandler.getDynamicComponents(0));
	this->m_physicsHandler.CreatePhysicsComponent(test2);

	//Initialize the InputHandler
	this->m_inputHandler = new InputHandler();
	this->m_inputHandler->Initialize(SCREEN_WIDTH, SCREEN_HEIGHT);
	//Initialize the ComponentHandler. This must happen before the initialization of the gamestatehandler
	this->m_componentHandler.Initialize(this->m_graphicsHandler, &this->m_physicsHandler);
	//Initialize the GameStateHandler
	this->m_gsh.Initialize(&this->m_componentHandler);
	//Initialize the network module
	this->m_networkModule.Initialize();

	this->m_Anim = new Animation();

	DebugHandler::instance().CreateCustomLabel("Frame counter", 0);

	return result;
}

//Do not place things here without talking to the system designers. Place any update method in the System::Update(float dt) method
int System::Run()
{
	int result = 0;
	LARGE_INTEGER frequency, currTime, prevTime, elapsedTime;
	QueryPerformanceFrequency(&frequency);
	//QueryPerformanceCounter(&prevTime);
	QueryPerformanceCounter(&currTime);
	while (this->m_running)
	{
		DebugHandler::instance().StartProgram();
		prevTime = currTime;
		QueryPerformanceCounter(&currTime);
		elapsedTime.QuadPart = currTime.QuadPart - prevTime.QuadPart;
		elapsedTime.QuadPart *= 1000000;
		elapsedTime.QuadPart /= frequency.QuadPart;

		//Prepare the InputHandler
		this->m_inputHandler->Update();
		//Handle events and update inputhandler through said events
		result = this->HandleEvents();
		SDL_PumpEvents();
		//Update game
		if (this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_ESCAPE))
		{
			this->m_running = false;
		}
		if (!this->Update((float)elapsedTime.QuadPart))
		{
			this->m_running = false;
		}
		if (this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_F))
		{
			this->FullscreenToggle();
		}
		if (this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_C))
		{
			DebugHandler::instance().ResetMinMax();
			printf("Reseted min max on timers\n");
		}

		DebugHandler::instance().EndProgram();
		DebugHandler::instance().Display((float)elapsedTime.QuadPart);
	}
	if (this->m_fullscreen)
		this->FullscreenToggle();

	return result;
}

//Place all the update functions within the System::Update(float deltaTime) function.
int System::Update(float deltaTime)
{
	DebugHandler::instance().StartTimer("Update");
	int result = 1;

	//Update the network module
	this->m_networkModule.Update();

	int translateCameraX = 0, translateCameraY = 0, translateCameraZ = 0;
	int rotateCameraY = 0;
	std::list<CameraPacket> cList;

	//Check for camera updates from the network
	cList = this->m_networkModule.PacketBuffer_GetCameraPackets();
	OBB* tempHold = nullptr;
	this->m_physicsHandler.GetPhysicsComponentOBB(tempHold, 0);

	this->m_graphicsHandler->RenderBoundingVolume(*tempHold);
	if (!cList.empty())
	{
		std::list<CameraPacket>::iterator iter;

		for (iter = cList.begin(); iter != cList.end();)
		{
			this->m_camera->SetCameraPos((iter)->pos);
			this->m_camera->Update();
			iter++;
		}

		cList.empty();	//When we have read all the packets, empty the list

	}

	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_W))
	{
		translateCameraZ++;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_S))
	{
		translateCameraZ--;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_SPACE))
	{
		translateCameraY++;
		if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_LSHIFT))
		{
			translateCameraY *= -1;
		}
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_D))
	{
		translateCameraX++;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_A))
	{
		translateCameraX--;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_E))
	{
		rotateCameraY++;
	}
	if (this->m_inputHandler->IsKeyDown(SDL_SCANCODE_Q))
	{
		rotateCameraY--;
	}
	if (translateCameraY || translateCameraX || translateCameraZ || rotateCameraY)
	{
		DirectX::XMFLOAT3 posTranslation = DirectX::XMFLOAT3(float(translateCameraX) * (deltaTime / 1000000.0f), float(translateCameraY) * (deltaTime / 1000000.0f), float(translateCameraZ) * (deltaTime / 1000000.0f));
		this->m_camera->ApplyLocalTranslation(posTranslation);
		//this->m_camera->AddToLookAt(posTranslation);
		float rotationAmount = DirectX::XM_PI / 6;
		rotationAmount *= deltaTime / 1000000.0f;
		DirectX::XMFLOAT4 newRotation = DirectX::XMFLOAT4(0.0f, rotateCameraY * DirectX::XMScalarSin(rotationAmount / 2.0f), 0.0f, DirectX::XMScalarCos(rotationAmount / 2.0f));
		this->m_camera->SetRotation(newRotation);
		this->m_camera->Update();

		//Send updates over the network
		if (this->m_networkModule.GetNrOfConnectedClients() != 0)
		{
			DirectX::XMFLOAT4 updatePos;
			this->m_camera->GetCameraPos(updatePos);
			this->m_networkModule.SendCameraPacket(updatePos);
		}

	}
	//Network
	if(this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_J))
	{
		if (this->m_networkModule.GetNrOfConnectedClients() <= 0)	//If the network module is NOT connected to other clients
		{
			if (this->m_networkModule.Join(this->m_ip))				//If we succsefully connected
			{
				printf("Joined client with the ip %s\n", this->m_ip);
			}
			else
			{
				printf("Failed to connect to the client\n", this->m_ip);
			}

		}
		else
		{
			printf("Join failed since this module is already connected to other clients\n");
		}
	}
	if (this->m_inputHandler->IsKeyPressed(SDL_SCANCODE_K))
	{
		this->m_networkModule.SendFlagPacket(DISCONNECT_REQUEST);
	}
	//Update animations here. Temp place right now.
	m_Anim->Update(deltaTime);
	m_graphicsHandler->SetTempAnimComponent((void*)m_Anim->GetAnimationComponentTEMP());

	this->m_physicsHandler.Update();
	//Update the logic and transfer the data from physicscomponents to the graphicscomponents
	this->m_gsh.Update(deltaTime, this->m_inputHandler);
	DebugHandler::instance().UpdateCustomLabelIncrease(0, 1.0f);
	DebugHandler::instance().EndTimer();
	//Render
	DebugHandler::instance().StartTimer("Render");
	this->m_graphicsHandler->Render();
	DebugHandler::instance().EndTimer();
	return result;
}

int System::HandleEvents()
{
	SDL_Event m_event;
	while (SDL_PollEvent(&m_event))
	{
		switch (m_event.type)
		{
#pragma region
		case SDL_WINDOWEVENT:
		{
			switch (m_event.window.event)
			{
			case SDL_WINDOWEVENT_ENTER:
			{
				//OnMouseFocus();
				break;
			}
			case SDL_WINDOWEVENT_LEAVE:
			{
				//OnMouseBlur();
				break;
			}
			case SDL_WINDOWEVENT_FOCUS_GAINED:
			{
				//OnInputFocus();
				break;
			}
			case SDL_WINDOWEVENT_FOCUS_LOST:
			{
				//OnInputBlur();
				break;
			}
			case SDL_WINDOWEVENT_SHOWN:
			{
				break;
			}
			case SDL_WINDOWEVENT_HIDDEN:
			{
				break;
			}
			case SDL_WINDOWEVENT_EXPOSED:
			{
				break;
			}
			case SDL_WINDOWEVENT_MOVED:
			{
				break;
			}
			case SDL_WINDOWEVENT_RESIZED:
			{
				break;
			}
			case SDL_WINDOWEVENT_SIZE_CHANGED:
			{
				break;
			}
			case SDL_WINDOWEVENT_MINIMIZED:
			{
				break;
			}
			case SDL_WINDOWEVENT_MAXIMIZED:
			{
				break;
			}
			case SDL_WINDOWEVENT_RESTORED:
			{
				break;
			}
			case SDL_WINDOWEVENT_CLOSE:
			{
				break;
			}
			}
			break;
		}
#pragma endregion window events
		case SDL_MOUSEMOTION:
		{
			break;
		}
		case SDL_QUIT:
		{
			//The big X in the corner
			this->m_running = false;
			break;
		}
#pragma region
		case SDL_KEYDOWN:
		{
			//OnKeyDown(Event->key.keysym.sym, Event->key.keysym.mod, Event->key.keysym.scancode);

			this->m_inputHandler->SetKeyState(m_event.key.keysym.scancode, true);
			break;
		}
		case SDL_KEYUP:
		{
			//OnKeyUp(Event->key.keysym.sym, Event->key.keysym.mod, Event->key.keysym.scancode);
			this->m_inputHandler->SetKeyState(m_event.key.keysym.scancode, false);
			break;
		}
		case SDL_MOUSEBUTTONDOWN:
		{
			this->m_inputHandler->SetMouseState(m_event.button.button, true);
			break;
		}
		case SDL_MOUSEBUTTONUP:
		{
			this->m_inputHandler->SetMouseState(m_event.button.button, false);
			break;
		}
#pragma endregion Key / Button events
		case SDL_MOUSEWHEEL:
		{
			this->m_inputHandler->ApplyMouseWheel(m_event.wheel.x, m_event.wheel.y);
			break;
		}
		}
	}
	return 1;
}

int System::FullscreenToggle()
{
	int result = 0;
	this->m_fullscreen = SDL_GetWindowFlags(this->m_window) & SDL_WINDOW_FULLSCREEN;
	SDL_SetWindowFullscreen(this->m_window, this->m_fullscreen ? 0 : SDL_WINDOW_FULLSCREEN);
	this->m_fullscreen = SDL_GetWindowFlags(this->m_window) & SDL_WINDOW_FULLSCREEN;
	return result;
}
<|endoftext|>