<commit_before>#include "window.h"
#include <cmath>

/*
	Simple test programm

	compile with: g++ *.cpp -lSDL
*/

class test_window: public koku::opengl::windowCallback
{
	private:
		koku::opengl::window my_window;
		koku::opengl::buffer my_buffer;
		koku::opengl::shader my_shader;
		koku::opengl::shader_uniform my_camera_pos;
		koku::opengl::compute my_compute;
		bool run;

	protected:
		void onQuit()
		{
			//stop everything !
			run = false;
		}

	public:
		test_window(): my_window(this, "test", 640, 480, true), my_buffer(&my_window), my_shader(&my_window), my_camera_pos("camera_pos"), my_compute(&my_window), run(true)
		{
			const float vertex[] =
			{
				1*0.8,1*0.8,-1, //right top
				-1*0.8,1*0.8,-1, //left top
				-1*0.8,-1*0.8,-1, //left bottom
				1*0.8, -1*0.8, -1, //right bottom

				1*0.8,1*0.8,1, //right top
				-1*0.8,1*0.8,1, //left top
				-1*0.8,-1*0.8,1, //left bottom
				1*0.8, -1*0.8, 1 //right bottom
			};

			const float color[] =
			{
				1,0,0,
				1,0,0,
				1,0,0,
				1,0,0,

				0,1,0,
				0,1,0,
				0,1,0,
				0,1,0
			};

			const float camera_matrix[] =
			{
				1,0,0,0,
				0,1,0,0,
				0,0,1,0,
				0,0,0,1
			};

			const unsigned short index[] =
			{
				0,1,3,2,0+4,1+4,3+4,2+4
			};

			my_buffer.upload(false,        vertex, 8*3, 3);
			my_buffer.upload(false,         color, 8*3, 3);
			my_buffer.upload(false, camera_matrix, 4*4, 1); //gets calculated by compute_shader ;)
			my_buffer.upload(true,          index, 8*1, 1);

			my_shader.uploadVertex("#version 400\n"
								   "layout(location = 0) in vec3 Position;\n"
								   "layout(location = 1) in vec3 Color;\n"
								   "out vec3 Position_tc;\n"
								   "out vec3 Color_tc;\n"
								   "void main()\n"
								   "{\n"
								   "	Position_tc = Position;\n" //pass position to tesslelation control shader
								   "	Color_tc = Color;\n"
								   "}\n");

			my_shader.uploadTessellationControl("#version 400\n"
												"layout(vertices = 4) out;"
												"in vec3 Position_tc[];\n"
												"in vec3 Color_tc[];\n"
												"out vec3 Position_te[];\n"
												"out vec3 Color_te[];\n"
												"#define ID gl_InvocationID\n"
												"void main()\n"
												"{\n"
												"	Position_te[ID] = Position_tc[ID];\n"
												"	Color_te[ID] = Color_tc[ID];\n"
												"	if (ID != 0)\n"
												"	{\n"
												"		gl_TessLevelInner[0] = 4;\n" //tes-level
												//"		gl_TessLevelInner[0] = int(int(gl_TessLevelInner[0])/2)*2;\n" //only 1,2,4,6, ...
												"		gl_TessLevelInner[1] = gl_TessLevelInner[0];\n"
												"		gl_TessLevelOuter[0] = gl_TessLevelInner[0];\n"
												"		gl_TessLevelOuter[1] = gl_TessLevelInner[0];\n"
												"		gl_TessLevelOuter[2] = gl_TessLevelInner[0];\n"
												"		gl_TessLevelOuter[3] = gl_TessLevelInner[0];\n"
												"	}\n"
												"}\n");

			my_shader.uploadTessellationEval("#version 400\n"
											 "layout(quads, equal_spacing) in;\n"
											 "in vec3 Position_te[];\n"
											 "in vec3 Color_te[];\n"
											 "out vec3 Color_geo;\n"
											 "out vec3 Position_geo;\n"
											 "void main()\n"
											 "{\n"
											 "	float u = gl_TessCoord.x, v = gl_TessCoord.y;\n"
											 "	vec3 a = mix(Position_te[0], Position_te[1], u);\n"
											 "	vec3 b = mix(Position_te[2], Position_te[3], u);\n"
											 "	Position_geo = mix(a, b, v);\n" //pass to geometry shader
											 "	a = mix(Color_te[0], Color_te[1], u);\n"
											 "	b = mix(Color_te[2], Color_te[3], u);\n"
											 "	Color_geo = mix(a, b, v);\n"
											 "}\n");

			my_shader.uploadGeometry("#version 430\n"
									 //"layout(quads) in;\n"
									 "layout(triangles) in;\n" //can't use quads
									 "layout(triangle_strip, max_vertices=24) out;\n"
									 "in vec3 Position_geo[];\n"
									 "in vec3 Color_geo[];\n"
									 "out vec3 Color_fr;\n"
									 "layout (binding=2) uniform result { mat4 CameraMatrix[]; }; \n" //gets data from compute shader
									 "void main()\n"
									 "{\n"
									 "	for(int i = 0; i < 3; i++)\n"
									 "	{\n"
									 "		gl_Position = CameraMatrix[0] * vec4(Position_geo[i], 1.0);\n" //again doesn't matter which ModelViewMatrix_geo (should be all the same)
									 "		Color_fr = Color_geo[i];\n"
									 "		EmitVertex();\n"
									 "	}\n"
									 "	EndPrimitive();\n"
									 //Dup it
									 "	for(int i = 0; i < 3; i++)\n"
									 "	{\n"
									 "		gl_Position = CameraMatrix[0] * vec4(Position_geo[i] + vec3(0,0,0.25), 1.0);\n" //again doesn't matter which ModelViewMatrix_geo (should be all the same)
									 "		Color_fr = Color_geo[i] + vec3(0,0,1);\n"
									 "		EmitVertex();\n"
									 "	}\n"
									 "	EndPrimitive();\n"
									 "}\n");

			my_shader.uploadFragment("#version 400\n"
									 "layout(location = 0) out vec4 FragColor;\n"
									 "in vec3 Color_fr;\n"
									 "void main()\n"
									 "{\n"
									 "	FragColor = vec4(Color_fr, 1.0);\n"
									 "}\n");

			my_shader.compile();

			my_compute.upload("#version 430\n"
							  "uniform vec3 camera_pos;\n"
							  "uniform vec3 camera_look_at_pos;\n"
							  "layout (binding=2) buffer result { mat4 matrix[]; }; \n" //perverted, layout(binding=4) mat4 result[]; wont work
							  "layout (local_size_x = 1) in;\n"
							  "void main()\n"
							  "{\n"
							  //calculate look up at gpu
							  "	vec3 from = camera_pos;\n" //from to doesn't work right ? no idea why
							  "	vec3 to   = camera_look_at_pos;\n"
							  "	vec3 dir  = normalize(to - from);\n"
							  "	vec3 up   = vec3(0,1,0);\n"
							  "	vec3 right= cross(dir, up);\n"
							  "	up = cross(dir, right);\n"
							  "	mat4 look_at_matrix = mat4(vec4(right, 0),\n"
							  "							   vec4(up   , 0),\n"
							  "							   vec4(dir  , 0),\n"
							  "							   vec4(-from, 1));\n"
							  "	matrix[gl_GlobalInvocationID.x] = inverse(look_at_matrix);\n"
							  /* PROJECTION */
							  "	float h = 1.0/tan(45*0.0087266);\n" //FOV
							  "	float zNear = 0.1;\n"
							  "	float zFar  = 1000.0; \n"
							  "	float frustrumLength = zFar - zNear;\n"
							  "	mat4 ProjectionMatrix = mat4(vec4(h, 0, 0, 0),\n"
							  "								 vec4(0, h, 0, 0),\n"
							  "								 vec4(0, 0, -(zFar + zNear)/frustrumLength, -1),\n"
							  "								 vec4(0, 0, -2.0*(zNear * zFar)/frustrumLength, 0));\n"
							  /* PROJECTION END */
							  "matrix[gl_GlobalInvocationID.x] = ProjectionMatrix * matrix[gl_GlobalInvocationID.x];"
							  "}\n");

			my_compute.compile();
		}

		bool update()
		{
			my_window.update();

			my_window.begin();
				glClearColor(1,1,1,1);
				glClear(GL_COLOR_BUFFER_BIT);
				glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); //uhm no lights yet
			my_window.end();

			static int frame = 0;
			frame = frame + 1;

			GLfloat pos[3] = {std::cos(frame/100.0f)*10.0f, 10, std::sin(frame/100.0f)*10.0f};
			my_compute.set(&my_camera_pos, 3, 1, pos); //will force to recheck my_camera_pos id ! not good !!

			my_compute.begin();
				my_buffer.execute(&my_compute, 1, 1, 1); //this also binds for my_buffer.render().. somehow stupid..
			my_compute.end();

			my_shader.begin();
				my_buffer.render(4, 8); //uses bindings of last my_buffer.execute() for uniform_buffer shader_storage_buffer ! .. not that nice
			my_shader.end();

			my_window.flip(1000/30); //max. 30Hz
			return run;
		}
};

int main()
{
	test_window test;

	while(test.update());

	return 0;
}

<commit_msg>Enabled depth testing, added simple wireframe to the shader<commit_after>#include "window.h"
#include <cmath>

/*
	Simple test programm

	compile with: g++ *.cpp -lSDL
*/

class test_window: public koku::opengl::windowCallback
{
	private:
		koku::opengl::window my_window;
		koku::opengl::buffer my_buffer;
		koku::opengl::shader my_shader;
		koku::opengl::shader_uniform my_camera_pos;
		koku::opengl::compute my_compute;
		bool run;

	protected:
		void onQuit()
		{
			//stop everything !
			run = false;
		}

