<commit_before>//
// Created by marwac-9 on 9/16/15.
//
#ifdef __linux__
#include <sys/resource.h>
#elif _WIN32 || _WIN64
#include "windows.h"
#undef near
#undef far
#include "psapi.h"
#endif
#include "SubdivApp.h"
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include "GraphicsManager.h"
#include "GraphicsStorage.h"
#include "Node.h"
#include "Material.h"
#include "Mesh.h"
#include "OBJ.h"
#include "HalfEdgeMesh.h"
#include <fstream>
#include "Scene.h"
#include "ShaderManager.h"
#include <string>
#include "PhysicsManager.h"
#include "Camera.h"
#include "Frustum.h"
#include "Render.h"
#include "CameraManager.h"
#include <chrono>
#include "Times.h"

using namespace mwm;
using namespace Display;

namespace Subdivision
{

	//------------------------------------------------------------------------------
	/**
	*/
	SubdivisionApp::SubdivisionApp()
	{
		// empty
	}

	//------------------------------------------------------------------------------
	/**
	*/
	SubdivisionApp::~SubdivisionApp()
	{
		// empty
	}

	//------------------------------------------------------------------------------
	/**
	*/
	bool
	SubdivisionApp::Open()
	{
		App::Open();
		this->window = new Display::Window;

		window->SetKeyPressFunction([this](int32 key, int32 scancode, int32 action, int32 mode)
		{
			KeyCallback(key, scancode, action, mode);
		});

		window->SetMouseMoveFunction([this](double mouseX, double mouseY)
		{
			MouseCallback(mouseX, mouseY);
		});

		// window resize callback
		this->window->SetWindowSizeFunction([this](int width, int height)
		{
			this->windowWidth = width;
			this->windowHeight = height;
			this->windowMidX = windowWidth / 2.0f;
			this->windowMidY = windowHeight / 2.0f;
			this->window->SetSize(this->windowWidth, this->windowHeight);

			currentCamera->UpdateSize(width, height);
		});

		if (this->window->Open())
		{
			running = true;
			return true;
		}
		return false;
	}

	//------------------------------------------------------------------------------
	/**
	*/
	void
	SubdivisionApp::Run()
	{

		InitGL();
		GraphicsManager::LoadAllAssets();

		LoadScene1();

		// For speed computation (FPS)
		Times::Instance()->currentTime = glfwGetTime();

		//camera rotates based on mouse movement, setting initial mouse pos will always focus camera at the beginning in specific position
		window->SetCursorPos(windowMidX, windowMidY + 100);
		window->SetCursorMode(GLFW_CURSOR_DISABLED);

		SetUpCamera();

		Scene::Instance()->Update();

		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		wireframe = true;
		//glfwSwapInterval(0); //unlock fps
		ShaderManager::Instance()->SetCurrentShader(GraphicsStorage::shaderIDs["color"]);
		while (running)
		{
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			this->window->Update();

			Times::Instance()->Update(glfwGetTime());

			Monitor(this->window);

			CameraManager::Instance()->Update(Times::Instance()->deltaTime);
			FrustumManager::Instance()->ExtractPlanes(CameraManager::Instance()->ViewProjection);

			Scene::Instance()->Update();

			Draw();

			this->window->SwapBuffers();
		}
		GraphicsStorage::Clear();
		ImGui_ImplGlfwGL3_Shutdown();
		this->window->Close();
	}

	void
	SubdivisionApp::KeyCallback(int key, int scancode, int action, int mods)
	{
		if (action == GLFW_PRESS)
		{
			if (key == GLFW_KEY_ESCAPE) {
				running = false;
			}
			//this is just used to show hide cursor, mouse steal on/off
			else if (key == GLFW_KEY_LEFT_ALT) {
				if (altButtonToggle) {
					altButtonToggle = false;
					window->SetCursorMode(GLFW_CURSOR_NORMAL);
				}
				else {
					altButtonToggle = true;
					window->SetCursorPos(windowWidth / 2.f, windowHeight / 2.f);
					window->SetCursorMode(GLFW_CURSOR_DISABLED);
				}
			}
			else if (key == GLFW_KEY_1) {
				LoadScene1();
			}
			else if (key == GLFW_KEY_2) {
				LoadScene2();
			}
			else if (key == GLFW_KEY_3) {
				LoadScene3();
			}
			else if (key == GLFW_KEY_4) {
				LoadScene4();
			}
			else if (key == GLFW_KEY_5) {
				LoadScene5();
			}
			else if (key == GLFW_KEY_6) {
				LoadScene6();
			}
			else if (key == GLFW_KEY_7) {
				LoadScene7();
			}
			else if (key == GLFW_KEY_8) {
				LoadScene8();
			}
			else if (key == GLFW_KEY_9) {
				LoadScene9();
			}
			else if (key == GLFW_KEY_TAB) {
				if (wireframe)
				{
					wireframe = false;
					printf("\nSHADED MODE\n");
					glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
				}
				else
				{
					wireframe = true;
					printf("\nWIREFRAME MODE\n");
					glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
				}
			}
			else if (key == GLFW_KEY_S && window->GetKey(GLFW_KEY_LEFT_CONTROL)) {
				GraphicsManager::SaveToOBJ(GraphicsStorage::objects.back());
				std::cout << "Last Mesh Saved" << std::endl;
			}

			else if (key == GLFW_KEY_E)
			{
				Object* cube = Scene::Instance()->addPhysicObject("cube", Vector3(0.f, 8.f, 0.f));
				cube->SetPosition(Vector3(0.f, (float)Scene::Instance()->idCounter * 2.f - 10.f + 0.001f, 0.f));
			}
		}
	}

	void
	SubdivisionApp::Monitor(Display::Window* window)
	{
		if (altButtonToggle)
		{
			currentCamera->holdingForward = (window->GetKey(GLFW_KEY_W) == GLFW_PRESS);
			currentCamera->holdingBackward = (window->GetKey(GLFW_KEY_S) == GLFW_PRESS);
			currentCamera->holdingRight = (window->GetKey(GLFW_KEY_D) == GLFW_PRESS);
			currentCamera->holdingLeft = (window->GetKey(GLFW_KEY_A) == GLFW_PRESS);
			currentCamera->holdingUp = (window->GetKey(GLFW_KEY_SPACE) == GLFW_PRESS);
			currentCamera->holdingDown = (window->GetKey(GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS);
		}
		currentCamera->fov = fov;
		currentCamera->near = near;
		currentCamera->far = far;
	}

	void
	SubdivisionApp::InitGL()
	{

		// grey background
		glClearColor(0.f, 0.f, 0.f, 1.0f);

		// Enable depth test
		glEnable(GL_DEPTH_TEST);
		// Accept fragment if it closer to the camera than the former one
		glDepthFunc(GL_LESS);

		// Cull triangles which normal is not towards the camera
		glEnable(GL_CULL_FACE);

		this->window->GetWindowSize(&this->windowWidth, &this->windowHeight);
		windowMidX = windowWidth / 2.0f;
		windowMidY = windowHeight / 2.0f;
	}

	void
	SubdivisionApp::Draw()
	{
		Matrix4F View = currentCamera->ViewMatrix.toFloat();
		GLuint currentShaderID = ShaderManager::Instance()->GetCurrentShaderID();
		GLuint ViewMatrixHandle = glGetUniformLocation(currentShaderID, "V");
		glUniformMatrix4fv(ViewMatrixHandle, 1, GL_FALSE, &View[0][0]);

		GLuint cameraPos = glGetUniformLocation(currentShaderID, "CameraPos");
		Vector3F camPos = currentCamera->GetPosition2().toFloat();
		glUniform3fv(cameraPos, 1, &camPos.x);

		objectsRendered = Render::Instance()->draw(Scene::Instance()->renderList, CameraManager::Instance()->ViewProjection, currentShaderID);
	}

	void
	SubdivisionApp::Clear()
	{
		Scene::Instance()->Clear();
		PhysicsManager::Instance()->Clear();
		GraphicsStorage::ClearMaterials();
		ClearSubdivisionData();
	}

	void
	SubdivisionApp::ClearSubdivisionData()
	{
		for (auto& obj : dynamicOBJs)
		{
			delete obj;
		}
		dynamicOBJs.clear();
		for (auto& mesh : dynamicMeshes)
		{
			delete mesh;
		}
		dynamicMeshes.clear();
		for (auto& mesh : dynamicHEMeshes)
		{
			delete mesh;
		}
		dynamicHEMeshes.clear();
	}

	void
	SubdivisionApp::LoadScene1()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[0]);
	}

	void
	SubdivisionApp::LoadScene2()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[1]);
	}

	void
	SubdivisionApp::LoadScene3()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[2]);
	}

	void
	SubdivisionApp::LoadScene4()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[3]);
	}

	void
	SubdivisionApp::LoadScene5()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[4]);
	}

	void
	SubdivisionApp::LoadScene6()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[5]);
	}

	void
	SubdivisionApp::LoadScene7()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[6]);
	}

	void
	SubdivisionApp::LoadScene8()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[7]);
	}

	void
	SubdivisionApp::LoadScene9()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[8]);
	}

	void
	SubdivisionApp::Subdivide(OBJ* objToSubdivide)
	{
		Object* ObjectHalfMesh = Scene::Instance()->addObject(); //Object added to scene for rendering

		printf("\nConstructing half edge mesh\n");
		HalfEdgeMesh* newHMesh = new HalfEdgeMesh();
		OBJ* constructedOBJ = new OBJ();
		dynamicOBJs.push_back(constructedOBJ);

		newHMesh->Construct(*objToSubdivide);
		HalfEdgeMesh::ExportMeshToOBJ(newHMesh, constructedOBJ);  // HE_Mesh -> OBJ
		constructedOBJ->CalculateDimensions();

		printf("\nDONE\n");

		std::ofstream myfile;
		myfile.open("log.txt");

		std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
		std::chrono::duration<double> elapsed_seconds;
		for (int i = 0; i < 5; i++)
		{
			printf("\nLET'S SUBDIVIDE STAGE%d\n", i + 1);
			start = std::chrono::high_resolution_clock::now();
			newHMesh->Subdivide();
			end = std::chrono::high_resolution_clock::now();
			elapsed_seconds = end - start;

			std::cout << "\nPass " << i + 1 << " subdivided in: " << elapsed_seconds.count() << "s\n";

			myfile << "\nPass " << i + 1 << " subdivided in: " << elapsed_seconds.count() << "s\n";

		}

#ifdef __linux__
		struct rusage r_usage;

		getrusage(RUSAGE_SELF, &r_usage);

		printf("Memory usage: %ld kB\n", r_usage.ru_maxrss);
	}
#elif _WIN32 || _WIN64
		PROCESS_MEMORY_COUNTERS pmc;
		GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
		//SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;
		SIZE_T physMemUsedByMe = pmc.WorkingSetSize;
		printf("Memory usage: %lu kB\n", physMemUsedByMe/1024);
		printf("Memory usage: %lu MB\n", physMemUsedByMe/1024000);

