<commit_before>#include <glow/Uniform.h>
#include <glow/Program.h>
#include <glow/Log.h>
#include <glm/gtc/type_ptr.hpp>

using namespace glow;

Uniform::Uniform(const std::string& name)
: _name(name)
, _type(Undefined)
{
}

Uniform::~Uniform()
{
}

const std::string& Uniform::name() const
{
	return _name;
}

void Uniform::registerProgram(Program* program)
{
	_programs.insert(program);
}

void Uniform::deregisterProgram(Program* program)
{
	_programs.erase(program);
}

void Uniform::changed()
{
	for (Program* program: _programs)
	{
		setFor(program);
	}
}

void Uniform::setFor(Program* program)
{
	program->use();
	setUniform(program->getUniformLocation(_name));
}

void Uniform::setUniform(GLint location)
{
	switch (_type)
	{
        	case Float:
        		glUniform1f(location, _value.float_value);
        		break;
		case Int:
			glUniform1i(location, _value.int_value);
			break;
		case UInt:
			glUniform1ui(location, _value.uint_value);
			break;
        	case Vec2:
        		glUniform2fv(location, 1, glm::value_ptr(_value.vec2_value));
        		break;
        	case Vec3:
        		glUniform3fv(location, 1, glm::value_ptr(_value.vec3_value));
        		break;
        	case Vec4:
        		glUniform3fv(location, 1, glm::value_ptr(_value.vec3_value));
        		break;
        	case IVec2:
        		glUniform2iv(location, 1, glm::value_ptr(_value.ivec2_value));
        		break;
        	case IVec3:
        		glUniform3iv(location, 1, glm::value_ptr(_value.ivec3_value));
        		break;
        	case IVec4:
        		glUniform4iv(location, 1, glm::value_ptr(_value.ivec4_value));
        		break;
        	case UVec2:
        		glUniform2uiv(location, 1, glm::value_ptr(_value.uvec2_value));
        		break;
        	case UVec3:
        		glUniform3uiv(location, 1, glm::value_ptr(_value.uvec3_value));
        		break;
        	case UVec4:
        		glUniform4uiv(location, 1, glm::value_ptr(_value.uvec4_value));
        		break;
        	case Mat2:
        		glUniformMatrix2fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat2_value));
        		break;
        	case Mat3:
        		glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat3_value));
        		break;
        	case Mat4:
        		glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat4_value));
        		break;
        	case Mat2x3:
        		glUniformMatrix2x3fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat2x3_value));
        		break;
        	case Mat3x2:
        		glUniformMatrix3x2fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat3x2_value));
        		break;
        	case Mat2x4:
        		glUniformMatrix2x4fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat2x4_value));
        		break;
        	case Mat4x2:
        		glUniformMatrix4x2fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat4x2_value));
        		break;
        	case Mat3x4:
        		glUniformMatrix3x4fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat3x4_value));
        		break;
        	case Mat4x3:
        		glUniformMatrix4x3fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat4x3_value));
        		break;
        	case FloatArray:
        		glUniform1fv(location, _value.float_array_value.size(), _value.float_array_value.data());
        		break;
		case IntArray:
			glUniform1iv(location, _value.int_array_value.size(), _value.int_array_value.data());
			break;
		case UIntArray:
			glUniform1uiv(location, _value.uint_array_value.size(), _value.uint_array_value.data());
			break;
        	case Vec2Array:
        		glUniform2fv(location, _value.vec2_array_value.size(), reinterpret_cast<const float*>(_value.vec2_array_value.rawData()));
        		break;
        	case Vec3Array:
        		glUniform3fv(location, _value.vec3_array_value.size(), reinterpret_cast<const float*>(_value.vec3_array_value.rawData()));
        		break;
        	case Vec4Array:
        		glUniform4fv(location, _value.vec4_array_value.size(), reinterpret_cast<const float*>(_value.vec4_array_value.rawData()));
        		break;
        	case IVec2Array:
        		glUniform2iv(location, _value.ivec2_array_value.size(), reinterpret_cast<const int*>(_value.ivec2_array_value.rawData()));
        		break;
        	case IVec3Array:
        		glUniform3iv(location, _value.ivec3_array_value.size(), reinterpret_cast<const int*>(_value.ivec3_array_value.rawData()));
        		break;
        	case IVec4Array:
        		glUniform4iv(location, _value.ivec4_array_value.size(), reinterpret_cast<const int*>(_value.ivec4_array_value.rawData()));
        		break;
        	case UVec2Array:
        		glUniform2uiv(location, _value.uvec2_array_value.size(), reinterpret_cast<const unsigned*>(_value.uvec2_array_value.rawData()));
        		break;
        	case UVec3Array:
        		glUniform3uiv(location, _value.uvec3_array_value.size(), reinterpret_cast<const unsigned*>(_value.uvec3_array_value.rawData()));
        		break;
        	case UVec4Array:
        		glUniform4uiv(location, _value.uvec4_array_value.size(), reinterpret_cast<const unsigned*>(_value.uvec4_array_value.rawData()));
        		break;
        	case Mat2Array:
        		glUniformMatrix2fv(location, _value.mat2_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat2_array_value.rawData()));
        		break;
        	case Mat3Array:
        		glUniformMatrix3fv(location, _value.mat3_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat3_array_value.rawData()));
        		break;
        	case Mat4Array:
        		glUniformMatrix2fv(location, _value.mat4_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat4_array_value.rawData()));
        		break;
        	case Mat2x3Array:
        		glUniformMatrix2x3fv(location, _value.mat2x3_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat2x3_array_value.rawData()));
        		break;
        	case Mat3x2Array:
        		glUniformMatrix3x2fv(location, _value.mat3x2_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat3x2_array_value.rawData()));
        		break;
        	case Mat2x4Array:
        		glUniformMatrix2x4fv(location, _value.mat2x4_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat2x4_array_value.rawData()));
        		break;
        	case Mat4x2Array:
        		glUniformMatrix4x2fv(location, _value.mat4x2_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat4x2_array_value.rawData()));
        		break;
        	case Mat3x4Array:
        		glUniformMatrix3x4fv(location, _value.mat3x4_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat3x4_array_value.rawData()));
        		break;
        	case Mat4x3Array:
        		glUniformMatrix4x3fv(location, _value.mat4x3_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat4x3_array_value.rawData()));
        		break;
		default:
			warning() << "Attempted to set untyped uniform";
	}
}
<commit_msg>fixed copy&paste error in Uniform<commit_after>#include <glow/Uniform.h>
#include <glow/Program.h>
#include <glow/Log.h>
#include <glm/gtc/type_ptr.hpp>

using namespace glow;

Uniform::Uniform(const std::string& name)
: _name(name)
, _type(Undefined)
{
}

Uniform::~Uniform()
{
}

const std::string& Uniform::name() const
{
	return _name;
}

void Uniform::registerProgram(Program* program)
{
	_programs.insert(program);
}

void Uniform::deregisterProgram(Program* program)
{
	_programs.erase(program);
}

void Uniform::changed()
{
	for (Program* program: _programs)
	{
		setFor(program);
	}
}

void Uniform::setFor(Program* program)
{
	program->use();
	setUniform(program->getUniformLocation(_name));
}

void Uniform::setUniform(GLint location)
{
	switch (_type)
	{
        	case Float:
        		glUniform1f(location, _value.float_value);
        		break;
		case Int:
			glUniform1i(location, _value.int_value);
			break;
		case UInt:
			glUniform1ui(location, _value.uint_value);
			break;
        	case Vec2:
        		glUniform2fv(location, 1, glm::value_ptr(_value.vec2_value));
        		break;
        	case Vec3:
        		glUniform3fv(location, 1, glm::value_ptr(_value.vec3_value));
        		break;
        	case Vec4:
        		glUniform4fv(location, 1, glm::value_ptr(_value.vec4_value));
        		break;
        	case IVec2:
        		glUniform2iv(location, 1, glm::value_ptr(_value.ivec2_value));
        		break;
        	case IVec3:
        		glUniform3iv(location, 1, glm::value_ptr(_value.ivec3_value));
        		break;
        	case IVec4:
        		glUniform4iv(location, 1, glm::value_ptr(_value.ivec4_value));
        		break;
        	case UVec2:
        		glUniform2uiv(location, 1, glm::value_ptr(_value.uvec2_value));
        		break;
        	case UVec3:
        		glUniform3uiv(location, 1, glm::value_ptr(_value.uvec3_value));
        		break;
        	case UVec4:
        		glUniform4uiv(location, 1, glm::value_ptr(_value.uvec4_value));
        		break;
        	case Mat2:
        		glUniformMatrix2fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat2_value));
        		break;
        	case Mat3:
        		glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat3_value));
        		break;
        	case Mat4:
        		glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat4_value));
        		break;
        	case Mat2x3:
        		glUniformMatrix2x3fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat2x3_value));
        		break;
        	case Mat3x2:
        		glUniformMatrix3x2fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat3x2_value));
        		break;
        	case Mat2x4:
        		glUniformMatrix2x4fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat2x4_value));
        		break;
        	case Mat4x2:
        		glUniformMatrix4x2fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat4x2_value));
        		break;
        	case Mat3x4:
        		glUniformMatrix3x4fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat3x4_value));
        		break;
        	case Mat4x3:
        		glUniformMatrix4x3fv(location, 1, GL_FALSE, glm::value_ptr(_value.mat4x3_value));
        		break;
        	case FloatArray:
        		glUniform1fv(location, _value.float_array_value.size(), _value.float_array_value.data());
        		break;
		case IntArray:
			glUniform1iv(location, _value.int_array_value.size(), _value.int_array_value.data());
			break;
		case UIntArray:
			glUniform1uiv(location, _value.uint_array_value.size(), _value.uint_array_value.data());
			break;
        	case Vec2Array:
        		glUniform2fv(location, _value.vec2_array_value.size(), reinterpret_cast<const float*>(_value.vec2_array_value.rawData()));
        		break;
        	case Vec3Array:
        		glUniform3fv(location, _value.vec3_array_value.size(), reinterpret_cast<const float*>(_value.vec3_array_value.rawData()));
        		break;
        	case Vec4Array:
        		glUniform4fv(location, _value.vec4_array_value.size(), reinterpret_cast<const float*>(_value.vec4_array_value.rawData()));
        		break;
        	case IVec2Array:
        		glUniform2iv(location, _value.ivec2_array_value.size(), reinterpret_cast<const int*>(_value.ivec2_array_value.rawData()));
        		break;
        	case IVec3Array:
        		glUniform3iv(location, _value.ivec3_array_value.size(), reinterpret_cast<const int*>(_value.ivec3_array_value.rawData()));
        		break;
        	case IVec4Array:
        		glUniform4iv(location, _value.ivec4_array_value.size(), reinterpret_cast<const int*>(_value.ivec4_array_value.rawData()));
        		break;
        	case UVec2Array:
        		glUniform2uiv(location, _value.uvec2_array_value.size(), reinterpret_cast<const unsigned*>(_value.uvec2_array_value.rawData()));
        		break;
        	case UVec3Array:
        		glUniform3uiv(location, _value.uvec3_array_value.size(), reinterpret_cast<const unsigned*>(_value.uvec3_array_value.rawData()));
        		break;
        	case UVec4Array:
        		glUniform4uiv(location, _value.uvec4_array_value.size(), reinterpret_cast<const unsigned*>(_value.uvec4_array_value.rawData()));
        		break;
        	case Mat2Array:
        		glUniformMatrix2fv(location, _value.mat2_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat2_array_value.rawData()));
        		break;
        	case Mat3Array:
        		glUniformMatrix3fv(location, _value.mat3_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat3_array_value.rawData()));
        		break;
        	case Mat4Array:
        		glUniformMatrix2fv(location, _value.mat4_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat4_array_value.rawData()));
        		break;
        	case Mat2x3Array:
        		glUniformMatrix2x3fv(location, _value.mat2x3_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat2x3_array_value.rawData()));
        		break;
        	case Mat3x2Array:
        		glUniformMatrix3x2fv(location, _value.mat3x2_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat3x2_array_value.rawData()));
        		break;
        	case Mat2x4Array:
        		glUniformMatrix2x4fv(location, _value.mat2x4_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat2x4_array_value.rawData()));
        		break;
        	case Mat4x2Array:
        		glUniformMatrix4x2fv(location, _value.mat4x2_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat4x2_array_value.rawData()));
        		break;
        	case Mat3x4Array:
        		glUniformMatrix3x4fv(location, _value.mat3x4_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat3x4_array_value.rawData()));
        		break;
        	case Mat4x3Array:
        		glUniformMatrix4x3fv(location, _value.mat4x3_array_value.size(), GL_FALSE, reinterpret_cast<const float*>(_value.mat4x3_array_value.rawData()));
        		break;
		default:
			warning() << "Attempted to set untyped uniform";
	}
}
<|endoftext|>