	public:
		test_window(): my_window(this, "test", 640, 480, true), my_buffer(&my_window), my_shader(&my_window), my_camera_pos("camera_pos"), my_compute(&my_window), run(true)
		{
			const float vertex[] =
			{
				1*0.8,1*0.8,-1, //right top
				-1*0.8,1*0.8,-1, //left top
				-1*0.8,-1*0.8,-1, //left bottom
				1*0.8, -1*0.8, -1, //right bottom

				1*0.8,1*0.8,1, //right top
				-1*0.8,1*0.8,1, //left top
				-1*0.8,-1*0.8,1, //left bottom
				1*0.8, -1*0.8, 1 //right bottom
			};

			const float color[] =
			{
				1,0,0,
				1,0,0,
				1,0,0,
				1,0,0,

				0,1,0,
				0,1,0,
				0,1,0,
				0,1,0
			};

			const float camera_matrix[] =
			{
				1,0,0,0,
				0,1,0,0,
				0,0,1,0,
				0,0,0,1
			};

			const unsigned short index[] =
			{
				0,1,3,2,0+4,1+4,3+4,2+4
			};

			my_buffer.upload(false,        vertex, 8*3, 3);
			my_buffer.upload(false,         color, 8*3, 3);
			my_buffer.upload(false, camera_matrix, 4*4, 1); //gets calculated by compute_shader ;)
			my_buffer.upload(true,          index, 8*1, 1);

			my_shader.uploadVertex("#version 400\n"
								   "layout(location = 0) in vec3 Position;\n"
								   "layout(location = 1) in vec3 Color;\n"
								   "out vec3 Position_tc;\n"
								   "out vec3 Color_tc;\n"
								   "void main()\n"
								   "{\n"
								   "	Position_tc = Position;\n" //pass position to tesslelation control shader
								   "	Color_tc = Color;\n"
								   "}\n");

			my_shader.uploadTessellationControl("#version 400\n"
												"layout(vertices = 4) out;"
												"in vec3 Position_tc[];\n"
												"in vec3 Color_tc[];\n"
												"out vec3 Position_te[];\n"
												"out vec3 Color_te[];\n"
												"#define ID gl_InvocationID\n"
												"void main()\n"
												"{\n"
												"	Position_te[ID] = Position_tc[ID];\n"
												"	Color_te[ID] = Color_tc[ID];\n"
												"	if (ID != 0)\n"
												"	{\n"
												"		gl_TessLevelInner[0] = 4;\n" //tes-level
												//"		gl_TessLevelInner[0] = int(int(gl_TessLevelInner[0])/2)*2;\n" //only 1,2,4,6, ...
												"		gl_TessLevelInner[1] = gl_TessLevelInner[0];\n"
												"		gl_TessLevelOuter[0] = gl_TessLevelInner[0];\n"
												"		gl_TessLevelOuter[1] = gl_TessLevelInner[0];\n"
												"		gl_TessLevelOuter[2] = gl_TessLevelInner[0];\n"
												"		gl_TessLevelOuter[3] = gl_TessLevelInner[0];\n"
												"	}\n"
												"}\n");

			my_shader.uploadTessellationEval("#version 400\n"
											 "layout(quads, equal_spacing) in;\n"
											 "in vec3 Position_te[];\n"
											 "in vec3 Color_te[];\n"
											 "out vec3 Color_geo;\n"
											 "out vec3 Position_geo;\n"
											 "void main()\n"
											 "{\n"
											 "	float u = gl_TessCoord.x, v = gl_TessCoord.y;\n"
											 "	vec3 a = mix(Position_te[0], Position_te[1], u);\n"
											 "	vec3 b = mix(Position_te[2], Position_te[3], u);\n"
											 "	Position_geo = mix(a, b, v);\n" //pass to geometry shader
											 "	a = mix(Color_te[0], Color_te[1], u);\n"
											 "	b = mix(Color_te[2], Color_te[3], u);\n"
											 "	Color_geo = mix(a, b, v);\n"
											 "}\n");

			my_shader.uploadGeometry("#version 430\n"
									 //"layout(quads) in;\n"
									 "layout(triangles) in;\n" //can't use quads
									 "layout(triangle_strip, max_vertices=24) out;\n"
									 "in vec3 Position_geo[];\n"
									 "in vec3 Color_geo[];\n"
									 "out vec3 Color_fr;\n"
									 "out vec3 Distance;\n"
									 "layout (binding=2) uniform result { mat4 CameraMatrix[]; }; \n" //gets data from compute shader
									 "void main()\n"
									 "{\n"
									 "	for(int i = 0; i < 3; i++)\n"
									 "	{\n"
									 "		gl_Position = CameraMatrix[0] * vec4(Position_geo[i], 1.0);\n" //again doesn't matter which ModelViewMatrix_geo (should be all the same)
									 "		Color_fr = Color_geo[i];\n"
									 "		if (i == 0) Distance = vec3(1,0,0);\n"
									 "		else if (i == 1) Distance = vec3(0,1,0);\n"
									 "		else Distance = vec3(0,0,1);\n"
									 "		EmitVertex();\n"
									 "	}\n"
									 "	EndPrimitive();\n"
									 //Dup it
									 "	for(int i = 0; i < 3; i++)\n"
									 "	{\n"
									 "		gl_Position = CameraMatrix[0] * vec4(Position_geo[i] + vec3(0,0,0.25), 1.0);\n" //again doesn't matter which ModelViewMatrix_geo (should be all the same)
									 "		Color_fr = Color_geo[i] + vec3(0,0,1);\n"
									 "		if (i == 0) Distance = vec3(1,0,0);\n"
									 "		else if (i == 1) Distance = vec3(0,1,0);\n"
									 "		else Distance = vec3(0,0,1);\n"
									 "		EmitVertex();\n"
									 "	}\n"
									 "	EndPrimitive();\n"
									 "}\n");

			my_shader.uploadFragment("#version 400\n"
									 "layout(location = 0) out vec4 FragColor;\n"
									 "in vec3 Color_fr;\n"
									 "in vec3 Distance;\n"
									 "void main()\n"
									 "{\n"
									 "	float D = clamp(min(min(Distance.x, Distance.y), Distance.z) / 0.08, 0, 1);\n"
									 "	FragColor = vec4(D,D,D,1) * vec4(Color_fr, 1.0);\n"
									 "}\n");

			my_shader.compile();

			my_compute.upload("#version 430\n"
							  "uniform vec3 camera_pos;\n"
							  "uniform vec3 camera_look_at_pos;\n"
							  "layout (binding=2) buffer result { mat4 matrix[]; }; \n" //perverted, layout(binding=4) mat4 result[]; wont work
							  "layout (local_size_x = 1) in;\n"
							  "void main()\n"
							  "{\n"
							  //calculate look up at gpu
							  "	vec3 from = camera_pos;\n" //from to doesn't work right ? no idea why
							  "	vec3 to   = camera_look_at_pos;\n"
							  "	vec3 dir  = normalize(to - from);\n" //could be a "normal" for collisions detection
							  "	vec3 up   = vec3(0,1,0);\n"
							  "	vec3 right= cross(dir, up);\n"
							  "	up = cross(dir, right);\n"
							  "	mat4 look_at_matrix = mat4(vec4(right, 0),\n"
							  "							   vec4(up   , 0),\n"
							  "							   vec4(dir  , 0),\n"
							  "							   vec4(-from, 1));\n"
							  "	matrix[gl_GlobalInvocationID.x] = inverse(look_at_matrix);\n"
							  /* PROJECTION */
							  "	float h = 1.0/tan(45*0.0087266);\n" //FOV
							  "	float zNear = 0.1;\n"
							  "	float zFar  = 1000.0; \n"
							  "	float frustrumLength = zFar - zNear;\n"
							  "	mat4 ProjectionMatrix = mat4(vec4(h, 0, 0, 0),\n"
							  "								 vec4(0, h, 0, 0),\n"
							  "								 vec4(0, 0, -(zFar + zNear)/frustrumLength, -1),\n"
							  "								 vec4(0, 0, -2.0*(zNear * zFar)/frustrumLength, 0));\n"
							  /* PROJECTION END */
							  "matrix[gl_GlobalInvocationID.x] = ProjectionMatrix * matrix[gl_GlobalInvocationID.x];"
							  "}\n");

			my_compute.compile();
		}

		bool update()
		{
			my_window.update();

			my_window.begin();

				glClearColor(1,1,1,1);
				glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
				glEnable(GL_DEPTH_TEST);

				static int frame = 0;
				frame = frame + 1;

				GLfloat pos[3] = {std::cos(frame/100.0f)*10.0f, 10, std::sin(frame/100.0f)*10.0f};
				my_compute.set(&my_camera_pos, 3, 1, pos);

				my_compute.begin();
					//my_compute.bind(my_buffer); //binds the buffer to storage buffer block binding=0..n
					//my_compute.execute(1,1,1);
					my_buffer.execute(&my_compute, 1, 1, 1); //this also binds for my_buffer.render().. somehow stupid..
				my_compute.end();

				my_shader.begin();
					//my_shader.bind(my_buffer); //binds the buffers to uniform block binding=0..n
					my_buffer.render(4, 8); //uses bindings of last my_buffer.execute() for uniform_buffer shader_storage_buffer ! .. not that nice
				my_shader.end();

				my_window.flip(1000/30); //max. 30Hz

			my_window.end();
			return run;
		}
};

int main()
{
	test_window test;

	while(test.update());

	return 0;
}

<|endoftext|>


<commit_before>e2bdf3f5-2747-11e6-af2f-e0f84713e7b8<commit_msg>I finished programming, there is nothing left to program<commit_after>e2da6b57-2747-11e6-9d6d-e0f84713e7b8<|endoftext|>


<commit_before>d057db91-4b02-11e5-ac71-28cfe9171a43<commit_msg>Made changes so it will hopefully compile by the next commit<commit_after>d064a014-4b02-11e5-8ab6-28cfe9171a43<|endoftext|>


<commit_before>1d2a6319-ad59-11e7-a858-ac87a332f658<commit_msg>Fix that bug where things didn't work but now they should<commit_after>1dd1b0a1-ad59-11e7-8965-ac87a332f658<|endoftext|>


<commit_before>ce682aee-4b02-11e5-a2a4-28cfe9171a43<commit_msg>more fixes<commit_after>ce769e35-4b02-11e5-9efe-28cfe9171a43<|endoftext|>


<commit_before>b97ce5bd-4b02-11e5-9159-28cfe9171a43<commit_msg>Really doesn't crash if X, now<commit_after>b988c33d-4b02-11e5-aece-28cfe9171a43<|endoftext|>


<commit_before>994be09c-4b02-11e5-bacd-28cfe9171a43<commit_msg>compiles now<commit_after>9958c438-4b02-11e5-87f7-28cfe9171a43<|endoftext|>


<commit_before>5d72c8f0-ad5d-11e7-84b8-ac87a332f658<commit_msg>update testing<commit_after>5e55be6b-ad5d-11e7-abfc-ac87a332f658<|endoftext|>


<commit_before>#include <fountain.h>
#include <string>
#define abs(x) ((x)>0?(x):-(x))

ftPhysics::Body* bdPoint;

namespace Game {

double xAngle = 0.0f;
double yAngle = 0.0f;
double scale = 1.0f;
//int testPic;
ftVec2 deltaV;

//TODO: move this internal(ftTime)
ftTime::Clock mainClock(60.0);

//ft3DModel::ObjModel simpleModel("first.obj");

//TODO: move this internal(ftRender)
ftRender::Camera mainCamera(0, 0, 500);
};

void fountain::setBasicVarible()
{
	mainWin.setW(800);
	mainWin.setH(600);
	mainWin.title = std::string("fountain-prototype ") + std::string(FOUNTAIN_VERSION);
	mainWin.icon = "fountain.ico";
	mainWin.isFullScreen = false;
	mainWin.hideCursor = false;
}

void fountain::gameInit()
{
	ftRender::openLineSmooth();
	glLineWidth(1.5f);
	ftRender::openPointSmooth();
	Game::mainCamera.setWinSize(fountain::mainWin.w, fountain::mainWin.h);
	//Game::testPic = ftRender::getPicture("test.jpg");
	Game::mainClock.init();
	//glEnable(GL_DEPTH_TEST);

	for (int i = 0; i < 10; i++) {
		for (int j = 0 - i; j <= i; j++) {
			bdPoint = new ftPhysics::Body(j, -i, false);
			if (!fountain::mainWorld.addBody(bdPoint)) {
				delete bdPoint;
			}
		}
	}

	bdPoint = new ftPhysics::Body(0, -100, false);
	bdPoint->setRectSize(ftVec2(100, 1));
	if (!fountain::mainWorld.addBody(bdPoint)) {
		delete bdPoint;
	}

	for (int i = -50; i <= 50; i+=2) {
		bdPoint = new ftPhysics::Body(i, -100 + 3.6);
		bdPoint->setRectSize(ftVec2(0.5, 3));
		if (!fountain::mainWorld.addBody(bdPoint)) {
			delete bdPoint;
		}
	}
}

void fountain::singleFrame()
{
	ftVec2 mPos = fountain::sysMouse.getPos();
	mPos = Game::mainCamera.mouseToWorld(mPos);

	//TODO: move this internal
	fountain::mainWorld.update(Game::mainClock.getDeltaT());

	//TODO: move these to update(ftScene hook)
	if (fountain::sysMouse.getState(1)) {
		bdPoint = new ftPhysics::Body(mPos.x, mPos.y);
		if (!fountain::mainWorld.addBody(bdPoint)) {
			delete bdPoint;
		}
	}
	if (fountain::sysMouse.getState(2)) {
		bdPoint = new ftPhysics::Body(mPos.x, mPos.y, false);
		if (!fountain::mainWorld.addBody(bdPoint)) {
			delete bdPoint;
		}
	}
	if (fountain::sysMouse.getState(4)) {
		Game::scale *= 1.15f;
	}
	if (fountain::sysMouse.getState(5)) {
		Game::scale /= 1.15f;
	}
	if (fountain::sysMouse.getState(3)) {
		Game::deltaV = fountain::sysMouse.getDeltaV();
		Game::mainCamera.move(-Game::deltaV.x / Game::scale, -Game::deltaV.y / Game::scale);
	}
	if (fountain::sysKeyboard.getState(FT_W))
		Game::mainCamera.move(0, 3);
	if (fountain::sysKeyboard.getState(FT_S))
		Game::mainCamera.move(0, -3);
	if (fountain::sysKeyboard.getState(FT_A))
		Game::mainCamera.move(-3, 0);
	if (fountain::sysKeyboard.getState(FT_D))
		Game::mainCamera.move(3, 0);

	Game::mainCamera.setScale(Game::scale);
	Game::mainCamera.update();

	fountain::mainWorld.draw();

	//TODO: move this internal(fountainMain)
	Game::mainClock.tick();
}
<commit_msg>main: change control logic<commit_after>#include <fountain.h>
#include <string>
#define abs(x) ((x)>0?(x):-(x))

ftPhysics::Body* bdPoint;

namespace Game {

double xAngle = 0.0f;
double yAngle = 0.0f;
double scale = 1.0f;
//int testPic;
ftVec2 deltaV;

//TODO: move this internal(ftTime)
ftTime::Clock mainClock(60.0);

//ft3DModel::ObjModel simpleModel("first.obj");

//TODO: move this internal(ftRender)
ftRender::Camera mainCamera(0, 0, 500);
};

void fountain::setBasicVarible()
{
	mainWin.setW(800);
	mainWin.setH(600);
	mainWin.title = std::string("fountain-prototype ") + std::string(FOUNTAIN_VERSION);
	mainWin.icon = "fountain.ico";
	mainWin.isFullScreen = false;
	mainWin.hideCursor = false;
}