#endif
		myfile.close();
		printf("\nDONE\n");

		printf("\nExporting subdivided mesh\n");
		OBJ* subdividedOBJ = new OBJ(); //we need new renderable OBJ for subdivided half-edge mesh while proxy will still use the first generated OBJ
		dynamicOBJs.push_back(subdividedOBJ);
		HalfEdgeMesh::ExportMeshToOBJ(newHMesh, subdividedOBJ);
		subdividedOBJ->CalculateDimensions();
		GraphicsManager::LoadOBJToVBO(subdividedOBJ, newHMesh);
		dynamicHEMeshes.push_back(newHMesh);

		ObjectHalfMesh->AssignMesh(newHMesh); //we assign the subdivided and exported mesh
		Material* newMaterial = new Material();
		newMaterial->AssignTexture(GraphicsStorage::textures.at(0));
		GraphicsStorage::materials.push_back(newMaterial);
		ObjectHalfMesh->AssignMaterial(newMaterial);
		ObjectHalfMesh->SetScale(Vector3(4.0f, 4.0f, 4.0f));
		ObjectHalfMesh->SetPosition(Vector3(0.f, 0.f, -10.f));
		printf("\nDONE\n");

		printf("\nCreating proxy mesh\n");
		Object* ObjectHalfMeshProxy = Scene::Instance()->addObjectTo(ObjectHalfMesh); //we create the object for proxy

		Mesh* proxyMesh = new Mesh(); //and a new mesh for proxy
		GraphicsManager::LoadOBJToVBO(constructedOBJ, proxyMesh); //proxy will use the originally generated OBJ from constructed half edge mesh
		dynamicMeshes.push_back(proxyMesh);

		ObjectHalfMeshProxy->AssignMesh(proxyMesh); //and we assign now generated proxy mesh from constructedOBJ to the proxy Object
		Material* newMaterialProxy = new Material();
		newMaterialProxy->SetColor(Vector3F(1.f, 0.f, 0.f));
		newMaterialProxy->AssignTexture(GraphicsStorage::textures.at(0));
		GraphicsStorage::materials.push_back(newMaterialProxy);
		ObjectHalfMeshProxy->AssignMaterial(newMaterialProxy);
		printf("\nDONE\n");
	}

	void
	SubdivisionApp::MouseCallback(double mouseX, double mouseY)
	{
		if (altButtonToggle)
		{
			currentCamera->UpdateOrientation(mouseX, mouseY);
			window->SetCursorPos(windowMidX, windowMidY);
		}
	}

	void
	SubdivisionApp::SetUpCamera()
	{
		currentCamera = new Camera(Vector3(0.0, 3.0, 16.0), windowWidth, windowHeight);
		currentCamera->Update(Times::Instance()->timeStep);
		window->SetCursorPos(windowMidX, windowMidY);
		CameraManager::Instance()->AddCamera("default", currentCamera);
		CameraManager::Instance()->SetCurrentCamera("default");
		currentCamera->ProjectionMatrix = Matrix4::OpenGLPersp(45.0, (double)this->windowWidth / (double)this->windowHeight, 0.1, 200.0);
	}

} // namespace Example
<commit_msg>removed unnecessary imgui line<commit_after>//
// Created by marwac-9 on 9/16/15.
//
#ifdef __linux__
#include <sys/resource.h>
#elif _WIN32 || _WIN64
#include "windows.h"
#undef near
#undef far
#include "psapi.h"
#endif
#include "SubdivApp.h"
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include "GraphicsManager.h"
#include "GraphicsStorage.h"
#include "Node.h"
#include "Material.h"
#include "Mesh.h"
#include "OBJ.h"
#include "HalfEdgeMesh.h"
#include <fstream>
#include "Scene.h"
#include "ShaderManager.h"
#include <string>
#include "PhysicsManager.h"
#include "Camera.h"
#include "Frustum.h"
#include "Render.h"
#include "CameraManager.h"
#include <chrono>
#include "Times.h"

using namespace mwm;
using namespace Display;

namespace Subdivision
{

	//------------------------------------------------------------------------------
	/**
	*/
	SubdivisionApp::SubdivisionApp()
	{
		// empty
	}

	//------------------------------------------------------------------------------
	/**
	*/
	SubdivisionApp::~SubdivisionApp()
	{
		// empty
	}

	//------------------------------------------------------------------------------
	/**
	*/
	bool
	SubdivisionApp::Open()
	{
		App::Open();
		this->window = new Display::Window;

		window->SetKeyPressFunction([this](int32 key, int32 scancode, int32 action, int32 mode)
		{
			KeyCallback(key, scancode, action, mode);
		});

		window->SetMouseMoveFunction([this](double mouseX, double mouseY)
		{
			MouseCallback(mouseX, mouseY);
		});

		// window resize callback
		this->window->SetWindowSizeFunction([this](int width, int height)
		{
			this->windowWidth = width;
			this->windowHeight = height;
			this->windowMidX = windowWidth / 2.0f;
			this->windowMidY = windowHeight / 2.0f;
			this->window->SetSize(this->windowWidth, this->windowHeight);

			currentCamera->UpdateSize(width, height);
		});

		if (this->window->Open())
		{
			running = true;
			return true;
		}
		return false;
	}

	//------------------------------------------------------------------------------
	/**
	*/
	void
	SubdivisionApp::Run()
	{

		InitGL();
		GraphicsManager::LoadAllAssets();

		LoadScene1();

		// For speed computation (FPS)
		Times::Instance()->currentTime = glfwGetTime();

		//camera rotates based on mouse movement, setting initial mouse pos will always focus camera at the beginning in specific position
		window->SetCursorPos(windowMidX, windowMidY + 100);
		window->SetCursorMode(GLFW_CURSOR_DISABLED);

		SetUpCamera();

		Scene::Instance()->Update();

		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		wireframe = true;
		//glfwSwapInterval(0); //unlock fps
		ShaderManager::Instance()->SetCurrentShader(GraphicsStorage::shaderIDs["color"]);
		while (running)
		{
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			this->window->Update();

			Times::Instance()->Update(glfwGetTime());

			Monitor(this->window);

			CameraManager::Instance()->Update(Times::Instance()->deltaTime);
			FrustumManager::Instance()->ExtractPlanes(CameraManager::Instance()->ViewProjection);

			Scene::Instance()->Update();

			Draw();

			this->window->SwapBuffers();
		}
		GraphicsStorage::Clear();
		this->window->Close();
	}

	void
	SubdivisionApp::KeyCallback(int key, int scancode, int action, int mods)
	{
		if (action == GLFW_PRESS)
		{
			if (key == GLFW_KEY_ESCAPE) {
				running = false;
			}
			//this is just used to show hide cursor, mouse steal on/off
			else if (key == GLFW_KEY_LEFT_ALT) {
				if (altButtonToggle) {
					altButtonToggle = false;
					window->SetCursorMode(GLFW_CURSOR_NORMAL);
				}
				else {
					altButtonToggle = true;
					window->SetCursorPos(windowWidth / 2.f, windowHeight / 2.f);
					window->SetCursorMode(GLFW_CURSOR_DISABLED);
				}
			}
			else if (key == GLFW_KEY_1) {
				LoadScene1();
			}
			else if (key == GLFW_KEY_2) {
				LoadScene2();
			}
			else if (key == GLFW_KEY_3) {
				LoadScene3();
			}
			else if (key == GLFW_KEY_4) {
				LoadScene4();
			}
			else if (key == GLFW_KEY_5) {
				LoadScene5();
			}
			else if (key == GLFW_KEY_6) {
				LoadScene6();
			}
			else if (key == GLFW_KEY_7) {
				LoadScene7();
			}
			else if (key == GLFW_KEY_8) {
				LoadScene8();
			}
			else if (key == GLFW_KEY_9) {
				LoadScene9();
			}
			else if (key == GLFW_KEY_TAB) {
				if (wireframe)
				{
					wireframe = false;
					printf("\nSHADED MODE\n");
					glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
				}
				else
				{
					wireframe = true;
					printf("\nWIREFRAME MODE\n");
					glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
				}
			}
			else if (key == GLFW_KEY_S && window->GetKey(GLFW_KEY_LEFT_CONTROL)) {
				GraphicsManager::SaveToOBJ(GraphicsStorage::objects.back());
				std::cout << "Last Mesh Saved" << std::endl;
			}

			else if (key == GLFW_KEY_E)
			{
				Object* cube = Scene::Instance()->addPhysicObject("cube", Vector3(0.f, 8.f, 0.f));
				cube->SetPosition(Vector3(0.f, (float)Scene::Instance()->idCounter * 2.f - 10.f + 0.001f, 0.f));
			}
		}
	}

	void
	SubdivisionApp::Monitor(Display::Window* window)
	{
		if (altButtonToggle)
		{
			currentCamera->holdingForward = (window->GetKey(GLFW_KEY_W) == GLFW_PRESS);
			currentCamera->holdingBackward = (window->GetKey(GLFW_KEY_S) == GLFW_PRESS);
			currentCamera->holdingRight = (window->GetKey(GLFW_KEY_D) == GLFW_PRESS);
			currentCamera->holdingLeft = (window->GetKey(GLFW_KEY_A) == GLFW_PRESS);
			currentCamera->holdingUp = (window->GetKey(GLFW_KEY_SPACE) == GLFW_PRESS);
			currentCamera->holdingDown = (window->GetKey(GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS);
		}
		currentCamera->fov = fov;
		currentCamera->near = near;
		currentCamera->far = far;
	}

	void
	SubdivisionApp::InitGL()
	{

		// grey background
		glClearColor(0.f, 0.f, 0.f, 1.0f);

		// Enable depth test
		glEnable(GL_DEPTH_TEST);
		// Accept fragment if it closer to the camera than the former one
		glDepthFunc(GL_LESS);

		// Cull triangles which normal is not towards the camera
		glEnable(GL_CULL_FACE);

		this->window->GetWindowSize(&this->windowWidth, &this->windowHeight);
		windowMidX = windowWidth / 2.0f;
		windowMidY = windowHeight / 2.0f;
	}

	void
	SubdivisionApp::Draw()
	{
		Matrix4F View = currentCamera->ViewMatrix.toFloat();
		GLuint currentShaderID = ShaderManager::Instance()->GetCurrentShaderID();
		GLuint ViewMatrixHandle = glGetUniformLocation(currentShaderID, "V");
		glUniformMatrix4fv(ViewMatrixHandle, 1, GL_FALSE, &View[0][0]);

		GLuint cameraPos = glGetUniformLocation(currentShaderID, "CameraPos");
		Vector3F camPos = currentCamera->GetPosition2().toFloat();
		glUniform3fv(cameraPos, 1, &camPos.x);

		objectsRendered = Render::Instance()->draw(Scene::Instance()->renderList, CameraManager::Instance()->ViewProjection, currentShaderID);
	}

	void
	SubdivisionApp::Clear()
	{
		Scene::Instance()->Clear();
		PhysicsManager::Instance()->Clear();
		GraphicsStorage::ClearMaterials();
		ClearSubdivisionData();
	}

	void
	SubdivisionApp::ClearSubdivisionData()
	{
		for (auto& obj : dynamicOBJs)
		{
			delete obj;
		}
		dynamicOBJs.clear();
		for (auto& mesh : dynamicMeshes)
		{
			delete mesh;
		}
		dynamicMeshes.clear();
		for (auto& mesh : dynamicHEMeshes)
		{
			delete mesh;
		}
		dynamicHEMeshes.clear();
	}

	void
	SubdivisionApp::LoadScene1()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[0]);
	}

	void
	SubdivisionApp::LoadScene2()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[1]);
	}

	void
	SubdivisionApp::LoadScene3()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[2]);
	}

	void
	SubdivisionApp::LoadScene4()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[3]);
	}

	void
	SubdivisionApp::LoadScene5()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[4]);
	}

	void
	SubdivisionApp::LoadScene6()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[5]);
	}

	void
	SubdivisionApp::LoadScene7()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[6]);
	}

	void
	SubdivisionApp::LoadScene8()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[7]);
	}

	void
	SubdivisionApp::LoadScene9()
	{
		Clear();
		Subdivide(GraphicsStorage::objects[8]);
	}

	void
	SubdivisionApp::Subdivide(OBJ* objToSubdivide)
	{
		Object* ObjectHalfMesh = Scene::Instance()->addObject(); //Object added to scene for rendering

		printf("\nConstructing half edge mesh\n");
		HalfEdgeMesh* newHMesh = new HalfEdgeMesh();
		OBJ* constructedOBJ = new OBJ();
		dynamicOBJs.push_back(constructedOBJ);

		newHMesh->Construct(*objToSubdivide);
		HalfEdgeMesh::ExportMeshToOBJ(newHMesh, constructedOBJ);  // HE_Mesh -> OBJ
		constructedOBJ->CalculateDimensions();

		printf("\nDONE\n");

		std::ofstream myfile;
		myfile.open("log.txt");

		std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
		std::chrono::duration<double> elapsed_seconds;
		for (int i = 0; i < 5; i++)
		{
			printf("\nLET'S SUBDIVIDE STAGE%d\n", i + 1);
			start = std::chrono::high_resolution_clock::now();
			newHMesh->Subdivide();
			end = std::chrono::high_resolution_clock::now();
			elapsed_seconds = end - start;

			std::cout << "\nPass " << i + 1 << " subdivided in: " << elapsed_seconds.count() << "s\n";

			myfile << "\nPass " << i + 1 << " subdivided in: " << elapsed_seconds.count() << "s\n";

		}

#ifdef __linux__
		struct rusage r_usage;

		getrusage(RUSAGE_SELF, &r_usage);

		printf("Memory usage: %ld kB\n", r_usage.ru_maxrss);
	}