<commit_before>/**
 * Tests for CacheTagArray
 * @author Oleg Ladin, Denis Los
 */

#include <catch.hpp>

// Module
#include "../cache_tag_array.h"

#include <infra/types.h>

#include <fstream>
#include <vector>

TEST_CASE( "pass_wrong_arguments: Pass_Wrong_Arguments_To_CacheTagArraySizeCheck")
{
    // size_in_bytes = 128
    // ways = 0
    // line_size = 4
    // addr_size_in_bits = 32
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 128, 0, 4, 32), CacheTagArrayInvalidSizeException);

    // size_in_bytes = 0
    // ways = 16
    // line_size = 4
    // addr_size_in_bits = 32
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 0, 16, 4, 32), CacheTagArrayInvalidSizeException);

    // size_in_bytes = 128
    // ways = 16
    // line_size = 0
    // addr_size_in_bits = 32
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 128, 16, 0, 32), CacheTagArrayInvalidSizeException);

    // size_in_bytes = 128
    // ways = 16
    // line_size = 4
    // addr_size_in_bits = 0
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 128, 16, 4, 0), CacheTagArrayInvalidSizeException);

    // size_in_bytes = 0
    // ways = 0
    // line_size = 0
    // addr_size_in_bits = 0
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 0, 0, 0, 0), CacheTagArrayInvalidSizeException);

    // size_in_bytes is power of 2,
    // but the number of ways is not
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 64, 9, 4, 32), CacheTagArrayInvalidSizeException);

    // the number of ways is power of 2,
    // but size_in_bytes is not
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 500, 16, 4, 32), CacheTagArrayInvalidSizeException);

    // line_size is not power of 2
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 512, 16, 12, 32), CacheTagArrayInvalidSizeException);
}

static const uint32 LINE_SIZE = 4; // why not 32?

static void test( std::ifstream& miss_rate_file, const std::vector<Addr>& values,
                  uint32 associativity, uint32 _size)
{
    CacheTagArray cta(_size, associativity, LINE_SIZE);

    std::size_t hit = 0;
    std::size_t miss = 0;

    for ( const auto& addr : values)
        if ( cta.read( addr).first)
        {
            hit++;
        }
        else
        {
            miss++;
            cta.write( addr); // load to the
        }

    // hit and miss numbers are both needed
    // because mem_trace file can be changed
    std::size_t sample_hit;
    std::size_t sample_miss;

    // read sample miss rates from miss_rate file
    // and check whether a file with sample miss rates has been corrupted
    miss_rate_file >> sample_miss;
    miss_rate_file >> sample_hit;

    // check whether sample hit and miss numbers
    // are equal to the evaluated ones
    CHECK( hit == sample_hit);
    CHECK( miss == sample_miss);
}

TEST_CASE( "miss_rate_sim: Miss_Rate_Sim_Test")
{
    const std::string MEM_TRACE_FILENAME = TEST_DATA_PATH "mem_trace.txt";
    const std::string MISS_RATE_FILENAME = TEST_DATA_PATH "miss_rate.txt";

    // open and check mem_trace file
    std::ifstream mem_trace_file;
    mem_trace_file.open( MEM_TRACE_FILENAME, std::ifstream::in);
    CHECK( mem_trace_file.is_open());

    // open and check miss_rate file
    std::ifstream miss_rate_file;
    miss_rate_file.open( MISS_RATE_FILENAME, std::ifstream::in);
    CHECK( miss_rate_file.is_open());

    // Cache parameters
    std::vector<uint32> associativities = { 1, 2, 4, 8, 16 };
    std::vector<uint32> cache_sizes = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 };

    Addr addr;
    std::vector<uint32> values;
    values.reserve(100000);
    while ( mem_trace_file >> std::hex >> addr)
        values.push_back(addr);

    // test CacheTagArray on different parameters
    for ( auto associativity : associativities)
        for ( auto cache_size : cache_sizes)
            test( miss_rate_file, values, associativity, 1024 * cache_size);

    // test full-assotiative
    for ( auto cache_size : cache_sizes)
        test( miss_rate_file, values, 1024 * cache_size / LINE_SIZE, 1024 * cache_size);

    mem_trace_file.close();
    miss_rate_file.close();
}
<commit_msg>Add tests for esoteric cache sizes<commit_after>/**
 * Tests for CacheTagArray
 * @author Oleg Ladin, Denis Los
 */

#include <catch.hpp>

// Module
#include "../cache_tag_array.h"

#include <infra/types.h>

#include <fstream>
#include <vector>

TEST_CASE( "pass_wrong_arguments: Pass_Wrong_Arguments_To_CacheTagArraySizeCheck")
{
    // size_in_bytes = 128
    // ways = 0
    // line_size = 4
    // addr_size_in_bits = 32
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 128, 0, 4, 32), CacheTagArrayInvalidSizeException);

    // size_in_bytes = 0
    // ways = 16
    // line_size = 4
    // addr_size_in_bits = 32
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 0, 16, 4, 32), CacheTagArrayInvalidSizeException);

    // size_in_bytes = 128
    // ways = 16
    // line_size = 0
    // addr_size_in_bits = 32
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 128, 16, 0, 32), CacheTagArrayInvalidSizeException);

    // size_in_bytes = 128
    // ways = 16
    // line_size = 4
    // addr_size_in_bits = 0
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 128, 16, 4, 0), CacheTagArrayInvalidSizeException);

    // size_in_bytes = 0
    // ways = 0
    // line_size = 0
    // addr_size_in_bits = 0
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 0, 0, 0, 0), CacheTagArrayInvalidSizeException);

    // size_in_bytes is power of 2,
    // but the number of ways is not
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 64, 9, 4, 32), CacheTagArrayInvalidSizeException);

    // the number of ways is power of 2,
    // but size_in_bytes is not
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 500, 16, 4, 32), CacheTagArrayInvalidSizeException);

    // line_size is not power of 2
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 512, 16, 12, 32), CacheTagArrayInvalidSizeException);

    // address is 48 bits
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 128, 4, 4, 48), CacheTagArrayInvalidSizeException);

    // too small cache
    CHECK_THROWS_AS( CacheTagArraySizeCheck( 8, 4, 4, 32), CacheTagArrayInvalidSizeException);
}

static const uint32 LINE_SIZE = 4; // why not 32?

static void test( std::ifstream& miss_rate_file, const std::vector<Addr>& values,
                  uint32 associativity, uint32 _size)
{
    CacheTagArray cta(_size, associativity, LINE_SIZE);

    std::size_t hit = 0;
    std::size_t miss = 0;

    for ( const auto& addr : values)
        if ( cta.read( addr).first)
        {
            hit++;
        }
        else
        {
            miss++;
            cta.write( addr); // load to the
        }

    // hit and miss numbers are both needed
    // because mem_trace file can be changed
    std::size_t sample_hit;
    std::size_t sample_miss;

    // read sample miss rates from miss_rate file
    // and check whether a file with sample miss rates has been corrupted
    miss_rate_file >> sample_miss;
    miss_rate_file >> sample_hit;

    // check whether sample hit and miss numbers
    // are equal to the evaluated ones
    CHECK( hit == sample_hit);
    CHECK( miss == sample_miss);
}

