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

#include <unotools/atom.hxx>

using namespace utl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
#define NMSP_UTIL ::com::sun::star::util

AtomProvider::AtomProvider()
{
    m_nAtoms = 1;
}

AtomProvider::~AtomProvider()
{
}

int AtomProvider::getAtom( const ::rtl::OUString& rString, sal_Bool bCreate )
{
    ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::iterator it = m_aAtomMap.find( rString );
    if( it != m_aAtomMap.end() )
        return it->second;
    if( ! bCreate )
        return INVALID_ATOM;
    m_aAtomMap[ rString ] = m_nAtoms;
    m_aStringMap[ m_nAtoms ] = rString;
    m_nAtoms++;
    return m_nAtoms-1;
}

void AtomProvider::getAll( ::std::list< ::utl::AtomDescription >& atoms )
{
    atoms.clear();
    ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::const_iterator it = m_aAtomMap.begin();

    ::utl::AtomDescription aDesc;
    while( it != m_aAtomMap.end() )
    {
        aDesc.atom          = it->second;
        aDesc.description   = it->first;
        atoms.push_back( aDesc );
        ++it;
    }
}

void AtomProvider::getRecent( int atom, ::std::list< ::utl::AtomDescription >& atoms )
{
    atoms.clear();

    ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::const_iterator it = m_aAtomMap.begin();

    ::utl::AtomDescription aDesc;
    while( it != m_aAtomMap.end() )
    {
        if( it->second > atom )
        {
            aDesc.atom          = it->second;
            aDesc.description   = it->first;
            atoms.push_back( aDesc );
        }
        ++it;
    }
}

const ::rtl::OUString& AtomProvider::getString( int nAtom ) const
{
    static ::rtl::OUString aEmpty;
    ::std::hash_map< int, ::rtl::OUString, ::std::hash< int > >::const_iterator it = m_aStringMap.find( nAtom );

    return it == m_aStringMap.end() ? aEmpty : it->second;
}

void AtomProvider::overrideAtom( int atom, const ::rtl::OUString& description )
{
    m_aAtomMap[ description ] = atom;
    m_aStringMap[ atom ] = description;
    if( m_nAtoms <= atom )
        m_nAtoms=atom+1;
}

sal_Bool AtomProvider::hasAtom( int atom ) const
{
    return m_aStringMap.find( atom ) != m_aStringMap.end() ? sal_True : sal_False;
}

// -----------------------------------------------------------------------

MultiAtomProvider::MultiAtomProvider()
{
}

MultiAtomProvider::~MultiAtomProvider()
{
    for( ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it = m_aAtomLists.begin(); it != m_aAtomLists.end(); ++it )
        delete it->second;
}

sal_Bool MultiAtomProvider::insertAtomClass( int atomClass )
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it =
          m_aAtomLists.find( atomClass );
    if( it != m_aAtomLists.end() )
        return sal_False;
    m_aAtomLists[ atomClass ] = new AtomProvider();
    return sal_True;
}

int MultiAtomProvider::getAtom( int atomClass, const ::rtl::OUString& rString, sal_Bool bCreate )
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it =
          m_aAtomLists.find( atomClass );
    if( it != m_aAtomLists.end() )
        return it->second->getAtom( rString, bCreate );

    if( bCreate )
    {
        AtomProvider* pNewClass;
        m_aAtomLists[ atomClass ] = pNewClass = new AtomProvider();
        return pNewClass->getAtom( rString, bCreate );
    }
    return INVALID_ATOM;
}

int MultiAtomProvider::getLastAtom( int atomClass ) const
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
          m_aAtomLists.find( atomClass );

    return it != m_aAtomLists.end() ? it->second->getLastAtom() : INVALID_ATOM;
}

void MultiAtomProvider::getRecent( int atomClass, int atom, ::std::list< ::utl::AtomDescription >& atoms )
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
          m_aAtomLists.find( atomClass );
    if( it != m_aAtomLists.end() )
        it->second->getRecent( atom, atoms );
    else
        atoms.clear();
}

const ::rtl::OUString& MultiAtomProvider::getString( int atomClass, int atom ) const
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
          m_aAtomLists.find( atomClass );
    if( it != m_aAtomLists.end() )
        return it->second->getString( atom );

    static ::rtl::OUString aEmpty;
    return aEmpty;
}

sal_Bool MultiAtomProvider::hasAtom( int atomClass, int atom ) const
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );
    return it != m_aAtomLists.end() ? it->second->hasAtom( atom ) : sal_False;
}

void MultiAtomProvider::getClass( int atomClass, ::std::list< ::utl::AtomDescription >& atoms) const
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );

    if( it != m_aAtomLists.end() )
        it->second->getAll( atoms );
    else
        atoms.clear();
}

void MultiAtomProvider::overrideAtom( int atomClass, int atom, const ::rtl::OUString& description )
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );
    if( it == m_aAtomLists.end() )
        m_aAtomLists[ atomClass ] = new AtomProvider();
    m_aAtomLists[ atomClass ]->overrideAtom( atom, description );
}

// -----------------------------------------------------------------------

AtomServer::AtomServer()
{
}

AtomServer::~AtomServer()
{
}

sal_Int32 AtomServer::getAtom( sal_Int32 atomClass, const ::rtl::OUString& description, sal_Bool create )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    return m_aProvider.getAtom( atomClass, description, create );
}

Sequence< Sequence< NMSP_UTIL::AtomDescription > > AtomServer::getClasses( const Sequence< sal_Int32 >& atomClasses )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    Sequence< Sequence< NMSP_UTIL::AtomDescription > > aRet( atomClasses.getLength() );
    for( int i = 0; i < atomClasses.getLength(); i++ )
    {
        aRet.getArray()[i] = getClass( atomClasses.getConstArray()[i] );
    }
    return aRet;
}

Sequence< NMSP_UTIL::AtomDescription > AtomServer::getClass( sal_Int32 atomClass )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    ::std::list< ::utl::AtomDescription > atoms;
    m_aProvider.getClass( atomClass, atoms );

    Sequence< NMSP_UTIL::AtomDescription > aRet( atoms.size() );
    for( int i = aRet.getLength()-1; i >= 0; i-- )
    {
        aRet.getArray()[i].atom         = atoms.back().atom;
        aRet.getArray()[i].description  = atoms.back().description;
        atoms.pop_back();
    }

    return aRet;
}

Sequence< NMSP_UTIL::AtomDescription > AtomServer::getRecentAtoms( sal_Int32 atomClass, sal_Int32 atom )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    ::std::list< ::utl::AtomDescription > atoms;
    m_aProvider.getRecent( atomClass, atom, atoms );

    Sequence< NMSP_UTIL::AtomDescription > aRet( atoms.size() );
    for( int i = aRet.getLength()-1; i >= 0; i-- )
    {
        aRet.getArray()[i].atom         = atoms.back().atom;
        aRet.getArray()[i].description  = atoms.back().description;
        atoms.pop_back();
    }

    return aRet;
}

Sequence< ::rtl::OUString > AtomServer::getAtomDescriptions( const Sequence< AtomClassRequest >& atoms )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    int nStrings = 0, i;
    for( i = 0; i < atoms.getLength(); i++ )
        nStrings += atoms.getConstArray()[ i ].atoms.getLength();
    Sequence< ::rtl::OUString > aRet( nStrings );
    for( i = 0, nStrings = 0; i < atoms.getLength(); i++ )
    {
        const AtomClassRequest& rRequest = atoms.getConstArray()[i];
        for( int n = 0; n < rRequest.atoms.getLength(); n++ )
            aRet.getArray()[ nStrings++ ] = m_aProvider.getString( rRequest.atomClass, rRequest.atoms.getConstArray()[ n ] );
    }
    return aRet;
}

// -----------------------------------------------------------------------

AtomClient::AtomClient( const Reference< XAtomServer >& xServer ) :
        m_xServer( xServer )
{
}

AtomClient::~AtomClient()
{
}

int AtomClient::getAtom( int atomClass, const ::rtl::OUString& description, sal_Bool bCreate )
{
    int nAtom = m_aProvider.getAtom( atomClass, description, sal_False );
    if( nAtom == INVALID_ATOM && bCreate )
    {
        nAtom = m_xServer->getAtom( atomClass, description, bCreate );
        if( nAtom != INVALID_ATOM )
            m_aProvider.overrideAtom( atomClass, nAtom, description );
    }
    return nAtom;
}

const ::rtl::OUString& AtomClient::getString( int atomClass, int atom )
{
    if( ! m_aProvider.hasAtom( atomClass, atom ) )
    {
        Sequence< NMSP_UTIL::AtomDescription > aSeq;
        aSeq = m_xServer->getRecentAtoms( atomClass, m_aProvider.getLastAtom( atomClass ) );
        const NMSP_UTIL::AtomDescription* pDescriptions = aSeq.getConstArray();
        for( int i = 0; i < aSeq.getLength(); i++ )
            m_aProvider.overrideAtom( atomClass,
                                      pDescriptions[i].atom,
                                      pDescriptions[i].description
                                      );

        if( ! m_aProvider.hasAtom( atomClass, atom ) )
        {
            // holes may occur by the above procedure!
            Sequence< AtomClassRequest > aSeq( 1 );
            aSeq.getArray()[0].atomClass = atomClass;
            aSeq.getArray()[0].atoms.realloc( 1 );
            aSeq.getArray()[0].atoms.getArray()[0] = atom;
            Sequence< ::rtl::OUString > aRet = m_xServer->getAtomDescriptions( aSeq );
            if( aRet.getLength() == 1 )
                m_aProvider.overrideAtom( atomClass, atom, aRet.getConstArray()[0] );
        }
    }
    return m_aProvider.getString( atomClass, atom );
}

void AtomClient::updateAtomClasses( const Sequence< sal_Int32 >& atomClasses )
{
    Sequence< Sequence< NMSP_UTIL::AtomDescription > > aUpdate = m_xServer->getClasses( atomClasses );
    for( int i = 0; i < atomClasses.getLength(); i++ )
    {
        int nClass = atomClasses.getConstArray()[i];
        const Sequence< NMSP_UTIL::AtomDescription >& rClass = aUpdate.getConstArray()[i];
        const NMSP_UTIL::AtomDescription* pDesc = rClass.getConstArray();
        for( int n = 0; n < rClass.getLength(); n++, pDesc++ )
            m_aProvider.overrideAtom( nClass, pDesc->atom, pDesc->description );
    }
}
<commit_msg>#89754# catch runtime exceptions<commit_after>/*************************************************************************
 *
 *  $RCSfile: atom.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: ssa $ $Date: 2001-07-18 11:57:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <unotools/atom.hxx>

using namespace utl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
#define NMSP_UTIL ::com::sun::star::util

