<commit_before>#include "equelle/RuntimeMPI.hpp"
#include <iostream>

#include <mpi.h>

#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <zoltan_cpp.h>
#pragma GCC diagnostic pop

#include <opm/core/grid/GridManager.hpp>
#include <boost/iterator/counting_iterator.hpp>

#include "EquelleRuntimeCPU.hpp"
#include "equelle/mpiutils.hpp"
#include "equelle/SubGridBuilder.hpp"

namespace equelle {

void RuntimeMPI::initializeZoltan()
{
    zoltan.reset( new Zoltan( MPI_COMM_WORLD ) );

    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "DEBUG_LEVEL", "0" ) );

#ifdef EQUELLE_DEBUG
    // Check that the query functions return valid input data; 0 or 1. (This slows performance; intended for debugging.)
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "CHECK_HYPERGRAPH", "1" ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "DEBUG_LEVEL", "2" ) );
#endif

    // Use hypergraph partitioning
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "LB_METHOD", "GRAPH" ) );
    // Partition everything without concern for cost.
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "LB_APPROACH", "PARTITION" ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "PHG_EDGE_SIZE_THRESHOLD", "1.0" ) );

}

void RuntimeMPI::initializeGrid()
{
    if ( getMPIRank() == 0 ) {
        globalGrid.reset( new Opm::GridManager( 6, 1 ) );
    } else {
        globalGrid.reset( new Opm::GridManager( 0, 0 ) );
    }
}

RuntimeMPI::RuntimeMPI()
{
    initializeZoltan();
    initializeGrid();
}

RuntimeMPI::~RuntimeMPI()
{
    // Zoltan resources must be deleted before we call MPI_Finalize.
    zoltan.release();
}

void RuntimeMPI::decompose()
{
    auto zr = computePartition();
    std::vector<int> localCells;

    if ( getMPIRank() == 0 ) {
        // Node 0 must compute which cells not to export.
        std::set_difference( boost::counting_iterator<int>(0), boost::counting_iterator<int>( globalGrid->c_grid()->number_of_cells ),
                             zr.exportGlobalGids, zr.exportGlobalGids + zr.numExport, std::back_inserter( localCells ) );
    } else {
        localCells.resize( zr.numImport );
        std::copy_n( zr.importGlobalGids, zr.numImport, localCells.begin() );
    }

    subGrid = SubGridBuilder::build( globalGrid->c_grid(), localCells );
}

zoltanReturns RuntimeMPI::computePartition()
{
    zoltanReturns zr;
    void* grid;
    Opm::GridManager emptyGrid( 0, 0 );
    // Let non rank-0 nodes pass in the empty grid here.l

    if ( getMPIRank() == 0 ) {
        grid = const_cast<void*>( reinterpret_cast<const void*>( globalGrid->c_grid() ) );
    } else {
        grid = const_cast<void*>( reinterpret_cast<const void*>( emptyGrid.c_grid()) );
    }

    ZOLTAN_SAFE_CALL( zoltan->Set_Num_Obj_Fn( ZoltanGrid::getNumberOfObjects, grid ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Obj_List_Fn( ZoltanGrid::getCellList, grid ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Num_Edges_Multi_Fn( ZoltanGrid::getNumberOfEdgesMulti, grid ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Edge_List_Multi_Fn( ZoltanGrid::getEdgeListMulti, grid ) );

    ZOLTAN_SAFE_CALL(
                zoltan->LB_Partition( zr.changes,         /* 1 if partitioning was changed, 0 otherwise */
                                      zr.numGidEntries,   /* Number of integers used for a global ID */
                                      zr.numLidEntries,   /* Number of integers used for a local ID */
                                      zr.numImport,       /* Number of vertices to be sent to me */
                                      zr.importGlobalGids,/* Global IDs of vertices to be sent to me */
                                      zr.importLocalGids, /* Local IDs of vertices to be sent to me */
                                      zr.importProcs,     /* Process rank for source of each incoming vertex */
                                      zr.importToPart,    /* New partition for each incoming vertex */
                                      zr.numExport,       /* Number of vertices I must send to other processes*/
                                      zr.exportGlobalGids,/* Global IDs of the vertices I must send */
                                      zr.exportLocalGids, /* Local IDs of the vertices I must send */
                                      zr.exportProcs,     /* Process to which I send each of the vertices */
                                      zr.exportToPart ) );  /* Partition to which each vertex will belong */

    return zr;
}

} // namespace equlle
<commit_msg>RuntimeMPI::initializeGrid is consistent with grid loading.<commit_after>#include "equelle/RuntimeMPI.hpp"
#include <iostream>

#include <mpi.h>

#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <zoltan_cpp.h>
#pragma GCC diagnostic pop

#include <opm/core/grid/GridManager.hpp>
#include <boost/iterator/counting_iterator.hpp>

#include "EquelleRuntimeCPU.hpp"
#include "equelle/mpiutils.hpp"
#include "equelle/SubGridBuilder.hpp"

namespace equelle {

void RuntimeMPI::initializeZoltan()
{
    zoltan.reset( new Zoltan( MPI_COMM_WORLD ) );

    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "DEBUG_LEVEL", "0" ) );

#ifdef EQUELLE_DEBUG
    // Check that the query functions return valid input data; 0 or 1. (This slows performance; intended for debugging.)
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "CHECK_HYPERGRAPH", "1" ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "DEBUG_LEVEL", "2" ) );
#endif

    // Use hypergraph partitioning
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "LB_METHOD", "GRAPH" ) );
    // Partition everything without concern for cost.
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "LB_APPROACH", "PARTITION" ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Param( "PHG_EDGE_SIZE_THRESHOLD", "1.0" ) );

}

void RuntimeMPI::initializeGrid()
{
    globalGrid.reset( new Opm::GridManager( 6, 1 ) );

}

RuntimeMPI::RuntimeMPI()
{
    initializeZoltan();
    initializeGrid();
}

RuntimeMPI::~RuntimeMPI()
{
    // Zoltan resources must be deleted before we call MPI_Finalize.
    zoltan.release();
}

void RuntimeMPI::decompose()
{
    auto zr = computePartition();
    std::vector<int> localCells;

    if ( getMPIRank() == 0 ) {
        // Node 0 must compute which cells not to export.
        std::set_difference( boost::counting_iterator<int>(0), boost::counting_iterator<int>( globalGrid->c_grid()->number_of_cells ),
                             zr.exportGlobalGids, zr.exportGlobalGids + zr.numExport, std::back_inserter( localCells ) );
    } else {
        localCells.resize( zr.numImport );
        std::copy_n( zr.importGlobalGids, zr.numImport, localCells.begin() );
    }

    subGrid = SubGridBuilder::build( globalGrid->c_grid(), localCells );
}

zoltanReturns RuntimeMPI::computePartition()
{
    zoltanReturns zr;
    void* grid;
    Opm::GridManager emptyGrid( 0, 0 );
    // Let non rank-0 nodes pass in the empty grid here.l

    if ( getMPIRank() == 0 ) {
        grid = const_cast<void*>( reinterpret_cast<const void*>( globalGrid->c_grid() ) );
    } else {
        grid = const_cast<void*>( reinterpret_cast<const void*>( emptyGrid.c_grid()) );
    }

    ZOLTAN_SAFE_CALL( zoltan->Set_Num_Obj_Fn( ZoltanGrid::getNumberOfObjects, grid ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Obj_List_Fn( ZoltanGrid::getCellList, grid ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Num_Edges_Multi_Fn( ZoltanGrid::getNumberOfEdgesMulti, grid ) );
    ZOLTAN_SAFE_CALL( zoltan->Set_Edge_List_Multi_Fn( ZoltanGrid::getEdgeListMulti, grid ) );

    ZOLTAN_SAFE_CALL(
                zoltan->LB_Partition( zr.changes,         /* 1 if partitioning was changed, 0 otherwise */
                                      zr.numGidEntries,   /* Number of integers used for a global ID */
                                      zr.numLidEntries,   /* Number of integers used for a local ID */
                                      zr.numImport,       /* Number of vertices to be sent to me */
                                      zr.importGlobalGids,/* Global IDs of vertices to be sent to me */
                                      zr.importLocalGids, /* Local IDs of vertices to be sent to me */
                                      zr.importProcs,     /* Process rank for source of each incoming vertex */
                                      zr.importToPart,    /* New partition for each incoming vertex */
                                      zr.numExport,       /* Number of vertices I must send to other processes*/
                                      zr.exportGlobalGids,/* Global IDs of the vertices I must send */
                                      zr.exportLocalGids, /* Local IDs of the vertices I must send */
                                      zr.exportProcs,     /* Process to which I send each of the vertices */
                                      zr.exportToPart ) );  /* Partition to which each vertex will belong */

    return zr;
}

} // namespace equlle
<|endoftext|>


<commit_before>//
//  main.cpp
//  Euchre
//
//  Created by Dillon Hammond on 9/12/14.
//  Copyright (c) 2014 Learning. All rights reserved.
//

#define GLEW_STATIC
#include "GL/glew.h"
#include <SDL2/SDL.h>
#include "SOIL.h"
#define GLM_FORCE_RADIANS
#include "glm.hpp"
#include <iostream>
#include <fstream>
#include <vector>

GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) {

	// Create the shaders
	GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
	GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

	// Read the Vertex Shader code from the file
	std::string VertexShaderCode;
	std::ifstream VertexShaderStream;
	VertexShaderStream.open(vertex_file_path);
	if(VertexShaderStream.is_open()) {
		std::string Line = "";
		while(getline(VertexShaderStream, Line)) {
			VertexShaderCode += "\n" + Line;
		}
		VertexShaderStream.close();
	}

	// Read the Fragment Shader code from the file
	std::string FragmentShaderCode;
	std::ifstream FragmentShaderStream;
	FragmentShaderStream.open(fragment_file_path);
	if(FragmentShaderStream.is_open()){
		std::string Line = "";
		while(getline(FragmentShaderStream, Line)) {
			FragmentShaderCode += "\n" + Line;
		}
		FragmentShaderStream.close();
	}
	GLint Result;
	// Compile Vertex Shader
	const char* VertexSourcePointer = VertexShaderCode.c_str();
	glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
	glCompileShader(VertexShaderID);
	glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
		if (Result == GL_FALSE) {
			std::cout << "NOOOV" << std::endl;
			std::cout << VertexSourcePointer << std::endl;
		}

	// Compile Fragment Shader
	const char* FragmentSourcePointer = FragmentShaderCode.c_str();
	glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
	glCompileShader(FragmentShaderID);
	glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
		if (Result == GL_FALSE) {
			std::cout << "NOOOF" << std::endl;
			std::cout << FragmentSourcePointer << std::endl;
		}

	// Link the program
	GLuint ProgramID = glCreateProgram();
	glAttachShader(ProgramID, VertexShaderID);
	glAttachShader(ProgramID, FragmentShaderID);
	glLinkProgram(ProgramID);

	glDeleteShader(VertexShaderID);
	glDeleteShader(FragmentShaderID);

	return ProgramID;
}

