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

using namespace dbaui;
using namespace ::com::sun::star::sdbc;
//========================================================================
// class OTableRow
//========================================================================
DBG_NAME(OTableRow);
//------------------------------------------------------------------------------
OTableRow::OTableRow()
    :m_pActFieldDescr( NULL )
    ,m_nPos( -1 )
    ,m_bReadOnly( sal_False )
    ,m_bFirstNameModify( sal_True )
    ,m_bFirstDescrModify( sal_True )
{
    DBG_CTOR(OTableRow,NULL);
}

//------------------------------------------------------------------------------
OTableRow::OTableRow( const OTableRow& rRow, long nPosition ) :
    m_nPos( nPosition )
    ,m_bReadOnly(rRow.IsReadOnly())
    ,m_bFirstNameModify(rRow.IsFirstNameModify())
    ,m_bFirstDescrModify(rRow.IsFirstDescrModify())
{
    DBG_CTOR(OTableRow,NULL);

    m_pActFieldDescr = new OFieldDescription(*rRow.GetActFieldDescr());
}

//------------------------------------------------------------------------------
OTableRow::~OTableRow()
{
    DBG_DTOR(OTableRow,NULL);
}

//------------------------------------------------------------------------------
void OTableRow::SetPrimaryKey( sal_Bool bSet )
{
    DBG_CHKTHIS(OTableRow,NULL);
    if(m_pActFieldDescr)
        m_pActFieldDescr->SetPrimaryKey(bSet);
}
// -----------------------------------------------------------------------------
sal_Bool OTableRow::IsPrimaryKey() const
{
    DBG_CHKTHIS(OTableRow,NULL);
    return m_pActFieldDescr && m_pActFieldDescr->IsPrimaryKey();
}
// -----------------------------------------------------------------------------
void OTableRow::SetFieldType( const OTypeInfo* _pType )
{
    DBG_CHKTHIS(OTableRow,NULL);
    if(_pType)
    {
        if( !m_pActFieldDescr )
        {
            m_pActFieldDescr = new OFieldDescription();
            switch(_pType->nType)
            {
                case DataType::CHAR:
                case DataType::VARCHAR:
                    m_pActFieldDescr->SetPrecision(::std::min(sal_Int32(50),_pType->nPrecision));
                    break;
                default:
                    if(_pType->nPrecision && _pType->nMaximumScale)
                    {
                        m_pActFieldDescr->SetPrecision(5);
                        m_pActFieldDescr->SetScale(0);
                    }
                    else if(_pType->nPrecision)
                        m_pActFieldDescr->SetPrecision(::std::min(sal_Int32(16),_pType->nPrecision));
            }
        }
        // type checking
        if(m_pActFieldDescr->GetPrecision() > _pType->nPrecision)
            m_pActFieldDescr->SetPrecision(_pType->nPrecision);
        if(m_pActFieldDescr->GetScale() > _pType->nMaximumScale)
            m_pActFieldDescr->SetScale(0);
        if(!_pType->bNullable && m_pActFieldDescr->IsNullable())
            m_pActFieldDescr->SetIsNullable(ColumnValue::NO_NULLS);
        if(!_pType->bAutoIncrement && m_pActFieldDescr->IsAutoIncrement())
            m_pActFieldDescr->SetAutoIncrement(sal_False);

        m_pActFieldDescr->SetType(_pType);
    }
    else
    {
        delete m_pActFieldDescr;
        m_pActFieldDescr = NULL;
    }
}
// -----------------------------------------------------------------------------

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

using namespace dbaui;
using namespace ::com::sun::star::sdbc;
//========================================================================
// class OTableRow
//========================================================================
DBG_NAME(OTableRow);
//------------------------------------------------------------------------------
OTableRow::OTableRow()
    :m_pActFieldDescr( NULL )
    ,m_nPos( -1 )
    ,m_bReadOnly( sal_False )
    ,m_bFirstNameModify( sal_True )
    ,m_bFirstDescrModify( sal_True )
{
    DBG_CTOR(OTableRow,NULL);
}

//------------------------------------------------------------------------------
OTableRow::OTableRow( const OTableRow& rRow, long nPosition ) :
    m_nPos( nPosition )
    ,m_bReadOnly(rRow.IsReadOnly())
    ,m_bFirstNameModify(rRow.IsFirstNameModify())
    ,m_bFirstDescrModify(rRow.IsFirstDescrModify())
{
    DBG_CTOR(OTableRow,NULL);

    m_pActFieldDescr = new OFieldDescription(*rRow.GetActFieldDescr());
}

//------------------------------------------------------------------------------
OTableRow::~OTableRow()
{
    DBG_DTOR(OTableRow,NULL);
}