AtomProvider::AtomProvider()
{
    m_nAtoms = 1;
}

AtomProvider::~AtomProvider()
{
}

int AtomProvider::getAtom( const ::rtl::OUString& rString, sal_Bool bCreate )
{
    ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::iterator it = m_aAtomMap.find( rString );
    if( it != m_aAtomMap.end() )
        return it->second;
    if( ! bCreate )
        return INVALID_ATOM;
    m_aAtomMap[ rString ] = m_nAtoms;
    m_aStringMap[ m_nAtoms ] = rString;
    m_nAtoms++;
    return m_nAtoms-1;
}

void AtomProvider::getAll( ::std::list< ::utl::AtomDescription >& atoms )
{
    atoms.clear();
    ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::const_iterator it = m_aAtomMap.begin();

    ::utl::AtomDescription aDesc;
    while( it != m_aAtomMap.end() )
    {
        aDesc.atom          = it->second;
        aDesc.description   = it->first;
        atoms.push_back( aDesc );
        ++it;
    }
}

void AtomProvider::getRecent( int atom, ::std::list< ::utl::AtomDescription >& atoms )
{
    atoms.clear();

    ::std::hash_map< ::rtl::OUString, int, ::rtl::OUStringHash >::const_iterator it = m_aAtomMap.begin();

    ::utl::AtomDescription aDesc;
    while( it != m_aAtomMap.end() )
    {
        if( it->second > atom )
        {
            aDesc.atom          = it->second;
            aDesc.description   = it->first;
            atoms.push_back( aDesc );
        }
        ++it;
    }
}

const ::rtl::OUString& AtomProvider::getString( int nAtom ) const
{
    static ::rtl::OUString aEmpty;
    ::std::hash_map< int, ::rtl::OUString, ::std::hash< int > >::const_iterator it = m_aStringMap.find( nAtom );

    return it == m_aStringMap.end() ? aEmpty : it->second;
}

void AtomProvider::overrideAtom( int atom, const ::rtl::OUString& description )
{
    m_aAtomMap[ description ] = atom;
    m_aStringMap[ atom ] = description;
    if( m_nAtoms <= atom )
        m_nAtoms=atom+1;
}

sal_Bool AtomProvider::hasAtom( int atom ) const
{
    return m_aStringMap.find( atom ) != m_aStringMap.end() ? sal_True : sal_False;
}

// -----------------------------------------------------------------------

MultiAtomProvider::MultiAtomProvider()
{
}

MultiAtomProvider::~MultiAtomProvider()
{
    for( ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it = m_aAtomLists.begin(); it != m_aAtomLists.end(); ++it )
        delete it->second;
}

sal_Bool MultiAtomProvider::insertAtomClass( int atomClass )
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it =
          m_aAtomLists.find( atomClass );
    if( it != m_aAtomLists.end() )
        return sal_False;
    m_aAtomLists[ atomClass ] = new AtomProvider();
    return sal_True;
}

int MultiAtomProvider::getAtom( int atomClass, const ::rtl::OUString& rString, sal_Bool bCreate )
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::iterator it =
          m_aAtomLists.find( atomClass );
    if( it != m_aAtomLists.end() )
        return it->second->getAtom( rString, bCreate );

    if( bCreate )
    {
        AtomProvider* pNewClass;
        m_aAtomLists[ atomClass ] = pNewClass = new AtomProvider();
        return pNewClass->getAtom( rString, bCreate );
    }
    return INVALID_ATOM;
}

int MultiAtomProvider::getLastAtom( int atomClass ) const
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
          m_aAtomLists.find( atomClass );

    return it != m_aAtomLists.end() ? it->second->getLastAtom() : INVALID_ATOM;
}

void MultiAtomProvider::getRecent( int atomClass, int atom, ::std::list< ::utl::AtomDescription >& atoms )
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
          m_aAtomLists.find( atomClass );
    if( it != m_aAtomLists.end() )
        it->second->getRecent( atom, atoms );
    else
        atoms.clear();
}

const ::rtl::OUString& MultiAtomProvider::getString( int atomClass, int atom ) const
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it =
          m_aAtomLists.find( atomClass );
    if( it != m_aAtomLists.end() )
        return it->second->getString( atom );

    static ::rtl::OUString aEmpty;
    return aEmpty;
}

sal_Bool MultiAtomProvider::hasAtom( int atomClass, int atom ) const
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );
    return it != m_aAtomLists.end() ? it->second->hasAtom( atom ) : sal_False;
}

void MultiAtomProvider::getClass( int atomClass, ::std::list< ::utl::AtomDescription >& atoms) const
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );

    if( it != m_aAtomLists.end() )
        it->second->getAll( atoms );
    else
        atoms.clear();
}

void MultiAtomProvider::overrideAtom( int atomClass, int atom, const ::rtl::OUString& description )
{
    ::std::hash_map< int, AtomProvider*, ::std::hash< int > >::const_iterator it = m_aAtomLists.find( atomClass );
    if( it == m_aAtomLists.end() )
        m_aAtomLists[ atomClass ] = new AtomProvider();
    m_aAtomLists[ atomClass ]->overrideAtom( atom, description );
}

// -----------------------------------------------------------------------

AtomServer::AtomServer()
{
}

AtomServer::~AtomServer()
{
}

sal_Int32 AtomServer::getAtom( sal_Int32 atomClass, const ::rtl::OUString& description, sal_Bool create )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    return m_aProvider.getAtom( atomClass, description, create );
}

Sequence< Sequence< NMSP_UTIL::AtomDescription > > AtomServer::getClasses( const Sequence< sal_Int32 >& atomClasses )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    Sequence< Sequence< NMSP_UTIL::AtomDescription > > aRet( atomClasses.getLength() );
    for( int i = 0; i < atomClasses.getLength(); i++ )
    {
        aRet.getArray()[i] = getClass( atomClasses.getConstArray()[i] );
    }
    return aRet;
}

Sequence< NMSP_UTIL::AtomDescription > AtomServer::getClass( sal_Int32 atomClass )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    ::std::list< ::utl::AtomDescription > atoms;
    m_aProvider.getClass( atomClass, atoms );

    Sequence< NMSP_UTIL::AtomDescription > aRet( atoms.size() );
    for( int i = aRet.getLength()-1; i >= 0; i-- )
    {
        aRet.getArray()[i].atom         = atoms.back().atom;
        aRet.getArray()[i].description  = atoms.back().description;
        atoms.pop_back();
    }

    return aRet;
}

Sequence< NMSP_UTIL::AtomDescription > AtomServer::getRecentAtoms( sal_Int32 atomClass, sal_Int32 atom )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    ::std::list< ::utl::AtomDescription > atoms;
    m_aProvider.getRecent( atomClass, atom, atoms );

    Sequence< NMSP_UTIL::AtomDescription > aRet( atoms.size() );
    for( int i = aRet.getLength()-1; i >= 0; i-- )
    {
        aRet.getArray()[i].atom         = atoms.back().atom;
        aRet.getArray()[i].description  = atoms.back().description;
        atoms.pop_back();
    }

    return aRet;
}

Sequence< ::rtl::OUString > AtomServer::getAtomDescriptions( const Sequence< AtomClassRequest >& atoms )
{
    ::osl::Guard< ::osl::Mutex > guard( m_aMutex );

    int nStrings = 0, i;
    for( i = 0; i < atoms.getLength(); i++ )
        nStrings += atoms.getConstArray()[ i ].atoms.getLength();
    Sequence< ::rtl::OUString > aRet( nStrings );
    for( i = 0, nStrings = 0; i < atoms.getLength(); i++ )
    {
        const AtomClassRequest& rRequest = atoms.getConstArray()[i];
        for( int n = 0; n < rRequest.atoms.getLength(); n++ )
            aRet.getArray()[ nStrings++ ] = m_aProvider.getString( rRequest.atomClass, rRequest.atoms.getConstArray()[ n ] );
    }
    return aRet;
}

// -----------------------------------------------------------------------

AtomClient::AtomClient( const Reference< XAtomServer >& xServer ) :
        m_xServer( xServer )
{
}

AtomClient::~AtomClient()
{
}

int AtomClient::getAtom( int atomClass, const ::rtl::OUString& description, sal_Bool bCreate )
{
    int nAtom = m_aProvider.getAtom( atomClass, description, sal_False );
    if( nAtom == INVALID_ATOM && bCreate )
    {
        try
        {
            nAtom = m_xServer->getAtom( atomClass, description, bCreate );
        }
        catch( RuntimeException& )
        {
            return INVALID_ATOM;
        }
        if( nAtom != INVALID_ATOM )
            m_aProvider.overrideAtom( atomClass, nAtom, description );
    }
    return nAtom;
}

const ::rtl::OUString& AtomClient::getString( int atomClass, int atom )
{
    if( ! m_aProvider.hasAtom( atomClass, atom ) )
    {
        Sequence< NMSP_UTIL::AtomDescription > aSeq;
        try
        {
            aSeq = m_xServer->getRecentAtoms( atomClass, m_aProvider.getLastAtom( atomClass ) );
        }
        catch( RuntimeException& )
        {
            return ::rtl::OUString();
        }
        const NMSP_UTIL::AtomDescription* pDescriptions = aSeq.getConstArray();
        for( int i = 0; i < aSeq.getLength(); i++ )
            m_aProvider.overrideAtom( atomClass,
                                      pDescriptions[i].atom,
                                      pDescriptions[i].description
                                      );

        if( ! m_aProvider.hasAtom( atomClass, atom ) )
        {
            // holes may occur by the above procedure!
            Sequence< AtomClassRequest > aSeq( 1 );
            aSeq.getArray()[0].atomClass = atomClass;
            aSeq.getArray()[0].atoms.realloc( 1 );
            aSeq.getArray()[0].atoms.getArray()[0] = atom;
            Sequence< ::rtl::OUString > aRet;
            try
            {
                aRet = m_xServer->getAtomDescriptions( aSeq );
            }
            catch( RuntimeException& )
            {
                return ::rtl::OUString();
            }
            if( aRet.getLength() == 1 )
                m_aProvider.overrideAtom( atomClass, atom, aRet.getConstArray()[0] );
        }
    }
    return m_aProvider.getString( atomClass, atom );
}

void AtomClient::updateAtomClasses( const Sequence< sal_Int32 >& atomClasses )
{
    Sequence< Sequence< NMSP_UTIL::AtomDescription > > aUpdate;
    try
    {
        aUpdate = m_xServer->getClasses( atomClasses );
    }
    catch( RuntimeException& )
    {
        return;
    }
    for( int i = 0; i < atomClasses.getLength(); i++ )
    {
        int nClass = atomClasses.getConstArray()[i];
        const Sequence< NMSP_UTIL::AtomDescription >& rClass = aUpdate.getConstArray()[i];
        const NMSP_UTIL::AtomDescription* pDesc = rClass.getConstArray();
        for( int n = 0; n < rClass.getLength(); n++, pDesc++ )
            m_aProvider.overrideAtom( nClass, pDesc->atom, pDesc->description );
    }
}
<|endoftext|>


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

