<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attrlist.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: rt $ $Date: 2008-03-12 10:28:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#include <vector>

#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif
#include <rtl/uuid.h>
#include <rtl/memory.h>

#if OSL_DEBUG_LEVEL == 0
#  ifndef NDEBUG
#    define NDEBUG
#  endif
#endif
#include <assert.h>

#include <xmloff/attrlist.hxx>

using ::rtl::OUString;

using namespace ::osl;
using namespace ::com::sun::star;
using namespace ::xmloff::token;

struct SvXMLTagAttribute_Impl
{
    SvXMLTagAttribute_Impl(){}
    SvXMLTagAttribute_Impl( const OUString &rName,
                         const OUString &rValue )
        : sName(rName),
        sValue(rValue)
    {
    }

    SvXMLTagAttribute_Impl( const SvXMLTagAttribute_Impl& r ) :
        sName(r.sName),
        sValue(r.sValue)
    {
    }

    OUString sName;
    OUString sValue;
};

struct SvXMLAttributeList_Impl
{
    SvXMLAttributeList_Impl()
    {
        // performance improvement during adding
        vecAttribute.reserve(20);
    }

    SvXMLAttributeList_Impl( const SvXMLAttributeList_Impl& r ) :
            vecAttribute( r.vecAttribute )
    {
    }

    ::std::vector<struct SvXMLTagAttribute_Impl> vecAttribute;
    typedef ::std::vector<struct SvXMLTagAttribute_Impl>::size_type size_type;
};

sal_Int16 SAL_CALL SvXMLAttributeList::getLength(void) throw( ::com::sun::star::uno::RuntimeException )
{
    return sal::static_int_cast< sal_Int16 >(m_pImpl->vecAttribute.size());
}

SvXMLAttributeList::SvXMLAttributeList( const SvXMLAttributeList &r ) :
    cppu::WeakImplHelper3<com::sun::star::xml::sax::XAttributeList, com::sun::star::util::XCloneable, com::sun::star::lang::XUnoTunnel>(r),
    m_pImpl( new SvXMLAttributeList_Impl( *r.m_pImpl ) )
{
}

SvXMLAttributeList::SvXMLAttributeList( const uno::Reference<
        xml::sax::XAttributeList> & rAttrList )
    : sType( GetXMLToken(XML_CDATA) )
{
    m_pImpl = new SvXMLAttributeList_Impl;

    SvXMLAttributeList* pImpl =
        SvXMLAttributeList::getImplementation( rAttrList );

    if( pImpl )
        *m_pImpl = *(pImpl->m_pImpl);
    else
        AppendAttributeList( rAttrList );
}

OUString SAL_CALL SvXMLAttributeList::getNameByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() ) {
        return m_pImpl->vecAttribute[i].sName;
    }
    return OUString();
}

OUString SAL_CALL SvXMLAttributeList::getTypeByIndex(sal_Int16) throw( ::com::sun::star::uno::RuntimeException )
{
    return sType;
}

OUString SAL_CALL  SvXMLAttributeList::getValueByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() ) {
        return m_pImpl->vecAttribute[i].sValue;
    }
    return OUString();

}

OUString SAL_CALL SvXMLAttributeList::getTypeByName( const OUString& ) throw( ::com::sun::star::uno::RuntimeException )
{
    return sType;
}

OUString SAL_CALL SvXMLAttributeList::getValueByName(const OUString& sName) throw( ::com::sun::star::uno::RuntimeException )
{
    ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin();

    for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) {
        if( (*ii).sName == sName ) {
            return (*ii).sValue;
        }
    }
    return OUString();
}

uno::Reference< ::com::sun::star::util::XCloneable >  SvXMLAttributeList::createClone() throw( ::com::sun::star::uno::RuntimeException )
{
    uno::Reference< ::com::sun::star::util::XCloneable >  r = new SvXMLAttributeList( *this );
    return r;
}

SvXMLAttributeList::SvXMLAttributeList()
    : sType( GetXMLToken(XML_CDATA) )
{
    m_pImpl = new SvXMLAttributeList_Impl;
}

SvXMLAttributeList::~SvXMLAttributeList()
{
    delete m_pImpl;
}

void SvXMLAttributeList::AddAttribute(  const OUString &sName ,
                                        const OUString &sValue )
{
    m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) );
}

void SvXMLAttributeList::Clear()
{
    m_pImpl->vecAttribute.clear();

    assert( ! getLength() );
}

void SvXMLAttributeList::RemoveAttribute( const OUString sName )
{
    ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin();

    for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) {
        if( (*ii).sName == sName ) {
            m_pImpl->vecAttribute.erase( ii );
            break;
        }
    }
}

void SvXMLAttributeList::SetAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList >  &r )
{
    Clear();
    AppendAttributeList( r );
}

void SvXMLAttributeList::AppendAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList >  &r )
{
    assert( r.is() );

    sal_Int16 nMax = r->getLength();
    SvXMLAttributeList_Impl::size_type nTotalSize =
        m_pImpl->vecAttribute.size() + nMax;
    m_pImpl->vecAttribute.reserve( nTotalSize );

    for( sal_Int16 i = 0 ; i < nMax ; ++i ) {
        m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl(
            r->getNameByIndex( i ) ,
            r->getValueByIndex( i )));
    }

    assert( nTotalSize == (SvXMLAttributeList_Impl::size_type)getLength());
}

void SvXMLAttributeList::SetValueByIndex( sal_Int16 i,
        const ::rtl::OUString& rValue )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() )
    {
        m_pImpl->vecAttribute[i].sValue = rValue;
    }
}

void SvXMLAttributeList::RemoveAttributeByIndex( sal_Int16 i )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() )
        m_pImpl->vecAttribute.erase( m_pImpl->vecAttribute.begin() + i );
}

void SvXMLAttributeList::RenameAttributeByIndex( sal_Int16 i,
                                                 const OUString& rNewName )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() )
    {
        m_pImpl->vecAttribute[i].sName = rNewName;
    }
}

sal_Int16 SvXMLAttributeList::GetIndexByName( const OUString& rName ) const
{
    ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii =
        m_pImpl->vecAttribute.begin();

    for( sal_Int16 nIndex=0; ii!=m_pImpl->vecAttribute.end(); ++ii, ++nIndex )
    {
        if( (*ii).sName == rName )
        {
            return nIndex;
        }
    }
    return -1;
}

// XUnoTunnel & co
const uno::Sequence< sal_Int8 > & SvXMLAttributeList::getUnoTunnelId() throw()
{
    static uno::Sequence< sal_Int8 > * pSeq = 0;
    if( !pSeq )
    {
        Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
        if( !pSeq )
        {
            static uno::Sequence< sal_Int8 > aSeq( 16 );
            rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
            pSeq = &aSeq;
        }
    }
    return *pSeq;
}

SvXMLAttributeList* SvXMLAttributeList::getImplementation( uno::Reference< uno::XInterface > xInt ) throw()
{
    uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY );
    if( xUT.is() )
    {
        return
            reinterpret_cast<SvXMLAttributeList*>(
                sal::static_int_cast<sal_IntPtr>(
                    xUT->getSomething( SvXMLAttributeList::getUnoTunnelId())));
    }
    else
        return NULL;
}

// XUnoTunnel
sal_Int64 SAL_CALL SvXMLAttributeList::getSomething( const uno::Sequence< sal_Int8 >& rId )
    throw( uno::RuntimeException )
{
    if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
                                                         rId.getConstArray(), 16 ) )
    {
        return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
    }
    return 0;
}

<commit_msg>INTEGRATION: CWS changefileheader (1.15.18); FILE MERGED 2008/04/01 16:09:35 thb 1.15.18.3: #i85898# Stripping all external header guards 2008/04/01 13:04:35 thb 1.15.18.2: #i85898# Stripping all external header guards 2008/03/31 16:28:04 rt 1.15.18.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: attrlist.cxx,v $
 * $Revision: 1.16 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"

#include <vector>
#include <osl/mutex.hxx>
#include <xmloff/xmltoken.hxx>
#include <rtl/uuid.h>
#include <rtl/memory.h>

#if OSL_DEBUG_LEVEL == 0
#  ifndef NDEBUG
#    define NDEBUG
#  endif
#endif
#include <assert.h>

#include <xmloff/attrlist.hxx>

using ::rtl::OUString;

using namespace ::osl;
using namespace ::com::sun::star;
using namespace ::xmloff::token;

struct SvXMLTagAttribute_Impl
{
    SvXMLTagAttribute_Impl(){}
    SvXMLTagAttribute_Impl( const OUString &rName,
                         const OUString &rValue )
        : sName(rName),
        sValue(rValue)
    {
    }

    SvXMLTagAttribute_Impl( const SvXMLTagAttribute_Impl& r ) :
        sName(r.sName),
        sValue(r.sValue)
    {
    }

    OUString sName;
    OUString sValue;
};

struct SvXMLAttributeList_Impl
{
    SvXMLAttributeList_Impl()
    {
        // performance improvement during adding
        vecAttribute.reserve(20);
    }

    SvXMLAttributeList_Impl( const SvXMLAttributeList_Impl& r ) :
            vecAttribute( r.vecAttribute )
    {
    }

    ::std::vector<struct SvXMLTagAttribute_Impl> vecAttribute;
    typedef ::std::vector<struct SvXMLTagAttribute_Impl>::size_type size_type;
};

sal_Int16 SAL_CALL SvXMLAttributeList::getLength(void) throw( ::com::sun::star::uno::RuntimeException )
{
    return sal::static_int_cast< sal_Int16 >(m_pImpl->vecAttribute.size());
}

SvXMLAttributeList::SvXMLAttributeList( const SvXMLAttributeList &r ) :
    cppu::WeakImplHelper3<com::sun::star::xml::sax::XAttributeList, com::sun::star::util::XCloneable, com::sun::star::lang::XUnoTunnel>(r),
    m_pImpl( new SvXMLAttributeList_Impl( *r.m_pImpl ) )
{
}

SvXMLAttributeList::SvXMLAttributeList( const uno::Reference<
        xml::sax::XAttributeList> & rAttrList )
    : sType( GetXMLToken(XML_CDATA) )
{
    m_pImpl = new SvXMLAttributeList_Impl;

    SvXMLAttributeList* pImpl =
        SvXMLAttributeList::getImplementation( rAttrList );

    if( pImpl )
        *m_pImpl = *(pImpl->m_pImpl);
    else
        AppendAttributeList( rAttrList );
}

OUString SAL_CALL SvXMLAttributeList::getNameByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() ) {
        return m_pImpl->vecAttribute[i].sName;
    }
    return OUString();
}

OUString SAL_CALL SvXMLAttributeList::getTypeByIndex(sal_Int16) throw( ::com::sun::star::uno::RuntimeException )
{
    return sType;
}

OUString SAL_CALL  SvXMLAttributeList::getValueByIndex(sal_Int16 i) throw( ::com::sun::star::uno::RuntimeException )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() ) {
        return m_pImpl->vecAttribute[i].sValue;
    }
    return OUString();

}

OUString SAL_CALL SvXMLAttributeList::getTypeByName( const OUString& ) throw( ::com::sun::star::uno::RuntimeException )
{
    return sType;
}

OUString SAL_CALL SvXMLAttributeList::getValueByName(const OUString& sName) throw( ::com::sun::star::uno::RuntimeException )
{
    ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin();

    for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) {
        if( (*ii).sName == sName ) {
            return (*ii).sValue;
        }
    }
    return OUString();
}

