<commit_before>

#include "../bigball.h"
#include "shader.h"
#include "drawutils.h"
#include "rendercontext.h"
#include "gfxmanager.h"

namespace bigball
{

STATIC_MANAGER_CPP( DrawUtils )

DrawUtils::DrawUtils()
{
	m_pStaticInstance = this;
}

DrawUtils::~DrawUtils()
{
	m_pStaticInstance = nullptr;
}

void DrawUtils::Create()
{
    m_util_seg_shader = GfxManager::GetStaticInstance()->LoadShader( "utilseg" );
    m_util_shape_shader = GfxManager::GetStaticInstance()->LoadShader( "utilshape2" );

    glGenVertexArrays( eVACount, m_varrays );
    glGenBuffers( eVBCount, m_vbuffers );

    glBindVertexArray( m_varrays[eVASeg] );
    glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBSeg] );

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(Draw::Vertex) /*stride*/, (void*)0 /*offset*/	);
    glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Draw::Vertex) /*stride*/, (void*)12 /*offset*/	);

    glBindVertexArray(0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    //////////////////////////////////////////////////////////
    // Shape
    const vec3 cube_data[] = { vec3(-1.f, -1.f, -1.f), vec3(-1.f, 1.f, -1.f), vec3(1.f, 1.f, -1.f), vec3(1.f, -1.f, -1.f),
                              vec3(-1.f, -1.f, 1.f), vec3(-1.f, 1.f, 1.f), vec3(1.f, 1.f, 1.f), vec3(1.f, -1.f, 1.f) };

    GLuint idx_data[] = {
            0,1,2, 0,2,3,
            1,0,4, 1,4,5,
            2,1,5, 2,5,6,
            3,2,6, 3,6,7,
            0,3,7, 0,7,4,
            5,4,7, 5,7,6
    };

    glBindVertexArray( m_varrays[eVAShape] );

    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_vbuffers[eVBShapeElt] );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, COUNT_OF(idx_data) * sizeof(GLuint), idx_data, GL_STATIC_DRAW );

    glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapePos] );
    glBufferData( GL_ARRAY_BUFFER, COUNT_OF(cube_data) * sizeof(vec3), cube_data, GL_STATIC_DRAW );
    glEnableVertexAttribArray(0);
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(vec3) /*stride*/, (void*)0 /*offset*/ );

    glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapeMat] );
    for (int i = 0; i < 4; i++ )
    {
        glEnableVertexAttribArray( 1 + i );
        glVertexAttribPointer( 1 + i, 4, GL_FLOAT, GL_FALSE, sizeof(mat4) /*stride*/, (void*)(sizeof(vec4) * i) /*offset*/ );
        glVertexAttribDivisor( 1 + i, 1 );
    }

    int offset_params = 0;
    glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapeParams] );
    glEnableVertexAttribArray(5);
    glVertexAttribPointer( 5, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Draw::InstanceParams) /*stride*/, (void*)offset_params );
    glVertexAttribDivisor( 5, 1 );
    offset_params += sizeof(u8vec4);

    //glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapeParams] );
    glEnableVertexAttribArray(6);
    glVertexAttribPointer( 6, 3, GL_FLOAT, GL_FALSE, sizeof(Draw::InstanceParams) /*stride*/, (void*)offset_params );
    glVertexAttribDivisor( 6, 1 );
    offset_params += sizeof(vec3);

    //glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapeEye] );
    glEnableVertexAttribArray(7);
    glVertexAttribPointer( 7, 3, GL_FLOAT, GL_FALSE, sizeof(Draw::InstanceParams) /*stride*/, (void*)offset_params);
    glVertexAttribDivisor( 7, 1 );

    glBindVertexArray(0);
    for( int attrib_idx = 0; attrib_idx < 8; attrib_idx++)
        glDisableVertexAttribArray( attrib_idx);
}

void DrawUtils::Destroy()
{
    glDeleteBuffers( eVBCount, m_vbuffers );
    glDeleteVertexArrays( eVACount, m_varrays );
}

void DrawUtils::Tick( TickContext& tick_ctxt )
{

}

void DrawUtils::_Render( struct RenderContext& render_ctxt )
{
	mat4 cam_to_world_mat(render_ctxt.m_view.m_transform.GetRotation(), render_ctxt.m_view.m_transform.GetTranslation(), (float)render_ctxt.m_view.m_transform.GetScale());
    mat4 view_mat = bigball::inverse(cam_to_world_mat);

    // Transform camera eye pos to box frame
    for( int32 shape_idx = 0; shape_idx < m_shape_params.size(); shape_idx++ )
    {
        Draw::InstanceParams& params = m_shape_params[shape_idx];
        mat4 const& box_to_world = m_shape_matrices[shape_idx];
        mat4 box_to_view = view_mat * box_to_world;
        params.m_eye_to_box = (inverse( box_to_view ) * vec4(0.f, 0.f, 0.f, 1.f)).xyz;
    }

    // Render Segments
    m_util_seg_shader->Bind();
    {
        ShaderUniform UniProj = m_util_seg_shader->GetUniformLocation("proj_mat");
        m_util_seg_shader->SetUniform( UniProj, render_ctxt.m_proj_mat );
        ShaderUniform UniView = m_util_seg_shader->GetUniformLocation("view_mat");
        m_util_seg_shader->SetUniform( UniView, view_mat );

        glBindVertexArray( m_varrays[eVASeg] );

        glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBSeg]);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_seg_buffer.size() * sizeof(Draw::Vertex), (GLvoid*)m_seg_buffer.Data(), GL_DYNAMIC_DRAW );

        for( int iSL = 0; iSL < m_seg_list.size(); iSL++)
        {
            Draw::BufferRange const& seg_list = m_seg_list[iSL];
            glDrawArrays(/*GL_TRIANGLE_STRIP*/GL_LINE_STRIP, seg_list.m_offset, seg_list.m_count );
        }

        glBindVertexArray(0);
    }
    m_util_seg_shader->Unbind();

    // Render Shapes
    m_util_shape_shader->Bind();
    {
        ShaderUniform UniProj = m_util_shape_shader->GetUniformLocation("proj_mat");
        m_util_shape_shader->SetUniform( UniProj, render_ctxt.m_proj_mat );
        ShaderUniform UniView = m_util_shape_shader->GetUniformLocation("view_mat");
        m_util_shape_shader->SetUniform( UniView, view_mat );

        glBindVertexArray( m_varrays[eVAShape] );

        //glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBShapeCol]);
        //glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_shape_colors.size() * sizeof(u8vec4), (GLvoid*)m_shape_colors.Data(), GL_DYNAMIC_DRAW );

        glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBShapeMat]);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_shape_matrices.size() * sizeof(mat4), (GLvoid*)m_shape_matrices.Data(), GL_DYNAMIC_DRAW );

        glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBShapeParams]);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_shape_params.size() * sizeof(Draw::InstanceParams), (GLvoid*)m_shape_params.Data(), GL_DYNAMIC_DRAW );

        //glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBShapeEye]);
        //glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_shape_eye_to_boxes.size() * sizeof(vec3), (GLvoid*)m_shape_eye_to_boxes.Data(), GL_DYNAMIC_DRAW );

        glDrawElementsInstanced( GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void*)0, m_shape_matrices.size() );

        glBindVertexArray(0);
    }
    m_util_shape_shader->Unbind();

	// Purge old elements
	RemoveOldElements( render_ctxt.m_delta_seconds );
}

void DrawUtils::RemoveOldElements( float delta_seconds )
{
    m_seg_list.clear();
    m_seg_buffer.clear();

    //for (int i = 0; i < Draw::ShapeType::Count; i++)
    {
        m_shapes.m_offset = 0;
        m_shapes.m_count = 0;
    }
    //m_shape_colors.clear();
    m_shape_matrices.clear();
    m_shape_params.clear();
    //m_shape_eye_to_boxes.clear();

#if 0
    for( int i = m_Segments.size() - 1; i >= 0 ; i++ )
    {
        if( m_Segments[i].persist_time < 0.f )
            continue;

        m_Segments[i].persist_time = bigball::max( 0.f, m_Segments[i].persist_time - DeltaSeconds );
        if( m_Segments[i].persist_time == 0.f )
            m_Segments.erase(i);
    }

    for( int i = m_SegmentList.size() - 1; i >= 0 ; i++ )
    {
        if( m_SegmentList[i].persist_time < 0.f )
            continue;

        m_SegmentList[i].persist_time = bigball::max( 0.f, m_SegmentList[i].persist_time - DeltaSeconds );
        if( m_SegmentList[i].persist_time == 0.f )
            m_SegmentList.erase(i);
    }

    for( int i = m_Shapes.size() - 1; i >= 0 ; i++ )
    {
        if( m_Shapes[i].persist_time < 0.f )
            continue;

        m_Shapes[i].persist_time = bigball::max( 0.f, m_Shapes[i].persist_time - DeltaSeconds );
        if( m_Shapes[i].persist_time == 0.f )
            m_Shapes.erase(i);
    }
#endif
}

void DrawUtils::PushSegment( vec3 p0, vec3 p1, u8vec4 color0, u8vec4 color1 )
{
    const int offset = m_seg_buffer.size();
	Draw::Vertex v0 = { p0, color0 };
	Draw::Vertex v1 = { p1, color1 };
    m_seg_buffer.push_back( v0 );
    m_seg_buffer.push_back( v1 );
	Draw::BufferRange seg_list = { offset, 2 };
    m_seg_list.push_back( seg_list );
}
void DrawUtils::PushSegmentList( Array<vec3> const& segment_list, u8vec4 color )
{
    const int offset = m_seg_buffer.size();
    for( int i =0; i < segment_list.size(); i++ )
    {
		Draw::Vertex v = { segment_list[i], color };
        m_seg_buffer.push_back( v );
    }
	Draw::BufferRange seg_list = { offset, segment_list.size() };
	m_seg_list.push_back( seg_list );
}
void DrawUtils::PushSegmentList( Array<vec3> const& segment_list, Array<u8vec4> const& color_list )
{
    const int offset = m_seg_buffer.size();
    for( int i =0; i < segment_list.size(); i++ )
    {
        Draw::Vertex v = { segment_list[i], color_list[i] };
        m_seg_buffer.push_back( v );
    }
    Draw::BufferRange seg_list = { offset, segment_list.size() };
    m_seg_list.push_back( seg_list );
}
void DrawUtils::PushOBB( transform const& t, u8vec4 color, float ratio_y, float ratio_z )
{
    PushGenericShape( t, color, Draw::Box, ratio_y, ratio_z);
}
void DrawUtils::PushAABB( vec3 pos, float scale, u8vec4 color, float ratio_y, float ratio_z )
{
    PushGenericShape( transform( quat(1.f,0.f,0.f,0.f), pos, scale ), color, Draw::Box, ratio_y, ratio_z);
}
void DrawUtils::PushSphere( vec3 pos, float scale, u8vec4 color )
{
    PushGenericShape( transform( quat(1.f,0.f,0.f,0.f), pos, scale ), color, Draw::Sphere );
}
void DrawUtils::PushCylinder( transform const& t, u8vec4 color, float ratio_radius )
{
    PushGenericShape( t, color, Draw::Cylinder, ratio_radius );
}
void DrawUtils::PushGenericShape( transform const& t, u8vec4 color, Draw::ShapeType type, float param0, float param1 )
{
    mat4 m( t.GetRotation(), t.GetTranslation(), t.GetScale() );
    m_shape_matrices.push_back( m );

    Draw::InstanceParams params = { color, vec3((float)type, param0, param1), t.GetTranslation() };
    m_shape_params.push_back(params);

    m_shapes.m_offset = 0;
    m_shapes.m_count = m_shape_matrices.size();
}

} /*namespace bigball*/<commit_msg>minor fix drawutils<commit_after>

#include "../bigball.h"
#include "shader.h"
#include "drawutils.h"
#include "rendercontext.h"
#include "gfxmanager.h"