//------------------------------------------------------------------------------
void OTableRow::SetPrimaryKey( sal_Bool bSet )
{
    DBG_CHKTHIS(OTableRow,NULL);
    if(m_pActFieldDescr)
        m_pActFieldDescr->SetPrimaryKey(bSet);
}
// -----------------------------------------------------------------------------
sal_Bool OTableRow::IsPrimaryKey() const
{
    DBG_CHKTHIS(OTableRow,NULL);
    return m_pActFieldDescr && m_pActFieldDescr->IsPrimaryKey();
}
// -----------------------------------------------------------------------------
void OTableRow::SetFieldType( const OTypeInfo* _pType )
{
    DBG_CHKTHIS(OTableRow,NULL);
    if(_pType)
    {
        if( !m_pActFieldDescr )
        {
            m_pActFieldDescr = new OFieldDescription();
            switch(_pType->nType)
            {
                case DataType::CHAR:
                case DataType::VARCHAR:
                    m_pActFieldDescr->SetPrecision(::std::min<sal_Int32>(sal_Int32(50),_pType->nPrecision));
                    break;
                default:
                    if(_pType->nPrecision && _pType->nMaximumScale)
                    {
                        m_pActFieldDescr->SetPrecision(5);
                        m_pActFieldDescr->SetScale(0);
                    }
                    else if(_pType->nPrecision)
                        m_pActFieldDescr->SetPrecision(::std::min<sal_Int32>(sal_Int32(16),_pType->nPrecision));
            }
        }
        // type checking
        if(m_pActFieldDescr->GetPrecision() > _pType->nPrecision)
            m_pActFieldDescr->SetPrecision(_pType->nPrecision);
        if(m_pActFieldDescr->GetScale() > _pType->nMaximumScale)
            m_pActFieldDescr->SetScale(0);
        if(!_pType->bNullable && m_pActFieldDescr->IsNullable())
            m_pActFieldDescr->SetIsNullable(ColumnValue::NO_NULLS);
        if(!_pType->bAutoIncrement && m_pActFieldDescr->IsAutoIncrement())
            m_pActFieldDescr->SetAutoIncrement(sal_False);

        m_pActFieldDescr->SetType(_pType);
    }
    else
    {
        delete m_pActFieldDescr;
        m_pActFieldDescr = NULL;
    }
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "EDDIFrontEnd.hpp"
#include "SemanticalException.hpp"
#include "DebugStopWatch.hpp"
#include "Options.hpp"
#include "StringPool.hpp"
#include "Type.hpp"
#include "GlobalContext.hpp"

#include "parser/SpiritParser.hpp"

#include "ast/SourceFile.hpp"

//Annotators
#include "ast/DefaultValues.hpp"
#include "ast/ContextAnnotator.hpp"
#include "ast/FunctionsAnnotator.hpp"
#include "ast/VariablesAnnotator.hpp"
#include "ast/StructuresAnnotator.hpp"

//Checkers
#include "ast/StringChecker.hpp"
#include "ast/TypeChecker.hpp"

//Visitors
#include "ast/DependenciesResolver.hpp"
#include "ast/OptimizationEngine.hpp"
#include "ast/TransformerEngine.hpp"
#include "ast/WarningsEngine.hpp"
#include "ast/Printer.hpp"
#include "ast/TemplateEngine.hpp"

#include "mtac/Compiler.hpp"
#include "mtac/RegisterAllocation.hpp"

using namespace eddic;

void check_for_main(std::shared_ptr<GlobalContext> context);
void mark(ast::SourceFile& program);
bool still_unmarked(ast::SourceFile& program);

std::shared_ptr<mtac::Program> EDDIFrontEnd::compile(const std::string& file){
    parser::SpiritParser parser;

    //The program to build
    ast::SourceFile program;

    //Parse the file into the program
    bool parsing = parser.parse(file, program);

    //If the parsing was sucessfully
    if(parsing){
        set_string_pool(std::make_shared<StringPool>());

        //Read dependencies
        resolveDependencies(program, parser);

        //Apply some cleaning transformations
        ast::cleanAST(program);

        ast::TemplateEngine template_engine;

        do {
            std::cout << "Phase " << std::endl;

            //Define contexts and structures
            ast::defineContexts(program);
            ast::defineStructures(program);

            //Add default values
            ast::defineDefaultValues(program);

            //Add some more informations to the AST
            ast::defineMemberFunctions(program);
            ast::defineVariables(program);
            ast::defineFunctions(program);

            //Mark all the functions and struct as transformed
            mark(program);

            //Instantiate templates
            template_engine.template_instantiation(program);
        } while(still_unmarked(program));

        //Fill the string pool
        ast::checkStrings(program, *pool);

        //Static analysis
        ast::checkTypes(program);

        //Transform the AST
        ast::transformAST(program);

        //Check for warnings
        ast::checkForWarnings(program);

        //Check that there is a main in the program
        check_for_main(program.Content->context);

        //Optimize the AST
        ast::optimizeAST(program, *pool);

        //If the user asked for it, print the Abstract Syntax Tree
        if(option_defined("ast") || option_defined("ast-only")){
            ast::Printer printer;
            printer.print(program);
        }

        //If the user wants only the AST prints, it is not necessary to compile the AST
        if(option_defined("ast-only")){
            return nullptr;
        }

        std::shared_ptr<mtac::Program> mtacProgram = std::make_shared<mtac::Program>();

        //Generate Three-Address-Code language
        mtac::Compiler compiler;
        compiler.compile(program, pool, mtacProgram);

        return mtacProgram;
    }

    //If the parsing fails, the error is already printed to the console
    return nullptr;
}

void check_for_main(std::shared_ptr<GlobalContext> context){
    if(context->exists("_F4main")){
        context->addReference("_F4main");
    } else if (context->exists("_F4mainAS")){
        context->addReference("_F4mainAS");
    } else {
        throw SemanticalException("The program does not contain a valid main function");
    }
}

void mark(ast::SourceFile& program){
    for(auto& block : program.Content->blocks){
        if(auto* ptr = boost::get<ast::FunctionDeclaration>(&block)){
            ptr->Content->marked = true;
        } else if(auto* ptr = boost::get<ast::Struct>(&block)){
            ptr->Content->marked = true;

            for(auto& function : ptr->Content->functions){
               function.Content->marked = true;
            }

            for(auto& function : ptr->Content->destructors){
               function.Content->marked = true;
            }

            for(auto& function : ptr->Content->constructors){
               function.Content->marked = true;
            }
        }
    }
}

bool still_unmarked(ast::SourceFile& program){
    for(auto& block : program.Content->blocks){
        if(auto* ptr = boost::get<ast::FunctionDeclaration>(&block)){
            if(!ptr->Content->marked){
                return true;
            }
        } else if(auto* ptr = boost::get<ast::Struct>(&block)){
            if(!ptr->Content->marked){
                return true;
            }

            for(auto& function : ptr->Content->functions){
                if(!function.Content->marked){
                    return true;
                }
            }

            for(auto& function : ptr->Content->destructors){
                if(!function.Content->marked){
                    return true;
                }
            }

            for(auto& function : ptr->Content->constructors){
                if(!function.Content->marked){
                    return true;
                }
            }
        }
    }

    return false;
}
<commit_msg>Improve printer<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "EDDIFrontEnd.hpp"
#include "SemanticalException.hpp"
#include "DebugStopWatch.hpp"
#include "Options.hpp"
#include "StringPool.hpp"
#include "Type.hpp"
#include "GlobalContext.hpp"

#include "parser/SpiritParser.hpp"

#include "ast/SourceFile.hpp"

//Annotators
#include "ast/DefaultValues.hpp"
#include "ast/ContextAnnotator.hpp"
#include "ast/FunctionsAnnotator.hpp"
#include "ast/VariablesAnnotator.hpp"
#include "ast/StructuresAnnotator.hpp"

//Checkers
#include "ast/StringChecker.hpp"
#include "ast/TypeChecker.hpp"

//Visitors
#include "ast/DependenciesResolver.hpp"
#include "ast/OptimizationEngine.hpp"
#include "ast/TransformerEngine.hpp"
#include "ast/WarningsEngine.hpp"
#include "ast/Printer.hpp"
#include "ast/TemplateEngine.hpp"

#include "mtac/Compiler.hpp"
#include "mtac/RegisterAllocation.hpp"

using namespace eddic;

void check_for_main(std::shared_ptr<GlobalContext> context);
void mark(ast::SourceFile& program);
bool still_unmarked(ast::SourceFile& program);

std::shared_ptr<mtac::Program> EDDIFrontEnd::compile(const std::string& file){
    parser::SpiritParser parser;

    //The program to build
    ast::SourceFile program;

    //Parse the file into the program
    bool parsing = parser.parse(file, program);

    //If the parsing was sucessfully
    if(parsing){
        set_string_pool(std::make_shared<StringPool>());

        //Read dependencies
        resolveDependencies(program, parser);

        //Apply some cleaning transformations
        ast::cleanAST(program);

        ast::TemplateEngine template_engine;

        do {
            std::cout << "Phase " << std::endl;

            ast::Printer printer;
            printer.print(program);

            //Define contexts and structures
            ast::defineContexts(program);
            ast::defineStructures(program);

            //Add default values
            ast::defineDefaultValues(program);

            //Add some more informations to the AST
            ast::defineMemberFunctions(program);
            ast::defineVariables(program);
            ast::defineFunctions(program);

            //Mark all the functions and struct as transformed
            mark(program);

            //Instantiate templates
            template_engine.template_instantiation(program);
        } while(still_unmarked(program));

        //Fill the string pool
        ast::checkStrings(program, *pool);

        //Static analysis
        ast::checkTypes(program);

        //Transform the AST
        ast::transformAST(program);

        //Check for warnings
        ast::checkForWarnings(program);

        //Check that there is a main in the program
        check_for_main(program.Content->context);

        //Optimize the AST
        ast::optimizeAST(program, *pool);

        //If the user asked for it, print the Abstract Syntax Tree
        if(option_defined("ast") || option_defined("ast-only")){
            ast::Printer printer;
            printer.print(program);
        }

        //If the user wants only the AST prints, it is not necessary to compile the AST
        if(option_defined("ast-only")){
            return nullptr;
        }

        std::shared_ptr<mtac::Program> mtacProgram = std::make_shared<mtac::Program>();

        //Generate Three-Address-Code language
        mtac::Compiler compiler;
        compiler.compile(program, pool, mtacProgram);

        return mtacProgram;
    }

    //If the parsing fails, the error is already printed to the console
    return nullptr;
}

void check_for_main(std::shared_ptr<GlobalContext> context){
    if(context->exists("_F4main")){
        context->addReference("_F4main");
    } else if (context->exists("_F4mainAS")){
        context->addReference("_F4mainAS");
    } else {
        throw SemanticalException("The program does not contain a valid main function");
    }
}

void mark(ast::SourceFile& program){
    for(auto& block : program.Content->blocks){
        if(auto* ptr = boost::get<ast::FunctionDeclaration>(&block)){
            ptr->Content->marked = true;
        } else if(auto* ptr = boost::get<ast::Struct>(&block)){
            ptr->Content->marked = true;

            for(auto& function : ptr->Content->functions){
               function.Content->marked = true;
            }

            for(auto& function : ptr->Content->destructors){
               function.Content->marked = true;
            }

            for(auto& function : ptr->Content->constructors){
               function.Content->marked = true;
            }
        }
    }
}

bool still_unmarked(ast::SourceFile& program){
    for(auto& block : program.Content->blocks){
        if(auto* ptr = boost::get<ast::FunctionDeclaration>(&block)){
            if(!ptr->Content->marked){
                return true;
            }
        } else if(auto* ptr = boost::get<ast::Struct>(&block)){
            if(!ptr->Content->marked){
                return true;
            }

            for(auto& function : ptr->Content->functions){
                if(!function.Content->marked){
                    return true;
                }
            }

            for(auto& function : ptr->Content->destructors){
                if(!function.Content->marked){
                    return true;
                }
            }

            for(auto& function : ptr->Content->constructors){
                if(!function.Content->marked){
                    return true;
                }
            }
        }
    }

    return false;
}
<|endoftext|>


<commit_before>#include <UtH/Engine/Layer.hpp>

using namespace uth;

Layer::Layer()
	: layerName(NULL),
	  objectCount(NULL),
	  m_objects(NULL),
	  layerId(NULL)
{
}

Layer::Layer(const int layerId)
	: layerName(NULL),
	  objectCount(0),
	  m_objects(NULL),
	  layerId(layerId)
{
}

Layer::Layer(const char* layerName, const int layerId)
	: layerName(layerName),
	  objectCount(0),
	  m_objects(NULL),
	  layerId(layerId)
{
}

Layer::~Layer()
{
	m_objects.clear();
}

void Layer::SetLayerName(const char* layerName)
{
	this->layerName = layerName;
}

const char* Layer::GetLayerName()
{
	return layerName;
}

const int Layer::GetLayerId()
{
	return layerId;
}

bool Layer::AddGameObject(GameObject* gameObject)
{
	m_objects.push_back(gameObject);

	if(m_objects.size() < objectCount)
		return false;

	objectCount++;
	return true;
}

bool Layer::RemoveGameObject(GameObject* gameObject)
{
	std::vector<GameObject*>::iterator it;
	for(it = m_objects.begin(); it != m_objects.end(); ++it)
	{
		if((*it) == gameObject)
		{
			m_objects.erase(it);
			objectCount--;
			return true;
		}
	}
	return false;
}

void Layer::Update(float dt)
{
	UpdateTransform();

	for(size_t i = 0; i < m_objects.size(); ++i)
	{
		m_objects.at(i)->Update(dt);
	}
}

void Layer::Draw(RenderTarget& target)
{
	for(size_t i = 0; i < m_objects.size(); ++i)
	{
		if(m_objects.at(i)->transform.IsActive())
			m_objects.at(i)->Draw(target);
	}
}

void Layer::SetObjectsActive(bool value)
{
	for(size_t i = 0; i < m_objects.size(); ++i)
	{
		m_objects.at(i)->transform.SetActive(value);
		//m_objects.at(i)->transform.SetDrawable(value);
	}
}

void Layer::UpdateTransform()
{

	for(size_t i = 0; i < m_objects.size(); ++i)
	{
		m_objects.at(i)->transform.AddTransform(transform.GetTransform());
		/*
		m_objects.at(i)->transform.SetTransform(transform.GetTransform() *
			m_objects.at(i)->transform.GetTransform());
			*/
	}

}<commit_msg>Fixed layertransform with rigidbody objects<commit_after>#include <UtH/Engine/Layer.hpp>

using namespace uth;

Layer::Layer()
	: layerName(NULL),
	  objectCount(NULL),
	  m_objects(NULL),
	  layerId(NULL)
{
}

Layer::Layer(const int layerId)
	: layerName(NULL),
	  objectCount(0),
	  m_objects(NULL),
	  layerId(layerId)
{
}

Layer::Layer(const char* layerName, const int layerId)
	: layerName(layerName),
	  objectCount(0),
	  m_objects(NULL),
	  layerId(layerId)
{
}

Layer::~Layer()
{
	m_objects.clear();
}

void Layer::SetLayerName(const char* layerName)
{
	this->layerName = layerName;
}

const char* Layer::GetLayerName()
{
	return layerName;
}

const int Layer::GetLayerId()
{
	return layerId;
}

bool Layer::AddGameObject(GameObject* gameObject)
{
	m_objects.push_back(gameObject);

	if(m_objects.size() < objectCount)
		return false;

	objectCount++;
	return true;
}

bool Layer::RemoveGameObject(GameObject* gameObject)
{
	std::vector<GameObject*>::iterator it;
	for(it = m_objects.begin(); it != m_objects.end(); ++it)
	{
		if((*it) == gameObject)
		{
			m_objects.erase(it);
			objectCount--;
			return true;
		}
	}
	return false;
}

void Layer::Update(float dt)
{
	for(size_t i = 0; i < m_objects.size(); ++i)
	{
		m_objects.at(i)->Update(dt);
	}

	UpdateTransform();
}

void Layer::Draw(RenderTarget& target)
{
	for(size_t i = 0; i < m_objects.size(); ++i)
	{
		if(m_objects.at(i)->transform.IsActive())
			m_objects.at(i)->Draw(target);
	}
}

void Layer::SetObjectsActive(bool value)
{
	for(size_t i = 0; i < m_objects.size(); ++i)
	{
		m_objects.at(i)->transform.SetActive(value);
		//m_objects.at(i)->transform.SetDrawable(value);
	}
}

void Layer::UpdateTransform()
{

	for(size_t i = 0; i < m_objects.size(); ++i)
	{
		m_objects.at(i)->transform.AddTransform(transform.GetTransform());
		/*
		m_objects.at(i)->transform.SetTransform(transform.GetTransform() *
			m_objects.at(i)->transform.GetTransform());
			*/
	}

}<|endoftext|>


<commit_before>#include "FffProcessor.h"

namespace cura
{

FffProcessor FffProcessor::instance; // definition must be in cpp

std::string FffProcessor::getAllSettingsString(MeshGroup& meshgroup, bool first_meshgroup)
{
    std::stringstream sstream;
    if (first_meshgroup)
    {
        sstream << " -g";
    }
    else
    {
        sstream << " --next";
    }
    sstream << meshgroup.getAllLocalSettingsString();
    for (int extruder_nr = 0; extruder_nr < meshgroup.getExtruderCount(); extruder_nr++)
    {
        ExtruderTrain* train = meshgroup.getExtruderTrain(extruder_nr);
        sstream << " -e" << extruder_nr << train->getAllLocalSettingsString();
    }
    for (unsigned int mesh_idx = 0; mesh_idx < meshgroup.meshes.size(); mesh_idx++)
    {
        Mesh& mesh = meshgroup.meshes[mesh_idx];
        sstream << " -e" << mesh.getSettingAsCount("extruder_nr") << " -l \"" << mesh_idx << "\"" << mesh.getAllLocalSettingsString();
    }
    sstream << "\n";
    return sstream.str();
}

bool FffProcessor::processFiles(const std::vector< std::string >& files)
{
    time_keeper.restart();
    MeshGroup* meshgroup = new MeshGroup(this);

    for(std::string filename : files)
    {
        log("Loading %s from disk...\n", filename.c_str());

        FMatrix3x3 matrix;
        if (!loadMeshIntoMeshGroup(meshgroup, filename.c_str(), matrix))
        {
            logError("Failed to load model: %s\n", filename.c_str());
            return false;
        }
    }

    meshgroup->finalize();

    log("Loaded from disk in %5.3fs\n", time_keeper.restart());
    return processMeshGroup(meshgroup);
}

bool FffProcessor::processMeshGroup(MeshGroup* meshgroup)
{
    if (SHOW_ALL_SETTINGS) { logWarning(getAllSettingsString(*meshgroup, first_meshgroup).c_str()); }
    time_keeper.restart();
    if (!meshgroup)
        return false;

    TimeKeeper time_keeper_total;

    if (meshgroup->getSettingBoolean("wireframe_enabled"))
    {
        log("starting Neith Weaver...\n");

        Weaver w(this);
        w.weave(meshgroup, command_socket);

        log("starting Neith Gcode generation...\n");
        Wireframe2gcode gcoder(w, gcode_writer.gcode, this);
        gcoder.writeGCode(command_socket);
        log("finished Neith Gcode generation...\n");

    } else
    {
        SliceDataStorage storage(meshgroup);

        if (!polygon_generator.generateAreas(storage, meshgroup, time_keeper))
        {
            return false;
        }
        gcode_writer.setCommandSocket(command_socket);

        Progress::messageProgressStage(Progress::Stage::EXPORT, &time_keeper, command_socket);
        gcode_writer.writeGCode(storage, time_keeper);
    }

    Progress::messageProgress(Progress::Stage::FINISH, 1, 1, command_socket); //Report the GUI that a file has been fully processed.
    log("Total time elapsed %5.2fs.\n", time_keeper_total.restart());

    profile_string += getAllSettingsString(*meshgroup, first_meshgroup);
    first_meshgroup = false;
    return true;
}

} // namespace cura <commit_msg>early out when meshgroup is empty (CURA-349)<commit_after>#include "FffProcessor.h"

namespace cura
{

FffProcessor FffProcessor::instance; // definition must be in cpp

std::string FffProcessor::getAllSettingsString(MeshGroup& meshgroup, bool first_meshgroup)
{
    std::stringstream sstream;
    if (first_meshgroup)
    {
        sstream << " -g";
    }
    else
    {
        sstream << " --next";
    }
    sstream << meshgroup.getAllLocalSettingsString();
    for (int extruder_nr = 0; extruder_nr < meshgroup.getExtruderCount(); extruder_nr++)
    {
        ExtruderTrain* train = meshgroup.getExtruderTrain(extruder_nr);
        sstream << " -e" << extruder_nr << train->getAllLocalSettingsString();
    }
    for (unsigned int mesh_idx = 0; mesh_idx < meshgroup.meshes.size(); mesh_idx++)
    {
        Mesh& mesh = meshgroup.meshes[mesh_idx];
        sstream << " -e" << mesh.getSettingAsCount("extruder_nr") << " -l \"" << mesh_idx << "\"" << mesh.getAllLocalSettingsString();
    }
    sstream << "\n";
    return sstream.str();
}

bool FffProcessor::processFiles(const std::vector< std::string >& files)
{
    time_keeper.restart();
    MeshGroup* meshgroup = new MeshGroup(this);

    for(std::string filename : files)
    {
        log("Loading %s from disk...\n", filename.c_str());

        FMatrix3x3 matrix;
        if (!loadMeshIntoMeshGroup(meshgroup, filename.c_str(), matrix))
        {
            logError("Failed to load model: %s\n", filename.c_str());
            return false;
        }
    }

    meshgroup->finalize();

    log("Loaded from disk in %5.3fs\n", time_keeper.restart());
    return processMeshGroup(meshgroup);
}

bool FffProcessor::processMeshGroup(MeshGroup* meshgroup)
{
    if (SHOW_ALL_SETTINGS) { logWarning(getAllSettingsString(*meshgroup, first_meshgroup).c_str()); }
    time_keeper.restart();
    if (!meshgroup)
        return false;

    TimeKeeper time_keeper_total;

    if (meshgroup->meshes.empty())
    {
        Progress::messageProgress(Progress::Stage::FINISH, 1, 1, command_socket); //Report the GUI that a file has been fully processed.
        log("Total time elapsed %5.2fs.\n", time_keeper_total.restart());

        profile_string += getAllSettingsString(*meshgroup, first_meshgroup);
        return;
    }

    if (meshgroup->getSettingBoolean("wireframe_enabled"))
    {
        log("starting Neith Weaver...\n");

        Weaver w(this);
        w.weave(meshgroup, command_socket);

        log("starting Neith Gcode generation...\n");
        Wireframe2gcode gcoder(w, gcode_writer.gcode, this);
        gcoder.writeGCode(command_socket);
        log("finished Neith Gcode generation...\n");

    } else
    {
        SliceDataStorage storage(meshgroup);

        if (!polygon_generator.generateAreas(storage, meshgroup, time_keeper))
        {
            return false;
        }
        gcode_writer.setCommandSocket(command_socket);

        Progress::messageProgressStage(Progress::Stage::EXPORT, &time_keeper, command_socket);
        gcode_writer.writeGCode(storage, time_keeper);
    }

    Progress::messageProgress(Progress::Stage::FINISH, 1, 1, command_socket); //Report the GUI that a file has been fully processed.
    log("Total time elapsed %5.2fs.\n", time_keeper_total.restart());

    profile_string += getAllSettingsString(*meshgroup, first_meshgroup);
    first_meshgroup = false;
    return true;
}

} // namespace cura <|endoftext|>


<commit_before>/**
 *  Copyright 2014-2016 CyberVision, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <memory>
#include <string>
#include <cstdint>
#include <iostream>

#include <kaa/Kaa.hpp>
#include <kaa/event/registration/IUserAttachCallback.hpp>
#include <kaa/event/IFetchEventListeners.hpp>
#include <kaa/event/gen/EventFamilyFactory.hpp>
#include <kaa/event/gen/Chat.hpp>

using namespace kaa;

static const char * const CHAT_EVENT_FQN = "org.kaaproject.kaa.examples.event.ChatEvent";
static const char * const CHAT_MESSAGE_FQN = "org.kaaproject.kaa.examples.event.Message";

class ChatApp: public Chat::ChatListener {
public:
    ChatApp(EventFamilyFactory &factory):
        eventFactory_(factory)
    {}

    ~ChatApp() = default;

    bool joinRoom(const std::string &name)
    {
        if (std::find(rooms_.begin(), rooms_.end(), name) == rooms_.end()) {
            return false;
        }
        currentRoom_ = name;
        return true;
    }

    void leaveRoom() {
        currentRoom_ = "";
    }

    bool createRoom(const std::string &name)
    {
        if (std::find(rooms_.begin(), rooms_.end(), name) == rooms_.end()) {
            nsChat::ChatEvent cev;
            cev.ChatName = name;
            cev.EventType = nsChat::CREATE;
            eventFactory_.getChat().sendEventToAll(cev);
            rooms_.push_back(name);
            return true;
        }
        return false;
    }

    bool deleteRoom(const std::string &name)
    {
        auto pos = std::find(rooms_.begin(), rooms_.end(), name);
        if (pos != rooms_.end()) {
            nsChat::ChatEvent cev;
            cev.ChatName = name;
            cev.EventType = nsChat::DELETE;
            eventFactory_.getChat().sendEventToAll(cev);
            rooms_.erase(pos);
            return true;
        }
        return false;
    }

    const std::vector<std::string> &getRooms() const
    {
        return rooms_;
    }

    void sendMessage(const std::string message)
    {
        if (currentRoom_.empty()) {
            return;
        }

        nsChat::Message msg;
        msg.message = message;
        msg.ChatName = currentRoom_;
        eventFactory_.getChat().sendEventToAll(msg);
    }

    virtual void onEvent(const nsChat::ChatEvent &event, const std::string &source)
    {
        static_cast<void>(source);

        switch (event.EventType) {
            case nsChat::CREATE:
                createRoom(event.ChatName);
            break;
            case nsChat::DELETE:
                deleteRoom(event.ChatName);
            break;
        }
    }

    virtual void onEvent(const nsChat::Message &message, const std::string &source)
    {
        static_cast<void>(source);
        if (message.ChatName == currentRoom_) {
            std::cout << message.message << std::endl;
        }
    }

private:
    EventFamilyFactory &eventFactory_;
    std::string currentRoom_;
    std::vector<std::string> rooms_;
};

class ChatMenu {
public:
    ChatMenu(ChatApp &chat):
        chat_(chat)
    {}

    ~ChatMenu() = default;

    bool process(const std::string &input)
    {
        if (inMenu_) {
            return processCommand(input);
        }

        if (input == "/quit") {
            inMenu_ = true;
            chat_.leaveRoom();
            printHelp();
            printRooms();
        } else {
            chat_.sendMessage(input);
        }
        return true;
    }

    void printHelp() const {
        std::cout << "Available commands:\n";
        std::cout << "join <room> - join room\n";
        std::cout << "create <room> - create room\n";
        std::cout << "delete <room> - delete room\n";
        std::cout << "rooms - list available rooms\n";
        std::cout << "quit - exit application\n";
    }

    void printRooms() const {
        const auto &rooms = chat_.getRooms();
        if (rooms.size() == 0) {
            std::cout << "No rooms available\n";
            return;
        }
        std::cout << "Available rooms:\n";
        for (const auto &room : rooms) {
            std::cout << room << '\n';
        }
    }

private:
    bool processCommand(const std::string &command) {
        if (command.compare(0, sizeof("quit")-1, "quit") == 0) {
            return false;
        }

        if (command.compare(0, sizeof("rooms")-1, "rooms") == 0) {
            printRooms();
            return true;
        }

        std::string room = "";
        size_t pos = command.find_first_of(" ", 0);
        if (pos != std::string::npos && pos+1 < command.length()) {
            room = command.substr(pos+1);
        }

        if (command.compare(0, sizeof("join")-1, "join") == 0) {
            return command_join(room);
        } else if (command.compare(0, sizeof("create")-1, "create") == 0) {
            return command_create(room);
        }  else if (command.compare(0, sizeof("delete")-1, "delete") == 0) {
            return command_delete(room);
        }

        std::cout << "Unknown command " << command << '\n';
        return true;
    }

    bool command_join(const std::string &room)
    {
        if (room.empty()) {
            std::cout << "Wrong command syntax\n";
            printHelp();
            return true;
        }
        if (!chat_.joinRoom(room)) {
            std::cout << "Failed to join " << room << '\n';
            printRooms();
            return true;
        }
        std::cout << "Joined " << room << '\n';
        std::cout << "Enter /quit to leave room\n";
        inMenu_ = false;
        return true;
    }

    bool command_create(const std::string &room)
    {
        if (room.empty()) {
            std::cout << "Wrong command syntax\n";
            printHelp();
            return true;
        }
        if (!chat_.createRoom(room)) {
            std::cout << "Failed to create " << room << '\n';
            printRooms();
            return true;
        }

        std::cout << "Created " << room << '\n';
        return true;
    }

    bool command_delete(const std::string &room)
    {
        if (room.empty()) {
            std::cout << "Wrong command syntax\n";
            printHelp();
            return true;
        }
        if (!chat_.deleteRoom(room)) {
            std::cout << "Failed to delete " << room << '\n';
            printRooms();
            return true;
        }
        std::cout << "Deleted " << room << '\n';
        return true;
    }

private:
    ChatApp &chat_;
    bool inMenu_;
};

class ChatListenersCallback: public IFetchEventListeners {
public:

    ChatListenersCallback(EventFamilyFactory &factory) : eventFactory_(factory)
    {}

    ~ChatListenersCallback() = default;

    virtual void onEventListenersReceived(const std::vector<std::string> &eventListeners)
    {}

    virtual void onRequestFailed()
    {}

private:
    EventFamilyFactory& eventFactory_;

};

class UserAttachCallback: public IUserAttachCallback {
public:

    UserAttachCallback(IKaaClient& client) : kaaClient_(client) { }

    virtual void onAttachSuccess()
    {
        kaaClient_.findEventListeners(std::list<std::string>( { CHAT_EVENT_FQN, CHAT_MESSAGE_FQN }),
                                      std::make_shared<ChatListenersCallback>(kaaClient_.getEventFamilyFactory()));
    }

    virtual void onAttachFailed(UserAttachErrorCode errorCode, const std::string& reason)
    {
        std::cout << "Kaa Demo attach failed (" << (int) errorCode << "): " << reason << std::endl;
    }

private:
    IKaaClient& kaaClient_;
};

int main(int argc, char *argv[])
{
    const std::string KAA_USER_ID("userid");
    const std::string KAA_USER_ACCESS_TOKEN("token");

    /*
     * Initialize the Kaa endpoint.
     */
    auto kaaClient = Kaa::newClient();

    /*
     * Run the Kaa endpoint.
     */
    kaaClient->start();

    ChatApp chat(kaaClient->getEventFamilyFactory());

    kaaClient->getEventFamilyFactory().getChat().addEventFamilyListener(chat);
    kaaClient->attachUser(KAA_USER_ID, KAA_USER_ACCESS_TOKEN, std::make_shared<UserAttachCallback>(*kaaClient));

    std::cout << "Endpoint key hash: " << kaaClient->getEndpointKeyHash() << '\n';

    ChatMenu menu(chat);
    std::string userInput;

    menu.printHelp();
    menu.printRooms();
    do {
        std::getline(std::cin, userInput);
    } while (menu.process(userInput));

    /*
     * Stop the Kaa endpoint.
     */
    kaaClient->stop();

    return 0;
}
<commit_msg>[C++] Event demo build fix<commit_after>/**
 *  Copyright 2014-2016 CyberVision, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <memory>
#include <string>
#include <cstdint>
#include <iostream>

#include <kaa/Kaa.hpp>
#include <kaa/event/registration/IUserAttachCallback.hpp>
#include <kaa/event/IFetchEventListeners.hpp>
#include <kaa/event/gen/EventFamilyFactory.hpp>
#include <kaa/event/gen/Chat.hpp>

using namespace kaa;

static const char * const CHAT_EVENT_FQN = "org.kaaproject.kaa.examples.event.ChatEvent";
static const char * const CHAT_MESSAGE_FQN = "org.kaaproject.kaa.examples.event.Message";

class ChatApp: public Chat::ChatListener {
public:
    ChatApp(EventFamilyFactory &factory):
        eventFactory_(factory)
    {}

    ~ChatApp() = default;

    bool joinRoom(const std::string &name)
    {
        if (std::find(rooms_.begin(), rooms_.end(), name) == rooms_.end()) {
            return false;
        }
        currentRoom_ = name;
        return true;
    }

    void leaveRoom() {
        currentRoom_ = "";
    }

    bool createRoom(const std::string &name)
    {
        if (std::find(rooms_.begin(), rooms_.end(), name) == rooms_.end()) {
            nsChat::ChatEvent cev;
            cev.ChatName = name;
            cev.EventType = nsChat::CREATE;
            eventFactory_.getChat().sendEventToAll(cev);
            rooms_.push_back(name);
            return true;
        }
        return false;
    }

    bool deleteRoom(const std::string &name)
    {
        auto pos = std::find(rooms_.begin(), rooms_.end(), name);
        if (pos != rooms_.end()) {
            nsChat::ChatEvent cev;
            cev.ChatName = name;
            cev.EventType = nsChat::DELETE;
            eventFactory_.getChat().sendEventToAll(cev);
            rooms_.erase(pos);
            return true;
        }
        return false;
    }

    const std::vector<std::string> &getRooms() const
    {
        return rooms_;
    }

    void sendMessage(const std::string message)
    {
        if (currentRoom_.empty()) {
            return;
        }

        nsChat::Message msg;
        msg.Message = message;
        msg.ChatName = currentRoom_;
        eventFactory_.getChat().sendEventToAll(msg);
    }

    virtual void onEvent(const nsChat::ChatEvent &event, const std::string &source)
    {
        static_cast<void>(source);

        switch (event.EventType) {
            case nsChat::CREATE:
                createRoom(event.ChatName);
            break;
            case nsChat::DELETE:
                deleteRoom(event.ChatName);
            break;
        }
    }

    virtual void onEvent(const nsChat::Message &message, const std::string &source)
    {
        static_cast<void>(source);
        if (message.ChatName == currentRoom_) {
            std::cout << message.Message << std::endl;
        }
    }

private:
    EventFamilyFactory &eventFactory_;
    std::string currentRoom_;
    std::vector<std::string> rooms_;
};

class ChatMenu {
public:
    ChatMenu(ChatApp &chat):
        chat_(chat)
    {}

    ~ChatMenu() = default;

    bool process(const std::string &input)
    {
        if (inMenu_) {
            return processCommand(input);
        }

        if (input == "/quit") {
            inMenu_ = true;
            chat_.leaveRoom();
            printHelp();
            printRooms();
        } else {
            chat_.sendMessage(input);
        }
        return true;
    }

    void printHelp() const {
        std::cout << "Available commands:\n";
        std::cout << "join <room> - join room\n";
        std::cout << "create <room> - create room\n";
        std::cout << "delete <room> - delete room\n";
        std::cout << "rooms - list available rooms\n";
        std::cout << "quit - exit application\n";
    }

    void printRooms() const {
        const auto &rooms = chat_.getRooms();
        if (rooms.size() == 0) {
            std::cout << "No rooms available\n";
            return;
        }
        std::cout << "Available rooms:\n";
        for (const auto &room : rooms) {
            std::cout << room << '\n';
        }
    }

private:
    bool processCommand(const std::string &command) {
        if (command.compare(0, sizeof("quit")-1, "quit") == 0) {
            return false;
        }

        if (command.compare(0, sizeof("rooms")-1, "rooms") == 0) {
            printRooms();
            return true;
        }

        std::string room = "";
        size_t pos = command.find_first_of(" ", 0);
        if (pos != std::string::npos && pos+1 < command.length()) {
            room = command.substr(pos+1);
        }

        if (command.compare(0, sizeof("join")-1, "join") == 0) {
            return command_join(room);
        } else if (command.compare(0, sizeof("create")-1, "create") == 0) {
            return command_create(room);
        }  else if (command.compare(0, sizeof("delete")-1, "delete") == 0) {
            return command_delete(room);
        }

        std::cout << "Unknown command " << command << '\n';
        return true;
    }

    bool command_join(const std::string &room)
    {
        if (room.empty()) {
            std::cout << "Wrong command syntax\n";
            printHelp();
            return true;
        }
        if (!chat_.joinRoom(room)) {
            std::cout << "Failed to join " << room << '\n';
            printRooms();
            return true;
        }
        std::cout << "Joined " << room << '\n';
        std::cout << "Enter /quit to leave room\n";
        inMenu_ = false;
        return true;
    }

    bool command_create(const std::string &room)
    {
        if (room.empty()) {
            std::cout << "Wrong command syntax\n";
            printHelp();
            return true;
        }
        if (!chat_.createRoom(room)) {
            std::cout << "Failed to create " << room << '\n';
            printRooms();
            return true;
        }

        std::cout << "Created " << room << '\n';
        return true;
    }

    bool command_delete(const std::string &room)
    {
        if (room.empty()) {
            std::cout << "Wrong command syntax\n";
            printHelp();
            return true;
        }
        if (!chat_.deleteRoom(room)) {
            std::cout << "Failed to delete " << room << '\n';
            printRooms();
            return true;
        }
        std::cout << "Deleted " << room << '\n';
        return true;
    }

private:
    ChatApp &chat_;
    bool inMenu_;
};

class ChatListenersCallback: public IFetchEventListeners {
public:

    ChatListenersCallback(EventFamilyFactory &factory) : eventFactory_(factory)
    {}

    ~ChatListenersCallback() = default;

    virtual void onEventListenersReceived(const std::vector<std::string> &eventListeners)
    {}

    virtual void onRequestFailed()
    {}

private:
    EventFamilyFactory& eventFactory_;

};

class UserAttachCallback: public IUserAttachCallback {
public:

    UserAttachCallback(IKaaClient& client) : kaaClient_(client) { }

    virtual void onAttachSuccess()
    {
        kaaClient_.findEventListeners(std::list<std::string>( { CHAT_EVENT_FQN, CHAT_MESSAGE_FQN }),
                                      std::make_shared<ChatListenersCallback>(kaaClient_.getEventFamilyFactory()));
    }

    virtual void onAttachFailed(UserAttachErrorCode errorCode, const std::string& reason)
    {
        std::cout << "Kaa Demo attach failed (" << (int) errorCode << "): " << reason << std::endl;
    }

private:
    IKaaClient& kaaClient_;
};

int main(int argc, char *argv[])
{
    const std::string KAA_USER_ID("userid");
    const std::string KAA_USER_ACCESS_TOKEN("token");

    /*
     * Initialize the Kaa endpoint.
     */
    auto kaaClient = Kaa::newClient();

    /*
     * Run the Kaa endpoint.
     */
    kaaClient->start();

    ChatApp chat(kaaClient->getEventFamilyFactory());

    kaaClient->getEventFamilyFactory().getChat().addEventFamilyListener(chat);
    kaaClient->attachUser(KAA_USER_ID, KAA_USER_ACCESS_TOKEN, std::make_shared<UserAttachCallback>(*kaaClient));

    std::cout << "Endpoint key hash: " << kaaClient->getEndpointKeyHash() << '\n';

    ChatMenu menu(chat);
    std::string userInput;

    menu.printHelp();
    menu.printRooms();
    do {
        std::getline(std::cin, userInput);
    } while (menu.process(userInput));

    /*
     * Stop the Kaa endpoint.
     */
    kaaClient->stop();

    return 0;
}
<|endoftext|>