void fountain::gameInit()
{
	ftRender::openLineSmooth();
	glLineWidth(1.5f);
	ftRender::openPointSmooth();
	Game::mainCamera.setWinSize(fountain::mainWin.w, fountain::mainWin.h);
	//Game::testPic = ftRender::getPicture("test.jpg");
	Game::mainClock.init();
	//glEnable(GL_DEPTH_TEST);

	for (int i = 0; i < 10; i++) {
		for (int j = 0 - i; j <= i; j++) {
			bdPoint = new ftPhysics::Body(j, -i, false);
			if (!fountain::mainWorld.addBody(bdPoint)) {
				delete bdPoint;
			}
		}
	}

	bdPoint = new ftPhysics::Body(0, -100, false);
	bdPoint->setRectSize(ftVec2(100, 1));
	if (!fountain::mainWorld.addBody(bdPoint)) {
		delete bdPoint;
	}

	for (int i = -50; i <= 50; i+=2) {
		bdPoint = new ftPhysics::Body(i, -100 + 3.6);
		bdPoint->setRectSize(ftVec2(0.5, 3));
		if (!fountain::mainWorld.addBody(bdPoint)) {
			delete bdPoint;
		}
	}
}

void fountain::singleFrame()
{
	ftVec2 mPos = fountain::sysMouse.getPos();
	mPos = Game::mainCamera.mouseToWorld(mPos);

	//TODO: move this internal
	fountain::mainWorld.update(Game::mainClock.getDeltaT());

	//TODO: move these to update(ftScene hook)
	if (fountain::sysMouse.getState(1)) {
		bdPoint = new ftPhysics::Body(mPos.x, mPos.y);
		if (!fountain::mainWorld.addBody(bdPoint)) {
			delete bdPoint;
		}
	}

	if (fountain::sysMouse.getState(3)) {
		bdPoint = new ftPhysics::Body(mPos.x, mPos.y, false);
		if (!fountain::mainWorld.addBody(bdPoint)) {
			delete bdPoint;
		}
	}
	if (fountain::sysMouse.getState(4)) {
		Game::scale *= 1.15f;
	}
	if (fountain::sysMouse.getState(5)) {
		Game::scale /= 1.15f;
	}
	if (fountain::sysMouse.getState(2)) {
		Game::deltaV = fountain::sysMouse.getDeltaV();
		Game::mainCamera.move(-Game::deltaV.x / Game::scale, -Game::deltaV.y / Game::scale);
	}

	Game::mainCamera.setScale(Game::scale);
	Game::mainCamera.update();

	fountain::mainWorld.draw();

	//TODO: move this internal(fountainMain)
	Game::mainClock.tick();
}
<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------------
** This software is implemented as part of the course Dynamic Algorithms
** (Q4 2015) at Aarhus Univerity Denmark.
**
** main.cpp
** Runs tests (correctness and execution time) for all implementations.
**
** Author: Martin Storgaard and Konstantinos Mampentzidis
** -------------------------------------------------------------------------*/

#include <iostream>
#include <stdio.h>
#include <string>

#include "TC.h"
#include "FW_LAZY.h"
#include "FW_EAGER.h"
#include "DFS_LAZY.h"
#include "DFS_EAGER.h"
#include "TD_EAGER.h"

#include "input_reader.h"
#include "performance.h"

const std::string inputPath ("input/");

int main(int argc, const char* argv[]) {
	if(argc != 2) {
		return -1;
	}
	Performance *perf = new Performance();
	// Read input file (at most 255 characters)
	std::string inputFile (argv[1], 255);

	// First define which algorithms to run
	std::vector<TC*> algorithms = {
		//new FW_LAZY(),
		new FW_EAGER(),
		//new DFS_LAZY(),
		new DFS_EAGER(),
		new TD_EAGER()
	};
	// Then define input
	std::vector<Input> change_sequence;
	read_input(inputFile.c_str(), change_sequence);

	// Format the output prefix
	unsigned long idx = inputFile.find("change");
	unsigned long idxEnd = inputFile.find(".txt");
	std::string output_prefix = inputFile.substr(idx, idxEnd-idx);
	perf->run(algorithms, change_sequence, output_prefix);

	return 0;
}
<commit_msg>Added error statement if input reader fails<commit_after>/* ---------------------------------------------------------------------------
** This software is implemented as part of the course Dynamic Algorithms
** (Q4 2015) at Aarhus Univerity Denmark.
**
** main.cpp
** Runs tests (correctness and execution time) for all implementations.
**
** Author: Martin Storgaard and Konstantinos Mampentzidis
** -------------------------------------------------------------------------*/

#include <iostream>
#include <stdio.h>
#include <string>

#include "TC.h"
#include "FW_LAZY.h"
#include "FW_EAGER.h"
#include "DFS_LAZY.h"
#include "DFS_EAGER.h"
#include "TD_EAGER.h"

#include "input_reader.h"
#include "performance.h"

const std::string inputPath ("input/");

int main(int argc, const char* argv[]) {
	if(argc != 2) {
		return -1;
	}
	Performance *perf = new Performance();
	// Read input file (at most 255 characters)
	std::string inputFile (argv[1], 255);

	// First define which algorithms to run
	std::vector<TC*> algorithms = {
		//new FW_LAZY(),
		new FW_EAGER(),
		//new DFS_LAZY(),
		new DFS_EAGER(),
		new TD_EAGER()
	};
	// Then define input
	std::vector<Input> change_sequence;
	read_input(inputFile.c_str(), change_sequence);
	if(change_sequence.size() == 0) {
		std::cout << "ERROR" << std::endl;
		return -1;
	}
	// Format the output prefix
	unsigned long idx = inputFile.find("change");
	unsigned long idxEnd = inputFile.find(".txt");
	std::string output_prefix = inputFile.substr(idx, idxEnd-idx);
	perf->run(algorithms, change_sequence, output_prefix);

	return 0;
}
<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** main.cpp
**
** -------------------------------------------------------------------------*/

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <map>
#include <list>

#include "PeerConnectionManager.h"

#include "webrtc/base/ssladapter.h"
#include "webrtc/base/thread.h"
#include "webrtc/p2p/base/stunserver.h"
#include "webrtc/base/httpserver.h"
#include "webrtc/base/pathutils.h"

/* ---------------------------------------------------------------------------
**  http callback
** -------------------------------------------------------------------------*/
class HttpServerRequestHandler : public sigslot::has_slots<>
{
	public:
		HttpServerRequestHandler(rtc::HttpServer* server, PeerConnectionManager* webRtcServer) : m_server(server), m_webRtcServer(webRtcServer)
		{
			m_server->SignalHttpRequest.connect(this, &HttpServerRequestHandler::OnRequest);
		}

		void OnRequest(rtc::HttpServer*, rtc::HttpServerTransaction* t)
		{
			std::string host;
			std::string path;
			t-> request.getRelativeUri(&host, &path);
			std::cout << "===>" <<  path << std::endl;

			rtc::HttpAttributeList attributes;
			rtc::HttpParseAttributes(t-> request.path.c_str(), t-> request.path.size(), attributes);

			rtc::scoped_ptr<rtc::StreamInterface>& stream(t-> request.document);
			size_t size = 0;
			stream->GetSize(&size);
			stream->Rewind();
			char buffer[size];
			size_t readsize = 0;
			rtc::StreamResult res = stream->ReadAll(&buffer, size, &readsize, NULL);
			std::cout << "res:" << res << std::endl;
			std::string body(buffer, readsize);
			std::cout << "readsize:" << readsize << std::endl;
			std::cout << "body:" << body << std::endl;

			std::string answer;
			if (path == "/getDeviceList")
			{
				std::string answer(Json::StyledWriter().write(m_webRtcServer->getDeviceList()));

				rtc::MemoryStream* mem = new rtc::MemoryStream(answer.c_str(), answer.size());
				t->response.set_success("text/plain", mem);
			}
			else if (path == "/offer")
			{
				std::string url;
				t-> request.hasHeader("url", &url);
				url = rtc::s_url_decode(url);
				std::string peerid;
				std::string answer(m_webRtcServer->getOffer(peerid,url));
				std::cout << peerid << ":" << answer << std::endl;

				rtc::MemoryStream* mem = new rtc::MemoryStream(answer.c_str(), answer.size());
				t->response.addHeader("peerid",peerid);
				t->response.set_success("text/plain", mem);
			}
			else if (path == "/answer")
			{
				std::string peerid;
				t-> request.hasHeader("peerid", &peerid);
				m_webRtcServer->setAnswer(peerid, body);

				t->response.addHeader("peerid",peerid);
				t->response.set_success();
			}
			else if (path == "/getIceCandidate")
			{
				std::string peerid;
				t-> request.hasHeader("peerid", &peerid);

				std::string answer(Json::StyledWriter().write(m_webRtcServer->getIceCandidateList(peerid)));
				rtc::MemoryStream* mem = new rtc::MemoryStream(answer.c_str(), answer.size());
				t->response.set_success("text/plain", mem);
			}
			else if (path == "/addIceCandidate")
			{
				std::string peerid;
				t-> request.hasHeader("peerid", &peerid);
				m_webRtcServer->addIceCandidate(peerid, body);

				t->response.set_success();
			}
			else
			{
				rtc::Pathname pathname("index.html");
				rtc::FileStream* fs(rtc::Filesystem::OpenFile(pathname, "rb"));
				t->response.set_success("text/html", fs);
			}
			t->response.setHeader(rtc::HH_CONNECTION,"Close");
			m_server->Respond(t);
		}

	protected:
		rtc::HttpServer*       m_server;
		PeerConnectionManager* m_webRtcServer;
};

/* ---------------------------------------------------------------------------
**  main
** -------------------------------------------------------------------------*/
int main(int argc, char* argv[]) {
	const char* port     = "0.0.0.0:8000";
	const char* stunurl  = "127.0.0.1:3478";
	int logLevel = rtc::LERROR;

	int c = 0;
	while ((c = getopt (argc, argv, "hS:H:v::")) != -1)
	{
		switch (c)
		{
			case 'v': logLevel--; if (optarg) logLevel-=strlen(optarg); break;
			case 'H': port = optarg; break;
			case 'S': stunurl = optarg; break;
			case 'h':
			default:
				std::cout << argv[0] << " [-P http port] [-S stun address] -[v[v]]"                             << std::endl;
				std::cout << "\t -v[v[v]]         : verbosity"                                                  << std::endl;
				std::cout << "\t -H [hostname:]port : HTTP server binding (default "   << port    << ")"        << std::endl;
				std::cout << "\t -S stun_address    : STUN listenning address (default " << stunurl << ")"        << std::endl;
				exit(0);
		}
	}

	rtc::LogMessage::LogToDebug((rtc::LoggingSeverity)logLevel);
	rtc::LogMessage::LogTimestamps();
	rtc::LogMessage::LogThreads();
	std::cout << "Logger level:" <<  rtc::LogMessage::GetMinLogSeverity() << std::endl;

	rtc::Thread* thread = rtc::Thread::Current();
	rtc::InitializeSSL();

	// webrtc server
	PeerConnectionManager webRtcServer(stunurl);
	if (!webRtcServer.InitializePeerConnection())
	{
		std::cout << "Cannot Initialize WebRTC server" << std::endl;
	}
	else
	{
		// http server
		rtc::HttpListenServer httpServer;
		rtc::SocketAddress http_addr;
		http_addr.FromString(port);
		int ret = httpServer.Listen(http_addr);
		if (ret != 0)
		{
			std::cout << "Cannot Initialize start HTTP server " << strerror(ret) << std::endl;
		}
		else
		{
			// connect httpserver to a request handler
			HttpServerRequestHandler http(&httpServer, &webRtcServer);

			// STUN server
			rtc::SocketAddress server_addr;
			server_addr.FromString(stunurl);
			rtc::scoped_ptr<cricket::StunServer> stunserver;
			rtc::AsyncUDPSocket* server_socket = rtc::AsyncUDPSocket::Create(thread->socketserver(), server_addr);
			if (server_socket)
			{
				stunserver.reset(new cricket::StunServer(server_socket));
				std::cout << "STUN Listening at " << server_addr.ToString() << std::endl;
			}

			// mainloop
			while(thread->ProcessMessages(100));
		}
	}

	rtc::CleanupSSL();
	return 0;
}

<commit_msg>remove useless output peerid processing /answer<commit_after>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** main.cpp
**
** -------------------------------------------------------------------------*/

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <map>
#include <list>

#include "PeerConnectionManager.h"

#include "webrtc/base/ssladapter.h"
#include "webrtc/base/thread.h"
#include "webrtc/p2p/base/stunserver.h"
#include "webrtc/base/httpserver.h"
#include "webrtc/base/pathutils.h"

/* ---------------------------------------------------------------------------
**  http callback
** -------------------------------------------------------------------------*/
class HttpServerRequestHandler : public sigslot::has_slots<>
{
	public:
		HttpServerRequestHandler(rtc::HttpServer* server, PeerConnectionManager* webRtcServer) : m_server(server), m_webRtcServer(webRtcServer)
		{
			m_server->SignalHttpRequest.connect(this, &HttpServerRequestHandler::OnRequest);
		}