namespace bigball
{

STATIC_MANAGER_CPP( DrawUtils )

DrawUtils::DrawUtils()
{
	m_pStaticInstance = this;
}

DrawUtils::~DrawUtils()
{
	m_pStaticInstance = nullptr;
}

void DrawUtils::Create()
{
    m_util_seg_shader = GfxManager::GetStaticInstance()->LoadShader( "utilseg" );
    m_util_shape_shader = GfxManager::GetStaticInstance()->LoadShader( "utilshape" );

    glGenVertexArrays( eVACount, m_varrays );
    glGenBuffers( eVBCount, m_vbuffers );

    glBindVertexArray( m_varrays[eVASeg] );
    glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBSeg] );

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(Draw::Vertex) /*stride*/, (void*)0 /*offset*/	);
    glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Draw::Vertex) /*stride*/, (void*)12 /*offset*/	);

    glBindVertexArray(0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    //////////////////////////////////////////////////////////
    // Shape
    const vec3 cube_data[] = { vec3(-1.f, -1.f, -1.f), vec3(-1.f, 1.f, -1.f), vec3(1.f, 1.f, -1.f), vec3(1.f, -1.f, -1.f),
                              vec3(-1.f, -1.f, 1.f), vec3(-1.f, 1.f, 1.f), vec3(1.f, 1.f, 1.f), vec3(1.f, -1.f, 1.f) };

    GLuint idx_data[] = {
            0,1,2, 0,2,3,
            1,0,4, 1,4,5,
            2,1,5, 2,5,6,
            3,2,6, 3,6,7,
            0,3,7, 0,7,4,
            5,4,7, 5,7,6
    };

    glBindVertexArray( m_varrays[eVAShape] );

    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_vbuffers[eVBShapeElt] );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, COUNT_OF(idx_data) * sizeof(GLuint), idx_data, GL_STATIC_DRAW );

    glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapePos] );
    glBufferData( GL_ARRAY_BUFFER, COUNT_OF(cube_data) * sizeof(vec3), cube_data, GL_STATIC_DRAW );
    glEnableVertexAttribArray(0);
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof(vec3) /*stride*/, (void*)0 /*offset*/ );

    glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapeMat] );
    for (int i = 0; i < 4; i++ )
    {
        glEnableVertexAttribArray( 1 + i );
        glVertexAttribPointer( 1 + i, 4, GL_FLOAT, GL_FALSE, sizeof(mat4) /*stride*/, (void*)(sizeof(vec4) * i) /*offset*/ );
        glVertexAttribDivisor( 1 + i, 1 );
    }

    int offset_params = 0;
    glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapeParams] );
    glEnableVertexAttribArray(5);
    glVertexAttribPointer( 5, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Draw::InstanceParams) /*stride*/, (void*)offset_params );
    glVertexAttribDivisor( 5, 1 );
    offset_params += sizeof(u8vec4);

    //glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapeParams] );
    glEnableVertexAttribArray(6);
    glVertexAttribPointer( 6, 3, GL_FLOAT, GL_FALSE, sizeof(Draw::InstanceParams) /*stride*/, (void*)offset_params );
    glVertexAttribDivisor( 6, 1 );
    offset_params += sizeof(vec3);

    //glBindBuffer( GL_ARRAY_BUFFER, m_vbuffers[eVBShapeEye] );
    glEnableVertexAttribArray(7);
    glVertexAttribPointer( 7, 3, GL_FLOAT, GL_FALSE, sizeof(Draw::InstanceParams) /*stride*/, (void*)offset_params);
    glVertexAttribDivisor( 7, 1 );

    glBindVertexArray(0);
    for( int attrib_idx = 0; attrib_idx < 8; attrib_idx++)
        glDisableVertexAttribArray( attrib_idx);
}

void DrawUtils::Destroy()
{
    glDeleteBuffers( eVBCount, m_vbuffers );
    glDeleteVertexArrays( eVACount, m_varrays );
}

void DrawUtils::Tick( TickContext& tick_ctxt )
{

}

void DrawUtils::_Render( struct RenderContext& render_ctxt )
{
	mat4 cam_to_world_mat(render_ctxt.m_view.m_transform.GetRotation(), render_ctxt.m_view.m_transform.GetTranslation(), (float)render_ctxt.m_view.m_transform.GetScale());
    mat4 view_mat = bigball::inverse(cam_to_world_mat);

    // Transform camera eye pos to box frame
    for( int32 shape_idx = 0; shape_idx < m_shape_params.size(); shape_idx++ )
    {
        Draw::InstanceParams& params = m_shape_params[shape_idx];
        mat4 const& box_to_world = m_shape_matrices[shape_idx];
        mat4 box_to_view = view_mat * box_to_world;
        params.m_eye_to_box = (inverse( box_to_view ) * vec4(0.f, 0.f, 0.f, 1.f)).xyz;
    }

    // Render Segments
    m_util_seg_shader->Bind();
    {
        ShaderUniform UniProj = m_util_seg_shader->GetUniformLocation("proj_mat");
        m_util_seg_shader->SetUniform( UniProj, render_ctxt.m_proj_mat );
        ShaderUniform UniView = m_util_seg_shader->GetUniformLocation("view_mat");
        m_util_seg_shader->SetUniform( UniView, view_mat );

        glBindVertexArray( m_varrays[eVASeg] );

        glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBSeg]);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_seg_buffer.size() * sizeof(Draw::Vertex), (GLvoid*)m_seg_buffer.Data(), GL_DYNAMIC_DRAW );

        for( int iSL = 0; iSL < m_seg_list.size(); iSL++)
        {
            Draw::BufferRange const& seg_list = m_seg_list[iSL];
            glDrawArrays(/*GL_TRIANGLE_STRIP*/GL_LINE_STRIP, seg_list.m_offset, seg_list.m_count );
        }

        glBindVertexArray(0);
    }
    m_util_seg_shader->Unbind();

    // Render Shapes
    m_util_shape_shader->Bind();
    {
        ShaderUniform UniProj = m_util_shape_shader->GetUniformLocation("proj_mat");
        m_util_shape_shader->SetUniform( UniProj, render_ctxt.m_proj_mat );
        ShaderUniform UniView = m_util_shape_shader->GetUniformLocation("view_mat");
        m_util_shape_shader->SetUniform( UniView, view_mat );

        glBindVertexArray( m_varrays[eVAShape] );

        //glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBShapeCol]);
        //glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_shape_colors.size() * sizeof(u8vec4), (GLvoid*)m_shape_colors.Data(), GL_DYNAMIC_DRAW );

        glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBShapeMat]);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_shape_matrices.size() * sizeof(mat4), (GLvoid*)m_shape_matrices.Data(), GL_DYNAMIC_DRAW );

        glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBShapeParams]);
        glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_shape_params.size() * sizeof(Draw::InstanceParams), (GLvoid*)m_shape_params.Data(), GL_DYNAMIC_DRAW );

        //glBindBuffer(GL_ARRAY_BUFFER, m_vbuffers[eVBShapeEye]);
        //glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)m_shape_eye_to_boxes.size() * sizeof(vec3), (GLvoid*)m_shape_eye_to_boxes.Data(), GL_DYNAMIC_DRAW );

        glDrawElementsInstanced( GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void*)0, m_shape_matrices.size() );

        glBindVertexArray(0);
    }
    m_util_shape_shader->Unbind();

	// Purge old elements
	RemoveOldElements( render_ctxt.m_delta_seconds );
}

void DrawUtils::RemoveOldElements( float delta_seconds )
{
    m_seg_list.clear();
    m_seg_buffer.clear();

    //for (int i = 0; i < Draw::ShapeType::Count; i++)
    {
        m_shapes.m_offset = 0;
        m_shapes.m_count = 0;
    }
    //m_shape_colors.clear();
    m_shape_matrices.clear();
    m_shape_params.clear();
    //m_shape_eye_to_boxes.clear();

#if 0
    for( int i = m_Segments.size() - 1; i >= 0 ; i++ )
    {
        if( m_Segments[i].persist_time < 0.f )
            continue;

        m_Segments[i].persist_time = bigball::max( 0.f, m_Segments[i].persist_time - DeltaSeconds );
        if( m_Segments[i].persist_time == 0.f )
            m_Segments.erase(i);
    }

    for( int i = m_SegmentList.size() - 1; i >= 0 ; i++ )
    {
        if( m_SegmentList[i].persist_time < 0.f )
            continue;

        m_SegmentList[i].persist_time = bigball::max( 0.f, m_SegmentList[i].persist_time - DeltaSeconds );
        if( m_SegmentList[i].persist_time == 0.f )
            m_SegmentList.erase(i);
    }

    for( int i = m_Shapes.size() - 1; i >= 0 ; i++ )
    {
        if( m_Shapes[i].persist_time < 0.f )
            continue;

        m_Shapes[i].persist_time = bigball::max( 0.f, m_Shapes[i].persist_time - DeltaSeconds );
        if( m_Shapes[i].persist_time == 0.f )
            m_Shapes.erase(i);
    }
#endif
}

void DrawUtils::PushSegment( vec3 p0, vec3 p1, u8vec4 color0, u8vec4 color1 )
{
    const int offset = m_seg_buffer.size();
	Draw::Vertex v0 = { p0, color0 };
	Draw::Vertex v1 = { p1, color1 };
    m_seg_buffer.push_back( v0 );
    m_seg_buffer.push_back( v1 );
	Draw::BufferRange seg_list = { offset, 2 };
    m_seg_list.push_back( seg_list );
}
void DrawUtils::PushSegmentList( Array<vec3> const& segment_list, u8vec4 color )
{
    const int offset = m_seg_buffer.size();
    for( int i =0; i < segment_list.size(); i++ )
    {
		Draw::Vertex v = { segment_list[i], color };
        m_seg_buffer.push_back( v );
    }
	Draw::BufferRange seg_list = { offset, segment_list.size() };
	m_seg_list.push_back( seg_list );
}
void DrawUtils::PushSegmentList( Array<vec3> const& segment_list, Array<u8vec4> const& color_list )
{
    const int offset = m_seg_buffer.size();
    for( int i =0; i < segment_list.size(); i++ )
    {
        Draw::Vertex v = { segment_list[i], color_list[i] };
        m_seg_buffer.push_back( v );
    }
    Draw::BufferRange seg_list = { offset, segment_list.size() };
    m_seg_list.push_back( seg_list );
}
void DrawUtils::PushOBB( transform const& t, u8vec4 color, float ratio_y, float ratio_z )
{
    PushGenericShape( t, color, Draw::Box, ratio_y, ratio_z);
}
void DrawUtils::PushAABB( vec3 pos, float scale, u8vec4 color, float ratio_y, float ratio_z )
{
    PushGenericShape( transform( quat(1.f,0.f,0.f,0.f), pos, scale ), color, Draw::Box, ratio_y, ratio_z);
}
void DrawUtils::PushSphere( vec3 pos, float scale, u8vec4 color )
{
    PushGenericShape( transform( quat(1.f,0.f,0.f,0.f), pos, scale ), color, Draw::Sphere );
}
void DrawUtils::PushCylinder( transform const& t, u8vec4 color, float ratio_radius )
{
    PushGenericShape( t, color, Draw::Cylinder, ratio_radius );
}
void DrawUtils::PushGenericShape( transform const& t, u8vec4 color, Draw::ShapeType type, float param0, float param1 )
{
    mat4 m( t.GetRotation(), t.GetTranslation(), t.GetScale() );
    m_shape_matrices.push_back( m );

    Draw::InstanceParams params = { color, vec3((float)type, param0, param1), t.GetTranslation() };
    m_shape_params.push_back(params);

    m_shapes.m_offset = 0;
    m_shapes.m_count = m_shape_matrices.size();
}

} /*namespace bigball*/<|endoftext|>


<commit_before>#ifndef IAUNS_ENTITY_SYSTEM_BASESYSTEM_HPP
#define IAUNS_ENTITY_SYSTEM_BASESYSTEM_HPP