/// \file
/// Tests for the LinearSolveAndInverse.cpp functions.

#include <windows.h>
#include <gtest/gtest.h>

#include "SurgSim/Math/LinearSolveAndInverse.h"

namespace SurgSim
{

namespace Math
{

class LinearSolveAndInverseTests : public ::testing::Test
{
private:
	size_t size;

	void initializeVector(Vector* v)
	{
		v->resize(size);
		for (size_t row = 0; row < size; row++)
		{
			(*v)(row) = fmod(-4.1 * row * row + 3.46, 5.0);
		}
	}

	void initializeDenseMatrix(Matrix* m)
	{
		m->resize(size, size);
		for (size_t row = 0; row < size; row++)
		{
			for (size_t col = 0; col < size; col++)
			{
				(*m)(row, col) = fmod((10.3 * cos(static_cast<double>(row * col)) + 3.24), 10.0);
			}
			}
	}

	void initializeDiagonalMatrix(Matrix* m)
	{
		m->resize(size, size);
		m->setZero();
		for (size_t row = 0; row < size; row++)
		{
			(*m)(row, row) = fmod((10.3 * cos(static_cast<double>(row * row)) + 3.24), 10.0);
		}
	}

	template <size_t BlockSize>
	void initializeTriDiagonalBlockMatrix(Matrix* m, bool isSymmetric)
	{
		size_t numBlocks = size / BlockSize;

		m->resize(size, size);
		m->setZero();

		for (size_t rowBlockId = 0; rowBlockId < numBlocks; rowBlockId++)
		{
			for (int colBlockId = static_cast<int>(rowBlockId) - 1;
				colBlockId <= static_cast<int>(rowBlockId) + 1;
				colBlockId++)
			{
				if (colBlockId < 0 || colBlockId >= static_cast<int>(numBlocks))
				{
					continue;
				}

				for (size_t rowInBlockId = 0; rowInBlockId < BlockSize; ++rowInBlockId)
				{
					for (size_t colInBlockId = 0; colInBlockId < BlockSize; ++colInBlockId)
					{
						size_t row = rowBlockId * BlockSize + rowInBlockId;
						size_t col = colBlockId * BlockSize + colInBlockId;
						(*m)(row, col) = fmod((10.3 * cos(static_cast<double>(row * col)) + 3.24), 10.0);
					}
				}
			}
		}

		if (isSymmetric)
		{
			// Force symmetry (lower triangular is copied from the upper triangular)
			for (size_t row = 0; row < size; ++row)
			{
				for (size_t col = row + 1; col < size; ++col)
				{
					(*m)(col, row) = (*m)(row, col);
				}
			}
		}
	}

	void setupTest()
	{
		initializeVector(&b);
		expectedInverse = matrix.inverse();
		expectedX = expectedInverse * b;
	}

public:

	void setupDenseMatrixTest()
	{
		size = 18;
		initializeDenseMatrix(&matrix);
		setupTest();
	}

	void setupDiagonalMatrixTest()
	{
		size = 18;
		initializeDiagonalMatrix(&matrix);
		setupTest();
	}

	template <size_t BlockSize>
	void setupTriDiagonalBlockMatrixTest(bool isSymmetric = false)
	{
		size = BlockSize * 6;
		initializeTriDiagonalBlockMatrix<BlockSize>(&matrix, isSymmetric);
		setupTest();
	}

	Matrix matrix;
	Matrix inverseMatrix, expectedInverse;
	Vector b;
	Vector x, expectedX;
};

TEST_F(LinearSolveAndInverseTests, DenseMatrixTests)
{
	setupDenseMatrixTest();

	LinearSolveAndInverseDenseMatrix solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, DiagonalMatrixTests)
{
	setupDiagonalMatrixTest();

	LinearSolveAndInverseDiagonalMatrix solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize2Tests)
{
	setupTriDiagonalBlockMatrixTest<2>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<2> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize3Tests)
{
	setupTriDiagonalBlockMatrixTest<3>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<3> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize4Tests)
{
	setupTriDiagonalBlockMatrixTest<4>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<4> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize5Tests)
{
	setupTriDiagonalBlockMatrixTest<5>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<5> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize6Tests)
{
	setupTriDiagonalBlockMatrixTest<6>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<6> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize2Tests)
{
	setupTriDiagonalBlockMatrixTest<2>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<2> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize3Tests)
{
	setupTriDiagonalBlockMatrixTest<3>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<3> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize4Tests)
{
	setupTriDiagonalBlockMatrixTest<4>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<4> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize5Tests)
{
	setupTriDiagonalBlockMatrixTest<5>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<5> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize6Tests)
{
	setupTriDiagonalBlockMatrixTest<6>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<6> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};
}; // namespace Math

}; // namespace SurgSim
<commit_msg>Clean up unnecessary #include <windows.h><commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// \file
/// Tests for the LinearSolveAndInverse.cpp functions.

#include <gtest/gtest.h>

#include "SurgSim/Math/LinearSolveAndInverse.h"

namespace SurgSim
{

namespace Math
{

class LinearSolveAndInverseTests : public ::testing::Test
{
private:
	size_t size;

	void initializeVector(Vector* v)
	{
		v->resize(size);
		for (size_t row = 0; row < size; row++)
		{
			(*v)(row) = fmod(-4.1 * row * row + 3.46, 5.0);
		}
	}

	void initializeDenseMatrix(Matrix* m)
	{
		m->resize(size, size);
		for (size_t row = 0; row < size; row++)
		{
			for (size_t col = 0; col < size; col++)
			{
				(*m)(row, col) = fmod((10.3 * cos(static_cast<double>(row * col)) + 3.24), 10.0);
			}
			}
	}

	void initializeDiagonalMatrix(Matrix* m)
	{
		m->resize(size, size);
		m->setZero();
		for (size_t row = 0; row < size; row++)
		{
			(*m)(row, row) = fmod((10.3 * cos(static_cast<double>(row * row)) + 3.24), 10.0);
		}
	}

	template <size_t BlockSize>
	void initializeTriDiagonalBlockMatrix(Matrix* m, bool isSymmetric)
	{
		size_t numBlocks = size / BlockSize;

		m->resize(size, size);
		m->setZero();

		for (size_t rowBlockId = 0; rowBlockId < numBlocks; rowBlockId++)
		{
			for (int colBlockId = static_cast<int>(rowBlockId) - 1;
				colBlockId <= static_cast<int>(rowBlockId) + 1;
				colBlockId++)
			{
				if (colBlockId < 0 || colBlockId >= static_cast<int>(numBlocks))
				{
					continue;
				}

				for (size_t rowInBlockId = 0; rowInBlockId < BlockSize; ++rowInBlockId)
				{
					for (size_t colInBlockId = 0; colInBlockId < BlockSize; ++colInBlockId)
					{
						size_t row = rowBlockId * BlockSize + rowInBlockId;
						size_t col = colBlockId * BlockSize + colInBlockId;
						(*m)(row, col) = fmod((10.3 * cos(static_cast<double>(row * col)) + 3.24), 10.0);
					}
				}
			}
		}

		if (isSymmetric)
		{
			// Force symmetry (lower triangular is copied from the upper triangular)
			for (size_t row = 0; row < size; ++row)
			{
				for (size_t col = row + 1; col < size; ++col)
				{
					(*m)(col, row) = (*m)(row, col);
				}
			}
		}
	}

	void setupTest()
	{
		initializeVector(&b);
		expectedInverse = matrix.inverse();
		expectedX = expectedInverse * b;
	}

public:

	void setupDenseMatrixTest()
	{
		size = 18;
		initializeDenseMatrix(&matrix);
		setupTest();
	}

	void setupDiagonalMatrixTest()
	{
		size = 18;
		initializeDiagonalMatrix(&matrix);
		setupTest();
	}

	template <size_t BlockSize>
	void setupTriDiagonalBlockMatrixTest(bool isSymmetric = false)
	{
		size = BlockSize * 6;
		initializeTriDiagonalBlockMatrix<BlockSize>(&matrix, isSymmetric);
		setupTest();
	}

	Matrix matrix;
	Matrix inverseMatrix, expectedInverse;
	Vector b;
	Vector x, expectedX;
};

TEST_F(LinearSolveAndInverseTests, DenseMatrixTests)
{
	setupDenseMatrixTest();

	LinearSolveAndInverseDenseMatrix solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, DiagonalMatrixTests)
{
	setupDiagonalMatrixTest();

	LinearSolveAndInverseDiagonalMatrix solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize2Tests)
{
	setupTriDiagonalBlockMatrixTest<2>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<2> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize3Tests)
{
	setupTriDiagonalBlockMatrixTest<3>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<3> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize4Tests)
{
	setupTriDiagonalBlockMatrixTest<4>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<4> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize5Tests)
{
	setupTriDiagonalBlockMatrixTest<5>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<5> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, TriDiagonalBlockMatrixBlockSize6Tests)
{
	setupTriDiagonalBlockMatrixTest<6>();

	LinearSolveAndInverseTriDiagonalBlockMatrix<6> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize2Tests)
{
	setupTriDiagonalBlockMatrixTest<2>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<2> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize3Tests)
{
	setupTriDiagonalBlockMatrixTest<3>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<3> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize4Tests)
{
	setupTriDiagonalBlockMatrixTest<4>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<4> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize5Tests)
{
	setupTriDiagonalBlockMatrixTest<5>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<5> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};

TEST_F(LinearSolveAndInverseTests, SymmetricTriDiagonalBlockMatrixBlockSize6Tests)
{
	setupTriDiagonalBlockMatrixTest<6>(true);

	LinearSolveAndInverseSymmetricTriDiagonalBlockMatrix<6> solveAndInverse;
	solveAndInverse.setMatrix(matrix);
	x = solveAndInverse.solve(b);
	inverseMatrix = solveAndInverse.getInverse();

	EXPECT_TRUE(x.isApprox(expectedX));
	EXPECT_TRUE(inverseMatrix.isApprox(expectedInverse));
};
}; // namespace Math

}; // namespace SurgSim
<|endoftext|>