		void OnRequest(rtc::HttpServer*, rtc::HttpServerTransaction* t)
		{
			std::string host;
			std::string path;
			t-> request.getRelativeUri(&host, &path);
			std::cout << "===>" <<  path << std::endl;

			rtc::HttpAttributeList attributes;
			rtc::HttpParseAttributes(t-> request.path.c_str(), t-> request.path.size(), attributes);

			rtc::scoped_ptr<rtc::StreamInterface>& stream(t-> request.document);
			size_t size = 0;
			stream->GetSize(&size);
			stream->Rewind();
			char buffer[size];
			size_t readsize = 0;
			rtc::StreamResult res = stream->ReadAll(&buffer, size, &readsize, NULL);
			std::cout << "res:" << res << std::endl;
			std::string body(buffer, readsize);
			std::cout << "readsize:" << readsize << std::endl;
			std::cout << "body:" << body << std::endl;

			std::string answer;
			if (path == "/getDeviceList")
			{
				std::string answer(Json::StyledWriter().write(m_webRtcServer->getDeviceList()));

				rtc::MemoryStream* mem = new rtc::MemoryStream(answer.c_str(), answer.size());
				t->response.set_success("text/plain", mem);
			}
			else if (path == "/offer")
			{
				std::string url;
				t-> request.hasHeader("url", &url);
				url = rtc::s_url_decode(url);
				std::string peerid;
				std::string answer(m_webRtcServer->getOffer(peerid,url));
				std::cout << peerid << ":" << answer << std::endl;

				rtc::MemoryStream* mem = new rtc::MemoryStream(answer.c_str(), answer.size());
				t->response.addHeader("peerid",peerid);
				t->response.set_success("text/plain", mem);
			}
			else if (path == "/answer")
			{
				std::string peerid;
				t-> request.hasHeader("peerid", &peerid);
				m_webRtcServer->setAnswer(peerid, body);

				t->response.set_success();
			}
			else if (path == "/getIceCandidate")
			{
				std::string peerid;
				t-> request.hasHeader("peerid", &peerid);

				std::string answer(Json::StyledWriter().write(m_webRtcServer->getIceCandidateList(peerid)));
				rtc::MemoryStream* mem = new rtc::MemoryStream(answer.c_str(), answer.size());
				t->response.set_success("text/plain", mem);
			}
			else if (path == "/addIceCandidate")
			{
				std::string peerid;
				t-> request.hasHeader("peerid", &peerid);
				m_webRtcServer->addIceCandidate(peerid, body);

				t->response.set_success();
			}
			else
			{
				rtc::Pathname pathname("index.html");
				rtc::FileStream* fs(rtc::Filesystem::OpenFile(pathname, "rb"));
				t->response.set_success("text/html", fs);
			}
			t->response.setHeader(rtc::HH_CONNECTION,"Close");
			m_server->Respond(t);
		}

	protected:
		rtc::HttpServer*       m_server;
		PeerConnectionManager* m_webRtcServer;
};

/* ---------------------------------------------------------------------------
**  main
** -------------------------------------------------------------------------*/
int main(int argc, char* argv[]) {
	const char* port     = "0.0.0.0:8000";
	const char* stunurl  = "127.0.0.1:3478";
	int logLevel = rtc::LERROR;

	int c = 0;
	while ((c = getopt (argc, argv, "hS:H:v::")) != -1)
	{
		switch (c)
		{
			case 'v': logLevel--; if (optarg) logLevel-=strlen(optarg); break;
			case 'H': port = optarg; break;
			case 'S': stunurl = optarg; break;
			case 'h':
			default:
				std::cout << argv[0] << " [-P http port] [-S stun address] -[v[v]]"                             << std::endl;
				std::cout << "\t -v[v[v]]         : verbosity"                                                  << std::endl;
				std::cout << "\t -H [hostname:]port : HTTP server binding (default "   << port    << ")"        << std::endl;
				std::cout << "\t -S stun_address    : STUN listenning address (default " << stunurl << ")"        << std::endl;
				exit(0);
		}
	}

	rtc::LogMessage::LogToDebug((rtc::LoggingSeverity)logLevel);
	rtc::LogMessage::LogTimestamps();
	rtc::LogMessage::LogThreads();
	std::cout << "Logger level:" <<  rtc::LogMessage::GetMinLogSeverity() << std::endl;

	rtc::Thread* thread = rtc::Thread::Current();
	rtc::InitializeSSL();

	// webrtc server
	PeerConnectionManager webRtcServer(stunurl);
	if (!webRtcServer.InitializePeerConnection())
	{
		std::cout << "Cannot Initialize WebRTC server" << std::endl;
	}
	else
	{
		// http server
		rtc::HttpListenServer httpServer;
		rtc::SocketAddress http_addr;
		http_addr.FromString(port);
		int ret = httpServer.Listen(http_addr);
		if (ret != 0)
		{
			std::cout << "Cannot Initialize start HTTP server " << strerror(ret) << std::endl;
		}
		else
		{
			// connect httpserver to a request handler
			HttpServerRequestHandler http(&httpServer, &webRtcServer);

			// STUN server
			rtc::SocketAddress server_addr;
			server_addr.FromString(stunurl);
			rtc::scoped_ptr<cricket::StunServer> stunserver;
			rtc::AsyncUDPSocket* server_socket = rtc::AsyncUDPSocket::Create(thread->socketserver(), server_addr);
			if (server_socket)
			{
				stunserver.reset(new cricket::StunServer(server_socket));
				std::cout << "STUN Listening at " << server_addr.ToString() << std::endl;
			}

			// mainloop
			while(thread->ProcessMessages(10));
		}
	}

	rtc::CleanupSSL();
	return 0;
}

<|endoftext|>


<commit_before>7e50cf78-4b02-11e5-9ae5-28cfe9171a43<commit_msg>Adding stuff<commit_after>7e5deb21-4b02-11e5-909c-28cfe9171a43<|endoftext|>


<commit_before>#include <stdio.h>
#include <mpi.h>
#include <math.h>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <algorithm>

int g_world_size;
int g_mpi_rank;
int start_id;
int end_id;
int g_max_id = 125000000;
MPI_Offset file_start;
MPI_Offset file_end;
std::map<int, std::set<int>> g_adj_list;
std::map<int, std::set<int>> g_bonus_list;

void parse_file();
void listen();
void add_to_adjlist(std::string line);
int id_to_rank(int id);

int main(int argc, char** argv) {
  // Initialize the MPI environment
  MPI_Init(&argc, &argv);

  // Get the number of processes
  MPI_Comm_size(MPI_COMM_WORLD, &g_world_size);

  // Get the rank of the process
  MPI_Comm_rank(MPI_COMM_WORLD, &g_mpi_rank);

  start_id = g_mpi_rank*(g_max_id / g_world_size);
  end_id = (g_mpi_rank+1)*(g_max_id / g_world_size);
  if (g_mpi_rank == g_world_size-1){
    end_id = g_max_id;
  }

  //printf("Rank %d: start_id: %d end_id: %d\n", g_mpi_rank, start_id, end_id);

  // Print off a hello world message
  parse_file();
  printf("Rank: %d    g_adj_list.size(): %lu    g_bonus_list.size(): %lu\n", g_mpi_rank, g_adj_list.size(), g_bonus_list.size());
  if (g_mpi_rank == 0){
   // parse_file();
    //printf("Rank: %d    g_adj_list.size(): %lu\n", g_mpi_rank, g_adj_list.size());
  }

  // Finalize the MPI environment.
  MPI_Finalize();

  return 0;
}

void parse_file(){
  char filename[70];
  //sprintf(filename, "com-friendster.ungraph.txt");
  sprintf(filename, "/gpfs/u/home/PCP5/PCP5stns/scratch-shared/com-friendster.ungraph.txt");

  MPI_File infile;
  MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &infile);
  MPI_Offset filesize = 0;
  MPI_File_get_size(infile, &filesize);

  file_start = (g_mpi_rank)*(filesize/g_world_size);
  if (g_mpi_rank == 0){
    file_start = 124;
  }else{
    file_start -= 50; // allow some overlap to catch newlines
  }
  file_end = (g_mpi_rank+1)*(filesize/g_world_size);
  if (g_mpi_rank == g_world_size-1){
    file_end = filesize;
  }
  /*if (g_mpi_rank != 0){
   MPI_File_close(&infile);
   return;
  }*/
  MPI_Offset offset = file_start;
  char * buffer;
  std::string chunk = "";
  unsigned int buffer_size = 100000;

  bool skip = (g_mpi_rank != 0);

  while (offset < file_end){
   // printf("Rank: %d offset: %lld, file_end: %lld, remaining: %lld  size of adj_list: %lu\n", g_mpi_rank, offset, file_end, file_end-offset, g_adj_list.size());
    buffer = (char *)malloc( (buffer_size + 1)*sizeof(char));
    MPI_File_read_at(infile, offset, buffer, buffer_size, MPI_CHAR, MPI_STATUS_IGNORE);
    offset += buffer_size;
    // end the string
    buffer[buffer_size] = '\0';
    std::string new_string(buffer);
    free(buffer);
    chunk += new_string;

    if (skip){
      // skip up to the first newline to remove any broken lines from starting in the middle of the file
      chunk = chunk.substr(chunk.find('\n')+1);
    }else{
      skip = true;
    }

    int found_nl = chunk.find('\n');
    while (found_nl < chunk.size()){
      std::string line = chunk.substr(0, found_nl);
      add_to_adjlist(line);

      chunk = chunk.substr(found_nl+1);
      found_nl = chunk.find('\n');
    }
  }
  printf("Rank %d: finished read in of own portion of file    %lu\n", g_mpi_rank, g_adj_list.size());
  //MPI_Barrier(MPI_COMM_WORLD);
  MPI_File_close(&infile);
}

int id_to_rank(int id){
  int max_id=0;
  for (int i=0; i<g_world_size; i++){
    max_id += g_max_id / g_world_size;
    if (id < max_id){
      return i;
    }
  }
  return g_world_size-1;
}

void add_to_adjlist(std::string line){

  int tab_pos = line.find("\t");
  int one = atoi(line.substr(0, tab_pos).c_str());
  int two = atoi(line.substr(tab_pos+1).c_str());

  if (one >= start_id && one < end_id){
    g_adj_list[one].insert(two);
    if (two >= start_id && two < end_id){
      g_adj_list[two].insert(one);
    }else{
      g_bonus_list[two].insert(one);
    }
  }else{
    g_bonus_list[one].insert(two);
    g_bonus_list[two].insert(one);
  }
}
<commit_msg>gather implementation<commit_after>#include <stdio.h>
#include <mpi.h>
#include <math.h>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <algorithm>

int g_world_size;
int g_mpi_rank;
int start_id;
int end_id;
int g_max_id = 550000;
MPI_Offset file_start;
MPI_Offset file_end;
std::map<int, std::set<int>> g_adj_list;
std::map<int, std::set<int>> g_bonus_list;

void parse_file();
void add_to_adjlist(std::string line);
int id_to_rank(int id);
int * bonus_to_list(int id);
int bonus_list_size(int id);

int main(int argc, char** argv) {
  // Initialize the MPI environment
  MPI_Init(&argc, &argv);

  // Get the number of processes
  MPI_Comm_size(MPI_COMM_WORLD, &g_world_size);

  // Get the rank of the process
  MPI_Comm_rank(MPI_COMM_WORLD, &g_mpi_rank);

  start_id = g_mpi_rank*(g_max_id / g_world_size);
  end_id = (g_mpi_rank+1)*(g_max_id / g_world_size);
  if (g_mpi_rank == g_world_size-1){
    end_id = g_max_id;
  }

  //printf("Rank %d: start_id: %d end_id: %d\n", g_mpi_rank, start_id, end_id);

  // Print off a hello world message
  parse_file();
  printf("Rank: %d    g_adj_list.size(): %lu    g_bonus_list.size(): %lu\n", g_mpi_rank, g_adj_list.size(), g_bonus_list.size());
  if (g_mpi_rank == 0){
   // parse_file();
    //printf("Rank: %d    g_adj_list.size(): %lu\n", g_mpi_rank, g_adj_list.size());
  }

  // Finalize the MPI environment.
  MPI_Finalize();

  return 0;
}