TEST_CASE( "miss_rate_sim: Miss_Rate_Sim_Test")
{
    const std::string MEM_TRACE_FILENAME = TEST_DATA_PATH "mem_trace.txt";
    const std::string MISS_RATE_FILENAME = TEST_DATA_PATH "miss_rate.txt";

    // open and check mem_trace file
    std::ifstream mem_trace_file;
    mem_trace_file.open( MEM_TRACE_FILENAME, std::ifstream::in);
    CHECK( mem_trace_file.is_open());

    // open and check miss_rate file
    std::ifstream miss_rate_file;
    miss_rate_file.open( MISS_RATE_FILENAME, std::ifstream::in);
    CHECK( miss_rate_file.is_open());

    // Cache parameters
    std::vector<uint32> associativities = { 1, 2, 4, 8, 16 };
    std::vector<uint32> cache_sizes = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 };

    Addr addr;
    std::vector<uint32> values;
    values.reserve(100000);
    while ( mem_trace_file >> std::hex >> addr)
        values.push_back(addr);

    // test CacheTagArray on different parameters
    for ( auto associativity : associativities)
        for ( auto cache_size : cache_sizes)
            test( miss_rate_file, values, associativity, 1024 * cache_size);

    // test full-assotiative
    for ( auto cache_size : cache_sizes)
        test( miss_rate_file, values, 1024 * cache_size / LINE_SIZE, 1024 * cache_size);

    mem_trace_file.close();
    miss_rate_file.close();
}
<|endoftext|>


<commit_before>// Copyright (C) 2010 and 2011 Marcin Arkadiusz Skrobiranda.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. 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.
// 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.

#ifndef NETWORK_XMLRPCCOMMON_REQUEST_REQUEST_HPP
#define NETWORK_XMLRPCCOMMON_REQUEST_REQUEST_HPP

#include "../Common/Message.hpp"

#include "InvalidRequest.hpp"

namespace Network
{
namespace XmlRPCCommon
{
namespace Request
{

/**
 * @brief The identifiers of the requests.
 */
unsigned short int const REQUEST_ID_ECHO                               =  1;
unsigned short int const REQUEST_ID_ERROR                              =  2;

unsigned short int const REQUEST_ID_CREATE_LAND                        =  3;
unsigned short int const REQUEST_ID_DELETE_LAND                        =  4;
unsigned short int const REQUEST_ID_GET_LAND_BY_ID_LAND                =  5;
unsigned short int const REQUEST_ID_GET_LAND_BY_NAME                   =  6;
unsigned short int const REQUEST_ID_GET_LANDS_BY_ID_WORLD              =  7;

unsigned short int const REQUEST_ID_CREATE_SETTLEMENT                  =  8;
unsigned short int const REQUEST_ID_DELETE_SETTLEMENT                  =  9;
unsigned short int const REQUEST_ID_GET_SETTLEMENT_BY_ID_LAND_AND_NAME =  0;
unsigned short int const REQUEST_ID_GET_SETTLEMENT_BY_ID_SETTLEMENT    = 11;
unsigned short int const REQUEST_ID_GET_SETTLEMENTS_BY_ID_LAND         = 12;

unsigned short int const REQUEST_ID_BUILD_BUILDING                     = 13;
unsigned short int const REQUEST_ID_DESTROY_BUILDING                   = 14;
unsigned short int const REQUEST_ID_GET_BUILDING                       = 15;
unsigned short int const REQUEST_ID_GET_BUILDINGS                      = 16;

unsigned short int const REQUEST_ID_DISMISS_HUMAN                      = 17;
unsigned short int const REQUEST_ID_ENGAGE_HUMAN                       = 18;
unsigned short int const REQUEST_ID_GET_HUMAN                          = 19;
unsigned short int const REQUEST_ID_GET_HUMANS                         = 20;

unsigned short int const REQUEST_ID_GET_RESOURCE                       = 21;
unsigned short int const REQUEST_ID_GET_RESOURCES                      = 22;

unsigned short int const REQUEST_ID_CREATE_USER                        = 23;

unsigned short int const REQUEST_ID_CREATE_WORLD                       = 24;

unsigned short int const REQUEST_ID_TURN                               = 25;

unsigned short int const REQUEST_ID_CREATE_EPOCH                       = 26;
unsigned short int const REQUEST_ID_DELETE_EPOCH                       = 27;
unsigned short int const REQUEST_ID_ACTIVATE_EPOCH                     = 28;
unsigned short int const REQUEST_ID_DEACTIVATE_EPOCH                   = 29;
unsigned short int const REQUEST_ID_FINISH_EPOCH                       = 30;
unsigned short int const REQUEST_ID_TICK_EPOCH                         = 31;
unsigned short int const REQUEST_ID_GET_EPOCH                          = 32;

unsigned short int const REQUEST_ID_TRANSPORT_HUMAN                    = 33;
unsigned short int const REQUEST_ID_TRANSPORT_RESOURCE                 = 34;

/**
 * @brief A request class.
 */
class Request
    : public Common::Message
{
public:
    /**
     * @brief Constructs the request.
     */
    Request();

    /**
     * @brief Constructs the request.
     *
     * @param a_content A content of the request.
     */
    explicit Request(
        std::string const & a_content
    );

    /**
     * @brief Constructs the request.
     *
     * @param a_message_wrapper A message wrapper.
     */
    explicit Request(
        Network::XmlRPCCommon::Common::MessageWrapperShrPtr a_message_wrapper
    );

    /**
     * @brief Gets the identifier of the request.
     *
     * @return The identifier of the request.
     *
     * @throws InvalidRequestShrPtr When any of the following:
     *           - the "request" tag does not exist,
     *           - the "request" tag does not have the "id" attribute,
     *           - the "id" attribute is not an integer,
     *           - the value of the "id" attribute is negative
     *         is true.
     */
    unsigned short int const getIdRequest() const;

    /**
     * @brief Gets the value of the identifier of the user.
     *
     * @return The value of the identifier of the user.
     *
     * @throws InvalidRequestShrPtr When the value of the identifier of the user cannot be determined.
     */
    unsigned int getIDUserValue() const;

    /**
     * @brief Gets the value of the password of the user.
     *
     * @return The value of the password of the user.
     *
     * @throws InvalidRequestShrPtr When the value of the password of the user cannot be determined.
     */
    std::string getPasswordValue() const;

    /**
     * @brief Gets the value of the unsigned integer parameter by name.
     *
     * @param a_name The name of the parameter.
     *
     * @return The value of the unsigned integer parameter.
     *
     * @throws InvalidRequestShrPtr When any of the following:
     *           - the parameter does not exist,
     *           - the parameter is not declared as an unsigned integer,
     *           - the parameter does not have a value,
     *           - the parameter is declared as an unsigned integer and its value's type is not an unsigned integer,
     *           - the value is negative
     *         is true.
     */
    unsigned int const getParameterValueUnsignedInteger(
        std::string const & a_name
    ) const;

    /**
     * @brief Gets the value of the string parameter by name.
     *
     * @param a_name The name of the parameter.
     *
     * @return The value of the string parameter.
     *
     * @throws InvalidRequestShrPtr When any of the following:
     *           - the parameter does not exist,
     *           - the parameter is not declared as an string,
     *           - the parameter does not have a value
     *         is true.
     */
    std::string const getParameterValueString(
        std::string const & a_name
    ) const;

private:
    /**
     * @brief Verifies if parameter of given name exists.
     *
     * @param a_name The name of the parameter.
     *
     * @return A node representing the parameter.
     *
     * @throws InvalidRequestShrPtr If the parameter does not exist.
     */
    Xml::IXmlNodeShrPtr verifyIfParameterExists(
        std::string const & a_name
    ) const;

    /**
     * @brief Verifies if parameter has a "value" attribute.
     *
     * @param a_parameter A node representing the parameter.
     *
     * @return The "value" attribute.
     *
     * @throws InvalidRequestShrPtr If the parameter does not have the "value" attribute.
     */
    Xml::IXmlAttributeShrPtr verifyIfParameterHasAValueAtribute(
        Xml::IXmlNodeShrPtr a_parameter
    ) const;

    /**
     * @brief Sets the xml document basing on string.
     *
     * @param a_string A string representation of the xml document.
     */
    void setXmlDocument(
        std::string const & a_string
    );
};

/**
 * @brief A shared pointer of request.
 */
typedef boost::shared_ptr<Request> RequestShrPtr;

} // namespace Request
} // namespace XmlRPCCommon
} // namespace Network

#endif // NETWORK_XMLRPCCOMMON_REQUEST_REQUEST_HPP
<commit_msg>Fix: Missing declaration added.<commit_after>// Copyright (C) 2010 and 2011 Marcin Arkadiusz Skrobiranda.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. 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.
// 3. Neither the name of the project 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 PROJECT 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 PROJECT 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.

#ifndef NETWORK_XMLRPCCOMMON_REQUEST_REQUEST_HPP
#define NETWORK_XMLRPCCOMMON_REQUEST_REQUEST_HPP

#include "../Common/Message.hpp"

#include "InvalidRequest.hpp"