#elif _WIN32 || _WIN64
		PROCESS_MEMORY_COUNTERS pmc;
		GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
		//SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;
		SIZE_T physMemUsedByMe = pmc.WorkingSetSize;
		printf("Memory usage: %lu kB\n", physMemUsedByMe/1024);
		printf("Memory usage: %lu MB\n", physMemUsedByMe/1024000);

#endif
		myfile.close();
		printf("\nDONE\n");

		printf("\nExporting subdivided mesh\n");
		OBJ* subdividedOBJ = new OBJ(); //we need new renderable OBJ for subdivided half-edge mesh while proxy will still use the first generated OBJ
		dynamicOBJs.push_back(subdividedOBJ);
		HalfEdgeMesh::ExportMeshToOBJ(newHMesh, subdividedOBJ);
		subdividedOBJ->CalculateDimensions();
		GraphicsManager::LoadOBJToVBO(subdividedOBJ, newHMesh);
		dynamicHEMeshes.push_back(newHMesh);

		ObjectHalfMesh->AssignMesh(newHMesh); //we assign the subdivided and exported mesh
		Material* newMaterial = new Material();
		newMaterial->AssignTexture(GraphicsStorage::textures.at(0));
		GraphicsStorage::materials.push_back(newMaterial);
		ObjectHalfMesh->AssignMaterial(newMaterial);
		ObjectHalfMesh->SetScale(Vector3(4.0f, 4.0f, 4.0f));
		ObjectHalfMesh->SetPosition(Vector3(0.f, 0.f, -10.f));
		printf("\nDONE\n");

		printf("\nCreating proxy mesh\n");
		Object* ObjectHalfMeshProxy = Scene::Instance()->addObjectTo(ObjectHalfMesh); //we create the object for proxy

		Mesh* proxyMesh = new Mesh(); //and a new mesh for proxy
		GraphicsManager::LoadOBJToVBO(constructedOBJ, proxyMesh); //proxy will use the originally generated OBJ from constructed half edge mesh
		dynamicMeshes.push_back(proxyMesh);

		ObjectHalfMeshProxy->AssignMesh(proxyMesh); //and we assign now generated proxy mesh from constructedOBJ to the proxy Object
		Material* newMaterialProxy = new Material();
		newMaterialProxy->SetColor(Vector3F(1.f, 0.f, 0.f));
		newMaterialProxy->AssignTexture(GraphicsStorage::textures.at(0));
		GraphicsStorage::materials.push_back(newMaterialProxy);
		ObjectHalfMeshProxy->AssignMaterial(newMaterialProxy);
		printf("\nDONE\n");
	}

	void
	SubdivisionApp::MouseCallback(double mouseX, double mouseY)
	{
		if (altButtonToggle)
		{
			currentCamera->UpdateOrientation(mouseX, mouseY);
			window->SetCursorPos(windowMidX, windowMidY);
		}
	}

	void
	SubdivisionApp::SetUpCamera()
	{
		currentCamera = new Camera(Vector3(0.0, 3.0, 16.0), windowWidth, windowHeight);
		currentCamera->Update(Times::Instance()->timeStep);
		window->SetCursorPos(windowMidX, windowMidY);
		CameraManager::Instance()->AddCamera("default", currentCamera);
		CameraManager::Instance()->SetCurrentCamera("default");
		currentCamera->ProjectionMatrix = Matrix4::OpenGLPersp(45.0, (double)this->windowWidth / (double)this->windowHeight, 0.1, 200.0);
	}

} // namespace Example
<|endoftext|>


<commit_before>
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

#include <raspberry/raspberry.hpp>

#include <string>

RASPBERRY_DECL_METHOD(FuncConcept, func);
RASPBERRY_DECL_METHOD(SquareConcept, square);

using AnyFunc = raspberry::Any<FuncConcept<int()const>,SquareConcept<float(float)>>;

struct SomeFunc {
    int func() const {
        return 42;
    }

    float square(float x) {
        return x*x;
    }
};

TEST_CASE("Objects can be stored in Any", "[raspberry]") {
    AnyFunc f = SomeFunc{};

    REQUIRE(f.func() == 42);
    REQUIRE(f.square(12) == 144);
}

struct negative_test_assign {
    template <typename AF>
    static decltype( AF(std::declval<const AF&>()), bool{} ) test(int) { return false; }

    template <typename AF>
    static bool test(long) { return true; }
};

TEST_CASE("Any cannot be stored in Any or copied", "[raspberry]") {
    REQUIRE(negative_test_assign::test<AnyFunc>(int{}));
}

RASPBERRY_DECL_METHOD(RefDetectConcept, ref_detect);

using AnyRefDetector = raspberry::Any<RefDetectConcept<void(int)>>;

struct RefDetector {
    int value = 0;

    void ref_detect(int x) {
        value = x;
    }
};

TEST_CASE("Objects are copied by default", "[raspberry]") {
    RefDetector rd;
    REQUIRE(rd.value == 0);

    AnyRefDetector ard = rd;
    REQUIRE(rd.value == 0);

    ard.ref_detect(42);
    REQUIRE(rd.value == 0);
}

TEST_CASE("std::reference_wrapper is used to capture by reference", "[raspberry]") {
    RefDetector rd;
    REQUIRE(rd.value == 0);

    AnyRefDetector ard = std::ref(rd);
    REQUIRE(rd.value == 0);

    ard.ref_detect(42);
    REQUIRE(rd.value == 42);
}

RASPBERRY_DECL_METHOD(SetStringConcept, set_string);

using AnySetString = raspberry::Any<
        SetStringConcept< void(const std::string&) >,
        SetStringConcept< void(const char*) >
>;

struct StringSetter {
    std::string value;

    void set_string(const std::string& s) {
        value = s;
    }

    void set_string(const char* s) {
        value = s;
    }
};

TEST_CASE("Methods can be overloaded", "[raspberry]") {
    StringSetter s;
    AnySetString a = std::ref(s);

    a.set_string("char[]");
    REQUIRE(s.value == "char[]");

    a.set_string(std::string("std::string"));
    REQUIRE(s.value == "std::string");

}

RASPBERRY_DECL_METHOD(MaybeConstGetter, get);

using AnyMaybeConstGetter = raspberry::Any<
        MaybeConstGetter< int&() >,
        MaybeConstGetter< const int&() const >
>;

struct SomeMaybeConstGetter {
    int value;
    int& get() { return value; }
    const int& get() const { return value; }
};

TEST_CASE("Const and non-const overloads can coexist", "[raspberry]") {
    SomeMaybeConstGetter s;
    AnyMaybeConstGetter a = std::ref(s);

    s.value = 7;
    REQUIRE(s.value == 7);

    a.get() = 42;
    REQUIRE(s.value == 42);

    const auto& ac = a;
    REQUIRE(ac.get() == 42);
    REQUIRE(std::is_const<std::remove_reference_t<decltype(ac.get())>>::value);
}

using AnyMaybeConstGetterReversed = raspberry::Any<
        MaybeConstGetter< const int&() const >,
        MaybeConstGetter< int&() >
>;

TEST_CASE("Const and non-const overloads can come in any order", "[raspberry]") {
    SomeMaybeConstGetter s;
    AnyMaybeConstGetterReversed a = std::ref(s);

    s.value = 7;
    REQUIRE(s.value == 7);

    a.get() = 42;
    REQUIRE(s.value == 42);

    const auto& ac = a;
    REQUIRE(ac.get() == 42);
    REQUIRE(std::is_const<std::remove_reference_t<decltype(ac.get())>>::value);
}

<commit_msg>Added test case for calling const methods via non-const concepts<commit_after>
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

#include <raspberry/raspberry.hpp>

#include <string>

RASPBERRY_DECL_METHOD(FuncConcept, func);
RASPBERRY_DECL_METHOD(SquareConcept, square);

using AnyFunc = raspberry::Any<FuncConcept<int()const>,SquareConcept<float(float)>>;

struct SomeFunc {
    int func() const {
        return 42;
    }

    float square(float x) {
        return x*x;
    }
};

TEST_CASE("Objects can be stored in Any", "[raspberry]") {
    AnyFunc f = SomeFunc{};

    REQUIRE(f.func() == 42);
    REQUIRE(f.square(12) == 144);
}

struct negative_test_assign {
    template <typename AF>
    static decltype( AF(std::declval<const AF&>()), bool{} ) test(int) { return false; }

    template <typename AF>
    static bool test(long) { return true; }
};

TEST_CASE("Any cannot be stored in Any or copied", "[raspberry]") {
    REQUIRE(negative_test_assign::test<AnyFunc>(int{}));
}

RASPBERRY_DECL_METHOD(RefDetectConcept, ref_detect);

using AnyRefDetector = raspberry::Any<RefDetectConcept<void(int)>>;

struct RefDetector {
    int value = 0;

    void ref_detect(int x) {
        value = x;
    }
};

TEST_CASE("Objects are copied by default", "[raspberry]") {
    RefDetector rd;
    REQUIRE(rd.value == 0);

    AnyRefDetector ard = rd;
    REQUIRE(rd.value == 0);

    ard.ref_detect(42);
    REQUIRE(rd.value == 0);
}

TEST_CASE("std::reference_wrapper is used to capture by reference", "[raspberry]") {
    RefDetector rd;
    REQUIRE(rd.value == 0);

    AnyRefDetector ard = std::ref(rd);
    REQUIRE(rd.value == 0);

    ard.ref_detect(42);
    REQUIRE(rd.value == 42);
}

RASPBERRY_DECL_METHOD(SetStringConcept, set_string);