void parse_file(){
  char filename[70];
  sprintf(filename, "com-amazon.ungraph.txt");
  //sprintf(filename, "/gpfs/u/home/PCP5/PCP5stns/scratch-shared/com-amazon.ungraph.txt");

  MPI_File infile;
  MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &infile);
  MPI_Offset filesize = 0;
  MPI_File_get_size(infile, &filesize);

  file_start = (g_mpi_rank)*(filesize/g_world_size);
  if (g_mpi_rank == 0){
    file_start = 124;
  }else{
    file_start -= 50; // allow some overlap to catch newlines
  }
  file_end = (g_mpi_rank+1)*(filesize/g_world_size);
  if (g_mpi_rank == g_world_size-1){
    file_end = filesize;
  }
  /*if (g_mpi_rank != 0){c
   MPI_File_close(&infile);
   return;
  }*/
  MPI_Offset offset = file_start;
  char * buffer;
  std::string chunk = "";
  unsigned int buffer_size = 10000;

  bool skip = (g_mpi_rank != 0);

  while (offset < file_end){
   // printf("Rank: %d offset: %lld, file_end: %lld, remaining: %lld  size of adj_list: %lu\n", g_mpi_rank, offset, file_end, file_end-offset, g_adj_list.size());
    buffer = (char *)malloc( (buffer_size + 1)*sizeof(char));
    MPI_File_read_at(infile, offset, buffer, buffer_size, MPI_CHAR, MPI_STATUS_IGNORE);
    offset += buffer_size;
    // end the string
    buffer[buffer_size] = '\0';
    std::string new_string(buffer);
    free(buffer);
    chunk += new_string;

    if (skip){
      // skip up to the first newline to remove any broken lines from starting in the middle of the file
      chunk = chunk.substr(chunk.find('\n')+1);
    }else{
      skip = true;
    }

    int found_nl = chunk.find('\n');
    while (found_nl < chunk.size()){
      std::string line = chunk.substr(0, found_nl);
      add_to_adjlist(line);

      chunk = chunk.substr(found_nl+1);
      found_nl = chunk.find('\n');
    }
  }
  printf("Rank: %d    g_adj_list.size(): %lu    g_bonus_list.size(): %lu\n", g_mpi_rank, g_adj_list.size(), g_bonus_list.size());

  for (int id=0; id<g_max_id; id++){
    int r1 = id_to_rank(id);
    int * bonus = bonus_to_list(id);
    int bonus_size = bonus_list_size(id);
    int * to_recv = NULL;
    int * disp = NULL;
    if (r1 == g_mpi_rank){
      to_recv = (int *)calloc(g_world_size, sizeof(int));
      disp = (int *)calloc(g_world_size, sizeof(int));
    }
    MPI_Gather(&bonus_size, 1, MPI_INT, to_recv, g_world_size, MPI_INT, r1, MPI_COMM_WORLD);
    //MPI_Barrier(MPI_COMM_WORLD);
    int total = 0;
    int *to_recv2 = NULL;

    if (r1 == g_mpi_rank){
      for (int i=0; i<g_world_size; i++){
        disp[i] = total;
        total += to_recv[i];
      }
      to_recv2 = (int *)calloc(total, sizeof(int));
      //printf("rank %d   id: %d    %d\n", g_mpi_rank, id, total);
    }
    //printf("id %d: id %d: total %d\n", g_mpi_rank, id, total);
    MPI_Gatherv(bonus, bonus_size, MPI_INT, to_recv2, to_recv, disp, MPI_INT, r1, MPI_COMM_WORLD);
    //MPI_Barrier(MPI_COMM_WORLD);
    g_bonus_list.erase(id);
    for (int i=0; i<total; i++){
      g_adj_list[id].insert(to_recv2[i]);
    }
    free(to_recv);
    free(to_recv2);
    free(disp);
  }

  //MPI_Barrier(MPI_COMM_WORLD);
  MPI_File_close(&infile);
}

int * bonus_to_list(int id){
  int size = bonus_list_size(id);
  int* bonus = (int *)malloc((size)*sizeof(int));
  if (size == 0){
    return bonus;
  }
  auto itr = g_bonus_list[id].begin();
  for (int i=0; i<size; i++){
    bonus[i] = *itr;
    itr++;
  }
  return bonus;
}
int bonus_list_size(int id){
  if (g_bonus_list.find(id) != g_bonus_list.end()){
    return g_bonus_list[id].size();
  }else{
    return 0;
  }
}

int id_to_rank(int id){
  int max_id=0;
  for (int i=0; i<g_world_size; i++){
    max_id += g_max_id / g_world_size;
    if (id < max_id){
      return i;
    }
  }
  return g_world_size-1;
}

void add_to_adjlist(std::string line){

  int tab_pos = line.find("\t");
  int one = atoi(line.substr(0, tab_pos).c_str());
  int two = atoi(line.substr(tab_pos+1).c_str());

  if (one >= start_id && one < end_id){
    g_adj_list[one].insert(two);
    if (two >= start_id && two < end_id){
      g_adj_list[two].insert(one);
    }else{
      g_bonus_list[two].insert(one);
    }
  }else{
    //std::cout << "adding to bonus list" << std::endl;
    g_bonus_list[one].insert(two);
    g_bonus_list[two].insert(one);
  }
}
<|endoftext|>


<commit_before>59a88c61-ad5a-11e7-8890-ac87a332f658<commit_msg>bug fix<commit_after>5a1d7611-ad5a-11e7-a798-ac87a332f658<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int level,pv,vel,exp_agg,exp,num,inum,lunghezza,nums;
unsigned int Pokemonum;
char a[100];
string Pokemon,Shiny,scheda,fisico=":fisico:",mosse_apprese,azione,lista_mosse_if,nome_pokemon,nome_pokemonm,typing,mossa[4],snum,nomefile_pv, nomefile_vel;
int main()
{
	printf("Benvenuto nel generatore schede di Bestfast!\nIniziamo!\n");
	// printf("Quanti Pokemon vuoi creare?");
	// cin>>snum;
	// for(int i=1;i<=inum;i++)
	// {
		do
		{
		printf("\nInserisci il numero Pokedex del Pokemon, guarda 'LISTA_POKEMON.txt' per la lista dei Pokemon: ");
		cin >> Pokemonum;
		}while(Pokemonum<=0 or Pokemonum>802);
		switch(Pokemonum)
			{
				case 1:
				nome_pokemon = "bulbasaur";
				nome_pokemonm = "Bulbasaur";
				typing=":erba: :veleno:";
				exp_agg = 2;
				break;

				case 2:
				nome_pokemon = "ivysaur";
				nome_pokemonm = "Ivysaur";
				typing=":erba: :veleno:";
				exp_agg = 2;
				break;

				case 3:
				nome_pokemon = "venusaur";
				nome_pokemonm = "Venusaur";
				typing=":erba: :veleno:";
				exp_agg=2;
				break;

				case 4:
				nome_pokemon = "charmander";
				nome_pokemonm = "Charmander";
				typing=":fuoco:";
				exp_agg=2;
				break;

				case 7:
				nome_pokemon = "squirtle";
				nome_pokemonm = "Squirtle";
				typing=":acqua:";
				exp_agg=2;
				break;

				default:
				printf("Non implementato\n");
				cin.get();
			}
			cout << "a";
			nomefile_pv = "Data//" + nome_pokemonm + "_pv.txt";
			nomefile_vel = "Data//" + nome_pokemonm + "_vel.txt";
			char *nome_file_pv = &nomefile_pv[0u];
			char *nome_file_vel = &nomefile_vel[0u];
			FILE *filepv, *filevel;
			filepv = fopen(nome_file_pv,"a+");
			rewind(filepv);
			fscanf(filepv,"%d",&pv);
			fclose(filepv);
			filevel = fopen(nome_file_vel,"a+");
			rewind(filevel);
			fscanf(filevel,"%d",&vel);
			fclose(filevel);
			cout<<"Hai scelto "<<nome_pokemonm<<"!\nIl Poke'mon e' shiny? Rispondi con 'Si' o 'No'\n";
			cin >> Shiny;
			if (Shiny == "Sì" or Shiny == "sì" or Shiny == "Si" or Shiny == "si")
			{
				cout<<"Ok, hai selezionato "<<nome_pokemonm<<" shiny!\n";
				Pokemon = "[IMG=https://play.pokemonshowdown.com/sprites/xyani-shiny/"+nome_pokemon+".gif]\n"+nome_pokemonm+""+typing+"\n";
			}
			if (Shiny == "No" or Shiny == "no")
			{
				cout<<"Ok, hai selezionato "<<nome_pokemonm<<" NON shiny!\n";
				Pokemon = "[IMG=https://play.pokemonshowdown.com/sprites/xyani/"+nome_pokemon+".gif]\n"+nome_pokemonm+""+typing+"\n";
			}
		do
		{
		    printf("Digita il livello del Pokemon!\n");
	 	    cin >> level;
		} while(level<=0 or level>100);
		vel = vel + level - 1;
		int pot_da_aggiungere;
		if (level >= 51)
		{
			pv = (49 * 3) + ((level - 50) * 5) + pv;
			pot_da_aggiungere = 49 + (level - 50) * 2;
		}
		else
		{
			pv = (level - 1) * 3 + pv;
			pot_da_aggiungere = level - 1;
		}
		int pot_azione = 4 + pot_da_aggiungere;
		printf("Vuoi vedere la lista delle mosse che puo' imparare questo Pokemon?\n");
		cin >>	 lista_mosse_if;
		if ((lista_mosse_if.compare("Sì") or lista_mosse_if.compare("sì") or lista_mosse_if.compare("Si") or lista_mosse_if.compare("si")) == 0)
		{
			switch(Pokemonum)
			{
				case 1:
				mosse_apprese = "Affannoseme\nAmnesia\nAttrazione\nAzione\nBullo\nCampo Erboso\nCapocciata\nConfidenza\nCoro\nCrescita\nCuordileone\nDanzaspada\nDoppioteam\nEccheggiavoce\nEnergipalla\nErbapatto\nFacciata\nFango\nFangobomba\nFascino\nFogliamagica\nFoglielama\nFrustata\nFrustazione\nGigassorbimento\nGiornodisole\nIntroforza\nLaccioerboso\nLegatutto\nMaledizione\nMeloderba\nNaturforza\nPetalodanza\nPrivazione\nProfumino\nProtezione\nRadicamento\nResistenza\nRiduttore\nRiposo\nRitorno\nRuggito\nRussare\nSalvaguardia\nSchermoluce\nSdoppiatore\nSemebomba\nSintesi\nSolarraggio\nSonnifero\nSonnolalia\nSostituto\nTossina\nVelenoshock\nVelenpolvere\nVerdebufera\nVigorcolpo";
				break;

				case 2:
				mosse_apprese = "Affannoseme\nAmnesia\nAttrazione\nAzione\nBullo\nCampo Erboso\nCapocciata\nConfidenza\nCoro\nCrescita\nCuordileone\nDanzaspada\nDoppioteam\nEccheggiavoce\nEnergipalla\nErbapatto\nFacciata\nFango\nFangobomba\nFascino\nFogliamagica\nFoglielama\nFrustata\nFrustazione\nGigassorbimento\nGiornodisole\nIntroforza\nLaccioerboso\nLegatutto\nMaledizione\nMeloderba\nNaturforza\nPetalodanza\nPrivazione\nProfumino\nProtezione\nRadicamento\nResistenza\nRiduttore\nRiposo\nRitorno\nRuggito\nRussare\nSalvaguardia\nSchermoluce\nSdoppiatore\nSemebomba\nSintesi\nSolarraggio\nSonnifero\nSonnolalia\nSostituto\nTossina\nVelenoshock\nVelenpolvere\nVerdebufera\nVigorcolpo";
				break;

				case 3:
				mosse_apprese = "Affannoseme\nAmnesia\nAttrazione\nAzione\nBullo\nCampo Erboso\nCapocciata\nConfidenza\nCoro\nCrescita\nCuordileone\nDanzaspada\nDoppioteam\nEccheggiavoce\nEnergipalla\nErbapatto\nFacciata\nFango\nFangobomba\nFascino\nFogliamagica\nFoglielama\nFrustata\nFrustazione\nGigassorbimento\nGiornodisole\nIntroforza\nLaccioerboso\nLegatutto\nMaledizione\nMeloderba\nNaturforza\nPetalodanza\nPrivazione\nProfumino\nProtezione\nRadicamento\nResistenza\nRiduttore\nRiposo\nRitorno\nRuggito\nRussare\nSalvaguardia\nSchermoluce\nSdoppiatore\nSemebomba\nSintesi\nSolarraggio\nSonnifero\nSonnolalia\nSostituto\nTossina\nVelenoshock\nVelenpolvere\nVerdebufera\nVigorcolpo";
				break;

				case 4:
				mosse_apprese= "Graffio\nRuggito\nBraciere\nMuro di Fumo\nIra di Drago\nVisotruce\nRogodenti\nPirolancio\nLacerazione\nLanciafiamme\nTurbofuoco\nMarchiatura";
				break;

				case 7:
				mosse_apprese= "Azione\nColpocoda\nPistolacqua\nRitirata\nBolla\nMorso\nRapigiro\nProtezione\nIdropulsar\nIdrondata\nCapocciata\nFerroscudo\nPioggiadanza\nIdropompa";
				break;
			}
			cout << nome_pokemon << " puo' imparare queste mosse:\n" << mosse_apprese << "\n";
		}
		printf("Inserisci la mossa numero 1\n");
	 	cin>>mossa[0];
	 	printf("Inserisci la mossa numero 2\n");
	 	cin>>mossa[1];
	 	printf("Inserisci la mossa numero 3\n");
	 	cin>>mossa[2];
	 	printf("Inserisci la mossa numero 4\n");
	 	cin>>mossa[3];
	 	exp = exp_agg * level;
	 	FILE * fp;
	 	fp = fopen("num.txt","a+");
		fclose(fp);
		ofstream ofs;
		ifstream ifs;
		ifs.open("num.txt", ios::binary);
		ifs.seekg(0, ios::end);
		lunghezza = ifs.tellg();
		ifs.close();
		if (lunghezza == 0)
		{
			fp = fopen("num.txt","a+");
			nums = 1;
			fprintf(fp,"%d", nums);
			fclose(fp);
		}
		else
		{
			fp = fopen("num.txt","a+");
			rewind(fp);
			fscanf(fp,"%s",a);
			fclose(fp);
			ofs.open("num.txt");
			nums = std::stoi(a);
			nums++;
			ofs.close();
			ofs.open("num.txt",ios::trunc);
			fprintf(fp, "%d", nums);
			ofs.close();
    	}

	 	scheda = "Scheda numero " + to_string(nums) + ":\n\n\n" +  Pokemon + "Lv: " + to_string(level) + "\n" + "Pv: " + to_string(pv) + "\n" + "Vel " + to_string(vel) + "\n" + mossa[0] + "\n" + mossa[1] + "\n" + mossa[2] + "\n" + mossa[3] + "\n" + "EXP: 0/" + to_string(exp) + "\n\n\n";
	 	FILE * schedaF;
	 	schedaF = fopen("Scheda.txt", "a+");
		fputs(scheda.c_str(), schedaF);
		fclose(schedaF);
	printf("Ben fatto! Trovi la scheda nel file 'Scheda.txt', il numero della scheda è %d.\n", nums);
	cin.get();
 }