uno::Reference< ::com::sun::star::util::XCloneable >  SvXMLAttributeList::createClone() throw( ::com::sun::star::uno::RuntimeException )
{
    uno::Reference< ::com::sun::star::util::XCloneable >  r = new SvXMLAttributeList( *this );
    return r;
}

SvXMLAttributeList::SvXMLAttributeList()
    : sType( GetXMLToken(XML_CDATA) )
{
    m_pImpl = new SvXMLAttributeList_Impl;
}

SvXMLAttributeList::~SvXMLAttributeList()
{
    delete m_pImpl;
}

void SvXMLAttributeList::AddAttribute(  const OUString &sName ,
                                        const OUString &sValue )
{
    m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) );
}

void SvXMLAttributeList::Clear()
{
    m_pImpl->vecAttribute.clear();

    assert( ! getLength() );
}

void SvXMLAttributeList::RemoveAttribute( const OUString sName )
{
    ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii = m_pImpl->vecAttribute.begin();

    for( ; ii != m_pImpl->vecAttribute.end() ; ++ii ) {
        if( (*ii).sName == sName ) {
            m_pImpl->vecAttribute.erase( ii );
            break;
        }
    }
}

void SvXMLAttributeList::SetAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList >  &r )
{
    Clear();
    AppendAttributeList( r );
}

void SvXMLAttributeList::AppendAttributeList( const uno::Reference< ::com::sun::star::xml::sax::XAttributeList >  &r )
{
    assert( r.is() );

    sal_Int16 nMax = r->getLength();
    SvXMLAttributeList_Impl::size_type nTotalSize =
        m_pImpl->vecAttribute.size() + nMax;
    m_pImpl->vecAttribute.reserve( nTotalSize );

    for( sal_Int16 i = 0 ; i < nMax ; ++i ) {
        m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl(
            r->getNameByIndex( i ) ,
            r->getValueByIndex( i )));
    }

    assert( nTotalSize == (SvXMLAttributeList_Impl::size_type)getLength());
}

void SvXMLAttributeList::SetValueByIndex( sal_Int16 i,
        const ::rtl::OUString& rValue )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() )
    {
        m_pImpl->vecAttribute[i].sValue = rValue;
    }
}

void SvXMLAttributeList::RemoveAttributeByIndex( sal_Int16 i )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() )
        m_pImpl->vecAttribute.erase( m_pImpl->vecAttribute.begin() + i );
}

void SvXMLAttributeList::RenameAttributeByIndex( sal_Int16 i,
                                                 const OUString& rNewName )
{
    if( static_cast< SvXMLAttributeList_Impl::size_type >( i )
            < m_pImpl->vecAttribute.size() )
    {
        m_pImpl->vecAttribute[i].sName = rNewName;
    }
}

sal_Int16 SvXMLAttributeList::GetIndexByName( const OUString& rName ) const
{
    ::std::vector<struct SvXMLTagAttribute_Impl>::iterator ii =
        m_pImpl->vecAttribute.begin();

    for( sal_Int16 nIndex=0; ii!=m_pImpl->vecAttribute.end(); ++ii, ++nIndex )
    {
        if( (*ii).sName == rName )
        {
            return nIndex;
        }
    }
    return -1;
}

// XUnoTunnel & co
const uno::Sequence< sal_Int8 > & SvXMLAttributeList::getUnoTunnelId() throw()
{
    static uno::Sequence< sal_Int8 > * pSeq = 0;
    if( !pSeq )
    {
        Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
        if( !pSeq )
        {
            static uno::Sequence< sal_Int8 > aSeq( 16 );
            rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
            pSeq = &aSeq;
        }
    }
    return *pSeq;
}

SvXMLAttributeList* SvXMLAttributeList::getImplementation( uno::Reference< uno::XInterface > xInt ) throw()
{
    uno::Reference< lang::XUnoTunnel > xUT( xInt, uno::UNO_QUERY );
    if( xUT.is() )
    {
        return
            reinterpret_cast<SvXMLAttributeList*>(
                sal::static_int_cast<sal_IntPtr>(
                    xUT->getSomething( SvXMLAttributeList::getUnoTunnelId())));
    }
    else
        return NULL;
}

// XUnoTunnel
sal_Int64 SAL_CALL SvXMLAttributeList::getSomething( const uno::Sequence< sal_Int8 >& rId )
    throw( uno::RuntimeException )
{
    if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
                                                         rId.getConstArray(), 16 ) )
    {
        return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
    }
    return 0;
}

<|endoftext|>


<commit_before>//
//  parameters.hpp
//  yamcmc++
//
//  Created by Brandon Kelly on 4/15/13.
//  Copyright (c) 2013 Brandon Kelly. All rights reserved.
//

#ifndef yamcmc___parameters_hpp
#define yamcmc___parameters_hpp

// Standard includes
#include <iostream>
#include <string>
// Boost includes
#include <boost/ptr_container/ptr_vector.hpp>
// Local includes
#include "random.hpp"

// Global random number generator object, instantiated in random.cpp
extern boost::random::mt19937 rng;

// Global object for generating random variables from various distributions,
// instantiated in steps.cpp
extern RandomGenerator RandGen;

// This is the base Parameter class. It is abstract, so it should
// never be instantiated directly. Users should subclass the Parameter class,
// not BaseParameter class as the parameter value type is not specified in the
// BaseParameter class. Because of this, the MCMC step classes take a reference
// to the Parameter class.
class BaseParameter {
public:
    // Constructor
    BaseParameter(bool track, std::string label, double temperature=1.0) :
    track_(track), label_(label), temperature_(temperature) {}

	// Return the current value of the log-posterior. Useful for
	// Metropolis steps so we don't have to compute the log-posterior
	// for the current value of the parameter more than once
	double GetLogDensity() {
		return log_posterior_;
	}

    // Method to directly set the log-posterior of the parameter. Useful for certain steps
    // when we do not need to recalculate the posterior. Used in the exchange step.
    void SetLogDensity(double logpost) {
        log_posterior_ = logpost;
    }

    // Return the value of the temperature used. Primarily used in tempered transitions.
    double GetTemperature() {
        return temperature_;
    }

	// Return a string representation of the parameter value.
	virtual std::string StringValue() {
		return " ";
	}

	// Parameter is tracked / saved. Return True if parameter is tracked.
	bool Track() {
		return track_;
	}

    // Set whether a parameter is tracked or not.
    void SetTracking(bool track) {
        track_ = track;
    }

	// Return the a string containing the parameter label. This is used to identify the parameter.
	std::string Label() {
		return label_;
	}

    // Set the size of the vector containing the MCMC samples. This will be overidden by the Parameter class.
    virtual void SetSampleSize(int sample_size) = 0;

    // Add a value to the set of MCMC samples. This will be overidden by the Parameter class.
    virtual void AddToSample(int current_iter) = 0;

protected:
    // Temperature value, used when doing tempered steps. By default this is one.
    double temperature_;
	/// Should this variable be tracked?
	bool track_;
	/// Name of variable for tracking purposes.
	std::string label_;
    double log_posterior_; // The log of the posterior distribution
};

// Templated abstract parameter class. Users should subclass the Parameter class because the
// Step classes need to know the type of the parameter values.
template<class ParValueType>
class Parameter : public BaseParameter {
public:
    // Constructor
    Parameter(bool track, std::string label, double temperature=1.0) :
    BaseParameter(track, label, temperature) {}

	// Method to return the starting value for the parameter.
	virtual ParValueType StartingValue() = 0;

	// Method to return the log of the probability density (plus constant).
	// value: Value of parameter to evaluate density at.
	virtual double LogDensity(ParValueType value) {
		return 0.0;
    }

	// Return a random draw from the posterior.
	// Random draw from posterior is called by GibbsStep.
	virtual ParValueType RandomPosterior() {
        ParValueType p;
		return p;
	}

	// Return the current value of the parameter.
	ParValueType Value() {
        return value_;
    }

	// Save a new value of the parameter.
	// new_value: New value to save.
	virtual void Save(ParValueType new_value) {
        value_ = new_value;
        log_posterior_ = LogDensity(new_value);
    }

    // Set the size of the vector containing the MCMC samples
    void SetSampleSize(int sample_size) {
        samples_.resize(sample_size);
        logposts_.resize(sample_size);
    }

    // Add a value to the set of MCMC samples
    void AddToSample(int current_iter) {
        // TODO: Should be able to replace this with an iterator for efficiency, since we probably
        // will always add values sequentially for MCMC samplers
        samples_[current_iter] = value_;
        logposts_[current_iter] = log_posterior_;
    }

    // Return a copy of the MCMC samples
    std::vector<ParValueType> GetSamples() {
        return samples_;
    }

    // Return a copy of the MCMC samples
    std::vector<std::vector<double> > getSamples() {
        int nx = samples_.size();
        int ny = samples_[0].n_elem;
        std::vector<std::vector<double> > samples(nx,std::vector<double>(ny));
        for (int i = 0; i < nx; i++) {
            samples[i] = arma::conv_to<std::vector<double> >::from(samples_[i]);
        }
        return samples;
    }

    // Return a copy of the MCMC samples
    std::vector<double> GetLogLikes() {
        return logposts_;
    }

protected:
    ParValueType value_; // The current value of the parameter
    std::vector<ParValueType> samples_; // Vector containing the MCMC samples
    std::vector<double> logposts_; // Vector containing the posterior likelihoods
};

// This is the Ensemble class. It is basically a class
// containing a pointer container (boost::ptr_vector) that allows
// one to collect an ensemble of objects. This is the basis for
// the Ensemble MCMC samplers, which require both an ensemble of
// parameter and proposal objects.

template <class EnsembleType>
class Ensemble {
public:
    // Empty constructor
    Ensemble() {}

    // Add parameter object to the parameter ensemble
    void AddObject(EnsembleType* pObject) {
        the_objects_.push_back(pObject);
    }

    // Return the number of parameters in the ensemble
    int size() {
        return the_objects_.size();
    }

    // Access elements of the parameter ensemble. This done by overloading
    // the [] operator so that one can obtain a reference to a parameter
    // as parameter = ensemble[i].
    EnsembleType& operator [] (const int index)
    {
        return the_objects_[index];
    }

    EnsembleType const & operator [] (const int index) const
    {
        return the_objects_[index];
    }

    //private:
    boost::ptr_vector<EnsembleType> the_objects_;
};

#endif
<commit_msg>Moved Parameter::getSamples() to carma_pack, since this method assumes the parameter value is of type arma::vec which is not always true.<commit_after>//
//  parameters.hpp
//  yamcmc++
//
//  Created by Brandon Kelly on 4/15/13.
//  Copyright (c) 2013 Brandon Kelly. All rights reserved.
//

#ifndef yamcmc___parameters_hpp
#define yamcmc___parameters_hpp

// Standard includes
#include <iostream>
#include <string>
// Boost includes
#include <boost/ptr_container/ptr_vector.hpp>
// Local includes
#include "random.hpp"

// Global random number generator object, instantiated in random.cpp
extern boost::random::mt19937 rng;

// Global object for generating random variables from various distributions,
// instantiated in steps.cpp
extern RandomGenerator RandGen;

// This is the base Parameter class. It is abstract, so it should
// never be instantiated directly. Users should subclass the Parameter class,
// not BaseParameter class as the parameter value type is not specified in the
// BaseParameter class. Because of this, the MCMC step classes take a reference
// to the Parameter class.
class BaseParameter {
public:
    // Constructor
    BaseParameter(bool track, std::string label, double temperature=1.0) :
    track_(track), label_(label), temperature_(temperature) {}