using AnySetString = raspberry::Any<
        SetStringConcept< void(const std::string&) >,
        SetStringConcept< void(const char*) >
>;

struct StringSetter {
    std::string value;

    void set_string(const std::string& s) {
        value = s;
    }

    void set_string(const char* s) {
        value = s;
    }
};

TEST_CASE("Methods can be overloaded", "[raspberry]") {
    StringSetter s;
    AnySetString a = std::ref(s);

    a.set_string("char[]");
    REQUIRE(s.value == "char[]");

    a.set_string(std::string("std::string"));
    REQUIRE(s.value == "std::string");

}

RASPBERRY_DECL_METHOD(MaybeConstGetter, get);

using AnyMaybeConstGetter = raspberry::Any<
        MaybeConstGetter< int&() >,
        MaybeConstGetter< const int&() const >
>;

struct SomeMaybeConstGetter {
    int value;
    int& get() { return value; }
    const int& get() const { return value; }
};

TEST_CASE("Const and non-const overloads can coexist", "[raspberry]") {
    SomeMaybeConstGetter s;
    AnyMaybeConstGetter a = std::ref(s);

    s.value = 7;
    REQUIRE(s.value == 7);

    a.get() = 42;
    REQUIRE(s.value == 42);

    const auto& ac = a;
    REQUIRE(ac.get() == 42);
    REQUIRE(std::is_const<std::remove_reference_t<decltype(ac.get())>>::value);
}

using AnyMaybeConstGetterReversed = raspberry::Any<
        MaybeConstGetter< const int&() const >,
        MaybeConstGetter< int&() >
>;

TEST_CASE("Const and non-const overloads can come in any order", "[raspberry]") {
    SomeMaybeConstGetter s;
    AnyMaybeConstGetterReversed a = std::ref(s);

    s.value = 7;
    REQUIRE(s.value == 7);

    a.get() = 42;
    REQUIRE(s.value == 42);

    const auto& ac = a;
    REQUIRE(ac.get() == 42);
    REQUIRE(std::is_const<std::remove_reference_t<decltype(ac.get())>>::value);
}

RASPBERRY_DECL_METHOD(ConstTester, c_func);

using AnyConstTester = raspberry::Any< ConstTester< void() > >;

struct SomeConstTester {
    void c_func() const {}
};

TEST_CASE("Const methods can be called from non-const concepts", "[raspberry]") {
    AnyConstTester ac = SomeConstTester{};
    ac.c_func();
    REQUIRE(true);
}
<|endoftext|>


<commit_before>/*
  This file is part of Ingen.
  Copyright 2007-2012 David Robillard <http://drobilla.net/>

  Ingen is free software: you can redistribute it and/or modify it under the
  terms of the GNU Affero General Public License as published by the Free
  Software Foundation, either version 3 of the License, or any later version.

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

  You should have received a copy of the GNU Affero General Public License
  along with Ingen.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef INGEN_CLIENT_NODEMODEL_HPP
#define INGEN_CLIENT_NODEMODEL_HPP

#include <cstdlib>
#include <string>
#include <vector>

#include "raul/SharedPtr.hpp"

#include "ingen/Node.hpp"
#include "ingen/Port.hpp"
#include "ingen/client/ObjectModel.hpp"
#include "ingen/client/PortModel.hpp"
#include "ingen/client/PluginModel.hpp"

namespace Raul { class Path; }

namespace Ingen {

namespace Shared { class URIs; }

namespace Client {

class PluginModel;
class ClientStore;

/** Node model class, used by the client to store engine's state.
 *
 * \ingroup IngenClient
 */
class NodeModel : public ObjectModel,
                  virtual public Ingen::Node
{
public:
	NodeModel(const NodeModel& copy);
	virtual ~NodeModel();

	typedef std::vector< SharedPtr<const PortModel> > Ports;

	SharedPtr<const PortModel> get_port(const Raul::Symbol& symbol) const;

	Port* port(uint32_t index) const;

	const Raul::URI&       plugin_uri()   const { return _plugin_uri; }
	const Plugin*          plugin()       const { return _plugin.get(); }
	Plugin*                plugin()             { return _plugin.get(); }
	SharedPtr<PluginModel> plugin_model() const { return _plugin; }
	uint32_t               num_ports()    const { return _ports.size(); }
	const Ports&           ports()        const { return _ports; }

	void default_port_value_range(SharedPtr<const PortModel> port,
	                              float& min, float& max, uint32_t srate=1) const;

	void port_value_range(SharedPtr<const PortModel> port,
	                      float& min, float& max, uint32_t srate=1) const;

	std::string port_label(SharedPtr<const PortModel> port) const;

	// Signals
	INGEN_SIGNAL(new_port, void, SharedPtr<const PortModel>);
	INGEN_SIGNAL(removed_port, void, SharedPtr<const PortModel>);

protected:
	friend class ClientStore;

	NodeModel(Shared::URIs&          uris,
	          const Raul::URI&       plugin_uri,
	          const Raul::Path&      path);
	NodeModel(Shared::URIs&          uris,
	          SharedPtr<PluginModel> plugin,
	          const Raul::Path&      path);
	explicit NodeModel(const Raul::Path& path);

	void add_child(SharedPtr<ObjectModel> c);
	bool remove_child(SharedPtr<ObjectModel> c);
	void add_port(SharedPtr<PortModel> pm);
	void remove_port(SharedPtr<PortModel> pm);
	void remove_port(const Raul::Path& port_path);
	void add_program(int bank, int program, const std::string& name);
	void remove_program(int bank, int program);
	void set(SharedPtr<ObjectModel> model);

	virtual void clear();

	Ports                  _ports; ///< Vector of ports (not a Table to preserve order)
	Raul::URI              _plugin_uri; ///< Plugin URI (if PluginModel is unknown)
	SharedPtr<PluginModel> _plugin; ///< The plugin this node is an instance of

private:
	mutable uint32_t _num_values; ///< Size of _min_values and _max_values
	mutable float*   _min_values; ///< Port min values (cached for LV2)
	mutable float*   _max_values; ///< Port max values (cached for LV2)
};

} // namespace Client
} // namespace Ingen

#endif // INGEN_CLIENT_NODEMODEL_HPP
<commit_msg>Remove unused method prototypes.<commit_after>/*
  This file is part of Ingen.
  Copyright 2007-2012 David Robillard <http://drobilla.net/>

  Ingen is free software: you can redistribute it and/or modify it under the
  terms of the GNU Affero General Public License as published by the Free
  Software Foundation, either version 3 of the License, or any later version.

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

  You should have received a copy of the GNU Affero General Public License
  along with Ingen.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef INGEN_CLIENT_NODEMODEL_HPP
#define INGEN_CLIENT_NODEMODEL_HPP

#include <cstdlib>
#include <string>
#include <vector>

#include "raul/SharedPtr.hpp"

#include "ingen/Node.hpp"
#include "ingen/Port.hpp"
#include "ingen/client/ObjectModel.hpp"
#include "ingen/client/PortModel.hpp"
#include "ingen/client/PluginModel.hpp"

namespace Raul { class Path; }

namespace Ingen {

namespace Shared { class URIs; }

namespace Client {

class PluginModel;
class ClientStore;

/** Node model class, used by the client to store engine's state.
 *
 * \ingroup IngenClient
 */
class NodeModel : public ObjectModel,
                  virtual public Ingen::Node
{
public:
	NodeModel(const NodeModel& copy);
	virtual ~NodeModel();

	typedef std::vector< SharedPtr<const PortModel> > Ports;

	SharedPtr<const PortModel> get_port(const Raul::Symbol& symbol) const;

	Port* port(uint32_t index) const;

	const Raul::URI&       plugin_uri()   const { return _plugin_uri; }
	const Plugin*          plugin()       const { return _plugin.get(); }
	Plugin*                plugin()             { return _plugin.get(); }
	SharedPtr<PluginModel> plugin_model() const { return _plugin; }
	uint32_t               num_ports()    const { return _ports.size(); }
	const Ports&           ports()        const { return _ports; }

	void default_port_value_range(SharedPtr<const PortModel> port,
	                              float& min, float& max, uint32_t srate=1) const;

	void port_value_range(SharedPtr<const PortModel> port,
	                      float& min, float& max, uint32_t srate=1) const;

	std::string port_label(SharedPtr<const PortModel> port) const;

	// Signals
	INGEN_SIGNAL(new_port, void, SharedPtr<const PortModel>);
	INGEN_SIGNAL(removed_port, void, SharedPtr<const PortModel>);

protected:
	friend class ClientStore;

	NodeModel(Shared::URIs&          uris,
	          const Raul::URI&       plugin_uri,
	          const Raul::Path&      path);
	NodeModel(Shared::URIs&          uris,
	          SharedPtr<PluginModel> plugin,
	          const Raul::Path&      path);
	explicit NodeModel(const Raul::Path& path);

	void add_child(SharedPtr<ObjectModel> c);
	bool remove_child(SharedPtr<ObjectModel> c);
	void add_port(SharedPtr<PortModel> pm);
	void remove_port(SharedPtr<PortModel> pm);
	void remove_port(const Raul::Path& port_path);
	void set(SharedPtr<ObjectModel> model);

	virtual void clear();

	Ports                  _ports; ///< Vector of ports (not a Table to preserve order)
	Raul::URI              _plugin_uri; ///< Plugin URI (if PluginModel is unknown)
	SharedPtr<PluginModel> _plugin; ///< The plugin this node is an instance of

private:
	mutable uint32_t _num_values; ///< Size of _min_values and _max_values
	mutable float*   _min_values; ///< Port min values (cached for LV2)
	mutable float*   _max_values; ///< Port max values (cached for LV2)
};

} // namespace Client
} // namespace Ingen

#endif // INGEN_CLIENT_NODEMODEL_HPP
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: pyuno_impl.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2004-02-02 19:30:27 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Ralph Thomas
 *
 *   Copyright: 2000 by Sun Microsystems, Inc.
 *
 *   All Rights Reserved.
 *
 *   Contributor(s): Ralph Thomas, Joerg Budischewski
 *
 *
 ************************************************************************/
#ifndef _PYUNO_IMPL_
#define _PYUNO_IMPL_

#include <hash_map>
#include <hash_set>

#include <pyuno/pyuno.hxx>

#include <com/sun/star/beans/XIntrospection.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/script/XInvocation2.hpp>
#include <com/sun/star/script/XInvocationAdapterFactory2.hpp>

#include <com/sun/star/reflection/XIdlReflection.hpp>

#include <com/sun/star/container/XHierarchicalNameAccess.hpp>

#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>

#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/weakref.hxx>

namespace pyuno
{

typedef ::std::hash_map
<
    PyRef,
    com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >,
    PyRef::Hash,
    std::equal_to< PyRef >
> PyRef2Adapter;

typedef ::std::hash_map
<
rtl::OUString,
PyRef,
rtl::OUStringHash,
std::equal_to<rtl::OUString>
> ExceptionClassMap;

typedef ::std::hash_map
<
    rtl::OUString,
    com::sun::star::uno::Sequence< sal_Int16 >,
    rtl::OUStringHash,
    std::equal_to< rtl::OUString >
> MethodOutIndexMap;

typedef ::std::hash_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet;

PyObject* PyUNO_new(
    const com::sun::star::uno::Any & targetInterface,
    const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);

PyObject* PyUNO_new_UNCHECKED (
    const com::sun::star::uno::Any & targetInterface,
    const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);

typedef struct
{
    com::sun::star::uno::Reference <com::sun::star::script::XInvocation2> xInvocation;
    com::sun::star::uno::Any wrappedObject;
} PyUNOInternals;

typedef struct
{
    PyObject_HEAD
    PyUNOInternals* members;
} PyUNO;

PyRef ustring2PyUnicode( const rtl::OUString &source );
PyRef ustring2PyString( const ::rtl::OUString & source );
rtl::OUString pyString2ustring( PyObject *str );

PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r )
    throw ( com::sun::star::uno::RuntimeException );