<commit_msg>Sistemato i link delle gif e rimosse alcune variabili inutilizzate<commit_after>#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int level,pv,vel,exp_agg,exp,num,inum,lunghezza,nums;
unsigned int Pokemonum;
char a[100];
string Pokemon,Shiny,scheda,fisico=":fisico:",mosse_apprese,azione,lista_mosse_if,nome_pokemonm,typing,mossa[4],snum,nomefile_pv, nomefile_vel;
int main()
{
	printf("Benvenuto nel generatore schede di Bestfast!\nIniziamo!\n");
	// printf("Quanti Pokemon vuoi creare?");
	// cin>>snum;
	// for(int i=1;i<=inum;i++)
	// {
		do
		{
		printf("\nInserisci il numero Pokedex del Pokemon, guarda 'LISTA_POKEMON.txt' per la lista dei Pokemon: ");
		cin >> Pokemonum;
		}while(Pokemonum<=0 or Pokemonum>802);
		switch(Pokemonum)
			{
				case 1:
				nome_pokemonm = "Bulbasaur";
				typing=":erba: :veleno:";
				exp_agg = 2;
				break;

				case 2:
				nome_pokemonm = "Ivysaur";
				typing=":erba: :veleno:";
				exp_agg = 2;
				break;

				case 3:
				nome_pokemonm = "Venusaur";
				typing=":erba: :veleno:";
				exp_agg=2;
				break;

				case 4:
				nome_pokemonm = "Charmander";
				typing=":fuoco:";
				exp_agg=2;
				break;

				case 7:
				nome_pokemonm = "Squirtle";
				typing=":acqua:";
				exp_agg=2;
				break;

				default:
				printf("Non implementato\n");
				cin.get();
			}
			cout << "a";
			nomefile_pv = "Data//" + nome_pokemonm + "_pv.txt";
			nomefile_vel = "Data//" + nome_pokemonm + "_vel.txt";
			char *nome_file_pv = &nomefile_pv[0u];
			char *nome_file_vel = &nomefile_vel[0u];
			FILE *filepv, *filevel;
			filepv = fopen(nome_file_pv,"a+");
			rewind(filepv);
			fscanf(filepv,"%d",&pv);
			fclose(filepv);
			filevel = fopen(nome_file_vel,"a+");
			rewind(filevel);
			fscanf(filevel,"%d",&vel);
			fclose(filevel);
			cout<<"Hai scelto "<<nome_pokemonm<<"!\nIl Pokemon e' shiny? Rispondi con 'Si' o 'No'\n";
			cin >> Shiny;
			if (Shiny == "Sì" or Shiny == "sì" or Shiny == "Si" or Shiny == "si")
			{
				cout<<"Ok, hai selezionato "<<nome_pokemonm<<" shiny!\n";
				Pokemon = "[IMG=https://raw.githubusercontent.com/Bestfast/sprites_pkmn/master/sprites_shiny/"+nome_pokemonm+".gif]\n"+nome_pokemonm+""+typing+"\n";
			}
			if (Shiny == "No" or Shiny == "no")
			{
				cout<<"Ok, hai selezionato "<<nome_pokemonm<<" NON shiny!\n";
				Pokemon = "[IMG=https://raw.githubusercontent.com/Bestfast/sprites_pkmn/master/sprites/"+nome_pokemonm+".gif]\n"+nome_pokemonm+""+typing+"\n";
			}
		do
		{
		    printf("Digita il livello del Pokemon!\n");
	 	    cin >> level;
		} while(level<=0 or level>100);
		vel = vel + level - 1;
		int pot_da_aggiungere;
		if (level >= 51)
		{
			pv = (49 * 3) + ((level - 50) * 5) + pv;
			pot_da_aggiungere = 49 + (level - 50) * 2;
		}
		else
		{
			pv = (level - 1) * 3 + pv;
			pot_da_aggiungere = level - 1;
		}
		int pot_azione = 4 + pot_da_aggiungere;
		printf("Vuoi vedere la lista delle mosse che puo' imparare questo Pokemon?\n");
		cin >>	 lista_mosse_if;
		if ((lista_mosse_if.compare("Sì") or lista_mosse_if.compare("sì") or lista_mosse_if.compare("Si") or lista_mosse_if.compare("si")) == 0)
		{
			switch(Pokemonum)
			{
				case 1:
				mosse_apprese = "Affannoseme\nAmnesia\nAttrazione\nAzione\nBullo\nCampo Erboso\nCapocciata\nConfidenza\nCoro\nCrescita\nCuordileone\nDanzaspada\nDoppioteam\nEccheggiavoce\nEnergipalla\nErbapatto\nFacciata\nFango\nFangobomba\nFascino\nFogliamagica\nFoglielama\nFrustata\nFrustazione\nGigassorbimento\nGiornodisole\nIntroforza\nLaccioerboso\nLegatutto\nMaledizione\nMeloderba\nNaturforza\nPetalodanza\nPrivazione\nProfumino\nProtezione\nRadicamento\nResistenza\nRiduttore\nRiposo\nRitorno\nRuggito\nRussare\nSalvaguardia\nSchermoluce\nSdoppiatore\nSemebomba\nSintesi\nSolarraggio\nSonnifero\nSonnolalia\nSostituto\nTossina\nVelenoshock\nVelenpolvere\nVerdebufera\nVigorcolpo";
				break;

				case 2:
				mosse_apprese = "Affannoseme\nAmnesia\nAttrazione\nAzione\nBullo\nCampo Erboso\nCapocciata\nConfidenza\nCoro\nCrescita\nCuordileone\nDanzaspada\nDoppioteam\nEccheggiavoce\nEnergipalla\nErbapatto\nFacciata\nFango\nFangobomba\nFascino\nFogliamagica\nFoglielama\nFrustata\nFrustazione\nGigassorbimento\nGiornodisole\nIntroforza\nLaccioerboso\nLegatutto\nMaledizione\nMeloderba\nNaturforza\nPetalodanza\nPrivazione\nProfumino\nProtezione\nRadicamento\nResistenza\nRiduttore\nRiposo\nRitorno\nRuggito\nRussare\nSalvaguardia\nSchermoluce\nSdoppiatore\nSemebomba\nSintesi\nSolarraggio\nSonnifero\nSonnolalia\nSostituto\nTossina\nVelenoshock\nVelenpolvere\nVerdebufera\nVigorcolpo";
				break;

				case 3:
				mosse_apprese = "Affannoseme\nAmnesia\nAttrazione\nAzione\nBullo\nCampo Erboso\nCapocciata\nConfidenza\nCoro\nCrescita\nCuordileone\nDanzaspada\nDoppioteam\nEccheggiavoce\nEnergipalla\nErbapatto\nFacciata\nFango\nFangobomba\nFascino\nFogliamagica\nFoglielama\nFrustata\nFrustazione\nGigassorbimento\nGiornodisole\nIntroforza\nLaccioerboso\nLegatutto\nMaledizione\nMeloderba\nNaturforza\nPetalodanza\nPrivazione\nProfumino\nProtezione\nRadicamento\nResistenza\nRiduttore\nRiposo\nRitorno\nRuggito\nRussare\nSalvaguardia\nSchermoluce\nSdoppiatore\nSemebomba\nSintesi\nSolarraggio\nSonnifero\nSonnolalia\nSostituto\nTossina\nVelenoshock\nVelenpolvere\nVerdebufera\nVigorcolpo";
				break;

				case 4:
				mosse_apprese= "Graffio\nRuggito\nBraciere\nMuro di Fumo\nIra di Drago\nVisotruce\nRogodenti\nPirolancio\nLacerazione\nLanciafiamme\nTurbofuoco\nMarchiatura";
				break;

				case 7:
				mosse_apprese= "Azione\nColpocoda\nPistolacqua\nRitirata\nBolla\nMorso\nRapigiro\nProtezione\nIdropulsar\nIdrondata\nCapocciata\nFerroscudo\nPioggiadanza\nIdropompa";
				break;
			}
			cout << nome_pokemon << " puo' imparare queste mosse:\n" << mosse_apprese << "\n";
		}
		printf("Inserisci la mossa numero 1\n");
	 	cin>>mossa[0];
	 	printf("Inserisci la mossa numero 2\n");
	 	cin>>mossa[1];
	 	printf("Inserisci la mossa numero 3\n");
	 	cin>>mossa[2];
	 	printf("Inserisci la mossa numero 4\n");
	 	cin>>mossa[3];
	 	exp = exp_agg * level;
	 	FILE * fp;
	 	fp = fopen("num.txt","a+");
		fclose(fp);
		ofstream ofs;
		ifstream ifs;
		ifs.open("num.txt", ios::binary);
		ifs.seekg(0, ios::end);
		lunghezza = ifs.tellg();
		ifs.close();
		if (lunghezza == 0)
		{
			fp = fopen("num.txt","a+");
			nums = 1;
			fprintf(fp,"%d", nums);
			fclose(fp);
		}
		else
		{
			fp = fopen("num.txt","a+");
			rewind(fp);
			fscanf(fp,"%s",a);
			fclose(fp);
			ofs.open("num.txt");
			nums = std::stoi(a);
			nums++;
			ofs.close();
			ofs.open("num.txt",ios::trunc);
			fprintf(fp, "%d", nums);
			ofs.close();
    	}

	 	scheda = "Scheda numero " + to_string(nums) + ":\n\n\n" +  Pokemon + "Lv: " + to_string(level) + "\n" + "Pv: " + to_string(pv) + "\n" + "Vel " + to_string(vel) + "\n" + mossa[0] + "\n" + mossa[1] + "\n" + mossa[2] + "\n" + mossa[3] + "\n" + "EXP: 0/" + to_string(exp) + "\n\n\n";
	 	FILE * schedaF;
	 	schedaF = fopen("Scheda.txt", "a+");
		fputs(scheda.c_str(), schedaF);
		fclose(schedaF);
	printf("Ben fatto! Trovi la scheda nel file 'Scheda.txt', il numero della scheda è %d.\n", nums);
	cin.get();
 }
<|endoftext|>


<commit_before>db76a7d7-4b02-11e5-9a00-28cfe9171a43<commit_msg>bobby added more bugs<commit_after>db86dc1e-4b02-11e5-8341-28cfe9171a43<|endoftext|>


<commit_before>#include <QWidget>
#include <QApplication>
#include <QDebug>
#include <QGamepadManager>
#include <QGamepad>
#include <QtEndian>
#include <QUdpSocket>
#include <QTimer>
#include <QFormLayout>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QCheckBox>
#include <QDialog>
#include <QMouseEvent>
#include <QCloseEvent>

#include <algorithm>
#include <cmath>

#define CPAD_BOUND          0x5d0
#define CPP_BOUND           0x7f

#define TOUCH_SCREEN_WIDTH  320
#define TOUCH_SCREEN_HEIGHT 240

typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;

double lx = 0.0, ly = 0.0;
double rx = 0.0, ry = 0.0;
QGamepadManager::GamepadButtons buttons = 0;
u32 specialButtons = 0;
QString ipAddress;
int yAxisMultiplier = 1;

bool touchScreenPressed;
QPoint touchScreenPosition;