namespace CPM_ES_NS {

class ESCoreBase;

class BaseSystem
{
public:
  BaseSystem() {}
  virtual ~BaseSystem() {}

  virtual void walkComponents(ESCoreBase& core) = 0;
  virtual bool walkEntity(ESCoreBase& core, uint64_t entityID) = 0;

  virtual const char* getID() {return nullptr;}
};

} // namespace CPM_ES_NS

#endif
<commit_msg>Get rid of getID virtual method call.<commit_after>#ifndef IAUNS_ENTITY_SYSTEM_BASESYSTEM_HPP
#define IAUNS_ENTITY_SYSTEM_BASESYSTEM_HPP

namespace CPM_ES_NS {

class ESCoreBase;

class BaseSystem
{
public:
  BaseSystem()          {}
  virtual ~BaseSystem() {}

  virtual void walkComponents(ESCoreBase& core) = 0;
  virtual bool walkEntity(ESCoreBase& core, uint64_t entityID) = 0;
};

} // namespace CPM_ES_NS

#endif
<|endoftext|>


<commit_before>#pragma once
/*
* Copyright (c) Aldebaran Robotics 2013 All Rights Reserved
*/
#ifndef _QI_PERIODICTASK_HPP_
# define _QI_PERIODICTASK_HPP_

# include <string>

# include <boost/function.hpp>
# include <boost/utility.hpp>

# include <qi/atomic.hpp>
# include <qi/future.hpp>
# include <qi/stats.hpp>
# include <qi/trackable.hpp>
# include <qi/actor.hpp>
# include <qi/clock.hpp>

namespace qi
{
  struct PeriodicTaskPrivate;
  /**
   * \brief Control a task executed periodically and asynchronously.
   * \includename{qi/periodictask.hpp}
   */
  class QI_API PeriodicTask: public boost::noncopyable
  {
  public:
    /// \brief Callback is a boost::function.
    typedef boost::function<void()> Callback;
    // internal
    typedef boost::function<qi::Future<void>(
        const Callback&, qi::Duration delay)> ScheduleCallback;

    /// \brief Default constructor.
    PeriodicTask();

    /// \brief Default destructor.
    ~PeriodicTask();

    /// @{
    /**
     * One of the setCallback() functions below must be called before
     * any other operation. Once set the callback cannot be changed.
     * If the callback throws, async task will be stopped
     */
    void setCallback(const Callback& cb);
#ifdef DOXYGEN
    template <typename T, typename ARG0> PeriodicTask& setCallback(T&& callable, ARG0&& tracked, ...);
#else
    template <typename AF, typename ARG0, typename... ARGS>
    inline void setCallback(AF&& callable, ARG0&& arg0, ARGS&&... args)
    {
      setCallback(boost::bind(std::forward<AF>(callable), arg0, std::forward<ARGS>(args)...));
      _connectMaybeActor<ARG0>(arg0);
    }
#endif

    /**
     * Set the strand on which to schedule the calls
     *
     * \warning This must be called *after* the call to setCallback or it will
     * have no effect.
     */
    void setStrand(qi::Strand* strand);

    /** \brief Set the call interval in microseconds.
     * \deprecated since 2.3. Use setPeriod.
     */
    void setUsPeriod(qi::int64_t usPeriod);

    /**
     * \brief Set the call interval.
     * \param period the PeriodicTask period
     *
     * This call will wait until next callback invocation to apply the change.
     * If you call this function from within the callback, it will be taken into
     * account immediately.
     */
    void setPeriod(qi::Duration period);

    /**
     * \brief Start the periodic task at specified period.
     *
     * No effect if already running. No effect if called from within the
     * callback.
     * \param immediate if true, first schedule of the task will happen with no delay.
     * \warning concurrent calls to start() and stop() will result in undefined behavior.
     */
    void start(bool immediate = true);

    /**
     * Trigger a started periodic task to run right now.
     * Does nothing if the periodic task just ran, is running, starting,
     * stopping or stopped.
     * This function is lockfree.
     */
    void trigger();

    /**
     * \brief Stop the periodic task.
     *
     * When this function returns, the callback will not be called anymore.
     * Can be called from within the callback function.
     * \warning concurrent calls to start() and stop() will result in undefined behavior.
     */
    void stop();

    /**
     * \brief Request for periodic task to stop asynchronously.
     * Can be safely called from within the callback.
     */
    void asyncStop();

    /**
     * If argument is true, call interval will take into account call duration
     * to maintain the period.
     */
    void compensateCallbackTime(bool compensate);

    /// \brief Set name for debugging and tracking purpose.
    /// \param name Name of the periodic task.
    void setName(const std::string& name);

    /// \return true if task is running
    bool isRunning() const;

    /**
     * \return whether state is stopping or stopped
     *
     * Can be called from within the callback to know if stop() or asyncStop()
     * was called.
     */
    bool isStopping() const;

  private:
    boost::shared_ptr<PeriodicTaskPrivate> _p;

    template <typename ARG0>
    inline typename boost::enable_if<
        boost::is_base_of<Actor, typename detail::Unwrap<ARG0>::type>,
        void>::type
        _connectMaybeActor(const ARG0& arg0)
    {
      setStrand(detail::Unwrap<ARG0>::unwrap(arg0)->strand());
    }
    template <typename ARG0>
    inline typename boost::disable_if<
        boost::is_base_of<Actor, typename detail::Unwrap<ARG0>::type>,
        void>::type
        _connectMaybeActor(const ARG0& arg0)
    {
      setStrand(0);
    }
  };

}
#endif
<commit_msg>PeriodicTask: add forward<commit_after>#pragma once
/*
* Copyright (c) Aldebaran Robotics 2013 All Rights Reserved
*/
#ifndef _QI_PERIODICTASK_HPP_
# define _QI_PERIODICTASK_HPP_

# include <string>

# include <boost/function.hpp>
# include <boost/utility.hpp>

# include <qi/atomic.hpp>
# include <qi/future.hpp>
# include <qi/stats.hpp>
# include <qi/trackable.hpp>
# include <qi/actor.hpp>
# include <qi/clock.hpp>

namespace qi
{
  struct PeriodicTaskPrivate;
  /**
   * \brief Control a task executed periodically and asynchronously.
   * \includename{qi/periodictask.hpp}
   */
  class QI_API PeriodicTask: public boost::noncopyable
  {
  public:
    /// \brief Callback is a boost::function.
    typedef boost::function<void()> Callback;
    // internal
    typedef boost::function<qi::Future<void>(
        const Callback&, qi::Duration delay)> ScheduleCallback;

    /// \brief Default constructor.
    PeriodicTask();

    /// \brief Default destructor.
    ~PeriodicTask();

    /// @{
    /**
     * One of the setCallback() functions below must be called before
     * any other operation. Once set the callback cannot be changed.
     * If the callback throws, async task will be stopped
     */
    void setCallback(const Callback& cb);
#ifdef DOXYGEN
    template <typename T, typename ARG0> PeriodicTask& setCallback(T&& callable, ARG0&& tracked, ...);
#else
    template <typename AF, typename ARG0, typename... ARGS>
    inline void setCallback(AF&& callable, ARG0&& arg0, ARGS&&... args)
    {
      _connectMaybeActor(arg0);
      setCallback(boost::bind(std::forward<AF>(callable), std::forward<ARG0>(arg0), std::forward<ARGS>(args)...));
    }
#endif

    /**
     * Set the strand on which to schedule the calls
     *
     * \warning This must be called *after* the call to setCallback or it will
     * have no effect.
     */
    void setStrand(qi::Strand* strand);

    /** \brief Set the call interval in microseconds.
     * \deprecated since 2.3. Use setPeriod.
     */
    void setUsPeriod(qi::int64_t usPeriod);

    /**
     * \brief Set the call interval.
     * \param period the PeriodicTask period
     *
     * This call will wait until next callback invocation to apply the change.
     * If you call this function from within the callback, it will be taken into
     * account immediately.
     */
    void setPeriod(qi::Duration period);

    /**
     * \brief Start the periodic task at specified period.
     *
     * No effect if already running. No effect if called from within the
     * callback.
     * \param immediate if true, first schedule of the task will happen with no delay.
     * \warning concurrent calls to start() and stop() will result in undefined behavior.
     */
    void start(bool immediate = true);

    /**
     * Trigger a started periodic task to run right now.
     * Does nothing if the periodic task just ran, is running, starting,
     * stopping or stopped.
     * This function is lockfree.
     */
    void trigger();

    /**
     * \brief Stop the periodic task.
     *
     * When this function returns, the callback will not be called anymore.
     * Can be called from within the callback function.
     * \warning concurrent calls to start() and stop() will result in undefined behavior.
     */
    void stop();

    /**
     * \brief Request for periodic task to stop asynchronously.
     * Can be safely called from within the callback.
     */
    void asyncStop();

    /**
     * If argument is true, call interval will take into account call duration
     * to maintain the period.
     */
    void compensateCallbackTime(bool compensate);

    /// \brief Set name for debugging and tracking purpose.
    /// \param name Name of the periodic task.
    void setName(const std::string& name);

    /// \return true if task is running
    bool isRunning() const;

    /**
     * \return whether state is stopping or stopped
     *
     * Can be called from within the callback to know if stop() or asyncStop()
     * was called.
     */
    bool isStopping() const;

  private:
    boost::shared_ptr<PeriodicTaskPrivate> _p;

    template <typename ARG0>
    inline typename boost::enable_if<
        boost::is_base_of<Actor, typename detail::Unwrap<ARG0>::type>,
        void>::type
        _connectMaybeActor(const ARG0& arg0)
    {
      setStrand(detail::Unwrap<ARG0>::unwrap(arg0)->strand());
    }
    template <typename ARG0>
    inline typename boost::disable_if<
        boost::is_base_of<Actor, typename detail::Unwrap<ARG0>::type>,
        void>::type
        _connectMaybeActor(const ARG0& arg0)
    {
      setStrand(0);
    }
  };

}
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "query-result-set.hh"
#include "query-result-reader.hh"
#include "partition_slice_builder.hh"
#include "mutation.hh"
#include "types/map.hh"
#include "utils/exceptions.hh"

#include <fmt/format.h>