<commit_before>#include "ExecutionEngine.h"

#include <chrono>

#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#pragma warning(push)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#pragma warning(pop)
#pragma GCC diagnostic pop
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Host.h>

#include "Runtime.h"
#include "Compiler.h"
#include "Cache.h"

#if defined(NDEBUG)
#define DEBUG_ENV_OPTION(name) false
#else
#include <cstdlib>
#define DEBUG_ENV_OPTION(name) (std::getenv(#name) != nullptr)
#endif

namespace dev
{
namespace eth
{
namespace jit
{

namespace
{
typedef ReturnCode(*EntryFuncPtr)(Runtime*);

ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime)
{
	// That function uses long jumps to handle "execeptions".
	// Do not create any non-POD objects here

	ReturnCode returnCode{};
	auto sj = setjmp(_runtime->getJmpBuf());
	if (sj == 0)
		returnCode = _mainFunc(_runtime);
	else
		returnCode = static_cast<ReturnCode>(sj);

	return returnCode;
}

std::string codeHash(code_iterator _begin, code_iterator _end)
{
	uint32_t hash = 0;
	std::for_each(_begin, _end, [&hash](decltype(*_begin) b)
	{
		hash += b;
		hash += (hash << 10);
		hash ^= (hash >> 6);
	});
	hash += (hash << 3);
	hash ^= (hash >> 11);
	hash += (hash << 15);
	return std::to_string(hash);
}

}

ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env)
{
	static std::unique_ptr<llvm::ExecutionEngine> ee;  // TODO: Use Managed Objects from LLVM?
	static auto debugDumpModule = DEBUG_ENV_OPTION(EVMJIT_DUMP_MODULE);
	static bool objectCacheEnabled = !DEBUG_ENV_OPTION(EVMJIT_CACHE_OFF);

	auto codeBegin = _data->code;
	auto codeEnd = codeBegin + _data->codeSize;
	assert(codeBegin || !codeEnd); //TODO: Is it good idea to execute empty code?
	auto mainFuncName = codeHash(codeBegin, codeEnd);
	EntryFuncPtr entryFuncPtr{};
	Runtime runtime(_data, _env);	// TODO: I don't know why but it must be created before getFunctionAddress() calls

	if (ee && (entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName)))
	{
	}
	else
	{
		auto objectCache = objectCacheEnabled ? Cache::getObjectCache() : nullptr;
		std::unique_ptr<llvm::Module> module;
		if (objectCache)
			module = Cache::getObject(mainFuncName);
		if (!module)
			module = Compiler({}).compile(codeBegin, codeEnd, mainFuncName);
		if (debugDumpModule)
			module->dump();
		if (!ee)
		{
			llvm::InitializeNativeTarget();
			llvm::InitializeNativeTargetAsmPrinter();

			llvm::EngineBuilder builder(module.get());
			builder.setEngineKind(llvm::EngineKind::JIT);
			builder.setUseMCJIT(true);
			std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
			builder.setMCJITMemoryManager(memoryManager.get());
			builder.setOptLevel(llvm::CodeGenOpt::None);

			auto triple = llvm::Triple(llvm::sys::getProcessTriple());
			if (triple.getOS() == llvm::Triple::OSType::Win32)
				triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);  // MCJIT does not support COFF format
			module->setTargetTriple(triple.str());

			ee.reset(builder.create());
			if (!ee)
				return ReturnCode::LLVMConfigError;

			module.release();         // Successfully created llvm::ExecutionEngine takes ownership of the module
			memoryManager.release();  // and memory manager

			if (objectCache)
				ee->setObjectCache(objectCache);
			entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
		}
		else
		{
			if (!entryFuncPtr)
			{
				ee->addModule(module.get());
				module.release();
				entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
			}
		}
	}
	assert(entryFuncPtr);

	auto executionStartTime = std::chrono::high_resolution_clock::now();

	auto returnCode = runEntryFunc(entryFuncPtr, &runtime);
	if (returnCode == ReturnCode::Return)
	{
		returnData = runtime.getReturnData();     // Save reference to return data
		std::swap(m_memory, runtime.getMemory()); // Take ownership of memory
	}

	auto executionEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms\n";

	return returnCode;
}

}
}
}
<commit_msg>Environment options for EVM JIT updated: - EVMJIT_CACHE=0 disables disk cache, default 1 - EVMJIT_DUMP=1 dumps LLVM module to error output, default 0<commit_after>#include "ExecutionEngine.h"