<commit_before>#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofSetLogLevel(OF_LOG_VERBOSE);
    //disable vertical Sync is too bad with light sometimes
    ofSetVerticalSync(true);
    ofSetFrameRate(60);
    ofBackground(10, 10, 10);
    ofEnableAntiAliasing();
    ofEnableDepthTest();

    displaceSphere.setPosition(-550, 0, -500);
    displaceSphere.setRadius(150);
    displaceSphere.setResolution(50);

    alphaBlendSphere.setPosition(0, 0, -500);
    alphaBlendSphere.setRadius(150);
    alphaBlendSphere.setResolution(50);

    colorKeySphere.setPosition(550, 0, -500);
    colorKeySphere.setRadius(150);
    colorKeySphere.setResolution(50);
    colorKeySphere.rotate(90, 1.0f, 0.0f, 0.0f);

    directional.setDirectional();
    directional.setOrientation( ofVec3f(0, 230, 0) );

    colormap.loadImage("earth.jpg");
    bumpmap.loadImage("earth-bumps.jpg");
    blendMap.loadImage("clouds.jpg");
    colorKeyMap.loadImage("colorkey.gif");

    displaceSphere.mapTexCoordsFromTexture(colormap.getTextureReference());
    alphaBlendSphere.mapTexCoordsFromTexture(colormap.getTextureReference());
    colorKeySphere.mapTexCoordsFromTexture(colormap.getTextureReference());

    target = 0; // First target at the center sphere
    bShowHelp = true;
}