namespace query {

class deserialization_error : public std::runtime_error {
public:
    using runtime_error::runtime_error;
};

// Result set builder is passed as a visitor to query_result::consume()
// function. You can call the build() method to obtain a result set that
// contains cells from the visited results.
class result_set_builder {
    schema_ptr _schema;
    const partition_slice& _slice;
    std::vector<result_set_row> _rows;
    std::unordered_map<sstring, non_null_data_value> _pkey_cells;
    uint64_t _row_count;
public:
    // Keep slice live as long as the builder is used.
    result_set_builder(schema_ptr schema, const partition_slice& slice);
    result_set build();
    void accept_new_partition(const partition_key& key, uint64_t row_count);
    void accept_new_partition(uint64_t row_count);
    void accept_new_row(const clustering_key& key, const result_row_view& static_row, const result_row_view& row);
    void accept_new_row(const result_row_view &static_row, const result_row_view &row);
    void accept_partition_end(const result_row_view& static_row);
private:
    std::unordered_map<sstring, non_null_data_value> deserialize(const partition_key& key);
    std::unordered_map<sstring, non_null_data_value> deserialize(const clustering_key& key);
    std::unordered_map<sstring, non_null_data_value> deserialize(const result_row_view& row, bool is_static);
};

std::ostream& operator<<(std::ostream& out, const result_set_row& row) {
    for (auto&& cell : row._cells) {
        auto&& type = static_cast<const data_value&>(cell.second).type();
        auto&& value = cell.second;
        out << cell.first << "=\"" << type->to_string(type->decompose(value)) << "\" ";
    }
    return out;
}

std::ostream& operator<<(std::ostream& out, const result_set& rs) {
    for (auto&& row : rs._rows) {
        out << row << std::endl;
    }
    return out;
}

static logging::logger query_result_log("query result log");

non_null_data_value::non_null_data_value(data_value&& v) : _v(std::move(v)) {
    if (_v.is_null()) {
        on_internal_error(query_result_log, "Trying to add a null data_value to a result_set_row");
    }
}

result_set_builder::result_set_builder(schema_ptr schema, const partition_slice& slice)
    : _schema{schema}, _slice(slice)
{ }

result_set result_set_builder::build() {
    return { _schema, std::move(_rows) };
}

void result_set_builder::accept_new_partition(const partition_key& key, uint64_t row_count)
{
    _pkey_cells = deserialize(key);
    accept_new_partition(row_count);
}

void result_set_builder::accept_new_partition(uint64_t row_count)
{
    _row_count = row_count;
}

void result_set_builder::accept_new_row(const clustering_key& key, const result_row_view& static_row, const result_row_view& row)
{
    auto ckey_cells = deserialize(key);
    auto static_cells = deserialize(static_row, true);
    auto regular_cells = deserialize(row, false);

    std::unordered_map<sstring, non_null_data_value> cells;
    cells.insert(_pkey_cells.begin(), _pkey_cells.end());
    cells.insert(ckey_cells.begin(), ckey_cells.end());
    cells.insert(static_cells.begin(), static_cells.end());
    cells.insert(regular_cells.begin(), regular_cells.end());
    _rows.emplace_back(_schema, std::move(cells));
}

void result_set_builder::accept_new_row(const query::result_row_view &static_row, const query::result_row_view &row)
{
    auto static_cells = deserialize(static_row, true);
    auto regular_cells = deserialize(row, false);

    std::unordered_map<sstring, non_null_data_value> cells;
    cells.insert(_pkey_cells.begin(), _pkey_cells.end());
    cells.insert(static_cells.begin(), static_cells.end());
    cells.insert(regular_cells.begin(), regular_cells.end());
    _rows.emplace_back(_schema, std::move(cells));
}

void result_set_builder::accept_partition_end(const result_row_view& static_row)
{
    if (_row_count == 0) {
        auto static_cells = deserialize(static_row, true);
        std::unordered_map<sstring, non_null_data_value> cells;
        cells.insert(_pkey_cells.begin(), _pkey_cells.end());
        cells.insert(static_cells.begin(), static_cells.end());
        _rows.emplace_back(_schema, std::move(cells));
    }
    _pkey_cells.clear();
}

std::unordered_map<sstring, non_null_data_value>
result_set_builder::deserialize(const partition_key& key)
{
    std::unordered_map<sstring, non_null_data_value> cells;
    auto i = key.begin(*_schema);
    for (auto&& col : _schema->partition_key_columns()) {
        cells.emplace(col.name_as_text(), col.type->deserialize_value(*i));
        ++i;
    }
    return cells;
}

std::unordered_map<sstring, non_null_data_value>
result_set_builder::deserialize(const clustering_key& key)
{
    std::unordered_map<sstring, non_null_data_value> cells;
    auto i = key.begin(*_schema);
    for (auto&& col : _schema->clustering_key_columns()) {
        if (i == key.end(*_schema)) {
            break;
        }
        cells.emplace(col.name_as_text(), col.type->deserialize_value(*i));
        ++i;
    }
    return cells;
}

std::unordered_map<sstring, non_null_data_value>
result_set_builder::deserialize(const result_row_view& row, bool is_static)
{
    std::unordered_map<sstring, non_null_data_value> cells;
    auto i = row.iterator();
    auto column_ids = is_static ? _slice.static_columns : _slice.regular_columns;
    auto columns = column_ids | boost::adaptors::transformed([this, is_static] (column_id id) -> const column_definition& {
        if (is_static) {
            return _schema->static_column_at(id);
        } else {
            return _schema->regular_column_at(id);
        }
    });
    size_t index = 0;
    for (auto &&col : columns) {
      try {
        if (col.is_atomic()) {
            auto cell = i.next_atomic_cell();
            if (cell) {
                cell->value().with_linearized([&] (bytes_view value_view) {
                    cells.emplace(col.name_as_text(), col.type->deserialize_value(value_view));
                });
            }
        } else {
            auto cell = i.next_collection_cell();
            if (cell) {
                cell->with_linearized([&] (bytes_view value_view) {
                    if (col.type->is_collection()) {
                        auto ctype = static_pointer_cast<const collection_type_impl>(col.type);
                        if (_slice.options.contains<partition_slice::option::collections_as_maps>()) {
                            ctype = map_type_impl::get_instance(ctype->name_comparator(), ctype->value_comparator(), true);
                        }

                        cells.emplace(col.name_as_text(), ctype->deserialize_value(value_view, _slice.cql_format()));
                    } else {
                        cells.emplace(col.name_as_text(), col.type->deserialize_value(value_view));
                    }
                });
            }
        }
        index++;
      } catch (...) {
            throw deserialization_error(fmt::format(FMT_STRING("failed on column {}.{}#{} (version: {}, id: {}, index: {}, type: {}): {}"),
                _schema->ks_name(), _schema->cf_name(), col.name_as_text(), _schema->version(), col.id, index, col.type->name(), std::current_exception()));
      }
    }
    return cells;
}

result_set
result_set::from_raw_result(schema_ptr s, const partition_slice& slice, const result& r) {
    result_set_builder builder{std::move(s), slice};
    result_view::consume(r, slice, builder);
    return builder.build();
}

result_set::result_set(const mutation& m) : result_set([&m] {
    auto slice = partition_slice_builder(*m.schema()).build();
    auto qr = mutation(m).query(slice, query::result_memory_accounter{ query::result_memory_limiter::unlimited_result_size }, result_options::only_result());
    return result_set::from_raw_result(m.schema(), slice, qr);
}())
{ }

}
<commit_msg>query-result-set: don't linearize in result_set_builder::deserialize<commit_after>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "query-result-set.hh"
#include "query-result-reader.hh"
#include "partition_slice_builder.hh"
#include "mutation.hh"
#include "types/map.hh"
#include "utils/exceptions.hh"

#include <fmt/format.h>

namespace query {

class deserialization_error : public std::runtime_error {
public:
    using runtime_error::runtime_error;
};

// Result set builder is passed as a visitor to query_result::consume()
// function. You can call the build() method to obtain a result set that
// contains cells from the visited results.
class result_set_builder {
    schema_ptr _schema;
    const partition_slice& _slice;
    std::vector<result_set_row> _rows;
    std::unordered_map<sstring, non_null_data_value> _pkey_cells;
    uint64_t _row_count;
public:
    // Keep slice live as long as the builder is used.
    result_set_builder(schema_ptr schema, const partition_slice& slice);
    result_set build();
    void accept_new_partition(const partition_key& key, uint64_t row_count);
    void accept_new_partition(uint64_t row_count);
    void accept_new_row(const clustering_key& key, const result_row_view& static_row, const result_row_view& row);
    void accept_new_row(const result_row_view &static_row, const result_row_view &row);
    void accept_partition_end(const result_row_view& static_row);
private:
    std::unordered_map<sstring, non_null_data_value> deserialize(const partition_key& key);
    std::unordered_map<sstring, non_null_data_value> deserialize(const clustering_key& key);
    std::unordered_map<sstring, non_null_data_value> deserialize(const result_row_view& row, bool is_static);
};

std::ostream& operator<<(std::ostream& out, const result_set_row& row) {
    for (auto&& cell : row._cells) {
        auto&& type = static_cast<const data_value&>(cell.second).type();
        auto&& value = cell.second;
        out << cell.first << "=\"" << type->to_string(type->decompose(value)) << "\" ";
    }
    return out;
}

std::ostream& operator<<(std::ostream& out, const result_set& rs) {
    for (auto&& row : rs._rows) {
        out << row << std::endl;
    }
    return out;
}

static logging::logger query_result_log("query result log");

non_null_data_value::non_null_data_value(data_value&& v) : _v(std::move(v)) {
    if (_v.is_null()) {
        on_internal_error(query_result_log, "Trying to add a null data_value to a result_set_row");
    }
}

result_set_builder::result_set_builder(schema_ptr schema, const partition_slice& slice)
    : _schema{schema}, _slice(slice)
{ }

result_set result_set_builder::build() {
    return { _schema, std::move(_rows) };
}

void result_set_builder::accept_new_partition(const partition_key& key, uint64_t row_count)
{
    _pkey_cells = deserialize(key);
    accept_new_partition(row_count);
}

void result_set_builder::accept_new_partition(uint64_t row_count)
{
    _row_count = row_count;
}

void result_set_builder::accept_new_row(const clustering_key& key, const result_row_view& static_row, const result_row_view& row)
{
    auto ckey_cells = deserialize(key);
    auto static_cells = deserialize(static_row, true);
    auto regular_cells = deserialize(row, false);

    std::unordered_map<sstring, non_null_data_value> cells;
    cells.insert(_pkey_cells.begin(), _pkey_cells.end());
    cells.insert(ckey_cells.begin(), ckey_cells.end());
    cells.insert(static_cells.begin(), static_cells.end());
    cells.insert(regular_cells.begin(), regular_cells.end());
    _rows.emplace_back(_schema, std::move(cells));
}

void result_set_builder::accept_new_row(const query::result_row_view &static_row, const query::result_row_view &row)
{
    auto static_cells = deserialize(static_row, true);
    auto regular_cells = deserialize(row, false);

    std::unordered_map<sstring, non_null_data_value> cells;
    cells.insert(_pkey_cells.begin(), _pkey_cells.end());
    cells.insert(static_cells.begin(), static_cells.end());
    cells.insert(regular_cells.begin(), regular_cells.end());
    _rows.emplace_back(_schema, std::move(cells));
}

void result_set_builder::accept_partition_end(const result_row_view& static_row)
{
    if (_row_count == 0) {
        auto static_cells = deserialize(static_row, true);
        std::unordered_map<sstring, non_null_data_value> cells;
        cells.insert(_pkey_cells.begin(), _pkey_cells.end());
        cells.insert(static_cells.begin(), static_cells.end());
        _rows.emplace_back(_schema, std::move(cells));
    }
    _pkey_cells.clear();
}

std::unordered_map<sstring, non_null_data_value>
result_set_builder::deserialize(const partition_key& key)
{
    std::unordered_map<sstring, non_null_data_value> cells;
    auto i = key.begin(*_schema);
    for (auto&& col : _schema->partition_key_columns()) {
        cells.emplace(col.name_as_text(), col.type->deserialize_value(*i));
        ++i;
    }
    return cells;
}

std::unordered_map<sstring, non_null_data_value>
result_set_builder::deserialize(const clustering_key& key)
{
    std::unordered_map<sstring, non_null_data_value> cells;
    auto i = key.begin(*_schema);
    for (auto&& col : _schema->clustering_key_columns()) {
        if (i == key.end(*_schema)) {
            break;
        }
        cells.emplace(col.name_as_text(), col.type->deserialize_value(*i));
        ++i;
    }
    return cells;
}

std::unordered_map<sstring, non_null_data_value>
result_set_builder::deserialize(const result_row_view& row, bool is_static)
{
    std::unordered_map<sstring, non_null_data_value> cells;
    auto i = row.iterator();
    auto column_ids = is_static ? _slice.static_columns : _slice.regular_columns;
    auto columns = column_ids | boost::adaptors::transformed([this, is_static] (column_id id) -> const column_definition& {
        if (is_static) {
            return _schema->static_column_at(id);
        } else {
            return _schema->regular_column_at(id);
        }
    });
    size_t index = 0;
    for (auto &&col : columns) {
      try {
        if (col.is_atomic()) {
            auto cell = i.next_atomic_cell();
            if (cell) {
                cells.emplace(col.name_as_text(), col.type->deserialize_value(cell->value()));
            }
        } else {
            auto cell = i.next_collection_cell();
            if (cell) {
                    if (col.type->is_collection()) {
                        auto ctype = static_pointer_cast<const collection_type_impl>(col.type);
                        if (_slice.options.contains<partition_slice::option::collections_as_maps>()) {
                            ctype = map_type_impl::get_instance(ctype->name_comparator(), ctype->value_comparator(), true);
                        }

                        cells.emplace(col.name_as_text(), ctype->deserialize_value(*cell, _slice.cql_format()));
                    } else {
                        cells.emplace(col.name_as_text(), col.type->deserialize_value(*cell));
                    }
            }
        }
        index++;
      } catch (...) {
            throw deserialization_error(fmt::format(FMT_STRING("failed on column {}.{}#{} (version: {}, id: {}, index: {}, type: {}): {}"),
                _schema->ks_name(), _schema->cf_name(), col.name_as_text(), _schema->version(), col.id, index, col.type->name(), std::current_exception()));
      }
    }
    return cells;
}

result_set
result_set::from_raw_result(schema_ptr s, const partition_slice& slice, const result& r) {
    result_set_builder builder{std::move(s), slice};
    result_view::consume(r, slice, builder);
    return builder.build();
}

result_set::result_set(const mutation& m) : result_set([&m] {
    auto slice = partition_slice_builder(*m.schema()).build();
    auto qr = mutation(m).query(slice, query::result_memory_accounter{ query::result_memory_limiter::unlimited_result_size }, result_options::only_result());
    return result_set::from_raw_result(m.schema(), slice, qr);
}())
{ }

}
<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include <PField.h>
#include <string.h>
#include <stdio.h>   // for snprintf