	// Return the current value of the log-posterior. Useful for
	// Metropolis steps so we don't have to compute the log-posterior
	// for the current value of the parameter more than once
	double GetLogDensity() {
		return log_posterior_;
	}

    // Method to directly set the log-posterior of the parameter. Useful for certain steps
    // when we do not need to recalculate the posterior. Used in the exchange step.
    void SetLogDensity(double logpost) {
        log_posterior_ = logpost;
    }

    // Return the value of the temperature used. Primarily used in tempered transitions.
    double GetTemperature() {
        return temperature_;
    }

	// Return a string representation of the parameter value.
	virtual std::string StringValue() {
		return " ";
	}

	// Parameter is tracked / saved. Return True if parameter is tracked.
	bool Track() {
		return track_;
	}

    // Set whether a parameter is tracked or not.
    void SetTracking(bool track) {
        track_ = track;
    }

	// Return the a string containing the parameter label. This is used to identify the parameter.
	std::string Label() {
		return label_;
	}

    // Set the size of the vector containing the MCMC samples. This will be overidden by the Parameter class.
    virtual void SetSampleSize(int sample_size) = 0;

    // Add a value to the set of MCMC samples. This will be overidden by the Parameter class.
    virtual void AddToSample(int current_iter) = 0;

protected:
    // Temperature value, used when doing tempered steps. By default this is one.
    double temperature_;
	/// Should this variable be tracked?
	bool track_;
	/// Name of variable for tracking purposes.
	std::string label_;
    double log_posterior_; // The log of the posterior distribution
};

// Templated abstract parameter class. Users should subclass the Parameter class because the
// Step classes need to know the type of the parameter values.
template<class ParValueType>
class Parameter : public BaseParameter {
public:
    // Constructor
    Parameter(bool track, std::string label, double temperature=1.0) :
    BaseParameter(track, label, temperature) {}

	// Method to return the starting value for the parameter.
	virtual ParValueType StartingValue() = 0;

	// Method to return the log of the probability density (plus constant).
	// value: Value of parameter to evaluate density at.
	virtual double LogDensity(ParValueType value) {
		return 0.0;
    }

	// Return a random draw from the posterior.
	// Random draw from posterior is called by GibbsStep.
	virtual ParValueType RandomPosterior() {
        ParValueType p;
		return p;
	}

	// Return the current value of the parameter.
	ParValueType Value() {
        return value_;
    }

	// Save a new value of the parameter.
	// new_value: New value to save.
	virtual void Save(ParValueType new_value) {
        value_ = new_value;
        log_posterior_ = LogDensity(new_value);
    }

    // Set the size of the vector containing the MCMC samples
    void SetSampleSize(int sample_size) {
        samples_.resize(sample_size);
        logposts_.resize(sample_size);
    }

    // Add a value to the set of MCMC samples
    void AddToSample(int current_iter) {
        // TODO: Should be able to replace this with an iterator for efficiency, since we probably
        // will always add values sequentially for MCMC samplers
        samples_[current_iter] = value_;
        logposts_[current_iter] = log_posterior_;
    }

    // Return a copy of the MCMC samples
    std::vector<ParValueType> GetSamples() {
        return samples_;
    }

    // Return a copy of the MCMC samples
    std::vector<double> GetLogLikes() {
        return logposts_;
    }

protected:
    ParValueType value_; // The current value of the parameter
    std::vector<ParValueType> samples_; // Vector containing the MCMC samples
    std::vector<double> logposts_; // Vector containing the posterior likelihoods
};

// This is the Ensemble class. It is basically a class
// containing a pointer container (boost::ptr_vector) that allows
// one to collect an ensemble of objects. This is the basis for
// the Ensemble MCMC samplers, which require both an ensemble of
// parameter and proposal objects.

template <class EnsembleType>
class Ensemble {
public:
    // Empty constructor
    Ensemble() {}

    // Add parameter object to the parameter ensemble
    void AddObject(EnsembleType* pObject) {
        the_objects_.push_back(pObject);
    }

    // Return the number of parameters in the ensemble
    int size() {
        return the_objects_.size();
    }

    // Access elements of the parameter ensemble. This done by overloading
    // the [] operator so that one can obtain a reference to a parameter
    // as parameter = ensemble[i].
    EnsembleType& operator [] (const int index)
    {
        return the_objects_[index];
    }

    EnsembleType const & operator [] (const int index) const
    {
        return the_objects_[index];
    }

    //private:
    boost::ptr_vector<EnsembleType> the_objects_;
};

#endif
<|endoftext|>