#include <chrono>
#include <cstdlib>	// env options

#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#pragma warning(push)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#pragma warning(pop)
#pragma GCC diagnostic pop
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Host.h>

#include "Runtime.h"
#include "Compiler.h"
#include "Cache.h"

namespace dev
{
namespace eth
{
namespace jit
{

namespace
{
typedef ReturnCode(*EntryFuncPtr)(Runtime*);

ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime)
{
	// That function uses long jumps to handle "execeptions".
	// Do not create any non-POD objects here

	ReturnCode returnCode{};
	auto sj = setjmp(_runtime->getJmpBuf());
	if (sj == 0)
		returnCode = _mainFunc(_runtime);
	else
		returnCode = static_cast<ReturnCode>(sj);

	return returnCode;
}

std::string codeHash(code_iterator _begin, code_iterator _end)
{
	uint32_t hash = 0;
	std::for_each(_begin, _end, [&hash](decltype(*_begin) b)
	{
		hash += b;
		hash += (hash << 10);
		hash ^= (hash >> 6);
	});
	hash += (hash << 3);
	hash ^= (hash >> 11);
	hash += (hash << 15);
	return std::to_string(hash);
}

bool getEnvOption(char const* _name, bool _default)
{
	auto var = std::getenv(_name);
	if (!var)
		return _default;
	return std::strtol(var, nullptr, 10) != 0;
}

}

ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env)
{
	static std::unique_ptr<llvm::ExecutionEngine> ee;  // TODO: Use Managed Objects from LLVM?
	static auto debugDumpModule = getEnvOption("EVMJIT_DUMP", false);
	static auto objectCacheEnabled = getEnvOption("EVMJIT_CACHE", true);

	auto codeBegin = _data->code;
	auto codeEnd = codeBegin + _data->codeSize;
	assert(codeBegin || !codeEnd); //TODO: Is it good idea to execute empty code?
	auto mainFuncName = codeHash(codeBegin, codeEnd);
	EntryFuncPtr entryFuncPtr{};
	Runtime runtime(_data, _env);	// TODO: I don't know why but it must be created before getFunctionAddress() calls

	if (ee && (entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName)))
	{
	}
	else
	{
		auto objectCache = objectCacheEnabled ? Cache::getObjectCache() : nullptr;
		std::unique_ptr<llvm::Module> module;
		if (objectCache)
			module = Cache::getObject(mainFuncName);
		if (!module)
			module = Compiler({}).compile(codeBegin, codeEnd, mainFuncName);
		if (debugDumpModule)
			module->dump();
		if (!ee)
		{
			llvm::InitializeNativeTarget();
			llvm::InitializeNativeTargetAsmPrinter();

			llvm::EngineBuilder builder(module.get());
			builder.setEngineKind(llvm::EngineKind::JIT);
			builder.setUseMCJIT(true);
			std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
			builder.setMCJITMemoryManager(memoryManager.get());
			builder.setOptLevel(llvm::CodeGenOpt::None);

			auto triple = llvm::Triple(llvm::sys::getProcessTriple());
			if (triple.getOS() == llvm::Triple::OSType::Win32)
				triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);  // MCJIT does not support COFF format
			module->setTargetTriple(triple.str());

			ee.reset(builder.create());
			if (!ee)
				return ReturnCode::LLVMConfigError;

			module.release();         // Successfully created llvm::ExecutionEngine takes ownership of the module
			memoryManager.release();  // and memory manager

			if (objectCache)
				ee->setObjectCache(objectCache);
			entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
		}
		else
		{
			if (!entryFuncPtr)
			{
				ee->addModule(module.get());
				module.release();
				entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
			}
		}
	}
	assert(entryFuncPtr);

	auto executionStartTime = std::chrono::high_resolution_clock::now();

	auto returnCode = runEntryFunc(entryFuncPtr, &runtime);
	if (returnCode == ReturnCode::Return)
	{
		returnData = runtime.getReturnData();     // Save reference to return data
		std::swap(m_memory, runtime.getMemory()); // Take ownership of memory
	}

	auto executionEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms\n";

	return returnCode;
}

}
}
}
<|endoftext|>