inline int max(int x, int y) { return (x >= y) ? x : y; }
inline int min(int x, int y) { return (x < y) ? x : y; }

// PField

PField::~PField() {}

int PField::print(FILE *file) const
{
	int chars = 0;
	for (int n = 0; n < values(); ++n)
		chars += fprintf(file, "%.6f\n", doubleValue(n));
	return chars;
}

int PField::copyValues(double *array) const
{
	const int len = values();
	for (int n = 0; n < len; ++n)
		array[n] = doubleValue(n);
	return len;
}

// SingleValuePField

double SingleValuePField::doubleValue(double) const
{
	return _value;
}

// ConstPField

ConstPField::ConstPField(double value) : SingleValuePField(value) {}

ConstPField::~ConstPField() {}

// StringPField

StringPField::StringPField(const char *value)
	: _string(new char [strlen(value) + 1])
{
	strcpy(_string, value);
}

StringPField::~StringPField() { delete [] _string; }

// Note:  We use the same old trick here to pass the string as a double,
// but the conversion is entirely contained within the PField class system.
// PField::stringValue() casts it back to a const char *.

double StringPField::doubleValue(double) const
{
	return (double) (int) _string;
}

int StringPField::print(FILE *file) const
{
	return fprintf(file, "\"%s\"\n", _string);
}

// RTNumberPField

RTNumberPField::RTNumberPField(double value) : SingleValuePField(value) {}

double RTNumberPField::set(double value) { return setValue(value); }

// PFieldBinaryOperator

PFieldBinaryOperator::PFieldBinaryOperator(PField *pf1, PField *pf2,
										   PFieldBinaryOperator::Operator op)
	: _pfield1(pf1), _pfield2(pf2), _operator(op)
{
	_pfield1->ref();
	_pfield2->ref();
}

PFieldBinaryOperator::~PFieldBinaryOperator()
{
	_pfield2->unref();
	_pfield1->unref();
}

double PFieldBinaryOperator::doubleValue(int indx) const
{
	const int rindx = min(indx, values() - 1);
	return (*_operator)(_pfield1->doubleValue(rindx), _pfield2->doubleValue(rindx));
}

double PFieldBinaryOperator::doubleValue(double frac) const
{
	return (*_operator)(_pfield1->doubleValue(frac), _pfield2->doubleValue(frac));
}

int PFieldBinaryOperator::values() const
{
	const int len1 = _pfield1->values();
	const int len2 = _pfield2->values();
	return (len1 == 1 || len2 == 1) ? max(len1, len2) : min(len1, len2);
}

int PFieldBinaryOperator::print(FILE *file) const
{
	const int len1 = _pfield1->values();
	const int len2 = _pfield2->values();
	int maxlen;
	PField *mintable, *maxtable;
	if (len1 >= len2) {
		maxlen = len1;
		maxtable = _pfield1;
		mintable = _pfield2;
	}
	else {
		maxlen = len2;
		maxtable = _pfield2;
		mintable = _pfield1;
	}
	int chars = 0;
	for (int n = 0; n < maxlen; ++n) {
		double frac = (double) n/(maxlen-1);
		double value = maxtable->doubleValue(n) * mintable->doubleValue(frac);
		chars += fprintf(file, "%.6f\n", value);
	}
	return chars;
}

// TablePField

TablePField::TablePField(double *tableArray, int length)
	: _table(tableArray), _len(length)
{
}

TablePField::~TablePField()
{
	delete [] _table;
}

double TablePField::doubleValue(int indx) const
{
	return _table[min(indx, values() - 1)];
}

double TablePField::doubleValue(double percent) const
{
	if (percent > 1.0)
		percent = 1.0;
	const int len = values();
	double didx = (len - 1) * percent;
	const int idx = int(didx);
	const int idx2 = min(idx + 1, len - 1);
	double frac = didx - idx;
	return _table[idx] + frac * (_table[idx2] - _table[idx]);
}

int TablePField::print(FILE *file) const
{
	int chars = 0;
	for (int i = 0; i < values(); i++) {
		chars += fprintf(file, "%d %.6f\n", i, _table[i]);
	}
	return chars;
}

// Optimized version for table

int TablePField::copyValues(double *array) const
{
	const int len = values();
	for (int n = 0; n < len; ++n)
		array[n] = _table[n];
	return len;
}

// PFieldWrapper

PFieldWrapper::PFieldWrapper(PField *innerPField) : _pField(innerPField)
{
	_pField->ref();
}

PFieldWrapper::~PFieldWrapper() { _pField->unref(); }

// LoopedPField

LoopedPField::LoopedPField(PField *innerPField, double loopFactor)
	: PFieldWrapper(innerPField), _factor(loopFactor), _len(innerPField->values())
{
}

double LoopedPField::doubleValue(double didx) const
{
	double dfrac = didx * _factor;
	while (dfrac > 1.0)
		dfrac -= 1.0;
	return field()->doubleValue(dfrac);
}

double LoopedPField::doubleValue(int idx) const
{
	int nidx = int(idx * _factor);
	while (nidx >= _len)
		nidx -= _len;
	return field()->doubleValue(nidx);
}

// ReversePField

ReversePField::ReversePField(PField *innerPField)
	: PFieldWrapper(innerPField), _len(innerPField->values())
{
}

double ReversePField::doubleValue(double didx) const
{
	return field()->doubleValue(1.0 - didx);
}

double ReversePField::doubleValue(int idx) const
{
	return field()->doubleValue(_len - idx);
}

<commit_msg>Fixed copying of binary PFields<commit_after>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include <PField.h>
#include <string.h>
#include <stdio.h>   // for snprintf

inline int max(int x, int y) { return (x >= y) ? x : y; }
inline int min(int x, int y) { return (x < y) ? x : y; }

// PField

PField::~PField() {}

int PField::print(FILE *file) const
{
	int chars = 0;
	for (int n = 0; n < values(); ++n)
		chars += fprintf(file, "%.6f\n", doubleValue(n));
	return chars;
}

int PField::copyValues(double *array) const
{
	const int len = values();
	for (int n = 0; n < len; ++n)
		array[n] = doubleValue(n);
	return len;
}

// SingleValuePField

double SingleValuePField::doubleValue(double) const
{
	return _value;
}

// ConstPField

ConstPField::ConstPField(double value) : SingleValuePField(value) {}

ConstPField::~ConstPField() {}

// StringPField

StringPField::StringPField(const char *value)
	: _string(new char [strlen(value) + 1])
{
	strcpy(_string, value);
}

StringPField::~StringPField() { delete [] _string; }

// Note:  We use the same old trick here to pass the string as a double,
// but the conversion is entirely contained within the PField class system.
// PField::stringValue() casts it back to a const char *.

double StringPField::doubleValue(double) const
{
	return (double) (int) _string;
}

int StringPField::print(FILE *file) const
{
	return fprintf(file, "\"%s\"\n", _string);
}

// RTNumberPField

RTNumberPField::RTNumberPField(double value) : SingleValuePField(value) {}

double RTNumberPField::set(double value) { return setValue(value); }

// PFieldBinaryOperator

PFieldBinaryOperator::PFieldBinaryOperator(PField *pf1, PField *pf2,
										   PFieldBinaryOperator::Operator op)
	: _pfield1(pf1), _pfield2(pf2), _operator(op)
{
	_pfield1->ref();
	_pfield2->ref();
}

PFieldBinaryOperator::~PFieldBinaryOperator()
{
	_pfield2->unref();
	_pfield1->unref();
}

double PFieldBinaryOperator::doubleValue(int indx) const
{
	const int rindx = min(indx, values() - 1);
	return (*_operator)(_pfield1->doubleValue(rindx), _pfield2->doubleValue(rindx));
}

double PFieldBinaryOperator::doubleValue(double frac) const
{
	return (*_operator)(_pfield1->doubleValue(frac), _pfield2->doubleValue(frac));
}

int PFieldBinaryOperator::values() const
{
	const int len1 = _pfield1->values();
	const int len2 = _pfield2->values();
	return max(len1, len2);
}

int PFieldBinaryOperator::print(FILE *file) const
{
	const int len1 = _pfield1->values();
	const int len2 = _pfield2->values();
	int maxlen;
	PField *mintable, *maxtable;
	if (len1 >= len2) {
		maxlen = len1;
		maxtable = _pfield1;
		mintable = _pfield2;
	}
	else {
		maxlen = len2;
		maxtable = _pfield2;
		mintable = _pfield1;
	}
	int chars = 0;
	for (int n = 0; n < maxlen; ++n) {
		double frac = (double) n/(maxlen-1);
		double value = (*_operator)(maxtable->doubleValue(n), mintable->doubleValue(frac));
		chars += fprintf(file, "%.6f\n", value);
	}
	return chars;
}

int PFieldBinaryOperator::copyValues(double *array) const
{
	const int len1 = _pfield1->values();
	const int len2 = _pfield2->values();
	int maxlen;
	PField *mintable, *maxtable;
	if (len1 >= len2) {
		maxlen = len1;
		maxtable = _pfield1;
		mintable = _pfield2;
	}
	else {
		maxlen = len2;
		maxtable = _pfield2;
		mintable = _pfield1;
	}
	int chars = 0;
	for (int n = 0; n < maxlen; ++n) {
		double frac = (double) n/(maxlen-1);
		double value = (*_operator)(maxtable->doubleValue(n), mintable->doubleValue(frac));
		array[n] = value;
	}
	return maxlen;
}

// TablePField

TablePField::TablePField(double *tableArray, int length)
	: _table(tableArray), _len(length)
{
}

TablePField::~TablePField()
{
	delete [] _table;
}

double TablePField::doubleValue(int indx) const
{
	return _table[min(indx, values() - 1)];
}

double TablePField::doubleValue(double percent) const
{
	if (percent > 1.0)
		percent = 1.0;
	const int len = values();
	double didx = (len - 1) * percent;
	const int idx = int(didx);
	const int idx2 = min(idx + 1, len - 1);
	double frac = didx - idx;
	return _table[idx] + frac * (_table[idx2] - _table[idx]);
}

int TablePField::print(FILE *file) const
{
	int chars = 0;
	for (int i = 0; i < values(); i++) {
		chars += fprintf(file, "%d %.6f\n", i, _table[i]);
	}
	return chars;
}

// Optimized version for table

int TablePField::copyValues(double *array) const
{
	const int len = values();
	for (int n = 0; n < len; ++n)
		array[n] = _table[n];
	return len;
}

// PFieldWrapper

PFieldWrapper::PFieldWrapper(PField *innerPField) : _pField(innerPField)
{
	_pField->ref();
}

PFieldWrapper::~PFieldWrapper() { _pField->unref(); }

// LoopedPField

LoopedPField::LoopedPField(PField *innerPField, double loopFactor)
	: PFieldWrapper(innerPField), _factor(loopFactor), _len(innerPField->values())
{
}