com::sun::star::uno::Any PyObjectToAny (PyObject* o)
    throw ( com::sun::star::uno::RuntimeException );

void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
    throw ( com::sun::star::reflection::InvocationTargetException );

// bool CheckPyObjectTypes (PyObject* o, Sequence<Type> types);
// bool CheckPyObjectType (PyObject* o, Type type); //Only check 1 object.

com::sun::star::uno::TypeClass StringToTypeClass (char* string);

PyRef PyUNO_callable_new (
    const com::sun::star::uno::Reference<com::sun::star::script::XInvocation2> &xInv,
    const rtl::OUString &methodName,
    const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> &ssf,
    const com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> &tc,
    ConversionMode mode = REJECT_UNO_ANY );

PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r );
PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r);
PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r );

PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName );

PyRef getTypeClass( const Runtime &);
PyRef getEnumClass( const Runtime &);
PyRef getBoolClass( const Runtime &);
PyRef getCharClass( const Runtime &);
PyRef getByteSequenceClass( const Runtime & );
PyRef getPyUnoClass( const Runtime &);
PyRef getClass( const rtl::OUString & name , const Runtime & runtime );
PyRef getAnyClass( const Runtime &);
PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args );

com::sun::star::uno::Any PyEnum2Enum( PyObject *obj, const Runtime & r )
    throw ( com::sun::star::uno::RuntimeException );
sal_Bool PyBool2Bool( PyObject *o, const Runtime & r )
    throw ( com::sun::star::uno::RuntimeException );
sal_Unicode PyChar2Unicode( PyObject *o, const Runtime & r )
    throw ( com::sun::star::uno::RuntimeException );
com::sun::star::uno::Type PyType2Type( PyObject * o, const Runtime & r )
    throw( com::sun::star::uno::RuntimeException );

void raisePyExceptionWithAny( const com::sun::star::uno::Any &a );
const char *typeClassToString( com::sun::star::uno::TypeClass t );

PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object )
    throw ( com::sun::star::uno::RuntimeException );

sal_Bool isInterfaceClass( const Runtime &, PyObject *obj );
sal_Bool isInstanceOfStructOrException( const Runtime & runtime, PyObject *obj);
com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces(
    const Runtime & runtime, PyObject *obj );

struct RuntimeCargo
{
    com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation;
    com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter;
    com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext;
    com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection;
    com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr;
    com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
    com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection;
    PyRef dictUnoModule;
    bool valid;
    ExceptionClassMap exceptionMap;
    ClassSet interfaceSet;
    PyRef2Adapter mappedObjects;

    PyRef getUnoModule();
};

struct stRuntimeImpl
{
    PyObject_HEAD
    struct RuntimeCargo *cargo;
public:
    static void del( PyObject *self );

    static PyRef create(
        const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext )
        throw ( com::sun::star::uno::RuntimeException );
};

class Adapter : public cppu::WeakImplHelper2<
    com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
{
    PyRef mWrappedObject;
    PyInterpreterState *mInterpreter;  // interpreters don't seem to be refcounted !
    com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes;
    MethodOutIndexMap m_methodOutIndexMap;

private:
    com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName );

public:
public:
    Adapter( const PyRef &obj, const Runtime &,
             const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types );

    static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
    PyRef getWrappedObject() { return mWrappedObject; }
    com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; }
    virtual ~Adapter();

    // XInvocation
    virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >
           SAL_CALL getIntrospection(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL invoke(
        const ::rtl::OUString& aFunctionName,
        const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams,
        ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
        ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam )
        throw (::com::sun::star::lang::IllegalArgumentException,
               ::com::sun::star::script::CannotConvertException,
               ::com::sun::star::reflection::InvocationTargetException,
               ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL setValue(
        const ::rtl::OUString& aPropertyName,
        const ::com::sun::star::uno::Any& aValue )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::script::CannotConvertException,
               ::com::sun::star::reflection::InvocationTargetException,
               ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName )
        throw (::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName )
        throw (::com::sun::star::uno::RuntimeException);

    // XUnoTunnel
    virtual sal_Int64 SAL_CALL getSomething(
        const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
        throw (::com::sun::star::uno::RuntimeException);
};

/** releases a refcount on the interpreter object and on another given python object.

   The function can be called from any thread regardless of whether the global
   interpreter lock is held.

 */
void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object );

#ifdef PYUNO_DEBUG
#define PYUNO_DEBUG_1( msg ) fprintf( stdout, msg )
#define PYUNO_DEBUG_2( msg, arg1 ) fprintf( stdout, msg ,  arg1 )
#define PYUNO_DEBUG_3( msg, arg1 , arg2 ) fprintf( stdout, msg, arg1, arg2 )
#else
#define PYUNO_DEBUG_1(msg) ((void)0)
#define PYUNO_DEBUG_2(msg,arg1) ((void)0)
#define PYUNO_DEBUG_3(msg,arg2,arg3) ((void)0)
#endif

}

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.42); FILE MERGED 2005/09/05 18:39:21 rt 1.3.42.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pyuno_impl.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:52:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _PYUNO_IMPL_
#define _PYUNO_IMPL_

#include <hash_map>
#include <hash_set>

#include <pyuno/pyuno.hxx>

#include <com/sun/star/beans/XIntrospection.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/script/XInvocation2.hpp>
#include <com/sun/star/script/XInvocationAdapterFactory2.hpp>

#include <com/sun/star/reflection/XIdlReflection.hpp>

#include <com/sun/star/container/XHierarchicalNameAccess.hpp>

#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>

#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/weakref.hxx>

namespace pyuno
{

typedef ::std::hash_map
<
    PyRef,
    com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >,
    PyRef::Hash,
    std::equal_to< PyRef >
> PyRef2Adapter;

typedef ::std::hash_map
<
rtl::OUString,
PyRef,
rtl::OUStringHash,
std::equal_to<rtl::OUString>
> ExceptionClassMap;

typedef ::std::hash_map
<
    rtl::OUString,
    com::sun::star::uno::Sequence< sal_Int16 >,
    rtl::OUStringHash,
    std::equal_to< rtl::OUString >
> MethodOutIndexMap;

typedef ::std::hash_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet;

PyObject* PyUNO_new(
    const com::sun::star::uno::Any & targetInterface,
    const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);

PyObject* PyUNO_new_UNCHECKED (
    const com::sun::star::uno::Any & targetInterface,
    const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);

typedef struct
{
    com::sun::star::uno::Reference <com::sun::star::script::XInvocation2> xInvocation;
    com::sun::star::uno::Any wrappedObject;
} PyUNOInternals;

typedef struct
{
    PyObject_HEAD
    PyUNOInternals* members;
} PyUNO;

PyRef ustring2PyUnicode( const rtl::OUString &source );
PyRef ustring2PyString( const ::rtl::OUString & source );
rtl::OUString pyString2ustring( PyObject *str );

PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r )
    throw ( com::sun::star::uno::RuntimeException );

com::sun::star::uno::Any PyObjectToAny (PyObject* o)
    throw ( com::sun::star::uno::RuntimeException );

void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
    throw ( com::sun::star::reflection::InvocationTargetException );

// bool CheckPyObjectTypes (PyObject* o, Sequence<Type> types);
// bool CheckPyObjectType (PyObject* o, Type type); //Only check 1 object.

com::sun::star::uno::TypeClass StringToTypeClass (char* string);

PyRef PyUNO_callable_new (
    const com::sun::star::uno::Reference<com::sun::star::script::XInvocation2> &xInv,
    const rtl::OUString &methodName,
    const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> &ssf,
    const com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> &tc,
    ConversionMode mode = REJECT_UNO_ANY );

PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r );
PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r);
PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r );

PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName );

PyRef getTypeClass( const Runtime &);
PyRef getEnumClass( const Runtime &);
PyRef getBoolClass( const Runtime &);
PyRef getCharClass( const Runtime &);
PyRef getByteSequenceClass( const Runtime & );
PyRef getPyUnoClass( const Runtime &);
PyRef getClass( const rtl::OUString & name , const Runtime & runtime );
PyRef getAnyClass( const Runtime &);
PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args );

com::sun::star::uno::Any PyEnum2Enum( PyObject *obj, const Runtime & r )
    throw ( com::sun::star::uno::RuntimeException );
sal_Bool PyBool2Bool( PyObject *o, const Runtime & r )
    throw ( com::sun::star::uno::RuntimeException );
sal_Unicode PyChar2Unicode( PyObject *o, const Runtime & r )
    throw ( com::sun::star::uno::RuntimeException );
com::sun::star::uno::Type PyType2Type( PyObject * o, const Runtime & r )
    throw( com::sun::star::uno::RuntimeException );

void raisePyExceptionWithAny( const com::sun::star::uno::Any &a );
const char *typeClassToString( com::sun::star::uno::TypeClass t );

PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object )
    throw ( com::sun::star::uno::RuntimeException );

sal_Bool isInterfaceClass( const Runtime &, PyObject *obj );
sal_Bool isInstanceOfStructOrException( const Runtime & runtime, PyObject *obj);
com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces(
    const Runtime & runtime, PyObject *obj );

struct RuntimeCargo
{
    com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation;
    com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter;
    com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext;
    com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection;
    com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr;
    com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
    com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection;
    PyRef dictUnoModule;
    bool valid;
    ExceptionClassMap exceptionMap;
    ClassSet interfaceSet;
    PyRef2Adapter mappedObjects;

    PyRef getUnoModule();
};

struct stRuntimeImpl
{
    PyObject_HEAD
    struct RuntimeCargo *cargo;
public:
    static void del( PyObject *self );

    static PyRef create(
        const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext )
        throw ( com::sun::star::uno::RuntimeException );
};

class Adapter : public cppu::WeakImplHelper2<
    com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
{
    PyRef mWrappedObject;
    PyInterpreterState *mInterpreter;  // interpreters don't seem to be refcounted !
    com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes;
    MethodOutIndexMap m_methodOutIndexMap;

private:
    com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName );

public:
public:
    Adapter( const PyRef &obj, const Runtime &,
             const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types );

    static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
    PyRef getWrappedObject() { return mWrappedObject; }
    com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; }
    virtual ~Adapter();

    // XInvocation
    virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >
           SAL_CALL getIntrospection(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL invoke(
        const ::rtl::OUString& aFunctionName,
        const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams,
        ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
        ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam )
        throw (::com::sun::star::lang::IllegalArgumentException,
               ::com::sun::star::script::CannotConvertException,
               ::com::sun::star::reflection::InvocationTargetException,
               ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL setValue(
        const ::rtl::OUString& aPropertyName,
        const ::com::sun::star::uno::Any& aValue )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::script::CannotConvertException,
               ::com::sun::star::reflection::InvocationTargetException,
               ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName )
        throw (::com::sun::star::beans::UnknownPropertyException,
               ::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName )
        throw (::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName )
        throw (::com::sun::star::uno::RuntimeException);

    // XUnoTunnel
    virtual sal_Int64 SAL_CALL getSomething(
        const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
        throw (::com::sun::star::uno::RuntimeException);
};

/** releases a refcount on the interpreter object and on another given python object.

   The function can be called from any thread regardless of whether the global
   interpreter lock is held.

 */
void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object );