<commit_before>#include "FileSelector.h"
#include "Renderer.h"
#include "Color.h"
#include "SDL.h"
#include "TextEditor.h"
#include "Label.h"
#include "MessageBox.h"
#include <cstdio>
#include <cstring>
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>

FileSelector::FileSelector(EditorState& editorState)
	: Editor(editorState), mSelectedItem(0), mCheckOverwrite(false)
{
	mNameField = new TextEditor(editorState);
	mNameField->setBuffer(mFilename, filenameSize);
	mNameField->setIsEditing(true);
	mNameField->setAlwaysShowCursor(true);
	mLabel = new Label(editorState);
	mLabel->setColor(Color(0, 0, 0));
	mLabel->setBackground(Color(255, 255, 255));
	mFilenameLabel = new Label(editorState);
	mFilenameLabel->setColor(Color(0, 0, 0));
	mFilenameLabel->setBackground(Color(255, 255, 255));
	mFilenameLabel->setText("FILENAME:");
	addChild(mLabel, 0, 0, 280, 8);
	addChild(mFilenameLabel, 0, 8, 8*9, 8);
	addChild(mNameField, 8*9, 8, 208, 8);
	strcpy(mFilename, "");
	strcpy(mFilter, "");
	strcpy(mTitle, "");
	setFocus(mNameField);
	mMessageBox = new MessageBox(editorState);
}

FileSelector::~FileSelector()
{
	delete mNameField;
	delete mLabel;
	delete mFilenameLabel;
	delete mMessageBox;
}

void FileSelector::selectItem(int index)
{
	mSelectedItem = index;

	if (mSelectedItem >= static_cast<int>(mItems.size()))
		mSelectedItem = static_cast<int>(mItems.size()) - 1;

	if (mSelectedItem < 0)
		mSelectedItem = 0;

	if (mItems.size() > 0)
	{
		strncpy(mFilename, mItems[mSelectedItem].path.c_str(), filenameSize);
		mNameField->setText(mFilename);
	}

	setDirty(true);
}

void FileSelector::setTitle(const char *title)
{
	strncpy(mTitle, title, titleSize);
	mLabel->setText(mTitle);
	setModal(NULL);
}

bool FileSelector::fileExists(const char *path)
{
	FILE *f = fopen(path, "r");

	if (!f)
		return false;

	fclose(f);

	return true;
}

void FileSelector::accept(bool isFinal)
{
	if (isFinal)
		mParent->onFileSelectorEvent(*this, true);
	else
	{
		if (FileItem::checkDirectory(getSelectedPath()))
		{
			setPath(getSelectedPath());
			return;
		}

		if (mCheckOverwrite && fileExists(getSelectedPath()))
		{
			mMessageBox->setTitle("Overwrite y/n");
			mMessageBox->setId(MessageBoxOverwrite);
			setModal(mMessageBox);
		}
		else
			mParent->onFileSelectorEvent(*this, true);
	}
}

void FileSelector::onMessageBoxEvent(const Editor& _messageBox, int code)
{
	const MessageBox& messageBox = reinterpret_cast<const MessageBox&>(_messageBox);

	if (messageBox.getId() == MessageBoxOverwrite)
	{
		if (code == 1)
		{
			accept(true);
		}
		else
		{
		}
	}

	setModal(NULL);
}

void FileSelector::reject(bool isFinal)
{
	mParent->onFileSelectorEvent(*this, false);
}

bool FileSelector::onEvent(SDL_Event& event)
{
	if (mModal)
		return mModal->onEvent(event);

	switch (event.type)
	{
		case SDL_KEYDOWN:
			if (event.key.keysym.sym == SDLK_ESCAPE)
			{
				reject(true);
				return true;
			}

			if (event.key.keysym.sym == SDLK_RETURN)
			{
				accept(false);
				return true;
			}

			switch (event.key.keysym.sym)
			{
				case SDLK_UP:
					selectItem(mSelectedItem - 1);
					return true;

				case SDLK_DOWN:
					selectItem(mSelectedItem + 1);
					return true;
			}

			break;
	}

	return mNameField->onEvent(event);
}

void FileSelector::renderItem(Renderer& renderer, const SDL_Rect& area, const FileItem& item, bool isSelected)
{
	Color color;

	if (isSelected)
		color = Color(255, 0, 0);

	renderer.clearRect(area, Color(0, 0, 0));

	if (item.isDirectory)
		renderer.renderTextV(area, color, "<%-25s>     DIR", item.path.c_str());
	else
		renderer.renderTextV(area, color, "%-25s %9d", item.path.c_str(), item.size);
}