double LoopedPField::doubleValue(double didx) const
{
	double dfrac = didx * _factor;
	while (dfrac > 1.0)
		dfrac -= 1.0;
	return field()->doubleValue(dfrac);
}

double LoopedPField::doubleValue(int idx) const
{
	int nidx = int(idx * _factor);
	while (nidx >= _len)
		nidx -= _len;
	return field()->doubleValue(nidx);
}

// ReversePField

ReversePField::ReversePField(PField *innerPField)
	: PFieldWrapper(innerPField), _len(innerPField->values())
{
}

double ReversePField::doubleValue(double didx) const
{
	return field()->doubleValue(1.0 - didx);
}

double ReversePField::doubleValue(int idx) const
{
	return field()->doubleValue(_len - idx);
}

<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <pthread.h>
#include <iostream.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/time.h>

#include <globals.h>
#include <prototypes.h>
#include "../rtstuff/rtdefs.h"
#include "sockdefs.h"
#include "../H/dbug.h"

#include "notetags.h"

double schedtime; 	// up here so that rtsetoutput can access this info
// (see below)

extern "C" {
  void *sockit(void*)
  {

    extern double baseTime;
    extern long elapsed;
    double buftime,sec,usec;
    struct timeval tv;
    struct timezone tz;
    char ttext[MAXTEXTARGS][512];
    int i,tmpint;

    // socket stuff
    int s, ns;
    int len;
    struct sockaddr_in sss;
    int err;
    struct sockdata *sinfo;
    int amt,tamt;
    char *sptr;
    int val,optlen;
    double a,b,c;
    int ntag,pval;

    // tz.tz_minuteswest = 0;
    // tz.tz_dsttime = DST_NONE;

    // timerclear(&tv);
    /* create the socket for listening */

    cout << "ENTERING sockit() FUNCTION **********\n";
    if( (s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      perror("socket");
      exit(1);
    }

    /* set up the receive buffer nicely for us */
    optlen = sizeof(char);
    val = sizeof(struct sockdata);
    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &val, optlen);

    /* set up the socket address */
    sss.sin_family = AF_INET;
    sss.sin_addr.s_addr = INADDR_ANY;
    // socknew is offset from MYPORT to allow more than one inst
    sss.sin_port = htons(MYPORT+socknew);

    err = bind(s, (struct sockaddr *)&sss, sizeof(sss));
    if (err < 0) {
      perror("bind");
      exit(1);
    }

    listen(s, 1);

    len = sizeof(sss);
    ns = accept(s, (struct sockaddr *)&sss, &len);
    if(ns < 0) {
      perror("accept");
      exit(1);
    }
    else {

      buftime = (float)RTBUFSAMPS/SR;
      cout << "buftime:  " << buftime << endl;

      sinfo = new (struct sockdata);
      // Zero the socket structure
      sinfo->name[0] = '\0';
      for (i=0;i<MAXDISPARGS;i++) {
	sinfo->data.p[i] = 0;
      }

      // we do this when the -n flag is set, it has to parse rtsetparams()
      // coming over the socket before it can access the values of RTBUFSAMPS,
      // SR, NCHANS, etc.
      if (noParse) {
	cout << "sockit():  waiting for audio config\n";

	sptr = (char *)sinfo;
	amt = read(ns, (void *)sptr, sizeof(struct sockdata));
	while (amt < sizeof(struct sockdata)) amt += read(ns, (void *)(sptr+amt), sizeof(struct sockdata)-amt);

	parse_dispatch(sinfo->name, sinfo->data.p, sinfo->n_args);
      }

      buftime = (float)RTBUFSAMPS/SR;

      // Main socket reading loop
      while(1) {

	sptr = (char *)sinfo;
	amt = read(ns, (void *)sptr, sizeof(struct sockdata));
	while (amt < sizeof(struct sockdata)) amt += read(ns, (void *)(sptr+amt), sizeof(struct sockdata)-amt);

	if ( (strcmp(sinfo->name, "rtinput") == 0) || (strcmp(sinfo->name, "rtoutput") == 0) || (strcmp(sinfo->name,"set_option") == 0) || (strcmp(sinfo->name, "load")==0) ) {
	  // these two commands use text data
	  // replace the text[i] with p[i] pointers
	  for (i = 0; i < sinfo->n_args; i++)
	    strcpy(ttext[i],sinfo->data.text[i]);
	  for (i = 0; i < sinfo->n_args; i++) {
	    tmpint = (int)ttext[i];
	    sinfo->data.p[i] = (double)tmpint;
	  }
	}

	if ( (strcmp(sinfo->name, "end") == 0) ) {
	  rtInteractive = 0;
	}

	// if it is an rtupdate, set the pval array
	if (strcmp(sinfo->name, "rtupdate") == 0) {
				// rtupdate params are:
				//	p0 = note tag # 0 for all notes
				//	p1,2... pn,pn+1 = pfield, value
	  ntag = (int)sinfo->data.p[0];
	  pthread_mutex_lock(&pfieldLock);
	  for (i = 1; i < sinfo->n_args; i += 2) {
	    pval = (int)sinfo->data.p[i];
	    pupdatevals[ntag][pval] = sinfo->data.p[i+1];
	  }
	  pthread_mutex_unlock(&pfieldLock);
	  tag_sem=1;
	}

	else {

	  gettimeofday(&tv, &tz);
	  sec = (double)tv.tv_sec;
	  usec = (double)tv.tv_usec;
	  schedtime = (((sec * 1e6) + usec) - baseTime) * 1e-6;
	  schedtime += ((double)elapsed/(double)SR);
	  schedtime += buftime;

#ifdef DBUG
	  cout << "sockit(): schedtime = " << schedtime << endl;
	  cout << "sockit(): buftime = " << buftime << endl;
	  cout << "sockit(): baseTime = " << baseTime << endl;
	  cout << "sockit(): elapsed = " << elapsed << endl;
	  cout << "sockit(): SR = " << SR << endl;
#endif

	  // schedtime is accessed in rtsetoutput() to
	  // set the current time.  Plus, in interactive
	  // mode we have to run a slight delay from
	  // "0" or we wind up scheduling events in the past.

	  if(sinfo->name) {
#ifdef ALLBUG
	    cout << "SOCKET RECIEVED\n";
	    cout << "sinfo->name = " << sinfo->name << endl;
	    cout << "sinfo->n_args = " << sinfo->n_args << endl;
	    for (i=0;i<sinfo->n_args;i++) {
	      cout << "sinfo->data.p[" << i << "] =" << sinfo->data.p[i] << endl;
	    }
#endif
	    parse_dispatch(sinfo->name, sinfo->data.p, sinfo->n_args);

	  }
	}
      }
    }
    cout << "EXITING sockit() FUNCTION **********\n";
  }
}
<commit_msg>Changed type of 'amt' var to size_t, due to compiler warnings.<commit_after>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <pthread.h>
#include <iostream.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/time.h>

#include <globals.h>
#include <prototypes.h>
#include "../rtstuff/rtdefs.h"
#include "sockdefs.h"
#include "../H/dbug.h"

#include "notetags.h"

double schedtime; 	// up here so that rtsetoutput can access this info
// (see below)

extern "C" {
  void *sockit(void*)
  {

    extern double baseTime;
    extern long elapsed;
    double buftime,sec,usec;
    struct timeval tv;
    struct timezone tz;
    char ttext[MAXTEXTARGS][512];
    int i,tmpint;

    // socket stuff
    int s, ns;
    int len;
    struct sockaddr_in sss;
    int err;
    struct sockdata *sinfo;
    size_t amt;
    char *sptr;
    int val,optlen;
    int ntag,pval;

    // tz.tz_minuteswest = 0;
    // tz.tz_dsttime = DST_NONE;

    // timerclear(&tv);
    /* create the socket for listening */

    cout << "ENTERING sockit() FUNCTION **********\n";
    if( (s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      perror("socket");
      exit(1);
    }

    /* set up the receive buffer nicely for us */
    optlen = sizeof(char);
    val = sizeof(struct sockdata);
    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &val, optlen);

    /* set up the socket address */
    sss.sin_family = AF_INET;
    sss.sin_addr.s_addr = INADDR_ANY;
    // socknew is offset from MYPORT to allow more than one inst
    sss.sin_port = htons(MYPORT+socknew);

    err = bind(s, (struct sockaddr *)&sss, sizeof(sss));
    if (err < 0) {
      perror("bind");
      exit(1);
    }

    listen(s, 1);

    len = sizeof(sss);
    ns = accept(s, (struct sockaddr *)&sss, &len);
    if(ns < 0) {
      perror("accept");
      exit(1);
    }
    else {

      buftime = (float)RTBUFSAMPS/SR;
      cout << "buftime:  " << buftime << endl;

      sinfo = new (struct sockdata);
      // Zero the socket structure
      sinfo->name[0] = '\0';
      for (i=0;i<MAXDISPARGS;i++) {
	sinfo->data.p[i] = 0;
      }

      // we do this when the -n flag is set, it has to parse rtsetparams()
      // coming over the socket before it can access the values of RTBUFSAMPS,
      // SR, NCHANS, etc.
      if (noParse) {
	cout << "sockit():  waiting for audio config\n";

	sptr = (char *)sinfo;
	amt = read(ns, (void *)sptr, sizeof(struct sockdata));
	while (amt < sizeof(struct sockdata)) amt += read(ns, (void *)(sptr+amt), sizeof(struct sockdata)-amt);

	parse_dispatch(sinfo->name, sinfo->data.p, sinfo->n_args);
      }

      buftime = (float)RTBUFSAMPS/SR;

      // Main socket reading loop
      while(1) {

	sptr = (char *)sinfo;
	amt = read(ns, (void *)sptr, sizeof(struct sockdata));
	while (amt < sizeof(struct sockdata)) amt += read(ns, (void *)(sptr+amt), sizeof(struct sockdata)-amt);

	if ( (strcmp(sinfo->name, "rtinput") == 0) || (strcmp(sinfo->name, "rtoutput") == 0) || (strcmp(sinfo->name,"set_option") == 0) || (strcmp(sinfo->name, "load")==0) ) {
	  // these two commands use text data
	  // replace the text[i] with p[i] pointers
	  for (i = 0; i < sinfo->n_args; i++)
	    strcpy(ttext[i],sinfo->data.text[i]);
	  for (i = 0; i < sinfo->n_args; i++) {
	    tmpint = (int)ttext[i];
	    sinfo->data.p[i] = (double)tmpint;
	  }
	}

	if ( (strcmp(sinfo->name, "end") == 0) ) {
	  rtInteractive = 0;
	}

	// if it is an rtupdate, set the pval array
	if (strcmp(sinfo->name, "rtupdate") == 0) {
				// rtupdate params are:
				//	p0 = note tag # 0 for all notes
				//	p1,2... pn,pn+1 = pfield, value
	  ntag = (int)sinfo->data.p[0];
	  pthread_mutex_lock(&pfieldLock);
	  for (i = 1; i < sinfo->n_args; i += 2) {
	    pval = (int)sinfo->data.p[i];
	    pupdatevals[ntag][pval] = sinfo->data.p[i+1];
	  }
	  pthread_mutex_unlock(&pfieldLock);
	  tag_sem=1;
	}

	else {

	  gettimeofday(&tv, &tz);
	  sec = (double)tv.tv_sec;
	  usec = (double)tv.tv_usec;
	  schedtime = (((sec * 1e6) + usec) - baseTime) * 1e-6;
	  schedtime += ((double)elapsed/(double)SR);
	  schedtime += buftime;

#ifdef DBUG
	  cout << "sockit(): schedtime = " << schedtime << endl;
	  cout << "sockit(): buftime = " << buftime << endl;
	  cout << "sockit(): baseTime = " << baseTime << endl;
	  cout << "sockit(): elapsed = " << elapsed << endl;
	  cout << "sockit(): SR = " << SR << endl;
#endif

	  // schedtime is accessed in rtsetoutput() to
	  // set the current time.  Plus, in interactive
	  // mode we have to run a slight delay from
	  // "0" or we wind up scheduling events in the past.

	  if(sinfo->name) {
#ifdef ALLBUG
	    cout << "SOCKET RECIEVED\n";
	    cout << "sinfo->name = " << sinfo->name << endl;
	    cout << "sinfo->n_args = " << sinfo->n_args << endl;
	    for (i=0;i<sinfo->n_args;i++) {
	      cout << "sinfo->data.p[" << i << "] =" << sinfo->data.p[i] << endl;
	    }
#endif
	    parse_dispatch(sinfo->name, sinfo->data.p, sinfo->n_args);

	  }
	}
      }
    }
    cout << "EXITING sockit() FUNCTION **********\n";
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <script/ismine.h>

#include <key.h>
#include <keystore.h>
#include <script/script.h>
#include <script/sign.h>

typedef std::vector<unsigned char> valtype;

unsigned int HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore)
{
    unsigned int nResult = 0;
    for (const valtype& pubkey : pubkeys)
    {
        CKeyID keyID = CPubKey(pubkey).GetID();
        if (keystore.HaveKey(keyID))
            ++nResult;
    }
    return nResult;
}

isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion sigversion)
{
    bool isInvalid = false;
    return IsMine(keystore, scriptPubKey, isInvalid, sigversion);
}

isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, SigVersion sigversion)
{
    bool isInvalid = false;
    return IsMine(keystore, dest, isInvalid, sigversion);
}

isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest, bool& isInvalid, SigVersion sigversion)
{
    CScript script = GetScriptForDestination(dest);
    return IsMine(keystore, script, isInvalid, sigversion);
}

isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion sigversion)
{
    isInvalid = false;

    std::vector<valtype> vSolutions;
    txnouttype whichType;
    if (!Solver(scriptPubKey, whichType, vSolutions)) {
        if (keystore.HaveWatchOnly(scriptPubKey))
            return ISMINE_WATCH_UNSOLVABLE;
        return ISMINE_NO;
    }

    CKeyID keyID;
    switch (whichType)
    {
    case TX_NONSTANDARD:
    case TX_NULL_DATA:
    case TX_WITNESS_UNKNOWN:
        break;
    case TX_PUBKEY:
        keyID = CPubKey(vSolutions[0]).GetID();
        if (sigversion != SIGVERSION_BASE && vSolutions[0].size() != 33) {
            isInvalid = true;
            return ISMINE_NO;
        }
        if (keystore.HaveKey(keyID))
            return ISMINE_SPENDABLE;
        break;
    case TX_WITNESS_V0_KEYHASH:
    {
        if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
            // We do not support bare witness outputs unless the P2SH version of it would be
            // acceptable as well. This protects against matching before segwit activates.
            // This also applies to the P2WSH case.
            break;
        }
        isminetype ret = ::IsMine(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), isInvalid, SIGVERSION_WITNESS_V0);
        if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
            return ret;
        break;
    }
    case TX_PUBKEYHASH:
        keyID = CKeyID(uint160(vSolutions[0]));
        if (sigversion != SIGVERSION_BASE) {
            CPubKey pubkey;
            if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) {
                isInvalid = true;
                return ISMINE_NO;
            }
        }
        if (keystore.HaveKey(keyID))
            return ISMINE_SPENDABLE;
        break;
    case TX_SCRIPTHASH:
    {
        CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
        CScript subscript;
        if (keystore.GetCScript(scriptID, subscript)) {
            isminetype ret = IsMine(keystore, subscript, isInvalid);
            if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
                return ret;
        }
        break;
    }
    case TX_WITNESS_V0_SCRIPTHASH:
    {
        if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
            break;
        }
        uint160 hash;
        CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin());
        CScriptID scriptID = CScriptID(hash);
        CScript subscript;
        if (keystore.GetCScript(scriptID, subscript)) {
            isminetype ret = IsMine(keystore, subscript, isInvalid, SIGVERSION_WITNESS_V0);
            if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
                return ret;
        }
        break;
    }

    case TX_MULTISIG:
    {
        // Only consider transactions "mine" if we own ALL the
        // keys involved. Multi-signature transactions that are
        // partially owned (somebody else has a key that can spend
        // them) enable spend-out-from-under-you attacks, especially
        // in shared-wallet situations.
        std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
        if (sigversion != SIGVERSION_BASE) {
            for (size_t i = 0; i < keys.size(); i++) {
                if (keys[i].size() != 33) {
                    isInvalid = true;
                    return ISMINE_NO;
                }
            }
        }
        if (HaveKeys(keys, keystore) == keys.size())
            return ISMINE_SPENDABLE;
        break;
    }
    }

    if (keystore.HaveWatchOnly(scriptPubKey)) {
        // TODO: This could be optimized some by doing some work after the above solver
        SignatureData sigs;
        return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE;
    }
    return ISMINE_NO;
}
<commit_msg>Refactor HaveKeys to early return on false result<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <script/ismine.h>

#include <key.h>
#include <keystore.h>
#include <script/script.h>
#include <script/sign.h>

typedef std::vector<unsigned char> valtype;

static bool HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore)
{
    for (const valtype& pubkey : pubkeys) {
        CKeyID keyID = CPubKey(pubkey).GetID();
        if (!keystore.HaveKey(keyID)) return false;
    }
    return true;
}

isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey, SigVersion sigversion)
{
    bool isInvalid = false;
    return IsMine(keystore, scriptPubKey, isInvalid, sigversion);
}

isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest, SigVersion sigversion)
{
    bool isInvalid = false;
    return IsMine(keystore, dest, isInvalid, sigversion);
}

isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest, bool& isInvalid, SigVersion sigversion)
{
    CScript script = GetScriptForDestination(dest);
    return IsMine(keystore, script, isInvalid, sigversion);
}

isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey, bool& isInvalid, SigVersion sigversion)
{
    isInvalid = false;

    std::vector<valtype> vSolutions;
    txnouttype whichType;
    if (!Solver(scriptPubKey, whichType, vSolutions)) {
        if (keystore.HaveWatchOnly(scriptPubKey))
            return ISMINE_WATCH_UNSOLVABLE;
        return ISMINE_NO;
    }

    CKeyID keyID;
    switch (whichType)
    {
    case TX_NONSTANDARD:
    case TX_NULL_DATA:
    case TX_WITNESS_UNKNOWN:
        break;
    case TX_PUBKEY:
        keyID = CPubKey(vSolutions[0]).GetID();
        if (sigversion != SIGVERSION_BASE && vSolutions[0].size() != 33) {
            isInvalid = true;
            return ISMINE_NO;
        }
        if (keystore.HaveKey(keyID))
            return ISMINE_SPENDABLE;
        break;
    case TX_WITNESS_V0_KEYHASH:
    {
        if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
            // We do not support bare witness outputs unless the P2SH version of it would be
            // acceptable as well. This protects against matching before segwit activates.
            // This also applies to the P2WSH case.
            break;
        }
        isminetype ret = ::IsMine(keystore, GetScriptForDestination(CKeyID(uint160(vSolutions[0]))), isInvalid, SIGVERSION_WITNESS_V0);
        if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
            return ret;
        break;
    }
    case TX_PUBKEYHASH:
        keyID = CKeyID(uint160(vSolutions[0]));
        if (sigversion != SIGVERSION_BASE) {
            CPubKey pubkey;
            if (keystore.GetPubKey(keyID, pubkey) && !pubkey.IsCompressed()) {
                isInvalid = true;
                return ISMINE_NO;
            }
        }
        if (keystore.HaveKey(keyID))
            return ISMINE_SPENDABLE;
        break;
    case TX_SCRIPTHASH:
    {
        CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
        CScript subscript;
        if (keystore.GetCScript(scriptID, subscript)) {
            isminetype ret = IsMine(keystore, subscript, isInvalid);
            if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
                return ret;
        }
        break;
    }
    case TX_WITNESS_V0_SCRIPTHASH:
    {
        if (!keystore.HaveCScript(CScriptID(CScript() << OP_0 << vSolutions[0]))) {
            break;
        }
        uint160 hash;
        CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(hash.begin());
        CScriptID scriptID = CScriptID(hash);
        CScript subscript;
        if (keystore.GetCScript(scriptID, subscript)) {
            isminetype ret = IsMine(keystore, subscript, isInvalid, SIGVERSION_WITNESS_V0);
            if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || (ret == ISMINE_NO && isInvalid))
                return ret;
        }
        break;
    }

    case TX_MULTISIG:
    {
        // Only consider transactions "mine" if we own ALL the
        // keys involved. Multi-signature transactions that are
        // partially owned (somebody else has a key that can spend
        // them) enable spend-out-from-under-you attacks, especially
        // in shared-wallet situations.
        std::vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
        if (sigversion != SIGVERSION_BASE) {
            for (size_t i = 0; i < keys.size(); i++) {
                if (keys[i].size() != 33) {
                    isInvalid = true;
                    return ISMINE_NO;
                }
            }
        }
        if (HaveKeys(keys, keystore))
            return ISMINE_SPENDABLE;
        break;
    }
    }

    if (keystore.HaveWatchOnly(scriptPubKey)) {
        // TODO: This could be optimized some by doing some work after the above solver
        SignatureData sigs;
        return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, sigs) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE;
    }
    return ISMINE_NO;
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 1997, 1998, 1999 by Alex Pfaffe
	(Digital Dawn Graphics Inc)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

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

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "util/ddgerror.h"
#include "util/ddgstr.h"

// ----------------------------------------------------------------------
//
// Str:
//
//  Memory allocation must remain in the same DLL, so this can not be inlined.
//
ddgStr::ddgStr(void)
{
	s = NULL;
	l = 0;
}

ddgStr::ddgStr(const char *ss, int size)
{
	s = NULL;
	_assign(ss,size);
}

ddgStr::ddgStr(const int size)
{
	s = new char[size];
	s[0] = 0;
}

ddgStr::~ddgStr()
{
	delete [] s;
}

// OPTIM: Don't call delete/new if old string is same size as new string.
bool ddgStr::_assign( const char * b, int size )
{
	if (s == b )
		return ddgFailure;

	if (b)
	{
		unsigned int i = len(b);
		if (i != l)
		{
			delete[] s;
			l = i;
			if (!(s = new char[(size ? size : l+1)]))
				return ddgFailure;
		}
		if (s)
			s[l] = 0;		// End the string.
		while (i)
		{
			i--;
			s[i]= b[i];
		}
	}
	else				// Null assignment.
	{
		delete[] s;
		s = NULL;
	}

	return ddgSuccess;
}

bool ddgStr::assign(const char *b)
{
	return _assign(b,0);
}
float ddgStr::stof(const char *s)
{
    float r = 0.0f;
    float b = 0.0f;
    bool neg = false;
    while(*s)
    {
        if (*s == '.') b = 1;
        else if (*s == '+') ;
        else if (*s == '-') neg = true;
        else
        {
            if (b) b *= 10.0f;
            r = r*10.0 + (float)(*s - '0');
        }
        s++;
    }
    return (neg?-1.0:1.0)*(b ? r/b : r);
}

int ddgStr::stoi(const char *s)
{
    int b = 0;
    bool neg = false;
    while(*s)
    {
        if (*s == '+') ;
        else if (*s == '-') neg = true;
        else
        {
            b = b*10.0 + (float)(*s - '0');
        }
        s++;
    }
    return (neg?-1*b:b) ;
}

ddgStr& ddgStr::operator  +=( const ddgStr& s2)
{
	char *t = new char[l + s2.l + 1], *tp;
	unsigned int i;
	tp = t;
	for (i=0;s[i]; i++,tp++) *tp = s[i];
	for (i=0;s2.s[i]; i++,tp++) *tp = s2.s[i];
	tp = 0;
	delete[] s;
	s = t;
	return *this;
}

char *ddgStr::findChar(const char target)
{
	char *tmp = s;
	while (*tmp && *tmp !=target)
		tmp++;
	return tmp;
}
// This method corrupts strings when used with.
/*
ostream& operator << ( ostream&strm, Str str )
{
	return strm << str.s;
}
*/
// Define an input and output stream operator for Vector2.
// Output format is "abcd"
ostream& operator << ( ostream &stream, const ddgStr str )
     { return stream << str.s; }