//--------------------------------------------------------------
void ofApp::update(){
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofBackground(ofColor::lightBlue);
    cam.begin();

    // DISPLACE SHADER

    displaceShader.setColormap(&colormap);
    displaceShader.setDisplaceMap(&bumpmap);
    if (target == 2) {
        displaceShader.setMaximumHeight(mouseX);
    }
    // Actually mandatory only in OpenGL 3.3 - don't do it if ofIsGLProgrammableRenderer() == false
    if (!ofIsGLProgrammableRenderer()) {
        const ofMatrix4x4 normalMatrix = ofMatrix4x4::getTransposedOf(cam.getModelViewMatrix().getInverse());
        displaceShader.setNormalMatrix(normalMatrix);
    }
    displaceShader.begin();
    displaceSphere.draw();
    displaceShader.end();

    // ALPHA BLENDING SHADER

    alphaBlendShader.setColormap(&colormap);
    alphaBlendShader.setAlphaBlendMap(&blendMap);
    if (target == 0) {
        const float blendAlpha = ofMap(mouseX, 0.0f, ofGetWidth() - 1, 0.0f, 1.0f);
        alphaBlendShader.setBlendAlpha(blendAlpha);
    }
    alphaBlendShader.begin();
    alphaBlendSphere.draw();
    alphaBlendShader.end();

    // COLOR KEY SHADER

    colorKeyShader.setColormap(&colormap);
    colorKeyShader.setColorKeyMap(&colorKeyMap);
    colorKeyShader.setKeyColor(ofFloatColor(1.0f, 0.0f, 0.0f, 1.0f));
    colorKeyShader.begin();
    colorKeySphere.draw();
    colorKeyShader.end();

    cam.end();

    if (bShowHelp) {
        string shaderName;
        if (target == 0) {
            shaderName = "Alpha Blending Shader";
            cam.setTarget(alphaBlendSphere.getPosition());
        } else if (target == 1) {
            shaderName = "Color Key Shader";
            cam.setTarget(colorKeySphere.getPosition());
        } else if (target == 2) {
            shaderName = "Displacement Shader";
            cam.setTarget(displaceSphere.getPosition());
        }
        ofSetColor(ofColor::black);
        ofDrawBitmapString(string("Move your mouse to trigger changes on target (except color key)\nTarget (T): " + shaderName + "\n" +
                           "Show/Hide help (E)"),
                           20, 20);
    }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    switch (key) {
        case 'e':
            bShowHelp = !bShowHelp;
            break;
        case 't':
            target = (target + 1) % 3;
            break;
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>Finish removing deprecated functions in example Mapping project<commit_after>#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofSetLogLevel(OF_LOG_VERBOSE);
    //disable vertical Sync is too bad with light sometimes
    ofSetVerticalSync(true);
    ofSetFrameRate(60);
    ofBackground(10, 10, 10);
    ofEnableAntiAliasing();
    ofEnableDepthTest();

    displaceSphere.setPosition(-550, 0, -500);
    displaceSphere.setRadius(150);
    displaceSphere.setResolution(50);

    alphaBlendSphere.setPosition(0, 0, -500);
    alphaBlendSphere.setRadius(150);
    alphaBlendSphere.setResolution(50);

    colorKeySphere.setPosition(550, 0, -500);
    colorKeySphere.setRadius(150);
    colorKeySphere.setResolution(50);
    colorKeySphere.rotate(90, 1.0f, 0.0f, 0.0f);

    directional.setDirectional();
    directional.setOrientation( ofVec3f(0, 230, 0) );

    colormap.load("earth.jpg");
    bumpmap.load("earth-bumps.jpg");
    blendMap.load("clouds.jpg");
    colorKeyMap.load("colorkey.gif");

    displaceSphere.mapTexCoordsFromTexture(colormap.getTexture());
    alphaBlendSphere.mapTexCoordsFromTexture(colormap.getTexture());
    colorKeySphere.mapTexCoordsFromTexture(colormap.getTexture());

    target = 0; // First target at the center sphere
    bShowHelp = true;
}

//--------------------------------------------------------------
void ofApp::update(){
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofBackground(ofColor::lightBlue);
    cam.begin();

    // DISPLACE SHADER

    displaceShader.setColormap(&colormap);
    displaceShader.setDisplaceMap(&bumpmap);
    if (target == 2) {
        displaceShader.setMaximumHeight(mouseX);
    }
    // Actually mandatory only in OpenGL 3.3 - don't do it if ofIsGLProgrammableRenderer() == false
    if (!ofIsGLProgrammableRenderer()) {
        const ofMatrix4x4 normalMatrix = ofMatrix4x4::getTransposedOf(cam.getModelViewMatrix().getInverse());
        displaceShader.setNormalMatrix(normalMatrix);
    }
    displaceShader.begin();
    displaceSphere.draw();
    displaceShader.end();

    // ALPHA BLENDING SHADER

    alphaBlendShader.setColormap(&colormap);
    alphaBlendShader.setAlphaBlendMap(&blendMap);
    if (target == 0) {
        const float blendAlpha = ofMap(mouseX, 0.0f, ofGetWidth() - 1, 0.0f, 1.0f);
        alphaBlendShader.setBlendAlpha(blendAlpha);
    }
    alphaBlendShader.begin();
    alphaBlendSphere.draw();
    alphaBlendShader.end();

    // COLOR KEY SHADER

    colorKeyShader.setColormap(&colormap);
    colorKeyShader.setColorKeyMap(&colorKeyMap);
    colorKeyShader.setKeyColor(ofFloatColor(1.0f, 0.0f, 0.0f, 1.0f));
    colorKeyShader.begin();
    colorKeySphere.draw();
    colorKeyShader.end();

    cam.end();

    if (bShowHelp) {
        string shaderName;
        if (target == 0) {
            shaderName = "Alpha Blending Shader";
            cam.setTarget(alphaBlendSphere.getPosition());
        } else if (target == 1) {
            shaderName = "Color Key Shader";
            cam.setTarget(colorKeySphere.getPosition());
        } else if (target == 2) {
            shaderName = "Displacement Shader";
            cam.setTarget(displaceSphere.getPosition());
        }
        ofSetColor(ofColor::black);
        ofDrawBitmapString(string("Move your mouse to trigger changes on target (except color key)\nTarget (T): " + shaderName + "\n" +
                           "Show/Hide help (E)"),
                           20, 20);
    }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    switch (key) {
        case 'e':
            bShowHelp = !bShowHelp;
            break;
        case 't':
            target = (target + 1) % 3;
            break;
    }
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>


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

#include "SurgSim/Physics/DeformableCollisionRepresentation.h"

#include "SurgSim/Framework/Component.h"
#include "SurgSim/Framework/FrameworkConvert.h"
#include "SurgSim/DataStructures/TriangleMesh.h"
#include "SurgSim/Physics/DeformableRepresentation.h"
#include "SurgSim/Math/MeshShape.h"
#include "SurgSim/Math/Shape.h"

namespace
{
SURGSIM_REGISTER(SurgSim::Framework::Component, SurgSim::Physics::DeformableCollisionRepresentation);
}

namespace SurgSim
{
namespace Physics
{
DeformableCollisionRepresentation::DeformableCollisionRepresentation(const std::string& name) :
	SurgSim::Collision::Representation(name)
{

}

DeformableCollisionRepresentation::~DeformableCollisionRepresentation()
{
}

void DeformableCollisionRepresentation::setMesh(std::shared_ptr<SurgSim::DataStructures::TriangleMesh> mesh)
{
	SURGSIM_ASSERT(!isInitialized()) << "Can't set mesh after initialization.";
	SURGSIM_ASSERT(mesh != nullptr) << "Can't use nullptr mesh.";
	m_shape = std::make_shared<SurgSim::Math::MeshShape>(*mesh);
	m_mesh = mesh;
}

std::shared_ptr<SurgSim::DataStructures::TriangleMesh> DeformableCollisionRepresentation::getMesh() const
{
	return m_mesh;
}

void DeformableCollisionRepresentation::update(const double& dt)
{
	SURGSIM_ASSERT(!m_deformable.expired()) << "Deformable has expired, cannot update the mesh.";
	auto state = m_deformable.lock()->getCurrentState();

	const size_t numNodes = state->getNumNodes();

	SURGSIM_ASSERT(m_mesh->getNumVertices() == numNodes) << "The number of nodes in the deformable does not match " <<
			"the number of vertices in the mesh.";

	for (size_t nodeId = 0; nodeId < numNodes; ++nodeId)
	{
		m_mesh->setVertexPosition(nodeId, state->getPosition(nodeId));
	}
}

bool DeformableCollisionRepresentation::doInitialize()
{
	SURGSIM_ASSERT(m_mesh != nullptr) << "Mesh was not set.";
	SURGSIM_ASSERT(!m_deformable.expired()) << "Can't startup without a deformable.";

	auto state = m_deformable.lock()->getCurrentState();
	SURGSIM_ASSERT(m_mesh->getNumVertices() == state->getNumNodes()) <<
			"The number of nodes in the deformable does not match " <<
			"the number of vertices in the mesh.";

	update(0.0);
	return true;
}

int DeformableCollisionRepresentation::getShapeType() const
{
	SURGSIM_ASSERT(m_shape != nullptr) << "No mesh or shape assigned to DeformableCollisionRepresentation " <<
									   getName();
	return m_shape->getType();
}

void DeformableCollisionRepresentation::setShape(std::shared_ptr<SurgSim::Math::Shape> shape)
{
	SURGSIM_ASSERT(shape->getType() == SurgSim::Math::SHAPE_TYPE_MESH) <<
			"Deformable collision shape has to be a mesh." <<
			" currently " << m_shape->getType();

	auto meshShape = std::dynamic_pointer_cast<SurgSim::Math::MeshShape>(shape);
	m_mesh = meshShape->getMesh();

}

void DeformableCollisionRepresentation::setInitialPose(const SurgSim::Math::RigidTransform3d& pose)
{
	SURGSIM_FAILURE() << "The initial pose cannot be set";
}

const SurgSim::Math::RigidTransform3d& DeformableCollisionRepresentation::getInitialPose() const
{
	SURGSIM_ASSERT(m_deformable.expired()) <<
										   "Cannot get the initial pose because the deformable was not initialized.";
	return m_deformable.lock()->getInitialPose();
}

void DeformableCollisionRepresentation::setPose(const SurgSim::Math::RigidTransform3d& pose)
{
	SURGSIM_FAILURE() << "The pose cannot be set";
}

const SurgSim::Math::RigidTransform3d& DeformableCollisionRepresentation::getPose() const
{
	SURGSIM_ASSERT(m_deformable.expired()) << "Cannot get the pose because the deformable was not initialized.";
	return m_deformable.lock()->getInitialPose();
}

const std::shared_ptr<SurgSim::Math::Shape> DeformableCollisionRepresentation::getShape() const
{
	return m_shape;
}

void DeformableCollisionRepresentation::setDeformableRepresentation(
	std::shared_ptr<SurgSim::Physics::DeformableRepresentationBase>representation)
{
	m_deformable = representation;
}

}
}

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

#include "SurgSim/Physics/DeformableCollisionRepresentation.h"

#include "SurgSim/Framework/Component.h"
#include "SurgSim/Framework/FrameworkConvert.h"
#include "SurgSim/DataStructures/TriangleMesh.h"
#include "SurgSim/Physics/DeformableRepresentation.h"
#include "SurgSim/Math/MeshShape.h"
#include "SurgSim/Math/Shape.h"

namespace
{
SURGSIM_REGISTER(SurgSim::Framework::Component, SurgSim::Physics::DeformableCollisionRepresentation);
}

namespace SurgSim
{
namespace Physics
{
DeformableCollisionRepresentation::DeformableCollisionRepresentation(const std::string& name) :
	SurgSim::Collision::Representation(name)
{

}

DeformableCollisionRepresentation::~DeformableCollisionRepresentation()
{
}

void DeformableCollisionRepresentation::setMesh(std::shared_ptr<SurgSim::DataStructures::TriangleMesh> mesh)
{
	SURGSIM_ASSERT(!isInitialized()) << "Can't set mesh after initialization.";
	SURGSIM_ASSERT(mesh != nullptr) << "Can't use nullptr mesh.";
	m_shape = std::make_shared<SurgSim::Math::MeshShape>(*mesh);
	m_mesh = mesh;
}

std::shared_ptr<SurgSim::DataStructures::TriangleMesh> DeformableCollisionRepresentation::getMesh() const
{
	return m_mesh;
}

void DeformableCollisionRepresentation::update(const double& dt)
{
	SURGSIM_ASSERT(!m_deformable.expired()) << "Deformable has expired, cannot update the mesh.";
	auto state = m_deformable.lock()->getCurrentState();

	const size_t numNodes = state->getNumNodes();

	SURGSIM_ASSERT(m_mesh->getNumVertices() == numNodes) << "The number of nodes in the deformable does not match " <<
			"the number of vertices in the mesh.";

	for (size_t nodeId = 0; nodeId < numNodes; ++nodeId)
	{
		m_mesh->setVertexPosition(nodeId, state->getPosition(nodeId));
	}
}

bool DeformableCollisionRepresentation::doInitialize()
{
	SURGSIM_ASSERT(m_mesh != nullptr) << "Mesh was not set.";
	SURGSIM_ASSERT(!m_deformable.expired()) << "Can't startup without a deformable.";

	auto state = m_deformable.lock()->getCurrentState();
	SURGSIM_ASSERT(m_mesh->getNumVertices() == state->getNumNodes()) <<
			"The number of nodes in the deformable does not match " <<
			"the number of vertices in the mesh.";

	update(0.0);
	return true;
}

int DeformableCollisionRepresentation::getShapeType() const
{
	SURGSIM_ASSERT(m_shape != nullptr) << "No mesh or shape assigned to DeformableCollisionRepresentation " <<
									   getName();
	return m_shape->getType();
}

void DeformableCollisionRepresentation::setShape(std::shared_ptr<SurgSim::Math::Shape> shape)
{
	SURGSIM_ASSERT(shape->getType() == SurgSim::Math::SHAPE_TYPE_MESH) <<
			"Deformable collision shape has to be a mesh." <<
			" currently " << m_shape->getType();

	auto meshShape = std::dynamic_pointer_cast<SurgSim::Math::MeshShape>(shape);
	m_mesh = meshShape->getMesh();

}

void DeformableCollisionRepresentation::setInitialPose(const SurgSim::Math::RigidTransform3d& pose)
{
	SURGSIM_FAILURE() << "The initial pose cannot be set";
}

const SurgSim::Math::RigidTransform3d& DeformableCollisionRepresentation::getInitialPose() const
{
	SURGSIM_ASSERT(m_deformable.expired()) <<
										   "Cannot get the initial pose because the deformable was not initialized.";
	return m_deformable.lock()->getInitialPose();
}

void DeformableCollisionRepresentation::setPose(const SurgSim::Math::RigidTransform3d& pose)
{
	SURGSIM_FAILURE() << "The pose cannot be set";
}

const SurgSim::Math::RigidTransform3d& DeformableCollisionRepresentation::getPose() const
{
	SURGSIM_ASSERT(m_deformable.expired()) << "Cannot get the pose because the deformable was not initialized.";
	return m_deformable.lock()->getInitialPose();
}

const std::shared_ptr<SurgSim::Math::Shape> DeformableCollisionRepresentation::getShape() const
{
	return m_shape;
}

void DeformableCollisionRepresentation::setDeformableRepresentation(
	std::shared_ptr<SurgSim::Physics::DeformableRepresentationBase>representation)
{
	m_deformable = representation;
}

const std::shared_ptr<SurgSim::Physics::DeformableRepresentationBase>
	DeformableCollisionRepresentation::getDeformableRepresentation() const
{
	SURGSIM_ASSERT(m_deformable.expired())
		<< "Cannot get the deformable representation because it was not initialized.";
	return m_deformable.lock();
}

}
}

<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkExceptionObject.h"
#include <iostream>
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbExtractROI.h"

int otbImageFileReaderRADComplexShort(int argc, char* argv[])
{
  // Verify the number of parameters in the command line
  const char * inputFilename  = argv[1];
  const char * outputFilename = argv[2];
/*
  typedef std::complex<short>  	                        InputPixelType;
  typedef std::complex<short>                 		OutputPixelType;
  const   unsigned int        	                        Dimension = 2;

  typedef otb::Image< InputPixelType,  Dimension >        InputImageType;
  typedef otb::Image< OutputPixelType, Dimension >        OutputImageType;

  typedef otb::ImageFileReader< InputImageType  >         ReaderType;
  typedef otb::ImageFileWriter< OutputImageType >         WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( inputFilename  );
  writer->SetFileName( outputFilename );

  writer->SetInput( reader->GetOutput() );
  writer->Update();
   */
  return EXIT_SUCCESS;
}

<commit_msg>ENH. Update Testing for RAD format<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkExceptionObject.h"
#include <iostream>
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbExtractROI.h"

int otbImageFileReaderRADComplexShort(int argc, char* argv[])
{
  // Verify the number of parameters in the command line
  const char * inputFilename  = argv[1];
  const char * outputFilename = argv[2];

  typedef int                           InputPixelType;
  typedef int                 		OutputPixelType;

  const   unsigned int        	                        Dimension = 2;

  typedef otb::Image< InputPixelType,  Dimension >        InputImageType;
  typedef otb::Image< OutputPixelType, Dimension >        OutputImageType;

  typedef otb::ImageFileReader< InputImageType  >         ReaderType;
  typedef otb::ImageFileWriter< OutputImageType >         WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName( inputFilename  );
  writer->SetFileName( outputFilename );

  writer->SetInput( reader->GetOutput() );
  writer->Update();

  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include <UnitTest11.hpp>
#include <UnitTest11/TestFixtureRunner.hpp>

namespace ut11
{
	namespace Utility
	{
		template<> struct ParseToString<ut11::Output*>
		{
			inline std::string operator()(ut11::Output* value) const
			{
				std::stringstream stream;
				stream << value;
				return stream.str();
			}
		};
	}
}

namespace
{
	class FakeOutput : public ut11::Output
	{
	public:
		virtual ~FakeOutput() { }

		MockAction(Begin)
		MockAction(Finish, std::size_t, std::size_t)

		MockAction(BeginFixture, std::string)
		MockAction(EndFixture, std::string)

		MockAction(BeginGiven, std::string)
		MockAction(EndGiven, std::string)

		MockAction(BeginWhen, std::string)
		MockAction(EndWhen, std::string)

		MockAction(BeginThen, std::string)
		MockAction(EndThen, std::string)

		MockAction(BeginFinally, std::string)
		MockAction(EndFinally, std::string)

		MockAction(OnError, std::size_t, std::string, std::string)
		MockAction(OnUnknownError)

		ut11::Mock<void (std::exception)> mockOnError1;
		virtual void OnError(const std::exception& ex) { mockOnError1(ex); }
	};

	class FakeTestFixture : public ut11::TestFixtureAbstract
	{
	private:
		ut11::TestFixtureResults m_runResults;

	public:
		ut11::Output* RunOutputUsed;

		FakeTestFixture(ut11::TestFixtureResults runResults)
			: m_runResults(runResults), RunOutputUsed(nullptr)
		{
		}

        MockAction(Given, std::string, std::function<void(void)>);
        MockAction(When, std::string, std::function<void(void)>);
        MockAction(Then, std::string, std::function<void(void)>);
        MockAction(Finally, std::string, std::function<void(void)>);

        MockFunction(std::string, GetName);

        virtual ut11::TestFixtureResults Run(ut11::Output& output)
        {
        	RunOutputUsed = &output;
        	return m_runResults;
        }
	};
}

class TestFixtureRunnerTests : public ut11::TestFixture
{
private:
    ut11::TestFixtureRunner m_runner;
    FakeOutput m_output;

    int m_expectedResult;
    int m_result;

public:
    virtual void Run()
    {
        Given("a TestFixtureRunner with added Fixture with failing tests", [&]() {
            m_runner = ut11::TestFixtureRunner();

            ut11::TestFixtureResults fixtureResults;
            fixtureResults.ran = 5;
            fixtureResults.succeeded = 3;
            m_expectedResult = 2;

            FakeTestFixture* fixture = new FakeTestFixture(fixtureResults);
            fixture->mockGetName.SetReturn("name");

            m_runner.AddFixture(std::unique_ptr<ut11::TestFixtureAbstract>(fixture));

        });
        When("running the TestFixtureRunner", [&]() {
            m_result = m_runner.Run(m_output);
        });
        Then("the number of failing tests is returned", [&]() {
            AssertThat(m_result, ut11::Is::EqualTo(m_expectedResult));
        });
    }
};
DeclareFixture(TestFixtureRunnerTests);

class TestFixtureRunnerMultipleFixturesTests : public ut11::TestFixture
{
private:
	ut11::TestFixtureRunner m_runner;
    FakeOutput m_output;
    FakeTestFixture* m_fixtureOne;
    FakeTestFixture* m_fixtureTwo;

public:
	virtual void Run()
	{
		Given("a TestFixtureRunner where two fixtures with the same names are added", [&]() {
			m_runner = ut11::TestFixtureRunner();
			m_output = FakeOutput();

			m_fixtureOne = new FakeTestFixture(ut11::TestFixtureResults());
			m_fixtureTwo = new FakeTestFixture(ut11::TestFixtureResults());

			m_fixtureOne->mockGetName.SetReturn("name");
			m_fixtureTwo->mockGetName.SetReturn("name");

			m_runner.AddFixture(std::unique_ptr<ut11::TestFixtureAbstract>(m_fixtureOne));
			m_runner.AddFixture(std::unique_ptr<ut11::TestFixtureAbstract>(m_fixtureTwo));
		});
		When("Running the test fixture runner", [&]() {
			m_runner.Run(m_output);
		});
		Then("only the first test fixture is ran", [&]() {
			AssertThat(m_fixtureOne->RunOutputUsed, ut11::Is::Not::Null);
			AssertThat(m_fixtureTwo->RunOutputUsed, ut11::Is::Null);
		});
	}
};
<commit_msg>Adds handling of multiple fixtures with same name in code<commit_after>#include <UnitTest11.hpp>
#include <UnitTest11/TestFixtureRunner.hpp>

namespace ut11
{
	namespace Utility
	{
		template<> struct ParseToString<ut11::Output*>
		{
			inline std::string operator()(ut11::Output* value) const
			{
				std::stringstream stream;
				stream << value;
				return stream.str();
			}
		};
	}
}

namespace
{
	class FakeOutput : public ut11::Output
	{
	public:
		virtual ~FakeOutput() { }

		MockAction(Begin)
		MockAction(Finish, std::size_t, std::size_t)

		MockAction(BeginFixture, std::string)
		MockAction(EndFixture, std::string)

		MockAction(BeginGiven, std::string)
		MockAction(EndGiven, std::string)

		MockAction(BeginWhen, std::string)
		MockAction(EndWhen, std::string)

		MockAction(BeginThen, std::string)
		MockAction(EndThen, std::string)

		MockAction(BeginFinally, std::string)
		MockAction(EndFinally, std::string)

		MockAction(OnError, std::size_t, std::string, std::string)
		MockAction(OnUnknownError)

		ut11::Mock<void (std::exception)> mockOnError1;
		virtual void OnError(const std::exception& ex) { mockOnError1(ex); }
	};

	class FakeTestFixture : public ut11::TestFixtureAbstract
	{
	private:
		ut11::TestFixtureResults m_runResults;

	public:
		ut11::Output* RunOutputUsed;

		FakeTestFixture(ut11::TestFixtureResults runResults)
			: m_runResults(runResults), RunOutputUsed(nullptr)
		{
		}

        MockAction(Given, std::string, std::function<void(void)>);
        MockAction(When, std::string, std::function<void(void)>);
        MockAction(Then, std::string, std::function<void(void)>);
        MockAction(Finally, std::string, std::function<void(void)>);

        MockFunction(std::string, GetName);

        virtual ut11::TestFixtureResults Run(ut11::Output& output)
        {
        	RunOutputUsed = &output;
        	return m_runResults;
        }
	};
}

class TestFixtureRunnerTests : public ut11::TestFixture
{
private:
    ut11::TestFixtureRunner m_runner;
    FakeOutput m_output;

    int m_expectedResult;
    int m_result;

public:
    virtual void Run()
    {
        Given("a TestFixtureRunner with added Fixture with failing tests", [&]() {
            m_runner = ut11::TestFixtureRunner();

            ut11::TestFixtureResults fixtureResults;
            fixtureResults.ran = 5;
            fixtureResults.succeeded = 3;
            m_expectedResult = 2;

            FakeTestFixture* fixture = new FakeTestFixture(fixtureResults);
            fixture->mockGetName.SetReturn("name");

            m_runner.AddFixture(std::unique_ptr<ut11::TestFixtureAbstract>(fixture));

        });
        When("running the TestFixtureRunner", [&]() {
            m_result = m_runner.Run(m_output);
        });
        Then("the number of failing tests is returned", [&]() {
            AssertThat(m_result, ut11::Is::EqualTo(m_expectedResult));
        });
    }
};
DeclareFixture(TestFixtureRunnerTests);

class TestFixtureRunnerMultipleFixturesTests : public ut11::TestFixture
{
private:
	ut11::TestFixtureRunner m_runner;
    FakeOutput m_output;
    FakeTestFixture* m_fixtureOne;
    FakeTestFixture* m_fixtureTwo;

public:
	virtual void Run()
	{
		Given("a TestFixtureRunner where two fixtures with the same names are added", [&]() {
			m_runner = ut11::TestFixtureRunner();
			m_output = FakeOutput();

			m_fixtureOne = new FakeTestFixture(ut11::TestFixtureResults());
			m_fixtureTwo = new FakeTestFixture(ut11::TestFixtureResults());

			m_fixtureOne->mockGetName.SetReturn("name");
			m_fixtureTwo->mockGetName.SetReturn("name");

			m_runner.AddFixture(std::unique_ptr<ut11::TestFixtureAbstract>(m_fixtureOne));
			m_runner.AddFixture(std::unique_ptr<ut11::TestFixtureAbstract>(m_fixtureTwo));
		});
		When("Running the test fixture runner", [&]() {
			m_runner.Run(m_output);
		});
		Then("only the first test fixture is ran", [&]() {
			AssertThat(m_fixtureOne->RunOutputUsed, ut11::Is::Not::Null);
			AssertThat(m_fixtureTwo->RunOutputUsed, ut11::Is::Null);
		});
	}
};
DeclareFixture(TestFixtureRunnerMultipleFixturesTests);
<|endoftext|>


<commit_before>#ifndef ORM_QUERYSET_HPP
#define ORM_QUERYSET_HPP

#include <ORM/backends/Filter.hpp>
#include <ORM/core/Cache.hpp>

namespace orm
{
    template<typename T> class SQLObject;

    template <typename T>
    class QuerySet
    {
        public:
            QuerySet(QuerySet<T>&& tmp);

            template<typename U,typename ... Args>
            QuerySet<T>& filter(const U& value,const std::string& operande,const std::string& colum,const Args& ... args);
            QuerySet<T>& filter(const std::list<Filter>& filter_list);
            QuerySet<T>& filter(std::list<Filter>&& filter_list);

            QuerySet<T>& orderBy(const std::string& colum);
            QuerySet<T>& orderBy(std::string&& colum);
            //QuerySet& orderBy(int,const std::string& colum);

            template<typename U,typename ... Args>
            QuerySet<T>& exclude(const U& value,const std::string& operande,const std::string& colum,const Args& ... args);
            QuerySet<T>& exclude(const std::list<Filter>& exclude_list);
            QuerySet<T>& exclude(std::list<Filter>&& exclude_list);

            QuerySet<T>& limit(const unsigned int& max);
            QuerySet<T>& limit(const unsigned int& min,const unsigned int& max);

            //QuerySet& agregate();

            bool get(T& obj,int max_depth=ORM_DEFAULT_MAX_DEPTH);
            //bool get(typename std::list<Cache<T>::type_ptr>& obj,int max_depth=ORM_DEFAULT_MAX_DEPTH);

            void __print__() const;

        private:
            friend class SQLObject<T>;

            explicit QuerySet();

            template<typename ... Args>
            static std::string makeColumName(const std::string& prefix,const std::string& colum,Args&& ... args);
            template<typename ... Args>
            static std::string makeColumName(std::string&& prefix,std::string&& colum,Args&& ... args);
            static std::string makeColumName(std::string colum);

            Query* makeQuery(int max_depth);

            QuerySet(const QuerySet&) = delete;
            QuerySet& operator=(const QuerySet&) = delete;

            std::list<Filter> filters;
            std::list<Filter> excludes;
            std::vector<std::string> order_by;
            int limit_min,limit_max;

    };
}
#include <ORM/backends/private/QuerySet.tpl>
#endif
<commit_msg>add doc to QuerySet<commit_after>#ifndef ORM_QUERYSET_HPP
#define ORM_QUERYSET_HPP

#include <ORM/backends/Filter.hpp>
#include <ORM/core/Cache.hpp>

namespace orm
{
    template<typename T> class SQLObject;

    /**
     * \brief A class that allow you to make query on the type T
     *
     * Note : T must be a SQLObject
     *
     * \see SQLObject
     **/
    template <typename T>
    class QuerySet
    {
        public:
            /**
             * \brief Construct a QuerySet from a tmp value
             *
             * \param tmp the tmp value to use
             *
             * Note : tmp as an undefined status after the call of this function
             **/
            QuerySet(QuerySet<T>&& tmp);

            /**
             * \brief Construct a filter to apply in the query
             *
             * \param value The value to compare with
             * \param The operator to use see Bdd::Operators for detail
             * \param colum The colum to apply the comparasion
             * \param args If more than one collum is send, all colum will be concatenate (with the correct format) to create the correct colum name. Args must be std::string
             * \return *this
             **/
            template<typename U,typename ... Args>
            QuerySet<T>& filter(const U& value,const std::string& operande,const std::string& colum,const Args& ... args);

            /**
             * \brief Add some filters to apply in the query
             *
             * \param filter_list some Filter to apply to the query.
             *
             * \return *this
             **/
            QuerySet<T>& filter(const std::list<Filter>& filter_list);

            /**
             * \brief Add some filters to apply in the query from a tmp value
             *
             * \param filter_list some Filter to apply to the query.
             *
             * \return *this
             *
             * Note : filter_list as an undefined status after the call of this function
             **/
            QuerySet<T>& filter(std::list<Filter>&& filter_list);

            /**
             * \brief Add a order by constrait to the query
             *
             * \param colum The colum to use for ordering
             *
             * \return *this;
             **/
            QuerySet<T>& orderBy(const std::string& colum);

            /**
             * \brief Add a order by constrait to the query
             *
             * \param colum The colum to use for ordering
             *
             * \return *this;
             **/
            QuerySet<T>& orderBy(std::string&& colum);
            //QuerySet& orderBy(int,const std::string& colum);

            /**
             * \brief Add a negatide filter to the query
             *
             * \param value The value to compare with
             * \param The operator to use see Bdd::Operators for detail
             * \param colum The colum to apply the comparasion
             * \param args If more than one collum is send, all colum will be concatenate (with the correct format) to create the correct colum name. Args must be std::string
             *
             * \return *this
             **/
            template<typename U,typename ... Args>
            QuerySet<T>& exclude(const U& value,const std::string& operande,const std::string& colum,const Args& ... args);

            /**
             * \brief Add some negative filters to apply in the query
             *
             * \param filter_list some Filter to apply to the query.
             *
             * \return *this
             **/
            QuerySet<T>& exclude(const std::list<Filter>& exclude_list);

            /**
             * \brief Add some negative filters to apply in the query
             *
             * \param filter_list some Filter to apply to the query.
             *
             * \return *this
             **/
            QuerySet<T>& exclude(std::list<Filter>&& exclude_list);

            /**
             * \brief Add a limite of the number of object return by the dbtabase
             *
             * \param max Maximun number of object
             *
             * \return *this
             **/
            QuerySet<T>& limit(const unsigned int& max);

            /**
             * \brief Add a limite of the number of object return by the dbtabase.
             *
             * .limite(2,5) will return in maximun 3 (5-2) objects after the execution of the query.
             *
             * \param min Minimal range of object
             * \param max Maximun range of object
             *
             *
             *
             * \return *this
             **/
            QuerySet<T>& limit(const unsigned int& min,const unsigned int& max);

            //QuerySet& agregate();

            /**
             * \brief Execute tho query and return the coresponding object
             *
             * \param obj Where the result will be stored. If mor than one object are return by the databse, only the fist is construct
             * \param max_depth the maximun recursion depth for the object construction (for fk)
             *
             * \return false if no object match with the query.
             **/
            bool get(T& obj,int max_depth=ORM_DEFAULT_MAX_DEPTH);
            //bool get(typename std::list<Cache<T>::type_ptr>& obj,int max_depth=ORM_DEFAULT_MAX_DEPTH);

            /**
             * \brief Print the content of the filter for debug help
             **/
            void __print__() const;

        private:
            friend class SQLObject<T>;

            /**
             * \brief Construct a empty QuerySet
             **/
            explicit QuerySet();

            /**
             * \brief Merge colum name to build the alias
             *
             * \param prefix The prefix colum alias
             * \param colum  The colum alias to merge
             * \param args Some optional colum alias
             *
             * \return the complet alias
             **/
            template<typename ... Args>
            static std::string makeColumName(const std::string& prefix,const std::string& colum,Args&& ... args);

            /**
             * \brief Merge colum name to build the alias
             *
             * \param prefix The prefix colum alias
             * \param colum  The colum alias to merge
             * \param args Some optional colum alias
             *
             * \return the complet alias
             **/
            template<typename ... Args>
            static std::string makeColumName(std::string&& prefix,std::string&& colum,Args&& ... args);

            /**
             * \brief Do nothing
             *
             * \param colum  The colum alias to merge
             *
             * \return colum
             **/
            static std::string makeColumName(std::string colum);

            /**
             * \brief Construct the query with all constraints
             *
             * \param max_depth Maximun depth of recursion in join (if object have FK only)
             *
             * \return NULL if fail or the query to use in othe case
             **/
            Query* makeQuery(int max_depth);

            QuerySet(const QuerySet&) = delete;
            QuerySet& operator=(const QuerySet&) = delete;

            std::list<Filter> filters; ///< Store all the filters
            std::list<Filter> excludes;///< Store all the negative filters
            std::vector<std::string> order_by; ///< store the colum name for ordering
            int limit_min, ///< minimun limite (default is none)
                limit_max; ///< maximun limite (default is none)
    };
}
#include <ORM/backends/private/QuerySet.tpl>
#endif
<|endoftext|>


<commit_before>#include "babylon/babylon_imgui/babylon_studio_layout.h"

#include "imgui_internal.h"
#include "imgui_utils/app_runner/imgui_runner.h"
#include "imgui_utils/icons_font_awesome_5.h"

namespace BABYLON {

BabylonStudioLayout::BabylonStudioLayout()
{
  _dockableWindowsInfos = {
    {DockableWindowId::Scene3d, {ICON_FA_CUBE " 3D Scene", true}},
    {DockableWindowId::SampleBrowser, {ICON_FA_PALETTE " Browse samples", true}},
    {DockableWindowId::SamplesCodeViewer, {ICON_FA_EDIT " Samples Code Viewer", true}},
#ifdef BABYLON_BUILD_PLAYGROUND
    {DockableWindowId::PlaygroundEditor, {ICON_FA_FLASK " Playground", true}},
#endif
    {DockableWindowId::Logs, {ICON_FA_STREAM " Logs", true}},
    {DockableWindowId::Inspector, {ICON_FA_EDIT " Inspector", true}},
  };
}

std::vector<BABYLON::DockableWindowId> BabylonStudioLayout::dockableWindowsList()
{
  std::vector<DockableWindowId> r;
  for (const auto& kv : _dockableWindowsInfos) {
    r.push_back(kv.first);
  }
  return r;
}

void BabylonStudioLayout::registerGuiRenderFunction(DockableWindowId id, GuiRenderFunction fn)
{
  _dockableWindowsInfos.at(id).RenderFunction = fn;
}

void BabylonStudioLayout::renderGui()
{
  for (const auto& kv : _dockableWindowsInfos) {
    const DockableWindowInfo& dockableWindowInfo = kv.second;
    if (dockableWindowInfo.RenderFunction && dockableWindowInfo.IsVisible) {
      bool visible = true;
      ImGui::Begin(dockableWindowInfo.Label.c_str(), &visible);
      dockableWindowInfo.RenderFunction();
      ImGui::End();
      setVisible(kv.first, visible);
    }
  }
}

void BabylonStudioLayout::renderMenu()
{
  if (ImGui::BeginMenu("Layout")) {
    static std::map<LayoutMode, std::string> layoutModeLabels{
      {LayoutMode::Scene, ICON_FA_CUBE " Scene"},
      {LayoutMode::SceneAndBrowser, ICON_FA_CUBES " Scene and Samples Browser"},
      {LayoutMode::Dev, ICON_FA_FILE_CODE " Dev"},
    };
    for (const auto& kv : layoutModeLabels) {
      if (ImGui::MenuItem(kv.second.c_str(), "", _layoutMode == kv.first)) {
        _layoutMode = kv.first;
        ApplyLayoutMode(_layoutMode);
      }
    }
    ImGui::EndMenu();
  }

  if (ImGui::BeginMenu("Windows")) {
    for (const auto& kv : _dockableWindowsInfos) {
      const DockableWindowInfo& dockableWindowInfo = kv.second;
      auto id                                      = kv.first;
      if (dockableWindowInfo.RenderFunction) {
        if (ImGui::MenuItem(dockableWindowInfo.Label.c_str(), "", isVisible(id)))
          setVisible(id, !isVisible(id));
      }
    }
    ImGui::EndMenu();
  }
}

bool BabylonStudioLayout::isVisible(DockableWindowId id)
{
  return _dockableWindowsInfos.at(id).IsVisible;
}

void BabylonStudioLayout::setVisible(DockableWindowId id, bool v)
{
  _dockableWindowsInfos.at(id).IsVisible = v;
}

std::string BabylonStudioLayout::Label(DockableWindowId id)
{
  return _dockableWindowsInfos.at(id).Label;
}

const char* BabylonStudioLayout::Label_c(DockableWindowId id)
{
  return _dockableWindowsInfos.at(id).Label.c_str();
}

void BabylonStudioLayout::DoDock(DockableWindowId id, ImGuiID dockId)
{
  ImGui::DockBuilderDockWindow(Label_c(id), dockId);
}

ImGuiID BabylonStudioLayout::DoSplit(ImGuiID* io_dockToSplit, ImGuiDir_ splitDirection, float ratio)
{
  ImGuiID new_dock
    = ImGui::DockBuilderSplitNode(*io_dockToSplit, splitDirection, ratio, NULL, io_dockToSplit);
  return new_dock;
}

bool BabylonStudioLayout::IsShowingSceneOnly()
{
  if (!isVisible(DockableWindowId::Scene3d))
    return false;
  for (auto id : dockableWindowsList())
    if (isVisible(id) && id != DockableWindowId::Scene3d)
      return false;
  return true;
}

void BabylonStudioLayout::PrepareLayout(ImGuiID fullDockSpaceId)
{
  ImGuiViewport* viewport = ImGui::GetMainViewport();
  ImGui::DockBuilderRemoveNode(fullDockSpaceId); // Clear out existing layout
  ImGui::DockBuilderAddNode(fullDockSpaceId);    // Add empty node
  ImGui::DockBuilderSetNodeSize(fullDockSpaceId, viewport->Size);

  ImGuiID dock_main_id = fullDockSpaceId;
  ImGuiID dock_id_bottom = DoSplit(&dock_main_id, ImGuiDir_Down, 0.25f);
  ImGuiID dock_id_left = DoSplit(&dock_main_id, ImGuiDir_Left, 0.30f);
  ImGuiID dock_id_right = DoSplit(&dock_main_id, ImGuiDir_Right, 0.45f);

#ifdef BABYLON_BUILD_PLAYGROUND
  DoDock(DockableWindowId::PlaygroundEditor, dock_main_id);
#endif
  DoDock(DockableWindowId::SamplesCodeViewer, dock_main_id);

  if (_layoutMode == LayoutMode::Dev) {
    DoDock(DockableWindowId::Inspector, dock_main_id);
    DoDock(DockableWindowId::SampleBrowser, dock_main_id);
  }
  else {
    DoDock(DockableWindowId::Inspector, dock_id_left);
    DoDock(DockableWindowId::SampleBrowser, dock_id_left);
  }

  DoDock(DockableWindowId::Scene3d, dock_id_right);
  DoDock(DockableWindowId::Logs, dock_id_bottom);

  ImGui::DockBuilderFinish(fullDockSpaceId);
}

void BabylonStudioLayout::FocusWindow(DockableWindowId id)
{
  ImGuiWindow* window = ImGui::FindWindowByName(Label_c(id));
  ImGui::FocusWindow(window);
}

void BabylonStudioLayout::ApplyLayoutMode(LayoutMode mode)
{
  _layoutMode = mode;
  switch (_layoutMode) {

    case LayoutMode::Scene:
      for (auto id : dockableWindowsList())
        setVisible(id, false);
      setVisible(DockableWindowId::Scene3d, true);
      break;

    case LayoutMode::SceneAndBrowser:
      setVisible(DockableWindowId::Scene3d, true);
      setVisible(DockableWindowId::Inspector, false);
      setVisible(DockableWindowId::SampleBrowser, true);
      setVisible(DockableWindowId::SamplesCodeViewer, false);
      setVisible(DockableWindowId::PlaygroundEditor, false);
      setVisible(DockableWindowId::Logs, false);
      break;

    case LayoutMode::Dev:
      for (auto id : dockableWindowsList())
        setVisible(id, true);
      break;
    default:
      break;
  }
  ImGuiUtils::ImGuiRunner::ResetDockLayout();
}

} // namespace BABYLON
<commit_msg>babylon_studio_layout: handle cases when playground is not available<commit_after>#include "babylon/babylon_imgui/babylon_studio_layout.h"

#include "imgui_internal.h"
#include "imgui_utils/app_runner/imgui_runner.h"
#include "imgui_utils/icons_font_awesome_5.h"

namespace BABYLON {

BabylonStudioLayout::BabylonStudioLayout()
{
  _dockableWindowsInfos = {
    {DockableWindowId::Scene3d, {ICON_FA_CUBE " 3D Scene", true}},
    {DockableWindowId::SampleBrowser, {ICON_FA_PALETTE " Browse samples", true}},
    {DockableWindowId::SamplesCodeViewer, {ICON_FA_EDIT " Samples Code Viewer", true}},
#ifdef BABYLON_BUILD_PLAYGROUND
    {DockableWindowId::PlaygroundEditor, {ICON_FA_FLASK " Playground", true}},
#endif
    {DockableWindowId::Logs, {ICON_FA_STREAM " Logs", true}},
    {DockableWindowId::Inspector, {ICON_FA_EDIT " Inspector", true}},
  };
}

std::vector<BABYLON::DockableWindowId> BabylonStudioLayout::dockableWindowsList()
{
  std::vector<DockableWindowId> r;
  for (const auto& kv : _dockableWindowsInfos) {
    r.push_back(kv.first);
  }
  return r;
}

void BabylonStudioLayout::registerGuiRenderFunction(DockableWindowId id, GuiRenderFunction fn)
{
  _dockableWindowsInfos.at(id).RenderFunction = fn;
}

void BabylonStudioLayout::renderGui()
{
  for (const auto& kv : _dockableWindowsInfos) {
    const DockableWindowInfo& dockableWindowInfo = kv.second;
    if (dockableWindowInfo.RenderFunction && dockableWindowInfo.IsVisible) {
      bool visible = true;
      ImGui::Begin(dockableWindowInfo.Label.c_str(), &visible);
      dockableWindowInfo.RenderFunction();
      ImGui::End();
      setVisible(kv.first, visible);
    }
  }
}

void BabylonStudioLayout::renderMenu()
{
  if (ImGui::BeginMenu("Layout")) {
    static std::map<LayoutMode, std::string> layoutModeLabels{
      {LayoutMode::Scene, ICON_FA_CUBE " Scene"},
      {LayoutMode::SceneAndBrowser, ICON_FA_CUBES " Scene and Samples Browser"},
      {LayoutMode::Dev, ICON_FA_FILE_CODE " Dev"},
    };
    for (const auto& kv : layoutModeLabels) {
      if (ImGui::MenuItem(kv.second.c_str(), "", _layoutMode == kv.first)) {
        _layoutMode = kv.first;
        ApplyLayoutMode(_layoutMode);
      }
    }
    ImGui::EndMenu();
  }

  if (ImGui::BeginMenu("Windows")) {
    for (const auto& kv : _dockableWindowsInfos) {
      const DockableWindowInfo& dockableWindowInfo = kv.second;
      auto id                                      = kv.first;
      if (dockableWindowInfo.RenderFunction) {
        if (ImGui::MenuItem(dockableWindowInfo.Label.c_str(), "", isVisible(id)))
          setVisible(id, !isVisible(id));
      }
    }
    ImGui::EndMenu();
  }
}

bool BabylonStudioLayout::isVisible(DockableWindowId id)
{
  return _dockableWindowsInfos.at(id).IsVisible;
}

void BabylonStudioLayout::setVisible(DockableWindowId id, bool v)
{
  _dockableWindowsInfos.at(id).IsVisible = v;
}

std::string BabylonStudioLayout::Label(DockableWindowId id)
{
  return _dockableWindowsInfos.at(id).Label;
}

const char* BabylonStudioLayout::Label_c(DockableWindowId id)
{
  return _dockableWindowsInfos.at(id).Label.c_str();
}

void BabylonStudioLayout::DoDock(DockableWindowId id, ImGuiID dockId)
{
  ImGui::DockBuilderDockWindow(Label_c(id), dockId);
}

ImGuiID BabylonStudioLayout::DoSplit(ImGuiID* io_dockToSplit, ImGuiDir_ splitDirection, float ratio)
{
  ImGuiID new_dock
    = ImGui::DockBuilderSplitNode(*io_dockToSplit, splitDirection, ratio, NULL, io_dockToSplit);
  return new_dock;
}

bool BabylonStudioLayout::IsShowingSceneOnly()
{
  if (!isVisible(DockableWindowId::Scene3d))
    return false;
  for (auto id : dockableWindowsList())
    if (isVisible(id) && id != DockableWindowId::Scene3d)
      return false;
  return true;
}

void BabylonStudioLayout::PrepareLayout(ImGuiID fullDockSpaceId)
{
  ImGuiViewport* viewport = ImGui::GetMainViewport();
  ImGui::DockBuilderRemoveNode(fullDockSpaceId); // Clear out existing layout
  ImGui::DockBuilderAddNode(fullDockSpaceId);    // Add empty node
  ImGui::DockBuilderSetNodeSize(fullDockSpaceId, viewport->Size);

  ImGuiID dock_main_id = fullDockSpaceId;
  ImGuiID dock_id_bottom = DoSplit(&dock_main_id, ImGuiDir_Down, 0.25f);
  ImGuiID dock_id_left = DoSplit(&dock_main_id, ImGuiDir_Left, 0.30f);
  ImGuiID dock_id_right = DoSplit(&dock_main_id, ImGuiDir_Right, 0.45f);

#ifdef BABYLON_BUILD_PLAYGROUND
  DoDock(DockableWindowId::PlaygroundEditor, dock_main_id);
#endif
  DoDock(DockableWindowId::SamplesCodeViewer, dock_main_id);

  if (_layoutMode == LayoutMode::Dev) {
    DoDock(DockableWindowId::Inspector, dock_main_id);
    DoDock(DockableWindowId::SampleBrowser, dock_main_id);
  }
  else {
    DoDock(DockableWindowId::Inspector, dock_id_left);
    DoDock(DockableWindowId::SampleBrowser, dock_id_left);
  }

  DoDock(DockableWindowId::Scene3d, dock_id_right);
  DoDock(DockableWindowId::Logs, dock_id_bottom);

  ImGui::DockBuilderFinish(fullDockSpaceId);
}

void BabylonStudioLayout::FocusWindow(DockableWindowId id)
{
  ImGuiWindow* window = ImGui::FindWindowByName(Label_c(id));
  ImGui::FocusWindow(window);
}

void BabylonStudioLayout::ApplyLayoutMode(LayoutMode mode)
{
  _layoutMode = mode;
  switch (_layoutMode) {

    case LayoutMode::Scene:
      for (auto id : dockableWindowsList())
        setVisible(id, false);
      setVisible(DockableWindowId::Scene3d, true);
      break;

    case LayoutMode::SceneAndBrowser:
      setVisible(DockableWindowId::Scene3d, true);
      setVisible(DockableWindowId::Inspector, false);
      setVisible(DockableWindowId::SampleBrowser, true);
      setVisible(DockableWindowId::SamplesCodeViewer, false);
#ifdef BABYLON_BUILD_PLAYGROUND
      setVisible(DockableWindowId::PlaygroundEditor, false);
#endif
      setVisible(DockableWindowId::Logs, false);
      break;

    case LayoutMode::Dev:
      for (auto id : dockableWindowsList())
        setVisible(id, true);
      break;
    default:
      break;
  }
  ImGuiUtils::ImGuiRunner::ResetDockLayout();
}

} // namespace BABYLON
<|endoftext|>


<commit_before>//
// Copyright (c) 2017 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//
#include "CorLib.h"

HRESULT Library_corlib_native_System_Diagnostics_Debugger::get_IsAttached___STATIC__BOOLEAN( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    NANOCLR_HEADER();

#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)

    stack.SetResult_Boolean( CLR_EE_DBG_IS( SourceLevelDebugging ));

#else

    stack.SetResult_Boolean( false );

#endif

    NANOCLR_NOCLEANUP_NOLABEL();
}

HRESULT Library_corlib_native_System_Diagnostics_Debugger::Break___STATIC__VOID( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    NANOCLR_HEADER();

#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)

    if(stack.m_customState == 0)
    {
        stack.m_customState++;
        g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Break( &stack );

        hr = CLR_E_RESCHEDULE;  NANOCLR_LEAVE();
    }

    NANOCLR_NOCLEANUP();

#else

    NANOCLR_NOCLEANUP_NOLABEL();

#endif

}
<commit_msg>Fix potential issue with Diagnostics_Debugger::Break<commit_after>//
// Copyright (c) 2017 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//
#include "CorLib.h"

HRESULT Library_corlib_native_System_Diagnostics_Debugger::get_IsAttached___STATIC__BOOLEAN( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    NANOCLR_HEADER();

#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)

    stack.SetResult_Boolean( CLR_EE_DBG_IS( SourceLevelDebugging ));

#else

    stack.SetResult_Boolean( false );

#endif

    NANOCLR_NOCLEANUP_NOLABEL();
}

HRESULT Library_corlib_native_System_Diagnostics_Debugger::Break___STATIC__VOID( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    NANOCLR_HEADER();

#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)

    if(stack.m_customState == 0)
    {
        stack.m_customState++;
        g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Break( &stack );

        hr = CLR_E_RESCHEDULE;  NANOCLR_LEAVE();
    }

    NANOCLR_NOCLEANUP();

#else
    (void)stack;
    NANOCLR_NOCLEANUP_NOLABEL();

#endif

}
<|endoftext|>