void FileSelector::onDraw(Renderer& renderer, const SDL_Rect& area)
{
	if (shouldRedrawBackground())
	{
		renderer.clearRect(area, Color(0, 0, 0));

		/*SDL_Rect fieldArea = { area.x, area.y + 8, area.w, renderer.getFontHeight() };

		renderer.clearRect(fieldArea, Color(255, 0, 0));*/
	}

	int countVisible = (area.h - 8 - 8 - 8) / 8;
	int firstVisible = mSelectedItem - countVisible / 2;

	if (firstVisible < 0)
	{
		firstVisible = 0;
	}

	int lastVisible = firstVisible + countVisible;

	if (lastVisible >= mItems.size())
	{
		lastVisible = mItems.size() - 1;
		firstVisible = lastVisible - countVisible;
		if (firstVisible < 0)
		{
			firstVisible = 0;
		}
	}

	for (int row = firstVisible ; row <= lastVisible ; ++row)
	{
		SDL_Rect textArea = {area.x, (row - firstVisible) * 8 + area.y + 16, area.w, 8};
		renderItem(renderer, textArea, mItems[row], row == mSelectedItem);
	}
}

void FileSelector::setPath(const char *path)
{
	chdir(path);
	setDirty(true);
	populate();
}

void FileSelector::populate()
{
	invalidateParent();

	mSelectedItem = 0;
	mItems.clear();

	DIR *directory = opendir(".");

	if (!directory)
		return;

	while (true)
	{
		struct dirent *entry;
		struct stat statBuf;

		entry = readdir(directory);

		if (entry == NULL)
			break;

		//if (strlen(entry->d_name) > strlen(mFilter) && strcmp(entry->d_name + strlen(entry->d_name) - strlen(mFilter), mFilter) == 0)

		if (!stat(entry->d_name, &statBuf))
		{
			mItems.push_back(FileItem(statBuf.st_mode & S_IFDIR, entry->d_name, statBuf.st_size));
		}
	}

	closedir(directory);

	std::sort(mItems.begin(), mItems.end(), FileItem::directorySort);

	selectItem(0);
}

const char * FileSelector::getSelectedPath() const
{
	return mFilename;
}

const FileSelector::FileItem& FileSelector::getSelectedItem() const
{
	return mItems[mSelectedItem];
}

int FileSelector::getId() const
{
	return mId;
}

void FileSelector::setId(int id)
{
	mId = id;
}

void FileSelector::setFilter(const char *extension)
{
	strncpy(mFilter, extension, filterSize);
}

void FileSelector::setOverwriteCheck(bool state)
{
	mCheckOverwrite = state;
}

FileSelector::FileItem::FileItem(bool _isDirectory, const char *_path, int _size)
	: isDirectory(_isDirectory), path(_path), size(_size)
{
}

bool FileSelector::FileItem::directorySort(const FileSelector::FileItem& a, const FileSelector::FileItem& b)
{
	// Directories first

	if (a.isDirectory && !b.isDirectory)
		return true;

	// Then in alphabetical order

	if (strcmp(a.path.c_str(), b.path.c_str()) < 0)
		return true;

	return false;
}

bool FileSelector::FileItem::checkDirectory(const char *name)
{
	struct stat statBuf;

	if (!stat(name, &statBuf))
	{
		return (statBuf.st_mode & S_IFDIR) == S_IFDIR;
	}

	return false;
}

<commit_msg>Fixed file list sorting logic<commit_after>#include "FileSelector.h"
#include "Renderer.h"
#include "Color.h"
#include "SDL.h"
#include "TextEditor.h"
#include "Label.h"
#include "MessageBox.h"
#include <cstdio>
#include <cstring>
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>

FileSelector::FileSelector(EditorState& editorState)
	: Editor(editorState), mSelectedItem(0), mCheckOverwrite(false)
{
	mNameField = new TextEditor(editorState);
	mNameField->setBuffer(mFilename, filenameSize);
	mNameField->setIsEditing(true);
	mNameField->setAlwaysShowCursor(true);
	mLabel = new Label(editorState);
	mLabel->setColor(Color(0, 0, 0));
	mLabel->setBackground(Color(255, 255, 255));
	mFilenameLabel = new Label(editorState);
	mFilenameLabel->setColor(Color(0, 0, 0));
	mFilenameLabel->setBackground(Color(255, 255, 255));
	mFilenameLabel->setText("FILENAME:");
	addChild(mLabel, 0, 0, 280, 8);
	addChild(mFilenameLabel, 0, 8, 8*9, 8);
	addChild(mNameField, 8*9, 8, 208, 8);
	strcpy(mFilename, "");
	strcpy(mFilter, "");
	strcpy(mTitle, "");
	setFocus(mNameField);
	mMessageBox = new MessageBox(editorState);
}

FileSelector::~FileSelector()
{
	delete mNameField;
	delete mLabel;
	delete mFilenameLabel;
	delete mMessageBox;
}

void FileSelector::selectItem(int index)
{
	mSelectedItem = index;

	if (mSelectedItem >= static_cast<int>(mItems.size()))
		mSelectedItem = static_cast<int>(mItems.size()) - 1;

	if (mSelectedItem < 0)
		mSelectedItem = 0;

	if (mItems.size() > 0)
	{
		strncpy(mFilename, mItems[mSelectedItem].path.c_str(), filenameSize);
		mNameField->setText(mFilename);
	}

	setDirty(true);
}

void FileSelector::setTitle(const char *title)
{
	strncpy(mTitle, title, titleSize);
	mLabel->setText(mTitle);
	setModal(NULL);
}

bool FileSelector::fileExists(const char *path)
{
	FILE *f = fopen(path, "r");

	if (!f)
		return false;

	fclose(f);

	return true;
}

void FileSelector::accept(bool isFinal)
{
	if (isFinal)
		mParent->onFileSelectorEvent(*this, true);
	else
	{
		if (FileItem::checkDirectory(getSelectedPath()))
		{
			setPath(getSelectedPath());
			return;
		}

		if (mCheckOverwrite && fileExists(getSelectedPath()))
		{
			mMessageBox->setTitle("Overwrite y/n");
			mMessageBox->setId(MessageBoxOverwrite);
			setModal(mMessageBox);
		}
		else
			mParent->onFileSelectorEvent(*this, true);
	}
}

void FileSelector::onMessageBoxEvent(const Editor& _messageBox, int code)
{
	const MessageBox& messageBox = reinterpret_cast<const MessageBox&>(_messageBox);

	if (messageBox.getId() == MessageBoxOverwrite)
	{
		if (code == 1)
		{
			accept(true);
		}
		else
		{
		}
	}

	setModal(NULL);
}

void FileSelector::reject(bool isFinal)
{
	mParent->onFileSelectorEvent(*this, false);
}

bool FileSelector::onEvent(SDL_Event& event)
{
	if (mModal)
		return mModal->onEvent(event);

	switch (event.type)
	{
		case SDL_KEYDOWN:
			if (event.key.keysym.sym == SDLK_ESCAPE)
			{
				reject(true);
				return true;
			}

			if (event.key.keysym.sym == SDLK_RETURN)
			{
				accept(false);
				return true;
			}

			switch (event.key.keysym.sym)
			{
				case SDLK_UP:
					selectItem(mSelectedItem - 1);
					return true;

				case SDLK_DOWN:
					selectItem(mSelectedItem + 1);
					return true;
			}

			break;
	}

	return mNameField->onEvent(event);
}

void FileSelector::renderItem(Renderer& renderer, const SDL_Rect& area, const FileItem& item, bool isSelected)
{
	Color color;

	if (isSelected)
		color = Color(255, 0, 0);

	renderer.clearRect(area, Color(0, 0, 0));

	if (item.isDirectory)
		renderer.renderTextV(area, color, "<%-25s>     DIR", item.path.c_str());
	else
		renderer.renderTextV(area, color, "%-25s %9d", item.path.c_str(), item.size);
}

void FileSelector::onDraw(Renderer& renderer, const SDL_Rect& area)
{
	if (shouldRedrawBackground())
	{
		renderer.clearRect(area, Color(0, 0, 0));

		/*SDL_Rect fieldArea = { area.x, area.y + 8, area.w, renderer.getFontHeight() };

		renderer.clearRect(fieldArea, Color(255, 0, 0));*/
	}

	int countVisible = (area.h - 8 - 8 - 8) / 8;
	int firstVisible = mSelectedItem - countVisible / 2;

	if (firstVisible < 0)
	{
		firstVisible = 0;
	}

	int lastVisible = firstVisible + countVisible;

	if (lastVisible >= mItems.size())
	{
		lastVisible = mItems.size() - 1;
		firstVisible = lastVisible - countVisible;
		if (firstVisible < 0)
		{
			firstVisible = 0;
		}
	}

	for (int row = firstVisible ; row <= lastVisible ; ++row)
	{
		SDL_Rect textArea = {area.x, (row - firstVisible) * 8 + area.y + 16, area.w, 8};
		renderItem(renderer, textArea, mItems[row], row == mSelectedItem);
	}
}

void FileSelector::setPath(const char *path)
{
	chdir(path);
	setDirty(true);
	populate();
}

void FileSelector::populate()
{
	invalidateParent();

	mSelectedItem = 0;
	mItems.clear();

	DIR *directory = opendir(".");

	if (!directory)
		return;

	while (true)
	{
		struct dirent *entry;
		struct stat statBuf;

		entry = readdir(directory);

		if (entry == NULL)
			break;

		//if (strlen(entry->d_name) > strlen(mFilter) && strcmp(entry->d_name + strlen(entry->d_name) - strlen(mFilter), mFilter) == 0)

		if (!stat(entry->d_name, &statBuf))
		{
			mItems.push_back(FileItem(statBuf.st_mode & S_IFDIR, entry->d_name, statBuf.st_size));
		}
	}

	closedir(directory);

	std::sort(mItems.begin(), mItems.end(), FileItem::directorySort);

	selectItem(0);
}

const char * FileSelector::getSelectedPath() const
{
	return mFilename;
}

const FileSelector::FileItem& FileSelector::getSelectedItem() const
{
	return mItems[mSelectedItem];
}

int FileSelector::getId() const
{
	return mId;
}

void FileSelector::setId(int id)
{
	mId = id;
}

void FileSelector::setFilter(const char *extension)
{
	strncpy(mFilter, extension, filterSize);
}

void FileSelector::setOverwriteCheck(bool state)
{
	mCheckOverwrite = state;
}

FileSelector::FileItem::FileItem(bool _isDirectory, const char *_path, int _size)
	: isDirectory(_isDirectory), path(_path), size(_size)
{
}

bool FileSelector::FileItem::directorySort(const FileSelector::FileItem& a, const FileSelector::FileItem& b)
{
	// Directories first

	if (a.isDirectory && !b.isDirectory)
		return true;

	// Then in alphabetical order if BOTH a & b are either directories or files

	if (a.isDirectory == b.isDirectory && strcmp(a.path.c_str(), b.path.c_str()) < 0)
		return true;

	return false;
}

bool FileSelector::FileItem::checkDirectory(const char *name)
{
	struct stat statBuf;

	if (!stat(name, &statBuf))
	{
		return (statBuf.st_mode & S_IFDIR) == S_IFDIR;
	}

	return false;
}

<|endoftext|>