namespace Network
{
namespace XmlRPCCommon
{
namespace Request
{

/**
 * @brief The identifiers of the requests.
 */
unsigned short int const REQUEST_ID_ECHO                               =  1;
unsigned short int const REQUEST_ID_ERROR                              =  2;

unsigned short int const REQUEST_ID_CREATE_LAND                        =  3;
unsigned short int const REQUEST_ID_DELETE_LAND                        =  4;
unsigned short int const REQUEST_ID_GET_LAND_BY_ID_LAND                =  5;
unsigned short int const REQUEST_ID_GET_LAND_BY_NAME                   =  6;
unsigned short int const REQUEST_ID_GET_LANDS_BY_ID_WORLD              =  7;

unsigned short int const REQUEST_ID_CREATE_SETTLEMENT                  =  8;
unsigned short int const REQUEST_ID_DELETE_SETTLEMENT                  =  9;
unsigned short int const REQUEST_ID_GET_SETTLEMENT_BY_ID_LAND_AND_NAME =  0;
unsigned short int const REQUEST_ID_GET_SETTLEMENT_BY_ID_SETTLEMENT    = 11;
unsigned short int const REQUEST_ID_GET_SETTLEMENTS_BY_ID_LAND         = 12;

unsigned short int const REQUEST_ID_BUILD_BUILDING                     = 13;
unsigned short int const REQUEST_ID_DESTROY_BUILDING                   = 14;
unsigned short int const REQUEST_ID_GET_BUILDING                       = 15;
unsigned short int const REQUEST_ID_GET_BUILDINGS                      = 16;

unsigned short int const REQUEST_ID_DISMISS_HUMAN                      = 17;
unsigned short int const REQUEST_ID_ENGAGE_HUMAN                       = 18;
unsigned short int const REQUEST_ID_GET_HUMAN                          = 19;
unsigned short int const REQUEST_ID_GET_HUMANS                         = 20;

unsigned short int const REQUEST_ID_GET_RESOURCE                       = 21;
unsigned short int const REQUEST_ID_GET_RESOURCES                      = 22;

unsigned short int const REQUEST_ID_CREATE_USER                        = 23;

unsigned short int const REQUEST_ID_CREATE_WORLD                       = 24;

unsigned short int const REQUEST_ID_TURN                               = 25;

unsigned short int const REQUEST_ID_CREATE_EPOCH                       = 26;
unsigned short int const REQUEST_ID_DELETE_EPOCH                       = 27;
unsigned short int const REQUEST_ID_ACTIVATE_EPOCH                     = 28;
unsigned short int const REQUEST_ID_DEACTIVATE_EPOCH                   = 29;
unsigned short int const REQUEST_ID_FINISH_EPOCH                       = 30;
unsigned short int const REQUEST_ID_TICK_EPOCH                         = 31;
unsigned short int const REQUEST_ID_GET_EPOCH                          = 32;

unsigned short int const REQUEST_ID_TRANSPORT_HUMAN                    = 33;
unsigned short int const REQUEST_ID_TRANSPORT_RESOURCE                 = 34;

/**
 * @brief A request class.
 */
class Request
    : public Common::Message
{
public:
    /**
     * @brief Constructs the request.
     */
    Request();

    /**
     * @brief Constructs the request.
     *
     * @param a_content A content of the request.
     */
    explicit Request(
        std::string const & a_content
    );

    /**
     * @brief Constructs the request.
     *
     * @param a_message_wrapper A message wrapper.
     */
    explicit Request(
        Network::XmlRPCCommon::Common::MessageWrapperShrPtr a_message_wrapper
    );

    /**
     * @brief Gets the identifier of the request.
     *
     * @return The identifier of the request.
     *
     * @throws InvalidRequestShrPtr When any of the following:
     *           - the "request" tag does not exist,
     *           - the "request" tag does not have the "id" attribute,
     *           - the "id" attribute is not an integer,
     *           - the value of the "id" attribute is negative
     *         is true.
     */
    unsigned short int const getIdRequest() const;

    /**
     * @brief Gets the value of the identifier of the user.
     *
     * @return The value of the identifier of the user.
     *
     * @throws InvalidRequestShrPtr When the value of the identifier of the user cannot be determined.
     */
    unsigned int getIDUserValue() const;

    /**
     * @brief Gets the value of the password of the user.
     *
     * @return The value of the password of the user.
     *
     * @throws InvalidRequestShrPtr When the value of the password of the user cannot be determined.
     */
    std::string getPasswordValue() const;

    /**
     * @brief Gets the value of the login of the user.
     *
     * @return The value of the login of the user.
     *
     * @throws InvalidRequestShrPtr When the value of the login of the user cannot be determined.
     */
    std::string getLoginValue() const;

    /**
     * @brief Gets the value of the unsigned integer parameter by name.
     *
     * @param a_name The name of the parameter.
     *
     * @return The value of the unsigned integer parameter.
     *
     * @throws InvalidRequestShrPtr When any of the following:
     *           - the parameter does not exist,
     *           - the parameter is not declared as an unsigned integer,
     *           - the parameter does not have a value,
     *           - the parameter is declared as an unsigned integer and its value's type is not an unsigned integer,
     *           - the value is negative
     *         is true.
     */
    unsigned int const getParameterValueUnsignedInteger(
        std::string const & a_name
    ) const;

    /**
     * @brief Gets the value of the string parameter by name.
     *
     * @param a_name The name of the parameter.
     *
     * @return The value of the string parameter.
     *
     * @throws InvalidRequestShrPtr When any of the following:
     *           - the parameter does not exist,
     *           - the parameter is not declared as an string,
     *           - the parameter does not have a value
     *         is true.
     */
    std::string const getParameterValueString(
        std::string const & a_name
    ) const;

private:
    /**
     * @brief Verifies if parameter of given name exists.
     *
     * @param a_name The name of the parameter.
     *
     * @return A node representing the parameter.
     *
     * @throws InvalidRequestShrPtr If the parameter does not exist.
     */
    Xml::IXmlNodeShrPtr verifyIfParameterExists(
        std::string const & a_name
    ) const;

    /**
     * @brief Verifies if parameter has a "value" attribute.
     *
     * @param a_parameter A node representing the parameter.
     *
     * @return The "value" attribute.
     *
     * @throws InvalidRequestShrPtr If the parameter does not have the "value" attribute.
     */
    Xml::IXmlAttributeShrPtr verifyIfParameterHasAValueAtribute(
        Xml::IXmlNodeShrPtr a_parameter
    ) const;

    /**
     * @brief Sets the xml document basing on string.
     *
     * @param a_string A string representation of the xml document.
     */
    void setXmlDocument(
        std::string const & a_string
    );
};

/**
 * @brief A shared pointer of request.
 */
typedef boost::shared_ptr<Request> RequestShrPtr;

} // namespace Request
} // namespace XmlRPCCommon
} // namespace Network

#endif // NETWORK_XMLRPCCOMMON_REQUEST_REQUEST_HPP
<|endoftext|>


<commit_before><commit_msg>readded post generation edge clipping<commit_after><|endoftext|>


<commit_before> //
 // This file is part of Easylogging++ samples
 // MAKE_LOGGABLE sample
 //
 // Feature since: v9.12
 // Revision 1.0
 // @author mkhan3189
 //

#include "easylogging++.h"

_INITIALIZE_EASYLOGGINGPP

class Integer {
public:
    Integer(int i) : m_underlyingInt(i) {}
    Integer& operator=(const Integer& integer) { m_underlyingInt = integer.m_underlyingInt; return *this; }
    virtual ~Integer(void) { m_underlyingInt = -1; }
    int getInt(void) const { return m_underlyingInt; }
private:
    int m_underlyingInt;
};

// Lets say Integer class is in some third party library

// We use MAKE_LOGGABLE(class, instance, outputStream) to make it loggable
inline MAKE_LOGGABLE(Integer, integer, os) {
    os << integer.getInt();
    return os;
}

int main(void) {

    Integer count = 5;
    LOG(INFO) << count;
    return 0;
}
<commit_msg>reverse from Integer to int in sample<commit_after> //
 // This file is part of Easylogging++ samples
 // MAKE_LOGGABLE sample
 //
 // Feature since: v9.12
 // Revision 1.0
 // @author mkhan3189
 //

#include "easylogging++.h"

_INITIALIZE_EASYLOGGINGPP

class Integer {
public:
    Integer(int i) : m_underlyingInt(i) {}
    Integer& operator=(const Integer& integer) { m_underlyingInt = integer.m_underlyingInt; return *this; }
    virtual ~Integer(void) { m_underlyingInt = -1; }
    int getInt(void) const { return m_underlyingInt; }
    inline operator int() const { return m_underlyingInt; }
private:
    int m_underlyingInt;
};

// Lets say Integer class is in some third party library

// We use MAKE_LOGGABLE(class, instance, outputStream) to make it loggable
inline MAKE_LOGGABLE(Integer, integer, os) {
    os << integer.getInt();
    return os;
}

int main(void) {

    Integer count = 5;
    LOG(INFO) << "Integer count = " << count;
    int reverse = count;
    LOG(INFO) << "int reverse = " << reverse;
    return 0;
}
<|endoftext|>


<commit_before>#include "ClientHelper.hpp"

namespace Network {

SocketClientHelper::SocketClientHelper(const std::shared_ptr<Network::ABasicSocket>& sock, size_t readSize)
  : _readSize(readSize), _connected(true), _disconnectWhenAllWrited(false), _socket(sock)
{
  _socket->setReadeableCallback(std::bind(&SocketClientHelper::onReadeable, this));
  _socket->setWritableCallback(std::bind(&SocketClientHelper::onWritable, this));
  _socket->setPollUpdateCallback(std::bind(&SocketClientHelper::onPollUpdate, this));
  _socket->setEventRequest(Network::ASocket::Event::READ);
}

SocketClientHelper::SocketClientHelper(size_t readSize)
  : _readSize(readSize), _connected(false), _socket(nullptr)
{

}

void SocketClientHelper::setSocket(const std::shared_ptr<Network::ABasicSocket>& sock)
{
  _socket = sock;
  _socket->setReadeableCallback(std::bind(&SocketClientHelper::onReadeable, this));
  _socket->setWritableCallback(std::bind(&SocketClientHelper::onWritable, this));
  _socket->setPollUpdateCallback(std::bind(&SocketClientHelper::onPollUpdate, this));
  _socket->setEventRequest(Network::ASocket::Event::READ);
  _connected = true;
}

void SocketClientHelper::onReadeable()
{
  Buffer buff;
  size_t size = _readBuff.getLeftWrite();

  if (_readSize > size)
    size = _readSize;
  try {
      _socket->read(buff, size);
      size = buff.size();
      _readBuff.writeBuffer(buff);
      onRead(size);
      if (size == 0 && _socket->getSockType() == ASocket::SockType::TCP)
        _connected = false;
    }
  catch (Network::Error& e)
    {
      _connected = false;
    }
  if (!_connected)
    {
      _socket->setEventRequest(Network::ASocket::Event::NONE);
      _socket->closeSocket();
      onDisconnet();
    }
}

void SocketClientHelper::onWritable()
{
  size_t size = _writeBuff.getLeftRead();
  size_t sizeWrite;
  Buffer buff;

  _writeBuff.readBuffer(buff, size);
  try {
      sizeWrite = _socket->write(buff);
      _writeBuff.rollbackReadBuffer(size - sizeWrite);
      onWrite(sizeWrite);
      if (_disconnectWhenAllWrited && (sizeWrite == size))
        _connected = false;
    }
  catch (Network::Error& e)
    {
      _connected = false;
      _writeBuff.rollbackReadBuffer(size);
    }
  if (!_connected)
    {
      _socket->setEventRequest(Network::ASocket::Event::NONE);
      _socket->closeSocket();
      onDisconnet();
    }
}

void SocketClientHelper::onPollUpdate()
{
  if (_writeBuff.getLeftRead() > 0)
    _socket->setEventRequest(Network::ASocket::Event::RDWR);
  else
    _socket->setEventRequest(Network::ASocket::Event::READ);
}

IdentityClientHelper::IdentityClientHelper(const std::shared_ptr<Network::Identity>& id,
    const std::weak_ptr<Network::AListenSocket>& listener)
  : _listener(listener), _id(id)
{
  _id->onRead = std::bind(&IdentityClientHelper::readData, this, std::placeholders::_1);
}

void IdentityClientHelper::setId(const std::shared_ptr<Network::Identity>& id)
{
  _id = id;
  _id->onRead = std::bind(&IdentityClientHelper::readData, this, std::placeholders::_1);
}

void IdentityClientHelper::readData(const Network::Buffer& data)
{
  _readBuff.writeBuffer(data);
  onRead();
  writeData();
}

void IdentityClientHelper::writeData()
{
  size_t size = _writeBuff.getLeftRead();
  size_t sizeWrite;
  Buffer buff;
  std::shared_ptr<Network::AListenSocket> listener = _listener.lock();

  if (!listener)
    throw std::runtime_error("Can't lock listener.");
  _writeBuff.readBuffer(buff, size);
  try {
      sizeWrite = listener->sendTo(*(_id.get()), buff);
      _writeBuff.rollbackReadBuffer(size - sizeWrite);
    }
  catch (Network::Error& e)
    {
      _writeBuff.rollbackReadBuffer(size);
    }
}

};
<commit_msg>check _disconnectWhenAllWrited in onREadeable<commit_after>#include "ClientHelper.hpp"