void sendFrame(void)
{
    static const QGamepadManager::GamepadButton hidButtons[] = {
        QGamepadManager::ButtonA,
        QGamepadManager::ButtonB,
        QGamepadManager::ButtonSelect,
        QGamepadManager::ButtonStart,
        QGamepadManager::ButtonRight,
        QGamepadManager::ButtonLeft,
        QGamepadManager::ButtonUp,
        QGamepadManager::ButtonDown,
        QGamepadManager::ButtonR1,
        QGamepadManager::ButtonL1,
        QGamepadManager::ButtonX,
        QGamepadManager::ButtonY,
    };

    static const QGamepadManager::GamepadButton irButtons[] = {
        QGamepadManager::ButtonR2,
        QGamepadManager::ButtonL2,
    };

    u32 hidPad = 0xfff;
    for(u32 i = 0; i < 12; i++)
    {
        if(buttons & (1 << hidButtons[i]))
            hidPad &= ~(1 << i);
    }

    u32 irButtonsState = 0;
    for(u32 i = 0; i < 2; i++)
    {
        if(buttons & (1 << irButtons[i]))
            hidPad |= 1 << (i + 1);
    }

    specialButtons |= (buttons & (1 << QGamepadManager::ButtonGuide)) ? 1 : 0;

    u32 touchScreenState = 0x2000000;
    u32 circlePadState = 0x7ff7ff;
    u32 cppState = 0x80800081;

    if(lx != 0.0 || ly != 0.0)
    {
        u32 x = (u32)(lx * CPAD_BOUND + 0x800);
        u32 y = (u32)(ly * CPAD_BOUND + 0x800);
        x = x >= 0xfff ? 0xfff : x;
        y = y >= 0xfff ? 0xfff : y;

        circlePadState = (y << 12) | x;
    }

    if(rx != 0.0 || ry != 0.0 || irButtonsState != 0)
    {
        // We have to rotate the c-stick position 45°. Thanks, Nintendo.
        u32 x = (u32)(M_SQRT1_2 * (rx + ry) * CPP_BOUND + 0x80);
        u32 y = (u32)(M_SQRT1_2 * (ry - rx) * CPP_BOUND + 0x80);
        x = x >= 0xff ? 0xff : x;
        y = y >= 0xff ? 0xff : y;

        cppState = (y << 24) | (x << 16) | (irButtonsState << 8) | 0x81;
    }

    if(touchScreenPressed)
    {
        u32 x = (u32)(0xfff * std::min(std::max(0, touchScreenPosition.x()), TOUCH_SCREEN_WIDTH)) / TOUCH_SCREEN_WIDTH;
        u32 y = (u32)(0xfff * std::min(std::max(0, touchScreenPosition.y()), TOUCH_SCREEN_HEIGHT)) / TOUCH_SCREEN_HEIGHT;
        touchScreenState = (1 << 24) | (y << 12) | x;
    }

    QByteArray ba(20, 0);
    qToLittleEndian(hidPad, (uchar *)ba.data());
    qToLittleEndian(touchScreenState, (uchar *)ba.data() + 4);
    qToLittleEndian(circlePadState, (uchar *)ba.data() + 8);
    qToLittleEndian(cppState, (uchar *)ba.data() + 12);
    qToLittleEndian(specialButtons, (uchar *)ba.data() + 16);
    QUdpSocket().writeDatagram(ba, QHostAddress(ipAddress), 4950);
}

struct GamepadMonitor : public QObject {

    GamepadMonitor(QObject *parent = nullptr) : QObject(parent)
    {
        connect(QGamepadManager::instance(), &QGamepadManager::gamepadButtonPressEvent, this,
            [](int deviceId, QGamepadManager::GamepadButton button, double value)
        {
            (void)deviceId;
            (void)value;
            buttons |= QGamepadManager::GamepadButtons(1 << button);
            sendFrame();
        });

        connect(QGamepadManager::instance(), &QGamepadManager::gamepadButtonReleaseEvent, this,
            [](int deviceId, QGamepadManager::GamepadButton button)
        {
            (void)deviceId;
            buttons &= QGamepadManager::GamepadButtons(~(1 << button));
            sendFrame();
        });
        connect(QGamepadManager::instance(), &QGamepadManager::gamepadAxisEvent, this,
            [](int deviceId, QGamepadManager::GamepadAxis axis, double value)
        {
            (void)deviceId;
            (void)value;
            switch(axis)
            {
                case QGamepadManager::AxisLeftX:
                    lx = value;
                    break;
                case QGamepadManager::AxisLeftY:
                    ly = yAxisMultiplier * -value; // for some reason qt inverts this
                    break;

                case QGamepadManager::AxisRightX:
                    rx = value;
                    break;
                case QGamepadManager::AxisRightY:
                    ry = yAxisMultiplier * -value; // for some reason qt inverts this
                    break;
                    default: break;
            }
            sendFrame();
        });
    }
};

struct TouchScreen : public QDialog {
    TouchScreen(QWidget *parent = nullptr) : QDialog(parent)
    {
        this->setFixedSize(TOUCH_SCREEN_WIDTH, TOUCH_SCREEN_HEIGHT);
        this->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
        this->setWindowTitle(tr("InputRedirectionClient-Qt - Touch screen"));
    }

    void mousePressEvent(QMouseEvent *ev)
    {
        if(ev->button() == Qt::LeftButton)
        {
            touchScreenPressed = true;
            touchScreenPosition = ev->pos();
            sendFrame();
        }
    }

    void mouseMoveEvent(QMouseEvent *ev)
    {
        if(touchScreenPressed && (ev->buttons() & Qt::LeftButton))
        {
            touchScreenPosition = ev->pos();
            sendFrame();
        }
    }

    void mouseReleaseEvent(QMouseEvent *ev)
    {
        if(ev->button() == Qt::LeftButton)
        {
            touchScreenPressed = false;
            sendFrame();
        }
    }
};

struct FrameTimer : public QTimer {
    FrameTimer(QObject *parent = nullptr) : QTimer(parent)
    {
        connect(this, &QTimer::timeout, this,
                [](void)
        {
            sendFrame();
        });
    }
};

class Widget : public QWidget
{
private:
    QVBoxLayout *layout;
    QFormLayout *formLayout;
    QLineEdit *addrLineEdit;
    QCheckBox *invertYCheckbox;
    QPushButton *homeButton, *powerButton, *longPowerButton;
    TouchScreen *touchScreen;
public:
    Widget(QWidget *parent = nullptr) : QWidget(parent)
    {
        layout = new QVBoxLayout(this);

        addrLineEdit = new QLineEdit(this);
        invertYCheckbox = new QCheckBox(this);
        formLayout = new QFormLayout;

        formLayout->addRow(tr("IP &address"), addrLineEdit);
        formLayout->addRow(tr("&Invert Y axis"), invertYCheckbox);

        homeButton = new QPushButton(tr("&HOME"), this);
        powerButton = new QPushButton(tr("&POWER"), this);
        longPowerButton = new QPushButton(tr("POWER (&long)"), this);

        layout->addLayout(formLayout);
        layout->addWidget(homeButton);
        layout->addWidget(powerButton);
        layout->addWidget(longPowerButton);

        connect(addrLineEdit, &QLineEdit::textChanged, this,
                [](const QString &text)
        {
            ipAddress = text;
        });

        connect(invertYCheckbox, &QCheckBox::stateChanged, this,
                [](int state)
        {
            switch(state)
            {
                case Qt::Unchecked:
                    yAxisMultiplier = 1;
                    break;
                case Qt::Checked:
                    yAxisMultiplier = -1;
                    break;
                default: break;
            }
        });

        connect(homeButton, &QPushButton::pressed, this,
                [](void)
        {
           specialButtons |= 1;
           sendFrame();
        });

        connect(homeButton, &QPushButton::released, this,
                [](void)
        {
           specialButtons &= ~1;
           sendFrame();
        });

        connect(powerButton, &QPushButton::pressed, this,
                [](void)
        {
           specialButtons |= 2;
           sendFrame();
        });

        connect(powerButton, &QPushButton::released, this,
                [](void)
        {
           specialButtons &= ~2;
           sendFrame();
        });

        connect(longPowerButton, &QPushButton::pressed, this,
                [](void)
        {
           specialButtons |= 4;
           sendFrame();
        });

        connect(longPowerButton, &QPushButton::released, this,
                [](void)
        {
           specialButtons &= ~4;
           sendFrame();
        });

        touchScreen = new TouchScreen(nullptr);
        this->setWindowTitle(tr("InputRedirectionClient-Qt"));
    }

    void show(void)
    {
        QWidget::show();
        touchScreen->show();
    }

    void closeEvent(QCloseEvent *ev)
    {
        touchScreen->close();
        ev->accept();
    }

    virtual ~Widget(void)
    {
        delete touchScreen;
    }

};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    GamepadMonitor m(&w);
    FrameTimer t(&w);
    TouchScreen ts;
    t.start(50);
    w.show();

    return a.exec();
}
<commit_msg>Oops ( ͡° ͜ʖ ͡°)<commit_after>#include <QWidget>
#include <QApplication>
#include <QDebug>
#include <QGamepadManager>
#include <QGamepad>
#include <QtEndian>
#include <QUdpSocket>
#include <QTimer>
#include <QFormLayout>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QCheckBox>
#include <QDialog>
#include <QMouseEvent>
#include <QCloseEvent>

#include <algorithm>
#include <cmath>

#define CPAD_BOUND          0x5d0
#define CPP_BOUND           0x7f

#define TOUCH_SCREEN_WIDTH  320
#define TOUCH_SCREEN_HEIGHT 240

typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;

double lx = 0.0, ly = 0.0;
double rx = 0.0, ry = 0.0;
QGamepadManager::GamepadButtons buttons = 0;
u32 specialButtons = 0;
QString ipAddress;
int yAxisMultiplier = 1;

bool touchScreenPressed;
QPoint touchScreenPosition;

void sendFrame(void)
{
    static const QGamepadManager::GamepadButton hidButtons[] = {
        QGamepadManager::ButtonA,
        QGamepadManager::ButtonB,
        QGamepadManager::ButtonSelect,
        QGamepadManager::ButtonStart,
        QGamepadManager::ButtonRight,
        QGamepadManager::ButtonLeft,
        QGamepadManager::ButtonUp,
        QGamepadManager::ButtonDown,
        QGamepadManager::ButtonR1,
        QGamepadManager::ButtonL1,
        QGamepadManager::ButtonX,
        QGamepadManager::ButtonY,
    };

    static const QGamepadManager::GamepadButton irButtons[] = {
        QGamepadManager::ButtonR2,
        QGamepadManager::ButtonL2,
    };

    u32 hidPad = 0xfff;
    for(u32 i = 0; i < 12; i++)
    {
        if(buttons & (1 << hidButtons[i]))
            hidPad &= ~(1 << i);
    }

    u32 irButtonsState = 0;
    for(u32 i = 0; i < 2; i++)
    {
        if(buttons & (1 << irButtons[i]))
            irButtonsState |= 1 << (i + 1);
    }

    specialButtons |= (buttons & (1 << QGamepadManager::ButtonGuide)) ? 1 : 0;

    u32 touchScreenState = 0x2000000;
    u32 circlePadState = 0x7ff7ff;
    u32 cppState = 0x80800081;

    if(lx != 0.0 || ly != 0.0)
    {
        u32 x = (u32)(lx * CPAD_BOUND + 0x800);
        u32 y = (u32)(ly * CPAD_BOUND + 0x800);
        x = x >= 0xfff ? 0xfff : x;
        y = y >= 0xfff ? 0xfff : y;

        circlePadState = (y << 12) | x;
    }

    if(rx != 0.0 || ry != 0.0 || irButtonsState != 0)
    {
        // We have to rotate the c-stick position 45°. Thanks, Nintendo.
        u32 x = (u32)(M_SQRT1_2 * (rx + ry) * CPP_BOUND + 0x80);
        u32 y = (u32)(M_SQRT1_2 * (ry - rx) * CPP_BOUND + 0x80);
        x = x >= 0xff ? 0xff : x;
        y = y >= 0xff ? 0xff : y;

        cppState = (y << 24) | (x << 16) | (irButtonsState << 8) | 0x81;
    }

    if(touchScreenPressed)
    {
        u32 x = (u32)(0xfff * std::min(std::max(0, touchScreenPosition.x()), TOUCH_SCREEN_WIDTH)) / TOUCH_SCREEN_WIDTH;
        u32 y = (u32)(0xfff * std::min(std::max(0, touchScreenPosition.y()), TOUCH_SCREEN_HEIGHT)) / TOUCH_SCREEN_HEIGHT;
        touchScreenState = (1 << 24) | (y << 12) | x;
    }

    QByteArray ba(20, 0);
    qToLittleEndian(hidPad, (uchar *)ba.data());
    qToLittleEndian(touchScreenState, (uchar *)ba.data() + 4);
    qToLittleEndian(circlePadState, (uchar *)ba.data() + 8);
    qToLittleEndian(cppState, (uchar *)ba.data() + 12);
    qToLittleEndian(specialButtons, (uchar *)ba.data() + 16);
    QUdpSocket().writeDatagram(ba, QHostAddress(ipAddress), 4950);
}

struct GamepadMonitor : public QObject {