<commit_before>
/* FmtTextDecor.cpp
 *
 * Copyright (C) 2013 Michael Imamura
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

#include "StdAfx.h"

#include "utf8/utf8.h"

#include "Exception.h"
#include "ResStr.h"

#include "FmtTextDecor.h"

namespace AISDL {

namespace {
	const SDL_Color FMT_COLORS[] = {
		{ 0x00, 0x00, 0x00, 0xff },  // 0   ^0
		{ 0xff, 0x00, 0x00, 0xff },  // 1   ^1
		{ 0x00, 0xff, 0x00, 0xff },  // 2   ^2
		{ 0xff, 0xff, 0x00, 0xff },  // 3   ^3
		{ 0x00, 0x00, 0xff, 0xff },  // 4   ^4
		{ 0x00, 0xff, 0xff, 0xff },  // 5   ^5
		{ 0xff, 0x00, 0xff, 0xff },  // 6   ^6
		{ 0xff, 0xff, 0xff, 0xff },  // 7   ^7  default white
		{ 0xff, 0x7f, 0x00, 0xff },  // 8   ^8
		{ 0x7f, 0x7f, 0x7f, 0xff },  // 9   ^9
		{ 0xbf, 0xbf, 0xbf, 0xff },  // 10  ^:
		{ 0xbf, 0xbf, 0xbf, 0xff },  // 11  ^;
		{ 0x00, 0x7f, 0x00, 0xff },  // 12  ^<
		{ 0x7f, 0x7f, 0x00, 0xff },  // 13  ^=
		{ 0x00, 0x00, 0x7f, 0xff },  // 14  ^>
		{ 0x7f, 0x00, 0x00, 0xff },  // 15  ^?
		{ 0x7f, 0x3f, 0x00, 0xff },  // 16  ^@
		{ 0xff, 0x99, 0x19, 0xff },  // 17  ^a
		{ 0x00, 0x7f, 0x7f, 0xff },  // 18  ^b
		{ 0x7f, 0x00, 0x7f, 0xff },  // 19  ^c
		{ 0x00, 0x7f, 0xff, 0xff },  // 20  ^d
		{ 0x7f, 0x00, 0xff, 0xff },  // 21  ^e
		{ 0x33, 0x99, 0xcc, 0xff },  // 22  ^f  external link
		{ 0xcc, 0xff, 0xcc, 0xff },  // 23  ^g
		{ 0x00, 0x66, 0x33, 0xff },  // 24  ^h
		{ 0xff, 0x00, 0x33, 0xff },  // 25  ^i
		{ 0xb2, 0x19, 0x19, 0xff },  // 26  ^j
		{ 0x99, 0x33, 0x00, 0xff },  // 27  ^k
		{ 0xcc, 0x99, 0x33, 0xff },  // 28  ^l
		{ 0x99, 0x99, 0x33, 0xff },  // 29  ^m
		{ 0xff, 0xff, 0xbf, 0xff },  // 30  ^n
		{ 0xff, 0xff, 0x7f, 0xff },  // 31  ^o
	};
}

/**
 * Constructor when using static string.
 * @param display The target display.
 * @param font The font to use to render the text.
 * @param text The text itself.
 * @param width The maximum width of the text area (currently unused).
 */
FmtTextDecor::FmtTextDecor(Display &display, std::shared_ptr<Ttf> font,
	const std::string &s, int width) :
	display(display), font(std::move(font)), s(s),
	width(width)
{
	Reformat();
}

/**
 * Constructor when using resource string.
 * @param display The target display.
 * @param font The font to use to render the text.
 * @param text The text itself.
 * @param width The maximum width of the text area (currently unused).
 */
FmtTextDecor::FmtTextDecor(Display &display, std::shared_ptr<Ttf> font,
	std::shared_ptr<ResStr> text, int width) :
	display(display), font(std::move(font)), text(std::move(text)),
	width(width)
{
	Reformat();

	// Automatically trigger Reformat() when the text changes.
	this->text->SetOnReload([&]() {
		Reformat();
	});
}

/**
 * Process the text and generate the list of formatted renderables.
 */
void FmtTextDecor::Reformat()
{
	int lineHeight = TTF_FontLineSkip(**font);
	if (text) s = **text;
	int x = 0, y = 0;
	int fmtColor = 7;

	rends.clear();
	rends.reserve(s.length());

	for (auto iter = s.cbegin(), iend = s.cend(); iter != iend; ) {
		uint32_t ch32 = utf8::next(iter, iend);

		// Only handle characters which we have included in the type case.
		if (ch32 > font->glyphs.size()) {
			SDL_Log("Unrenderable code point: %d", ch32);
			continue;
		}
		Uint16 ch = static_cast<Uint16>(ch32);

		switch (ch) {
			case '\n':  // Newlines.
				x = 0;
				y += lineHeight;
				continue;

			case '^':  // Color codes.
				if (iter == iend) {
					return;
				}
				else {
					uint32_t idx = utf8::next(iter, iend);

					// Allow "^^" as an escape sequence for "^".
					if (idx == '^') break;

					fmtColor = (idx + 16) & 31;
				}
				continue;

			case '\r':  // Ignore CRs.
				continue;
		}

		const Ttf::Glyph &glyph = font->glyphs[ch];
		if (!glyph.avail) continue;

		rends.push_back(Rend(&glyph, x, y, fmtColor));

		x += glyph.layoutW;
	}
}

/**
 * Render the text at the specified coordinates.
 * @param x The X coordinate.
 * @param y The Y coordinate.
 * @param alpha The opacity (0 is fully transparent, 255 is fully opaque).
 */
void FmtTextDecor::Render(int x, int y, int alpha)
{
	// If completely transparent, do nothing.
	if (alpha == 0) return;

	int fmtColor = 7;

	SDL_SetTextureAlphaMod(font->typeCase, alpha);

	// Reset default color to white.
	SDL_SetTextureColorMod(font->typeCase, 0xff, 0xff, 0xff);

	for (auto iter = rends.cbegin(); iter != rends.cend(); ++iter) {
		if (fmtColor != iter->fmtColor) {
			fmtColor = iter->fmtColor;
			const SDL_Color &color = FMT_COLORS[fmtColor];
			SDL_SetTextureColorMod(font->typeCase, color.r, color.g, color.b);
		}

		SDL_Rect destRect = {
			iter->x + x,
			iter->y + y,
			iter->glyph->texRect.w,
			iter->glyph->texRect.h,
		};
		if (SDL_RenderCopy(display.renderer, font->typeCase,
			&iter->glyph->texRect, &destRect) < 0)
		{
			throw Exception(SDL_GetError());
		}
	}
}

}
<commit_msg>Remove unnecessary cast.<commit_after>
/* FmtTextDecor.cpp
 *
 * Copyright (C) 2013 Michael Imamura
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

#include "StdAfx.h"

#include "utf8/utf8.h"

#include "Exception.h"
#include "ResStr.h"

#include "FmtTextDecor.h"

namespace AISDL {

namespace {
	const SDL_Color FMT_COLORS[] = {
		{ 0x00, 0x00, 0x00, 0xff },  // 0   ^0
		{ 0xff, 0x00, 0x00, 0xff },  // 1   ^1
		{ 0x00, 0xff, 0x00, 0xff },  // 2   ^2
		{ 0xff, 0xff, 0x00, 0xff },  // 3   ^3
		{ 0x00, 0x00, 0xff, 0xff },  // 4   ^4
		{ 0x00, 0xff, 0xff, 0xff },  // 5   ^5
		{ 0xff, 0x00, 0xff, 0xff },  // 6   ^6
		{ 0xff, 0xff, 0xff, 0xff },  // 7   ^7  default white
		{ 0xff, 0x7f, 0x00, 0xff },  // 8   ^8
		{ 0x7f, 0x7f, 0x7f, 0xff },  // 9   ^9
		{ 0xbf, 0xbf, 0xbf, 0xff },  // 10  ^:
		{ 0xbf, 0xbf, 0xbf, 0xff },  // 11  ^;
		{ 0x00, 0x7f, 0x00, 0xff },  // 12  ^<
		{ 0x7f, 0x7f, 0x00, 0xff },  // 13  ^=
		{ 0x00, 0x00, 0x7f, 0xff },  // 14  ^>
		{ 0x7f, 0x00, 0x00, 0xff },  // 15  ^?
		{ 0x7f, 0x3f, 0x00, 0xff },  // 16  ^@
		{ 0xff, 0x99, 0x19, 0xff },  // 17  ^a
		{ 0x00, 0x7f, 0x7f, 0xff },  // 18  ^b
		{ 0x7f, 0x00, 0x7f, 0xff },  // 19  ^c
		{ 0x00, 0x7f, 0xff, 0xff },  // 20  ^d
		{ 0x7f, 0x00, 0xff, 0xff },  // 21  ^e
		{ 0x33, 0x99, 0xcc, 0xff },  // 22  ^f  external link
		{ 0xcc, 0xff, 0xcc, 0xff },  // 23  ^g
		{ 0x00, 0x66, 0x33, 0xff },  // 24  ^h
		{ 0xff, 0x00, 0x33, 0xff },  // 25  ^i
		{ 0xb2, 0x19, 0x19, 0xff },  // 26  ^j
		{ 0x99, 0x33, 0x00, 0xff },  // 27  ^k
		{ 0xcc, 0x99, 0x33, 0xff },  // 28  ^l
		{ 0x99, 0x99, 0x33, 0xff },  // 29  ^m
		{ 0xff, 0xff, 0xbf, 0xff },  // 30  ^n
		{ 0xff, 0xff, 0x7f, 0xff },  // 31  ^o
	};
}

/**
 * Constructor when using static string.
 * @param display The target display.
 * @param font The font to use to render the text.
 * @param text The text itself.
 * @param width The maximum width of the text area (currently unused).
 */
FmtTextDecor::FmtTextDecor(Display &display, std::shared_ptr<Ttf> font,
	const std::string &s, int width) :
	display(display), font(std::move(font)), s(s),
	width(width)
{
	Reformat();
}

/**
 * Constructor when using resource string.
 * @param display The target display.
 * @param font The font to use to render the text.
 * @param text The text itself.
 * @param width The maximum width of the text area (currently unused).
 */
FmtTextDecor::FmtTextDecor(Display &display, std::shared_ptr<Ttf> font,
	std::shared_ptr<ResStr> text, int width) :
	display(display), font(std::move(font)), text(std::move(text)),
	width(width)
{
	Reformat();

	// Automatically trigger Reformat() when the text changes.
	this->text->SetOnReload([&]() {
		Reformat();
	});
}

/**
 * Process the text and generate the list of formatted renderables.
 */
void FmtTextDecor::Reformat()
{
	int lineHeight = TTF_FontLineSkip(**font);
	if (text) s = **text;
	int x = 0, y = 0;
	int fmtColor = 7;

	rends.clear();
	rends.reserve(s.length());

	for (auto iter = s.cbegin(), iend = s.cend(); iter != iend; ) {
		uint32_t ch = utf8::next(iter, iend);

		// Only handle characters which we have included in the type case.
		if (ch > font->glyphs.size()) {
			SDL_Log("Unrenderable code point: %d", ch);
			continue;
		}

		switch (ch) {
			case '\n':  // Newlines.
				x = 0;
				y += lineHeight;
				continue;

			case '^':  // Color codes.
				if (iter == iend) {
					return;
				}
				else {
					uint32_t idx = utf8::next(iter, iend);

					// Allow "^^" as an escape sequence for "^".
					if (idx == '^') break;

					fmtColor = (idx + 16) & 31;
				}
				continue;

			case '\r':  // Ignore CRs.
				continue;
		}

		const Ttf::Glyph &glyph = font->glyphs[ch];
		if (!glyph.avail) continue;

		rends.push_back(Rend(&glyph, x, y, fmtColor));

		x += glyph.layoutW;
	}

	SDL_Log("%d elements to render.", rends.size());
}