namespace Network {

SocketClientHelper::SocketClientHelper(const std::shared_ptr<Network::ABasicSocket>& sock, size_t readSize)
  : _readSize(readSize), _connected(true), _disconnectWhenAllWrited(false), _socket(sock)
{
  _socket->setReadeableCallback(std::bind(&SocketClientHelper::onReadeable, this));
  _socket->setWritableCallback(std::bind(&SocketClientHelper::onWritable, this));
  _socket->setPollUpdateCallback(std::bind(&SocketClientHelper::onPollUpdate, this));
  _socket->setEventRequest(Network::ASocket::Event::READ);
}

SocketClientHelper::SocketClientHelper(size_t readSize)
  : _readSize(readSize), _connected(false), _socket(nullptr)
{

}

void SocketClientHelper::setSocket(const std::shared_ptr<Network::ABasicSocket>& sock)
{
  _socket = sock;
  _socket->setReadeableCallback(std::bind(&SocketClientHelper::onReadeable, this));
  _socket->setWritableCallback(std::bind(&SocketClientHelper::onWritable, this));
  _socket->setPollUpdateCallback(std::bind(&SocketClientHelper::onPollUpdate, this));
  _socket->setEventRequest(Network::ASocket::Event::READ);
  _connected = true;
}

void SocketClientHelper::onReadeable()
{
  Buffer buff;
  size_t size = _readBuff.getLeftWrite();

  if (_readSize > size)
    size = _readSize;
  try {
      _socket->read(buff, size);
      size = buff.size();
      _readBuff.writeBuffer(buff);
      onRead(size);
      if ((size == 0 && _socket->getSockType() == ASocket::SockType::TCP)
          || (_disconnectWhenAllWrited && (_writeBuff.getLeftRead() == 0)))
        _connected = false;
    }
  catch (Network::Error& e)
    {
      _connected = false;
    }
  if (!_connected)
    {
      _socket->setEventRequest(Network::ASocket::Event::NONE);
      _socket->closeSocket();
      onDisconnet();
    }
}

void SocketClientHelper::onWritable()
{
  size_t size = _writeBuff.getLeftRead();
  size_t sizeWrite;
  Buffer buff;

  _writeBuff.readBuffer(buff, size);
  try {
      sizeWrite = _socket->write(buff);
      _writeBuff.rollbackReadBuffer(size - sizeWrite);
      onWrite(sizeWrite);
      if (_disconnectWhenAllWrited && (_writeBuff.getLeftRead() == 0))
        _connected = false;
    }
  catch (Network::Error& e)
    {
      _connected = false;
      _writeBuff.rollbackReadBuffer(size);
    }
  if (!_connected)
    {
      _socket->setEventRequest(Network::ASocket::Event::NONE);
      _socket->closeSocket();
      onDisconnet();
    }
}

void SocketClientHelper::onPollUpdate()
{
  if (_writeBuff.getLeftRead() > 0)
    _socket->setEventRequest(Network::ASocket::Event::RDWR);
  else
    _socket->setEventRequest(Network::ASocket::Event::READ);
}

IdentityClientHelper::IdentityClientHelper(const std::shared_ptr<Network::Identity>& id,
    const std::weak_ptr<Network::AListenSocket>& listener)
  : _listener(listener), _id(id)
{
  _id->onRead = std::bind(&IdentityClientHelper::readData, this, std::placeholders::_1);
}

void IdentityClientHelper::setId(const std::shared_ptr<Network::Identity>& id)
{
  _id = id;
  _id->onRead = std::bind(&IdentityClientHelper::readData, this, std::placeholders::_1);
}

void IdentityClientHelper::readData(const Network::Buffer& data)
{
  _readBuff.writeBuffer(data);
  onRead();
  writeData();
}

void IdentityClientHelper::writeData()
{
  size_t size = _writeBuff.getLeftRead();
  size_t sizeWrite;
  Buffer buff;
  std::shared_ptr<Network::AListenSocket> listener = _listener.lock();

  if (!listener)
    throw std::runtime_error("Can't lock listener.");
  _writeBuff.readBuffer(buff, size);
  try {
      sizeWrite = listener->sendTo(*(_id.get()), buff);
      _writeBuff.rollbackReadBuffer(size - sizeWrite);
    }
  catch (Network::Error& e)
    {
      _writeBuff.rollbackReadBuffer(size);
    }
}

};
<|endoftext|>


<commit_before><commit_msg>fix compile error<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cassert>
#include <algorithm>
#include "Camera.h"
#include "core/Engine.h"
#include "graphics/Renderer.h"
#include "Layer.h"
#include "graphics/Texture.h"
#include "graphics/RenderTarget.h"
#include "math/Matrix4.h"
#include "utils/Utils.h"

namespace ouzel
{
    namespace scene
    {
        Camera::Camera()
        {
        }

        Camera::~Camera()
        {
        }

        void Camera::recalculateProjection()
        {
            Size2 renderTargetSize = renderTarget ?
                renderTarget->getTexture()->getSize() :
                sharedEngine->getRenderer()->getSize();

            renderViewport.x = renderTargetSize.width * viewport.x;
            renderViewport.y = renderTargetSize.height * viewport.y;
            renderViewport.width = renderTargetSize.width * viewport.width;
            renderViewport.height = renderTargetSize.height * viewport.height;

            assert(renderViewport.width > 0.0f && renderViewport.height > 0.0f);

            if (targetContentSize.width > 0.0f && targetContentSize.height > 0.0f)
            {
                contentScale.x = renderViewport.width / targetContentSize.width;
                contentScale.y = renderViewport.height / targetContentSize.height;

                switch (scaleMode)
                {
                    case ScaleMode::NONE:
                    {
                        break;
                    }
                    case ScaleMode::EXACT_FIT:
                    {
                        contentScale.x = 1.0f;
                        contentScale.y = 1.0f;
                        break;
                    }
                    case ScaleMode::NO_BORDER:
                    {
                        contentScale.x = contentScale.y = std::max(contentScale.x, contentScale.y);
                        break;
                    }
                    case ScaleMode::SHOW_ALL:
                    {
                        contentScale.x = contentScale.y = std::min(contentScale.x, contentScale.y);
                        break;
                    }
                }

                contentSize = Size2(renderViewport.width / contentScale.x, renderViewport.height / contentScale.y);
                contentPosition = Vector2((contentSize.width - targetContentSize.width) / 2.0f,
                                          (contentSize.height - targetContentSize.height) / 2.0f);
            }
            else
            {
                contentSize = Size2(renderViewport.width, renderViewport.height);
                contentScale = Vector2(1.0f, 1.0f);
            }

            Matrix4::createOrthographic(contentSize.width, contentSize.height, -1.0f, 1.0f, projection);

            inverseProjection = projection;
            inverseProjection.invert();

            viewProjectionDirty = true;
        }

        const Matrix4& Camera::getViewProjection() const
        {
            if (viewProjectionDirty || transformDirty)
            {
                viewProjection = projection * getTransform();
                viewProjectionDirty = false;
            }

            return viewProjection;
        }

        void Camera::calculateLocalTransform() const
        {
            Matrix4 translationMatrix = Matrix4::IDENTITY;
            translationMatrix.translate(-position.x, -position.y, 0.0f);

            Matrix4 rotationMatrix = Matrix4::IDENTITY;
            rotationMatrix.rotate(Vector3(0.0f, 0.0f, -1.0f), -rotation);

            Matrix4 scaleMatrix = Matrix4::IDENTITY;
            Vector3 inverseScale(0.0f, 0.0f, 1.0f);
            if (scale.x != 0.0f) inverseScale.x = 1.0f / scale.x;
            if (scale.y != 0.0f) inverseScale.y = 1.0f / scale.y;
            scaleMatrix.scale(inverseScale);

            localTransform = scaleMatrix * rotationMatrix * translationMatrix;

            localTransformDirty = false;
        }

        Vector2 Camera::convertNormalizedToWorld(const Vector2& position)
        {
            Matrix4 inverseViewMatrix = getViewProjection();
            inverseViewMatrix.invert();

            // convert window normalized to viewport clip position
            Vector3 result = Vector3(((position.x - viewport.x) / viewport.width - 0.5f) * 2.0f,
                                     ((position.y - viewport.y) / viewport.height - 0.5f) * 2.0f,
                                     0.0f);

            inverseViewMatrix.transformPoint(result);

            return Vector2(result.x, result.y);
        }

        Vector2 Camera::convertWorldToNormalized(const Vector2& position)
        {
            Vector3 result = Vector3(position.x, position.y, 0.0f);
            getViewProjection().transformPoint(result);

            // convert viewport clip position to window normalized
            return Vector2((result.x / 2.0f + 0.5f) * viewport.width + viewport.x,
                           (result.y / 2.0f + 0.5f) * viewport.height + viewport.y);
        }