    GamepadMonitor(QObject *parent = nullptr) : QObject(parent)
    {
        connect(QGamepadManager::instance(), &QGamepadManager::gamepadButtonPressEvent, this,
            [](int deviceId, QGamepadManager::GamepadButton button, double value)
        {
            (void)deviceId;
            (void)value;
            buttons |= QGamepadManager::GamepadButtons(1 << button);
            sendFrame();
        });

        connect(QGamepadManager::instance(), &QGamepadManager::gamepadButtonReleaseEvent, this,
            [](int deviceId, QGamepadManager::GamepadButton button)
        {
            (void)deviceId;
            buttons &= QGamepadManager::GamepadButtons(~(1 << button));
            sendFrame();
        });
        connect(QGamepadManager::instance(), &QGamepadManager::gamepadAxisEvent, this,
            [](int deviceId, QGamepadManager::GamepadAxis axis, double value)
        {
            (void)deviceId;
            (void)value;
            switch(axis)
            {
                case QGamepadManager::AxisLeftX:
                    lx = value;
                    break;
                case QGamepadManager::AxisLeftY:
                    ly = yAxisMultiplier * -value; // for some reason qt inverts this
                    break;

                case QGamepadManager::AxisRightX:
                    rx = value;
                    break;
                case QGamepadManager::AxisRightY:
                    ry = yAxisMultiplier * -value; // for some reason qt inverts this
                    break;
                    default: break;
            }
            sendFrame();
        });
    }
};

struct TouchScreen : public QDialog {
    TouchScreen(QWidget *parent = nullptr) : QDialog(parent)
    {
        this->setFixedSize(TOUCH_SCREEN_WIDTH, TOUCH_SCREEN_HEIGHT);
        this->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
        this->setWindowTitle(tr("InputRedirectionClient-Qt - Touch screen"));
    }

    void mousePressEvent(QMouseEvent *ev)
    {
        if(ev->button() == Qt::LeftButton)
        {
            touchScreenPressed = true;
            touchScreenPosition = ev->pos();
            sendFrame();
        }
    }

    void mouseMoveEvent(QMouseEvent *ev)
    {
        if(touchScreenPressed && (ev->buttons() & Qt::LeftButton))
        {
            touchScreenPosition = ev->pos();
            sendFrame();
        }
    }

    void mouseReleaseEvent(QMouseEvent *ev)
    {
        if(ev->button() == Qt::LeftButton)
        {
            touchScreenPressed = false;
            sendFrame();
        }
    }
};

struct FrameTimer : public QTimer {
    FrameTimer(QObject *parent = nullptr) : QTimer(parent)
    {
        connect(this, &QTimer::timeout, this,
                [](void)
        {
            sendFrame();
        });
    }
};

class Widget : public QWidget
{
private:
    QVBoxLayout *layout;
    QFormLayout *formLayout;
    QLineEdit *addrLineEdit;
    QCheckBox *invertYCheckbox;
    QPushButton *homeButton, *powerButton, *longPowerButton;
    TouchScreen *touchScreen;
public:
    Widget(QWidget *parent = nullptr) : QWidget(parent)
    {
        layout = new QVBoxLayout(this);

        addrLineEdit = new QLineEdit(this);
        invertYCheckbox = new QCheckBox(this);
        formLayout = new QFormLayout;

        formLayout->addRow(tr("IP &address"), addrLineEdit);
        formLayout->addRow(tr("&Invert Y axis"), invertYCheckbox);

        homeButton = new QPushButton(tr("&HOME"), this);
        powerButton = new QPushButton(tr("&POWER"), this);
        longPowerButton = new QPushButton(tr("POWER (&long)"), this);

        layout->addLayout(formLayout);
        layout->addWidget(homeButton);
        layout->addWidget(powerButton);
        layout->addWidget(longPowerButton);

        connect(addrLineEdit, &QLineEdit::textChanged, this,
                [](const QString &text)
        {
            ipAddress = text;
        });

        connect(invertYCheckbox, &QCheckBox::stateChanged, this,
                [](int state)
        {
            switch(state)
            {
                case Qt::Unchecked:
                    yAxisMultiplier = 1;
                    break;
                case Qt::Checked:
                    yAxisMultiplier = -1;
                    break;
                default: break;
            }
        });

        connect(homeButton, &QPushButton::pressed, this,
                [](void)
        {
           specialButtons |= 1;
           sendFrame();
        });

        connect(homeButton, &QPushButton::released, this,
                [](void)
        {
           specialButtons &= ~1;
           sendFrame();
        });

        connect(powerButton, &QPushButton::pressed, this,
                [](void)
        {
           specialButtons |= 2;
           sendFrame();
        });

        connect(powerButton, &QPushButton::released, this,
                [](void)
        {
           specialButtons &= ~2;
           sendFrame();
        });

        connect(longPowerButton, &QPushButton::pressed, this,
                [](void)
        {
           specialButtons |= 4;
           sendFrame();
        });

        connect(longPowerButton, &QPushButton::released, this,
                [](void)
        {
           specialButtons &= ~4;
           sendFrame();
        });

        touchScreen = new TouchScreen(nullptr);
        this->setWindowTitle(tr("InputRedirectionClient-Qt"));
    }

    void show(void)
    {
        QWidget::show();
        touchScreen->show();
    }

    void closeEvent(QCloseEvent *ev)
    {
        touchScreen->close();
        ev->accept();
    }

    virtual ~Widget(void)
    {
        delete touchScreen;
    }

};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    GamepadMonitor m(&w);
    FrameTimer t(&w);
    TouchScreen ts;
    t.start(50);
    w.show();

    return a.exec();
}
<|endoftext|>


<commit_before>//c and posix
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>

//c++
#include <string>
#include <fstream>
#include <iostream>
#include <unordered_map>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <future>

namespace cnc
{
    class ThreadPool
    {
    public:
        ThreadPool(size_t);

        template<class F, class... Args>
        auto enqueue(F &&f, Args &&... args) -> std::future<typename std::result_of<F(Args...)>::type>;

        ~ThreadPool();

    private:
        // need to keep track of threads so we can join them
        std::vector<std::thread> workers;
        // the task queue
        std::queue<std::function<void()>> tasks;

        // synchronization
        std::mutex queue_mutex;
        std::condition_variable condition;
        bool stop;
    };

    // the constructor just launches some amount of workers
    inline ThreadPool::ThreadPool(size_t threads)
            : stop(false)
    {
        for (size_t i = 0; i < threads; ++i)
            workers.emplace_back(
                    [this]
                    {
                        for (; ;)
                        {
                            std::function<void()> task;

                            {
                                std::unique_lock<std::mutex> lock(this->queue_mutex);
                                this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                                if (this->stop && this->tasks.empty())
                                    return;
                                task = std::move(this->tasks.front());
                                this->tasks.pop();
                            }

                            task();
                        }
                    }
            );
    }

    // add new work item to the pool
    template<class F, class... Args>
    auto ThreadPool::enqueue(F &&f, Args &&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
        using return_type = typename std::result_of<F(Args...)>::type;

        auto task = std::make_shared<std::packaged_task<return_type()>>
        (
                std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );

        std::future<return_type> res = task->get_future();
        {
            std::unique_lock<std::mutex> lock(queue_mutex);

            // don't allow enqueueing after stopping the pool
            if (stop)
                throw std::runtime_error("enqueue on stopped ThreadPool");

            tasks.emplace([task]() { (*task)(); });
        }
        condition.notify_one();
        return res;
    }

    // the destructor joins all threads
    inline ThreadPool::~ThreadPool()
    {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            stop = true;
        }
        condition.notify_all();
        for (auto& worker: workers) worker.join();
    }

    template<typename Socket>
    void send_file(std::string const &filename, Socket const &socket)
    {
        std::ifstream ifs{filename};
        for (std::string str; ifs >> str;)
        {
            auto msg = str + "\r\n";
            send(socket, msg.c_str(), msg.size(), 0);
        }
    }

    template <typename StatusCode>
    auto make_reply_header(StatusCode code) -> std::string
    {
        const static std::unordered_map<StatusCode, std::string> status
                {
                        {200, "200 OK"},
                        {404, "404 Not Found"},
                        {501, "501 Not Implemented"}
                };

        return status.at(code);
    }

}// end of namespace ccur

int main()
{
    auto const PORT = 3490;
    struct sockaddr_in addr;

    // Construct address information
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = INADDR_ANY;
    memset( addr.sin_zero, '\0', sizeof(addr.sin_zero) );

    // Create a socket and bind it the port PORT
    auto const soc = socket(PF_INET,SOCK_STREAM, 0);
    bind(soc, (struct sockaddr *)&addr, sizeof(addr));
    printf("%d", addr.sin_port);

    // Allow up to 10 incoming connections
    auto const limit = 10;
    listen(soc,limit);
    std::cout << "listenning\n";

    auto const header = cnc::make_reply_header(200);
    for(cnc::ThreadPool pool{ limit }; true;)
    {
        auto request_handler = [&] (int socket){
            char data[512];
            char filename[256];
            auto size = recv(socket, data, 512, 0);                 // recieve the request using fd
            data[size] = 0;                                         // NUL terminate it
            sscanf(data, "GET /%s ", filename);                     // get the name of the file
            send(socket, header.c_str(), header.size(), 0);
            std::this_thread::sleep_for(std::chrono::seconds(10));
            cnc::send_file(filename, socket);
            close(socket);                                          // close the socket
        };

        pool.enqueue(request_handler, accept(soc, NULL, NULL));
    }
}
<commit_msg>polishing<commit_after>//c and posix
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>

//c++
#include <string>
#include <fstream>
#include <iostream>
#include <unordered_map>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <future>

namespace cnc
{
    class ThreadPool
    {
    public:
        ThreadPool(size_t);

        template<class F, class... Args>
        auto enqueue(F &&f, Args &&... args) -> std::future<typename std::result_of<F(Args...)>::type>;

        ~ThreadPool();

    private:
        // need to keep track of threads so we can join them
        std::vector<std::thread> workers;
        // the task queue
        std::queue<std::function<void()>> tasks;

        // synchronization
        std::mutex queue_mutex;
        std::condition_variable condition;
        bool stop;
    };

    // the constructor just launches some amount of workers
    inline ThreadPool::ThreadPool(size_t threads)
            : stop(false)
    {
        for (size_t i = 0; i < threads; ++i)
            workers.emplace_back(
                    [this]
                    {
                        for (; ;)
                        {
                            std::function<void()> task;

                            {
                                std::unique_lock<std::mutex> lock(this->queue_mutex);
                                this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                                if (this->stop && this->tasks.empty())
                                    return;
                                task = std::move(this->tasks.front());
                                this->tasks.pop();
                            }

                            task();
                        }
                    }
            );
    }

    // add new work item to the pool
    template<class F, class... Args>
    auto ThreadPool::enqueue(F &&f, Args &&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
        using return_type = typename std::result_of<F(Args...)>::type;

        auto task = std::make_shared<std::packaged_task<return_type()>>
        (
                std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );

        std::future<return_type> res = task->get_future();
        {
            std::unique_lock<std::mutex> lock(queue_mutex);

            // don't allow enqueueing after stopping the pool
            if (stop)
                throw std::runtime_error("enqueue on stopped ThreadPool");

            tasks.emplace([task]() { (*task)(); });
        }
        condition.notify_one();
        return res;
    }

    // the destructor joins all threads
    inline ThreadPool::~ThreadPool()
    {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            stop = true;
        }
        condition.notify_all();
        for (auto& worker: workers) worker.join();
    }

    template<typename Socket>
    void send_file(std::string const &filename, Socket const &socket)
    {
        std::ifstream ifs{filename};
        for (std::string str; ifs >> str;)
        {
            auto msg = str + "\r\n";
            send(socket, msg.c_str(), msg.size(), 0);
        }
    }

    template <typename StatusCode>
    auto make_reply_header(StatusCode code) -> std::string
    {
        const static std::unordered_map<StatusCode, std::string> status
                {
                        {200, "200 OK"},
                        {404, "404 Not Found"},
                        {501, "501 Not Implemented"}
                };

        return status.at(code);
    }

}// end of namespace ccur

int main()
{
    auto const PORT = 3490;

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = INADDR_ANY;
    memset( addr.sin_zero, '\0', sizeof(addr.sin_zero) );

    // Create a socket and bind it the port PORT
    auto const soc = socket(PF_INET,SOCK_STREAM, 0);
    bind(soc, (struct sockaddr *)&addr, sizeof(addr));
    printf("%d", addr.sin_port);

    // Allow up to 10 incoming connections
    auto const limit = 10;
    listen(soc,limit);
    std::cout << "listenning\n";

    auto const header = cnc::make_reply_header(200);
    for(cnc::ThreadPool pool{ limit }; true;)
    {
        auto request_handler = [&] (int socket){
            char data[512];
            char filename[256];
            auto size = recv(socket, data, 512, 0);                 // recieve the request using fd
            data[size] = 0;                                         // NUL terminate it
            sscanf(data, "GET /%s ", filename);                     // get the name of the file
            send(socket, header.c_str(), header.size(), 0);
            std::this_thread::sleep_for(std::chrono::seconds(10));
            cnc::send_file(filename, socket);
            close(socket);                                          // close the socket
        };

        pool.enqueue(request_handler, accept(soc, NULL, NULL));
    }
}
<|endoftext|>


<commit_before>9e7accab-2747-11e6-abeb-e0f84713e7b8<commit_msg>more fixes<commit_after>9e88f5dc-2747-11e6-be55-e0f84713e7b8<|endoftext|>