/**
 * Render the text at the specified coordinates.
 * @param x The X coordinate.
 * @param y The Y coordinate.
 * @param alpha The opacity (0 is fully transparent, 255 is fully opaque).
 */
void FmtTextDecor::Render(int x, int y, int alpha)
{
	// If completely transparent, do nothing.
	if (alpha == 0) return;

	int fmtColor = 7;

	SDL_SetTextureAlphaMod(font->typeCase, alpha);

	// Reset default color to white.
	SDL_SetTextureColorMod(font->typeCase, 0xff, 0xff, 0xff);

	for (auto iter = rends.cbegin(); iter != rends.cend(); ++iter) {
		if (fmtColor != iter->fmtColor) {
			fmtColor = iter->fmtColor;
			const SDL_Color &color = FMT_COLORS[fmtColor];
			SDL_SetTextureColorMod(font->typeCase, color.r, color.g, color.b);
		}

		SDL_Rect destRect = {
			iter->x + x,
			iter->y + y,
			iter->glyph->texRect.w,
			iter->glyph->texRect.h,
		};
		if (SDL_RenderCopy(display.renderer, font->typeCase,
			&iter->glyph->texRect, &destRect) < 0)
		{
			throw Exception(SDL_GetError());
		}
	}
}

}
<|endoftext|>


<commit_before>#include <cassert>
#include <iostream>
#include <iomanip>

#include "sixtracklib/testlib.h"
#include "sixtracklib/sixtracklib.hpp"

int main( int argc, char* argv[] )
{
    namespace st     = sixtrack;
    using buf_size_t = st::Buffer::size_type;

    buf_size_t const NUM_BEAM_ELEMENTS = ( buf_size_t)25u;
    buf_size_t const DATA_CAPACITY     = ( buf_size_t )( 1u << 20u );

    st::Buffer eb( DATA_CAPACITY );

    buf_size_t ii = buf_size_t{ 0 };
    double length = double{ 10.0L };

    /* add a new drift to the eb buffer using the st::Drift_new function ->
     * the resulting drift will have default values, i.e. length == 0 */

    st::Drift* drift = st::Drift_new( eb );
    assert( drift  != nullptr );

    drift->setLength( length );
    length += double{ 1.0L };
    ++ii;

    /* add a new drift to the eb buffer using the st::Drift_add function ->
     * the resulting drift will already have the provided length */

    drift = st::Drift_add( eb, length );
    assert( drift != 0 );

    length += double{ 1.0L };
    ++ii;

    /* add a new drift to the eb buffer which is an exact copy of an already
     * existing st::Drift -> the two instances will have the exact same length */

    st::Drift* copy_of_drift = st::Drift_add_copy( eb, *drift );

    assert( copy_of_drift != 0 );
    assert( copy_of_drift != drift  );
    assert( memcmp( copy_of_drift, drift, sizeof( st_Drift ) ) == 0 );

    length += ( double )1.0L;
    ++ii;

    /* Using C++, we can add beam elements and similar Objects also via the
     * buffer using a template interface. The calls below are equivalent to the
     * free-standing calls above: */

    drift = eb.createNew< st::Drift >();
    assert( drift != nullptr );
    drift->setLength( length );

    length += ( double )1.0L;
    ++ii;

    for( ; ii < NUM_BEAM_ELEMENTS ; ++ii, length += ( double )1.0L )
    {
        drift = eb.add< st::Drift >( length );
        assert( drift != 0 );
    }

    /* print out all existing beam elements using the convenience
     * st_BeamElement_print() function from testlib */

    for( ii = 0u ; ii < NUM_BEAM_ELEMENTS ; ++ii )
    {
        /* get the ii-th beam element object from the eb buffer */
        st::Buffer::object_t* be_object = eb[ ii ];
        assert( be_object != 0 );

        /* We are about to modify the length of each drift ->
         * print the current drift before we change the length to have
         * something to compare against: */

        std::cout << "before changing the length of beam belement "
                  << ii << "\r\n";

        /* Print the be with the generic print helper function */
        ::st_BeamElement_print( be_object );

        /* Try to access the stored drift: */
        st::Drift* stored_drift = st::Drift::FromBuffer( eb, ii );

        /* if the object with the index ii would not have been a drift,
         * the returned pointer would have been a nullptr: */

        assert( stored_drift != nullptr);

        double const new_length = stored_drift->getLength() + double{ 1L };
        stored_drift->setLength( new_length );

        /* Print the be with the generic print helper function after the change */
        std::cout << "after  changing the length of beam belement "
                  << ii << "\r\n";

        st_BeamElement_print( be_object );

        std::cout << "\r\n";
    }

    std::cout << std::endl;

    return 0;
}

/* end:  examples/c99/simple_drift_buffer.c */
<commit_msg>examples/c99: fix problems in C++ example preventing compilation under release mode due to -Werror and unused variables<commit_after>#include <cassert>
#include <iostream>
#include <iomanip>

#include "sixtracklib/testlib.h"
#include "sixtracklib/sixtracklib.hpp"

int main( int argc, char* argv[] )
{
    namespace st     = sixtrack;
    using buf_size_t = st::Buffer::size_type;

    buf_size_t const NUM_BEAM_ELEMENTS = ( buf_size_t)25u;
    buf_size_t const DATA_CAPACITY     = ( buf_size_t )( 1u << 20u );

    st::Buffer eb( DATA_CAPACITY );

    buf_size_t ii = buf_size_t{ 0 };
    double length = double{ 10.0L };

    /* add a new drift to the eb buffer using the st::Drift_new function ->
     * the resulting drift will have default values, i.e. length == 0 */

    st::Drift* drift = st::Drift_new( eb );
    assert( drift  != nullptr );

    drift->setLength( length );
    length += double{ 1.0L };
    ++ii;

    /* add a new drift to the eb buffer using the st::Drift_add function ->
     * the resulting drift will already have the provided length */

    drift = st::Drift_add( eb, length );
    assert( drift != 0 );

    length += double{ 1.0L };
    ++ii;

    /* add a new drift to the eb buffer which is an exact copy of an already
     * existing st::Drift -> the two instances will have the exact same length */

    st::Drift* copy_of_drift = st::Drift_add_copy( eb, *drift );

    assert( copy_of_drift != 0 );
    assert( copy_of_drift != drift  );
    assert( memcmp( copy_of_drift, drift, sizeof( st_Drift ) ) == 0 );

    #if defined( NDEBUG )
    ( void )copy_of_drift;
    #endif /* defiend( NDEBUG ) */

    length += ( double )1.0L;
    ++ii;

    /* Using C++, we can add beam elements and similar Objects also via the
     * buffer using a template interface. The calls below are equivalent to the
     * free-standing calls above: */

    drift = eb.createNew< st::Drift >();
    assert( drift != nullptr );
    drift->setLength( length );

    length += ( double )1.0L;
    ++ii;

    for( ; ii < NUM_BEAM_ELEMENTS ; ++ii, length += ( double )1.0L )
    {
        drift = eb.add< st::Drift >( length );
        assert( drift != 0 );
    }

    /* print out all existing beam elements using the convenience
     * st_BeamElement_print() function from testlib */

    for( ii = 0u ; ii < NUM_BEAM_ELEMENTS ; ++ii )
    {
        /* get the ii-th beam element object from the eb buffer */
        st::Buffer::object_t* be_object = eb[ ii ];
        assert( be_object != 0 );

        /* We are about to modify the length of each drift ->
         * print the current drift before we change the length to have
         * something to compare against: */

        std::cout << "before changing the length of beam belement "
                  << ii << "\r\n";

        /* Print the be with the generic print helper function */
        ::st_BeamElement_print( be_object );

        /* Try to access the stored drift: */
        st::Drift* stored_drift = st::Drift::FromBuffer( eb, ii );

        /* if the object with the index ii would not have been a drift,
         * the returned pointer would have been a nullptr: */

        assert( stored_drift != nullptr);

        double const new_length = stored_drift->getLength() + double{ 1L };
        stored_drift->setLength( new_length );

        /* Print the be with the generic print helper function after the change */
        std::cout << "after  changing the length of beam belement "
                  << ii << "\r\n";

        st_BeamElement_print( be_object );

        std::cout << "\r\n";
    }

    std::cout << std::endl;

    return 0;
}

/* end:  examples/c99/simple_drift_buffer.c */
<|endoftext|>


<commit_before>/*
 * SSL and TLS filter.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "ssl_init.hxx"

#include <inline/compiler.h>

#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include <openssl/engine.h>
#include <openssl/err.h>

#include <mutex>

#include <pthread.h>

static std::mutex *ssl_mutexes;

static void
locking_function(int mode, int n,
                 gcc_unused const char *file, gcc_unused int line)
{
    if (mode & CRYPTO_LOCK)
        ssl_mutexes[n].lock();
    else
        ssl_mutexes[n].unlock();
}

static unsigned long
id_function()
{
    return pthread_self();
}

void
ssl_global_init()
{
    SSL_load_error_strings();
    SSL_library_init();
    ENGINE_load_builtin_engines();

    /* initialise OpenSSL multi-threading; this is needed because the
       SSL_CTX object is shared among all threads, which need to
       modify it in a safe manner */

    ssl_mutexes = new std::mutex[CRYPTO_num_locks()];

    CRYPTO_set_locking_callback(locking_function);
    CRYPTO_set_id_callback(id_function);
}

void
ssl_global_deinit()
{
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();

#if OPENSSL_VERSION_NUMBER >= 0x10000000L
    ERR_remove_thread_state(nullptr);
#else
    ERR_remove_state(0);
#endif

    ERR_free_strings();

    CRYPTO_set_id_callback(nullptr);
    CRYPTO_set_locking_callback(nullptr);

    delete[] ssl_mutexes;
}

void
ssl_thread_deinit()
{
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
    ERR_remove_thread_state(nullptr);
#else
    ERR_remove_state(0);
#endif
}
<commit_msg>ssl/init: call ENGINE_cleanup() in _deinit()<commit_after>/*
 * SSL and TLS filter.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "ssl_init.hxx"

#include <inline/compiler.h>

#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include <openssl/engine.h>
#include <openssl/err.h>

#include <mutex>

#include <pthread.h>

static std::mutex *ssl_mutexes;

static void
locking_function(int mode, int n,
                 gcc_unused const char *file, gcc_unused int line)
{
    if (mode & CRYPTO_LOCK)
        ssl_mutexes[n].lock();
    else
        ssl_mutexes[n].unlock();
}

static unsigned long
id_function()
{
    return pthread_self();
}

void
ssl_global_init()
{
    SSL_load_error_strings();
    SSL_library_init();
    ENGINE_load_builtin_engines();

    /* initialise OpenSSL multi-threading; this is needed because the
       SSL_CTX object is shared among all threads, which need to
       modify it in a safe manner */

    ssl_mutexes = new std::mutex[CRYPTO_num_locks()];

    CRYPTO_set_locking_callback(locking_function);
    CRYPTO_set_id_callback(id_function);
}

void
ssl_global_deinit()
{
    ENGINE_cleanup();
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();

#if OPENSSL_VERSION_NUMBER >= 0x10000000L
    ERR_remove_thread_state(nullptr);
#else
    ERR_remove_state(0);
#endif

    ERR_free_strings();

    CRYPTO_set_id_callback(nullptr);
    CRYPTO_set_locking_callback(nullptr);

    delete[] ssl_mutexes;
}

void
ssl_thread_deinit()
{
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
    ERR_remove_thread_state(nullptr);
#else
    ERR_remove_state(0);
#endif
}
<|endoftext|>