SDL_Window* createWindow(const char* title, int x, int y, int w, int h, Uint32 flags) {
	SDL_Init(SDL_INIT_VIDEO);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_Window *window = SDL_CreateWindow(title, x, y, w, h, flags);
	return window;
}

void LoadTextures(std::vector<GLuint> textures, const char* filename, const char* texName, GLuint shaderProgram, int texNum) {
	int width, height;
	unsigned char* image;

	glActiveTexture(GL_TEXTURE0 + texNum);

	glBindTexture(GL_TEXTURE_2D, textures.at(texNum));
	image = SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
	SOIL_free_image_data(image);
	glUniform1i(glGetUniformLocation(shaderProgram, "backGround"), texNum);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

std::vector<float> LoadVertices(const char* file_path) {
	// Read Vertices in from a file
	std::vector<float> vertices;
	std::string fileCode;
	std::ifstream fileStream;
	fileStream.open(file_path);
	if(fileStream.is_open()) {
		std::string Line;
		while(getline(fileStream, Line, ',')) {
			fileCode = Line;
			float numRead = std::stof(fileCode);
			vertices.push_back(numRead);
		}
		fileStream.close();
	}
	return vertices;
}

int main() {
	SDL_Window* window = createWindow("Euchre", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
	SDL_GLContext context = SDL_GL_CreateContext(window);

	// Initialize GLEW
	glewExperimental = GL_TRUE;
	glewInit();

	// Initialize Depth Testing
//	glEnable(GL_DEPTH_TEST);

	// Create Vertex Array Object
	GLuint vao;
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	// Create a Vertex Buffer Object and copy the vertex data to it
	GLuint vbo;
	glGenBuffers(1, &vbo);

	std::vector<float> bgPosition = LoadVertices("./Resources/bgPosition.txt");
	std::vector<float> bgColor = LoadVertices("./Resources/bgColor.txt");
//	std::vector<float> bgTexture = LoadVertices("./Resources/bgTexture.txt");

	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER, bgPosition.size() * sizeof(float), &bgPosition.at(0), GL_STATIC_DRAW);

	// Create an element array
	GLuint ebo;
	glGenBuffers(1, &ebo);

	GLuint elements[] = { // Describes which set of points are drawn each time
		0, 1, 2,
		2, 3, 0
	};

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

	GLuint shaderProgram = LoadShaders("./Resources/vertexShader.txt", "./Resources/fragmentShader.txt");
	glUseProgram(shaderProgram);

	// Specify the layout of the vertex data
	GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
	glEnableVertexAttribArray(posAttrib);
	glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

	GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
	glEnableVertexAttribArray(colAttrib);
	glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_TRUE, 0, 0);

	/*
	GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
	glEnableVertexAttribArray(texAttrib);
	glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
	*/
	std::vector<GLuint> textures(1,0);
	glGenTextures(1, &textures.at(0));

//	LoadTextures(textures, "./Resources/Background.png", "backGround", shaderProgram, 0);

	SDL_Event windowEvent;
	while (true) {
		if (SDL_PollEvent(&windowEvent)) {
			if (windowEvent.type == SDL_QUIT) {
				break;
			}
		}

		// Clear the screen to black
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// Draw a rectangle from the 2 triangles using 6 indices
		glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(bgPosition.size()), GL_UNSIGNED_INT, 0);

		SDL_GL_SwapWindow(window);
	}
//	glDeleteTextures(static_cast<GLsizei>(textures.size()), &textures.at(0)); // Casted to remove warning about precision loss (this doesn't matter)

	glDeleteProgram(shaderProgram);

	glDeleteBuffers(1, &ebo);
	glDeleteBuffers(1, &vbo);

	glDeleteVertexArrays(1, &vao);

	SDL_GL_DeleteContext(context);
	return 0;
}<commit_msg>Draws white rectangle now, only texture doesn't work<commit_after>//
//  main.cpp
//  Euchre
//
//  Created by Dillon Hammond on 9/12/14.
//  Copyright (c) 2014 Learning. All rights reserved.
//

#define GLEW_STATIC
#include "GL/glew.h"
#include <SDL2/SDL.h>
#include "SOIL.h"
#define GLM_FORCE_RADIANS
#include "glm.hpp"
#include <iostream>
#include <fstream>
#include <vector>

GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) {

	// Create the shaders
	GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
	GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

	// Read the Vertex Shader code from the file
	std::string VertexShaderCode;
	std::ifstream VertexShaderStream;
	VertexShaderStream.open(vertex_file_path);
	if(VertexShaderStream.is_open()) {
		std::string Line = "";
		while(getline(VertexShaderStream, Line)) {
			VertexShaderCode += "\n" + Line;
		}
		VertexShaderStream.close();
	}

	// Read the Fragment Shader code from the file
	std::string FragmentShaderCode;
	std::ifstream FragmentShaderStream;
	FragmentShaderStream.open(fragment_file_path);
	if(FragmentShaderStream.is_open()){
		std::string Line = "";
		while(getline(FragmentShaderStream, Line)) {
			FragmentShaderCode += "\n" + Line;
		}
		FragmentShaderStream.close();
	}
	GLint Result;
	// Compile Vertex Shader
	const char* VertexSourcePointer = VertexShaderCode.c_str();
	glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
	glCompileShader(VertexShaderID);
	glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
		if (Result == GL_FALSE) {
			std::cout << "NOOOV" << std::endl;
			std::cout << VertexSourcePointer << std::endl;
		}

	// Compile Fragment Shader
	const char* FragmentSourcePointer = FragmentShaderCode.c_str();
	glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
	glCompileShader(FragmentShaderID);
	glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
		if (Result == GL_FALSE) {
			std::cout << "NOOOF" << std::endl;
			std::cout << FragmentSourcePointer << std::endl;
		}

	// Link the program
	GLuint ProgramID = glCreateProgram();
	glAttachShader(ProgramID, VertexShaderID);
	glAttachShader(ProgramID, FragmentShaderID);
	glLinkProgram(ProgramID);

	glDeleteShader(VertexShaderID);
	glDeleteShader(FragmentShaderID);

	return ProgramID;
}

SDL_Window* createWindow(const char* title, int x, int y, int w, int h, Uint32 flags) {
	SDL_Init(SDL_INIT_VIDEO);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
	SDL_Window *window = SDL_CreateWindow(title, x, y, w, h, flags);
	return window;
}