        bool Camera::checkVisibility(const Matrix4& boxTransform, const AABB2& boundingBox)
        {
            // transform center point to screen space
            Vector2 diff = boundingBox.max - boundingBox.min;

            Vector3 v3p(boundingBox.min.x + diff.x / 2.0f, boundingBox.min.y + diff.y / 2.0f, 0.0f);

            boxTransform.transformPoint(v3p);

            Vector4 clipPos;
            getViewProjection().transformVector(Vector4(v3p.x, v3p.y, v3p.z, 1.0f), clipPos);

            assert(clipPos.w != 0.0f);

            Vector2 v2p((clipPos.x / clipPos.w + 1.0f) * 0.5f * renderViewport.width,
                        (clipPos.y / clipPos.w + 1.0f) * 0.5f * renderViewport.height);

            Size2 halfSize(diff.x / 2.0f, diff.y / 2.0f);

            // convert content size to world coordinates
            Size2 halfWorldSize;

            halfWorldSize.width = std::max(fabsf(halfSize.width * boxTransform.m[0] + halfSize.height * boxTransform.m[4]),
                                           fabsf(halfSize.width * boxTransform.m[0] - halfSize.height * boxTransform.m[4]));
            halfWorldSize.height = std::max(fabsf(halfSize.width * boxTransform.m[1] + halfSize.height * boxTransform.m[5]),
                                            fabsf(halfSize.width * boxTransform.m[1] - halfSize.height * boxTransform.m[5]));

            // scale half size by camera scale
            halfWorldSize.width *= transform.m[0] + fabsf(transform.m[4]);
            halfWorldSize.height *= fabsf(transform.m[1]) + transform.m[5];

            // enlarge visible rect half size in screen coord
            Rectangle visibleRect(0.0f, 0.0f, renderViewport.width, renderViewport.height);

            visibleRect.x -= halfWorldSize.width;
            visibleRect.y -= halfWorldSize.height;
            visibleRect.width += halfWorldSize.width * 2.0f;
            visibleRect.height += halfWorldSize.height * 2.0f;

            return visibleRect.containsPoint(v2p);
        }

        void Camera::setViewport(const Rectangle& newViewport)
        {
            viewport = newViewport;
            recalculateProjection();
        }

        void Camera::setScaleMode(ScaleMode newScaleMode)
        {
            scaleMode = newScaleMode;
            recalculateProjection();
        }

        void Camera::setTargetContentSize(const Size2& newTargetContentSize)
        {
            targetContentSize = newTargetContentSize;
            recalculateProjection();
        }

        void Camera::addToLayer(Layer* newLayer)
        {
            layer = newLayer;
        }

        void Camera::removeFromLayer()
        {
            layer = nullptr;
        }

        void Camera::setRenderTarget(const graphics::RenderTargetPtr& newRenderTarget)
        {
            renderTarget = newRenderTarget;

            recalculateProjection();
        }
    } // namespace scene
} // namespace ouzel
<commit_msg>Remake visibility check to clip space and use view projection matrix<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cassert>
#include <algorithm>
#include "Camera.h"
#include "core/Engine.h"
#include "graphics/Renderer.h"
#include "Layer.h"
#include "graphics/Texture.h"
#include "graphics/RenderTarget.h"
#include "math/Matrix4.h"
#include "utils/Utils.h"

namespace ouzel
{
    namespace scene
    {
        Camera::Camera()
        {
        }

        Camera::~Camera()
        {
        }

        void Camera::recalculateProjection()
        {
            Size2 renderTargetSize = renderTarget ?
                renderTarget->getTexture()->getSize() :
                sharedEngine->getRenderer()->getSize();

            renderViewport.x = renderTargetSize.width * viewport.x;
            renderViewport.y = renderTargetSize.height * viewport.y;
            renderViewport.width = renderTargetSize.width * viewport.width;
            renderViewport.height = renderTargetSize.height * viewport.height;

            assert(renderViewport.width > 0.0f && renderViewport.height > 0.0f);

            if (targetContentSize.width > 0.0f && targetContentSize.height > 0.0f)
            {
                contentScale.x = renderViewport.width / targetContentSize.width;
                contentScale.y = renderViewport.height / targetContentSize.height;

                switch (scaleMode)
                {
                    case ScaleMode::NONE:
                    {
                        break;
                    }
                    case ScaleMode::EXACT_FIT:
                    {
                        contentScale.x = 1.0f;
                        contentScale.y = 1.0f;
                        break;
                    }
                    case ScaleMode::NO_BORDER:
                    {
                        contentScale.x = contentScale.y = std::max(contentScale.x, contentScale.y);
                        break;
                    }
                    case ScaleMode::SHOW_ALL:
                    {
                        contentScale.x = contentScale.y = std::min(contentScale.x, contentScale.y);
                        break;
                    }
                }

                contentSize = Size2(renderViewport.width / contentScale.x, renderViewport.height / contentScale.y);
                contentPosition = Vector2((contentSize.width - targetContentSize.width) / 2.0f,
                                          (contentSize.height - targetContentSize.height) / 2.0f);
            }
            else
            {
                contentSize = Size2(renderViewport.width, renderViewport.height);
                contentScale = Vector2(1.0f, 1.0f);
            }

            Matrix4::createOrthographic(contentSize.width, contentSize.height, -1.0f, 1.0f, projection);

            inverseProjection = projection;
            inverseProjection.invert();

            viewProjectionDirty = true;
        }

        const Matrix4& Camera::getViewProjection() const
        {
            if (viewProjectionDirty || transformDirty)
            {
                viewProjection = projection * getTransform();
                viewProjectionDirty = false;
            }

            return viewProjection;
        }

        void Camera::calculateLocalTransform() const
        {
            Matrix4 translationMatrix = Matrix4::IDENTITY;
            translationMatrix.translate(-position.x, -position.y, 0.0f);

            Matrix4 rotationMatrix = Matrix4::IDENTITY;
            rotationMatrix.rotate(Vector3(0.0f, 0.0f, -1.0f), -rotation);

            Matrix4 scaleMatrix = Matrix4::IDENTITY;
            Vector3 inverseScale(0.0f, 0.0f, 1.0f);
            if (scale.x != 0.0f) inverseScale.x = 1.0f / scale.x;
            if (scale.y != 0.0f) inverseScale.y = 1.0f / scale.y;
            scaleMatrix.scale(inverseScale);

            localTransform = scaleMatrix * rotationMatrix * translationMatrix;

            localTransformDirty = false;
        }

        Vector2 Camera::convertNormalizedToWorld(const Vector2& position)
        {
            Matrix4 inverseViewMatrix = getViewProjection();
            inverseViewMatrix.invert();

            // convert window normalized to viewport clip position
            Vector3 result = Vector3(((position.x - viewport.x) / viewport.width - 0.5f) * 2.0f,
                                     ((position.y - viewport.y) / viewport.height - 0.5f) * 2.0f,
                                     0.0f);

            inverseViewMatrix.transformPoint(result);

            return Vector2(result.x, result.y);
        }

        Vector2 Camera::convertWorldToNormalized(const Vector2& position)
        {
            Vector3 result = Vector3(position.x, position.y, 0.0f);
            getViewProjection().transformPoint(result);

            // convert viewport clip position to window normalized
            return Vector2((result.x / 2.0f + 0.5f) * viewport.width + viewport.x,
                           (result.y / 2.0f + 0.5f) * viewport.height + viewport.y);
        }

        bool Camera::checkVisibility(const Matrix4& boxTransform, const AABB2& boundingBox)
        {
            // calculate center point of the bounding box
            Vector2 diff = boundingBox.max - boundingBox.min;

            // offset the center point, so that it is relative to 0,0
            Vector3 v3p(boundingBox.min.x + diff.x / 2.0f, boundingBox.min.y + diff.y / 2.0f, 0.0f);

            // apply local transform to the center point
            boxTransform.transformPoint(v3p);

            // tranform the center to viewport's clip space
            Vector4 clipPos;
            getViewProjection().transformVector(Vector4(v3p.x, v3p.y, v3p.z, 1.0f), clipPos);

            assert(clipPos.w != 0.0f);

            // normalize position of the center point
            Vector2 v2p((clipPos.x / clipPos.w + 1.0f) * 0.5f,
                        (clipPos.y / clipPos.w + 1.0f) * 0.5f);

            // calculate half size
            Size2 halfSize(diff.x / 2.0f, diff.y / 2.0f);

            // convert content size to world coordinates
            Size2 halfWorldSize;

            halfWorldSize.width = std::max(fabsf(halfSize.width * boxTransform.m[0] + halfSize.height * boxTransform.m[4]),
                                           fabsf(halfSize.width * boxTransform.m[0] - halfSize.height * boxTransform.m[4]));
            halfWorldSize.height = std::max(fabsf(halfSize.width * boxTransform.m[1] + halfSize.height * boxTransform.m[5]),
                                            fabsf(halfSize.width * boxTransform.m[1] - halfSize.height * boxTransform.m[5]));

            // scale half size by camera projection to get the size in clip space coordinates
            halfWorldSize.width *= (fabsf(viewProjection.m[0]) + fabsf(viewProjection.m[4])) / 2.0f;
            halfWorldSize.height *= (fabsf(viewProjection.m[1]) + fabsf(viewProjection.m[5])) / 2.0f;

            // create visible rect in clip space
            Rectangle visibleRect(visibleRect.x = -halfWorldSize.width,
                                  visibleRect.y = -halfWorldSize.height,
                                  visibleRect.width = 1.0f + halfWorldSize.width * 2.0f,
                                  visibleRect.height = 1.0f + halfWorldSize.height * 2.0f);

            return visibleRect.containsPoint(v2p);
        }

        void Camera::setViewport(const Rectangle& newViewport)
        {
            viewport = newViewport;
            recalculateProjection();
        }

        void Camera::setScaleMode(ScaleMode newScaleMode)
        {
            scaleMode = newScaleMode;
            recalculateProjection();
        }

        void Camera::setTargetContentSize(const Size2& newTargetContentSize)
        {
            targetContentSize = newTargetContentSize;
            recalculateProjection();
        }

        void Camera::addToLayer(Layer* newLayer)
        {
            layer = newLayer;
        }

        void Camera::removeFromLayer()
        {
            layer = nullptr;
        }

        void Camera::setRenderTarget(const graphics::RenderTargetPtr& newRenderTarget)
        {
            renderTarget = newRenderTarget;

            recalculateProjection();
        }
    } // namespace scene
} // namespace ouzel
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
#include <BALL/VIEW/DIALOGS/downloadPDBFile.h>