<commit_before>//=====================================================================//
/*! @file
	@brief  player クラス
	@author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <iostream>
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include "core/glcore.hpp"
#include "gui_test.hpp"
#include "widgets/widget_utils.hpp"

namespace app {

	//-----------------------------------------------------------------//
	/*!
		@brief  初期化
	*/
	//-----------------------------------------------------------------//
	void gui_test::initialize()
	{
		gl::core& core = gl::core::get_instance();

		using namespace gui;
		widget_director& wd = director_.at().widget_director_;

		if(1) {	// ラジオボタンのテスト
			widget::param wpr(vtx::irect(20, 20, 130, 130), 0);
			widget_null::param wpr_;
			widget* root = wd.add_widget<widget_null>(wpr, wpr_);
			root->set_state(widget::state::POSITION_LOCK);

			widget::param wp(vtx::irect(0, 0, 130, 30), root);
			widget_radio::param wp_("Enable");
			for(int i = 0; i < 3; ++i) {
				if(i == 2) wp_.check_ = true;
				widget_radio* w = wd.add_widget<widget_radio>(wp, wp_);
				w->at_local_param().select_func_ = [this](bool f, int n) {
					std::cout << "Radio button: " << static_cast<int>(f) << " (" << n << ")" << std::endl;
				};
				wp.rect_.org.y += 40;
			}
		}

		if(1) {	// イメージのテスト
			widget::param wp(vtx::irect(400, 20, 500, 250));
			img::paint pa;
			pa.set_fore_color(img::rgba8(0, 255, 0));
			pa.create(vtx::spos(500, 250), true);
			pa.fill(img::rgba8(255, 100, 100));
			pa.alpha_blend();
			pa.fill_circle(vtx::spos(250), 220);
			vtx::sposs ss;
			ss.push_back(vtx::spos(10, 10));
			ss.push_back(vtx::spos(100, 100));
			ss.push_back(vtx::spos(50, 200));
			pa.set_fore_color(img::rgba8(240, 40, 50));
//			pa.fill_polygon(ss);
			widget_image::param wp_(&pa);
			image_ = wd.add_widget<widget_image>(wp, wp_);
		}

		if(1) {	// テキストのテスト
			widget::param wp(vtx::irect(40, 50, 200, 250), image_);
			widget_text::param wp_;
			wp_.text_param_.set_text("日本の美しい漢字\n吉野家qwertyuiop\nxcvbnm"
				);
			wp_.text_param_.placement_.vpt = vtx::placement::vertical::CENTER;
			wd.add_widget<widget_text>(wp, wp_);
		}

		if(1) { // ダイアログのテスト
			widget::param wp(vtx::irect(300, 300, 300, 200));
			widget_dialog::param wp_;
			wp_.style_ = widget_dialog::param::style::CANCEL_OK;
			dialog_ = wd.add_widget<widget_dialog>(wp, wp_);
			dialog_->set_text("ああああ\nうううう\nいいいい\n漢字\n日本");
		}

		if(1) { // ボタンのテスト（ファイラー開始ボタン）
			widget::param wp(vtx::irect(30, 150, 100, 40));
			widget_button::param wp_("Filer");
			filer_open_ = wd.add_widget<widget_button>(wp, wp_);
			filer_open_->at_local_param().text_param_.set_alias("ファイラー");
			filer_open_->at_local_param().text_param_.alias_enable_ = true;
		}

		if(1) { // ボタンのテスト（メニュー開始ボタン）
			widget::param wp(vtx::irect(30, 200, 100, 40));
			widget_button::param wp_("Menu");
			menu_open_ = wd.add_widget<widget_button>(wp, wp_);
		}

		if(1) { // ボタンのテスト（ダイアログ開始ボタン）
			widget::param wp(vtx::irect(30, 250, 100, 40));
			widget_button::param wp_("Daialog");
			dialog_open_ = wd.add_widget<widget_button>(wp, wp_);
		}

		if(1) { // ラベルのテスト
			widget::param wp(vtx::irect(30, 300, 150, 40));
			widget_label::param wp_("Asdfg", false);
			label_ = wd.add_widget<widget_label>(wp, wp_);
			label_->at_local_param().select_func_ = [this](const std::string& t) {
				std::cout << "Label: " << t << std::endl << std::flush;
			};
		}

		if(1) {	// チェックボックスのテスト
			widget::param wp(vtx::irect(20, 350, 150, 40));
			widget_check::param wp_("Disable-g");
			check_ = wd.add_widget<widget_check>(wp, wp_);
			check_->at_local_param().select_func_ = [this](bool f) {
				std::cout << "Check: " << static_cast<int>(f) << std::endl;
			};
		}

		if(1) { // リストのテスト
			widget::param wp(vtx::irect(30, 400, 150, 40), 0);
			widget_list::param wp_("List Box");
			wp_.text_list_.push_back("abc");
			wp_.text_list_.push_back("1234");
			wp_.text_list_.push_back("qwert");
			wd.add_widget<widget_list>(wp, wp_);
		}

		if(1) { // スライダーのテスト
			widget::param wp(vtx::irect(30, 450, 180, 20));
			widget_slider::param wp_;
			slider_ = wd.add_widget<widget_slider>(wp, wp_);
		}

		if(1) { // スピンボックスのテスト
			widget::param wp(vtx::irect(30, 500, 100, 40));
			widget_spinbox::param wp_;
			wp_.text_list_.push_back("0");
			wp_.text_list_.push_back("1");
			wp_.text_list_.push_back("2");
			wp_.text_list_.push_back("3");
			wp_.text_list_.push_back("4");
			wp_.text_list_.push_back("5");
			spinbox_ = wd.add_widget<widget_spinbox>(wp, wp_);
			spinbox_->at_local_param().select_func_ = [this](const std::string& st, int pos){
				std::cout << "SpinBox select: '" << st << "', (" << pos << ")" << std::endl;
			};
		}

		if(1) { // メニューのテスト
			widget::param wp(vtx::irect(10, 10, 180, 30));
			widget_menu::param wp_;
//			wp_.round_ = false;
			wp_.text_list_.push_back("First");
			wp_.text_list_.push_back("Second");
			wp_.text_list_.push_back("Third");
			wp_.text_list_.push_back("Force");
			menu_ = wd.add_widget<widget_menu>(wp, wp_);
		}

		if(1) { // フレームのテスト
			widget::param wp(vtx::irect(200, 20, 100, 80));
			widget_frame::param wp_;
			frame_ = wd.add_widget<widget_frame>(wp, wp_);
		}

		if(1) {	// ファイラーのテスト
			widget::param wp(vtx::irect(10, 30, 300, 200));
			widget_filer::param wp_(core.get_current_path(), "", true);
			filer_ = wd.add_widget<widget_filer>(wp, wp_);
			filer_->enable(false);
		}

		if(1) {	// ツリーのテスト
			{
				widget::param wp(vtx::irect(400, 500, 200, 200));
				widget_frame::param wp_;
				wp_.plate_param_.set_caption(30);
				tree_frame_ = wd.add_widget<widget_frame>(wp, wp_);
			}

			widget::param wp(vtx::irect(0), tree_frame_);
			widget_tree::param wp_;
			tree_core_ = wd.add_widget<widget_tree>(wp, wp_);
			tree_core_->set_state(widget::state::CLIP_PARENTS);
///			tree_core_->set_state(widget::state::POSITION_LOCK);
			tree_core_->set_state(widget::state::RESIZE_ROOT);
			tree_core_->set_state(widget::state::MOVE_ROOT, false);
#if 0
			widget_tree::tree_unit& tu = tree_core_->at_tree_unit();
			tu.make_directory("/root0");
			tu.make_directory("/root1");
			tu.set_current_path("/root0");
			{
				widget_tree::value v;
				v.data_ = "AAA";
				tu.install("sub0", v);
			}
			{
				widget_tree::value v;
				v.data_ = "BBB";
				tu.install("sub1", v);
			}
			tu.make_directory("sub2");
			tu.set_current_path("sub2");
			{
				widget_tree::value v;
				v.data_ = "CCC";
				tu.install("sub-sub", v);
			}
			tu.set_current_path("/root1");
			{
				widget_tree::value v;
				v.data_ = "ASDFG";
				tu.install("sub_A", v);
			}
			{
				widget_tree::value v;
				v.data_ = "ZXCVB";
				tu.install("sub_B", v);
			}
#endif

//			tu.list("/root");
//			tu.list();
		}

		if(1) {	// ターミナルのテスト
			{
				widget::param wp(vtx::irect(700, 500, 200, 200));
				widget_frame::param wp_;
				wp_.plate_param_.set_caption(30);
				terminal_frame_ = wd.add_widget<widget_frame>(wp, wp_);
			}
			{
				widget::param wp(vtx::irect(0), terminal_frame_);
				widget_terminal::param wp_;
				terminal_core_ = wd.add_widget<widget_terminal>(wp, wp_);
				terminal_core_->output("漢字");
			}
		}

		// プリファレンスの取得
		sys::preference& pre = director_.at().preference_;
		if(filer_) {
			filer_->load(pre);
		}
		if(label_) {
			label_->load(pre);
		}
		if(slider_) {
			slider_->load(pre);
		}
		if(check_) {
			check_->load(pre);
		}
		if(frame_) {
			frame_->load(pre);
		}
		if(tree_frame_) {
			tree_frame_->load(pre);
		}
		if(terminal_frame_) {
			terminal_frame_->load(pre);
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  アップデート
	*/
	//-----------------------------------------------------------------//
	void gui_test::update()
	{
		gui::widget_director& wd = director_.at().widget_director_;

		if(dialog_open_) {
			if(dialog_open_->get_selected()) {
				if(dialog_) {
					dialog_->enable();
				}
			}
		}

		if(filer_open_) {
			if(filer_open_->get_selected()) {
				if(filer_) {
					filer_->enable(!filer_->get_state(gui::widget::state::ENABLE));
				}
			}
		}
		if(filer_) {
			if(filer_id_ != filer_->get_select_file_id()) {
				filer_id_ = filer_->get_select_file_id();
				std::cout << "Filer: '" << filer_->get_file() << "'" << std::endl;
				std::cout << std::flush;
			}
		}

		if(menu_open_) {
			if(menu_open_->get_selected()) {
				if(menu_) {
					menu_->enable(!menu_->get_state(gui::widget::state::ENABLE));
					if(menu_->get_state(gui::widget::state::ENABLE)) {
//						menu_->at_rect().org =
					}

				}
			}
		}
		// メニューが選択された！
		if(menu_) {
			if(menu_id_ != menu_->get_select_id()) {
				menu_id_ = menu_->get_select_id();
				std::cout << "Menu: " << menu_->get_select_text() << std::endl;
			}
		}

		if(terminal_core_) {
//			static wchar_t ch = ' ';
//			terminal_core_->output(ch);
//			++ch;
//			if(ch >= 0x7f) ch = ' ';
		}

		wd.update();
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  レンダリング
	*/
	//-----------------------------------------------------------------//
	void gui_test::render()
	{
		director_.at().widget_director_.service();
		director_.at().widget_director_.render();
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  廃棄
	*/
	//-----------------------------------------------------------------//
	void gui_test::destroy()
	{
		sys::preference& pre = director_.at().preference_;
		if(filer_) {
			filer_->save(pre);
		}
		if(terminal_frame_) {
			terminal_frame_->save(pre);
		}
		if(tree_frame_) {
			tree_frame_->save(pre);
		}
		if(check_) {
			check_->save(pre);
		}
		if(slider_) {
			slider_->save(pre);
		}
		if(label_) {
			label_->save(pre);
		}
		if(frame_) {
			frame_->save(pre);
		}
	}
}
<commit_msg>update spinbox<commit_after>//=====================================================================//
/*! @file
	@brief  player クラス
	@author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <iostream>
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include "core/glcore.hpp"
#include "gui_test.hpp"
#include "widgets/widget_utils.hpp"

namespace app {

	//-----------------------------------------------------------------//
	/*!
		@brief  初期化
	*/
	//-----------------------------------------------------------------//
	void gui_test::initialize()
	{
		gl::core& core = gl::core::get_instance();

		using namespace gui;
		widget_director& wd = director_.at().widget_director_;

		if(1) {	// ラジオボタンのテスト
			widget::param wpr(vtx::irect(20, 20, 130, 130), 0);
			widget_null::param wpr_;
			widget* root = wd.add_widget<widget_null>(wpr, wpr_);
			root->set_state(widget::state::POSITION_LOCK);

			widget::param wp(vtx::irect(0, 0, 130, 30), root);
			widget_radio::param wp_("Enable");
			for(int i = 0; i < 3; ++i) {
				if(i == 2) wp_.check_ = true;
				widget_radio* w = wd.add_widget<widget_radio>(wp, wp_);
				w->at_local_param().select_func_ = [this](bool f, int n) {
					std::cout << "Radio button: " << static_cast<int>(f) << " (" << n << ")" << std::endl;
				};
				wp.rect_.org.y += 40;
			}
		}

		if(1) {	// イメージのテスト
			widget::param wp(vtx::irect(400, 20, 500, 250));
			img::paint pa;
			pa.set_fore_color(img::rgba8(0, 255, 0));
			pa.create(vtx::spos(500, 250), true);
			pa.fill(img::rgba8(255, 100, 100));
			pa.alpha_blend();
			pa.fill_circle(vtx::spos(250), 220);
			vtx::sposs ss;
			ss.push_back(vtx::spos(10, 10));
			ss.push_back(vtx::spos(100, 100));
			ss.push_back(vtx::spos(50, 200));
			pa.set_fore_color(img::rgba8(240, 40, 50));
//			pa.fill_polygon(ss);
			widget_image::param wp_(&pa);
			image_ = wd.add_widget<widget_image>(wp, wp_);
		}

		if(1) {	// テキストのテスト
			widget::param wp(vtx::irect(40, 50, 200, 250), image_);
			widget_text::param wp_;
			wp_.text_param_.set_text("日本の美しい漢字\n吉野家qwertyuiop\nxcvbnm"
				);
			wp_.text_param_.placement_.vpt = vtx::placement::vertical::CENTER;
			wd.add_widget<widget_text>(wp, wp_);
		}

		if(1) { // ダイアログのテスト
			widget::param wp(vtx::irect(300, 300, 300, 200));
			widget_dialog::param wp_;
			wp_.style_ = widget_dialog::param::style::CANCEL_OK;
			dialog_ = wd.add_widget<widget_dialog>(wp, wp_);
			dialog_->set_text("ああああ\nうううう\nいいいい\n漢字\n日本");
		}

		if(1) { // ボタンのテスト（ファイラー開始ボタン）
			widget::param wp(vtx::irect(30, 150, 100, 40));
			widget_button::param wp_("Filer");
			filer_open_ = wd.add_widget<widget_button>(wp, wp_);
			filer_open_->at_local_param().text_param_.set_alias("ファイラー");
			filer_open_->at_local_param().text_param_.alias_enable_ = true;
		}

		if(1) { // ボタンのテスト（メニュー開始ボタン）
			widget::param wp(vtx::irect(30, 200, 100, 40));
			widget_button::param wp_("Menu");
			menu_open_ = wd.add_widget<widget_button>(wp, wp_);
		}

		if(1) { // ボタンのテスト（ダイアログ開始ボタン）
			widget::param wp(vtx::irect(30, 250, 100, 40));
			widget_button::param wp_("Daialog");
			dialog_open_ = wd.add_widget<widget_button>(wp, wp_);
		}

		if(1) { // ラベルのテスト
			widget::param wp(vtx::irect(30, 300, 150, 40));
			widget_label::param wp_("Asdfg", false);
			label_ = wd.add_widget<widget_label>(wp, wp_);
			label_->at_local_param().select_func_ = [this](const std::string& t) {
				std::cout << "Label: " << t << std::endl << std::flush;
			};
		}

		if(1) {	// チェックボックスのテスト
			widget::param wp(vtx::irect(20, 350, 150, 40));
			widget_check::param wp_("Disable-g");
			check_ = wd.add_widget<widget_check>(wp, wp_);
			check_->at_local_param().select_func_ = [this](bool f) {
				std::cout << "Check: " << static_cast<int>(f) << std::endl;
			};
		}

		if(1) { // リストのテスト
			widget::param wp(vtx::irect(30, 400, 150, 40), 0);
			widget_list::param wp_("List Box");
			wp_.text_list_.push_back("abc");
			wp_.text_list_.push_back("1234");
			wp_.text_list_.push_back("qwert");
			wd.add_widget<widget_list>(wp, wp_);
		}

		if(1) { // スライダーのテスト
			widget::param wp(vtx::irect(30, 450, 180, 20));
			widget_slider::param wp_;
			slider_ = wd.add_widget<widget_slider>(wp, wp_);
		}

		if(1) { // スピンボックスのテスト
			widget::param wp(vtx::irect(30, 500, 100, 40));
			widget_spinbox::param wp_(1, 3, 5);
			spinbox_ = wd.add_widget<widget_spinbox>(wp, wp_);
			spinbox_->at_local_param().select_func_ = [this](widget_spinbox::state st, int before, int newpos) {
				std::cout << "SpinBox ";
				if(st == widget_spinbox::state::initial) std::cout << "initial";
				else if(st == widget_spinbox::state::inc) std::cout << "inc";
				else if(st == widget_spinbox::state::dec) std::cout << "dec";
				else std::cout << "select";
				std::cout << ": " << newpos << std::endl;
				return (boost::format("%d") % newpos).str();
			};
		}

		if(1) { // メニューのテスト
			widget::param wp(vtx::irect(10, 10, 180, 30));
			widget_menu::param wp_;
//			wp_.round_ = false;
			wp_.text_list_.push_back("First");
			wp_.text_list_.push_back("Second");
			wp_.text_list_.push_back("Third");
			wp_.text_list_.push_back("Force");
			menu_ = wd.add_widget<widget_menu>(wp, wp_);
		}

		if(1) { // フレームのテスト
			widget::param wp(vtx::irect(200, 20, 100, 80));
			widget_frame::param wp_;
			frame_ = wd.add_widget<widget_frame>(wp, wp_);
		}

		if(1) {	// ファイラーのテスト
			widget::param wp(vtx::irect(10, 30, 300, 200));
			widget_filer::param wp_(core.get_current_path(), "", true);
			filer_ = wd.add_widget<widget_filer>(wp, wp_);
			filer_->enable(false);
		}

		if(1) {	// ツリーのテスト
			{
				widget::param wp(vtx::irect(400, 500, 200, 200));
				widget_frame::param wp_;
				wp_.plate_param_.set_caption(30);
				tree_frame_ = wd.add_widget<widget_frame>(wp, wp_);
			}

			widget::param wp(vtx::irect(0), tree_frame_);
			widget_tree::param wp_;
			tree_core_ = wd.add_widget<widget_tree>(wp, wp_);
			tree_core_->set_state(widget::state::CLIP_PARENTS);
///			tree_core_->set_state(widget::state::POSITION_LOCK);
			tree_core_->set_state(widget::state::RESIZE_ROOT);
			tree_core_->set_state(widget::state::MOVE_ROOT, false);
#if 0
			widget_tree::tree_unit& tu = tree_core_->at_tree_unit();
			tu.make_directory("/root0");
			tu.make_directory("/root1");
			tu.set_current_path("/root0");
			{
				widget_tree::value v;
				v.data_ = "AAA";
				tu.install("sub0", v);
			}
			{
				widget_tree::value v;
				v.data_ = "BBB";
				tu.install("sub1", v);
			}
			tu.make_directory("sub2");
			tu.set_current_path("sub2");
			{
				widget_tree::value v;
				v.data_ = "CCC";
				tu.install("sub-sub", v);
			}
			tu.set_current_path("/root1");
			{
				widget_tree::value v;
				v.data_ = "ASDFG";
				tu.install("sub_A", v);
			}
			{
				widget_tree::value v;
				v.data_ = "ZXCVB";
				tu.install("sub_B", v);
			}
#endif

//			tu.list("/root");
//			tu.list();
		}

		if(1) {	// ターミナルのテスト
			{
				widget::param wp(vtx::irect(700, 500, 200, 200));
				widget_frame::param wp_;
				wp_.plate_param_.set_caption(30);
				terminal_frame_ = wd.add_widget<widget_frame>(wp, wp_);
			}
			{
				widget::param wp(vtx::irect(0), terminal_frame_);
				widget_terminal::param wp_;
				terminal_core_ = wd.add_widget<widget_terminal>(wp, wp_);
				terminal_core_->output("漢字");
			}
		}

		// プリファレンスの取得
		sys::preference& pre = director_.at().preference_;
		if(filer_) {
			filer_->load(pre);
		}
		if(label_) {
			label_->load(pre);
		}
		if(slider_) {
			slider_->load(pre);
		}
		if(check_) {
			check_->load(pre);
		}
		if(frame_) {
			frame_->load(pre);
		}
		if(tree_frame_) {
			tree_frame_->load(pre);
		}
		if(terminal_frame_) {
			terminal_frame_->load(pre);
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  アップデート
	*/
	//-----------------------------------------------------------------//
	void gui_test::update()
	{
		gui::widget_director& wd = director_.at().widget_director_;

		if(dialog_open_) {
			if(dialog_open_->get_selected()) {
				if(dialog_) {
					dialog_->enable();
				}
			}
		}

		if(filer_open_) {
			if(filer_open_->get_selected()) {
				if(filer_) {
					filer_->enable(!filer_->get_state(gui::widget::state::ENABLE));
				}
			}
		}
		if(filer_) {
			if(filer_id_ != filer_->get_select_file_id()) {
				filer_id_ = filer_->get_select_file_id();
				std::cout << "Filer: '" << filer_->get_file() << "'" << std::endl;
				std::cout << std::flush;
			}
		}

		if(menu_open_) {
			if(menu_open_->get_selected()) {
				if(menu_) {
					menu_->enable(!menu_->get_state(gui::widget::state::ENABLE));
					if(menu_->get_state(gui::widget::state::ENABLE)) {
//						menu_->at_rect().org =
					}

				}
			}
		}
		// メニューが選択された！
		if(menu_) {
			if(menu_id_ != menu_->get_select_id()) {
				menu_id_ = menu_->get_select_id();
				std::cout << "Menu: " << menu_->get_select_text() << std::endl;
			}
		}

		if(terminal_core_) {
//			static wchar_t ch = ' ';
//			terminal_core_->output(ch);
//			++ch;
//			if(ch >= 0x7f) ch = ' ';
		}

		wd.update();
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  レンダリング
	*/
	//-----------------------------------------------------------------//
	void gui_test::render()
	{
		director_.at().widget_director_.service();
		director_.at().widget_director_.render();
	}

	//-----------------------------------------------------------------//
	/*!
		@brief  廃棄
	*/
	//-----------------------------------------------------------------//
	void gui_test::destroy()
	{
		sys::preference& pre = director_.at().preference_;
		if(filer_) {
			filer_->save(pre);
		}
		if(terminal_frame_) {
			terminal_frame_->save(pre);
		}
		if(tree_frame_) {
			tree_frame_->save(pre);
		}
		if(check_) {
			check_->save(pre);
		}
		if(slider_) {
			slider_->save(pre);
		}
		if(label_) {
			label_->save(pre);
		}
		if(frame_) {
			frame_->save(pre);
		}
	}
}
<|endoftext|>


<commit_before>#include <opencv2/highgui/highgui.hpp>
#include "GoalDetector.hpp"

using namespace std;
using namespace cv;

GoalDetector::GoalDetector(cv::Point2f fov_size, cv::Size frame_size, bool gui) :
	_goal_shape(3)
{
	_goal_found = false;
	_fov_size = fov_size;
	_frame_size = frame_size;
	_draw = false;
	_min_valid_confidence = 0.2;

	_blue_scale = 50;
	_red_scale  = 100;

	if (gui)
	{
		cv::namedWindow("Goal Detect Adjustments", CV_WINDOW_NORMAL);
		createTrackbar("Blue Scale","Goal Detect Adjustments", &_blue_scale, 100);
		createTrackbar("Red Scale","Goal Detect Adjustments", &_red_scale, 100);
	}
}

// Values around 0.5 are good. Values away from that are progressively
// worse.  Wrap stuff above 0.5 around 0.5 so the range
// of values go from 0 (bad) to 0.5 (good).
void GoalDetector::wrapConfidence(float &confidence)
{
	confidence = confidence > 0.5 ? 1 - confidence : confidence;
}

void GoalDetector::processFrame(Mat& image, const Mat& depth)
{
	// Use to mask the contour off from the rest of the
	// image - used when grabbing depth data for the contour
    Mat contour_mask(image.rows, image.cols, CV_8UC1, Scalar(0));

	// Reset goal_found flag for each frame. Set it later if
	// the goal is found
	_goal_found = false;
	_dist_to_goal = -1.0;
	_angle_to_goal = -1.0;
	_goal_rect = Rect(0,0,0,0);

	// Look for parts the the image which are within the
	// expected bright green color range
    Mat threshold_image;
	if (!generateThresholdAddSubtract(image, threshold_image))
		return;

	// find contours in the thresholded image - these will be blobs
	// of green to check later on to see how well they match the
	// expected shape of the goal
    vector<vector<Point> > contours;
    vector<Vec4i>          hierarchy;
    findContours(threshold_image, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    float maxConfidence = _min_valid_confidence;
	//cout << contours.size() << " goalDetect contours found" << endl;

	int best_contour_index;

	//center of mass as a percentage of the object size from top left
	Point2f com_percent_expected(_goal_shape.com().x / _goal_shape.width(),
				     _goal_shape.com().y / _goal_shape.height());

    for (size_t i = 0; i < contours.size(); i++)
    {
	    Rect br = boundingRect(contours[i]);
		contour_mask.setTo(Scalar(0));

		drawContours(contour_mask, contours, i, Scalar(255), CV_FILLED); //create a mask on the contour

		// get the minimum and maximum depth values in the contour,
		// copy them into individual floats
		pair<float, float> minMax = utils::minOfDepthMat(depth, contour_mask, br, 10);
		float depth_z_min = minMax.first;
		float depth_z_max = minMax.second;

		//make sure the depth exists before doing other things
		//also don't bother with targets too close to see (need more exact value here)
		if ((depth_z_min < 1.) || (depth_z_max < 1.))
			continue;

		// ObjectType computes a ton of useful properties so create
		// one for what we're looking at
		ObjectType goal_actual(contours[i]);

		if (goal_actual.area() < 200.0)
			continue;
		//create a trackedobject to get x,y,z of the goal
		TrackedObject goal_tracked_obj(0, _goal_shape, br, minMax.second, _fov_size, _frame_size);

		//percentage of the object filled in
		float filledPercentageActual   = goal_actual.area() / goal_actual.boundingArea();
		float filledPercentageExpected = _goal_shape.area() / _goal_shape.boundingArea();

		//center of mass as a percentage of the object size from top left
		Point2f com_percent_actual((goal_actual.com().x - br.tl().x) / goal_actual.width(),
				           (goal_actual.com().y - br.tl().y) / goal_actual.height());

		//width to height ratio
		float actualRatio   = goal_actual.width() / goal_actual.height();
		float expectedRatio = _goal_shape.width() / _goal_shape.height();

		//parameters for the normal distributions
		//values for standard deviation were determined by taking the standard deviation of a bunch of values from the goal
		pair<float,float> height_normal = make_pair(_goal_height, 0.059273877);
		pair<float,float> com_x_normal  = make_pair(com_percent_expected.x, 0.05157222);
		pair<float,float> com_y_normal  = make_pair(com_percent_expected.y, 0.0439207);
		pair<float,float> area_normal   = make_pair(filledPercentageExpected, 0.057567619);
		pair<float,float> ratio_normal  = make_pair(expectedRatio, 0.537392);
		pair<float,float> ideal_area    = make_pair(1.0, 1.0/3.0);

		//confidence is near 0.5 when value is near the mean
		//confidence is small or large when value is not near mean
		float confidence_height     = utils::normalCFD(height_normal, goal_tracked_obj.getPosition().z);
		float confidence_com_x      = utils::normalCFD(com_x_normal,  com_percent_actual.x);
		float confidence_com_y      = utils::normalCFD(com_y_normal,  com_percent_actual.y);
		float confidence_area       = utils::normalCFD(area_normal,   filledPercentageActual);
		float confidence_ratio      = utils::normalCFD(ratio_normal,  actualRatio);
		float confidence_ideal_area = utils::normalCFD(ideal_area,  (float)br.area() / goal_tracked_obj.getScreenPosition(_fov_size, _frame_size).area());

		// Normalize values between 0 and 0.5
		wrapConfidence(confidence_height);
		wrapConfidence(confidence_com_x);
		wrapConfidence(confidence_com_y);
		wrapConfidence(confidence_area);
		wrapConfidence(confidence_ratio);
		wrapConfidence(confidence_ideal_area);

		// higher is better
		float confidence = (confidence_height + confidence_com_x + confidence_com_y + confidence_area + confidence_ratio + confidence_ideal_area) / 6.0;

#if 0
		cout << "-------------------------------------------" << endl;
		cout << "Contour " << i << endl;
		cout << "confidence_height: " << confidence_height << endl;
		cout << "confidence_com_x: " << confidence_com_x << endl;
		cout << "confidence_com_y: " << confidence_com_y << endl;
		cout << "confidence_area: " << confidence_area << endl;
		cout << "confidence_ratio: " << confidence_ratio << endl;
		cout << "confidence_ideal_area: " << confidence_ideal_area << endl;
		cout << "confidence: " << confidence << endl;
		cout << "-------------------------------------------" << endl;
#endif

		if(_draw) {
			drawContours(image, contours,i,Scalar(0,0,255),3);
			rectangle(image, br, Scalar(255,0,0), 2);
			putText(image, to_string(confidence),br.tl(), FONT_HERSHEY_PLAIN, 1, Scalar(255,0,0));
			putText(image, to_string(i), br.br(), FONT_HERSHEY_PLAIN,1,Scalar(0,255,0));
		}

		if(confidence > maxConfidence) {
			float h_dist_with_min = hypotf(depth_z_min, _goal_height);                                            //uses pythagorean theorem to determine horizontal distance to goal using minimum
			float h_dist_with_max = hypotf(depth_z_max, _goal_height + _goal_shape.height());                     //this one uses maximum
			float h_dist          = (h_dist_with_max + h_dist_with_min) / 2.0;                                    //average of the two is more accurate
			float goal_to_center_px = ((float)br.tl().x + ((float)br.width / 2.0)) - ((float)image.cols / 2.0);   //number of pixels from center of contour to center of image (e.g. how far off center it is)
			float goal_to_center_deg = _fov_size.x * (goal_to_center_px / (float)image.cols);                     //converts to angle using the field of view
			_dist_to_goal  = h_dist;
			_angle_to_goal = goal_to_center_deg * (180.0 / M_PI);
			_goal_rect     = br;

			maxConfidence = confidence;
			best_contour_index = i;
			_goal_found = true;
		}

		/*vector<string> info;
		info.push_back(to_string(confidence_height));
		info.push_back(to_string(confidence_com_x));
		info.push_back(to_string(confidence_com_y));
		info.push_back(to_string(confidence_area));
		info.push_back(to_string(confidence_ratio));
		info.push_back(to_string(confidence));
		info.push_back(to_string(h_dist));
		info.push_back(to_string(goal_to_center_deg));
		info_writer.log(info); */
	}
	if(_goal_found && _draw)
		rectangle(image, boundingRect(contours[best_contour_index]), Scalar(0,255,0), 2);
}

bool GoalDetector::generateThresholdAddSubtract(const Mat& imageIn, Mat& imageOut)
{
    vector<Mat> splitImage;
    Mat         bluePlusRed;

    split(imageIn, splitImage);
	addWeighted(splitImage[0], _blue_scale / 100.0,
			    splitImage[2], _red_scale / 100.0, 0.0,
				bluePlusRed);
	subtract(splitImage[1], bluePlusRed, imageOut);

    Mat erodeElement(getStructuringElement(MORPH_RECT, Size(3, 3)));
    Mat dilateElement(getStructuringElement(MORPH_ELLIPSE, Size(2, 2)));
    erode(imageOut, imageOut, erodeElement, Point(-1, -1), 2);
    dilate(imageOut, imageOut, dilateElement, Point(-1, -1), 2);

	//adaptiveThreshold(imageOut, imageOut, 255.0, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 11, 2);
	threshold(imageOut, imageOut, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
    return (countNonZero(imageOut) != 0);
}

float GoalDetector::dist_to_goal(void) const
{
 	//floor distance to goal in m
	return _goal_found ? _dist_to_goal : -1.0;
}
float GoalDetector::angle_to_goal(void) const
{
	//angle robot has to turn to face goal in degrees
	return _goal_found ? _angle_to_goal : -1.0;
}

Rect GoalDetector::goal_rect(void) const
{
	return _goal_found ? _goal_rect : Rect();
}

void GoalDetector::draw(bool drawFlag)
{
	_draw = drawFlag;
}

bool GoalDetector::draw(void) const
{
	return _draw;
}
<commit_msg>lowered blue threshold from 50 to 30<commit_after>#include <opencv2/highgui/highgui.hpp>
#include "GoalDetector.hpp"

using namespace std;
using namespace cv;

GoalDetector::GoalDetector(cv::Point2f fov_size, cv::Size frame_size, bool gui) :
	_goal_shape(3)
{
	_goal_found = false;
	_fov_size = fov_size;
	_frame_size = frame_size;
	_draw = false;
	_min_valid_confidence = 0.2;

	_blue_scale = 30;
	_red_scale  = 100;

	if (gui)
	{
		cv::namedWindow("Goal Detect Adjustments", CV_WINDOW_NORMAL);
		createTrackbar("Blue Scale","Goal Detect Adjustments", &_blue_scale, 100);
		createTrackbar("Red Scale","Goal Detect Adjustments", &_red_scale, 100);
	}
}

// Values around 0.5 are good. Values away from that are progressively
// worse.  Wrap stuff above 0.5 around 0.5 so the range
// of values go from 0 (bad) to 0.5 (good).
void GoalDetector::wrapConfidence(float &confidence)
{
	confidence = confidence > 0.5 ? 1 - confidence : confidence;
}

void GoalDetector::processFrame(Mat& image, const Mat& depth)
{
	// Use to mask the contour off from the rest of the
	// image - used when grabbing depth data for the contour
    Mat contour_mask(image.rows, image.cols, CV_8UC1, Scalar(0));

	// Reset goal_found flag for each frame. Set it later if
	// the goal is found
	_goal_found = false;
	_dist_to_goal = -1.0;
	_angle_to_goal = -1.0;
	_goal_rect = Rect(0,0,0,0);

	// Look for parts the the image which are within the
	// expected bright green color range
    Mat threshold_image;
	if (!generateThresholdAddSubtract(image, threshold_image))
		return;

	// find contours in the thresholded image - these will be blobs
	// of green to check later on to see how well they match the
	// expected shape of the goal
    vector<vector<Point> > contours;
    vector<Vec4i>          hierarchy;
    findContours(threshold_image, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    float maxConfidence = _min_valid_confidence;
	//cout << contours.size() << " goalDetect contours found" << endl;

	int best_contour_index;

	//center of mass as a percentage of the object size from top left
	Point2f com_percent_expected(_goal_shape.com().x / _goal_shape.width(),
				     _goal_shape.com().y / _goal_shape.height());

    for (size_t i = 0; i < contours.size(); i++)
    {
	    Rect br = boundingRect(contours[i]);
		contour_mask.setTo(Scalar(0));

		drawContours(contour_mask, contours, i, Scalar(255), CV_FILLED); //create a mask on the contour

		// get the minimum and maximum depth values in the contour,
		// copy them into individual floats
		pair<float, float> minMax = utils::minOfDepthMat(depth, contour_mask, br, 10);
		float depth_z_min = minMax.first;
		float depth_z_max = minMax.second;

		//make sure the depth exists before doing other things
		//also don't bother with targets too close to see (need more exact value here)
		if ((depth_z_min < 1.) || (depth_z_max < 1.))
			continue;

		// ObjectType computes a ton of useful properties so create
		// one for what we're looking at
		ObjectType goal_actual(contours[i]);

		if (goal_actual.area() < 200.0)
			continue;
		//create a trackedobject to get x,y,z of the goal
		TrackedObject goal_tracked_obj(0, _goal_shape, br, minMax.second, _fov_size, _frame_size);

		//percentage of the object filled in
		float filledPercentageActual   = goal_actual.area() / goal_actual.boundingArea();
		float filledPercentageExpected = _goal_shape.area() / _goal_shape.boundingArea();

		//center of mass as a percentage of the object size from top left
		Point2f com_percent_actual((goal_actual.com().x - br.tl().x) / goal_actual.width(),
				           (goal_actual.com().y - br.tl().y) / goal_actual.height());

		//width to height ratio
		float actualRatio   = goal_actual.width() / goal_actual.height();
		float expectedRatio = _goal_shape.width() / _goal_shape.height();

		//parameters for the normal distributions
		//values for standard deviation were determined by taking the standard deviation of a bunch of values from the goal
		pair<float,float> height_normal = make_pair(_goal_height, 0.059273877);
		pair<float,float> com_x_normal  = make_pair(com_percent_expected.x, 0.05157222);
		pair<float,float> com_y_normal  = make_pair(com_percent_expected.y, 0.0439207);
		pair<float,float> area_normal   = make_pair(filledPercentageExpected, 0.057567619);
		pair<float,float> ratio_normal  = make_pair(expectedRatio, 0.537392);
		pair<float,float> ideal_area    = make_pair(1.0, 1.0/3.0);

		//confidence is near 0.5 when value is near the mean
		//confidence is small or large when value is not near mean
		float confidence_height     = utils::normalCFD(height_normal, goal_tracked_obj.getPosition().z);
		float confidence_com_x      = utils::normalCFD(com_x_normal,  com_percent_actual.x);
		float confidence_com_y      = utils::normalCFD(com_y_normal,  com_percent_actual.y);
		float confidence_area       = utils::normalCFD(area_normal,   filledPercentageActual);
		float confidence_ratio      = utils::normalCFD(ratio_normal,  actualRatio);
		float confidence_ideal_area = utils::normalCFD(ideal_area,  (float)br.area() / goal_tracked_obj.getScreenPosition(_fov_size, _frame_size).area());

		// Normalize values between 0 and 0.5
		wrapConfidence(confidence_height);
		wrapConfidence(confidence_com_x);
		wrapConfidence(confidence_com_y);
		wrapConfidence(confidence_area);
		wrapConfidence(confidence_ratio);
		wrapConfidence(confidence_ideal_area);

		// higher is better
		float confidence = (confidence_height + confidence_com_x + confidence_com_y + confidence_area + confidence_ratio + confidence_ideal_area) / 6.0;

#if 0
		cout << "-------------------------------------------" << endl;
		cout << "Contour " << i << endl;
		cout << "confidence_height: " << confidence_height << endl;
		cout << "confidence_com_x: " << confidence_com_x << endl;
		cout << "confidence_com_y: " << confidence_com_y << endl;
		cout << "confidence_area: " << confidence_area << endl;
		cout << "confidence_ratio: " << confidence_ratio << endl;
		cout << "confidence_ideal_area: " << confidence_ideal_area << endl;
		cout << "confidence: " << confidence << endl;
		cout << "-------------------------------------------" << endl;
#endif

		if(_draw) {
			drawContours(image, contours,i,Scalar(0,0,255),3);
			rectangle(image, br, Scalar(255,0,0), 2);
			putText(image, to_string(confidence),br.tl(), FONT_HERSHEY_PLAIN, 1, Scalar(255,0,0));
			putText(image, to_string(i), br.br(), FONT_HERSHEY_PLAIN,1,Scalar(0,255,0));
		}

		if(confidence > maxConfidence) {
			float h_dist_with_min = hypotf(depth_z_min, _goal_height);                                            //uses pythagorean theorem to determine horizontal distance to goal using minimum
			float h_dist_with_max = hypotf(depth_z_max, _goal_height + _goal_shape.height());                     //this one uses maximum
			float h_dist          = (h_dist_with_max + h_dist_with_min) / 2.0;                                    //average of the two is more accurate
			float goal_to_center_px = ((float)br.tl().x + ((float)br.width / 2.0)) - ((float)image.cols / 2.0);   //number of pixels from center of contour to center of image (e.g. how far off center it is)
			float goal_to_center_deg = _fov_size.x * (goal_to_center_px / (float)image.cols);                     //converts to angle using the field of view
			_dist_to_goal  = h_dist;
			_angle_to_goal = goal_to_center_deg * (180.0 / M_PI);
			_goal_rect     = br;

			maxConfidence = confidence;
			best_contour_index = i;
			_goal_found = true;
		}

		/*vector<string> info;
		info.push_back(to_string(confidence_height));
		info.push_back(to_string(confidence_com_x));
		info.push_back(to_string(confidence_com_y));
		info.push_back(to_string(confidence_area));
		info.push_back(to_string(confidence_ratio));
		info.push_back(to_string(confidence));
		info.push_back(to_string(h_dist));
		info.push_back(to_string(goal_to_center_deg));
		info_writer.log(info); */
	}
	if(_goal_found && _draw)
		rectangle(image, boundingRect(contours[best_contour_index]), Scalar(0,255,0), 2);
}

bool GoalDetector::generateThresholdAddSubtract(const Mat& imageIn, Mat& imageOut)
{
    vector<Mat> splitImage;
    Mat         bluePlusRed;

    split(imageIn, splitImage);
	addWeighted(splitImage[0], _blue_scale / 100.0,
			    splitImage[2], _red_scale / 100.0, 0.0,
				bluePlusRed);
	subtract(splitImage[1], bluePlusRed, imageOut);

    Mat erodeElement(getStructuringElement(MORPH_RECT, Size(3, 3)));
    Mat dilateElement(getStructuringElement(MORPH_ELLIPSE, Size(2, 2)));
    erode(imageOut, imageOut, erodeElement, Point(-1, -1), 2);
    dilate(imageOut, imageOut, dilateElement, Point(-1, -1), 2);

	//adaptiveThreshold(imageOut, imageOut, 255.0, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 11, 2);
	threshold(imageOut, imageOut, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
    return (countNonZero(imageOut) != 0);
}

float GoalDetector::dist_to_goal(void) const
{
 	//floor distance to goal in m
	return _goal_found ? _dist_to_goal : -1.0;
}
float GoalDetector::angle_to_goal(void) const
{
	//angle robot has to turn to face goal in degrees
	return _goal_found ? _angle_to_goal : -1.0;
}

Rect GoalDetector::goal_rect(void) const
{
	return _goal_found ? _goal_rect : Rect();
}

void GoalDetector::draw(bool drawFlag)
{
	_draw = drawFlag;
}

bool GoalDetector::draw(void) const
{
	return _draw;
}
<|endoftext|>


<commit_before>#include "BaseAuRegClass.h"
/*
	All right reseved, Ethan Riley.
	:)
*/

std::vector<std::string> Regex_Search_Iterate(std::string input, boost::regex Regex) {

	std::string::const_iterator start = input.begin();
	std::string::const_iterator end = input.end();
	boost::smatch matches;
	std::vector<std::string> tmp;

	while (boost::regex_search(start, end, matches, Regex)) {
		tmp.push_back(std::string(matches[1].first, matches[1].second));

		start = matches[0].second;
	}
	return tmp;
}
bool AutoRegister::ReadClass(bool isClass){
	std::string HeaderFileData;
	while (!HeaderFile.eof()) {
		HeaderFileData.push_back(HeaderFile.get());
	}

	boost::regex RegularExp(R"((\w+)(?=[{]))");
	boost::smatch Results;
	boost::regex_search(HeaderFileData, Results, RegularExp);
	RegData.classname = Results[1];
	std::cout << RegData.classname << std::endl;

	RegularExp.assign(R"(([\w\s\(),\n]+)(?=[;]))");
	std::vector<std::string> functionStrs=Regex_Search_Iterate(HeaderFileData, RegularExp);

	for (unsigned i = 0; i < functionStrs.size(); i++) {
		Function TempFunction;
		RegularExp.assign(R"((\w+)(?=[(]))");
		boost::regex_search(functionStrs[i], Results, RegularExp);
		TempFunction.functioname = Results[0];

		RegularExp.assign(R"(([\w\s]+)(?=[(]))");
		boost::regex_search(functionStrs[i], Results, RegularExp);
		std::string FunctionTillBrackets = Results[0].str();
		FunctionTillBrackets.resize(FunctionTillBrackets.size()-TempFunction.functioname.size());
		TempFunction.returntype = FunctionTillBrackets;

		RegularExp.assign(R"((\w+)(?=[,)]))");
		TempFunction.Argumentypes = Regex_Search_Iterate(functionStrs[i], RegularExp);

		if (isClass) {
			RegularExp.assign(R"((\w+)(?=[,)]))");
			TempFunction.Arguments = Regex_Search_Iterate(functionStrs[i], RegularExp);
		}

		RegData.Functions.push_back(TempFunction);
	}

	return true;
}
bool AutoRegister::WriteArgs(int i) {
	if (RegData.Functions[i].Arguments.size() != 0) {
		for (unsigned b = 0; b < RegData.Functions[i].Arguments.size(); b++) {
			OutputFile << ",  " << RegData.Functions[i].Arguments[i];
		}
	}
	return true;
}
bool AutoRegister::CreateClassSelfFunctions(std::string newNamespaceFilename) {//currently not working
	std::fstream N_OutputFile(newNamespaceFilename + ".h",std::ios::out|std::ios::trunc);
	N_OutputFile << "namespace " << RegData.classname << "{\n";

	for (unsigned i = 0; i < RegData.Functions.size(); i++) {
		N_OutputFile << '\t' <<RegData.Functions[i].returntype << RegData.Functions[i].functioname << "(";
		N_OutputFile << RegData.classname << "* self";
		if (RegData.Functions[i].Arguments.size() != 0) {
			OutputFile << RegData.Functions[i].Arguments[0];
		}
		WriteArgs(i);
		N_OutputFile << ')';

		N_OutputFile << "{ \n\t\treturn" << " self";
		N_OutputFile << "->" << RegData.Functions[i].functioname << '(';
		WriteArgs(i);
		N_OutputFile << ");\n\t}";
	}
	N_OutputFile << "\\END \n}";
	return true;
}

bool AutoRegister::CreateFunctionCalls() {
	OutputFile << "bool RegisterFuncs(VMClassRegistry* registry) {";

	for (unsigned i = 0; i < RegData.Functions.size(); i++) {
		OutputFile << '\n' << "\tregistry->RegisterFunction(" << '\n';

		unsigned RegArgTySize = RegData.Functions[i].Argumentypes.size();
		OutputFile << "\t\tnew NativeFunction" << RegArgTySize << '<' << RegData.classname << ", " << RegData.Functions[i].returntype ;

		for (unsigned b = 0; b < RegArgTySize; b++) {
			OutputFile << ", " << RegData.Functions[i].Argumentypes[b];
		}
		OutputFile << '>';

		OutputFile << '(' << '"' << RegData.Functions[i].functioname << '"' << ", " << '"' << RegData.classname << '"' << ", ";
		OutputFile << RegData.classname << "::" << RegData.Functions[i].functioname << ", " << "registry));\n";
	}
	OutputFile << "\n\treturn true; \n}";
	return true;
}

<commit_msg>added pointer & culy brace newline support, needs boost.<commit_after>#include "BaseAuRegClass.h"
/*
	All right reseved, Ethan Riley.
	:)
*/

std::vector<std::string> Regex_Search_Iterate(std::string input, boost::regex Regex) {

	std::string::const_iterator start = input.begin();
	std::string::const_iterator end = input.end();
	boost::smatch matches;
	std::vector<std::string> tmp;

	while (boost::regex_search(start, end, matches, Regex)) {
		tmp.push_back(std::string(matches[1].first, matches[1].second));

		start = matches[0].second;
	}
	return tmp;
}
bool AutoRegister::ReadClass(bool isClass){
	std::string HeaderFileData;
	while (!HeaderFile.eof()) {
		HeaderFileData.push_back(HeaderFile.get());
	}

	boost::regex RegularExp(R"(([\w\n]+)(?=[{]))");
	boost::smatch Results;
	boost::regex_search(HeaderFileData, Results, RegularExp);
	RegData.classname = Results[1];
	std::cout << RegData.classname << std::endl;

	RegularExp.assign(R"(([\w\s\*\(),\n]+)(?=[)]))");
	std::vector<std::string> functionStrs=Regex_Search_Iterate(HeaderFileData, RegularExp);

	for (unsigned i = 0; i < functionStrs.size(); i++) {
		Function TempFunction;
		RegularExp.assign(R"((\w+)(?=[(]))");
		boost::regex_search(functionStrs[i], Results, RegularExp);
		TempFunction.functioname = Results[0];

		RegularExp.assign(R"(([\w\s\*]+)(?=[(]))");
		boost::regex_search(functionStrs[i], Results, RegularExp);
		std::string FunctionTillBrackets = Results[0].str();
		FunctionTillBrackets.resize(FunctionTillBrackets.size()-TempFunction.functioname.size());
		TempFunction.returntype = FunctionTillBrackets;

		RegularExp.assign(R"(([\w\*]+)(?=[,)]))");
		TempFunction.Argumentypes = Regex_Search_Iterate(functionStrs[i], RegularExp);

		if (isClass) {
			RegularExp.assign(R"(([\w\*]+)(?=[,)]))");
			TempFunction.Arguments = Regex_Search_Iterate(functionStrs[i], RegularExp);
		}

		RegData.Functions.push_back(TempFunction);
	}

	return true;
}
bool AutoRegister::WriteArgs(int i) {
	if (RegData.Functions[i].Arguments.size() != 0) {
		for (unsigned b = 0; b < RegData.Functions[i].Arguments.size(); b++) {
			OutputFile << ",  " << RegData.Functions[i].Arguments[i];
		}
	}
	return true;
}
bool AutoRegister::CreateClassSelfFunctions(std::string newNamespaceFilename) {//currently not working
	std::fstream N_OutputFile(newNamespaceFilename + ".h",std::ios::out|std::ios::trunc);
	N_OutputFile << "namespace " << RegData.classname << "{\n";

	for (unsigned i = 0; i < RegData.Functions.size(); i++) {
		N_OutputFile << '\t' <<RegData.Functions[i].returntype << RegData.Functions[i].functioname << "(";
		N_OutputFile << RegData.classname << "* self";
		if (RegData.Functions[i].Arguments.size() != 0) {
			OutputFile << RegData.Functions[i].Arguments[0];
		}
		WriteArgs(i);
		N_OutputFile << ')';

		N_OutputFile << "{ \n\t\treturn" << " self";
		N_OutputFile << "->" << RegData.Functions[i].functioname << '(';
		WriteArgs(i);
		N_OutputFile << ");\n\t}";
	}
	N_OutputFile << "\\END \n}";
	return true;
}

bool AutoRegister::CreateFunctionCalls() {
	OutputFile << "bool RegisterFuncs(VMClassRegistry* registry) {";

	for (unsigned i = 0; i < RegData.Functions.size(); i++) {
		OutputFile << '\n' << "\tregistry->RegisterFunction(" << '\n';

		unsigned RegArgTySize = RegData.Functions[i].Argumentypes.size();
		OutputFile << "\t\tnew NativeFunction" << RegArgTySize << '<' << RegData.classname << ", " << RegData.Functions[i].returntype ;

		for (unsigned b = 0; b < RegArgTySize; b++) {
			OutputFile << ", " << RegData.Functions[i].Argumentypes[b];
		}
		OutputFile << '>';

		OutputFile << '(' << '"' << RegData.Functions[i].functioname << '"' << ", " << '"' << RegData.classname << '"' << ", ";
		OutputFile << RegData.classname << "::" << RegData.Functions[i].functioname << ", " << "registry));\n";
	}
	OutputFile << "\n\treturn true; \n}";
	return true;
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Compositor.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
**     of its contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "waylandeglclientbufferintegration.h"

#include <QtCompositor/private/qwlcompositor_p.h>
#include <QtCompositor/private/qwlsurface_p.h>
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLContext>
#include <qpa/qplatformscreen.h>
#include <QtGui/QWindow>
#include <QtCore/QPointer>

#include <QDebug>

#include <EGL/egl.h>
#include <EGL/eglext.h>

#ifndef EGL_WL_bind_wayland_display
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_buffer *buffer, EGLint attribute, EGLint *value);
#endif

#ifndef EGL_KHR_image
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
#endif

#ifndef GL_OES_EGL_image
typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
#endif

QT_BEGIN_NAMESPACE

class WaylandEglClientBufferIntegrationPrivate
{
public:
    WaylandEglClientBufferIntegrationPrivate()
        : egl_display(EGL_NO_DISPLAY)
        , valid(false)
        , display_bound(false)
        , egl_bind_wayland_display(0)
        , egl_unbind_wayland_display(0)
        , egl_query_wayland_buffer(0)
        , egl_create_image(0)
        , egl_destroy_image(0)
        , gl_egl_image_target_texture_2d(0)
    { }
    EGLDisplay egl_display;
    bool valid;
    bool display_bound;
    PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display;
    PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display;
    PFNEGLQUERYWAYLANDBUFFERWL egl_query_wayland_buffer;

    PFNEGLCREATEIMAGEKHRPROC egl_create_image;
    PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image;

    PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d;
};

WaylandEglClientBufferIntegration::WaylandEglClientBufferIntegration()
    : QWaylandClientBufferIntegration()
    , d_ptr(new WaylandEglClientBufferIntegrationPrivate)
{
}

void WaylandEglClientBufferIntegration::initializeHardware(QtWayland::Display *waylandDisplay)
{
    Q_D(WaylandEglClientBufferIntegration);

    const bool ignoreBindDisplay = !qgetenv("QT_WAYLAND_IGNORE_BIND_DISPLAY").isEmpty();

    QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
    if (!nativeInterface) {
        qWarning("Failed to initialize egl display. No native platform interface available.\n");
        return;
    }

    d->egl_display = nativeInterface->nativeResourceForWindow("EglDisplay", m_compositor->window());
    if (!d->egl_display) {
        qWarning("Failed to initialize egl display. Could not get EglDisplay for window.\n");
        return;
    }

    const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS);
    if ((!extensionString || !strstr(extensionString, "EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) {
        qWarning("Failed to initialize egl display. There is no EGL_WL_bind_wayland_display extension.\n");
        return;
    }

    d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL"));
    d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL"));
    if ((!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display) && !ignoreBindDisplay) {
        qWarning("Failed to initialize egl display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL.\n");
        return;
    }

    d->egl_query_wayland_buffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL>(eglGetProcAddress("eglQueryWaylandBufferWL"));
    if (!d->egl_query_wayland_buffer) {
        qWarning("Failed to initialize egl display. Could not find eglQueryWaylandBufferWL.\n");
        return;
    }

    d->egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
    d->egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
    if (!d->egl_create_image || !d->egl_destroy_image) {
        qWarning("Failed to initialize egl display. Could not find eglCreateImageKHR and eglDestroyImageKHR.\n");
        return;
    }

    d->gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
    if (!d->gl_egl_image_target_texture_2d) {
        qWarning("Failed to initialize egl display. Could not find glEGLImageTargetTexture2DOES.\n");
        return;
    }

    if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) {
        d->display_bound = d->egl_bind_wayland_display(d->egl_display, waylandDisplay->handle());
        if (!d->display_bound && !ignoreBindDisplay) {
            qWarning("Failed to initialize egl display. Could not bind Wayland display.\n");
            return;
        }
    }

    d->valid = true;

    qWarning("EGL Wayland extension successfully initialized.%s\n", !d->display_bound ? " eglBindWaylandDisplayWL ignored" : "");
}

void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
{
    Q_D(WaylandEglClientBufferIntegration);
    if (!d->valid) {
        qWarning("bindTextureToBuffer() failed");
        return;
    }

    EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT,
                                          EGL_WAYLAND_BUFFER_WL,
                                          buffer, NULL);

    d->gl_egl_image_target_texture_2d(GL_TEXTURE_2D, image);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    d->egl_destroy_image(d->egl_display, image);
}

bool WaylandEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const
{
#if defined(EGL_WAYLAND_Y_INVERTED_WL)
    Q_D(const WaylandEglClientBufferIntegration);

    EGLint isYInverted;
    EGLBoolean ret;
    ret = d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);

    // Yes, this looks strange, but the specification says that EGL_FALSE return
    // value (not supported) should be treated the same as EGL_TRUE return value
    // and EGL_TRUE in value.
    if (ret == EGL_FALSE || isYInverted == EGL_TRUE)
        return true;
#endif

    return QWaylandClientBufferIntegration::isYInverted(buffer);
}

void *WaylandEglClientBufferIntegration::lockNativeBuffer(struct ::wl_resource *buffer, QOpenGLContext *) const
{
    Q_D(const WaylandEglClientBufferIntegration);

    EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT,
                                          EGL_WAYLAND_BUFFER_WL,
                                          buffer, NULL);
    return image;
}

void WaylandEglClientBufferIntegration::unlockNativeBuffer(void *native_buffer, QOpenGLContext *) const
{
    Q_D(const WaylandEglClientBufferIntegration);
    EGLImageKHR image = static_cast<EGLImageKHR>(native_buffer);

    d->egl_destroy_image(d->egl_display, image);
}

QSize WaylandEglClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const
{
    Q_D(const WaylandEglClientBufferIntegration);

    int width, height;
    d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_WIDTH, &width);
    d->egl_query_wayland_buffer(d->egl_display, reinterpret_cast<struct ::wl_buffer *>(buffer), EGL_HEIGHT, &height);

    return QSize(width, height);
}

QT_END_NAMESPACE
<commit_msg>fix compile with Mesa 10.0<commit_after>/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Compositor.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
**     of its contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "waylandeglclientbufferintegration.h"

#include <QtCompositor/private/qwlcompositor_p.h>
#include <QtCompositor/private/qwlsurface_p.h>
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLContext>
#include <qpa/qplatformscreen.h>
#include <QtGui/QWindow>
#include <QtCore/QPointer>

#include <QDebug>

#include <EGL/egl.h>
#include <EGL/eglext.h>

/* Needed for compatibility with Mesa older than 10.0. */
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL_compat) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);

#ifndef EGL_WL_bind_wayland_display
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
#endif

#ifndef EGL_KHR_image
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
#endif

#ifndef GL_OES_EGL_image
typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
#endif

QT_BEGIN_NAMESPACE

class WaylandEglClientBufferIntegrationPrivate
{
public:
    WaylandEglClientBufferIntegrationPrivate()
        : egl_display(EGL_NO_DISPLAY)
        , valid(false)
        , display_bound(false)
        , egl_bind_wayland_display(0)
        , egl_unbind_wayland_display(0)
        , egl_query_wayland_buffer(0)
        , egl_create_image(0)
        , egl_destroy_image(0)
        , gl_egl_image_target_texture_2d(0)
    { }
    EGLDisplay egl_display;
    bool valid;
    bool display_bound;
    PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display;
    PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display;
    PFNEGLQUERYWAYLANDBUFFERWL_compat egl_query_wayland_buffer;

    PFNEGLCREATEIMAGEKHRPROC egl_create_image;
    PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image;

    PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d;
};

WaylandEglClientBufferIntegration::WaylandEglClientBufferIntegration()
    : QWaylandClientBufferIntegration()
    , d_ptr(new WaylandEglClientBufferIntegrationPrivate)
{
}

void WaylandEglClientBufferIntegration::initializeHardware(QtWayland::Display *waylandDisplay)
{
    Q_D(WaylandEglClientBufferIntegration);

    const bool ignoreBindDisplay = !qgetenv("QT_WAYLAND_IGNORE_BIND_DISPLAY").isEmpty();

    QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
    if (!nativeInterface) {
        qWarning("Failed to initialize egl display. No native platform interface available.\n");
        return;
    }

    d->egl_display = nativeInterface->nativeResourceForWindow("EglDisplay", m_compositor->window());
    if (!d->egl_display) {
        qWarning("Failed to initialize egl display. Could not get EglDisplay for window.\n");
        return;
    }

    const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS);
    if ((!extensionString || !strstr(extensionString, "EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) {
        qWarning("Failed to initialize egl display. There is no EGL_WL_bind_wayland_display extension.\n");
        return;
    }

    d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL"));
    d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL"));
    if ((!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display) && !ignoreBindDisplay) {
        qWarning("Failed to initialize egl display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL.\n");
        return;
    }

    d->egl_query_wayland_buffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL_compat>(eglGetProcAddress("eglQueryWaylandBufferWL"));
    if (!d->egl_query_wayland_buffer) {
        qWarning("Failed to initialize egl display. Could not find eglQueryWaylandBufferWL.\n");
        return;
    }

    d->egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
    d->egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
    if (!d->egl_create_image || !d->egl_destroy_image) {
        qWarning("Failed to initialize egl display. Could not find eglCreateImageKHR and eglDestroyImageKHR.\n");
        return;
    }

    d->gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
    if (!d->gl_egl_image_target_texture_2d) {
        qWarning("Failed to initialize egl display. Could not find glEGLImageTargetTexture2DOES.\n");
        return;
    }

    if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) {
        d->display_bound = d->egl_bind_wayland_display(d->egl_display, waylandDisplay->handle());
        if (!d->display_bound && !ignoreBindDisplay) {
            qWarning("Failed to initialize egl display. Could not bind Wayland display.\n");
            return;
        }
    }

    d->valid = true;

    qWarning("EGL Wayland extension successfully initialized.%s\n", !d->display_bound ? " eglBindWaylandDisplayWL ignored" : "");
}

void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
{
    Q_D(WaylandEglClientBufferIntegration);
    if (!d->valid) {
        qWarning("bindTextureToBuffer() failed");
        return;
    }

    EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT,
                                          EGL_WAYLAND_BUFFER_WL,
                                          buffer, NULL);

    d->gl_egl_image_target_texture_2d(GL_TEXTURE_2D, image);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    d->egl_destroy_image(d->egl_display, image);
}

bool WaylandEglClientBufferIntegration::isYInverted(struct ::wl_resource *buffer) const
{
#if defined(EGL_WAYLAND_Y_INVERTED_WL)
    Q_D(const WaylandEglClientBufferIntegration);

    EGLint isYInverted;
    EGLBoolean ret;
    ret = d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);

    // Yes, this looks strange, but the specification says that EGL_FALSE return
    // value (not supported) should be treated the same as EGL_TRUE return value
    // and EGL_TRUE in value.
    if (ret == EGL_FALSE || isYInverted == EGL_TRUE)
        return true;
#endif

    return QWaylandClientBufferIntegration::isYInverted(buffer);
}

void *WaylandEglClientBufferIntegration::lockNativeBuffer(struct ::wl_resource *buffer, QOpenGLContext *) const
{
    Q_D(const WaylandEglClientBufferIntegration);

    EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT,
                                          EGL_WAYLAND_BUFFER_WL,
                                          buffer, NULL);
    return image;
}

void WaylandEglClientBufferIntegration::unlockNativeBuffer(void *native_buffer, QOpenGLContext *) const
{
    Q_D(const WaylandEglClientBufferIntegration);
    EGLImageKHR image = static_cast<EGLImageKHR>(native_buffer);

    d->egl_destroy_image(d->egl_display, image);
}

QSize WaylandEglClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const
{
    Q_D(const WaylandEglClientBufferIntegration);

    int width, height;
    d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &width);
    d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_HEIGHT, &height);

    return QSize(width, height);
}

QT_END_NAMESPACE
<|endoftext|>