void LoadTextures(std::vector<GLuint> textures, const char* filename, const char* texName, GLuint shaderProgram, int texNum) {
	int width, height;
	unsigned char* image;

	glActiveTexture(GL_TEXTURE0 + texNum);

	glBindTexture(GL_TEXTURE_2D, textures.at(texNum));
	image = SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
	SOIL_free_image_data(image);
	glUniform1i(glGetUniformLocation(shaderProgram, "backGround"), texNum);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

std::vector<float> LoadVertices(const char* file_path) {
	// Read Vertices in from a file
	std::vector<float> vertices;
	std::string fileCode;
	std::ifstream fileStream;
	fileStream.open(file_path);
	if(fileStream.is_open()) {
		std::string Line;
		while(getline(fileStream, Line, ',')) {
			fileCode = Line;
			float numRead = std::stof(fileCode);
			vertices.push_back(numRead);
		}
		fileStream.close();
	}
	return vertices;
}

int main() {
	SDL_Window* window = createWindow("Euchre", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
	SDL_GLContext context = SDL_GL_CreateContext(window);

	// Initialize GLEW
	glewExperimental = GL_TRUE;
	glewInit();

	// Create Vertex Array Object
	GLuint vao;
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	// Create a Position Buffer Object and copy the vertex data to it
	GLuint positionBuffer;
	glGenBuffers(1, &positionBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);

	std::vector<float> bgPosition = LoadVertices("./Resources/bgPosition.txt");

	glBufferData(GL_ARRAY_BUFFER, bgPosition.size() * sizeof(float), &bgPosition.at(0), GL_STATIC_DRAW);

	// Create a Color Buffer Object and copy the vertex data to it
	GLuint colorBuffer;
	glGenBuffers(1, &colorBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);

	std::vector<float> bgColor = LoadVertices("./Resources/bgColor.txt");

	glBufferData(GL_ARRAY_BUFFER, bgColor.size() * sizeof(float), &bgColor.at(0), GL_STATIC_DRAW);

	// Create a Texture Buffer Object and copy the vertex data to it
	GLuint textureBuffer;
	glGenBuffers(1, &textureBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);

	std::vector<float> bgTexture = LoadVertices("./Resources/bgTexture.txt");

	glBufferData(GL_ARRAY_BUFFER, bgTexture.size() * sizeof(float), &bgTexture.at(0), GL_STATIC_DRAW);

	// Create an element array
	GLuint ebo;
	glGenBuffers(1, &ebo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

	GLuint elements[] = { // Describes which set of points are drawn each time
		0, 1, 2,
		2, 3, 0
	};

	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

	GLuint shaderProgram = LoadShaders("./Resources/vertexShader.txt", "./Resources/fragmentShader.txt");
	glUseProgram(shaderProgram);

	// Specify the layout of the vertex data
	GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
	glEnableVertexAttribArray(posAttrib);
	glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
	glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

	// Specify the color attributes
	GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
	glEnableVertexAttribArray(colAttrib);
	glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
	glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);

	// Specifiy the texture usage
	GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
	glEnableVertexAttribArray(texAttrib);
	glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
	glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

	std::vector<GLuint> textures(1,0);
	glGenTextures(1, &textures.at(0));

	LoadTextures(textures, "./Resources/Background.png", "backGround", shaderProgram, 0);

	SDL_Event windowEvent;
	while (true) {
		if (SDL_PollEvent(&windowEvent)) {
			if (windowEvent.type == SDL_QUIT) {
				break;
			}
		}

		// Clear the screen to black
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		// Draw a rectangle from the 2 triangles using 6 indices
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

		SDL_GL_SwapWindow(window);
	}
	glDeleteTextures(static_cast<GLsizei>(textures.size()), &textures.at(0)); // Casted to remove warning about precision loss (this doesn't matter)

	glDeleteProgram(shaderProgram);

	glDeleteBuffers(1, &ebo);
	glDeleteBuffers(1, &positionBuffer);

	glDeleteVertexArrays(1, &vao);

	SDL_GL_DeleteContext(context);
	return 0;
}<|endoftext|>


<commit_before>//
//  GuiObjectView.cpp
//  MusicPlayer
//
//  Created by Albert Zeyer on 23.01.14.
//  Copyright (c) 2014 Albert Zeyer. All rights reserved.
//

#include "QtBaseWidget.hpp"
#include "PyQtGuiObject.hpp"
#include "PythonHelpers.h"
#include "PyThreading.hpp"
#include <QThread>
#include <QApplication>

QtBaseWidget::ScopedRef::ScopedRef(const WeakRef& ref) : ptr(NULL), lock(true) {
   _ref = ref.ref.lock();
   if(_ref) {
	   lock = (QThread::currentThread() == qApp->thread());
	   if(lock) _ref->mutex.lock();
	   ptr = _ref->ptr;
   }
}

QtBaseWidget::ScopedRef::~ScopedRef() {
   if(_ref && lock)
	   _ref->mutex.unlock();
}

QtBaseWidget::~QtBaseWidget() {
	selfRef->reset();
	selfRef.reset();

	{
		PyScopedGIL gil;
		Py_CLEAR(controlRef);
	}
}

QtBaseWidget::QtBaseWidget(PyQtGuiObject* control) : QWidget(control->getParentWidget().scoped().ptr) {
	selfRef = boost::shared_ptr<LockedRef>(new LockedRef(*this));
	control->widget = QtBaseWidget::WeakRef(*this);

	resize(control->PresetSize.x, control->PresetSize.y);

	{
		PyScopedGIL gil;
		controlRef = (PyWeakReference*) PyWeakref_NewRef((PyObject*) control, NULL);
		canHaveFocus = attrChain_bool_default(control->attr, "canHaveFocus", false);
	}

	if(!controlRef)
		printf("QtBaseWidget: cannot create controlRef\n");

	if(canHaveFocus)
		this->setFocusPolicy(Qt::StrongFocus);
	else
		this->setFocusPolicy(Qt::NoFocus);

	//if(canHaveFocus)
	//	[self setDrawsBackground:YES];
}

PyQtGuiObject* QtBaseWidget::getControl() {
	PyQtGuiObject* control = (PyQtGuiObject*) PyWeakref_GET_OBJECT(controlRef);
	if(!control) return NULL;
	if(!PyType_IsSubtype(Py_TYPE(control), &QtGuiObject_Type)) {
		printf("QtBaseWidget: control is wrong type\n");
		return NULL;
	}
	Py_INCREF(control);
	return control;
}

/*
- (BOOL)becomeFirstResponder
{
	if(![super becomeFirstResponder]) return NO;
	[self setDrawsFocusRing:YES];
	//[self setBackgroundColor:[NSColor selectedTextBackgroundColor]];
	return YES;
}

- (BOOL)resignFirstResponder
{
	if(![super resignFirstResponder]) return NO;
	[self setDrawsFocusRing:NO];
	//[self setBackgroundColor:[NSColor textBackgroundColor]];
	return YES;
}
*/

void QtBaseWidget::mousePressEvent(QMouseEvent* ev) {
	QWidget::mousePressEvent(ev);

	PyScopedGIL gil;
	PyQtGuiObject* control = getControl();
	if(control) control->handleCurSelectedSong();
	Py_XDECREF(control);
}

/*
- (void)mouseDragged:(NSEvent *)ev
{
	bool res = false;

	PyGILState_STATE gstate = PyGILState_Ensure();
	CocoaGuiObject* control = [self getControl];
	PyObject* subjectObj = control ? control->subjectObject : NULL;
	Py_XINCREF(subjectObj);
	if(control && subjectObj) {
		// For example, if this is a Song object, we have the "url" attrib.
		PyObject* filename = PyObject_GetAttrString(subjectObj, "url");
		if(!filename) {
			if(PyErr_ExceptionMatches(PyExc_AttributeError))
				PyErr_Clear();
			else
				PyErr_Print();
		}
		int ret = filename ? PyObject_IsTrue(filename) : 0;
		if(ret < 0 && PyErr_Occurred())
			PyErr_Print();
		NSString* fn = (ret > 0) ? convertToStr(filename) : nil;
		if(fn) {
			NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
			[pboard declareTypes:@[NSFilenamesPboardType] owner:nil];
			[pboard setPropertyList:@[fn] forType:NSFilenamesPboardType];
			NSImage* dragImage = [[NSWorkspace sharedWorkspace] iconForFile:fn];
			NSPoint dragPosition = [self convertPoint:[ev locationInWindow] toView:nil];
			dragPosition.x -= 16;
			dragPosition.y += 32;

			[self
			 dragImage:dragImage
			 at:dragPosition
			 offset:NSZeroSize
			 event:ev
			 pasteboard:pboard
			 source:self
			 slideBack:NO];

			res = true;
		}
		Py_XDECREF(filename);
	}
	Py_XDECREF(subjectObj);
	Py_XDECREF(control);
	PyGILState_Release(gstate);

	if(!res)
		[super mouseDragged:ev];
}
*/

void QtBaseWidget::updateContent() {
	PyScopedGIL gil;

	PyObject* s = PyString_FromString("updateContent");
	Py_INCREF(this);
	PyObject* func = s ? PyObject_GenericGetAttr((PyObject*) this, s) : NULL;
	PyObject* res = func ? PyObject_CallFunction(func, NULL) : NULL;
	if(!res && PyErr_Occurred()) PyErr_Print();
	Py_XDECREF(s);
	Py_XDECREF(func);
	Py_XDECREF(res);
	Py_DECREF(this);
}

<commit_msg>stupid fix<commit_after>//
//  GuiObjectView.cpp
//  MusicPlayer
//
//  Created by Albert Zeyer on 23.01.14.
//  Copyright (c) 2014 Albert Zeyer. All rights reserved.
//

#include "QtBaseWidget.hpp"
#include "PyQtGuiObject.hpp"
#include "PythonHelpers.h"
#include "PyThreading.hpp"
#include <QThread>
#include <QApplication>

QtBaseWidget::ScopedRef::ScopedRef(const WeakRef& ref) : ptr(NULL), lock(true) {
   _ref = ref.ref.lock();
   if(_ref) {
	   lock = (QThread::currentThread() == qApp->thread());
	   if(lock) _ref->mutex.lock();
	   ptr = _ref->ptr;
   }
}

QtBaseWidget::ScopedRef::~ScopedRef() {
   if(_ref && lock)
	   _ref->mutex.unlock();
}

QtBaseWidget::~QtBaseWidget() {
	selfRef->reset();
	selfRef.reset();

	{
		PyScopedGIL gil;
		Py_CLEAR(controlRef);
	}
}

QtBaseWidget::QtBaseWidget(PyQtGuiObject* control) : QWidget(control->getParentWidget().scoped().ptr) {
	selfRef = boost::shared_ptr<LockedRef>(new LockedRef(*this));
	control->widget = QtBaseWidget::WeakRef(*this);

	resize(control->PresetSize.x, control->PresetSize.y);

	{
		PyScopedGIL gil;
		controlRef = (PyWeakReference*) PyWeakref_NewRef((PyObject*) control, NULL);
		canHaveFocus = attrChain_bool_default(control->attr, "canHaveFocus", false);
	}

	if(!controlRef)
		printf("QtBaseWidget: cannot create controlRef\n");

	if(canHaveFocus)
		this->setFocusPolicy(Qt::StrongFocus);
	else
		this->setFocusPolicy(Qt::NoFocus);

	//if(canHaveFocus)
	//	[self setDrawsBackground:YES];
}

PyQtGuiObject* QtBaseWidget::getControl() {
	PyQtGuiObject* control = (PyQtGuiObject*) PyWeakref_GET_OBJECT(controlRef);
	if(!control) return NULL;
	if(!PyType_IsSubtype(Py_TYPE(control), &QtGuiObject_Type)) {
		printf("QtBaseWidget: control is wrong type\n");
		return NULL;
	}
	Py_INCREF(control);
	return control;
}

/*
- (BOOL)becomeFirstResponder
{
	if(![super becomeFirstResponder]) return NO;
	[self setDrawsFocusRing:YES];
	//[self setBackgroundColor:[NSColor selectedTextBackgroundColor]];
	return YES;
}

- (BOOL)resignFirstResponder
{
	if(![super resignFirstResponder]) return NO;
	[self setDrawsFocusRing:NO];
	//[self setBackgroundColor:[NSColor textBackgroundColor]];
	return YES;
}
*/

void QtBaseWidget::mousePressEvent(QMouseEvent* ev) {
	QWidget::mousePressEvent(ev);

	PyScopedGIL gil;
	PyQtGuiObject* control = getControl();
	if(control) control->handleCurSelectedSong();
	Py_XDECREF(control);
}

/*
- (void)mouseDragged:(NSEvent *)ev
{
	bool res = false;

	PyGILState_STATE gstate = PyGILState_Ensure();
	CocoaGuiObject* control = [self getControl];
	PyObject* subjectObj = control ? control->subjectObject : NULL;
	Py_XINCREF(subjectObj);
	if(control && subjectObj) {
		// For example, if this is a Song object, we have the "url" attrib.
		PyObject* filename = PyObject_GetAttrString(subjectObj, "url");
		if(!filename) {
			if(PyErr_ExceptionMatches(PyExc_AttributeError))
				PyErr_Clear();
			else
				PyErr_Print();
		}
		int ret = filename ? PyObject_IsTrue(filename) : 0;
		if(ret < 0 && PyErr_Occurred())
			PyErr_Print();
		NSString* fn = (ret > 0) ? convertToStr(filename) : nil;
		if(fn) {
			NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
			[pboard declareTypes:@[NSFilenamesPboardType] owner:nil];
			[pboard setPropertyList:@[fn] forType:NSFilenamesPboardType];
			NSImage* dragImage = [[NSWorkspace sharedWorkspace] iconForFile:fn];
			NSPoint dragPosition = [self convertPoint:[ev locationInWindow] toView:nil];
			dragPosition.x -= 16;
			dragPosition.y += 32;

			[self
			 dragImage:dragImage
			 at:dragPosition
			 offset:NSZeroSize
			 event:ev
			 pasteboard:pboard
			 source:self
			 slideBack:NO];

			res = true;
		}
		Py_XDECREF(filename);
	}
	Py_XDECREF(subjectObj);
	Py_XDECREF(control);
	PyGILState_Release(gstate);

	if(!res)
		[super mouseDragged:ev];
}
*/

void QtBaseWidget::updateContent() {
	PyScopedGIL gil;

	PyObject* control = (PyObject*) getControl();
	if(!control) return;

	PyObject* s = PyString_FromString("updateContent");
	PyObject* func = s ? PyObject_GenericGetAttr(control, s) : NULL;
	PyObject* res = func ? PyObject_CallFunction(func, NULL) : NULL;
	if(!res && PyErr_Occurred()) PyErr_Print();
	Py_XDECREF(s);
	Py_XDECREF(func);
	Py_XDECREF(res);
	Py_DECREF(control);
}

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// Borrowed from Chromium's src/base/threading/thread_checker_unittest.cc.

#include <assert.h>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/base/scoped_ptr.h"

// Duplicated from base/threading/thread_checker.h so that we can be
// good citizens there and undef the macro.
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define ENABLE_THREAD_CHECKER 1
#else
#define ENABLE_THREAD_CHECKER 0
#endif

namespace rtc {

namespace {

// Simple class to exercise the basics of ThreadChecker.
// Both the destructor and DoStuff should verify that they were
// called on the same thread as the constructor.
class ThreadCheckerClass : public ThreadChecker {
 public:
  ThreadCheckerClass() {}

  // Verifies that it was called on the same thread as the constructor.
  void DoStuff() {
    assert(CalledOnValidThread());
  }

  void DetachFromThread() {
    ThreadChecker::DetachFromThread();
  }

  static void MethodOnDifferentThreadImpl();
  static void DetachThenCallFromDifferentThreadImpl();

 private:
  DISALLOW_COPY_AND_ASSIGN(ThreadCheckerClass);
};

// Calls ThreadCheckerClass::DoStuff on another thread.
class CallDoStuffOnThread : public Thread {
 public:
  explicit CallDoStuffOnThread(ThreadCheckerClass* thread_checker_class)
      : Thread(),
        thread_checker_class_(thread_checker_class) {
    SetName("call_do_stuff_on_thread", NULL);
  }

  virtual void Run() OVERRIDE {
    thread_checker_class_->DoStuff();
  }

  // New method. Needed since Thread::Join is protected, and it is called by
  // the TEST.
  void Join() {
    Thread::Join();
  }

 private:
  ThreadCheckerClass* thread_checker_class_;

  DISALLOW_COPY_AND_ASSIGN(CallDoStuffOnThread);
};

// Deletes ThreadCheckerClass on a different thread.
class DeleteThreadCheckerClassOnThread : public Thread {
 public:
  explicit DeleteThreadCheckerClassOnThread(
      ThreadCheckerClass* thread_checker_class)
      : Thread(),
        thread_checker_class_(thread_checker_class) {
    SetName("delete_thread_checker_class_on_thread", NULL);
  }

  virtual void Run() OVERRIDE {
    thread_checker_class_.reset();
  }

  // New method. Needed since Thread::Join is protected, and it is called by
  // the TEST.
  void Join() {
    Thread::Join();
  }

 private:
  scoped_ptr<ThreadCheckerClass> thread_checker_class_;

  DISALLOW_COPY_AND_ASSIGN(DeleteThreadCheckerClassOnThread);
};

}  // namespace

TEST(ThreadCheckerTest, CallsAllowedOnSameThread) {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // Verify that DoStuff doesn't assert.
  thread_checker_class->DoStuff();

  // Verify that the destructor doesn't assert.
  thread_checker_class.reset();
}

TEST(ThreadCheckerTest, DestructorAllowedOnDifferentThread) {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // Verify that the destructor doesn't assert
  // when called on a different thread.
  DeleteThreadCheckerClassOnThread delete_on_thread(
      thread_checker_class.release());

  delete_on_thread.Start();
  delete_on_thread.Join();
}

TEST(ThreadCheckerTest, DetachFromThread) {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // Verify that DoStuff doesn't assert when called on a different thread after
  // a call to DetachFromThread.
  thread_checker_class->DetachFromThread();
  CallDoStuffOnThread call_on_thread(thread_checker_class.get());

  call_on_thread.Start();
  call_on_thread.Join();
}

#if GTEST_HAS_DEATH_TEST || !ENABLE_THREAD_CHECKER

void ThreadCheckerClass::MethodOnDifferentThreadImpl() {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // DoStuff should assert in debug builds only when called on a
  // different thread.
  CallDoStuffOnThread call_on_thread(thread_checker_class.get());

  call_on_thread.Start();
  call_on_thread.Join();
}

#if ENABLE_THREAD_CHECKER
TEST(ThreadCheckerDeathTest, MethodNotAllowedOnDifferentThreadInDebug) {
  ASSERT_DEATH({
      ThreadCheckerClass::MethodOnDifferentThreadImpl();
    }, "");
}
#else
TEST(ThreadCheckerTest, MethodAllowedOnDifferentThreadInRelease) {
  ThreadCheckerClass::MethodOnDifferentThreadImpl();
}
#endif  // ENABLE_THREAD_CHECKER

void ThreadCheckerClass::DetachThenCallFromDifferentThreadImpl() {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // DoStuff doesn't assert when called on a different thread
  // after a call to DetachFromThread.
  thread_checker_class->DetachFromThread();
  CallDoStuffOnThread call_on_thread(thread_checker_class.get());

  call_on_thread.Start();
  call_on_thread.Join();

  // DoStuff should assert in debug builds only after moving to
  // another thread.
  thread_checker_class->DoStuff();
}

#if ENABLE_THREAD_CHECKER
TEST(ThreadCheckerDeathTest, DetachFromThreadInDebug) {
  ASSERT_DEATH({
    ThreadCheckerClass::DetachThenCallFromDifferentThreadImpl();
    }, "");
}
#else
TEST(ThreadCheckerTest, DetachFromThreadInRelease) {
  ThreadCheckerClass::DetachThenCallFromDifferentThreadImpl();
}
#endif  // ENABLE_THREAD_CHECKER

#endif  // GTEST_HAS_DEATH_TEST || !ENABLE_THREAD_CHECKER

// Just in case we ever get lumped together with other compilation units.
#undef ENABLE_THREAD_CHECKER

}  // namespace rtc
<commit_msg>Disable MethodNotAllowedOnDifferentThreadInDebug.<commit_after>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// Borrowed from Chromium's src/base/threading/thread_checker_unittest.cc.

#include <assert.h>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/base/scoped_ptr.h"

// Duplicated from base/threading/thread_checker.h so that we can be
// good citizens there and undef the macro.
#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#define ENABLE_THREAD_CHECKER 1
#else
#define ENABLE_THREAD_CHECKER 0
#endif

namespace rtc {

namespace {

// Simple class to exercise the basics of ThreadChecker.
// Both the destructor and DoStuff should verify that they were
// called on the same thread as the constructor.
class ThreadCheckerClass : public ThreadChecker {
 public:
  ThreadCheckerClass() {}

  // Verifies that it was called on the same thread as the constructor.
  void DoStuff() {
    assert(CalledOnValidThread());
  }

  void DetachFromThread() {
    ThreadChecker::DetachFromThread();
  }

  static void MethodOnDifferentThreadImpl();
  static void DetachThenCallFromDifferentThreadImpl();

 private:
  DISALLOW_COPY_AND_ASSIGN(ThreadCheckerClass);
};

// Calls ThreadCheckerClass::DoStuff on another thread.
class CallDoStuffOnThread : public Thread {
 public:
  explicit CallDoStuffOnThread(ThreadCheckerClass* thread_checker_class)
      : Thread(),
        thread_checker_class_(thread_checker_class) {
    SetName("call_do_stuff_on_thread", NULL);
  }

  virtual void Run() OVERRIDE {
    thread_checker_class_->DoStuff();
  }

  // New method. Needed since Thread::Join is protected, and it is called by
  // the TEST.
  void Join() {
    Thread::Join();
  }

 private:
  ThreadCheckerClass* thread_checker_class_;

  DISALLOW_COPY_AND_ASSIGN(CallDoStuffOnThread);
};

// Deletes ThreadCheckerClass on a different thread.
class DeleteThreadCheckerClassOnThread : public Thread {
 public:
  explicit DeleteThreadCheckerClassOnThread(
      ThreadCheckerClass* thread_checker_class)
      : Thread(),
        thread_checker_class_(thread_checker_class) {
    SetName("delete_thread_checker_class_on_thread", NULL);
  }

  virtual void Run() OVERRIDE {
    thread_checker_class_.reset();
  }

  // New method. Needed since Thread::Join is protected, and it is called by
  // the TEST.
  void Join() {
    Thread::Join();
  }

 private:
  scoped_ptr<ThreadCheckerClass> thread_checker_class_;

  DISALLOW_COPY_AND_ASSIGN(DeleteThreadCheckerClassOnThread);
};

}  // namespace

TEST(ThreadCheckerTest, CallsAllowedOnSameThread) {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // Verify that DoStuff doesn't assert.
  thread_checker_class->DoStuff();

  // Verify that the destructor doesn't assert.
  thread_checker_class.reset();
}

TEST(ThreadCheckerTest, DestructorAllowedOnDifferentThread) {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // Verify that the destructor doesn't assert
  // when called on a different thread.
  DeleteThreadCheckerClassOnThread delete_on_thread(
      thread_checker_class.release());

  delete_on_thread.Start();
  delete_on_thread.Join();
}

TEST(ThreadCheckerTest, DetachFromThread) {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // Verify that DoStuff doesn't assert when called on a different thread after
  // a call to DetachFromThread.
  thread_checker_class->DetachFromThread();
  CallDoStuffOnThread call_on_thread(thread_checker_class.get());

  call_on_thread.Start();
  call_on_thread.Join();
}

#if GTEST_HAS_DEATH_TEST || !ENABLE_THREAD_CHECKER

void ThreadCheckerClass::MethodOnDifferentThreadImpl() {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // DoStuff should assert in debug builds only when called on a
  // different thread.
  CallDoStuffOnThread call_on_thread(thread_checker_class.get());

  call_on_thread.Start();
  call_on_thread.Join();
}

#if ENABLE_THREAD_CHECKER
TEST(ThreadCheckerDeathTest,
     DISABLED_MethodNotAllowedOnDifferentThreadInDebug) {
  ASSERT_DEATH({
      ThreadCheckerClass::MethodOnDifferentThreadImpl();
    }, "");
}
#else
TEST(ThreadCheckerTest, MethodAllowedOnDifferentThreadInRelease) {
  ThreadCheckerClass::MethodOnDifferentThreadImpl();
}
#endif  // ENABLE_THREAD_CHECKER

void ThreadCheckerClass::DetachThenCallFromDifferentThreadImpl() {
  scoped_ptr<ThreadCheckerClass> thread_checker_class(
      new ThreadCheckerClass);

  // DoStuff doesn't assert when called on a different thread
  // after a call to DetachFromThread.
  thread_checker_class->DetachFromThread();
  CallDoStuffOnThread call_on_thread(thread_checker_class.get());

  call_on_thread.Start();
  call_on_thread.Join();

  // DoStuff should assert in debug builds only after moving to
  // another thread.
  thread_checker_class->DoStuff();
}

#if ENABLE_THREAD_CHECKER
TEST(ThreadCheckerDeathTest, DetachFromThreadInDebug) {
  ASSERT_DEATH({
    ThreadCheckerClass::DetachThenCallFromDifferentThreadImpl();
    }, "");
}
#else
TEST(ThreadCheckerTest, DetachFromThreadInRelease) {
  ThreadCheckerClass::DetachThenCallFromDifferentThreadImpl();
}
#endif  // ENABLE_THREAD_CHECKER

#endif  // GTEST_HAS_DEATH_TEST || !ENABLE_THREAD_CHECKER

// Just in case we ever get lumped together with other compilation units.
#undef ENABLE_THREAD_CHECKER

}  // namespace rtc
<|endoftext|>


<commit_before>
// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of ff_handler, a data handler for the OPeNDAP data
// server.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This 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 software 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
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// FFRequestHandler.cc

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <sstream>

using std::ostringstream;

#include "FFRequestHandler.h"

#include "config_ff.h"
#include "FFTypeFactory.h"
#include "ff_ce_functions.h"

#include "BESDASResponse.h"
#include "BESDDSResponse.h"
#include "BESDataDDSResponse.h"
#include "BESInfo.h"
#include "BESResponseNames.h"
#include "BESContainer.h"
#include "BESResponseHandler.h"
#include "BESVersionInfo.h"
#include "BESDataNames.h"

#include "BESHandlerException.h"

#include <DDS.h>
#include <Error.h>
#include <cgi_util.h>

long BufPtr = 0;                // cache pointer
long BufSiz = 0;                // Cache size
char *BufVal = NULL;            // cache buffer

extern void ff_read_descriptors(DDS & dds,
                                const string & filename) throw(Error);
extern void ff_get_attributes(DAS & das, string filename) throw(Error);

FFRequestHandler::FFRequestHandler(string name)
:  BESRequestHandler(name)
{
    add_handler(DAS_RESPONSE, FFRequestHandler::ff_build_das);
    add_handler(DDS_RESPONSE, FFRequestHandler::ff_build_dds);
    add_handler(DATA_RESPONSE, FFRequestHandler::ff_build_data);
    add_handler(HELP_RESPONSE, FFRequestHandler::ff_build_help);
    add_handler(VERS_RESPONSE, FFRequestHandler::ff_build_version);
}

FFRequestHandler::~FFRequestHandler()
{
}

bool FFRequestHandler::ff_build_das(BESDataHandlerInterface & dhi)
{
    BESDASResponse *bdas =
        dynamic_cast <
        BESDASResponse * >(dhi.response_handler->get_response_object());
    DAS *das = bdas->get_das();

    try {
        ff_get_attributes(*das, dhi.container->access());
        string name = find_ancillary_file(dhi.container->access(), "das", "", "");
        das->parse(name);
    }
    catch(Error & e) {
        ostringstream s;
        s << "libdap exception building Freeform DAS"
            << ": error_code = " << e.get_error_code()
            << ": " << e.get_error_message();
        BESHandlerException ex(s.str(), __FILE__, __LINE__);
        throw ex;
    }
    catch(...) {
        string s = "unknown exception caught building Freeform DAS";
        BESHandlerException ex(s, __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_dds(BESDataHandlerInterface & dhi)
{
    BESDDSResponse *bdds =
        dynamic_cast <
        BESDDSResponse * >(dhi.response_handler->get_response_object());
    DDS *dds = bdds->get_dds();
    ConstraintEvaluator & ce = bdds->get_ce();

    try {
        FFTypeFactory *factory = new FFTypeFactory;
        dds->set_factory(factory);

        ff_register_functions(ce);
        dds->filename(dhi.container->access());
        ff_read_descriptors(*dds, dhi.container->access());

        DAS das;
        ff_get_attributes(das, dhi.container->access());
        string name = find_ancillary_file(dhi.container->access(), "das", "", "");
        das.parse(name);

        dds->transfer_attributes(&das);

        dhi.data[POST_CONSTRAINT] = dhi.container->get_constraint();
#if 0
        // see ticket 720
        dds->set_factory(NULL);
        delete factory;
#endif
    }
    catch(Error & e) {
        ostringstream s;
        s << "libdap exception building Freeform DDS"
            << ": error_code = " << e.get_error_code()
            << ": " << e.get_error_message();
        BESHandlerException ex(s.str(), __FILE__, __LINE__);
        throw ex;
    }
    catch(...) {
        string s = "unknown exception caught building Freeform DDS";
        BESHandlerException ex(s, __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_data(BESDataHandlerInterface & dhi)
{
    BufPtr = 0;                 // cache pointer
    BufSiz = 0;                 // Cache size
    BufVal = NULL;              // cache buffer

    BESDataDDSResponse *bdds =
        dynamic_cast <
        BESDataDDSResponse *
        >(dhi.response_handler->get_response_object());
    DataDDS *dds = bdds->get_dds();
    ConstraintEvaluator & ce = bdds->get_ce();

    try {
        FFTypeFactory *factory = new FFTypeFactory;
        dds->set_factory(factory);

        ff_register_functions(ce);
        dds->filename(dhi.container->access());
        ff_read_descriptors(*dds, dhi.container->access());

        DAS das;
        ff_get_attributes(das, dhi.container->access());
        string name = find_ancillary_file(dds->filename(), "das", "", "");
        das.parse(name);

        dds->transfer_attributes(&das);

        dhi.data[POST_CONSTRAINT] = dhi.container->get_constraint();
#if 0
        // see ticket 720
        dds->set_factory(NULL);
        delete factory;
#endif
    }
    catch(Error & e) {
        ostringstream s;
        s << "libdap exception building Freeform DataDDS"
            << ": error_code = " << e.get_error_code()
            << ": " << e.get_error_message();
        BESHandlerException ex(s.str(), __FILE__, __LINE__);
        throw ex;
    }
    catch(...) {
        string s = "unknown exception caught building Freeform DataDDS";
        BESHandlerException ex(s, __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_help(BESDataHandlerInterface & dhi)
{
    BESInfo *info =
        (BESInfo *) dhi.response_handler->get_response_object();
    info->begin_tag("Handler");
    info->add_tag("name", PACKAGE_NAME);
    string handles = (string) DAS_RESPONSE + "," + DDS_RESPONSE
        + "," + DATA_RESPONSE + "," + HELP_RESPONSE + "," + VERS_RESPONSE;
    info->add_tag("handles", handles);
    info->add_tag("version", PACKAGE_STRING);
    info->end_tag("Handler");

    return true;
}

bool FFRequestHandler::ff_build_version(BESDataHandlerInterface & dhi)
{
    BESVersionInfo *info =
        (BESVersionInfo *) dhi.response_handler->get_response_object();
    info->addHandlerVersion(PACKAGE_NAME, PACKAGE_VERSION);
    return true;
}
<commit_msg>FFRequestHandler.cc: Fix for ticket 752. Files could not be read because I goofed when adding support for ancillary DAS files. The code added dis not test for the case where a file is not found. Now it does.<commit_after>
// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of ff_handler, a data handler for the OPeNDAP data
// server.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This 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 software 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
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// FFRequestHandler.cc

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <sstream>

using std::ostringstream;

#include "FFRequestHandler.h"

#include "config_ff.h"
#include "FFTypeFactory.h"
#include "ff_ce_functions.h"

#include "BESDASResponse.h"
#include "BESDDSResponse.h"
#include "BESDataDDSResponse.h"
#include "BESInfo.h"
#include "BESResponseNames.h"
#include "BESContainer.h"
#include "BESResponseHandler.h"
#include "BESVersionInfo.h"
#include "BESDataNames.h"

#include "BESHandlerException.h"

#include <DDS.h>
#include <Error.h>
#include <cgi_util.h>

long BufPtr = 0;                // cache pointer
long BufSiz = 0;                // Cache size
char *BufVal = NULL;            // cache buffer

extern void ff_read_descriptors(DDS & dds,
                                const string & filename) throw(Error);
extern void ff_get_attributes(DAS & das, string filename) throw(Error);

FFRequestHandler::FFRequestHandler(string name)
:  BESRequestHandler(name)
{
    add_handler(DAS_RESPONSE, FFRequestHandler::ff_build_das);
    add_handler(DDS_RESPONSE, FFRequestHandler::ff_build_dds);
    add_handler(DATA_RESPONSE, FFRequestHandler::ff_build_data);
    add_handler(HELP_RESPONSE, FFRequestHandler::ff_build_help);
    add_handler(VERS_RESPONSE, FFRequestHandler::ff_build_version);
}

FFRequestHandler::~FFRequestHandler()
{
}

bool FFRequestHandler::ff_build_das(BESDataHandlerInterface & dhi)
{
    BESDASResponse *bdas =
        dynamic_cast <
        BESDASResponse * >(dhi.response_handler->get_response_object());
    DAS *das = bdas->get_das();

    try {
        ff_get_attributes(*das, dhi.container->access());
        string name = find_ancillary_file(dhi.container->access(), "das", "", "");
        if (!name.empty())
            das->parse(name);
    }
    catch(Error & e) {
        ostringstream s;
        s << "libdap exception building Freeform DAS"
            << ": error_code = " << e.get_error_code()
            << ": " << e.get_error_message();
        BESHandlerException ex(s.str(), __FILE__, __LINE__);
        throw ex;
    }
    catch(...) {
        string s = "unknown exception caught building Freeform DAS";
        BESHandlerException ex(s, __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_dds(BESDataHandlerInterface & dhi)
{
    BESDDSResponse *bdds =
        dynamic_cast <
        BESDDSResponse * >(dhi.response_handler->get_response_object());
    DDS *dds = bdds->get_dds();
    ConstraintEvaluator & ce = bdds->get_ce();

    try {
        FFTypeFactory *factory = new FFTypeFactory;
        dds->set_factory(factory);

        ff_register_functions(ce);
        dds->filename(dhi.container->access());
        ff_read_descriptors(*dds, dhi.container->access());

        DAS das;
        ff_get_attributes(das, dhi.container->access());
        string name = find_ancillary_file(dhi.container->access(), "das", "", "");
        if (!name.empty())
            das.parse(name);

        dds->transfer_attributes(&das);

        dhi.data[POST_CONSTRAINT] = dhi.container->get_constraint();
#if 0
        // see ticket 720
        dds->set_factory(NULL);
        delete factory;
#endif
    }
    catch(Error & e) {
        ostringstream s;
        s << "libdap exception building Freeform DDS"
            << ": error_code = " << e.get_error_code()
            << ": " << e.get_error_message();
        BESHandlerException ex(s.str(), __FILE__, __LINE__);
        throw ex;
    }
    catch(...) {
        string s = "unknown exception caught building Freeform DDS";
        BESHandlerException ex(s, __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_data(BESDataHandlerInterface & dhi)
{
    BufPtr = 0;                 // cache pointer
    BufSiz = 0;                 // Cache size
    BufVal = NULL;              // cache buffer

    BESDataDDSResponse *bdds =
        dynamic_cast <
        BESDataDDSResponse *
        >(dhi.response_handler->get_response_object());
    DataDDS *dds = bdds->get_dds();
    ConstraintEvaluator & ce = bdds->get_ce();

    try {
        FFTypeFactory *factory = new FFTypeFactory;
        dds->set_factory(factory);

        ff_register_functions(ce);
        dds->filename(dhi.container->access());
        ff_read_descriptors(*dds, dhi.container->access());

        DAS das;
        ff_get_attributes(das, dhi.container->access());
        string name = find_ancillary_file(dds->filename(), "das", "", "");
        if (!name.empty())
            das.parse(name);

        dds->transfer_attributes(&das);

        dhi.data[POST_CONSTRAINT] = dhi.container->get_constraint();
#if 0
        // see ticket 720
        dds->set_factory(NULL);
        delete factory;
#endif
    }
    catch(Error & e) {
        ostringstream s;
        s << "libdap exception building Freeform DataDDS"
            << ": error_code = " << e.get_error_code()
            << ": " << e.get_error_message();
        BESHandlerException ex(s.str(), __FILE__, __LINE__);
        throw ex;
    }
    catch(...) {
        string s = "unknown exception caught building Freeform DataDDS";
        BESHandlerException ex(s, __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_help(BESDataHandlerInterface & dhi)
{
    BESInfo *info =
        (BESInfo *) dhi.response_handler->get_response_object();
    info->begin_tag("Handler");
    info->add_tag("name", PACKAGE_NAME);
    string handles = (string) DAS_RESPONSE + "," + DDS_RESPONSE
        + "," + DATA_RESPONSE + "," + HELP_RESPONSE + "," + VERS_RESPONSE;
    info->add_tag("handles", handles);
    info->add_tag("version", PACKAGE_STRING);
    info->end_tag("Handler");

    return true;
}

bool FFRequestHandler::ff_build_version(BESDataHandlerInterface & dhi)
{
    BESVersionInfo *info =
        (BESVersionInfo *) dhi.response_handler->get_response_object();
    info->addHandlerVersion(PACKAGE_NAME, PACKAGE_VERSION);
    return true;
}
<|endoftext|>


<commit_before>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2015 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
**    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
**      disclaimer.
**    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
**      following disclaimer in the documentation and/or other materials provided with the distribution.
**    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
**      derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
***********************************************************************************************************************/

#include "APIPrinter.h"

#include "Config.h"

APIPrinter::APIPrinter()
{
	// Create out file
	if (!outFile_.open(QIODevice::WriteOnly | QIODevice::Text)) Q_ASSERT(false);
	out_.setDevice(&outFile_);

	maxLineLength_ = Config::instance().maxLineLength();
}

APIPrinter::~APIPrinter()
{
	outFile_.close();
}

void APIPrinter::print()
{
	printLicense();
	out_ << "// GENERATED FILE: CHANGES WILL BE LOST!" << endl;
	out_ << endl;
	printHeaders();
	out_ << "namespace InformationScripting {" << endl << endl;
	out_ << "using namespace boost::python;" << endl << endl;
	out_ << "BOOST_PYTHON_MODULE(AstApi) {" << endl << endl;
	printClasses();
	printTypedListWrappers();
	out_ << endl << "}" << endl;
	out_ << endl << "} /* namespace InformationScripting */" << endl;
}

void APIPrinter::printLicense()
{
	auto licensePath = Config::instance().envisionReadPath() + "LICENSE";
	QFile licenseFile(licensePath);
	bool open = licenseFile.open(QIODevice::ReadOnly);
	Q_ASSERT(open);
	out_ << licenseFile.readAll() << endl;
}

void APIPrinter::printHeaders()
{
	for (QString includePath : APIData::instance().includePaths_)
		out_ << "#include \"" << includePath << "\"" << endl;
	out_ << endl;
}

void APIPrinter::printClasses()
{
	for (const auto& cData : APIData::instance().classes()) printClass(cData);
}

void APIPrinter::printClass(const ClassData& cData)
{
	// each class gets it's own scope:
	out_ << "{" << endl;
	indent();
	if (!cData.usingAlias_.isNull())
		out_ << indent_ << "using " << cData.usingAlias_ << " = " << cData.qualifiedName_ << ";" << endl;

	for (const auto& overload : cData.overloadAliases_)
		printOverload(overload);

	QString classString;
	if (cData.enums_.size()) // We only need a scope variable if we have enums
		classString = QString("scope %1scope = ").arg(cData.className_);
	classString += "class_<" + cData.qualifiedName_;
	// print bases:
	if (cData.baseClasses_.size())
		classString += ", bases<" + cData.baseClasses_.join(", ") + ">";
	else if (cData.abstract_)
		classString += ", boost::noncopyable";
	classString += ">";
	// print name:
	classString += "(\"" + cData.className_ + "\"";
	// TODO print constructors:
	if (cData.abstract_) // abstract classes have no constructor
		classString += ", no_init";
	classString += ")";
	printPossiblyLongString(classString);

	// printProperties
	indent();
	int propertyCount = cData.attributes_.size();
	if (propertyCount > 0)
	{
		out_ << endl;
		for (int i = 0; i < propertyCount - 1; ++i)
		{
			printAttribute(cData.attributes_[i]);
			out_ << endl;
		}
		printAttribute(cData.attributes_[propertyCount-1]);
	}
	int methodCount = cData.methods_.size();
	if (methodCount> 0)
	{
		out_ << endl;
		for (int i = 0; i < methodCount - 1; ++i)
		{
			printMethod(cData.methods_[i]);
			out_ << endl;
		}
		printMethod(cData.methods_[methodCount-1]);
	}
	out_ << ";" << endl;
	unIndent();

	printEnumsOfClass(cData);
	// close scope
	unIndent();
	out_ << "}" << endl << endl;
}

void APIPrinter::printOverload(const OverloadDescriptor& overload)
{
	printPossiblyLongString(QString("%1 = %2;\n").arg(overload.signature_, overload.functionAddress_));
}

void APIPrinter::printEnumsOfClass(const ClassData& cData)
{
	for (const auto& eData : cData.enums_) printEnum(eData);
}

void APIPrinter::printEnum(const EnumData& eData)
{
	out_ << indent_ <<"enum_<" << eData.qualifiedName_ << ">(\"" << eData.enumName_ << "\")";
	indent();
	int valueCount = eData.values_.size();
	if (valueCount > 0)
	{
		out_ << endl;
		for (int i = 0; i < valueCount - 1; ++i)
		{
			auto enumConstant = eData.values_[i];
			QString enumValue = ".value(\"" + enumConstant.first + "\", " + enumConstant.second + ")";
			printPossiblyLongString(enumValue);
			out_ << endl;
		}
		auto enumConstant = eData.values_[valueCount-1];
		QString enumValue = ".value(\"" + enumConstant.first + "\", " + enumConstant.second + ")";
		printPossiblyLongString(enumValue, 1);
	}
	out_ << ";" << endl;
	unIndent();
}

void APIPrinter::printAttribute(const ClassAttribute& attr)
{
	out_ << indent_ << ".add_property(\"" << attr.name_ << "\"," << endl;
	indent();
	printPossiblyLongString(attr.getterQualified_ + ",");
	out_ << endl;
	out_ << indent_ << attr.setterQualified_ << ")";
	unIndent();
}

void APIPrinter::printMethod(const ClassMethod& method)
{
	printPossiblyLongString(QString(".def(\"%1\", %2)").arg(method.name_, method.wrappedFunctionPointer_));
	if (method.static_)
		out_ << endl << indent_ << ".staticmethod(\"" << method.name_ << "\")";
}

void APIPrinter::printTypedListWrappers()
{
	auto typedLists = APIData::instance().typedLists();
	if (typedLists.empty()) return;

	out_ << "{" << endl;
	indent();
	for (auto it = typedLists.begin(); it != typedLists.end(); ++it)
	{
		out_ << indent_ << "using " << it.value() << " = " << it.key() << ";" << endl;
		out_ << indent_ << "class_<" << it.key() << ">" << "(\"" << it.value() << "\")" << endl;
		indent();
		out_ << indent_ << ".def(\"__len__\", &" << it.value() << "::size)" << endl;
		out_ << indent_ << ".def(\"__iter__\", iterator<" << it.value() << ", return_internal_reference<>>())";
		out_ << ";" << endl << endl;
		unIndent();
	}
	unIndent();
	out_ << "}" << endl;
}

void APIPrinter::printPossiblyLongString(const QString& data, int additionalLength)
{
	static const QList<QChar> splitSymbols{' ', ',', '(', '='};
	if (data.length() + indent_.length() + additionalLength > maxLineLength_)
	{
		int mid = maxLineLength_ / 2;
		int offset = 1;
		// Search for a position nearest to mid to split:
		while (std::abs(offset) < mid)
		{
			if (splitSymbols.contains(data.at(mid + offset))) break;
			if (offset > 0) offset *= -1;
			else offset = offset * -1 + 1;
		}
		int splitIndex = mid + offset;
		QString firstPart = data.mid(0, splitIndex + 1);
		QString secondPart = data.mid(splitIndex + 1);

		printPossiblyLongString(firstPart.trimmed() + "\n");
		printPossiblyLongString("\t" + secondPart);
	}
	else
	{
		out_ << indent_ << data;
	}
}

void APIPrinter::indent()
{
	indent_.append('\t');
}

void APIPrinter::unIndent()
{
	indent_.remove(indent_.size()-1, 1);
}
<commit_msg>Refactor: clean APIPrinter code<commit_after>/***********************************************************************************************************************
**
** Copyright (c) 2011, 2015 ETH Zurich
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
** following conditions are met:
**
**    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
**      disclaimer.
**    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
**      following disclaimer in the documentation and/or other materials provided with the distribution.
**    * Neither the name of the ETH Zurich nor the names of its contributors may be used to endorse or promote products
**      derived from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
***********************************************************************************************************************/

#include "APIPrinter.h"

#include "Config.h"

APIPrinter::APIPrinter()
{
	// Create out file
	if (!outFile_.open(QIODevice::WriteOnly | QIODevice::Text)) Q_ASSERT(false);
	out_.setDevice(&outFile_);

	maxLineLength_ = Config::instance().maxLineLength();
}

APIPrinter::~APIPrinter()
{
	outFile_.close();
}

void APIPrinter::print()
{
	printLicense();
	out_ << "// GENERATED FILE: CHANGES WILL BE LOST!" << endl << endl;
	printHeaders();
	out_ << "namespace InformationScripting {" << endl << endl;
	out_ << "using namespace boost::python;" << endl << endl;
	out_ << "BOOST_PYTHON_MODULE(AstApi) {" << endl << endl;
	printClasses();
	printTypedListWrappers();
	out_ << endl << "}" << endl;
	out_ << endl << "} /* namespace InformationScripting */" << endl;
}

void APIPrinter::printLicense()
{
	auto licensePath = Config::instance().envisionReadPath() + "LICENSE";
	QFile licenseFile(licensePath);
	bool open = licenseFile.open(QIODevice::ReadOnly);
	Q_ASSERT(open);
	out_ << licenseFile.readAll() << endl;
}

void APIPrinter::printHeaders()
{
	for (const QString& includePath : APIData::instance().includePaths_)
		out_ << QString("#include \"%1\"").arg(includePath) << endl;
	out_ << endl;
}

void APIPrinter::printClasses()
{
	for (const auto& cData : APIData::instance().classes()) printClass(cData);
}

void APIPrinter::printClass(const ClassData& cData)
{
	// each class gets it's own scope:
	out_ << "{" << endl;
	indent();
	if (!cData.usingAlias_.isNull())
		out_ << indent_ << "using " << cData.usingAlias_ << " = " << cData.qualifiedName_ << ";" << endl;

	for (const auto& overload : cData.overloadAliases_)
		printOverload(overload);

	QString classString = "";
	if (cData.enums_.size()) // We only need a scope variable if we have enums
		classString = QString("scope %1scope = ").arg(cData.className_);
	// print bases:
	QString basesString = "";
	if (cData.baseClasses_.size())
		basesString = QString(", bases<%1>").arg(cData.baseClasses_.join(", "));
	else if (cData.abstract_)
		basesString = ", boost::noncopyable";

	QString noInit = "";
	if (cData.abstract_) noInit = ", no_init";
	classString += QString("class_<%1%2>(\"%3\"%4)").arg(cData.qualifiedName_, basesString, cData.className_, noInit);

	printPossiblyLongString(classString);

	indent();
	for (const auto& attribute : cData.attributes_)
		printAttribute(attribute);
	for (const auto& method : cData.methods_)
		printMethod(method);
	out_ << ";" << endl;
	unIndent();

	printEnumsOfClass(cData);
	// close scope
	unIndent();
	out_ << "}" << endl << endl;
}

void APIPrinter::printOverload(const OverloadDescriptor& overload)
{
	printPossiblyLongString(QString("%1 = %2;\n").arg(overload.signature_, overload.functionAddress_));
}

void APIPrinter::printEnumsOfClass(const ClassData& cData)
{
	for (const auto& eData : cData.enums_) printEnum(eData);
}

void APIPrinter::printEnum(const EnumData& eData)
{
	out_ << indent_ <<"enum_<" << eData.qualifiedName_ << ">(\"" << eData.enumName_ << "\")";
	indent();
	for (const auto& enumConstant : eData.values_)
	{
		out_ << endl;
		printPossiblyLongString(QString(".value(\"%1\", %2)").arg(enumConstant.first, enumConstant.second));
	}
	out_ << ";" << endl;
	unIndent();
}

void APIPrinter::printAttribute(const ClassAttribute& attr)
{
	out_ << endl << indent_ << ".add_property(\"" << attr.name_ << "\"," << endl;
	indent();
	printPossiblyLongString(attr.getterQualified_ + ",");
	out_ << endl;
	out_ << indent_ << attr.setterQualified_ << ")";
	unIndent();
}

void APIPrinter::printMethod(const ClassMethod& method)
{
	out_ << endl;
	printPossiblyLongString(QString(".def(\"%1\", %2)").arg(method.name_, method.wrappedFunctionPointer_));
	if (method.static_)
		out_ << endl << indent_ << ".staticmethod(\"" << method.name_ << "\")";
}

void APIPrinter::printTypedListWrappers()
{
	auto typedLists = APIData::instance().typedLists();
	if (typedLists.empty()) return;

	out_ << "{" << endl;
	indent();
	for (auto it = typedLists.begin(); it != typedLists.end(); ++it)
	{
		out_ << indent_ << "using " << it.value() << " = " << it.key() << ";" << endl;
		out_ << indent_ << "class_<" << it.key() << ">" << "(\"" << it.value() << "\")" << endl;
		indent();
		out_ << indent_ << ".def(\"__len__\", &" << it.value() << "::size)" << endl;
		out_ << indent_ << ".def(\"__iter__\", iterator<" << it.value() << ", return_internal_reference<>>())";
		out_ << ";" << endl << endl;
		unIndent();
	}
	unIndent();
	out_ << "}" << endl;
}

void APIPrinter::printPossiblyLongString(const QString& data, int additionalLength)
{
	static const QList<QChar> splitSymbols{' ', ',', '(', '='};
	if (data.length() + indent_.length() + additionalLength > maxLineLength_)
	{
		int mid = maxLineLength_ / 2;
		int offset = 1;
		// Search for a position nearest to mid to split:
		while (std::abs(offset) < mid)
		{
			if (splitSymbols.contains(data.at(mid + offset))) break;
			if (offset > 0) offset *= -1;
			else offset = offset * -1 + 1;
		}
		int splitIndex = mid + offset;
		QString firstPart = data.mid(0, splitIndex + 1);
		QString secondPart = data.mid(splitIndex + 1);

		printPossiblyLongString(firstPart.trimmed() + "\n");
		printPossiblyLongString("\t" + secondPart);
	}
	else
	{
		out_ << indent_ << data;
	}
}

void APIPrinter::indent()
{
	indent_.append('\t');
}

void APIPrinter::unIndent()
{
	indent_.remove(indent_.size()-1, 1);
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    SurfacePlusEdges.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

// This test draws a stick with non-finite values.  The topology of the stick is
// as follows.
//
//  +---+  INF  Red
//  |   |
//  +---+  1.0  Red
//  |   |
//  +---+  0.5  Green
//  |   |
//  +---+  NAN  Magenta
//  |   |
//  +---+  0.5  Green
//  |   |
//  +---+  0.0  Blue
//  |   |
//  +---+  -INF Blue
//
// These values are mapped to the spectrum colors from blue (low) to red (high).
// -INF should be blue, INF should be red.  Since these are near extrema,
// whatever interpolation used should be constant.  NAN should be drawn as
// magenta.  The interpolation to NAN is ill defined in a texture map.  I would
// expect a sharp transition to the NAN color, but that might depend on graphics
// hardware.

#include "vtkActor.h"
#include "vtkCellArray.h"
#include "vtkColorTransferFunction.h"
#include "vtkDiscretizableColorTransferFunction.h"
#include "vtkDoubleArray.h"
#include "vtkLookupTable.h"
#include "vtkLogLookupTable.h"
#include "vtkMath.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"

#include "vtkSmartPointer.h"
#define VTK_CREATE(type, var) \
  vtkSmartPointer<type> var = vtkSmartPointer<type>::New()

// Create the data described above.
static vtkSmartPointer<vtkPolyData> CreateData()
{
  const int cellsHigh = 6;
  const int pointsHigh = cellsHigh + 1;
  const double pointValues[pointsHigh] = {
    vtkMath::NegInf(), 0.0, 0.5, vtkMath::Nan(), 0.5, 1.0, vtkMath::Inf()
  };

  VTK_CREATE(vtkPolyData, polyData);

  VTK_CREATE(vtkPoints, points);
  for (int y = 0; y < pointsHigh; y++)
    {
    for (int x = 0; x < 2; x++)
      {
      points->InsertNextPoint(static_cast<double>(x),
                              static_cast<double>(y), 0.0);
      }
    }
  polyData->SetPoints(points);

  VTK_CREATE(vtkCellArray, cells);
  for (int c = 0; c < cellsHigh; c++)
    {
    cells->InsertNextCell(4);
    cells->InsertCellPoint(2*c);
    cells->InsertCellPoint(2*c+1);
    cells->InsertCellPoint(2*c+3);
    cells->InsertCellPoint(2*c+2);
    }
  polyData->SetPolys(cells);

  VTK_CREATE(vtkDoubleArray, scalars);
  for (int height = 0; height < pointsHigh; height++)
    {
    scalars->InsertNextTuple1(pointValues[height]);
    scalars->InsertNextTuple1(pointValues[height]);
    }
  polyData->GetPointData()->SetScalars(scalars);

  return polyData;
}

static vtkSmartPointer<vtkLookupTable> CreateLookupTable()
{
  VTK_CREATE(vtkLookupTable, lut);

  lut->SetRampToLinear();
  lut->SetScaleToLinear();
  lut->SetTableRange(0.0, 1.0);
  lut->SetHueRange(0.6, 0.0);
  lut->SetNanColor(1.0, 0.0, 1.0, 1.0);

  return lut;
}

static vtkSmartPointer<vtkLogLookupTable> CreateLogLookupTable()
{
  VTK_CREATE(vtkLogLookupTable, lut);

  lut->SetRampToLinear();
  lut->SetScaleToLinear();
  lut->SetTableRange(0.0, 1.0);
  lut->SetHueRange(0.6, 0.0);
  lut->SetNanColor(1.0, 0.0, 1.0, 1.0);

  return lut;
}

static vtkSmartPointer<vtkColorTransferFunction> CreateColorTransferFunction()
{
  VTK_CREATE(vtkColorTransferFunction, ctf);

  ctf->SetColorSpaceToHSV();
  ctf->HSVWrapOff();
  ctf->AddHSVSegment(0.0, 0.6, 1.0, 1.0,
                     1.0, 0.0, 1.0, 1.0);
  ctf->SetNanColor(1.0, 0.0, 1.0);

  return ctf;
}

static vtkSmartPointer<vtkDiscretizableColorTransferFunction> CreateDiscretizableColorTransferFunction()
{
  VTK_CREATE(vtkDiscretizableColorTransferFunction, ctf);

  ctf->DiscretizeOn();
  ctf->SetColorSpaceToHSV();
  ctf->HSVWrapOff();
  ctf->AddHSVSegment(0.0, 0.6, 1.0, 1.0,
                     1.0, 0.0, 1.0, 1.0);
  ctf->SetNanColor(1.0, 0.0, 1.0);
  ctf->Build();

  return ctf;
}

static vtkSmartPointer<vtkRenderer> CreateRenderer(vtkPolyData *input,
                                                   vtkScalarsToColors *lut,
                                                   int interpolate)
{
  VTK_CREATE(vtkPolyDataMapper, mapper);
  mapper->SetInputData(input);
  mapper->SetLookupTable(lut);
  mapper->SetInterpolateScalarsBeforeMapping(interpolate);

  VTK_CREATE(vtkActor, actor);
  actor->SetMapper(mapper);

  VTK_CREATE(vtkRenderer, renderer);
  renderer->AddActor(actor);
  renderer->ResetCamera();

  return renderer;
}

const int NUM_RENDERERS = 8;
static void AddRenderer(vtkRenderer *renderer, vtkRenderWindow *renwin)
{
  static int rencount = 0;
  renderer->SetViewport(static_cast<double>(rencount)/NUM_RENDERERS, 0.0,
                        static_cast<double>(rencount+1)/NUM_RENDERERS, 1.0);
  renwin->AddRenderer(renderer);
  rencount++;
}

int RenderNonFinite(int argc, char *argv[])
{
  vtkSmartPointer<vtkPolyData> input = CreateData();

  VTK_CREATE(vtkRenderWindow, renwin);
  renwin->SetSize(300, 200);

  vtkSmartPointer<vtkRenderer> renderer;

  renderer = CreateRenderer(input, CreateLookupTable(), 0);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateLookupTable(), 1);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateLogLookupTable(), 0);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateLogLookupTable(), 1);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateColorTransferFunction(), 0);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateColorTransferFunction(), 1);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateDiscretizableColorTransferFunction(), 0);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateDiscretizableColorTransferFunction(), 1);
  AddRenderer(renderer, renwin);

  int retVal = vtkRegressionTestImage(renwin);
  if (retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    VTK_CREATE(vtkRenderWindowInteractor, iren);
    iren->SetRenderWindow(renwin);
    iren->Initialize();
    iren->Start();
    retVal = vtkRegressionTester::PASSED;
    }

  return (retVal == vtkRegressionTester::PASSED) ? 0 : 1;
}
<commit_msg>Add extra render call to RenderNonFinite test<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    SurfacePlusEdges.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

// This test draws a stick with non-finite values.  The topology of the stick is
// as follows.
//
//  +---+  INF  Red
//  |   |
//  +---+  1.0  Red
//  |   |
//  +---+  0.5  Green
//  |   |
//  +---+  NAN  Magenta
//  |   |
//  +---+  0.5  Green
//  |   |
//  +---+  0.0  Blue
//  |   |
//  +---+  -INF Blue
//
// These values are mapped to the spectrum colors from blue (low) to red (high).
// -INF should be blue, INF should be red.  Since these are near extrema,
// whatever interpolation used should be constant.  NAN should be drawn as
// magenta.  The interpolation to NAN is ill defined in a texture map.  I would
// expect a sharp transition to the NAN color, but that might depend on graphics
// hardware.

#include "vtkActor.h"
#include "vtkCellArray.h"
#include "vtkColorTransferFunction.h"
#include "vtkDiscretizableColorTransferFunction.h"
#include "vtkDoubleArray.h"
#include "vtkLookupTable.h"
#include "vtkLogLookupTable.h"
#include "vtkMath.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"

#include "vtkSmartPointer.h"
#define VTK_CREATE(type, var) \
  vtkSmartPointer<type> var = vtkSmartPointer<type>::New()

// Create the data described above.
static vtkSmartPointer<vtkPolyData> CreateData()
{
  const int cellsHigh = 6;
  const int pointsHigh = cellsHigh + 1;
  const double pointValues[pointsHigh] = {
    vtkMath::NegInf(), 0.0, 0.5, vtkMath::Nan(), 0.5, 1.0, vtkMath::Inf()
  };

  VTK_CREATE(vtkPolyData, polyData);

  VTK_CREATE(vtkPoints, points);
  for (int y = 0; y < pointsHigh; y++)
    {
    for (int x = 0; x < 2; x++)
      {
      points->InsertNextPoint(static_cast<double>(x),
                              static_cast<double>(y), 0.0);
      }
    }
  polyData->SetPoints(points);

  VTK_CREATE(vtkCellArray, cells);
  for (int c = 0; c < cellsHigh; c++)
    {
    cells->InsertNextCell(4);
    cells->InsertCellPoint(2*c);
    cells->InsertCellPoint(2*c+1);
    cells->InsertCellPoint(2*c+3);
    cells->InsertCellPoint(2*c+2);
    }
  polyData->SetPolys(cells);

  VTK_CREATE(vtkDoubleArray, scalars);
  for (int height = 0; height < pointsHigh; height++)
    {
    scalars->InsertNextTuple1(pointValues[height]);
    scalars->InsertNextTuple1(pointValues[height]);
    }
  polyData->GetPointData()->SetScalars(scalars);

  return polyData;
}

static vtkSmartPointer<vtkLookupTable> CreateLookupTable()
{
  VTK_CREATE(vtkLookupTable, lut);

  lut->SetRampToLinear();
  lut->SetScaleToLinear();
  lut->SetTableRange(0.0, 1.0);
  lut->SetHueRange(0.6, 0.0);
  lut->SetNanColor(1.0, 0.0, 1.0, 1.0);

  return lut;
}

static vtkSmartPointer<vtkLogLookupTable> CreateLogLookupTable()
{
  VTK_CREATE(vtkLogLookupTable, lut);

  lut->SetRampToLinear();
  lut->SetScaleToLinear();
  lut->SetTableRange(0.0, 1.0);
  lut->SetHueRange(0.6, 0.0);
  lut->SetNanColor(1.0, 0.0, 1.0, 1.0);

  return lut;
}

static vtkSmartPointer<vtkColorTransferFunction> CreateColorTransferFunction()
{
  VTK_CREATE(vtkColorTransferFunction, ctf);

  ctf->SetColorSpaceToHSV();
  ctf->HSVWrapOff();
  ctf->AddHSVSegment(0.0, 0.6, 1.0, 1.0,
                     1.0, 0.0, 1.0, 1.0);
  ctf->SetNanColor(1.0, 0.0, 1.0);

  return ctf;
}

static vtkSmartPointer<vtkDiscretizableColorTransferFunction> CreateDiscretizableColorTransferFunction()
{
  VTK_CREATE(vtkDiscretizableColorTransferFunction, ctf);

  ctf->DiscretizeOn();
  ctf->SetColorSpaceToHSV();
  ctf->HSVWrapOff();
  ctf->AddHSVSegment(0.0, 0.6, 1.0, 1.0,
                     1.0, 0.0, 1.0, 1.0);
  ctf->SetNanColor(1.0, 0.0, 1.0);
  ctf->Build();

  return ctf;
}

static vtkSmartPointer<vtkRenderer> CreateRenderer(vtkPolyData *input,
                                                   vtkScalarsToColors *lut,
                                                   int interpolate)
{
  VTK_CREATE(vtkPolyDataMapper, mapper);
  mapper->SetInputData(input);
  mapper->SetLookupTable(lut);
  mapper->SetInterpolateScalarsBeforeMapping(interpolate);

  VTK_CREATE(vtkActor, actor);
  actor->SetMapper(mapper);

  VTK_CREATE(vtkRenderer, renderer);
  renderer->AddActor(actor);
  renderer->ResetCamera();

  return renderer;
}

const int NUM_RENDERERS = 8;
static void AddRenderer(vtkRenderer *renderer, vtkRenderWindow *renwin)
{
  static int rencount = 0;
  renderer->SetViewport(static_cast<double>(rencount)/NUM_RENDERERS, 0.0,
                        static_cast<double>(rencount+1)/NUM_RENDERERS, 1.0);
  renwin->AddRenderer(renderer);
  rencount++;
}

int RenderNonFinite(int argc, char *argv[])
{
  vtkSmartPointer<vtkPolyData> input = CreateData();

  VTK_CREATE(vtkRenderWindow, renwin);
  renwin->SetSize(300, 200);

  vtkSmartPointer<vtkRenderer> renderer;

  renderer = CreateRenderer(input, CreateLookupTable(), 0);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateLookupTable(), 1);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateLogLookupTable(), 0);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateLogLookupTable(), 1);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateColorTransferFunction(), 0);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateColorTransferFunction(), 1);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateDiscretizableColorTransferFunction(), 0);
  AddRenderer(renderer, renwin);

  renderer = CreateRenderer(input, CreateDiscretizableColorTransferFunction(), 1);
  AddRenderer(renderer, renwin);

  renwin->Render();

  int retVal = vtkRegressionTestImage(renwin);
  if (retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    VTK_CREATE(vtkRenderWindowInteractor, iren);
    iren->SetRenderWindow(renwin);
    iren->Initialize();
    iren->Start();
    retVal = vtkRegressionTester::PASSED;
    }

  return (retVal == vtkRegressionTester::PASSED) ? 0 : 1;
}
<|endoftext|>