#include <BALL/FORMAT/lineBasedFile.h>
#include <BALL/FORMAT/PDBFile.h>
#include <BALL/VIEW/KERNEL/mainControl.h>
#include <BALL/VIEW/KERNEL/message.h>
#include <BALL/KERNEL/system.h>
#include <BALL/VIEW/KERNEL/threads.h>

#include <qcombobox.h>
#include <qlineedit.h>
#include <qtextedit.h>
#include <qfile.h>
#include <qurl.h>
#include <qradiobutton.h>
#include <qcheckbox.h>
#include <qimage.h>
#include <qpushbutton.h>
#include <qgroupbox.h>
#include <qapplication.h>

namespace BALL
{
	namespace VIEW
	{

DownloadPDBFile::DownloadPDBFile( QWidget* parent, const char* name, bool modal, WFlags fl )
	throw()
	: DownloadPDBFileData(parent, name, modal, fl),
		ModularWidget(name),
		thread_(0),
		aborted_(false)
{
#ifdef BALL_VIEW_DEBUG
	Log.error() << "new DownloadPDBFile" << this << std::endl;
#endif
	// register the widget with the MainControl
	registerWidget(this);
	hide();
	connect(results, SIGNAL(activated(const QString&)), this, SLOT(slotNewId(const QString&)));

#ifdef BALL_QT_HAS_THREADS
	thread_ = new FetchHTMLThread();
#endif
}

DownloadPDBFile::~DownloadPDBFile()
	throw()
{
#ifdef BALL_VIEW_DEBUG
	Log.info() << "Destructing object " << this << " of class DownloadPDBFile" << std::endl;
#endif

#ifdef BALL_QT_HAS_THREADS
	if (thread_ != 0)
	{
		if (thread_->running())
		{
			thread_->terminate();
			thread_->wait();
		}
		delete thread_;
	}
#endif
}

void DownloadPDBFile::initializeWidget(MainControl& main_control)
	throw()
{
	String hint("Download a PDB file from www.rcsb.org");
	main_control.insertMenuEntry(MainControl::FILE_OPEN, "Download Structure", (QObject *)this,
															 SLOT(show()), ALT+Key_I, -1, hint);
}

void DownloadPDBFile::finalizeWidget(MainControl& main_control)
	throw()
{
	main_control.removeMenuEntry(MainControl::FILE_OPEN, "Downlo&ad Structure", (QObject *)this,
															 SLOT(show()), ALT+Key_A);
}

void DownloadPDBFile::slotSearch()
{
	results->clear();

	QString filename = "http://www.rcsb.org/pdb/cgi/resultBrowser.cgi?Lucene::keyword=";
	QString search_contents = searchField->text();
	QUrl::encode(search_contents);

	filename+=search_contents;
	filename+="&Lucene::keyword_op=";

	filename+=(fullText->isOn()) ? "fullText" : "name";

	if (exactMatch->isOn())
		filename+="&exact=1";
	else
		filename+="&exact=0";

	if (removeSimilar->isOn())
		filename+="&SelectorRedundFilt::on=1";

	try {
		LineBasedFile search_result;
#ifndef BALL_QT_HAS_THREADS
		search_result = LineBasedFile(filename.latin1());
#else   // =============================
		downloadStarted_();
		thread_->setURL(filename.latin1());
		thread_->start();
		while (thread_->running())
		{
			qApp->wakeUpGuiThread();
			qApp->processEvents(500);
			thread_->wait(50);
		}

		search_result = LineBasedFile(thread_->getFilename());
#endif

		vector<String> result;
		String tmp;
		while (search_result.readLine())
		{
			tmp = search_result.getLine();
			Size pos = tmp.find("name=\"PDBID_");

			if (pos != string::npos)
			{
				Size end_pos = tmp.find("\"", pos+12);
				result.push_back(tmp.substr(pos+12,end_pos-(pos+12)));
			}
		}

		for (Size i=0; i<result.size(); i++)
		{
			results->insertItem(result[i].c_str());
		}

		if (result.size() != 0)
		{
			pdbId->setText(result[0].c_str());
		}
	}
	catch (...) { }

	downloadEnded_();
}

void DownloadPDBFile::threadedDownload_(const String& url)
{
	// prevent compiler warnings
	url.isValid();

#ifdef BALL_QT_HAS_THREADS
	downloadStarted_();
	thread_->setURL(url);
	thread_->start();
	while (thread_->running())
	{
		qApp->processEvents(100);
		try
		{
			setStatusbarText("Downloaded: " + String(File::getSize(thread_->getFilename())));
		}
		catch(...)
		{
		}
		thread_->wait(100);
	}

#endif
}

void DownloadPDBFile::slotDownload()
{
	System *system = new System();

	try
	{
		String filename = "http://www.rcsb.org/pdb/cgi/export.cgi/";
		filename += pdbId->text().latin1();
		filename += ".pdb?format=PDB&pdbId=";
		filename += pdbId->text().latin1();
		filename +="&compression=None";
		PDBFile* pdb_file = 0;
#ifndef BALL_QT_HAS_THREADS
		pdb_file = new PDBFile(filename);
#else   // =============================
		downloadStarted_();
		threadedDownload_(filename);
		downloadEnded_();

		if (aborted_)
		{
			delete system;
			return;
		}

		pdb_file = new PDBFile(thread_->getFilename());
#endif

		(*pdb_file) >> *system;
		(*pdb_file).close();
		delete pdb_file;

#ifdef BALL_QT_HAS_THREADS
		try
		{
			File::remove(thread_->getFilename());
		}
		catch(...) {}
#endif

		Log.info() << "> read " << system->countAtoms() << " atoms from URL \"" << filename<< "\"" << std::endl;
		if (system->countAtoms() == 0)
		{
			delete system;
			setStatusbarText("Could not fetch the given PDBFile");
			return;
		}

		if (system->getName() == "")
		{
			system->setName(pdbId->text().latin1());
		}

		system->setProperty("FROM_FILE", filename);
		close();
		getMainControl()->insert(*system, pdbId->text().latin1());
		CompositeMessage* message = new CompositeMessage(*system, CompositeMessage::CENTER_CAMERA);
		notify_(message);
		download->setDefault(true);
		pdbId->setText("");
		pdbId->setFocus();
	}
	catch(...)
	{
		Log.info() << "> download PDB file failed." << std::endl;
		delete system;
	}
}

void DownloadPDBFile::slotShowDetail()
{
	setStatusbarText("Downloading information, please wait...");
	QString filename = "http://www.rcsb.org/pdb/cgi/explore.cgi?job=summary&pdbId=";
	filename += pdbId->text();
	filename += "&page=";

	displayHTML(filename);
}

void DownloadPDBFile::slotNewId(const QString& new_id)
{
	pdbId->setText(new_id);
}

void DownloadPDBFile::displayHTML(const QString& url)
{
	try
	{
		QString filename;

		if (url.find("http://") == -1)
			filename = "http://www.rcsb.org/"+url;
		else
			filename = url;

		Log.info() << "Reading " << filename << std::endl;

		LineBasedFile search_result;
#ifndef BALL_QT_HAS_THREADS
		search_result = LineBasedFile(filename.latin1());
#else
		threadedDownload_(filename.ascii());
		if (aborted_)
		{
			return;
		}

		search_result = LineBasedFile(thread_->getFilename());
#endif

		setStatusbarText("Please wait, while loading images...");

		if (qb_ != 0) delete qb_;
		qb_ = new QTextBrowser();
		String result;

		HashMap<String, QImage> hm;
		String current_line;

		while (search_result.readLine())
		{
			current_line = search_result.getLine();
			result += current_line + "\n";

			// find out all the images
			String tmp = current_line;
			tmp.toUpper();
			Size pos_1 = 0;
			Size pos_2 = 0;

			while ( (pos_1 = tmp.find("<IMG", pos_2)) != string::npos )
			{
				pos_1 = tmp.find("SRC=\"", pos_1);
				pos_2 = current_line.find("\"", pos_1+9);

				String img_url = current_line.substr(pos_1+5, pos_2 - (pos_1+5));
				if (!hm.has(img_url))
				{
					File img("http://www.rcsb.org/"+img_url);
					String tmp_filename;

					File::createTemporaryFilename(tmp_filename);
					img.copyTo(tmp_filename);

					QImage qi;
					qi.load(tmp_filename.c_str());

					File::remove(tmp_filename);

					hm[img_url] = qi;
				}
			}
		}

		HashMap<String, QImage>::Iterator hi;
		for (hi = hm.begin(); hi!=hm.end(); hi++)
		{
			qb_->mimeSourceFactory()->setImage(hi->first.c_str(), hi->second);
		}

		qb_->setText(QString(result.c_str()));

		connect(qb_, SIGNAL(linkClicked(const QString&)), this, SLOT(displayHTML(const QString&)));

		Log.info() << "Finished download of HTML page" << std::endl;

		qb_->showMaximized();
		qb_->show();
	}
	catch (...)
	{
		setStatusbarText("Failed to download HTML page.");
	}

#ifdef BALL_QT_HAS_THREADS
	try
	{
		File::remove(thread_->getFilename());
	}
	catch(...){}
#endif
}

void DownloadPDBFile::idChanged()
{
	download->setEnabled(pdbId->text() != "");
}

void DownloadPDBFile::abort()
{
#ifdef BALL_QT_HAS_THREADS
	if (thread_ != 0)
	{
		thread_->terminate();
	}
	aborted_ = true;

	try
	{
		File::remove(thread_->getFilename());
	}
	catch(...){}
#endif
}

void DownloadPDBFile::downloadStarted_()
	throw()
{
	aborted_ = false;
	setStatusbarText("Started download, please wait...");
	button_abort->setEnabled(true);
	download->setEnabled(false);
	pdbId->setEnabled(false);
	search_box->setEnabled(false);
	showDetails->setEnabled(false);
	buttonClose->setEnabled(false);
}

void DownloadPDBFile::downloadEnded_()
	throw()
{
	if (!aborted_)
	{
		setStatusbarText("Finished downloading, please wait...");
	}
	else
	{
		setStatusbarText("Aborted download");
	}
	button_abort->setEnabled(false);
	download->setEnabled(true);
	pdbId->setEnabled(true);
	search_box->setEnabled(true);
	showDetails->setEnabled(true);
	buttonClose->setEnabled(true);
	idChanged();
}

	}
}
<commit_msg>no message<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
#include <BALL/VIEW/DIALOGS/downloadPDBFile.h>