#ifdef PYUNO_DEBUG
#define PYUNO_DEBUG_1( msg ) fprintf( stdout, msg )
#define PYUNO_DEBUG_2( msg, arg1 ) fprintf( stdout, msg ,  arg1 )
#define PYUNO_DEBUG_3( msg, arg1 , arg2 ) fprintf( stdout, msg, arg1, arg2 )
#else
#define PYUNO_DEBUG_1(msg) ((void)0)
#define PYUNO_DEBUG_2(msg,arg1) ((void)0)
#define PYUNO_DEBUG_3(msg,arg2,arg3) ((void)0)
#endif

}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/system_monitor.h"
#include "testing/gtest/include/gtest/gtest.h"

class PowerTest : public base::SystemMonitor::PowerObserver {
 public:
  PowerTest()
    : battery_(false),
      power_state_changes_(0),
      suspends_(0),
      resumes_(0) {};

  // PowerObserver callbacks.
  void OnPowerStateChange(base::SystemMonitor*) { power_state_changes_++; };
  void OnSuspend(base::SystemMonitor*) { suspends_++; };
  void OnResume(base::SystemMonitor*) { resumes_++; };

  // Test status counts.
  bool battery() { return battery_; }
  int power_state_changes() { return power_state_changes_; }
  int suspends() { return suspends_; }
  int resumes() { return resumes_; }

 private:
  bool battery_;   // Do we currently think we're on battery power.
  int power_state_changes_;  // Count of OnPowerStateChange notifications.
  int suspends_;  // Count of OnSuspend notifications.
  int resumes_;  // Count of OnResume notifications.
};

// Disabled as a temporary workaround for http://crbug.com/12187
TEST(SystemMonitor, DISABLED_PowerNotifications) {
  const int kObservers = 5;

  // Initialize a message loop for this to run on.
  MessageLoop loop;
  // Initialize time() since it registers as a SystemMonitor observer.
  base::Time now = base::Time::Now();

  base::SystemMonitor* monitor = base::SystemMonitor::Get();
  PowerTest test[kObservers];
  for (int index = 0; index < kObservers; ++index)
    monitor->AddObserver(&test[index]);

  // Send a bunch of power changes.  Since the battery power hasn't
  // actually changed, we shouldn't get notifications.
  for (int index = 0; index < 5; index++) {
    monitor->ProcessPowerMessage(base::SystemMonitor::POWER_STATE_EVENT);
    EXPECT_EQ(test[0].power_state_changes(), 0);
  }

  // Sending resume when not suspended should have no effect.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 0);

  // Pretend we suspended.
  monitor->ProcessPowerMessage(base::SystemMonitor::SUSPEND_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].suspends(), 1);

  // Send a second suspend notification.  This should be suppressed.
  monitor->ProcessPowerMessage(base::SystemMonitor::SUSPEND_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].suspends(), 1);

  // Pretend we were awakened.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 1);

  // Send a duplicate resume notification.  This should be suppressed.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 1);
}
<commit_msg>Re-enable SystemMonitor.* in base_unittests.<commit_after>// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/system_monitor.h"
#include "testing/gtest/include/gtest/gtest.h"

class PowerTest : public base::SystemMonitor::PowerObserver {
 public:
  PowerTest()
    : battery_(false),
      power_state_changes_(0),
      suspends_(0),
      resumes_(0) {};

  // PowerObserver callbacks.
  void OnPowerStateChange(base::SystemMonitor*) { power_state_changes_++; };
  void OnSuspend(base::SystemMonitor*) { suspends_++; };
  void OnResume(base::SystemMonitor*) { resumes_++; };

  // Test status counts.
  bool battery() { return battery_; }
  int power_state_changes() { return power_state_changes_; }
  int suspends() { return suspends_; }
  int resumes() { return resumes_; }

 private:
  bool battery_;   // Do we currently think we're on battery power.
  int power_state_changes_;  // Count of OnPowerStateChange notifications.
  int suspends_;  // Count of OnSuspend notifications.
  int resumes_;  // Count of OnResume notifications.
};

TEST(SystemMonitor, PowerNotifications) {
  const int kObservers = 5;

  // Initialize a message loop for this to run on.
  MessageLoop loop;
  // Initialize time() since it registers as a SystemMonitor observer.
  base::Time now = base::Time::Now();

  base::SystemMonitor* monitor = base::SystemMonitor::Get();
  PowerTest test[kObservers];
  for (int index = 0; index < kObservers; ++index)
    monitor->AddObserver(&test[index]);

  // Send a bunch of power changes.  Since the battery power hasn't
  // actually changed, we shouldn't get notifications.
  for (int index = 0; index < 5; index++) {
    monitor->ProcessPowerMessage(base::SystemMonitor::POWER_STATE_EVENT);
    EXPECT_EQ(test[0].power_state_changes(), 0);
  }

  // Sending resume when not suspended should have no effect.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 0);

  // Pretend we suspended.
  monitor->ProcessPowerMessage(base::SystemMonitor::SUSPEND_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].suspends(), 1);

  // Send a second suspend notification.  This should be suppressed.
  monitor->ProcessPowerMessage(base::SystemMonitor::SUSPEND_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].suspends(), 1);

  // Pretend we were awakened.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 1);

  // Send a duplicate resume notification.  This should be suppressed.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 1);
}
<|endoftext|>


<commit_before>// g++ -I../include -O3 -pg -o benchmark_sorting -std=c11 benchmark_sorting.cpp

#include <numeric>
#include <cstring>
#include <random>
#include <algorithm>
#include <functional>
#include <utility>
#include <ctime>

#include "rfr/data_containers/mostly_continuous_data_container.hpp"
#include "rfr/splits/binary_split_one_feature_rss_loss.hpp"

#include "rfr/forests/regression_forest.hpp"

typedef double num_type;
typedef double response_type;
typedef unsigned int index_type;
typedef std::default_random_engine rng_type;

typedef rfr::data_containers::mostly_continuous_data<num_type, response_type, index_type> data_container_type;

typedef rfr::splits::binary_split_one_feature_rss_loss<rng_type, num_type, response_type, index_type> split_type;
typedef rfr::nodes::k_ary_node<2, split_type, rng_type, num_type, response_type, index_type> node_type;
typedef rfr::nodes::temporary_node<num_type, index_type> tmp_node_type;

typedef rfr::trees::k_ary_random_tree<2, split_type, rng_type, num_type, response_type, index_type> tree_type;

typedef rfr::forests::regression_forest< tree_type, rng_type, num_type, response_type, index_type> tree_type;

int main (int argc, char** argv){

	index_type num_features = atoi(argv[1]);
	index_type num_data_points = atoi(argv[2]);
	index_type sample_size = atoi(argv[3]);
	index_type num_trees = atoi(argv[4]);

	data_type data (num_features);

	clock_t t;
	num_type best_loss;

	std::default_random_engine rng;
	std::uniform_real_distribution<response_type> dist1(-1.0,1.0);
	std::uniform_int_distribution<index_type> dist2(0,num_data_points);

	auto random_num = std::bind(dist1, rng);
	auto random_ind = std::bind(dist2, rng);

	for (auto i=0u; i < num_data_points; i++){

		num_type feature_vector[num_features];
		std::generate_n(feature_vector, num_features, random_num);
		response_type response = random_num();

		data.add_data_point(feature_vector, num_features, response);
	}

	t

    return(0);
}
<commit_msg>minor update<commit_after>// g++ -I../include -O3 -pg -o benchmark_sorting -std=c11 benchmark_sorting.cpp

#include <numeric>
#include <cstring>
#include <random>
#include <algorithm>
#include <functional>
#include <utility>
#include <ctime>

#include "rfr/data_containers/mostly_continuous_data_container.hpp"
#include "rfr/splits/binary_split_one_feature_rss_loss.hpp"

#include "rfr/forests/regression_forest.hpp"

typedef double num_type;
typedef double response_type;
typedef unsigned int index_type;
typedef std::default_random_engine rng_type;

typedef rfr::data_containers::mostly_continuous_data<num_type, response_type, index_type> data_container_type;

typedef rfr::splits::binary_split_one_feature_rss_loss<rng_type, num_type, response_type, index_type> split_type;
typedef rfr::nodes::k_ary_node<2, split_type, rng_type, num_type, response_type, index_type> node_type;
typedef rfr::nodes::temporary_node<num_type, index_type> tmp_node_type;

typedef rfr::trees::k_ary_random_tree<2, split_type, rng_type, num_type, response_type, index_type> tree_type;

typedef rfr::forests::regression_forest< tree_type, rng_type, num_type, response_type, index_type> tree_type;

int main (int argc, char** argv){

	index_type num_features = atoi(argv[1]);
	index_type num_data_points = atoi(argv[2]);
	index_type sample_size = atoi(argv[3]);
	index_type num_trees = atoi(argv[4]);

	data_type data (num_features);

	clock_t t;
	num_type best_loss;

	std::default_random_engine rng;
	std::uniform_real_distribution<response_type> dist1(-1.0,1.0);
	std::uniform_int_distribution<index_type> dist2(0,num_data_points);

	auto random_num = std::bind(dist1, rng);
	auto random_ind = std::bind(dist2, rng);

	for (auto i=0u; i < num_data_points; i++){

		num_type feature_vector[num_features];
		std::generate_n(feature_vector, num_features, random_num);
		response_type response = random_num();

		data.add_data_point(feature_vector, num_features, response);
	}

	rfr::forests::forest_options

    return(0);
}
<|endoftext|>


<commit_before>#pragma once

#include <map>
#include <functional>
#include <Components/Component.hh>
#include <Entities/EntityTypedef.hpp>

#define TYPE_TO_STRING(T)(#T);

namespace AGE
{
	class AScene;
	struct ComponentBase;

	class ComponentRegistrationManager
	{
		typedef std::function<void(ComponentBase *, cereal::JSONOutputArchive &)> RegisterJsonFn;
		typedef std::function<void(void *, cereal::JSONInputArchive &)> LoadJsonFn;
		typedef std::function<void(AScene *)> CreateComponentPoolFn;
		typedef std::function<void(void *, ComponentBase *)> CopyFn;

		typedef std::function<void(ComponentBase *, cereal::PortableBinaryOutputArchive &)> RegisterBinaryFn;

	private:
		ComponentRegistrationManager();

	public:
		~ComponentRegistrationManager();
		static ComponentRegistrationManager &getInstance()
		{
			static ComponentRegistrationManager instance;
			return instance;
		}

		// This function is called at scene creation, so that pool are already created
		// and we can deserialize components without knowing their types
		void createComponentPool(AScene *scene)
		{
			for (auto &e : _createComponentPoolMap)
			{
				e.second(scene);
			}
		}