ostream& operator << ( ostream &stream, const ddgStr *str )
     { return stream << str->s; }

// Input format is "abcd"
istream& operator >> ( istream& stream, ddgStr& str)
     { char c[256]; stream >> c; str.assign(c); return stream; }

<commit_msg>Fixed an error and warning.<commit_after>/*
    Copyright (C) 1997, 1998, 1999 by Alex Pfaffe
	(Digital Dawn Graphics Inc)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

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

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "util/ddgerror.h"
#include "util/ddgstr.h"

// ----------------------------------------------------------------------
//
// Str:
//
//  Memory allocation must remain in the same DLL, so this can not be inlined.
//
ddgStr::ddgStr(void)
{
	s = NULL;
	l = 0;
}

ddgStr::ddgStr(const char *ss, int size)
{
	s = NULL;
	_assign(ss,size);
}

ddgStr::ddgStr(const int size)
{
	s = new char[size];
	s[0] = 0;
}

ddgStr::~ddgStr()
{
	delete [] s;
}

// OPTIM: Don't call delete/new if old string is same size as new string.
bool ddgStr::_assign( const char * b, int size )
{
	if (s == b )
		return ddgFailure;

	if (b)
	{
		unsigned int i = len(b);
		if (i != l)
		{
			delete[] s;
			l = i;
			if (!(s = new char[(size ? size : l+1)]))
				return ddgFailure;
		}
		if (s)
			s[l] = 0;		// End the string.
		while (i)
		{
			i--;
			s[i]= b[i];
		}
	}
	else				// Null assignment.
	{
		delete[] s;
		s = NULL;
	}

	return ddgSuccess;
}

bool ddgStr::assign(const char *b)
{
	return _assign(b,0);
}
float ddgStr::stof(const char *s)
{
    float r = 0.0f;
    float b = 0.0f;
    bool neg = false;
    while(*s)
    {
        if (*s == '.') b = 1;
        else if (*s == '+') ;
        else if (*s == '-') neg = true;
        else
        {
            if (b) b *= 10.0f;
            r = r*10.0 + (float)(*s - '0');
        }
        s++;
    }
    return (neg?-1.0:1.0)*(b ? r/b : r);
}

int ddgStr::stoi(const char *s)
{
    int b = 0;
    bool neg = false;
    while(*s)
    {
        if (*s == '+') ;
        else if (*s == '-') neg = true;
        else
        {
            b = (int)(b*10.0 + (float)(*s - '0'));
        }
        s++;
    }
    return (neg?-1*b:b) ;
}

ddgStr& ddgStr::operator  +=( const ddgStr& s2)
{
	char *t = new char[l + s2.l + 1], *tp;
	unsigned int i;
	tp = t;
	for (i=0;s[i]; i++,tp++) *tp = s[i];
	for (i=0;s2.s[i]; i++,tp++) *tp = s2.s[i];
	tp = 0;
	delete[] s;
	s = t;
	return *this;
}

char *ddgStr::findChar(const char target)
{
	char *tmp = s;
	while (*tmp && *tmp !=target)
		tmp++;
	return tmp;
}
// This method corrupts strings when used with.
/*
ostream& operator << ( ostream&strm, Str str )
{
	return strm << str.s;
}
*/
// Define an input and output stream operator for Vector2.
// Output format is "abcd"
#ifdef DDGSTREAM
ostream& operator << ( ostream &stream, const ddgStr str )
     { return stream << str.s; }
ostream& operator << ( ostream &stream, const ddgStr *str )
     { return stream << str->s; }

// Input format is "abcd"
istream& operator >> ( istream& stream, ddgStr& str)
     { char c[256]; stream >> c; str.assign(c); return stream; }
#endif

<|endoftext|>


<commit_before>#include <XdmfArray.h>
#include <XdmfHDF.h>

char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFSerial";

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

  XdmfHDF* H5 = new XdmfHDF();
  XdmfArray* MyData = new XdmfArray();

  MyData->SetNumberType( XDMF_FLOAT32_TYPE );
  MyData->SetNumberOfElements( 100 );
  MyData->Generate( 0, 99 );

  H5->CopyType( MyData );
  H5->CopyShape( MyData );
  H5->Open( kDatasetName, "w" );
  H5->Write( MyData );
  H5->Close();

  XdmfHDF* H5In = new XdmfHDF();
  H5In->Open( kDatasetName, "r" );
  XdmfArray* result = H5In->Read();

  bool failure = false;
  for ( size_t i = 0; i < 100; ++i ) {
    float value = result->GetValueAsFloat32( i );
    std::cout << i << " " << value << std::endl;
    failure = ( value != i );
  }

  if ( failure ) {
    return -1;
  } else {
    return 0;
  }
};

<commit_msg>BUG: Make sure we clean up tests<commit_after>#include <XdmfArray.h>
#include <XdmfHDF.h>

char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFSerial";

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

  XdmfHDF* H5 = new XdmfHDF();
  XdmfArray* MyData = new XdmfArray();

  MyData->SetNumberType( XDMF_FLOAT32_TYPE );
  MyData->SetNumberOfElements( 100 );
  MyData->Generate( 0, 99 );

  H5->CopyType( MyData );
  H5->CopyShape( MyData );
  H5->Open( kDatasetName, "w" );
  H5->Write( MyData );
  H5->Close();

  XdmfHDF* H5In = new XdmfHDF();
  H5In->Open( kDatasetName, "r" );
  XdmfArray* result = H5In->Read();
  H5In->Close();

  bool failure = false;
  for ( size_t i = 0; i < 100; ++i ) {
    float value = result->GetValueAsFloat32( i );
    std::cout << i << " " << value << std::endl;
    failure = ( value != i );
  }

  delete result;
  delete MyData;
  delete H5;
  delete H5In;

  if ( failure ) {
    return -1;
  } else {
    return 0;
  }
};

<|endoftext|>


<commit_before>/**\file
 * \brief Matrix-esque terminal animation
 *
 * \copyright
 * Copyright (c) 2012-2013, ef.gy Project Members
 * \copyright
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: http://git.becquerel.org/jyujin/libefgy.git
 */

#include <iostream>

#include <ef.gy/vt100.h>
#include <ef.gy/random.h>
#include <unistd.h>
#include <chrono>

using namespace efgy;
using namespace std::chrono;

terminal::vt100<> output;
random::mersenneTwister<> rng(1337);
system_clock::time_point now;

class matrixStream
{
    public:
        class cell
        {
            public:
                cell(const unsigned long &pCharacter)
                    : character(pCharacter), created(now) {}

                unsigned long character;
                system_clock::time_point created;
        };

        matrixStream(const std::size_t &pLine, const std::size_t &pColumn)
            : line(pLine), column(pColumn), last(now) {}

        std::size_t line;
        std::size_t column;
        std::vector<cell> data;
        system_clock::time_point last;

        bool update (void)
        {
            if ((now - last) > std::chrono::microseconds(40))
            {
                last = now;
                switch (rng() % 4)
                {
                    case 0:
                        if (data.size() > 0)
                        {
                            data.erase(data.begin() + (rng() % data.size()));
                        }
                        else
                        {
                            data.push_back(cell(rng() % (1 << 7)));
                        }
                        break;
                    default:
                        data.push_back(cell(rng() % (1 << 7)));
                }
            }
            std::array<std::size_t,2> s = output.size();
            int i = line;
            for (cell &d : data)
            {
                if (i >= s[1])
                {
                    break;
                }
                output.target[i][column].content = d.character;
                output.target[i][column].foregroundColour = (now - d.created) > std::chrono::microseconds(120) ? 2 : 7;
                output.target[i][column].backgroundColour = 0;
                i++;
            }
            return true;
        }
};

int main (int argc, char **argv)
{
    output.resize(output.getOSDimensions());
    std::array<std::size_t,2> s = output.size();

    int i;

    std::vector<matrixStream> streams;

    while (1)
    {
        i++;
        now = system_clock::now();

        if (i % 100 == 0)
        {
            std::size_t l = rng() % s[1];
            std::size_t c = rng() % s[0];
            streams.push_back(matrixStream(l, c));
        }
        if (streams.size() > 200)
        {
            streams.erase(streams.begin());
        }

        for (matrixStream &s : streams)
        {
            if (rng() % 10 == 0)
            {
                s.update();
            }
        }

        std::cout << output.flush();
        usleep(10);
    }

    for (std::string s = output.flush(); s != ""; s = output.flush())
    {
        std::cout << s;
        i++;
    }

    std::cout << "\e[39;49;0m\n";

    return 0;
}
<commit_msg>some improvements to the matrix animation<commit_after>/**\file
 * \brief Matrix-esque terminal animation
 *
 * \copyright
 * Copyright (c) 2012-2013, ef.gy Project Members
 * \copyright
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \see Project Documentation: http://ef.gy/documentation/libefgy
 * \see Project Source Code: http://git.becquerel.org/jyujin/libefgy.git
 */

#include <iostream>

#include <ef.gy/vt100.h>
#include <ef.gy/random.h>
#include <unistd.h>
#include <chrono>

using namespace efgy;
using namespace std::chrono;

terminal::vt100<> output;
random::mersenneTwister<> rng(1337);
system_clock::time_point now;

class matrixStream
{
    public:
        class cell
        {
            public:
                cell(const unsigned long &pCharacter)
                    : character(pCharacter), created(now) {}

                unsigned long character;
                system_clock::time_point created;
        };

        matrixStream(const std::size_t &pLine, const std::size_t &pColumn)
            : line(pLine), column(pColumn), last(now), doDelete(false) {}

        std::size_t line;
        std::size_t column;
        std::vector<cell> data;
        system_clock::time_point last;
        bool doDelete;

        bool update (void)
        {
            if ((now - last) > std::chrono::milliseconds(10))
            {
                last = now;
                switch (rng() % 3)
                {
                    case 0:
                        if (data.size() > 0)
                        {
                            data.erase(data.begin() + (rng() % data.size()));
                        }
                        else
                        {
                            data.push_back(cell(rng() % (1 << 7)));
                        }
                        break;
                    default:
                        data.push_back(cell(rng() % (1 << 7)));
                }
            }
            std::array<std::size_t,2> s = output.size();
            if (data.size() > (s[1]/2))
            {
                if (line < s[1])
                {
                    if (rng() % 5 == 0)
                    {
                        output.target[line][column].content = ' ';
                        line++;
                    }
                }
                else
                {
                    doDelete = true;
                }
                data.erase(data.begin());
            }
            int i = line;
            for (cell &d : data)
            {
                if (i >= s[1])
                {
                    break;
                }
                output.target[i][column].content = d.character;
                output.target[i][column].foregroundColour = (now - d.created) > std::chrono::milliseconds(120) ? 2 : 7;
                output.target[i][column].backgroundColour = 0;
                i++;
            }
            return true;
        }
};

int main (int argc, char **argv)
{
    output.resize(output.getOSDimensions());
    std::array<std::size_t,2> s = output.size();

    int i;

    std::vector<matrixStream> streams;

    while (1)
    {
        i++;
        now = system_clock::now();

        if (i % 50 == 0)
        {
            std::size_t l = rng() % (s[1] / 3);
            std::size_t c = rng() %  s[0];
            streams.push_back(matrixStream(l, c));
        }
        if (streams.size() > 100)
        {
            streams.erase(streams.begin());
        }

        for (matrixStream &s : streams)
        {
            s.update();
        }

        for (unsigned int i = 0; i < streams.size(); i++)
        {
            if (streams[i].doDelete)
            {
                streams.erase(streams.begin() + i);
            }
        }

        std::cout << output.flush();
        usleep(50);
    }

    for (std::string s = output.flush(); s != ""; s = output.flush())
    {
        std::cout << s;
        i++;
    }

    std::cout << "\e[39;49;0m\n";

    return 0;
}
<|endoftext|>