#include <BALL/FORMAT/lineBasedFile.h>
#include <BALL/FORMAT/PDBFile.h>
#include <BALL/VIEW/KERNEL/mainControl.h>
#include <BALL/VIEW/KERNEL/message.h>
#include <BALL/KERNEL/system.h>
#include <BALL/VIEW/KERNEL/threads.h>

#include <qcombobox.h>
#include <qlineedit.h>
#include <qtextedit.h>
#include <qfile.h>
#include <qurl.h>
#include <qradiobutton.h>
#include <qcheckbox.h>
#include <qimage.h>
#include <qpushbutton.h>
#include <qgroupbox.h>
#include <qapplication.h>

namespace BALL
{
	namespace VIEW
	{

DownloadPDBFile::DownloadPDBFile( QWidget* parent, const char* name, bool modal, WFlags fl )
	throw()
	: DownloadPDBFileData(parent, name, modal, fl),
		ModularWidget(name),
		thread_(0),
		aborted_(false)
{
#ifdef BALL_VIEW_DEBUG
	Log.error() << "new DownloadPDBFile" << this << std::endl;
#endif
	// register the widget with the MainControl
	registerWidget(this);
	hide();
	connect(results, SIGNAL(activated(const QString&)), this, SLOT(slotNewId(const QString&)));

#ifdef BALL_QT_HAS_THREADS
	thread_ = new FetchHTMLThread();
#endif
}

DownloadPDBFile::~DownloadPDBFile()
	throw()
{
#ifdef BALL_VIEW_DEBUG
	Log.info() << "Destructing object " << this << " of class DownloadPDBFile" << std::endl;
#endif

#ifdef BALL_QT_HAS_THREADS
	if (thread_ != 0)
	{
		if (thread_->running())
		{
			thread_->terminate();
			thread_->wait();
		}
		delete thread_;
	}
#endif
}

void DownloadPDBFile::initializeWidget(MainControl& main_control)
	throw()
{
	String hint("Download a PDB file from www.rcsb.org");
	main_control.insertMenuEntry(MainControl::FILE_OPEN, "Download Structure", (QObject *)this,
															 SLOT(show()), ALT+Key_I, -1, hint);
}

void DownloadPDBFile::finalizeWidget(MainControl& main_control)
	throw()
{
	main_control.removeMenuEntry(MainControl::FILE_OPEN, "Downlo&ad Structure", (QObject *)this,
															 SLOT(show()), ALT+Key_A);
}

void DownloadPDBFile::slotSearch()
{
	results->clear();

	QString filename = "http://www.rcsb.org/pdb/cgi/resultBrowser.cgi?Lucene::keyword=";
	QString search_contents = searchField->text();
	QUrl::encode(search_contents);

	filename+=search_contents;
	filename+="&Lucene::keyword_op=";

	filename+=(fullText->isOn()) ? "fullText" : "name";

	if (exactMatch->isOn())
		filename+="&exact=1";
	else
		filename+="&exact=0";

	if (removeSimilar->isOn())
		filename+="&SelectorRedundFilt::on=1";

	try {
		LineBasedFile search_result;
#ifndef BALL_QT_HAS_THREADS
		search_result = LineBasedFile(filename.latin1());
#else   // =============================
		downloadStarted_();
		thread_->setURL(filename.latin1());
		thread_->start();
		while (thread_->running())
		{
			qApp->wakeUpGuiThread();
			qApp->processEvents(500);
			thread_->wait(50);
		}

		search_result = LineBasedFile(thread_->getFilename());
#endif

		vector<String> result;
		String tmp;
		while (search_result.readLine())
		{
			tmp = search_result.getLine();
			Size pos = tmp.find("name=\"PDBID_");

			if (pos != string::npos)
			{
				Size end_pos = tmp.find("\"", pos+12);
				result.push_back(tmp.substr(pos+12,end_pos-(pos+12)));
			}
		}

		for (Size i=0; i<result.size(); i++)
		{
			results->insertItem(result[i].c_str());
		}

		if (result.size() != 0)
		{
			pdbId->setText(result[0].c_str());
		}
	}
	catch (...) { }

	downloadEnded_();
}

void DownloadPDBFile::threadedDownload_(const String& url)
{
	// prevent compiler warnings
	url.isValid();

#ifdef BALL_QT_HAS_THREADS
	downloadStarted_();
	thread_->setURL(url);
	thread_->start();
	while (thread_->running())
	{
		qApp->processEvents();
		try
		{
			setStatusbarText("Downloaded: " + String(File::getSize(thread_->getFilename())));
		}
		catch(...)
		{
		}
		thread_->wait(100);
	}

#endif
}

void DownloadPDBFile::slotDownload()
{
	System *system = new System();

	try
	{
		String filename = "http://www.rcsb.org/pdb/cgi/export.cgi/";
		filename += pdbId->text().latin1();
		filename += ".pdb?format=PDB&pdbId=";
		filename += pdbId->text().latin1();
		filename +="&compression=None";
		PDBFile* pdb_file = 0;
#ifndef BALL_QT_HAS_THREADS
		pdb_file = new PDBFile(filename);
#else   // =============================
		downloadStarted_();
		threadedDownload_(filename);
		downloadEnded_();

		if (aborted_)
		{
			delete system;
			return;
		}

		pdb_file = new PDBFile(thread_->getFilename());
#endif

		(*pdb_file) >> *system;
		(*pdb_file).close();
		delete pdb_file;

#ifdef BALL_QT_HAS_THREADS
		try
		{
			File::remove(thread_->getFilename());
		}
		catch(...) {}
#endif

		setStatusbarText(String("read ") + String(system->countAtoms()) + " atoms from URL \"" + filename + "\"", true);
		if (system->countAtoms() == 0)
		{
			delete system;
			show();
			setStatusbarText("Could not fetch the given PDBFile", true);
			return;
		}

		if (system->getName() == "")
		{
			system->setName(pdbId->text().latin1());
		}

		system->setProperty("FROM_FILE", filename);
		close();
		getMainControl()->insert(*system, pdbId->text().latin1());
		CompositeMessage* message = new CompositeMessage(*system, CompositeMessage::CENTER_CAMERA);
		notify_(message);
		download->setDefault(true);
		pdbId->setText("");
		pdbId->setFocus();
	}
	catch(...)
	{
		setStatusbarText("download PDB file failed", true);
		delete system;
	}
}

void DownloadPDBFile::slotShowDetail()
{
	setStatusbarText("Downloading information, please wait...");
	QString filename = "http://www.rcsb.org/pdb/cgi/explore.cgi?job=summary&pdbId=";
	filename += pdbId->text();
	filename += "&page=";

	displayHTML(filename);
}

void DownloadPDBFile::slotNewId(const QString& new_id)
{
	pdbId->setText(new_id);
}

void DownloadPDBFile::displayHTML(const QString& url)
{
	try
	{
		QString filename;

		if (url.find("http://") == -1)
			filename = "http://www.rcsb.org/"+url;
		else
			filename = url;

		Log.info() << "Reading " << filename << std::endl;

		LineBasedFile search_result;
#ifndef BALL_QT_HAS_THREADS
		search_result = LineBasedFile(filename.latin1());
#else
		threadedDownload_(filename.ascii());
		if (aborted_)
		{
			return;
		}

		search_result = LineBasedFile(thread_->getFilename());
#endif

		setStatusbarText("Please wait, while loading images...");

		if (qb_ != 0) delete qb_;
		qb_ = new QTextBrowser();
		String result;

		HashMap<String, QImage> hm;
		String current_line;

		while (search_result.readLine())
		{
			current_line = search_result.getLine();
			result += current_line + "\n";

			// find out all the images
			String tmp = current_line;
			tmp.toUpper();
			Size pos_1 = 0;
			Size pos_2 = 0;

			while ( (pos_1 = tmp.find("<IMG", pos_2)) != string::npos )
			{
				pos_1 = tmp.find("SRC=\"", pos_1);
				pos_2 = current_line.find("\"", pos_1+9);

				String img_url = current_line.substr(pos_1+5, pos_2 - (pos_1+5));
				if (!hm.has(img_url))
				{
					File img("http://www.rcsb.org/"+img_url);
					String tmp_filename;

					File::createTemporaryFilename(tmp_filename);
					img.copyTo(tmp_filename);

					QImage qi;
					qi.load(tmp_filename.c_str());

					File::remove(tmp_filename);

					hm[img_url] = qi;
				}
			}
		}

		HashMap<String, QImage>::Iterator hi;
		for (hi = hm.begin(); hi!=hm.end(); hi++)
		{
			qb_->mimeSourceFactory()->setImage(hi->first.c_str(), hi->second);
		}

		qb_->setText(QString(result.c_str()));

		connect(qb_, SIGNAL(linkClicked(const QString&)), this, SLOT(displayHTML(const QString&)));

		Log.info() << "Finished download of HTML page" << std::endl;

		qb_->showMaximized();
		qb_->show();
	}
	catch (...)
	{
		setStatusbarText("Failed to download HTML page.");
	}

#ifdef BALL_QT_HAS_THREADS
	try
	{
		File::remove(thread_->getFilename());
	}
	catch(...){}
#endif
}

void DownloadPDBFile::idChanged()
{
	download->setEnabled(pdbId->text() != "");
}

void DownloadPDBFile::abort()
{
#ifdef BALL_QT_HAS_THREADS
	if (thread_ != 0)
	{
		thread_->terminate();
	}
	aborted_ = true;

	try
	{
		File::remove(thread_->getFilename());
	}
	catch(...){}
#endif
}

void DownloadPDBFile::downloadStarted_()
	throw()
{
	hide();
	aborted_ = false;
	setStatusbarText("Started download, please wait...");
	button_abort->setEnabled(true);
	download->setEnabled(false);
	pdbId->setEnabled(false);
	search_box->setEnabled(false);
	showDetails->setEnabled(false);
	buttonClose->setEnabled(false);
}

void DownloadPDBFile::downloadEnded_()
	throw()
{
	if (!aborted_)
	{
		setStatusbarText("Finished downloading, please wait...");
	}
	else
	{
		setStatusbarText("Aborted download");
	}
	button_abort->setEnabled(false);
	download->setEnabled(true);
	pdbId->setEnabled(true);
	search_box->setEnabled(true);
	showDetails->setEnabled(true);
	buttonClose->setEnabled(true);
	idChanged();
}

	}
}
<|endoftext|>