		template <class T>
		void registerComponentType(const char *name)
		{
			std::size_t key = typeid(T).hash_code();
			auto ageId = Component<T>::getTypeId();
			auto it = _creationFunctions.find(key);
			if (it != std::end(_creationFunctions))
				return;
			_creationFunctions.insert(std::make_pair(key, [](Entity *e){return e->addComponent<T>(); }));
			_typeIds.insert(std::make_pair(key, ageId));
			_ageTypeIds.insert(std::make_pair(ageId, key));

			_jsonSaveMap.insert(std::make_pair(ageId, RegisterJsonFn([=](ComponentBase *c, cereal::JSONOutputArchive &ar)
			{
				ar(cereal::make_nvp(name,*(static_cast<T*>(c))));
			})));

			_jsonLoadMap.insert(std::make_pair(ageId, LoadJsonFn([=](void *ptr, cereal::JSONInputArchive &ar){
				std::cout << "Loading component of type : " << name << std::endl;
				T *c = new(ptr)T();
				ar(*c);
			})));

			_binarySaveMap.insert(std::make_pair(ageId, RegisterBinaryFn([](ComponentBase *c, cereal::PortableBinaryOutputArchive &ar)
			{
				ar(*(static_cast<T*>(c)));
			})));

			_createComponentPoolMap.insert(std::make_pair(ageId, CreateComponentPoolFn([](AScene *scene)
			{
				scene->createComponentPool<T>();
			})));

			_copyMap.insert(std::make_pair(ageId, CopyFn([](void *dest, ComponentBase *src)
			{
				T *c = new(dest)T();
			})));

			_componentNames.insert(std::make_pair(ageId, name));
		}

		const std::string &getComponentName(ComponentType type);
		void serializeJson(ComponentBase *c, cereal::JSONOutputArchive &ar);
		void loadJson(std::size_t componentHashId, Entity &e, cereal::JSONInputArchive &ar);
		std::size_t getSystemIdForAgeId(ComponentType id);
		ComponentBase *copyComponent(ComponentBase *c, AScene *scene);

		inline const std::map<std::size_t, std::function<ComponentBase*(Entity *)>> &getCreationFunctions() { return _creationFunctions; }
		inline const std::map<std::size_t, ComponentType> &getSystemIdToAgeIdMap() const { return _typeIds; }
		inline const std::map<ComponentType, std::size_t> &getAgeIdToSystemIdMap() const { return _ageTypeIds; }

	private:
		std::map<std::size_t, std::function<ComponentBase*(Entity *)>> _creationFunctions;
		std::map<std::size_t, ComponentType> _typeIds;
		std::map<ComponentType, std::size_t> _ageTypeIds;
		std::map < ComponentType, RegisterJsonFn> _jsonSaveMap;
		std::map < ComponentType, LoadJsonFn> _jsonLoadMap;
		std::map < ComponentType, RegisterBinaryFn> _binarySaveMap;
		std::map < ComponentType, CopyFn> _copyMap;
		std::map < ComponentType, CreateComponentPoolFn> _createComponentPoolMap;
		std::map < ComponentType, std::string> _componentNames;
	};
}

#define REGISTER_COMPONENT_TYPE(T)(AGE::ComponentRegistrationManager::getInstance().registerComponentType<T>(#T));<commit_msg>new hash used<commit_after>#pragma once

#include <map>
#include <functional>
#include <Components/Component.hh>
#include <Entities/EntityTypedef.hpp>

#define TYPE_TO_STRING(T)(#T);

namespace AGE
{
	class AScene;
	struct ComponentBase;

	class ComponentRegistrationManager
	{
		typedef std::function<void(ComponentBase *, cereal::JSONOutputArchive &)> RegisterJsonFn;
		typedef std::function<void(void *, cereal::JSONInputArchive &)> LoadJsonFn;
		typedef std::function<void(AScene *)> CreateComponentPoolFn;
		typedef std::function<void(void *, ComponentBase *)> CopyFn;

		typedef std::function<void(ComponentBase *, cereal::PortableBinaryOutputArchive &)> RegisterBinaryFn;

	private:
		ComponentRegistrationManager();

	public:
		~ComponentRegistrationManager();
		static ComponentRegistrationManager &getInstance()
		{
			static ComponentRegistrationManager instance;
			return instance;
		}

		// This function is called at scene creation, so that pool are already created
		// and we can deserialize components without knowing their types
		void createComponentPool(AScene *scene)
		{
			for (auto &e : _createComponentPoolMap)
			{
				e.second(scene);
			}
		}

		template <class T>
		void registerComponentType(const char *name)
		{
			std::size_t key = T::getSerializableId();
			auto ageId = Component<T>::getTypeId();
			auto it = _creationFunctions.find(key);
			if (it != std::end(_creationFunctions))
				return;
			_creationFunctions.insert(std::make_pair(key, [](Entity *e){return e->addComponent<T>(); }));
			_typeIds.insert(std::make_pair(key, ageId));
			_ageTypeIds.insert(std::make_pair(ageId, key));

			_jsonSaveMap.insert(std::make_pair(ageId, RegisterJsonFn([=](ComponentBase *c, cereal::JSONOutputArchive &ar)
			{
				ar(cereal::make_nvp(name,*(static_cast<T*>(c))));
			})));

			_jsonLoadMap.insert(std::make_pair(ageId, LoadJsonFn([=](void *ptr, cereal::JSONInputArchive &ar){
				std::cout << "Loading component of type : " << name << std::endl;
				T *c = new(ptr)T();
				ar(*c);
			})));

			_binarySaveMap.insert(std::make_pair(ageId, RegisterBinaryFn([](ComponentBase *c, cereal::PortableBinaryOutputArchive &ar)
			{
				ar(*(static_cast<T*>(c)));
			})));

			_createComponentPoolMap.insert(std::make_pair(ageId, CreateComponentPoolFn([](AScene *scene)
			{
				scene->createComponentPool<T>();
			})));

			_copyMap.insert(std::make_pair(ageId, CopyFn([](void *dest, ComponentBase *src)
			{
				T *c = new(dest)T();
			})));

			_componentNames.insert(std::make_pair(ageId, name));
		}

		const std::string &getComponentName(ComponentType type);
		void serializeJson(ComponentBase *c, cereal::JSONOutputArchive &ar);
		void loadJson(std::size_t componentHashId, Entity &e, cereal::JSONInputArchive &ar);
		std::size_t getSystemIdForAgeId(ComponentType id);
		ComponentBase *copyComponent(ComponentBase *c, AScene *scene);

		inline const std::map<std::size_t, std::function<ComponentBase*(Entity *)>> &getCreationFunctions() { return _creationFunctions; }
		inline const std::map<std::size_t, ComponentType> &getSystemIdToAgeIdMap() const { return _typeIds; }
		inline const std::map<ComponentType, std::size_t> &getAgeIdToSystemIdMap() const { return _ageTypeIds; }

	private:
		std::map<std::size_t, std::function<ComponentBase*(Entity *)>> _creationFunctions;
		std::map<std::size_t, ComponentType> _typeIds;
		std::map<ComponentType, std::size_t> _ageTypeIds;
		std::map < ComponentType, RegisterJsonFn> _jsonSaveMap;
		std::map < ComponentType, LoadJsonFn> _jsonLoadMap;
		std::map < ComponentType, RegisterBinaryFn> _binarySaveMap;
		std::map < ComponentType, CopyFn> _copyMap;
		std::map < ComponentType, CreateComponentPoolFn> _createComponentPoolMap;
		std::map < ComponentType, std::string> _componentNames;
	};
}

#define REGISTER_COMPONENT_TYPE(T)(AGE::ComponentRegistrationManager::getInstance().registerComponentType<T>(#T));<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////
//
//                             Pixie
//
// Copyright  1999 - 2003, Okan Arikan
//
// Contact: okan@cs.utexas.edu
//
//	This library is free software; you can redistribute it and/or
//	modify it under the terms of the GNU Lesser General Public
//	License as published by the Free Software Foundation; either
//	version 2.1 of the License, or (at your option) any later version.
//
//	This library is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//	Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public
//	License along with this library; if not, write to the Free Software
//	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//
//  File				:	texture3d.cpp
//  Classes				:	CTexture3d
//  Description			:	Implementation - George
//
////////////////////////////////////////////////////////////////////////
#include "texture3d.h"
#include "error.h"
#include "renderer.h"
#include "displayChannel.h"

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	CTexture3d
// Description			:	Ctor
// Return Value			:	-
// Comments				:
CTexture3d::CTexture3d(const char *n,const float *f,const float *t,int nc,CTexture3dChannel *ch) : CFileResource(n) {
	dataSize	=	0;
	channels	=	NULL;
	numChannels	=	0;
	movmm(from,f);
	movmm(to,t);
	dPscale		=	pow(fabs(determinantm(to)),1.0f / 3.0f);

	if (nc > 0) {
		int	i;

		numChannels		=	nc;
		channels		=	new CTexture3dChannel[nc];
		memcpy(channels,ch,sizeof(CTexture3dChannel)*numChannels);
		for (i=0,dataSize=0;i<numChannels;i++)
			dataSize	+= channels[i].numSamples;
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	~CTexture3d
// Description			:	Dtor
// Return Value			:	-
// Comments				:
CTexture3d::~CTexture3d() {
	if (channels != NULL) delete [] channels;
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	defineChannels
// Description			:	Define the channels
// Return Value			:	-
// Comments				:
void CTexture3d::defineChannels(const char *channelDefinitions) {
	char				*nextComma,*sampleName,*tmp;
	CDisplayChannel		*oChannel;

	// This is used by remote channels
	// The channel definitions will be loaded when
	// creating the remote channel
	if (channelDefinitions == NULL) return;

	// determinte the channels
	numChannels		=	1;
	dataSize		=	0;

	const char	*sd = channelDefinitions;
	while ((sd = strchr(sd,',')) != NULL) {
		sd++;
		numChannels++;
	}
	channels		=	new CTexture3dChannel[numChannels];

	// parse the channels / sample types
	char *sampleDefinition = strdup(channelDefinitions); // duplicate to tokenize
	nextComma = sampleName = sampleDefinition;
	numChannels = 0;
	do {
		// parse to next comma, remove spaces
		nextComma = strchr(sampleName,',');
		if (nextComma != NULL) {
			for (tmp=nextComma-1;isspace(*tmp)&&(tmp>sampleName);tmp--) *tmp = '\0';
			*nextComma++ = '\0';
			while (isspace(*nextComma)) nextComma++;
		}
		while (isspace(*sampleName)) sampleName++;

		// is the sample name a channel we know about?
		oChannel = CRenderer::retrieveDisplayChannel(sampleName);
		if (oChannel != NULL) {
			// it's a predefined / already seen channel
			strcpy(channels[numChannels].name,oChannel->name);
			channels[numChannels].sampleStart		= dataSize;
			channels[numChannels].numSamples		= oChannel->numSamples;
			channels[numChannels].fill				= oChannel->fill;
			//GSHTODO: duplicate fill

			dataSize								+= oChannel->numSamples;
			numChannels++;
		} else  {
			error(CODE_BADTOKEN,"Unknown display channel \"%s\"\n",sampleName);
		}

		sampleName = nextComma;
	} while((sampleName != NULL) && (*sampleName != '\0'));

	free(sampleDefinition);
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	writeChannels
// Description			:	Write the channels to file
// Return Value			:	-
// Comments				:
void CTexture3d::writeChannels(FILE *out) {
	// Write out the header and channels
	fwrite(&numChannels,sizeof(int),1,out);
	for (int i=0;i<numChannels;i++) {
		fwrite(&channels[i],sizeof(CTexture3dChannel),1,out);
		//GSHTODO:  deal with fill
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	readChannels
// Description			:	Read the channels from file
// Return Value			:	-
// Comments				:
void CTexture3d::readChannels(FILE *in) {
	if (channels != NULL)	delete [] channels;

	// Write out the header and channels
	fread(&numChannels,sizeof(int),1,in);
	channels = new CTexture3dChannel[numChannels];
	for (int i=0;i<numChannels;i++) {
		fread(&channels[i],sizeof(CTexture3dChannel),1,in);
		dataSize += channels[i].numSamples;
		//GSHTODO:  deal with fill
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	bindChannelNamess
// Description			:	Resolve the channel names
// Return Value			:	-
// Comments				:
int CTexture3d::bindChannelNames(int &n,const char **names,CTexture3dChannel ***bindings) {
	CTexture3dChannel	**entryPointers		= new CTexture3dChannel*[numChannels];
	int					numChannelsBound	= 0;
	int					i,j;

	for (i=0;i<n;i++) {
		for(j=0;j<numChannels;j++) {
			if (strcmp(names[i],channels[j].name) ==0) {
				entryPointers[numChannelsBound++] = &channels[j];
				break;
			}
		}
		if (j==numChannels) {
			error(CODE_BADTOKEN,"Unknown 3d texture channel \"%s\"\n",names[i]);
			bindings[i] = NULL;
		}
	}
	// zero unbound channels
	for (i=numChannelsBound;i<numChannels;i++) {
		bindings[i] = NULL;
	}
	n			= numChannelsBound;
	*bindings	= entryPointers;

	return dataSize;
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	prepareSample
// Description			:	prepareSample
// Return Value			:	-
// Comments				:
void CTexture3d::prepareSample(float *C,float **samples,CTexture3dChannel **bindings) {
	float *src,*dest;

	for (int i=0;i<numChannels;i++)	{
		CTexture3dChannel *binding = bindings[i];

		if (binding != NULL) {
			dest	= C + binding->sampleStart;
			src		= samples[i];
			for (int j=0;j<binding->numSamples;j++)
				*dest++ = *src++;
		} else {
			// GSHTODO : zero / fill the samples
		}
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	unpackSample
// Description			:	unpackSample
// Return Value			:	-
// Comments				:
void CTexture3d::unpackSample(float *C,float **samples,CTexture3dChannel **bindings) {
	float *src,*dest;

	for (int i=0;i<numChannels;i++)	{
		CTexture3dChannel *binding = bindings[i];
		if (binding != NULL) {
			src		= C + binding->sampleStart;
			dest	= samples[i];
			for (int j=0;j<binding->numSamples;j++)
				*dest++ = *src++;
		}
	}
}

<commit_msg>ptc api support<commit_after>//////////////////////////////////////////////////////////////////////
//
//                             Pixie
//
// Copyright  1999 - 2003, Okan Arikan
//
// Contact: okan@cs.utexas.edu
//
//	This library is free software; you can redistribute it and/or
//	modify it under the terms of the GNU Lesser General Public
//	License as published by the Free Software Foundation; either
//	version 2.1 of the License, or (at your option) any later version.
//
//	This library is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//	Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public
//	License along with this library; if not, write to the Free Software
//	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//
//  File				:	texture3d.cpp
//  Classes				:	CTexture3d
//  Description			:	Implementation - George
//
////////////////////////////////////////////////////////////////////////
#include "texture3d.h"
#include "error.h"
#include "renderer.h"
#include "displayChannel.h"

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	CTexture3d
// Description			:	Ctor
// Return Value			:	-
// Comments				:
CTexture3d::CTexture3d(const char *n,const float *f,const float *t,int nc,CTexture3dChannel *ch) : CFileResource(n) {
	dataSize	=	0;
	channels	=	NULL;
	numChannels	=	0;
	movmm(from,f);
	movmm(to,t);
	dPscale		=	pow(fabs(determinantm(to)),1.0f / 3.0f);

	if (nc > 0) {
		int	i;

		numChannels		=	nc;
		channels		=	new CTexture3dChannel[nc];
		memcpy(channels,ch,sizeof(CTexture3dChannel)*numChannels);
		for (i=0,dataSize=0;i<numChannels;i++)
			dataSize	+= channels[i].numSamples;
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	~CTexture3d
// Description			:	Dtor
// Return Value			:	-
// Comments				:
CTexture3d::~CTexture3d() {
	if (channels != NULL) delete [] channels;
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	defineChannels
// Description			:	Define the channels
// Return Value			:	-
// Comments				:
void CTexture3d::defineChannels(const char *channelDefinitions) {
	char				*nextComma,*sampleName,*tmp;
	CDisplayChannel		*oChannel;

	// This is used by remote channels
	// The channel definitions will be loaded when
	// creating the remote channel
	if (channelDefinitions == NULL) return;

	// determinte the channels
	numChannels		=	1;
	dataSize		=	0;

	const char	*sd = channelDefinitions;
	while ((sd = strchr(sd,',')) != NULL) {
		sd++;
		numChannels++;
	}
	channels		=	new CTexture3dChannel[numChannels];

	// parse the channels / sample types
	char *sampleDefinition = strdup(channelDefinitions); // duplicate to tokenize
	nextComma = sampleName = sampleDefinition;
	numChannels = 0;
	do {
		// parse to next comma, remove spaces
		nextComma = strchr(sampleName,',');
		if (nextComma != NULL) {
			for (tmp=nextComma-1;isspace(*tmp)&&(tmp>sampleName);tmp--) *tmp = '\0';
			*nextComma++ = '\0';
			while (isspace(*nextComma)) nextComma++;
		}
		while (isspace(*sampleName)) sampleName++;

		// is the sample name a channel we know about?
		oChannel = CRenderer::retrieveDisplayChannel(sampleName);
		if (oChannel != NULL) {
			// it's a predefined / already seen channel
			strcpy(channels[numChannels].name,oChannel->name);
			channels[numChannels].sampleStart		= dataSize;
			channels[numChannels].numSamples		= oChannel->numSamples;
			if (oChannel->variable != NULL)
				channels[numChannels].type			= oChannel->variable->type;
			else
				channels[numChannels].type			= TYPE_FLOAT;
			channels[numChannels].fill				= oChannel->fill;
			//GSHTODO: duplicate fill

			dataSize								+= oChannel->numSamples;
			numChannels++;
		} else  {
			error(CODE_BADTOKEN,"Unknown display channel \"%s\"\n",sampleName);
		}

		sampleName = nextComma;
	} while((sampleName != NULL) && (*sampleName != '\0'));

	free(sampleDefinition);
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	defineChannels
// Description			:	Define the channels
// Return Value			:	-
// Comments				:	used by ptcapi, does not require RiBegin()
void CTexture3d::defineChannels(int n,char **channelNames,char **channelTypes) {
	// determinte the channels
	dataSize		=	0;
	channels		=	new CTexture3dChannel[numChannels];

	// parse the channels / sample types
	numChannels = 0;
	for (int i=0;i<n;i++) {
		// parse to next comma, remove spaces

		CVariable var;
		if (parseVariable(&var,channelNames[i],channelTypes[i]) == TRUE) {

			// it's a predefined / already seen channel
			strcpy(channels[numChannels].name,channelNames[i]);
			channels[numChannels].sampleStart		= dataSize;
			channels[numChannels].numSamples		= var.numFloats;
			channels[numChannels].fill				= NULL;
			channels[numChannels].type				= var.type;
			//GSHTODO: deal with fill

			dataSize								+= var.numFloats;
			numChannels++;
		} else  {
			error(CODE_BADTOKEN,"Unable to interpret display channel name \"%s\"\n",channelNames[i]);
		}
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	writeChannels
// Description			:	Write the channels to file
// Return Value			:	-
// Comments				:
void CTexture3d::writeChannels(FILE *out) {
	// Write out the header and channels
	fwrite(&numChannels,sizeof(int),1,out);
	for (int i=0;i<numChannels;i++) {
		fwrite(&channels[i],sizeof(CTexture3dChannel),1,out);
		//GSHTODO:  deal with fill
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	readChannels
// Description			:	Read the channels from file
// Return Value			:	-
// Comments				:
void CTexture3d::readChannels(FILE *in) {
	if (channels != NULL)	delete [] channels;

	// Write out the header and channels
	fread(&numChannels,sizeof(int),1,in);
	channels = new CTexture3dChannel[numChannels];
	for (int i=0;i<numChannels;i++) {
		fread(&channels[i],sizeof(CTexture3dChannel),1,in);
		dataSize += channels[i].numSamples;
		//GSHTODO:  deal with fill
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	bindChannelNamess
// Description			:	Resolve the channel names
// Return Value			:	-
// Comments				:
int CTexture3d::bindChannelNames(int &n,const char **names,CTexture3dChannel ***bindings) {
	CTexture3dChannel	**entryPointers		= new CTexture3dChannel*[numChannels];
	int					numChannelsBound	= 0;
	int					i,j;

	for (i=0;i<n;i++) {
		for(j=0;j<numChannels;j++) {
			if (strcmp(names[i],channels[j].name) ==0) {
				entryPointers[numChannelsBound++] = &channels[j];
				break;
			}
		}
		if (j==numChannels) {
			error(CODE_BADTOKEN,"Unknown 3d texture channel \"%s\"\n",names[i]);
			bindings[i] = NULL;
		}
	}
	// zero unbound channels
	for (i=numChannelsBound;i<numChannels;i++) {
		bindings[i] = NULL;
	}
	n			= numChannelsBound;
	*bindings	= entryPointers;

	return dataSize;
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	prepareSample
// Description			:	prepareSample
// Return Value			:	-
// Comments				:
void CTexture3d::prepareSample(float *C,float **samples,CTexture3dChannel **bindings) {
	float *src,*dest;

	for (int i=0;i<numChannels;i++)	{
		CTexture3dChannel *binding = bindings[i];

		if (binding != NULL) {
			dest	= C + binding->sampleStart;
			src		= samples[i];
			for (int j=0;j<binding->numSamples;j++)
				*dest++ = *src++;
		} else {
			// GSHTODO : zero / fill the samples
		}
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	unpackSample
// Description			:	unpackSample
// Return Value			:	-
// Comments				:
void CTexture3d::unpackSample(float *C,float **samples,CTexture3dChannel **bindings) {
	float *src,*dest;

	for (int i=0;i<numChannels;i++)	{
		CTexture3dChannel *binding = bindings[i];
		if (binding != NULL) {
			src		= C + binding->sampleStart;
			dest	= samples[i];
			for (int j=0;j<binding->numSamples;j++)
				*dest++ = *src++;
		}
	}
}

///////////////////////////////////////////////////////////////////////
// Class				:	CTexture3d
// Method				:	unpackSample
// Description			:	unpackSample
// Return Value			:	-
// Comments				:
void CTexture3d::queryChannels(int *num,char **vartypes,char **varnames) {
	num[0] = numChannels;
	for (int i=0;i<numChannels;i++)	{
		strcpy(varnames[i],channels[i].name);
		switch(channels[i].type) {
			case TYPE_FLOAT:
				strcpy(vartypes[i],"float");
				break;
			case TYPE_COLOR:
				strcpy(vartypes[i],"color");
				break;
			case TYPE_VECTOR:
				strcpy(vartypes[i],"vector");
				break;
			case TYPE_NORMAL:
				strcpy(vartypes[i],"normal");
				break;
			case TYPE_POINT:
				strcpy(vartypes[i],"point");
				break;
			case TYPE_MATRIX:
				strcpy(vartypes[i],"matrix");
				break;
			default:
				error(CODE_BADTOKEN,"Unknown texture3d channel type\n");
		}
	}
}

<|endoftext|>